We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • Given that I have 3 integers representing a date
    dd
    mm
    and yyyy
    I tried to set a date property in an object. So far I can’t figure out the "right" or easy way to do it.
    I know that the final representation of the date is going to be yyyy-mm-dd, so it seems like it should be easy to do.
    After looking at the xPDOObject::set method:
                                if (in_array($v, $this->_currentDates) || $v === '0000-00-00') {
                                    $this->_fields[$k]= $v;
                                    $set= true;
                                } elseif ($v) {
                                    $ts= strtotime($v);
                                    if ($ts !== -1 && $ts !== false) {
                                        $this->_fields[$k]= $this->strftime('%Y-%m-%d', $ts);
                                        $set= true;
                                    }
                                }
    

    .. if the date you pass in is not in the _currentDates list, or is not ’0000-00-00’, then it gets passed to php’s strtotime() function.
    Just looking at the documentation for that function, it seems to have some fairly irregular behavior across different versions of php. Also, the date I was trying to set in my own little test, 1968-12-10, since it’s pre-Unix epoch, doesn’t work in Windows or "some versions of Linux".

    I wonder if it would be preferable to open up the first test to allow the user to pass in a string already in the right format. I don’t know if this would incur too much overhead.. something like
                                if (in_array($v, $this->_currentDates) || preg_match("/^\d{4}\-\d{2}\-\d{2}$/", $v)) {
    


    Of course, I might be overlooking some obvious approach to setting the date using the code as it is.

    Tock tick...
    nP
      Mike Schell
      Lead Developer, MODX Cloud
      Email: [email protected]
      GitHub: https://github.com/netProphET/
      Twitter: @mkschell
    • Hmmmm, if you want to do it that way, just change the phptype to string and it will simply be treated as a string? The preg thing, IMO, is too much overhead, and too limiting for my taste, but you could simply override the xPDOObject::set() function in your own classes (or your own baseClass) to do this...
      <?php
      function set($k, $v=null, $vType='') {
          $set= false;
          if ($k == 'somedatefield' && preg_match("/^\d{4}\-\d{2}\-\d{2}$/", $v)) {
              $this->_fields['somedatefield']= $validmysqldatestring;
              $this->_dirty['somedatefield']= 'somedatefield';
              $set = true;
          } else {
              $set = parent :: set($k, $v, $vType);
          }
          return $set;
      }
      ?>

      or just cheat a little whereever you need to and set the field value directly...
      <?php
      $obj->_fields['somedatefield']= $validmysqldatestring;
      $obj->_dirty['somedatefield']= 'somedatefield';
      ?>

      I can’t solve the issues with pre-epoch on earlier versions of PHP; works great in recent versions though. Spent over a month trying and the results were never very accurate, but the inclusion of the adodbtime stuff (and another function gleaned from php documentation comments) was meant to address that.

      I like the flexibility of specifying the datetime/date/timestamp format as any valid strtotime() value and could not find a better alternative; just one wheel I wasn’t about to try and re-engineer.
      • OpenGeek,
        Great ideas and explanation. Thanks for taking the time.
        nP
          Mike Schell
          Lead Developer, MODX Cloud
          Email: [email protected]
          GitHub: https://github.com/netProphET/
          Twitter: @mkschell
        • Actually, just had a better idea for the code...

          What we could do is define a value to look for in the $vType parameter, maybe ’utc’. Then use this value to skip the transformation on the datetime/date/timestamp fields, rather than relying on the preg_match(). What do you think?

          In addition, I’m considering testing the $vType parameter to see if it is a callback function, and if so, allow the callback function to handle the operation of transforming the $v parameter, skipping the switch statement in xPDOObject->set().
          • I like both ideas - utilizing $vType to flag bypassing the transformation or as a callback.
            What’s the overall philosophy of how xPDO handles bad input? In this case, what should xPDO do if you tell it you’re passing it ’utc’ but you pass it garbage?
              Mike Schell
              Lead Developer, MODX Cloud
              Email: [email protected]
              GitHub: https://github.com/netProphET/
              Twitter: @mkschell
            • Quote from: netProphET at Nov 23, 2007, 04:13 AM

              I like both ideas - utilizing $vType to flag bypassing the transformation or as a callback.
              What’s the overall philosophy of how xPDO handles bad input? In this case, what should xPDO do if you tell it you’re passing it ’utc’ but you pass it garbage?
              No real philosophy subscribed to there. I just left it open for developers to choose how they wanted to apply validation so far; didn’t really want to impose any specific approach or implementation on everyone. Sometimes it would make sense to apply validation on set(), other times on save(), etc., so I’m not sure I want to subscribe to any particular philosophy on this one.