/freemius/includes/managers/class-fs-admin-notice-manager.php

  1. <?php 
  2. /** 
  3. * @package Freemius 
  4. * @copyright Copyright (c) 2015, Freemius, Inc. 
  5. * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License 
  6. * @since 1.0.7 
  7. */ 
  8.  
  9. if ( ! defined( 'ABSPATH' ) ) { 
  10. exit; 
  11.  
  12. class FS_Admin_Notice_Manager { 
  13. /** 
  14. * @var string 
  15. */ 
  16. protected $_slug; 
  17. /** 
  18. * @var string 
  19. */ 
  20. protected $_title; 
  21. /** 
  22. * @var array[] 
  23. */ 
  24. private $_admin_messages = array(); 
  25. /** 
  26. * @var FS_Key_Value_Storage 
  27. */ 
  28. private $_sticky_storage; 
  29. /** 
  30. * @var FS_Plugin_Manager[] 
  31. */ 
  32. private static $_instances = array(); 
  33. /** 
  34. * @var FS_Logger 
  35. */ 
  36. protected $_logger; 
  37.  
  38. /** 
  39. * @param string $slug 
  40. * @param string $title 
  41. * 
  42. * @return FS_Admin_Notice_Manager 
  43. */ 
  44. static function instance( $slug, $title = '' ) { 
  45. if ( ! isset( self::$_instances[ $slug ] ) ) { 
  46. self::$_instances[ $slug ] = new FS_Admin_Notice_Manager( $slug, $title ); 
  47.  
  48. return self::$_instances[ $slug ]; 
  49.  
  50. protected function __construct( $slug, $title = '' ) { 
  51. $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $slug . '_data', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); 
  52.  
  53. $this->_slug = $slug; 
  54. $this->_title = ! empty( $title ) ? $title : ''; 
  55. $this->_sticky_storage = FS_Key_Value_Storage::instance( 'admin_notices', $this->_slug ); 
  56.  
  57. if ( is_admin() ) { 
  58. if ( 0 < count( $this->_sticky_storage ) ) { 
  59. // If there are sticky notices for the current slug, add a callback 
  60. // to the AJAX action that handles message dismiss. 
  61. add_action( "wp_ajax_fs_dismiss_notice_action_{$slug}", array( 
  62. &$this,  
  63. 'dismiss_notice_ajax_callback' 
  64. ) ); 
  65.  
  66. foreach ( $this->_sticky_storage as $id => $msg ) { 
  67. // Add admin notice. 
  68. $this->add( 
  69. $msg['message'],  
  70. $msg['title'],  
  71. $msg['type'],  
  72. true,  
  73. $msg['all'],  
  74. $msg['id'],  
  75. false 
  76. ); 
  77.  
  78. /** 
  79. * Remove sticky message by ID. 
  80. * 
  81. * @author Vova Feldman (@svovaf) 
  82. * @since 1.0.7 
  83. * 
  84. */ 
  85. function dismiss_notice_ajax_callback() { 
  86. $this->_sticky_storage->remove( $_POST['message_id'] ); 
  87. wp_die(); 
  88.  
  89. /** 
  90. * Rendered sticky message dismiss JavaScript. 
  91. * 
  92. * @author Vova Feldman (@svovaf) 
  93. * @since 1.0.7 
  94. */ 
  95. static function _add_sticky_dismiss_javascript() { 
  96. $params = array(); 
  97. fs_require_once_template( 'sticky-admin-notice-js.php', $params ); 
  98.  
  99. private static $_added_sticky_javascript = false; 
  100.  
  101. /** 
  102. * Hook to the admin_footer to add sticky message dismiss JavaScript handler. 
  103. * 
  104. * @author Vova Feldman (@svovaf) 
  105. * @since 1.0.7 
  106. */ 
  107. private static function has_sticky_messages() { 
  108. if ( ! self::$_added_sticky_javascript ) { 
  109. add_action( 'admin_footer', array( 'FS_Admin_Notice_Manager', '_add_sticky_dismiss_javascript' ) ); 
  110.  
  111. /** 
  112. * Handle admin_notices by printing the admin messages stacked in the queue. 
  113. * 
  114. * @author Vova Feldman (@svovaf) 
  115. * @since 1.0.4 
  116. * 
  117. */ 
  118. function _admin_notices_hook() { 
  119. $notice_type = 'admin_notices'; 
  120.  
  121. if ( function_exists( 'current_user_can' ) && 
  122. ! current_user_can( 'manage_options' ) 
  123. ) { 
  124. // Only show messages to admins. 
  125. return; 
  126.  
  127. if ( ! isset( $this->_admin_messages[ $notice_type ] ) || ! is_array( $this->_admin_messages[ $notice_type ] ) ) { 
  128. return; 
  129.  
  130. foreach ( $this->_admin_messages[ $notice_type ] as $id => $msg ) { 
  131. fs_require_template( 'admin-notice.php', $msg ); 
  132.  
  133. if ( $msg['sticky'] ) { 
  134. self::has_sticky_messages(); 
  135.  
  136. /** 
  137. * Handle all_admin_notices by printing the admin messages stacked in the queue. 
  138. * 
  139. * @author Vova Feldman (@svovaf) 
  140. * @since 1.0.4 
  141. * 
  142. */ 
  143. function _all_admin_notices_hook() { 
  144. $notice_type = 'all_admin_notices'; 
  145.  
  146. if ( ! isset( $this->_admin_messages[ $notice_type ] ) || ! is_array( $this->_admin_messages[ $notice_type ] ) ) { 
  147. return; 
  148.  
  149. foreach ( $this->_admin_messages[ $notice_type ] as $id => $msg ) { 
  150. fs_require_template( 'all-admin-notice.php', $msg ); 
  151.  
  152. /** 
  153. * Enqueue common stylesheet to style admin notice. 
  154. * 
  155. * @author Vova Feldman (@svovaf) 
  156. * @since 1.0.7 
  157. */ 
  158. function _enqueue_styles() { 
  159. fs_enqueue_local_style( 'fs_common', '/admin/common.css' ); 
  160.  
  161. /** 
  162. * Add admin message to admin messages queue, and hook to admin_notices / all_admin_notices if not yet hooked. 
  163. * 
  164. * @author Vova Feldman (@svovaf) 
  165. * @since 1.0.4 
  166. * 
  167. * @param string $message 
  168. * @param string $title 
  169. * @param string $type 
  170. * @param bool $is_sticky 
  171. * @param bool $all_admin 
  172. * @param string $id Message ID 
  173. * @param bool $store_if_sticky 
  174. * 
  175. * @uses add_action() 
  176. */ 
  177. function add( $message, $title = '', $type = 'success', $is_sticky = false, $all_admin = false, $id = '', $store_if_sticky = true ) { 
  178. $key = ( $all_admin ? 'all_admin_notices' : 'admin_notices' ); 
  179.  
  180. if ( ! isset( $this->_admin_messages[ $key ] ) ) { 
  181. $this->_admin_messages[ $key ] = array(); 
  182.  
  183. add_action( $key, array( &$this, "_{$key}_hook" ) ); 
  184. add_action( 'admin_enqueue_scripts', array( &$this, '_enqueue_styles' ) ); 
  185.  
  186.  
  187. if ( '' === $id ) { 
  188. $id = md5( $title . ' ' . $message . ' ' . $type ); 
  189.  
  190. $message_object = array( 
  191. 'message' => $message,  
  192. 'title' => $title,  
  193. 'type' => $type,  
  194. 'sticky' => $is_sticky,  
  195. 'id' => $id,  
  196. 'all' => $all_admin,  
  197. 'slug' => $this->_slug,  
  198. 'plugin' => $this->_title,  
  199. ); 
  200.  
  201. if ( $is_sticky && $store_if_sticky ) { 
  202. $this->_sticky_storage->{$id} = $message_object; 
  203.  
  204. $this->_admin_messages[ $key ][ $id ] = $message_object; 
  205.  
  206. /** 
  207. * @author Vova Feldman (@svovaf) 
  208. * @since 1.0.7 
  209. * 
  210. * @param string|string[] $ids 
  211. */ 
  212. function remove_sticky( $ids ) { 
  213. if ( ! is_array( $ids ) ) { 
  214. $ids = array( $ids ); 
  215.  
  216. foreach ( $ids as $id ) { 
  217. // Remove from sticky storage. 
  218. $this->_sticky_storage->remove( $id ); 
  219.  
  220. // Remove from current admin messages. 
  221. if ( isset( $this->_admin_messages['all_admin_notices'] ) && isset( $this->_admin_messages['all_admin_notices'][ $id ] ) ) { 
  222. unset( $this->_admin_messages['all_admin_notices'][ $id ] ); 
  223. if ( isset( $this->_admin_messages['admin_notices'] ) && isset( $this->_admin_messages['admin_notices'][ $id ] ) ) { 
  224. unset( $this->_admin_messages['admin_notices'][ $id ] ); 
  225.  
  226. /** 
  227. * Check if sticky message exists by id. 
  228. * 
  229. * @author Vova Feldman (@svovaf) 
  230. * @since 1.0.9 
  231. * 
  232. * @param $id 
  233. * 
  234. * @return bool 
  235. */ 
  236. function has_sticky( $id ) { 
  237. return isset( $this->_sticky_storage[ $id ] ); 
  238.  
  239. /** 
  240. * Adds sticky admin notification. 
  241. * 
  242. * @author Vova Feldman (@svovaf) 
  243. * @since 1.0.7 
  244. * 
  245. * @param string $message 
  246. * @param string $id Message ID 
  247. * @param string $title 
  248. * @param string $type 
  249. * @param bool $all_admin 
  250. */ 
  251. function add_sticky( $message, $id, $title = '', $type = 'success', $all_admin = false ) { 
  252. $message = fs_apply_filter( $this->_slug, "sticky_message_{$id}", $message ); 
  253. $title = fs_apply_filter( $this->_slug, "sticky_title_{$id}", $title ); 
  254.  
  255. $this->add( $message, $title, $type, true, $all_admin, $id ); 
  256.  
  257. /** 
  258. * Clear all sticky messages. 
  259. * 
  260. * @author Vova Feldman (@svovaf) 
  261. * @since 1.0.8 
  262. */ 
  263. function clear_all_sticky() { 
  264. $this->_sticky_storage->clear_all(); 
  265.  
  266. /** 
  267. * Add admin message to all admin messages queue, and hook to all_admin_notices if not yet hooked. 
  268. * 
  269. * @author Vova Feldman (@svovaf) 
  270. * @since 1.0.4 
  271. * 
  272. * @param string $message 
  273. * @param string $title 
  274. * @param string $type 
  275. * @param bool $is_sticky 
  276. * @param string $id Message ID 
  277. */ 
  278. function add_all( $message, $title = '', $type = 'success', $is_sticky = false, $id = '' ) { 
  279. $this->add( $message, $title, $type, $is_sticky, true, $id ); 
.