Editing a thread content
Create site27 by copying site26.
- /cms
- ...
- site26
- site27
In this chapter, we are going to create the thread content editor.
To test the result online, enter http://www.frasq.org/cms/site27 in the address bar of your navigator.
Identify yourself with the name foobar
and the password f00bar
.
Edit the page Legal information.
Click on the name of the thread in the top right corner of the page.
NOTE: In this demonstration version, the content of the site can not be modified.
Edit the file models/thread.inc and add the functions thread_create_node
, thread_delete_node
and thread_set_node_number
with the following contents:
- function thread_create_node($lang, $thread_id, $node_name, $node_title, $node_number=0) {
- $tabthreadnode=db_prefix_table('thread_node');
- $sql="SELECT COUNT(*)+1 AS n FROM $tabthreadnode WHERE thread_id=$thread_id";
- $r = db_query($sql);
- if (!$r) {
- return false;
- }
- $n = $r[0]['n'];
- if ($node_number < 1 or $node_number > $n) {
- $node_number = $n;
- }
- $r = node_create($lang, $node_name, $node_title);
- if (!$r) {
- return false;
- }
- extract($r); /* node_id */
- if ($node_number != $n) {
- $sql="UPDATE $tabthreadnode SET number=number+1 WHERE thread_id=$thread_id AND number >= $node_number ORDER BY number";
- db_update($sql);
- }
- $sql="INSERT $tabthreadnode SET thread_id=$thread_id, node_id=$node_id, number=$node_number";
- $r = db_insert($sql);
- return $r ? compact('node_id', 'node_number') : false;
- }
thread_create_node
adds a new node to thread $thread_id
with $node_url
as URL and $node_title
as title for the language $lang
.
The new node is placed at position $number
in the thread or, if $number
isn't specified, at the end of the thread.
thread_create_node
returns the identifier of the new node and its position in the thread or false
in case of error.
thread_create_node
checks if the parameter $number
is between 1 and the number of nodes in the thread plus one. If $number
isn't specified or if it's invalid, the node is added at the end of the thread.
Once the node has been created by node_create
, if the node isn't added at the end of the thread, all the nodes following the position of the new node are shifted.
thread_create_node
finishes the creation of the node by adding it to the thread at the requested position.
- function thread_delete_node($thread_id, $node_id) {
- $tabthreadnode=db_prefix_table('thread_node');
- $sql="DELETE FROM $tabthreadnode WHERE thread_id=$thread_id AND node_id=$node_id LIMIT 1";
- $r = db_delete($sql);
- if (!$r) {
- return false;
- }
- $sql="SET @n=0";
- db_update($sql);
- $sql="UPDATE $tabthreadnode SET number=(@n:=@n+1) WHERE thread_id=$thread_id ORDER BY number";
- db_update($sql);
- $sql="SELECT COUNT(*) AS count FROM $tabthreadnode WHERE node_id=$node_id";
- $r = db_query($sql);
- if (!$r) {
- return false;
- }
- if ($r[0]['count'] != 0) {
- return true;
- }
- $r = node_delete($node_id);
- if (!$r) {
- return false;
- }
- return true;
- }
thread_delete_node
removes node $node_id
from thread $thread_id
and deletes it if no other thread contains it.
thread_delete_node
returns true
or false
in case of error.
thread_delete_node
starts by deleting the link between the thread and the node and renumbering all the nodes of the thread.
thread_delete_node
then counts how many threads contain $node_id
and deletes $node_id
with node_delete
if the answer is 0.
- function thread_set_node_number($thread_id, $node_id, $number) {
- $tabthreadnode=db_prefix_table('thread_node');
- $sql="UPDATE $tabthreadnode SET number=$number WHERE thread_id=$thread_id AND node_id=$node_id LIMIT 1";
- $r = db_update($sql);
- return $r;
- }
thread_set_node_number
sets the order number of node $node_id
in thread $thread_id
to $number
.
- else if (isset($_POST['thread_reorder'])) {
- $action='reorder';
- }
- else if (isset($_POST['node_create'])) {
- $action='create';
- }
- else if (isset($_POST['node_delete'])) {
- $action='delete';
- }
- $new_node_name=$new_node_title=$new_node_number=false;
- $old_node_number=false;
- $thread_contents = false;
- $p=false;
- case 'create':
- case 'delete':
- case 'reorder':
- if (isset($_POST['new_node_title'])) {
- $new_node_title=readarg($_POST['new_node_title']);
- $new_node_name = strtofname($new_node_title);
- }
- if (isset($_POST['new_node_number'])) {
- $new_node_number=readarg($_POST['new_node_number']);
- }
- if (isset($_POST['old_node_number'])) {
- $old_node_number=readarg($_POST['old_node_number']);
- }
- if (isset($_POST['p'])) {
- $p=$_POST['p']; // DON'T readarg!
- }
- $r = thread_get_contents($clang, $thread_id, false); /* node_id node_name node_title node_cloud node_number ... */
- if (count($p) != count($r)) {
- $p = false;
- }
- if ($r) {
- $pos=1;
- $thread_contents = array();
- $thread_url = url('threadedit', $lang) . '/'. $thread_id;
- foreach ($r as $c) {
- $c['node_url'] = $thread_url . '/' . $c['node_id'];
- $c['pos'] = $p ? $p[$pos] : $pos;
- $thread_contents[$pos] = $c;
- $pos++;
- }
- }
- $missing_new_node_title=false;
- $bad_new_node_title=false;
- $bad_new_node_number=false;
- $missing_old_node_number=false;
- $bad_old_node_number=false;
- case 'create':
- if (empty($new_node_title)) {
- $missing_new_node_title = true;
- }
- else if (empty($new_node_name)) {
- $bad_new_node_title = true;
- }
- else if (!preg_match('#^[\w-]{3,}$#', $new_node_name)) {
- $bad_new_node_title = true;
- }
- if (empty($new_node_number)) {
- $new_node_number = false;
- }
- else if (!is_numeric($new_node_number)) {
- $bad_new_node_number = true;
- }
- else if ($new_node_number < 1 or $new_node_number > count($thread_contents) + 1) {
- $bad_new_node_number = true;
- }
- break;
- case 'delete':
- if (empty($old_node_number)) {
- $missing_old_node_number = true;
- }
- else if (!is_numeric($old_node_number)) {
- $bad_old_node_number = true;
- }
- else if ($old_node_number < 1 or $old_node_number > count($thread_contents)) {
- $bad_old_node_number = true;
- }
- break;
- break;
- case 'create':
- if ($missing_new_node_title or $bad_new_node_title or $bad_new_node_number) {
- break;
- }
- $np = thread_create_node($clang, $thread_id, $new_node_name, $new_node_title, $new_node_number);
- if (!$np) {
- break;
- }
- extract($np); /* node_id node_number node_ignored */
- $node_title = $new_node_title;
- $node_url = url('threadedit', $lang) . '/'. $thread_id . '/' . $node_id;
- $pos = $node_number;
- if ($thread_contents) {
- foreach ($thread_contents as &$c) {
- if ($c['node_number'] >= $pos) {
- $c['node_number']++;
- }
- if ($c['pos'] >= $pos) {
- $c['pos']++;
- }
- }
- array_splice($thread_contents, $pos-1, 0, array(compact('node_id', 'node_title', 'node_number', 'node_url', 'pos')));
- }
- else {
- $pos=1;
- $thread_contents=array($pos => compact('node_id', 'node_title', 'node_number', 'node_url', 'pos'));
- }
- break;
- case 'delete':
- if ($missing_old_node_number or $bad_old_node_number) {
- break;
- }
- if (!$confirmed) {
- $confirm_delete_node=true;
- break;
- }
- $node_id = $thread_contents[$old_node_number]['node_id'];
- $r = thread_delete_node($thread_id, $node_id);
- if (!$r) {
- break;
- }
- unset($thread_contents[$old_node_number]);
- $thread_contents = array_values($thread_contents);
- foreach ($thread_contents as &$c) {
- if ($c['node_number'] >= $old_node_number) {
- $c['node_number']--;
- }
- if ($c['pos'] >= $old_node_number) {
- $c['pos']--;
- }
- }
- $old_node_number = false;
- break;
- case 'reorder':
- if (!$p) {
- break;
- }
- $neworder=range(1, count($p));
- array_multisort($p, SORT_NUMERIC, $neworder);
- $thread_contents = $nc;
- break;
- <h4>Contents</h4>
- <p>
- <input id="node_create" name="node_create" type="submit" value="Add" />
- content
- <input id="new_node_title" name="new_node_title" type="text" size="50" maxlength="100" value="<?php echo htmlspecialchars($new_node_title, ENT_COMPAT, 'UTF-8'); ?>" title="Title" onkeypress="return focusonenter(event, 'new_node_number')"/>
- #
- <input id="new_node_number" name="new_node_number" type="text" size="2" maxlength="3" value="<?php echo htmlspecialchars($new_node_number, ENT_COMPAT, 'UTF-8'); ?>" title="Number" onkeypress="return submitonenter(event, 'node_create')"/>
- </p>
- <?php if ($missing_new_node_title or $bad_new_node_title or $bad_new_node_number): ?>
- <div class="alert">
- <?php if ($missing_new_node_title): ?>
- <p>You didn't input the title of the new content.</p>
- <?php elseif ($bad_new_node_title): ?>
- <p>The title of the new content is invalid.</p>
- <?php endif; ?>
- <?php if ($bad_new_node_number): ?>
- <p>The new content number is not correct.</p>
- <?php endif; ?>
- </div>
- <?php endif; ?>
- <?php if ($thread_contents): ?>
- <fieldset>
- <legend>Summary</legend>
- <table cellpadding="2" cellspacing="0">
- <tbody>
- <?php
- $i=1;
- $maxlen=strlen(count($thread_contents))+1;
- foreach ($thread_contents as $c) {
- extract($c); /* pos, node_title, node_url, node_number */
- $node_title = htmlspecialchars($node_title, ENT_COMPAT, 'UTF-8');
- $node_url .= '?' . 'clang=' . $clang;
- echo <<<_MARK_
- <tr><td><input name="p[$i]" type="text" size="2" maxlength="$maxlen" value="$pos" /></td><td class="aright"><a href="$node_url">$node_number</a></td><td><a href="$node_url">$node_title</a></td></tr>\n
- _MARK_;
- $i++;
- }
- ?>
- </tbody>
- </table>
- </fieldset>
- <p>
- <input id="thread_reorder" name="thread_reorder" type="submit" value="Sort" />
- the list or
- <input id="node_delete" name="node_delete" type="submit" value="Delete" />
- content #
- <input id="old_node_number" name="old_node_number" type="text" size="2" maxlength="3" value="<?php echo htmlspecialchars($old_node_number, ENT_COMPAT, 'UTF-8'); ?>" title="Number" onkeypress="return submitonenter(event, 'node_delete')"/>
- </p>
- <?php if ($missing_old_node_number or $bad_old_node_number): ?>
- <div class="alert">
- <?php if ($missing_old_node_number): ?>
- <p>You didn't specify the content number to delete.</p>
- <?php elseif ($bad_old_node_number): ?>
- <p>The content number to delete is not correct.</p>
- <?php endif; ?>
- </div>
- <?php endif; ?>
- <?php endif; ?>
- </form>
- <h4>Contenu</h4>
- <p>
- <input id="node_create" name="node_create" type="submit" value="Ajouter" />
- le contenu
- <input id="new_node_title" name="new_node_title" type="text" size="50" maxlength="100" value="<?php echo htmlspecialchars($new_node_title, ENT_COMPAT, 'UTF-8'); ?>" title="Titre" onkeypress="return focusonenter(event, 'new_node_number')"/>
- #
- <input id="new_node_number" name="new_node_number" type="text" size="2" maxlength="3" value="<?php echo htmlspecialchars($new_node_number, ENT_COMPAT, 'UTF-8'); ?>" title="Numéro" onkeypress="return submitonenter(event, 'node_create')"/>
- </p>
- <?php if ($missing_new_node_title or $bad_new_node_title or $bad_new_node_number): ?>
- <div class="alert">
- <?php if ($missing_new_node_title): ?>
- <p>Vous n'avez pas saisi le titre du nouveau contenu.</p>
- <?php elseif ($bad_new_node_title): ?>
- <p>Le titre du nouveau contenu est invalide.</p>
- <?php endif; ?>
- <?php if ($bad_new_node_number): ?>
- <p>Le numéro du nouveau contenu n'est pas correct.</p>
- <?php endif; ?>
- </div>
- <?php endif; ?>
- <?php if ($thread_contents): ?>
- <fieldset>
- <legend>Sommaire</legend>
- <table cellpadding="2" cellspacing="0">
- <tbody>
- <?php
- $i=1;
- $maxlen=strlen(count($thread_contents))+1;
- foreach ($thread_contents as $c) {
- extract($c); /* pos, node_title, node_number, node_url */
- $node_title = htmlspecialchars($node_title, ENT_COMPAT, 'UTF-8');
- $node_url .= '?' . 'clang=' . $clang;
- echo <<<_MARK_
- <tr><td><input name="p[$i]" type="text" size="2" maxlength="$maxlen" value="$pos" /></td><td class="aright"><a href="$node_url">$node_number</a></td><td><a href="$node_url">$node_title</a></td></tr>\n
- _MARK_;
- $i++;
- }
- ?>
- </tbody>
- </table>
- </fieldset>
- <p>
- <input id="thread_reorder" name="thread_reorder" type="submit" value="Trier" />
- la liste ou
- <input id="node_delete" name="node_delete" type="submit" value="Supprimer" />
- le contenu #
- <input id="old_node_number" name="old_node_number" type="text" size="2" maxlength="3" value="<?php echo htmlspecialchars($old_node_number, ENT_COMPAT, 'UTF-8'); ?>" title="Numéro" onkeypress="return submitonenter(event, 'node_delete')"/>
- </p>
- <?php if ($missing_old_node_number or $bad_old_node_number): ?>
- <div class="alert">
- <?php if ($missing_old_node_number): ?>
- <p>Vous n'avez pas saisi le numéro du contenu à supprimer.</p>
- <?php elseif ($bad_old_node_number): ?>
- <p>Le numéro du contenu à supprimer est incorrect.</p>
- <?php endif; ?>
- </div>
- <?php endif; ?>
- <?php endif; ?>
- </form>
Comments