woocommerce-multilingual
/
addons
/
wpml-dependencies
/
lib
/
classes
/
notices
/
class-wpml-notice-render.php
pages
4 years ago
DismissNotices.php
4 weeks ago
class-wpml-notice-action.php
4 weeks ago
class-wpml-notice-render.php
4 weeks ago
class-wpml-notice.php
4 weeks ago
class-wpml-notices.php
4 weeks ago
class-wpml-notice-render.php
334 lines
| 1 | <?php |
| 2 | |
| 3 | class WPML_Notice_Render { |
| 4 | private $dismiss_html_added; |
| 5 | private $hide_html_added; |
| 6 | private $collapse_html_added; |
| 7 | |
| 8 | public function render( WPML_Notice $notice ) { |
| 9 | echo $this->get_html( $notice ); |
| 10 | } |
| 11 | |
| 12 | public function get_html( WPML_Notice $notice ) { |
| 13 | $result = ''; |
| 14 | |
| 15 | if ( $this->must_display_notice( $notice ) ) { |
| 16 | if ( $notice->should_be_text_only() ) { |
| 17 | return $notice->get_text(); |
| 18 | } |
| 19 | |
| 20 | $actions_html = $this->get_actions_html( $notice ); |
| 21 | |
| 22 | $temp_types = $notice->get_css_class_types(); |
| 23 | foreach ( $temp_types as $temp_type ) { |
| 24 | if ( strpos( $temp_type, 'notice-' ) === false ) { |
| 25 | $temp_types[] = 'notice-' . $temp_type; |
| 26 | } |
| 27 | if ( strpos( $temp_type, 'notice-' ) === 0 ) { |
| 28 | $temp_types[] = substr( $temp_type, 0, strlen( 'notice-' ) ); |
| 29 | } |
| 30 | } |
| 31 | $temp_classes = $notice->get_css_classes(); |
| 32 | |
| 33 | $classes = array_merge( $temp_classes, $temp_types ); |
| 34 | |
| 35 | if ( $this->hide_html_added || $this->dismiss_html_added || $notice->can_be_hidden() || $notice->can_be_dismissed() ) { |
| 36 | $classes[] = 'is-dismissible'; |
| 37 | } |
| 38 | $classes[] = 'notice'; |
| 39 | $classes[] = 'otgs-notice'; |
| 40 | |
| 41 | $classes = array_unique( $classes ); |
| 42 | |
| 43 | $class = implode( ' ', $classes ); |
| 44 | |
| 45 | $result .= '<div class="' . $class . '" data-id="' . esc_attr( $notice->get_id() ) . '" data-group="' . esc_attr( $notice->get_group() ) . '"'; |
| 46 | $result .= $this->get_data_nonce_attribute(); |
| 47 | |
| 48 | if ( $this->hide_html_added || $notice->can_be_hidden() ) { |
| 49 | $result .= ' data-hide-text="' . __( 'Hide', 'sitepress' ) . '" '; |
| 50 | } |
| 51 | $result .= '>'; |
| 52 | |
| 53 | if ( $notice->can_be_collapsed() ) { |
| 54 | $result .= $this->sanitize_and_format_text( $this->get_collapsed_html( $notice ) ); |
| 55 | } else { |
| 56 | $result .= '<p>' . $this->sanitize_and_format_text( $notice->get_text() ) . '</p>'; |
| 57 | } |
| 58 | |
| 59 | $this->dismiss_html_added = false; |
| 60 | $this->hide_html_added = false; |
| 61 | $this->collapse_html_added = false; |
| 62 | |
| 63 | $result .= $actions_html; |
| 64 | |
| 65 | if ( $notice->can_be_hidden() ) { |
| 66 | $result .= $this->get_hide_html(); |
| 67 | } |
| 68 | |
| 69 | if ( $notice->can_be_dismissed() ) { |
| 70 | $result .= $this->get_dismiss_html(); |
| 71 | } |
| 72 | |
| 73 | if ( $notice->can_be_collapsed() ) { |
| 74 | $result .= $this->get_collapse_html(); |
| 75 | } |
| 76 | |
| 77 | if ( $notice->get_nonce_action() ) { |
| 78 | $result .= $this->add_nonce( $notice ); |
| 79 | } |
| 80 | |
| 81 | $result .= '</div>'; |
| 82 | } |
| 83 | |
| 84 | return $result; |
| 85 | } |
| 86 | |
| 87 | private function add_nonce( $notice ) { |
| 88 | return wp_nonce_field( $notice->get_nonce_action(), $notice->get_nonce_action(), true, false ); |
| 89 | } |
| 90 | |
| 91 | public function must_display_notice( WPML_Notice $notice ) { |
| 92 | if ( ! $notice->is_for_current_user() || ! $notice->is_user_cap_allowed() ) { |
| 93 | return false; |
| 94 | } |
| 95 | |
| 96 | return $this->is_current_page_allowed( $notice ) && $this->is_allowed_by_callback( $notice ); |
| 97 | } |
| 98 | |
| 99 | private function get_actions_html( WPML_Notice $notice ) { |
| 100 | $actions_html = ''; |
| 101 | if ( $notice->get_actions() ) { |
| 102 | $actions_html .= '<div class="otgs-notice-actions">'; |
| 103 | foreach ( $notice->get_actions() as $action ) { |
| 104 | $actions_html .= $this->get_action_html( $action ); |
| 105 | } |
| 106 | |
| 107 | $actions_html .= '</div>'; |
| 108 | |
| 109 | return $actions_html; |
| 110 | } |
| 111 | |
| 112 | return $actions_html; |
| 113 | } |
| 114 | |
| 115 | private function sanitize_and_format_text( $text ) { |
| 116 | $backticks_pattern = '|`(.*)`|U'; |
| 117 | preg_match_all( $backticks_pattern, $text, $matches ); |
| 118 | |
| 119 | $sanitized_notice = $text; |
| 120 | if ( 2 === count( $matches ) ) { |
| 121 | $matches_to_sanitize = $matches[1]; |
| 122 | |
| 123 | foreach ( $matches_to_sanitize as &$match_to_sanitize ) { |
| 124 | $match_to_sanitize = '<pre>' . esc_html( $match_to_sanitize ) . '</pre>'; |
| 125 | } |
| 126 | unset( $match_to_sanitize ); |
| 127 | |
| 128 | $sanitized_notice = str_replace( $matches[0], $matches_to_sanitize, $sanitized_notice ); |
| 129 | } |
| 130 | |
| 131 | return stripslashes( $sanitized_notice ); |
| 132 | } |
| 133 | |
| 134 | private function get_hide_html( $localized_text = null ) { |
| 135 | $hide_html = ''; |
| 136 | $hide_html .= '<span class="otgs-notice-hide notice-hide"><span class="screen-reader-text">'; |
| 137 | if ( $localized_text ) { |
| 138 | $hide_html .= esc_html( $localized_text ); |
| 139 | } else { |
| 140 | $hide_html .= esc_html__( 'Hide this notice.', 'sitepress' ); |
| 141 | } |
| 142 | $hide_html .= '</span></span>'; |
| 143 | |
| 144 | return $hide_html; |
| 145 | } |
| 146 | |
| 147 | private function get_dismiss_html( $localized_text = null ) { |
| 148 | $dismiss_html = ''; |
| 149 | $dismiss_html .= '<span class="otgs-notice-dismiss notice-dismiss">'; |
| 150 | $dismiss_html .= '<span class="screen-reader-text"><input class="otgs-notice-dismiss-check" type="checkbox" value="1" />'; |
| 151 | if ( $localized_text ) { |
| 152 | $dismiss_html .= esc_html( $localized_text ); |
| 153 | } else { |
| 154 | $dismiss_html .= esc_html__( 'Dismiss this notice.', 'sitepress' ); |
| 155 | } |
| 156 | $dismiss_html .= '</span></span>'; |
| 157 | |
| 158 | return $dismiss_html; |
| 159 | } |
| 160 | |
| 161 | private function get_collapse_html( $localized_text = null ) { |
| 162 | $hide_html = '<span class="otgs-notice-collapse-hide"><span class="screen-reader-text">'; |
| 163 | if ( $localized_text ) { |
| 164 | $hide_html .= esc_html( $localized_text ); |
| 165 | } else { |
| 166 | $hide_html .= esc_html__( 'Hide this notice.', 'sitepress' ); |
| 167 | } |
| 168 | $hide_html .= '</span></span>'; |
| 169 | |
| 170 | return $hide_html; |
| 171 | } |
| 172 | |
| 173 | private function get_collapsed_html( WPML_Notice $notice, $localized_text = null ) { |
| 174 | $content = ' |
| 175 | <div class="otgs-notice-collapsed-text"> |
| 176 | <p>%s |
| 177 | <span class="otgs-notice-collapse-show notice-collapse"><span class="screen-reader-text"> |
| 178 | %s |
| 179 | </span></span> |
| 180 | </p> |
| 181 | </div> |
| 182 | <div class="otgs-notice-collapse-text"> |
| 183 | %s |
| 184 | </div> |
| 185 | '; |
| 186 | |
| 187 | $content = sprintf( |
| 188 | $content, |
| 189 | $notice->get_collapsed_text(), |
| 190 | $localized_text ? esc_html( $localized_text ) : esc_html__( 'Show this notice.', 'sitepress' ), |
| 191 | $notice->get_text() |
| 192 | ); |
| 193 | |
| 194 | return $content; |
| 195 | } |
| 196 | |
| 197 | private function get_action_html( $action ) { |
| 198 | $action_html = ''; |
| 199 | if ( $action->can_hide() ) { |
| 200 | $action_html .= $this->get_hide_html( $action->get_text() ); |
| 201 | $this->hide_html_added = true; |
| 202 | } elseif ( $action->can_dismiss() ) { |
| 203 | $action_html .= $this->get_dismiss_html( $action->get_text() ); |
| 204 | $this->dismiss_html_added = true; |
| 205 | } else { |
| 206 | if ( $action->get_url() ) { |
| 207 | $action_html .= $this->get_action_anchor( $action ); |
| 208 | } else { |
| 209 | $action_html .= $action->get_text(); |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | return $action_html; |
| 214 | } |
| 215 | |
| 216 | private function get_action_anchor( WPML_Notice_Action $action ) { |
| 217 | $anchor_attributes = array(); |
| 218 | |
| 219 | $action_url = '<a'; |
| 220 | |
| 221 | $anchor_attributes['href'] = esc_url_raw( $action->get_url() ); |
| 222 | if ( $action->get_link_target() ) { |
| 223 | $anchor_attributes['target'] = $action->get_link_target(); |
| 224 | } |
| 225 | |
| 226 | $action_url_classes = array( 'notice-action' ); |
| 227 | if ( $action->must_display_as_button() ) { |
| 228 | $button_style = 'button-secondary'; |
| 229 | if ( is_string( $action->must_display_as_button() ) ) { |
| 230 | $button_style = $action->must_display_as_button(); |
| 231 | } |
| 232 | $action_url_classes[] = esc_attr( $button_style ); |
| 233 | $action_url_classes[] = 'notice-action-' . esc_attr( $button_style ); |
| 234 | } else { |
| 235 | $action_url_classes[] = 'notice-action-link'; |
| 236 | } |
| 237 | $anchor_attributes['class'] = implode( ' ', $action_url_classes ); |
| 238 | |
| 239 | if ( $action->get_group_to_dismiss() ) { |
| 240 | $anchor_attributes['data-dismiss-group'] = esc_attr( $action->get_group_to_dismiss() ); |
| 241 | } |
| 242 | if ( $action->get_js_callback() ) { |
| 243 | $anchor_attributes['data-js-callback'] = esc_attr( $action->get_js_callback() ) |
| 244 | . '"'; |
| 245 | } |
| 246 | |
| 247 | foreach ( $anchor_attributes as $name => $value ) { |
| 248 | $action_url .= ' ' . $name . '="' . $value . '"'; |
| 249 | } |
| 250 | |
| 251 | $action_url .= $this->get_data_nonce_attribute(); |
| 252 | $action_url .= '>'; |
| 253 | $action_url .= $action->get_text(); |
| 254 | $action_url .= '</a>'; |
| 255 | |
| 256 | return $action_url; |
| 257 | } |
| 258 | |
| 259 | private function get_data_nonce_attribute() { |
| 260 | return ' data-nonce="' . wp_create_nonce( WPML_Notices::NONCE_NAME ) . '"'; |
| 261 | } |
| 262 | |
| 263 | private function is_current_screen_allowed( WPML_Notice $notice ) { |
| 264 | $allow_current_screen = true; |
| 265 | $restrict_to_screen_ids = $notice->get_restrict_to_screen_ids(); |
| 266 | if ( $restrict_to_screen_ids && function_exists( 'get_current_screen' ) ) { |
| 267 | $screen = get_current_screen(); |
| 268 | $allow_current_screen = $screen && in_array( $screen->id, $restrict_to_screen_ids, true ); |
| 269 | } |
| 270 | |
| 271 | return $allow_current_screen; |
| 272 | } |
| 273 | |
| 274 | private function is_current_page_prefix_allowed( WPML_Notice $notice, $current_page ) { |
| 275 | $restrict_to_page_prefixes = $notice->get_restrict_to_page_prefixes(); |
| 276 | if ( $current_page && $restrict_to_page_prefixes ) { |
| 277 | $allow_current_page_prefix = false; |
| 278 | foreach ( $restrict_to_page_prefixes as $restrict_to_prefix ) { |
| 279 | if ( stripos( $current_page, $restrict_to_prefix ) === 0 ) { |
| 280 | $allow_current_page_prefix = true; |
| 281 | break; |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | return $allow_current_page_prefix; |
| 286 | } |
| 287 | |
| 288 | return true; |
| 289 | } |
| 290 | |
| 291 | private function is_current_page_allowed( WPML_Notice $notice ) { |
| 292 | $current_page = array_key_exists( 'page', $_GET ) ? $_GET['page'] : null; |
| 293 | |
| 294 | if ( ! $this->is_current_screen_allowed( $notice ) ) { |
| 295 | return false; |
| 296 | } |
| 297 | |
| 298 | if ( $current_page ) { |
| 299 | |
| 300 | $exclude_from_pages = $notice->get_exclude_from_pages(); |
| 301 | if ( $exclude_from_pages && in_array( $current_page, $exclude_from_pages, true ) ) { |
| 302 | return false; |
| 303 | } |
| 304 | |
| 305 | if ( ! $this->is_current_page_prefix_allowed( $notice, $current_page ) ) { |
| 306 | return false; |
| 307 | } |
| 308 | |
| 309 | $restrict_to_pages = $notice->get_restrict_to_pages(); |
| 310 | if ( $restrict_to_pages && ! in_array( $current_page, $restrict_to_pages, true ) ) { |
| 311 | return false; |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | return true; |
| 316 | } |
| 317 | |
| 318 | private function is_allowed_by_callback( WPML_Notice $notice ) { |
| 319 | $allow_by_callback = true; |
| 320 | $display_callbacks = $notice->get_display_callbacks(); |
| 321 | if ( $display_callbacks ) { |
| 322 | $allow_by_callback = false; |
| 323 | foreach ( $display_callbacks as $callback ) { |
| 324 | if ( is_callable( $callback ) && call_user_func( $callback ) ) { |
| 325 | $allow_by_callback = true; |
| 326 | break; |
| 327 | } |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | return $allow_by_callback; |
| 332 | } |
| 333 | } |
| 334 |