We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 813 ☆ A M B ☆
    • 326 Posts
    I have no idea if this is even possible, but is there any way to write a script that sends an e-mail to a predetermined address whenever a resource’s "Unpublish" date kicks in?

    I have a feeling this is more complicated than it sounds. I’m guessing that when an unpub date is set, it just puts that date string into a DB field, and then when the page is rendered, it’s only shown if the unpub date field is not in the past. So, there’s no active process occurring whenever a page becomes unpublished; it only takes place when the page is being called.

    If that’s the case, is there any way to write some sort of automated plugin, or even a cron-job, that does this sort of thing? I’m pretty decent with PHP, but this (particularly if it’s a cron-job) is beyond my pay grade. I would appreciate some sample code if anyone has an idea.

    Thanks!
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      There is an event for OnDocUnPublished that you can use. It appears that this is only invoked if a Manager user does the publishing/unpublishing.

      The IDs of the documents that need publishing/unpublishing and the dates are stored in the assets/cache/sitePublishing.idx.php file.

      Hmm... on looking at line 522 and 533 of the manager/includes/document.parser.class.inc.php file where this is done, it does not appear to invoke the OnDocPublished or the OnDocUnPublished events when doing this; all it does is change the settings in the database for any resources it finds that need to be published/unpublished. Very interesting. Is there any reason why it couldn’t invoke those events with an array of the resources so modified?
        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 813 ☆ A M B ☆
        • 326 Posts
        sottwell, thanks for the reply...although I’m not sure I know what to do with the info you provided wink Also, my assets/cache/sitePublishing.idx.php file doesn’t contain any IDs; it only contains this:

        <?php $cacheRefreshTime=1273869060; ?>


        And thanks for mentioning the OnDocUnPublished event -- even though it doesn’t sound like it’s quite what I need, I didn’t even realize it existed. Any other suggestions/ideas?
          • 813 ☆ A M B ☆
          • 326 Posts
          Also, just FYI: I tried modifying this plugin (http://modxrules.com/articles/send-email-notifications-when-a-document-is-saved) to use the OnDocUnPublished event, and maunually changed an element to "Unpublished." Nothing happened -- I never got an e-mail. Here’s the code I used:

          $e = &$modx->Event;
          
          if ($e->name == "OnDocUnPublished"){
          	if($ids){//check Ids
          		$aIds = explode(',',$ids);
          		foreach($aIds as $dId){//loop ids
          			if($id == trim($dId)){
          				global $modx;
          				$aTitle = $modx->getPageInfo($id,'','pagetitle'); //get pagetitle 
          				$message = str_replace("%X%", '"'. $aTitle['pagetitle']. '" ('. $id . ')', wordwrap($message, 100));//create message
          				sendEmail($email, $subject, $message);
          			}
          		}
          	}
          }
          
           // Send email
          function sendEmail($to, $subject, $message) {
          	$headers ="MIME-Version: 1.0\n".
                        "Content-type: text/html; charset=iso-8859-1\n".
                        "From: ".$_SERVER['SERVER_NAME']."<no-reply@{$_SERVER['HTTP_HOST']}>\n".
                        "X-Mailer: PHP/".phpversion();
          
          $body = <<<EOD
          $message
          EOD;
          
             $mail = mail($to, $subject, $body, $headers);
          }


          I know this wouldn’t solve my issue anyway, but I’m curious why it didn’t work. It works fine when it’s tied to the OnDocFormSave event it was meant to do.
            • 28042 ☆ A M B ☆
            • 24,524 Posts
            That’s what I meant; the event isn’t invoked by the parser when it’s doing its automatic publishing/unpublishing. So a plugin using that event won’t work.

            As for what exactly is in the cache file, you are correct. I wasn’t paying attention to that, I was looking for the event invocation in the parser’s code (and it’s after 1 AM here!) As far as I can see, it’s just a quick way of letting the parser know that there is a document that needs attention at this time, so that it’s not digging through the database scanning every document’s pubdate and unpubdate fields on every page request.

            You could use a plugin with an event that is invoked before the parser gets to that point, check the cache file’s timestamp, and if it’s within a few seconds of triggering a publish/unpublish, run a query to find which documents are being unpublished within the next few seconds, and send off the email with that information. That way, it will catch any documents within the time (probably only milliseconds, but it’s better to be safe than sorry) that the parser itself will determine they need attention.

            On that note, I shall say goodnight grin
              Studying MODX in the desert - http://sottwell.com
              Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
              Join the Slack Community - http://modx.org
              • 813 ☆ A M B ☆
              • 326 Posts
              Wow, you’re still helping at one in the morning? Now that’s dedication! I appreciate your help.

              I think I’ve come up with a solution outside of MODx, but it could probably be ported into the system by someone with a better understanding of the events sytem (even with your explanation, I’m not sure I understand which event I could tie to that would fire before the parser). Basically, I just wrote a script that gets the current time, created a second variable that adds one week to the current time(time + 604,800 seconds), then queries the DB and gathers up and emails documents with unpub_dates that are greater than the current time but less than the one-week-out time. Also, I only wanted docs that were assigned a certain template, which is where the ($template == 4) line comes in, but you could remove this if you didn’t need it. Then, I set up a cron job to run once a week on this script. So far, it’s working great!

              It looks like this, with the confidential info removed and all editable values in uppercase (please excuse my rookie php; I’m open to suggestions if anyone would like to critique it):

              <?php
              
              $today = time();
              $today_formatted = date( 'l, F j, Y', $today ).' at '.date('g:s a', $today);
              $oneweek = ($today + 604800);
              
              include "/PATH/TO/MYSQLCONNECTION.PHP";
              
              mysql_connect($SERVER, $USERNAME, $PASSWORD) or die(mysql_error()) ;
              mysql_select_db("DATABASENAME") or die(mysql_error()) ; 
              $results = mysql_query("SELECT * FROM DATABASE_TABLENAME") or die(mysql_error());
              
              while($data = mysql_fetch_array($results)) {
              	$pagetitle = $data['pagetitle'];
              	$template = $data['template'];
              	$unpub_date = $data['unpub_date'];
              	$unpub_date_formatted = date( 'l, F j', $unpub_date ); 
              
              	if(($unpub_date > $today) && ($template==4) && ($unpub_date < $oneweek)){
              		$message_content .= ($pagetitle.' ('.$unpub_date_formatted.')'.'<br />');
              	}
              }
              
              if (!empty($message_content)) {
              
              	$to = '[email protected]';
              	$subject = 'SUBJECT';
              	$message = '
              	<html>
              	<head>
              	  <title>SUBJECT</title>
              	</head>
              	<body>
              	<p>Message sent on ';
              	$message .= $today_formatted;
              	$message .= '</p>
              	<p><strong>BELOW IS THE CONTENT THAT IS SCHEDULED TO UNPUBLISH IN THE NEXT WEEK</strong></p><br />
              	';
              	$message .= $message_content;
              	$message .= '
              	</body>
              	</html>
              	';
              	$headers  = 'MIME-Version: 1.0' . "\r\n";
              	$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
              	$headers .= 'To: RECIPIENT <[email protected]>' . "\r\n";
              	$headers .= 'From: SENDER <[email protected]>' . "\r\n";
              	$headers .= 'Reply-To: SENDER <[email protected]>' . "\r\n";
              	$headers .= 'X-Mailer: PHP/' . phpversion();
              	
              	mail($to, $subject, $message, $headers);
              
              }
              
              ?>