Ok…I’ve tracked this down…I think 🙂
The html for the stats shortcode displayed date range appears to be described on lines 21-22 in inc.stataway-range.php. The range values are set using $_GET on lines 5-6 though I’m not sure who the caller is that is initialising and passing these parameters into this shortcode logic.
Regardless…based on errorlog debug statements I added I observed that the call to the class.fileaway_utility.php timezone() function is occurring AFTER these calls to the $_GET function.
Because I have other plugins that reset the default timezone as WordPress executes the loop it means that these $_GET calls in inc.stataway-range.php are not providing a local timezone relative result since they precede the timezone() function call and are subject to the timezone set by other plugins.
PS: Just out of curiosity…I understand that the Javascript associated with the datepicker feeds fsb and fse parameters on click but, for the life of me, I couldn’t backtrace who called this in.stataway-range logic on shortcode initiation and passed in the default fsb and fse parameters.
Thanks in advance 🙂
The inc.stataway-range.php script is called from line 36 of class.stataway.php.
So my timezone() method called at the very top of the plugin is a new thing. Prior to this, I only allowed users to use Timezone Strings, not UTC offsets, in their WordPress settings. I recently wrote the method to calculate the timezone string from the UTC offset. When I tested it, I got correct results in all my shortcodes (fileaway, stataway) for Australian time. I tested every single UTC offset in my WordPress settings. So I guess it’s not working as expected, or your other plugins are overriding. I’m confused as to how they can be overriding within the limited domain of my plugin, but I guess that’s just my limited understanding. Do you have any suggestions?
If you wanna do some testing, we’ll have you write a date/time to echo, and we’ll paste it in different places throughout the plugin.
echo date('Y-m-d H:i:s').'<br>';
Open up the main file-away.php plugin file, paste it directly before, and directly after, line 35 which reads: fileaway_utility::timezone()
Then take the same echo and paste it at the top of the sc() method in lib/cls/class.stataway.php.
We’ll see where we’re at.
Also, I realize you may have been just using the language loosely, but stats do not monitor uploads; they monitor downloads. Just to make sure we’re clear on that.
Probably we could solve this by adding:
fileaway_utility::timezone();
to the __constructor() methods of the relevant shortcode classes:
class.stataway.php
class.fileaway.php
etc.
I suppose if you have another shortcode plugin processing stuff prior to placing those shortcodes on the page, maybe that’s overriding the date_default_timezone_set() from the main plugin file.
Thanks for the quick response. Much appreciated 🙂
I did notice that the inc.stataway-range.php script is included in line 36 of class.stataway.php but line 5-6 in inc.stataway-range.php are referencing the $_GET[‘fsb’] and $_GET[‘fse’] superglobals and I was hoping you could point me to where in the class.stataway.php (or included code) these global variables were being initialised. That would seem a likely place to put the call to fileaway_utility::timezone();
With respect to the question you posed earlier as to how other plug-ins could interfere with the TimeZone setting it is my understanding of the WordPress architecture that shortcode processing is recursive to support nested shortcodes (not sure how they avoid looping…still looking for a good WordPress architecture reference…proving elusive). So it seems to me that shortcodes should probably not change system level settings such as php default timezone in support of implicit operations but rather always rely on explicit operations (to avoid cross-plugin side-effects).
So there would seem to be two options:
1) Put a call to fileaway_utility::timezone() where the $_GET[‘fsb’] and $_GET[‘fse’] superglobals are initialised in the stats shortcode
2) Replace all calls to date( ‘Y-m-d H:i:s’) with calls to date(‘Y-m-d H:i:s’, current_time(‘timestamp’)) which changes an implicit reference to php timezone for an explicit reference to WordPress blog timezone.
I would lean towards option #2 as it is architecturally cleaner but I defer to you as the plugin author…whichever you prefer I will try out and let you know the results.
Tangential Note:
When I was debugging it appeared that file-away.php was being called multiple times per page which seemed odd to me. I thought that the plugin main file was only called once per page! Might be worth looking into.
The fsb and fse queries are generated by the stats.js file when you click on the refresh icon next to the datepicker fields.
I don’t think current_time(‘timestamp’) will work if the default timezone is not set to your local time, hence, please try adding
fileaway_utility::timezone();
to the top of the class.stataway.php constructor method, or to the top of the class.stataway.php sc() method.
On second thought, you may be right about current_time() (that’s a WP function, right? pulls from your WP time settings?). Anyway, if calling my timezone() method in the constructor works, it’s a simpler fix than a find and replace for all my date() calls.
Re your tangential note: I have no idea how that would be possible. What debugging did you do to get those results displayed? The plugin file should absolutely only be called once.
I understand that fsb and fse queries are generated by the stats.js file when you click on the refresh icon next to the datepicker fields…but where are the fsb and fse initialised when the page is first rendered?
Regarding current_time(‘timestamp’) this is based on the WordPress Blog settings and is a reasonable basis for selecting the timezone.
There are only 4 choices for timezone which I have listed in the order of highest accuracy from a user’s perspective:
1) client browser
2) wordpress settings
3) php
4) server
It would be great if the date came from 1 or 2 but I will go with door #3 if that is still your preference.
Regarding my tangential note…I put a errorlog statement in file-away.php to display the timezone that was being set and noticed that it was triggered multiple times. I was as puzzled as you.
I wonder if it has anything to do with the change we made yesterday, where we included wp-includes/plugin.php in order to see if the s2member plugin is active. Try commenting out that include line real quick and see if the multiple instances goes away. It’s an include_once though, so I’d still be at a loss for an explanation if that’s the culprit.
I do not understand what you mean by: “where are the fsb and fse initialised when the page is first rendered?”.
On the inc.stataway-range.php page, I check to see if those variables are set in the $_GET superglobal, and if they are, I use them.
On your File Away tables, are your Date Modified values correct?
I can see that fsb and fse are checked…but where were they originally initialised when the page rendered the shortcode?
According to the php documentation $_GET obtains its values base on parameters passed in a url. They are passed as parameters in the javascript call based on input fields in html generated by…wait for it…inc.stataway-range.php but these are not also passed in as shortcode parameters on initial render.
Apologies if I’m thick as a brick on this and thanks in advance for your patience.
>> According to the php documentation $_GET obtains its values base on parameters passed in a url.
Correct. So I check to see if fsb and fse are in the url. If not, I use the current date and one week ago for my end and begin values.
If they are set (because the javascript reloads the page, now with those parameters set in the url), then I use those values from the url to set my begin and end dates for the sql query.
The fsb and fse variables don’t need to be initialized on initial page render. If they’re not in the url, they have no use.
I’m just as likely to assume that I’m thick as a brick and missing something, than that you’re thick as a brick. But it seems simple enough to me. If they’re in the url, I get their values and use their values. If they’re not in the url, I don’t use them at all. Thus, on initial page render, they are not used.