Algolia_Woo_Indexer::load_textdomain()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php
2
3
/**
4
 * Main Algolia Woo Indexer class
5
 * Called from main plugin file algolia-woo-indexer.php
6
 *
7
 * @package algolia-woo-indexer
8
 */
9
10
namespace Algowoo;
11
12
use Algowoo\Algolia_Check_Requirements;
13
use Algowoo\Algolia_Verify_Nonces;
14
use Algowoo\Algolia_Send_Products;
15
16
/**
17
 * Abort if this file is called directly
18
 */
19
if ( ! defined( 'ABSPATH' ) ) {
20
	exit;
21
}
22
23
/**
24
 * Include plugin file if function is_plugin_active does not exist
25
 */
26
if ( ! function_exists( 'is_plugin_active' ) ) {
27
	require_once ABSPATH . '/wp-admin/includes/plugin.php';
28
}
29
30
if ( ! class_exists( 'Algolia_Woo_Indexer' ) ) {
31
	/**
32
	 * Algolia WooIndexer main class
33
	 */
34
	// TODO Rename class "Algolia_Woo_Indexer" to match the regular expression ^[A-Z][a-zA-Z0-9]*$.
35
	class Algolia_Woo_Indexer {
36
37
		const PLUGIN_NAME      = 'Algolia Woo Indexer';
38
		const PLUGIN_TRANSIENT = 'algowoo-plugin-notice';
39
40
		/**
41
		 * Class instance
42
		 *
43
		 * @var object
44
		 */
45
		private static $instance;
46
47
		/**
48
		 * The plugin URL
49
		 *
50
		 * @var string
51
		 */
52
		private static $plugin_url = '';
53
54
		/**
55
		 * Class constructor
56
		 *
57
		 * @return void
58
		 */
59
		public function __construct() {
60
			$this->init();
61
		}
62
63
		/**
64
		 * Setup sections and fields to store and retrieve values from Settings API
65
		 *
66
		 * @return void
67
		 */
68
		public static function setup_settings_sections() {
69
			/**
70
			 * Setup arguments for settings sections and fields
71
			 *
72
			 * @see https://developer.wordpress.org/reference/functions/register_setting/
73
			 */
74
			if ( is_admin() ) {
75
				$arguments = array(
76
					'type'              => 'string',
77
					'sanitize_callback' => 'settings_fields_validate_options',
78
					'default'           => null,
79
				);
80
				register_setting( 'algolia_woo_options', 'algolia_woo_options', $arguments );
81
82
				/**
83
				 * Make sure we reference the instance of the current class by using self::get_instance()
84
				 * This way we can setup the correct callback function for add_settings_section and add_settings_field
85
				 */
86
				$algowooindexer = self::get_instance();
87
88
				/**
89
				 * Add our necessary settings sections and fields
90
				 */
91
				add_settings_section(
92
					'algolia_woo_indexer_main',
93
					esc_html__( 'Algolia Woo Plugin Settings', 'algolia-woo-indexer' ),
94
					array( $algowooindexer, 'algolia_woo_indexer_section_text' ),
95
					'algolia_woo_indexer'
96
				);
97
				add_settings_field(
98
					'algolia_woo_indexer_application_id',
99
					esc_html__( 'Application ID', 'algolia-woo-indexer' ),
100
					array( $algowooindexer, 'algolia_woo_indexer_application_id_output' ),
101
					'algolia_woo_indexer',
102
					'algolia_woo_indexer_main'
103
				);
104
				add_settings_field(
105
					'algolia_woo_indexer_admin_api_key',
106
					esc_html__( 'Admin API Key', 'algolia-woo-indexer' ),
107
					array( $algowooindexer, 'algolia_woo_indexer_admin_api_key_output' ),
108
					'algolia_woo_indexer',
109
					'algolia_woo_indexer_main'
110
				);
111
				add_settings_field(
112
					'algolia_woo_indexer_index_name',
113
					esc_html__( 'Index name (will be created if not existing)', 'algolia-woo-indexer' ),
114
					array( $algowooindexer, 'algolia_woo_indexer_index_name_output' ),
115
					'algolia_woo_indexer',
116
					'algolia_woo_indexer_main'
117
				);
118
				add_settings_field(
119
					'algolia_woo_indexer_automatically_send_new_products',
120
					esc_html__( 'Automatically index new products', 'algolia-woo-indexer' ),
121
					array( $algowooindexer, 'algolia_woo_indexer_automatically_send_new_products_output' ),
122
					'algolia_woo_indexer',
123
					'algolia_woo_indexer_main'
124
				);
125
			}
126
		}
127
128
		/**
129
		 * Output for admin API key field
130
		 *
131
		 * @see https://developer.wordpress.org/reference/functions/wp_nonce_field/
132
		 *
133
		 * @return void
134
		 */
135
		public static function algolia_woo_indexer_admin_api_key_output() {
136
			$api_key = get_option( ALGOWOO_DB_OPTION . ALGOLIA_API_KEY );
137
			$api_key = is_string( $api_key ) ? $api_key : CHANGE_ME;
138
139
			wp_nonce_field( 'algolia_woo_indexer_admin_api_nonce_action', 'algolia_woo_indexer_admin_api_nonce_name' );
140
141
			echo "<input id='algolia_woo_indexer_admin_api_key' name='algolia_woo_indexer_admin_api_key[key]'
142
				type='text' value='" . esc_attr( $api_key ) . "' />";
143
		}
144
145
		/**
146
		 * Output for application ID field
147
		 *
148
		 * @return void
149
		 */
150
		public static function algolia_woo_indexer_application_id_output() {
151
			$application_id = get_option( ALGOWOO_DB_OPTION . ALGOLIA_APP_ID );
152
			$application_id = is_string( $application_id ) ? $application_id : CHANGE_ME;
153
154
			echo "<input id='algolia_woo_indexer_application_id' name='algolia_woo_indexer_application_id[id]'
155
				type='text' value='" . esc_attr( $application_id ) . "' />";
156
		}
157
158
		/**
159
		 * Output for index name field
160
		 *
161
		 * @return void
162
		 */
163
		public static function algolia_woo_indexer_index_name_output() {
164
			$index_name = get_option( ALGOWOO_DB_OPTION . INDEX_NAME );
165
			$index_name = is_string( $index_name ) ? $index_name : CHANGE_ME;
166
167
			echo "<input id='algolia_woo_indexer_index_name' name='algolia_woo_indexer_index_name[name]'
168
				type='text' value='" . esc_attr( $index_name ) . "' />";
169
		}
170
171
		/**
172
		 * Output for checkbox to check if we automatically send new products to Algolia
173
		 *
174
		 * @return void
175
		 */
176
		public static function algolia_woo_indexer_automatically_send_new_products_output() {
177
			/**
178
			 * Sanitization is not really needed as the variable is not directly echoed
179
			 * But I have still done it to be 100% safe
180
			 */
181
			$auto_send = get_option( ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS );
182
			$auto_send = ( ! empty( $auto_send ) ) ? 1 : 0; ?>
183
			<input id="algolia_woo_indexer_automatically_send_new_products" name="algolia_woo_indexer_automatically_send_new_products[checked]" type="checkbox" <?php checked( 1, $auto_send ); ?> />
184
			<?php
185
		}
186
187
		/**
188
		 * Section text for plugin settings section text
189
		 *
190
		 * @return void
191
		 */
192
		public static function algolia_woo_indexer_section_text() {
193
			echo esc_html__( 'Enter your settings here', 'algolia-woo-indexer' );
194
		}
195
196
		/**
197
		 * Check if we are going to send products by verifying send products nonce
198
		 *
199
		 * @return void
200
		 */
201
		public static function maybe_send_products() {
202
			if ( true === Algolia_Verify_Nonces::verify_send_products_nonce() ) {
203
				Algolia_Send_Products::send_products_to_algolia();
204
			}
205
		}
206
207
		/**
208
		 * Initialize class, setup settings sections and fields
209
		 *
210
		 * @return void
211
		 */
212
		public static function init() {
213
214
			/**
215
			 * Fetch the option to see if we are going to automatically send new products
216
			 */
217
			$auto_send = get_option( ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS );
218
219
			/**
220
			 * Check that we have the minimum versions required and all of the required PHP extensions
221
			 */
222
			Algolia_Check_Requirements::check_unmet_requirements();
223
224
			if ( ! Algolia_Check_Requirements::algolia_wp_version_check() || ! Algolia_Check_Requirements::algolia_php_version_check() ) {
225
				add_action(
226
					'admin_notices',
227
					function () {
228
						echo '<div class="error notice">
229
                                  <p>' . esc_html__( 'Please check the server requirements for Algolia Woo Indexer. <br/> It requires minimum PHP version 7.2 and WordPress version 5.0', 'algolia-woo-indexer' ) . '</p>
230
                                </div>';
231
					}
232
				);
233
			}
234
235
			$ob_class = get_called_class();
236
237
			/**
238
			 * Setup translations
239
			 */
240
			add_action( 'plugins_loaded', array( $ob_class, 'load_textdomain' ) );
241
242
			/**
243
			 * Add actions to setup admin menu
244
			 */
245
			if ( is_admin() ) {
246
				add_action( 'admin_menu', array( $ob_class, 'admin_menu' ) );
247
				add_action( 'admin_init', array( $ob_class, 'setup_settings_sections' ) );
248
				add_action( 'admin_init', array( $ob_class, 'update_settings_options' ) );
249
				add_action( 'admin_init', array( $ob_class, 'maybe_send_products' ) );
250
251
				/**
252
				 * Register hook to automatically send new products if the option is set
253
				 */
254
255
				if ( '1' === $auto_send ) {
256
					add_action( 'save_post', array( $ob_class, 'send_new_product_to_algolia' ), 10, 3 );
257
				}
258
259
				self::$plugin_url = admin_url( 'options-general.php?page=algolia-woo-indexer-settings' );
260
261
				if ( ! is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
262
					add_action(
263
						'admin_notices',
264
						function () {
265
							echo '<div class="error notice">
266
								  <p>' . esc_html__( 'WooCommerce plugin must be enabled for Algolia Woo Indexer to work.', 'algolia-woo-indexer' ) . '</p>
267
								</div>';
268
						}
269
					);
270
				}
271
			}
272
		}
273
274
		/**
275
		 * Send a single product to Algolia once a new product has been published
276
		 *
277
		 * @param int   $post_id ID of the product.
278
		 * @param array $post Post array.
279
		 *
280
		 * @return void
281
		 */
282
		public static function send_new_product_to_algolia( $post_id, $post ) {
283
			if ( 'publish' !== $post->post_status || 'product' !== $post->post_type ) {
284
				return;
285
			}
286
			Algolia_Send_Products::send_products_to_algolia( $post_id );
287
		}
288
289
		/**
290
		 * Verify nonces before we update options and settings
291
		 * Also retrieve the value from the send_products_to_algolia hidden field to check if we are sending products to Algolia
292
		 *
293
		 * @return void
294
		 */
295
		public static function update_settings_options() {
296
			Algolia_Verify_Nonces::verify_settings_nonce();
297
298
			if ( Algolia_Verify_Nonces::verify_send_products_nonce() ) {
299
				return;
300
			}
301
302
			$application_id = filter_input( INPUT_POST, 'algolia_woo_indexer_application_id', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
303
			$api_key        = filter_input( INPUT_POST, 'algolia_woo_indexer_admin_api_key', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
304
			$index_name     = filter_input( INPUT_POST, 'algolia_woo_indexer_index_name', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
305
			$auto_send      = filter_input( INPUT_POST, 'algolia_woo_indexer_automatically_send_new_products', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
306
307
			$sanitized_app_id     = sanitize_text_field( $application_id['id'] );
308
			$sanitized_api_key    = sanitize_text_field( $api_key['key'] );
309
			$sanitized_index_name = sanitize_text_field( $index_name['name'] );
310
			$sanitized_auto_send  = ( ! empty( $auto_send ) ) ? 1 : 0;
311
312
			$options = array(
313
				ALGOWOO_DB_OPTION . ALGOLIA_APP_ID  => $sanitized_app_id,
314
				ALGOWOO_DB_OPTION . ALGOLIA_API_KEY => $sanitized_api_key,
315
				ALGOWOO_DB_OPTION . INDEX_NAME      => $sanitized_index_name,
316
				ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS => $sanitized_auto_send,
317
			);
318
319
			foreach ( $options as $option_key => $option_value ) {
320
				if ( isset( $option_value ) && ( ! empty( $option_value ) ) ) {
321
					update_option( $option_key, $option_value );
322
				}
323
			}
324
		}
325
326
327
328
329
		/**
330
		 * Sanitize input in settings fields and filter through regex to accept only a-z and A-Z
331
		 *
332
		 * @param string $input Settings text data
333
		 * @return array
334
		 */
335
		public static function settings_fields_validate_options( $input ) {
336
			$valid         = array();
337
			$valid['name'] = preg_replace(
338
				'/[^a-zA-Z\s]/',
339
				'',
340
				$input['name']
341
			);
342
			return $valid;
343
		}
344
345
		/**
346
		 * Load text domain for translations
347
		 *
348
		 * @return void
349
		 */
350
		public static function load_textdomain() {
351
			load_plugin_textdomain( 'algolia-woo-indexer', false, basename( __DIR__ ) . '/languages/' );
352
		}
353
354
		/**
355
		 * Add the new menu to settings section so that we can configure the plugin
356
		 *
357
		 * @return void
358
		 */
359
		public static function admin_menu() {
360
			add_submenu_page(
361
				'options-general.php',
362
				esc_html__( 'Algolia Woo Indexer Settings', 'algolia-woo-indexer' ),
363
				esc_html__( 'Algolia Woo Indexer Settings', 'algolia-woo-indexer' ),
364
				'manage_options',
365
				'algolia-woo-indexer-settings',
366
				array( get_called_class(), 'algolia_woo_indexer_settings' )
367
			);
368
		}
369
370
		/**
371
		 * Display settings and allow user to modify them
372
		 *
373
		 * @return void
374
		 */
375
		public static function algolia_woo_indexer_settings() {
376
			/**
377
			 * Verify that the user can access the settings page
378
			 */
379
			if ( ! current_user_can( 'manage_options' ) ) {
380
				wp_die( esc_html__( 'Action not allowed.', 'algolia_woo_indexer_settings' ) );
381
			}
382
			?>
383
			<div class="wrap">
384
				<h1><?php esc_html__( 'Algolia Woo Indexer Settings', 'algolia-woo-indexer' ); ?></h1>
385
				<form action="<?php echo esc_url( self::$plugin_url ); ?>" method="POST">
386
					<?php
387
					settings_fields( 'algolia_woo_options' );
388
					do_settings_sections( 'algolia_woo_indexer' );
389
					submit_button( '', 'primary wide' );
390
					?>
391
				</form>
392
				<form action="<?php echo esc_url( self::$plugin_url ); ?>" method="POST">
393
					<?php wp_nonce_field( 'send_products_to_algolia_nonce_action', 'send_products_to_algolia_nonce_name' ); ?>
394
					<input type="hidden" name="send_products_to_algolia" id="send_products_to_algolia" value="true" />
395
					<?php submit_button( esc_html__( 'Send products to Algolia', 'algolia_woo_indexer_settings' ), 'primary wide', '', false ); ?>
396
				</form>
397
			</div>
398
			<?php
399
		}
400
401
		/**
402
		 * Get active object instance
403
		 *
404
		 * @return object
405
		 */
406
		public static function get_instance() {
407
			if ( ! self::$instance ) {
408
				self::$instance = new Algolia_Woo_Indexer();
409
			}
410
			return self::$instance;
411
		}
412
413
		/**
414
		 * The actions to execute when the plugin is activated.
415
		 *
416
		 * @return void
417
		 */
418
		public static function activate_plugin() {
419
420
			/**
421
			 * Set default values for options if not already set
422
			 */
423
			$auto_send              = get_option( ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS );
424
			$algolia_application_id = get_option( ALGOWOO_DB_OPTION . ALGOLIA_APP_ID );
425
			$algolia_api_key        = get_option( ALGOWOO_DB_OPTION . ALGOLIA_API_KEY );
426
			$algolia_index_name     = get_option( ALGOWOO_DB_OPTION . INDEX_NAME );
427
428
			if ( empty( $auto_send ) ) {
429
				add_option(
430
					ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS,
431
					'0'
432
				);
433
			}
434
435
			if ( empty( $algolia_application_id ) ) {
436
				add_option(
437
					ALGOWOO_DB_OPTION . ALGOLIA_APP_ID,
438
					'Change me'
439
				);
440
			}
441
442
			if ( empty( $algolia_api_key ) ) {
443
				add_option(
444
					ALGOWOO_DB_OPTION . ALGOLIA_API_KEY,
445
					'Change me'
446
				);
447
			}
448
449
			if ( empty( $algolia_index_name ) ) {
450
				add_option(
451
					ALGOWOO_DB_OPTION . INDEX_NAME,
452
					'Change me'
453
				);
454
			}
455
			set_transient( self::PLUGIN_TRANSIENT, true );
456
		}
457
458
		/**
459
		 * The actions to execute when the plugin is deactivated.
460
		 *
461
		 * @return void
462
		 */
463
		public static function deactivate_plugin() {
464
			delete_transient( self::PLUGIN_TRANSIENT );
465
		}
466
	}
467
}
468