OSDN Git Service

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