[New Plugin] jQuery4CMSimple
Moderator: Tata
Re: [New Plugin] jQuery4CMSimple
Hello Holger,
I've just came across an issue with the jQuery4CMSimple documentation. The example code given in section "How to use" doesn't work. It mandatory to declare $plugin_cf as global, when jquery.inc.php is included from within a function. Typically this will be the case, as the plugin developer needs access the configuration, but perhaps it should be documented explicitly.
Christoph
I've just came across an issue with the jQuery4CMSimple documentation. The example code given in section "How to use" doesn't work. It mandatory to declare $plugin_cf as global, when jquery.inc.php is included from within a function. Typically this will be the case, as the plugin developer needs access the configuration, but perhaps it should be documented explicitly.
Christoph
Christoph M. Becker – Plugins for CMSimple_XH
Re: [New Plugin] jQuery4CMSimple
Hello Christoph,
That's the code we're speaking from:
The example code only needs $pth array from CMSimple.
If a developer needs other globals he should know which ones, or am I totally wrong here?
KR
Holger
Hmm, for me it's working...cmb wrote:The example code given in section "How to use" doesn't work.
That's the code we're speaking from:
Code: Select all
<?php
function myplugin(){
global $pth; //be sure CMSimple variables are accessible in your function
$jqerror = '';
if(!file_exists($pth['folder']['plugins'].'jquery/jquery.inc.php')){
$jqerror = '<div class="cmsimplecore_warning">'.
'<b>Ups!</b>'.tag('br').
'Plugin '.ucfirst(basename(dirname(__FILE__))).
' requires jQuery4CMSimple - Plugin!'.tag('br').
'Please download and install jQuery4CMSimple'.tag('br').
'from <a href='.
'"http://cmsimple-xh.com/wiki/doku.php/plugins:jquery4cmsimple">'.
' www.cmsimple-xh.com/wiki</a>.'.
'</div>';
//drop the rest of the plugin-code
return($jqerror);
} else {
//load include-file from jQuery-plugin
//always use "include_once"!
include_once($pth['folder']['plugins'].'jquery/jquery.inc.php');
//include jQuery to the <head>
include_jQuery();
//include jQuery UI to the <head>, if you use it in your plugin
include_jQueryUI();
//....
//your other code ...
//....
}
}
?>
Where?cmb wrote:It mandatory to declare $plugin_cf as global, when jquery.inc.php is included from within a function.
The example code only needs $pth array from CMSimple.
If a developer needs other globals he should know which ones, or am I totally wrong here?
KR
Holger
Re: [New Plugin] jQuery4CMSimple
Hello Holger,
the problem is with jquery.inc.php. It includes jquery/config/config.php to have access to $plugin_cf['jquery']. That's indeed important, because it's needed in include_jQuery() and declared there as global. But if a developer includes jquery.inc.php from within a function, jquery/config/config.php will be included in the functions scope, and so the global declaration in include_jQuery() fails!
That means that
will be included to the <head>. Note the missing jquery-1.6.1-min.js!
Christoph
the problem is with jquery.inc.php. It includes jquery/config/config.php to have access to $plugin_cf['jquery']. That's indeed important, because it's needed in include_jQuery() and declared there as global. But if a developer includes jquery.inc.php from within a function, jquery/config/config.php will be included in the functions scope, and so the global declaration in include_jQuery() fails!
That means that
Code: Select all
<script type="text/javascript" src="./plugins/jquery/lib/jquery"></script>
Christoph
Christoph M. Becker – Plugins for CMSimple_XH
Re: [New Plugin] jQuery4CMSimple
Hi Christoph!
to the include - file is for further/advanced usage (e.g. to make it available in code that runs before the pluginloader is called).
You can comment out this line and everything will work.
Function include_jQuery() can of course access $plugin_cf because that array was made accessible withat the top of the function.
So it's available in include_jQuery() function, but not in the parent function myplugin(); .
It's the same with $hjs and the new declared $jQueryPlugins array from function include_jQueryPlugin():
it's accessible within that function but not outside until you not make it accessible with "global" in e.g. your plugin-function.
I've checked that more than one time, because I thought the same way like you.
So I've made again a little demo with three plugins.
Plug0 is only a index.php with the code from the documentation.
Plug1 is the same in a function plug1()
Plug2 is a copy of Plug1.
Here's a sample code of Plug1:
To show the contents of $jQueryPlugins, I've added a var_dump() to function include_jQueryPlugin():
BTW: here's a little typo in the code: "$jQueryPlugins[] .= $name;" should be "$jQueryPlugins[] = $name;" but it works with the dot too
See it in action altogether here with preCall:
http://holgerirmler.de/jqtest/?jQuery-Tests
and here with classic CMSimple-Scripting:
http://holgerirmler.de/jqtest/?jQuery-Tests2
Have a look at the source to see that everything is ok.
I've checked that with CMSimple 3.3 and the pluginloader from the wiki with success too.
KR
Holger
Sorry but you're wrong here. The only reason why I've addedcmb wrote:Hello Holger,
the problem is with jquery.inc.php. It includes jquery/config/config.php to have access to $plugin_cf['jquery']. That's indeed important, because it's needed in include_jQuery() and declared there as global.
Code: Select all
//load plugin-configuration
require($pth['folder']['plugins'].'jquery/config/config.php');
You can comment out this line and everything will work.
Function include_jQuery() can of course access $plugin_cf because that array was made accessible with
Code: Select all
global $plugin_cf;
So it's available in include_jQuery() function, but not in the parent function myplugin(); .
It's the same with $hjs and the new declared $jQueryPlugins array from function include_jQueryPlugin():
it's accessible within that function but not outside until you not make it accessible with "global" in e.g. your plugin-function.
And this is IMO impossible too, if we say you're right, because the functions from the jQuery4CMSimple-Plugin are writing to $hjs, which isn't available in myplugin() too.cmb wrote:That means thatwill be included to the <head>. Note the missing jquery-1.6.1-min.js!Code: Select all
<script type="text/javascript" src="./plugins/jquery/lib/jquery"></script>
I've checked that more than one time, because I thought the same way like you.
So I've made again a little demo with three plugins.
Plug0 is only a index.php with the code from the documentation.
Plug1 is the same in a function plug1()
Plug2 is a copy of Plug1.
Here's a sample code of Plug1:
Code: Select all
<?php
function plug1(){
global $pth; //be sure CMSimple variables are accessible in your function
$jqerror ='';
if(!file_exists($pth['folder']['plugins'].'jquery/jquery.inc.php')){
$jqerror = '<div class="cmsimplecore_warning">'.
'<b>Ups!</b>'.tag('br').
'Plugin '.ucfirst(basename(dirname(__FILE__))).
' requires jQuery4CMSimple - Plugin!'.tag('br').
'Please download and install jQuery4CMSimple'.tag('br').
'from <a href='.
'"http://cmsimple-xh.com/wiki/doku.php/plugins:jquery4cmsimple">'.
' www.cmsimple-xh.com/wiki</a>.'.
'</div>';
//drop the rest of the plugin-code
return($jqerror);
} else {
//load inculde-file from jQuery-plugin
//always use "include_once"!
include_once($pth['folder']['plugins'].'jquery/jquery.inc.php');
//include jQuery to the <head>
include_jQuery();
//include jQuery UI to the <head>, if you use it in your plugin
include_jQueryUI();
//include other jQuery plugins
echo "<br>Plug1: <br>";
include_jQueryPlugin('test1',$pth['folder']['plugins'].'plug1/libs/test1.js');
//....
//your other code ...
//....
}
}
?>
Code: Select all
function include_jQueryPlugin($name='', $path='') {
global $hjs, $jQueryPlugins;
if(!isset($jQueryPlugins)) {
$jQueryPlugins = array();
}
if(defined('JQUERY')) {
if($name != '') {
if(!file_exists($path)) {
e('missing', 'file', $path);
return;
}
$name = strtolower($name);
if (!in_array($name, $jQueryPlugins)) {
$hjs .= "\n".'<script type="text/javascript" src="'.$path.'"></script>';
$jQueryPlugins[] .= $name;
var_dump($jQueryPlugins);
}
}
}
}
See it in action altogether here with preCall:
http://holgerirmler.de/jqtest/?jQuery-Tests
and here with classic CMSimple-Scripting:
http://holgerirmler.de/jqtest/?jQuery-Tests2
Have a look at the source to see that everything is ok.
I've checked that with CMSimple 3.3 and the pluginloader from the wiki with success too.
KR
Holger
Re: [New Plugin] jQuery4CMSimple
Hello Holger,
thanks for your comprehensive answer. I have to check all the details later. But this afternoon I had the problem, that the filename of the jquery.js was not included to the <head> because bca included jquery.inc.php from a funtion without declaring $plugin_cf global. So, what happened:
1. his plugin (HandheldXH) was called first by the plugin loader (before the jquery plugin)
2. in index.php it globally included handheld.inc.php und called handheld()
3. handheld() included jquery.inc.php
4. jquery.inc.php required it's config.php globally (and defined some functions), so $plugin_cf got a local variable of handheld()
5. handheld() called include_jQuery()
6. include_jQuery() declared $plugin_cf as global, but that was not read by the pluginloader, nor was it introduced to the global namespace by jquery.inc.php
7. include_jQuery() added the path to jquery.js to the head using global $plugin_cf['jquery']['file_core'], which was empty() at that time
Everything worked fine, after I declared $plugin_cf global in handheld(), because when (6) happens now, $plugin_cf is a global.
You might try HandheldXHbeta2 for yourself. Just put JS debugging on, and watch the HTML source.
Christoph
PS: I've just checked your demo. Indeed that works, because $jQueryPlugins is always in the global namespace by declaration in include_jQueryPlugin. (BTW: the typo .= might trigger a notice). But the problem is with include/require:
thanks for your comprehensive answer. I have to check all the details later. But this afternoon I had the problem, that the filename of the jquery.js was not included to the <head> because bca included jquery.inc.php from a funtion without declaring $plugin_cf global. So, what happened:
1. his plugin (HandheldXH) was called first by the plugin loader (before the jquery plugin)
2. in index.php it globally included handheld.inc.php und called handheld()
3. handheld() included jquery.inc.php
4. jquery.inc.php required it's config.php globally (and defined some functions), so $plugin_cf got a local variable of handheld()
5. handheld() called include_jQuery()
6. include_jQuery() declared $plugin_cf as global, but that was not read by the pluginloader, nor was it introduced to the global namespace by jquery.inc.php
7. include_jQuery() added the path to jquery.js to the head using global $plugin_cf['jquery']['file_core'], which was empty() at that time
Everything worked fine, after I declared $plugin_cf global in handheld(), because when (6) happens now, $plugin_cf is a global.
You might try HandheldXHbeta2 for yourself. Just put JS debugging on, and watch the HTML source.
Christoph
PS: I've just checked your demo. Indeed that works, because $jQueryPlugins is always in the global namespace by declaration in include_jQueryPlugin. (BTW: the typo .= might trigger a notice). But the problem is with include/require:
PPS: I was just confused, because I'd included jquery.inc.php in Advancedform_XH from within a function without having $plugin_cf declared globally -- but it worked! But after I thought about it, I found, that it's no problem, if this inclusion is triggered by a plugin-call. The only problem is, when a plugin includes jquery.inc.php directly when it's included by the plugin loader, before the jquery plugin was included, and if the inclusion happens within a function without declaring $plugin_cf as global. This is indeed a very rare occasionphp.net wrote: When a file is included, the code it contains inherits the variable scope of the line on which the include occurs.
...
If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function.
Christoph M. Becker – Plugins for CMSimple_XH
Re: [New Plugin] jQuery4CMSimple
Hi Christoph,
now I've checked that Handheld-Plugin.
It's written in the "new coding style" to keep the index.php small....
And there is the problem:
jquery.inc.php is "the include" of the included handheld.inc.php which is included from handheld-index.php... and finally from the pluginloader.
Ok in this case (the include from the included include ) it is clear that $plugin_cf can't be available when it's not made accessible by the parent include.
If a author writes a code with such deep include-levels he should be familiar with the way how "globals" work.
Ok I can't see that huge parse-time-advantage by putting the whole plugin - functionality into an include-file, but when it's a "must be", I'll suggest to include
all the stuff at the same level in index.php of the plugin - to make the authors (and our) live easier :
Handheld-Plugin - index.php:(tested and working)
So keep the include-levels as short as possible to prevent a mess with not accessible variables.
KR
Holger
now I've checked that Handheld-Plugin.
It's written in the "new coding style" to keep the index.php small....
And there is the problem:
jquery.inc.php is "the include" of the included handheld.inc.php which is included from handheld-index.php... and finally from the pluginloader.
Ok in this case (the include from the included include ) it is clear that $plugin_cf can't be available when it's not made accessible by the parent include.
If a author writes a code with such deep include-levels he should be familiar with the way how "globals" work.
Ok I can't see that huge parse-time-advantage by putting the whole plugin - functionality into an include-file, but when it's a "must be", I'll suggest to include
all the stuff at the same level in index.php of the plugin - to make the authors (and our) live easier :
Handheld-Plugin - index.php:
Code: Select all
<?php
/**
* Handheld CMSimple
*
* @author Brett Allen
* @version 0.2 - 20-08-2011
**/
/* utf8-marker = äöüß */
if($plugin_cf['handheld']['enable'] == "1"){
//do some error-check if jQuery-plugin is available here
include_once($pth['folder']['plugins'].'jquery/jquery.inc.php');
//include jQuery to the <head>
include_jQuery();
include_once($pth['folder']['plugins'].'handheld/handheld.inc.php');
handheld();
include_handheld();
$dest=$plugin_cf['handheld']['destination'];
$hjs .= <<<SCRIPT
<script type="text/javascript">
/* <![CDATA[ */
if(jQuery.browser.mobile){window.location.replace('$dest');}
(jQuery);
/* ]]> */
</script>
SCRIPT;
}
?>
So keep the include-levels as short as possible to prevent a mess with not accessible variables.
KR
Holger
Re: [New Plugin] jQuery4CMSimple
Sorry, again:cmb wrote:The only problem is, when a plugin includes jquery.inc.php directly when it's included by the plugin loader, before the jquery plugin was included, and if the inclusion happens within a function without declaring $plugin_cf as global.
no!
Even in this case (see the demo with Plug0, which prints his output on every page) jquery.inc.php finds it's cf-array because of the declared require of it's config.php.
And, because it's done as "require", it will complete die with a blank page, when $pth - array isn't available too.
So a developer will notice that early .
Hehe, I was wondering about that: it doesn't (in the demo is XHdebugmode on with level 6). So I think it's allowed and I'll add the names on right side of the array anyway .cmb wrote:(BTW: the typo .= might trigger a notice)
The problem with the handheld-plugin is the included included include - as written in your quote from php.net.
KR
Holger
Re: [New Plugin] jQuery4CMSimple
Hello Holger,
thanks for having a further look at this issue and at HandheldXH. Well, you're absolutely right, that it's the best not to nest includes too deeply. IMO HandheldXH doesn't need another include file at all, because index.php would be small enough to not cause any noticeable overhead. But that's not the problem.
I've just written a plugin called "A". Just one file: index.php:
That's exactly the code from the documentation, with the call to myplugin() inserted globally. No deep nesting. After installing it, if I look at the HTML source code of a page of my CMSimple installation, it shows:
Note the missing filename of jquery.js. Everything will be fine, if either the plugin would be included by the pluginloader after the jquery plugin, or I've added global $plugin_cf.
If the line
would be missing from jquery.inc.php any plugin that directly calls include_jQuery() (instead of calling it through a plugin call/CMSimple script), will fail, if that plugin will be included before the jQuery plugin. This is due to the pluginloaders strategy to include all files of a plugin (index, admin, config, etc) instead of first including the configs of all plugins, and then the rest of the plugin files.
Christoph
thanks for having a further look at this issue and at HandheldXH. Well, you're absolutely right, that it's the best not to nest includes too deeply. IMO HandheldXH doesn't need another include file at all, because index.php would be small enough to not cause any noticeable overhead. But that's not the problem.
I've just written a plugin called "A". Just one file: index.php:
Code: Select all
<?php
function myplugin(){
global $pth; //be sure CMSimple variables are accessible in your function
$jqerror = '';
if(!file_exists($pth['folder']['plugins'].'jquery/jquery.inc.php')){
$jqerror = '<div class="cmsimplecore_warning">'.
'<b>Ups!</b>'.tag('br').
'Plugin '.ucfirst(basename(dirname(__FILE__))).
' requires jQuery4CMSimple - Plugin!'.tag('br').
'Please download and install jQuery4CMSimple'.tag('br').
'from <a href='.
'"http://cmsimple-xh.com/wiki/doku.php/plugins:jquery4cmsimple">'.
' www.cmsimple-xh.com/wiki</a>.'.
'</div>';
//drop the rest of the plugin-code
return($jqerror);
} else {
//load include-file from jQuery-plugin
//always use "include_once"!
include_once($pth['folder']['plugins'].'jquery/jquery.inc.php');
//include jQuery to the <head>
include_jQuery();
//include jQuery UI to the <head>, if you use it in your plugin
include_jQueryUI();
//....
//your other code ...
//....
}
}
myplugin();
?>
Code: Select all
<script type="text/javascript" src="./plugins/jquery/lib/jquery/"></script>
If the line
Code: Select all
require($pth['folder']['plugins'].'jquery/config/config.php');
Christoph
Christoph M. Becker – Plugins for CMSimple_XH
Re: [New Plugin] jQuery4CMSimple
Hello Holger,
Christoph
Yes, you're right. jquery.inc.php will find it's $plugin_cf. But when it's included from within a function, $plugin_cf will be local to that function. So it will not be seen by include_jQuery().Holger wrote: Even in this case (see the demo with Plug0, which prints his output on every page) jquery.inc.php finds it's cf-array because of the declared require of it's config.php.
Christoph
Christoph M. Becker – Plugins for CMSimple_XH
Re: [New Plugin] jQuery4CMSimple
Hmm, now I can't follow you :
The codewill make $bar from the instance outside this function accessible inside function foo() and not the other way.
Holger
PS: again, IMO it's better to make things not more complicated than they are.
Where is the advantage to include jquery.inc.php inside another include and not in the plugins index.php?
andcmb wrote:I'd included jquery.inc.php in Advancedform_XH from within a function without having $plugin_cf declared globally -- but it worked!
I think there's a general misunderstanding on how "global" works or between what "global" is doing or not doing (= the superglobals in PHP)...cmb wrote:when it's included from within a function, $plugin_cf will be local to that function. So it will not be seen by include_jQuery().
The code
Code: Select all
function foo() {
global $bar;
}
Holger
PS: again, IMO it's better to make things not more complicated than they are.
Where is the advantage to include jquery.inc.php inside another include and not in the plugins index.php?