Problems, need help? Have a tip or advice? Post it here.
16 posts Page 2 of 2
Thanks a lot for all the information you have posted.
Here's my working Cron Job line
(fires every 5 minutes)
Code: Select all
*/5   *   *   *   *   /usr/local/bin/php /home/USERNAME/public_html/calendar/notifications.php


I have a question concerning your approach though.
I changed the "notification.php" for the masterpage to "contract.php", since in my case, the information about the contract is set in the "contract" template. "notifications.php" is just containing the code for the cron job.

That would look like this:

Code: Select all
<cms:pages masterpage='contract.php' show_future_entries='1' custom_field="my_datetime >= '2018-04-25 06:09' | my_datetime <= '2018-04-25 06:11' " >

<cms:send_mail from='admin@mysite.com' to='johndoe@gmail.com' subject='Feedback from your site'>

Hello <cms:show client_name/>, here's the link to access your contract for the event that will happen on <cms:show start_date/> at <cms:show start_time/>:
<cms:k_page_link/>
Thank you

</cms:send_mail>

</cms:pages>


If I understand correctly, let's say the cron job is running every 5 minutes, this "notifications.php" page would be fired, a bit like if someone would visit it, every 5 minutes.
In your example (and the code I pasted above), that would only send emails from pages that has the "my_datetime >= '2018-04-25 06:09'" and "my_datetime <= '2018-04-25 06:11'" data saved. So if I have multiple pages with the notification set to this time and date, the email will look like this, let's say I have 2 of them set for the same time, right? :

Code: Select all
Hello <cms:show client_name/>, here's the link to access your contract for the event that will happen on <cms:show start_date/> at <cms:show start_time/>:
<cms:k_page_link/>
Thank you

Hello <cms:show client_name/>, here's the link to access your contract for the event that will happen on <cms:show start_date/> at <cms:show start_time/>:
<cms:k_page_link/>
Thank you


Since it will find 2 pages?

I need to make sure that even if there's multiple pages with the same date and time for the notification section, it sends 1 email per pages.

Before going further, can you confirm this is possible if I follow your instructions?
Thank you very much
I see that you can understand the process with "cms:send_mail" tag by considering following example with 2 variants, where first collects all messages and then pastes the collection into a single email body and second does the job separately:
Code: Select all
<!-- store all messages into one variable and then fire send_mail once -->
<cms:pages ..>
    <cms:set email_body = "<cms:concat email_body  some_text_from_backend />" scope='global' />
</cms:pages>

<cms:send_mail ..>
    <cms:show email_body />
</cms:send_mail>

-------------------
<!-- fire send_mail so many times according to number of found pages -->
<cms:pages ..>
    <cms:send_mail ..>
        <cms:show some_text_from_backend />
    </cms:send_mail>
</cms:pages>


Given that, "cms:send_mail" offers complete procedure, from talking to email server to getting its responses and writing into log (if parameter debug='1' present). And it would happen for each found page one by one. "cms:pages" works just like "cms:repeat" if it helps to understand how loops work. So, the answer is that each email will be sent separately.

If you could test it locally, would be best. For example, in my local environment all emails are never really sent, but stored in some temp folder as txt files. Really helps to debug things.
Must mention that CouchCMS now has a new core tag: "cms:calc_date" should work in present version. No docs yet, but it is rather simple
Code: Select all
<h3>Date: <cms:date format='Y-m-d H:i:s' /></h3>
<h3>Date +1 minute: <cms:calc_date '+1 minute' /></h3>
<h3>Date -1 minute: <cms:calc_date '-1 minute' /></h3>
Thanks for your help trendoman!

I managed to make it work.

I have created 2 fields in the "contract.php" page:
Code: Select all
<cms:editable name='start_date' label='Date to send notification' type='text' />
<cms:editable name='start_time' label='Time to send notification' type='text' />


I have to enter the Date and Time in the same format as how the <cms:date/> field displays date and time.

Then I changed the code for the "notifications.php" page:
Code: Select all
<?php require_once( 'edit/cms.php' ); ?>
<cms:pages masterpage="index.php">
<cms:set current_date = "<cms:date format='Y-m-d H:i' />"/>
  <cms:set notification_date = "<cms:show start_date /> <cms:show start_time />"/>
<cms:if current_date = notification_date>
  <cms:send_mail from='admin@mysite.com' to="<cms:show email />" subject='Subject' debug="1">
Email content
</cms:send_mail>
</cms:if>
</cms:pages>
<?php COUCH::invoke(); ?>


So bascially, if a page has the date and time matching the live date and time, the cron job will send the email.
The Cron job is being triggered every minutes. So if I manually set the following date and time for a page: "2018-04-03 3:55", as soon we reach that time, at that exact minute, the email will be sent, with the data of the right page, to the right email.

I will have to test it more, but seems to be working fine!
Thanks again for your help!
A few questions, if I may..
Why did you ditch the datetime picker? If user misses semicolon or dash or space in text field, date becomes invalid..
Also, do not set current_date for each page.. set it once, before "cms:pages" and make it 'global'.
Also, why go through all pages with "cms:pages" and compare dates for each page in template? It would be more effective to pre-filter pages that match criteria.. Obvious drawback of going through all pages is that sometimes notifications will not be found that way, because website has visitors and perhaps 10 visitors requesting any other page during a single minute will create unforeseen consequences and delay the script by some seconds... so time may not match. Remember, that send_mail represents complete process of interacting with a smtp server (authentication, sending, getting response), which takes time. It makes sense to rewrite your script in 2 parts - first, find ids of matching pages, then in a separate loop of cms:pages run the send_mail thing to not be dependent on possible time leak.
I have integrated a jQuery Datepicker instead. When I click in that date field, a calendar pops, and I just have to click on the date and the text is placed automatically. It's more user-friendly.

But even I wanted to, from what I have seen, Datetime picker will add the seconds to the datetime text, and checking every minutes for a page that matches the exact second will not work properly. Is there a way to disable seconds, but still allowing time with the Datetime picker? I have made some research and couldn't find any answer about this.

Here's how my code looks now (not using time for now, wanted to test with matching date only)

Code: Select all
<?php require_once( 'edit/cms.php' ); ?>
<cms:pages masterpage="contract.php" custom_field="start_date = <cms:date format='Y-m-d' />">
<cms:send_mail from='admin@mysite.com' to="<cms:show email />" subject='Subject' debug="1">
Hello, here's your email:
<cms:show email/>
</cms:send_mail>
</cms:pages>
<?php COUCH::invoke(); ?>


And it's working too.
Is that how you would do it?

Thanks!
16 posts Page 2 of 2