From d32b00160e746352cd1d3b1f3914cbb72ee94b20 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Tue, 17 Jan 2023 23:54:08 +0300 Subject: [PATCH 01/35] Fix: more --- Core.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Core.php b/Core.php index 123466a..e5368df 100644 --- a/Core.php +++ b/Core.php @@ -179,7 +179,7 @@ public function fileProcessing(string $file_path): bool { $decoder = new Decoder(); } - catch(Exception $exception) + catch(\Exception $exception) { $this->log()->error(__('The file cannot be processed. DecoderCML threw an exception.', 'wc1c-main'), ['exception' => $exception]); return false; @@ -187,15 +187,15 @@ public function fileProcessing(string $file_path): bool if(has_filter('wc1c_schema_productscml_file_processing_decoder')) { - $decoder = apply_filters('wc1c_schema_productscml_file_processing_decoder', $decoder, $this); $this->log()->info(__('DecoderCML has been overridden by external algorithms.', 'wc1c-main')); + $decoder = apply_filters('wc1c_schema_productscml_file_processing_decoder', $decoder, $this); } try { $reader = new Reader($file_path, $decoder); } - catch(Exception $exception) + catch(\Exception $exception) { $this->log()->error(__('The file cannot be processed. ReaderCML threw an exception.', 'wc1c-main'), ['exception' => $exception]); return false; @@ -205,8 +205,8 @@ public function fileProcessing(string $file_path): bool if(has_filter('wc1c_schema_productscml_file_processing_reader')) { - $reader = apply_filters('wc1c_schema_productscml_file_processing_reader', $reader, $this); $this->log()->info(__('ReaderCML has been overridden by external algorithms.', 'wc1c-main')); + $reader = apply_filters('wc1c_schema_productscml_file_processing_reader', $reader, $this); } while($reader->read()) @@ -215,7 +215,7 @@ public function fileProcessing(string $file_path): bool { do_action('wc1c_schema_productscml_file_processing_read', $reader, $this); } - catch(Exception $e) + catch(\Exception $e) { $this->log()->error(__('Import file processing not completed. ReaderCML threw an exception.', 'wc1c-main'), ['exception' => $e]); break; From 274129e331b43a310943a616a479ee0a4924186f Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 19 Jan 2023 02:52:52 +0300 Subject: [PATCH 02/35] Fix: more --- Core.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core.php b/Core.php index e5368df..023b6a1 100644 --- a/Core.php +++ b/Core.php @@ -179,7 +179,7 @@ public function fileProcessing(string $file_path): bool { $decoder = new Decoder(); } - catch(\Exception $exception) + catch(\Throwable $exception) { $this->log()->error(__('The file cannot be processed. DecoderCML threw an exception.', 'wc1c-main'), ['exception' => $exception]); return false; @@ -195,7 +195,7 @@ public function fileProcessing(string $file_path): bool { $reader = new Reader($file_path, $decoder); } - catch(\Exception $exception) + catch(\Throwable $exception) { $this->log()->error(__('The file cannot be processed. ReaderCML threw an exception.', 'wc1c-main'), ['exception' => $exception]); return false; @@ -215,7 +215,7 @@ public function fileProcessing(string $file_path): bool { do_action('wc1c_schema_productscml_file_processing_read', $reader, $this); } - catch(\Exception $e) + catch(\Throwable $e) { $this->log()->error(__('Import file processing not completed. ReaderCML threw an exception.', 'wc1c-main'), ['exception' => $e]); break; @@ -291,7 +291,7 @@ public function processingClassifier(Reader $reader) { do_action('wc1c_schema_productscml_processing_classifier_item', $classifier, $reader, $this); } - catch(Exception $e) + catch(\Throwable $e) { $this->log()->warning(__('An exception was thrown while saving the classifier.', 'wc1c-main'), ['exception' => $e]); } From 26c44908dbe41735cf8a8841b75155ea18146450 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 19 Jan 2023 03:27:14 +0300 Subject: [PATCH 03/35] Fix: more --- Admin.php | 14 ++++++++++++++ Receiver.php | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Admin.php b/Admin.php index 305a97a..087c901 100644 --- a/Admin.php +++ b/Admin.php @@ -187,6 +187,20 @@ public function configurationsFieldsOther(array $fields): array 'css' => 'min-width: 100px;', ]; + $fields['browser_debug'] = + [ + 'title' => __('Browser debug mode', 'wc1c-main'), + 'type' => 'checkbox', + 'label' => __('Check the box if you want to enable this feature. Disabled by default.', 'wc1c-main'), + 'description' => sprintf + ( + '%s
%s', + __('The setting is required only for debugging activities and must be turned off when such activities are completed.', 'wc1c-main'), + __('Only used in debug mode.', 'wc1c-main') + ), + 'default' => 'no' + ]; + return $fields; } diff --git a/Receiver.php b/Receiver.php index edcaaba..6c29790 100644 --- a/Receiver.php +++ b/Receiver.php @@ -325,6 +325,7 @@ public function handlerCheckauth() $session_id = session_id(); + $this->core()->configuration()->addMetaData('session_name', maybe_serialize($session_name), true); $this->core()->configuration()->addMetaData('session_id', maybe_serialize($session_id), true); $this->core()->configuration()->saveMetaData(); @@ -362,6 +363,11 @@ public function handlerCheckauthKey(bool $send_response = false): bool { if(!isset($_GET['lazysign'])) { + if('yes' === $this->core()->getOptions('browser_debug', 'no')) + { + return true; + } + $warning = __('Authorization key verification failed. 1C did not send the name of the lazy signature.', 'wc1c-main'); $this->core()->log()->warning($warning); @@ -389,7 +395,7 @@ public function handlerCheckauthKey(bool $send_response = false): bool return false; } - $session_name = sanitize_text_field(session_name()); + $session_name = sanitize_text_field($this->core()->configuration()->getMeta('session_name')); if(!isset($_COOKIE[$session_name])) { From 8f5cd0b503a18ff422b1c55b9192595c880e19a4 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 19 Jan 2023 03:27:45 +0300 Subject: [PATCH 04/35] Prepare: 0.8.0 --- Core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core.php b/Core.php index 023b6a1..de548d5 100644 --- a/Core.php +++ b/Core.php @@ -53,7 +53,7 @@ class Core extends SchemaAbstract public function __construct() { $this->setId('productscml'); - $this->setVersion('0.7.0'); + $this->setVersion('0.8.0'); $this->setName(__('Products data exchange via CommerceML', 'wc1c-main')); $this->setDescription(__('Creation and updating of products (goods) in WooCommerce according to data from 1C using the CommerceML protocol of various versions.', 'wc1c-main')); From c56492d6a6ca2f14c295672407d559116787809b Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:32:40 +0300 Subject: [PATCH 05/35] Settings: directory_clean_mode --- Admin.php | 23 +++++++++++++++++++++++ Receiver.php | 6 +++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Admin.php b/Admin.php index 087c901..4ba98b6 100644 --- a/Admin.php +++ b/Admin.php @@ -201,6 +201,29 @@ public function configurationsFieldsOther(array $fields): array 'default' => 'no' ]; + $clean_options = + [ + 'no' => __('Do not use', 'wc1c-main'), + 'standard' => __('Standard', 'wc1c-main'), + ]; + + $fields['directory_clean_mode'] = + [ + 'title' => __('Cleaning up a directory', 'wc1c-main'), + 'type' => 'select', + 'description' => sprintf + ('%s - %s
%s - %s

%s', + __('Do not use', 'wc1c-main'), + __('File deletion steps will be skipped.', 'wc1c-main'), + __('Standard', 'wc1c-main'), + __('The standard cleaning algorithm will be used. Suitable for most users.', 'wc1c-main'), + __('The choice of deletion mode must be taken very seriously.', 'wc1c-main') + ), + 'default' => 'standard', + 'css' => 'min-width:100%', + 'options' => $clean_options + ]; + return $fields; } diff --git a/Receiver.php b/Receiver.php index 6c29790..e8c3226 100644 --- a/Receiver.php +++ b/Receiver.php @@ -33,7 +33,11 @@ public function initHandler() add_action('wc1c_schema_productscml_catalog_handler_checkauth', [$this, 'handlerCheckauth'], 10, 0); - add_action('wc1c_schema_productscml_catalog_handler_init', [$this, 'handlerCatalogDirectoryClean'], 10, 0); + if('standard' === $this->core()->getOptions('directory_clean_mode', 'standard')) + { + add_action('wc1c_schema_productscml_catalog_handler_init', [$this, 'handlerCatalogDirectoryClean'], 10, 0); + } + add_action('wc1c_schema_productscml_catalog_handler_init', [$this, 'handlerCatalogModeInit'], 10, 0); add_action('wc1c_schema_productscml_catalog_handler_file', [$this, 'handlerCatalogModeFile'], 10, 0); From 23965d1f8e644a59d460ade2bf1b5b305ed7ca9c Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 19 Jan 2023 13:16:43 +0300 Subject: [PATCH 06/35] Inline receiver --- Core.php | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Core.php b/Core.php index de548d5..f059f9a 100644 --- a/Core.php +++ b/Core.php @@ -241,6 +241,59 @@ public function processingTimer(Reader $reader) } } + /** + * Receiver + * + * @return void + */ + public function receiver() + { + if($this->configuration()->isEnabled() === false) + { + $message = __('Configuration is offline.', 'wc1c-main'); + + wc1c()->log('receiver')->warning($message); + $this->receiver->sendResponseByType('failure', $message); + } + + try + { + $this->configuration()->setDateActivity(time()); + $this->configuration()->save(); + } + catch(Exception $e) + { + $message = __('Error saving configuration.', 'wc1c-main'); + + wc1c()->log('receiver')->error($message, ['exception' => $e]); + $this->receiver->sendResponseByType('failure', $message); + } + + $action = false; + $wc1c_receiver_action = 'wc1c_receiver_' . $this->getId(); + + if(has_action($wc1c_receiver_action)) + { + $action = true; + + ob_start(); + nocache_headers(); + + wc1c()->log('receiver')->info(__('The request was successfully submitted for processing in the schema for the configuration.', 'wc1c-main'), ['action' => $wc1c_receiver_action]); + + do_action($wc1c_receiver_action); + ob_end_clean(); + } + + if(false === $action) + { + $message = __('Receiver request is very bad! Action not found.', 'wc1c-main'); + + wc1c()->log('receiver')->warning($message, ['action' => $wc1c_receiver_action]); + $this->receiver->sendResponseByType('failure', $message); + } + } + /** * Обработка данных классификатора * From de6933bd880263466b16ae6d0dd26aaf6ef7f8b7 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 19 Jan 2023 20:05:22 +0300 Subject: [PATCH 07/35] Fix: more --- Core.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Core.php b/Core.php index f059f9a..cebc398 100644 --- a/Core.php +++ b/Core.php @@ -1505,17 +1505,21 @@ public function assignProductsItemCategories(ProductContract $internal_product, return $internal_product; } - /** @var CategoriesStorageContract $categories_storage */ - $categories_storage = Storage::load('category'); - $cats = []; - foreach($external_product->getClassifierGroups() as $classifier_group) + + if($external_product->hasClassifierGroups()) { - $cat = $categories_storage->getByExternalId($classifier_group); + /** @var CategoriesStorageContract $categories_storage */ + $categories_storage = Storage::load('category'); - if($cat instanceof Category) + foreach($external_product->getClassifierGroups() as $classifier_group) { - $cats[] = $cat->getId(); + $cat = $categories_storage->getByExternalId($classifier_group); + + if($cat instanceof Category) + { + $cats[] = $cat->getId(); + } } } From 70cd0d006ecec439d80249dc226e8dee62a6cb9c Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 19 Jan 2023 22:23:01 +0300 Subject: [PATCH 08/35] Add setProductTimes --- Core.php | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/Core.php b/Core.php index cebc398..3230639 100644 --- a/Core.php +++ b/Core.php @@ -1039,6 +1039,29 @@ public function assignProductsItemName(ProductContract $internal_product, Produc return $internal_product; } + /** + * Назначение данных по времени + * + * @param ProductContract $product Экземпляр продукта - либо существующий, либо новый + * + * @return mixed + */ + public function setProductTimes(ProductContract $product) + { + $time = current_time('timestamp'); + + /** + * _wc1c_time + * _wc1c_schema_time_{schema_id} + * _wc1c_configuration_time_{configuration_id} + */ + $product->update_meta_data('_wc1c_time', $time); + $product->update_meta_data('_wc1c_schema_time_' . $this->getId(), $time); + $product->update_meta_data('_wc1c_configuration_time_' . $this->configuration()->getId(), $time); + + return $product; + } + /** * Назначение данных продукта исходя из режима: артикул * @@ -2867,7 +2890,8 @@ public function processingProductsItem(ProductDataContract $external_product, Re */ if($external_product->hasCharacteristicId()) { - $this->log()->info(__('The product contains the characteristics.', 'wc1c-main')); // todo: реализация + $this->log()->notice(__('The product contains the characteristics.', 'wc1c-main')); // todo: реализация + return; } else { @@ -2900,12 +2924,14 @@ public function processingProductsItem(ProductDataContract $external_product, Re $internal_product = apply_filters('wc1c_schema_productscml_processing_products_item_before_save', $internal_product, $external_product, 'create', $reader); } + $internal_product = $this->setProductTimes($internal_product); + try { $id = $internal_product->save(); $this->log()->info(__('The product is created.', 'wc1c-main'), ['product_id' => $id, 'product_type' => $internal_product->get_type()]); } - catch(\Exception $e) + catch(\Throwable $e) { throw new Exception($e->getMessage()); } @@ -2929,7 +2955,7 @@ public function processingProductsItem(ProductDataContract $external_product, Re $id = $internal_product->save(); $this->log()->info(__('The product has been updated using external algorithms.', 'wc1c-main'), ['product_id' => $id, 'product_type' => $internal_product->get_type()]); } - catch(\Exception $e) + catch(\Throwable $e) { throw new Exception($e->getMessage()); } @@ -3187,11 +3213,13 @@ public function processingOffersItem(ProductDataContract $external_offer, Reader $internal_offer = apply_filters('wc1c_schema_productscml_processing_offers_item_before_save', $internal_offer, $external_offer, $reader); } + $internal_offer = $this->setProductTimes($internal_offer); + try { $internal_offer->save(); } - catch(\Exception $e) + catch(\Throwable $e) { throw new Exception($e->getMessage()); } @@ -3296,7 +3324,7 @@ public function processingOffers(Reader $reader) { do_action('wc1c_schema_productscml_processing_offers_item', $offer, $reader, $this); } - catch(Exception $e) + catch(\Throwable $e) { $this->log()->warning(__('An exception was thrown while processing the offer.', 'wc1c-main'), ['exception' => $e]); } From d90e26c7f5ef6afdb315145b59e41ca0c6048ea4 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 19 Jan 2023 22:45:48 +0300 Subject: [PATCH 09/35] Fix: more --- Core.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Core.php b/Core.php index 3230639..266480c 100644 --- a/Core.php +++ b/Core.php @@ -3027,11 +3027,13 @@ public function processingProductsItem(ProductDataContract $external_product, Re $update_product = apply_filters('wc1c_schema_productscml_processing_products_item_before_save', $update_product, $external_product, 'update', $reader); } + $update_product = $this->setProductTimes($update_product); + try { $update_product->save(); } - catch(\Exception $e) + catch(\Throwable $e) { throw new Exception($e->getMessage()); } @@ -3054,7 +3056,7 @@ public function processingProductsItem(ProductDataContract $external_product, Re { $update_product->save(); } - catch(\Exception $e) + catch(\Throwable $e) { throw new Exception($e->getMessage()); } From 69b89133fa19b89b8eb378e6f8feec2c9a6ae5fb Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Fri, 20 Jan 2023 00:32:49 +0300 Subject: [PATCH 10/35] SKUs abilities --- Admin.php | 28 ++++++++++++++++++++++++---- Core.php | 16 +++++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Admin.php b/Admin.php index 4ba98b6..364e7ae 100644 --- a/Admin.php +++ b/Admin.php @@ -895,13 +895,33 @@ public function configurationsFieldsProductsSku(array $fields): array 'default' => 'yes' ]; + $products_update_sku_options = + [ + 'no' => __('Do not update', 'wc1c-main'), + 'yes' => __('Update in any case', 'wc1c-main'), + 'add' => __('Add if not on the site and available in 1C', 'wc1c-main'), + 'yes_yes' => __('Update if present on the site and in 1C', 'wc1c-main'), + ]; + $fields['products_update_sku'] = [ 'title' => __('Product SKU update when requesting product updates', 'wc1c-main'), - 'type' => 'checkbox', - 'label' => __('Check the box if you want to enable this feature. Disabled by default.', 'wc1c-main'), - 'description' => __('When changing the product SKU in 1C, the data will be changed on the site.', 'wc1c-main'), - 'default' => 'no' + 'default' => 'no', + 'type' => 'select', + 'description' => sprintf + ( + '%s - %s
%s - %s
%s - %s
%s - %s
%s', + __('Do not update', 'wc1c-main'), + __('SKUs updates will be skipped in any case.', 'wc1c-main'), + __('Update in any case', 'wc1c-main'), + __('SKUs will be updated in any case. The same value will always be on the site and in 1C.', 'wc1c-main'), + __('Add if not on the site and available in 1C', 'wc1c-main'), + __('Existing SKUs will not be affected. There will be a filling of those missing on the site if they are available in 1C.', 'wc1c-main'), + __('Update if present on the site and in 1C', 'wc1c-main'), + __('SKUs will be updated only if they are filled in 1C and on the site at the same time.', 'wc1c-main'), + __('The setting works when updating products (goods).', 'wc1c-main') + ), + 'options' => $products_update_sku_options ]; $products_sku_by_cml_options = diff --git a/Core.php b/Core.php index 266480c..ab575c8 100644 --- a/Core.php +++ b/Core.php @@ -1074,12 +1074,12 @@ public function setProductTimes(ProductContract $product) */ public function assignProductsItemSku(ProductContract $internal_product, ProductDataContract $external_product, string $mode, Reader $reader): ProductContract { - if('update' === $mode && 'yes' !== $this->getOptions('products_update_sku', 'no')) + if('update' === $mode && 'no' === $this->getOptions('products_update_sku', 'no')) { return $internal_product; } - if('create' === $mode && 'yes' !== $this->getOptions('products_create_adding_sku', 'no')) + if('create' === $mode && 'no' === $this->getOptions('products_create_adding_sku', 'yes')) { return $internal_product; } @@ -1120,11 +1120,21 @@ public function assignProductsItemSku(ProductContract $internal_product, Product $sku = $external_product->getSku(); } + if('update' === $mode && 'add' === $this->getOptions('products_update_sku', 'no') && !empty($internal_product->getSku())) + { + return $internal_product; + } + + if('update' === $mode && 'yes_yes' === $this->getOptions('products_update_sku', 'no') && empty($internal_product->getSku()) && empty($external_product->getSku())) + { + return $internal_product; + } + try { $internal_product->setSku($sku); } - catch(Exception $e) + catch(\Throwable $e) { $this->log()->notice(__('Failed to set SKU for product.', 'wc1c-main'), ['exception' => $e, 'sku' => $external_product->getSku()]); } From dfafb02e6ce073bf2f392d4a83afeb3002e3cbe5 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Fri, 20 Jan 2023 00:33:43 +0300 Subject: [PATCH 11/35] Fix: source for SKUs abilities --- Core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core.php b/Core.php index ab575c8..1779f05 100644 --- a/Core.php +++ b/Core.php @@ -1125,7 +1125,7 @@ public function assignProductsItemSku(ProductContract $internal_product, Product return $internal_product; } - if('update' === $mode && 'yes_yes' === $this->getOptions('products_update_sku', 'no') && empty($internal_product->getSku()) && empty($external_product->getSku())) + if('update' === $mode && 'yes_yes' === $this->getOptions('products_update_sku', 'no') && empty($internal_product->getSku()) && empty($sku)) { return $internal_product; } From 8aff746893de39c371b1dd8928a5c7e04357c55c Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Fri, 20 Jan 2023 01:11:58 +0300 Subject: [PATCH 12/35] Description abilities --- Admin.php | 80 ++++++++++++++++++++++++++++++++++++++----------------- Core.php | 41 +++++++++++++++++++++------- 2 files changed, 87 insertions(+), 34 deletions(-) diff --git a/Admin.php b/Admin.php index 364e7ae..144fff3 100644 --- a/Admin.php +++ b/Admin.php @@ -1062,37 +1062,33 @@ public function configurationsFieldsProductsDescriptions(array $fields): array 'default' => 'yes' ]; - $fields['products_update_description'] = + $products_update_description_options = [ - 'title' => __('Product description update when requesting product updates', 'wc1c-main'), - 'type' => 'checkbox', - 'label' => __('Check the box if you want to enable this feature. Disabled by default.', 'wc1c-main'), - 'description' => __('When changing the product description in 1C, the data will be changed on the site.', 'wc1c-main'), - 'default' => 'no' + 'no' => __('Do not update', 'wc1c-main'), + 'yes' => __('Update in any case', 'wc1c-main'), + 'add' => __('Add if not on the site and available in 1C', 'wc1c-main'), + 'yes_yes' => __('Update if present on the site and in 1C', 'wc1c-main'), ]; - $fields['products_create_adding_description_full'] = + $fields['products_update_description'] = [ - 'title' => __('Filling a full description of the created product', 'wc1c-main'), - 'type' => 'checkbox', - 'label' => __('Check the box to enable this feature. Disabled by default.', 'wc1c-main'), + 'title' => __('Description update when requesting product updates', 'wc1c-main'), + 'default' => 'no', + 'type' => 'select', 'description' => sprintf ( - '%s
%s %s', - __('The data received from 1C may contain full descriptions of products that will be placed in the full description.', 'wc1c-main'), - __('If there are no brief full descriptions in 1C, you can turn off the filling and edit the data directly on the site.', 'wc1c-main'), - __('The choice of a source for a brief full description in 1C is in a separate settings block - Products (goods): descriptions.', 'wc1c-main') + '%s - %s
%s - %s
%s - %s
%s - %s
%s', + __('Do not update', 'wc1c-main'), + __('Description updates will be skipped in any case.', 'wc1c-main'), + __('Update in any case', 'wc1c-main'), + __('Description will be updated in any case. The same value will always be on the site and in 1C.', 'wc1c-main'), + __('Add if not on the site and available in 1C', 'wc1c-main'), + __('Existing description will not be affected. There will be a filling of those missing on the site if they are available in 1C.', 'wc1c-main'), + __('Update if present on the site and in 1C', 'wc1c-main'), + __('Description will be updated only if they are filled in 1C and on the site at the same time.', 'wc1c-main'), + __('The setting works when updating products (goods).', 'wc1c-main') ), - 'default' => 'no' - ]; - - $fields['products_update_description_full'] = - [ - 'title' => __('Product full description update when requesting product updates', 'wc1c-main'), - 'type' => 'checkbox', - 'label' => __('Check the box if you want to enable this feature. Disabled by default.', 'wc1c-main'), - 'description' => __('When changing the product full description in 1C, the data will be changed on the site.', 'wc1c-main'), - 'default' => 'no' + 'options' => $products_update_description_options ]; $products_descriptions_by_cml_options = @@ -1136,6 +1132,42 @@ public function configurationsFieldsProductsDescriptions(array $fields): array 'css' => 'min-width: 370px;', ]; + $fields['products_create_adding_description_full'] = + [ + 'title' => __('Filling a full description of the created product', 'wc1c-main'), + 'type' => 'checkbox', + 'label' => __('Check the box to enable this feature. Disabled by default.', 'wc1c-main'), + 'description' => sprintf + ( + '%s
%s %s', + __('The data received from 1C may contain full descriptions of products that will be placed in the full description.', 'wc1c-main'), + __('If there are no brief full descriptions in 1C, you can turn off the filling and edit the data directly on the site.', 'wc1c-main'), + __('The choice of a source for a brief full description in 1C is in a separate settings block - Products (goods): descriptions.', 'wc1c-main') + ), + 'default' => 'no' + ]; + + $fields['products_update_description_full'] = + [ + 'title' => __('Full description update when requesting product updates', 'wc1c-main'), + 'default' => 'no', + 'type' => 'select', + 'description' => sprintf + ( + '%s - %s
%s - %s
%s - %s
%s - %s
%s', + __('Do not update', 'wc1c-main'), + __('Description updates will be skipped in any case.', 'wc1c-main'), + __('Update in any case', 'wc1c-main'), + __('Description will be updated in any case. The same value will always be on the site and in 1C.', 'wc1c-main'), + __('Add if not on the site and available in 1C', 'wc1c-main'), + __('Existing description will not be affected. There will be a filling of those missing on the site if they are available in 1C.', 'wc1c-main'), + __('Update if present on the site and in 1C', 'wc1c-main'), + __('Description will be updated only if they are filled in 1C and on the site at the same time.', 'wc1c-main'), + __('The setting works when updating products (goods).', 'wc1c-main') + ), + 'options' => $products_update_description_options + ]; + $fields['products_descriptions_by_cml'] = [ 'title' => __('Descriptions based on CommerceML data: full', 'wc1c-main'), diff --git a/Core.php b/Core.php index 1779f05..b4b6239 100644 --- a/Core.php +++ b/Core.php @@ -1387,21 +1387,22 @@ public function assignProductsItemStockStatus(ProductContract $internal_product, */ public function assignProductsItemDescriptions(ProductContract $internal_product, ProductDataContract $external_product, string $mode, Reader $reader): ProductContract { - if('create' === $mode && 'yes' !== $this->getOptions('products_create_adding_description', 'yes')) + if('create' === $mode && 'no' === $this->getOptions('products_create_adding_description', 'yes')) { return $internal_product; } - if('update' === $mode && 'yes' !== $this->getOptions('products_update_description', 'no')) + if('update' === $mode && 'no' === $this->getOptions('products_update_description', 'no')) { return $internal_product; } - $short = $this->getOptions('products_descriptions_short_by_cml', 'no'); + $short_description = ''; + + $short = $this->getOptions('products_descriptions_short_by_cml', 'yes'); if('no' !== $short) { - $short_description = ''; switch($short) { case 'yes_html': @@ -1433,10 +1434,20 @@ public function assignProductsItemDescriptions(ProductContract $internal_product default: $short_description = $external_product->getDescription(); } + } - $internal_product->set_short_description($short_description); + if('update' === $mode && 'add' === $this->getOptions('products_update_description', 'yes') && !empty($internal_product->get_short_description())) + { + return $internal_product; } + if('update' === $mode && empty($short_description) && 'yes_yes' === $this->getOptions('products_update_description', 'yes') && empty($internal_product->get_short_description())) + { + return $internal_product; + } + + $internal_product->set_short_description($short_description); + return $internal_product; } @@ -1452,21 +1463,21 @@ public function assignProductsItemDescriptions(ProductContract $internal_product */ public function assignProductsItemDescriptionsFull(ProductContract $internal_product, ProductDataContract $external_product, string $mode, Reader $reader): ProductContract { - if('create' === $mode && 'yes' !== $this->getOptions('products_create_adding_description_full', 'no')) + if('create' === $mode && 'no' === $this->getOptions('products_create_adding_description_full', 'yes')) { return $internal_product; } - if('update' === $mode && 'yes' !== $this->getOptions('products_update_description_full', 'no')) + if('update' === $mode && 'no' === $this->getOptions('products_update_description_full', 'no')) { return $internal_product; } - $full = $this->getOptions('products_descriptions_by_cml', 'no'); + $full_description = ''; + $full = $this->getOptions('products_descriptions_by_cml', 'yes'); if('no' !== $full) { - $full_description = ''; switch($full) { case 'yes_html': @@ -1498,10 +1509,20 @@ public function assignProductsItemDescriptionsFull(ProductContract $internal_pro default: $full_description = $external_product->getDescription(); } + } + + if('update' === $mode && 'add' === $this->getOptions('products_update_description_full', 'yes') && !empty($internal_product->get_description())) + { + return $internal_product; + } - $internal_product->set_description($full_description); + if('update' === $mode && empty($full_description) && 'yes_yes' === $this->getOptions('products_update_description_full', 'yes') && empty($internal_product->get_description())) + { + return $internal_product; } + $internal_product->set_description($full_description); + return $internal_product; } From 920b52336fd708830a6702bc5c4c7afdcd4c4407 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Fri, 20 Jan 2023 02:01:05 +0300 Subject: [PATCH 13/35] Fix: more --- Admin.php | 87 +++++++++++++++++++++++++++++++++---------------------- Core.php | 36 ++++++++++++++++++++++- 2 files changed, 88 insertions(+), 35 deletions(-) diff --git a/Admin.php b/Admin.php index 144fff3..7958956 100644 --- a/Admin.php +++ b/Admin.php @@ -1472,15 +1472,43 @@ public function configurationsFieldsProductsOther(array $fields): array 'options' => $statuses ]; + $products_update_options = + [ + 'no' => __('Do not update', 'wc1c-main'), + 'yes' => __('Check', 'wc1c-main'), + 'none' => __('Uncheck', 'wc1c-main'), + ]; + + $products_update_options_description = sprintf + ( + '%s - %s
%s - %s
%s - %s
%s', + __('Do not update', 'wc1c-main'), + __('The current value of the option will remain.', 'wc1c-main'), + __('Check', 'wc1c-main'), + __('The mark will be set.', 'wc1c-main'), + __('Uncheck', 'wc1c-main'), + __('The mark will be removed.', 'wc1c-main'), + __('The setting works when updating products (goods).', 'wc1c-main') + ); + $fields['products_create_set_featured'] = [ 'title' => __('Featured on create products', 'wc1c-main'), 'type' => 'checkbox', 'label' => __('Check the box to enable this feature. Disabled by default.', 'wc1c-main'), - 'description' => __('The created product will be marked as recommended.', 'wc1c-main'), + 'description' => __('The created product will be marked as featured.', 'wc1c-main'), 'default' => 'no' ]; + $fields['products_update_set_featured'] = + [ + 'title' => __('Featured on update products', 'wc1c-main'), + 'default' => 'no', + 'type' => 'select', + 'description' => $products_update_options_description, + 'options' => $products_update_options + ]; + $fields['products_create_set_sold_individually'] = [ 'title' => __('Individual sale on create products', 'wc1c-main'), @@ -1490,7 +1518,16 @@ public function configurationsFieldsProductsOther(array $fields): array 'default' => 'no' ]; - $options = wc_get_product_visibility_options(); + $fields['products_update_set_sold_individually'] = + [ + 'title' => __('Individual sale on update products', 'wc1c-main'), + 'default' => 'no', + 'type' => 'select', + 'description' => $products_update_options_description, + 'options' => $products_update_options + ]; + + $visibility_options = wc_get_product_visibility_options(); $fields['products_create_set_catalog_visibility'] = [ @@ -1498,52 +1535,34 @@ public function configurationsFieldsProductsOther(array $fields): array 'type' => 'select', 'description' => __('This setting determines which pages products will be displayed on.', 'wc1c-main'), 'default' => 'visible', - 'options' => $options - ]; - - $fields['products_create_set_reviews_allowed'] = - [ - 'title' => __('Allow reviews on create products', 'wc1c-main'), - 'type' => 'checkbox', - 'label' => __('Check the box to enable this feature. Disabled by default.', 'wc1c-main'), - 'description' => __('It will be allowed to leave reviews for created products.', 'wc1c-main'), - 'default' => 'no' + 'options' => $visibility_options ]; - $fields['products_update_set_featured'] = + $fields['products_update_set_catalog_visibility'] = [ - 'title' => __('Featured on update products', 'wc1c-main'), - 'type' => 'checkbox', - 'label' => __('Check the box to enable this feature. Disabled by default.', 'wc1c-main'), - 'description' => __('The updated product will be marked as recommended.', 'wc1c-main'), - 'default' => 'no' + 'title' => __('Product visibility on update products', 'wc1c-main'), + 'type' => 'select', + 'description' => __('This setting determines which pages products will be displayed on.', 'wc1c-main'), + 'default' => '', + 'options' => array_merge($default_statuses, $visibility_options) ]; - $fields['products_update_set_sold_individually'] = + $fields['products_create_set_reviews_allowed'] = [ - 'title' => __('Individual sale on update products', 'wc1c-main'), + 'title' => __('Allow reviews on create products', 'wc1c-main'), 'type' => 'checkbox', 'label' => __('Check the box to enable this feature. Disabled by default.', 'wc1c-main'), - 'description' => __('Enable to have the product sold individually in one order. Two units of a product in one order will be impossible to order.', 'wc1c-main'), + 'description' => __('It will be allowed to leave reviews for created products.', 'wc1c-main'), 'default' => 'no' ]; - $fields['products_update_set_catalog_visibility'] = - [ - 'title' => __('Product visibility on update products', 'wc1c-main'), - 'type' => 'select', - 'description' => __('This setting determines which pages products will be displayed on.', 'wc1c-main'), - 'default' => 'visible', - 'options' => $options - ]; - $fields['products_update_set_reviews_allowed'] = [ 'title' => __('Allow reviews on update products', 'wc1c-main'), - 'type' => 'checkbox', - 'label' => __('Check the box to enable this feature. Disabled by default.', 'wc1c-main'), - 'description' => __('It will be allowed to leave reviews for updated products.', 'wc1c-main'), - 'default' => 'no' + 'default' => 'no', + 'type' => 'select', + 'description' => $products_update_options_description, + 'options' => $products_update_options ]; return $fields; diff --git a/Core.php b/Core.php index b4b6239..b58a4cf 100644 --- a/Core.php +++ b/Core.php @@ -1165,7 +1165,12 @@ public function assignProductsItemCatalogVisibility(ProductContract $internal_pr return $internal_product; } - $internal_product->set_catalog_visibility($this->getOptions('products_update_set_catalog_visibility', 'visible')); + $visible = $this->getOptions('products_update_set_catalog_visibility', ''); + + if(!empty($visible)) + { + $internal_product->set_catalog_visibility($visible); + } return $internal_product; } @@ -1198,10 +1203,19 @@ public function assignProductsItemReviews(ProductContract $internal_product, Pro return $internal_product; } + if('no' === $this->getOptions('products_update_set_reviews_allowed', 'no')) + { + return $internal_product; + } + if('yes' === $this->getOptions('products_update_set_reviews_allowed', 'no')) { $internal_product->set_reviews_allowed(true); } + else + { + $internal_product->set_reviews_allowed(false); + } return $internal_product; } @@ -1220,6 +1234,7 @@ public function assignProductsItemSoldIndividually(ProductContract $internal_pro { if($mode === 'create') { + $internal_product->set_sold_individually(false); if('yes' === $this->getOptions('products_create_set_sold_individually', 'no')) { $internal_product->set_sold_individually(true); @@ -1228,10 +1243,19 @@ public function assignProductsItemSoldIndividually(ProductContract $internal_pro return $internal_product; } + if('no' === $this->getOptions('products_update_set_sold_individually', 'no')) + { + return $internal_product; + } + if('yes' === $this->getOptions('products_update_set_sold_individually', 'no')) { $internal_product->set_sold_individually(true); } + else + { + $internal_product->set_sold_individually(false); + } return $internal_product; } @@ -1255,6 +1279,7 @@ public function assignProductsItemFeatured(ProductContract $internal_product, Pr if($mode === 'create') { + $internal_product->set_featured(false); if('yes' === $this->getOptions('products_create_set_featured', 'no')) { $internal_product->set_featured(true); @@ -1263,10 +1288,19 @@ public function assignProductsItemFeatured(ProductContract $internal_product, Pr return $internal_product; } + if('no' === $this->getOptions('products_update_set_featured', 'no')) + { + return $internal_product; + } + if('yes' === $this->getOptions('products_update_set_featured', 'no')) { $internal_product->set_featured(true); } + else + { + $internal_product->set_featured(false); + } return $internal_product; } From 7780af2b08583c1d0fca1db2a0358da957ae3695 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Fri, 20 Jan 2023 02:28:16 +0300 Subject: [PATCH 14/35] Fix: more --- Admin.php | 38 +++++++++++++++++++------------------- Core.php | 24 ++++++++++++++---------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/Admin.php b/Admin.php index 7958956..f1185ea 100644 --- a/Admin.php +++ b/Admin.php @@ -1278,6 +1278,13 @@ public function configurationsFieldsProductsTaxes(array $fields): array 'none' => _x( 'None', 'Tax status', 'wc1c-main'), ]; + $products_default_options = + [ + 'no' => __('Do not update', 'wc1c-main'), + ]; + + $taxes_status_update = array_merge($products_default_options, $taxes_status); + $fields['products_create_taxes_status'] = [ 'title' => __('Tax status of created products', 'wc1c-main'), @@ -1292,39 +1299,32 @@ public function configurationsFieldsProductsTaxes(array $fields): array 'options' => $taxes_status ]; - $fields['products_create_taxes_class'] = + $fields['products_update_taxes_status'] = [ - 'title' => __('Tax class for created products', 'wc1c-main'), + 'title' => __('Tax status for updated products', 'wc1c-main'), 'type' => 'select', 'description' => sprintf ( '%s
%s', - __('Choose a tax class for this product. Tax classes are used to apply different tax rates specific to certain types of product.', 'wc1c-main'), - __('The setting works when creating products (goods).', 'wc1c-main') + __('Define whether or not the entire product is taxable, or just the cost of shipping it.', 'wc1c-main'), + __('The setting works when updating products (goods).', 'wc1c-main') ), - 'default' => 'standard', - 'options' => wc_get_product_tax_class_options() - ]; - - $products_default_options = - [ - 'no' => __('Do not update', 'wc1c-main'), + 'default' => 'no', + 'options' => $taxes_status_update ]; - $taxes_status_update = array_merge($products_default_options, $taxes_status); - - $fields['products_update_taxes_status'] = + $fields['products_create_taxes_class'] = [ - 'title' => __('Tax status for updated products', 'wc1c-main'), + 'title' => __('Tax class for created products', 'wc1c-main'), 'type' => 'select', 'description' => sprintf ( '%s
%s', - __('Define whether or not the entire product is taxable, or just the cost of shipping it.', 'wc1c-main'), - __('The setting works when updating products (goods).', 'wc1c-main') + __('Choose a tax class for this product. Tax classes are used to apply different tax rates specific to certain types of product.', 'wc1c-main'), + __('The setting works when creating products (goods).', 'wc1c-main') ), - 'default' => 'no', - 'options' => $taxes_status_update + 'default' => 'standard', + 'options' => wc_get_product_tax_class_options() ]; $products_taxes_class_options = array_merge($products_default_options, wc_get_product_tax_class_options()); diff --git a/Core.php b/Core.php index b58a4cf..fff7133 100644 --- a/Core.php +++ b/Core.php @@ -1634,19 +1634,21 @@ public function assignProductsItemTaxesStatus(ProductContract $internal_product, return $internal_product; } - if('update' === $mode && 'no' === $this->getOptions('products_update_taxes_status', 'no')) + if('create' === $mode) { + $internal_product->set_tax_status($this->getOptions('products_create_taxes_status', 'taxable')); + return $internal_product; } - if('create' === $mode) - { - $internal_product->set_tax_status($this->getOptions('products_create_taxes_status', 'taxable')); + $status = $this->getOptions('products_update_taxes_status', 'no'); + if('no' === $status) + { return $internal_product; } - $internal_product->set_tax_status($this->getOptions('products_update_taxes_status', 'taxable')); + $internal_product->set_tax_status($status); return $internal_product; } @@ -1669,19 +1671,21 @@ public function assignProductsItemTaxesClass(ProductContract $internal_product, return $internal_product; } - if('update' === $mode && 'no' === $this->getOptions('products_update_taxes_class', 'no')) + if('create' === $mode) { + $internal_product->set_tax_class($this->getOptions('products_create_taxes_class', 'standard')); + return $internal_product; } - if('create' === $mode) - { - $internal_product->set_tax_class($this->getOptions('products_create_taxes_class', 'standard')); + $class = $this->getOptions('products_update_taxes_class', 'no'); + if('no' === $class) + { return $internal_product; } - $internal_product->set_tax_class($this->getOptions('products_update_taxes_class', 'standard')); + $internal_product->set_tax_class($class); return $internal_product; } From 5510c10961051eb59ea97487036948a0a98e8aff Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Sat, 21 Jan 2023 01:06:49 +0300 Subject: [PATCH 15/35] Fix: more --- Core.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/Core.php b/Core.php index fff7133..735f091 100644 --- a/Core.php +++ b/Core.php @@ -278,9 +278,6 @@ public function receiver() ob_start(); nocache_headers(); - - wc1c()->log('receiver')->info(__('The request was successfully submitted for processing in the schema for the configuration.', 'wc1c-main'), ['action' => $wc1c_receiver_action]); - do_action($wc1c_receiver_action); ob_end_clean(); } From cca9975f37f2316dedbfd85a3a79d267d651320b Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Sat, 21 Jan 2023 01:07:34 +0300 Subject: [PATCH 16/35] Prepare: 0.9.0 --- Core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core.php b/Core.php index 735f091..6223a92 100644 --- a/Core.php +++ b/Core.php @@ -53,7 +53,7 @@ class Core extends SchemaAbstract public function __construct() { $this->setId('productscml'); - $this->setVersion('0.8.0'); + $this->setVersion('0.9.0'); $this->setName(__('Products data exchange via CommerceML', 'wc1c-main')); $this->setDescription(__('Creation and updating of products (goods) in WooCommerce according to data from 1C using the CommerceML protocol of various versions.', 'wc1c-main')); From cb27f4152c8449e6ec780b2907c980294ff65f4b Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Wed, 25 Jan 2023 22:24:37 +0300 Subject: [PATCH 17/35] Fix: more --- Core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core.php b/Core.php index 6223a92..d7fd485 100644 --- a/Core.php +++ b/Core.php @@ -1041,7 +1041,7 @@ public function assignProductsItemName(ProductContract $internal_product, Produc * * @param ProductContract $product Экземпляр продукта - либо существующий, либо новый * - * @return mixed + * @return ProductContract */ public function setProductTimes(ProductContract $product) { From b760d8c2f76ca700b58c21aebec007e5ccee9d73 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Wed, 25 Jan 2023 22:36:51 +0300 Subject: [PATCH 18/35] Fix: more --- Core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core.php b/Core.php index d7fd485..41fbeeb 100644 --- a/Core.php +++ b/Core.php @@ -1043,7 +1043,7 @@ public function assignProductsItemName(ProductContract $internal_product, Produc * * @return ProductContract */ - public function setProductTimes(ProductContract $product) + public function setProductTimes(ProductContract $product): ProductContract { $time = current_time('timestamp'); From e1cacf5a3efc0b47763ab4d6daf9323123f252d3 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Sun, 5 Feb 2023 14:25:03 +0300 Subject: [PATCH 19/35] Fix: get price types from classifier import --- Core.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Core.php b/Core.php index 41fbeeb..e670a9f 100644 --- a/Core.php +++ b/Core.php @@ -847,6 +847,12 @@ public function processingClassifierItem(ClassifierDataContract $classifier, Rea $this->configuration()->updateMetaData('classifier-properties:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_properties); } + $classifier_prices = $classifier->getPriceTypes(); + if(!empty($classifier_prices)) + { + $this->configuration()->updateMetaData('classifier-prices:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_prices); + } + $this->configuration()->save(); } @@ -961,7 +967,7 @@ public function processingCatalog(Reader $reader) { do_action('wc1c_schema_productscml_processing_products_item', $product, $reader, $this); } - catch(Exception $e) + catch(\Throwable $e) { $this->log()->warning(__('An exception was thrown while saving the product.', 'wc1c-main'), ['exception' => $e]); } @@ -3363,6 +3369,20 @@ public function processingOffers(Reader $reader) } } + if($reader->nodeName === 'Предложения' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + { + $this->log()->info(__('Saving the offer package to configuration meta data.', 'wc1c-main'), ['filetype' => $reader->getFiletype()]); + + $this->configuration()->addMetaData('offers_package:' . $reader->getFiletype() . ':' . $reader->offers_package->getId(), maybe_serialize($reader->offers_package), true); + $this->configuration()->saveMetaData(); + + $price_types = $this->configuration()->getMeta('classifier-prices:import:' . $reader->offers_package->getClassifierId()); + if(is_array($price_types)) + { + $reader->offers_package->setPriceTypes($price_types); + } + } + if($reader->parentNodeName === 'Предложения' && $reader->nodeName === 'Предложение' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) { // todo: сохранение пакета предложений From 64c085bdec64928ec530d172459cc12c4bb878d3 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Mon, 6 Feb 2023 22:26:12 +0300 Subject: [PATCH 20/35] Fix: more --- Core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core.php b/Core.php index e670a9f..a26ad01 100644 --- a/Core.php +++ b/Core.php @@ -261,7 +261,7 @@ public function receiver() $this->configuration()->setDateActivity(time()); $this->configuration()->save(); } - catch(Exception $e) + catch(\Throwable $e) { $message = __('Error saving configuration.', 'wc1c-main'); From f24eb6f932d4a26e158ee081ed43ea2f89164aca Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Tue, 7 Feb 2023 01:43:54 +0300 Subject: [PATCH 21/35] Fix: more --- Receiver.php | 67 +++++++++------------------------------------------- 1 file changed, 11 insertions(+), 56 deletions(-) diff --git a/Receiver.php b/Receiver.php index e8c3226..2e0c2c3 100644 --- a/Receiver.php +++ b/Receiver.php @@ -3,6 +3,8 @@ defined('ABSPATH') || exit; use Wc1c\Main\Exceptions\Exception; +use Wc1c\Main\Schemas\Abstracts\Cml\ReceiverAbstract; +use Wc1c\Main\Schemas\Contracts\SchemaContract; use Wc1c\Main\Traits\SingletonTrait; use Wc1c\Main\Traits\UtilityTrait; use Wc1c\Wc\Contracts\ImagesStorageContract; @@ -14,13 +16,13 @@ * * @package Wc1c\Main\Schemas\Productscml */ -final class Receiver +final class Receiver extends ReceiverAbstract { use SingletonTrait; use UtilityTrait; /** - * @var Core Schema core + * @var SchemaContract Core Schema core */ protected $core; @@ -47,68 +49,21 @@ public function initHandler() } /** - * @return Core - */ - public function core(): Core - { + * @return SchemaContract + */ + public function core(): SchemaContract + { return $this->core; } /** - * @param Core $core + * @param SchemaContract $core */ - public function setCore(Core $core) + public function setCore(SchemaContract $core) { $this->core = $core; } - /** - * @return array - */ - public function getModeAndType(): array - { - $data = - [ - 'mode' => '', - 'type' => '' - ]; - - if(wc1c()->getVar($_GET['get_param'], '') !== '' || wc1c()->getVar($_GET['get_param?type'], '') !== '') - { - $output = []; - if(isset($_GET['get_param'])) - { - $get_param = ltrim(sanitize_text_field($_GET['get_param']), '?'); - parse_str($get_param, $output); - } - - if(array_key_exists('mode', $output)) - { - $data['mode'] = sanitize_key($output['mode']); - } - elseif(isset($_GET['mode'])) - { - $data['mode'] = sanitize_key($_GET['mode']); - } - - if(array_key_exists('type', $output)) - { - $data['type'] = sanitize_key($output['type']); - } - elseif(isset($_GET['type'])) - { - $data['type'] = sanitize_key($_GET['type']); - } - - if($data['type'] === '') - { - $data['type'] = sanitize_key($_GET['get_param?type']); - } - } - - return $data; - } - /** * Handler */ @@ -116,7 +71,7 @@ public function handler() { $this->core()->log()->info(__('Received new request for Receiver.', 'wc1c-main')); - $mode_and_type = $this->getModeAndType(); + $mode_and_type = $this->detectModeAndType(); $mode = $mode_and_type['mode']; $type = $mode_and_type['type']; From 910ab3e289bb9a397b138047740a2e6fa6c0ec34 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Fri, 10 Feb 2023 22:52:53 +0300 Subject: [PATCH 22/35] Fix: more --- Core.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Core.php b/Core.php index a26ad01..70319af 100644 --- a/Core.php +++ b/Core.php @@ -917,10 +917,9 @@ public function processingCatalog(Reader $reader) /* * Пропуск создания и обновления продуктов */ - if - ( - $reader->nodeName === 'Товары' && $reader->xml_reader->nodeType === XMLReader::ELEMENT && - 'yes' !== $this->getOptions('products_update', 'no') && 'yes' !== $this->getOptions('products_create', 'no') + if($reader->nodeName === 'Товары' && $reader->xml_reader->nodeType === XMLReader::ELEMENT + && 'yes' !== $this->getOptions('products_update', 'no') + && 'yes' !== $this->getOptions('products_create', 'no') ) { $this->log()->info(__('Products creation and updating is disabled. The processing of goods was skipped.', 'wc1c-main')); @@ -1128,7 +1127,7 @@ public function assignProductsItemSku(ProductContract $internal_product, Product return $internal_product; } - if('update' === $mode && 'yes_yes' === $this->getOptions('products_update_sku', 'no') && empty($internal_product->getSku()) && empty($sku)) + if('update' === $mode && empty($sku) && 'yes_yes' === $this->getOptions('products_update_sku', 'no') && empty($internal_product->getSku())) { return $internal_product; } From 51265dc518b3582d6fc26c6b65b10f27743c472b Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Fri, 10 Feb 2023 23:09:21 +0300 Subject: [PATCH 23/35] SKUs from barcode --- Admin.php | 18 +++++++++++++----- Core.php | 6 ++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Admin.php b/Admin.php index f1185ea..60f9e46 100644 --- a/Admin.php +++ b/Admin.php @@ -891,8 +891,13 @@ public function configurationsFieldsProductsSku(array $fields): array 'title' => __('Filling the SKU of the created product', 'wc1c-main'), 'type' => 'checkbox', 'label' => __('Check the box to enable this feature. Enabled by default.', 'wc1c-main'), - 'description' => __('The product SKU will be added according to data from 1C. It is recommended to enable this feature.', 'wc1c-main'), - 'default' => 'yes' + 'description' => sprintf + ( + '%s
%s', + __('The product SKU will be added according to data from 1C. It is recommended to enable this feature.', 'wc1c-main'), + __('The setting works when creating products (goods).', 'wc1c-main') + ), + 'default' => 'yes' ]; $products_update_sku_options = @@ -929,6 +934,7 @@ public function configurationsFieldsProductsSku(array $fields): array 'no' => __('Do not use', 'wc1c-main'), 'sku' => __('From the standard SKU', 'wc1c-main'), 'code' => __('From the code', 'wc1c-main'), + 'barcode' => __('From the barcode', 'wc1c-main'), 'yes_requisites' => __('From requisite with the specified name', 'wc1c-main'), ]; @@ -938,7 +944,7 @@ public function configurationsFieldsProductsSku(array $fields): array 'type' => 'select', 'description' => sprintf ( - '%s
%s - %s
%s - %s
%s - %s
%s - %s', + '%s
%s - %s
%s - %s
%s - %s
%s - %s
%s - %s', __('The setting works when creating and updating products (goods).', 'wc1c-main'), __('Do not use', 'wc1c-main'), __('Populating the SKU data from CommerceML data will be skipped. If a product is updating, then its current SKU will not be updated.', 'wc1c-main'), @@ -946,10 +952,12 @@ public function configurationsFieldsProductsSku(array $fields): array __('This SKU is contained in the standard SKU of 1C products. It is located in the conditional tag - sku.', 'wc1c-main'), __('From the code', 'wc1c-main'), __('In 1C it is presented in the form of the code of the nomenclature. Unloaded as a requisite with the appropriate name.', 'wc1c-main'), - __('From requisite with the specified name', 'wc1c-main'), + __('From the barcode', 'wc1c-main'), + __('The SKUs will be filled in from the product barcode.', 'wc1c-main'), + __('From requisite with the specified name', 'wc1c-main'), __('The SKU data will be filled in based on the completed name of the requisite of the products (goods).', 'wc1c-main') ), - 'default' => 'name', + 'default' => 'sku', 'options' => $products_sku_by_cml_options ]; diff --git a/Core.php b/Core.php index 70319af..61b4231 100644 --- a/Core.php +++ b/Core.php @@ -1107,6 +1107,12 @@ public function assignProductsItemSku(ProductContract $internal_product, Product } } break; + case 'barcode': + if($barcode = $external_product->getBarcode()) + { + $sku = $barcode; + } + break; case 'yes_requisites': $requisite = $this->getOptions('products_sku_from_requisites_name', ''); if($external_product->hasRequisites($requisite)) From 63cefe686921a8409c4672f0c989c966dcf08c51 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Fri, 10 Feb 2023 23:49:06 +0300 Subject: [PATCH 24/35] Fix: more --- Admin.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Admin.php b/Admin.php index 60f9e46..829adbf 100644 --- a/Admin.php +++ b/Admin.php @@ -1377,9 +1377,8 @@ public function configurationsFieldsProductsImages(array $fields): array 'label' => __('Check the box to enable this feature. Enabled by default.', 'wc1c-main'), 'description' => sprintf ( - '%s
%s', - __('Products in 1C can have images. When this setting is enabled, they will be added to newly created products on the site.', 'wc1c-main'), - __('The choice of a source for a brief images from 1C is in a separate settings block - Products (goods): images.', 'wc1c-main') + '%s', + __('Products in 1C can have images. When this setting is enabled, they will be added to newly created products on the site.', 'wc1c-main') ), 'default' => 'yes' ]; From 26c4643eabb042662b2450fa91ddbad4d5da3e9c Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Sat, 11 Feb 2023 00:24:19 +0300 Subject: [PATCH 25/35] Fix: more --- Receiver.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Receiver.php b/Receiver.php index 2e0c2c3..1323e79 100644 --- a/Receiver.php +++ b/Receiver.php @@ -667,7 +667,8 @@ public function handlerCatalogModeImport() if($filename === '') { $response_description = __('1C sent an empty file name for data import.', 'wc1c-main'); - $this->core()->log()->warning($response_description); + + $this->core()->log()->warning($response_description); $this->sendResponseByType('failure', $response_description); } @@ -676,7 +677,8 @@ public function handlerCatalogModeImport() if(!wc1c()->filesystem()->exists($file)) { $response_description = __('File for import is not exists.', 'wc1c-main'); - $this->core()->log()->error($response_description); + + $this->core()->log()->error($response_description); $this->sendResponseByType('success', $response_description); } @@ -687,19 +689,22 @@ public function handlerCatalogModeImport() if($result_file_processing) { $response_description = __('Import of data from file completed successfully.', 'wc1c-main'); - $this->core()->log()->info($response_description, ['file_name' => $filename, 'file_path' => $file]); + + $this->core()->log()->info($response_description, ['file_name' => $filename, 'file_path' => $file]); $this->sendResponseByType('success', $response_description); } } - catch(Exception $e) + catch(\Throwable $e) { $response_description = __('Importing data from a file ended with an error:', 'wc1c-main') . ' ' . $e->getMessage(); - $this->core()->log()->error($response_description, ['exception' => $e]); + + $this->core()->log()->error($response_description, ['exception' => $e]); $this->sendResponseByType('failure', $response_description); } $response_description = __('Importing data from a file ended with an error.', 'wc1c-main'); - $this->core()->log()->error($response_description); + + $this->core()->log()->error($response_description); $this->sendResponseByType('failure', $response_description); } } \ No newline at end of file From 0a51f3e9ad0127713468a42b74d222391f8af92f Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Sat, 11 Feb 2023 02:52:06 +0300 Subject: [PATCH 26/35] Fix: more --- Core.php | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Core.php b/Core.php index 61b4231..b88ad0f 100644 --- a/Core.php +++ b/Core.php @@ -2,6 +2,7 @@ defined('ABSPATH') || exit; +use SimpleXMLElement; use XMLReader; use Wc1c\Wc\Products\AttributeProduct; use Wc1c\Cml\Contracts\ClassifierDataContract; @@ -313,20 +314,28 @@ public function processingClassifier(Reader $reader) if($reader->nodeName === 'Классификатор' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) { - /** - * Декодируем данные классификатора из XML в объект - */ - $classifier = $reader->decoder()->process('classifier', $reader->xml_reader->readOuterXml()); + $classifier_xml = new SimpleXMLElement($reader->xml_reader->readOuterXml()); + + try + { + $classifier = $reader->decoder()->process('classifier', $classifier_xml); + } + catch(\Throwable $e) + { + $this->log()->warning(__('DecoderCML threw an exception while converting the classifier.', 'wc1c-main'), ['exception' => $e]); + return; + } /** * Внешняя обработка классификатора * * @param ClassifierDataContract $classifier * @param SchemaAbstract $this + * @param SimpleXMLElement $classifier_xml */ if(has_filter('wc1c_schema_productscml_processing_classifier')) { - $classifier = apply_filters('wc1c_schema_productscml_processing_classifier', $classifier, $this); + $classifier = apply_filters('wc1c_schema_productscml_processing_classifier', $classifier, $this, $classifier_xml); } if(!$classifier instanceof ClassifierDataContract) @@ -811,11 +820,6 @@ public function processingClassifierProperties(ClassifierDataContract $classifie */ public function processingClassifierItem(ClassifierDataContract $classifier, Reader $reader) { - if($reader->getFiletype() !== 'import' && $reader->getFiletype() !== 'offers') - { - return; - } - $classifier_push = true; $all_classifiers = $this->configuration()->getMeta('classifier:' . $reader->getFiletype(), false, 'edit'); @@ -853,6 +857,18 @@ public function processingClassifierItem(ClassifierDataContract $classifier, Rea $this->configuration()->updateMetaData('classifier-prices:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_prices); } + $classifier_units = $classifier->getUnits(); + if(!empty($classifier_units)) + { + $this->configuration()->updateMetaData('classifier-units:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_units); + } + + $classifier_warehouses = $classifier->getWarehouses(); + if(!empty($classifier_warehouses)) + { + $this->configuration()->updateMetaData('classifier-warehouses:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_warehouses); + } + $this->configuration()->save(); } From a7d8461dda565f12686604e560212c84e141ad63 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Sat, 11 Feb 2023 03:56:35 +0300 Subject: [PATCH 27/35] Fix: more --- Core.php | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Core.php b/Core.php index b88ad0f..e40049f 100644 --- a/Core.php +++ b/Core.php @@ -312,7 +312,7 @@ public function processingClassifier(Reader $reader) return; } - if($reader->nodeName === 'Классификатор' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + if($reader->nodeName === 'Классификатор' && $reader->isElement()) { $classifier_xml = new SimpleXMLElement($reader->xml_reader->readOuterXml()); @@ -892,7 +892,7 @@ public function processingCatalog(Reader $reader) $reader->catalog = new Catalog(); } - if($reader->nodeName === 'Каталог' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + if($reader->nodeName === 'Каталог' && $reader->isElement()) { $only_changes = $reader->xml_reader->getAttribute('СодержитТолькоИзменения') ?: true; if($only_changes === 'false') @@ -902,7 +902,7 @@ public function processingCatalog(Reader $reader) $reader->catalog->setOnlyChanges($only_changes); } - if($reader->parentNodeName === 'Каталог' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + if($reader->parentNodeName === 'Каталог' && $reader->isElement()) { switch($reader->nodeName) { @@ -933,7 +933,7 @@ public function processingCatalog(Reader $reader) /* * Пропуск создания и обновления продуктов */ - if($reader->nodeName === 'Товары' && $reader->xml_reader->nodeType === XMLReader::ELEMENT + if($reader->nodeName === 'Товары' && $reader->isElement() && 'yes' !== $this->getOptions('products_update', 'no') && 'yes' !== $this->getOptions('products_create', 'no') ) @@ -942,14 +942,14 @@ public function processingCatalog(Reader $reader) $reader->next(); } - if($reader->parentNodeName === 'Товары' && $reader->nodeName === 'Товар' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + if($reader->parentNodeName === 'Товары' && $reader->nodeName === 'Товар' && $reader->isElement()) { - // todo: сохранение каталога + $product_xml = new SimpleXMLElement($reader->xml_reader->readOuterXml()); /** * Декодирование данных продукта из XML в объект реализующий ProductDataContract */ - $product = $reader->decoder->process('product', $reader->xml_reader->readOuterXml()); + $product = $reader->decoder->process('product', $product_xml); /** * Внешняя фильтрация перед непосредственной обработкой @@ -957,10 +957,11 @@ public function processingCatalog(Reader $reader) * @param ProductDataContract $product * @param Reader $reader * @param SchemaAbstract $this + * @param SimpleXMLElement $product_xml */ if(has_filter('wc1c_schema_productscml_processing_products')) { - $product = apply_filters('wc1c_schema_productscml_processing_products', $product, $reader, $this); + $product = apply_filters('wc1c_schema_productscml_processing_products', $product, $reader, $this, $product_xml); } if(!$product instanceof ProductDataContract) @@ -3346,7 +3347,7 @@ public function processingOffers(Reader $reader) $reader->offers_package = new OffersPackage(); } - if($reader->nodeName === 'ПакетПредложений' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + if($reader->nodeName === 'ПакетПредложений' && $reader->isElement()) { $only_changes = $reader->xml_reader->getAttribute('СодержитТолькоИзменения') ?: true; if($only_changes === 'false') @@ -3356,7 +3357,7 @@ public function processingOffers(Reader $reader) $reader->offers_package->setOnlyChanges($only_changes); } - if($reader->parentNodeName === 'ПакетПредложений' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + if($reader->parentNodeName === 'ПакетПредложений' && $reader->isElement()) { switch($reader->nodeName) { @@ -3390,7 +3391,7 @@ public function processingOffers(Reader $reader) } } - if($reader->nodeName === 'Предложения' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + if($reader->nodeName === 'Предложения' && $reader->isElement()) { $this->log()->info(__('Saving the offer package to configuration meta data.', 'wc1c-main'), ['filetype' => $reader->getFiletype()]); @@ -3404,7 +3405,7 @@ public function processingOffers(Reader $reader) } } - if($reader->parentNodeName === 'Предложения' && $reader->nodeName === 'Предложение' && $reader->xml_reader->nodeType === XMLReader::ELEMENT) + if($reader->parentNodeName === 'Предложения' && $reader->nodeName === 'Предложение' && $reader->isElement()) { // todo: сохранение пакета предложений From 49e7507cd0d7a4397f3006eb86c27f3491003cbe Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:06:00 +0300 Subject: [PATCH 28/35] Fix: more --- Receiver.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Receiver.php b/Receiver.php index 1323e79..937cfee 100644 --- a/Receiver.php +++ b/Receiver.php @@ -77,6 +77,10 @@ public function handler() $this->core()->log()->debug(__('Received request params.', 'wc1c-main'), ['type' => $type, 'mode=' => $mode]); + $this->core()->configuration()->addMetaData('_receiver_mode', $mode, true); + $this->core()->configuration()->addMetaData('_receiver_type', $type, true); + $this->core()->configuration()->saveMetaData(); + if($type === 'catalog' && $mode !== '') { do_action('wc1c_schema_productscml_catalog_handler', $mode, $this); @@ -114,7 +118,8 @@ public function handler() do_action('wc1c_schema_productscml_handler_none', $mode, $this); - $response_description = __('Schema: action not found.', 'wc1c-main'); + $response_description = __('Action is not found in schema.', 'wc1c-main'); + $this->core()->log()->warning($response_description); $this->sendResponseByType('failure', $response_description); } @@ -261,14 +266,18 @@ public function handlerCheckauth() { if($credentials['login'] !== $this->core()->getOptions('user_login', '')) { - $this->core()->log()->notice(__('Not a valid username.', 'wc1c-main')); - $this->sendResponseByType('failure', __('Not a valid username.', 'wc1c-main')); + $message = __('Not a valid username.', 'wc1c-main'); + + $this->core()->log()->notice($message); + $this->sendResponseByType('failure', $message); } if($credentials['password'] !== $this->core()->getOptions('user_password', '')) { - $this->core()->log()->notice(__('Not a valid user password.', 'wc1c-main')); - $this->sendResponseByType('failure', __('Not a valid user password.', 'wc1c-main')); + $message = __('Not a valid user password.', 'wc1c-main'); + + $this->core()->log()->notice($message); + $this->sendResponseByType('failure', $message); } } @@ -389,7 +398,7 @@ public function handlerCheckauthKey(bool $send_response = false): bool { session_id($session_id); - $this->core()->log()->info(__('PHP session none, restart PHP session.', 'wc1c-main'), ['session_id' => $session_id]); + $this->core()->log()->info(__('PHP session none, restart last PHP session.', 'wc1c-main'), ['session_id' => $session_id]); session_start(); } @@ -534,6 +543,7 @@ public function handlerCatalogModeFile() if(empty($filename)) { $response_description = __('Filename is empty.', 'wc1c-main'); + $this->core()->log()->error($response_description); $this->sendResponseByType('failure', $response_description); } From fc2a0b408e3815a45f3dbd04247cfbb01a5cdd1b Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:40:30 +0300 Subject: [PATCH 29/35] Times for images --- Core.php | 24 ++++++++++++++++++++++++ Receiver.php | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/Core.php b/Core.php index e40049f..72f5e18 100644 --- a/Core.php +++ b/Core.php @@ -3,6 +3,7 @@ defined('ABSPATH') || exit; use SimpleXMLElement; +use Wc1c\Wc\Entities\Image; use XMLReader; use Wc1c\Wc\Products\AttributeProduct; use Wc1c\Cml\Contracts\ClassifierDataContract; @@ -1081,6 +1082,29 @@ public function setProductTimes(ProductContract $product): ProductContract return $product; } + /** + * Назначение данных по времени для изображений + * + * @param Image $image Экземпляр продукта - либо существующий, либо новый + * + * @return Image + */ + public function setImageTimes(Image $image): Image + { + $time = current_time('timestamp'); + + /** + * _wc1c_time + * _wc1c_schema_time_{schema_id} + * _wc1c_configuration_time_{configuration_id} + */ + $image->updateMetaData('_wc1c_time', $time); + $image->updateMetaData('_wc1c_schema_time_' . $this->getId(), $time); + $image->updateMetaData('_wc1c_configuration_time_' . $this->configuration()->getId(), $time); + + return $image; + } + /** * Назначение данных продукта исходя из режима: артикул * diff --git a/Receiver.php b/Receiver.php index 937cfee..97df9c5 100644 --- a/Receiver.php +++ b/Receiver.php @@ -624,6 +624,7 @@ public function handlerCatalogModeFile() if(false === $image_current) { $new_image = new Image(); + $this->core()->setImageTimes($new_image); $new_image->setName(__('No name', 'wc1c-main')); $new_image->setExternalName($image_file_name[0]); @@ -648,6 +649,9 @@ public function handlerCatalogModeFile() } else { + $image_current = $this->core()->setImageTimes($image_current); + $image_current->save(); + $response_description .= '. ' . __('The image has not been added to the media library. It was added earlier, id:', 'wc1c-main') . ' ' . $image_current->getId(); } } From 2bfbb37b4a762a4abf4b99fa377aef1d011909e5 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:56:24 +0300 Subject: [PATCH 30/35] Fix: more --- Core.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Core.php b/Core.php index 72f5e18..d5a1954 100644 --- a/Core.php +++ b/Core.php @@ -4,7 +4,6 @@ use SimpleXMLElement; use Wc1c\Wc\Entities\Image; -use XMLReader; use Wc1c\Wc\Products\AttributeProduct; use Wc1c\Cml\Contracts\ClassifierDataContract; use Wc1c\Cml\Contracts\ProductDataContract; From aa670e919698b85751cff27620203820f0c278a7 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Mon, 13 Feb 2023 23:33:31 +0300 Subject: [PATCH 31/35] Fix: more --- Receiver.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/Receiver.php b/Receiver.php index 97df9c5..bcf5d27 100644 --- a/Receiver.php +++ b/Receiver.php @@ -5,6 +5,7 @@ use Wc1c\Main\Exceptions\Exception; use Wc1c\Main\Schemas\Abstracts\Cml\ReceiverAbstract; use Wc1c\Main\Schemas\Contracts\SchemaContract; +use Wc1c\Main\Traits\CoreTrait; use Wc1c\Main\Traits\SingletonTrait; use Wc1c\Main\Traits\UtilityTrait; use Wc1c\Wc\Contracts\ImagesStorageContract; @@ -20,6 +21,7 @@ final class Receiver extends ReceiverAbstract { use SingletonTrait; use UtilityTrait; + use CoreTrait; /** * @var SchemaContract Core Schema core @@ -48,22 +50,6 @@ public function initHandler() add_action('wc1c_schema_productscml_catalog_handler_complete', [$this, 'handlerCatalogModeComplete'], 10, 0); } - /** - * @return SchemaContract - */ - public function core(): SchemaContract - { - return $this->core; - } - - /** - * @param SchemaContract $core - */ - public function setCore(SchemaContract $core) - { - $this->core = $core; - } - /** * Handler */ From e169a628e35cb10afbd70c4a2fc29a0a420857f1 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Mon, 13 Feb 2023 23:34:54 +0300 Subject: [PATCH 32/35] Fix: more --- Admin.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/Admin.php b/Admin.php index 829adbf..7d6ff9f 100644 --- a/Admin.php +++ b/Admin.php @@ -2,6 +2,7 @@ defined('ABSPATH') || exit; +use Wc1c\Main\Traits\CoreTrait; use Wc1c\Main\Traits\SingletonTrait; use Wc1c\Main\Traits\UtilityTrait; @@ -14,28 +15,13 @@ class Admin { use SingletonTrait; use UtilityTrait; + use CoreTrait; /** * @var Core Schema core */ protected $core; - /** - * @return Core - */ - public function core(): Core - { - return $this->core; - } - - /** - * @param Core $core - */ - public function setCore(Core $core) - { - $this->core = $core; - } - /** * @return void */ From 90082bf6e56ed97e4953397f45af02681ae1890c Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Mon, 13 Feb 2023 23:44:30 +0300 Subject: [PATCH 33/35] Interface CoreContract --- Contracts/CoreContract.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Contracts/CoreContract.php diff --git a/Contracts/CoreContract.php b/Contracts/CoreContract.php new file mode 100644 index 0000000..1589185 --- /dev/null +++ b/Contracts/CoreContract.php @@ -0,0 +1,13 @@ + Date: Thu, 16 Feb 2023 20:54:25 +0300 Subject: [PATCH 34/35] Fix: more --- Core.php | 152 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 117 insertions(+), 35 deletions(-) diff --git a/Core.php b/Core.php index d5a1954..b2b32c4 100644 --- a/Core.php +++ b/Core.php @@ -3,6 +3,7 @@ defined('ABSPATH') || exit; use SimpleXMLElement; +use Wc1c\Main\Traits\UtilityTrait; use Wc1c\Wc\Entities\Image; use Wc1c\Wc\Products\AttributeProduct; use Wc1c\Cml\Contracts\ClassifierDataContract; @@ -33,6 +34,8 @@ */ class Core extends SchemaAbstract { + use UtilityTrait; + /** * @var string Текущий каталог в файловой системе */ @@ -48,6 +51,16 @@ class Core extends SchemaAbstract */ public $receiver; + /** + * @var string[] + */ + public $offers_types = + [ + 'offers', + 'rests', + 'prices', + ]; + /** * Core constructor. */ @@ -159,6 +172,22 @@ public function getUploadDirectory(): string return $this->upload_directory; } + /** + * @return array string[] + */ + public function getOffersTypes(): array + { + return $this->offers_types; + } + + /** + * @param string[] $offers_types + */ + public function setOffersTypes(array $offers_types) + { + $this->offers_types = $offers_types; + } + /** * @param mixed $upload_directory */ @@ -302,11 +331,6 @@ public function receiver() */ public function processingClassifier(Reader $reader) { - if($reader->filetype !== 'import' && $reader->filetype !== 'offers') - { - return; - } - if(!is_null($reader->classifier)) { return; @@ -314,6 +338,12 @@ public function processingClassifier(Reader $reader) if($reader->nodeName === 'Классификатор' && $reader->isElement()) { + $only_changes = $reader->xml_reader->getAttribute('СодержитТолькоИзменения') ?: false; + if($only_changes === 'true') + { + $only_changes = true; + } + $classifier_xml = new SimpleXMLElement($reader->xml_reader->readOuterXml()); try @@ -326,6 +356,8 @@ public function processingClassifier(Reader $reader) return; } + $classifier->setOnlyChanges($only_changes); + /** * Внешняя обработка классификатора * @@ -821,7 +853,7 @@ public function processingClassifierProperties(ClassifierDataContract $classifie public function processingClassifierItem(ClassifierDataContract $classifier, Reader $reader) { $classifier_push = true; - $all_classifiers = $this->configuration()->getMeta('classifier:' . $reader->getFiletype(), false, 'edit'); + $all_classifiers = $this->configuration()->getMeta('classifier', false, 'edit'); if(!empty($all_classifiers) && is_array($all_classifiers)) { @@ -839,34 +871,66 @@ public function processingClassifierItem(ClassifierDataContract $classifier, Rea if($classifier_push) { - $this->configuration()->addMetaData('classifier:' . $reader->getFiletype(), ['id' => $classifier->getId(), 'name' => $classifier->getName()]); $this->configuration()->addMetaData('classifier', ['id' => $classifier->getId(), 'name' => $classifier->getName(), 'filetype' => $reader->getFiletype()]); } - $this->configuration()->updateMetaData('classifier:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier); + $internal_classifier = $this->configuration()->getMeta('classifier:' . $classifier->getId(), true, 'edit'); + + /* + * Если классификатор существует, обновляем данные пришедшего из текущего + */ + if($internal_classifier instanceof ClassifierDataContract) + { + if($internal_classifier->hasProperties()) + { + $classifier->assignProperties($internal_classifier->getProperties()); + } + + if($internal_classifier->hasGroups()) + { + $classifier->assignGroups($internal_classifier->getGroups()); + } + + if($internal_classifier->hasUnits()) + { + $classifier->assignUnits($internal_classifier->getUnits()); + } + + if($internal_classifier->hasWarehouses()) + { + $classifier->assignWarehouses($internal_classifier->getWarehouses()); + } + + if($internal_classifier->hasPriceTypes()) + { + $classifier->assignPriceTypes($internal_classifier->getPriceTypes()); + } + } + + $this->configuration()->updateMetaData('classifier:' . $classifier->getId(), $classifier); $classifier_properties = $classifier->getProperties(); if(!empty($classifier_properties)) { - $this->configuration()->updateMetaData('classifier-properties:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_properties); + $this->configuration()->updateMetaData('classifier-properties:' . $classifier->getId(), $classifier_properties); } $classifier_prices = $classifier->getPriceTypes(); if(!empty($classifier_prices)) { - $this->configuration()->updateMetaData('classifier-prices:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_prices); + $this->configuration()->updateMetaData('classifier-price-types:' . $classifier->getId(), $classifier_prices); } $classifier_units = $classifier->getUnits(); if(!empty($classifier_units)) { - $this->configuration()->updateMetaData('classifier-units:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_units); + $this->configuration()->updateMetaData('classifier-units:' . $classifier->getId(), $classifier_units); } $classifier_warehouses = $classifier->getWarehouses(); if(!empty($classifier_warehouses)) { - $this->configuration()->updateMetaData('classifier-warehouses:' . $reader->getFiletype() . ':' . $classifier->getId(), $classifier_warehouses); + $this->configuration()->updateMetaData('classifier-warehouses:' . $classifier->getId(), $classifier_warehouses); } $this->configuration()->save(); @@ -3354,17 +3418,11 @@ public function processingOffersItem(ProductDataContract $external_offer, Reader */ public function processingOffers(Reader $reader) { - $types = - [ - 'offers', - 'rests', - 'prices', - ]; - - if(!in_array($reader->getFiletype(), $types)) + if(!in_array($reader->getFiletype(), $this->getOffersTypes(), true)) { return; } + if(is_null($reader->offers_package)) { $reader->offers_package = new OffersPackage(); @@ -3378,23 +3436,36 @@ public function processingOffers(Reader $reader) $only_changes = false; } $reader->offers_package->setOnlyChanges($only_changes); + + if($only_changes) + { + $this->log()->debug(__('The offer package object contains only the changes.', 'wc1c-main')); + } + } + elseif($reader->nodeName === 'ИзмененияПакетаПредложений' && $reader->isElement()) + { + $this->log()->debug(__('The offer package object contains only the changes.', 'wc1c-main')); + $reader->offers_package->setOnlyChanges(true); } - if($reader->parentNodeName === 'ПакетПредложений' && $reader->isElement()) + if(($reader->parentNodeName === 'ПакетПредложений' || $reader->parentNodeName === 'ИзмененияПакетаПредложений') && $reader->isElement()) { switch($reader->nodeName) { case 'Ид': - $reader->offers_package->setId($reader->xml_reader->readString()); + $id = $reader->decoder()->normalizeId($reader->xml_reader->readString()); + $reader->offers_package->setId($id); break; case 'Наименование': $reader->offers_package->setName($reader->xml_reader->readString()); break; case 'ИдКаталога': - $reader->offers_package->setCatalogId($reader->xml_reader->readString()); + $id = $reader->decoder()->normalizeId($reader->xml_reader->readString()); + $reader->offers_package->setCatalogId($id); break; case 'ИдКлассификатора': - $reader->offers_package->setClassifierId($reader->xml_reader->readString()); + $id = $reader->decoder()->normalizeId($reader->xml_reader->readString()); + $reader->offers_package->setClassifierId($id); break; case 'Владелец': $owner = $reader->decoder()->process('counterparty', $reader->xml_reader->readOuterXml()); @@ -3416,27 +3487,38 @@ public function processingOffers(Reader $reader) if($reader->nodeName === 'Предложения' && $reader->isElement()) { - $this->log()->info(__('Saving the offer package to configuration meta data.', 'wc1c-main'), ['filetype' => $reader->getFiletype()]); + if(false === $reader->offers_package->isOnlyChanges()) + { + $this->log()->info(__('Saving the offer package to configuration meta data.', 'wc1c-main'), ['filetype' => $reader->getFiletype()]); - $this->configuration()->addMetaData('offers_package:' . $reader->getFiletype() . ':' . $reader->offers_package->getId(), maybe_serialize($reader->offers_package), true); - $this->configuration()->saveMetaData(); + $this->configuration()->addMetaData('offers_package:' . $reader->offers_package->getId(), $reader->offers_package, true); + $this->configuration()->saveMetaData(); + } - $price_types = $this->configuration()->getMeta('classifier-prices:import:' . $reader->offers_package->getClassifierId()); - if(is_array($price_types)) - { - $reader->offers_package->setPriceTypes($price_types); - } + if(empty($reader->offers_package->getPriceTypes())) + { + $price_types = $this->configuration()->getMeta('classifier-prices:import:' . $reader->offers_package->getClassifierId()); + if(is_array($price_types)) + { + $reader->offers_package->setPriceTypes($price_types); + } + } + + if('yes' === $this->getOptions('browser_debug', 'no')) + { + $this->dump($reader->offers_package); + } } if($reader->parentNodeName === 'Предложения' && $reader->nodeName === 'Предложение' && $reader->isElement()) { - // todo: сохранение пакета предложений + $offer_xml = new SimpleXMLElement($reader->xml_reader->readOuterXml()); - $offer = $reader->decoder->process('offer', $reader->xml_reader->readOuterXml()); + $offer = $reader->decoder->process('offer', $offer_xml); if(has_filter('wc1c_schema_productscml_processing_offers')) { - $offer = apply_filters('wc1c_schema_productscml_processing_offers', $offer, $reader, $this); + $offer = apply_filters('wc1c_schema_productscml_processing_offers', $offer, $reader, $this, $offer_xml); } if(!$offer instanceof ProductDataContract) From c9cdb0376ed00faffef1e70f71d8b25060291e21 Mon Sep 17 00:00:00 2001 From: Oleg <109225168+frescoref@users.noreply.github.com> Date: Thu, 16 Feb 2023 21:53:26 +0300 Subject: [PATCH 35/35] Fix: more --- Core.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Core.php b/Core.php index b2b32c4..e95160c 100644 --- a/Core.php +++ b/Core.php @@ -909,6 +909,18 @@ public function processingClassifierItem(ClassifierDataContract $classifier, Rea $this->configuration()->updateMetaData('classifier:' . $classifier->getId(), $classifier); + $classifier_groups = $classifier->getGroups(); + if(!empty($classifier_groups)) + { + $this->configuration()->updateMetaData('classifier-groups:' . $classifier->getId(), $classifier_groups); + } + + $classifier_categories = $classifier->getCategories(); + if(!empty($classifier_categories)) + { + $this->configuration()->updateMetaData('classifier-categories:' . $classifier->getId(), $classifier_categories); + } + $classifier_properties = $classifier->getProperties(); if(!empty($classifier_properties)) {