PageRenderTime 9ms CodeModel.GetById 1ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 1ms

/wp-content/plugins/wordpress-seo/admin/class-yoast-notification.php

https://bitbucket.org/carloskikea/helpet
PHP | 332 lines | 126 code | 46 blank | 160 comment | 16 complexity | 8fc438942af5773208244edff9880ab6 MD5 | raw file
  1<?php
  2/**
  3 * WPSEO plugin file.
  4 *
  5 * @package WPSEO\Admin\Notifications
  6 * @since   1.5.3
  7 */
  8
  9/**
 10 * Implements individual notification.
 11 */
 12class Yoast_Notification {
 13
 14	/**
 15	 * @var string Type of capability check.
 16	 */
 17	const MATCH_ALL = 'all';
 18
 19	/**
 20	 * @var string Type of capability check.
 21	 */
 22	const MATCH_ANY = 'any';
 23
 24	/**
 25	 * @var string Notification type.
 26	 */
 27	const ERROR = 'error';
 28
 29	/**
 30	 * @var string Notification type.
 31	 */
 32	const WARNING = 'warning';
 33
 34	/**
 35	 * @var string Notification type.
 36	 */
 37	const UPDATED = 'updated';
 38
 39	/**
 40	 * Contains optional arguments:
 41	 *
 42	 * -             type: The notification type, i.e. 'updated' or 'error'
 43	 * -               id: The ID of the notification
 44	 * -            nonce: Security nonce to use in case of dismissible notice.
 45	 * -         priority: From 0 to 1, determines the order of Notifications.
 46	 * -    dismissal_key: Option name to save dismissal information in, ID will be used if not supplied.
 47	 * -     capabilities: Capabilities that a user must have for this Notification to show.
 48	 * - capability_check: How to check capability pass: all or any.
 49	 * -  wpseo_page_only: Only display on wpseo page or on every page.
 50	 *
 51	 * @var array Options of this Notification.
 52	 */
 53	private $options = array();
 54
 55	/** @var array Contains default values for the optional arguments */
 56	private $defaults = array(
 57		'type'             => self::UPDATED,
 58		'id'               => '',
 59		'nonce'            => null,
 60		'priority'         => 0.5,
 61		'data_json'        => array(),
 62		'dismissal_key'    => null,
 63		'capabilities'     => array(),
 64		'capability_check' => self::MATCH_ALL,
 65	);
 66
 67	/**
 68	 * Notification class constructor.
 69	 *
 70	 * @param string $message Message string.
 71	 * @param array  $options Set of options.
 72	 */
 73	public function __construct( $message, $options = array() ) {
 74		$this->message = $message;
 75		$this->options = $this->normalize_options( $options );
 76	}
 77
 78	/**
 79	 * Retrieve notification ID string.
 80	 *
 81	 * @return string
 82	 */
 83	public function get_id() {
 84		return $this->options['id'];
 85	}
 86
 87	/**
 88	 * Retrieve nonce identifier.
 89	 *
 90	 * @return null|string Nonce for this Notification.
 91	 */
 92	public function get_nonce() {
 93		if ( $this->options['id'] && empty( $this->options['nonce'] ) ) {
 94			$this->options['nonce'] = wp_create_nonce( $this->options['id'] );
 95		}
 96
 97		return $this->options['nonce'];
 98	}
 99
100	/**
101	 * Make sure the nonce is up to date
102	 */
103	public function refresh_nonce() {
104		if ( $this->options['id'] ) {
105			$this->options['nonce'] = wp_create_nonce( $this->options['id'] );
106		}
107	}
108
109	/**
110	 * Get the type of the notification
111	 *
112	 * @return string
113	 */
114	public function get_type() {
115		return $this->options['type'];
116	}
117
118	/**
119	 * Priority of the notification
120	 *
121	 * Relative to the type.
122	 *
123	 * @return float Returns the priority between 0 and 1.
124	 */
125	public function get_priority() {
126		return $this->options['priority'];
127	}
128
129	/**
130	 * Get the User Meta key to check for dismissal of notification
131	 *
132	 * @return string User Meta Option key that registers dismissal.
133	 */
134	public function get_dismissal_key() {
135		if ( empty( $this->options['dismissal_key'] ) ) {
136			return $this->options['id'];
137		}
138
139		return $this->options['dismissal_key'];
140	}
141
142	/**
143	 * Is this Notification persistent
144	 *
145	 * @return bool True if persistent, False if fire and forget.
146	 */
147	public function is_persistent() {
148		$id = $this->get_id();
149
150		return ! empty( $id );
151	}
152
153	/**
154	 * Check if the notification is relevant for the current user
155	 *
156	 * @return bool True if a user needs to see this Notification, False if not.
157	 */
158	public function display_for_current_user() {
159		// If the notification is for the current page only, always show.
160		if ( ! $this->is_persistent() ) {
161			return true;
162		}
163
164		// If the current user doesn't match capabilities.
165		return $this->match_capabilities();
166	}
167
168	/**
169	 * Does the current user match required capabilities
170	 *
171	 * @return bool
172	 */
173	public function match_capabilities() {
174		// Super Admin can do anything.
175		if ( is_multisite() && is_super_admin() ) {
176			return true;
177		}
178
179		/**
180		 * Filter capabilities that enable the displaying of this notification.
181		 *
182		 * @since 3.2
183		 *
184		 * @param array              $capabilities The capabilities that must be present for this Notification.
185		 * @param Yoast_Notification $notification The notification object.
186		 *
187		 * @return array of capabilities or empty for no restrictions.
188		 */
189		$capabilities = apply_filters( 'wpseo_notification_capabilities', $this->options['capabilities'], $this );
190
191		// Should be an array.
192		if ( ! is_array( $capabilities ) ) {
193			$capabilities = (array) $capabilities;
194		}
195
196		/**
197		 * Filter capability check to enable all or any capabilities.
198		 *
199		 * @since 3.2
200		 *
201		 * @param string             $capability_check The type of check that will be used to determine if an capability is present.
202		 * @param Yoast_Notification $notification     The notification object.
203		 *
204		 * @return string self::MATCH_ALL or self::MATCH_ANY.
205		 */
206		$capability_check = apply_filters( 'wpseo_notification_capability_check', $this->options['capability_check'], $this );
207
208		if ( ! in_array( $capability_check, array( self::MATCH_ALL, self::MATCH_ANY ), true ) ) {
209			$capability_check = self::MATCH_ALL;
210		}
211
212		if ( ! empty( $capabilities ) ) {
213
214			$has_capabilities = array_filter( $capabilities, array( $this, 'has_capability' ) );
215
216			switch ( $capability_check ) {
217				case self::MATCH_ALL:
218					return $has_capabilities === $capabilities;
219				case self::MATCH_ANY:
220					return ! empty( $has_capabilities );
221			}
222		}
223
224		return true;
225	}
226
227	/**
228	 * Array filter function to find matched capabilities
229	 *
230	 * @param string $capability Capability to test.
231	 *
232	 * @return bool
233	 */
234	private function has_capability( $capability ) {
235		return current_user_can( $capability );
236	}
237
238	/**
239	 * Return the object properties as an array
240	 *
241	 * @return array
242	 */
243	public function to_array() {
244		return array(
245			'message' => $this->message,
246			'options' => $this->options,
247		);
248	}
249
250	/**
251	 * Adds string (view) behaviour to the Notification
252	 *
253	 * @return string
254	 */
255	public function __toString() {
256		return $this->render();
257	}
258
259	/**
260	 * Renders the notification as a string.
261	 *
262	 * @return string The rendered notification.
263	 */
264	public function render() {
265		$attributes = array();
266
267		// Default notification classes.
268		$classes = array(
269			'yoast-alert',
270		);
271
272		// Maintain WordPress visualisation of alerts when they are not persistent.
273		if ( ! $this->is_persistent() ) {
274			$classes[] = 'notice';
275			$classes[] = $this->get_type();
276		}
277
278		if ( ! empty( $classes ) ) {
279			$attributes['class'] = implode( ' ', $classes );
280		}
281
282		// Combined attribute key and value into a string.
283		array_walk( $attributes, array( $this, 'parse_attributes' ) );
284
285		// Build the output DIV.
286		return '<div ' . implode( ' ', $attributes ) . '>' . wpautop( $this->message ) . '</div>' . PHP_EOL;
287	}
288
289	/**
290	 * Get the JSON if provided
291	 *
292	 * @return false|string
293	 */
294	public function get_json() {
295		if ( empty( $this->options['data_json'] ) ) {
296			return '';
297		}
298
299		return wp_json_encode( $this->options['data_json'] );
300	}
301
302	/**
303	 * Make sure we only have values that we can work with
304	 *
305	 * @param array $options Options to normalize.
306	 *
307	 * @return array
308	 */
309	private function normalize_options( $options ) {
310		$options = wp_parse_args( $options, $this->defaults );
311
312		// Should not exceed 0 or 1.
313		$options['priority'] = min( 1, max( 0, $options['priority'] ) );
314
315		// Set default capabilities when not supplied.
316		if ( empty( $options['capabilities'] ) || array() === $options['capabilities'] ) {
317			$options['capabilities'] = array( 'wpseo_manage_options' );
318		}
319
320		return $options;
321	}
322
323	/**
324	 * Format HTML element attributes
325	 *
326	 * @param string $value Attribute value.
327	 * @param string $key   Attribute name.
328	 */
329	private function parse_attributes( & $value, $key ) {
330		$value = sprintf( '%s="%s"', $key, esc_attr( $value ) );
331	}
332}