OSDN Git Service

本家Nucleus CMS 4.0のリビジョン1626をコミット
[nucleus-jp/nucleus-next.git] / nucleus / libs / PLUGIN.php
1 <?php
2         /*
3          * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
4          * Copyright (C) 2002-2009 The Nucleus Group
5          *
6          * This program is free software; you can redistribute it and/or
7          * modify it under the terms of the GNU General Public License
8          * as published by the Free Software Foundation; either version 2
9          * of the License, or (at your option) any later version.
10          * (see nucleus/documentation/index.html#license for more info)
11          */
12         /**
13          * This is an (abstract) class of which all Nucleus Plugins must inherit
14          *
15          * for more information on plugins and how to write your own, see the
16          * plugins.html file that is included with the Nucleus documenation
17          *
18          * @license http://nucleuscms.org/license.txt GNU General Public License
19          * @copyright Copyright (C) 2002-2009 The Nucleus Group
20          * @version $Id: PLUGIN.php 1575 2011-08-03 14:58:04Z ftruscot $
21          */
22         class NucleusPlugin {
23
24                 // these functions _have_ to be redefined in your plugin
25
26                 function getName() 
27                 { 
28                         return 'Undefined'; 
29                 }
30                 
31                 function getAuthor()  
32                 { 
33                         return 'Undefined'; 
34                 }
35                 
36                 function getURL()  
37                 { 
38                         return 'Undefined'; 
39                 }
40                 
41                 function getVersion() 
42                 { 
43                         return '0.0'; 
44                 }
45                 
46                 function getDescription() 
47                 { 
48                         return 'Undefined';
49                 }
50
51                 // these function _may_ be redefined in your plugin
52
53                 function getMinNucleusVersion() 
54                 { 
55                         return 150; 
56                 }
57                 
58                 function getMinNucleusPatchLevel() 
59                 { 
60                         return 0; 
61                 }
62                 
63                 function getEventList() 
64                 { 
65                         return array(); 
66                 }
67                 
68                 function getTableList() 
69                 { 
70                         return array(); 
71                 }
72                 
73                 function hasAdminArea() 
74                 { 
75                         return 0; 
76                 }
77
78                 function install() 
79                 {
80                 }
81                 
82                 function unInstall() 
83                 {
84                 }
85                 
86                 function init() 
87                 {
88                 }
89
90                 function doSkinVar($skinType) 
91                 {
92                 }
93                 
94                 function doTemplateVar(&$item) 
95                 {
96                         $args = func_get_args();
97                         array_shift($args);
98                         array_unshift($args, 'template');
99                         call_user_func_array(array(&$this,'doSkinVar'),$args);
100                 }
101                 
102                 function doTemplateCommentsVar(&$item, &$comment) 
103                 {
104                         $args = func_get_args();
105                         array_shift($args);
106                         array_shift($args);
107                         array_unshift($args, 'template');
108                         call_user_func_array(array(&$this,'doSkinVar'),$args);
109                 }
110                 
111                 function doAction($type) 
112                 { 
113                         return _ERROR_PLUGIN_NOSUCHACTION; 
114                 }
115                 
116                 function doIf($key,$value) 
117                 { 
118                         return false; 
119                 }
120                 
121                 function doItemVar (&$item) 
122                 {
123                 }
124
125                 /**
126                  * Checks if a plugin supports a certain feature.
127                  *
128                  * @returns 1 if the feature is reported, 0 if not
129                  * @param $feature
130                  *              Name of the feature. See plugin documentation for more info
131                  *                      'SqlTablePrefix' -> if the plugin uses the sql_table() method to get table names
132                  *                      'HelpPage' -> if the plugin provides a helppage
133                  *                              'SqlApi' -> if the plugin uses the complete sql_* api (must also require nucleuscms 3.5)
134                  */
135                 function supportsFeature($feature) 
136                 {
137                         return 0;
138                 }
139
140                 /**
141                  * Report a list of plugin that is required to function
142                  *
143                  * @returns an array of names of plugin, an empty array indicates no dependency
144                  */
145                 function getPluginDep() 
146                 { 
147                         return array(); 
148                 }
149
150                 // these helper functions should not be redefined in your plugin
151
152                 /**
153                   * Creates a new option for this plugin
154                   *
155                   * @param name
156                   *             A string uniquely identifying your option. (max. length is 20 characters)
157                   * @param description
158                   *             A description that will show up in the nucleus admin area (max. length: 255 characters)
159                   * @param type
160                   *             Either 'text', 'yesno' or 'password'
161                   *             This info is used when showing 'edit plugin options' screens
162                   * @param value
163                   *             Initial value for the option (max. value length is 128 characters)
164                   */
165                 function createOption($name, $desc, $type, $defValue = '', $typeExtras = '') 
166                 {
167                         return $this->_createOption('global', $name, $desc, $type, $defValue, $typeExtras);
168                 }
169                 
170                 function createBlogOption($name, $desc, $type, $defValue = '', $typeExtras = '') 
171                 {
172                         return $this->_createOption('blog', $name, $desc, $type, $defValue, $typeExtras);
173                 }
174                 
175                 function createMemberOption($name, $desc, $type, $defValue = '', $typeExtras = '') 
176                 {
177                         return $this->_createOption('member', $name, $desc, $type, $defValue, $typeExtras);
178                 }
179                 
180                 function createCategoryOption($name, $desc, $type, $defValue = '', $typeExtras = '') 
181                 {
182                         return $this->_createOption('category', $name, $desc, $type, $defValue, $typeExtras);
183                 }
184                 
185                 function createItemOption($name, $desc, $type, $defValue = '', $typeExtras = '') 
186                 {
187                         return $this->_createOption('item', $name, $desc, $type, $defValue, $typeExtras);
188                 }
189
190                 /**
191                   * Removes the option from the database
192                   *
193                   * Note: Options get erased automatically on plugin uninstall
194                   */
195                 function deleteOption($name) 
196                 {
197                         return $this->_deleteOption('global', $name);
198                 }
199                 
200                 function deleteBlogOption($name) 
201                 {
202                         return $this->_deleteOption('blog', $name);
203                 }
204                 
205                 function deleteMemberOption($name) 
206                 {
207                         return $this->_deleteOption('member', $name);
208                 }
209                 
210                 function deleteCategoryOption($name) 
211                 {
212                         return $this->_deleteOption('category', $name);
213                 }
214                 
215                 function deleteItemOption($name) 
216                 {
217                         return $this->_deleteOption('item', $name);
218                 }
219
220                 /**
221                   * Sets the value of an option to something new
222                   */
223                 function setOption($name, $value) 
224                 {
225                         return $this->_setOption('global', 0, $name, $value);
226                 }
227                 
228                 function setBlogOption($blogid, $name, $value) 
229                 {
230                         return $this->_setOption('blog', $blogid, $name, $value);
231                 }
232                 
233                 function setMemberOption($memberid, $name, $value) 
234                 {
235                         return $this->_setOption('member', $memberid, $name, $value);
236                 }
237                 
238                 function setCategoryOption($catid, $name, $value) 
239                 {
240                         return $this->_setOption('category', $catid, $name, $value);
241                 }
242                 
243                 function setItemOption($itemid, $name, $value) {
244                         return $this->_setOption('item', $itemid, $name, $value);
245                 }
246
247                 /**
248                   * Retrieves the current value for an option
249                   */
250                 function getOption($name)
251                 {
252                         // only request the options the very first time. On subsequent requests
253                         // the static collection is used to save SQL queries.
254                         if ( $this->plugin_options == 0 )
255                         {
256                                 $this->plugin_options = array();
257                                 $query = sql_query(
258                                          'SELECT d.oname as name, o.ovalue as value '.
259                                          'FROM '.
260                                          sql_table('plugin_option').' o, '.
261                                          sql_table('plugin_option_desc').' d '.
262                                          'WHERE d.opid='. intval($this->getID()).' AND d.oid=o.oid'
263                                 );
264                                 while ( $row = sql_fetch_object($query) )
265                                 {
266                                         $this->plugin_options[strtolower($row->name)] = $row->value;
267                                 }
268                         }
269                         if ( isset($this->plugin_options[strtolower($name)]) )
270                         {
271                                 return $this->plugin_options[strtolower($name)];
272                         }
273                         else {
274                                 return $this->_getOption('global', 0, $name);
275                         }
276                 }
277
278                 function getBlogOption($blogid, $name) 
279                 {
280                         return $this->_getOption('blog', $blogid, $name);
281                 }
282                 
283                 function getMemberOption($memberid, $name) 
284                 {
285                         return $this->_getOption('member', $memberid, $name);
286                 }
287                 
288                 function getCategoryOption($catid, $name) 
289                 {
290                         return $this->_getOption('category', $catid, $name);
291                 }
292                 
293                 function getItemOption($itemid, $name) 
294                 {
295                         return $this->_getOption('item', $itemid, $name);
296                 }
297
298                 /**
299                  * Retrieves an associative array with the option value for each
300                  * context id
301                  */
302                 function getAllBlogOptions($name) 
303                 {
304                         return $this->_getAllOptions('blog', $name);
305                 }
306                 
307                 function getAllMemberOptions($name) 
308                 {
309                         return $this->_getAllOptions('member', $name);
310                 }
311                 
312                 function getAllCategoryOptions($name) 
313                 {
314                         return $this->_getAllOptions('category', $name);
315                 }
316                 
317                 function getAllItemOptions($name) 
318                 {
319                         return $this->_getAllOptions('item', $name);
320                 }
321
322                 /**
323                  * Retrieves an indexed array with the top (or bottom) of an option
324                  * (delegates to _getOptionTop())
325                  */
326                 function getBlogOptionTop($name, $amount = 10, $sort = 'desc') 
327                 {
328                         return $this->_getOptionTop('blog', $name, $amount, $sort);
329                 }
330                 
331                 function getMemberOptionTop($name, $amount = 10, $sort = 'desc') 
332                 {
333                         return $this->_getOptionTop('member', $name, $amount, $sort);
334                 }
335                 
336                 function getCategoryOptionTop($name, $amount = 10, $sort = 'desc') 
337                 {
338                         return $this->_getOptionTop('category', $name, $amount, $sort);
339                 }
340                 
341                 function getItemOptionTop($name, $amount = 10, $sort = 'desc') 
342                 {
343                         return $this->_getOptionTop('item', $name, $amount, $sort);
344                 }
345
346                 /**
347                   * Returns the plugin ID
348                   * 
349                   * public                                
350                   */
351                 function getID() 
352                 {
353                         return $this->plugid;
354                 }
355
356                 /**
357                   * Returns the URL of the admin area for this plugin (in case there's
358                   * no such area, the returned information is invalid)
359                   * 
360                   * public                                
361                   */
362                 function getAdminURL() 
363                 {
364                         global $CONF;
365                         return $CONF['PluginURL'] . $this->getShortName() . '/';
366                 }
367
368                 /**
369                   * Returns the directory where the admin directory is located and
370                   * where the plugin can maintain his extra files
371                   * 
372                   * public                                
373                   */
374                 function getDirectory() 
375                 {
376                         global $DIR_PLUGINS;
377                         return $DIR_PLUGINS . $this->getShortName() . '/';
378                 }
379
380                 /**
381                   * Derives the short name for the plugin from the classname (all 
382                   * lowercase)
383                   * 
384                   * public                                
385                   */
386                 function getShortName() 
387                 {
388                         return str_replace('np_','',strtolower(get_class($this)));
389                 }
390
391                 /**
392                  *      Clears the option value cache which saves the option values during
393                  *      the plugin execution. This function is usefull if the options has 
394                  *      changed during the plugin execution (especially in association with
395                  *      the PrePluginOptionsUpdate and the PostPluginOptionsUpdate events)
396                  *      
397                  *  public                               
398                  **/                            
399                 function clearOptionValueCache()
400                 {
401                         $this->_aOptionValues = array();
402                         $this->plugin_options = 0;
403                 }
404
405                 // internal functions of the class starts here
406
407                 var $_aOptionValues;    // oid_contextid => value
408                 var $_aOptionToInfo;    // context_name => array('oid' => ..., 'default' => ...)
409                 var $plugin_options;    // see getOption()
410                 var $plugid;                    // plugin id
411
412
413                 /**
414                  * Class constructor: Initializes some internal data
415                  */                                             
416                 function NucleusPlugin() 
417                 {
418                         $this->_aOptionValues = array();        // oid_contextid => value
419                         $this->_aOptionToInfo = array();        // context_name => array('oid' => ..., 'default' => ...)
420                         $this->plugin_options = 0;
421                 }
422
423                 /**
424                  * Retrieves an array of the top (or bottom) of an option from a plugin.
425                  * @author TeRanEX
426                  * @param  string $context the context for the option: item, blog, member,...
427                  * @param  string $name    the name of the option
428                  * @param  int    $amount  how many rows must be returned
429                  * @param  string $sort    desc or asc
430                  * @return array           array with both values and contextid's
431                  * @access private
432                  */
433                 function _getOptionTop($context, $name, $amount = 10, $sort = 'desc') 
434                 {
435                         if ( ($sort != 'desc') && ($sort != 'asc') ) 
436                         {
437                                 $sort= 'desc';
438                         }
439
440                         $oid = $this->_getOID($context, $name);
441
442                         // retrieve the data and return
443                         $q = 'SELECT otype, oextra FROM '.sql_table('plugin_option_desc').' WHERE oid = '.$oid;
444                         $query = sql_query($q);
445
446                         $o = sql_fetch_array($query);
447
448                         if ( ($this->optionCanBeNumeric($o['otype'])) && ($o['oextra'] == 'number' ) ) 
449                         {
450                                 $orderby = 'CAST(ovalue AS SIGNED)';
451                         } 
452                         else 
453                         {
454                                 $orderby = 'ovalue';
455                         }
456                         $q = 'SELECT ovalue value, ocontextid id FROM '.sql_table('plugin_option').' WHERE oid = '.$oid.' ORDER BY '.$orderby.' '.$sort.' LIMIT 0,'.intval($amount);
457                         $query = sql_query($q);
458
459                         // create the array
460                         $i = 0;
461                         $top = array();
462                         while( $row = sql_fetch_array($query) ) 
463                         {
464                                 $top[$i++] = $row;
465                         }
466
467                         // return the array (duh!)
468                         return $top;
469                 }
470
471                 /**
472                  * Creates an option in the database table plugin_option_desc
473                  *               
474                  * private
475                  */                                             
476                 function _createOption($context, $name, $desc, $type, $defValue, $typeExtras = '') 
477                 {
478                         // create in plugin_option_desc
479                         $query = 'INSERT INTO ' . sql_table('plugin_option_desc')
480                                    .' (opid, oname, ocontext, odesc, otype, odef, oextra)'
481                                    .' VALUES ('.intval($this->plugid)
482                                                          .', \''.sql_real_escape_string($name).'\''
483                                                          .', \''.sql_real_escape_string($context).'\''
484                                                          .', \''.sql_real_escape_string($desc).'\''
485                                                          .', \''.sql_real_escape_string($type).'\''
486                                                          .', \''.sql_real_escape_string($defValue).'\''
487                                                          .', \''.sql_real_escape_string($typeExtras).'\')';
488                         sql_query($query);
489                         $oid = sql_insert_id();
490
491                         $key = $context . '_' . $name;
492                         $this->_aOptionToInfo[$key] = array('oid' => $oid, 'default' => $defValue);
493                         return 1;
494                 }
495
496
497                 /**
498                  * Deletes an option from the database tables
499                  * plugin_option and plugin_option_desc 
500                  *
501                  * private               
502                  */                                             
503                 function _deleteOption($context, $name) 
504                 {
505                         $oid = $this->_getOID($context, $name);
506                         if ( !$oid ) 
507                         {
508                                 return 0; // no such option
509                         }
510
511                         // delete all things from plugin_option
512                         sql_query('DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid=' . $oid);
513
514                         // delete entry from plugin_option_desc
515                         sql_query('DELETE FROM ' . sql_table('plugin_option_desc') . ' WHERE oid=' . $oid);
516
517                         // clear from cache
518                         unset($this->_aOptionToInfo[$context . '_' . $name]);
519                         $this->_aOptionValues = array();
520                         return 1;
521                 }
522
523                 /**
524                  * Update an option in the database table plugin_option
525                  *               
526                  * returns: 1 on success, 0 on failure
527                  * private
528                  */
529                 function _setOption($context, $contextid, $name, $value) 
530                 {
531                         global $manager;
532
533                         $oid = $this->_getOID($context, $name);
534                         if ( !$oid ) 
535                         {
536                                 return 0;
537                         }
538
539                         // check if context id exists
540                         switch ( $context ) 
541                         {
542                                 case 'member':
543                                         if ( !MEMBER::existsID($contextid) ) 
544                                         {
545                                                 return 0;
546                                         }
547                                         break;
548                                 case 'blog':
549                                         if ( !$manager->existsBlogID($contextid) ) 
550                                         {
551                                                 return 0;
552                                         }
553                                         break;
554                                 case 'category':
555                                         if ( !$manager->existsCategory($contextid) ) 
556                                         {
557                                                 return 0;
558                                         }
559                                         break;
560                                 case 'item':
561                                         if ( !$manager->existsItem($contextid, true, true) ) 
562                                         {
563                                                 return 0;
564                                         }
565                                         break;
566                                 case 'global':
567                                         if ( $contextid != 0 ) 
568                                         {
569                                                 return 0;
570                                         }
571                                         break;
572                         }
573
574
575                         // update plugin_option
576                         sql_query('DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid='.intval($oid) . ' and ocontextid='. intval($contextid));
577                         sql_query('INSERT INTO ' . sql_table('plugin_option') . ' (ovalue, oid, ocontextid) VALUES (\''.sql_real_escape_string($value).'\', '. intval($oid) . ', ' . intval($contextid) . ')');
578
579                         // update cache
580                         $this->_aOptionValues[$oid . '_' . $contextid] = $value;
581                         if ( $context == 'global')
582                         {
583                                 $this->plugin_options[strtolower($name)] = $value;
584                         }
585
586                         return 1;
587                 }
588
589                 /**
590                  * Get an option from Cache or database
591                  *       - if not in the option Cache read it from the database
592                  *   - if not in the database write default values into the database
593                  *                
594                  * private               
595                  */                                             
596                 function _getOption($context, $contextid, $name) 
597                 {
598                         $oid = $this->_getOID($context, $name);
599                         if ( !$oid ) 
600                         {
601                                 return '';
602                         }
603
604
605                         $key = $oid . '_' . $contextid;
606
607                         if ( isset($this->_aOptionValues[$key]) )
608                         {
609                                 return $this->_aOptionValues[$key];
610                         }
611
612                         // get from DB
613                         $res = sql_query('SELECT ovalue FROM ' . sql_table('plugin_option') . ' WHERE oid='.intval($oid).' and ocontextid=' . intval($contextid));
614
615                         if ( !$res || (sql_num_rows($res) == 0) ) 
616                         {
617                                 $defVal = $this->_getDefVal($context, $name);
618                                 $this->_aOptionValues[$key] = $defVal;
619
620                                 // fill DB with default value
621                                 $query = 'INSERT INTO ' . sql_table('plugin_option') . ' (oid,ocontextid,ovalue)'
622                                            .' VALUES ('.intval($oid).', '.intval($contextid).', \''.sql_real_escape_string($defVal).'\')';
623                                 sql_query($query);
624                         }
625                         else 
626                         {
627                                 $o = sql_fetch_object($res);
628                                 $this->_aOptionValues[$key] = $o->ovalue;
629                         }
630
631                         return $this->_aOptionValues[$key];
632                 }
633
634                 /**
635                  * Returns assoc array with all values for a given option 
636                  * (one option per possible context id)
637                  * 
638                  * private                               
639                  */
640                 function _getAllOptions($context, $name) 
641                 {
642                         $oid = $this->_getOID($context, $name);
643                         if ( !$oid ) 
644                         {
645                                 return array();
646                         }
647                         $defVal = $this->_getDefVal($context, $name);
648
649                         $aOptions = array();
650                         switch ( $context ) 
651                         {
652                                 case 'blog':
653                                         $r = sql_query('SELECT bnumber as contextid FROM ' . sql_table('blog'));
654                                         break;
655                                 case 'category':
656                                         $r = sql_query('SELECT catid as contextid FROM ' . sql_table('category'));
657                                         break;
658                                 case 'member':
659                                         $r = sql_query('SELECT mnumber as contextid FROM ' . sql_table('member'));
660                                         break;
661                                 case 'item':
662                                         $r = sql_query('SELECT inumber as contextid FROM ' . sql_table('item'));
663                                         break;
664                         }
665                         if ( $r ) 
666                         {
667                                 while ( $o = sql_fetch_object($r) )
668                                 {
669                                         $aOptions[$o->contextid] = $defVal;
670                                 }
671                         }
672
673                         $res = sql_query('SELECT ocontextid, ovalue FROM ' . sql_table('plugin_option') . ' WHERE oid=' . $oid);
674                         while ( $o = sql_fetch_object($res) )
675                         {
676                                 $aOptions[$o->ocontextid] = $o->ovalue;
677                         }
678
679                         return $aOptions;
680                 }
681
682                 /**
683                  * Gets the 'option identifier' that corresponds to a given option name.
684                  * When this method is called for the first time, all the OIDs for the plugin
685                  * are loaded into memory, to avoid re-doing the same query all over.
686                  */
687                 function _getOID($context, $name) 
688                 {
689                         $key = $context . '_' . $name;
690                         $info = $this->_aOptionToInfo[$key];
691                         if ( is_array($info) ) 
692                         {
693                                 return $info['oid'];
694                         }
695
696                         // load all OIDs for this plugin from the database
697                         $this->_aOptionToInfo = array();
698                         $query = 'SELECT oid, oname, ocontext, odef FROM ' . sql_table('plugin_option_desc') . ' WHERE opid=' . intval($this->plugid);
699                         $res = sql_query($query);
700                         while ( $o = sql_fetch_object($res) ) 
701                         {
702                                 $k = $o->ocontext . '_' . $o->oname;
703                                 $this->_aOptionToInfo[$k] = array('oid' => $o->oid, 'default' => $o->odef);
704                         }
705                         sql_free_result($res);
706
707                         return $this->_aOptionToInfo[$key]['oid'];
708                 }
709                 function _getDefVal($context, $name) 
710                 {
711                         $key = $context . '_' . $name;
712                         $info = $this->_aOptionToInfo[$key];
713                         if ( is_array($info) ) 
714                         {
715                                 return $info['default'];
716                         }
717                 }
718
719
720                 /**
721                  * Deletes all option values for a given context and contextid
722                  * (used when e.g. a blog, member or category is deleted)
723                  *
724                  * (static method)
725                  */
726                 function _deleteOptionValues($context, $contextid) 
727                 {
728                         // delete all associated plugin options
729                         $aOIDs = array();
730                                 // find ids
731                         $query = 'SELECT oid FROM '.sql_table('plugin_option_desc') . ' WHERE ocontext=\''.sql_real_escape_string($context).'\'';
732                         $res = sql_query($query);
733                         while ( $o = sql_fetch_object($res) )
734                         {
735                                 array_push($aOIDs, $o->oid);
736                         }
737                         sql_free_result($res);
738                                 // delete those options. go go go
739                         if ( count($aOIDs) > 0 ) 
740                         {
741                                 $query = 'DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid in ('.implode(',',$aOIDs).') and ocontextid=' . intval($contextid);
742                                 sql_query($query);
743                         }
744                 }
745
746                 /**
747                  * splits the option's typeextra field (at ;'s) to split the meta collection
748                  * @param string $typeExtra the value of the typeExtra field of an option
749                  * @return array array of the meta-key/value-pairs
750                  * @author TeRanEX
751                  * @static
752                  */
753                 function getOptionMeta($typeExtra) 
754                 {
755                         $tmpMeta = i18n::explode(';', $typeExtra);
756                         $meta = array();
757                         for ( $i = 0; $i < count($tmpMeta); $i++ ) 
758                         {
759                                 if ( ($i == 0) && (!strstr($tmpMeta[0], '=')) ) 
760                                 {
761                                         // we have the select-list
762                                         $meta['select'] = $tmpMeta[0];
763                                 } 
764                                 else 
765                                 {
766                                         $tmp = i18n::explode('=', $tmpMeta[$i]);
767                                         $meta[$tmp[0]] = $tmp[1];
768                                 }
769                         }
770                         return $meta;
771                 }
772
773                 /**
774                  * filters the selectlists out of the meta collection
775                  * @param string $typeExtra the value of the typeExtra field of an option
776                  * @return string the selectlist
777                  * @author TeRanEX
778                  */
779                 function getOptionSelectValues($typeExtra) 
780                 {
781                         $meta = NucleusPlugin::getOptionMeta($typeExtra);
782                         //the select list must always be the first part
783                         return $meta['select'];
784                 }
785
786                 /**
787                  * checks if the eventlist in the database is up-to-date
788                  * @return bool if it is up-to-date it return true, else false
789                  * @author TeRanEX
790                  */
791                 function subscribtionListIsUptodate() 
792                 {
793                         $res = sql_query('SELECT event FROM '.sql_table('plugin_event').' WHERE pid = '.$this->getID());
794                         $ev = array();
795                         while( $a = sql_fetch_array($res) ) 
796                         {
797                                 array_push($ev, $a['event']);
798                         }
799                         if ( count($ev) != count($this->getEventList()) ) 
800                         {
801                                 return false;
802                         }
803                         $d = array_diff($ev, $this->getEventList());
804                         if ( count($d) > 0 ) 
805                         {
806                                 // there are differences so the db is not up-to-date
807                                 return false;
808                         }
809                         return true;
810                 }
811
812                 /**
813                  * @param $aOptions: array ( 'oid' => array( 'contextid' => 'value'))
814                  *        (taken from request using requestVar())
815                  * @param $newContextid: integer (accepts a contextid when it is for a new
816                  *        contextid there was no id available at the moment of writing the
817                  *        formcontrols into the page (by ex: itemOptions for new item)
818                  * @static
819                  */
820                 function _applyPluginOptions(&$aOptions, $newContextid = 0) 
821                 {
822                         global $manager;
823                         if ( !is_array($aOptions) ) 
824                         {
825                                 return;
826                         }
827
828                         foreach ( $aOptions as $oid => $values ) 
829                         {
830
831                                 // get option type info
832                                 $query = 'SELECT opid, oname, ocontext, otype, oextra, odef FROM ' . sql_table('plugin_option_desc') . ' WHERE oid=' . intval($oid);
833                                 $res = sql_query($query);
834                                 if ( $o = sql_fetch_object($res) )
835                                 {
836                                         foreach ( $values as $key => $value ) 
837                                         {
838                                                 // avoid overriding the key used by foreach statement
839                                                 $contextid=$key;
840
841                                                 // retreive any metadata
842                                                 $meta = NucleusPlugin::getOptionMeta($o->oextra);
843
844                                                 // if the option is readonly or hidden it may not be saved
845                                                 if ( ($meta['access'] != 'readonly') && ($meta['access'] != 'hidden') ) 
846                                                 {
847
848                                                         $value = undoMagic($value);     // value comes from request
849
850                                                         switch ( $o->otype ) 
851                                                         {
852                                                                 case 'yesno':
853                                                                         if ( ($value != 'yes') && ($value != 'no') ) 
854                                                                         {
855                                                                                 $value = 'no';
856                                                                         }
857                                                                         break;
858                                                                 default:
859                                                                         break;
860                                                         }
861
862                                                         // check the validity of numerical options
863                                                         if ( ($meta['datatype'] == 'numerical') && (!is_numeric($value)) ) 
864                                                         {
865                                                                 //the option must be numeric, but the it isn't
866                                                                 //use the default for this option
867                                                                 $value = $o->odef;
868                                                         }
869
870                                                         // decide wether we are using the contextid of newContextid
871                                                         if ( $newContextid != 0 ) 
872                                                         {
873                                                                 $contextid = $newContextid;
874                                                         }
875
876                                                         //trigger event PrePluginOptionsUpdate to give the plugin the
877                                                         //possibility to change/validate the new value for the option
878                                                         $manager->notify('PrePluginOptionsUpdate',array('context' => $o->ocontext, 'plugid' => $o->opid, 'optionname' => $o->oname, 'contextid' => $contextid, 'value' => &$value));
879
880                                                         // delete the old value for the option
881                                                         sql_query('DELETE FROM '.sql_table('plugin_option').' WHERE oid='.intval($oid).' AND ocontextid='.intval($contextid));
882                                                         sql_query('INSERT INTO '.sql_table('plugin_option')." (oid, ocontextid, ovalue) VALUES (".intval($oid).",".intval($contextid).",'" . sql_real_escape_string($value) . "')");
883                                                 }
884                                         }
885                                 }
886                                 // clear option value cache if the plugin object is already loaded
887                                 if ( is_object($o) ) 
888                                 {
889                                         $plugin=& $manager->pidLoaded($o->opid);
890                                         if ( $plugin ) 
891                                         {
892                                                 $plugin->clearOptionValueCache();
893                                         }
894                                 }
895                         }
896                 }
897         }
898 ?>