OSDN Git Service

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