|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Better Optin. |
|
4
|
|
|
* |
|
5
|
|
|
* @package BetterOptin |
|
6
|
|
|
* @author ThemeAvenue <[email protected]> |
|
7
|
|
|
* @license GPL-2.0+ |
|
8
|
|
|
* @link http://themeavenue.net |
|
9
|
|
|
* @copyright 2014 ThemeAvenue |
|
10
|
|
|
* |
|
11
|
|
|
* @wordpress-plugin |
|
12
|
|
|
* Plugin Name: BetterOptin |
|
13
|
|
|
* Plugin URI: https://betteropt.in/ |
|
14
|
|
|
* Description: BetterOptin helps you convert your visitors in subscribers and fill up your mailing lists. |
|
15
|
|
|
* Version: 2.0.2 |
|
16
|
|
|
* Author: ThemeAvenue |
|
17
|
|
|
* Author URI: https://themeavenue.net |
|
18
|
|
|
* Text Domain: betteroptin |
|
19
|
|
|
* License: GPL-2.0+ |
|
20
|
|
|
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt |
|
21
|
|
|
* Domain Path: /languages |
|
22
|
|
|
*/ |
|
23
|
|
|
|
|
24
|
|
|
// If this file is called directly, abort. |
|
25
|
|
|
if ( ! defined( 'WPINC' ) ) { |
|
26
|
|
|
die; |
|
27
|
|
|
} |
|
28
|
|
|
|
|
29
|
|
|
if ( ! class_exists( 'BetterOptin' ) ): |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* Main BetterOptin class |
|
33
|
|
|
* |
|
34
|
|
|
* This class is the one and only instance of the plugin. It is used |
|
35
|
|
|
* to load the core and all its components. |
|
36
|
|
|
* |
|
37
|
|
|
* @since 2.0 |
|
38
|
|
|
*/ |
|
39
|
|
|
final class BetterOptin { |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* @var BetterOptin Holds the unique instance of BetterOptin |
|
43
|
|
|
* @since 2.0 |
|
44
|
|
|
*/ |
|
45
|
|
|
private static $instance; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* Possible error message. |
|
49
|
|
|
* |
|
50
|
|
|
* @since 2.0 |
|
51
|
|
|
* @var null|WP_Error |
|
52
|
|
|
*/ |
|
53
|
|
|
protected $error = null; |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* Instantiate and return the unique BetterOptin object |
|
57
|
|
|
* |
|
58
|
|
|
* @since 2.0 |
|
59
|
|
|
* @return object BetterOptin Unique instance of BetterOptin |
|
60
|
|
|
*/ |
|
61
|
|
|
public static function instance() { |
|
62
|
|
|
|
|
63
|
|
|
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof BetterOptin ) ) { |
|
64
|
|
|
|
|
65
|
|
|
// Instantiate |
|
66
|
|
|
self::$instance = new BetterOptin; |
|
67
|
|
|
self::$instance->init(); |
|
68
|
|
|
|
|
69
|
|
|
|
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
return self::$instance; |
|
73
|
|
|
|
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
/** |
|
77
|
|
|
* Instantiate the plugin |
|
78
|
|
|
* |
|
79
|
|
|
* @since 2.0 |
|
80
|
|
|
* @return void |
|
81
|
|
|
*/ |
|
82
|
|
|
private function init() { |
|
83
|
|
|
|
|
84
|
|
|
self::$instance->setup_constants(); |
|
85
|
|
|
|
|
86
|
|
|
// Make sure the WordPress version is recent enough |
|
87
|
|
|
if ( ! self::$instance->are_dependencies_loaded() ) { |
|
88
|
|
|
self::$instance->add_error( wp_kses_post( sprintf( __( 'BetterOptin cannot load because its dependencies are missing. If you don't know what this means, please purchase the pro version on %s', 'betteroptin' ), '<a href="https://betteropt.in/?utm_source=plugin&utm_medium=dependencies_nag&utm_campaign=upsell" target="_blank">https://betteropt.in</a>' ) ) ); |
|
89
|
|
|
} |
|
90
|
|
|
|
|
91
|
|
|
// If we have any error, don't load the plugin |
|
92
|
|
|
if ( is_a( self::$instance->error, 'WP_Error' ) ) { |
|
93
|
|
|
add_action( 'admin_notices', array( self::$instance, 'display_error' ), 10, 0 ); |
|
94
|
|
|
return; |
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
self::$instance->setup_database_constants(); |
|
98
|
|
|
self::$instance->includes(); |
|
99
|
|
|
self::$instance->load_providers(); |
|
100
|
|
|
|
|
101
|
|
|
if ( is_admin() ) { |
|
102
|
|
|
self::$instance->includes_admin(); |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
add_action( 'plugins_loaded', array( self::$instance, 'load_plugin_textdomain' ) ); |
|
106
|
|
|
add_action( 'init', array( self::$instance, 'license_notification' ) ); |
|
107
|
|
|
add_action( 'init', array( self::$instance, 'check_provider_ready' ) ); |
|
108
|
|
|
add_filter( 'pre_set_site_transient_update_plugins', array( self::$instance, 'maybe_disable_wordpress_updates' ) ); |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* Throw error on object clone |
|
113
|
|
|
* |
|
114
|
|
|
* The whole idea of the singleton design pattern is that there is a single |
|
115
|
|
|
* object therefore, we don't want the object to be cloned. |
|
116
|
|
|
* |
|
117
|
|
|
* @since 2.0 |
|
118
|
|
|
* @return void |
|
119
|
|
|
*/ |
|
120
|
|
|
public function __clone() { |
|
121
|
|
|
// Cloning instances of the class is forbidden |
|
122
|
|
|
_doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'betteroptin' ), '2.0' ); |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
/** |
|
126
|
|
|
* Disable unserializing of the class |
|
127
|
|
|
* |
|
128
|
|
|
* @since 2.0 |
|
129
|
|
|
* @return void |
|
130
|
|
|
*/ |
|
131
|
|
|
public function __wakeup() { |
|
132
|
|
|
// Unserializing instances of the class is forbidden |
|
133
|
|
|
_doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'betteroptin' ), '2.0' ); |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
/** |
|
137
|
|
|
* Setup all plugin constants |
|
138
|
|
|
* |
|
139
|
|
|
* @since 2.0 |
|
140
|
|
|
* @return void |
|
141
|
|
|
*/ |
|
142
|
|
|
private function setup_constants() { |
|
143
|
|
|
define( 'WPBO_URL', trailingslashit( plugin_dir_url( __FILE__ ) ) ); |
|
144
|
|
|
define( 'WPBO_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) ); |
|
145
|
|
|
define( 'WPBO_BASENAME', plugin_basename( __FILE__ ) ); |
|
146
|
|
|
define( 'WPBO_PLUGIN_FILE', __FILE__ ); |
|
147
|
|
|
define( 'WPBO_VERSION', '2.0.2' ); |
|
148
|
|
|
define( 'WPBO_DB_VERSION', '1' ); |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
private function are_dependencies_loaded() { |
|
152
|
|
|
return is_dir( WPBO_PATH . 'vendor' ); |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
/** |
|
156
|
|
|
* Add error. |
|
157
|
|
|
* |
|
158
|
|
|
* Add a new error to the WP_Error object |
|
159
|
|
|
* and create the object if it doesn't exist yet. |
|
160
|
|
|
* |
|
161
|
|
|
* @since 2.0 |
|
162
|
|
|
* |
|
163
|
|
|
* @param string $message Error message to add |
|
164
|
|
|
* |
|
165
|
|
|
* @return void |
|
166
|
|
|
*/ |
|
167
|
|
|
private function add_error( $message ) { |
|
168
|
|
|
|
|
169
|
|
|
if ( ! is_object( $this->error ) || ! is_a( $this->error, 'WP_Error' ) ) { |
|
170
|
|
|
$this->error = new WP_Error(); |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
$this->error->add( 'addon_error', $message ); |
|
174
|
|
|
|
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* Display error. |
|
179
|
|
|
* |
|
180
|
|
|
* Get all the error messages and display them |
|
181
|
|
|
* in the admin notices. |
|
182
|
|
|
* |
|
183
|
|
|
* @since 2.0 |
|
184
|
|
|
* @return void |
|
185
|
|
|
*/ |
|
186
|
|
|
public function display_error() { |
|
187
|
|
|
if ( ! is_a( $this->error, 'WP_Error' ) ) { |
|
188
|
|
|
return; |
|
189
|
|
|
} |
|
190
|
|
|
$message = self::$instance->error->get_error_messages(); ?> |
|
191
|
|
|
|
|
192
|
|
|
<div class="error"> |
|
193
|
|
|
<p> |
|
194
|
|
|
<?php |
|
195
|
|
|
if ( count( $message ) > 1 ) { |
|
196
|
|
|
echo '<ul>'; |
|
197
|
|
|
foreach ( $message as $msg ) { |
|
198
|
|
|
echo "<li>$msg</li>"; |
|
199
|
|
|
} |
|
200
|
|
|
echo '</li>'; |
|
201
|
|
|
} else { |
|
202
|
|
|
echo $message[0]; |
|
203
|
|
|
} |
|
204
|
|
|
?> |
|
205
|
|
|
</p> |
|
206
|
|
|
</div> |
|
207
|
|
|
<?php |
|
208
|
|
|
} |
|
209
|
|
|
|
|
210
|
|
|
/** |
|
211
|
|
|
* Setup the custom database table constants |
|
212
|
|
|
* |
|
213
|
|
|
* @since 2.0 |
|
214
|
|
|
* @return void |
|
215
|
|
|
*/ |
|
216
|
|
|
private function setup_database_constants() { |
|
217
|
|
|
|
|
218
|
|
|
global $wpdb; |
|
219
|
|
|
|
|
220
|
|
|
define( 'wpbo_analytics_table_name', 'wpbo_analytics' ); |
|
221
|
|
|
define( 'wpbo_failsafe_table_name', 'wpbo_failsafe' ); |
|
222
|
|
|
define( 'wpbo_analytics_table', $wpdb->prefix . wpbo_analytics_table_name ); |
|
223
|
|
|
define( 'wpbo_failsafe_table', $wpdb->prefix . wpbo_failsafe_table_name ); |
|
224
|
|
|
|
|
225
|
|
|
} |
|
226
|
|
|
|
|
227
|
|
|
/** |
|
228
|
|
|
* Include all files used sitewide |
|
229
|
|
|
* |
|
230
|
|
|
* @since 2.0 |
|
231
|
|
|
* @return void |
|
232
|
|
|
*/ |
|
233
|
|
|
private function includes() { |
|
234
|
|
|
|
|
235
|
|
|
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) { |
|
236
|
|
|
|
|
237
|
|
|
require( WPBO_PATH . 'includes/scripts.php' ); |
|
238
|
|
|
require( WPBO_PATH . 'includes/shortcode.php' ); |
|
239
|
|
|
require( WPBO_PATH . 'includes/functions-templating.php' ); |
|
240
|
|
|
require( WPBO_PATH . 'includes/functions-dummy.php' ); |
|
241
|
|
|
|
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
require( WPBO_PATH . 'includes/class-popup.php' ); |
|
245
|
|
|
require( WPBO_PATH . 'includes/functions-post-type.php' ); |
|
246
|
|
|
require( WPBO_PATH . 'includes/functions-analytics.php' ); |
|
247
|
|
|
require( WPBO_PATH . 'includes/functions-failsafe.php' ); |
|
248
|
|
|
require( WPBO_PATH . 'includes/functions-popup.php' ); |
|
249
|
|
|
require( WPBO_PATH . 'includes/functions-misc.php' ); |
|
250
|
|
|
require( WPBO_PATH . 'includes/functions-ajax.php' ); |
|
251
|
|
|
|
|
252
|
|
|
} |
|
253
|
|
|
|
|
254
|
|
|
/** |
|
255
|
|
|
* Include all files used in admin only |
|
256
|
|
|
* |
|
257
|
|
|
* @since 2.0 |
|
258
|
|
|
* @return void |
|
259
|
|
|
*/ |
|
260
|
|
|
private function includes_admin() { |
|
261
|
|
|
|
|
262
|
|
|
require( WPBO_PATH . 'includes/admin/functions-misc.php' ); |
|
263
|
|
|
require( WPBO_PATH . 'vendor/julien731/wp-dismissible-notices-handler/handler.php' ); |
|
264
|
|
|
|
|
265
|
|
|
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) { |
|
266
|
|
|
require( WPBO_PATH . 'includes/admin/EDD_SL_Plugin_Updater.php' ); // Load before Titan Framework to override the one bundled with the framework |
|
267
|
|
|
require( WPBO_PATH . 'includes/admin/class-titan-framework.php' ); |
|
268
|
|
|
require( WPBO_PATH . 'includes/admin/settings/settings-general.php' ); |
|
269
|
|
|
require( WPBO_PATH . 'includes/admin/functions-menu.php' ); |
|
270
|
|
|
require( WPBO_PATH . 'includes/admin/functions-metabox.php' ); |
|
271
|
|
|
require( WPBO_PATH . 'includes/admin/functions-list-table.php' ); |
|
272
|
|
|
require( WPBO_PATH . 'includes/install.php' ); |
|
273
|
|
|
} |
|
274
|
|
|
|
|
275
|
|
|
} |
|
276
|
|
|
|
|
277
|
|
|
/** |
|
278
|
|
|
* Load all the providers from the providers directory |
|
279
|
|
|
* |
|
280
|
|
|
* @since 2.0 |
|
281
|
|
|
* @return void |
|
282
|
|
|
*/ |
|
283
|
|
|
private function load_providers() { |
|
284
|
|
|
require( WPBO_PATH . 'includes/providers/wordpress/load.php' ); |
|
285
|
|
|
require( WPBO_PATH . 'includes/providers/mailchimp/load.php' ); |
|
286
|
|
|
require( WPBO_PATH . 'includes/providers/mailpoet/load.php' ); |
|
287
|
|
|
require( WPBO_PATH . 'includes/providers/aweber/load.php' ); |
|
288
|
|
|
} |
|
289
|
|
|
|
|
290
|
|
|
/** |
|
291
|
|
|
* Load the plugin text domain for translation. |
|
292
|
|
|
* |
|
293
|
|
|
* @since 1.0.0 |
|
294
|
|
|
*/ |
|
295
|
|
|
public function load_plugin_textdomain() { |
|
296
|
|
|
|
|
297
|
|
|
apply_filters( 'plugin_locale', get_locale(), 'betteroptin' ); |
|
298
|
|
|
|
|
299
|
|
|
load_plugin_textdomain( 'betteroptin', false, basename( plugin_dir_path( dirname( __FILE__ ) ) ) . '/languages/' ); |
|
300
|
|
|
|
|
301
|
|
|
} |
|
302
|
|
|
|
|
303
|
|
|
/** |
|
304
|
|
|
* Display an admin notice if license key is missing |
|
305
|
|
|
* |
|
306
|
|
|
* @since 2.0 |
|
307
|
|
|
* @return void |
|
308
|
|
|
*/ |
|
309
|
|
|
public function license_notification() { |
|
310
|
|
|
|
|
311
|
|
|
if ( ! function_exists( 'DNH' ) ) { |
|
312
|
|
|
return; |
|
313
|
|
|
} |
|
314
|
|
|
|
|
315
|
|
|
$license = wpbo_get_option( 'license_key', '' ); |
|
316
|
|
|
|
|
317
|
|
|
/** |
|
318
|
|
|
* Do not show the notice if the license key has already been entered. |
|
319
|
|
|
*/ |
|
320
|
|
|
if ( ! empty( $license ) ) { |
|
321
|
|
|
return; |
|
322
|
|
|
} |
|
323
|
|
|
|
|
324
|
|
|
$license_page = wpbo_get_settings_page_link(); |
|
325
|
|
|
|
|
326
|
|
|
dnh_register_notice( 'wpbo_no_license', 'error', sprintf( __( 'You haven't entered your BetterOptin license key. This means that you will not get automatic updates and you will not get technical support. <a %s>Click here to enter your license key</a>.', 'betteroptin' ), "href='$license_page'" ), array( 'cap' => 'administrator' ) ); |
|
327
|
|
|
|
|
328
|
|
|
} |
|
329
|
|
|
|
|
330
|
|
|
/** |
|
331
|
|
|
* Make sure a provider is selected for the lead collection |
|
332
|
|
|
* |
|
333
|
|
|
* @since 2.0 |
|
334
|
|
|
* @return void |
|
335
|
|
|
*/ |
|
336
|
|
|
public function check_provider_ready() { |
|
337
|
|
|
|
|
338
|
|
|
if ( ! function_exists( 'DNH' ) ) { |
|
339
|
|
|
return; |
|
340
|
|
|
} |
|
341
|
|
|
|
|
342
|
|
|
if ( false !== wpbo_is_provider_ready() ) { |
|
343
|
|
|
return; |
|
344
|
|
|
} |
|
345
|
|
|
|
|
346
|
|
|
$license_page = wpbo_get_settings_page_link(); |
|
347
|
|
|
|
|
348
|
|
|
dnh_register_notice( 'wpbo_no_provider', 'error', sprintf( __( 'You haven't selected your provider for catching leads. <strong>BetterOptin will not work until you do so!</strong> <a %s>Click here to select your provider</a>.', 'betteroptin' ), "href='$license_page'" ) ); |
|
349
|
|
|
|
|
350
|
|
|
} |
|
351
|
|
|
|
|
352
|
|
|
/** |
|
353
|
|
|
* Disable WordPress auto-update if the user has the pro version |
|
354
|
|
|
* |
|
355
|
|
|
* For pro version, the updates will come directly from our server. |
|
356
|
|
|
* With the custom EDD SL Updater updates should only come through https://betteropt.in |
|
357
|
|
|
* but just to make sure nobody gets downgraded to the lite version |
|
358
|
|
|
* we double check that no update comes from WP.org for BetterOptin. |
|
359
|
|
|
* |
|
360
|
|
|
* @since 2.0.3 |
|
361
|
|
|
* |
|
362
|
|
|
* @param object $value Auto-update object |
|
363
|
|
|
* |
|
364
|
|
|
* @return object |
|
365
|
|
|
*/ |
|
366
|
|
|
public function maybe_disable_wordpress_updates( $value ) { |
|
367
|
|
|
|
|
368
|
|
|
// Get the product license |
|
369
|
|
|
$license = wpbo_get_option( 'license_key', '' ); |
|
370
|
|
|
|
|
371
|
|
|
// If no license is entered we're on the lite version and need WP.org updates |
|
372
|
|
|
if ( empty( $license ) ) { |
|
373
|
|
|
return $value; |
|
374
|
|
|
} |
|
375
|
|
|
|
|
376
|
|
|
// Get the license hash/ID |
|
377
|
|
|
$key = substr( md5( $license ), 0, 10 ); |
|
378
|
|
|
|
|
379
|
|
|
// Try and get the activation status from the transient |
|
380
|
|
|
// @see TitanFrameworkOptionEddLicense::check() |
|
|
|
|
|
|
381
|
|
|
$status = get_transient( "tf_edd_license_status_$key" ); |
|
382
|
|
|
|
|
383
|
|
|
if ( false === $status ) { |
|
384
|
|
|
|
|
385
|
|
|
$edd_license = new TitanFrameworkOptionEddLicense( array( |
|
386
|
|
|
'server' => esc_url( 'https://betteropt.in' ), |
|
387
|
|
|
'item_id' => 81877, |
|
388
|
|
|
'file' => WPBO_PLUGIN_FILE |
|
389
|
|
|
), 'me' ); |
|
390
|
|
|
|
|
391
|
|
|
$status = $edd_license->check( $license ); |
|
392
|
|
|
|
|
393
|
|
|
} |
|
394
|
|
|
|
|
395
|
|
|
// This is a pro version, we make sure no auto-update comes from WP.org |
|
396
|
|
|
if ( 'valid' === $status && is_object( $value ) && is_array( $value->response ) && array_key_exists( plugin_basename( __FILE__ ), $value->response ) ) { |
|
397
|
|
|
|
|
398
|
|
|
// Remove the download package if it comes from WP.org |
|
399
|
|
|
if ( false === strpos( $value->response[ plugin_basename( __FILE__ ) ]->url, 'betteropt.in' ) ) { |
|
400
|
|
|
unset( $value->response[ plugin_basename( __FILE__ ) ] ); |
|
401
|
|
|
} |
|
402
|
|
|
|
|
403
|
|
|
} |
|
404
|
|
|
|
|
405
|
|
|
return $value; |
|
406
|
|
|
|
|
407
|
|
|
} |
|
408
|
|
|
|
|
409
|
|
|
} |
|
410
|
|
|
|
|
411
|
|
|
endif; |
|
412
|
|
|
|
|
413
|
|
|
/** |
|
414
|
|
|
* The main function responsible for returning the unique BetterOptin instance |
|
415
|
|
|
* |
|
416
|
|
|
* Use this function like you would a global variable, except without needing |
|
417
|
|
|
* to declare the global. |
|
418
|
|
|
* |
|
419
|
|
|
* @since 2.0 |
|
420
|
|
|
* @return object BetterOptin |
|
421
|
|
|
*/ |
|
422
|
|
|
function BO() { |
|
423
|
|
|
return BetterOptin::instance(); |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
// Get BetterOptin Running |
|
427
|
|
|
BO(); |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.