OSDN Git Service

ver 0.5.9.2
[nucleus-jp/nucleus-plugins.git] / trunk / NP_MitasNom / NP_MitasNom.php
1 <?php 
2 /*
3  * NP_MitasNom ver 0.5.9.2
4  * Written by Katsumi
5  * This library is GPL
6  */
7 class NP_MitasNom extends NucleusPlugin { 
8         var $actionplugin=false;
9         var $bconvertbreaks;
10         function getName() {
11                 $this->_checkVersion();
12                 return 'NP_MitasNom'; 
13         }
14         function getMinNucleusVersion() { return 220; }
15         function getAuthor()  { return 'Katsumi'; }
16         function getVersion() { return '0.5.9.2'; }
17         function getURL() {return 'http://japan.nucleuscms.org/wiki/plugins:mitasnom';}
18         function getDescription() { return $this->translated('WYSIWYG HTML editor plagin using FCKeditor'); } 
19         function supportsFeature($what) { return (int)($what=='SqlTablePrefix'); }
20         function install() {
21                 // Install, upgrade options, and Refresh member options.
22                 // Note: createOption() is overrided (see below).
23                 $this->createOption('version','version','text',$this->getVersion(),'access=hidden');
24                 $this->createOption('width',$this->translated('Width'),'text','100%'); 
25                 $this->createOption('height',$this->translated('Height'),'text','400'); 
26                 $this->createOption('toolbar',$this->translated('Toolbar'),'select','Default','Default|Default|Full|Full|Basic|Basic|Custom|Custom'); 
27                 $this->createOption('toolbar_custom',$this->translated('Custom Toolbar'), 'textarea',
28                         "['Source','DocProps','-','Save','NewPage','Preview','-','Templates'],\n".
29                         "['Cut','Copy','Paste','PasteText','PasteWord','-','Print','SpellCheck'],\n".
30                         "['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],\n".
31                         "['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],\n".
32                         "['OrderedList','UnorderedList','-','Outdent','Indent'],\n".
33                         "['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],\n".
34                         "['Link','Unlink','Anchor'],\n".
35                         "['Image','Flash','Table','Rule','Smiley','SpecialChar','PageBreak','UniversalKey'],\n".
36                         "['Form','Checkbox','Radio','TextField','Textarea','Select','Button','ImageButton','HiddenField'],'/',\n".
37                         "['Style','FontFormat','FontName','FontSize'],\n".
38                         "['TextColor','BGColor'],\n".
39                         "['About']");
40                 $this->createOption('addremovetoolbar',$this->translated('Add new toolbar to the menu / Delete toolbar from the menu'),'text',''); 
41                 $this->createOption('returnafterbr',$this->translated('"<br />" => "<br />\n" conversion?'),'yesno','yes'); 
42                 $this->createOption('returnafterbrbr',$this->translated('"<br /><br />" => "<br />\n<br />\n" conversion?'),'yesno','no'); 
43                 $this->createOption('dialogwidth',$this->translated('Width of Popup dialog'),'text','500'); 
44                 $this->createOption('dialogheight',$this->translated('Height of Popup dialog'),'text','450'); 
45                 $this->createOption('protectedsource',$this->translated('Protected Sources'), 'textarea',
46                         '/<script[\s\S]*?\/script>/gi'."\n".
47                         '/<%[\s\S]*?%>/g');
48                 //$this->createOption('additionalpsource',$this->translated('Additional Protected Sources'), 'textarea','');
49                 $this->createOption('usemembersettings',$this->translated('Use member-specific settings?'),'yesno','no'); 
50                 $this->createOption('useimagemanager',$this->translated('Use Image-Manager plugin instead of media.php?'),'yesno','no'); 
51                 $this->createOption('usehttps',$this->translated('Use secure server (https) for edititing item?'),'yesno','no'); 
52                 $this->createOption('usep',$this->translated('Use P tag instead of BR for enter key (IE only)?'),'yesno','no'); 
53         }
54         function getEventList() { return array('EditItemFormExtras','AddItemFormExtras','PrepareItemForEdit',
55                                         'PreAddItem','PreUpdateItem',
56                                         'PreItem','PostPluginOptionsUpdate','PrePluginOptionsEdit'); }
57
58         // SkinVar is currently used for showing link to create item
59         function doSkinVar($skinType,$type,$text='') {
60                 global $blogid,$CONF,$member;
61                 switch (strtolower($type)) {
62                 case 'newitem':
63                 default:
64                         if (!$member->isLoggedIn()) return;
65                         if (!$text) $text=$this->translated('New Item with WYSIWYG');
66                         $url=$CONF['ActionURL'].'?action=plugin&name=MitasNom&type=createitem&blogid='.$blogid;
67                         $url=htmlspecialchars($url);
68                         if ($this->getOption('usehttps')=='yes') $url=preg_replace('/^http:/','https:',$url);
69                         echo "<a href=\"$url\">$text</a>\n";
70                         break;
71                 }
72         }
73
74         // TemplateVar is currently used for showing link to edit item
75         function doTemplateVar(&$item,$type,$text='') {
76                 global $CONF,$member;
77                 switch (strtolower($type)) {
78                 case 'edititem':
79                 default:
80                         if (!$text) $text=$text=$this->translated('Edit Item with WYSIWYG');
81                         $itemid=$item->itemid;
82                         $url=htmlspecialchars($url);
83                         if ($this->getOption('usehttps')=='yes') $url=preg_replace('/^http:/','https:',$url);
84                         $url=$CONF['ActionURL'].'?action=plugin&name=MitasNom&type=itemedit&itemid='.$itemid;
85                         echo "<a href=\"$url\">$text</a>\n";
86                         break;
87                 }
88         }
89
90         // Action is used to show item-editing/newitem-creating window.
91         function doAction($type){
92                 global $DIR_LIBS,$member,$manager,$CONF,$blogid,$itemid;
93                 if (!$member->isLoggedIn()) return _NOTLOGGEDIN;
94                 if (!strstr('createitem itemedit',$type)) return _BADACTION;
95
96                 // Resolve itemid and blogid
97                 if (!$blogid && $itemid) $blogid=getBlogIDFromItemID($itemid);
98                 if (!$blogid) return _BADACTION;
99                 if (!$member->teamRights($blogid)) return _ERROR_DISALLOWED;
100                 $blog=&$manager->getBlog($blogid);
101                 $convBreaks=false;
102                 if ($blog) if ($blog->convertBreaks()) $convBreaks=true;
103
104                 // Get editing HTML
105                 $this->actionplugin=true;
106                 include($DIR_LIBS . 'ADMIN.php');
107                 $a=new ADMIN();
108                 switch ($type) {
109                 case 'createitem':
110                         ob_start();
111                         $a->action_createitem();
112                         $buff=ob_get_contents();
113                         ob_end_clean();
114                         break;
115                 case 'itemedit':
116                         ob_start();
117                         $a->action_itemedit();
118                         $buff=ob_get_contents();
119                         ob_end_clean();
120                         break;
121                 default:
122                         return _BADACTION;
123                 }
124                 
125                 // Return if not valid editing HTML
126                 // These codes must be changed when non-compatible Nucleus version comes out.
127                 if (!preg_match('/<head>/',$buff)) return _ERRORMSG;
128                 if (!preg_match('/<div class="jsbuttonbar">/',$buff)) return _ERRORMSG;
129                 if (!preg_match('/<textarea([^>]*)inputbody([^>]*)>([^>]*)<\/textarea>/',$buff)) return _ERRORMSG;
130                 if (!preg_match('/<textarea([^>]*)inputmore([^>]*)>([^>]*)<\/textarea>/',$buff)) return _ERRORMSG;
131
132                 // Create NucleusFCKeditor instances
133                 if (!class_exists('NucleusFCKeditor')) include ($this->getDirectory().'fckclass.php');
134                 $body='';
135                 $more='';
136                 if ($type=='itemedit') {
137                         if (preg_match ('/<textarea([^>]*)inputbody([^>]*)>([^>]*)<\/textarea>/',$buff,$matches))
138                                 $body=$matches[3];
139                                 $body=$this->unhtmlentities($body);
140                         if (preg_match ('/<textarea([^>]*)inputmore([^>]*)>([^>]*)<\/textarea>/',$buff,$matches))
141                                 $more=$matches[3];
142                                 $more=$this->unhtmlentities($more);
143                 }
144                 if ($convBreaks) {
145                         $body=addBreaks($body);
146                         $more=addBreaks($more);
147                 }
148                 $FCKedit1=new NucleusFCKEditor('body',$this,$body);
149                 $FCKedit2=new NucleusFCKEditor('more',$this,$more);
150                 $buff1=$FCKedit1->CreateHtml();
151                 $buff2=$FCKedit2->CreateHtml();
152
153                 // Replace texts of editing page
154                 // These codes must be changed when non-compatible Nucleus version comes out.
155                 $buff=preg_replace ('/<head>/','<head><base href="'.$CONF['AdminURL'].'">', $buff,1);
156                 $buff=preg_replace ('/<div class="jsbuttonbar">/','<div class="jsbuttonbar" style="DISPLAY: none;">', $buff,2);
157                 $buff=preg_replace ('/<textarea([^>]*)inputbody([^>]*)>([^>]*)<\/textarea>/',$buff1, $buff,1);
158                 $buff=preg_replace ('/<textarea([^>]*)inputmore([^>]*)>([^>]*)<\/textarea>/',$buff2, $buff,1);
159                 echo $buff;
160         }
161         
162         // Solve <%image%> tag for showing items
163         function event_PreItem(&$data) {
164                 $item=&$data['item'];
165                 $pattern=$this->_patternBeforeEdit();
166                 $replace=$this->_replaceBeforeEdit($item->authorid);
167                 for ($i=0;$i<1;$i++){
168                         $item->body=preg_replace($pattern[$i],$replace[$i],$item->body);
169                         $item->more=preg_replace($pattern[$i],$replace[$i],$item->more);
170                 }
171         }
172         
173         // NP_MitasNom option in editing dialog.
174         // This is more compatible to newer Nucleus version,
175         // unless 'id="inputbody"' and 'id="inputmore"' changed.
176         function event_AddItemFormExtras(&$data) { return $this->event_EditItemFormExtras($data); }
177         function event_EditItemFormExtras(&$data) {
178                 global $DIR_LIBS,$member,$manager,$CONF,$blogid,$itemid;
179                 // Resolve itemid and blogid
180                 if (!$blogid && $itemid) $blogid=getBlogIDFromItemID($itemid);
181                 if (!$blogid) return _BADACTION;
182                 if (!$member->teamRights($blogid)) return _ERROR_DISALLOWED;
183                 $blog=&$manager->getBlog($blogid);
184                 $convBreaks=false;
185                 if ($blog) if ($blog->convertBreaks()) $convBreaks=true;
186                 $authorid=$member->getID();
187                 if ($itemid) {
188                         $item=&$manager->getItem($itemid,1,1);
189                         $authorid=$item['authorid'];
190                 }
191
192                 if ($this->actionplugin) {
193                         echo '<input type="hidden" name="mitasnom_wysiwyged" id="mitasnom_wysiwyged" value="full"/>';
194                         return;
195                 } else  echo '<input type="hidden" name="mitasnom_wysiwyged" id="mitasnom_wysiwyged" value=""/>';
196                 $dwidth=$this->this_getOption('dialogwidth');
197                 $dheight=$this->this_getOption('dialogheight');
198                 $mURL=$CONF['MediaURL'].$member->getID().'/';
199 ?>
200 <h3>NP_MitasNom</h3>
201 <script type="text/javascript">
202 //<![CDATA[
203 function WYSIWYGpopup(textId){
204         window.open('plugins/mitasnom/popup.php?blogid=<?php echo (int)$blogid; ?>&id='+textId,'name',
205 <?php echo "'status=yes,toolbar=no,scrollbars=yes,resizable=yes,width=$dwidth,height=$dheight,top=0,left=0');\n"; ?>
206 }
207 function convBreaks(T) {
208         T=T+'';
209         T=T.replace(/\x0D\x0A/g,"\x0A");
210         T=T.replace(/\x0D/g,"\x0A");
211         T=T.replace(/\x0A/g,"<br />\x0A");
212         return T;
213 }
214 function rmvBreaks(T) {
215         T=T+'';
216         T=T.replace(/\x0A/g,'');
217         T=T.replace(/\x0D/g,'');
218         T=T.replace(/<br \/>/g,'\n');
219         <?php
220                 if ($this->this_getOption('returnafterbrbr')!='yes') 
221                         echo 'while (T.match(/\n\n/g)) T=T.replace(/\n\n/g,"\n<br />");'."\n"; 
222                 echo 'while (T.match(/<br \/>\n/g)) T=T.replace(/<br \/>\n/g,"<br /><br />");'."\n"; 
223         ?>
224         T=T.replace(/\n<br \/>/g,'<br />\n');
225         return T;
226 }
227 function WYSIWYGgettext(id){
228         var T=document.getElementById(id).value+'';
229 <?php
230         if ($convBreaks) echo "\tT=convBreaks(T);\n";
231         $replacearray=$this->_replaceBeforeEdit($authorid);
232         foreach($this->_patternBeforeEdit() as $key => $pattern) {
233                 $replace=$replacearray[$key];
234                 echo "\tT=T.replace($pattern"."g,'$replace');\n";
235         }
236 ?>
237         return T;
238 }
239 function WYSIWYGsettext(id,T){
240 <?php
241         if ($convBreaks) echo "\tT=rmvBreaks(T);\n"; 
242         $replacearray=$this->_replaceAfterEdit();
243         foreach($this->_patternAfterEdit() as $key => $pattern) {
244                 $replace=$replacearray[$key];
245                 echo "\tT=T.replace($pattern"."g,'$replace');\n";
246         }
247 ?>
248         document.getElementById(id).value=T;
249         document.getElementById('mitasnom_wysiwyged').value='image';
250 }
251 //]]>
252 </script>
253 <p>
254 <a href="javascript:WYSIWYGpopup('inputbody');" title="Edit by HTML editor"><?php echo $this->translated('WYSIWYG:body'); ?></a>&nbsp;&nbsp;
255 <a href="javascript:WYSIWYGpopup('inputmore');" title="Edit by HTML editor"><?php echo $this->translated('WYSIWYG:more'); ?></a>
256 </p>
257 <?php
258         }
259
260         //<%image%>, <%popup%> conversion
261         function event_PrepareItemForEdit(&$data) {
262                 global $CONF,$member;
263                 if (!$this->actionplugin) return;
264                 $item=&$data['item'];
265                 $pattern=$this->_patternBeforeEdit();
266                 $replace=$this->_replaceBeforeEdit($item['authorid']);
267                 $item['body']=preg_replace($pattern,$replace,$item['body']);
268                 $item['more']=preg_replace($pattern,$replace,$item['more']);
269         }
270         
271         // Creates Nucleus-specific tags (<%image%> <%popup%>) from general HTML tags.
272         function event_PreAddItem(&$item) { return $this->event_PreUpdateItem($item); }
273         function event_PreUpdateItem(&$item) {
274                 if (!requestVar('mitasnom_wysiwyged')) return;
275                 $body=&$item['body'];
276                 $more=&$item['more'];
277                 $blog=&$item['blog'];
278                 $body=$this->_restoreImgPopup($body);
279                 $more=$this->_restoreImgPopup($more);
280                 if (requestVar('mitasnom_wysiwyged')!='full') return;
281                 if ($blog->convertBreaks()) {
282                         $body=removeBreaks($body);
283                         $more=removeBreaks($more);
284                 }
285                 if ($this->this_getOption('returnafterbr')=='yes') {
286                         $body=$this->_addEnterAfterBr($body);
287                         $more=$this->_addEnterAfterBr($more);
288                 }
289                 $pattern=$this->_patternAfterEdit();
290                 $replace=$this->_replaceAfterEdit();
291                 $body=preg_replace($pattern,$replace,$body);
292                 $more=preg_replace($pattern,$replace,$more);
293         }
294         function _addEnterAfterBr(&$data){
295                 // <br/> => <br/>\n conversion
296                 $ret='';
297                 $data=str_replace(array("\r","\n"),'',$data);
298                 while ($data) {
299                         if (($i=strpos($data,'<br />'))===false) break;
300                         $ret.=substr($data,0,$i+6);
301                         $data=substr($data,$i+6);
302                         if (substr($data,0,1)=="\x0D" || substr($data,0,1)=="\x0A") continue;
303                         if (substr($data,0,6)!='<br />' || $this->this_getOption('returnafterbrbr')=='yes') $ret.="\n";
304                 }
305                 return $ret.$data;
306         }
307         function _restoreImgPopup(&$data){
308                 global $CONF,$member,$DIR_MEDIA;
309                 //$mURL=$CONF['MediaURL'].$member->getID().'/';
310                 $mURL=$CONF['MediaURL'];
311                 $pattern='/<img [^>]*?src="'.str_replace('/','\/',$mURL).'[^"]*?"[^>]*? \/>/';
312                 if (preg_match_all ( $pattern, $data, $matches,PREG_SET_ORDER)) {
313                         foreach($matches as $match){
314                                 $subject=$match[0];
315                                 $src=$width=$height=$alt='';
316                                 $prop=array();
317                                 foreach(explode('" ',substr($subject,5)) as $value) {
318                                         $i=strpos($value,'=');
319                                         $j=strpos($value,'"');
320                                         if ($i===false || $j===false) continue;
321                                         $key=substr($value,0,$i);
322                                         $value=substr($value,$j+1);
323                                         switch ($key) {
324                                         case 'src':
325                                                 if (preg_match('/src="'.str_replace('/','\/',$mURL).'([^"]*?)"/',$subject,$match)) $src=$match[1];
326                                                 break;
327                                         case 'width':
328                                                 $width=$value;
329                                                 break;
330                                         case 'height':
331                                                 $height=$value;
332                                                 break;
333                                         default:
334                                                 $prop[$key]=$value;
335                                                 break;
336                                         }
337                                 }
338                                 if (!$prop['title']) $prop['title']=$prop['alt'];
339                                 if (!$prop['alt']) $prop['alt']=$prop['title'];
340                                 foreach ($prop as $key => $value) {
341                                         if (!$alt) $alt.=' ';
342                                         $alt.=$key.'="'.$value.'"';
343                                 }
344                                 $data=str_replace($subject,"<%image($src|$width|$height|$alt)%>",$data);
345                         }
346                 }
347                 $pattern='/<a [\s\S]*?href="'.str_replace('/','\/',$mURL).'[^"]*?"[\s\S]*?<\/a>/';
348                 if (preg_match_all ( $pattern, $data, $matches,PREG_SET_ORDER)) {
349                         $i=0;
350                         foreach($matches as $match){
351                                 $subject=$match[0];
352                                 if (preg_match('/href="'.str_replace('/','\/',$mURL).'([^"]*?)"/',$subject,$match)) $href=$match[1];
353                                 else $href='';
354                                 if (preg_match('/title="width=([^\|]*?)\|height=([^"]*?)"/',$subject,$match)) {
355                                         $width=$match[1];
356                                         $height=$match[2];
357                                 } else {
358                                         $old_level = error_reporting(0);
359                                         $size = @GetImageSize($DIR_MEDIA.$href); 
360                                         error_reporting($old_level);
361                                         $width = ($height = 0);
362                                         if ($size) {
363                                                 $width = $size[0];
364                                                 $height = $size[1];
365                                         }
366                                 }
367                                 if (preg_match('/>([^<]*?)<\/a>/',$subject,$match)) $alt=$match[1];
368                                 else $alt='';
369                                 if (!$width) $width=100;
370                                 if (!$height) $height=100;
371                                 if ($alt) $data=str_replace($subject,"<%popup($href|$width|$height|$alt)%>",$data);
372                         }
373                 }
374                 return $data;
375         }
376
377         //Replacement for <%image%>, <%popup%>
378         function _patternBeforeEdit(){
379                 return array(   '/<%image\(([0-9]*?)\/([^\|]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)alt="([^"]*?)"([^\)]*?)\)%>/',
380                                 '/<%image\(([^\|\/]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)alt="([^"]*?)"([^\)]*?)\)%>/',
381                                 '/<%image\(([^\|]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)alt="([^"]*?)"([^\)]*?)\)%>/',
382                                 '/<%image\(([0-9]*?)\/([^\|]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)\)%>/',
383                                 '/<%image\(([^\|\/]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)\)%>/',
384                                 '/<%image\(([^\|]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)\)%>/',
385                                 '/<%popup\(([0-9]*?)\/([^\|]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)\)%>/',
386                                 '/<%popup\(([^\|\/]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)\)%>/',
387                                 '/<%popup\(([^\|]*?)\|([0-9]*?)\|([0-9]*?)\|([^\)]*?)\)%>/',
388                                 '/<%([^%]*?)%>/');
389         }
390         function _replaceBeforeEdit($authorid) {
391                 global $CONF;
392                 $mURL=$CONF['MediaURL'].$authorid.'/';
393                 return array(   '<img src="'.$CONF['MediaURL'].'$1/$2" width="$3" height="$4" $5 alt="$6"$7 />',
394                                 '<img src="'.$mURL.'$1" width="$2" height="$3" $4 alt="$5"$6 />',
395                                 '<img src="'.$CONF['MediaURL'].'$1" width="$2" height="$3" $4 alt="$5"$6 />',
396                                 '<img src="'.$CONF['MediaURL'].'$1/$2" width="$3" height="$4" alt="$5" title="$5" />',
397                                 '<img src="'.$mURL.'$1" width="$2" height="$3" alt="$4" title="$4" />',
398                                 '<img src="'.$CONF['MediaURL'].'$1" width="$2" height="$3" alt="$4" title="$4" />',
399                                 '<a href="'.$CONF['MediaURL'].'$1/$2" title="width=$3|height=$4">$5</a>',
400                                 '<a href="'.$mURL.'$1" title="width=$2|height=$3">$4</a>',
401                                 '<a href="'.$CONF['MediaURL'].'$1" title="width=$2|height=$3">$4</a>',
402                                 '<mitasnom title="nucleustag"></mitasnom><%$1%>');
403         }
404         function _patternAfterEdit(){
405                 return array(   '/<mitasnom title="nucleustag"><\/mitasnom>/');
406         }
407         function _replaceAfterEdit() {
408                 return array(   '');
409         }
410         
411         // Show information when editing plugin option
412         var $errormessage;
413         function event_PrePluginOptionsEdit($data){
414                 if ($this->errormessage) echo "<h4>".$this->errormessage."</h4>";
415         }
416         function returnWithMessage($text) { $this->errormessage=$text;}
417
418         // Customize toolbar menu
419         function event_PostPluginOptionsUpdate($data) {
420                 $plugid=$data['plugid'];
421                 if ($plugid!=$this->GetID()) return;
422                 $this->install();// Refresh member option settings.
423                 if (!($name=$this->getOption('addremovetoolbar'))) return;
424                 $name=ereg_replace("[^0-9a-zA-Z]","",$name);
425                 $this->setOption('addremovetoolbar','');
426                 if (!($toolbar=$this->getOption('toolbar_custom')))
427                         return $this->returnWithMessage($this->translated('Toolbar definition is empty'));
428                 if (strstr(' default full basic custom ',strtolower($name)))
429                         return $this->returnWithMessage($this->translated('Default, Full, Basic and Custom toolbars cannot be removed.'));
430                 $ret=$this->getOption('toolbar_'.strtolower($name));//$ret=$this->getOption('toolbar_'.$this);
431                 if (!($oid=$this->this_getOid('toolbar'))) return;
432                 if (!($extra=$this->this_getExtra($oid))) return;
433                 if (strstr(strtolower($extra),strtolower($name))) {
434                         //delete
435                         $extra=eregi_replace("\|$name\|$name","",$extra);
436                         sql_query('UPDATE ' . sql_table('plugin_option_desc') .
437                                 ' SET oextra = "'.addslashes($extra). '" WHERE oid=' . (int)$oid);
438                         $this->deleteOption('toolbar_'.strtolower($name));
439                         $this->returnWithMessage($name.$this->translated(' toolbar is deleted.'));
440                 } else {
441                         //add
442                         $extra=str_replace("|Custom|Custom","|$name|$name|Custom|Custom",$extra);
443                         sql_query('UPDATE ' . sql_table('plugin_option_desc') .
444                                 ' SET oextra = "'.addslashes($extra). '" WHERE oid=' . (int)$oid);
445                         $this->createOption('toolbar_'.strtolower($name), $name.$this->translated(' Toolbar'), 'textarea', $toolbar);
446                         $this->returnWithMessage($name.$this->translated(' toolbar is added.'));
447                 }
448         }
449
450         // Member specific stuff
451         function this_getOption($name) {
452                 global $member;
453                 if ($this->getOption('usemembersettings')!='yes') return $this->getOption($name);
454                 if (!$this->_useMemberSpecificOption($name)) return $this->getOption($name);
455                 return $this->getMemberOption($member->getID(), $name);
456         }
457         function _useMemberSpecificOption($name) {
458                 foreach ($this->_allMemberSpecificOptions() as $value) if ($name==$value) return true;
459                 return false;
460         }
461         function _allMemberSpecificOptions() {
462                 return array('width','height','toolbar','returnafterbr','returnafterbrbr',
463                                 'dialogwidth','dialogheight','additionalpsource');
464         }
465
466         // SQL stuff
467         function this_getOid($name,$context='global'){
468                 $query = 'SELECT oid, oname FROM ' . sql_table('plugin_option_desc') . 
469                         ' WHERE opid=' . intval($this->plugid).
470                         ' and ocontext="'.addslashes($context).'"';
471                 $res = sql_query($query);
472                 while ($o = mysql_fetch_object($res)) if ($o->oname==$name) return $o->oid;
473                 return null;
474         }
475         function this_getExtra($oid){
476                 $query = 'SELECT oextra FROM ' . sql_table('plugin_option_desc') . ' WHERE oid=' . intval($oid);
477                 $res = sql_query($query);
478                 if ($o = mysql_fetch_object($res)) return $o->oextra;
479                 return null;
480         }
481
482         // Uppgrading stuff
483         function _checkVersion(){
484                 if (!$this->this_getOid('version')) $this->install();
485                 else if ($this->getVersion()!=$this->getOption('version')) $this->install();
486                 $this->setOption('version',$this->getVersion());
487         }
488
489         // Overrided function
490         function createOption($name, $desc, $type, $defValue = '', $typeExtras = '') {
491                 if (!$this->this_getOid($name)) parent::createOption($name, $desc, $type, $defValue, $typeExtras);
492                 if ($this->_useMemberSpecificOption($name)) {
493                         if ($this->getOption('usemembersettings')=='yes') {
494                                 if (!$this->this_getOid($name,'member')) {
495                                         if ($name=='toolbar') {
496                                                 $typeExtras=quickQuery(
497                                                         'SELECT oextra as result FROM '.sql_table('plugin_option_desc').
498                                                         ' WHERE opid='.(int)$this->getID().' AND oname="toolbar"');
499                                         }
500                                         if (($Extras=$typeExtras)=='access=hidden') $Extras='';
501                                         $Extras=str_replace('|Custom|Custom','',$Extras);
502                                         $Extras=str_replace('|Full|Full','',$Extras);
503                                         $this->createMemberOption($name, $desc, $type,$this->getOption($name), $Extras);
504                                 }
505                         } else {
506                                 if ($this->this_getOid($name,'member'))
507                                         $this->deleteMemberOption($name);
508                         }
509                 }
510                 return 1;
511         }
512
513         // Language stuff
514         var $langArray;
515         function translated($english){
516                 if (!is_array($this->langArray)) {
517                         $this->langArray=array();
518                         $language=$this->getDirectory().'language/'.ereg_replace( '[\\|/]', '', getLanguageName()).'.php';
519                         if (file_exists($language)) include($language);
520                 }
521                 if (!($ret=$this->langArray[$english])) $ret=$english;
522                 return $ret;
523         }
524
525         // General function (found on PHP help page) follows
526         function unhtmlentities($string) {
527                 $trans_tbl = get_html_translation_table (HTML_ENTITIES);
528                 $trans_tbl = array_flip ($trans_tbl);
529                 return strtr ($string, $trans_tbl);
530         }
531
532 ?>