OSDN Git Service

FIX: リファレンスにまつわるコードを修正
[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 1866 2012-05-20 13:21:55Z sakamocchi $
21  */
22 abstract class NucleusPlugin
23 {
24         // these public functions should to be redefined in your plugin
25         public function getName()
26         {
27                 return __CLASS__;
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_* or DB::* 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 = DB::getResult($query);
267                         foreach ( $result as $row )
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                 $row = DB::getRow($query);
466                 
467                 if ( ($this->optionCanBeNumeric($row['otype'])) && ($row['oextra'] == 'number' ) )
468                 {
469                         $orderby = 'CAST(ovalue AS SIGNED)';
470                 }
471                 else
472                 {
473                         $orderby = 'ovalue';
474                 }
475                 $query = "SELECT ovalue value, ocontextid id FROM %s WHERE oid = %d ORDER BY %s %s LIMIT 0,%d;";
476                 $query = sprintf($query, sql_table('plugin_option'), $oid, $orderby, $sort, (integer) $amount);
477                 $result = DB::getResult($query);
478                 
479                 // create the array
480                 $i = 0;
481                 $top = array();
482                 foreach( $result as $row )
483                 {
484                         $top[$i++] = $row;
485                 }
486                 
487                 // return the array (duh!)
488                 return $top;
489         }
490         
491         /**
492          * Creates an option in the database table plugin_option_desc
493          *      
494          * private
495          */
496         final protected function create_option($context, $name, $desc, $type, $defValue, $typeExtras = '')
497         {
498                 // create in plugin_option_desc
499                 $query = 'INSERT INTO ' . sql_table('plugin_option_desc')
500                                 .' (opid, oname, ocontext, odesc, otype, odef, oextra)'
501                                 .' VALUES ('.intval($this->plugid)
502                                         .', '.DB::quoteValue($name)
503                                         .', '.DB::quoteValue($context)
504                                         .', '.DB::quoteValue($desc)
505                                         .', '.DB::quoteValue($type)
506                                         .', '.DB::quoteValue($defValue)
507                                         .', '.DB::quoteValue($typeExtras).')';
508                 DB::execute($query);
509                 $oid = DB::getInsertId();
510                 
511                 $key = $context . '_' . $name;
512                 $this->option_info[$key] = array('oid' => $oid, 'default' => $defValue);
513                 return 1;
514         }
515         
516         /**
517          * Deletes an option from the database tables
518          * plugin_option and plugin_option_desc
519          *
520          * private
521          */
522         final protected function delete_option($context, $name)
523         {
524                 $oid = $this->get_option_id($context, $name);
525                 if ( !$oid )
526                 {
527                         return 0; // no such option
528                 }
529                 
530                 // delete all things from plugin_option
531                 $query = "DELETE FROM %s WHERE oid=%d;";
532                 $query = sprintf($query, sql_table('plugin_option'), (integer) $oid);
533                 DB::execute($query);
534                 
535                 // delete entry from plugin_option_desc
536                 $query = "DELETE FROM %s WHERE oid=%d;";
537                 $query = sprintf($query, sql_table('plugin_option_desc'), $oid);
538                 DB::execute($query);
539                 
540                 // clear from cache
541                 unset($this->option_info["{$context}_{$name}"]);
542                 $this->option_values = array();
543                 return 1;
544         }
545         
546         /**
547          * Update an option in the database table plugin_option
548          *              
549          * returns: 1 on success, 0 on failure
550          * private
551          */
552         final protected function set_option($context, $contextid, $name, $value)
553         {
554                 global $manager;
555                 
556                 $oid = $this->get_option_id($context, $name);
557                 if ( !$oid )
558                 {
559                         return 0;
560                 }
561                 
562                 // check if context id exists
563                 switch ( $context )
564                 {
565                         case 'member':
566                                 if ( !Member::existsID($contextid) )
567                                 {
568                                         return 0;
569                                 }
570                                 break;
571                         case 'blog':
572                                 if ( !$manager->existsBlogID($contextid) )
573                                 {
574                                         return 0;
575                                 }
576                                 break;
577                         case 'category':
578                                 if ( !$manager->existsCategory($contextid) )
579                                 {
580                                         return 0;
581                                 }
582                                 break;
583                         case 'item':
584                                 if ( !$manager->existsItem($contextid, true, true) )
585                                 {
586                                         return 0;
587                                 }
588                                 break;
589                         case 'global':
590                                 if ( $contextid != 0 )
591                                 {
592                                         return 0;
593                                 }
594                                 break;
595                 }
596                 
597                 // update plugin_option
598                 $query = "DELETE FROM %s WHERE oid=%d and ocontextid=%d;";
599                 $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid);
600                 DB::execute($query);
601                 
602                 $query = "INSERT INTO %s (ovalue, oid, ocontextid) VALUES (%s, %d, %d);";
603                 $query = sprintf($query, sql_table('plugin_option'), DB::quoteValue($value), $oid, $contextid);
604                 DB::execute($query);
605                 
606                 // update cache
607                 $this->option_values["{$oid}_{$contextid}"] = $value;
608                 if ( $context == 'global' )
609                 {
610                         $this->plugin_options[strtolower($name)] = $value;
611                 }
612                 
613                 return 1;
614         }
615         
616         /**
617          * Get an option from Cache or database
618          *       - if not in the option Cache read it from the database
619          *   - if not in the database write default values into the database
620          *              
621          * private              
622          */                                             
623         final protected function get_option($context, $contextid, $name)
624         {
625                 $oid = $this->get_option_id($context, $name);
626                 if ( !$oid )
627                 {
628                         return '';
629                 }
630                 
631                 $key = "{$oid}_{$contextid}";
632                 
633                 if ( isset($this->option_values[$key]) )
634                 {
635                         return $this->option_values[$key];
636                 }
637                 
638                 // get from DB
639                 $query = "SELECT ovalue FROM %s WHERE oid=%d and ocontextid=%d;";
640                 $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid);
641                 $result = DB::getResult($query);
642                 
643                 if ( !$result || ($result->rowCount() == 0) )
644                 {
645                         // fill DB with default value
646                         $this->option_values[$key] = $this->get_default_value($context, $name);
647                         $query = "INSERT INTO %s (oid, ocontextid, ovalue) VALUES (%d, %d, %s);";
648                         $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid, DB::quoteValue($this->option_values[$key]));
649                         DB::execute($query);
650                 }
651                 else
652                 {
653                         $row = $result->fetch();
654                         $this->option_values[$key] = $row['ovalue'];
655                 }
656                 
657                 return $this->option_values[$key];
658         }
659         
660         /**
661          * Returns assoc array with all values for a given option
662          * (one option per possible context id)
663          *
664          * private                              
665          */
666         final protected function get_all_options($context, $name)
667         {
668                 $oid = $this->get_option_id($context, $name);
669                 if ( !$oid )
670                 {
671                         return array();
672                 }
673                 $default_value = $this->get_default_value($context, $name);
674                 
675                 $options = array();
676                 $query = "SELECT %s as contextid FROM %s;";
677                 switch ( $context )
678                 {
679                         case 'blog':
680                                 $query = sprintf($query, 'bnumber', sql_table('blog'));
681                                 break;
682                         case 'category':
683                                 $query = sprintf($query, 'catid', sql_table('category'));
684                                 break;
685                         case 'member':
686                                 $query = sprintf($query, 'mnumber', sql_table('member'));
687                                 break;
688                         case 'item':
689                                 $query = sprintf($query, 'inumber', sql_table('item'));
690                                 break;
691                 }
692                 
693                 $result = DB::getResult($query);
694                 if ( $result )
695                 {
696                         foreach ( $result as $row )
697                         {
698                                 $options[$row['contextid']] = $default_value;
699                         }
700                 }
701                 
702                 $query = "SELECT ocontextid, ovalue FROM %s WHERE oid=%d;";
703                 $query = sprintf($query, sql_table('plugin_option'), $oid);
704                 $result = DB::getResult($query);
705                 foreach ( $result as $row )
706                 {
707                         $options[$row['ocontextid']] = $row['ovalue'];
708                 }
709
710                 return $options;
711         }
712         
713         /**
714          * NucleusPlugin::get_option_id
715          * 
716          * Gets the 'option identifier' that corresponds to a given option name.
717          * When this method is called for the first time, all the OIDs for the plugin
718          * are loaded into memory, to avoid re-doing the same query all over.
719          * 
720          * @param       string  $context        option context
721          * @param       string  $name           plugin name
722          * @return              integer option id
723          */
724         final protected function get_option_id($context, $name)
725         {
726                 $key = "{$context}_{$name}";
727                 
728                 if ( array_key_exists($key, $this->option_info)
729                  && array_key_exists('oid', $this->option_info[$key]) )
730                 {
731                         return $this->option_info[$key]['oid'];
732                 }
733                 
734                 // load all OIDs for this plugin from the database
735                 $this->option_info = array();
736                 $query = "SELECT oid, oname, ocontext, odef FROM %s WHERE opid=%d;";
737                 $query = sprintf($query, sql_table('plugin_option_desc'), $this->plugid);
738                 $result = DB::getResult($query);
739                 foreach ( $result as $row )
740                 {
741                         $k = $row['ocontext'] . '_' . $row['oname'];
742                         $this->option_info[$k] = array('oid' => $row['oid'], 'default' => $row['odef']);
743                 }
744                 $result->closeCursor();
745                 
746                 return $this->option_info[$key]['oid'];
747         }
748         final protected function get_default_value($context, $name)
749         {
750                 $key = $context . '_' . $name;
751                 
752                 if ( array_key_exists($key, $this->option_info)
753                  && array_key_exists('default', $this->option_info[$key]) )
754                 {
755                         return $this->option_info[$key]['default'];
756                 }
757                 return;
758         }
759         
760         /**
761          * NucleusPlugin::delete_option_values()
762          * Deletes all option values for a given context and contextid
763          * (used when e.g. a blog, member or category is deleted)
764          *
765          *@static
766          *@param        String  $context        global/blog/category/item/member
767          *@param        Integer $contextid              ID
768          *@return       Void
769          */
770         static public function delete_option_values($context, $contextid)
771         {
772                 // delete all associated plugin options
773                 $aOIDs = array();
774                 // find ids
775                 $query = "SELECT oid FROM %s WHERE ocontext=%s;";
776                 $query = sprintf($query, sql_table('plugin_option_desc'), DB::quoteValue($context));
777                 
778                 $result = DB::getResult($query);
779                 foreach ( $result as $row )
780                 {
781                         array_push($aOIDs, $row['oid']);
782                 }
783                 $result->closeCursor();
784                 // delete those options. go go go
785                 if ( count($aOIDs) > 0 )
786                 {
787                         $query = "DELETE FROM %s WHERE oid in (%s) and ocontextid=%d;";
788                         $query = sprintf($query, sql_table('plugin_option'), implode(',',$aOIDs), (integer) $contextid);
789                         DB::execute($query);
790                 }
791                 return;
792         }
793         
794         /**
795          * NucleusPlugin::getOptionMeta()
796          * splits the option's typeextra field (at ;'s) to split the meta collection
797          * 
798          * @static
799          * @param string $typeExtra the value of the typeExtra field of an option
800          * @return array array of the meta-key/value-pairs
801          */
802         static public function getOptionMeta($typeExtra)
803         {
804                 $meta = array();
805                 
806                 /* 1. if $typeExtra includes delimiter ';', split it to tokens */
807                 $tokens = preg_split('#;#', $typeExtra);
808                 
809                 /*
810                  * 2. if each of tokens includes "=", it consists of key => value
811                  *    else it's 'select' option
812                  */
813                 foreach ( $tokens as $token )
814                 {
815                         $matches = array();
816                         if ( preg_match("#^([^=]+)?=([^=]+)?$#", $token, $matches) )
817                         {
818                                 $meta[$matches[1]] = $matches[2];
819                         }
820                         else
821                         {
822                                 $meta['select'] = $token;
823                         }
824                 }
825                 return $meta;
826         }
827         
828         /**
829          * NucleusPlugin::getOptionSelectValues()
830          * filters the selectlists out of the meta collection
831          * 
832          * @static
833          * @param string $typeExtra the value of the typeExtra field of an option
834          * @return string the selectlist
835          */
836         static public function getOptionSelectValues($typeExtra)
837         {
838                 $meta = NucleusPlugin::getOptionMeta($typeExtra);
839                 
840                 if ( array_key_exists('select', $meta) )
841                 {
842                         return $meta['select'];
843                 }
844                 return;
845         }
846         
847         /**
848          * checks if the eventlist in the database is up-to-date
849          * @return bool if it is up-to-date it return true, else false
850          * @author TeRanEX
851          */
852         public function subscribtionListIsUptodate()
853         {
854                 $res = DB::getResult('SELECT event FROM '.sql_table('plugin_event').' WHERE pid = '.$this->plugid);
855                 $ev = array();
856                 foreach ( $res as $row )
857                 {
858                         array_push($ev, $row['event']);
859                 }
860                 if ( count($ev) != count($this->getEventList()) )
861                 {
862                         return false;
863                 }
864                 $d = array_diff($ev, $this->getEventList());
865                 if ( count($d) > 0 )
866                 {
867                         // there are differences so the db is not up-to-date
868                         return false;
869                 }
870                 return true;
871         }
872         
873         /**
874          * NucleusPlugin::apply_plugin_options()
875          * Update its entry in database table
876          * 
877          * @static
878          * @param       $options: array ( 'oid' => array( 'contextid' => 'value'))
879          *                       (taken from request using requestVar())
880          * @param       $new_contextid: integer (accepts a contextid when it is for a new
881          *                       contextid there was no id available at the moment of writing the
882          *                        formcontrols into the page (by ex: itemOptions for new item)
883          * @return void
884          */
885         static public function apply_plugin_options(&$options, $new_contextid = 0)
886         {
887                 global $manager;
888                 
889                 if ( !is_array($options) )
890                 {
891                         return;
892                 }
893                 
894                 foreach ( $options as $oid => $values )
895                 {
896                         // get option type info
897                         $query = "SELECT opid, oname, ocontext, otype, oextra, odef FROM %s WHERE oid=%d;";
898                         $query = sprintf($query, sql_table('plugin_option_desc'), (integer) $oid);
899                         $result = DB::getRow($query);
900                         if ( $result )
901                         {
902                                 foreach ( $values as $id => $value )
903                                 {
904                                         // decide wether we are using the contextid of newContextid
905                                         if ( $new_contextid != 0 )
906                                         {
907                                                 $contextid = $new_contextid;
908                                         }
909                                         else
910                                         {
911                                                 $contextid = $id;
912                                         }
913                                         
914                                         // retreive any metadata
915                                         $meta = NucleusPlugin::getOptionMeta($result['oextra']);
916                                         
917                                         // if the option is readonly or hidden it may not be saved
918                                         if ( array_key_exists('access', $meta)
919                                          && in_array($meta['access'], array('readonly', 'hidden')) )
920                                         {
921                                                 return;
922                                         }
923                                         
924                                         // value comes from request
925                                         $value = undoMagic($value);
926                                         
927                                         /* validation the value according to its type */
928                                         switch ( $result['otype'] )
929                                         {
930                                                 case 'yesno':
931                                                         if ( ($value != 'yes') && ($value != 'no') )
932                                                         {
933                                                                 $value = 'no';
934                                                         }
935                                                         break;
936                                                 case 'text':
937                                                 case 'select':
938                                                         if ( array_key_exists('datatype', $meta)
939                                                          && ($meta['datatype'] == 'numerical') && ($value != (integer) $value) )
940                                                         {
941                                                                 $value = (integer) $result['odef'];
942                                                         }
943                                                         break;
944                                                 case 'password':
945                                                 case 'textarea':
946                                                 default:
947                                                         break;
948                                         }
949                                         
950                                         /*
951                                          * trigger event PrePluginOptionsUpdate to give the plugin the
952                                          * possibility to change/validate the new value for the option
953                                          */
954                                         $data = array(
955                                                 'context'               => $result['ocontext'],
956                                                 'plugid'                => $result['opid'],
957                                                 'optionname'    => $result['oname'],
958                                                 'contextid'     => $contextid,
959                                                 'value'         => &$value);
960                                         $manager->notify('PrePluginOptionsUpdate', $data);
961                                         
962                                         // delete and insert its fields of table in database
963                                         $query = "DELETE FROM %s WHERE oid=%d AND ocontextid=%d;";
964                                         $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid);
965                                         DB::execute($query);
966                                         $query = "INSERT INTO %s (oid, ocontextid, ovalue) VALUES (%d, %d, %s);";
967                                         $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid, DB::quoteValue($value));
968                                         DB::execute($query);
969                                         
970                                         // clear option value cache if the plugin object is already loaded
971                                         $plugin=& $manager->pidLoaded($result['opid']);
972                                         if ( $plugin )
973                                         {
974                                                 $plugin->clearOptionValueCache();
975                                         }
976                                         
977                                         continue;
978                                 }
979                         }
980                         continue;
981                 }
982                 return;
983         }
984 }