Changeset 3761245
- Timestamp:
- 10/23/2026 09:09:10 AM (62 minutes ago)
- Location:
- moloni-on
- Files:
-
- 2 added
- 14 edited
- 1 copied
-
tags/4.0.14 (copied) (copied from moloni-on/trunk )
-
tags/4.0.14/.claude/journal/2026-10-21-single-product-webhook.md (added)
-
tags/4.0.14/moloni-on.php (modified) (1 diff)
-
tags/4.0.14/readme.txt (modified) (2 diffs)
-
tags/4.0.14/src/API/Queries/hooks.graphql (modified) (1 diff)
-
tags/4.0.14/src/Helpers/WebHooks.php (modified) (3 diffs)
-
tags/4.0.14/src/Plugin.php (modified) (2 diffs)
-
tags/4.0.14/src/WebHooks/Products.php (modified) (4 diffs)
-
tags/4.0.14/vendor/composer/installed.php (modified) (2 diffs)
-
trunk/.claude/journal/2026-10-21-single-product-webhook.md (added)
-
trunk/moloni-on.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/src/API/Queries/hooks.graphql (modified) (1 diff)
-
trunk/src/Helpers/WebHooks.php (modified) (3 diffs)
-
trunk/src/Plugin.php (modified) (2 diffs)
-
trunk/src/WebHooks/Products.php (modified) (4 diffs)
-
trunk/vendor/composer/installed.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
moloni-on/tags/4.0.14/moloni-on.php
r3754588 r3761245 5 5 * Requires Plugins: woocommerce 6 6 * Description: Simple invoicing integration with Moloni ON. 7 * Version: 4.0.1 37 * Version: 4.0.14 8 8 * Tested up to: 7.0 9 9 * WC tested up to: 10.7.0 -
moloni-on/tags/4.0.14/readme.txt
r3754588 r3761245 3 3 Requires Plugins: woocommerce 4 4 Tags: invoicing, orders 5 Stable tag: 4.0.1 35 Stable tag: 4.0.14 6 6 Tested up to: 7.0 7 7 WC tested up to: 10.7.0 … … 59 59 60 60 == Changelog == 61 = 4.0.14= 62 * Install a single Moloni ON Product webhook instead of one per operation, so the plugin uses fewer webhooks from the plan's quota. Existing shops switch to it the next time they save the automation settings or reinstall the webhooks. 63 61 64 = 4.0.13= 62 65 * Create the shipping and fee products with a fixed name, so they no longer keep the first order's shipping method or fee name forever. -
moloni-on/tags/4.0.14/src/API/Queries/hooks.graphql
r3675991 r3761245 14 14 msg 15 15 } 16 options 17 { 18 pagination 19 { 20 page 21 qty 22 count 23 } 24 } 16 25 } 17 26 } -
moloni-on/tags/4.0.14/src/Helpers/WebHooks.php
r3487173 r3761245 23 23 * Create hook in moloni 24 24 * 25 * Omit $operation (or pass null) to receive every operation of the model in one hook. 26 * 25 27 * @param string $model 26 * @param string $operation28 * @param string|null $operation 27 29 * 28 30 * @throws APIExeption 29 31 */ 30 public static function createHook(string $model, string $operation)32 public static function createHook(string $model, ?string $operation = null) 31 33 { 32 34 if (!isset(self::$routes[$model])) { … … 43 45 'model' => $model, 44 46 'url' => $url, 45 'operation' => $operation46 47 ]; 48 49 if ($operation !== null) { 50 $variables['data']['operation'] = $operation; 51 } 47 52 48 53 Hooks::mutationHookCreate($variables); … … 58 63 $ids = []; 59 64 65 /** Filter by this site's URL — without it the query returns (and we'd delete) every hook of the company */ 60 66 $variables = [ 61 ' data' => [67 'options' => [ 62 68 'search' => [ 63 69 'field' => 'url', -
moloni-on/tags/4.0.14/src/Plugin.php
r3569805 r3761245 293 293 WebHooks::deleteHooks(); 294 294 295 if (Context::settings()->getInt('hook_stock_sync') === Boolean::YES) { 296 WebHooks::createHook('Product', 'stockChanged'); 297 } 298 299 if (Context::settings()->getInt('hook_product_sync') === Boolean::YES) { 300 WebHooks::createHook('Product', 'create'); 301 WebHooks::createHook('Product', 'update'); 295 if ( 296 Context::settings()->getInt('hook_stock_sync') === Boolean::YES || 297 Context::settings()->getInt('hook_product_sync') === Boolean::YES 298 ) { 299 WebHooks::createHook('Product'); 302 300 } 303 301 … … 354 352 WebHooks::deleteHooks(); 355 353 356 if (isset($options['hook_stock_sync']) && (int)$options['hook_stock_sync'] === Boolean::YES) { 357 WebHooks::createHook('Product', 'stockChanged'); 358 } 359 360 if (isset($options['hook_product_sync']) && (int)$options['hook_product_sync'] === Boolean::YES) { 361 WebHooks::createHook('Product', 'create'); 362 WebHooks::createHook('Product', 'update'); 354 $hookStockSync = isset($options['hook_stock_sync']) && (int)$options['hook_stock_sync'] === Boolean::YES; 355 $hookProductSync = isset($options['hook_product_sync']) && (int)$options['hook_product_sync'] === Boolean::YES; 356 357 if ($hookStockSync || $hookProductSync) { 358 WebHooks::createHook('Product'); 363 359 } 364 360 } catch (APIExeption $e) { -
moloni-on/tags/4.0.14/src/WebHooks/Products.php
r3511501 r3761245 73 73 $productId = (int)sanitize_text_field($parameters['productId']); 74 74 75 $this->fetchMoloniProduct($productId); 76 77 //switch between operations 78 switch ($parameters['operation']) { 75 /** 76 * One hook receives every Product operation. Each handler checks its own setting 77 * before fetching the Moloni product, so a disabled sync costs no API call. 78 * Other operations (e.g. delete) are acknowledged and ignored. 79 */ 80 switch ($parameters['operation'] ?? '') { 79 81 case 'create': 80 $this->onCreate( );82 $this->onCreate($productId); 81 83 break; 82 84 case 'update': 83 $this->onUpdate( );85 $this->onUpdate($productId); 84 86 break; 85 87 case 'stockChanged': 86 $this->onStockUpdate( );88 $this->onStockUpdate($productId); 87 89 break; 88 90 } … … 127 129 * Create action 128 130 * 131 * @param int $productId Moloni product id 132 * 129 133 * @throws WebhookException 130 134 */ 131 private function onCreate( )135 private function onCreate(int $productId) 132 136 { 133 137 if (!$this->shouldSyncProduct()) { 134 138 return; 135 139 } 140 141 $this->fetchMoloniProduct($productId); 136 142 137 143 $this->validateMoloniProduct(); … … 175 181 * On Moloni product update action 176 182 * 183 * @param int $productId Moloni product id 184 * 177 185 * @throws HelperException|WebhookException 178 186 */ 179 private function onUpdate( )187 private function onUpdate(int $productId) 180 188 { 181 189 if (!$this->shouldSyncProduct()) { 182 190 return; 183 191 } 192 193 $this->fetchMoloniProduct($productId); 184 194 185 195 $this->validateMoloniProduct(); … … 237 247 * On Moloni stock update 238 248 * 249 * @param int $productId Moloni product id 250 * 239 251 * @throws HelperException|WebhookException 240 252 */ 241 private function onStockUpdate( )253 private function onStockUpdate(int $productId) 242 254 { 243 255 if (!$this->shouldSyncStock()) { 244 256 return; 245 257 } 258 259 $this->fetchMoloniProduct($productId); 246 260 247 261 $this->validateMoloniProduct(); -
moloni-on/tags/4.0.14/vendor/composer/installed.php
r3754588 r3761245 2 2 'root' => array( 3 3 'name' => 'moloni/woocommerce-dev', 4 'pretty_version' => 'v4.0.1 3',5 'version' => '4.0.1 3.0',6 'reference' => ' 18091161cfb0f7b4d3aca78ab0a4c56e4ea165c6',4 'pretty_version' => 'v4.0.14', 5 'version' => '4.0.14.0', 6 'reference' => '776d7f8f79f81afe54a9122788f74c3297243b69', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'moloni/woocommerce-dev' => array( 14 'pretty_version' => 'v4.0.1 3',15 'version' => '4.0.1 3.0',16 'reference' => ' 18091161cfb0f7b4d3aca78ab0a4c56e4ea165c6',14 'pretty_version' => 'v4.0.14', 15 'version' => '4.0.14.0', 16 'reference' => '776d7f8f79f81afe54a9122788f74c3297243b69', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../', -
moloni-on/trunk/moloni-on.php
r3754588 r3761245 5 5 * Requires Plugins: woocommerce 6 6 * Description: Simple invoicing integration with Moloni ON. 7 * Version: 4.0.1 37 * Version: 4.0.14 8 8 * Tested up to: 7.0 9 9 * WC tested up to: 10.7.0 -
moloni-on/trunk/readme.txt
r3754588 r3761245 3 3 Requires Plugins: woocommerce 4 4 Tags: invoicing, orders 5 Stable tag: 4.0.1 35 Stable tag: 4.0.14 6 6 Tested up to: 7.0 7 7 WC tested up to: 10.7.0 … … 59 59 60 60 == Changelog == 61 = 4.0.14= 62 * Install a single Moloni ON Product webhook instead of one per operation, so the plugin uses fewer webhooks from the plan's quota. Existing shops switch to it the next time they save the automation settings or reinstall the webhooks. 63 61 64 = 4.0.13= 62 65 * Create the shipping and fee products with a fixed name, so they no longer keep the first order's shipping method or fee name forever. -
moloni-on/trunk/src/API/Queries/hooks.graphql
r3675991 r3761245 14 14 msg 15 15 } 16 options 17 { 18 pagination 19 { 20 page 21 qty 22 count 23 } 24 } 16 25 } 17 26 } -
moloni-on/trunk/src/Helpers/WebHooks.php
r3487173 r3761245 23 23 * Create hook in moloni 24 24 * 25 * Omit $operation (or pass null) to receive every operation of the model in one hook. 26 * 25 27 * @param string $model 26 * @param string $operation28 * @param string|null $operation 27 29 * 28 30 * @throws APIExeption 29 31 */ 30 public static function createHook(string $model, string $operation)32 public static function createHook(string $model, ?string $operation = null) 31 33 { 32 34 if (!isset(self::$routes[$model])) { … … 43 45 'model' => $model, 44 46 'url' => $url, 45 'operation' => $operation46 47 ]; 48 49 if ($operation !== null) { 50 $variables['data']['operation'] = $operation; 51 } 47 52 48 53 Hooks::mutationHookCreate($variables); … … 58 63 $ids = []; 59 64 65 /** Filter by this site's URL — without it the query returns (and we'd delete) every hook of the company */ 60 66 $variables = [ 61 ' data' => [67 'options' => [ 62 68 'search' => [ 63 69 'field' => 'url', -
moloni-on/trunk/src/Plugin.php
r3569805 r3761245 293 293 WebHooks::deleteHooks(); 294 294 295 if (Context::settings()->getInt('hook_stock_sync') === Boolean::YES) { 296 WebHooks::createHook('Product', 'stockChanged'); 297 } 298 299 if (Context::settings()->getInt('hook_product_sync') === Boolean::YES) { 300 WebHooks::createHook('Product', 'create'); 301 WebHooks::createHook('Product', 'update'); 295 if ( 296 Context::settings()->getInt('hook_stock_sync') === Boolean::YES || 297 Context::settings()->getInt('hook_product_sync') === Boolean::YES 298 ) { 299 WebHooks::createHook('Product'); 302 300 } 303 301 … … 354 352 WebHooks::deleteHooks(); 355 353 356 if (isset($options['hook_stock_sync']) && (int)$options['hook_stock_sync'] === Boolean::YES) { 357 WebHooks::createHook('Product', 'stockChanged'); 358 } 359 360 if (isset($options['hook_product_sync']) && (int)$options['hook_product_sync'] === Boolean::YES) { 361 WebHooks::createHook('Product', 'create'); 362 WebHooks::createHook('Product', 'update'); 354 $hookStockSync = isset($options['hook_stock_sync']) && (int)$options['hook_stock_sync'] === Boolean::YES; 355 $hookProductSync = isset($options['hook_product_sync']) && (int)$options['hook_product_sync'] === Boolean::YES; 356 357 if ($hookStockSync || $hookProductSync) { 358 WebHooks::createHook('Product'); 363 359 } 364 360 } catch (APIExeption $e) { -
moloni-on/trunk/src/WebHooks/Products.php
r3511501 r3761245 73 73 $productId = (int)sanitize_text_field($parameters['productId']); 74 74 75 $this->fetchMoloniProduct($productId); 76 77 //switch between operations 78 switch ($parameters['operation']) { 75 /** 76 * One hook receives every Product operation. Each handler checks its own setting 77 * before fetching the Moloni product, so a disabled sync costs no API call. 78 * Other operations (e.g. delete) are acknowledged and ignored. 79 */ 80 switch ($parameters['operation'] ?? '') { 79 81 case 'create': 80 $this->onCreate( );82 $this->onCreate($productId); 81 83 break; 82 84 case 'update': 83 $this->onUpdate( );85 $this->onUpdate($productId); 84 86 break; 85 87 case 'stockChanged': 86 $this->onStockUpdate( );88 $this->onStockUpdate($productId); 87 89 break; 88 90 } … … 127 129 * Create action 128 130 * 131 * @param int $productId Moloni product id 132 * 129 133 * @throws WebhookException 130 134 */ 131 private function onCreate( )135 private function onCreate(int $productId) 132 136 { 133 137 if (!$this->shouldSyncProduct()) { 134 138 return; 135 139 } 140 141 $this->fetchMoloniProduct($productId); 136 142 137 143 $this->validateMoloniProduct(); … … 175 181 * On Moloni product update action 176 182 * 183 * @param int $productId Moloni product id 184 * 177 185 * @throws HelperException|WebhookException 178 186 */ 179 private function onUpdate( )187 private function onUpdate(int $productId) 180 188 { 181 189 if (!$this->shouldSyncProduct()) { 182 190 return; 183 191 } 192 193 $this->fetchMoloniProduct($productId); 184 194 185 195 $this->validateMoloniProduct(); … … 237 247 * On Moloni stock update 238 248 * 249 * @param int $productId Moloni product id 250 * 239 251 * @throws HelperException|WebhookException 240 252 */ 241 private function onStockUpdate( )253 private function onStockUpdate(int $productId) 242 254 { 243 255 if (!$this->shouldSyncStock()) { 244 256 return; 245 257 } 258 259 $this->fetchMoloniProduct($productId); 246 260 247 261 $this->validateMoloniProduct(); -
moloni-on/trunk/vendor/composer/installed.php
r3754588 r3761245 2 2 'root' => array( 3 3 'name' => 'moloni/woocommerce-dev', 4 'pretty_version' => 'v4.0.1 3',5 'version' => '4.0.1 3.0',6 'reference' => ' 18091161cfb0f7b4d3aca78ab0a4c56e4ea165c6',4 'pretty_version' => 'v4.0.14', 5 'version' => '4.0.14.0', 6 'reference' => '776d7f8f79f81afe54a9122788f74c3297243b69', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'moloni/woocommerce-dev' => array( 14 'pretty_version' => 'v4.0.1 3',15 'version' => '4.0.1 3.0',16 'reference' => ' 18091161cfb0f7b4d3aca78ab0a4c56e4ea165c6',14 'pretty_version' => 'v4.0.14', 15 'version' => '4.0.14.0', 16 'reference' => '776d7f8f79f81afe54a9122788f74c3297243b69', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../',
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)