PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 3.0.2
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v3.0.2
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 / commercebird.php
commercebird Last commit date
admin 2 weeks ago includes 2 weeks ago languages 1 year ago mu-plugins 5 months ago templates 2 months ago vendor 2 weeks ago LICENSE 1 year ago commercebird.php 2 weeks ago composer.json 3 weeks ago index.php 1 year ago readme.txt 2 weeks ago wp-dependencies.json 1 month ago
commercebird.php
337 lines
1 <?php
2 /**
3 * Plugin Name: CommerceBird
4 * Plugin URI: https://commercebird.com
5 * Author: CommerceBird
6 * Description: This plugin helps you get the most of CommerceBird AI App and use integrations like Zoho Inventory, Zoho CRM, Exact Online and more. Requires a subscription at CommerceBird.com.
7 * Version: 3.0.2
8 * Requires PHP: 8.2
9 * Requires Plugins: woocommerce
10 * Requires at least: 7.0
11 * Tested up to: 7.0
12 * Text Domain: commercebird
13 * Domain Path: /languages
14 *
15 * License: GNU General Public License v3.0
16 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
17 *
18 * @category Fulfillment
19 * @package CommerceBird
20 * @author Fawad Tiemoerie <info@commercebird.com>
21 * @copyright Copyright (c) 2026, CommerceBird
22 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL-3.0-or-later
23 *
24 * WC requires at least: 10.6.0
25 * WC tested up to: 10.8.0
26 */
27
28 if ( ! defined( 'ABSPATH' ) ) {
29 exit; // Exit if accessed directly.
30 }
31
32 if ( ! defined( 'CMBIRD_VERSION' ) ) {
33 define( 'CMBIRD_VERSION', '3.0.2' );
34 }
35 if ( ! defined( 'CMBIRD_ZI_CATEGORY_MAP_LEGACY_FALLBACK' ) ) {
36 define( 'CMBIRD_ZI_CATEGORY_MAP_LEGACY_FALLBACK', true );
37 }
38 if ( ! defined( 'CMBIRD_PATH' ) ) {
39 define( 'CMBIRD_PATH', plugin_dir_path( __FILE__ ) );
40 }
41 if ( ! defined( 'CMBIRD_URL' ) ) {
42 define( 'CMBIRD_URL', plugin_dir_url( __FILE__ ) );
43 }
44 if ( ! defined( 'CMBIRD_MENU_SLUG' ) ) {
45 define( 'CMBIRD_MENU_SLUG', 'commercebird-app' );
46 }
47
48 require_once CMBIRD_PATH . 'includes/woo-functions.php';
49 require_once CMBIRD_PATH . 'includes/sync/order-backend.php';
50
51 // Load the Jetpack autoloader instead of vendor/autoload.php.
52 require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload_packages.php';
53
54 use Automattic\WooCommerce\Utilities\FeaturesUtil;
55 use WP\MCP\Core\McpAdapter;
56 use CommerceBird\Admin\Actions\Sync\ExactOnlineSync;
57 use CommerceBird\Admin\Actions\Ajax\ExactOnlineAjax;
58 use CommerceBird\Admin\Actions\Sync\ZohoCRMSync;
59 use CommerceBird\API\CMBird_APIs;
60 use CommerceBird\API\CreateOrderWebhook;
61 use CommerceBird\API\Exact;
62 use CommerceBird\API\ProductWebhook;
63 use CommerceBird\API\ShippingWebhook;
64 use CommerceBird\API\Zoho;
65 use CommerceBird\CMBIRD_MCP;
66 use CommerceBird\Plugin;
67
68 /*
69 |--------------------------------------------------------------------------
70 | Activation, deactivation and uninstall event.
71 |--------------------------------------------------------------------------
72 */
73
74 register_activation_hook( __FILE__, array( Plugin::class, 'activate' ) );
75 register_deactivation_hook( __FILE__, array( Plugin::class, 'deactivate' ) );
76 register_uninstall_hook( __FILE__, array( Plugin::class, 'uninstall' ) );
77
78 /*
79 |--------------------------------------------------------------------------
80 | Load the plugin translations
81 |--------------------------------------------------------------------------
82 | Note: WordPress.org automatically loads translations for plugins since WP 4.6.
83 | Manual loading not required for plugins hosted on WordPress.org.
84 */
85
86 /** Loading Purchase Order Class
87 *
88 * @since 1.0.0
89 */
90 function cmbird_purchase_order_class() {
91 if ( class_exists( 'WooCommerce' ) ) {
92 new CMBIRD_Purchase_Order();
93 }
94 }
95 add_action( 'woocommerce_init', 'cmbird_purchase_order_class' );
96 add_action( 'init', array( CMBIRD_PO_Admin_Manager::class, 'init' ), 11 );
97
98 /*
99 |--------------------------------------------------------------------------
100 | Start the plugin
101 |--------------------------------------------------------------------------
102 */
103 Plugin::init();
104
105 /**
106 * Declaring compatibility for WooCommerce HPOS
107 */
108 add_action(
109 'before_woocommerce_init',
110 function () {
111 if ( class_exists( FeaturesUtil::class ) ) {
112 FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
113 FeaturesUtil::declare_compatibility( 'product_instance_caching', __FILE__, true );
114 }
115 }
116 );
117
118 /*
119 --------------------------------------------------------------------------
120 | Install required dependencies
121 |--------------------------------------------------------------------------
122 */
123 add_action(
124 'plugins_loaded',
125 static function () {
126 // Initialize Quotes module.
127 CMBIRD_Quotes::init();
128 // Initialize MCP abilities.
129 CMBIRD_MCP::init();
130 // Only if plan is active via transient subscription_details.
131 $subscription = get_transient( 'subscription_details' );
132 // return if no subscription found.
133 if ( empty( $subscription ) ) {
134 return;
135 } else {
136 WP_Dependency_Installer::instance( __DIR__ )->run();
137 }
138 }
139 );
140
141 /**
142 * Hooks for WC Action Scheduler to import or export products
143 */
144 $cmbird_import_products = new CMBIRD_Products_ZI();
145 $cmbird_import_pricelist = new CMBIRD_Pricelist_ZI();
146 $cmbird_product_class = new CMBIRD_Products_ZI_Export();
147 $cmbird_common_class = new CMBIRD_Common_Functions();
148 $cmbird_contact_class = new CMBIRD_Contact_ZI();
149 $cmbird_category_class = new CMBIRD_Categories_ZI();
150 $cmbird_import_pricelist->wc_b2b_groups();
151 add_action( 'import_group_items_cron', array( $cmbird_import_products, 'sync_groupitem_recursively' ), 10, 2 );
152 add_action( 'import_simple_items_cron', array( $cmbird_import_products, 'sync_items_batch' ), 10, 2 );
153 add_action( 'import_variable_product_cron', array( $cmbird_import_products, 'import_variable_product_variations' ), 10, 2 );
154 add_action( 'sync_zi_product_cron', array( $cmbird_product_class, 'cmbird_zi_products_prepare_sync' ), 10, 2 );
155 add_action( 'sync_zi_pricelist', array( $cmbird_import_pricelist, 'zi_get_pricelist' ), 10, 2 );
156 add_action( 'cmbird_pricelist_addify_page', array( $cmbird_import_pricelist, 'process_addify_page' ), 10, 3 );
157 add_action( 'cmbird_pricelist_wc_b2b_page', array( $cmbird_import_pricelist, 'process_wc_b2b_page' ), 10, 3 );
158 add_action( 'sync_zi_order', array( $cmbird_common_class, 'cmbird_orders_prepare_sync' ), 10, 2 );
159 add_action( 'sync_zi_import_contacts', array( $cmbird_contact_class, 'cmbird_get_zoho_contacts' ), 10, 2 );
160 // Cascade Zoho category mapping deletion when a WC product category is deleted.
161 add_action(
162 'delete_term',
163 static function ( $term_id, $tt_id, $taxonomy ) {
164 if ( 'product_cat' !== $taxonomy ) {
165 return;
166 }
167 ( new \CommerceBird\Admin\Mappings\ZohoCategoryMap() )->forget_term( (int) $term_id );
168 },
169 10,
170 3
171 );
172 // add action to set the zoho rate limit option exceeded to false.
173 add_action( 'cmbird_common', array( CMBIRD_Common_Functions::class, 'set_zoho_rate_limit_option' ) );
174 // Zoho CRM Hooks.
175 add_action( 'sync_zcrm_order', array( $cmbird_common_class, 'cmbird_orders_prepare_sync' ) );
176 add_action( 'sync_zcrm_contact', array( ZohoCRMSync::class, 'cmbird_zcrm_contact_sync' ) );
177 // Exact Online Hooks.
178 add_action( 'cmbird_sync_eo', array( ExactOnlineSync::class, 'sync' ), 10, 3 );
179 add_action( 'cmbird_exact_online_sync_orders', array( ExactOnlineSync::class, 'sync_orders_via_cron' ) );
180 add_action( 'cmbird_payment_status', array( ExactOnlineSync::class, 'cmbird_payment_status' ), 10, 1 );
181 add_action( 'cmbird_eo_get_payment_statuses', array( ExactOnlineSync::class, 'get_payment_status_via_cron' ) );
182 add_filter( 'cron_schedules', array( ExactOnlineAjax::instance(), 'register_product_cron_schedules' ) );
183 add_action( 'cmbird_eo_product_mapping_daily', array( ExactOnlineAjax::instance(), 'product_map_cron' ) );
184 add_action( 'cmbird_eo_product_daily_reset', array( ExactOnlineAjax::instance(), 'product_map_daily_reset' ) );
185 // Callback functions for scheduled action to process product or customer chunk.
186 add_action(
187 'cmbird_process_product_chunk',
188 function ( $args ) {
189 if ( ! is_array( $args ) || empty( $args['transient_key'] ) ) {
190 return;
191 }
192 $transient_key = $args['transient_key'];
193 $import_products = $args['import_products'] ?? false;
194 $chunked_products = get_transient( $transient_key );
195 if ( $chunked_products ) {
196 $sync = new ExactOnlineSync();
197 $sync->sync( 'product', $chunked_products, (bool) $import_products );
198 // Remove transient after processing.
199 delete_transient( $transient_key );
200 }
201 },
202 10,
203 1
204 );
205 add_action(
206 'cmbird_process_customer_chunk',
207 function ( $args ) {
208 if ( ! is_array( $args ) || empty( $args['transient_key'] ) ) {
209 return;
210 }
211 $transient_key = $args['transient_key'];
212 $import_customers = $args['import_customers'] ?? false;
213 $chunked_customers = get_transient( $transient_key );
214 if ( $chunked_customers ) {
215 $sync = new ExactOnlineSync();
216 $sync->sync( 'customer', $chunked_customers, (bool) $import_customers );
217 // Remove transient after processing.
218 delete_transient( $transient_key );
219 }
220 },
221 10,
222 1
223 );
224 // Zoho CRM Hooks.
225 add_action( 'init', array( ZohoCRMSync::class, 'refresh_token' ) );
226 // Zoho Inventory Cron Hook for importing items.
227 add_action( 'zi_execute_import_sync', array( Plugin::class, 'dispatch_import_simple_items' ) );
228
229 // add classes to REST API.
230 add_action(
231 'rest_api_init',
232 function () {
233 new Zoho();
234 new Exact();
235 new ProductWebhook();
236 new ShippingWebhook();
237 new CreateOrderWebhook();
238 new CMBird_APIs();
239 $po_controller = new CMBIRD_REST_Shop_Purchase_Controller();
240 $po_controller->register_routes();
241 }
242 );
243
244 add_action(
245 'save_post',
246 function ( $post_id, $post ) {
247 if ( 'wcb2b_group' === $post->post_type ) {
248 delete_option( 'cmbird_wcb2b_groups' );
249 }
250 },
251 10,
252 2
253 );
254
255 /**
256 * Perform actions when the plugin is updated
257 *
258 * @param string $upgrader_object
259 * @param array $options
260 * @return void
261 */
262 add_action( 'upgrader_process_complete', 'cmbird_update_plugin_tasks', 10, 2 );
263
264 /**
265 * Perform tasks when the plugin is updated.
266 *
267 * @param \WP_Upgrader $upgrader_object - Upgrader object.
268 * @param array $options - Options array.
269 *
270 * @see https://developer.wordpress.org/reference/hooks/upgrader_process_complete/
271 */
272 function cmbird_update_plugin_tasks( $upgrader_object, $options ) {
273 $this_plugin = plugin_basename( __FILE__ );
274
275 if ( ! is_array( $options ) ) {
276 return;
277 }
278
279 if ( ! isset( $options['action'], $options['type'], $options['plugins'] ) || ! is_array( $options['plugins'] ) ) {
280 return;
281 }
282
283 if ( 'update' === $options['action'] && 'plugin' === $options['type'] ) {
284 foreach ( $options['plugins'] as $plugin ) {
285 if ( $plugin === $this_plugin ) {
286 // Ensure category mapping table exists before any table-backed migrations run.
287 Plugin::ensure_zi_category_map_table();
288
289 // Perform tasks when the plugin is updated.
290 // Updating meta key from '_cost_price' to '_cogs_total_value'.
291 global $wpdb;
292 $wpdb->query(
293 $wpdb->prepare(
294 "UPDATE {$wpdb->postmeta} SET meta_key = %s WHERE meta_key = %s",
295 '_cogs_total_value',
296 '_cost_price'
297 )
298 );
299 // Enable MCP WooCommerce integration. Remove this when enabled in Woo core.
300 update_option( 'woocommerce_feature_mcp_integration_enabled', 'yes' );
301 update_option( 'woocommerce_feature_cost_of_goods_sold_enabled', 'yes' );
302 update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
303 // One-time cleanup for old per-minute Zoho API rate limit counters.
304 $wpdb->query(
305 $wpdb->prepare(
306 "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
307 $wpdb->esc_like( 'cmbird_zoho_api_calls_' ) . '%'
308 )
309 );
310 break;
311 }
312 }
313 }
314
315 // One-shot migration of legacy category mapping options into the new table.
316 if ( ! get_option( 'cmbird_zi_category_map_migrated' ) ) {
317 $report = \CommerceBird\Admin\Mappings\ZohoCategoryMap::migrate_legacy_options();
318
319 if ( ! empty( $report['skipped'] ) ) {
320 set_transient( 'cmbird_zi_category_map_migration_report', $report['skipped'], DAY_IN_SECONDS );
321 }
322
323 update_option( 'cmbird_zi_category_map_migrated', '1', false );
324 }
325 }
326
327 /**
328 * Instantiate the MCP adapter. Remove this when its included in Woo core.
329 */
330 // 1. Check if MCP Adapter is available
331 if ( ! class_exists( McpAdapter::class ) ) {
332 // Handle missing dependency (show admin notice, etc.).
333 return;
334 }
335 // 2. Initialize the adapter
336 McpAdapter::instance();
337