Advertisement
Guest User

Untitled

a guest
Feb 19th, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 20.15 KB | None | 0 0
  1. <?php
  2. namespace Bookly\Lib\Utils;
  3.  
  4. use Bookly\Lib;
  5. use Bookly\Lib\Entities;
  6.  
  7. define( 'WP_USE_THEMES', false );
  8. if ( isset( $argv ) ) {
  9.     foreach ( $argv as $argument ) {
  10.         if ( strpos( $argument, 'host=' ) === 0 ) {
  11.             $_SERVER['HTTP_HOST'] = substr( $argument, 5 );
  12.         }
  13.     }
  14. }
  15. require_once __DIR__ . '/../../../../../wp-load.php';
  16. require_once ABSPATH . WPINC . '/formatting.php';
  17. require_once ABSPATH . WPINC . '/general-template.php';
  18. require_once ABSPATH . WPINC . '/pluggable.php';
  19. require_once ABSPATH . WPINC . '/link-template.php';
  20.  
  21. if ( ! class_exists( '\Bookly\Lib\Plugin' ) ) {
  22.     // Bookly on host is inactive.
  23.     if ( is_multisite() ) {
  24.         $working_directory = getcwd();
  25.         // absolute path for dir appointment-booking
  26.         chdir( realpath( __DIR__ . '/../../' ) );
  27.         include_once 'autoload.php';
  28.         // Restore working directory.
  29.         chdir( $working_directory );
  30.     } else {
  31.         die( 'Bookly is inactive' );
  32.     }
  33. } else {
  34.     add_action( 'bookly_send_notifications', function() { new Notifier(); } );
  35. }
  36.  
  37. /**
  38.  * Class Notifier
  39.  * @package Bookly\Lib\Utils
  40.  */
  41. class Notifier
  42. {
  43.     /** @var string Format: YYYY-MM-DD HH:MM:SS */
  44.     private $mysql_now;
  45.  
  46.     /** @var int */
  47.     private $hours;
  48.  
  49.     /** @var Lib\SMS $sms */
  50.     private $sms;
  51.  
  52.     /**
  53.      * @param Entities\Notification $notification
  54.      */
  55.     public function processNotification( Entities\Notification $notification )
  56.     {
  57.         /** @var \wpdb $wpdb */
  58.         global $wpdb;
  59.  
  60.         $hours     = get_option( 'bookly_cron_reminder_times' );
  61.         $compounds = array();
  62.  
  63.         switch ( $notification->get( 'type' ) ) {
  64.             case 'staff_agenda':
  65.                 if ( $this->hours >= $hours[ $notification->get( 'type' ) ] ) {
  66.                     /** @var \stdClass[] $rows */
  67.                     $rows = $wpdb->get_results(
  68.                         'SELECT
  69.                            `a`.*,
  70.                            `ca`.`locale`,
  71.                            `ca`.`extras`,
  72.                            `ca`.`location_id`,
  73.                            `c`.`full_name`  AS `customer_name`,
  74.                            `s`.`title`      AS `service_title`,
  75.                            `s`.`info`       AS `service_info`,
  76.                            `st`.`email`     AS `staff_email`,
  77.                            `st`.`phone`     AS `staff_phone`,
  78.                            `st`.`full_name` AS `staff_name`,
  79.                            `st`.`info`      AS `staff_info`
  80.                        FROM `' . Entities\CustomerAppointment::getTableName() . '` `ca`
  81.                        LEFT JOIN `' . Entities\Appointment::getTableName() . '` `a`   ON `a`.`id` = `ca`.`appointment_id`
  82.                        LEFT JOIN `' . Entities\Customer::getTableName() . '` `c`      ON `c`.`id` = `ca`.`customer_id`
  83.                        LEFT JOIN `' . Entities\Service::getTableName() . '` `s`       ON `s`.`id` = `a`.`service_id`
  84.                        LEFT JOIN `' . Entities\Staff::getTableName() . '` `st`        ON `st`.`id` = `a`.`staff_id`
  85.                        LEFT JOIN `' . Entities\StaffService::getTableName() . '` `ss` ON `ss`.`staff_id` = `a`.`staff_id` AND `ss`.`service_id` = `a`.`service_id`
  86.                        WHERE `ca`.`status` IN("' . Entities\CustomerAppointment::STATUS_PENDING. '","' . Entities\CustomerAppointment::STATUS_APPROVED . '") AND
  87.                        DATE(DATE_ADD("' . $this->mysql_now . '", INTERVAL 1 DAY)) = DATE(`a`.`start_date`) AND NOT EXISTS (
  88.                            SELECT * FROM `' . Entities\SentNotification::getTableName() . '` `sn` WHERE
  89.                                DATE(`sn`.`created`) = DATE("' . $this->mysql_now . '") AND
  90.                                `sn`.`gateway`       = "' . $notification->get( 'gateway' ) . '" AND
  91.                                `sn`.`type`          = "staff_agenda" AND
  92.                                `sn`.`ref_id`        = `a`.`staff_id`
  93.                        )
  94.                        ORDER BY `a`.`start_date`'
  95.                     );
  96.  
  97.                     if ( $rows ) {
  98.                         $appointments = array();
  99.                         foreach ( $rows as $row ) {
  100.                             $appointments[ $row->staff_id ][] = $row;
  101.                         }
  102.  
  103.                         $columns = array(
  104.                             '{10_date}'     => __( 'Date', 'bookly' ),
  105.                             '{30_service}'  => __( 'Service', 'bookly' ),
  106.                             '{40_customer}' => __( 'Customer', 'bookly' ),
  107.                         );
  108.                         if ( Lib\Config::locationsEnabled() ) {
  109.                             $columns['{20_location}'] = __( 'Location', 'bookly' );
  110.                         }
  111.                         ksort( $columns );
  112.                         $is_html = ( get_option( 'bookly_email_send_as' ) == 'html' && $notification->get( 'gateway' ) != 'sms' );
  113.                         if ( $is_html ) {
  114.                             $table = '<table cellspacing="1" border="1" cellpadding="5"><thead><tr><td>'
  115.                                      . implode( '</td><td>', $columns )
  116.                                      . '</td></tr></thead><tbody>%s</tbody></table>';
  117.                             $tr = '<tr><td>' . implode( '</td><td>', array_keys( $columns ) ) . '</td></tr>';
  118.                         } else {
  119.                             $table = '%s';
  120.                             $tr    = implode( ', ', array_keys( $columns ) ) . PHP_EOL;
  121.                         }
  122.  
  123.                         foreach ( $appointments as $staff_id => $collection ) {
  124.                             $sent        = false;
  125.                             $staff_email = null;
  126.                             $staff_phone = null;
  127.                             $agenda      = '';
  128.                             foreach ( $collection as $appointment ) {
  129.                                 if ( ! Lib\Config::booklyExpired() ) {
  130.                                     $tr_data = array(
  131.                                         '{10_date}'     => Lib\Utils\DateTime::formatTime( $appointment->start_date ) . '-' . Lib\Utils\DateTime::formatTime( $appointment->end_date ),
  132.                                         '{40_customer}' => $appointment->customer_name,
  133.                                     );
  134.  
  135.                                     $location = Lib\Proxy\Locations::findById( $appointment->location_id );
  136.                                     $tr_data['{20_location}'] = $location ? $location->get( 'name' ) : '';
  137.  
  138.                                     // Extras
  139.                                     $extras  = '';
  140.                                     $_extras = (array) Lib\Proxy\ServiceExtras::getInfo( $appointment->extras, false );
  141.                                     if ( ! empty ( $_extras ) ) {
  142.                                         foreach ( $_extras as $extra ) {
  143.                                             if ( $is_html ) {
  144.                                                 $extras .= sprintf( '<li>%s</li>', $extra['title'] );
  145.                                             } else {
  146.                                                 $extras .= sprintf( ', %s', str_replace( '&nbsp;&times;&nbsp;', ' x ', $extra['title'] ) );
  147.                                             }
  148.                                         }
  149.                                         if ( $is_html ) {
  150.                                             $extras = '<ul>' . $extras . '</ul>';
  151.                                         }
  152.                                     }
  153.  
  154.                                     $tr_data['{30_service}'] = $appointment->service_title . $extras;
  155.                                     $agenda .= strtr( $tr, $tr_data );
  156.                                 } else {
  157.                                     $agenda = __( 'To view the details of this appointments, please contact your website administrator in order to verify Bookly license.', 'bookly' );
  158.                                 }
  159.                                 $staff_email = $appointment->staff_email;
  160.                                 $staff_phone = $appointment->staff_phone;
  161.                             }
  162.  
  163.                             if ( $notification->get( 'gateway' ) == 'email' && $staff_email != '' || $notification->get( 'gateway' ) == 'sms' && $staff_phone != '' ) {
  164.                                 $codes = new Lib\NotificationCodes();
  165.                                 $codes->set( 'next_day_agenda',   sprintf( $table, $agenda ) );
  166.                                 $codes->set( 'appointment_start', $appointment->start_date );
  167.                                 $codes->set( 'staff_name',        $appointment->staff_name );
  168.                                 $codes->set( 'staff_info',        $appointment->staff_info );
  169.                                 $codes->set( 'service_info',      $appointment->service_info );
  170.  
  171.                                 $sent = Lib\NotificationSender::sendFromCronToStaff( $notification, $codes, $staff_email, $staff_phone );
  172.                             }
  173.  
  174.                             if ( $sent ) {
  175.                                 $this->_notificationSent( $notification->get( 'type' ), $notification->get( 'gateway' ), $staff_id );
  176.                             }
  177.                         }
  178.                     }
  179.                 }
  180.                 break;
  181.             case 'client_follow_up':
  182.                 if ( $this->hours >= $hours[ $notification->get( 'type' ) ] ) {
  183.                     $appointments = $wpdb->get_results(
  184.                         'SELECT `ca`.*
  185.                        FROM `' . Entities\CustomerAppointment::getTableName() . '` `ca`
  186.                        LEFT JOIN `' . Entities\Appointment::getTableName() . '` `a` ON `a`.`id` = `ca`.`appointment_id`
  187.                        WHERE `ca`.`status` IN("' . Entities\CustomerAppointment::STATUS_PENDING . '","' . Entities\CustomerAppointment::STATUS_APPROVED . '") AND
  188.                        DATE("' . $this->mysql_now . '") = DATE(`a`.`start_date`) AND NOT EXISTS (
  189.                            SELECT * FROM `' . Entities\SentNotification::getTableName() . '` `sn` WHERE
  190.                                DATE(`sn`.`created`) = DATE("' . $this->mysql_now . '") AND
  191.                                `sn`.`gateway`       = "' . $notification->get( 'gateway' ) . '" AND
  192.                                `sn`.`type`          = "client_follow_up" AND
  193.                                `sn`.`ref_id`        = `ca`.`id`
  194.                        ) ORDER BY `a`.`start_date`',
  195.                         ARRAY_A
  196.                     );
  197.  
  198.                     if ( $appointments ) {
  199.                         foreach ( $appointments as $ca ) {
  200.                             if ( ! in_array( $ca['compound_token'], $compounds ) ) {
  201.                                 $customer_appointment = new Entities\CustomerAppointment( $ca );
  202.                                 if ( Lib\NotificationSender::sendFromCronToClient( $notification, $customer_appointment ) ) {
  203.                                     $this->_notificationSent( $notification->get( 'type' ), $notification->get( 'gateway' ), $ca['id'] );
  204.                                 }
  205.                                 if ( ! empty( $ca['compound_token'] ) ) {
  206.                                     $compounds[] = $ca['compound_token'];
  207.                                 }
  208.                             } else {
  209.                                 // Mark the 'sent' notifications for services included in the compound service.
  210.                                 $this->_notificationSent( $notification->get( 'type' ), $notification->get( 'gateway' ), $ca['id'] );
  211.                             }
  212.                         }
  213.                     }
  214.                 }
  215.                 break;
  216.             case 'client_reminder':
  217.                 if ( $this->hours >= $hours[ $notification->get( 'type' ) ] ) {
  218.                     $appointments = $wpdb->get_results(
  219.                         'SELECT `ca`.*
  220.                        FROM `' . Entities\CustomerAppointment::getTableName() . '` `ca`
  221.                        LEFT JOIN `' . Entities\Appointment::getTableName() . '` `a` ON `a`.`id` = `ca`.`appointment_id`
  222.                        WHERE `ca`.`status` IN("' . Entities\CustomerAppointment::STATUS_PENDING . '","' . Entities\CustomerAppointment::STATUS_APPROVED . '") AND
  223.                        DATE(DATE_ADD("' . $this->mysql_now . '", INTERVAL 1 DAY)) = DATE(`a`.`start_date`) AND NOT EXISTS (
  224.                            SELECT * FROM `' . Entities\SentNotification::getTableName() . '` `sn` WHERE
  225.                                DATE(`sn`.`created`) = DATE("' . $this->mysql_now . '") AND
  226.                                `sn`.`gateway`       = "' . $notification->get( 'gateway' ) . '" AND
  227.                                `sn`.`type`          = "client_reminder" AND
  228.                                `sn`.`ref_id`        = `ca`.`id`
  229.                        ) ORDER BY `a`.`start_date`',
  230.                         ARRAY_A
  231.                     );
  232.  
  233.                     if ( $appointments ) {
  234.                         foreach ( $appointments as $ca ) {
  235.                             if ( ! in_array( $ca['compound_token'], $compounds ) ) {
  236.                                 $customer_appointment = new Entities\CustomerAppointment( $ca );
  237.                                 if ( Lib\NotificationSender::sendFromCronToClient( $notification, $customer_appointment ) ) {
  238.                                     $this->_notificationSent( $notification->get( 'type' ), $notification->get( 'gateway' ), $ca['id'] );
  239.                                 }
  240.                                 if ( ! empty( $ca['compound_token'] ) ) {
  241.                                     $compounds[] = $ca['compound_token'];
  242.                                 }
  243.                             } else {
  244.                                 // Mark the 'sent' notifications for services included in the compound service.
  245.                                 $this->_notificationSent( $notification->get( 'type' ), $notification->get( 'gateway' ), $ca['id'] );
  246.                             }
  247.                         }
  248.                     }
  249.                 }
  250.                 break;
  251.             case 'client_reminder_1st':
  252.             case 'client_reminder_2nd':
  253.             case 'client_reminder_3rd':
  254.                 $appointments = $this->getClientReminderAppointments( $notification, $hours[ $notification->get( 'type' ) ] * 60 /* minutes */ );
  255.                 if ( $appointments ) {
  256.                     foreach ( $appointments as $ca ) {
  257.                         if ( ! in_array( $ca['compound_token'], $compounds ) ) {
  258.                             $customer_appointment = new Entities\CustomerAppointment( $ca );
  259.                             if ( Lib\NotificationSender::sendFromCronToClient( $notification, $customer_appointment ) ) {
  260.                                 $this->_notificationSent( $notification->get( 'type' ), $notification->get( 'gateway' ), $ca['id'] );
  261.                             }
  262.                             if ( ! empty( $ca['compound_token'] ) ) {
  263.                                 $compounds[] = $ca['compound_token'];
  264.                             }
  265.                         } else {
  266.                             // Mark the 'sent' notifications for services included in the compound service.
  267.                             $this->_notificationSent( $notification->get( 'type' ), $notification->get( 'gateway' ), $ca['id'] );
  268.                         }
  269.                     }
  270.                 }
  271.                 break;
  272.             case 'client_birthday_greeting':
  273.                 if ( $this->hours >= $hours[ $notification->get( 'type' ) ] ) {
  274.                     $customers = $wpdb->get_results(
  275.                         'SELECT `c`.*
  276.                        FROM `' . Entities\Customer::getTableName() . '` `c`
  277.                        WHERE `c`.`birthday` IS NOT NULL AND
  278.                            DATE_FORMAT(`c`.`birthday`, "%m-%d") = DATE_FORMAT("' . $this->mysql_now . '", "%m-%d") AND
  279.                            NOT EXISTS (
  280.                                SELECT * FROM `' . Entities\SentNotification::getTableName() . '` `sn` WHERE
  281.                                    DATE(`sn`.`created`) = DATE("' . $this->mysql_now . '") AND
  282.                                    `sn`.`gateway`       = "' . $notification->get( 'gateway' ) . '" AND
  283.                                    `sn`.`type`          = "client_birthday_greeting" AND
  284.                                    `sn`.`ref_id`        = `c`.`id`
  285.                            )',
  286.                         ARRAY_A
  287.                     );
  288.  
  289.                     if ( $customers ) {
  290.                         foreach ( $customers as $customer ) {
  291.                             if ( Lib\NotificationSender::sendFromCronBirthdayGreeting( $notification, $customer ) ) {
  292.                                 $this->_notificationSent( $notification->get( 'type' ), $notification->get( 'gateway' ), $customer['id'] );
  293.                             }
  294.                         }
  295.                     }
  296.                 }
  297.                 break;
  298.         }
  299.     }
  300.  
  301.     /**
  302.      * @param Entities\Notification $notification
  303.      * @param integer               $minutes_interval
  304.      * @return array
  305.      */
  306.     private function getClientReminderAppointments( Entities\Notification $notification, $minutes_interval )
  307.     {
  308.         /** @var \wpdb $wpdb */
  309.         global $wpdb;
  310.  
  311.         /**
  312.          * Current mysql time + time left >= ymdH of appointment start
  313.          * AND DATE(Current mysql time)   <= DATE(appointment.start_date)
  314.          * AND the reminder wasn't send yet.
  315.          */
  316.         return $wpdb->get_results(
  317.             'SELECT `ca`.*
  318.                     FROM `' . Entities\CustomerAppointment::getTableName() . '` `ca`
  319.                LEFT JOIN `' . Entities\Appointment::getTableName() . '` `a` ON `a`.`id` = `ca`.`appointment_id`
  320.                    WHERE `ca`.`status` IN("' . Entities\CustomerAppointment::STATUS_PENDING . '","' . Entities\CustomerAppointment::STATUS_APPROVED . '")
  321.                      AND DATE_FORMAT(DATE_ADD("' . $this->mysql_now . '", INTERVAL ' . (int) $minutes_interval . ' MINUTE),\'%y%m%d%H\') >= DATE_FORMAT(`a`.`start_date`,\'%y%m%d%H\')
  322.                      AND DATE("' . $this->mysql_now . '") <= DATE(`a`.`start_date`)
  323.                      AND NOT EXISTS (
  324.                            SELECT * FROM `' . Entities\SentNotification::getTableName() . '` `sn`
  325.                             WHERE `sn`.`created` >= DATE_SUB("' . $this->mysql_now . '", INTERVAL 14 DAY)
  326.                               AND `sn`.`gateway`  = "' . $notification->get( 'gateway' ) . '"
  327.                               AND `sn`.`type`     = "' . $notification->get( 'type' ) . '"
  328.                               AND `sn`.`ref_id`   = `ca`.`id`
  329.                    ) ORDER BY `a`.`start_date`',
  330.             ARRAY_A
  331.         );
  332.     }
  333.  
  334.     /**
  335.      * Mark sent notification.
  336.      *
  337.      * @param $type
  338.      * @param $gateway
  339.      * @param $ref_id
  340.      */
  341.     private function _notificationSent( $type, $gateway, $ref_id )
  342.     {
  343.         $sent_notification = new Entities\SentNotification();
  344.         $sent_notification
  345.             ->set( 'ref_id',  $ref_id )
  346.             ->set( 'type',    $type )
  347.             ->set( 'gateway', $gateway )
  348.             ->set( 'created', $this->mysql_now )
  349.             ->save();
  350.     }
  351.  
  352.     /**
  353.      * Constructor
  354.      */
  355.     public function __construct()
  356.     {
  357.         // Disable caching.
  358.         Lib\Utils\Common::noCache();
  359.  
  360.         date_default_timezone_set( 'UTC' );
  361.  
  362.         wp_load_translations_early();
  363.  
  364.         $now = Lib\Slots\DatePoint::now();
  365.         $this->mysql_now = $now->format( 'Y-m-d H:i:s' );
  366.         $this->hours     = $now->format( 'H' );
  367.         $this->sms       = new Lib\SMS();
  368.  
  369.         $query = Entities\Notification::query()
  370.             ->where( 'active', 1 )
  371.             ->whereIn( 'type', array( 'staff_agenda', 'client_follow_up', 'client_reminder', 'client_reminder_1st', 'client_reminder_2nd', 'client_reminder_3rd', 'client_birthday_greeting' ) );
  372.  
  373.         foreach ( $query->find() as $notification ) {
  374.             $this->processNotification( $notification );
  375.         }
  376.     }
  377.  
  378. }
  379.  
  380. do_action( 'bookly_send_notifications' );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement