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