addons
11 years ago
external
11 years ago
rules
11 years ago
class-popup-admin.php
11 years ago
class-popup-base.php
11 years ago
class-popup-database.php
11 years ago
class-popup-help.php
11 years ago
class-popup-item.php
11 years ago
class-popup-posttype.php
11 years ago
class-popup-public.php
11 years ago
class-popup-rule.php
11 years ago
config-defaults.php
11 years ago
class-popup-public.php
408 lines
| 1 | <?php |
| 2 | // Load dependencies. |
| 3 | require_once PO_INC_DIR . 'class-popup-base.php'; |
| 4 | |
| 5 | /** |
| 6 | * Defines the popup class for front end pages |
| 7 | * |
| 8 | * @since 4.6 |
| 9 | */ |
| 10 | class IncPopup extends IncPopupBase { |
| 11 | |
| 12 | /** |
| 13 | * Data added to the page via wp_localize_script() |
| 14 | * @var array |
| 15 | */ |
| 16 | protected $script_data = array(); |
| 17 | |
| 18 | /** |
| 19 | * Lists all popups that have been enqueued via the footer loading method. |
| 20 | * @var array |
| 21 | */ |
| 22 | protected $enqueued = array(); |
| 23 | |
| 24 | /** |
| 25 | * Returns the singleton instance of the popup (front end) class. |
| 26 | * |
| 27 | * @since 4.6 |
| 28 | */ |
| 29 | static public function instance() { |
| 30 | static $Inst = null; |
| 31 | |
| 32 | // In theory the "public" class does not need this, but to avoid |
| 33 | // unexpected problems we initialize only after current user is known... |
| 34 | if ( ! did_action( 'set_current_user' ) ) { |
| 35 | add_action( 'set_current_user', array( __CLASS__, 'instance' ) ); |
| 36 | return null; |
| 37 | } |
| 38 | |
| 39 | if ( null === $Inst ) { |
| 40 | $Inst = new IncPopup(); |
| 41 | } |
| 42 | |
| 43 | return $Inst; |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * Private constructor (singleton) |
| 48 | * |
| 49 | * @since 4.6 |
| 50 | */ |
| 51 | protected function __construct() { |
| 52 | parent::__construct(); |
| 53 | |
| 54 | // Init loading-process of the PopUp. |
| 55 | add_action( |
| 56 | 'wp', // "wp", not "init"! |
| 57 | array( $this, 'init_public' ) |
| 58 | ); |
| 59 | |
| 60 | /** |
| 61 | * Experimental hook to dynamically create popups on your site. |
| 62 | * Call the action hook `wdev-popup` with param 1 being the content and |
| 63 | * param 2 is an optional array of popup options. |
| 64 | * |
| 65 | * Note that currently this plays nice with existing popups if FOOTER |
| 66 | * loading method is used, but all other loading methods will interfere |
| 67 | * with this hook and only show either the dynamic or predefined popups. |
| 68 | * |
| 69 | * @since 4.7.1 |
| 70 | * @param string $content The popup contents (HTML code allowed). |
| 71 | * @param array $options Optional. List of popup configuration options. |
| 72 | */ |
| 73 | add_action( |
| 74 | 'wdev-popup', |
| 75 | array( $this, 'show_popup' ), |
| 76 | 10, 2 |
| 77 | ); |
| 78 | } |
| 79 | |
| 80 | /** |
| 81 | * Initialize the public part of the plugin on every front-end page: |
| 82 | * Determine how the popup is loaded. |
| 83 | * |
| 84 | * @since 4.6 |
| 85 | */ |
| 86 | public function init_public() { |
| 87 | // Load plugin settings. |
| 88 | $settings = IncPopupDatabase::get_settings(); |
| 89 | |
| 90 | // Initialize javascript-data. |
| 91 | $this->script_data['ajaxurl'] = ''; |
| 92 | $this->script_data['do'] = 'get_data'; |
| 93 | $this->script_data['ajax_data'] = array(); |
| 94 | |
| 95 | // Find the current loading method. |
| 96 | $cur_method = isset( $settings['loadingmethod'] ) ? $settings['loadingmethod'] : 'ajax'; |
| 97 | if ( empty( $cur_method ) ) { $cur_method = 'ajax'; } |
| 98 | |
| 99 | if ( isset( $_POST['_po_method_'] ) ) { $cur_method = $_POST['_po_method_']; } |
| 100 | |
| 101 | /* |
| 102 | * Apply the specific loading method to include the popup on the page. |
| 103 | * Details to the loading methods are documented in the header comment |
| 104 | * of the "load_method_xyz()" functions. |
| 105 | */ |
| 106 | switch ( $cur_method ) { |
| 107 | case 'ajax': // former 'external' |
| 108 | $this->load_method_ajax(); |
| 109 | break; |
| 110 | |
| 111 | case 'front': // former 'frontloading' |
| 112 | $this->load_method_front(); |
| 113 | |
| 114 | if ( isset( $_GET['action'] ) |
| 115 | && 'inc_popup' == $_GET['action'] |
| 116 | ) { |
| 117 | $this->ajax_load_popup(); |
| 118 | } |
| 119 | break; |
| 120 | |
| 121 | case 'footer': |
| 122 | $this->load_method_footer(); |
| 123 | break; |
| 124 | |
| 125 | case 'raw': // Set via form field "_po_method_" |
| 126 | $this->load_method_raw(); |
| 127 | break; |
| 128 | |
| 129 | default: |
| 130 | /** |
| 131 | * Custom loading handler can be processed by an add-on. |
| 132 | */ |
| 133 | do_action( 'popup-init-loading-method', $cur_method, $this ); |
| 134 | break; |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | /** |
| 139 | * Action handler that allows us to add a popup via WordPress hook. |
| 140 | * |
| 141 | * @since 4.7.1 |
| 142 | * @param string $contents The PopUp contents. |
| 143 | * @param array $options PopUp options. |
| 144 | */ |
| 145 | public function show_popup( $contents, $options = array() ) { |
| 146 | $this->script_data['popup'] = lib2()->array->get( $this->script_data['popup'] ); |
| 147 | |
| 148 | $popup = new IncPopupItem(); |
| 149 | $data = lib2()->array->get( $options ); |
| 150 | $data['content'] = $contents; |
| 151 | $popup->populate( $data ); |
| 152 | $popup->script_data['manual'] = true; |
| 153 | |
| 154 | // 1. Add the popup to the global popup-list. |
| 155 | $this->popups[] = $popup; |
| 156 | |
| 157 | // 2. Enqueue the popup in the page footer. |
| 158 | $item = $popup->get_script_data( false ); |
| 159 | unset( $item['html'] ); |
| 160 | unset( $item['styles'] ); |
| 161 | $this->script_data['popup'][] = $item; |
| 162 | |
| 163 | $this->load_scripts(); |
| 164 | $this->enqueue_footer(); |
| 165 | } |
| 166 | |
| 167 | /** |
| 168 | * Enqueues the PopUp javascripts and data. |
| 169 | * |
| 170 | * @since 4.6 |
| 171 | */ |
| 172 | public function load_scripts() { |
| 173 | static $Loaded = false; |
| 174 | |
| 175 | if ( ! did_action( 'wp' ) ) { |
| 176 | // We have to make sure that wp is fully initialized: |
| 177 | // Some rules that use filter 'popup-ajax-data' depend on this. |
| 178 | add_action( |
| 179 | 'wp', |
| 180 | array( $this, 'load_scripts' ) |
| 181 | ); |
| 182 | return; |
| 183 | } |
| 184 | |
| 185 | if ( ! $Loaded ) { |
| 186 | if ( is_array( $this->script_data ) && ! empty( $this->script_data ) ) { |
| 187 | $popup_data = apply_filters( 'popup-ajax-data', $this->script_data ); |
| 188 | lib2()->ui->data( '_popup_data', $popup_data, 'front' ); |
| 189 | |
| 190 | $popup_data['popup'] = lib2()->array->get( $popup_data['popup'] ); |
| 191 | foreach ( $popup_data['popup'] as $item ) { |
| 192 | $this->enqueued[] = $item['html_id']; |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | lib2()->ui->add( PO_JS_URL . 'public.min.js', 'front' ); |
| 197 | lib2()->ui->add( PO_CSS_URL . 'animate.min.css', 'front' ); |
| 198 | } else { |
| 199 | if ( is_array( $this->script_data ) && is_array( $this->script_data['popup'] ) ) { |
| 200 | foreach ( $this->script_data['popup'] as $popup ) { |
| 201 | if ( in_array( $popup['html_id'], $this->enqueued ) ) { |
| 202 | continue; |
| 203 | } |
| 204 | |
| 205 | $script = 'window._popup_data.popup.push(' . json_encode( $popup ) . ')'; |
| 206 | lib2()->ui->script( $script ); |
| 207 | $this->enqueued[] = $popup['html_id']; |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | $Loaded = true; |
| 212 | } |
| 213 | |
| 214 | |
| 215 | /*==================================*\ |
| 216 | ====================================== |
| 217 | == == |
| 218 | == LOAD METHODS == |
| 219 | == == |
| 220 | ====================================== |
| 221 | \*==================================*/ |
| 222 | |
| 223 | |
| 224 | /** |
| 225 | * Load-Method: External |
| 226 | * |
| 227 | * IS AJAX |
| 228 | * IS ADMIN |
| 229 | * |
| 230 | * PopUp data is loaded via a normal WordPress ajax request, directed at |
| 231 | * the admin-ajax.php handler. |
| 232 | * |
| 233 | * @since 4.6 |
| 234 | */ |
| 235 | protected function load_method_ajax() { |
| 236 | global $pagenow; |
| 237 | |
| 238 | if ( ! in_array( $pagenow, array( 'wp-login.php', 'wp-register.php' ) ) ) { |
| 239 | // Data is loaded via a normal WordPress ajax request. |
| 240 | $this->script_data['ajaxurl'] = admin_url( 'admin-ajax.php' ); |
| 241 | $this->script_data['ajax_data']['orig_request_uri'] = $_SERVER['REQUEST_URI']; |
| 242 | $this->load_scripts(); |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | /** |
| 247 | * Load-Method: Front/Frontloading |
| 248 | * |
| 249 | * NOT AJAX |
| 250 | * NOT ADMIN |
| 251 | * |
| 252 | * PopUp data is loaded in an ajax request. The ajax request is directed |
| 253 | * at the same URL that is currently displayed, but a few URL-parameters are |
| 254 | * added to instruct the plugin to return popup-data instead the the normal |
| 255 | * webpage. |
| 256 | * |
| 257 | * @since 4.6 |
| 258 | */ |
| 259 | protected function load_method_front() { |
| 260 | global $pagenow; |
| 261 | |
| 262 | if ( ! in_array( $pagenow, array( 'wp-login.php', 'wp-register.php' ) ) ) { |
| 263 | /* |
| 264 | * Data is loaded via the public URL of the page, simply by adding |
| 265 | * some URL parameters. |
| 266 | */ |
| 267 | $this->script_data['ajaxurl'] = ''; |
| 268 | $this->script_data['ajax_data']['request_uri'] = $_SERVER['REQUEST_URI']; |
| 269 | $this->load_scripts(); |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | /** |
| 274 | * Load-Method: Footer |
| 275 | * |
| 276 | * NOT AJAX |
| 277 | * NOT ADMIN |
| 278 | * |
| 279 | * The PopUp styles and html is directly injected into the webpage header |
| 280 | * and footer. The PopUp is ready when the page is loaded. No ajax request |
| 281 | * is made. |
| 282 | * |
| 283 | * @since 4.6 |
| 284 | */ |
| 285 | protected function load_method_footer() { |
| 286 | /** |
| 287 | * Set up the rquest information from here. |
| 288 | * These values are used by some rules and need to be set manually here |
| 289 | * In an ajax request they would already be defined by the ajax url. |
| 290 | */ |
| 291 | $_REQUEST['thereferrer'] = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : ''; |
| 292 | $_REQUEST['thefrom'] = lib2()->net->current_url(); |
| 293 | |
| 294 | // Populates $this->popups |
| 295 | $this->select_popup(); |
| 296 | |
| 297 | if ( empty( $this->popups ) ) { return; } |
| 298 | |
| 299 | $data = $this->get_popup_data(); |
| 300 | foreach ( $data as $item ) { |
| 301 | if ( ! empty( $item['manual'] ) ) { continue; } |
| 302 | if ( in_array( $item['html_id'], $this->enqueued ) ) { continue; } |
| 303 | |
| 304 | unset( $item['html'] ); |
| 305 | unset( $item['styles'] ); |
| 306 | $this->script_data['popup'][] = $item; |
| 307 | } |
| 308 | $this->load_scripts(); |
| 309 | |
| 310 | $this->enqueue_footer(); |
| 311 | } |
| 312 | |
| 313 | /** |
| 314 | * Load-Method: Raw |
| 315 | * |
| 316 | * This is used when a form is submitted inside a PopUp - it means that we |
| 317 | * should only return the contents of the PopUp(s) and not the whole page. |
| 318 | * Set via form field "_po_method_". |
| 319 | * |
| 320 | * @since 4.6.1.2 |
| 321 | */ |
| 322 | protected function load_method_raw() { |
| 323 | /** |
| 324 | * Set up the rquest information from here. |
| 325 | * These values are used by some rules and need to be set manually here |
| 326 | * In an ajax request they would already be defined by the ajax url. |
| 327 | */ |
| 328 | $_REQUEST['thereferrer'] = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : ''; |
| 329 | $_REQUEST['thefrom'] = lib2()->net->current_url(); |
| 330 | |
| 331 | // Populates $this->popups |
| 332 | $this->select_popup(); |
| 333 | |
| 334 | if ( empty( $this->popups ) ) { die(); } |
| 335 | |
| 336 | echo '<div>'; |
| 337 | $this->show_footer(); |
| 338 | echo '</div>'; |
| 339 | |
| 340 | die(); |
| 341 | } |
| 342 | |
| 343 | |
| 344 | /*======================================*\ |
| 345 | ========================================== |
| 346 | == == |
| 347 | == HELPER FUNCTIONS == |
| 348 | == == |
| 349 | ========================================== |
| 350 | \*======================================*/ |
| 351 | |
| 352 | |
| 353 | /** |
| 354 | * Adds the wp_header/wp_footer actions to the action queue. |
| 355 | * |
| 356 | * @since 4.7.1 |
| 357 | */ |
| 358 | protected function enqueue_footer() { |
| 359 | static $Did_Enqueue = false; |
| 360 | |
| 361 | if ( $Did_Enqueue ) { return; } |
| 362 | $Did_Enqueue = true; |
| 363 | |
| 364 | add_action( |
| 365 | 'wp_head', |
| 366 | array( $this, 'show_header') |
| 367 | ); |
| 368 | |
| 369 | add_action( |
| 370 | 'wp_footer', |
| 371 | array( $this, 'show_footer') |
| 372 | ); |
| 373 | } |
| 374 | |
| 375 | /** |
| 376 | * Used by "load_method_footer" to print the popup CSS styles. |
| 377 | * |
| 378 | * @since 4.6 |
| 379 | */ |
| 380 | public function show_header() { |
| 381 | if ( empty( $this->popups ) ) { return; } |
| 382 | |
| 383 | $code = ''; |
| 384 | $data = $this->get_popup_data(); |
| 385 | foreach ( $data as $ind => $item ) { |
| 386 | $code .= $item['styles']; |
| 387 | } |
| 388 | echo '<style type="text/css">' . $code . '</style>'; |
| 389 | } |
| 390 | |
| 391 | /** |
| 392 | * Used by "load_method_footer" to print the popup HTML code. |
| 393 | * |
| 394 | * @since 4.6 |
| 395 | */ |
| 396 | public function show_footer() { |
| 397 | if ( empty( $this->popups ) ) { return; } |
| 398 | |
| 399 | $code = ''; |
| 400 | $data = $this->get_popup_data(); |
| 401 | foreach ( $data as $ind => $item ) { |
| 402 | $code .= $item['html']; |
| 403 | } |
| 404 | echo $code; |
| 405 | } |
| 406 | |
| 407 | }; |
| 408 |