root/trunk/wifidog-auth/wifidog/classes/Content.php @ 828

Revision 828, 43.0 KB (checked in by fproulx, 8 years ago)

2005-11-11 Fran�ois Proulx <francois.proulx@…>

  • Fixed Admin hotspot location map
  • Take note : Google Maps updated their API key system, so that you simply need to register a key for the whole domain. ie. one key for  http://auth.abc.org will work even in sub-directories
  • Changed the Content classes structure to make them "pluggable" more easily. as requested during last developpers meeting
  • node_list.php now support column sorting, node_id are naturally sorted (numerical order, alphabetic)
  • Added 2-dimensionnal natural sort algorithm to Utils class
  • fixed Node::getSelectNodeUI to naturally sort by node_id
  • Improved Flickr content class
  • Modified Flickr database schema
  • Modified CSS look and feel
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2
3
4/********************************************************************\
5 * This program is free software; you can redistribute it and/or    *
6 * modify it under the terms of the GNU General Public License as   *
7 * published by the Free Software Foundation; either version 2 of   *
8 * the License, or (at your option) any later version.              *
9 *                                                                  *
10 * This program is distributed in the hope that it will be useful,  *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
13 * GNU General Public License for more details.                     *
14 *                                                                  *
15 * You should have received a copy of the GNU General Public License*
16 * along with this program; if not, contact:                        *
17 *                                                                  *
18 * Free Software Foundation           Voice:  +1-617-542-5942       *
19 * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
20 * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
21 *                                                                  *
22 \********************************************************************/
23/**@file Content.php
24 * @author Copyright (C) 2005 Benoit Grégoire <bock@step.polymtl.ca>,
25 * Technologies Coeus inc.
26 */
27require_once BASEPATH.'include/common.php';
28require_once BASEPATH.'classes/FormSelectGenerator.php';
29require_once BASEPATH.'classes/GenericObject.php';
30
31/** Any type of content */
32class Content implements GenericObject
33{
34        protected $id;
35        protected $content_row;
36        private $content_type;
37        private $is_trivial_content;
38        private $is_logging_enabled;
39
40        /** Create a new Content object in the database
41         * @param $content_type Optionnal, the content type to be given to the new object
42         * @param $id Optionnal, the id to be given to the new Content.  If null, a new id will be assigned
43         * @return the newly created Content object, or null if there was an error (an exception is also trown
44         */
45        static function createNewObject($content_type = 'Content', $id = null)
46        {
47                global $db;
48                if (empty ($id))
49                {
50                        $content_id = get_guid();
51                }
52                else
53                {
54                        $content_id = $db->EscapeString($id);
55                }
56
57                if (empty ($content_type))
58                {
59                        throw new Exception(_('Content type is optionnal, but cannot be empty!'));
60                }
61                else
62                {
63                        $content_type = $db->EscapeString($content_type);
64                }
65                $sql = "INSERT INTO content (content_id, content_type) VALUES ('$content_id', '$content_type')";
66
67                if (!$db->ExecSqlUpdate($sql, false))
68                {
69                        throw new Exception(_('Unable to insert new content into database!'));
70                }
71
72                $object = self :: getObject($content_id);
73                /* At least add the current user as the default owner */
74                $object->AddOwner(User :: getCurrentUser());
75                /* By default, make it persistent */
76                $object->setIsPersistent(true);
77
78                return $object;
79        }
80
81        /** Get an interface to create a new object.
82        * @return html markup
83        */
84        public static function getCreateNewObjectUI()
85        {
86                $html = '';
87                $i = 0;
88                $tab = array ();
89                foreach (self :: getAvailableContentTypes() as $classname)
90                {
91                        $tab[$i][0] = $classname;
92                        $tab[$i][1] = $classname;
93                        $i ++;
94                }
95                $name = "new_content_content_type";
96                $default = 'TrivialLangstring';
97                if (empty ($tab))
98                        $html .= _("It appears that you have not installed any Content plugin !");
99                else
100                {
101                        $html .= _("You must select a content type: ");
102                        $html .= FormSelectGenerator :: generateFromArray($tab, $default, $name, "Content", false);
103                }
104                return $html;
105        }
106
107        /** Process the new object interface.
108         *  Will       return the new object if the user has the credentials
109         * necessary (Else an exception is thrown) and and the form was fully
110         * filled (Else the object returns null).
111         * @return the node object or null if no new node was created.
112         */
113        static function processCreateNewObjectUI()
114        {
115                $retval = null;
116                $name = "new_content_content_type";
117                $content_type = FormSelectGenerator :: getResult($name, "Content");
118                if ($content_type)
119                {
120                        $retval = self :: createNewObject($content_type);
121                }
122
123                return $retval;
124        }
125
126        /** Get the Content object, specific to it's content type
127         * @param $content_id The content id
128         * @return the Content object, or null if there was an error (an exception is also thrown)
129         */
130        static function getObject($content_id)
131        {
132                global $db;
133                $content_id = $db->EscapeString($content_id);
134                $sql = "SELECT content_type FROM content WHERE content_id='$content_id'";
135                $db->ExecSqlUniqueRes($sql, $row, false);
136                if ($row == null)
137                {
138                        throw new Exception(_("The content with the following id could not be found in the database: ").$content_id);
139                }
140                $content_type = $row['content_type'];
141                $object = new $content_type ($content_id);
142                return $object;
143        }
144
145        /** Get the list of available content type on the system
146         * @return an array of class names */
147        public static function getAvailableContentTypes()
148        {
149                $dir = BASEPATH.'classes/Content';
150                if ($dir_handle = @opendir($dir))
151                {
152                        $content_types = array();
153                       
154                        /* This is the correct way to loop over the directory. */
155                        while (false !== ($sub_dir = readdir($dir_handle)))
156                        {
157                                // Loop through sub-directories of Content
158                                if ($sub_dir != '.' && $sub_dir != '..' && is_dir("{$dir}/{$sub_dir}"))
159                                {
160                                        // Only add directories containing corresponding initial Content class
161                                        if(is_file("{$dir}/{$sub_dir}/{$sub_dir}.php"))
162                                                $content_types[] = $sub_dir;
163                                }
164                        }
165                        closedir($dir_handle);
166                }
167                else
168                {
169                        throw new Exception(_('Unable to open directory ').$dir);
170                }
171               
172                // Cleanup PHP file extensions and sort the result array
173                $content_types = str_ireplace('.php', '', $content_types);
174                sort($content_types);
175               
176                return $content_types;
177        }
178
179        /**
180         * Get all content, can be restricted to a given content type
181         */
182        public static function getAllContent($content_type = "")
183        {
184                global $db;
185                $where_clause = "";
186                if (!empty ($content_type))
187                {
188                        $content_type = $db->EscapeString($content_type);
189                        $where_clause = "WHERE content_type = '$content_type'";
190                }
191                $db->ExecSql("SELECT content_id FROM content $where_clause", $rows, false);
192                $objects = array ();
193                if ($rows)
194                        foreach ($rows as $row)
195                                $objects[] = self :: getObject($row['content_id']);
196                return $objects;
197        }
198
199        /** Get a flexible interface to generate new content objects
200         * @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
201         * @param $content_type If set, the created content will be of this type, otherwise, the user will have to chose
202         * @return html markup
203         */
204        static function getNewContentUI($user_prefix, $content_type = null)
205        {
206                global $db;
207                $html = '';
208                $available_content_types = self :: getAvailableContentTypes();
209
210                $name = "get_new_content_{$user_prefix}_content_type";
211                if (empty ($content_type))
212                {
213                        $html .= _("Content type: ");
214                        $i = 0;
215                        foreach ($available_content_types as $classname)
216                        {
217                                $tab[$i][0] = $classname;
218                                $tab[$i][1] = $classname;
219                                $i ++;
220                        }
221                        $html .= FormSelectGenerator :: generateFromArray($tab, 'TrivialLangstring', $name, null, false);
222                }
223                else
224                {
225                        if (false === array_search($content_type, $available_content_types, true))
226                        {
227                                throw new Exception(_("The following content type isn't valid: ").$content_type);
228                        }
229                        $html .= "<input type='hidden' name='$name' value='$content_type'>";
230                }
231                $name = "get_new_content_{$user_prefix}_add";
232
233                if ($content_type)
234                {
235                        $value = _("Add a")." $content_type";
236                }
237                else
238                {
239                        $value = _("Add");
240                }
241                $html .= "<input type='submit' name='$name' value='$value'>";
242                return $html;
243        }
244
245        /** Get the created Content object, IF one was created
246         * OR Get existing content ( depending on what the user clicked )
247         * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
248         * @param $associate_existing_content boolean if true allows to get existing
249         * object
250         * @return the Content object, or null if the user didn't greate one
251         */
252        static function processNewContentUI($user_prefix, $associate_existing_content = false)
253        {
254                $object = null;
255                if ($associate_existing_content == true)
256                        $name = "{$user_prefix}_add";
257                else
258                        $name = "get_new_content_{$user_prefix}_add";
259                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
260                {
261                        if ($associate_existing_content == true)
262                                $name = "{$user_prefix}";
263                        else
264                                $name = "get_new_content_{$user_prefix}_content_type";
265
266                        // The result can be either a Content type or a Content ID depending on the form ( associate_existing_content or NOT )
267                        $content_ui_result = FormSelectGenerator :: getResult($name, null);
268                        if ($associate_existing_content == true)
269                                $object = self :: getObject($content_ui_result);
270                        else
271                                $object = self :: createNewObject($content_ui_result);
272                }
273                return $object;
274        }
275
276        /** Get a flexible interface to manage content linked to a node, a network or anything else
277         * @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
278         * @param $content_type If set, the created content will be of this type, otherwise, the user will have to chose
279         * @return html markup
280         */
281        static function getLinkedContentUI($user_prefix, $link_table, $link_table_obj_key_col, $link_table_obj_key, $display_location)
282        {
283                global $db;
284                $html = '';
285                $link_table = $db->EscapeString($link_table);
286                $link_table_obj_key_col = $db->EscapeString($link_table_obj_key_col);
287                $link_table_obj_key = $db->EscapeString($link_table_obj_key);
288                $display_location = $db->EscapeString($display_location);
289                $name = "{$user_prefix}_display_location";
290
291                $html .= "<input type='hidden' name='{$name}' value='{$display_location}'>\n";
292                $current_content_sql = "SELECT * FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key' AND display_location='$display_location' ORDER BY subscribe_timestamp DESC";
293                $rows = null;
294                $db->ExecSql($current_content_sql, $rows, false);
295                $html .= "<ul class='admin_section_list'>\n";
296                if ($rows)
297                        foreach ($rows as $row)
298                        {
299                                $content = Content :: getObject($row['content_id']);
300                                $html .= "<li class='admin_section_list_item'>\n";
301                                $html .= "<div class='admin_section_data'>\n";
302                                $html .= $content->getListUI();
303                                $html .= "</div>\n";
304                                $html .= "<div class='admin_section_tools'>\n";
305                                $name = "{$user_prefix}_".$content->GetId()."_edit";
306                                $html .= "<input type='button' name='$name' value='"._("Edit")."' onClick='window.location.href = \"".GENERIC_OBJECT_ADMIN_ABS_HREF."?object_class=Content&action=edit&object_id=".$content->GetId()."\";'>\n";
307                                $name = "{$user_prefix}_".$content->GetId()."_erase";
308                                $html .= "<input type='submit' name='$name' value='"._("Remove")."'>";
309                                $html .= "</div>\n";
310                                $html .= "</li>\n";
311                        }
312                $html .= "<li class='admin_section_list_item'>\n";
313                $name = "{$user_prefix}_new_existing";
314                $html .= Content :: getSelectContentUI($name, "AND content_id NOT IN (SELECT content_id FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key')");
315                $name = "{$user_prefix}_new_display_location";
316
317                $html .= "<input type='hidden' name='{$name}' value='{$display_location}'>\n";
318                $name = "{$user_prefix}_new_existing_submit";
319                $html .= "<input type='submit' name='$name' value='"._("Add")."'>";
320                $html .= "</li>\n";
321                $html .= "<li class='admin_section_list_item'>\n";
322                $html .= "Add new content: ";
323                $name = "{$user_prefix}_new";
324                $html .= self :: getNewContentUI($name, $content_type = null);
325                $html .= "</li>\n";
326                $html .= "</ul>\n";
327
328                return $html;
329        }
330
331        /** Get the created Content object, IF one was created
332         * OR Get existing content ( depending on what the user clicked )
333         * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
334         * @param $associate_existing_content boolean if true allows to get existing
335         * object
336         * @return the Content object, or null if the user didn't greate one
337         */
338        static function processLinkedContentUI($user_prefix, $link_table, $link_table_obj_key_col, $link_table_obj_key)
339        {
340
341                global $db;
342                $link_table = $db->EscapeString($link_table);
343                $link_table_obj_key_col = $db->EscapeString($link_table_obj_key_col);
344                $link_table_obj_key = $db->EscapeString($link_table_obj_key);
345                $name = "{$user_prefix}_display_location";
346                $display_location = $db->EscapeString($_REQUEST[$name]);
347                $name = "{$user_prefix}_new_display_location";
348                $display_location_new = $db->EscapeString($_REQUEST[$name]);
349                $current_content_sql = "SELECT * FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key' AND display_location='$display_location' ORDER BY subscribe_timestamp DESC";
350                $rows = null;
351                $db->ExecSql($current_content_sql, $rows, false);
352                if ($rows)
353                        foreach ($rows as $row)
354                        {
355                                $content = Content :: getObject($row['content_id']);
356                                $content_id = $db->EscapeString($content->getId());
357                                $name = "{$user_prefix}_".$content->GetId()."_erase";
358                                if (!empty ($_REQUEST[$name]))
359                                {
360                                        $sql = "DELETE FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id'";
361                                        $db->ExecSqlUpdate($sql, $rows, false);
362                                }
363                        }
364
365                $name = "{$user_prefix}_new_existing_submit";
366                if (!empty ($_REQUEST[$name]))
367                {
368                        $name = "{$user_prefix}_new_existing";
369                        $content = Content :: processSelectContentUI($name);
370                        if ($content)
371                        {
372                                $content_id = $db->EscapeString($content->getId());
373                                $sql = "INSERT INTO $link_table (content_id, $link_table_obj_key_col, display_location) VALUES ('$content_id', '$link_table_obj_key', '$display_location_new');\n";
374                                $db->ExecSqlUpdate($sql, $rows, false);
375                        }
376                }
377                $name = "{$user_prefix}_new";
378                $content = self :: processNewContentUI($name);
379                if ($content)
380                {
381                        $content_id = $db->EscapeString($content->getId());
382                        $sql = "INSERT INTO $link_table (content_id, $link_table_obj_key_col, display_location) VALUES ('$content_id', '$link_table_obj_key', '$display_location_new');\n";
383                        $db->ExecSqlUpdate($sql, $rows, false);
384                }
385
386        }
387
388        /** Get an interface to pick content from all persistent content.
389        * @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
390          @param $sql_additional_where Addidional where conditions to restrict the candidate objects
391        * @return html markup
392        */
393        public static function getSelectContentUI($user_prefix, $sql_additional_where = null)
394        {
395                $html = '';
396                $name = "{$user_prefix}";
397                $html .= _("Select existing Content : ")."\n";
398                global $db;
399                $retval = array ();
400                $sql = "SELECT * FROM content WHERE is_persistent=TRUE $sql_additional_where ORDER BY creation_timestamp";
401                $db->ExecSql($sql, $content_rows, false);
402                if ($content_rows != null)
403                {
404                        $i = 0;
405                        foreach ($content_rows as $content_row)
406                        {
407                                $content = Content :: getObject($content_row['content_id']);
408                                $tab[$i][0] = $content->getId();
409                                $tab[$i][1] = $content->__toString()." (".get_class($content).")";
410                                $i ++;
411                        }
412                        $html .= FormSelectGenerator :: generateFromArray($tab, null, $name, null, false);
413
414                }
415                else
416                {
417                        $html .= "<div class='warningmsg'>"._("Sorry, no content available in the database")."</div>\n";
418                }
419                return $html;
420        }
421
422        /** Get the selected Content object.
423         * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
424         * @return the Content object
425         */
426        static function processSelectContentUI($user_prefix)
427        {
428                $name = "{$user_prefix}";
429                if (!empty ($_REQUEST[$name]))
430                        return Content :: getObject($_REQUEST[$name]);
431                else
432                        return null;
433        }
434
435        private function __construct($content_id)
436        {
437                global $db;
438
439                $content_id = $db->EscapeString($content_id);
440                $sql = "SELECT * FROM content WHERE content_id='$content_id'";
441                $db->ExecSqlUniqueRes($sql, $row, false);
442                if ($row == null)
443                {
444                        throw new Exception(_("The content with the following id could not be found in the database: ").$content_id);
445                }
446                $this->content_row = $row;
447                $this->id = $row['content_id'];
448                $this->content_type = $row['content_type'];
449
450                // By default Content display logging is enabled
451                $this->setLoggingStatus(true);
452        }
453
454        /** A short string representation of the content */
455        public function __toString()
456        {
457                if (empty ($this->content_row['title']))
458                {
459                        $string = _("Untitled content");
460                }
461                else
462                {
463                        $title = self :: getObject($this->content_row['title']);
464                        $string = $title->__toString();
465                }
466                return $string;
467        }
468
469        /** Get the true object type represented by this isntance
470         * @return an array of class names */
471        public function getObjectType()
472        {
473                return $this->content_type;
474        }
475
476        /**
477         * Get content title
478         * @return content a content sub-class
479         */
480        public function getTitle()
481        {
482                try
483                {
484                        return self :: getObject($this->content_row['title']);
485                }
486                catch (Exception $e)
487                {
488                        return null;
489                }
490        }
491
492        /**
493         * Get content description
494         * @return content a content sub-class
495         */
496        public function getDescription()
497        {
498                try
499                {
500                        return self :: getObject($this->content_row['description']);
501                }
502                catch (Exception $e)
503                {
504                        return null;
505                }
506        }
507
508        /**
509         * Get content long description
510         * @return content a content sub-class
511         */
512        public function getLongDescription()
513        {
514                try
515                {
516                        return self :: getObject($this->content_row['long_description']);
517                }
518                catch (Exception $e)
519                {
520                        return null;
521                }
522        }
523
524        /**
525         * Get content project info
526         * @return content a content sub-class
527         */
528        public function getProjectInfo()
529        {
530                try
531                {
532                        return self :: getObject($this->content_row['project_info']);
533                }
534                catch (Exception $e)
535                {
536                        return null;
537                }
538        }
539
540        /**
541         * Get content sponsor info
542         * @return content a content sub-class
543         */
544        public function getSponsorInfo()
545        {
546                try
547                {
548                        return self :: getObject($this->content_row['sponsor_info']);
549                }
550                catch (Exception $e)
551                {
552                        return null;
553                }
554        }
555
556        /** Set the object type of this object
557         * Note that after using this, the object must be re-instanciated to have the right type
558         * */
559        private function setContentType($content_type)
560        {
561                global $db;
562                $content_type = $db->EscapeString($content_type);
563                $available_content_types = self :: getAvailableContentTypes();
564                if (false === array_search($content_type, $available_content_types, true))
565                {
566                        throw new Exception(_("The following content type isn't valid: ").$content_type);
567                }
568                $sql = "UPDATE content SET content_type = '$content_type' WHERE content_id='$this->id'";
569
570                if (!$db->ExecSqlUpdate($sql, false))
571                {
572                        throw new Exception(_("Update was unsuccessfull (database error)"));
573                }
574
575        }
576
577        /** Check if a user is one of the owners of the object
578         * @param $user The user to be added to the owners list
579         * @param $is_author Optionnal, true or false.  Set to true if the user is one of the actual authors of the Content
580         * @return true on success, false on failure */
581        public function addOwner(User $user, $is_author = false)
582        {
583                global $db;
584                $content_id = "'".$this->id."'";
585                $user_id = "'".$db->EscapeString($user->getId())."'";
586                $is_author ? $is_author = 'TRUE' : $is_author = 'FALSE';
587                $sql = "INSERT INTO content_has_owners (content_id, user_id, is_author) VALUES ($content_id, $user_id, $is_author)";
588
589                if (!$db->ExecSqlUpdate($sql, false))
590                {
591                        throw new Exception(_('Unable to insert the new Owner into database.'));
592                }
593
594                return true;
595        }
596
597        /** Remove an owner of the content
598         * @param $user The user to be removed from the owners list
599         */
600        public function deleteOwner(User $user, $is_author = false)
601        {
602                global $db;
603                $content_id = "'".$this->id."'";
604                $user_id = "'".$db->EscapeString($user->getId())."'";
605
606                $sql = "DELETE FROM content_has_owners WHERE content_id=$content_id AND user_id=$user_id";
607
608                if (!$db->ExecSqlUpdate($sql, false))
609                {
610                        throw new Exception(_('Unable to remove the owner from the database.'));
611                }
612
613                return true;
614        }
615
616        /**
617         * Indicates display logging status
618         */
619        public function getLoggingStatus()
620        {
621                return $this->is_logging_enabled;
622        }
623
624        /**
625         * Sets display logging status
626         */
627        public function setLoggingStatus($status)
628        {
629                if (is_bool($status))
630                        $this->is_logging_enabled = $status;
631        }
632
633        /** Get the PHP timestamp of the last time this content was displayed
634         * @param $user User, Optional, if present, restrict to the selected user
635         * @param $node Node, Optional, if present, restrict to the selected node
636         * @return PHP timestamp (seconds since UNIX epoch) if the content has been
637         * displayed before, an empty string otherwise.
638         */
639        public function getLastDisplayTimestamp($user = null, $node = null)
640        {
641                global $db;
642                $retval = '';
643                $sql = "SELECT EXTRACT(EPOCH FROM last_display_timestamp) as last_display_unix_timestamp FROM content_display_log WHERE content_id='{$this->id}' \n";
644
645                if ($user)
646                {
647                        $user_id = $db->EscapeString($user->getId());
648                        $sql .= " AND user_id = '{$user_id}' \n";
649                }
650                if ($node)
651                {
652                        $node_id = $db->EscapeString($node->getId());
653                        $sql .= " AND node_id = '{$node_id}' \n";
654                }
655                $sql .= " ORDER BY last_display_timestamp DESC ";
656                $db->ExecSql($sql, $log_rows, false);
657                if ($log_rows)
658                {
659                        $retval = $log_rows[0]['last_display_unix_timestamp'];
660                }
661
662                return $retval;
663        }
664
665        /** Is this Content element displayable at this hotspot, many classer override this
666         * @param $node Node, optionnal
667         * @return true or false */
668        public function isDisplayableAt($node)
669        {
670                return true;
671        }
672
673        /** Check if a user is one of the owners of the object
674         * @param $user User object:  the user to be tested.
675         * @return true if the user is a owner, false if he isn't of the user is null */
676        public function isOwner($user)
677        {
678                global $db;
679                $retval = false;
680                if ($user != null)
681                {
682                        $user_id = $db->EscapeString($user->GetId());
683                        $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id' AND user_id='$user_id'";
684                        $db->ExecSqlUniqueRes($sql, $content_owner_row, false);
685                        if ($content_owner_row != null)
686                        {
687                                $retval = true;
688                        }
689                }
690
691                return $retval;
692        }
693        /** Get the authors of the Content
694         * @return null or array of User objects */
695        public function getAuthors()
696        {
697                global $db;
698                $retval = array ();
699                $sql = "SELECT user_id FROM content_has_owners WHERE content_id='$this->id' AND is_author=TRUE";
700                $db->ExecSqlUniqueRes($sql, $content_owner_row, false);
701                if ($content_owner_row != null)
702                {
703                        $user = User :: getObject($content_owner_row['user_id']);
704                        $retval[] = $user;
705                }
706
707                return $retval;
708        }
709        /** @see GenricObject
710         * @return The id */
711        public function getId()
712        {
713                return $this->id;
714        }
715
716        /** When a content object is set as trivial, it means that is is used merely to contain it's own data.  No title, description or other data will be set or displayed, during display or administration
717         * @param $is_trivial true or false */
718        public function setIsTrivialContent($is_trivial)
719        {
720                $this->is_trivial_content = $is_trivial;
721        }
722
723        /** Retreives the user interface of this object.  Anything that overrides this method should call the parent method with it's output at the END of processing.
724         * @param $subclass_admin_interface Html content of the interface element of a children
725         * @return The HTML fragment for this interface */
726        public function getUserUI($subclass_user_interface = null)
727        {
728                $html = '';
729                $html .= "<div class='user_ui_main_outer'>\n";
730                $html .= "<div class='user_ui_main_inner'>\n";
731                $html .= "<div class='user_ui_object_class'>Content (".get_class($this)." instance)</div>\n";
732
733                if (!empty ($this->content_row['title']))
734                {
735                        $html .= "<div class='user_ui_title'>\n";
736                        $title = self :: getObject($this->content_row['title']);
737                        // If the content logging is disabled, all the children will inherit this property temporarly
738                        if ($this->getLoggingStatus() == false)
739                                $title->setLoggingStatus(false);
740                        $html .= $title->getUserUI();
741                        $html .= "</div>\n";
742                }
743
744                $html .= "<table><tr><td>\n";
745                $authors = $this->getAuthors();
746                if (count($authors) > 0)
747                {
748                        $html .= "<div class='user_ui_authors'>\n";
749                        $html .= _("Author(s):");
750                        foreach ($authors as $user)
751                        {
752                                $html .= $user->getUsername()." ";
753                        }
754                        $html .= "</div>\n";
755                }
756
757                if (!empty ($this->content_row['description']))
758                {
759                        $html .= "<div class='user_ui_description'>\n";
760                        $description = self :: getObject($this->content_row['description']);
761                        // If the content logging is disabled, all the children will inherit this property temporarly
762                        if ($this->getLoggingStatus() == false)
763                                $description->setLoggingStatus(false);
764                        $html .= $description->getUserUI();
765                        $html .= "</div>\n";
766                }
767
768                if (!empty ($this->content_row['project_info']) || !empty ($this->content_row['sponsor_info']))
769                {
770                        if (!empty ($this->content_row['project_info']))
771                        {
772                                $html .= "<div class='user_ui_projet_info'>\n";
773                                $html .= "<b>"._("Project information:")."</b>";
774                                $project_info = self :: getObject($this->content_row['project_info']);
775                                // If the content logging is disabled, all the children will inherit this property temporarly
776                                if ($this->getLoggingStatus() == false)
777                                        $project_info->setLoggingStatus(false);
778                                $html .= $project_info->getUserUI();
779                                $html .= "</div>\n";
780                        }
781
782                        if (!empty ($this->content_row['sponsor_info']))
783                        {
784                                $html .= "<div class='user_ui_sponsor_info'>\n";
785                                $html .= "<b>"._("Project sponsor:")."</b>";
786                                $sponsor_info = self :: getObject($this->content_row['sponsor_info']);
787                                // If the content logging is disabled, all the children will inherit this property temporarly
788                                if ($this->getLoggingStatus() == false)
789                                        $sponsor_info->setLoggingStatus(false);
790                                $html .= $sponsor_info->getUserUI();
791                                $html .= "</div>\n";
792                        }
793                }
794
795                $html .= "</td>\n";
796
797                $html .= "<td>\n$subclass_user_interface</td>\n";
798                $html .= "</tr></table>\n";
799
800                $html .= "</div>\n";
801                $html .= "</div>\n";
802                $this->logContentDisplay();
803                return $html;
804        }
805
806        /** Log that this content has just been displayed to the user.  Will only log if the user is logged in */
807        private function logContentDisplay()
808        {
809                if ($this->getLoggingStatus() == true)
810                {
811                        // DEBUG::
812                        //echo "Logging ".get_class($this)." :: ".$this->__toString()."<br>";
813                        $user = User :: getCurrentUser();
814                        $node = Node :: getCurrentNode();
815                        if ($user != null && $node != null)
816                        {
817                                $user_id = $user->getId();
818                                $node_id = $node->getId();
819                                global $db;
820
821                                $sql = "SELECT * FROM content_display_log WHERE user_id='$user_id' AND node_id='$node_id' AND content_id='$this->id'";
822                                $db->ExecSql($sql, $log_rows, false);
823                                if ($log_rows != null)
824                                {
825                                        $sql = "UPDATE content_display_log SET last_display_timestamp = NOW() WHERE user_id='$user_id' AND content_id='$this->id' AND node_id='$node_id'";
826                                }
827                                else
828                                {
829                                        $sql = "INSERT INTO content_display_log (user_id, content_id, node_id) VALUES ('$user_id', '$this->id', '$node_id')";
830                                }
831                                $db->ExecSqlUpdate($sql, false);
832                        }
833                }
834        }
835
836        /** Retreives the list interface of this object.  Anything that overrides this method should call the parent method with it's output at the END of processing.
837         * @param $subclass_admin_interface Html content of the interface element of a children
838         * @return The HTML fragment for this interface */
839        public function getListUI($subclass_list_interface = null)
840        {
841                $html = '';
842                $html .= "<div class='list_ui_container'>\n";
843                $html .= $this->__toString()." (".get_class($this).")\n";
844                $html .= $subclass_list_interface;
845                $html .= "</div>\n";
846                return $html;
847        }
848
849        /** Retreives the admin interface of this object.  Anything that overrides this method should call the parent method with it's output at the END of processing.
850         * @param $subclass_admin_interface Html content of the interface element of a children
851         * @return The HTML fragment for this interface */
852        public function getAdminUI($subclass_admin_interface = null)
853        {
854                global $db;
855                $html = '';
856                $html .= "<div class='admin_container'>\n";
857                $html .= "<div class='admin_class'>Content (".get_class($this)." instance)</div>\n";
858                if ($this->getObjectType() == 'Content') /* The object hasn't yet been typed */
859                {
860                        $html .= _("You must select a content type: ");
861                        $i = 0;
862                        foreach (self :: getAvailableContentTypes() as $classname)
863                        {
864                                $tab[$i][0] = $classname;
865                                $tab[$i][1] = $classname;
866                                $i ++;
867                        }
868                        $html .= FormSelectGenerator :: generateFromArray($tab, null, "content_".$this->id."_content_type", "Content", false);
869                }
870                else
871                        if ($this->is_trivial_content == false)
872                        {
873                                /* title */
874                                $html .= "<div class='admin_section_container'>\n";
875                                $html .= "<div class='admin_section_title'>"._("Title:")."</div>\n";
876                                $html .= "<div class='admin_section_data'>\n";
877                                if (empty ($this->content_row['title']))
878                                {
879                                        $html .= self :: getNewContentUI("title_{$this->id}_new");
880                                        $html .= "</div>\n";
881                                }
882                                else
883                                {
884                                        $title = self :: getObject($this->content_row['title']);
885                                        $html .= $title->getAdminUI();
886                                        $html .= "</div>\n";
887                                        $html .= "<div class='admin_section_tools'>\n";
888                                        $name = "content_".$this->id."_title_erase";
889                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
890                                        $html .= "</div>\n";
891                                }
892                                $html .= "</div>\n";
893
894                                /* is_persistent */
895                                $html .= "<div class='admin_section_container'>\n";
896                                $html .= "<div class='admin_section_title'>Is persistent (reusable and read-only)?: </div>\n";
897                                $html .= "<div class='admin_section_data'>\n";
898                                $name = "content_".$this->id."_is_persistent";
899                                $this->isPersistent() ? $checked = 'CHECKED' : $checked = '';
900                                $html .= "<input type='checkbox' name='$name' $checked>\n";
901                                $html .= "</div>\n";
902                                $html .= "</div>\n";
903
904                                /* description */
905                                $html .= "<div class='admin_section_container'>\n";
906                                $html .= "<div class='admin_section_title'>"._("Description:")."</div>\n";
907                                $html .= "<div class='admin_section_data'>\n";
908                                if (empty ($this->content_row['description']))
909                                {
910                                        $html .= self :: getNewContentUI("description_{$this->id}_new");
911                                        $html .= "</div>\n";
912                                }
913                                else
914                                {
915                                        $description = self :: getObject($this->content_row['description']);
916                                        $html .= $description->getAdminUI();
917                                        $html .= "</div>\n";
918                                        $html .= "<div class='admin_section_tools'>\n";
919                                        $name = "content_".$this->id."_description_erase";
920                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
921                                        $html .= "</div>\n";
922                                }
923                                $html .= "</div>\n";
924
925                                /* long description */
926                                $html .= "<div class='admin_section_container'>\n";
927                                $html .= "<div class='admin_section_title'>"._("Long description:")."</div>\n";
928                                $html .= "<div class='admin_section_data'>\n";
929                                if (empty ($this->content_row['long_description']))
930                                {
931                                        $html .= self :: getNewContentUI("long_description_{$this->id}_new");
932                                        $html .= "</div>\n";
933                                }
934                                else
935                                {
936                                        $description = self :: getObject($this->content_row['long_description']);
937                                        $html .= $description->getAdminUI();
938                                        $html .= "</div>\n";
939                                        $html .= "<div class='admin_section_tools'>\n";
940                                        $name = "content_".$this->id."_long_description_erase";
941                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
942                                        $html .= "</div>\n";
943                                }
944                                $html .= "</div>\n";
945
946                                /* project_info */
947                                $html .= "<div class='admin_section_container'>\n";
948                                $html .= "<div class='admin_section_title'>"._("Information on this project:")."</div>\n";
949                                $html .= "<div class='admin_section_data'>\n";
950                                if (empty ($this->content_row['project_info']))
951                                {
952                                        $html .= self :: getNewContentUI("project_info_{$this->id}_new");
953                                        $html .= "</div>\n";
954                                }
955                                else
956                                {
957                                        $project_info = self :: getObject($this->content_row['project_info']);
958                                        $html .= $project_info->getAdminUI();
959                                        $html .= "</div>\n";
960                                        $html .= "<div class='admin_section_tools'>\n";
961                                        $name = "content_".$this->id."_project_info_erase";
962                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
963                                        $html .= "</div>\n";
964                                }
965                                $html .= "</div>\n";
966
967                                /* sponsor_info */
968                                $html .= "<div class='admin_section_container'>\n";
969                                $html .= "<div class='admin_section_title'>"._("Sponsor of this project:")."</div>\n";
970                                $html .= "<div class='admin_section_data'>\n";
971                                if (empty ($this->content_row['sponsor_info']))
972                                {
973                                        $html .= self :: getNewContentUI("sponsor_info_{$this->id}_new");
974                                        $html .= "</div>\n";
975                                }
976                                else
977                                {
978                                        $sponsor_info = self :: getObject($this->content_row['sponsor_info']);
979                                        $html .= $sponsor_info->getAdminUI();
980                                        $html .= "</div>\n";
981                                        $html .= "<div class='admin_section_tools'>\n";
982                                        $name = "content_".$this->id."_sponsor_info_erase";
983                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
984                                        $html .= "</div>\n";
985                                }
986                                $html .= "</div>\n";
987
988                                /* content_has_owners */
989                                $html .= "<div class='admin_section_container'>\n";
990                                $html .= "<span class='admin_section_title'>"._("Content owner list")."</span>\n";
991                                $html .= "<ul class='admin_section_list'>\n";
992
993                                global $db;
994                                $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id'";
995                                $db->ExecSql($sql, $content_owner_rows, false);
996                                if ($content_owner_rows != null)
997                                {
998                                        foreach ($content_owner_rows as $content_owner_row)
999                                        {
1000                                                $html .= "<li class='admin_section_list_item'>\n";
1001                                                $html .= "<div class='admin_section_data'>\n";
1002                                                $user = User :: getObject($content_owner_row['user_id']);
1003
1004                                                $html .= $user->getUserListUI();
1005                                                $name = "content_".$this->id."_owner_".$user->GetId()."_is_author";
1006                                                $html .= " Is content author? ";
1007
1008                                                $content_owner_row['is_author'] == 't' ? $checked = 'CHECKED' : $checked = '';
1009                                                $html .= "<input type='checkbox' name='$name' $checked>\n";
1010                                                $html .= "</div>\n";
1011                                                $html .= "<div class='admin_section_tools'>\n";
1012                                                $name = "content_".$this->id."_owner_".$user->GetId()."_remove";
1013                                                $html .= "<input type='submit' name='$name' value='"._("Remove")."'>";
1014                                                $html .= "</div>\n";
1015                                                $html .= "</li>\n";
1016                                        }
1017                                }
1018
1019                                $html .= "<li class='admin_section_list_item'>\n";
1020                                $html .= "<div class='admin_section_data'>\n";
1021                                $html .= User :: getSelectUserUI("content_{$this->id}_new_owner");
1022                                $html .= "</div>\n";
1023                                $html .= "<div class='admin_section_tools'>\n";
1024                                $name = "content_{$this->id}_add_owner_submit";
1025                                $value = _("Add owner");
1026                                $html .= "<input type='submit' name='$name' value='$value'>";
1027                                $html .= "</div>\n";
1028                                $html .= "</li>\n";
1029                                $html .= "</ul>\n";
1030                                $html .= "</div>\n";
1031                        }
1032                $html .= $subclass_admin_interface;
1033                $html .= "</div>\n";
1034                return $html;
1035        }
1036        /** Process admin interface of this object.  When an object overrides this method, they should call the parent processAdminUI at the BEGINING of processing.
1037       
1038        */
1039        public function processAdminUI()
1040        {
1041                if ($this->isOwner(User :: getCurrentUser()) || User :: getCurrentUser()->isSuperAdmin())
1042                {
1043                        global $db;
1044                        if ($this->getObjectType() == 'Content') /* The object hasn't yet been typed */
1045                        {
1046                                $content_type = FormSelectGenerator :: getResult("content_".$this->id."_content_type", "Content");
1047                                $this->setContentType($content_type);
1048                        }
1049                        else
1050                                if ($this->is_trivial_content == false)
1051                                {
1052                                        /* title */
1053                                        if (empty ($this->content_row['title']))
1054                                        {
1055                                                $title = self :: processNewContentUI("title_{$this->id}_new");
1056                                                if ($title != null)
1057                                                {
1058                                                        $title_id = $title->GetId();
1059                                                        $db->ExecSqlUpdate("UPDATE content SET title = '$title_id' WHERE content_id = '$this->id'", FALSE);
1060                                                }
1061                                        }
1062                                        else
1063                                        {
1064                                                $title = self :: getObject($this->content_row['title']);
1065                                                $name = "content_".$this->id."_title_erase";
1066                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1067                                                {
1068                                                        $db->ExecSqlUpdate("UPDATE content SET title = NULL WHERE content_id = '$this->id'", FALSE);
1069                                                        $title->delete($errmsg);
1070                                                }
1071                                                else
1072                                                {
1073                                                        $title->processAdminUI();
1074                                                }
1075                                        }
1076
1077                                        /* is_persistent */
1078                                        $name = "content_".$this->id."_is_persistent";
1079                                        !empty ($_REQUEST[$name]) ? $this->setIsPersistent(true) : $this->setIsPersistent(false);
1080
1081                                        /* description */
1082                                        if (empty ($this->content_row['description']))
1083                                        {
1084                                                $description = self :: processNewContentUI("description_{$this->id}_new");
1085                                                if ($description != null)
1086                                                {
1087                                                        $description_id = $description->GetId();
1088                                                        $db->ExecSqlUpdate("UPDATE content SET description = '$description_id' WHERE content_id = '$this->id'", FALSE);
1089                                                }
1090                                        }
1091                                        else
1092                                        {
1093                                                $description = self :: getObject($this->content_row['description']);
1094                                                $name = "content_".$this->id."_description_erase";
1095                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1096                                                {
1097                                                        $db->ExecSqlUpdate("UPDATE content SET description = NULL WHERE content_id = '$this->id'", FALSE);
1098                                                        $description->delete($errmsg);
1099                                                }
1100                                                else
1101                                                {
1102                                                        $description->processAdminUI();
1103                                                }
1104                                        }
1105
1106                                        /* long description */
1107                                        if (empty ($this->content_row['long_description']))
1108                                        {
1109                                                $long_description = self :: processNewContentUI("long_description_{$this->id}_new");
1110                                                if ($long_description != null)
1111                                                {
1112                                                        $long_description_id = $long_description->GetId();
1113                                                        $db->ExecSqlUpdate("UPDATE content SET long_description = '$long_description_id' WHERE content_id = '$this->id'", FALSE);
1114                                                }
1115                                        }
1116                                        else
1117                                        {
1118                                                $long_description = self :: getObject($this->content_row['long_description']);
1119                                                $name = "content_".$this->id."_long_description_erase";
1120                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1121                                                {
1122                                                        $db->ExecSqlUpdate("UPDATE content SET long_description = NULL WHERE content_id = '$this->id'", FALSE);
1123                                                        $long_description->delete($errmsg);
1124                                                }
1125                                                else
1126                                                {
1127                                                        $long_description->processAdminUI();
1128                                                }
1129                                        }
1130
1131                                        /* project_info */
1132                                        if (empty ($this->content_row['project_info']))
1133                                        {
1134                                                $project_info = self :: processNewContentUI("project_info_{$this->id}_new");
1135                                                if ($project_info != null)
1136                                                {
1137                                                        $project_info_id = $project_info->GetId();
1138                                                        $db->ExecSqlUpdate("UPDATE content SET project_info = '$project_info_id' WHERE content_id = '$this->id'", FALSE);
1139                                                }
1140                                        }
1141                                        else
1142                                        {
1143                                                $project_info = self :: getObject($this->content_row['project_info']);
1144                                                $name = "content_".$this->id."_project_info_erase";
1145                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1146                                                {
1147                                                        $db->ExecSqlUpdate("UPDATE content SET project_info = NULL WHERE content_id = '$this->id'", FALSE);
1148                                                        $project_info->delete($errmsg);
1149                                                }
1150                                                else
1151                                                {
1152                                                        $project_info->processAdminUI();
1153                                                }
1154                                        }
1155
1156                                        /* sponsor_info */
1157                                        if (empty ($this->content_row['sponsor_info']))
1158                                        {
1159                                                $sponsor_info = self :: processNewContentUI("sponsor_info_{$this->id}_new");
1160                                                if ($sponsor_info != null)
1161                                                {
1162                                                        $sponsor_info_id = $sponsor_info->GetId();
1163                                                        $db->ExecSqlUpdate("UPDATE content SET sponsor_info = '$sponsor_info_id' WHERE content_id = '$this->id'", FALSE);
1164                                                }
1165                                        }
1166                                        else
1167                                        {
1168                                                $sponsor_info = self :: getObject($this->content_row['sponsor_info']);
1169                                                $name = "content_".$this->id."_sponsor_info_erase";
1170                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1171                                                {
1172                                                        $db->ExecSqlUpdate("UPDATE content SET sponsor_info = NULL WHERE content_id = '$this->id'", FALSE);
1173                                                        $sponsor_info->delete($errmsg);
1174                                                }
1175                                                else
1176                                                {
1177                                                        $sponsor_info->processAdminUI();
1178                                                }
1179                                        }
1180                                        /* content_has_owners */
1181                                        $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id'";
1182                                        $db->ExecSql($sql, $content_owner_rows, false);
1183                                        if ($content_owner_rows != null)
1184                                        {
1185                                                foreach ($content_owner_rows as $content_owner_row)
1186                                                {
1187                                                        $user = User :: getObject($content_owner_row['user_id']);
1188                                                        $user_id = $user->getId();
1189                                                        $name = "content_".$this->id."_owner_".$user->GetId()."_remove";
1190                                                        if (!empty ($_REQUEST[$name]))
1191                                                        {
1192                                                                $this->deleteOwner($user);
1193                                                        }
1194                                                        else
1195                                                        {
1196                                                                $name = "content_".$this->id."_owner_".$user->GetId()."_is_author";
1197                                                                $content_owner_row['is_author'] == 't' ? $is_author = true : $is_author = false;
1198                                                                !empty ($_REQUEST[$name]) ? $should_be_author = true : $should_be_author = false;
1199                                                                if ($is_author != $should_be_author)
1200                                                                {
1201                                                                        $should_be_author ? $is_author_sql = 'TRUE' : $is_author_sql = 'FALSE';
1202                                                                        $sql = "UPDATE content_has_owners SET is_author=$is_author_sql WHERE content_id='$this->id' AND user_id='$user_id'";
1203
1204                                                                        if (!$db->ExecSqlUpdate($sql, false))
1205                                                                        {
1206                                                                                throw new Exception(_('Unable to set as author in the database.'));
1207                                                                        }
1208
1209                                                                }
1210
1211                                                        }
1212                                                }
1213                                        }
1214                                        $user = User :: processSelectUserUI("content_{$this->id}_new_owner");
1215                                        $name = "content_{$this->id}_add_owner_submit";
1216                                        if (!empty ($_REQUEST[$name]) && $user != null)
1217                                        {
1218                                                $this->addOwner($user);
1219                                        }
1220
1221                                }
1222                        $this->refresh();
1223                }
1224        }
1225
1226        /**
1227         * Tell if a given user is already subscribed to this content
1228         * @param User the given user
1229         * @return boolean
1230         */
1231        public function isUserSubscribed(User $user)
1232        {
1233                global $db;
1234                $sql = "SELECT content_id FROM user_has_content WHERE user_id = '{$user->getId()}' AND content_id = '{$this->getId()}';";
1235                $db->ExecSqlUniqueRes($sql, $row, false);
1236
1237                if ($row)
1238                        return true;
1239                else
1240                        return false;
1241        }
1242
1243        /** Subscribe to the project
1244         * @return true on success, false on failure */
1245        public function subscribe(User $user)
1246        {
1247                return $user->addContent($this);
1248        }
1249        /** Unsubscribe to the project
1250         * @return true on success, false on failure */
1251        public function unsubscribe(User $user)
1252        {
1253                return $user->removeContent($this);
1254        }
1255
1256        /** Persistent (or read-only) content is meant for re-use.  It will not be deleted when the delete() method is called.  When a containing element (ContentGroup, ContentGroupElement) is deleted, it calls delete on all the content it includes.  If the content is persistent, only the association will be removed.
1257        * @return true or false */
1258        public function isPersistent()
1259        {
1260                if ($this->content_row['is_persistent'] == 't')
1261                {
1262                        $retval = true;
1263                }
1264                else
1265                {
1266                        $retval = false;
1267                }
1268                return $retval;
1269        }
1270
1271        /** Set if the content group is persistent
1272         * @param $is_locative_content true or false
1273         * */
1274        public function setIsPersistent($is_persistent)
1275        {
1276                if ($is_persistent != $this->isPersistent()) /* Only update database if there is an actual change */
1277                {
1278                        $is_persistent ? $is_persistent_sql = 'TRUE' : $is_persistent_sql = 'FALSE';
1279
1280                        global $db;
1281                        $db->ExecSqlUpdate("UPDATE content SET is_persistent = $is_persistent_sql WHERE content_id = '$this->id'", false);
1282                        $this->refresh();
1283                }
1284
1285        }
1286
1287        /** Reloads the object from the database.  Should normally be called after a set operation.
1288         * This function is private because calling it from a subclass will call the
1289         * constructor from the wrong scope */
1290        private function refresh()
1291        {
1292                $this->__construct($this->id);
1293        }
1294
1295        /** @see GenericObject
1296         * @note Persistent content will not be deleted
1297        */
1298        public function delete(& $errmsg)
1299        {
1300                $retval = false;
1301                if ($this->isPersistent())
1302                {
1303                        $errmsg = _("Content is persistent (you must make it non persistent before you can delete it)");
1304                }
1305                else
1306                {
1307                        global $db;
1308                        if ($this->isOwner(User :: getCurrentUser()) || User :: getCurrentUser()->isSuperAdmin())
1309                        {
1310                                $sql = "DELETE FROM content WHERE content_id='$this->id'";
1311                                $db->ExecSqlUpdate($sql, false);
1312                                $retval = true;
1313                        }
1314                        else
1315                        {
1316                                $errmsg = _("Access denied (not owner of content)");
1317                        }
1318                }
1319                return $retval;
1320        }
1321
1322} // End class
1323
1324/* This allows the class to enumerate it's children properly */
1325$class_names = Content :: getAvailableContentTypes();
1326foreach ($class_names as $class_name)
1327{
1328        require_once BASEPATH."classes/Content/{$class_name}/{$class_name}.php";
1329}
1330?>
Note: See TracBrowser for help on using the browser.