The first email sent is empty.

This is because this:


    if (empty($params['last'])) {
      // Estimate the time to send from if this is the first mail.
      $str = $params['weeks_interval'] . " weeks";
      $params['last'] = strtotime(-$str);
    }

In particular this part: $params['last'] = strtotime(-$str); if you add a minus sign (-) and the "1 weeks" string you will get -1, instead of the string "-1 week".

I'm going to attach a patch in my next comment.

Regards.

CommentFileSizeAuthor
#2 2832284-first-mail.patch512 bytesgnuget
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

gnuget created an issue. See original summary.

gnuget’s picture

Status: Needs work » Needs review
FileSize
512 bytes

Patch attached.

matslats’s picture

Thanks again.
I pushed a fix similar to your patch.
In future don't worry about providing actual patches for small things I'll apply by hand and probably do it my own way.

gnuget’s picture

Status: Needs review » Fixed

Thanks, I'm going to mark this issue as fixed.

Regards.

gnuget’s picture

Status: Fixed » Needs work

Hi Matslats

I just checked your last commit and I found a few problems with your approach in the processItem method:

public function processItem($data) {
    $recipient = User::load($data);
    $settings = $this->userDataStore->get('personal_digest', $data, 'digest') + [
      'last' => strtotime('-'. $params['weeks_interval'] .' weeks')
    ];
    // Check the last sending time again in case something got put in the queue
    // twice.
    if ($settings['last'] < strtotime('today')) {
      $this->mailManager
        ->mail('personal_digest',
          'digest',
          $recipient->getEmail(),
          $recipient->getPreferredLangcode(),
          [
            'user' => $recipient,
            'displays'  => $settings['displays'],
            'weeks_interval' => $settings['weeks_interval'],
            'last' => $settings['last'],
          ]
        );
      //the mail is sent, so save the last sent time..
      $settings['last'] = REQUEST_TIME;
      $this->userDataStore->set('personal_digest', $data, 'digest', $settings);
    }

  }

The first one is on this line: 'last' => strtotime('-'. $params['weeks_interval'] .' weeks') in that moment $params is not even defined, $params is the third param of the hook_mail hook, it this method you might want first load the $settings and after use it to calculate the 'last' value.

The second problem is related with the `last` value, right now, that value is used to get the nodes from that point in the time and newer and only if the user hasn't defined this value the module use the weeks_interval value to calculate since when the user will get data, and that is cool because the first emails contain a few weeks of data and the rest of the emails will contain only new content because the LAST value is updated using the request time:
In theory this shoudn't happend because the next mail will be send after the next interval has been passed so no old content will be send. so nevermind this second problem :-)

//the mail is sent, so save the last sent time..
$settings['last'] = REQUEST_TIME;

But using your new approach the user will ever get old content because by default the module is calculating the LAST value every time, getting the same content.

And a third problem (which I think is not related):

Right now the module is using the hook_mail to load the views and send the emails but as far as I'm aware inthe hook_mail you can just alter the email before to be send, you cannot cancel the email at that point and that makes me wonder, what would happend if there is no new content since the last value? the mails are going to be sent empty which I think is a not desirable result.

I propuse to move that part of the code inside the processItem() and leave the hook_mail jsut to add the link to change the user preferences, in this way we can check if the views are empty and if that is the case then avoid sending the mail.

What do you think?

matslats’s picture

1) Big Oops
2) Well spotted that is very intricate. better documentation might have prevented that.
3) Sounds great. I didn't know there was a way to check if a view is empty.

gnuget’s picture

ok, I will create a new issue with the point 3.

Thanks!

gnuget’s picture

Status: Needs work » Fixed
gnuget’s picture

The points mentioned on #5 were fixed on #2832993: Avoid sending empty digest emails.

matslats’s picture

Status: Fixed » Closed (fixed)