Passed
Push — master ( 6d02eb...4a4aa8 )
by Daniel
02:05 queued 11s
created

Algolia_Send_Products   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 56
c 2
b 0
f 0
dl 0
loc 152
rs 10
wmc 11

2 Methods

Rating   Name   Duplication   Size   Complexity  
B send_products_to_algolia() 0 114 9
A can_connect_to_algolia() 0 14 2
1
<?php
2
/**
3
 * Algolia Woo Indexer class for sending products
4
 * Called from main plugin file algolia-woo-indexer.php
5
 *
6
 * @package algolia-woo-indexer
7
 */
8
9
namespace Algowoo;
10
11
use \Algowoo\Algolia_Check_Requirements as Algolia_Check_Requirements;
12
13
/**
14
 * Abort if this file is called directly
15
 */
16
if ( ! defined( 'ABSPATH' ) ) {
17
	exit;
18
}
19
20
/**
21
 * Include plugin file if function is_plugin_active does not exist
22
 */
23
if (! function_exists('is_plugin_active')) {
24
    require_once(ABSPATH . '/wp-admin/includes/plugin.php');
25
}
26
27
/**
28
 * Define the plugin version and the database table name
29
 */
30
define( 'ALGOWOO_DB_OPTION', '_algolia_woo_indexer' );
31
define( 'ALGOWOO_CURRENT_DB_VERSION', '0.3' );
32
33
/**
34
 * Define application constants
35
 */
36
define( 'CHANGE_ME', 'change me' );
37
38
/**
39
 * Database table names
40
 */
41
define('INDEX_NAME', '_index_name');
42
define('AUTOMATICALLY_SEND_NEW_PRODUCTS', '_automatically_send_new_products');
43
define('ALGOLIA_APPLICATION_ID', '_application_id');
44
define('ALGOLIA_API_KEY', '_admin_api_key');
45
46
if (! class_exists('Algolia_Send_Products')) {
47
    /**
48
     * Algolia WooIndexer main class
49
     */
50
    class Algolia_Send_Products
51
    {
52
        const PLUGIN_NAME      = 'Algolia Woo Indexer';
53
        const PLUGIN_TRANSIENT = 'algowoo-plugin-notice';
54
55
        /**
56
         * The Algolia instance
57
         *
58
         * @var \Algolia\AlgoliaSearch\SearchClient
59
         */
60
        private static $algolia = null;
61
62
        /**
63
         * Check if we can connect to Algolia, if not, handle the exception, display an error and then return
64
         */
65
        public static function can_connect_to_algolia()
66
        {
67
            try {
68
                self::$algolia->listApiKeys();
69
            } catch (\Algolia\AlgoliaSearch\Exceptions\UnreachableException $error) {
70
                add_action(
71
                    'admin_notices',
72
                    function () {
73
                        echo '<div class="error notice">
74
							  <p>' . esc_html__('An error has been encountered. Please check your application ID and API key. ', 'algolia-woo-indexer') . '</p>
75
							</div>';
76
                    }
77
                );
78
                return;
79
            }
80
        }
81
82
        /**
83
        * Send WooCommerce products to Algolia
84
        *
85
        * @param Int $id Product to send to Algolia if we send only a single product
86
        * @return void
87
        */
88
        public static function send_products_to_algolia($id = '')
89
        {
90
            /**
91
             * Remove classes from plugin URL and autoload Algolia with Composer
92
             */
93
94
            $base_plugin_directory = str_replace('classes', '', dirname(__FILE__));
95
            require_once $base_plugin_directory . '/vendor/autoload.php';
96
97
            /**
98
             * Fetch the required variables from the Settings API
99
             */
100
101
            $algolia_application_id = get_option(ALGOWOO_DB_OPTION . ALGOLIA_APPLICATION_ID);
102
            $algolia_application_id = is_string($algolia_application_id) ? $algolia_application_id : CHANGE_ME;
103
104
            $algolia_api_key        = get_option(ALGOWOO_DB_OPTION . ALGOLIA_API_KEY);
105
            $algolia_api_key		= is_string($algolia_api_key) ?$algolia_api_key : CHANGE_ME;
106
107
            $algolia_index_name     = get_option(ALGOWOO_DB_OPTION . INDEX_NAME);
108
            $algolia_index_name		= is_string($algolia_index_name) ? $algolia_index_name : CHANGE_ME;
109
110
            /**
111
             * Display admin notice and return if not all values have been set
112
             */
113
114
            Algolia_Check_Requirements::check_algolia_input_values($algolia_application_id, $algolia_api_key, $algolia_index_name);
115
116
            /**
117
             * Initiate the Algolia client
118
             */
119
            self::$algolia = \Algolia\AlgoliaSearch\SearchClient::create($algolia_application_id, $algolia_api_key);
120
121
            /**
122
             * Check if we can connect, if not, handle the exception, display an error and then return
123
             */
124
            self::can_connect_to_algolia();
125
            
126
            /**
127
             * Initialize the search index and set the name to the option from the database
128
             */
129
            $index = self::$algolia->initIndex($algolia_index_name);
130
131
            /**
132
             * Setup arguments for sending all products to Algolia
133
             *
134
             * Limit => -1 means we send all products
135
             */
136
            $arguments = array(
137
                'status'   => 'publish',
138
                'limit'    => -1,
139
                'paginate' => false,
140
            );
141
142
            /**
143
            * Setup arguments for sending only a single product
144
            */
145
            if (isset($id) && '' !== $id) {
146
                $arguments = array(
147
                    'status'   => 'publish',
148
                    'include'  => array( $id ),
149
                    'paginate' => false,
150
                );
151
            }
152
153
            /**
154
             * Fetch all products from WooCommerce
155
             *
156
             * @see https://docs.woocommerce.com/wc-apidocs/function-wc_get_products.html
157
             */
158
            $products = /** @scrutinizer ignore-call */ wc_get_products($arguments);
159
160
            if (empty($products)) {
161
                return;
162
            }
163
            $records = array();
164
            $record  = array();
165
166
            foreach ($products as $product) {
167
                /**
168
                 * Extract image from $product->get_image()
169
                 */
170
                preg_match('/<img(.*)src(.*)=(.*)"(.*)"/U', $product->get_image(), $result);
171
                $product_image = array_pop($result);
172
                /**
173
                 * Build the record array using the information from the WooCommerce product
174
                 */
175
                $record['objectID']          = $product->get_id();
176
                $record['product_name']      = $product->get_name();
177
                $record['product_image']     = $product_image;
178
                $record['short_description'] = $product->get_short_description();
179
                $record['regular_price']     = $product->get_regular_price();
180
                $record['sale_price']        = $product->get_sale_price();
181
                $record['on_sale']           = $product->is_on_sale();
182
183
                $records[] = $record;
184
            }
185
            wp_reset_postdata();
186
187
            /**
188
             * Send the information to Algolia and save the result
189
             * If result is NullResponse, print an error message
190
             */
191
            $result = $index->saveObjects($records);
192
193
            if ('Algolia\AlgoliaSearch\Response\NullResponse' === get_class($result)) {
194
                wp_die(esc_html__('No response from the server. Please check your settings and try again', 'algolia_woo_indexer_settings'));
195
            }
196
197
            /**
198
             * Display success message
199
             */
200
            echo '<div class="notice notice-success is-dismissible">
201
					 	<p>' . esc_html__('Product(s) sent to Algolia.', 'algolia-woo-indexer') . '</p>
202
				  		</div>';
203
        }
204
    }
205
}