PluginProbe ʕ •ᴥ•ʔ
Hustle – Email Marketing, Lead Generation, Optins, Popups / 5.1.1
Hustle – Email Marketing, Lead Generation, Optins, Popups v5.1.1
7.8.13 7.8.13.1 trunk 3.0 3.1 3.1.1 3.1.2 3.1.3 3.1.4 4.3.2 4.4.4 4.4.5 4.4.5.1 4.4.5.4 4.6 4.6.1.1 4.6.1.4 4.7.0.2 4.7.0.3 4.7.0.7 4.7.0.9 4.7.1.0 4.7.1.1 4.8.0.0 5.0.0 5.0.1 5.0.1.1 5.0.1.2 5.1 5.1.1 5.1.2 5.1.3 5.1.3.1 5.1.3.2 5.1.4 5.1.5 6.0 6.0.1 6.0.2 6.0.3 6.0.4.2 6.0.5 6.0.6.1 6.0.7 6.0.8.1 6.0.9 7.0.0.1 7.0.2 7.0.3 7.0.4 7.1.0 7.1.1 7.2.0 7.2.1 7.3.0 7.3.1 7.3.3 7.3.5 7.3.6 7.3.7 7.4.0 7.4.1 7.4.11 7.4.13 7.4.13.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.5.1 7.4.5.2 7.4.6 7.4.7 7.5.0 7.6.0 7.6.1 7.6.3 7.6.4 7.6.6 7.7.0 7.7.1 7.8.0 7.8.1 7.8.10 7.8.10.1 7.8.10.2 7.8.11 7.8.12 7.8.12.1 7.8.2 7.8.3 7.8.4 7.8.5 7.8.6 7.8.7 7.8.8 7.8.9 7.8.9.1 7.8.9.2 7.8.9.3
wordpress-popup / lib / free-dashboard / module.php
wordpress-popup / lib / free-dashboard Last commit date
admin.css 9 years ago admin.js 9 years ago module.php 9 years ago
module.php
537 lines
1 <?php
2 /**
3 * WPMUDEV Frash - Free Dashboard Notification module.
4 * Used by wordpress.org hosted plugins.
5 *
6 * @version 1.1.0
7 * @author Incsub (Philipp Stracker)
8 */
9
10 if ( ! class_exists( 'WDev_Frash' ) ) {
11 class WDev_Frash {
12
13 /**
14 * List of all registered plugins.
15 *
16 * @since 1.0.0
17 * @var array
18 */
19 protected $plugins = array();
20
21 /**
22 * Module options that are stored in database.
23 * Timestamps are stored here.
24 *
25 * Note that this option is stored in site-meta for multisite installs.
26 *
27 * @since 1.0.0
28 * @var array
29 */
30 protected $stored = array();
31
32 /**
33 * Initializes and returns the singleton instance.
34 *
35 * @since 1.0.0
36 */
37 static public function instance() {
38 static $Inst = null;
39
40 if ( null === $Inst ) {
41 $Inst = new WDev_Frash();
42 }
43
44 return $Inst;
45 }
46
47 /**
48 * Set up the WDev_Frash module. Private singleton constructor.
49 *
50 * @since 1.0.0
51 */
52 private function __construct() {
53
54 $this->read_stored_data();
55
56 $this->add_action( 'wdev-register-plugin', 5 );
57 //$this->add_action( 'load-index.php' );
58 $this->add_action( 'admin_init' );
59 $this->add_action( 'wp_ajax_frash_act' );
60 $this->add_action( 'wp_ajax_frash_dismiss' );
61 }
62
63 /**
64 * Load persistent module-data from the WP Database.
65 *
66 * @since 1.0.0
67 */
68 protected function read_stored_data() {
69 $data = get_site_option( 'wdev-frash', false, false );
70
71 if ( ! is_array( $data ) ) {
72 $data = array();
73 }
74
75 // A list of all plugins with timestamp of first registration.
76 if ( ! isset( $data['plugins'] ) || ! is_array( $data['plugins'] ) ) {
77 $data['plugins'] = array();
78 }
79
80 // A list with pending messages and earliest timestamp for display.
81 if ( ! isset( $data['queue'] ) || ! is_array( $data['queue'] ) ) {
82 $data['queue'] = array();
83 }
84
85 // A list with all messages that were handles already.
86 if ( ! isset( $data['done'] ) || ! is_array( $data['done'] ) ) {
87 $data['done'] = array();
88 }
89
90 $this->stored = $data;
91 }
92
93 /**
94 * Save persistent module-data to the WP database.
95 *
96 * @since 1.0.0
97 */
98 protected function store_data() {
99 $t = update_site_option( 'wdev-frash', $this->stored );
100 }
101
102 /**
103 * Action handler for 'wdev-register-plugin'
104 * Register an active plugin.
105 *
106 * @since 1.0.0
107 * @param string $plugin_id WordPress plugin-ID (see: plugin_basename).
108 * @param string $title Plugin name for display.
109 * @param string $url_wp URL to the plugin on wp.org (domain not needed)
110 * @param string $cta_email Title of the Email CTA button.
111 * @param string $drip_plugin Optional. Plugin-param for the getdrip rule.
112 */
113 public function wdev_register_plugin( $plugin_id, $title, $url_wp, $cta_email = '', $drip_plugin = '' ) {
114
115 // Ignore incorrectly registered plugins to avoid errors later.
116 if ( empty( $plugin_id ) ) { return; }
117 if ( empty( $title ) ) { return; }
118 if ( empty( $url_wp ) ) { return; }
119
120 if ( false === strpos( $url_wp, '://' ) ) {
121 $url_wp = 'https://wordpress.org/' . trim( $url_wp, '/' );
122 }
123
124 $this->plugins[$plugin_id] = (object) array(
125 'id' => $plugin_id,
126 'title' => $title,
127 'url_wp' => $url_wp,
128 'cta_email' => $cta_email,
129 'drip_plugin' => $drip_plugin,
130 );
131 /*
132 * When the plugin is registered the first time we store some infos
133 * in the persistent module-data that help us later to find out
134 * if/which message should be displayed.
135 */
136
137 if ( empty( $this->stored['plugins'][$plugin_id] ) ) {
138 // First register the plugin permanently.
139 $this->stored['plugins'][$plugin_id] = time();
140
141 // Second schedule the messages to display.
142 $hash = md5( $plugin_id . '-email' );
143 $this->stored['queue'][$hash] = array(
144 'plugin' => $plugin_id,
145 'type' => 'email',
146 'show_at' => time(), // Earliest time to display note.
147 );
148
149 $hash = md5( $plugin_id . '-rate' );
150 $this->stored['queue'][$hash] = array(
151 'plugin' => $plugin_id,
152 'type' => 'rate',
153 'show_at' => time() + 7 * DAY_IN_SECONDS,
154 );
155
156 // Finally save the details.
157 $this->store_data();
158 }
159 }
160
161 /**
162 * Ajax handler called when the user chooses the CTA button.
163 *
164 * @since 1.0.0
165 */
166 public function wp_ajax_frash_act() {
167 $plugin = $_POST['plugin_id'];
168 $type = $_POST['type'];
169
170 $this->mark_as_done( $plugin, $type, 'ok' );
171
172 echo 1;
173 exit;
174 }
175
176 /**
177 * Ajax handler called when the user chooses the dismiss button.
178 *
179 * @since 1.0.0
180 */
181 public function wp_ajax_frash_dismiss() {
182 $plugin = $_POST['plugin_id'];
183 $type = $_POST['type'];
184
185 $this->mark_as_done( $plugin, $type, 'ignore' );
186
187 echo 1;
188 exit;
189 }
190
191 /**
192 * Action handler for 'load-index.php'
193 * Set-up the Dashboard notification.
194 *
195 * @since 1.0.0
196 */
197 public function admin_init() {
198
199 if ( is_super_admin() ) {
200 $this->add_action( 'all_admin_notices' );
201 }
202 }
203
204 /**
205 * Action handler for 'admin_notices'
206 * Display the Dashboard notification.
207 *
208 * @since 1.0.0
209 */
210 public function all_admin_notices() {
211 $info = $this->choose_message();
212 if ( ! $info ) { return; }
213
214 $this->render_message( $info );
215 }
216
217 /**
218 * Check to see if there is a pending message to display and returns
219 * the message details if there is.
220 *
221 * Note that this function is only called on the main Dashboard screen
222 * and only when logged in as super-admin.
223 *
224 * @since 1.0.0
225 * @return object|false
226 * string $type [rate|email] Which message type?
227 * string $plugin WordPress plugin ID?
228 */
229 protected function choose_message() {
230 $obj = false;
231 $chosen = false;
232 $earliest = false;
233
234 $now = time();
235
236 // The "current" time can be changed via $_GET to test the module.
237 if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! empty( $_GET['time'] ) ) {
238 $custom_time = $_GET['time'];
239 if ( ' ' == $custom_time[0] ) { $custom_time[0] = '+'; }
240 if ( $custom_time ) { $now = strtotime( $custom_time ); }
241 if ( ! $now ) { $now = time(); }
242 }
243
244 $tomorrow = $now + DAY_IN_SECONDS;
245
246 foreach ( $this->stored['queue'] as $hash => $item ) {
247 $show_at = intval( $item['show_at'] );
248 $is_sticky = ! empty( $item['sticky'] );
249
250 if ( ! isset( $this->plugins[ $item['plugin'] ] ) ) {
251 // Deactivated plugin before the message was displayed.
252 continue;
253 }
254 $plugin = $this->plugins[ $item['plugin'] ];
255
256 $can_display = true;
257 if ( wp_is_mobile() ) {
258 // Do not display rating message on mobile devices.
259 if ( 'rate' == $item['type'] ) {
260 $can_display = false;
261 }
262 }
263 if ( 'email' == $item['type'] ) {
264 if ( ! $plugin->drip_plugin || ! $plugin->cta_email ) {
265 // Do not display email message with missing email params.
266 $can_display = false;
267 }
268 }
269
270 if ( $now < $show_at ) {
271 // Do not display messages that are not due yet.
272 $can_display = false;
273 }
274
275 if ( ! $can_display ) { continue; }
276
277 if ( $is_sticky ) {
278 // If sticky item is present then choose it!
279 $chosen = $hash;
280 break;
281 } elseif ( ! $earliest || $earliest < $show_at ) {
282 $earliest = $show_at;
283 $chosen = $hash;
284 // Don't use `break` because a sticky item might follow...
285 // Find the item with the earliest schedule.
286 }
287 }
288
289 if ( $chosen ) {
290 // Make the chosen item sticky.
291 $this->stored['queue'][$chosen]['sticky'] = true;
292
293 // Re-schedule other messages that are due today.
294 foreach ( $this->stored['queue'] as $hash => $item ) {
295 $show_at = intval( $item['show_at'] );
296
297 if ( empty( $item['sticky'] ) && $tomorrow > $show_at ) {
298 $this->stored['queue'][$hash]['show_at'] = $tomorrow;
299 }
300 }
301
302 // Save the changes.
303 $this->store_data();
304
305 $obj = (object) $this->stored['queue'][$chosen];
306 }
307
308 return $obj;
309 }
310
311 /**
312 * Moves a message from the queue to the done list.
313 *
314 * @since 1.0.0
315 * @param string $plugin Plugin ID.
316 * @param string $type [rate|email] Message type.
317 * @param string $state [ok|ignore] Button clicked.
318 */
319 protected function mark_as_done( $plugin, $type, $state ) {
320 $done_item = false;
321
322 foreach ( $this->stored['queue'] as $hash => $item ) {
323 unset( $this->stored['queue'][$hash]['sticky'] );
324
325 if ( $item['plugin'] == $plugin && $item['type'] == $type ) {
326 $done_item = $item;
327 unset( $this->stored['queue'][$hash] );
328 }
329 }
330
331 if ( $done_item ) {
332 $done_item['state'] = $state;
333 $done_item['hash'] = $hash;
334 $done_item['handled_at'] = time();
335 unset( $done_item['sticky'] );
336
337 $this->stored['done'][] = $done_item;
338 $this->store_data();
339 }
340 }
341
342 /**
343 * Renders the actual Notification message.
344 *
345 * @since 1.0.0
346 */
347 protected function render_message( $info ) {
348 $plugin = $this->plugins[$info->plugin];
349 $css_url = plugin_dir_url( __FILE__ ) . '/admin.css';
350 $js_url = plugin_dir_url( __FILE__ ) . '/admin.js';
351
352 ?>
353 <link rel="stylesheet" type="text/css" href="<?php echo esc_url( $css_url ); ?>" />
354 <div class="notice frash-notice frash-notice-<?php echo esc_attr( $info->type ); ?>" style="display:none">
355 <input type="hidden" name="type" value="<?php echo esc_attr( $info->type ); ?>" />
356 <input type="hidden" name="plugin_id" value="<?php echo esc_attr( $info->plugin ); ?>" />
357 <input type="hidden" name="url_wp" value="<?php echo esc_attr( $plugin->url_wp ); ?>" />
358 <input type="hidden" name="drip_plugin" value="<?php echo esc_attr( $plugin->drip_plugin ); ?>" />
359 <?php
360 if ( 'email' == $info->type ) {
361 $this->render_email_message( $plugin );
362 } elseif ( 'rate' == $info->type ) {
363 $this->render_rate_message( $plugin );
364 }
365 ?>
366 </div>
367 <script src="<?php echo esc_url( $js_url ); ?>"></script>
368 <?php
369 }
370
371 /**
372 * Output the contents of the email message.
373 * No return value. The code is directly output.
374 *
375 * @since 1.0.0
376 */
377 protected function render_email_message( $plugin ) {
378 $user = wp_get_current_user();
379 $user_name = $user->display_name;
380 $admin_email = get_site_option( 'admin_email' );
381
382 $msg = __( "We're happy that you've chosen to install %s! Are you interested in how to make the most of this plugin? How would you like a quick 5 day email crash course with actionable advice on building your membership site? Only the info you want, no subscription!", 'wdev_frash' );
383 $msg = apply_filters( 'wdev-email-message-' . $plugin->id, $msg );
384
385 ?>
386 <div class="frash-notice-logo"><span></span></div>
387 <div class="frash-notice-message">
388 <?php
389 printf(
390 $msg,
391 '<strong>' . $plugin->title . '</strong>'
392 );
393 ?>
394 </div>
395 <div class="frash-notice-cta">
396 <input type="email" name="email" value="<?php echo esc_attr( $admin_email ); ?>" />
397 <button class="frash-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', 'wdev_frash' ); ?>">
398 <?php echo esc_html( $plugin->cta_email ); ?>
399 </button>
400 <button class="frash-notice-dismiss" data-msg="<?php _e( 'Saving', 'wdev_frash' ); ?>">
401 <?php _e( 'No thanks', 'wdev_frash' ); ?>
402 </button>
403 </div>
404 <?php
405 }
406
407 /**
408 * Output the contents of the rate-this-plugin message.
409 * No return value. The code is directly output.
410 *
411 * @since 1.0.0
412 */
413 protected function render_rate_message( $plugin ) {
414 $user = wp_get_current_user();
415 $user_name = $user->display_name;
416
417 $msg = __( "Hey %s, you've been using %s for a week now and we hope you’re enjoying it!", 'wdev_frash' ) . '<br />'. __( "We put a lot of development time into building this free plugin so anyone can create awesome opt-ins that convert. We would really appreciated it if you dropped us a quick rating!", 'wdev_frash' );
418 $msg = apply_filters( 'wdev-rating-message-' . $plugin->id, $msg );
419
420 ?>
421 <div class="frash-notice-logo"><span></span></div>
422 <div class="frash-notice-message">
423 <?php
424 printf(
425 $msg,
426 '<strong>' . $user_name . '</strong>',
427 '<strong>' . $plugin->title . '</strong>'
428 );
429 ?>
430 </div>
431 <div class="frash-notice-cta">
432 <button class="frash-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', 'wdev_frash' ); ?>">
433 <?php
434 printf(
435 __( 'Rate %s', 'wdev_frash' ),
436 esc_html( $plugin->title )
437 ); ?>
438 </button>
439 <button class="frash-notice-dismiss" data-msg="<?php _e( 'Saving', 'wdev_frash' ); ?>">
440 <?php _e( 'No thanks', 'wdev_frash' ); ?>
441 </button>
442 </div>
443 <?php
444 }
445
446 /**
447 * Registers a new action handler. The callback function has the same
448 * name as the action hook.
449 *
450 * @since 1.0.0
451 */
452 protected function add_action( $hook, $params = 1 ) {
453 $method_name = strtolower( $hook );
454 $method_name = preg_replace( '/[^a-z0-9]/', '_', $method_name );
455 $handler = array( $this, $method_name );
456
457 add_action( $hook, $handler, 5, $params );
458 }
459 }
460
461 // Initialize the module.
462 WDev_Frash::instance();
463 }
464
465 /**
466 * Filters the rating message, include stats if greater than 1Mb
467 *
468 * @param $message
469 *
470 * @return string
471 */
472 if ( ! function_exists( 'wp_hustle_rating_message' ) ) {
473 function wp_hustle_rating_message( $message ) {
474 // global $wpsmushit_admin, $wpsmush_stats;
475 // $savings = $wpsmushit_admin->global_stats_from_ids();
476 // $image_count = $wpsmush_stats->total_count();
477 // $show_stats = false;
478
479 //If there is any saving, greater than 1Mb, show stats
480 // if ( ! empty( $savings ) && ! empty( $savings['bytes'] ) && $savings['bytes'] > 1048576 ) {
481 // $show_stats = true;
482 // }
483
484 $message = "Hey %s, you've been using %s for a week now and we hope you’re enjoying it!";
485
486 //Conditionally Show stats in rating message
487 // if ( $show_stats ) {
488 // $message .= sprintf( " You've smushed <strong>%s</strong> from %d images already, improving the speed and SEO ranking of this site!", $savings['human'], $image_count );
489 // }
490 $message .= " We put a lot of development time into building this free plugin so anyone can create awesome opt-ins that convert. We would really appreciated it if you dropped us a quick rating!";
491
492 return $message;
493 }
494 }
495
496 /**
497 * NewsLetter
498 *
499 * @param $message
500 *
501 * @return string
502 */
503 if ( ! function_exists( 'wp_hustle_email_message' ) ) {
504 function wp_hustle_email_message( $message ) {
505 $message = "You’re awesome for installing %s! Successfully converting your visitors into subscribers and paying customers doesn’t just stop when you get their email (although it helps!). So we've put together a bunch of guides to get you started.";
506
507 return $message;
508 }
509 }
510
511
512 // Register the current plugin.
513 do_action(
514 'wdev-register-plugin',
515 /* 1 Plugin ID */
516 plugin_basename( __FILE__ ), /* Plugin ID */
517 /* 2 Plugin Title */
518 'Hustle',
519 /* 3 https://wordpress.org */
520 '/plugins/wordpress-popup/',
521 /* 4 Email Button CTA */
522 __( 'Sign Me Up', 'hustle' ),
523 /* 5 getdrip Plugin param */
524 'Hustle'
525 );
526
527 // The rating message contains 2 variables: user-name, plugin-name
528 add_filter(
529 'wdev-rating-message-' . plugin_basename( __FILE__ ),
530 'wp_hustle_rating_message'
531 );
532
533 // The email message contains 1 variable: plugin-name
534 add_filter(
535 'wdev-email-message-' . plugin_basename( __FILE__ ),
536 'wp_hustle_email_message'
537 );