Changeset 1192

Show
Ignore:
Timestamp:
03/17/07 01:14:33 (5 years ago)
Author:
benoitg
Message:
  • Lots of work on profiles. The HTML and CSS are not final, but #18 can be considered closed.
  • ProfileField::getContentField(): Fix bug where the object wouldn't refresh properly.
  • Content: Delicate refactoring of the UI to create new content. The content object now supports directly adding the actual values of a new Content in getNewContentUI(), if the content filter only allows a single content type. For this to work, the Content type must overload the getNewUI() method. This saves many mouse clicks for form style interface, like profiles.
    • User: Don't create profile automatically.
    • Don't show profiles when user is invisible.
  • Langstring, SimpleString?, HTMLEditor: Support getNewUI(). As a result of these changes, SmartyTemplate?, SimpleSmartyTemplate?, Stylesheet also get it for free.
  • Add new standard Smarty value userOriginallyRequestedURL.

Note that this does NOT fix #266

  • Add new standard Smarty value nodeWebSiteURL
  • Some work towards #158 1- The "Use the Internet" link pointing to the originally requested URL is no longuer a part of every portal. To restore that functionnality, paste the following code in a SmartyTemplate? in the Content manager. {if $userOriginallyRequestedURL}

<a href='{$userOriginallyRequestedURL}'>Take me where I originally wanted to go</a>

{/if}
2- The "Where am I" link is gone. It made little sense to have that content common to all groups. To restore it, pu it inline in your login page, link a html page on your auth server, or link a Content display page.
3- Same with the link to the Network. To restore the unctionnality, paste the following code in a SmartyTemplate?:
<a class="administration" href="{$networkWebSiteURL}"><img class="administration" src="{$common_images_url}lien_ext.gif">&nbsp;{$networkName}</a>

Location:
trunk/wifidog-auth
Files:
3 removed
31 modified

Legend:

Unmodified
Added
Removed
  • trunk/wifidog-auth/CHANGELOG

    r1188 r1192  
     12007-03-16 Benoit Grégoire  <bock@step.polymtl.ca> 
     2        * Lots of work on profiles.  The HTML and CSS are not final, but #18 can be considered closed. 
     3        * ProfileField::getContentField():  Fix bug where the object wouldn't refresh properly. 
     4        * Content:  Delicate refactoring of the UI to create new content. 
     5        The content object now supports directly adding the actual values of a new  
     6        Content in getNewContentUI(), if the content filter only allows a single content type.   
     7        For this to work, the Content type must overload the getNewUI() method.   
     8        This saves many mouse clicks for form style interface, like profiles. 
     9        * User:  Don't create profile automatically. 
     10        * Don't show profiles when user is invisible. 
     11        * Langstring, SimpleString, HTMLEditor: Support getNewUI().  As a result of these changes, SmartyTemplate, SimpleSmartyTemplate, Stylesheet also get it for free. 
     12        * Add new standard Smarty value userOriginallyRequestedURL.   
     13 Note that this does NOT fix #266 
     14        * Add new standard Smarty value nodeWebSiteURL 
     15        * Some work towards #158 
     16         1- The "Use the Internet" link pointing to the originally requested URL is no longuer a part of every portal.  To restore that functionnality, paste the following code in a SmartyTemplate in the Content manager. 
     17        {if $userOriginallyRequestedURL} 
     18                <a href='{$userOriginallyRequestedURL}'>Take me where I originally wanted to go</a> 
     19        {/if} 
     20        2- The "Where am I" link is gone.  It made little sense to have that content common to all groups.  To restore it, pu it inline in your login page, link a html page on your auth server, or link a Content display page. 
     21        3- Same with the link to the Network.  To restore the unctionnality, paste the following code in a SmartyTemplate: 
     22        <a class="administration" href="{$networkWebSiteURL}"><img class="administration" src="{$common_images_url}lien_ext.gif">&nbsp;{$networkName}</a> 
     23        * ContentTypeFilter:  Saving still wasn't neutral.  Strip the array indexes to fix it. 
     24 
    1252007-03-03 Benoit Grégoire  <bock@step.polymtl.ca> 
    226        * CSS tweaks for RSS feeds. 
    327        * Fix detection of HTML Safe. 
    4          
     28        * Avatar.php:  Don't allow editing the picture size. 
     29        * ContentGroup:  In some cases, the same element could be picked twice in the same display.   
     30        Make sure that doesn't happen.  Also, implement the option to not rotate content at all,  
     31        usefull when showing all elements simultaneously in a specific order. Closes #294 
     32 
    5332007-02-24 Damien Raude-Morvan <drazzib@drazzib.com> 
    634        * Fix main SQL request in Node::getSelectNodeUI() to use 
  • trunk/wifidog-auth/wifidog/admin/generic_object_admin.php

    r1174 r1192  
    104104 * Check for debugging requests 
    105105 */ 
     106//$_REQUEST['debug']=true; 
    106107if (!empty ($_REQUEST['debug'])) { 
    107108    echo "<pre>"; 
  • trunk/wifidog-auth/wifidog/classes/Content.php

    r1174 r1192  
    6464    private static $instanceArray = array (); 
    6565    /** 
    66     * Id of content 
    67     * 
    68     * @var string     */ 
     66     * Id of content 
     67     * 
     68     * @var string     */ 
    6969    protected $id; 
    7070 
     
    110110     */ 
    111111    protected function __construct($content_id) { 
    112  
    113         $db = AbstractDb :: getObject(); 
    114  
    115         // Init values 
    116         $row = null; 
    117  
    118         // Get content from database 
    119         $content_id = $db->escapeString($content_id); 
    120         $sql = "SELECT * FROM content WHERE content_id='$content_id'"; 
    121         $db->execSqlUniqueRes($sql, $row, false); 
    122  
    123         if ($row == null) { 
    124                 throw new Exception(_("The content with the following id could not be found in the database: ") . $content_id); 
    125         } 
    126  
    127         $this->content_row = $row; 
    128         $this->id = $row['content_id']; 
    129         $this->content_type = $row['content_type']; 
    130         $kvp_rows = null; 
    131         $sql = "SELECT key, value FROM content_key_value_pairs WHERE content_id='$content_id'"; 
    132         $db->execSql($sql, $kvp_rows, false); 
    133         if ($kvp_rows) { 
    134                 foreach ($kvp_rows as $kvp_row) { 
    135                         $this->kvps[$kvp_row['key']] = $kvp_row['value']; 
    136                 } 
    137         } 
    138         // By default content display logging is enabled 
    139         $this->setLoggingStatus(true); 
    140         $this->log_as_content = & $this; 
     112        //echo "Content::__construct($content_id)<br/>\n"; 
     113        $db = AbstractDb :: getObject(); 
     114 
     115        // Init values 
     116        $row = null; 
     117 
     118        // Get content from database 
     119        $content_id = $db->escapeString($content_id); 
     120        $sql = "SELECT * FROM content WHERE content_id='$content_id'"; 
     121        $db->execSqlUniqueRes($sql, $row, false); 
     122 
     123        if ($row == null) { 
     124            throw new Exception(_("The content with the following id could not be found in the database: ") . $content_id); 
     125        } 
     126 
     127        $this->content_row = $row; 
     128        $this->id = $row['content_id']; 
     129        $this->content_type = $row['content_type']; 
     130        $kvp_rows = null; 
     131        $sql = "SELECT key, value FROM content_key_value_pairs WHERE content_id='$content_id'"; 
     132        $db->execSql($sql, $kvp_rows, false); 
     133        if ($kvp_rows) { 
     134            foreach ($kvp_rows as $kvp_row) { 
     135                $this->kvps[$kvp_row['key']] = $kvp_row['value']; 
     136            } 
     137        } 
     138        // By default content display logging is enabled 
     139        $this->setLoggingStatus(true); 
     140        $this->log_as_content = & $this; 
    141141    } 
    142142 
     
    147147     */ 
    148148    public function __toString() { 
    149         if (empty ($this->content_row['title'])) { 
    150                 $string = _("Untitled content"); 
    151         } else { 
    152                 $title = self :: getObject($this->content_row['title']); 
    153                 $string = $title->__toString(); 
    154         } 
    155  
    156         return $string; 
     149        if (empty ($this->content_row['title'])) { 
     150            $string = _("Untitled content"); 
     151        } else { 
     152            $title = self :: getObject($this->content_row['title']); 
     153            $string = $title->__toString(); 
     154        } 
     155 
     156        return $string; 
    157157    } 
    158158 
     
    166166     * @return object The newly created Content object, or null if there was an 
    167167     *                error (an exception is also trown) 
    168      
     168 
    169169     */ 
    170170    public static function createNewObject($content_type = "Content", $id = null) { 
    171171 
    172         $db = AbstractDb :: getObject(); 
    173  
    174         if (empty ($id)) { 
    175                 $contentId = get_guid(); 
    176         } else { 
    177                 $contentId = $db->escapeString($id); 
    178         } 
    179  
    180         if (empty ($content_type)) { 
    181                 throw new Exception(_('Content type is optionnal, but cannot be empty!')); 
    182         } else { 
    183                 $content_type = $db->escapeString($content_type); 
    184         } 
    185  
    186         $sql = "INSERT INTO content (content_id, content_type) VALUES ('$contentId', '$content_type')"; 
    187  
    188         if (!$db->execSqlUpdate($sql, false)) { 
    189                 throw new Exception(_('Unable to insert new content into database!')); 
    190         } 
    191  
    192         $object = self :: getObject($contentId); 
    193  
    194         // At least add the current user as the default owner 
    195         $object->AddOwner(User :: getCurrentUser()); 
    196  
    197         // By default, make it persistent 
    198         $object->setIsPersistent(true); 
    199  
    200         return $object; 
     172        $db = AbstractDb :: getObject(); 
     173 
     174        if (empty ($id)) { 
     175            $contentId = get_guid(); 
     176        } else { 
     177            $contentId = $db->escapeString($id); 
     178        } 
     179 
     180        if (empty ($content_type)) { 
     181            throw new Exception(_('Content type is optionnal, but cannot be empty!')); 
     182        } else { 
     183            $content_type = $db->escapeString($content_type); 
     184        } 
     185 
     186        $sql = "INSERT INTO content (content_id, content_type) VALUES ('$contentId', '$content_type')"; 
     187 
     188        if (!$db->execSqlUpdate($sql, false)) { 
     189            throw new Exception(_('Unable to insert new content into database!')); 
     190        } 
     191 
     192        $object = self :: getObject($contentId); 
     193 
     194        // At least add the current user as the default owner 
     195        $object->AddOwner(User :: getCurrentUser()); 
     196 
     197        // By default, make it persistent 
     198        $object->setIsPersistent(true); 
     199 
     200        return $object; 
    201201    } 
    202202 
     
    207207     */ 
    208208    public static function getCreateNewObjectUI() { 
    209         // Init values 
    210         $html = ""; 
    211         $i = 0; 
    212         $tab = array (); 
    213  
    214         foreach (self :: getAvailableContentTypes() as $className) { 
    215                 $tab[$i][0] = $className; 
    216                 $tab[$i][1] = $className; 
    217                 $i++; 
    218         } 
    219  
    220         if (empty ($tab)) { 
    221                 $html .= _("It appears that you have not installed any Content plugin !"); 
    222         } else { 
    223                 $html .= _("You must select a content type: "); 
    224                 $html .= FormSelectGenerator :: generateFromArray($tab, "TrivialLangstring", "new_content_content_type", "Content", false); 
    225         } 
    226  
    227         return $html; 
     209        // Init values 
     210        $html = ""; 
     211        $i = 0; 
     212        $tab = array (); 
     213 
     214        foreach (self :: getAvailableContentTypes() as $className) { 
     215            $tab[$i][0] = $className; 
     216            $tab[$i][1] = $className; 
     217            $i++; 
     218        } 
     219 
     220        if (empty ($tab)) { 
     221            $html .= _("It appears that you have not installed any Content plugin !"); 
     222        } else { 
     223            $html .= _("You must select a content type: "); 
     224            $html .= FormSelectGenerator :: generateFromArray($tab, "TrivialLangstring", "new_content_content_type", "Content", false); 
     225        } 
     226 
     227        return $html; 
    228228    } 
    229229 
     
    238238     */ 
    239239    public static function processCreateNewObjectUI() { 
    240         // Init values 
    241         $retVal = null; 
    242  
    243         $contentType = FormSelectGenerator :: getResult("new_content_content_type", "Content"); 
    244  
    245         if ($contentType) { 
    246                 $retVal = self :: createNewObject($contentType); 
    247         } 
    248  
    249         return $retVal; 
     240        // Init values 
     241        $retVal = null; 
     242 
     243        $contentType = FormSelectGenerator :: getResult("new_content_content_type", "Content"); 
     244 
     245        if ($contentType) { 
     246            $retVal = self :: createNewObject($contentType); 
     247        } 
     248 
     249        return $retVal; 
    250250    } 
    251251 
     
    257257     * @return object The Content object, or null if there was an error 
    258258     *                (an exception is also thrown) 
    259      
     259 
    260260     */ 
    261261    public static function getObject($content_id) { 
    262  
    263         if (!isset (self :: $instanceArray[$content_id])) { 
    264                 $db = AbstractDb :: getObject(); 
    265  
    266                 // Init values 
    267                 $row = null; 
    268  
    269                 $content_id = $db->escapeString($content_id); 
    270                 $sql = "SELECT content_type FROM content WHERE content_id='$content_id'"; 
    271                 $db->execSqlUniqueRes($sql, $row, false); 
    272  
    273                 if ($row == null) { 
    274                         throw new Exception(_("The content with the following id could not be found in the database: ") . $content_id); 
    275                 } 
    276                 if (!class_exists($row['content_type'])) { 
    277                         //throw new Exception(_("The following content type isn't valid: ").$row['content_type']); 
    278                         $object = null; 
    279                 } else { 
    280                         self :: $instanceArray[$content_id] = new $row['content_type'] ($content_id); 
    281                         $object = self :: $instanceArray[$content_id]; 
    282                 } 
    283         } else { 
    284                 $object = self :: $instanceArray[$content_id]; 
    285         } 
    286         return $object; 
     262        //echo "Content::g e tObject(".$content_id.")<br/>\n"; 
     263        if (!isset (self :: $instanceArray[$content_id])) { 
     264            //echo "Cache MISS!<br/>\n"; 
     265            $db = AbstractDb :: getObject(); 
     266 
     267            // Init values 
     268            $row = null; 
     269 
     270            $content_id = $db->escapeString($content_id); 
     271            $sql = "SELECT content_type FROM content WHERE content_id='$content_id'"; 
     272            $db->execSqlUniqueRes($sql, $row, false); 
     273 
     274            if ($row == null) { 
     275                throw new Exception(_("The content with the following id could not be found in the database: ") . $content_id); 
     276            } 
     277            if (!class_exists($row['content_type'])) { 
     278                //throw new Exception(_("The following content type isn't valid: ").$row['content_type']); 
     279                $object = null; 
     280            } else { 
     281                self :: $instanceArray[$content_id] = new $row['content_type'] ($content_id); 
     282                $object = self :: $instanceArray[$content_id]; 
     283            } 
     284        } else { 
     285            //echo "Cache HIT!<br/>\n"; 
     286            $object = self :: $instanceArray[$content_id]; 
     287        } 
     288        return $object; 
    287289 
    288290    } 
     
    294296     */ 
    295297    public static function getAvailableContentTypes() { 
    296         // Init values 
    297         $contentTypes = array (); 
    298         $useCache = false; 
    299         $cachedData = null; 
    300  
    301         // Create new cache object with a lifetime of one week 
    302         $cache = new Cache("ContentClasses", "ClassFileCaches", 604800); 
    303  
    304         // Check if caching has been enabled. 
    305         if ($cache->isCachingEnabled) { 
    306                 $cachedData = $cache->getCachedData("mixed"); 
    307  
    308                 if ($cachedData) { 
    309                         // Return cached data. 
    310                         $useCache = true; 
    311                         $contentTypes = $cachedData; 
    312                 } 
    313         } 
    314  
    315         if (!$useCache) { 
    316                 $dir = WIFIDOG_ABS_FILE_PATH . "classes/Content"; 
    317                 $dirHandle = @ opendir($dir); 
    318  
    319                 if ($dirHandle) { 
    320                         // Loop over the directory 
    321                         while (false !== ($subDir = readdir($dirHandle))) { 
    322                                 // Loop through sub-directories of Content 
    323                                 if ($subDir != '.' && $subDir != '..' && is_dir("{$dir}/{$subDir}")) { 
    324                                         // Only add directories containing corresponding initial Content class 
    325                                         if (is_file("{$dir}/{$subDir}/{$subDir}.php")) { 
    326                                                 $contentTypes[] = $subDir; 
    327                                         } 
    328                                 } 
    329                         } 
    330  
    331                         closedir($dirHandle); 
    332                 } else { 
    333                         throw new Exception(_('Unable to open directory ') . $dir); 
    334                 } 
    335  
    336                 // Cleanup PHP file extensions and sort the result array 
    337                 $contentTypes = str_ireplace('.php', '', $contentTypes); 
    338                 sort($contentTypes); 
    339  
    340                 // Check if caching has been enabled. 
    341                 if ($cache->isCachingEnabled) { 
    342                         // Save results into cache, because it wasn't saved into cache before. 
    343                         $cache->saveCachedData($contentTypes, "mixed"); 
    344                 } 
    345         } 
    346  
    347         return $contentTypes; 
    348     } 
    349     /** 
    350     * Check if this specific ContentType is usable (all dependencies 
    351     * met,etc. 
    352     * This method is meant to be overloaded by the different content classes 
    353     * @return true or flase 
    354     */ 
     298        // Init values 
     299        $contentTypes = array (); 
     300        $useCache = false; 
     301        $cachedData = null; 
     302 
     303        // Create new cache object with a lifetime of one week 
     304        $cache = new Cache("ContentClasses", "ClassFileCaches", 604800); 
     305 
     306        // Check if caching has been enabled. 
     307        if ($cache->isCachingEnabled) { 
     308            $cachedData = $cache->getCachedData("mixed"); 
     309 
     310            if ($cachedData) { 
     311                // Return cached data. 
     312                $useCache = true; 
     313                $contentTypes = $cachedData; 
     314            } 
     315        } 
     316 
     317        if (!$useCache) { 
     318            $dir = WIFIDOG_ABS_FILE_PATH . "classes/Content"; 
     319            $dirHandle = @ opendir($dir); 
     320 
     321            if ($dirHandle) { 
     322                // Loop over the directory 
     323                while (false !== ($subDir = readdir($dirHandle))) { 
     324                    // Loop through sub-directories of Content 
     325                    if ($subDir != '.' && $subDir != '..' && is_dir("{$dir}/{$subDir}")) { 
     326                        // Only add directories containing corresponding initial Content class 
     327                        if (is_file("{$dir}/{$subDir}/{$subDir}.php")) { 
     328                            $contentTypes[] = $subDir; 
     329                        } 
     330                    } 
     331                } 
     332 
     333                closedir($dirHandle); 
     334            } else { 
     335                throw new Exception(_('Unable to open directory ') . $dir); 
     336            } 
     337 
     338            // Cleanup PHP file extensions and sort the result array 
     339            $contentTypes = str_ireplace('.php', '', $contentTypes); 
     340            sort($contentTypes); 
     341 
     342            // Check if caching has been enabled. 
     343            if ($cache->isCachingEnabled) { 
     344                // Save results into cache, because it wasn't saved into cache before. 
     345                $cache->saveCachedData($contentTypes, "mixed"); 
     346            } 
     347        } 
     348 
     349        return $contentTypes; 
     350    } 
     351    /** 
     352     * Check if this specific ContentType is usable (all dependencies 
     353     * met,etc. 
     354     * This method is meant to be overloaded by the different content classes 
     355     * @return true or flase 
     356     */ 
    355357    public static function isContentTypeFunctional() { 
    356         return true; 
     358        return true; 
    357359    } 
    358360 
     
    363365     */ 
    364366    public static function isContentTypeAvailable($classname) { 
    365         if (false === array_search($classname, Content :: getAvailableContentTypes(), true)) { 
    366                 //throw new Exception(_("The following content type isn't valid: ").$contentType); 
    367                 return false; 
    368         } else { 
    369                 return $classname . isContentTypeFunctional(); 
    370         } 
     367        if (false === array_search($classname, Content :: getAvailableContentTypes(), true)) { 
     368            //throw new Exception(_("The following content type isn't valid: ").$contentType); 
     369            return false; 
     370        } else { 
     371            return call_user_func(array($classname, 'isContentTypeFunctional')); 
     372        } 
    371373    } 
    372374 
     
    378380     */ 
    379381    public static function isContentType($candidates, $classname) { 
    380         $retval = false; 
    381         if (false === is_array($candidates)) { 
    382                 throw new exception("classnames must be an array"); 
    383         } 
    384         $classname_reflector = new ReflectionClass($classname); 
    385  
    386         foreach ($candidates as $candidate) { 
    387                 $candidate_reflector = new ReflectionClass($candidate); 
    388                 //echo"classname: $classname, candidate: $candidate<br>"; 
    389                 if ($candidate == $classname || $classname_reflector->isSubclassOf($candidate_reflector)) { 
    390                         //As of PHP5.2, it would apear that isSubclass means a strict sublclass, so the first check was added. 
    391                         //The content meets the criteria 
    392                         //echo "TRUE<br>"; 
    393                         $retval = true; 
    394                         break; 
    395                 } 
    396         } 
    397         return $retval; 
    398     } 
    399  
    400     /** 
    401     * Check if this class is NOT any of the class or subclass of one of the content types given as parameter 
    402     * It's the opposite of isContentType() 
    403     *  
    404     * @param array $candidates The classnames to check 
    405     * @return true or flase 
    406     */ 
     382        $retval = false; 
     383        if (false === is_array($candidates)) { 
     384            throw new exception("classnames must be an array"); 
     385        } 
     386        $classname_reflector = new ReflectionClass($classname); 
     387 
     388        foreach ($candidates as $candidate) { 
     389            $candidate_reflector = new ReflectionClass($candidate); 
     390            //echo"classname: $classname, candidate: $candidate<br>"; 
     391            if ($candidate == $classname || $classname_reflector->isSubclassOf($candidate_reflector)) { 
     392                //As of PHP5.2, it would apear that isSubclass means a strict sublclass, so the first check was added. 
     393                //The content meets the criteria 
     394                //echo "TRUE<br>"; 
     395                $retval = true; 
     396                break; 
     397            } 
     398        } 
     399        return $retval; 
     400    } 
     401 
     402    /** 
     403     * Check if this class is NOT any of the class or subclass of one of the content types given as parameter 
     404     * It's the opposite of isContentType() 
     405     * 
     406     * @param array $candidates The classnames to check 
     407     * @return true or flase 
     408     */ 
    407409    public static function isNotContentType($candidates, $classname) { 
    408         return !self :: isContentType($candidates, $classname); 
     410        return !self :: isContentType($candidates, $classname); 
    409411    } 
    410412    /** 
     
    419421    public static function getAllContent($content_type = "") { 
    420422 
    421         $db = AbstractDb :: getObject(); 
    422  
    423         // Init values 
    424         $whereClause = ""; 
    425         $rows = null; 
    426         $objects = array (); 
    427  
    428         if (!empty ($content_type)) { 
    429                 $content_type = $db->escapeString($content_type); 
    430                 $whereClause = "WHERE content_type = '$content_type'"; 
    431         } 
    432  
    433         $db->execSql("SELECT content_id FROM content $whereClause", $rows, false); 
    434  
    435         if ($rows) { 
    436                 foreach ($rows as $row) { 
    437                         $objects[] = self :: getObject($row['content_id']); 
    438                 } 
    439         } 
    440  
    441         return $objects; 
     423        $db = AbstractDb :: getObject(); 
     424 
     425        // Init values 
     426        $whereClause = ""; 
     427        $rows = null; 
     428        $objects = array (); 
     429 
     430        if (!empty ($content_type)) { 
     431            $content_type = $db->escapeString($content_type); 
     432            $whereClause = "WHERE content_type = '$content_type'"; 
     433        } 
     434 
     435        $db->execSql("SELECT content_id FROM content $whereClause", $rows, false); 
     436 
     437        if ($rows) { 
     438            foreach ($rows as $row) { 
     439                $objects[] = self :: getObject($row['content_id']); 
     440            } 
     441        } 
     442 
     443        return $objects; 
     444    } 
     445 
     446    /** 
     447     * This method contains the interface to add an additional element to a 
     448     * content object.  (For example, a new string in a Langstring) 
     449     * It is called when getNewContentUI has only a single possible object type. 
     450     * It may also be called by the object getAdminUI to avoid code duplication. 
     451     * 
     452     * @param string $contentId      The id of the (possibly not yet created) content object. 
     453     * 
     454     * @param string $userData=null Array of contextual data optionally sent by displayAdminUI(), 
     455     *  and only understood by the class (or subclasses) where getNewUI() is defined. 
     456     *  The function must still function if none of it is present. 
     457     * 
     458     * This function understands: 
     459     *  $userData['contentTypeFilter'] 
     460     *  $userData['calledFromBaseClassNewUI'] 
     461     * @return HTML markup or false.  False means that this object does not support this interface. 
     462     */ 
     463    public static function getNewUI($contentId, $userData=null) { 
     464        $db = AbstractDb :: getObject(); 
     465        //echo "Content::getNewUI($contentId,$userData)<br/>\n"; 
     466 
     467        if(!empty($userData['calledFromBaseClassNewUI'])) { 
     468            //Break recursion if the subclass doesn't overload this method. 
     469            return false; 
     470        } 
     471 
     472        // Init values 
     473        $html = ""; 
     474        $getNewUIData = null; 
     475        $availableContentTypes = self :: getAvailableContentTypes(); 
     476 
     477        //echo "Content::getNewUI: userData";pretty_print_r($userData); 
     478        !empty($userData['contentTypeFilter'])?$contentTypeFilter=$userData['contentTypeFilter']:$contentTypeFilter=null; 
     479        //echo "Content::getNewUI: contentTypeFilter";pretty_print_r($contentTypeFilter); 
     480        if (!$contentTypeFilter) { 
     481            //echo "Get an empty filter"; 
     482            $contentTypeFilter = ContentTypeFilter :: getObject(array ()); 
     483        } 
     484        //pretty_print_r($content_type_filter); 
     485        $i = 0; 
     486        $tab = array (); 
     487        foreach ($availableContentTypes as $className) { 
     488            if ($contentTypeFilter->isAcceptableContentClass($className)) { 
     489                $tab[$i][0] = $className; 
     490                $tab[$i][1] = $className; 
     491                $i++; 
     492            } 
     493        } 
     494        $name = "get_new_ui_{$contentId}_content_type"; 
     495        if (count($tab) > 1) { 
     496            $label = _("Add new Content of type") . ": "; 
     497            $html .= "<div class='admin_element_data content_add'>"; 
     498            $html .= $label; 
     499            $html .= FormSelectGenerator :: generateFromArray($tab, 'TrivialLangstring', $name, null, false); 
     500            $html .= "</div>"; 
     501        } else 
     502        if (count($tab) == 1) { 
     503            $html .= '<input type="hidden" name="' . $name . '" value="' . $tab[0][0] . '">'; 
     504            $name = "get_new_ui_{$contentId}_content_type_is_unique"; 
     505            $html .= '<input type="hidden" name="' . $name . '" value="true">'; 
     506            $userData['calledFromBaseClassNewUI']=true; 
     507            $getNewUIData = call_user_func(array ($tab[0][0], 'getNewUI'), $contentId, $userData); 
     508 
     509        } else { 
     510            throw new Exception(_("No content type matches the filter.")); 
     511        } 
     512 
     513        if($getNewUIData != null) { 
     514            //If the single possible content type given by the filter defined an interface to directly create a new instance 
     515            $html .= $getNewUIData; 
     516        } 
     517        else { 
     518            if (count($tab) == 1) { 
     519                $value = sprintf(_("Add a %s"), $tab[0][1]); 
     520            } else { 
     521                $value = _("Add"); 
     522            } 
     523            $html .= "<div class='admin_element_tools'>"; 
     524            $name = "get_new_content_{$contentId}_add"; 
     525            $html .= '<input type="submit" class="submit" name="' . $name . '" value="' . $value . '">'; 
     526            $html .= "</div>"; 
     527        } 
     528        return $html; 
     529    } 
     530 
     531    /** 
     532     * 
     533     * 
     534     * @param string $contentId  The id of the (possibly not yet created) content object. 
     535     * 
     536     * @param string $checkOnly  If true, only check if there is data to be processed. 
     537     *  Will be used to decide if an object is to be created.  If there is 
     538     * processNewUI will typically be called again with $chechOnly=false 
     539     * 
     540     * @return true if there was data to be processed, false otherwise 
     541 
     542     */ 
     543    public static function processNewUI($contentId, $checkOnly=false, $userData=null) { 
     544        //echo "Content::processNewUI($contentId, $checkOnly)"; 
     545        $retval=false; 
     546        if(!empty($userData['calledFromBaseClassNewUI'])) { 
     547            //Break recursion if the subclass doesn't overload this method. 
     548            return false; 
     549        } 
     550        $processNewUIHasData = false; 
     551        $name = "get_new_ui_{$contentId}_content_type"; 
     552        $contentType = FormSelectGenerator :: getResult($name, null); 
     553 
     554        //Was there data to process 
     555        $name = "get_new_ui_{$contentId}_content_type_is_unique"; 
     556        if(!empty($_REQUEST[$name])){ 
     557            $userData['calledFromBaseClassNewUI']=true; 
     558            $processNewUIHasData = call_user_func(array ($contentType, 'processNewUI'), $contentId, true, $userData); 
     559        } 
     560        //Was add button clicked, or was there data in the new admin UI 
     561        $name = "get_new_content_{$contentId}_add"; 
     562        if ((!empty($_REQUEST[$name]) && $_REQUEST[$name] == true) || $processNewUIHasData) { 
     563            $retval=true; 
     564            if($checkOnly == false) { 
     565                $object = self::getObject($contentId); 
     566                $object->setContentType($contentType); 
     567                if($processNewUIHasData) { 
     568                //If there was data to processs, process it for real 
     569                call_user_func(array ($contentType, 'processNewUI'), $contentId, false); 
     570                } 
     571            } 
     572        } 
     573 
     574        return $retval; 
    442575    } 
    443576 
     
    454587     */ 
    455588    public static function getNewContentUI($user_prefix, $content_type_filter = null, $title = null) { 
    456  
    457         $db = AbstractDb :: getObject(); 
    458  
    459         // Init values 
    460         $html = ""; 
    461         $html .= "<fieldset class='admin_container Content'>\n"; 
    462         if (!empty ($title)) { 
    463                 $html .= "<legend>$title</legend>\n"; 
    464         } 
    465  
    466         $availableContentTypes = self :: getAvailableContentTypes(); 
    467  
    468         $name = "get_new_content_{$user_prefix}_content_type"; 
    469  
    470         if (!$content_type_filter) { 
    471                 //Get an empty filter 
    472                 $content_type_filter = ContentTypeFilter :: getObject(array ()); 
    473         } 
    474         //pretty_print_r($content_type_filter); 
    475         $i = 0; 
    476         $tab = array (); 
    477         foreach ($availableContentTypes as $className) { 
    478                 if ($content_type_filter->isAcceptableContentClass($className)) { 
    479                         $tab[$i][0] = $className; 
    480                         $tab[$i][1] = $className; 
    481                         $i++; 
    482                 } 
    483         } 
    484         if (count($tab) > 1) { 
    485                 $label = _("Add new Content of type") . ": "; 
    486                 $html .= "<div class='admin_element_data content_add'>"; 
    487                 $html .= $label; 
    488                 $html .= FormSelectGenerator :: generateFromArray($tab, 'TrivialLangstring', $name, null, false); 
    489                 $html .= "</div>"; 
    490         } else 
    491         if (count($tab) == 1) { 
    492                 $html .= '<input type="hidden" name="' . $name . '" value="' . $tab[0][0] . '">'; 
    493         } else { 
    494                 throw new Exception(_("No content type matches the filter.")); 
    495         } 
    496  
    497         $name = "get_new_content_{$user_prefix}_add"; 
    498  
    499         if (count($tab) == 1) { 
    500                 $value = sprintf(_("Add a %s"), $tab[0][1]); 
    501         } else { 
    502                 $value = _("Add"); 
    503         } 
    504  
    505         $html .= "<div class='admin_element_tools'>"; 
    506         $html .= '<input type="submit" class="submit" name="' . $name . '" value="' . $value . '">'; 
    507         $html .= "</div>"; 
    508         $html .= "</fieldset>\n"; 
    509         return $html; 
     589        //echo "Content::getNewContentUI()"; 
     590        // Init values 
     591        $html = ""; 
     592        $getNewUIData = null; 
     593        $html .= "<fieldset class='admin_container Content'>\n"; 
     594        if (!empty ($title)) { 
     595            $html .= "<legend>$title</legend>\n"; 
     596        } 
     597        $futureContentId = get_guid(); 
     598        $name = "get_new_content_{$user_prefix}_future_id"; 
     599        $html .= '<input type="hidden" name="' . $name . '" value="' . $futureContentId . '">'; 
     600        $userData['contentTypeFilter']=$content_type_filter; 
     601 
     602        $html .= Content::getNewUI($futureContentId, $userData); 
     603        $html .= "</fieldset>\n"; 
     604        return $html; 
    510605    } 
    511606 
     
    521616     * 
    522617     * @return object The Content object, or null if the user didn't create one 
    523      
    524      */ 
    525     public static function processNewContentUI($user_prefix, $associate_existing_content = false) { 
    526         // Init values 
    527         $object = null; 
    528  
    529         if ($associate_existing_content == true) { 
    530                 $name = "{$user_prefix}_add"; 
    531         } else { 
    532                 $name = "get_new_content_{$user_prefix}_add"; 
    533         } 
    534  
    535         if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true) { 
    536                 if ($associate_existing_content == true) { 
    537                         $name = "{$user_prefix}"; 
    538                 } else { 
    539                         $name = "get_new_content_{$user_prefix}_content_type"; 
    540                 } 
    541  
    542                 /* 
    543                  * The result can be either a content type or a content ID 
    544                  * depending on the form (associate_existing_content or NOT) 
    545                  */ 
    546                 $contentUiResult = FormSelectGenerator :: getResult($name, null); 
    547  
    548                 if ($associate_existing_content == true) { 
    549                         $object = self :: getObject($contentUiResult); 
    550                 } else { 
    551                         $object = self :: createNewObject($contentUiResult); 
    552                 } 
    553         } 
    554  
    555         return $object; 
     618 
     619     */ 
     620    public static function processNewContentUI($user_prefix) { 
     621        //echo "Content::processNewContentUI()"; 
     622        // Init values 
     623        $object = null; 
     624        $name = "get_new_content_{$user_prefix}_future_id"; 
     625        $futureContentId = $_REQUEST[$name]; 
     626 
     627        if(Content::processNewUI($futureContentId, true)) { 
     628            self :: createNewObject('Content', $futureContentId);//The true content type will be set by processNewUI() 
     629            //If there was data to processs, process it for real 
     630            Content::processNewUI($futureContentId, false); 
     631            $object = self :: getObject($futureContentId);//Content type has changed... 
     632        } 
     633        //pretty_print_r($object); 
     634        return $object; 
     635    } 
     636    /** 
     637     * Get the created content object, IF one was created OR get existing 
     638     * content (depending on what the user clicked) 
     639     * 
     640     * @param string $user_prefix                A identifier provided by the 
     641     *                                           programmer to recognise it's 
     642     *                                           generated form 
     643     * @return object The Content object, or null if the user didn't create one 
     644 
     645     */ 
     646    public static function processSelectExistingContentUI($user_prefix) { 
     647        // Init values 
     648        $object = null; 
     649        $name = "{$user_prefix}"; 
     650        /* 
     651         * The result is a content ID 
     652         */ 
     653        $contentUiResult = FormSelectGenerator :: getResult($name, null); 
     654        $name = "{$user_prefix}_add"; 
     655 
     656        //Was add button clicked, or whare there data in the new admin UI 
     657        if ((!empty($_REQUEST[$name]) && $_REQUEST[$name] == true)) { 
     658            $object = self :: getObject($contentUiResult); 
     659        } 
     660        return $object; 
    556661    } 
    557662 
     
    569674     * @param string $default_display_area 
    570675     * @return string HTML markup 
    571      
     676 
    572677     */ 
    573678    public static function getLinkedContentUI($user_prefix, $link_table, $link_table_obj_key_col, $link_table_obj_key, $default_display_page = 'portal', $default_display_area = 'main_area_middle') { 
    574679 
    575         $db = AbstractDb :: getObject(); 
    576  
    577         // Init values 
    578         $html = ""; 
    579  
    580         $link_table = $db->escapeString($link_table); 
    581         $link_table_obj_key_col = $db->escapeString($link_table_obj_key_col); 
    582         $link_table_obj_key = $db->escapeString($link_table_obj_key); 
    583  
    584         /* Content already linked */ 
    585         $current_content_sql = "SELECT * FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key' ORDER BY display_page, display_area, display_order, subscribe_timestamp DESC"; 
    586         $rows = null; 
    587         $db->execSql($current_content_sql, $rows, false); 
    588  
    589         $html .= "<table class='content_management_tools'>\n"; 
    590         $html .= "<th>" . _('Display page') . '</th><th>' . _('Area') . '</th><th>' . _('Order') . '</th><th>' . _('Content') . '</th><th>' . _('Actions') . '</th>' . "\n"; 
    591         if ($rows) 
    592         foreach ($rows as $row) { 
    593                 $content = self :: getObject($row['content_id']); 
    594                 $html .= "<tr class='already_linked_content'>\n"; 
    595                 /* Display page */ 
    596                 $name = "{$user_prefix}_" . $content->GetId() . "_display_page"; 
    597                 $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_pages', 'display_page', 'display_page', $row['display_page'], $name, null) . "</td>\n"; 
    598                 $name = "{$user_prefix}_" . $content->GetId() . "_display_area"; 
    599                 $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_areas', 'display_area', 'display_area', $row['display_area'], $name, null) . "</td>\n"; 
    600                 $name = "{$user_prefix}_" . $content->GetId() . "_display_order"; 
    601                 $html .= "<td><input type='text' name='$name' value='{$row['display_order']}' size=2 class='linked_content_order'></td>\n"; 
    602                 $html .= "<td>\n"; 
    603                 $html .= $content->getListUI(); 
    604                 $html .= "</td>\n"; 
    605                 $html .= "<td>\n"; 
    606                 $name = "{$user_prefix}_" . $content->GetId() . "_edit"; 
    607                 $html .= "<input type='button' class='submit' name='$name' value='" . _("Edit") . "' onClick='window.open(\"" . GENERIC_OBJECT_ADMIN_ABS_HREF . "?object_class=Content&action=edit&object_id=" . $content->GetId() . "\");'>\n"; 
    608                 $name = "{$user_prefix}_" . $content->GetId() . "_erase"; 
    609                 $html .= "<input type='submit' class='submit' name='$name' value='" . _("Remove") . "'>"; 
    610                 $html .= "</td>\n"; 
    611                 $html .= "</tr>\n"; 
    612         } 
    613  
    614         /* Add existing content */ 
    615         $html .= "<tr class='add_existing_content'>\n"; 
    616         $name = "{$user_prefix}_new_existing_display_page"; 
    617         $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_pages', 'display_page', 'display_page', $default_display_page, $name, null) . "</td>\n"; 
    618         $name = "{$user_prefix}_new_existing_display_area"; 
    619         $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_areas', 'display_area', 'display_area', $default_display_area, $name, null) . "</td>\n"; 
    620         $name = "{$user_prefix}_new_existing_display_order"; 
    621         $html .= "<td><input type='text' name='$name' value='1' size=2 class='linked_content_order'></td>\n"; 
    622         $html .= "<td colspan=2>\n"; 
    623         $name = "{$user_prefix}_new_existing"; 
    624         $contentSelector = Content :: getSelectExistingContentUI($name, "AND is_persistent=TRUE AND content_id NOT IN (SELECT content_id FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key')"); 
    625         $html .= $contentSelector; 
    626         $html .= "</td>\n"; 
    627         $html .= "</tr>\n"; 
    628  
    629         /* Add new content */ 
    630         $html .= "<tr class='add_new_content'>\n"; 
    631         $name = "{$user_prefix}_new_display_page"; 
    632         $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_pages', 'display_page', 'display_page', $default_display_page, $name, null) . "</td>\n"; 
    633         $name = "{$user_prefix}_new_display_area"; 
    634         $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_areas', 'display_area', 'display_area', $default_display_area, $name, null) . "</td>\n"; 
    635         $name = "{$user_prefix}_new_display_order"; 
    636         $html .= "<td><input type='text' name='$name' value='1' size=2 class='linked_content_order'></td>\n"; 
    637         $html .= "<td colspan=2>\n"; 
    638         $name = "{$user_prefix}_new"; 
    639         $html .= self :: getNewContentUI($name, $content_type = null); 
    640         $html .= "</td>\n"; 
    641         $html .= "</table>\n"; 
    642         return $html; 
     680        $db = AbstractDb :: getObject(); 
     681 
     682        // Init values 
     683        $html = ""; 
     684 
     685        $link_table = $db->escapeString($link_table); 
     686        $link_table_obj_key_col = $db->escapeString($link_table_obj_key_col); 
     687        $link_table_obj_key = $db->escapeString($link_table_obj_key); 
     688 
     689        /* Content already linked */ 
     690        $current_content_sql = "SELECT * FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key' ORDER BY display_page, display_area, display_order, subscribe_timestamp DESC"; 
     691        $rows = null; 
     692        $db->execSql($current_content_sql, $rows, false); 
     693 
     694        $html .= "<table class='content_management_tools'>\n"; 
     695        $html .= "<th>" . _('Display page') . '</th><th>' . _('Area') . '</th><th>' . _('Order') . '</th><th>' . _('Content') . '</th><th>' . _('Actions') . '</th>' . "\n"; 
     696        if ($rows) 
     697        foreach ($rows as $row) { 
     698            $content = self :: getObject($row['content_id']); 
     699            $html .= "<tr class='already_linked_content'>\n"; 
     700            /* Display page */ 
     701            $name = "{$user_prefix}_" . $content->GetId() . "_display_page"; 
     702            $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_pages', 'display_page', 'display_page', $row['display_page'], $name, null) . "</td>\n"; 
     703            $name = "{$user_prefix}_" . $content->GetId() . "_display_area"; 
     704            $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_areas', 'display_area', 'display_area', $row['display_area'], $name, null) . "</td>\n"; 
     705            $name = "{$user_prefix}_" . $content->GetId() . "_display_order"; 
     706            $html .= "<td><input type='text' name='$name' value='{$row['display_order']}' size=2 class='linked_content_order'></td>\n"; 
     707            $html .= "<td>\n"; 
     708            $html .= $content->getListUI(); 
     709            $html .= "</td>\n"; 
     710            $html .= "<td>\n"; 
     711            $name = "{$user_prefix}_" . $content->GetId() . "_edit"; 
     712            $html .= "<input type='button' class='submit' name='$name' value='" . _("Edit") . "' onClick='window.open(\"" . GENERIC_OBJECT_ADMIN_ABS_HREF . "?object_class=Content&action=edit&object_id=" . $content->GetId() . "\");'>\n"; 
     713            $name = "{$user_prefix}_" . $content->GetId() . "_erase"; 
     714            $html .= "<input type='submit' class='submit' name='$name' value='" . _("Remove") . "'>"; 
     715            $html .= "</td>\n"; 
     716            $html .= "</tr>\n"; 
     717        } 
     718 
     719        /* Add existing content */ 
     720        $html .= "<tr class='add_existing_content'>\n"; 
     721        $name = "{$user_prefix}_new_existing_display_page"; 
     722        $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_pages', 'display_page', 'display_page', $default_display_page, $name, null) . "</td>\n"; 
     723        $name = "{$user_prefix}_new_existing_display_area"; 
     724        $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_areas', 'display_area', 'display_area', $default_display_area, $name, null) . "</td>\n"; 
     725        $name = "{$user_prefix}_new_existing_display_order"; 
     726        $html .= "<td><input type='text' name='$name' value='1' size=2 class='linked_content_order'></td>\n"; 
     727        $html .= "<td colspan=2>\n"; 
     728        $name = "{$user_prefix}_new_existing"; 
     729        $contentSelector = Content :: getSelectExistingContentUI($name, "AND is_persistent=TRUE AND content_id NOT IN (SELECT content_id FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key')"); 
     730        $html .= $contentSelector; 
     731        $html .= "</td>\n"; 
     732        $html .= "</tr>\n"; 
     733 
     734        /* Add new content */ 
     735        $html .= "<tr class='add_new_content'>\n"; 
     736        $name = "{$user_prefix}_new_display_page"; 
     737        $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_pages', 'display_page', 'display_page', $default_display_page, $name, null) . "</td>\n"; 
     738        $name = "{$user_prefix}_new_display_area"; 
     739        $html .= "<td>" . FormSelectGenerator :: generateFromTable('content_available_display_areas', 'display_area', 'display_area', $default_display_area, $name, null) . "</td>\n"; 
     740        $name = "{$user_prefix}_new_display_order"; 
     741        $html .= "<td><input type='text' name='$name' value='1' size=2 class='linked_content_order'></td>\n"; 
     742        $html .= "<td colspan=2>\n"; 
     743        $name = "{$user_prefix}_new"; 
     744        $html .= self :: getNewContentUI($name, $content_type = null); 
     745        $html .= "</td>\n"; 
     746        $html .= "</table>\n"; 
     747        return $html; 
    643748    } 
    644749 
     
    648753     * @param $associate_existing_content boolean if true allows to get existing 
    649754     * object 
    650      * @return the Content object, or null if the user didn't greate one 
     755     * @return the Content object, or null if the user didn't create one 
    651756     */ 
    652757    static function processLinkedContentUI($user_prefix, $link_table, $link_table_obj_key_col, $link_table_obj_key) { 
    653         $db = AbstractDb :: getObject(); 
    654         $link_table = $db->escapeString($link_table); 
    655         $link_table_obj_key_col = $db->escapeString($link_table_obj_key_col); 
    656         $link_table_obj_key = $db->escapeString($link_table_obj_key); 
    657         /* Content already linked */ 
    658         $current_content_sql = "SELECT * FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key'"; 
    659         $rows = null; 
    660         $db->execSql($current_content_sql, $rows, false); 
    661         if ($rows) 
    662         foreach ($rows as $row) { 
    663                 $content = Content :: getObject($row['content_id']); 
    664                 $content_id = $db->escapeString($content->getId()); 
    665                 $sql = null; 
    666                 $name = "{$user_prefix}_" . $content->GetId() . "_erase"; 
    667                 if (!empty ($_REQUEST[$name])) { 
    668                         $sql .= "DELETE FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id';\n"; 
    669  
    670                 } else { 
    671                         /* Display page */ 
    672                         $name = "{$user_prefix}_" . $content->GetId() . "_display_page"; 
    673                         $new_display_page = FormSelectGenerator :: getResult($name, null); 
    674                         if ($new_display_page != $row['display_page']) { 
    675                                 $new_display_page = $db->escapeString($new_display_page); 
    676                                 $sql .= "UPDATE $link_table SET display_page='$new_display_page' WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id';\n"; 
    677  
    678                         } 
    679                         /* Display area */ 
    680                         $name = "{$user_prefix}_" . $content->GetId() . "_display_area"; 
    681                         $new_display_area = FormSelectGenerator :: getResult($name, null); 
    682                         if ($new_display_area != $row['display_area']) { 
    683                                 $new_display_area = $db->escapeString($new_display_area); 
    684                                 $sql .= "UPDATE $link_table SET display_area='$new_display_area' WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id';\n"; 
    685                         } 
    686                         /* Display order */ 
    687                         $name = "{$user_prefix}_" . $content->GetId() . "_display_order"; 
    688                         if ($_REQUEST[$name] != $row['display_order']) { 
    689                                 $new_display_order = $db->escapeString($_REQUEST[$name]); 
    690                                 $sql .= "UPDATE $link_table SET display_order='$new_display_order' WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id';\n"; 
    691                         } 
    692                 } 
    693                 if ($sql) { 
    694                         $db->execSqlUpdate($sql, false); 
    695                 } 
    696         } 
    697         /* Add existing content */ 
    698         $name = "{$user_prefix}_new_existing_add"; 
    699         if (!empty ($_REQUEST[$name])) { 
    700                 $name = "{$user_prefix}_new_existing"; 
    701                 $content = Content :: processSelectContentUI($name); 
    702                 if ($content) { 
    703                         /* Display page */ 
    704                         $name = "{$user_prefix}_new_existing_display_page"; 
    705                         $new_display_page = $db->escapeString(FormSelectGenerator :: getResult($name, null)); 
    706                         /* Display area */ 
    707                         $name = "{$user_prefix}_new_existing_display_area"; 
    708                         $new_display_area = $db->escapeString(FormSelectGenerator :: getResult($name, null)); 
    709                         /* Display order */ 
    710                         $name = "{$user_prefix}_new_existing_display_order"; 
    711                         $new_display_order = $db->escapeString($_REQUEST[$name]); 
    712                         $content_id = $db->escapeString($content->getId()); 
    713                         $sql = "INSERT INTO $link_table (content_id, $link_table_obj_key_col, display_page, display_area, display_order) VALUES ('$content_id', '$link_table_obj_key', '$new_display_page', '$new_display_area', $new_display_order);\n"; 
    714                         $db->execSqlUpdate($sql, false); 
    715                 } 
    716         } 
    717         /* Add new content */ 
    718         $name = "{$user_prefix}_new"; 
    719         $content = self :: processNewContentUI($name); 
    720         if ($content) { 
    721                 /* Display page */ 
    722                 $name = "{$user_prefix}_new_display_page"; 
    723                 $new_display_page = $db->escapeString(FormSelectGenerator :: getResult($name, null)); 
    724                 /* Display area */ 
    725                 $name = "{$user_prefix}_new_display_area"; 
    726                 $new_display_area = $db->escapeString(FormSelectGenerator :: getResult($name, null)); 
    727                 /* Display order */ 
    728                 $name = "{$user_prefix}_new_display_order"; 
    729                 $new_display_order = $db->escapeString($_REQUEST[$name]); 
    730                 $content_id = $db->escapeString($content->getId()); 
    731                 $sql = "INSERT INTO $link_table (content_id, $link_table_obj_key_col, display_page, display_area, display_order) VALUES ('$content_id', '$link_table_obj_key', '$new_display_page', '$new_display_area', $new_display_order);\n"; 
    732                 $db->execSqlUpdate($sql, false); 
    733         } 
     758        $db = AbstractDb :: getObject(); 
     759        $link_table = $db->escapeString($link_table); 
     760        $link_table_obj_key_col = $db->escapeString($link_table_obj_key_col); 
     761        $link_table_obj_key = $db->escapeString($link_table_obj_key); 
     762        /* Content already linked */ 
     763        $current_content_sql = "SELECT * FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key'"; 
     764        $rows = null; 
     765        $db->execSql($current_content_sql, $rows, false); 
     766        if ($rows) 
     767        foreach ($rows as $row) { 
     768            $content = Content :: getObject($row['content_id']); 
     769            $content_id = $db->escapeString($content->getId()); 
     770            $sql = null; 
     771            $name = "{$user_prefix}_" . $content->GetId() . "_erase"; 
     772            if (!empty ($_REQUEST[$name])) { 
     773                $sql .= "DELETE FROM $link_table WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id';\n"; 
     774 
     775            } else { 
     776                /* Display page */ 
     777                $name = "{$user_prefix}_" . $content->GetId() . "_display_page"; 
     778                $new_display_page = FormSelectGenerator :: getResult($name, null); 
     779                if ($new_display_page != $row['display_page']) { 
     780                    $new_display_page = $db->escapeString($new_display_page); 
     781                    $sql .= "UPDATE $link_table SET display_page='$new_display_page' WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id';\n"; 
     782 
     783                } 
     784                /* Display area */ 
     785                $name = "{$user_prefix}_" . $content->GetId() . "_display_area"; 
     786                $new_display_area = FormSelectGenerator :: getResult($name, null); 
     787                if ($new_display_area != $row['display_area']) { 
     788                    $new_display_area = $db->escapeString($new_display_area); 
     789                    $sql .= "UPDATE $link_table SET display_area='$new_display_area' WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id';\n"; 
     790                } 
     791                /* Display order */ 
     792                $name = "{$user_prefix}_" . $content->GetId() . "_display_order"; 
     793                if ($_REQUEST[$name] != $row['display_order']) { 
     794                    $new_display_order = $db->escapeString($_REQUEST[$name]); 
     795                    $sql .= "UPDATE $link_table SET display_order='$new_display_order' WHERE $link_table_obj_key_col='$link_table_obj_key' AND content_id = '$content_id';\n"; 
     796                } 
     797            } 
     798            if ($sql) { 
     799                $db->execSqlUpdate($sql, false); 
     800            } 
     801        } 
     802        /* Add existing content */ 
     803        $name = "{$user_prefix}_new_existing_add"; 
     804        if (!empty ($_REQUEST[$name])) { 
     805            $name = "{$user_prefix}_new_existing"; 
     806            $content = Content :: processSelectContentUI($name); 
     807            if ($content) { 
     808                /* Display page */ 
     809                $name = "{$user_prefix}_new_existing_display_page"; 
     810                $new_display_page = $db->escapeString(FormSelectGenerator :: getResult($name, null)); 
     811                /* Display area */ 
     812                $name = "{$user_prefix}_new_existing_display_area"; 
     813                $new_display_area = $db->escapeString(FormSelectGenerator :: getResult($name, null)); 
     814                /* Display order */ 
     815                $name = "{$user_prefix}_new_existing_display_order"; 
     816                $new_display_order = $db->escapeString($_REQUEST[$name]); 
     817                $content_id = $db->escapeString($content->getId()); 
     818                $sql = "INSERT INTO $link_table (content_id, $link_table_obj_key_col, display_page, display_area, display_order) VALUES ('$content_id', '$link_table_obj_key', '$new_display_page', '$new_display_area', $new_display_order);\n"; 
     819                $db->execSqlUpdate($sql, false); 
     820            } 
     821        } 
     822        /* Add new content */ 
     823        $name = "{$user_prefix}_new"; 
     824        $content = self :: processNewContentUI($name); 
     825        if ($content) { 
     826            /* Display page */ 
     827            $name = "{$user_prefix}_new_display_page"; 
     828            $new_display_page = $db->escapeString(FormSelectGenerator :: getResult($name, null)); 
     829            /* Display area */ 
     830            $name = "{$user_prefix}_new_display_area"; 
     831            $new_display_area = $db->escapeString(FormSelectGenerator :: getResult($name, null)); 
     832            /* Display order */ 
     833            $name = "{$user_prefix}_new_display_order"; 
     834            $new_display_order = $db->escapeString($_REQUEST[$name]); 
     835            $content_id = $db->escapeString($content->getId()); 
     836            $sql = "INSERT INTO $link_table (content_id, $link_table_obj_key_col, display_page, display_area, display_order) VALUES ('$content_id', '$link_table_obj_key', '$new_display_page', '$new_display_area', $new_display_order);\n"; 
     837            $db->execSqlUpdate($sql, false); 
     838        } 
    734839    } 
    735840 
     
    754859     * 
    755860     * @return string HTML markup 
    756      
     861 
    757862     */ 
    758863    public static function getSelectExistingContentUI($user_prefix, $sql_additional_where = null, $content_type_filter = null, $order = "creation_timestamp DESC", $type_interface = "select") { 
    759864 
    760         $db = AbstractDb :: getObject(); 
    761  
    762         // Init values 
    763         $html = ''; 
    764         $retVal = array (); 
    765         $contentRows = null; 
    766         if ($content_type_filter == null) { 
    767                 //Get an empty filter 
    768                 $content_type_filter = ContentTypeFilter :: getObject(array ()); 
    769         } 
    770  
    771         if (!User :: getCurrentUser()) { 
    772                 throw new Exception(_('Access denied!')); 
    773         } 
    774  
    775         if ($type_interface != "table") { 
    776                 $html .= "<fieldset class='admin_container Content'>\n"; 
    777  
    778                 if (!empty ($title)) { 
    779                         $html .= "<legend>$title</legend>\n"; 
    780                 } 
    781  
    782                 $html .= _("Select from reusable content library") . ": "; 
    783         } 
    784  
    785         $name = "{$user_prefix}"; 
    786  
    787         $sql = "SELECT * FROM content WHERE 1=1 $sql_additional_where ORDER BY $order"; 
    788  
    789         $db->execSql($sql, $contentRows, false); 
    790  
    791         if ($contentRows != null) { 
    792                 $i = 0; 
    793  
    794                 if ($type_interface == "table") { 
    795                         $html .= "<table class='content_admin'>\n"; 
    796                         $html .= "<tr><th>" . _("Title") . "</th><th>" . _("Content type") . "</th><th>" . _("Description") . "</th><th></th></tr>\n"; 
    797                 } 
    798  
    799                 foreach ($contentRows as $contentRow) { 
    800                         $content = Content :: getObject($contentRow['content_id']); 
    801                         //echo get_class($content)." ".$contentRow['content_id']."<br>"; 
    802                         if ($content && $content_type_filter->isAcceptableContentClass(get_class($content))) { 
    803                                 if ($type_interface != "table") { 
    804                                         $tab[$i][0] = $content->getId(); 
    805                                         $tab[$i][1] = $content->__toString() . " (" . get_class($content) . ")"; 
    806                                         $i++; 
    807                                 } else { 
    808                                         if (!empty ($contentRow['title'])) { 
    809                                                 $title = Content :: getObject($contentRow['title']); 
    810                                                 $titleUI = $title->__toString(); 
    811                                         } else { 
    812                                                 $titleUI = ""; 
    813                                         } 
    814  
    815                                         if (!empty ($contentRow['description'])) { 
    816                                                 $description = Content :: getObject($contentRow['description']); 
    817                                                 $descriptionUI = $description->__toString(); 
    818                                         } else { 
    819                                                 $descriptionUI = ""; 
    820                                         } 
    821  
    822                                         $href = GENERIC_OBJECT_ADMIN_ABS_HREF . "?object_id={$contentRow['content_id']}&object_class=Content&action=edit"; 
    823                                         $html .= "<tr><td>$titleUI</td><td><a href='$href'>{$contentRow['content_type']}</a></td><td>$descriptionUI</td>\n"; 
    824  
    825                                         $href = GENERIC_OBJECT_ADMIN_ABS_HREF . "?object_id={$contentRow['content_id']}&object_class=Content&action=delete"; 
    826                                         $html .= "<td><a href='$href'>" . _("Delete") . "</a></td>"; 
    827  
    828                                         $html .= "</tr>\n"; 
    829                                 } 
    830                         } 
    831                 } 
    832  
    833                 if ($type_interface != "table") { 
    834                         if (isset ($tab)) { 
    835                                 $html .= FormSelectGenerator :: generateFromArray($tab, null, $name, null, false, null, null, 40); 
    836                                 //DEBUG!! get_existing_content_ 
    837                                 $name = "{$user_prefix}_add"; 
    838                                 $value = _("Add"); 
    839                                 $html .= "<div class='admin_element_tools'>"; 
    840                                 $html .= '<input type="submit" class="submit" name="' . $name . '" value="' . $value . '">'; 
    841                                 $html .= "</div>"; 
    842                         } else { 
    843                                 $html .= "<div class='warningmsg'>" . _("Sorry, no elligible content available in the database") . "</div>\n"; 
    844                         } 
    845                         $html .= "</fieldset>\n"; 
    846                 } else { 
    847                         $html .= "</table>\n"; 
    848                 } 
    849         } else { 
    850                 $html .= "<div class='warningmsg'>" . _("Sorry, no elligible content available in the database") . "</div>\n"; 
    851         } 
    852  
    853         return $html; 
     865        $db = AbstractDb :: getObject(); 
     866 
     867        // Init values 
     868        $html = ''; 
     869        $retVal = array (); 
     870        $contentRows = null; 
     871        if ($content_type_filter == null) { 
     872            //Get an empty filter 
     873            $content_type_filter = ContentTypeFilter :: getObject(array ()); 
     874        } 
     875 
     876        if (!User :: getCurrentUser()) { 
     877            throw new Exception(_('Access denied!')); 
     878        } 
     879 
     880        if ($type_interface != "table") { 
     881            $html .= "<fieldset class='admin_container Content'>\n"; 
     882 
     883            if (!empty ($title)) { 
     884                $html .= "<legend>$title</legend>\n"; 
     885            } 
     886 
     887            $html .= _("Select from reusable content library") . ": "; 
     888        } 
     889 
     890        $name = "{$user_prefix}"; 
     891 
     892        $sql = "SELECT * FROM content WHERE 1=1 $sql_additional_where ORDER BY $order"; 
     893 
     894        $db->execSql($sql, $contentRows, false); 
     895 
     896        if ($contentRows != null) { 
     897            $i = 0; 
     898 
     899            if ($type_interface == "table") { 
     900                $html .= "<table class='content_admin'>\n"; 
     901                $html .= "<tr><th>" . _("Title") . "</th><th>" . _("Content type") . "</th><th>" . _("Description") . "</th><th></th></tr>\n"; 
     902            } 
     903 
     904            foreach ($contentRows as $contentRow) { 
     905                $content = Content :: getObject($contentRow['content_id']); 
     906                //echo get_class($content)." ".$contentRow['content_id']."<br>"; 
     907                if ($content && $content_type_filter->isAcceptableContentClass(get_class($content))) { 
     908                    if ($type_interface != "table") { 
     909                        $tab[$i][0] = $content->getId(); 
     910                        $tab[$i][1] = $content->__toString() . " (" . get_class($content) . ")"; 
     911                        $i++; 
     912                    } else { 
     913                        if (!empty ($contentRow['title'])) { 
     914                            $title = Content :: getObject($contentRow['title']); 
     915                            $titleUI = $title->__toString(); 
     916                        } else { 
     917                            $titleUI = ""; 
     918                        } 
     919 
     920                        if (!empty ($contentRow['description'])) { 
     921                            $description = Content :: getObject($contentRow['description']); 
     922                            $descriptionUI = $description->__toString(); 
     923                        } else { 
     924                            $descriptionUI = ""; 
     925                        } 
     926 
     927                        $href = GENERIC_OBJECT_ADMIN_ABS_HREF . "?object_id={$contentRow['content_id']}&object_class=Content&action=edit"; 
     928                        $html .= "<tr><td>$titleUI</td><td><a href='$href'>{$contentRow['content_type']}</a></td><td>$descriptionUI</td>\n"; 
     929 
     930                        $href = GENERIC_OBJECT_ADMIN_ABS_HREF . "?object_id={$contentRow['content_id']}&object_class=Content&action=delete"; 
     931                        $html .= "<td><a href='$href'>" . _("Delete") . "</a></td>"; 
     932 
     933                        $html .= "</tr>\n"; 
     934                    } 
     935                } 
     936            } 
     937 
     938            if ($type_interface != "table") { 
     939                if (isset ($tab)) { 
     940                    $html .= FormSelectGenerator :: generateFromArray($tab, null, $name, null, false, null, null, 40); 
     941                    //DEBUG!! get_existing_content_ 
     942                    $name = "{$user_prefix}_add"; 
     943                    $value = _("Add"); 
     944                    $html .= "<div class='admin_element_tools'>"; 
     945                    $html .= '<input type="submit" class="submit" name="' . $name . '" value="' . $value . '">'; 
     946                    $html .= "</div>"; 
     947                } else { 
     948                    $html .= "<div class='warningmsg'>" . _("Sorry, no elligible content available in the database") . "</div>\n"; 
     949                } 
     950                $html .= "</fieldset>\n"; 
     951            } else { 
     952                $html .= "</table>\n"; 
     953            } 
     954        } else { 
     955            $html .= "<div class='warningmsg'>" . _("Sorry, no elligible content available in the database") . "</div>\n"; 
     956        } 
     957 
     958        return $html; 
    854959    } 
    855960 
     
    859964     */ 
    860965    static function processSelectContentUI($user_prefix) { 
    861         $name = "{$user_prefix}"; 
    862         if (!empty ($_REQUEST[$name])) 
    863                 return Content :: getObject($_REQUEST[$name]); 
    864         else 
    865                 return null; 
     966        $name = "{$user_prefix}"; 
     967        if (!empty ($_REQUEST[$name])) 
     968        return Content :: getObject($_REQUEST[$name]); 
     969        else 
     970        return null; 
    866971    } 
    867972 
     
    869974     * @return an array of class names */ 
    870975    public function getObjectType() { 
    871         return $this->content_type; 
    872     } 
    873  
    874     /** 
    875      * Key-value pairs are an easy way to extend Content types  
     976        return $this->content_type; 
     977    } 
     978 
     979    /** 
     980     * Key-value pairs are an easy way to extend Content types 
    876981     * without having to needlessly modify the wifidog schema. 
    877      * They are appropriate when  you content subtype needs to  
     982     * They are appropriate when  you content subtype needs to 
    878983     * store simple type that fit the key-value model.  (that is 
    879      * onke key->single value for a given Content instance.   
     984     * onke key->single value for a given Content instance. 
    880985     * @throws exception if key cannot be found 
    881      * @param $key The key whose value is to be retrieved.Keys  
     986     * @param $key The key whose value is to be retrieved.Keys 
    882987     * must also be unique fo the entire object inheritance tree. 
    883988     * Because of this, key naming convention is as follows: 
    884989     * ClassName_key_name 
    885      * @return The value of the pair.  To check if a key exists,  
     990     * @return The value of the pair.  To check if a key exists, 
    886991     * check === null (and not == null) 
    887      
     992 
    888993     */ 
    889994    protected function getKVP($key) { 
    890         if (isset ($this->kvps[$key])) { 
    891                 return $this->kvps[$key]; 
    892         } else { 
    893                 //throw new exception (sprintf(_("Key %s does not exist"), $key)); 
    894                 return null; 
    895         } 
    896     } 
    897  
    898     /** 
    899      * Key-value pairs are an easy way to extend Content types  
     995        if (isset ($this->kvps[$key])) { 
     996            return $this->kvps[$key]; 
     997        } else { 
     998            //throw new exception (sprintf(_("Key %s does not exist"), $key)); 
     999            return null; 
     1000        } 
     1001    } 
     1002 
     1003    /** 
     1004     * Key-value pairs are an easy way to extend Content types 
    9001005     * without having to needlessly modify the wifidog schema. 
    901      * They are appropriate when  you content subtype needs to  
     1006     * They are appropriate when  you content subtype needs to 
    9021007     * store simple type that fit the key-value model.  (that is 
    9031008     * onke key->single value for a given Content instance. 
    9041009     * @throws exception if key cannot be found 
    905      * @param $key The key whose value is to be retrieved.  Keys  
     1010     * @param $key The key whose value is to be retrieved.  Keys 
    9061011     * must also be unique fo the entire object inheritance tree. 
    9071012     * Because of this, key naming convention is as follows: 
     
    9111016     */ 
    9121017    protected function setKVP($key, $value) { 
    913         $retval = true; 
    914         $db = AbstractDb :: getObject(); 
    915         $value_sql = $db->escapeString($value); 
    916         $key_sql = $db->escapeString($key); 
    917         //pretty_print_r($this->kvps); 
    918         if($key==null) { 
    919                 throw new Exception (_("KVP key cannot be null")); 
    920         } else if($value===null) { 
    921                 //Delete the KVP 
    922                 $retval = $db->execSqlUpdate("DELETE FROM content_key_value_pairs WHERE content_id='" . $this->getId() . "' AND key='$key_sql'", false); 
    923                 if(isset ($this->kvps[$key])) { 
    924                         unset ($this->kvps[$key]); 
    925                 } 
    926         } else if (!isset ($this->kvps[$key])) { 
    927                 //This is a new key 
    928                 $retval = $db->execSqlUpdate("INSERT INTO content_key_value_pairs (content_id, key, value) VALUES ('" . $this->getId() . "', '$key_sql', '$value_sql')", false); 
    929         } else 
    930         if ($this->kvps[$key] != $value) { 
    931                 //This is an existing key, and it's been modified 
    932                 $retval = $db->execSqlUpdate("UPDATE content_key_value_pairs SET value ='" . $value_sql . "' WHERE content_id='" . $this->getId() . "' AND key='$key_sql'", false); 
    933         } 
    934         $this->refresh(); 
    935         return $retval; 
     1018        $retval = true; 
     1019        $db = AbstractDb :: getObject(); 
     1020        $value_sql = $db->escapeString($value); 
     1021        $key_sql = $db->escapeString($key); 
     1022        //pretty_print_r($this->kvps); 
     1023        if($key==null) { 
     1024            throw new Exception (_("KVP key cannot be null")); 
     1025        } else if($value===null) { 
     1026            //Delete the KVP 
     1027            $retval = $db->execSqlUpdate("DELETE FROM content_key_value_pairs WHERE content_id='" . $this->getId() . "' AND key='$key_sql'", false); 
     1028            if(isset ($this->kvps[$key])) { 
     1029                unset ($this->kvps[$key]); 
     1030            } 
     1031        } else if (!isset ($this->kvps[$key])) { 
     1032            //This is a new key 
     1033            $retval = $db->execSqlUpdate("INSERT INTO content_key_value_pairs (content_id, key, value) VALUES ('" . $this->getId() . "', '$key_sql', '$value_sql')", false); 
     1034        } else 
     1035        if ($this->kvps[$key] != $value) { 
     1036            //This is an existing key, and it's been modified 
     1037            $retval = $db->execSqlUpdate("UPDATE content_key_value_pairs SET value ='" . $value_sql . "' WHERE content_id='" . $this->getId() . "' AND key='$key_sql'", false); 
     1038        } 
     1039        $this->refresh(); 
     1040        return $retval; 
    9361041    } 
    9371042 
     
    9411046     */ 
    9421047    public function getTitle() { 
    943         try { 
    944                 return self :: getObject($this->content_row['title']); 
    945         } catch (Exception $e) { 
    946                 return null; 
    947         } 
     1048        try { 
     1049            return self :: getObject($this->content_row['title']); 
     1050        } catch (Exception $e) { 
     1051            return null; 
     1052        } 
    9481053    } 
    9491054 
     
    9531058     */ 
    9541059    public function getDescription() { 
    955         try { 
    956                 return self :: getObject($this->content_row['description']); 
    957         } catch (Exception $e) { 
    958                 return null; 
    959         } 
     1060        try { 
     1061            return self :: getObject($this->content_row['description']); 
     1062        } catch (Exception $e) { 
     1063            return null; 
     1064        } 
    9601065    } 
    9611066 
     
    9651070     */ 
    9661071    public function getLongDescription() { 
    967         try { 
    968                 return self :: getObject($this->content_row['long_description']); 
    969         } catch (Exception $e) { 
    970                 return null; 
    971         } 
     1072        try { 
     1073            return self :: getObject($this->content_row['long_description']); 
     1074        } catch (Exception $e) { 
     1075            return null; 
     1076        } 
    9721077    } 
    9731078 
     
    9771082     */ 
    9781083    public function getProjectInfo() { 
    979         try { 
    980                 return self :: getObject($this->content_row['project_info']); 
    981         } catch (Exception $e) { 
    982                 return null; 
    983         } 
     1084        try { 
     1085            return self :: getObject($this->content_row['project_info']); 
     1086        } catch (Exception $e) { 
     1087            return null; 
     1088        } 
    9841089    } 
    9851090 
     
    9881093     * */ 
    9891094    private function setContentType($content_type) { 
    990         $db = AbstractDb :: getObject(); 
    991         $content_type = $db->escapeString($content_type); 
    992         if (!self :: isContentTypeAvailable($content_type)) { 
    993                 throw new Exception(_("The following content type isn't valid: ") . $content_type); 
    994         } 
    995         $sql = "UPDATE content SET content_type = '$content_type' WHERE content_id='$this->id'"; 
    996  
    997         if (!$db->execSqlUpdate($sql, false)) { 
    998                 throw new Exception(_("Update was unsuccessfull (database error)")); 
    999         } 
    1000  
     1095        $db = AbstractDb :: getObject(); 
     1096        $content_type = $db->escapeString($content_type); 
     1097        if (!self :: isContentTypeAvailable($content_type)) { 
     1098            throw new Exception(_("The following content type isn't valid: ") . $content_type); 
     1099        } 
     1100        $sql = "UPDATE content SET content_type = '$content_type' WHERE content_id='$this->id'"; 
     1101 
     1102        if (!$db->execSqlUpdate($sql, false)) { 
     1103            throw new Exception(_("Update was unsuccessfull (database error)")); 
     1104        } 
     1105        unset(self :: $instanceArray[$this->id]);//Clear the cache or we will have problems even if we re-instanciate. 
    10011106    } 
    10021107 
     
    10061111     * @return true on success, false on failure */ 
    10071112    public function addOwner(User $user, $is_author = false) { 
    1008         $db = AbstractDb :: getObject(); 
    1009         $content_id = "'" . $this->id . "'"; 
    1010         $user_id = "'" . $db->escapeString($user->getId()) . "'"; 
    1011         $is_author ? $is_author = 'TRUE' : $is_author = 'FALSE'; 
    1012         $sql = "INSERT INTO content_has_owners (content_id, user_id, is_author) VALUES ($content_id, $user_id, $is_author)"; 
    1013  
    1014         if (!$db->execSqlUpdate($sql, false)) { 
    1015                 throw new Exception(_('Unable to insert the new Owner into database.')); 
    1016         } 
    1017  
    1018         return true; 
     1113        $db = AbstractDb :: getObject(); 
     1114        $content_id = "'" . $this->id . "'"; 
     1115        $user_id = "'" . $db->escapeString($user->getId()) . "'"; 
     1116        $is_author ? $is_author = 'TRUE' : $is_author = 'FALSE'; 
     1117        $sql = "INSERT INTO content_has_owners (content_id, user_id, is_author) VALUES ($content_id, $user_id, $is_author)"; 
     1118 
     1119        if (!$db->execSqlUpdate($sql, false)) { 
     1120            throw new Exception(_('Unable to insert the new Owner into database.')); 
     1121        } 
     1122 
     1123        return true; 
    10191124    } 
    10201125 
     
    10231128     */ 
    10241129    public function deleteOwner(User $user, $is_author = false) { 
    1025         $db = AbstractDb :: getObject(); 
    1026         $content_id = "'" . $this->id . "'"; 
    1027         $user_id = "'" . $db->escapeString($user->getId()) . "'"; 
    1028  
    1029         $sql = "DELETE FROM content_has_owners WHERE content_id=$content_id AND user_id=$user_id"; 
    1030  
    1031         if (!$db->execSqlUpdate($sql, false)) { 
    1032                 throw new Exception(_('Unable to remove the owner from the database.')); 
    1033         } 
    1034  
    1035         return true; 
     1130        $db = AbstractDb :: getObject(); 
     1131        $content_id = "'" . $this->id . "'"; 
     1132        $user_id = "'" . $db->escapeString($user->getId()) . "'"; 
     1133 
     1134        $sql = "DELETE FROM content_has_owners WHERE content_id=$content_id AND user_id=$user_id"; 
     1135 
     1136        if (!$db->execSqlUpdate($sql, false)) { 
     1137            throw new Exception(_('Unable to remove the owner from the database.')); 
     1138        } 
     1139 
     1140        return true; 
    10361141    } 
    10371142 
     
    10401145     */ 
    10411146    public function getLoggingStatus() { 
    1042         return $this->is_logging_enabled; 
     1147        return $this->is_logging_enabled; 
    10431148    } 
    10441149 
     
    10471152     */ 
    10481153    public function setLoggingStatus($status) { 
    1049         if (is_bool($status)) 
    1050         $this->is_logging_enabled = $status; 
     1154        if (is_bool($status)) 
     1155        $this->is_logging_enabled = $status; 
    10511156    } 
    10521157 
     
    10581163     */ 
    10591164    public function getLastDisplayTimestamp($user = null, $node = null) { 
    1060         $db = AbstractDb :: getObject(); 
    1061         $retval = ''; 
    1062         $sql = "SELECT EXTRACT(EPOCH FROM last_display_timestamp) as last_display_unix_timestamp FROM content_display_log WHERE content_id='{$this->id}' \n"; 
    1063  
    1064         if ($user) { 
    1065                 $user_id = $db->escapeString($user->getId()); 
    1066                 $sql .= " AND user_id = '{$user_id}' \n"; 
    1067         } 
    1068         if ($node) { 
    1069                 $node_id = $db->escapeString($node->getId()); 
    1070                 $sql .= " AND node_id = '{$node_id}' \n"; 
    1071         } 
    1072         $sql .= " ORDER BY last_display_timestamp DESC "; 
    1073         $db->execSql($sql, $log_rows, false); 
    1074         if ($log_rows) { 
    1075                 $retval = $log_rows[0]['last_display_unix_timestamp']; 
    1076         } 
    1077  
    1078         return $retval; 
     1165        $db = AbstractDb :: getObject(); 
     1166        $retval = ''; 
     1167        $sql = "SELECT EXTRACT(EPOCH FROM last_display_timestamp) as last_display_unix_timestamp FROM content_display_log WHERE content_id='{$this->id}' \n"; 
     1168 
     1169        if ($user) { 
     1170            $user_id = $db->escapeString($user->getId()); 
     1171            $sql .= " AND user_id = '{$user_id}' \n"; 
     1172        } 
     1173        if ($node) { 
     1174            $node_id = $db->escapeString($node->getId()); 
     1175            $sql .= " AND node_id = '{$node_id}' \n"; 
     1176        } 
     1177        $sql .= " ORDER BY last_display_timestamp DESC "; 
     1178        $db->execSql($sql, $log_rows, false); 
     1179        if ($log_rows) { 
     1180            $retval = $log_rows[0]['last_display_unix_timestamp']; 
     1181        } 
     1182 
     1183        return $retval; 
    10791184    } 
    10801185 
     
    10831188     * @return true or false */ 
    10841189    public function isDisplayableAt($node) { 
    1085         return true; 
     1190        return true; 
    10861191    } 
    10871192 
     
    10901195     * @return true if the user is a owner, false if he isn't of the user is null */ 
    10911196    public function isOwner($user) { 
    1092         $db = AbstractDb :: getObject(); 
    1093         $retval = false; 
    1094         if ($user != null) { 
    1095                 $user_id = $db->escapeString($user->GetId()); 
    1096                 $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id' AND user_id='$user_id'"; 
    1097                 $db->execSqlUniqueRes($sql, $content_owner_row, false); 
    1098                 if ($content_owner_row != null) { 
    1099                         $retval = true; 
    1100                 } 
    1101         } 
    1102  
    1103         return $retval; 
     1197        $db = AbstractDb :: getObject(); 
     1198        $retval = false; 
     1199        if ($user != null) { 
     1200            $user_id = $db->escapeString($user->GetId()); 
     1201            $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id' AND user_id='$user_id'"; 
     1202            $db->execSqlUniqueRes($sql, $content_owner_row, false); 
     1203            if ($content_owner_row != null) { 
     1204                $retval = true; 
     1205            } 
     1206        } 
     1207 
     1208        return $retval; 
    11041209    } 
    11051210    /** Get the authors of the Content 
    11061211     * @return null or array of User objects */ 
    11071212    public function getAuthors() { 
    1108         $db = AbstractDb :: getObject(); 
    1109         $retval = array (); 
    1110         $sql = "SELECT user_id FROM content_has_owners WHERE content_id='$this->id' AND is_author=TRUE"; 
    1111         $db->execSqlUniqueRes($sql, $content_owner_row, false); 
    1112         if ($content_owner_row != null) { 
    1113                 $user = User :: getObject($content_owner_row['user_id']); 
    1114                 $retval[] = $user; 
    1115         } 
    1116  
    1117         return $retval; 
     1213        $db = AbstractDb :: getObject(); 
     1214        $retval = array (); 
     1215        $sql = "SELECT user_id FROM content_has_owners WHERE content_id='$this->id' AND is_author=TRUE"; 
     1216        $db->execSqlUniqueRes($sql, $content_owner_row, false); 
     1217        if ($content_owner_row != null) { 
     1218            $user = User :: getObject($content_owner_row['user_id']); 
     1219            $retval[] = $user; 
     1220        } 
     1221 
     1222        return $retval; 
    11181223    } 
    11191224    /** @see GenricObject 
    11201225     * @return The id */ 
    11211226    public function getId() { 
    1122         return $this->id; 
     1227        return $this->id; 
    11231228    } 
    11241229 
     
    11261231     * @return true or false */ 
    11271232    public function isSimpleContent() { 
    1128         return false; 
     1233        return false; 
    11291234    } 
    11301235 
     
    11321237     * @return true or false */ 
    11331238    public function isTextualContent() { 
    1134         return false; 
     1239        return false; 
    11351240    } 
    11361241 
     
    11401245     */ 
    11411246    public function prepareGetUserUI() { 
    1142         return null; 
     1247        return null; 
    11431248    } 
    11441249 
    11451250    /** Does the content have any displayable metadata? 
    1146       * @return true or false */ 
     1251     * @return true or false */ 
    11471252    protected function hasDisplayableMetadata() { 
    1148         $retval = false; 
    1149         $metadata = $this->getTitle(); 
    1150         if ($metadata && $this->titleShouldDisplay()){ 
    1151                 $retval = true; 
    1152         } 
    1153         elseif ($this->getDescription()){ 
    1154                 $retval = true; 
    1155         } 
    1156         elseif ($this->getLongDescription()){ 
    1157                 $retval = true; 
    1158         } 
    1159         elseif ($this->getProjectInfo()){ 
    1160                 $retval = true; 
    1161         } 
    1162         elseif($this->getAuthors()) { 
    1163                 $retval = true; 
    1164         } 
    1165         return $retval; 
     1253        $retval = false; 
     1254        $metadata = $this->getTitle(); 
     1255        if ($metadata && $this->titleShouldDisplay()){ 
     1256            $retval = true; 
     1257        } 
     1258        elseif ($this->getDescription()){ 
     1259            $retval = true; 
     1260        } 
     1261        elseif ($this->getLongDescription()){ 
     1262            $retval = true; 
     1263        } 
     1264        elseif ($this->getProjectInfo()){ 
     1265            $retval = true; 
     1266        } 
     1267        elseif($this->getAuthors()) { 
     1268            $retval = true; 
     1269        } 
     1270        return $retval; 
    11661271    } 
    11671272 
    11681273    /** Set the content to be displayed in the main display area.  Needs to be set by subclasses 
    1169       * @param $html:  Html markup for the displayed content */ 
     1274     * @param $html:  Html markup for the displayed content */ 
    11701275    protected function setUserUIMainDisplayContent($html) { 
    1171         $this->user_ui_main_content = $html; 
     1276        $this->user_ui_main_content = $html; 
    11721277    } 
    11731278 
    11741279    /** Set the content to be displayed in the interactive display area.  Needs to be set by subclasses 
    1175       * @param $html:  Html markup for the displayed content */ 
     1280     * @param $html:  Html markup for the displayed content */ 
    11761281    protected function setUserUIMainInteractionArea($html) { 
    1177         $this->user_ui_interaction_area = $html; 
    1178     } 
    1179     /** Retreives the user interface of this object.  Anything that overrides this method should use  
    1180      * setUserUIMainDisplayContent() and/or setUserUIMainInteractionArea before returning it's parent's  
     1282        $this->user_ui_interaction_area = $html; 
     1283    } 
     1284    /** Retreives the user interface of this object.  Anything that overrides this method should use 
     1285     * setUserUIMainDisplayContent() and/or setUserUIMainInteractionArea before returning it's parent's 
    11811286     * getUserUI() return value at the end of processing. 
    11821287 
    11831288     *      * @return The HTML fragment for this interface */ 
    11841289    public function getUserUI($subclass_user_interface = null) { 
    1185         $html = ''; 
    1186         $hasDisplayableMetadata = $this->hasDisplayableMetadata(); 
    1187         $hasDisplayableMetadata ? $hasDisplayableMetadataClass = 'hasDisplayableMetadata' : $hasDisplayableMetadataClass = null; 
    1188         $html .= "<div class='user_ui_main_outer " . get_class($this) . " $hasDisplayableMetadataClass'>\n"; 
    1189         $html .= "<div class='user_ui_main_inner'>\n"; 
    1190         if (!empty ($this->content_row['title']) && $this->titleShouldDisplay()) { 
    1191                 $html .= "<div class='user_ui_title'>\n"; 
    1192                 $title = self :: getObject($this->content_row['title']); 
    1193                 $title->setLogAsContent($this); 
    1194                 // If the content logging is disabled, all the children will inherit this property temporarly 
    1195                 if ($this->getLoggingStatus() == false) 
    1196                 $title->setLoggingStatus(false); 
    1197                 $html .= $title->getUserUI(); 
    1198                 $html .= "</div>\n"; 
    1199         } 
    1200         if($this->user_ui_main_content) { 
    1201                 if (!$hasDisplayableMetadata) { 
    1202                         $html .= "\n<div class='user_ui_main_content'>$this->user_ui_main_content</div>\n"; 
    1203                 } else { 
    1204                         $html .= "<table><tr>\n"; 
    1205                         $html .= "<td  class='user_ui_main_content'>\n$this->user_ui_main_content</td>\n"; 
    1206                         $html .= "<td>\n"; 
    1207                 } 
    1208         } 
    1209         $authors = $this->getAuthors(); 
    1210         if (count($authors) > 0) { 
    1211                 $html .= "<div class='user_ui_authors'>\n"; 
    1212                 $html .= _("Author(s):"); 
    1213                 foreach ($authors as $user) { 
    1214                         $html .= $user->getListUI() . " "; 
    1215                 } 
    1216                 $html .= "</div>\n"; 
    1217         } 
    1218  
    1219         if (!empty ($this->content_row['description'])) { 
    1220                 $html .= "<div class='user_ui_description'>\n"; 
    1221                 $description = self :: getObject($this->content_row['description']); 
    1222                 $description->setLogAsContent($this); 
    1223                 // If the content logging is disabled, all the children will inherit this property temporarly 
    1224                 if ($this->getLoggingStatus() == false) 
    1225                 $description->setLoggingStatus(false); 
    1226                 $html .= $description->getUserUI(); 
    1227                 $html .= "</div>\n"; 
    1228         } 
    1229  
    1230         if (!empty ($this->content_row['project_info'])) { 
    1231                 if (!empty ($this->content_row['project_info'])) { 
    1232                         $html .= "<div class='user_ui_projet_info'>\n"; 
    1233                         $html .= "<b>" . _("Project information:") . "</b>"; 
    1234                         $project_info = self :: getObject($this->content_row['project_info']); 
    1235                         $project_info->setLogAsContent($this); 
    1236                         // If the content logging is disabled, all the children will inherit this property temporarly 
    1237                         if ($this->getLoggingStatus() == false) 
    1238                         $project_info->setLoggingStatus(false); 
    1239                         $html .= $project_info->getUserUI(); 
    1240                         $html .= "</div>\n"; 
    1241                 } 
    1242         } 
    1243         if ($hasDisplayableMetadata) { 
    1244                 $html .= "</td>\n"; 
    1245                 $html .= "</tr>\n"; 
    1246         } 
    1247         if($this->user_ui_interaction_area) { 
    1248                 if (!$hasDisplayableMetadata) { 
    1249                         $html .= "\n<div class='user_ui_interaction_area'>$this->user_ui_interaction_area</div>\n"; 
    1250                 } else { 
    1251                         $html .= "<tr>\n"; 
    1252                         $html .= "<td colspan=2 class='user_ui_interaction_area'>\n$this->user_ui_interaction_area</td>\n"; 
    1253                         $html .= "</tr>\n"; 
    1254                 } 
    1255         } 
    1256  
    1257         if ($hasDisplayableMetadata) { 
    1258                 $html .= "</table>\n"; 
    1259         } 
    1260         $html .= "</div>\n"; 
    1261         $html .= "</div>\n"; 
    1262  
    1263  
    1264         $this->logContentDisplay(); 
    1265         return $html; 
     1290        $html = ''; 
     1291        $hasDisplayableMetadata = $this->hasDisplayableMetadata(); 
     1292        $hasDisplayableMetadata ? $hasDisplayableMetadataClass = 'hasDisplayableMetadata' : $hasDisplayableMetadataClass = null; 
     1293        $html .= "<div class='user_ui_main_outer " . get_class($this) . " $hasDisplayableMetadataClass'>\n"; 
     1294        $html .= "<div class='user_ui_main_inner'>\n"; 
     1295        if (!empty ($this->content_row['title']) && $this->titleShouldDisplay()) { 
     1296            $html .= "<div class='user_ui_title'>\n"; 
     1297            $title = self :: getObject($this->content_row['title']); 
     1298            $title->setLogAsContent($this); 
     1299            // If the content logging is disabled, all the children will inherit this property temporarly 
     1300            if ($this->getLoggingStatus() == false) 
     1301            $title->setLoggingStatus(false); 
     1302            $html .= $title->getUserUI(); 
     1303            $html .= "</div>\n"; 
     1304        } 
     1305        if($this->user_ui_main_content) { 
     1306            if (!$hasDisplayableMetadata) { 
     1307                $html .= "\n<div class='user_ui_main_content'>$this->user_ui_main_content</div>\n"; 
     1308            } else { 
     1309                $html .= "<table><tr>\n"; 
     1310                $html .= "<td  class='user_ui_main_content'>\n$this->user_ui_main_content</td>\n"; 
     1311                $html .= "<td>\n"; 
     1312            } 
     1313        } 
     1314        $authors = $this->getAuthors(); 
     1315        if (count($authors) > 0) { 
     1316            $html .= "<div class='user_ui_authors'>\n"; 
     1317            $html .= _("Author(s):"); 
     1318            foreach ($authors as $user) { 
     1319                $html .= $user->getListUI() . " "; 
     1320            } 
     1321            $html .= "</div>\n"; 
     1322        } 
     1323 
     1324        if (!empty ($this->content_row['description'])) { 
     1325            $html .= "<div class='user_ui_description'>\n"; 
     1326            $description = self :: getObject($this->content_row['description']); 
     1327            $description->setLogAsContent($this); 
     1328            // If the content logging is disabled, all the children will inherit this property temporarly 
     1329            if ($this->getLoggingStatus() == false) 
     1330            $description->setLoggingStatus(false); 
     1331            $html .= $description->getUserUI(); 
     1332            $html .= "</div>\n"; 
     1333        } 
     1334 
     1335        if (!empty ($this->content_row['project_info'])) { 
     1336            if (!empty ($this->content_row['project_info'])) { 
     1337                $html .= "<div class='user_ui_projet_info'>\n"; 
     1338                $html .= "<b>" . _("Project information:") . "</b>"; 
     1339                $project_info = self :: getObject($this->content_row['project_info']); 
     1340                $project_info->setLogAsContent($this); 
     1341                // If the content logging is disabled, all the children will inherit this property temporarly 
     1342                if ($this->getLoggingStatus() == false) 
     1343                $project_info->setLoggingStatus(false); 
     1344                $html .= $project_info->getUserUI(); 
     1345                $html .= "</div>\n"; 
     1346            } 
     1347        } 
     1348        if ($hasDisplayableMetadata) { 
     1349            $html .= "</td>\n"; 
     1350            $html .= "</tr>\n"; 
     1351        } 
     1352        if($this->user_ui_interaction_area) { 
     1353            if (!$hasDisplayableMetadata) { 
     1354                $html .= "\n<div class='user_ui_interaction_area'>$this->user_ui_interaction_area</div>\n"; 
     1355            } else { 
     1356                $html .= "<tr>\n"; 
     1357                $html .= "<td colspan=2 class='user_ui_interaction_area'>\n$this->user_ui_interaction_area</td>\n"; 
     1358                $html .= "</tr>\n"; 
     1359            } 
     1360        } 
     1361 
     1362        if ($hasDisplayableMetadata) { 
     1363            $html .= "</table>\n"; 
     1364        } 
     1365        $html .= "</div>\n"; 
     1366        $html .= "</div>\n"; 
     1367 
     1368 
     1369        $this->logContentDisplay(); 
     1370        return $html; 
    12661371    } 
    12671372 
     
    12701375     * display */ 
    12711376    protected function setLogAsContent(Content $content) { 
    1272         $this->log_as_content = $content; 
     1377        $this->log_as_content = $content; 
    12731378    } 
    12741379 
     
    12771382     * content was displayed for this user 
    12781383     * @param $node Node, optionnal.  If present, the date is the last time the 
    1279      * content was displayed at this node  
     1384     * content was displayed at this node 
    12801385     @return PHP timestamp or null */ 
    12811386    public function getLastDisplayedTimestamp($user = null, $node = null) { 
    1282         $retval = null; 
    1283         $log_row = null; 
    1284         $user ? $user_sql = " AND user_id='{$user->getId()}' " : $user_sql = ''; 
    1285         $node ? $node_sql = " AND node_id='{$node->getId()}' " : $node_sql = ''; 
    1286         $db = AbstractDb :: getObject(); 
    1287  
    1288         $sql = "SELECT EXTRACT('epoch' FROM last_display_timestamp) as last_display_timestamp FROM content_display_log WHERE content_id='$this->id' $user_sql $node_sql ORDER BY last_display_timestamp DESC limit 1"; 
    1289         $db->execSqlUniqueRes($sql, $log_row, false); 
    1290         if ($log_row != null) { 
    1291                 $retval = $log_row['last_display_timestamp']; 
    1292         } 
    1293         return $retval; 
     1387        $retval = null; 
     1388        $log_row = null; 
     1389        $user ? $user_sql = " AND user_id='{$user->getId()}' " : $user_sql = ''; 
     1390        $node ? $node_sql = " AND node_id='{$node->getId()}' " : $node_sql = ''; 
     1391        $db = AbstractDb :: getObject(); 
     1392 
     1393        $sql = "SELECT EXTRACT('epoch' FROM last_display_timestamp) as last_display_timestamp FROM content_display_log WHERE content_id='$this->id' $user_sql $node_sql ORDER BY last_display_timestamp DESC limit 1"; 
     1394        $db->execSqlUniqueRes($sql, $log_row, false); 
     1395        if ($log_row != null) { 
     1396            $retval = $log_row['last_display_timestamp']; 
     1397        } 
     1398        return $retval; 
    12941399    } 
    12951400 
    12961401    /** Log that this content has just been displayed to the user.  Will only log if the user is logged in */ 
    12971402    private function logContentDisplay() { 
    1298         if ($this->getLoggingStatus() == true && $this->log_as_content->getId() == $this->getId()) { 
    1299                 // DEBUG:: 
    1300                 //echo "Logging ".get_class($this)." :: ".$this->__toString()."<br>"; 
    1301                 $user = User :: getCurrentUser(); 
    1302                 $node = Node :: getCurrentNode(); 
    1303                 if ($user != null && $node != null) { 
    1304                         $user_id = $user->getId(); 
    1305                         $node_id = $node->getId(); 
    1306                         $db = AbstractDb :: getObject(); 
    1307  
    1308                         $sql = "SELECT * FROM content_display_log WHERE content_id='$this->id' AND user_id='$user_id' AND node_id='$node_id'"; 
    1309                         $db->execSql($sql, $log_rows, false); 
    1310                         if ($log_rows != null) { 
    1311                                 $sql = "UPDATE content_display_log SET num_display = num_display +1, last_display_timestamp = CURRENT_TIMESTAMP WHERE content_id='$this->id' AND user_id='$user_id' AND node_id='$node_id'"; 
    1312                         } else { 
    1313                                 $sql = "INSERT INTO content_display_log (user_id, content_id, node_id) VALUES ('$user_id', '$this->id', '$node_id')"; 
    1314                         } 
    1315                         $db->execSqlUpdate($sql, false); 
    1316                 } 
    1317         } 
     1403        if ($this->getLoggingStatus() == true && $this->log_as_content->getId() == $this->getId()) { 
     1404            // DEBUG:: 
     1405            //echo "Logging ".get_class($this)." :: ".$this->__toString()."<br>"; 
     1406            $user = User :: getCurrentUser(); 
     1407            $node = Node :: getCurrentNode(); 
     1408            if ($user != null && $node != null) { 
     1409                $user_id = $user->getId(); 
     1410                $node_id = $node->getId(); 
     1411                $db = AbstractDb :: getObject(); 
     1412 
     1413                $sql = "SELECT * FROM content_display_log WHERE content_id='$this->id' AND user_id='$user_id' AND node_id='$node_id'"; 
     1414                $db->execSql($sql, $log_rows, false); 
     1415                if ($log_rows != null) { 
     1416                    $sql = "UPDATE content_display_log SET num_display = num_display +1, last_display_timestamp = CURRENT_TIMESTAMP WHERE content_id='$this->id' AND user_id='$user_id' AND node_id='$node_id'"; 
     1417                } else { 
     1418                    $sql = "INSERT INTO content_display_log (user_id, content_id, node_id) VALUES ('$user_id', '$this->id', '$node_id')"; 
     1419                } 
     1420                $db->execSqlUpdate($sql, false); 
     1421            } 
     1422        } 
    13181423    } 
    13191424    /** Handle replacements of hyperlinks for clickthrough tracking (if appropriate) */ 
    13201425    protected function replaceHyperLinks(& $html) { 
    1321         /* Handle hyperlink clicktrough logging */ 
    1322         if ($this->getLoggingStatus() == true) { 
    1323                 $html = HyperLink :: replaceHyperLinks($html, $this->log_as_content); 
    1324         } 
    1325         return $html; 
     1426        /* Handle hyperlink clicktrough logging */ 
     1427        if ($this->getLoggingStatus() == true) { 
     1428            $html = HyperLink :: replaceHyperLinks($html, $this->log_as_content); 
     1429        } 
     1430        return $html; 
    13261431    } 
    13271432 
     
    13301435     * @return The HTML fragment for this interface */ 
    13311436    public function getListUI($subclass_list_interface = null) { 
    1332         $html = ''; 
    1333         $html .= "<div class='list_ui_container'>\n"; 
    1334         $html .= $this->__toString()."\n"; 
    1335         $html .= $subclass_list_interface; 
    1336         $html .= "</div>\n"; 
    1337         return $html; 
     1437        $html = ''; 
     1438        $html .= "<div class='list_ui_container'>\n"; 
     1439        $html .= $this->__toString()."\n"; 
     1440        $html .= $subclass_list_interface; 
     1441        $html .= "</div>\n"; 
     1442        return $html; 
    13381443    } 
    13391444 
     
    13471452     */ 
    13481453    public function getAdminUI($subclass_admin_interface = null, $title = null) { 
    1349         $db = AbstractDb :: getObject(); 
    1350  
    1351         $html = ''; 
    1352         if (!(User :: getCurrentUser()->isSuperAdmin() || $this->isOwner(User :: getCurrentUser()))) { 
    1353                 $html .= $this->getListUI(); 
    1354                 $html .= ' ' . _("(You do not have access to edit this piece of content)"); 
    1355         } else { 
    1356                 $html .= "<fieldset class='admin_container " . get_class($this) . "'>\n"; 
    1357                 if (!empty ($title)) { 
    1358                         $html .= "<legend>$title</legend>\n"; 
    1359                 } 
    1360                 $html .= "<ul class='admin_element_list'>\n"; 
    1361                 if ($this->getObjectType() == 'Content') { 
    1362                         // The object hasn't yet been typed. 
    1363                         $html .= _("You must select a content type: "); 
    1364                         $i = 0; 
    1365  
    1366                         foreach (self :: getAvailableContentTypes() as $classname) { 
    1367                                 $tab[$i][0] = $classname; 
    1368                                 $tab[$i][1] = $classname; 
    1369                                 $i++; 
    1370                         } 
    1371  
    1372                         $html .= FormSelectGenerator :: generateFromArray($tab, null, "content_" . $this->id . "_content_type", "Content", false); 
    1373                 } else { 
    1374                         $criteria_array = array ( 
    1375                         array ( 
    1376                         'isSimpleContent' 
     1454        $db = AbstractDb :: getObject(); 
     1455 
     1456        $html = ''; 
     1457        if (!(User :: getCurrentUser()->isSuperAdmin() || $this->isOwner(User :: getCurrentUser()))) { 
     1458            $html .= $this->getListUI(); 
     1459            $html .= ' ' . _("(You do not have access to edit this piece of content)"); 
     1460        } else { 
     1461            $html .= "<fieldset class='admin_container " . get_class($this) . "'>\n"; 
     1462            if (!empty ($title)) { 
     1463                $html .= "<legend>$title</legend>\n"; 
     1464            } 
     1465            $html .= "<ul class='admin_element_list'>\n"; 
     1466            if ($this->getObjectType() == 'Content') { 
     1467                // The object hasn't yet been typed. 
     1468                $html .= _("You must select a content type: "); 
     1469                $i = 0; 
     1470 
     1471                foreach (self :: getAvailableContentTypes() as $classname) { 
     1472                    $tab[$i][0] = $classname; 
     1473                    $tab[$i][1] = $classname; 
     1474                    $i++; 
     1475                } 
     1476 
     1477                $html .= FormSelectGenerator :: generateFromArray($tab, null, "content_" . $this->id . "_content_type", "Content", false); 
     1478            } else { 
     1479                $criteria_array = array ( 
     1480                array ( 
     1481                'isSimpleContent' 
    13771482                        ) 
    1378                         ); 
    1379                         $metadada_allowed_content_types = ContentTypeFilter :: getObject($criteria_array); 
    1380  
    1381                         // Content metadata 
    1382                         if ($this->isSimpleContent() == false || $this->isPersistent()) { 
    1383                                 $html .= "<fieldset class='admin_element_group'>\n"; 
    1384                                 $html .= "<legend>" . sprintf(_("%s MetaData"), get_class($this)) . "</legend>\n"; 
    1385  
    1386                                 /* title_is_displayed */ 
    1387                                 $html_title_is_displayed = _("Display the title?") . ": \n"; 
    1388                                 $name = "content_" . $this->id . "_title_is_displayed"; 
    1389                                 $this->titleShouldDisplay() ? $checked = 'CHECKED' : $checked = ''; 
    1390                                 $html_title_is_displayed .= "<input type='checkbox' name='$name' $checked>\n"; 
    1391  
    1392                                 /* title */ 
    1393                                 $html .= "<li class='admin_element_item_container admin_section_edit_title'>\n"; 
    1394                                 $html .= "<div class='admin_element_data'>\n"; 
    1395                                 if (empty ($this->content_row['title'])) { 
    1396                                         $html .= self :: getNewContentUI("title_{$this->id}_new", $metadada_allowed_content_types, _("Title:")); 
    1397                                         $html .= "</div>\n"; 
    1398                                 } else { 
    1399                                         $html .= $html_title_is_displayed; 
    1400                                         $title = self :: getObject($this->content_row['title']); 
    1401                                         $html .= $title->getAdminUI(null, _("Title:")); 
    1402                                         $html .= "</div>\n"; 
    1403                                         $html .= "<div class='admin_element_tools admin_section_delete_title'>\n"; 
    1404                                         $name = "content_" . $this->id . "_title_erase"; 
    1405                                         $html .= "<input type='submit' class='submit' name='$name' value='" . sprintf(_("Delete %s (%s)"), _("title"), get_class($title)) . "'>"; 
    1406                                         $html .= "</div>\n"; 
    1407                                 } 
    1408                                 $html .= "</li>\n"; 
     1483                ); 
     1484                $metadada_allowed_content_types = ContentTypeFilter :: getObject($criteria_array); 
     1485 
     1486                // Content metadata 
     1487                if ($this->isSimpleContent() == false || $this->isPersistent()) { 
     1488                    $html .= "<fieldset class='admin_element_group'>\n"; 
     1489                    $html .= "<legend>" . sprintf(_("%s MetaData"), get_class($this)) . "</legend>\n"; 
     1490 
     1491                    /* title_is_displayed */ 
     1492                    $html_title_is_displayed = _("Display the title?") . ": \n"; 
     1493                    $name = "content_" . $this->id . "_title_is_displayed"; 
     1494                    $this->titleShouldDisplay() ? $checked = 'CHECKED' : $checked = ''; 
     1495                    $html_title_is_displayed .= "<input type='checkbox' name='$name' $checked>\n"; 
     1496 
     1497                    /* title */ 
     1498                    $html .= "<li class='admin_element_item_container admin_section_edit_title'>\n"; 
     1499                    $html .= "<div class='admin_element_data'>\n"; 
     1500                    if (empty ($this->content_row['title'])) { 
     1501                        $html .= self :: getNewContentUI("title_{$this->id}_new", $metadada_allowed_content_types, _("Title:")); 
     1502                        $html .= "</div>\n"; 
     1503                    } else { 
     1504                        $html .= $html_title_is_displayed; 
     1505                        $title = self :: getObject($this->content_row['title']); 
     1506                        $html .= $title->getAdminUI(null, _("Title:")); 
     1507                        $html .= "</div>\n"; 
     1508                        $html .= "<div class='admin_element_tools admin_section_delete_title'>\n"; 
     1509                        $name = "content_" . $this->id . "_title_erase"; 
     1510                        $html .= "<input type='submit' class='submit' name='$name' value='" . sprintf(_("Delete %s (%s)"), _("title"), get_class($title)) . "'>"; 
     1511                        $html .= "</div>\n"; 
     1512                    } 
     1513                    $html .= "</li>\n"; 
     1514                } 
     1515 
     1516                if ($this->isSimpleContent() == false) { 
     1517                    /* description */ 
     1518                    $html .= "<li class='admin_element_item_container admin_section_edit_description'>\n"; 
     1519                    $html .= "<div class='admin_element_data'>\n"; 
     1520                    if (empty ($this->content_row['description'])) { 
     1521                        $html .= self :: getNewContentUI("description_{$this->id}_new", $metadada_allowed_content_types, _("Description:")); 
     1522                        $html .= "</div>\n"; 
     1523                    } else { 
     1524                        $description = self :: getObject($this->content_row['description']); 
     1525                        $html .= $description->getAdminUI(null, _("Description:")); 
     1526                        $html .= "</div>\n"; 
     1527                        $html .= "<div class='admin_element_tools'>\n"; 
     1528                        $name = "content_" . $this->id . "_description_erase"; 
     1529                        $html .= "<input type='submit' class='submit' name='$name' value='" . sprintf(_("Delete %s (%s)"), _("description"), get_class($description)) . "'>"; 
     1530                        $html .= "</div>\n"; 
     1531                    } 
     1532                    $html .= "</li>\n"; 
     1533 
     1534                    /* long description */ 
     1535                    $html .= "<li class='admin_element_item_container admin_section_edit_long_description'>\n"; 
     1536                    $html .= "<div class='admin_element_data'>\n"; 
     1537                    if (empty ($this->content_row['long_description'])) { 
     1538                        $html .= self :: getNewContentUI("long_description_{$this->id}_new", $metadada_allowed_content_types, _("Long description:")); 
     1539                        $html .= "</div>\n"; 
     1540                    } else { 
     1541                        $description = self :: getObject($this->content_row['long_description']); 
     1542                        $html .= $description->getAdminUI(null, _("Long description:")); 
     1543                        $html .= "</div>\n"; 
     1544                        $html .= "<div class='admin_element_tools'>\n"; 
     1545                        $name = "content_" . $this->id . "_long_description_erase"; 
     1546                        $html .= "<input type='submit' class='submit' name='$name' value='" . sprintf(_("Delete %s (%s)"), _("long description"), get_class($description)) . "'>"; 
     1547                        $html .= "</div>\n"; 
     1548                    } 
     1549                    $html .= "</li>\n"; 
     1550 
     1551                    /* project_info */ 
     1552                    $html .= "<li class='admin_element_item_container admin_section_edit_project'>\n"; 
     1553                    $html .= "<div class='admin_element_data'>\n"; 
     1554                    if (empty ($this->content_row['project_info'])) { 
     1555                        $html .= self :: getNewContentUI("project_info_{$this->id}_new", $metadada_allowed_content_types, _("Information on this project:")); 
     1556                        $html .= "</div>\n"; 
     1557                    } else { 
     1558                        $project_info = self :: getObject($this->content_row['project_info']); 
     1559                        $html .= $project_info->getAdminUI(null, _("Information on this project:")); 
     1560                        $html .= "</div>\n"; 
     1561                        $html .= "<div class='admin_element_tools'>\n"; 
     1562                        $name = "content_" . $this->id . "_project_info_erase"; 
     1563                        $html .= "<input type='submit' class='submit' name='$name' value='" . sprintf(_("Delete %s (%s)"), _("project information"), get_class($project_info)) . "'>"; 
     1564                        $html .= "</div>\n"; 
     1565                    } 
     1566                    $html .= "</li>\n"; 
     1567                } 
     1568 
     1569                //End content medatada 
     1570                if ($this->isSimpleContent() == false || $this->isPersistent()) { 
     1571                    $html .= "</fieldset>\n"; 
     1572                } 
     1573 
     1574                if ($this->isSimpleContent() == false || $this->isPersistent()) { 
     1575 
     1576                    $html .= "<fieldset class='admin_element_group'>\n"; 
     1577                    $html .= "<legend>" . sprintf(_("%s access control"), get_class($this)) . "</legend>\n"; 
     1578 
     1579                    /* is_persistent */ 
     1580                    $html .= "<li class='admin_element_item_container admin_section_edit_persistant'>\n"; 
     1581                    $html .= "<div class='admin_element_label'>" . _("Is part of reusable content library (protected from deletion)?") . ": </div>\n"; 
     1582                    $html .= "<div class='admin_element_data'>\n"; 
     1583                    $name = "content_" . $this->id . "_is_persistent"; 
     1584                    $this->isPersistent() ? $checked = 'CHECKED' : $checked = ''; 
     1585                    $html .= "<input type='checkbox' name='$name' $checked onChange='submit();'>\n"; 
     1586                    $html .= "</div>\n"; 
     1587                    $html .= "</li>\n"; 
     1588 
     1589                    /* content_has_owners */ 
     1590                    $html .= "<li class='admin_element_item_container content_has_owners'>\n"; 
     1591                    $html .= "<div class='admin_element_label'>" . _("Content owner list") . "</div>\n"; 
     1592                    $html .= "<ul class='admin_element_list'>\n"; 
     1593 
     1594                    $db = AbstractDb :: getObject(); 
     1595                    $sql = "SELECT * FROM content_has_owners WHERE content_id='$this->id'"; 
     1596                    $db->execSql($sql, $content_owner_rows, false); 
     1597                    if ($content_owner_rows != null) { 
     1598                        foreach ($content_owner_rows as $content_owner_row) { 
     1599                            $html .= "<li class='admin_element_item_container'>\n"; 
     1600                            $html .= "<div class='admin_element_data'>\n"; 
     1601                            $user = User :: getObject($content_owner_row['user_id']); 
     1602 
     1603                            $html .= $user->getListUI(); 
     1604                            $name = "content_" . $this->id . "_owner_" . $user->GetId() . "_is_author"; 
     1605                            $html .= " Is content author? "; 
     1606 
     1607                            $content_owner_row['is_author'] == 't' ? $checked = 'CHECKED' : $checked = ''; 
     1608                            $html .= "<input type='checkbox' name='$name' $checked>\n"; 
     1609                            $html .= "</div>\n"; 
     1610                            $html .= "<div class='admin_element_tools'>\n"; 
     1611                            $name = "content_" . $this->id . "_owner_" . $user->GetId() . "_remove"; 
     1612                            $html .= "<input type='submit' class='submit' name='$name' value='" . _("Remove owner") . "'>"; 
     1613                            $html .= "</div>\n"; 
     1614                            $html .= "</li>\n"; 
    14091615                        } 
    1410  
    1411                         if ($this->isSimpleContent() == false) { 
    1412                                 /* description */ 
    1413                                 $html .= "<li class='admin_element_item_container admin_section_edit_description'>\n"; 
    1414                                 $html .= "<div class='admin_element_data'>\n"; 
    1415                                 if (empty ($this->content_row['description'])) { 
    1416                                         $html .= self :: getNewContentUI("description_{$this->id}_new", $metadada_allowed_content_types, _("Description:")); 
    1417                                         $html .= "</div>\n"; 
    1418                                 } else { 
    1419                                         $description = self :: getObject($this->content_row['description']); 
    1420                                         $html .= $description->getAdminUI(null, _("Description:")); 
    1421                                         $html .= "</div>\n"; 
    1422                                         $html .= "<div class='admin_element_tools'>\n"; 
    1423                                         $name = "content_" . $this->id . "_description_erase"; 
    1424                                         $html .= "<input type='submit' class='submit' name='$name' value='" . sprintf(_("Delete %s (%s)"), _("description"), get_class($description)) . "'>"; 
    1425                                         $html .= "</div>\n"; 
    1426                                 } 
    1427                                 $html .= "</li>\n"; 
    1428  
    1429                                 /* long description */ 
    1430                                 $html .= "<li class='admin_element_item_container admin_section_edit_long_description'>\n"; 
    1431                                 $html .= "<div class='admin_element_data'>\n"; 
    1432                                 if (empty ($this->content_row['long_description'])) { 
    1433                                         $html .= self :: getNewContentUI("long_description_{$this->id}_new", $metadada_allowed_content_types, _("Long description:")); 
    1434                                         $html .= "</div>\n"; 
    1435                                 } else { 
    1436                                         $description = self :: getObject($this->content_row['long_description']); 
    1437                                         $html .= $description->getAdminUI(null, _("Long description:")); 
    1438                                         $html .= "</div>\n"; 
    1439                                         $html .= "<div class='admin_element_tools'>\n"; 
    1440                                         $name = "content_" . $this->id . "_long_description_erase"; 
    1441                                         $html .= "<input type='submit' class='submit' name='$name' value='" . sprintf(_("Delete %s (%s)"), _("long description"), get_class($description)) . "'>"; 
    1442                                         $html .= "</div>\n"; 
    1443                                 } 
    1444                                 $html .= "</li>\n"; 
    1445  
    1446                                 /* project_info */ 
    1447                                 $html .= "<li class='admin_element_item_container admin_section_edit_project'>\n"; 
    1448                                 $html .= "<div class='admin_element_data'>\n"; 
    1449                                 if (empty ($this->content_row['project_info'])) { 
    1450                                         $html .= self :: getNewContentUI("project_info_{$this->id}_new", $metadada_allowed_content_types, _("Information on this project:")); 
    1451                                         $html .= "</div>\n"; 
    1452                                 } else { 
    1453                                         $project_info = self :: getObject($this->content_row['project_info']); 
    1454                                         $html .= $project_info->getAdminUI(null, _("Information on this project:")); 
    1455                                         $html .= "</div>\n"; 
    1456                                         $html .= "<div class='admin_element_tools'>\n"; 
    1457                                         $name = "content_" . $this->id . "_project_info_erase"; 
    1458                                         $html .= "<input type='submit' class='submit' name='$name' value='" . sprintf(_("Delete %s (%s)"), _("project information"), get_class($project_info)) . "'>"; 
    1459                                         $html .= "</div>\n"; 
    1460                                 } 
    1461                                 $html .= "</li>\n"; 
    1462                         } 
    1463  
    1464                         //End content medatada 
    1465                         if ($this->isSimpleContent() == false || $this->isPersistent()) { 
    1466                                 $html .= "</fieldset>\n"; 
    1467                         } 
    1468  
    1469                         if ($this->isSimpleContent() == false || $this->isPersistent()) { 
    1470