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