3

I think I'm almost there with this one but obviously missing something as the postDate is not updating. I have the following in an onSaveEntry event. It's saying it's successful but the postDate does not change. Ideally I want this to update whether the entry is enabled or not.

public function onSaveEntry(Event $event)
{
    $entry = $event->params['entry'];
    // set postDate from assignedDate
    if($user->admin) {
        if($entry->assignedDate && $entry->assignedTimeslot) {
            $timeslot = $entry->assignedDate.' '.$entry->assignedTimeslot.'.000000';
            $params = $entry->postDate = $timeslot;
            $success = craft()->elements->saveElement($entry, $params);
        }
    }
    return $event;
}
3
  • I would try using a single field on the entry called assignedDateTime which can take a date and a time. This can then be used to set the postDate. Why has the timeslot got '.00000' after it? Commented May 17, 2016 at 11:59
  • @LukePearce just something I added after a bit of googling. But didn't work. Doesn't work when removed either.
    – Lettie
    Commented May 17, 2016 at 14:23
  • @LukePearce sorry correction on that as well as Googling I picked it up from the object postDate returns.
    – Lettie
    Commented May 17, 2016 at 14:39

3 Answers 3

4

$timeslot isn't formatted correctly to be used as the postDate. I'd create a field that takes a date and a time and then use DateTimeHelper::formatTimeForDb() to format for use as postDate.

You can't modify the postDate until after the entry has been saved - so will need to resave the entry with the newly set postDate. More info as to why you have to do this here.

craft()->on( 'entries.onSaveEntry', function( Event $event ){

  // Grab the entry from post request
  $entry = $event->params['entry'];

  // Get logged in user
  $user = craft()->userSession->getUser();

  if ( $user && $user->admin ) {
    $timeSlot = $entry->getContent()->assignedTimeslot;

    // If the postDate and Timeslot don't match (stops infinite loop)
    if ( !( $entry->postDate == $timeSlot ) ) {

        // Set postDate to timeSlot date
        $entry->postDate = DateTimeHelper::formatTimeForDb( $timeSlot );

        // Resave entry
        craft()->entries->saveEntry( $entry );
    }
  }
});
9
  • the $timeslot variable is set to 2016-11-10 14:00:00 and if I print_r the $entry->postDate it returns an object Craft\DateTime Object ( [date] => 2016-11-10 14:00:00.000000 [timezone_type] => 3 [timezone] => UTC ) So looks like it is formatted correctly. Any further clues?
    – Lettie
    Commented May 17, 2016 at 14:37
  • So I've updated the logic with DateTimeHelper::formatTimeForDb() this ensures the formats match. I've tested locally and this is working for me. Give it a go. Commented May 17, 2016 at 15:35
  • Not sure calling saveEntry inside of an onSaveEntry event is correct? The code hangs for me. Is that not setting up an infinite loop? Also the date is made up of 2 variables assignedDate and assignedTimeslot so you are only assigning the time to the DateTimeHelper without the date part.
    – Lettie
    Commented May 17, 2016 at 15:53
  • Yes, that was a mistake. My suggestion was to combine your assignedDate field with you assignedTimeslot field. What fieldtype are these currently set up with? Unfortunately I don't think the postDate is accessible onSaveEntry. I've also tried with beforeOnSaveEntry and can set other custom field values but not the postDate. Commented May 17, 2016 at 16:35
  • More info : craftcms.stackexchange.com/questions/6722/… Commented May 17, 2016 at 16:39
2

Thanks to @LukePearce I managed to re-write the code to work as follows:

craft()->on( 'entries.onSaveEntry', function( Event $event ){

  // Grab the entry from post request
  $entry = $event->params['entry'];

  // Get logged in user
  $user = craft()->userSession->getUser();

  // Set the timeslot
  $timeSlot = $entry->getContent()->assignedDate.' '.$entry->getContent()->assignedTimeslot;

  // Create a new dateTime object from timeslot
  $postDate = new \DateTime($timeSlot);

  // Check the postDate has changed
  if ($entry->postDate != $postDate) {

    // check user is set and is admin
    if ($user && $user->admin) {

      // Set entry postDate to new postDate
      $entry->postDate = $postDate;

      // Resave entry
      $success = craft()->entries->saveEntry($entry);

    }
   }
});
2

I have written a plugin for this exact use case. You can configure what time is set as the postDate or expiryDate via a Twig template.

https://github.com/carlcs/craft-autoexpire

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.