Passed
Pull Request — master (#169)
by
unknown
02:04
created

Algolia_Woo_Indexer::load_textdomain()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
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 3
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 as Algolia_Check_Requirements;
0 ignored issues
show
Bug introduced by
The type \Algowoo\Algolia_Check_Requirements was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
This use statement conflicts with another class in this namespace, Algowoo\Algolia_Check_Requirements. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
13
use \Algowoo\Algolia_Verify_Nonces as Algolia_Verify_Nonces;
0 ignored issues
show
Bug introduced by
The type \Algowoo\Algolia_Verify_Nonces was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
This use statement conflicts with another class in this namespace, Algowoo\Algolia_Verify_Nonces. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
14
use \Algowoo\Algolia_Send_Products as Algolia_Send_Products;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Algowoo\Algolia_Send_Products. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
Bug introduced by
The type \Algowoo\Algolia_Send_Products was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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
        {
61
            $this->init();
62
        }
63
64
        /**
65
         * Setup sections and fields to store and retrieve values from Settings API
66
         *
67
         * @return void
68
         */
69
        public static function setup_settings_sections()
70
        {
71
            /**
72
             * Setup arguments for settings sections and fields
73
             *
74
             * @see https://developer.wordpress.org/reference/functions/register_setting/
75
             */
76
            if (is_admin()) {
77
                $arguments = array(
78
                    'type'              => 'string',
79
                    'sanitize_callback' => 'settings_fields_validate_options',
80
                    'default'           => null,
81
                );
82
                register_setting('algolia_woo_options', 'algolia_woo_options', $arguments);
83
84
                /**
85
                 * Make sure we reference the instance of the current class by using self::get_instance()
86
                 * This way we can setup the correct callback function for add_settings_section and add_settings_field
87
                 */
88
                $algowooindexer = self::get_instance();
89
90
                /**
91
                 * Add our necessary settings sections and fields
92
                 */
93
                add_settings_section(
94
                    'algolia_woo_indexer_main',
95
                    esc_html__('Algolia Woo Plugin Settings', 'algolia-woo-indexer'),
96
                    array($algowooindexer, 'algolia_woo_indexer_section_text'),
97
                    'algolia_woo_indexer'
98
                );
99
                add_settings_field(
100
                    'algolia_woo_indexer_application_id',
101
                    esc_html__('Application ID', 'algolia-woo-indexer'),
102
                    array($algowooindexer, 'algolia_woo_indexer_application_id_output'),
103
                    'algolia_woo_indexer',
104
                    'algolia_woo_indexer_main'
105
                );
106
                add_settings_field(
107
                    'algolia_woo_indexer_admin_api_key',
108
                    esc_html__('Admin API Key', 'algolia-woo-indexer'),
109
                    array($algowooindexer, 'algolia_woo_indexer_admin_api_key_output'),
110
                    'algolia_woo_indexer',
111
                    'algolia_woo_indexer_main'
112
                );
113
                add_settings_field(
114
                    'algolia_woo_indexer_index_name',
115
                    esc_html__('Index name (will be created if not existing)', 'algolia-woo-indexer'),
116
                    array($algowooindexer, 'algolia_woo_indexer_index_name_output'),
117
                    'algolia_woo_indexer',
118
                    'algolia_woo_indexer_main'
119
                );
120
                add_settings_field(
121
                    'algolia_woo_indexer_automatically_send_new_products',
122
                    esc_html__('Automatically index new products', 'algolia-woo-indexer'),
123
                    array($algowooindexer, 'algolia_woo_indexer_automatically_send_new_products_output'),
124
                    'algolia_woo_indexer',
125
                    'algolia_woo_indexer_main'
126
                );
127
                add_settings_field(
128
                    'algolia_woo_indexer_automatically_send_new_products',
129
                    esc_html__('Automatically index new products', 'algolia-woo-indexer'),
130
                    array($algowooindexer, 'algolia_woo_indexer_automatically_send_new_products_output'),
131
                    'algolia_woo_indexer',
132
                    'algolia_woo_indexer_main'
133
                );
134
135
                /**
136
                 * Add sections and fields for the basic fields
137
                 */
138
                add_settings_section(
139
                    'algolia_woo_indexer_fields',
140
                    esc_html__('Fields indexing settings', 'algolia-woo-indexer'),
141
                    array($algowooindexer, 'algolia_woo_indexer_fields_section_text'),
142
                    'algolia_woo_indexer'
143
                );
144
                foreach (BASIC_FIELDS as $field) {
145
                    add_settings_field(
146
                        'algolia_woo_indexer_field_' . $field,
147
                        esc_html__($field, 'algolia-woo-indexer'),
148
                        array($algowooindexer, 'algolia_woo_indexer_field_output'),
149
                        'algolia_woo_indexer',
150
                        'algolia_woo_indexer_fields',
151
                        array(
152
                            'label_for' => 'algolia_woo_indexer_field_' . $field,
153
                            'name' => $field
154
                        )
155
                    );
156
                }
157
158
                /**
159
                 * Add sections and fields for the attributes
160
                 */
161
                add_settings_section(
162
                    'algolia_woo_indexer_attributes',
163
                    esc_html__('Attributes indexing settings', 'algolia-woo-indexer'),
164
                    array($algowooindexer, 'algolia_woo_indexer_attributes_section_text'),
165
                    'algolia_woo_indexer'
166
                );
167
                add_settings_field(
168
                    'algolia_woo_indexer_attributes_enabled',
169
                    esc_html__('Enable indexing of attributes', 'algolia-woo-indexer'),
170
                    array($algowooindexer, 'algolia_woo_indexer_attributes_enabled_output'),
171
                    'algolia_woo_indexer',
172
                    'algolia_woo_indexer_attributes'
173
                );
174
                add_settings_field(
175
                    'algolia_woo_indexer_attributes_visibility',
176
                    esc_html__('Visibility', 'algolia-woo-indexer'),
177
                    array($algowooindexer, 'algolia_woo_indexer_attributes_visibility_output'),
178
                    'algolia_woo_indexer',
179
                    'algolia_woo_indexer_attributes'
180
                );
181
182
                add_settings_field(
183
                    'algolia_woo_indexer_attributes_variation',
184
                    esc_html__('Used for variations', 'algolia-woo-indexer'),
185
                    array($algowooindexer, 'algolia_woo_indexer_attributes_variation_output'),
186
                    'algolia_woo_indexer',
187
                    'algolia_woo_indexer_attributes'
188
                );
189
                add_settings_field(
190
                    'algolia_woo_indexer_attributes_list',
191
                    esc_html__('Valid Attributes', 'algolia-woo-indexer'),
192
                    array($algowooindexer, 'algolia_woo_indexer_attributes_list_output'),
193
                    'algolia_woo_indexer',
194
                    'algolia_woo_indexer_attributes'
195
                );
196
                add_settings_field(
197
                    'algolia_woo_indexer_attributes_list_interpolate',
198
                    esc_html__('Numeric Interpolation', 'algolia-woo-indexer'),
199
                    array($algowooindexer, 'algolia_woo_indexer_attributes_list_interpolate_output'),
200
                    'algolia_woo_indexer',
201
                    'algolia_woo_indexer_attributes'
202
                );
203
            }
204
        }
205
206
        /**
207
         * Output for admin API key field
208
         *
209
         * @see https://developer.wordpress.org/reference/functions/wp_nonce_field/
210
         *
211
         * @return void
212
         */
213
        public static function algolia_woo_indexer_admin_api_key_output()
214
        {
215
            $api_key = get_option(ALGOWOO_DB_OPTION . ALGOLIA_API_KEY);
216
            $api_key = is_string($api_key) ? $api_key : CHANGE_ME;
217
218
            wp_nonce_field('algolia_woo_indexer_admin_api_nonce_action', 'algolia_woo_indexer_admin_api_nonce_name');
219
220
            echo "<input id='algolia_woo_indexer_admin_api_key' name='algolia_woo_indexer_admin_api_key[key]'
221
				type='text' value='" . esc_attr($api_key) . "' />";
222
        }
223
224
        /**
225
         * Output for application ID field
226
         *
227
         * @return void
228
         */
229
        public static function algolia_woo_indexer_application_id_output()
230
        {
231
            $application_id = get_option(ALGOWOO_DB_OPTION . ALGOLIA_APP_ID);
232
            $application_id = is_string($application_id) ? $application_id : CHANGE_ME;
233
234
            echo "<input id='algolia_woo_indexer_application_id' name='algolia_woo_indexer_application_id[id]'
235
				type='text' value='" . esc_attr($application_id) . "' />";
236
        }
237
238
        /**
239
         * Output for index name field
240
         *
241
         * @return void
242
         */
243
        public static function algolia_woo_indexer_index_name_output()
244
        {
245
            $index_name = get_option(ALGOWOO_DB_OPTION . INDEX_NAME);
246
            $index_name = is_string($index_name) ? $index_name : CHANGE_ME;
247
248
            echo "<input id='algolia_woo_indexer_index_name' name='algolia_woo_indexer_index_name[name]'
249
				type='text' value='" . esc_attr($index_name) . "' />";
250
        }
251
252
        /**
253
         * Output for checkbox to check if we automatically send new products to Algolia
254
         *
255
         * @return void
256
         */
257
        public static function algolia_woo_indexer_automatically_send_new_products_output()
258
        {
259
            /**
260
             * Sanitization is not really needed as the variable is not directly echoed
261
             * But I have still done it to be 100% safe
262
             */
263
            $auto_send = get_option(ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS);
264
            $auto_send = (!empty($auto_send)) ? 1 : 0; ?>
265
            <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); ?> />
266
        <?php
267
        }
268
269
        /**
270
         * Output for fields which data shall be sent to Algolia
271
         *
272
         * @return void
273
         */
274
        public static function algolia_woo_indexer_field_output($args)
275
        {
276
            $value = get_option(ALGOWOO_DB_OPTION . BASIC_FIELD_PREFIX . $args["name"]);
277
            $isChecked = (!empty($value)) ? 1 : 0;
278
        ?>
279
            <input id="<?php echo $args["label_for"] ?>" name="<?php echo $args["label_for"] ?>[checked]" type="checkbox" <?php checked(1, $isChecked); ?> />
280
        <?php
281
        }
282
283
        /**
284
         * Output for attributes if functionality is enabled
285
         *
286
         * @return void
287
         */
288
        public static function algolia_woo_indexer_attributes_enabled_output($args)
289
        {
290
            $value = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_ENABLED);
291
            $isChecked = (!empty($value)) ? 1 : 0;
292
        ?>
293
            <input id="algolia_woo_indexer_attributes_enabled" name="algolia_woo_indexer_attributes_enabled[checked]" type="checkbox" <?php checked(1, $isChecked); ?> />
294
            <?php
295
        }
296
297
        /**
298
         * Output for attributes how to handle visibility setting
299
         *
300
         * @return void
301
         */
302
        public static function algolia_woo_indexer_attributes_visibility_output($args)
303
        {
304
            $value = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_VISIBILITY);
305
            foreach (ATTRIBUTES_VISIBILITY_STATES as $state) {
306
                $id = 'algolia_woo_indexer_attributes_visibility_' . $state;
307
            ?>
308
                <p><input id="<?php echo $id; ?>" name="algolia_woo_indexer_attributes_visibility[value]" type="radio" value="<?php echo $state; ?>" <?php checked($state, $value); ?> /><label for="<?php echo $id; ?>"><?php echo esc_html__($state, 'algolia-woo-indexer'); ?></label></p>
309
            <?php
310
            }
311
        }
312
313
        /**
314
         * Output for attributes how to handle variant setting
315
         *
316
         * @return void
317
         */
318
        public static function algolia_woo_indexer_attributes_variation_output($args)
319
        {
320
            $value = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_VARIATION);
321
            foreach (ATTRIBUTES_VARIATION_STATES as $state) {
322
                $id = 'algolia_woo_indexer_attributes_variation_' . $state;
323
            ?>
324
                <p><input id="<?php echo $id; ?>" name="algolia_woo_indexer_attributes_variation[value]" type="radio" value="<?php echo $state; ?>" <?php checked($state, $value); ?> /><label for="<?php echo $id; ?>"><?php echo esc_html__($state, 'algolia-woo-indexer'); ?></label></p>
325
            <?php
326
            }
327
        }
328
329
        /**
330
         * Output for attributes list which attributes are whitelisted
331
         *
332
         * @return void
333
         */
334
        public static function algolia_woo_indexer_attributes_list_output($args)
335
        {
336
            $value = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_LIST);
337
            $selectedIds = explode(",", $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type false; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

337
            $selectedIds = explode(",", /** @scrutinizer ignore-type */ $value);
Loading history...
338
            $name = "algolia_woo_indexer_attributes_list[list]";
339
            $description = __('Here you can whitelist all the attributes. Use the <b>shift</b> or <b>control</b> buttons to select multiple attributes.', 'algolia-woo-indexer');
340
            self::generic_attributes_select_output($name, $selectedIds, $description);
341
        }
342
343
        /**
344
         * Output for attributes list which are using a numeric interpolation
345
         *
346
         * @return void
347
         */
348
        public static function algolia_woo_indexer_attributes_list_interpolate_output($args)
349
        {
350
            $value = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_LIST_INTERPOLATE);
351
            $selectedIds = explode(",", $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type false; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

351
            $selectedIds = explode(",", /** @scrutinizer ignore-type */ $value);
Loading history...
352
            $name = "algolia_woo_indexer_attributes_list_interpolate[list]";
353
            $description = __('If you have some attributes based on number which shall be interpolated between the lowest to the highest number, you can select it here. A common usecase for this is if you want to have a <b>range slider</b> in aloglia which works for a certain range. Example: a plant grows between 20 and 25cm tall. for this you enter 20 and 25 as attribute values to your product and it will automatically extend the data to [20,21,22,23,24,25]', 'algolia-woo-indexer');
354
            self::generic_attributes_select_output($name, $selectedIds, $description);
355
        }
356
357
        /**
358
         * Generic Output for attributes list where attributes are whitelisted
359
         *
360
         * @return void
361
         */
362
        public static function generic_attributes_select_output($name, $selectedIds, $description)
363
        {
364
            $attribute_taxonomies = wc_get_attribute_taxonomies();
0 ignored issues
show
Bug introduced by
The function wc_get_attribute_taxonomies was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

364
            $attribute_taxonomies = /** @scrutinizer ignore-call */ wc_get_attribute_taxonomies();
Loading history...
365
366
            if (!$attribute_taxonomies) {
367
                echo esc_html__('You don\'t have any attributes defined yet. Go to WooCommerce and add some to use this feature.', 'algolia-woo-indexer');
368
                return;
369
            }
370
            ?>
371
            <p><?php echo $description; ?></p>
372
            <select multiple="multiple" name="<?php echo $name; ?>[]" size="<?php echo count($attribute_taxonomies); ?>">
373
                <?php
374
                foreach ($attribute_taxonomies as $tax) {
375
376
                    $id = $tax->attribute_id;
377
                    $label = $tax->attribute_label;
378
                    $name = $tax->attribute_name;
379
                    $selected = in_array($id, $selectedIds) ? ' selected="selected" ' : '';
380
                ?>
381
                    <option value="<?php echo $id; ?>" <?php echo $selected; ?>>
382
                        <?php echo $label . ' (' . $name . ')'; ?>
383
                    </option>
384
                <?php
385
                }
386
                ?>
387
            </select>
388
        <?php
389
390
        }
391
392
        /**
393
         * Section text for plugin settings section text
394
         *
395
         * @return void
396
         */
397
        public static function algolia_woo_indexer_section_text()
398
        {
399
            echo esc_html__('Enter your API settings here.', 'algolia-woo-indexer');
400
        }
401
402
        /**
403
         * Section text for basic fields settings section text
404
         *
405
         * @return void
406
         */
407
        public static function algolia_woo_indexer_fields_section_text()
408
        {
409
            echo esc_html__('Choose which basic fields shall be indexed.', 'algolia-woo-indexer');
410
        }
411
412
        /**
413
         * Section text for attributes settings section text
414
         *
415
         * @return void
416
         */
417
        public static function algolia_woo_indexer_attributes_section_text()
418
        {
419
            echo esc_html__('Control if and how the attributes shall be indexed.', 'algolia-woo-indexer');
420
        }
421
422
        /**
423
         * Check if we are going to send products by verifying send products nonce
424
         *
425
         * @return void
426
         */
427
        public static function maybe_send_products()
428
        {
429
            if (true === Algolia_Verify_Nonces::verify_send_products_nonce()) {
430
                Algolia_Send_Products::send_products_to_algolia();
431
            }
432
        }
433
434
        /**
435
         * Initialize class, setup settings sections and fields
436
         *
437
         * @return void
438
         */
439
        public static function init()
440
        {
441
            /**
442
             * Fetch the option to see if we are going to automatically send new products
443
             */
444
            $auto_send = get_option(ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS);
445
446
            /**
447
             * Check that we have the minimum versions required and all of the required PHP extensions
448
             */
449
            Algolia_Check_Requirements::check_unmet_requirements();
450
451
            if (!Algolia_Check_Requirements::algolia_wp_version_check() || !Algolia_Check_Requirements::algolia_php_version_check()) {
452
                add_action(
453
                    'admin_notices',
454
                    function () {
455
                        echo '<div class="error notice">
456
                                  <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>
457
                                </div>';
458
                    }
459
                );
460
            }
461
462
            $ob_class = get_called_class();
463
464
            /**
465
             * Setup translations
466
             */
467
            add_action('plugins_loaded', array($ob_class, 'load_textdomain'));
468
469
            /**
470
             * Add actions to setup admin menu
471
             */
472
            if (is_admin()) {
473
                add_action('admin_menu', array($ob_class, 'admin_menu'));
474
                add_action('admin_init', array($ob_class, 'setup_settings_sections'));
475
                add_action('admin_init', array($ob_class, 'update_settings_options'));
476
                add_action('admin_init', array($ob_class, 'maybe_send_products'));
477
478
                /**
479
                 * Register hook to automatically send new products if the option is set
480
                 */
481
482
                if ('1' === $auto_send) {
483
                    add_action('save_post', array($ob_class, 'send_new_product_to_algolia'), 10, 3);
484
                }
485
486
                self::$plugin_url = admin_url('options-general.php?page=algolia-woo-indexer-settings');
487
488
                if (!is_plugin_active('woocommerce/woocommerce.php')) {
489
                    add_action(
490
                        'admin_notices',
491
                        function () {
492
                            echo '<div class="error notice">
493
								  <p>' . esc_html__('WooCommerce plugin must be enabled for Algolia Woo Indexer to work.', 'algolia-woo-indexer') . '</p>
494
								</div>';
495
                        }
496
                    );
497
                }
498
            }
499
        }
500
501
        /**
502
         * Send a single product to Algolia once a new product has been published
503
         *
504
         * @param int   $post_id ID of the product.
505
         * @param array $post Post array.
506
         *
507
         * @return void
508
         */
509
        public static function send_new_product_to_algolia($post_id, $post)
510
        {
511
            if ('publish' !== $post->post_status || 'product' !== $post->post_type) {
512
                return;
513
            }
514
            Algolia_Send_Products::send_products_to_algolia($post_id);
515
        }
516
517
        /**
518
         * Verify nonces before we update options and settings
519
         * Also retrieve the value from the send_products_to_algolia hidden field to check if we are sending products to Algolia
520
         *
521
         * @return void
522
         */
523
        public static function update_settings_options()
524
        {
525
            /**
526
             * Do not proceed if nonce for settings is not set
527
             */
528
            if (false === Algolia_Verify_Nonces::verify_settings_nonce()) {
529
                return;
530
            }
531
532
            /**
533
             * Do not proceed if we are going to send products
534
             */
535
            if (true === Algolia_Verify_Nonces::verify_send_products_nonce()) {
536
                return;
537
            }
538
539
            /**
540
             * Filter the application id, api key, index name and verify that the input is an array
541
             *
542
             * @see https://www.php.net/manual/en/function.filter-input.php
543
             */
544
            $post_application_id             = filter_input(INPUT_POST, 'algolia_woo_indexer_application_id', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
545
            $post_api_key                    = filter_input(INPUT_POST, 'algolia_woo_indexer_admin_api_key', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
546
            $post_index_name                 = filter_input(INPUT_POST, 'algolia_woo_indexer_index_name', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
547
            $auto_send                       = filter_input(INPUT_POST, 'algolia_woo_indexer_automatically_send_new_products', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
548
            $attributes_enabled              = filter_input(INPUT_POST, 'algolia_woo_indexer_attributes_enabled', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
549
            $attributes_visibility           = filter_input(INPUT_POST, 'algolia_woo_indexer_attributes_visibility', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
550
            $attributes_variation            = filter_input(INPUT_POST, 'algolia_woo_indexer_attributes_variation', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
551
            $attributes_list                 = filter_input(INPUT_POST, 'algolia_woo_indexer_attributes_list', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
552
            $attributes_list_interpolate     = filter_input(INPUT_POST, 'algolia_woo_indexer_attributes_list_interpolate', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
553
554
            /**
555
             * Properly sanitize text fields before updating data
556
             *
557
             * @see https://developer.wordpress.org/reference/functions/sanitize_text_field/
558
             */
559
            $filtered_app_id         = sanitize_text_field($post_application_id['id']);
560
            $filtered_api_key        = sanitize_text_field($post_api_key['key']);
561
            $filtered_index_name     = sanitize_text_field($post_index_name['name']);
562
            $filtered_attributes_visibility     = sanitize_text_field($attributes_visibility['value']);
563
            $filtered_attributes_variation     = sanitize_text_field($attributes_variation['value']);
564
565
            /**
566
             * sanitize select list of id's by getting integers and them implode seperated with comma
567
             */
568
569
            $attributes_list_integers = [];
570
            foreach ($attributes_list['list'] as $id) {
571
                array_push($attributes_list_integers, (int) $id);
572
            }
573
            $filtered_attributes_list = implode(',', $attributes_list_integers);
574
            $attributes_list_interpolate_integers = [];
575
            foreach ($attributes_list_interpolate['list'] as $id) {
576
                array_push($attributes_list_interpolate_integers, (int) $id);
577
            }
578
            $filtered_attributes_list_interpolate = implode(',', $attributes_list_interpolate_integers);
579
580
            /**
581
             * Sanitizing by setting the value to either 1 or 0
582
             */
583
            $filtered_product = (!empty($auto_send)) ? 1 : 0;
584
            $filtered_attributes_enabled = (!empty($attributes_enabled)) ? 1 : 0;
585
586
            /**
587
             * Filter the data fields checkboxes and verify that the input is an array and assign it to an associative array
588
             *
589
             * @see https://www.php.net/manual/en/function.filter-input.php
590
             */
591
            $filtered_fields = array();
592
            foreach (BASIC_FIELDS as $field) {
593
                $raw_field = filter_input(INPUT_POST, 'algolia_woo_indexer_field_' . $field, FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
594
                $filtered_field = (!empty($raw_field)) ? 1 : 0;
595
                $filtered_fields[$field] = $filtered_field;
596
            }
597
598
            /**
599
             * Values have been filtered and sanitized
600
             * Check if set and not empty and update the database
601
             *
602
             * @see https://developer.wordpress.org/reference/functions/update_option/
603
             */
604
            if (isset($filtered_app_id) && (!empty($filtered_app_id))) {
605
                update_option(
606
                    ALGOWOO_DB_OPTION . ALGOLIA_APP_ID,
607
                    $filtered_app_id
608
                );
609
            }
610
611
            if (isset($filtered_api_key) && (!empty($filtered_api_key))) {
612
                update_option(
613
                    ALGOWOO_DB_OPTION . ALGOLIA_API_KEY,
614
                    $filtered_api_key
615
                );
616
            }
617
618
            if (isset($filtered_index_name) && (!empty($filtered_index_name))) {
619
                update_option(
620
                    ALGOWOO_DB_OPTION . INDEX_NAME,
621
                    $filtered_index_name
622
                );
623
            }
624
625
            if (isset($filtered_product)) {
626
                update_option(
627
                    ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS,
628
                    $filtered_product
629
                );
630
            }
631
632
            if (isset($filtered_attributes_enabled)) {
633
                update_option(
634
                    ALGOWOO_DB_OPTION . ATTRIBUTES_ENABLED,
635
                    $filtered_attributes_enabled
636
                );
637
            }
638
639
            if (isset($filtered_attributes_visibility) && (!empty($filtered_attributes_visibility))) {
640
                update_option(
641
                    ALGOWOO_DB_OPTION . ATTRIBUTES_VISIBILITY,
642
                    $filtered_attributes_visibility
643
                );
644
            }
645
646
            if (isset($filtered_attributes_variation) && (!empty($filtered_attributes_variation))) {
647
                update_option(
648
                    ALGOWOO_DB_OPTION . ATTRIBUTES_VARIATION,
649
                    $filtered_attributes_variation
650
                );
651
            }
652
653
            if (isset($filtered_attributes_list) && (!empty($filtered_attributes_list))) {
654
                update_option(
655
                    ALGOWOO_DB_OPTION . ATTRIBUTES_LIST,
656
                    $filtered_attributes_list
657
                );
658
            }
659
660
            if (isset($filtered_attributes_list_interpolate) && (!empty($filtered_attributes_list_interpolate))) {
661
                update_option(
662
                    ALGOWOO_DB_OPTION . ATTRIBUTES_LIST_INTERPOLATE,
663
                    $filtered_attributes_list_interpolate
664
                );
665
            }
666
667
            if (isset($filtered_fields) && (!empty($filtered_fields))) {
668
                foreach ($filtered_fields as $key => $value) {
669
                    update_option(
670
                        ALGOWOO_DB_OPTION . BASIC_FIELD_PREFIX . $key,
671
                        $value
672
                    );
673
                }
674
            }
675
        }
676
677
        /**
678
         * Sanitize input in settings fields and filter through regex to accept only a-z and A-Z
679
         *
680
         * @param string $input Settings text data
681
         * @return array
682
         */
683
        public static function settings_fields_validate_options($input)
684
        {
685
            $valid         = array();
686
            $valid['name'] = preg_replace(
687
                '/[^a-zA-Z\s]/',
688
                '',
689
                $input['name']
690
            );
691
            return $valid;
692
        }
693
694
        /**
695
         * Load text domain for translations
696
         *
697
         * @return void
698
         */
699
        public static function load_textdomain()
700
        {
701
            load_plugin_textdomain('algolia-woo-indexer', false, basename(dirname(__FILE__)) . '/languages/');
702
        }
703
704
        /**
705
         * Add the new menu to settings section so that we can configure the plugin
706
         *
707
         * @return void
708
         */
709
        public static function admin_menu()
710
        {
711
            add_submenu_page(
712
                'options-general.php',
713
                esc_html__('Algolia Woo Indexer Settings', 'algolia-woo-indexer'),
714
                esc_html__('Algolia Woo Indexer Settings', 'algolia-woo-indexer'),
715
                'manage_options',
716
                'algolia-woo-indexer-settings',
717
                array(get_called_class(), 'algolia_woo_indexer_settings')
718
            );
719
        }
720
721
        /**
722
         * Display settings and allow user to modify them
723
         *
724
         * @return void
725
         */
726
        public static function algolia_woo_indexer_settings()
727
        {
728
            /**
729
             * Verify that the user can access the settings page
730
             */
731
            if (!current_user_can('manage_options')) {
732
                wp_die(esc_html__('Action not allowed.', 'algolia_woo_indexer_settings'));
733
            } ?>
734
            <div class="wrap">
735
                <h1><?php esc_html__('Algolia Woo Indexer Settings', 'algolia-woo-indexer'); ?></h1>
736
                <form action="<?php echo esc_url(self::$plugin_url); ?>" method="POST">
737
                    <?php
738
                    settings_fields('algolia_woo_options');
739
                    do_settings_sections('algolia_woo_indexer');
740
                    submit_button('', 'primary wide'); ?>
741
                </form>
742
                <form action="<?php echo esc_url(self::$plugin_url); ?>" method="POST">
743
                    <?php wp_nonce_field('send_products_to_algolia_nonce_action', 'send_products_to_algolia_nonce_name'); ?>
744
                    <input type="hidden" name="send_products_to_algolia" id="send_products_to_algolia" value="true" />
745
                    <?php submit_button(esc_html__('Send products to Algolia', 'algolia_woo_indexer_settings'), 'primary wide', '', false); ?>
746
                </form>
747
            </div>
748
<?php
749
        }
750
751
        /**
752
         * Get active object instance
753
         *
754
         * @return object
755
         */
756
        public static function get_instance()
757
        {
758
            if (!self::$instance) {
759
                self::$instance = new Algolia_Woo_Indexer();
760
            }
761
            return self::$instance;
762
        }
763
764
        /**
765
         * The actions to execute when the plugin is activated.
766
         *
767
         * @return void
768
         */
769
        public static function activate_plugin()
770
        {
771
772
            /**
773
             * Set default values for options if not already set
774
             */
775
            $auto_send = get_option(ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS);
776
            $algolia_application_id          = get_option(ALGOWOO_DB_OPTION . ALGOLIA_APP_ID);
777
            $algolia_api_key                 = get_option(ALGOWOO_DB_OPTION . ALGOLIA_API_KEY);
778
            $algolia_index_name              = get_option(ALGOWOO_DB_OPTION . INDEX_NAME);
779
            $attributes_enabled              = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_ENABLED);
780
            $attributes_visibility           = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_VISIBILITY);
781
            $attributes_variation            = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_VARIATION);
782
            $attributes_list                 = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_LIST);
783
            $attributes_list_interpolate     = get_option(ALGOWOO_DB_OPTION . ATTRIBUTES_LIST_INTERPOLATE);
784
785
            if (empty($auto_send)) {
786
                add_option(
787
                    ALGOWOO_DB_OPTION . AUTOMATICALLY_SEND_NEW_PRODUCTS,
788
                    '0'
789
                );
790
            }
791
792
            if (empty($algolia_application_id)) {
793
                add_option(
794
                    ALGOWOO_DB_OPTION . ALGOLIA_APP_ID,
795
                    'Change me'
796
                );
797
            }
798
799
            if (empty($algolia_api_key)) {
800
                add_option(
801
                    ALGOWOO_DB_OPTION . ALGOLIA_API_KEY,
802
                    'Change me'
803
                );
804
            }
805
806
            if (empty($algolia_index_name)) {
807
                add_option(
808
                    ALGOWOO_DB_OPTION . INDEX_NAME,
809
                    'Change me'
810
                );
811
            }
812
813
            if (empty($attributes_enabled)) {
814
                add_option(
815
                    ALGOWOO_DB_OPTION . ATTRIBUTES_ENABLED,
816
                    0
817
                );
818
            }
819
820
            if (empty($attributes_visibility)) {
821
                add_option(
822
                    ALGOWOO_DB_OPTION . ATTRIBUTES_VISIBILITY,
823
                    ATTRIBUTES_VISIBILITY_STATES[1]
824
                );
825
            }
826
            if (empty($attributes_variation)) {
827
                add_option(
828
                    ALGOWOO_DB_OPTION . ATTRIBUTES_VARIATION,
829
                    ATTRIBUTES_VARIATION_STATES[0]
830
                );
831
            }
832
            if (empty($attributes_list)) {
833
                add_option(
834
                    ALGOWOO_DB_OPTION . ATTRIBUTES_LIST,
835
                    ''
836
                );
837
            }
838
            if (empty($attributes_list_interpolate)) {
839
                add_option(
840
                    ALGOWOO_DB_OPTION . ATTRIBUTES_LIST_INTERPOLATE,
841
                    ''
842
                );
843
            }
844
845
            /**
846
             * Set default values for index fields if not already set
847
             */
848
            foreach (BASIC_FIELDS as $field) {
849
                $value = get_option(ALGOWOO_DB_OPTION . BASIC_FIELD_PREFIX . $field);
850
                if (empty($value)) {
851
                    update_option(
852
                        ALGOWOO_DB_OPTION . BASIC_FIELD_PREFIX . $field,
853
                        '1'
854
                    );
855
                }
856
            }
857
858
859
860
            set_transient(self::PLUGIN_TRANSIENT, true);
861
        }
862
863
        /**
864
         * The actions to execute when the plugin is deactivated.
865
         *
866
         * @return void
867
         */
868
        public static function deactivate_plugin()
869
        {
870
            delete_transient(self::PLUGIN_TRANSIENT);
871
        }
872
    }
873
}
874