Bug #23070 Fix is in Upcoming Release

Using a date format is causing a PHP warning error

Version: 3.5.6 Reporter: JT Thompson

While crafting a RSS feed we came accross this while using a date or gmt_date (or any of the other variants for that matter), we constantly get a php warning:

Warning<
gmdate() expects parameter 2 to be long, string given
ee/legacy/core/Output.php, line 459
 Severity: E_WARNING

We ‘fixed’ it by adding the following to line #455 in the Output.php file ( ‘/system/ee/legacy/core’ ), right ABOVE the line ‘$this->set_status_header(200);’.

 if ( is_string($last_update) )
 {
      $last_update = 0;
 }

Looks like a string value is getting thru to the function - which doesn’t like it. This problem was also in version 3.5.4 (and maybe even earlier) - just didn’t get around to reporting it till now. Currently using PHP Version: 5.6.30.

We HATE hacking core files - hope you fix this soon - thank you!

  • In place of the code you inserted to prevent the error, can you add a var_dump($last_update); and let me know what the value is? It should be a unix timestamp, which the date() functions are fine with on all PHP versions as a string, since PHP is a loose-type language and it casts easily to int/float. So if your $last_update includes something other than a unix timestamp string, it’s indicative of a problem elsewhere. Knowing what it contains should help me pinpoint why you’re encountering this error. Thanks!

    Derek Jones
    20th April, 2017 at 11:43am
  • No problem - result of the code:

    string(0) “”

    Of note we went and created an RSS feed using the exact code from the Docs (https://docs.expressionengine.com/latest/_downloads/sample_rss.txt), and get the same error and value from var_dump.

    Looks like it is getting passed an empty string… hope that helps.

    JT Thompson
    20th April, 2017 at 2:59pm
  • Forgot to mention, after seeing the result from var_dump and reading your explanation we have changed the code to be:

    if ( empty($last_update) ) { $last_update = 0; }

    This eliminates the error without disturbing any string values that may be valid (although If typecasting is an issue just typecast the variable as a long and be done with it), the function being used does not like strings. wink

    JT Thompson
    20th April, 2017 at 3:09pm
  • Hrm, yeah that would indicate that you may have an issue with your database. Let’s take a look at the query that’s causing it, which will give us an indication of where to look in your database.

    1. Change the template type from RSS Page to Web Page
    2. Ensure that Debugging is enabled in Settings > Debugging & Output
    3. Access the template on the front end, and in the Queries, look for _setup_meta_query, and cut and paste them here.
    4. Run that query manually via phpMyAdmin or similar, and cut and paste the results here.
    Derek Jones
    20th April, 2017 at 3:17pm
  • just typecast the variable as a long and be done with it), the function being used does not like strings. wink

    Ultimately we probably will, but we need to figure out why you’re ending up with an empty string in the first place. Your fix is potentially disguising a larger problem.

    Derek Jones
    20th April, 2017 at 3:19pm
  • first _setup_meta_query ( #system/ee/EllisLab/Addons/rss/mod.rss.php L:64 Rss::_setup_meta_query() ):

    SELECT exp_channel_titles.entry_id, exp_channel_titles.entry_date, exp_channel_titles.edit_date, GREATEST((UNIX_TIMESTAMP(exp_channel_titles.edit_date) + (UNIX_TIMESTAMP(DATE_ADD( ‘1970-01-01’, INTERVAL UNIX_TIMESTAMP() SECOND)) - UNIX_TIMESTAMP())), exp_channel_titles.entry_date) AS last_update FROM exp_channel_titles LEFT JOIN exp_channels ON exp_channel_titles.channel_id = exp_channels.channel_id LEFT JOIN exp_members ON exp_members.member_id = exp_channel_titles.author_id WHERE exp_channel_titles.entry_id !=” AND exp_channels.site_id IN (‘1’) AND exp_channel_titles.channel_id = ‘14’ AND exp_channel_titles.entry_date < 1492717132 AND (exp_channel_titles.expiration_date = 0 OR exp_channel_titles.expiration_date > 1492717132) AND exp_channel_titles.status = ‘open’ ORDER BY exp_channel_titles.entry_date desc LIMIT 1

    RESULT: entry_id entry_date edit_date last_update 14751 1478527200 1492656598


    second _setup_meta_query ( #system/ee/EllisLab/Addons/rss/mod.rss.php L:64 Rss::_setup_meta_query() ):

    SELECT c.channel_id, c.channel_title, c.channel_url, c.channel_lang, c.channel_description, ct.entry_date, m.email, m.username, m.screen_name, m.url FROM (exp_channel_titles ct) LEFT JOIN exp_channels c ON ct.channel_id = c.channel_id LEFT JOIN exp_members m ON m.member_id = ct.author_id WHERE ct.entry_id = 14751 AND c.site_id IN (1)

    RESULT: channel_id channel_title channel_url channel_lang channel_description entry_date email username screen_name url 14 Video /research/video english Securosis Video Library 1478527200 hide@mindzipper.com hide Nobody

    I replaced the email and name with bogus values for privacy concerns, however their values were correct, the url field was empty.

    Used Navicat for the Queries.

    Don’t see anything here out of place, but then again I’m sleep deprived and may have missed something. Hope this helps.

    If you don’t think this is a bug but a problem with the Db (which wouldn’t suprise me - it’s from a long time EE client that has gone thru many many upgrades over the years, I’d be happy to close the bug report and move it to the forums.

    JT Thompson
    20th April, 2017 at 3:53pm
  • Oh, and forgot to mention - you’re the man Derak. grin

    JT Thompson
    20th April, 2017 at 3:54pm
  • Dagnabit no edit option on a submitted comment - I mean Derek - I blame my fingers.

    JT Thompson
    20th April, 2017 at 3:55pm
  • After further review of the queries the issue seems to be the NULL value returned for ‘last_update’ by the first query posted (not easily detected because it pastes as just an empty string here).

    After poking around some in the Db I discovered 12 entries in a channel that had NULL values for the ’ edit date’ - so I set them to the same as their ‘entry_date’, however, it didn’t fix the issue (that channel wasn’t even in the query). The channel isn’t even used anymore (made back in 2006 - only kept for legacy reasons).

    For giggles I went into the backend of EE and re-saved the entry in question in the queires (14751) to see if that fixed the issue - it did not. Also I don’t see anything wrong with it’s values in the Db.

    Obviously this has to do with the query you are using to create the sudo ‘last_update’ value, but I’m too tired to go thru that code. grin

    Hope that helps.

    JT Thompson
    20th April, 2017 at 4:48pm
  • It is indeed. Any chance of getting access to this install via a support ticket? I could give more queries to try to figure out what’s going on, but could take a lot of back and forth. For some reason theGREATEST()expression is returning NULL, which should only happen if any of the arguments themselves are NULL, which should not be in this case. Just need to figure out which one, and why.

    Derek Jones
    20th April, 2017 at 5:18pm
  • I’ll ask - but the client is insane about security (they are a security research and advisory firm - and well known), and their website sits behind many - many layers of security, getting access is no trivial thing.

    Even we do not have (because nobody does) direct access to the public site thru SSH, and getting to the backend of the site requires an enormous amount of rule changes everywhere (and a fixed IP) to allow it. We actually run the backend of EE on seperate servers (AWS - load balancing and scaling) - the public front-end has EE lobotomized to be physically impossible to run the back-end (an interesting story on how we did that in itself).

    The easiest thing to do would be to fire up a sandbox instance at AWS (along with cloning the Db) that we could give you access to (this is how we develop on it). We’ll have to ask the client for permission first of course.

    The client holds the Lic. for it directly, something we insist on clients doing - hold all Lic. yourself for everything - we fight against the stranglehold some developers use on clients by providing the Lic. themselves - they may want a different developer or we may drop dead down the road, and then where would they be?

    I’m assuming we can’t issue a support ticket under our account for it - but will need to use theirs (because of Lic.), and we don’t have access to their account (did I mention they’re insane about security? - lol), and so everything would have to be relayed thru them - and that would not be ideal. wink

    I’ll see if they’ll give us access to their account for a brief time to handle this isssue (they can change the password to it after we are done), we have asked for their account credentials before (so we don’t have to ask them for updated files - we really need to take advantage of your sale on EE2 upgrades as we several Lic for EE1 and EE2, but not for EE3 and this would make the issue mute), but they said no (actually they never said no - just never gave them to us).

    After wiping the sleepies out of my eyes I took a deeper look into your code and here is what I discovered:

    1. Just running ‘UNIX_TIMESTAMP(exp_channel_titles.edit_date)’ as a replacement for that code returns NULL.
    2. All EE 3+ installations we have access to have this same issue.
    3. No EE 2+ installations we have access to have an issue with this query.
    4. The update to EE 3.0.0 (ud_3_00_00.php) changed the edit ‘edit_date’ from a bigint to an int (10).
    5. Pasting in a raw value into the query from a EE2+ installation (14 digits - bigint) returns a correct value.

    Soooo, I think we found the issue - that query does not like the change from bigint to int done on the ‘edit_date’ field. I didn’t dig into it any deeper - but it appears that ‘UNIX_TIMESTAMP(exp_channel_titles.edit_date) ’ is invalid - as the value given is not in the required format for that function.

    Of course I figured this all out after that long explanation above - lol, but this should point you to the solution. If you still want me to do a support ticket though - just let me know.

    Cheers!

    JT Thompson
    20th April, 2017 at 7:04pm
  • As a Note: changing the original query to:

    SELECT exp_channel_titles.entry_id, exp_channel_titles.entry_date, exp_channel_titles.edit_date, GREATEST((UNIX_TIMESTAMP(FROM_UNIXTIME(exp_channel_titles.edit_date)) + (UNIX_TIMESTAMP(DATE_ADD( ‘1970-01-01’, INTERVAL UNIX_TIMESTAMP() SECOND)) - UNIX_TIMESTAMP())), exp_channel_titles.entry_date) AS last_update FROM exp_channel_titles LEFT JOIN exp_channels ON exp_channel_titles.channel_id = exp_channels.channel_id LEFT JOIN exp_members ON exp_members.member_id = exp_channel_titles.author_id WHERE exp_channel_titles.entry_id !=” AND exp_channels.site_id IN (‘1’) AND exp_channel_titles.channel_id = ‘14’ AND exp_channel_titles.entry_date < 1492717132 AND (exp_channel_titles.expiration_date = 0 OR exp_channel_titles.expiration_date > 1492717132) AND exp_channel_titles.status = ‘open’ ORDER BY exp_channel_titles.entry_date desc LIMIT 1

    fixes the issue.

    All I’m doing is using the ‘FROM_UNIXTIME’ function to convert the ‘exp_channel_titles.edit_date’ data into the proper format that ‘UNIX_TIMESTAMP’ expects. This may be the easiest way to fix the issue.

    Hope that helps!

    JT Thompson
    20th April, 2017 at 7:14pm
  • Actually since this code looks like a holdover from EE2, the method used is overly complicated for how EE3 stores the data. I think I’d re-write the whole thing to be much simpler.

    JT Thompson
    20th April, 2017 at 10:13pm
  • No, you’ve got the nail on the head. I’ve been trying to track down database changes to see why that query was so complex to begin with, like if it was to accommodate legacy entries who might not have had their data converted. It looks like in ExpressionEngine 1 that edit_date used to be a MySQL timestamp field that would automatically update to a MySQL date string when the row was modified. In 1.4.0, it was switched to varchar, but the data not converted, and all new installs use int, and the app stores unix timestamps regardless.

    I think it’s safe at this point to replace that mess with: GREATEST(exp_channel_titles.edit_date, exp_channel_titles.entry_date) AS last_update. If you make that change, you shouldn’t need to worry about empty strings.

    Derek Jones
    21st April, 2017 at 11:24am
  • Yuppers, that fixed it.

    Modified the ‘/system/ee/EllisLab/Addons/rss/mod.rss.php’ file on line 238 with your syntax - works fine. grin

    Glad you scheduled it for a future update - I hate hacking core EE files.

    Thank you for your time - you are the greatest!

    JT Thompson
    21st April, 2017 at 2:15pm
  • No problem, thanks for reporting!

    Derek Jones
    21st April, 2017 at 8:50pm

You must be signed in to comment on a bug report.

  • On line 237 of system/ee/EllisLab/Addons/rss/mod.rss.php replace:

    GREATEST((UNIX_TIMESTAMP(exp_channel_titles.edit_date) +
         (UNIX_TIMESTAMP(DATE_ADD( '1970-01-01', INTERVAL UNIX_TIMESTAMP() SECOND)) - UNIX_TIMESTAMP())),
        exp_channel_titles.entry_date) AS last_update

    with:

    GREATEST(exp_channel_titles.edit_date, exp_channel_titles.entry_date) AS last_update

ExpressionEngine News

#eecms, #events, #releases