tagging as ATutor 1.5.4-release
[atutor.git] / include / classes / ContentManager.class.php
1 <?php
2 /****************************************************************/
3 /* ATutor                                                                                                               */
4 /****************************************************************/
5 /* Copyright (c) 2002-2006 by Greg Gay & Joel Kronenberg        */
6 /* Adaptive Technology Resource Centre / University of Toronto  */
7 /* http://atutor.ca                                                                                             */
8 /*                                                              */
9 /* This program is free software. You can redistribute it and/or*/
10 /* modify it under the terms of the GNU General Public License  */
11 /* as published by the Free Software Foundation.                                */
12 /****************************************************************/
13 // $Id$
14
15 class ContentManager
16 {
17         /* db handler   */
18         var $db;
19
20         /*      array           */
21         var $_menu;
22
23         /*      array           */
24         var $_menu_info;
25
26         /* int                  */
27         var $course_id;
28
29         // private
30         var $num_sections;
31
32         // private
33         var $max_depth;
34
35         // private
36         var $content_length;
37
38         /* constructor  */
39         function ContentManager(&$db, $course_id) {
40                 $this->db = $db;
41                 $this->course_id = $course_id;
42         }
43
44         function initContent( ) {
45                 if ($this->course_id == '') {
46                         return;
47                 }
48                 $sql = "SELECT content_id, content_parent_id, ordering, title, UNIX_TIMESTAMP(release_date) AS u_release_date FROM ".TABLE_PREFIX."content WHERE course_id=$this->course_id ORDER BY content_parent_id, ordering";
49                 $result = mysql_query($sql, $this->db);
50
51                 /* x could be the ordering or even the content_id       */
52                 /* don't really need the ordering anyway.                       */
53                 /* $_menu[content_parent_id][x] = array('content_id', 'ordering', 'title') */
54                 $_menu = array();
55
56                 /* number of content sections */
57                 $num_sections = 0;
58
59                 $max_depth = array();
60
61                 while ($row = mysql_fetch_assoc($result)) {
62                         $num_sections++;
63                         $_menu[$row['content_parent_id']][] = array('content_id'=> $row['content_id'],
64                                                                                                                 'ordering'      => $row['ordering'], 
65                                                                                                                 'title'         => htmlspecialchars($row['title']));
66
67                         $_menu_info[$row['content_id']] = array('content_parent_id' => $row['content_parent_id'],
68                                                                                                         'title'                         => htmlspecialchars($row['title']),
69                                                                                                         'ordering'                      => $row['ordering'],
70                                                                                                         'u_release_date'      => $row['u_release_date']);
71
72                         if ($row['content_parent_id'] == 0){
73                                 $max_depth[$row['content_id']] = 1;
74                         } else {
75                                 $max_depth[$row['content_id']] = $max_depth[$row['content_parent_id']]+1;
76                         }
77                 }
78
79                 $this->_menu = $_menu;
80
81                 $this->_menu_info =  $_menu_info;
82
83                 $this->num_sections = $num_sections;
84
85                 if (count($max_depth) > 1) {
86                         $this->max_depth = max($max_depth);
87                 } else {
88                         $this->max_depth = 0;
89                 }
90
91                 $this->content_length = count($_menu[0]);
92         }
93
94
95         function getContent($parent_id=-1, $length=-1) {
96                 if ($parent_id == -1) {
97                         $my_menu_copy = $this->_menu;
98                         if ($length != -1) {
99                                 $my_menu_copy[0] = array_slice($my_menu_copy[0], 0, $length);
100                         }
101                         return $my_menu_copy;
102                 }
103                 return $this->_menu[$parent_id];
104         }
105
106
107         function &getContentPath($content_id) {
108                 $path = array();
109
110                 $path[] = array('content_id' => $content_id, 'title' => $this->_menu_info[$content_id]['title']);
111
112                 $this->getContentPathRecursive($content_id, $path);
113
114                 $path = array_reverse($path);
115                 return $path;
116         }
117
118
119         function getContentPathRecursive($content_id, &$path) {
120                 $parent_id = $this->_menu_info[$content_id]['content_parent_id'];
121
122                 if ($parent_id > 0) {
123                         $path[] = array('content_id' => $parent_id, 'title' => $this->_menu_info[$parent_id]['title']);
124                         $this->getContentPathRecursive($parent_id, $path);
125                 }
126         }
127
128
129         function addContent($course_id, $content_parent_id, $ordering, $title, $text, $keywords, $related, $formatting, $release_date) {
130                 
131                 if (!authenticate(AT_PRIV_CONTENT, AT_PRIV_RETURN) && ($_SESSION['course_id'] != -1)) {
132                         return false;
133                 }
134
135                 // shift the new neighbouring content down
136                 $sql = "UPDATE ".TABLE_PREFIX."content SET ordering=ordering+1 WHERE ordering>=$ordering AND content_parent_id=$content_parent_id AND course_id=$_SESSION[course_id]";
137                 $result = mysql_query($sql, $this->db);
138
139                 /* main topics all have minor_num = 0 */
140                 $sql = "INSERT INTO ".TABLE_PREFIX."content VALUES (NULL,$course_id, $content_parent_id, $ordering, NOW(), 0, $formatting, '$release_date', '$keywords', '', '$title','$text')";
141
142                 $err = mysql_query($sql, $this->db);
143
144                 /* insert the related content */
145                 $sql = "SELECT LAST_INSERT_ID() AS insert_id";
146                 $result = mysql_query($sql, $this->db);
147                 $row = mysql_fetch_assoc($result);
148                 $cid = $row['insert_id'];
149
150                 $sql = '';
151                 if (is_array($related)) {
152                         foreach ($related as $x => $related_content_id) {
153                                 $related_content_id = intval($related_content_id);
154
155                                 if ($related_content_id != 0) {
156                                         if ($sql != '') {
157                                                 $sql .= ', ';
158                                         }
159                                         $sql .= '('.$cid.', '.$related_content_id.')';
160                                         $sql .= ', ('.$related_content_id.', '.$cid.')';
161                                 }
162                         }
163
164                         if ($sql != '') {
165                                 $sql    = 'INSERT INTO '.TABLE_PREFIX.'related_content VALUES '.$sql;
166                                 $result = mysql_query($sql, $this->db);
167                         }
168                 }
169
170                 return $cid;
171         }
172
173
174         function editContent($content_id, $title, $text, $keywords, $new_content_ordering, $related, $formatting, $new_content_parent_id, $release_date) {
175                 if (!authenticate(AT_PRIV_CONTENT, AT_PRIV_RETURN)) {
176                         return FALSE;
177                 }
178
179                 /* first get the content to make sure it exists */
180                 $sql    = "SELECT ordering, content_parent_id FROM ".TABLE_PREFIX."content WHERE content_id=$content_id AND course_id=$_SESSION[course_id]";
181                 $result = mysql_query($sql, $this->db);
182                 if (!($row = mysql_fetch_assoc($result)) ) {
183                         return FALSE;
184                 }
185                 $old_ordering           = $row['ordering'];
186                 $content_parent_id      = $row['content_parent_id'];
187                 if (($content_parent_id != $new_content_parent_id) || ($old_ordering != $new_content_ordering)) {
188                         // remove the gap left by the moved content
189                         $sql = "UPDATE ".TABLE_PREFIX."content SET ordering=ordering-1 WHERE ordering>=$old_ordering AND content_parent_id=$content_parent_id AND content_id<>$content_id AND course_id=$_SESSION[course_id]";
190                         $result = mysql_query($sql, $this->db);
191
192                         // shift the new neighbouring content down
193                         $sql = "UPDATE ".TABLE_PREFIX."content SET ordering=ordering+1 WHERE ordering>=$new_content_ordering AND content_parent_id=$new_content_parent_id AND content_id<>$content_id AND course_id=$_SESSION[course_id]";
194                         $result = mysql_query($sql, $this->db);
195                 }
196
197                 /* update the title, text of the newly moved (or not) content */
198                 $sql    = "UPDATE ".TABLE_PREFIX."content SET title='$title', text='$text', keywords='$keywords', formatting=$formatting, content_parent_id=$new_content_parent_id, ordering=$new_content_ordering, revision=revision+1, last_modified=NOW(), release_date='$release_date' WHERE content_id=$content_id AND course_id=$_SESSION[course_id]";
199                 $result = mysql_query($sql, $this->db);
200
201                 /* update the related content */
202                 $result = mysql_query("DELETE FROM ".TABLE_PREFIX."related_content WHERE content_id=$content_id OR related_content_id=$content_id", $this->db);
203                 $sql = '';
204                 if (is_array($related)) {
205                         foreach ($related as $x => $related_content_id) {
206                                 $related_content_id = intval($related_content_id);
207
208                                 if ($related_content_id != 0) {
209                                         if ($sql != '') {
210                                                 $sql .= ', ';
211                                         }
212                                         $sql .= '('.$content_id.', '.$related_content_id.')';
213                                         $sql .= ', ('.$related_content_id.', '.$content_id.')';
214                                 }
215                         }
216
217                         if ($sql != '') {
218                                 /* delete the old related content */
219                                 $result = mysql_query("DELETE FROM ".TABLE_PREFIX."related_content WHERE content_id=$content_id OR related_content_id=$content_id", $this->db);
220
221                                 /* insert the new, and the old related content again */
222                                 $sql    = 'INSERT INTO '.TABLE_PREFIX.'related_content VALUES '.$sql;
223                                 $result = mysql_query($sql, $this->db);
224                         }
225                 }
226         }
227
228
229         function deleteContent($content_id) {
230                 if (!authenticate(AT_PRIV_CONTENT, AT_PRIV_RETURN)) {
231                         return false;
232                 }
233
234                 /* check if exists */
235                 $sql    = "SELECT ordering, content_parent_id FROM ".TABLE_PREFIX."content WHERE content_id=$content_id AND course_id=$_SESSION[course_id]";
236                 $result = mysql_query($sql, $this->db);
237                 if (!($row = @mysql_fetch_assoc($result)) ) {
238                         return false;
239                 }
240                 $ordering                       = $row['ordering'];
241                 $content_parent_id      = $row['content_parent_id'];
242
243                 /* check if this content has sub content        */
244                 $children = $this->_menu[$content_id];
245
246                 if (is_array($children) && (count($children)>0) ) {
247                         /* delete its children recursively first*/
248                         foreach ($children as $x => $info) {
249                                 $this->deleteContentRecursive($info['content_id']);
250                         }
251                 }
252
253                 /* delete this content page                                     */
254                 $sql    = "DELETE FROM ".TABLE_PREFIX."content WHERE content_id=$content_id AND course_id=$_SESSION[course_id]";
255                 $result = mysql_query($sql, $this->db);
256
257                 /* delete this content from member tracking page        */
258                 $sql    = "DELETE FROM ".TABLE_PREFIX."member_track WHERE content_id=$content_id AND course_id=$_SESSION[course_id]";
259                 $result = mysql_query($sql, $this->db);
260
261                 $sql    = "DELETE FROM ".TABLE_PREFIX."related_content WHERE content_id=$content_id OR related_content_id=$content_id";
262                 $result = mysql_query($sql, $this->db);
263
264                 /* re-order the rest of the content */
265                 $sql = "UPDATE ".TABLE_PREFIX."content SET ordering=ordering-1 WHERE ordering>=$ordering AND content_parent_id=$content_parent_id AND course_id=$_SESSION[course_id]";
266                 $result = mysql_query($sql, $this->db);
267                 /* end moving block */
268
269                 /* remove the "resume" to this page, b/c it was deleted */
270                 $sql = "UPDATE ".TABLE_PREFIX."course_enrollment SET last_cid=0 WHERE course_id=$_SESSION[course_id] AND last_cid=$content_id";
271                 $result = mysql_query($sql, $this->db);
272
273                 return true;
274         }
275
276
277         /* private. call from deleteContent only. */
278         function deleteContentRecursive($content_id) {
279                 /* check if this content has sub content        */
280                 $children = $this->_menu[$content_id];
281
282                 if (is_array($children) && (count($children)>0) ) {
283                         /* delete its children recursively first*/
284                         foreach ($children as $x => $info) {
285                                 $this->deleteContent($info['content_id']);
286                         }
287                 }
288
289                 /* delete this content page                                     */
290                 $sql    = "DELETE FROM ".TABLE_PREFIX."content WHERE content_id=$content_id AND course_id=$_SESSION[course_id]";
291                 $result = mysql_query($sql, $this->db);
292
293                 /* delete this content from member tracking page        */
294                 $sql    = "DELETE FROM ".TABLE_PREFIX."member_track WHERE content_id=$content_id";
295                 $result = mysql_query($sql, $this->db);
296
297                 $sql    = "DELETE FROM ".TABLE_PREFIX."related_content WHERE content_id=$content_id OR related_content_id=$content_id";
298                 $result = mysql_query($sql, $this->db);
299         }
300
301         function & getContentPage($content_id) {
302                 $sql    = "SELECT *, DATE_FORMAT(release_date, '%Y-%m-%d %H:%i:00') AS release_date, release_date+0 AS r_date, NOW()+0 AS n_date FROM ".TABLE_PREFIX."content WHERE content_id=$content_id AND course_id=$this->course_id";
303                 $result = mysql_query($sql, $this->db);
304
305                 return $result;
306         }
307         
308         /* @See editor/edit_content.php include/html/dropdowns/related_topics.inc.php include/lib/editor_tabs_functions.inc.php */
309         function getRelatedContent($content_id, $all=false) {
310                 if ($content_id == 0) {
311                         return;
312                 }
313                 if ($content_id == '') {
314                         return;
315                 }
316                 $related_content = array();
317
318                 if ($all) {
319                         $sql = "SELECT * FROM ".TABLE_PREFIX."related_content WHERE content_id=$content_id OR related_content_id=$content_id";
320                 } else {
321                         $sql = "SELECT * FROM ".TABLE_PREFIX."related_content WHERE content_id=$content_id";
322                 }
323                 $result = mysql_query($sql, $this->db);
324
325                 while ($row = mysql_fetch_assoc($result)) {
326                         if ($row['related_content_id'] != $content_id) {
327                                 $related_content[] = $row['related_content_id'];
328                         } else {
329                                 $related_content[] = $row['content_id'];
330                         }
331                 }
332
333                 return $related_content;
334         }
335
336
337         function & cleanOutput($value) {
338                 return stripslashes(htmlspecialchars($value));
339         }
340
341
342         /* @See include/html/editor_tabs/properties.inc.php */
343         /* Access: Public */
344         function getNumSections() {
345                 return $this->num_sections;
346         }
347
348         /* Access: Public */
349         function getMaxDepth() {
350                 return $this->max_depth;
351         }
352
353         /* Access: Public */
354         function getContentLength() {
355                 return $this->content_length;
356         }
357
358         /* @See include/html/dropdowns/local_menu.inc.php */
359         function getLocationPositions($parent_id, $content_id) {
360                 $siblings = $this->getContent($parent_id);
361                 for ($i=0;$i<count($siblings); $i++){
362                         if ($siblings[$i]['content_id'] == $content_id) {
363                                 return $i;
364                         }
365                 }
366                 return 0;       
367         }
368
369         /* Access: Private */
370         function getNumbering($content_id) {
371                 $path = $this->getContentPath($content_id);
372                 $parent = 0;
373                 $numbering = '';
374                 foreach ($path as $page) {
375                         $num = $this->getLocationPositions($parent, $page['content_id']) +1;
376                         $parent = $page['content_id'];
377                         $numbering .= $num.'.';
378                 }
379                 $numbering = substr($numbering, 0, -1);
380
381                 return $numbering;
382         }
383
384         /* Access: Private */
385         function getPreviousContent($content_id, $order=0) {
386                 $myParent = $this->_menu_info[$content_id]['content_parent_id'];
387                 $myOrder  = $this->_menu_info[$content_id]['ordering'];
388
389                 if (($this->_menu[$myParent][$myOrder-2] != '') && ($order==0)) {
390                         // has sibling: checking if sibling has children
391                         
392                         $mySibling = $this->_menu[$myParent][$myOrder-2];
393                         
394                         if ( is_array($this->_menu[$mySibling['content_id']]) && ($order==0) ) {
395                                 $num_children = count($this->_menu[$mySibling['content_id']]);
396
397                                 // sibling has $num_children children
398                                 
399                                 return($this->getPreviousContent($this->_menu[$mySibling[content_id]][$num_children-1]['content_id'], 1));
400
401                         } else {
402                                 // sibling has no children. return it
403                                 return($this->_menu[$myParent][$myOrder-2]);
404                         }
405
406                 } else {
407                         if ($myParent == 0) {
408                                 /* we're at the top */
409                                 return '';
410                         }
411
412                         /* No more siblings */
413                         if ($order == 0) {
414                                 return(array('content_id'       => $myParent,
415                                                          'ordering'             => $this->_menu_info[$myParent]['ordering'],
416                                                          'title'                => $this->_menu_info[$myParent]['title']));
417                         } else {
418                                 if ( is_array($this->_menu[$content_id]) ) {
419                                         $num_children = count($this->_menu[$content_id]);
420                                         return ($this->getPreviousContent($this->_menu[$content_id][$num_children-1]['content_id'], 1));
421
422                                 } else {
423                                         /* no children */
424                                         return(array('content_id'       => $content_id,
425                                                                  'ordering'             => $this->_menu_info[$content_id]['ordering'],
426                                                                  'title'                => $this->_menu_info[$content_id]['title']));
427                                 }
428                         }
429                 }
430         }
431
432         /* Access: Private */
433         function getNextContent($content_id, $order=0) {
434                 $myParent = $this->_menu_info[$content_id]['content_parent_id'];
435                 $myOrder  = $this->_menu_info[$content_id]['ordering'];
436
437                 /* if this content has children, then take the first one. */
438                 if ( is_array($this->_menu[$content_id]) && ($order==0) ) {
439                         /* has children */
440                         return($this->_menu[$content_id][0]);
441                 } else {
442                         /* no children */
443                         if ($this->_menu[$myParent][$myOrder] != '') {
444                                 /* Has sibling */
445                                 return($this->_menu[$myParent][$myOrder]);
446                         } else {
447                                 /* No more siblings */
448                                 if ($myParent != 0) {
449                                         return($this->getNextContent($myParent, 1));
450                                 }
451                         }
452                 }
453         }
454
455         /* @See include/header.inc.php */
456         function generateSequenceCrumbs($cid) {
457                 global $_base_path;
458
459                 $sequence_links = array();
460
461                 $first = $this->getNextContent(0); // get first
462                 if ($_SESSION['prefs']['PREF_NUMBERING'] && $first) {
463                         $first['title'] = $this->getNumbering($first['content_id']).' '.$first['title'];
464                 }
465                 if ($first) {
466                         $first['url'] = $_base_path.'content.php?cid='.$first['content_id'];
467                         $sequence_links['first'] = $first;
468                 }
469
470                 if (!$cid && $_SESSION['s_cid']) {
471                         $resume['title'] = $this->_menu_info[$_SESSION['s_cid']]['title'];
472
473                         if ($_SESSION['prefs']['PREF_NUMBERING']) {
474                                 $resume['title'] = $this->getNumbering($_SESSION['s_cid']).' ' . $resume['title'];
475                         }
476
477                         $resume['url'] = $_base_path.'content.php?cid='.$_SESSION['s_cid'];
478
479                         $sequence_links['resume'] = $resume;
480                 } else {
481                         if ($cid) {
482                                 $previous = $this->getPreviousContent($cid);
483                         }
484                         $next = $this->getNextContent($cid ? $cid : 0);
485
486                         if ($_SESSION['prefs']['PREF_NUMBERING']) {
487                                 $previous['title'] = $this->getNumbering($previous['content_id']).' '.$previous['title'];
488                                 $next['title'] = $this->getNumbering($next['content_id']).' '.$next['title'];
489                         }
490
491                         $next['url'] = $_base_path.'content.php?cid='.$next['content_id'];
492                         $previous['url'] = $_base_path.'content.php?cid='.$previous['content_id'];
493                         
494                         if ($previous['content_id']) {
495                                 $sequence_links['previous'] = $previous;
496                         } else if ($cid) {
497                                 $previous['url']   = $_base_path . 'index.php';
498                                 $previous['title'] = _AT('home');
499                                 $sequence_links['previous'] = $previous;
500                         }
501                         if ($next['content_id']) {
502                                 $sequence_links['next'] = $next;
503                         }
504                 }
505
506                 return $sequence_links;
507         }
508
509         /* @See include/html/dropdowns/menu_menu.inc.php */
510         function printMainMenu( ) {
511                 $parent_id    = 0;
512                 $depth        = 0;
513                 $path         = '';
514                 $children     = array();
515                 $truncate     = true;
516                 $ignore_state = false;
517
518                 $this->start = true;
519                 $this->printMenu($parent_id, $depth, $path, $children, $truncate, $ignore_state);
520         }
521
522         /* @See tools/sitemap/index.php */
523         function printSiteMapMenu() {
524                 $parent_id    = 0;
525                 $depth        = 1;
526                 $path         = '';
527                 $children     = array();
528                 $truncate     = false;
529                 $ignore_state = true;
530
531                 $this->start = true;
532                 $this->printMenu($parent_id, $depth, $path, $children, $truncate, $ignore_state);
533         }
534
535         /* @See index.php */
536         function printTOCMenu($cid, $top_num) {
537                 $parent_id    = $cid;
538                 $depth        = 1;
539                 $path         = $top_num.'.';
540                 $children     = array();
541                 $truncate     = false;
542                 $ignore_state = false;
543
544                 $this->start = true;
545                 $this->printMenu($parent_id, $depth, $path, $children, $truncate, $ignore_state);
546         }
547
548         /* @See index.php include/html/dropdowns/local_menu.inc.php */
549         function printSubMenu($cid, $top_num) {
550                 $parent_id    = $cid;
551                 $depth        = 1;
552                 $path         = $top_num.'.';
553                 $children     = array();
554                 $truncate     = true;
555                 $ignore_state = false;
556         
557                 $this->start = true;
558                 $this->printMenu($parent_id, $depth, $path, $children, $truncate, $ignore_state);
559         }
560
561         /* @See include/html/menu_menu.inc.php  */
562         /* Access: PRIVATE */
563         function printMenu($parent_id, $depth, $path, $children, $truncate, $ignore_state) {
564                 
565                 global $cid, $_my_uri, $_base_path, $rtl;
566                 static $temp_path;
567
568                 if (!isset($temp_path)) {
569                         if ($cid) {
570                                 $temp_path      = $this->getContentPath($cid);
571                         } else {
572                                 $temp_path      = $this->getContentPath($_SESSION['s_cid']);
573                         }
574                 }
575
576                 $highlighted = array();
577                 if (is_array($temp_path)) {
578                         foreach ($temp_path as $temp_path_item) {
579                                 $_SESSION['menu'][$temp_path_item['content_id']] = 1;
580                                 $highlighted[$temp_path_item['content_id']] = true;
581                         }
582                 }
583
584                 if ($this->start) {
585                         reset($temp_path);
586                         $this->start = false;
587                 }
588
589                 $top_level = $this->_menu[$parent_id];
590
591                 if ( is_array($top_level) ) {
592                         $counter = 1;
593                         $num_items = count($top_level);
594                         foreach ($top_level as $garbage => $content) {
595                                 $link = '';
596                                 if (!$ignore_state) {
597                                         $link .= '<a name="menu'.$content['content_id'].'"></a>';
598                                 }
599
600                                 $on = false;
601
602                                 if ( ($_SESSION['s_cid'] != $content['content_id']) || ($_SESSION['s_cid'] != $cid) ) {
603                                         if ($highlighted[$content['content_id']]) {
604                                                 $link .= '<strong>';
605                                                 $on = true;
606                                         }
607
608                                         $link .= ' <a href="'.$_base_path.'content.php?cid='.$content['content_id'].'" title="';
609                                         if ($_SESSION['prefs']['PREF_NUMBERING']) {
610                                                 $link .= $path.$counter.' ';
611                                         }
612
613                                         $link .= $content['title'].'">';
614
615                                         if ($truncate && (strlen($content['title']) > (28-$depth*4)) ) {
616                                                 $content['title'] = rtrim(substr($content['title'], 0, (28-$depth*4)-4)).'...';
617                                         }
618                                         $link .= $content['title'];
619                                         $link .= '</a>';
620                                         if ($on) {
621                                                 $link .= '</strong>';
622                                         }
623                                 } else {
624                                         $link .= '<a href="'.$_my_uri.'"><img src="'.$_base_path.'images/clr.gif" alt="'._AT('you_are_here').': '.$content['title'].'" height="1" width="1" border="0" /></a><strong title="'.$content['title'].'">';
625                                         if ($truncate && (strlen($content['title']) > (26-$depth*4)) ) {
626                                                 $content['title'] = rtrim(substr($content['title'], 0, (26-$depth*4)-4)).'...';
627                                         }
628                                         $link .= trim($content['title']).'</strong>';
629                                         $on = true;
630                                 }
631
632                                 if ($ignore_state) {
633                                         $on = true;
634                                 }
635
636                                 if ( is_array($this->_menu[$content['content_id']]) ) {
637                                         /* has children */
638                                         for ($i=0; $i<$depth; $i++) {
639                                                 if ($children[$i] == 1) {
640                                                         echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_vertline.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
641                                                 } else {
642                                                         echo '<img src="'.$_base_path.'images/clr.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
643                                                 }
644                                         }
645
646                                         if (($counter == $num_items) && ($depth > 0)) {
647                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_end.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
648                                                 $children[$depth] = 0;
649                                         } else if ($counter == $num_items) {
650                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_end.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
651                                                 $children[$depth] = 0;
652                                         } else {
653                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_split.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
654                                                 $children[$depth] = 1;
655                                         }
656
657                                         if ($_SESSION['s_cid'] == $content['content_id']) {
658                                                 if (is_array($this->_menu[$content['content_id']])) {
659                                                         $_SESSION['menu'][$content['content_id']] = 1;
660                                                 }
661                                         }
662
663                                         if ($_SESSION['menu'][$content['content_id']] == 1) {
664                                                 if ($on) {
665                                                         echo '<img src="'.$_base_path.'images/tree/tree_disabled.gif" alt="'._AT('toggle_disabled').'" border="0" width="16" height="16" title="'._AT('toggle_disabled').'" class="img-size-tree" />';
666
667                                                 } else {
668                                                         echo '<a href="'.$_my_uri.'collapse='.$content['content_id'].'">';
669                                                         echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_collapse.gif" alt="'._AT('collapse').'" border="0" width="16" height="16" title="'._AT('collapse').' '.$content['title'].'" class="img-size-tree" />';
670                                                         echo '</a>';
671                                                 }
672                                         } else {
673                                                 if ($on) {
674                                                         echo '<img src="'.$_base_path.'images/tree/tree_disabled.gif" alt="'._AT('toggle_disabled').'" border="0" width="16" height="16" title="'._AT('toggle_disabled').'" class="img-size-tree" />';
675
676                                                 } else {
677                                                         echo '<a href="'.$_my_uri.'expand='.$content['content_id'].'">';
678                                                         echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_expand.gif" alt="'._AT('expand').'" border="0" width="16" height="16"   title="'._AT('expand').' '.$content['title'].'" class="img-size-tree" />';
679                                                         echo '</a>';
680                                                 }
681                                         }
682
683                                 } else {
684                                         /* doesn't have children */
685                                         if ($counter == $num_items) {
686                                                 for ($i=0; $i<$depth; $i++) {
687                                                         if ($children[$i] == 1) {
688                                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_vertline.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
689                                                         } else {
690                                                                 echo '<img src="'.$_base_path.'images/clr.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
691                                                         }
692                                                 }
693                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_end.gif" alt="" border="0" class="img-size-tree" />';
694                                         } else {
695                                                 for ($i=0; $i<$depth; $i++) {
696                                                         if ($children[$i] == 1) {
697                                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_vertline.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
698                                                         } else {
699                                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_space.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
700                                                         }
701                                                 }
702                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_split.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
703                                         }
704                                         echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_horizontal.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
705                                 }
706
707                                 if ($_SESSION['prefs']['PREF_NUMBERING']) {
708                                         echo $path.$counter;
709                                 }
710                                 
711                                 echo $link;
712                                 
713                                 echo '<br />';
714
715                                 if ( $ignore_state || ($_SESSION['menu'][$content['content_id']] == 1)) {
716
717                                         $depth ++;
718
719                                         $this->printMenu($content['content_id'],
720                                                                                 $depth, 
721                                                                                 $path.$counter.'.', 
722                                                                                 $children,
723                                                                                 $truncate, 
724                                                                                 $ignore_state);
725
726                                                                                 
727                                         $depth--;
728
729                                 }
730                                 $counter++;
731                         }
732                 }
733         }
734
735         /* @See include/html/editor_tabs/properties.inc.php */
736         function printMoveMenu($menu, $parent_id, $depth, $path, $children) {
737                 
738                 global $cid, $_my_uri, $_base_path, $rtl;
739
740                 static $end, $ignore;
741
742                 $top_level = $menu[$parent_id];
743
744                 if ( is_array($top_level) ) {
745                         $counter = 1;
746                         $num_items = count($top_level);
747                         foreach ($top_level as $garbage => $content) {
748
749                                 $link = ' ';
750
751                                 echo '<tr>';
752
753                                 if (($parent_id == $_POST['new_pid']) && ($content['ordering'] < $_POST['new_ordering'])) {
754                                         $text = _AT('before_topic', $content['title']);
755                                         $img = 'before.gif';
756                                 } else if ($parent_id != $_POST['new_pid']) {
757                                         $text = _AT('before_topic', $content['title']);
758                                         $img = 'before.gif';
759                                 } else {
760                                         $text = _AT('after_topic', $content['title']);
761                                         $img = 'after.gif';
762                                 }
763                                 if ($ignore && ($_POST['cid'] > 0)) {
764                                         $buttons = '<td><small>&nbsp;</small></td><td><small>&nbsp;</small></td><td>';
765                                 } else if ($_POST['new_pid'] == $content['content_id']) {
766                                         $buttons = '<td align="center"><small><input type="image" name="move['.$parent_id.'_'.$content['ordering'].']" src="'.$_base_path.'images/'.$img.'" alt="'.$text.'" title="'.$text.'" style="height:1.5em; width:1.9em;" /></small></td><td><small>&nbsp;</small></td><td>';
767                                 } else {
768                                         $buttons = '<td align="center"><small><input type="image" name="move['.$parent_id.'_'.$content['ordering'].']" src="'.$_base_path.'images/'.$img.'" title="'.$text.'" style="height:1.5em; width:1.9em;" /></small></td><td><input type="image" name="move['.$content['content_id'].'_1]" src="'.$_base_path.'images/child_of.gif" style="height:1.25em; width:1.7em;" alt="'._AT('child_of', $content['title']).'" title="'._AT('child_of', $content['title']).'" /></td><td>';
769                                 }
770
771                                 if (( $content['content_id'] == $cid ) || ($content['content_id'] == -1)) {
772                                         $ignore = true;
773                                         $link .= '<strong>'.trim($_POST['title']).' '._AT('current_location').'</strong>';
774                                         $buttons = '<td colspan="2"><small>&nbsp;</small></td><td>';
775                                 } else {
776                                         $link .= '<input type="checkbox" name="related[]" value="'.$content['content_id'].'" id="r'.$content['content_id'].'" ';
777                                         if (isset($_POST['related']) && in_array($content['content_id'], $_POST['related'])) {
778                                                 $link .= ' checked="checked"';
779                                         }
780                                         $link .= ' /><label for="r'.$content['content_id'].'">'.$content['title'].'</label>';
781                                 }
782
783                                 if ( is_array($menu[$content['content_id']]) && !empty($menu[$content['content_id']]) ) {
784                                         /* has children */
785
786                                         for ($i=0; $i<$depth; $i++) {
787                                                 if ($children[$i] == 1) {
788                                                         echo $buttons;
789                                                         unset($buttons);
790                                                         if ($end && ($i==0)) {
791                                                                 echo '<img src="'.$_base_path.'images/clr.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
792                                                         } else {
793                                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_vertline.gif" alt="" border="0" width="16" height="16" />';
794                                                         }
795                                                 } else {
796                                                         echo '<img src="'.$_base_path.'images/clr.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
797                                                 }
798                                         }
799
800                                         if (($counter == $num_items) && ($depth > 0)) {
801                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_end.gif" alt="" border="0" width="16" height="16" />';
802                                                 $children[$depth] = 0;
803                                         } else {
804                                                 echo $buttons;
805                                                 if (($num_items == $counter) && ($parent_id == 0)) {
806                                                         echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_end.gif" alt="" border="0" width="16" height="16" />';
807                                                         $end = true;
808                                                 } else {
809                                                         echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_split.gif" alt="" border="0" width="16" height="16" />';
810                                                 }
811                                                 $children[$depth] = 1;
812                                         }
813
814                                         if ($_SESSION['s_cid'] == $content['content_id']) {
815                                                 if (is_array($menu[$content['content_id']])) {
816                                                         $_SESSION['menu'][$content['content_id']] = 1;
817                                                 }
818                                         }
819
820                                         if ($_SESSION['menu'][$content['content_id']] == 1) {
821                                                 echo '<img src="'.$_base_path.'images/tree/tree_disabled.gif" alt="'._AT('toggle_disabled').'" border="0" width="16" height="16" title="'._AT('toggle_disabled').'" />';
822
823                                         } else {
824                                                 echo '<img src="'.$_base_path.'images/tree/tree_disabled.gif" alt="'._AT('toggle_disabled').'" border="0" width="16" height="16" title="'._AT('toggle_disabled').'" />';
825                                         }
826
827                                 } else {
828                                         /* doesn't have children */
829                                         if ($counter == $num_items) {
830                                                 if ($depth) {
831                                                         echo $buttons;
832                                                         for ($i=0; $i<$depth; $i++) {
833                                                                 if ($children[$i] == 1) {
834                                                                         if ($end && ($i == 0)) {
835                                                                                 echo '<img src="'.$_base_path.'images/clr.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
836                                                                         } else {
837                                                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_vertline.gif" alt="" border="0" width="16" height="16" />';
838                                                                         }
839                                                                 } else {
840                                                                         echo '<img src="'.$_base_path.'images/clr.gif" alt="" border="0" width="16" height="16" class="img-size-tree" />';
841                                                                 }
842                                                         }
843                                                 } else {
844                                                         echo $buttons;
845                                                 }
846                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_end.gif" alt="" border="0" />';
847                                         } else {
848                                                 if ($depth) {
849                                                         echo $buttons;
850                                                         $print = false;
851                                                         for ($i=0; $i<$depth; $i++) {
852                                                                 if ($children[$i] == 1) {
853                                                                         if ($end && !$print) {
854                                                                                 $print = true;
855                                                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_space.gif" alt="" border="0" width="16" height="16" />';
856                                                                         } else {
857                                                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_vertline.gif" alt="" border="0" width="16" height="16" />';
858                                                                         }
859                                                                 } else {
860                                                                         echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_space.gif" alt="" border="0" width="16" height="16" />';
861                                                                 }
862                                                         }
863                                                         $print = false;
864                                                 } else {
865                                                         echo $buttons;
866                                                 }
867                 
868                                                 echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_split.gif" alt="" border="0" width="16" height="16" />';
869                                         }
870                                         echo '<img src="'.$_base_path.'images/'.$rtl.'tree/tree_horizontal.gif" alt="" border="0" width="16" height="16" />';
871                                 }
872
873                                 echo '<small> '.$path.$counter;
874                                 
875                                 echo $link;
876                                 
877                                 echo '</small></td></tr>';
878
879                                 $this->printMoveMenu($menu,
880                                                                         $content['content_id'],
881                                                                         ++$depth, 
882                                                                         $path.$counter.'.', 
883                                                                         $children);
884                                 $depth--;
885
886                                 $counter++;
887
888                                 if ( $content['content_id'] == $cid ) {
889                                         $ignore =false;
890                                 }
891                         }
892                 }
893         }
894
895
896         /* returns the timestamp of release if this page has not yet been released, or is under a page that has not been released, true otherwise */
897         /* finds the max(timestamp) of all parents and returns that, true if less than now */
898         /* Access: public */
899         function isReleased($cid) {
900                 if ($this->_menu_info[$cid]['content_parent_id'] == 0) {
901                         // this $cid has no parent, so we check its release date directly
902                         if ($this->_menu_info[$cid]['u_release_date'] <= time()) {      
903                                 // yup! it's released
904                                 return true;
905                         } else {
906                                 // nope! not released
907                                 return $this->_menu_info[$cid]['u_release_date'];
908                         }
909                 }
910                 // this is a sub page, need to check ALL its parents
911                 $parent = $this->isReleased($this->_menu_info[$cid]['content_parent_id']); // recursion
912
913                 if ($parent !== TRUE && $parent > $this->_menu_info[$cid]['u_release_date']) {
914                         return $parent;
915                 } else if ($this->_menu_info[$cid]['u_release_date'] <= time()) {
916                         return true;
917                 } else {
918                         return $this->_menu_info[$cid]['u_release_date'];
919                 }
920         }
921 }
922
923 ?>