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

Revision 779, 41.8 KB (checked in by benoitg, 8 years ago)

2005-09-27 Benoit Gr�goire <bock@…>

  • Partial login page content manager support (Node only for now)
  • 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 ($handle = opendir($dir))
151                {
152                        $tab = Array ();
153                        $i = 0;
154                        /* This is the correct way to loop over the directory. */
155                        while (false !== ($file = readdir($handle)))
156                        {
157                                if ($file != '.' && $file != '..')
158                                {
159                                        if (preg_match("/^.*\.php$/", $file) > 0)
160                                        {
161                                                $tab[$i] = $file;
162                                                $i ++;
163                                        }
164                                }
165                        }
166                        closedir($handle);
167                        //echo $gfs->genererDeArray($tab, $this->GetStylesheet(), "stylesheet", "Theme::AfficherInterfaceAdmin", true, 'Style par défaut ou style du parent');
168                }
169                else
170                {
171                        throw new Exception(_('Unable to open directory ').$dir);
172                }
173                $tab = str_ireplace('.php', '', $tab);
174                sort($tab);
175                return $tab;
176        }
177
178        /**
179         * Get all content, can be restricted to a given content type
180         */
181        public static function getAllContent($content_type = "")
182        {
183                global $db;
184                $where_clause = "";
185                if (!empty ($content_type))
186                {
187                        $content_type = $db->EscapeString($content_type);
188                        $where_clause = "WHERE content_type = '$content_type'";
189                }
190                $db->ExecSql("SELECT content_id FROM content $where_clause", $rows, false);
191                $objects = array ();
192                if ($rows)
193                        foreach ($rows as $row)
194                                $objects[] = self :: getObject($row['content_id']);
195                return $objects;
196        }
197
198        /** Get a flexible interface to generate new content objects
199         * @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
200         * @param $content_type If set, the created content will be of this type, otherwise, the user will have to chose
201         * @return html markup
202         */
203        static function getNewContentUI($user_prefix, $content_type = null)
204        {
205                global $db;
206                $html = '';
207                $available_content_types = self :: getAvailableContentTypes();
208
209                $name = "get_new_content_{$user_prefix}_content_type";
210                if (empty ($content_type))
211                {
212                        $html .= _("Content type: ");
213                        $i = 0;
214                        foreach ($available_content_types as $classname)
215                        {
216                                $tab[$i][0] = $classname;
217                                $tab[$i][1] = $classname;
218                                $i ++;
219                        }
220                        $html .= FormSelectGenerator :: generateFromArray($tab, 'TrivialLangstring', $name, null, false);
221                }
222                else
223                {
224                        if (false === array_search($content_type, $available_content_types, true))
225                        {
226                                throw new Exception(_("The following content type isn't valid: ").$content_type);
227                        }
228                        $html .= "<input type='hidden' name='$name' value='$content_type'>";
229                }
230                $name = "get_new_content_{$user_prefix}_add";
231
232                if ($content_type)
233                {
234                        $value = _("Add a")." $content_type";
235                }
236                else
237                {
238                        $value = _("Add");
239                }
240                $html .= "<input type='submit' name='$name' value='$value'>";
241                return $html;
242        }
243
244        /** Get the created Content object, IF one was created
245         * OR Get existing content ( depending on what the user clicked )
246         * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
247         * @param $associate_existing_content boolean if true allows to get existing
248         * object
249         * @return the Content object, or null if the user didn't greate one
250         */
251        static function processNewContentUI($user_prefix, $associate_existing_content = false)
252        {
253                $object = null;
254                if ($associate_existing_content == true)
255                        $name = "{$user_prefix}_add";
256                else
257                        $name = "get_new_content_{$user_prefix}_add";
258                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
259                {
260                        if ($associate_existing_content == true)
261                                $name = "{$user_prefix}";
262                        else
263                                $name = "get_new_content_{$user_prefix}_content_type";
264
265                        // The result can be either a Content type or a Content ID depending on the form ( associate_existing_content or NOT )
266                        $content_ui_result = FormSelectGenerator :: getResult($name, null);
267                        if ($associate_existing_content == true)
268                                $object = self :: getObject($content_ui_result);
269                        else
270                                $object = self :: createNewObject($content_ui_result);
271                }
272                return $object;
273        }
274
275        /** Get a flexible interface to manage content linked to a node, a network or anything else
276         * @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
277         * @param $content_type If set, the created content will be of this type, otherwise, the user will have to chose
278         * @return html markup
279         */
280        static function getLinkedContentUI($user_prefix, $link_table, $link_table_obj_key_col, $link_table_obj_key, $display_location)
281        {
282                global $db;
283                $html = '';
284                $link_table = $db->EscapeString($link_table);
285                $link_table_obj_key_col = $db->EscapeString($link_table_obj_key_col);
286                $link_table_obj_key = $db->EscapeString($link_table_obj_key);
287                $display_location = $db->EscapeString($display_location);
288                $name = "{$user_prefix}_display_location";
289               
290                $html .= "<input type='hidden' name='{$name}' value='{$display_location}'>\n";
291                $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";
292                $rows = null;
293                $db->ExecSql($current_content_sql, $rows, false);
294                $html .= "<ul class='admin_section_list'>\n";
295                if ($rows)
296                        foreach ($rows as $row)
297                        {
298                                $content = Content :: getObject($row['content_id']);
299                                $html .= "<li class='admin_section_list_item'>\n";
300                                $html .= "<div class='admin_section_data'>\n";
301                                $html .= $content->getListUI();
302                                $html .= "</div>\n";
303                                $html .= "<div class='admin_section_tools'>\n";
304                                $name = "{$user_prefix}_".$content->GetId()."_edit";
305                                $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";
306                                $name = "{$user_prefix}_".$content->GetId()."_erase";
307                                $html .= "<input type='submit' name='$name' value='"._("Remove")."'>";
308                                $html .= "</div>\n";
309                                $html .= "</li>\n";
310                        }
311                $html .= "<li class='admin_section_list_item'>\n";
312                $name = "{$user_prefix}_new_existing";
313                $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')");
314                $name = "{$user_prefix}_new_display_location";
315               
316                $html .= "<input type='hidden' name='{$name}' value='{$display_location}'>\n";
317                $name = "{$user_prefix}_new_existing_submit";
318                $html .= "<input type='submit' name='$name' value='"._("Add")."'>";
319                $html .= "</li>\n";
320                $html .= "<li class='admin_section_list_item'>\n";
321                $html .= "Add new content: ";
322                $name = "{$user_prefix}_new";
323                $html .= self :: getNewContentUI($name, $content_type = null);
324                $html .= "</li>\n";
325                $html .= "</ul>\n";
326
327                return $html;
328        }
329
330        /** Get the created Content object, IF one was created
331         * OR Get existing content ( depending on what the user clicked )
332         * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
333         * @param $associate_existing_content boolean if true allows to get existing
334         * object
335         * @return the Content object, or null if the user didn't greate one
336         */
337        static function processLinkedContentUI($user_prefix, $link_table, $link_table_obj_key_col, $link_table_obj_key)
338        {
339
340                global $db;
341                $link_table = $db->EscapeString($link_table);
342                $link_table_obj_key_col = $db->EscapeString($link_table_obj_key_col);
343                $link_table_obj_key = $db->EscapeString($link_table_obj_key);
344                $name = "{$user_prefix}_display_location";
345                $display_location = $db->EscapeString($_REQUEST[$name]);
346                                $name = "{$user_prefix}_new_display_location";
347                                $display_location_new = $db->EscapeString($_REQUEST[$name]);
348                $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";
349                $rows = null;
350                $db->ExecSql($current_content_sql, $rows, false);
351                if ($rows)
352                        foreach ($rows as $row)
353                        {
354                                $content = Content :: getObject($row['content_id']);
355                                $content_id = $db->EscapeString($content->getId());
356                                $name = "{$user_prefix}_".$content->GetId()."_erase";
357                                if (!empty ($_REQUEST[$name]))
358                                {
359                                        $sql = "DELETE FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id'";
360                                        $db->ExecSqlUpdate($sql, $rows, false);
361                                }
362                        }
363
364                $name = "{$user_prefix}_new_existing_submit";
365                if (!empty ($_REQUEST[$name]))
366                {
367                        $name = "{$user_prefix}_new_existing";
368                        $content = Content :: processSelectContentUI($name);
369                        if ($content)
370                                {
371                                $content_id = $db->EscapeString($content->getId());
372                                $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";
373                                $db->ExecSqlUpdate($sql, $rows, false);
374                                }
375                }
376                        $name = "{$user_prefix}_new";
377                        $content = self :: processNewContentUI($name);
378                        if ($content)
379                                {
380                                $content_id = $db->EscapeString($content->getId());
381                                $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";
382                                $db->ExecSqlUpdate($sql, $rows, false);
383                                }
384
385        }
386
387        /** Get an interface to pick content from all persistent content.
388        * @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
389          @param $sql_additional_where Addidional where conditions to restrict the candidate objects
390        * @return html markup
391        */
392        public static function getSelectContentUI($user_prefix, $sql_additional_where = null)
393        {
394                $html = '';
395                $name = "{$user_prefix}";
396                $html .= _("Select existing Content : ")."\n";
397                global $db;
398                $retval = array ();
399                $sql = "SELECT * FROM content WHERE is_persistent=TRUE $sql_additional_where ORDER BY creation_timestamp";
400                $db->ExecSql($sql, $content_rows, false);
401                if ($content_rows != null)
402                {
403                        $i = 0;
404                        foreach ($content_rows as $content_row)
405                        {
406                                $content = Content :: getObject($content_row['content_id']);
407                                $tab[$i][0] = $content->getId();
408                                $tab[$i][1] = $content->__toString()." (".get_class($content).")";
409                                $i ++;
410                        }
411                        $html .= FormSelectGenerator :: generateFromArray($tab, null, $name, null, false);
412
413                }
414                else
415                {
416                        $html .= "<div class='warningmsg'>"._("Sorry, no content available in the database")."</div>\n";
417                }
418                return $html;
419        }
420
421        /** Get the selected Content object.
422         * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
423         * @return the Content object
424         */
425        static function processSelectContentUI($user_prefix)
426        {
427                $name = "{$user_prefix}";
428                if (!empty ($_REQUEST[$name]))
429                        return Content :: getObject($_REQUEST[$name]);
430                else
431                        return null;
432        }
433
434        private function __construct($content_id)
435        {
436                global $db;
437
438                $content_id = $db->EscapeString($content_id);
439                $sql = "SELECT * FROM content WHERE content_id='$content_id'";
440                $db->ExecSqlUniqueRes($sql, $row, false);
441                if ($row == null)
442                {
443                        throw new Exception(_("The content with the following id could not be found in the database: ").$content_id);
444                }
445                $this->content_row = $row;
446                $this->id = $row['content_id'];
447                $this->content_type = $row['content_type'];
448
449                // By default Content display logging is enabled
450                $this->setLoggingStatus(true);
451        }
452
453        /** A short string representation of the content */
454        public function __toString()
455        {
456                if (empty ($this->content_row['title']))
457                {
458                        $string = _("Untitled content");
459                }
460                else
461                {
462                        $title = self :: getObject($this->content_row['title']);
463                        $string = $title->__toString();
464                }
465                return $string;
466        }
467
468        /** Get the true object type represented by this isntance
469         * @return an array of class names */
470        public function getObjectType()
471        {
472                return $this->content_type;
473        }
474
475        /**
476         * Get content title
477         * @return content a content sub-class
478         */
479        public function getTitle()
480        {
481                try
482                {
483                        return self :: getObject($this->content_row['title']);
484                }
485                catch (Exception $e)
486                {
487                        return null;
488                }
489        }
490
491        /**
492         * Get content description
493         * @return content a content sub-class
494         */
495        public function getDescription()
496        {
497                try
498                {
499                        return self :: getObject($this->content_row['description']);
500                }
501                catch (Exception $e)
502                {
503                        return null;
504                }
505        }
506
507        /**
508         * Get content long description
509         * @return content a content sub-class
510         */
511        public function getLongDescription()
512        {
513                try
514                {
515                        return self :: getObject($this->content_row['long_description']);
516                }
517                catch (Exception $e)
518                {
519                        return null;
520                }
521        }
522
523        /**
524         * Get content project info
525         * @return content a content sub-class
526         */
527        public function getProjectInfo()
528        {
529                try
530                {
531                        return self :: getObject($this->content_row['project_info']);
532                }
533                catch (Exception $e)
534                {
535                        return null;
536                }
537        }
538
539        /**
540         * Get content sponsor info
541         * @return content a content sub-class
542         */
543        public function getSponsorInfo()
544        {
545                try
546                {
547                        return self :: getObject($this->content_row['sponsor_info']);
548                }
549                catch (Exception $e)
550                {
551                        return null;
552                }
553        }
554
555        /** Set the object type of this object
556         * Note that after using this, the object must be re-instanciated to have the right type
557         * */
558        private function setContentType($content_type)
559        {
560                global $db;
561                $content_type = $db->EscapeString($content_type);
562                $available_content_types = self :: getAvailableContentTypes();
563                if (false === array_search($content_type, $available_content_types, true))
564                {
565                        throw new Exception(_("The following content type isn't valid: ").$content_type);
566                }
567                $sql = "UPDATE content SET content_type = '$content_type' WHERE content_id='$this->id'";
568
569                if (!$db->ExecSqlUpdate($sql, false))
570                {
571                        throw new Exception(_("Update was unsuccessfull (database error)"));
572                }
573
574        }
575
576        /** Check if a user is one of the owners of the object
577         * @param $user The user to be added to the owners list
578         * @param $is_author Optionnal, true or false.  Set to true if the user is one of the actual authors of the Content
579         * @return true on success, false on failure */
580        public function addOwner(User $user, $is_author = false)
581        {
582                global $db;
583                $content_id = "'".$this->id."'";
584                $user_id = "'".$db->EscapeString($user->getId())."'";
585                $is_author ? $is_author = 'TRUE' : $is_author = 'FALSE';
586                $sql = "INSERT INTO content_has_owners (content_id, user_id, is_author) VALUES ($content_id, $user_id, $is_author)";
587
588                if (!$db->ExecSqlUpdate($sql, false))
589                {
590                        throw new Exception(_('Unable to insert the new Owner into database.'));
591                }
592
593                return true;
594        }
595
596        /** Remove an owner of the content
597         * @param $user The user to be removed from the owners list
598         */
599        public function deleteOwner(User $user, $is_author = false)
600        {
601                global $db;
602                $content_id = "'".$this->id."'";
603                $user_id = "'".$db->EscapeString($user->getId())."'";
604
605                $sql = "DELETE FROM content_has_owners WHERE content_id=$content_id AND user_id=$user_id";
606
607                if (!$db->ExecSqlUpdate($sql, false))
608                {
609                        throw new Exception(_('Unable to remove the owner from the database.'));
610                }
611
612                return true;
613        }
614
615        /**
616         * Indicates display logging status
617         */
618        public function getLoggingStatus()
619        {
620                return $this->is_logging_enabled;
621        }
622
623        /**
624         * Sets display logging status
625         */
626        public function setLoggingStatus($status)
627        {
628                if (is_bool($status))
629                        $this->is_logging_enabled = $status;
630        }
631
632        /** Is this Content element displayable at this hotspot, many classer override this
633         * @param $node Node, optionnal
634         * @return true or false */
635        public function isDisplayableAt($node)
636        {
637                return true;
638        }
639
640        /** Check if a user is one of the owners of the object
641         * @param $user User object:  the user to be tested.
642         * @return true if the user is a owner, false if he isn't of the user is null */
643        public function isOwner($user)
644        {
645                global $db;
646                $retval = false;
647                if ($user != null)
648                {
649                        $user_id = $db->EscapeString($user->GetId());
650                        $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id' AND user_id='$user_id'";
651                        $db->ExecSqlUniqueRes($sql, $content_owner_row, false);
652                        if ($content_owner_row != null)
653                        {
654                                $retval = true;
655                        }
656                }
657
658                return $retval;
659        }
660        /** Get the authors of the Content
661         * @return null or array of User objects */
662        public function getAuthors()
663        {
664                global $db;
665                $retval = array ();
666                $sql = "SELECT user_id FROM content_has_owners WHERE content_id='$this->id' AND is_author=TRUE";
667                $db->ExecSqlUniqueRes($sql, $content_owner_row, false);
668                if ($content_owner_row != null)
669                {
670                        $user = User :: getObject($content_owner_row['user_id']);
671                        $retval[] = $user;
672                }
673
674                return $retval;
675        }
676        /** @see GenricObject
677         * @return The id */
678        public function getId()
679        {
680                return $this->id;
681        }
682
683        /** 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
684         * @param $is_trivial true or false */
685        public function setIsTrivialContent($is_trivial)
686        {
687                $this->is_trivial_content = $is_trivial;
688        }
689
690        /** 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.
691         * @param $subclass_admin_interface Html content of the interface element of a children
692         * @return The HTML fragment for this interface */
693        public function getUserUI($subclass_user_interface = null)
694        {
695                $html = '';
696                $html .= "<div class='user_ui_main_outer'>\n";
697                $html .= "<div class='user_ui_main_inner'>\n";
698                $html .= "<div class='user_ui_object_class'>Content (".get_class($this)." instance)</div>\n";
699
700                if (!empty ($this->content_row['title']))
701                {
702                        $html .= "<div class='user_ui_title'>\n";
703                        $title = self :: getObject($this->content_row['title']);
704                        // If the content logging is disabled, all the children will inherit this property temporarly
705                        if ($this->getLoggingStatus() == false)
706                                $title->setLoggingStatus(false);
707                        $html .= $title->getUserUI();
708                        $html .= "</div>\n";
709                }
710
711                $html .= "<table><tr><td>\n";
712                $authors = $this->getAuthors();
713                if (count($authors) > 0)
714                {
715                        $html .= "<div class='user_ui_authors'>\n";
716                        $html .= _("Author(s):");
717                        foreach ($authors as $user)
718                        {
719                                $html .= $user->getUsername()." ";
720                        }
721                        $html .= "</div>\n";
722                }
723
724                if (!empty ($this->content_row['description']))
725                {
726                        $html .= "<div class='user_ui_description'>\n";
727                        $description = self :: getObject($this->content_row['description']);
728                        // If the content logging is disabled, all the children will inherit this property temporarly
729                        if ($this->getLoggingStatus() == false)
730                                $description->setLoggingStatus(false);
731                        $html .= $description->getUserUI();
732                        $html .= "</div>\n";
733                }
734
735                if (!empty ($this->content_row['project_info']) || !empty ($this->content_row['sponsor_info']))
736                {
737                        if (!empty ($this->content_row['project_info']))
738                        {
739                                $html .= "<div class='user_ui_projet_info'>\n";
740                                $html .= "<b>"._("Project information:")."</b>";
741                                $project_info = self :: getObject($this->content_row['project_info']);
742                                // If the content logging is disabled, all the children will inherit this property temporarly
743                                if ($this->getLoggingStatus() == false)
744                                        $project_info->setLoggingStatus(false);
745                                $html .= $project_info->getUserUI();
746                                $html .= "</div>\n";
747                        }
748
749                        if (!empty ($this->content_row['sponsor_info']))
750                        {
751                                $html .= "<div class='user_ui_sponsor_info'>\n";
752                                $html .= "<b>"._("Project sponsor:")."</b>";
753                                $sponsor_info = self :: getObject($this->content_row['sponsor_info']);
754                                // If the content logging is disabled, all the children will inherit this property temporarly
755                                if ($this->getLoggingStatus() == false)
756                                        $sponsor_info->setLoggingStatus(false);
757                                $html .= $sponsor_info->getUserUI();
758                                $html .= "</div>\n";
759                        }
760                }
761
762                $html .= "</td>\n";
763
764                $html .= "<td>\n$subclass_user_interface</td>\n";
765                $html .= "</tr></table>\n";
766
767                $html .= "</div>\n";
768                $html .= "</div>\n";
769                $this->logContentDisplay();
770                return $html;
771        }
772
773        /** Log that this content has just been displayed to the user.  Will only log if the user is logged in */
774        private function logContentDisplay()
775        {
776                if ($this->getLoggingStatus() == true)
777                {
778                        // DEBUG::
779                        //echo "Logging ".get_class($this)." :: ".$this->__toString()."<br>";
780                        $user = User :: getCurrentUser();
781                        $node = Node :: getCurrentNode();
782                        if ($user != null && $node != null)
783                        {
784                                $user_id = $user->getId();
785                                $node_id = $node->getId();
786                                global $db;
787
788                                $sql = "SELECT * FROM content_display_log WHERE user_id='$user_id' AND node_id='$node_id' AND content_id='$this->id'";
789                                $db->ExecSql($sql, $log_rows, false);
790                                if ($log_rows != null)
791                                {
792                                        $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'";
793                                }
794                                else
795                                {
796                                        $sql = "INSERT INTO content_display_log (user_id, content_id, node_id) VALUES ('$user_id', '$this->id', '$node_id')";
797                                }
798                                $db->ExecSqlUpdate($sql, false);
799                        }
800                }
801        }
802
803        /** 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.
804         * @param $subclass_admin_interface Html content of the interface element of a children
805         * @return The HTML fragment for this interface */
806        public function getListUI($subclass_list_interface = null)
807        {
808                $html = '';
809                $html .= "<div class='list_ui_container'>\n";
810                $html .= $this->__toString()." (".get_class($this).")\n";
811                $html .= $subclass_list_interface;
812                $html .= "</div>\n";
813                return $html;
814        }
815
816        /** 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.
817         * @param $subclass_admin_interface Html content of the interface element of a children
818         * @return The HTML fragment for this interface */
819        public function getAdminUI($subclass_admin_interface = null)
820        {
821                global $db;
822                $html = '';
823                $html .= "<div class='admin_container'>\n";
824                $html .= "<div class='admin_class'>Content (".get_class($this)." instance)</div>\n";
825                if ($this->getObjectType() == 'Content') /* The object hasn't yet been typed */
826                {
827                        $html .= _("You must select a content type: ");
828                        $i = 0;
829                        foreach (self :: getAvailableContentTypes() as $classname)
830                        {
831                                $tab[$i][0] = $classname;
832                                $tab[$i][1] = $classname;
833                                $i ++;
834                        }
835                        $html .= FormSelectGenerator :: generateFromArray($tab, null, "content_".$this->id."_content_type", "Content", false);
836                }
837                else
838                        if ($this->is_trivial_content == false)
839                        {
840                                /* title */
841                                $html .= "<div class='admin_section_container'>\n";
842                                $html .= "<div class='admin_section_title'>"._("Title:")."</div>\n";
843                                $html .= "<div class='admin_section_data'>\n";
844                                if (empty ($this->content_row['title']))
845                                {
846                                        $html .= self :: getNewContentUI("title_{$this->id}_new");
847                                        $html .= "</div>\n";
848                                }
849                                else
850                                {
851                                        $title = self :: getObject($this->content_row['title']);
852                                        $html .= $title->getAdminUI();
853                                        $html .= "</div>\n";
854                                        $html .= "<div class='admin_section_tools'>\n";
855                                        $name = "content_".$this->id."_title_erase";
856                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
857                                        $html .= "</div>\n";
858                                }
859                                $html .= "</div>\n";
860
861                                /* is_persistent */
862                                $html .= "<div class='admin_section_container'>\n";
863                                $html .= "<div class='admin_section_title'>Is persistent (reusable and read-only)?: </div>\n";
864                                $html .= "<div class='admin_section_data'>\n";
865                                $name = "content_".$this->id."_is_persistent";
866                                $this->isPersistent() ? $checked = 'CHECKED' : $checked = '';
867                                $html .= "<input type='checkbox' name='$name' $checked>\n";
868                                $html .= "</div>\n";
869                                $html .= "</div>\n";
870
871                                /* description */
872                                $html .= "<div class='admin_section_container'>\n";
873                                $html .= "<div class='admin_section_title'>"._("Description:")."</div>\n";
874                                $html .= "<div class='admin_section_data'>\n";
875                                if (empty ($this->content_row['description']))
876                                {
877                                        $html .= self :: getNewContentUI("description_{$this->id}_new");
878                                        $html .= "</div>\n";
879                                }
880                                else
881                                {
882                                        $description = self :: getObject($this->content_row['description']);
883                                        $html .= $description->getAdminUI();
884                                        $html .= "</div>\n";
885                                        $html .= "<div class='admin_section_tools'>\n";
886                                        $name = "content_".$this->id."_description_erase";
887                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
888                                        $html .= "</div>\n";
889                                }
890                                $html .= "</div>\n";
891
892                                /* long description */
893                                $html .= "<div class='admin_section_container'>\n";
894                                $html .= "<div class='admin_section_title'>"._("Long description:")."</div>\n";
895                                $html .= "<div class='admin_section_data'>\n";
896                                if (empty ($this->content_row['long_description']))
897                                {
898                                        $html .= self :: getNewContentUI("long_description_{$this->id}_new");
899                                        $html .= "</div>\n";
900                                }
901                                else
902                                {
903                                        $description = self :: getObject($this->content_row['long_description']);
904                                        $html .= $description->getAdminUI();
905                                        $html .= "</div>\n";
906                                        $html .= "<div class='admin_section_tools'>\n";
907                                        $name = "content_".$this->id."_long_description_erase";
908                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
909                                        $html .= "</div>\n";
910                                }
911                                $html .= "</div>\n";
912
913                                /* project_info */
914                                $html .= "<div class='admin_section_container'>\n";
915                                $html .= "<div class='admin_section_title'>"._("Information on this project:")."</div>\n";
916                                $html .= "<div class='admin_section_data'>\n";
917                                if (empty ($this->content_row['project_info']))
918                                {
919                                        $html .= self :: getNewContentUI("project_info_{$this->id}_new");
920                                        $html .= "</div>\n";
921                                }
922                                else
923                                {
924                                        $project_info = self :: getObject($this->content_row['project_info']);
925                                        $html .= $project_info->getAdminUI();
926                                        $html .= "</div>\n";
927                                        $html .= "<div class='admin_section_tools'>\n";
928                                        $name = "content_".$this->id."_project_info_erase";
929                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
930                                        $html .= "</div>\n";
931                                }
932                                $html .= "</div>\n";
933
934                                /* sponsor_info */
935                                $html .= "<div class='admin_section_container'>\n";
936                                $html .= "<div class='admin_section_title'>"._("Sponsor of this project:")."</div>\n";
937                                $html .= "<div class='admin_section_data'>\n";
938                                if (empty ($this->content_row['sponsor_info']))
939                                {
940                                        $html .= self :: getNewContentUI("sponsor_info_{$this->id}_new");
941                                        $html .= "</div>\n";
942                                }
943                                else
944                                {
945                                        $sponsor_info = self :: getObject($this->content_row['sponsor_info']);
946                                        $html .= $sponsor_info->getAdminUI();
947                                        $html .= "</div>\n";
948                                        $html .= "<div class='admin_section_tools'>\n";
949                                        $name = "content_".$this->id."_sponsor_info_erase";
950                                        $html .= "<input type='submit' name='$name' value='"._("Delete")."'>";
951                                        $html .= "</div>\n";
952                                }
953                                $html .= "</div>\n";
954
955                                /* content_has_owners */
956                                $html .= "<div class='admin_section_container'>\n";
957                                $html .= "<span class='admin_section_title'>"._("Content owner list")."</span>\n";
958                                $html .= "<ul class='admin_section_list'>\n";
959
960                                global $db;
961                                $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id'";
962                                $db->ExecSql($sql, $content_owner_rows, false);
963                                if ($content_owner_rows != null)
964                                {
965                                        foreach ($content_owner_rows as $content_owner_row)
966                                        {
967                                                $html .= "<li class='admin_section_list_item'>\n";
968                                                $html .= "<div class='admin_section_data'>\n";
969                                                $user = User :: getObject($content_owner_row['user_id']);
970
971                                                $html .= $user->getUserListUI();
972                                                $name = "content_".$this->id."_owner_".$user->GetId()."_is_author";
973                                                $html .= " Is content author? ";
974
975                                                $content_owner_row['is_author'] == 't' ? $checked = 'CHECKED' : $checked = '';
976                                                $html .= "<input type='checkbox' name='$name' $checked>\n";
977                                                $html .= "</div>\n";
978                                                $html .= "<div class='admin_section_tools'>\n";
979                                                $name = "content_".$this->id."_owner_".$user->GetId()."_remove";
980                                                $html .= "<input type='submit' name='$name' value='"._("Remove")."'>";
981                                                $html .= "</div>\n";
982                                                $html .= "</li>\n";
983                                        }
984                                }
985
986                                $html .= "<li class='admin_section_list_item'>\n";
987                                $html .= "<div class='admin_section_data'>\n";
988                                $html .= User :: getSelectUserUI("content_{$this->id}_new_owner");
989                                $html .= "</div>\n";
990                                $html .= "<div class='admin_section_tools'>\n";
991                                $name = "content_{$this->id}_add_owner_submit";
992                                $value = _("Add owner");
993                                $html .= "<input type='submit' name='$name' value='$value'>";
994                                $html .= "</div>\n";
995                                $html .= "</li>\n";
996                                $html .= "</ul>\n";
997                                $html .= "</div>\n";
998                        }
999                $html .= $subclass_admin_interface;
1000                $html .= "</div>\n";
1001                return $html;
1002        }
1003        /** Process admin interface of this object.  When an object overrides this method, they should call the parent processAdminUI at the BEGINING of processing.
1004       
1005        */
1006        public function processAdminUI()
1007        {
1008                if ($this->isOwner(User :: getCurrentUser()) || User :: getCurrentUser()->isSuperAdmin())
1009                {
1010                        global $db;
1011                        if ($this->getObjectType() == 'Content') /* The object hasn't yet been typed */
1012                        {
1013                                $content_type = FormSelectGenerator :: getResult("content_".$this->id."_content_type", "Content");
1014                                $this->setContentType($content_type);
1015                        }
1016                        else
1017                                if ($this->is_trivial_content == false)
1018                                {
1019                                        /* title */
1020                                        if (empty ($this->content_row['title']))
1021                                        {
1022                                                $title = self :: processNewContentUI("title_{$this->id}_new");
1023                                                if ($title != null)
1024                                                {
1025                                                        $title_id = $title->GetId();
1026                                                        $db->ExecSqlUpdate("UPDATE content SET title = '$title_id' WHERE content_id = '$this->id'", FALSE);
1027                                                }
1028                                        }
1029                                        else
1030                                        {
1031                                                $title = self :: getObject($this->content_row['title']);
1032                                                $name = "content_".$this->id."_title_erase";
1033                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1034                                                {
1035                                                        $db->ExecSqlUpdate("UPDATE content SET title = NULL WHERE content_id = '$this->id'", FALSE);
1036                                                        $title->delete($errmsg);
1037                                                }
1038                                                else
1039                                                {
1040                                                        $title->processAdminUI();
1041                                                }
1042                                        }
1043
1044                                        /* is_persistent */
1045                                        $name = "content_".$this->id."_is_persistent";
1046                                        !empty ($_REQUEST[$name]) ? $this->setIsPersistent(true) : $this->setIsPersistent(false);
1047
1048                                        /* description */
1049                                        if (empty ($this->content_row['description']))
1050                                        {
1051                                                $description = self :: processNewContentUI("description_{$this->id}_new");
1052                                                if ($description != null)
1053                                                {
1054                                                        $description_id = $description->GetId();
1055                                                        $db->ExecSqlUpdate("UPDATE content SET description = '$description_id' WHERE content_id = '$this->id'", FALSE);
1056                                                }
1057                                        }
1058                                        else
1059                                        {
1060                                                $description = self :: getObject($this->content_row['description']);
1061                                                $name = "content_".$this->id."_description_erase";
1062                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1063                                                {
1064                                                        $db->ExecSqlUpdate("UPDATE content SET description = NULL WHERE content_id = '$this->id'", FALSE);
1065                                                        $description->delete($errmsg);
1066                                                }
1067                                                else
1068                                                {
1069                                                        $description->processAdminUI();
1070                                                }
1071                                        }
1072
1073                                        /* long description */
1074                                        if (empty ($this->content_row['long_description']))
1075                                        {
1076                                                $long_description = self :: processNewContentUI("long_description_{$this->id}_new");
1077                                                if ($long_description != null)
1078                                                {
1079                                                        $long_description_id = $long_description->GetId();
1080                                                        $db->ExecSqlUpdate("UPDATE content SET long_description = '$long_description_id' WHERE content_id = '$this->id'", FALSE);
1081                                                }
1082                                        }
1083                                        else
1084                                        {
1085                                                $long_description = self :: getObject($this->content_row['long_description']);
1086                                                $name = "content_".$this->id."_long_description_erase";
1087                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1088                                                {
1089                                                        $db->ExecSqlUpdate("UPDATE content SET long_description = NULL WHERE content_id = '$this->id'", FALSE);
1090                                                        $long_description->delete($errmsg);
1091                                                }
1092                                                else
1093                                                {
1094                                                        $long_description->processAdminUI();
1095                                                }
1096                                        }
1097
1098                                        /* project_info */
1099                                        if (empty ($this->content_row['project_info']))
1100                                        {
1101                                                $project_info = self :: processNewContentUI("project_info_{$this->id}_new");
1102                                                if ($project_info != null)
1103                                                {
1104                                                        $project_info_id = $project_info->GetId();
1105                                                        $db->ExecSqlUpdate("UPDATE content SET project_info = '$project_info_id' WHERE content_id = '$this->id'", FALSE);
1106                                                }
1107                                        }
1108                                        else
1109                                        {
1110                                                $project_info = self :: getObject($this->content_row['project_info']);
1111                                                $name = "content_".$this->id."_project_info_erase";
1112                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1113                                                {
1114                                                        $db->ExecSqlUpdate("UPDATE content SET project_info = NULL WHERE content_id = '$this->id'", FALSE);
1115                                                        $project_info->delete($errmsg);
1116                                                }
1117                                                else
1118                                                {
1119                                                        $project_info->processAdminUI();
1120                                                }
1121                                        }
1122
1123                                        /* sponsor_info */
1124                                        if (empty ($this->content_row['sponsor_info']))
1125                                        {
1126                                                $sponsor_info = self :: processNewContentUI("sponsor_info_{$this->id}_new");
1127                                                if ($sponsor_info != null)
1128                                                {
1129                                                        $sponsor_info_id = $sponsor_info->GetId();
1130                                                        $db->ExecSqlUpdate("UPDATE content SET sponsor_info = '$sponsor_info_id' WHERE content_id = '$this->id'", FALSE);
1131                                                }
1132                                        }
1133                                        else
1134                                        {
1135                                                $sponsor_info = self :: getObject($this->content_row['sponsor_info']);
1136                                                $name = "content_".$this->id."_sponsor_info_erase";
1137                                                if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true)
1138                                                {
1139                                                        $db->ExecSqlUpdate("UPDATE content SET sponsor_info = NULL WHERE content_id = '$this->id'", FALSE);
1140                                                        $sponsor_info->delete($errmsg);
1141                                                }
1142                                                else
1143                                                {
1144                                                        $sponsor_info->processAdminUI();
1145                                                }
1146                                        }
1147                                        /* content_has_owners */
1148                                        $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id'";
1149                                        $db->ExecSql($sql, $content_owner_rows, false);
1150                                        if ($content_owner_rows != null)
1151                                        {
1152                                                foreach ($content_owner_rows as $content_owner_row)
1153                                                {
1154                                                        $user = User :: getObject($content_owner_row['user_id']);
1155                                                        $user_id = $user->getId();
1156                                                        $name = "content_".$this->id."_owner_".$user->GetId()."_remove";
1157                                                        if (!empty ($_REQUEST[$name]))
1158                                                        {
1159                                                                $this->deleteOwner($user);
1160                                                        }
1161                                                        else
1162                                                        {
1163                                                                $name = "content_".$this->id."_owner_".$user->GetId()."_is_author";
1164                                                                $content_owner_row['is_author'] == 't' ? $is_author = true : $is_author = false;
1165                                                                !empty ($_REQUEST[$name]) ? $should_be_author = true : $should_be_author = false;
1166                                                                if ($is_author != $should_be_author)
1167                                                                {
1168                                                                        $should_be_author ? $is_author_sql = 'TRUE' : $is_author_sql = 'FALSE';
1169                                                                        $sql = "UPDATE content_has_owners SET is_author=$is_author_sql WHERE content_id='$this->id' AND user_id='$user_id'";
1170
1171                                                                        if (!$db->ExecSqlUpdate($sql, false))
1172                                                                        {
1173                                                                                throw new Exception(_('Unable to set as author in the database.'));
1174                                                                        }
1175
1176                                                                }
1177
1178                                                        }
1179                                                }
1180                                        }
1181                                        $user = User :: processSelectUserUI("content_{$this->id}_new_owner");
1182                                        $name = "content_{$this->id}_add_owner_submit";
1183                                        if (!empty ($_REQUEST[$name]) && $user != null)
1184                                        {
1185                                                $this->addOwner($user);
1186                                        }
1187
1188                                }
1189                        $this->refresh();
1190                }
1191        }
1192
1193        /**
1194         * Tell if a given user is already subscribed to this content
1195         * @param User the given user
1196         * @return boolean
1197         */
1198        public function isUserSubscribed(User $user)
1199        {
1200                global $db;
1201                $sql = "SELECT content_id FROM user_has_content WHERE user_id = '{$user->getId()}' AND content_id = '{$this->getId()}';";
1202                $db->ExecSqlUniqueRes($sql, $row, false);
1203
1204                if ($row)
1205                        return true;
1206                else
1207                        return false;
1208        }
1209
1210        /** Subscribe to the project
1211         * @return true on success, false on failure */
1212        public function subscribe(User $user)
1213        {
1214                return $user->addContent($this);
1215        }
1216        /** Unsubscribe to the project
1217         * @return true on success, false on failure */
1218        public function unsubscribe(User $user)
1219        {
1220                return $user->removeContent($this);
1221        }
1222
1223        /** 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.
1224        * @return true or false */
1225        public function isPersistent()
1226        {
1227                if ($this->content_row['is_persistent'] == 't')
1228                {
1229                        $retval = true;
1230                }
1231                else
1232                {
1233                        $retval = false;
1234                }
1235                return $retval;
1236        }
1237
1238        /** Set if the content group is persistent
1239         * @param $is_locative_content true or false
1240         * */
1241        public function setIsPersistent($is_persistent)
1242        {
1243                if ($is_persistent != $this->isPersistent()) /* Only update database if there is an actual change */
1244                {
1245                        $is_persistent ? $is_persistent_sql = 'TRUE' : $is_persistent_sql = 'FALSE';
1246
1247                        global $db;
1248                        $db->ExecSqlUpdate("UPDATE content SET is_persistent = $is_persistent_sql WHERE content_id = '$this->id'", false);
1249                        $this->refresh();
1250                }
1251
1252        }
1253
1254        /** Reloads the object from the database.  Should normally be called after a set operation */
1255        protected function refresh()
1256        {
1257                $this->__construct($this->id);
1258        }
1259
1260        /** @see GenericObject
1261         * @note Persistent content will not be deleted
1262        */
1263        public function delete(& $errmsg)
1264        {
1265                $retval = false;
1266                if ($this->isPersistent())
1267                {
1268                        $errmsg = _("Content is persistent (you must make it non persistent before you can delete it)");
1269                }
1270                else
1271                {
1272                        global $db;
1273                        if ($this->isOwner(User :: getCurrentUser()) || User :: getCurrentUser()->isSuperAdmin())
1274                        {
1275                                $sql = "DELETE FROM content WHERE content_id='$this->id'";
1276                                $db->ExecSqlUpdate($sql, false);
1277                                $retval = true;
1278                        }
1279                        else
1280                        {
1281                                $errmsg = _("Access denied (not owner of content)");
1282                        }
1283                }
1284                return $retval;
1285        }
1286
1287} // End class
1288
1289/* This allows the class to enumerate it's children properly */
1290$class_names = Content :: getAvailableContentTypes();
1291foreach ($class_names as $class_name)
1292{
1293        require_once BASEPATH.'classes/Content/'.$class_name.'.php';
1294}
1295?>
Note: See TracBrowser for help on using the browser.