227 lines
5.5 KiB
PHP
227 lines
5.5 KiB
PHP
<?php
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Notifications Runner class.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @package UserFeedback
|
|
* @author David Paternina
|
|
*/
|
|
class UserFeedback_Notifications_Runner {
|
|
|
|
/**
|
|
* The instance of the current class.
|
|
*
|
|
* @var UserFeedback_Notifications_Runner
|
|
*/
|
|
private static $instance;
|
|
|
|
/**
|
|
* The static notifications registered.
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $notifications = array();
|
|
|
|
/**
|
|
* The key used to store in the options' table the last run times for notifications.
|
|
*
|
|
* @var string
|
|
*/
|
|
private $last_run_key = 'userfeedback_notifications_run';
|
|
|
|
/**
|
|
* This will be populated on demand with the last run timestamps for all the notifications.
|
|
*
|
|
* @var array|bool
|
|
*/
|
|
private $last_run;
|
|
|
|
/**
|
|
* Only update the option if something changed.
|
|
*
|
|
* @var bool
|
|
*/
|
|
private $changed = false;
|
|
|
|
/**
|
|
* MonsterInsights_Notification_Event_Runner constructor.
|
|
*/
|
|
private function __construct() {
|
|
add_action( 'userfeedback_run_notifications', array( $this, 'maybe_add_notifications' ), 9 );
|
|
}
|
|
|
|
/**
|
|
* Get the singleton instance.
|
|
*
|
|
* @return UserFeedback_Notifications_Runner
|
|
*/
|
|
public static function get_instance() {
|
|
if ( ! isset( self::$instance ) ) {
|
|
self::$instance = new self();
|
|
}
|
|
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Get the stored option for the last run times.
|
|
*
|
|
* @return false|mixed|void
|
|
*/
|
|
public function get_notifications_last_run() {
|
|
if ( ! isset( $this->last_run ) ) {
|
|
$this->last_run = get_option( $this->last_run_key );
|
|
}
|
|
|
|
return $this->last_run;
|
|
}
|
|
|
|
/**
|
|
* Update the last run time with a default of time.
|
|
*
|
|
* @param string $notification_id The notification id to update the last run time for.
|
|
* @param string|int $time The timestamp to store the last run time.
|
|
*/
|
|
public function update_last_run( $notification_id, $time = '' ) {
|
|
if ( empty( $time ) ) {
|
|
$time = time();
|
|
}
|
|
|
|
$this->last_run[ $notification_id ] = $time;
|
|
$this->changed = true;
|
|
}
|
|
|
|
/**
|
|
* Update the option stored in the db with the last run times.
|
|
*/
|
|
public function save_last_runs() {
|
|
if ( $this->changed ) {
|
|
update_option( $this->last_run_key, $this->last_run, false );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loop through notifications and check if they should be added based on the time passed since they were last added.
|
|
*/
|
|
public function maybe_add_notifications() {
|
|
|
|
if ( ! current_user_can( 'userfeedback_create_edit_surveys' )
|
|
&& ! current_user_can( 'userfeedback_save_settings' ) ) {
|
|
// No need to try adding the notification if the user can't see it.
|
|
return;
|
|
}
|
|
|
|
$notifications = $this->get_registered_notifications();
|
|
$last_runs = $this->get_notifications_last_run();
|
|
|
|
$current_runs = 0;
|
|
|
|
// Loop through registered notifications.
|
|
foreach ( $notifications as $notification ) {
|
|
/**¬
|
|
* The notification instance.
|
|
*
|
|
* @var UserFeedback_Notification_Event $notification
|
|
*/
|
|
if ( empty( $last_runs[ $notification->id ] ) ) {
|
|
// If the notification never ran, save current time to show it after the interval.
|
|
$this->update_last_run( $notification->id );
|
|
} else {
|
|
// Has run before so let's check if enough days passed since the last run.
|
|
$time_since = $last_runs[ $notification->id ] + $notification->interval * DAY_IN_SECONDS;
|
|
$time_now = time();
|
|
if ( apply_filters( 'userfeedback_notifications_skip_interval_check', false ) || $time_since < $time_now ) {
|
|
// Interval passed since it ran so let's add this one.
|
|
|
|
$current_runs ++;
|
|
$added_notification = self::$instance->add_notification( $notification->prepare() );
|
|
|
|
// Update the last run date as right now.
|
|
$this->update_last_run( $notification->id );
|
|
|
|
// Avoid adding multiple notifications at the same time, and
|
|
// also avoid running more than 5 notifications that returned
|
|
// no data, otherwise this request would take too long
|
|
if ( $added_notification || $current_runs > 5 ) {
|
|
// Let's not add multiple notifications at the same time.
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update the option with the new times.
|
|
$this->save_last_runs();
|
|
|
|
}
|
|
|
|
/**
|
|
* Add notification
|
|
*
|
|
* @param null|UserFeedback_Notification_Event $notification
|
|
* @return bool
|
|
*/
|
|
public function add_notification( $notification ) {
|
|
if ( $notification === null ) {
|
|
return false;
|
|
}
|
|
|
|
$notifications = UserFeedback()->notifications;
|
|
|
|
if ( $notifications->is_dismissed( $notification ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( $notification->should_display() ) {
|
|
return $notifications->add( $notification );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get the static notifications array.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_registered_notifications() {
|
|
return self::$notifications;
|
|
}
|
|
|
|
/**
|
|
* Register the notification for running it later.
|
|
*
|
|
* @param UserFeedback_Notification_Event $notification The instance of the notification.
|
|
*/
|
|
public function register_notification( $notification ) {
|
|
|
|
$notification_id = isset($notification->id) ? $notification->id : false;
|
|
|
|
if ( ! empty( $notification_id ) && ! isset( self::$notifications[ $notification_id ] ) ) {
|
|
self::$notifications[ $notification_id ] = $notification;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete the data on uninstall.
|
|
*/
|
|
public function delete_data() {
|
|
delete_option( $this->last_run_key );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the single instance of the event runner class.
|
|
*
|
|
* @return UserFeedback_Notifications_Runner
|
|
*/
|
|
function userfeedback_notification_event_runner() {
|
|
return UserFeedback_Notifications_Runner::get_instance();
|
|
}
|