Completed
Push — master ( 4e938f...04ef58 )
by Stephanie
27s queued 11s
created

FrmInbox::add_message()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 5
nop 1
dl 0
loc 27
rs 8.8657
c 0
b 0
f 0
1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	die( 'You are not allowed to call this page directly.' );
4
}
5
6
/**
7
 * @since 4.05
8
 */
9
class FrmInbox extends FrmFormApi {
10
11
	protected $cache_key;
12
13
	private $option = 'frm_inbox';
14
15
	private $messages = false;
16
17
	public function __construct( $for_parent = null ) {
18
		$this->set_cache_key();
19
		$this->set_messages();
20
	}
21
22
	/**
23
	 * @since 4.05
24
	 */
25
	protected function set_cache_key() {
26
		$this->cache_key = 'frm_inbox_cache';
27
	}
28
29
	/**
30
	 * @since 4.05
31
	 */
32
	protected function api_url() {
33
		return 'https://formidableforms.com/wp-json/inbox/v1/message/';
34
	}
35
36
	/**
37
	 * @since 4.05
38
	 */
39
	public function get_messages( $filter = false ) {
40
		$messages = $this->messages;
41
		if ( $filter === 'filter' ) {
42
			$this->filter_messages( $messages );
43
		}
44
		return $messages;
45
	}
46
47
	/**
48
	 * @since 4.05
49
	 */
50
	public function set_messages() {
51
		$this->messages = get_option( $this->option );
52
		if ( empty( $this->messages ) ) {
53
			$this->messages = array();
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type boolean of property $messages.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
		}
55
56
		$this->add_api_messages();
57
58
		/**
59
		 * Messages are in an array.
60
		 */
61
		$this->messages = apply_filters( 'frm_inbox', $this->messages );
62
	}
63
64
	/**
65
	 * @since 4.05
66
	 */
67
	private function add_api_messages() {
68
		$api = $this->get_api_info();
69
		if ( empty( $api ) ) {
70
			return;
71
		}
72
73
		foreach ( $api as $message ) {
74
			$this->add_message( $message );
75
		}
76
	}
77
78
	/**
79
	 * @param array|string $message
80
	 */
81
	public function add_message( $message ) {
82
		if ( ! is_array( $message ) ) {
83
			// if the API response is invalid, $message may not be an array.
84
			return;
85
		}
86
87
		if ( isset( $this->messages[ $message['key'] ] ) && ! isset( $message['force'] ) ) {
88
			// Don't replace messages unless required.
89
			return;
90
		}
91
92
		if ( $this->is_expired( $message ) ) {
93
			return;
94
		}
95
96
		if ( isset( $this->messages[ $message['key'] ] ) ) {
97
			// Move up and mark as new.
98
			unset( $this->messages[ $message['key'] ] );
99
		}
100
101
		$this->fill_message( $message );
102
		$this->messages[ $message['key'] ] = $message;
103
104
		$this->update_list();
105
106
		$this->clean_messages();
107
	}
108
109
	private function fill_message( &$message ) {
110
		$defaults = array(
111
			'time'    => time(),
112
			'message' => '',
113
			'subject' => '',
114
			'icon'    => 'frm_tooltip_icon',
115
			'cta'     => '',
116
			'expires' => false,
117
			'who'     => 'all', // use 'free', 'personal', 'business', 'elite', 'grandfathered'
118
			'type'    => '',
119
		);
120
121
		$message = array_merge( $defaults, $message );
122
123
		$message['created'] = $message['time'];
124
		unset( $message['time'] );
125
	}
126
127
	private function clean_messages() {
128
		$removed  = false;
129
		foreach ( $this->messages as $t => $message ) {
0 ignored issues
show
Bug introduced by
The expression $this->messages of type boolean is not traversable.
Loading history...
130
			$read    = isset( $message['read'] ) && ! empty( $message['read'] ) && isset( $message['read'][ get_current_user_id() ] ) && $message['read'][ get_current_user_id() ] < strtotime( '-1 month' );
131
			$dismissed = isset( $message['dismissed'] ) && ! empty( $message['dismissed'] ) && isset( $message['dismissed'][ get_current_user_id() ] ) && $message['dismissed'][ get_current_user_id() ] < strtotime( '-1 week' );
132
			$expired = $this->is_expired( $message );
133
			if ( $read || $expired || $dismissed ) {
134
				unset( $this->messages[ $t ] );
135
				$removed = true;
136
			}
137
		}
138
139
		if ( $removed ) {
140
			$this->update_list();
141
		}
142
	}
143
144
	private function filter_messages( &$messages ) {
145
		$user_id = get_current_user_id();
146
		foreach ( $messages as $k => $message ) {
147
			$dismissed = isset( $message['dismissed'] ) && isset( $message['dismissed'][ $user_id ] );
148
			if ( empty( $k ) || $this->is_expired( $message ) || $dismissed ) {
149
				unset( $messages[ $k ] );
150
			} elseif ( ! $this->is_for_user( $message ) ) {
151
				unset( $messages[ $k ] );
152
			}
153
		}
154
		$messages = apply_filters( 'frm_filter_inbox', $messages );
155
	}
156
157
	private function is_expired( $message ) {
158
		return isset( $message['expires'] ) && ! empty( $message['expires'] ) && $message['expires'] < time();
159
	}
160
161
	/**
162
	 * Show different messages for different accounts.
163
	 */
164
	private function is_for_user( $message ) {
165
		if ( ! isset( $message['who'] ) || $message['who'] === 'all' ) {
166
			return true;
167
		}
168
169
		return in_array( $this->get_user_type(), (array) $message['who'] );
170
	}
171
172
	private function get_user_type() {
173
		if ( ! FrmAppHelper::pro_is_installed() ) {
174
			return 'free';
175
		}
176
177
		return FrmAddonsController::license_type();
178
	}
179
180
	/**
181
	 * @param string $key
182
	 */
183 View Code Duplication
	public function mark_read( $key ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
		if ( ! $key || ! isset( $this->messages[ $key ] ) ) {
185
			return;
186
		}
187
188
		if ( ! isset( $this->messages[ $key ]['read'] ) ) {
189
			$this->messages[ $key ]['read'] = array();
190
		}
191
		$this->messages[ $key ]['read'][ get_current_user_id() ] = time();
192
193
		$this->update_list();
194
	}
195
196
	/**
197
	 * @param string $key
198
	 *
199
	 * @since 4.05.02
200
	 */
201
	public function mark_unread( $key ) {
202
		$is_read = isset( $this->messages[ $key ] ) && isset( $this->messages[ $key ]['read'] ) && isset( $this->messages[ $key ]['read'][ get_current_user_id() ] );
203
		if ( $is_read ) {
204
			unset( $this->messages[ $key ]['read'][ get_current_user_id() ] );
205
			$this->update_list();
206
		}
207
	}
208
209
	/**
210
	 * @param string $key
211
	 */
212 View Code Duplication
	public function dismiss( $key ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
213
		if ( $key === 'all' ) {
214
			$this->dismiss_all();
215
			return;
216
		}
217
218
		if ( ! isset( $this->messages[ $key ] ) ) {
219
			return;
220
		}
221
222
		if ( ! isset( $this->messages[ $key ]['dismissed'] ) ) {
223
			$this->messages[ $key ]['dismissed'] = array();
224
		}
225
		$this->messages[ $key ]['dismissed'][ get_current_user_id() ] = time();
226
227
		$this->update_list();
228
	}
229
230
	/**
231
	 * @since 4.06
232
	 */
233
	private function dismiss_all() {
234
		$user_id = get_current_user_id();
235
		foreach ( $this->messages as $key => $message ) {
0 ignored issues
show
Bug introduced by
The expression $this->messages of type boolean is not traversable.
Loading history...
236
			if ( ! isset( $message['dismissed'] ) ) {
237
				$this->messages[ $key ]['dismissed'] = array();
238
			}
239
240
			if ( ! isset( $message['dismissed'][ $user_id ] ) ) {
241
				$this->messages[ $key ]['dismissed'][ $user_id ] = time();
242
			}
243
		}
244
		$this->update_list();
245
	}
246
247
	public function unread() {
248
		$messages = $this->get_messages( 'filter' );
249
		$user_id  = get_current_user_id();
250
		foreach ( $messages as $t => $message ) {
251
			if ( isset( $message['read'] ) && isset( $message['read'][ $user_id ] ) ) {
252
				unset( $messages[ $t ] );
253
			}
254
		}
255
		return $messages;
256
	}
257
258
	public function unread_html() {
259
		$html = '';
260
		$count = count( $this->unread() );
261
		if ( $count ) {
262
			$html = ' <span class="update-plugins frm_inbox_count"><span class="plugin-count">' . absint( $count ) . '</span></span>';
263
264
			/**
265
			 * @since 4.06.01
266
			 */
267
			$html = apply_filters( 'frm_inbox_badge', $html );
268
		}
269
		return $html;
270
	}
271
272
	/**
273
	 * @since 4.05.02
274
	 */
275
	public function remove( $key ) {
276
		if ( isset( $this->messages[ $key ] ) ) {
277
			unset( $this->messages[ $key ] );
278
			$this->update_list();
279
		}
280
	}
281
282
	private function update_list() {
283
		update_option( $this->option, $this->messages, 'no' );
284
	}
285
}
286