OSDN Git Service

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