| @@ -1,9 +1,11 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | - * Admin notices system. | |
| 3 | + * Warning notices | |
| 4 | 4 | * |
| 5 | - * @package Woody_Code_Snippets | |
| 5 | + * @author Webcraftic <WordPress.webraftic@gmail.com> | |
| 6 | + * @copyright (c) 11.12.2018, Webcraftic | |
| 7 | + * @version 1.0 | |
| 6 | 8 | */ |
| 7 | 9 | |
| 8 | 10 | // Exit if accessed directly |
| 9 | 11 | if ( ! defined( 'ABSPATH' ) ) { |
| @@ -9,443 +11,190 @@ | ||
| 9 | 11 | if ( ! defined( 'ABSPATH' ) ) { |
| 10 | 12 | exit; |
| 11 | 13 | } |
| 12 | 14 | |
| 13 | -/** | |
| 14 | - * Class WINP_Notices | |
| 15 | - */ | |
| 16 | -class WINP_Notices { | |
| 15 | +class WINP_WarningNotices { | |
| 17 | 16 | |
| 18 | 17 | /** |
| 19 | - * Class instance. | |
| 20 | - * | |
| 21 | - * @var WINP_Notices | |
| 18 | + * @var string | |
| 22 | 19 | */ |
| 23 | - private static $instance = null; | |
| 20 | + private $prefix = 'inp_'; | |
| 24 | 21 | |
| 25 | 22 | /** |
| 26 | - * Prefix. | |
| 27 | - * | |
| 28 | - * @var string | |
| 23 | + * @var array | |
| 29 | 24 | */ |
| 30 | - private static $prefix = 'winp_notice_'; | |
| 25 | + private $notices = []; | |
| 31 | 26 | |
| 27 | + public function __construct() { | |
| 28 | + /** | |
| 29 | + * @since 2.2.8 Filter Name Changed | |
| 30 | + */ | |
| 31 | + add_filter( 'wbcr/factory/admin_notices', [ $this, 'register_notices' ], 10, 2 ); | |
| 32 | + } | |
| 33 | + | |
| 32 | 34 | /** |
| 33 | - * Notices storage. | |
| 34 | - * | |
| 35 | - * @var array<int, array<string, mixed>> Notices data | |
| 35 | + * @author Alexander Kovalev <alex.kovalevv@gmail.com> | |
| 36 | + * | |
| 37 | + * @param array $notices | |
| 38 | + * @param string $plugin_name | |
| 39 | + * | |
| 40 | + * @return array | |
| 41 | + * @throws \Exception | |
| 36 | 42 | */ |
| 37 | - private static $notices = []; | |
| 43 | + public function register_notices( $notices, $plugin_name ) { | |
| 44 | + if ( $plugin_name !== WINP_Plugin::app()->getPluginName() ) { | |
| 45 | + return $notices; | |
| 46 | + } | |
| 38 | 47 | |
| 39 | - /** | |
| 40 | - * Private constructor to prevent direct instantiation. | |
| 41 | - */ | |
| 42 | - private function __construct() { | |
| 43 | - add_action( 'admin_notices', [ $this, 'display_notices' ] ); | |
| 44 | - add_action( 'wp_ajax_winp_dismiss_notice', [ $this, 'ajax_dismiss_notice' ] ); | |
| 45 | - add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); | |
| 48 | + if ( ! WINP_Plugin::app()->currentUserCan() ) { | |
| 49 | + return $notices; | |
| 50 | + } | |
| 51 | + | |
| 52 | + $this->add_notice( 'warning_security_notice', $this->get_warning_notice(), 'warning' ); | |
| 53 | + | |
| 54 | + if ( WINP_Plugin::app()->getOption( 'need_show_attention_notice' ) ) { | |
| 55 | + $this->add_notice( 'upgrade_plugin2', $this->get_upgrade_notice(), 'warning' ); | |
| 56 | + } | |
| 57 | + | |
| 58 | + $this->add_notice( 'safe_mode', $this->get_safe_mode_notice(), 'success', false ); | |
| 59 | + $this->add_notice( 'result_error', $this->get_throw_php_error_notice(), 'error', false, 0, [ | |
| 60 | + 'post', | |
| 61 | + 'post-new', | |
| 62 | + 'edit', | |
| 63 | + ] ); | |
| 64 | + /* | |
| 65 | + $this->add_notice( 'leave_feedback', $this->get_leave_feedback_notice(), 'success', true, time() + 3600 * 60, [ | |
| 66 | + 'post', | |
| 67 | + 'post-new', | |
| 68 | + 'edit' | |
| 69 | + ] );*/ | |
| 70 | + | |
| 71 | + return array_merge( $notices, $this->notices ); | |
| 46 | 72 | } |
| 47 | 73 | |
| 48 | 74 | /** |
| 49 | - * Get singleton instance | |
| 75 | + * This warning is for users of the old version 1.3.0. The plugin has changed the way it works | |
| 76 | + * and requires user actions to continue working with plugin. | |
| 50 | 77 | * |
| 51 | - * @return WINP_Notices | |
| 78 | + * @return string | |
| 52 | 79 | */ |
| 53 | - public static function instance() { | |
| 54 | - if ( null === self::$instance ) { | |
| 55 | - self::$instance = new self(); | |
| 80 | + public function get_warning_notice() { | |
| 81 | + if ( is_multisite() ) { | |
| 82 | + $notice = '<b>' . WINP_Plugin::app()->getPluginTitle() . '</b>: ' . sprintf( __( "ATTENTION! Use this plugin with care! Check your php scripts before inserting on your site. If you don't understand how the php script you are using works, try to avoid using it. Using unverified or outdated php scripts can damage the security of your site! Using the plugin on multisites can be dangerous as it will allow all administrators to insert php, js code. If you cannot control the work of administrators, we recommend that you do not use this plugin for security reasons. We are constantly working to improve the security of the plugin, but unfortunately we cannot check the code scripts you use that may violate the security of your site!", 'insert-php' ), WINP_Plugin::app()->getPluginVersion() ); | |
| 83 | + } else { | |
| 84 | + $notice = '<b>' . WINP_Plugin::app()->getPluginTitle() . '</b>: ' . sprintf( __( "ATTENTION! Use this plugin with care! Check your php scripts before inserting on your site. If you don't understand how the php script you are using works, try to avoid using it. Using unverified or outdated php scripts can damage the security of your site!", 'insert-php' ), WINP_Plugin::app()->getPluginVersion() ); | |
| 56 | 85 | } |
| 57 | - return self::$instance; | |
| 86 | + return $notice; | |
| 58 | 87 | } |
| 59 | 88 | |
| 60 | 89 | /** |
| 61 | - * Enqueue scripts for dismissible notices | |
| 62 | - * | |
| 63 | - * @return void | |
| 90 | + * A small line that asks for feedback from user | |
| 91 | + * | |
| 92 | + * @return string | |
| 64 | 93 | */ |
| 65 | - public function enqueue_scripts() { | |
| 66 | - // Only enqueue if there are notices to display. | |
| 67 | - if ( empty( self::$notices ) ) { | |
| 68 | - return; | |
| 94 | + /* | |
| 95 | + public function get_leave_feedback_notice() { | |
| 96 | + $post_type = WINP_Plugin::app()->request->get( 'post_type' ); | |
| 97 | + if ( ! empty( $post_type ) && WINP_SNIPPETS_POST_TYPE == $post_type ) { | |
| 98 | + return '<strong>' . __( 'Have feedback on Woody ad Snippets?', 'insert-php' ) . '</strong> ' . __( 'Please take the time to answer a short survey on how you use this plugin and what you\'d like to see changed or added in the future.', 'insert-php' ) . ' | |
| 99 | + <a href="http://bit.ly/2MpVokA" class="button secondary" target="_blank" style="margin: auto .5em;">' . __( 'Take the survey now', 'insert-php' ) . '</a>'; | |
| 69 | 100 | } |
| 70 | - | |
| 71 | - // Add CSS for error notice styling. | |
| 72 | - wp_add_inline_style( | |
| 73 | - 'common', | |
| 74 | - '.winp-admin-notice { | |
| 75 | - padding: 12px 16px !important; | |
| 76 | - } | |
| 77 | - .winp-admin-notice.is-dismissible { | |
| 78 | - padding-right: 38px !important; | |
| 79 | - } | |
| 80 | - .winp-admin-notice p { margin: 0.5em 0; } | |
| 81 | - .winp-admin-notice p:first-child { margin-top: 0; } | |
| 82 | - .winp-admin-notice p:last-child { margin-bottom: 0; } | |
| 83 | - .winp-error-notice-header { | |
| 84 | - margin-bottom: 10px; | |
| 85 | - font-size: 14px; | |
| 86 | - line-height: 1.5; | |
| 87 | - } | |
| 88 | - .winp-snippet-edit-link { | |
| 89 | - color: #2271b1; | |
| 90 | - text-decoration: none; | |
| 91 | - font-weight: 500; | |
| 92 | - border-bottom: 1px solid transparent; | |
| 93 | - transition: all 0.15s ease; | |
| 94 | - } | |
| 95 | - .winp-snippet-edit-link:hover { | |
| 96 | - color: #135e96; | |
| 97 | - border-bottom-color: #135e96; | |
| 98 | - } | |
| 99 | - .winp-snippet-edit-link:focus { | |
| 100 | - box-shadow: 0 0 0 2px #2271b1; | |
| 101 | - outline: 2px solid transparent; | |
| 102 | - border-radius: 2px; | |
| 103 | - } | |
| 104 | - .winp-admin-notice details { | |
| 105 | - margin: 10px 0 4px; | |
| 106 | - border: 1px solid rgba(0, 0, 0, 0.15); | |
| 107 | - border-radius: 4px; | |
| 108 | - background: #fff; | |
| 109 | - } | |
| 110 | - .winp-admin-notice details summary { | |
| 111 | - cursor: pointer; | |
| 112 | - font-weight: 500; | |
| 113 | - color: #2271b1; | |
| 114 | - padding: 10px 12px; | |
| 115 | - user-select: none; | |
| 116 | - font-size: 13px; | |
| 117 | - display: flex; | |
| 118 | - align-items: center; | |
| 119 | - transition: all 0.15s ease; | |
| 120 | - } | |
| 121 | - .winp-admin-notice details summary::-webkit-details-marker { | |
| 122 | - display: none; | |
| 123 | - } | |
| 124 | - .winp-admin-notice details summary::before { | |
| 125 | - content: "▶"; | |
| 126 | - display: inline-block; | |
| 127 | - margin-right: 8px; | |
| 128 | - font-size: 10px; | |
| 129 | - transition: transform 0.2s ease; | |
| 130 | - } | |
| 131 | - .winp-admin-notice details[open] summary::before { | |
| 132 | - transform: rotate(90deg); | |
| 133 | - } | |
| 134 | - .winp-admin-notice details summary:hover { | |
| 135 | - color: #135e96; | |
| 136 | - background: rgba(0, 0, 0, 0.03); | |
| 137 | - } | |
| 138 | - .winp-admin-notice details[open] summary { | |
| 139 | - border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |
| 140 | - background: rgba(0, 0, 0, 0.02); | |
| 141 | - } | |
| 142 | - .winp-error-details { | |
| 143 | - padding: 14px; | |
| 144 | - } | |
| 145 | - .winp-error-message, | |
| 146 | - .winp-error-location { | |
| 147 | - margin-bottom: 14px; | |
| 148 | - } | |
| 149 | - .winp-error-location { | |
| 150 | - margin-bottom: 0; | |
| 151 | - } | |
| 152 | - .winp-error-message strong, | |
| 153 | - .winp-error-location strong { | |
| 154 | - display: block; | |
| 155 | - margin-bottom: 6px; | |
| 156 | - font-size: 11px; | |
| 157 | - text-transform: uppercase; | |
| 158 | - color: #646970; | |
| 159 | - font-weight: 600; | |
| 160 | - letter-spacing: 0.5px; | |
| 161 | - } | |
| 162 | - .winp-error-message code { | |
| 163 | - display: block; | |
| 164 | - padding: 10px 12px; | |
| 165 | - background: #f6f7f7; | |
| 166 | - border-left: 3px solid #d63638; | |
| 167 | - font-size: 13px; | |
| 168 | - line-height: 1.6; | |
| 169 | - color: #d63638; | |
| 170 | - word-break: break-word; | |
| 171 | - font-family: Consolas, Monaco, monospace; | |
| 172 | - } | |
| 173 | - .winp-error-location { | |
| 174 | - font-size: 13px; | |
| 175 | - color: #2c3338; | |
| 176 | - line-height: 1.5; | |
| 177 | - } | |
| 178 | - .winp-line-number { | |
| 179 | - color: #646970; | |
| 180 | - font-style: italic; | |
| 181 | - } | |
| 182 | - .winp-error-notice-footer { | |
| 183 | - margin-top: 12px; | |
| 184 | - padding-top: 12px; | |
| 185 | - border-top: 1px solid rgba(0, 0, 0, 0.1); | |
| 186 | - display: flex; | |
| 187 | - align-items: center; | |
| 188 | - justify-content: space-between; | |
| 189 | - gap: 12px; | |
| 190 | - } | |
| 191 | - .winp-dismiss-help { | |
| 192 | - margin: 0 !important; | |
| 193 | - font-size: 13px; | |
| 194 | - color: #646970; | |
| 195 | - flex: 1; | |
| 196 | - } | |
| 197 | - .winp-manual-dismiss-btn { | |
| 198 | - background: #f0f0f1; | |
| 199 | - border-color: #2271b1; | |
| 200 | - color: #2271b1; | |
| 201 | - flex-shrink: 0; | |
| 202 | - font-weight: 500; | |
| 203 | - } | |
| 204 | - .winp-manual-dismiss-btn:hover { | |
| 205 | - background: #2271b1; | |
| 206 | - border-color: #2271b1; | |
| 207 | - color: #fff; | |
| 208 | - }' | |
| 209 | - ); | |
| 210 | - | |
| 211 | - wp_add_inline_script( | |
| 212 | - 'common', | |
| 213 | - '(function($) { | |
| 214 | - // Handle X button dismiss | |
| 215 | - $(document).on("click", ".winp-admin-notice.is-dismissible .notice-dismiss", function(e) { | |
| 216 | - var notice = $(this).closest(".winp-admin-notice"); | |
| 217 | - var noticeId = notice.data("notice-id"); | |
| 218 | - var nonce = notice.data("nonce"); | |
| 219 | - | |
| 220 | - if (noticeId && nonce && typeof ajaxurl !== "undefined") { | |
| 221 | - $.post(ajaxurl, { | |
| 222 | - action: "winp_dismiss_notice", | |
| 223 | - notice_id: noticeId, | |
| 224 | - nonce: nonce | |
| 225 | - }); | |
| 226 | - } | |
| 227 | - }); | |
| 228 | - | |
| 229 | - // Handle manual dismiss button | |
| 230 | - $(document).on("click", ".winp-manual-dismiss-btn", function(e) { | |
| 231 | - e.preventDefault(); | |
| 232 | - var notice = $(this).closest(".winp-admin-notice"); | |
| 233 | - var noticeId = notice.data("notice-id"); | |
| 234 | - var nonce = notice.data("nonce"); | |
| 235 | - | |
| 236 | - if (noticeId && nonce && typeof ajaxurl !== "undefined") { | |
| 237 | - $(this).prop("disabled", true).text("Dismissing..."); | |
| 238 | - | |
| 239 | - $.post(ajaxurl, { | |
| 240 | - action: "winp_dismiss_notice", | |
| 241 | - notice_id: noticeId, | |
| 242 | - nonce: nonce | |
| 243 | - }).done(function() { | |
| 244 | - notice.fadeOut(300, function() { | |
| 245 | - $(this).remove(); | |
| 246 | - }); | |
| 247 | - }).fail(function() { | |
| 248 | - alert("Failed to dismiss notice. Please try again."); | |
| 249 | - $(this).prop("disabled", false).text("Dismiss Notice"); | |
| 250 | - }); | |
| 251 | - } | |
| 252 | - }); | |
| 253 | - })(jQuery);' | |
| 254 | - ); | |
| 255 | - } | |
| 101 | + }*/ | |
| 256 | 102 | |
| 257 | 103 | /** |
| 258 | - * Display admin notices | |
| 259 | - * | |
| 260 | - * @return void | |
| 104 | + * Show error notification after saving snippet. We can also show this message when the snippet is activated. | |
| 105 | + * We must warn the user that we can not perform the spippet due to an error. | |
| 106 | + * | |
| 107 | + * @return string|null | |
| 261 | 108 | */ |
| 262 | - public function display_notices() { | |
| 263 | - if ( ! WINP_Plugin::app()->current_user_car() ) { | |
| 264 | - return; | |
| 265 | - } | |
| 109 | + public function get_throw_php_error_notice() { | |
| 110 | + $save_snippet_result = WINP_Plugin::app()->request->get( 'wbcr_inp_save_snippet_result' ); | |
| 111 | + $post_id = WINP_Plugin::app()->request->get( 'post' ); | |
| 266 | 112 | |
| 267 | - $current_screen = get_current_screen(); | |
| 113 | + if ( ! empty( $save_snippet_result ) && 'code-error' == $save_snippet_result ) { | |
| 114 | + $post_id = ! empty( $post_id ) ? intval( $post_id ) : null; | |
| 268 | 115 | |
| 269 | - // Display all registered notices. | |
| 270 | - foreach ( self::$notices as $notice ) { | |
| 271 | - // Check if notice should be shown on current screen. | |
| 272 | - if ( ! empty( $notice['where'] ) && $current_screen ) { | |
| 273 | - if ( ! in_array( $current_screen->base, $notice['where'] ) ) { | |
| 274 | - continue; | |
| 116 | + if ( $post_id ) { | |
| 117 | + $error = WINP_Plugin::app()->getExecuteObject()->getSnippetError( $post_id ); | |
| 118 | + | |
| 119 | + if ( false !== $error ) { | |
| 120 | + return sprintf( '<p>%s</p><p><strong>%s</strong></p>', sprintf( __( 'The snippet has been deactivated due to an error on line %d:', 'insert-php' ), $error['line'] ), $error['message'] ); | |
| 275 | 121 | } |
| 276 | 122 | } |
| 123 | + } | |
| 277 | 124 | |
| 278 | - // Check if notice is dismissed. | |
| 279 | - if ( $notice['dismissible'] && $this->is_notice_dismissed( $notice['id'] ) ) { | |
| 280 | - continue; | |
| 281 | - } | |
| 282 | - | |
| 283 | - $this->render_notice( $notice ); | |
| 284 | - } | |
| 125 | + return null; | |
| 285 | 126 | } |
| 286 | 127 | |
| 287 | 128 | /** |
| 288 | - * Render a single notice | |
| 129 | + * This warning is for users of the old version 1.3.0. The plugin has changed the way it works | |
| 130 | + * and requires user actions to continue working with plugin. | |
| 289 | 131 | * |
| 290 | - * @param array<string, mixed> $notice Notice data. | |
| 291 | - * | |
| 292 | - * @return void | |
| 132 | + * @return string | |
| 293 | 133 | */ |
| 294 | - private function render_notice( $notice ) { | |
| 295 | - $type = $notice['type']; | |
| 296 | - $dismissible = $notice['dismissible'] ? 'is-dismissible' : ''; | |
| 297 | - $notice_class = "notice notice-{$type} {$dismissible}"; | |
| 298 | - $notice_text = is_string( $notice['text'] ) ? $notice['text'] : ''; | |
| 134 | + public function get_upgrade_notice() { | |
| 135 | + $create_notice_url = admin_url( 'edit.php?post_type=' . WINP_SNIPPETS_POST_TYPE ); | |
| 299 | 136 | |
| 300 | - ?> | |
| 301 | - <div | |
| 302 | - class="<?php echo esc_attr( $notice_class ); ?> winp-admin-notice" | |
| 303 | - <?php if ( $notice['dismissible'] ) : ?> | |
| 304 | - data-notice-id="<?php echo esc_attr( $notice['id'] ); ?>" | |
| 305 | - data-nonce="<?php echo esc_attr( wp_create_nonce( 'winp_dismiss_notice_' . $notice['id'] ) ); ?>" | |
| 306 | - <?php endif; ?> | |
| 307 | - > | |
| 308 | - <?php echo wp_kses( $notice_text, $this->get_allowed_notice_html() ); ?> | |
| 309 | - </div> | |
| 310 | - <?php | |
| 311 | - } | |
| 137 | + $notice = '<b>' . WINP_Plugin::app()->getPluginTitle() . '</b>: ' . sprintf( __( 'Attention! If you have previously used version 1.3.0 of plugin Insert php. This new %s plugin version, we added the ability to insert php code using snippets. This is a more convenient and secure way than using shortcodes [insert_php] code execute [/ insert_php]. However, for compatibility reasons, we left support for [insert_php] shortcodes until March 2019, after that we will stop supporting shortcodes [insert_php].', 'insert-php' ), WINP_Plugin::app()->getPluginVersion() ); | |
| 312 | 138 | |
| 313 | - /** | |
| 314 | - * Allowed HTML markup for notice messages. | |
| 315 | - * | |
| 316 | - * @return array<string, array<string, bool>> | |
| 317 | - */ | |
| 318 | - private function get_allowed_notice_html() { | |
| 319 | - $allowed_html = wp_kses_allowed_html( 'post' ); | |
| 139 | + $notice .= '<br><br>' . __( 'We strongly recommend you to porting your php code to snippets and call them in your posts/pages and widgets using [wbcr_php_snippet id = "000"] shortcodes.', 'insert-php' ); | |
| 140 | + $notice .= ' ' . sprintf( __( 'For more information on porting code and using snippets, see our plugin <a href="%s" target="_blank">documentation</a>', 'insert-php' ), WINP_Plugin::app()->get_support()->get_docs_url( true, 'admin-notice' ) ); | |
| 141 | + $notice .= '<br><br><a href="' . $create_notice_url . '" class="button button-default">' . __( 'Create new php snippet', 'insert-php' ) . '</a> '; | |
| 142 | + $notice .= '<a href="https://downloads.wordpress.org/plugin/insert-php.1.3.zip" class="button button-default">' . __( 'Download old version', 'insert-php' ) . '</a>'; | |
| 143 | + $notice .= '<br><br>' . sprintf( __( 'If you still want to use the old shortcodes [insert_php] and you don’t have time to upgrade to the new version, you can enable support for old shortcodes in the plugin <a href="%s">settings</a>.', 'insert-php' ), WINP_Plugin::app()->getPluginPageUrl( 'settings' ) ); | |
| 144 | + $notice .= '<br>' . sprintf( __( 'If you have issues with the plugin new version or any suggestions, please contact us on <a href="%s" target="_blank">our forum</a>.', 'insert-php' ), 'http://forum.webcraftic.com' ); | |
| 320 | 145 | |
| 321 | - $allowed_html['a']['class'] = true; | |
| 322 | - $allowed_html['a']['target'] = true; | |
| 323 | - $allowed_html['a']['rel'] = true; | |
| 324 | - $allowed_html['div']['class'] = true; | |
| 325 | - $allowed_html['span']['class'] = true; | |
| 326 | - $allowed_html['details'] = [ | |
| 327 | - 'class' => true, | |
| 328 | - 'open' => true, | |
| 329 | - ]; | |
| 330 | - $allowed_html['summary'] = [ 'class' => true ]; | |
| 331 | - $allowed_html['code']['class'] = true; | |
| 332 | - $allowed_html['button'] = [ | |
| 333 | - 'class' => true, | |
| 334 | - 'type' => true, | |
| 335 | - 'disabled' => true, | |
| 336 | - ]; | |
| 337 | - | |
| 338 | - return $allowed_html; | |
| 146 | + return $notice; | |
| 339 | 147 | } |
| 340 | 148 | |
| 341 | 149 | /** |
| 342 | - * Check if notice is dismissed | |
| 150 | + * When the safe mode of the plugin is enabled, this notification will remind | |
| 151 | + * the user to exit safe mode so that the user's snippets are available publicly. | |
| 343 | 152 | * |
| 344 | - * @param string $notice_id Notice ID. | |
| 345 | - * | |
| 346 | - * @return bool | |
| 153 | + * @return string | |
| 347 | 154 | */ |
| 348 | - private function is_notice_dismissed( $notice_id ) { | |
| 349 | - $dismissed_notices = get_option( 'winp_dismissed_notices', [] ); | |
| 350 | - | |
| 351 | - if ( ! is_array( $dismissed_notices ) || ! isset( $dismissed_notices[ $notice_id ] ) ) { | |
| 352 | - return false; | |
| 155 | + public function get_safe_mode_notice() { | |
| 156 | + if ( ! WINP_Helper::is_safe_mode() ) { | |
| 157 | + return null; | |
| 353 | 158 | } |
| 354 | - | |
| 355 | - $expires = (int) $dismissed_notices[ $notice_id ]; | |
| 356 | - | |
| 357 | - // If expires is 0, dismissed forever. | |
| 358 | - // If expires is set and still in future, still dismissed. | |
| 359 | - return 0 === $expires || $expires > time(); | |
| 360 | - } | |
| 361 | 159 | |
| 362 | - /** | |
| 363 | - * Handle AJAX dismiss request | |
| 364 | - * | |
| 365 | - * @return void | |
| 366 | - */ | |
| 367 | - public function ajax_dismiss_notice() { | |
| 368 | - $notice_id = isset( $_POST['notice_id'] ) ? sanitize_key( $_POST['notice_id'] ) : ''; | |
| 369 | - $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( $_POST['nonce'] ) : ''; | |
| 160 | + $disable_safe_mode_url = esc_url( add_query_arg( [ 'wbcr-php-snippets-disable-safe-mode' => 1 ] ) ); | |
| 370 | 161 | |
| 371 | - if ( ! $notice_id || ! wp_verify_nonce( $nonce, 'winp_dismiss_notice_' . $notice_id ) ) { | |
| 372 | - wp_send_json_error(); | |
| 373 | - } | |
| 162 | + $notice = WINP_Plugin::app()->getPluginTitle() . ': ' . __( 'Running in safe mode. This mode your snippets will not be started.', 'insert-php' ); | |
| 163 | + $notice .= ' <a href="' . $disable_safe_mode_url . '" class="button button-default">' . __( 'Disable Safe Mode', 'insert-php' ) . '</a>'; | |
| 374 | 164 | |
| 375 | - if ( ! WINP_Plugin::app()->current_user_car() ) { | |
| 376 | - wp_send_json_error(); | |
| 377 | - } | |
| 378 | - | |
| 379 | - // Find the notice to get its expiration time. | |
| 380 | - $expire_time = 0; // Default: dismiss forever. | |
| 381 | - foreach ( self::$notices as $notice ) { | |
| 382 | - if ( $notice['id'] === $notice_id ) { | |
| 383 | - $expire_time = $notice['dismiss_expires'] > 0 ? time() + $notice['dismiss_expires'] : 0; | |
| 384 | - break; | |
| 385 | - } | |
| 386 | - } | |
| 387 | - | |
| 388 | - // Get existing dismissed notices. | |
| 389 | - $dismissed_notices = get_option( 'winp_dismissed_notices', [] ); | |
| 390 | - if ( ! is_array( $dismissed_notices ) ) { | |
| 391 | - $dismissed_notices = []; | |
| 392 | - } | |
| 393 | - | |
| 394 | - // Clean up expired dismissals. | |
| 395 | - foreach ( $dismissed_notices as $id => $expires ) { | |
| 396 | - if ( 0 !== $expires && $expires < time() ) { | |
| 397 | - unset( $dismissed_notices[ $id ] ); | |
| 398 | - } | |
| 399 | - } | |
| 400 | - | |
| 401 | - // Limit size to prevent excessive growth (keep last 10 dismissals). | |
| 402 | - if ( count( $dismissed_notices ) > 10 ) { | |
| 403 | - // Sort by expiration time (oldest first). | |
| 404 | - asort( $dismissed_notices ); | |
| 405 | - // Remove oldest entries beyond limit. | |
| 406 | - $dismissed_notices = array_slice( $dismissed_notices, -10, null, true ); | |
| 407 | - } | |
| 408 | - | |
| 409 | - // Add this dismissal. | |
| 410 | - $dismissed_notices[ $notice_id ] = $expire_time; | |
| 411 | - | |
| 412 | - // Update option. | |
| 413 | - update_option( 'winp_dismissed_notices', $dismissed_notices, false ); | |
| 414 | - | |
| 415 | - wp_send_json_success(); | |
| 165 | + return $notice; | |
| 416 | 166 | } |
| 417 | 167 | |
| 418 | 168 | /** |
| 419 | - * Add notice to be displayed | |
| 169 | + * @author Alexander Kovalev <alex.kovalevv@gmail.com> | |
| 420 | 170 | * |
| 421 | - * @param string $id ID of the notice. | |
| 422 | - * @param string|null $message Message of the notice. | |
| 423 | - * @param string $type Type of the notice. Possible values: 'error', 'warning', 'success', 'info'. | |
| 424 | - * @param bool $dismissible Whether the notice can be dismissed. | |
| 425 | - * @param int $dismiss_expires Time in seconds, after which the notice will be shown again. 0 - forever. | |
| 426 | - * @param array<string> $where Where to show the notice. Screen base values: 'post', 'post-new', 'edit', etc. | |
| 427 | - * | |
| 428 | - * @return void | |
| 171 | + * @param string $id | |
| 172 | + * @param string $message | |
| 173 | + * @param string $type | |
| 174 | + * @param bool $dismissible | |
| 175 | + * @param int $dismiss_expires | |
| 176 | + * @param array $where | |
| 429 | 177 | */ |
| 430 | - public static function add_notice( $id, $message, $type = 'warning', $dismissible = true, $dismiss_expires = 0, $where = [] ) { | |
| 431 | - if ( is_null( $message ) || empty( $message ) ) { | |
| 178 | + protected function add_notice( $id, $message, $type = 'warning', $dismissible = true, $dismiss_expires = 0, $where = [] ) { | |
| 179 | + if ( is_null( $message ) ) { | |
| 432 | 180 | return; |
| 433 | 181 | } |
| 434 | 182 | |
| 435 | - // Prevent duplicate notices. | |
| 436 | - foreach ( self::$notices as $notice ) { | |
| 437 | - if ( $notice['id'] === self::$prefix . $id ) { | |
| 438 | - return; | |
| 183 | + if ( ! empty( $this->notices ) ) { | |
| 184 | + foreach ( $this->notices as $notice ) { | |
| 185 | + if ( $notice['id'] == $this->prefix . $id ) { | |
| 186 | + return; | |
| 187 | + } | |
| 439 | 188 | } |
| 440 | 189 | } |
| 441 | 190 | |
| 442 | - self::$notices[] = [ | |
| 443 | - 'id' => self::$prefix . $id, | |
| 191 | + $this->notices[] = [ | |
| 192 | + 'id' => $this->prefix . $id, | |
| 444 | 193 | 'type' => $type, |
| 445 | 194 | 'dismissible' => (bool) $dismissible, |
| 446 | 195 | 'dismiss_expires' => (int) $dismiss_expires, |
| 447 | 196 | 'where' => $where, |
| 448 | - 'text' => $message, | |
| 197 | + 'text' => '<p>' . $message . '</p>', | |
| 449 | 198 | ]; |
| 450 | 199 | } |
| 451 | 200 | } |