PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.9.1
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.9.1
3.0.3 3.0.2 3.0.1 trunk 2.2.14 2.2.15 2.2.16 2.2.17 2.2.18 2.2.19 2.3.0 2.3.1 2.3.10 2.3.11 2.3.12 2.3.13 2.3.14 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.8 2.3.9 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.7.91 2.7.92 2.7.93 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0
commercebird / includes / classes / class-plugin.php
commercebird / includes / classes Last commit date
apis 1 month ago purchase-orders 1 month ago quotes 1 month ago zoho-crm 6 months ago zoho-inventory 1 month ago class-api-handler-zoho.php 1 month ago class-auth-zoho.php 3 months ago class-common.php 1 month ago class-mcp.php 2 months ago class-plugin.php 1 month ago class-wc-api.php 5 months ago index.php 1 year ago
class-plugin.php
324 lines
1 <?php
2
3 namespace CommerceBird;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
10
11 use CommerceBird\Admin\Actions\Ajax\ExactOnlineAjax;
12 use CommerceBird\Admin\Actions\Ajax\ZohoInventoryAjax;
13 use CommerceBird\Admin\Actions\Ajax\ZohoCRMAjax;
14 use CommerceBird\Admin\Actions\Ajax\AcfAjax;
15 use CommerceBird\Admin\Actions\Ajax\SettingsAjax;
16 use CommerceBird\Admin\Template;
17 use CommerceBird\Admin\Cmbird_Acf;
18 use CommerceBird\Cmbird_WC_API;
19 use CMBIRD_Purchase_Orders_Automation;
20
21 /**
22 * Main plugin class for CommerceBird.
23 *
24 * Handles activation, deactivation, uninstall, and initialization logic.
25 *
26 * @since 1.0.0
27 */
28 class Plugin {
29
30
31 /**
32 * The constructor for the plugin.
33 *
34 * @since 1.0.0
35 *
36 * This function is called when the plugin is loaded. It hooks the init method to the admin_init action.
37 */
38 public function __construct() {
39 add_action( 'admin_init', array( $this, 'init' ) );
40 }
41
42 /**
43 * Plugin activation handler.
44 *
45 * - Installs the MU CLI helper.
46 * - Ensures the "vendor" role exists.
47 * - Creates {$wpdb->prefix}cmbird_zi_category_map via dbDelta (idempotent).
48 *
49 * @since 1.0.0
50 */
51 public static function activate() {
52 // Copy CLI script to mu-plugins folder for automatic loading.
53 self::install_mu_plugin();
54 // Create the "vendor" role — must run at activation, not on every init.
55 if ( ! get_role( 'vendor' ) ) {
56 add_role(
57 'vendor',
58 __( 'Vendor', 'commercebird' ),
59 array( 'read' => true )
60 );
61 }
62
63 global $wpdb;
64 $charset_collate = $wpdb->get_charset_collate();
65 $table = $wpdb->prefix . 'cmbird_zi_category_map';
66 $sql = "CREATE TABLE {$table} (
67 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
68 wc_term_id BIGINT UNSIGNED NOT NULL,
69 zoho_category_id VARCHAR(64) NOT NULL,
70 source ENUM('auto','manual') NOT NULL DEFAULT 'auto',
71 status ENUM('active','orphan','review') NOT NULL DEFAULT 'active',
72 review_reason VARCHAR(64) NULL,
73 created_at DATETIME NOT NULL,
74 updated_at DATETIME NOT NULL,
75 last_verified_at DATETIME NULL,
76 PRIMARY KEY (id),
77 UNIQUE KEY uniq_wc_term_active (wc_term_id, status),
78 UNIQUE KEY uniq_zoho_id_active (zoho_category_id, status),
79 KEY status_idx (status)
80 ) $charset_collate;";
81 dbDelta( $sql );
82 }
83
84 /**
85 * Copy the CLI script to mu-plugins folder.
86 *
87 * @since 2.6.5
88 */
89 private static function install_mu_plugin() {
90 $mu_plugins_dir = WP_CONTENT_DIR . '/mu-plugins';
91 $source_file = CMBIRD_PATH . 'mu-plugins/cmbird-media-cleanup-cli.php';
92 $dest_file = $mu_plugins_dir . '/cmbird-media-cleanup-cli.php';
93
94 // Create mu-plugins directory if it doesn't exist.
95 if ( ! is_dir( $mu_plugins_dir ) ) {
96 wp_mkdir_p( $mu_plugins_dir );
97 }
98
99 // Copy the file if source exists and destination doesn't or is outdated.
100 if ( file_exists( $source_file ) ) {
101 if ( ! file_exists( $dest_file ) || filemtime( $source_file ) > filemtime( $dest_file ) ) {
102 copy( $source_file, $dest_file );
103 }
104 }
105 }
106
107 /**
108 * Clear all the scheduled actions when the plugin is deactivated.
109 *
110 * @since 1.0.0
111 */
112 public static function deactivate() {
113 wp_clear_scheduled_hook( 'zi_execute_import_sync' );
114 wp_clear_scheduled_hook( 'cmbird_eo_get_payment_statuses' );
115 wp_clear_scheduled_hook( 'cmbird_exact_online_sync_orders' );
116 wp_clear_scheduled_hook( 'cmbird_eo_product_mapping_daily' );
117 wp_clear_scheduled_hook( 'cmbird_zoho_sync_category_cron' );
118 wp_clear_scheduled_hook( 'cmbird_zoho_contact_sync' );
119 }
120
121 /**
122 * Deletes all the options and post/user meta set by the plugin.
123 *
124 * This function is called when the plugin is uninstalled.
125 *
126 * @since 1.0.0
127 */
128 public static function uninstall() {
129 $post_meta_keys = array(
130 'zi_item_id',
131 'zi_purchase_account_id',
132 'zi_account_id',
133 'zi_account_name',
134 'zi_inventory_account_id',
135 'zi_salesorder_id',
136 'zi_category_id',
137 '_cost_price',
138 'eo_item_id',
139 );
140 $user_meta_keys = array(
141 'zi_contact_id',
142 'zi_primary_contact_id',
143 'zi_created_time',
144 'zi_last_modified_time',
145 'zi_billing_address_id',
146 'zi_shipping_address_id',
147 'zi_contact_persons_id',
148 'zi_currency_id',
149 'zi_currency_code',
150 'eo_contact_id',
151 'eo_account_id',
152 'eo_gl_account',
153 );
154 $zi_option_keys = array(
155 'cmbird_zi_webhook_password',
156 'cmbird_zoho_inventory_cron_class',
157 'cmbird_zoho_sync_status',
158 'cmbird_zoho_item_category',
159 'cmbird_zoho_stock_sync_status',
160 'cmbird_zoho_item_name_sync_status',
161 'cmbird_zoho_enable_auto_no_status',
162 'cmbird_zoho_product_sync_status',
163 'cmbird_zoho_disable_image_sync_status',
164 'cmbird_zoho_disable_price_sync_status',
165 'cmbird_zoho_disable_name_sync_status',
166 'cmbird_zoho_disable_description_sync_status',
167 'cmbird_zoho_enable_accounting_stock_status',
168 'cmbird_zoho_enable_order_status',
169 'cmbird_wootozoho_custom_fields',
170 'cmbird_zoho_pricelist_id',
171 'cmbird_zoho_location_id_status',
172 'cmbird_zoho_inventory_auth_code',
173 'cmbird_zoho_inventory_access_token',
174 'cmbird_zoho_inventory_refresh_token',
175 'cmbird_zoho_inventory_timestamp',
176 'cmbird_zoho_inventory_oid',
177 'cmbird_zoho_inventory_url',
178 'cmbird_zoho_inventory_cid',
179 'cmbird_zoho_inventory_cs',
180 'cmbird_zoho_inventory_domain',
181 'cmbird_authorization_redirect_uri',
182 'cmbird_zoho_crm_auth_code',
183 'cmbird_zoho_crm_access_token',
184 'cmbird_zoho_crm_refresh_token',
185 'cmbird_zoho_crm_timestamp',
186 'cmbird_location_data',
187 'cmbird_eo_product_cron_enabled',
188 );
189
190 foreach ( $zi_option_keys as $zi_option ) {
191 delete_option( $zi_option );
192 }
193
194 foreach ( $post_meta_keys as $post_key ) {
195 delete_post_meta_by_key( $post_key );
196 }
197
198 $users = get_users(
199 array(
200 'fields' => array( 'ID' ),
201 )
202 );
203 foreach ( $users as $user_id ) {
204 foreach ( $user_meta_keys as $user_key ) {
205 delete_user_meta( $user_id, $user_key );
206 }
207 }
208 // Drop the category mapping table.
209 global $wpdb;
210 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}cmbird_zi_category_map" ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
211
212 // Clean up any legacy mapping options (covers installs that never ran the migration).
213 $wpdb->query(
214 "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'cmbird_zoho_id_for_term_id_%'" // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
215 );
216
217 // And the migration flags.
218 delete_option( 'cmbird_zi_category_map_migrated' );
219 delete_option( 'cmbird_zi_category_map_legacy_purged' );
220 // clear scheduled zcrm_refresh_token.
221 wp_clear_scheduled_hook( 'zcrm_refresh_token' );
222
223 // Remove the mu-plugin file.
224 $mu_plugin_file = WP_CONTENT_DIR . '/mu-plugins/cmbird-media-cleanup-cli.php';
225 if ( file_exists( $mu_plugin_file ) ) {
226 wp_delete_file( $mu_plugin_file );
227 }
228 }
229
230 /**
231 * Initializes the plugin.
232 *
233 * Removes the option for Zoho Inventory access token if it contains only one character.
234 * Schedules a cronjob for import sync if the access token is not empty and the interval is not set to 'none'.
235 * Creates the webhook password if it does not exist.
236 * Loads the necessary Ajax handlers and templates.
237 *
238 * @since 1.0.0
239 */
240 public static function init() {
241 if ( is_admin() ) {
242 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
243 // remove option zoho_inventory_access_token if it contains only one character.
244 if ( $zoho_inventory_access_token && strlen( $zoho_inventory_access_token ) === 1 ) {
245 delete_option( 'cmbird_zoho_inventory_access_token' );
246 } else {
247 // schedule cronjob for import sync.
248 $interval = get_option( 'zi_cron_interval' );
249 if ( 'none' !== $interval && ! empty( $zoho_inventory_access_token ) ) {
250 if ( ! wp_next_scheduled( 'zi_execute_import_sync' ) ) {
251 wp_schedule_event( time(), $interval, 'zi_execute_import_sync' );
252 }
253 } else {
254 wp_clear_scheduled_hook( 'zi_execute_import_sync' );
255 }
256 }
257 // create webhook password if does not exists.
258 if ( ! get_option( 'cmbird_zi_webhook_password', false ) ) {
259 add_option( 'cmbird_zi_webhook_password', password_hash( 'commercebird-zi-webhook-token', PASSWORD_BCRYPT ) );
260 }
261 Template::instance();
262 // Load the necessary Ajax handlers and templates.
263 ZohoInventoryAjax::instance();
264 ZohoCRMAjax::instance();
265 AcfAjax::instance();
266 SettingsAjax::instance();
267 ExactOnlineAjax::instance();
268 if ( class_exists( 'ACF' ) ) {
269 Cmbird_Acf::instance();
270 }
271 }
272 new Cmbird_WC_API();
273 new CMBIRD_Purchase_Orders_Automation();
274 }
275
276 /**
277 * Cron callback for zoho import sync interval.
278 *
279 * When the WP cron fires this hook we simply forward the request to the
280 * existing `import_simple_items_cron` action. That action is already
281 * registered in the main plugin bootstrapping script and handles batch
282 * scheduling via Action Scheduler. Passing along the arguments allows for
283 * backwards compatibility if anybody ever runs the hook manually with
284 * parameters.
285 *
286 * @since 2.7.7
287 * @param mixed ...$args Optional arguments supplied by do_action.
288 * @return void
289 */
290 public static function dispatch_import_simple_items( ...$args ) {
291 // if the event was fired with explicit arguments we simply forward them.
292 // to the existing hook (primarily useful for manual/testing purposes).
293 if ( ! empty( $args ) ) {
294 do_action( 'import_simple_items_cron', ...$args );
295 return;
296 }
297 $zi_common_class = new \CMBIRD_Common_Functions();
298 $zi_common_class->clear_orphan_data();
299
300 // categories are stored as serialized zoho ids; convert them to WC terms.
301 $zoho_item_category = get_option( 'cmbird_zoho_item_category' );
302 if ( $zoho_item_category ) {
303 // convert serialized string to array.
304 $categories = maybe_unserialize( $zoho_item_category );
305 if ( ! is_array( $categories ) ) {
306 return; // invalid format -> nothing to do.
307 }
308 } else {
309 return; // no categories configured -> nothing to do.
310 }
311 foreach ( $categories as $category_id ) {
312 $data = array(
313 'page' => 1,
314 'category' => $category_id,
315 );
316 if ( function_exists( 'as_has_scheduled_action' )
317 && ! as_has_scheduled_action( 'import_simple_items_cron', $data, 'commercebird' )
318 ) {
319 as_schedule_single_action( time(), 'import_simple_items_cron', $data, 'commercebird' );
320 }
321 }
322 }
323 }
324