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->getID());
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          * Returns the plugin ID
352          *
353          * public
354          */
355         final public function getID()
356         {
357                 return $this->plugid;
358         }
359         
360         /**
361          * Returns the URL of the admin area for this plugin (in case there's
362          * no such area, the returned information is invalid)
363          *
364          * public
365          */
366         final public function getAdminURL()
367         {
368                 global $CONF;
369                 return $CONF['PluginURL'] . $this->getShortName() . '/';
370         }
371         
372         /**
373          * Returns the directory where the admin directory is located and
374          * where the plugin can maintain his extra files
375          *
376          * public
377          */
378         final public function getDirectory()
379         {
380                 global $DIR_PLUGINS;
381                 return $DIR_PLUGINS . $this->getShortName() . '/';
382         }
383         
384         /**
385          * Derives the short name for the plugin from the classname (all
386          * lowercase)
387          *
388          * public
389          */
390         final public function getShortName()
391         {
392                 return str_replace('np_','',strtolower(get_class($this)));
393         }
394         
395         /**
396          *      Clears the option value cache which saves the option values during
397          *      the plugin execution. This function is usefull if the options has
398          *      changed during the plugin execution (especially in association with
399          *      the PrePluginOptionsUpdate and the PostPluginOptionsUpdate events)
400          *      
401          *  public
402          **/
403         final public function clearOptionValueCache()
404         {
405                 $this->option_values = array();
406                 $this->plugin_options = 0;
407                 return;
408         }
409         
410         // internal functions of the class starts here
411         
412         protected $option_values;       // oid_contextid => value
413         protected $option_info; // context_name => array('oid' => ..., 'default' => ...)
414         protected $plugin_options;      // see getOption()
415         /* TODO: This should be protected member */
416         public $plugid;                 // plugin id
417         
418         /**
419          * Class constructor: Initializes some internal data
420          */
421         public function __construct()
422         {
423                 $this->option_values = array(); // oid_contextid => value
424                 $this->option_info = array();   // context_name => array('oid' => ..., 'default' => ...)
425                 $this->plugin_options = 0;
426         }
427         
428         /**
429          * Retrieves an array of the top (or bottom) of an option from a plugin.
430          * @author TeRanEX
431          * @param  string $context the context for the option: item, blog, member,...
432          * @param  string $name    the name of the option
433          * @param  int    $amount  how many rows must be returned
434          * @param  string $sort    desc or asc
435          * @return array           array with both values and contextid's
436          * @access private
437          */
438         final protected function get_option_top($context, $name, $amount = 10, $sort = 'desc')
439         {
440                 if ( ($sort != 'desc') && ($sort != 'asc') )
441                 {
442                         $sort= 'desc';
443                 }
444                 
445                 $oid = $this->get_option_id($context, $name);
446                 
447                 // retrieve the data and return
448                 $query = "SELECT otype, oextra FROM %s WHERE oid = %d;";
449                 $query = sprintf($query, sql_table('plugin_option_desc'), $oid);
450                 $result = sql_query($query);
451                 
452                 $o = sql_fetch_array($result);
453                 
454                 if ( ($this->optionCanBeNumeric($o['otype'])) && ($o['oextra'] == 'number' ) )
455                 {
456                         $orderby = 'CAST(ovalue AS SIGNED)';
457                 }
458                 else
459                 {
460                         $orderby = 'ovalue';
461                 }
462                 $query = "SELECT ovalue value, ocontextid id FROM %s WHERE oid = %d ORDER BY %s %s LIMIT 0,%d;";
463                 $query = sprintf($query, sql_table('plugin_option'), $oid, $orderby, $sort, (integer) $amount);
464                 $result = sql_query($query);
465                 
466                 // create the array
467                 $i = 0;
468                 $top = array();
469                 while( $row = sql_fetch_array($result) )
470                 {
471                         $top[$i++] = $row;
472                 }
473                 
474                 // return the array (duh!)
475                 return $top;
476         }
477         
478         /**
479          * Creates an option in the database table plugin_option_desc
480          *      
481          * private
482          */
483         final protected function create_option($context, $name, $desc, $type, $defValue, $typeExtras = '')
484         {
485                 // create in plugin_option_desc
486                 $query = 'INSERT INTO ' . sql_table('plugin_option_desc')
487                                 .' (opid, oname, ocontext, odesc, otype, odef, oextra)'
488                                 .' VALUES ('.intval($this->plugid)
489                                         .', \''.sql_real_escape_string($name).'\''
490                                         .', \''.sql_real_escape_string($context).'\''
491                                         .', \''.sql_real_escape_string($desc).'\''
492                                         .', \''.sql_real_escape_string($type).'\''
493                                         .', \''.sql_real_escape_string($defValue).'\''
494                                         .', \''.sql_real_escape_string($typeExtras).'\');';
495                 sql_query($query);
496                 $oid = sql_insert_id();
497                 
498                 $key = $context . '_' . $name;
499                 $this->option_info[$key] = array('oid' => $oid, 'default' => $defValue);
500                 return 1;
501         }
502         
503         /**
504          * Deletes an option from the database tables
505          * plugin_option and plugin_option_desc
506          *
507          * private
508          */
509         final protected function delete_option($context, $name)
510         {
511                 $oid = $this->get_option_id($context, $name);
512                 if ( !$oid )
513                 {
514                         return 0; // no such option
515                 }
516                 
517                 // delete all things from plugin_option
518                 $query = "DELETE FROM %s WHERE oid=%d;";
519                 $query = sprintf($query, sql_table('plugin_option'), (integer) $oid);
520                 sql_query($query);
521                 
522                 // delete entry from plugin_option_desc
523                 $query = "DELETE FROM %s WHERE oid=%d;";
524                 $query = sprintf($query, sql_table('plugin_option_desc'), $oid);
525                 sql_query($query);
526                 
527                 // clear from cache
528                 unset($this->option_info["{$context}_{$name}"]);
529                 $this->option_values = array();
530                 return 1;
531         }
532         
533         /**
534          * Update an option in the database table plugin_option
535          *              
536          * returns: 1 on success, 0 on failure
537          * private
538          */
539         final protected function set_option($context, $contextid, $name, $value)
540         {
541                 global $manager;
542                 
543                 $oid = $this->get_option_id($context, $name);
544                 if ( !$oid )
545                 {
546                         return 0;
547                 }
548                 
549                 // check if context id exists
550                 switch ( $context )
551                 {
552                         case 'member':
553                                 if ( !MEMBER::existsID($contextid) )
554                                 {
555                                         return 0;
556                                 }
557                                 break;
558                         case 'blog':
559                                 if ( !$manager->existsBlogID($contextid) )
560                                 {
561                                         return 0;
562                                 }
563                                 break;
564                         case 'category':
565                                 if ( !$manager->existsCategory($contextid) )
566                                 {
567                                         return 0;
568                                 }
569                                 break;
570                         case 'item':
571                                 if ( !$manager->existsItem($contextid, true, true) )
572                                 {
573                                         return 0;
574                                 }
575                                 break;
576                         case 'global':
577                                 if ( $contextid != 0 )
578                                 {
579                                         return 0;
580                                 }
581                                 break;
582                 }
583                 
584                 // update plugin_option
585                 $query = "DELETE FROM %s WHERE oid=%d and ocontextid=%d;";
586                 $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid);
587                 sql_query($query);
588                 
589                 $query = "INSERT INTO %s (ovalue, oid, ocontextid) VALUES ('%s', %d, %d);";
590                 $query = sprintf($query, sql_table('plugin_option'), sql_real_escape_string($value), $oid, $contextid);
591                 sql_query($query);
592                 
593                 // update cache
594                 $this->option_values["{$oid}_{$contextid}"] = $value;
595                 if ( $context == 'global' )
596                 {
597                         $this->plugin_options[strtolower($name)] = $value;
598                 }
599                 
600                 return 1;
601         }
602         
603         /**
604          * Get an option from Cache or database
605          *       - if not in the option Cache read it from the database
606          *   - if not in the database write default values into the database
607          *              
608          * private              
609          */                                             
610         final protected function get_option($context, $contextid, $name)
611         {
612                 $oid = $this->get_option_id($context, $name);
613                 if ( !$oid )
614                 {
615                         return '';
616                 }
617                 
618                 $key = "{$oid}_{$contextid}";
619                 
620                 if ( isset($this->option_values[$key]) )
621                 {
622                         return $this->option_values[$key];
623                 }
624                 
625                 // get from DB
626                 $query = "SELECT ovalue FROM %s WHERE oid=%d and ocontextid=%d;";
627                 $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid);
628                 $result = sql_query($query);
629                 
630                 if ( !$result || (sql_num_rows($result) == 0) )
631                 {
632                         // fill DB with default value
633                         $this->option_values[$key] = $this->get_default_value($context, $name);
634                         $query = "INSERT INTO %s (oid, ocontextid, ovalue) VALUES (%d, %d, '%s');";
635                         $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid, sql_real_escape_string($defVal));
636                         sql_query($query);
637                 }
638                 else
639                 {
640                         $o = sql_fetch_object($result);
641                         $this->option_values[$key] = $o->ovalue;
642                 }
643                 
644                 return $this->option_values[$key];
645         }
646         
647         /**
648          * Returns assoc array with all values for a given option
649          * (one option per possible context id)
650          *
651          * private                              
652          */
653         final protected function get_all_options($context, $name)
654         {
655                 $oid = $this->get_option_id($context, $name);
656                 if ( !$oid )
657                 {
658                         return array();
659                 }
660                 $default_value = $this->get_default_value($context, $name);
661                 
662                 $options = array();
663                 $query = "SELECT %s as contextid FROM %s;";
664                 switch ( $context )
665                 {
666                         case 'blog':
667                                 $query = sprintf($query, 'bnumber', sql_table('blog'));
668                                 break;
669                         case 'category':
670                                 $query = sprintf($query, 'catid', sql_table('category'));
671                                 break;
672                         case 'member':
673                                 $query = sprintf($query, 'mnumber', sql_table('member'));
674                                 break;
675                         case 'item':
676                                 $query = sprintf($query, 'inumber', sql_table('item'));
677                                 break;
678                 }
679                 
680                 $result = sql_query($query);
681                 if ( $result )
682                 {
683                         while ( $o = sql_fetch_object($r) )
684                         {
685                                 $options[$o->contextid] = $default_value;
686                         }
687                 }
688                 
689                 $query = "SELECT ocontextid, ovalue FROM %s WHERE oid=%d;";
690                 $query = sprintf($query, sql_table('plugin_option'), $oid);
691                 $result = sql_query($query);
692                 while ( $o = sql_fetch_object($result) )
693                 {
694                         $options[$o->ocontextid] = $o->ovalue;
695                 }
696
697                 return $options;
698         }
699         
700         /**
701          * NucleusPlugin::get_option_id
702          * 
703          * Gets the 'option identifier' that corresponds to a given option name.
704          * When this method is called for the first time, all the OIDs for the plugin
705          * are loaded into memory, to avoid re-doing the same query all over.
706          * 
707          * @param       string  $context        option context
708          * @param       string  $name           plugin name
709          * @return              integer option id
710          */
711         final protected function get_option_id($context, $name)
712         {
713                 $key = "{$context}_{$name}";
714                 
715                 if ( array_key_exists($key, $this->option_info)
716                  && array_key_exists('oid', $this->option_info[$key]) )
717                 {
718                         return $this->option_info[$key]['oid'];
719                 }
720                 
721                 // load all OIDs for this plugin from the database
722                 $this->option_info = array();
723                 $query = "SELECT oid, oname, ocontext, odef FROM %s WHERE opid=%d;";
724                 $query = sprintf($query, sql_table('plugin_option_desc'), $this->plugid);
725                 $result = sql_query($query);
726                 while ( $o = sql_fetch_object($result) )
727                 {
728                         $k = $o->ocontext . '_' . $o->oname;
729                         $this->option_info[$k] = array('oid' => $o->oid, 'default' => $o->odef);
730                 }
731                 sql_free_result($result);
732                 
733                 return $this->option_info[$key]['oid'];
734         }
735         final protected function get_default_value($context, $name)
736         {
737                 $key = $context . '_' . $name;
738                 
739                 if ( array_key_exists($key, $this->option_info)
740                  && array_key_exists('default', $this->option_info[$key]) )
741                 {
742                         return $this->option_info[$key]['default'];
743                 }
744                 return;
745         }
746         
747         /**
748          * Deletes all option values for a given context and contextid
749          * (used when e.g. a blog, member or category is deleted)
750          *
751          * (static method)
752          */
753         final protected function delete_option_values($context, $contextid)
754         {
755                 // delete all associated plugin options
756                 $aOIDs = array();
757                 // find ids
758                 $query = "SELECT oid FROM %s WHERE ocontext='%s';";
759                 $query = sprintf($query, sql_table('plugin_option_desc'), sql_real_escape_string($context));
760                 
761                 $result = sql_query($query);
762                 while ( $o = sql_fetch_object($result) )
763                 {
764                         array_push($aOIDs, $o->oid);
765                 }
766                 sql_free_result($result);
767                 // delete those options. go go go
768                 if ( count($aOIDs) > 0 )
769                 {
770                         $query = "DELETE FROM %s WHERE oid in (%s) and ocontextid=%d;";
771                         $query = sprintf($query, sql_table('plugin_option'), implode(',',$aOIDs), (integer) $contextid);
772                         sql_query($query);
773                 }
774                 return;
775         }
776         
777         /**
778          * NucleusPlugin::getOptionMeta()
779          * splits the option's typeextra field (at ;'s) to split the meta collection
780          * 
781          * @static
782          * @param string $typeExtra the value of the typeExtra field of an option
783          * @return array array of the meta-key/value-pairs
784          */
785         static public function getOptionMeta($typeExtra)
786         {
787                 $meta = array();
788                 
789                 /* 1. if $typeExtra includes delimiter ';', split it to tokens */
790                 $tokens = i18n::explode(';', $typeExtra);
791                 
792                 /*
793                  * 2. if each of tokens includes "=", it consists of key => value
794                  *    else it's 'select' option
795                  */
796                 foreach ( $tokens as $token )
797                 {
798                         $matches = array();
799                         if ( preg_match("#^([^=]+)?=([^=]+)?$#", $token, $matches) )
800                         {
801                                 $meta[$matches[1]] = $matches[2];
802                         }
803                         else
804                         {
805                                 $meta['select'] = $token;
806                         }
807                 }
808                 return $meta;
809         }
810         
811         /**
812          * NucleusPlugin::getOptionSelectValues()
813          * filters the selectlists out of the meta collection
814          * 
815          * @static
816          * @param string $typeExtra the value of the typeExtra field of an option
817          * @return string the selectlist
818          */
819         static public function getOptionSelectValues($typeExtra)
820         {
821                 $meta = NucleusPlugin::getOptionMeta($typeExtra);
822                 
823                 if ( array_key_exists('select', $meta) )
824                 {
825                         return $meta['select'];
826                 }
827                 return;
828         }
829         
830         /**
831          * checks if the eventlist in the database is up-to-date
832          * @return bool if it is up-to-date it return true, else false
833          * @author TeRanEX
834          */
835         public function subscribtionListIsUptodate()
836         {
837                 $res = sql_query('SELECT event FROM '.sql_table('plugin_event').' WHERE pid = '.$this->getID());
838                 $ev = array();
839                 while( $a = sql_fetch_array($res) )
840                 {
841                         array_push($ev, $a['event']);
842                 }
843                 if ( count($ev) != count($this->getEventList()) )
844                 {
845                         return false;
846                 }
847                 $d = array_diff($ev, $this->getEventList());
848                 if ( count($d) > 0 )
849                 {
850                         // there are differences so the db is not up-to-date
851                         return false;
852                 }
853                 return true;
854         }
855         
856         /**
857          * NucleusPlugin::_applyPluginOptions()
858          * Update its entry in database table
859          * 
860          * @static
861          * @param       $aOptions: array ( 'oid' => array( 'contextid' => 'value'))
862          *                       (taken from request using requestVar())
863          * @param       $newContextid: integer (accepts a contextid when it is for a new
864          *                       contextid there was no id available at the moment of writing the
865          *                        formcontrols into the page (by ex: itemOptions for new item)
866          * @return void
867          */
868         static public function _applyPluginOptions(&$aOptions, $newContextid = 0)
869         {
870                 global $manager;
871                 if ( !is_array($aOptions) )
872                 {
873                         return;
874                 }
875                 
876                 foreach ( $aOptions as $oid => $values )
877                 {
878                         // get option type info
879                         $query = "SELECT opid, oname, ocontext, otype, oextra, odef FROM %s WHERE oid=%d;";
880                         $query = sprintf($query, sql_table('plugin_option_desc'), (integer) $oid);
881                         $result = sql_query($query);
882                         if ( $info = sql_fetch_object($result) )
883                         {
884                                 foreach ( $values as $key => $value )
885                                 {
886                                         // avoid overriding the key used by foreach statement
887                                         $contextid=$key;
888                                         
889                                         // retreive any metadata
890                                         $meta = NucleusPlugin::getOptionMeta($info->oextra);
891                                         
892                                         // if the option is readonly or hidden it may not be saved
893                                         if ( array_key_exists('access', $meta)
894                                          && in_array($meta['access'], array('readonly', 'hidden')) )
895                                         {
896                                                 return;
897                                         }
898                                         
899                                         // value comes from request
900                                         $value = undoMagic($value);
901                                         
902                                         /* validation the value according to its type */
903                                         switch ( $info->otype )
904                                         {
905                                                 case 'yesno':
906                                                         if ( ($value != 'yes') && ($value != 'no') )
907                                                         {
908                                                                 $value = 'no';
909                                                         }
910                                                         break;
911                                                 case 'text':
912                                                 case 'select':
913                                                         if ( array_key_exists('datatype', $meta)
914                                                          && ($meta['datatype'] == 'numerical') && ($value != (integer) $value) )
915                                                         {
916                                                                 $value = (integer) $info->odef;
917                                                         }
918                                                         break;
919                                                 case 'password':
920                                                 case 'textarea':
921                                                 default:
922                                                         break;
923                                         }
924                                         
925                                         // decide wether we are using the contextid of newContextid
926                                         if ( $newContextid != 0 )
927                                         {
928                                                 $contextid = $newContextid;
929                                         }
930                                         
931                                         /*
932                                          * trigger event PrePluginOptionsUpdate to give the plugin the
933                                          * possibility to change/validate the new value for the option
934                                          */
935                                         $data = array(
936                                                 'context'               => $info->ocontext,
937                                                 'plugid'                => $info->opid,
938                                                 'optionname'    => $info->oname,
939                                                 'contextid'     => $contextid,
940                                                 'value'         => &$value);
941                                         $manager->notify('PrePluginOptionsUpdate', $data);
942                                         
943                                         // delete and insert its fields of table in database
944                                         $query = "DELETE FROM %s WHERE oid=%d AND ocontextid=%d;";
945                                         $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid);
946                                         sql_query($query);
947                                         $query = "INSERT INTO %s (oid, ocontextid, ovalue) VALUES (%d, %d, '%s');";
948                                         $query = sprintf($query, sql_table('plugin_option'), (integer) $oid, (integer) $contextid, sql_real_escape_string($value));
949                                         sql_query($query);
950                                 }
951                         }
952                         // clear option value cache if the plugin object is already loaded
953                         if ( is_object($info) )
954                         {
955                                 $plugin=& $manager->pidLoaded($info->opid);
956                                 if ( $plugin )
957                                 {
958                                         $plugin->clearOptionValueCache();
959                                 }
960                         }
961                 }
962                 return;
963         }
964 }