Passed
Push — master ( 2bd1cf...bfbffa )
by
unknown
05:03
created

MonsterInsights_Notification_Event_Runner   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 38
c 1
b 0
f 0
dl 0
loc 156
rs 10
wmc 19

8 Methods

Rating   Name   Duplication   Size   Complexity  
A get_notifications_last_run() 0 6 2
A register_notification() 0 5 4
A maybe_add_notifications() 0 37 5
A update_last_run() 0 7 2
A get_instance() 0 6 2
A save_last_runs() 0 3 2
A __construct() 0 2 1
A get_registered_notifications() 0 2 1
1
<?php
2
/**
3
 * Custom runner system for recurring notifications.
4
 *
5
 * @since 7.14
6
 * @author Mircea Sandu
7
 * @package MonsterInsights
8
 */
9
10
/**
11
 * Class MonsterInsights_Notification_Event_Runner
12
 */
13
class MonsterInsights_Notification_Event_Runner {
14
15
	/**
16
	 * The instance of the current class.
17
	 *
18
	 * @var MonsterInsights_Notification_Event_Runner
19
	 */
20
	private static $instance;
21
22
	/**
23
	 * The static notifications registered.
24
	 *
25
	 * @var array
26
	 */
27
	private static $notifications = array();
28
29
	/**
30
	 * The key used to store in the options table the last run times for notifications.
31
	 *
32
	 * @var string
33
	 */
34
	private $last_run_key = 'monsterinsights_notifications_run';
35
36
	/**
37
	 * This will be populated on demand with the last run timestamps for all the notifications.
38
	 *
39
	 * @var array|bool
40
	 */
41
	private $last_run;
42
43
	/**
44
	 * Only update the option if something changed.
45
	 *
46
	 * @var bool
47
	 */
48
	private $changed = false;
49
50
	/**
51
	 * MonsterInsights_Notification_Event_Runner constructor.
52
	 */
53
	private function __construct() {
54
		add_action( 'wp_ajax_monsterinsights_vue_get_notifications', array( $this, 'maybe_add_notifications' ), 9 );
55
	}
56
57
	/**
58
	 * Get the singleton instance.
59
	 *
60
	 * @return MonsterInsights_Notification_Event_Runner
61
	 */
62
	public static function get_instance() {
63
		if ( ! isset( self::$instance ) ) {
64
			self::$instance = new self();
65
		}
66
67
		return self::$instance;
68
	}
69
70
	/**
71
	 * Get the stored option for the last run times.
72
	 *
73
	 * @return false|mixed|void
74
	 */
75
	public function get_notifications_last_run() {
76
		if ( ! isset( $this->last_run ) ) {
77
			$this->last_run = get_option( $this->last_run_key );
78
		}
79
80
		return $this->last_run;
81
	}
82
83
	/**
84
	 * Update the last run time with a default of time.
85
	 *
86
	 * @param string     $notification_id The notification id to update the last run time for.
87
	 * @param string|int $time The timestamp to store the last run time.
88
	 */
89
	public function update_last_run( $notification_id, $time = '' ) {
90
		if ( empty( $time ) ) {
91
			$time = time();
92
		}
93
94
		$this->last_run[ $notification_id ] = $time;
95
		$this->changed                      = true;
96
	}
97
98
	/**
99
	 * Update the option stored in the db with the last run times.
100
	 */
101
	public function save_last_runs() {
102
		if ( $this->changed ) {
103
			update_option( $this->last_run_key, $this->last_run );
104
		}
105
	}
106
107
	/**
108
	 * Loop through notifications and check if they should be added based on the time passed since they were last added.
109
	 */
110
	public function maybe_add_notifications() {
111
112
		if ( ! current_user_can( 'monsterinsights_view_dashboard' ) ) {
113
			// No need to try adding the notification if the user can't see it.
114
			return;
115
		}
116
117
		$notifications = $this->get_registered_notifications();
118
		$last_runs     = $this->get_notifications_last_run();
119
120
		// Loop through registered notifications.
121
		foreach ( $notifications as $notification ) {
122
			/**¬
123
			 * The notification instance.
124
			 *
125
			 * @var MonsterInsights_Notification_Event $notification
126
			 */
127
			if ( empty( $last_runs[ $notification->notification_id ] ) ) {
128
				// If the notification never ran, save current time to show it after the interval.
129
				$this->update_last_run( $notification->notification_id );
130
			} else {
131
				// Has run before so let's check if enough days passed since the last run.
132
				$time_since = $last_runs[ $notification->notification_id ] + $notification->notification_interval * DAY_IN_SECONDS;
133
				$time_now   = time();
134
				if ( $time_since < $time_now ) {
135
					// Interval passed since it ran so let's add this one.
136
					$notification->add_notification();
137
					// Update the last run date as right now.
138
					$this->update_last_run( $notification->notification_id );
139
					// Let's not add multiple notifications at the same time.
140
					break;
141
				}
142
			}
143
		}
144
145
		// Update the option with the new times.
146
		$this->save_last_runs();
147
148
	}
149
150
	/**
151
	 * Get the static notifications array.
152
	 *
153
	 * @return array
154
	 */
155
	public function get_registered_notifications() {
156
		return self::$notifications;
157
	}
158
159
	/**
160
	 * Register the notification for running it later.
161
	 *
162
	 * @param MonsterInsights_Notification_Event $notification The instance of the notification.
163
	 */
164
	public function register_notification( $notification ) {
165
166
		$notification_id = isset( $notification->notification_id ) ? $notification->notification_id : false;
167
		if ( ! empty( $notification_id ) && ! isset( self::$notifications[ $notification_id ] ) ) {
168
			self::$notifications[ $notification_id ] = $notification;
169
		}
170
171
	}
172
173
}
174
175
/**
176
 * Get the single instance of the event runner class.
177
 *
178
 * @return MonsterInsights_Notification_Event_Runner
179
 */
180
function monsterinsights_notification_event_runner() {
181
	return MonsterInsights_Notification_Event_Runner::get_instance();
182
}
183