We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22213
    • 52 Posts
    Is this just me?

    following various ideas given to me in this thread, I have created a tv called ’sortDate’ as an EVAL. It converts the value in another date tv to unixtime.

    BUT

    although if I output the value to the screen, the value is, indeed, correct unixtime, in the DB, it appears in the db as mysql time, eg:’03-04-2006 12:29:41’

    So, my first question is, why, if the php function returns the value as unixtime, does the value get stored and displayed in the DB in another format?

    Here is the code for the EVAL:
    @EVAL 
    $rslt = $modx->getTemplateVar("eventTime","",$modx->documentObject['id'],true);
    $utime = array_values($rslt);
    $utime = $utime[count($utime)-1];
    
    $date = explode(" ",$utime);
    $d = explode("-",$date[0]);
    $t = explode(":",$date[1]);
    
    $tstamp = mktime($t[0],$t[1],$t[2],$d[1],$d[0],$d[2]);
    return $tstamp;
    

    I’m doing it this way so I can manipulate the components for mktime(). I have the type of value for the EVAL as number, and no widget associated with it.

    The second thing that seems perhaps odd is that when viewing the data in PHPmyadmin, the values in the tmplvarid column, are the same for both the ’sortDate’ (ie derived) tv, and the ’eventTime’ tv (see the first line of the EVAL). Shouldn’t they have different ids? All of them are the id of the source, ’eventTime’, not the ’sortDate’.

    Next: the values differ. Even when I update the value in the eventTime in the manager, the values for the EVAL’d tv don’t update.

    And finally, my NewsListing call looks like this:

    
    [[NewsListing? &startID=`47` &summarize=`6` &total=`6` &tpl=`eventListingHome`  &sortby=`sortDate`]]
    
    


    However, its not possible to say if sorting is happening. It does change order sometimes when eventTime values change, but I can’t say that I’m expecting it to work, given the above.

    One thing that occurs to me is that the call in the EVAL,

    $modx->getTemplateVar("eventTime","",$modx->documentObject['id'],true);


    if it were evaluated in the context of the home page, where the NewsListing is, would give a useless result. I had assumed that the evaluation would only take place when editing of the eventTime tv. But that doesn’t explain the other weirdness.

    Any ideas? Have I totally missed it?
      Web Designer
      PHP Programmer
      Cocoa Developer
      Boulevardier & Arriviste
      • 18397
      • 3,250 Posts
      MARKSVIRTUALDESK Reply #12, 18 years ago
      NewsListing sorts on the RENDERED OUTPUT of a TV. So if your TV outputs the correct value, then sorting by it should work just fine. Remember, you can also set the date field to use so NewsListing will automatically convert that unixtimestamp back into human readable form.
        • 22213
        • 52 Posts
        Quote from: Mark at Apr 05, 2006, 12:51 AM

        NewsListing sorts on the RENDERED OUTPUT of a TV. So if your TV outputs the correct value, then sorting by it should work just fine. Remember, you can also set the date field to use so NewsListing will automatically convert that unixtimestamp back into human readable form.

        Thanks again for the reply. I’m beginning to see the problem. Here again is the eval code I’m using:


        
        @EVAL $rslt = $modx->getTemplateVar("showDate","",$modx->documentObject['id'],true);
        $utime = $rslt['value']; 
        
        
        $date = explode(" ",$utime);
        $d = explode("-",$date[0]);
        $t = explode(":",$date[1]);
        
        $tstamp = mktime($t[0],$t[1],$t[2],$d[1],$d[0],$d[2]);
        return $tstamp;
        


        This works fine when I’m on the page. But when I’m calling NewsListing, I think that the problem is that the modx->documentObject[’id’] fails because I’m not on the page, the EVAL is triggered, and so it produces -1. Now the items don’t sort properly because the EVAL is for the value of showDate for the page I’m on, not the page that NL is pulling.

        So, how can I obtain the id of the page that the NewsListing is fetching ($nl_current_id, below), in the context of a template variable? And is there a way to conditionally distinguish those id’s in the sense of:

        $nl_id = $modx->documentObject['id'] == $newsListingStartID ? $nl_current_id : $modx->documentObject['id'];
        


        in other words, can I also obtain the starting id of the current NewsListing call in the context of the template variable EVAL during a NewsListing call?

        TIA
          Web Designer
          PHP Programmer
          Cocoa Developer
          Boulevardier & Arriviste
          • 22213
          • 52 Posts
          So, after much experimentation, here is my inelegant solution to sorting by a date other than the standard ones.

          This relies (in my solution) on 3 tvs:

          - a date tv that I use to enter dates with (these are dates a show will happen);

          - a processing tv that has an @EVAL statement in its default value;

          - a storage tv that the processing tv writes a number into (a unixtime value).

          Here is the code that is the EVAL statement for the processing tv:

          @EVAL 
          // these are the names of the tvs with the date, and that we use to store the unixtime
          $dateTV = "showDate";
          $storageTV = "unixtime";
          
          // get the data for the date that has been set for this event
          $rslt = $modx->getTemplateVar($dateTV,"",$modx->documentObject['id'],true);
          $utime = $rslt['value']; 
          
          // it's a mysql date formatted string, take it apart
          $date = explode(" ",$utime);
          $d = explode("-",$date[0]);
          $t = explode(":",$date[1]);
          
          // we can manipulate these elements: for instance, we can change the time values to midnight, if needed
          $tstamp = mktime($t[0],$t[1],$t[2],$d[1],$d[0],$d[2]);
          
          // since this only renders on the event page, we can refer to the modx documentObject
          $myId = $modx->documentObject['id'];
          // should really alter this to use $modx's table name methods, but in the meantime its late...
          $tbl1 = "modx_site_tmplvar_contentvalues";
          $tbl2 = "modx_site_tmplvars";
          $sql = "SELECT $tbl1.id FROM $tbl1, $tbl2 WHERE ";
          $sql.= "$tbl1.contentid = '$myId' AND $tbl1.tmplvarid = $tbl2.id AND $tbl2.name = '$storageTV' LIMIT 1";
          
          // lets find out if there's an existing unixtime record for this event
          $rslt = $modx->dbQuery($sql);
          if($modx->recordCount($rslt)){
          	// yes, there is, so get its id, and use that to update the record
          	$tvId = $modx->fetchRow($rslt);
          	$tvId = $tvId['id'];
          	$sql = "UPDATE $tbl1 SET value = '$tstamp' WHERE id='$tvId'";
          	$modx->dbQuery($sql);
          } else {
          	// no, there isn't so lets get the id for the tv we're storing in
          	$sql = "SELECT id FROM $tbl2 WHERE name='$storageTV'";
          
          	$rslt = $modx->dbQuery($sql);
          // should really add some error checking here
          	$tmplvarid = $modx->fetchRow($rslt);
          	$tmplvarid = $tmplvarid['id'];
          	// we have all the data, now create the new record
          	$sql = "INSERT INTO $tbl1 SET value='$tstamp', tmplvarid='$tmplvarid', contentid='$myId'";
          	$modx->dbQuery($sql);
          }
          return "$tstamp";
          


          Basically, what happens is this:

          - the user sets the date using the first tv. This is a date type, with a date formatter on it.

          - when the value is set, and the new value stored, the page is refreshed.

          - this causes as re-evaluation of the second (processing) tv. It is important that you have this tv in the page for the event. But it is also necessary that you not have it in the page where the NewsListing is. This is because the line

          @EVAL
          ...
          $rslt = $modx->getTemplateVar($dateTV,"",$modx->documentObject['id'],true);
          


          would use the id of the wrong page, and produce an incorrect result (usually -1). When the EVAL happens, the php checks to see if there is an existing record for the storage tv. This tv (the storage one) doesn’t need to be on any page AFAIK. In any event, the php calculates the unixtime from the data in the first, date tv and stores it, as a number, in the storage tv. If there isn’t a record existing, it creates it. If there is, it updates it. You don’t want to make any of these tvs, except probably the date one, editable by anyone.

          In the NewsListing call, ensure that you include the parameters

          [[NewsListing? &sortby=`tvunixtime` &sortdir=`asc`]]
          


          don’t forget the sortdir, as the default will be in the wrong direction for most uses - this is so we can show things coming in the future, so the order is reversed from most blog entries.

          Still to do is a filter for NewsListing to ensure that the first listing is the next one in the future.

          Hope that this is useful to someone.
            Web Designer
            PHP Programmer
            Cocoa Developer
            Boulevardier & Arriviste
            • 18397
            • 3,250 Posts
            MARKSVIRTUALDESK Reply #15, 18 years ago
            Jason, any ideas on how to do this (http://modxcms.com/forums/index.php/topic,3715.msg27524.html#msg27524) with one TV?