├── README.md ├── test └── protocol.py └── upload ├── admin ├── language │ ├── english │ │ └── module │ │ │ └── exchange1c.php │ └── russian │ │ └── module │ │ └── exchange1c.php ├── view │ └── template │ │ └── module │ │ └── exchange1c.tpl ├── controller │ └── module │ │ └── exchange1c.php └── model │ └── tool │ └── exchange1c.php ├── vqmod └── xml │ └── exchange1c.xml └── export └── exchange1c.php /README.md: -------------------------------------------------------------------------------- 1 | **Модуль не развивается с октября 2014 года.** Пожалуйста, имейте ввиду, что с новыми версиями OpenCart и 1C могут быть проблемы. Сейчас у меня нет планов на его дальнейшее развитие. 2 | 3 | # OpenCart Exchange 1C # 4 | 5 | Модуль обмена данными с 1С 8.x в формате CommerceML2 для OpenCart 6 | 7 | * Домашняя страница: http://zenwalker.ru/lab/opencart-exchange1c/ 8 | * Видеоинструкция установки: https://www.youtube.com/watch?v=wv_-ve_p1LA 9 | * Исходные коды: https://github.com/ethernet1/opencart-exchange1c 10 | * Тема поддержки: http://opencartforum.ru/topic/15471-opencart-exchange-1c/ 11 | 12 | ## Возможности ## 13 | 14 | * Выгрузка полной иерархии категорий 15 | * Выгрузка изображений 16 | * Выгрузка скидок 17 | * Выгрузка свойств (в атрибуты) 18 | * Обмен заказами (односторонний, OpenCart → 1C) 19 | * Наложение водяных знаков на загружаемые картинки товаров 20 | * Ручной импорт товаров через форму в админке 21 | * Автогенерация SEO URL (требуется Deadcow SEO 2.1) 22 | * Автогенерация SEO URL (путем транслитерации, применяется к товарам, производителям, категориям) (issue #12) 23 | 24 | ## Установка ## 25 | 26 | Установка модуля ничем не отличается от остальных, но для работы потребуется [vQmod](http://code.google.com/p/vqmod/downloads/list). 27 | 28 | 1. Загрузить содержимое директории upload в корень сайта 29 | 2. Активировать модуль в настройках и задать логин/пароль 30 | 3. В 1С в качестве адреса выгрузки указать http://%sitename%/export/exchange1c.php 31 | 32 | ## Лицензия ## 33 | 34 | Данное программное обеспечение распространяется на условиях [GNU General Public License v3.0](http://www.gnu.org/licenses/gpl.html). 35 | -------------------------------------------------------------------------------- /test/protocol.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from sys import stdout, stderr, argv 5 | import requests 6 | 7 | 8 | class Protocol: 9 | cookies = {} 10 | 11 | def __init__(self, base_url): 12 | self.base_url = base_url; 13 | 14 | def get_url(self): 15 | return self.base_url + "/export/exchange1c.php" 16 | 17 | def checkauth(self, username, password): 18 | response = requests.get(self.get_url(), 19 | params={"type": "sale", "mode": "checkauth"}, 20 | auth=(username, password) 21 | ) 22 | 23 | data = response.text.split("\n") 24 | status = data[0] 25 | 26 | if status == "success": 27 | cookie_name = data[1] 28 | cookie_value = data[2] 29 | self.cookies[cookie_name] = cookie_value 30 | return (True, None) 31 | 32 | elif status == "failure": 33 | message = data[1] 34 | return (False, "ERROR: %s \n" % message) 35 | 36 | return (False, "Unknown answer: %s \n" % response.text) 37 | 38 | def query_orders(self): 39 | response = requests.get(self.get_url(), 40 | params={"type": "sale", "mode": "query"}, 41 | cookies=self.cookies 42 | ) 43 | 44 | if not response.text.startswith(" (depends on Deadcow SEO)'; 41 | $_['entry_seo_url_deadcow'] = 'via Deadcow SEO'; 42 | $_['entry_seo_url_translit'] = 'Transliterate'; 43 | 44 | $_['entry_full_log'] = 'Enable log'; 45 | $_['entry_apply_watermark'] = 'Apply watermark'; 46 | $_['text_image_manager'] = 'Image Manager'; 47 | $_['text_browse'] = 'Browse Files'; 48 | $_['text_clear'] = 'Clear Image'; 49 | 50 | $_['entry_order_status_to_exchange'] = 'Orders status to exchange:'; 51 | $_['entry_order_status_to_exchange_not'] = "- don not use -"; 52 | $_['entry_relatedoptions'] = 'Load characteristics as related options (need extension Related Options):'; 53 | $_['entry_relatedoptions_help'] = 'Related options settings should be turned on: "Recalc quantity", "Update options", "Use different related options variants" '; 54 | $_['entry_dont_use_artsync'] = 'Do not search products by sku:'; 55 | 56 | $_['entry_order_status'] = 'Uploaded orders status:'; 57 | $_['entry_order_notify'] = 'Notify users of status change:'; 58 | $_['entry_order_currency'] = 'Orders currency:'; 59 | 60 | $_['entry_upload'] = 'Select file:'; 61 | $_['button_upload'] = 'Upload'; 62 | 63 | // Error 64 | $_['error_permission'] = 'Premission denied!'; -------------------------------------------------------------------------------- /upload/admin/language/russian/module/exchange1c.php: -------------------------------------------------------------------------------- 1 | требуется модуль Deadcow SEO)'; 41 | $_['entry_seo_url_deadcow'] = 'через Deadcow SEO'; 42 | $_['entry_seo_url_translit'] = 'Транслитерация'; 43 | 44 | $_['entry_full_log'] = 'Включить подробный лог загрузки'; 45 | $_['entry_apply_watermark'] = 'Накладывать водяные знаки при загрузке'; 46 | $_['text_image_manager'] = 'Менеджер изображений'; 47 | $_['text_browse'] = 'Обзор'; 48 | $_['text_clear'] = 'Очистить'; 49 | 50 | $_['entry_order_status_to_exchange'] = 'Выгружать заказы со статусом:'; 51 | $_['entry_order_status_to_exchange_not'] = '- не использовать -'; 52 | $_['entry_relatedoptions'] = 'Загружать характеристики как связанные опции (требуется модуль Связанные опции):'; 53 | $_['entry_relatedoptions_help'] = 'в настройках связанных опций обязательно должна быть включены галки: "Пересчитывать количество", "Обновлять опции", "Использовать различные варианты связанных опций" '; 54 | $_['entry_dont_use_artsync'] = 'Не искать товары по артикулам:'; 55 | 56 | $_['entry_order_status'] = 'Статус выгруженых заказов:'; 57 | $_['entry_order_notify'] = 'Уведомлять пользователей о смене статуса:'; 58 | $_['entry_order_currency'] = 'Обозначение валюты (руб.):'; 59 | 60 | $_['entry_upload'] = 'Выберите файл:'; 61 | $_['button_upload'] = 'Загрузить'; 62 | 63 | // Error 64 | $_['error_permission'] = 'У Вас нет прав для управления этим модулем!'; -------------------------------------------------------------------------------- /upload/vqmod/xml/exchange1c.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | data['feed'] = $this->url->link('extension/feed', 'token=' . $this->session->data['token'], 'SSL');]]> 38 | data['exchange1c'] = $this->url->link('module/exchange1c', 'token=' . $this->session->data['token'], 'SSL');]]> 39 | 40 | 41 | 42 | 43 | 44 | ]]> 45 | Opencart Exchange 1C]]> 46 | 47 | 48 | 49 | 50 | 51 | image = $this->create($file);]]> 52 | image = $this->create($file, 'auto');]]> 53 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | create($file);]]> 65 | create($file, $mime);]]> 66 | 67 | 68 | 69 | info['width'])/3; 72 | $watermark_pos_y = ($this->info['height'])/3; 73 | break; 74 | ]]> 75 | 76 | 77 | image, $watermark, $watermark_pos_x, $watermark_pos_y, 0, 0, 120, 40);]]> 78 | info['width']; 80 | $new_watermark_height = $this->info['height']; 81 | if ($watermark_width > 0) { 82 | $new_watermark_width = $this->info['width']; 83 | $new_watermark_height = $watermark_height * $this->info['width'] / $watermark_width; 84 | } 85 | imagecopyresized ($this->image , $watermark, 0, $watermark_pos_y, 0, 0, $new_watermark_width, $new_watermark_height, $watermark_width, $watermark_height); 86 | ]]> 87 | 88 | 89 | create($file);]]> 90 | create($file, 'auto');]]> 91 | 92 | 93 | -------------------------------------------------------------------------------- /upload/export/exchange1c.php: -------------------------------------------------------------------------------- 1 | set('load', $loader); 33 | 34 | // Config 35 | $config = new Config(); 36 | $registry->set('config', $config); 37 | 38 | // Database 39 | $db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE); 40 | $registry->set('db', $db); 41 | 42 | // Settings 43 | $query = $db->query("SELECT * FROM " . DB_PREFIX . "setting"); 44 | 45 | foreach ($query->rows as $setting) { 46 | if (!$setting['serialized']) { 47 | $config->set($setting['key'], $setting['value']); 48 | } else { 49 | $config->set($setting['key'], unserialize($setting['value'])); 50 | } 51 | } 52 | 53 | // Log 54 | $log = new Log($config->get('config_error_filename')); 55 | $registry->set('log', $log); 56 | 57 | // Error Handler 58 | function error_handler($errno, $errstr, $errfile, $errline) { 59 | global $config, $log; 60 | 61 | if (0 === error_reporting()) return TRUE; 62 | switch ($errno) { 63 | case E_NOTICE: 64 | case E_USER_NOTICE: 65 | $error = 'Notice'; 66 | break; 67 | case E_WARNING: 68 | case E_USER_WARNING: 69 | $error = 'Warning'; 70 | break; 71 | case E_ERROR: 72 | case E_USER_ERROR: 73 | $error = 'Fatal Error'; 74 | break; 75 | default: 76 | $error = 'Unknown'; 77 | break; 78 | } 79 | 80 | if ($config->get('config_error_display')) { 81 | echo '' . $error . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline . ''; 82 | } 83 | 84 | if ($config->get('config_error_log')) { 85 | $log->write('PHP ' . $error . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline); 86 | } 87 | 88 | return TRUE; 89 | } 90 | 91 | // Error Handler 92 | set_error_handler('error_handler'); 93 | 94 | // Request 95 | $request = new Request(); 96 | $registry->set('request', $request); 97 | 98 | // Response 99 | $response = new Response(); 100 | $response->addHeader('Content-Type: text/html; charset=utf-8'); 101 | $registry->set('response', $response); 102 | 103 | // Session 104 | $registry->set('session', new Session()); 105 | 106 | // Cache 107 | $registry->set('cache', new Cache()); 108 | 109 | // Document 110 | $registry->set('document', new Document()); 111 | 112 | // Language 113 | $languages = array(); 114 | 115 | $query = $db->query("SELECT * FROM " . DB_PREFIX . "language"); 116 | 117 | foreach ($query->rows as $result) { 118 | $languages[$result['code']] = array( 119 | 'language_id' => $result['language_id'], 120 | 'name' => $result['name'], 121 | 'code' => $result['code'], 122 | 'locale' => $result['locale'], 123 | 'directory' => $result['directory'], 124 | 'filename' => $result['filename'] 125 | ); 126 | } 127 | 128 | $config->set('config_language_id', $languages[$config->get('config_admin_language')]['language_id']); 129 | 130 | $language = new Language($languages[$config->get('config_admin_language')]['directory']); 131 | $language->load($languages[$config->get('config_admin_language')]['filename']); 132 | $registry->set('language', $language); 133 | 134 | // Currency 135 | $registry->set('currency', new Currency($registry)); 136 | 137 | // Weight 138 | $registry->set('weight', new Weight($registry)); 139 | 140 | // Length 141 | $registry->set('length', new Length($registry)); 142 | 143 | // User 144 | $registry->set('user', new User($registry)); 145 | 146 | // Front Controller 147 | $controller = new Front($registry); 148 | 149 | 150 | // Router 151 | if (isset($request->get['mode']) && $request->get['type'] == 'catalog') { 152 | 153 | switch ($request->get['mode']) { 154 | case 'checkauth': 155 | $action = new Action('module/exchange1c/modeCheckauth'); 156 | break; 157 | 158 | case 'init': 159 | $action = new Action('module/exchange1c/modeCatalogInit'); 160 | break; 161 | 162 | case 'file': 163 | $action = new Action('module/exchange1c/modeFile'); 164 | break; 165 | 166 | case 'import': 167 | $action = new Action('module/exchange1c/modeImport'); 168 | break; 169 | 170 | default: 171 | echo "success\n"; 172 | } 173 | 174 | } else if (isset($request->get['mode']) && $request->get['type'] == 'sale') { 175 | 176 | switch ($request->get['mode']) { 177 | case 'checkauth': 178 | $action = new Action('module/exchange1c/modeCheckauth'); 179 | break; 180 | 181 | case 'init': 182 | $action = new Action('module/exchange1c/modeSaleInit'); 183 | break; 184 | 185 | case 'query': 186 | $action = new Action('module/exchange1c/modeQueryOrders'); 187 | break; 188 | 189 | case 'success': 190 | $action = new Action('module/exchange1c/modeOrdersChangeStatus'); 191 | break; 192 | 193 | default: 194 | echo "success\n"; 195 | } 196 | 197 | } else { 198 | echo "success\n"; 199 | exit; 200 | } 201 | 202 | // Dispatch 203 | if (isset($action)) { 204 | $controller->dispatch($action, new Action('error/not_found')); 205 | } 206 | 207 | // Output 208 | $response->output(); 209 | ?> 210 | -------------------------------------------------------------------------------- /upload/admin/view/template/module/exchange1c.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 10 | 11 | 12 |
13 | 14 | 15 |
16 |
17 |
18 |
19 |

20 |
21 |
22 |
23 |
24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 62 | 63 |
60 | 61 |
64 |
65 | 66 |
67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
-- 
116 | 117 | 118 | 119 | 120 | 123 | 124 | 125 | 126 | 127 | 130 | 131 | 132 | 133 | 134 | 137 | 138 | 139 | 140 | 141 | 144 | 145 | 146 | 147 | 148 | 151 | 152 | 153 | 154 | 155 | 158 | 159 | 160 | 161 | 165 | 166 | 167 | 168 | 171 | 172 | 173 | 174 | 175 | 183 | 184 | 185 | 186 | 187 | 190 | 191 | 192 | 193 | 194 | 210 | 211 |
121 | > 122 |
128 | > 129 |
135 | > 136 |
142 | > 143 |
149 | > 150 |
156 | > 157 |
162 | > 163 | 164 |
169 | > 170 |
176 | 177 | 182 |
188 | > 189 |
195 | > 196 |
197 | 198 |
199 | 200 | 201 |   |   202 | 203 | 204 | 205 |
206 | 207 | 208 | 209 |
212 |
213 | 214 |
215 | 216 | 217 | 218 | 219 | 227 | 228 | 229 | 230 | 231 | 238 | 239 | 240 | 241 | 242 | 245 | 246 | 247 | 248 | 249 | 252 | 253 | 254 |
220 | 226 |
232 | 237 |
243 | 244 |
250 | > 251 |
255 |
256 | 257 |
258 | 259 | 260 | 263 | 266 | 269 | 270 |
261 | 262 | 264 | 265 | 267 | 268 |
271 |
272 | 273 |
274 | 275 |
276 | 277 |
278 |

|

279 |
280 |
281 |
282 | 283 | 286 | 287 | 288 | 312 | 335 | 362 | 363 | 364 | -------------------------------------------------------------------------------- /upload/admin/controller/module/exchange1c.php: -------------------------------------------------------------------------------- 1 | load->language('module/exchange1c'); 8 | $this->load->model('tool/image'); 9 | 10 | //$this->document->title = $this->language->get('heading_title'); 11 | $this->document->setTitle($this->language->get('heading_title')); 12 | 13 | $this->load->model('setting/setting'); 14 | 15 | if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { 16 | $this->request->post['exchange1c_order_date'] = $this->config->get('exchange1c_order_date'); 17 | $this->model_setting_setting->editSetting('exchange1c', $this->request->post); 18 | $this->session->data['success'] = $this->language->get('text_success'); 19 | $this->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL')); 20 | } 21 | 22 | $this->data['version'] = 'Version 1.6.0'; 23 | 24 | $this->data['heading_title'] = $this->language->get('heading_title'); 25 | $this->data['entry_username'] = $this->language->get('entry_username'); 26 | $this->data['entry_password'] = $this->language->get('entry_password'); 27 | $this->data['entry_allow_ip'] = $this->language->get('entry_allow_ip'); 28 | $this->data['text_price_default'] = $this->language->get('text_price_default'); 29 | $this->data['entry_config_price_type'] = $this->language->get('entry_config_price_type'); 30 | $this->data['entry_customer_group'] = $this->language->get('entry_customer_group'); 31 | $this->data['entry_quantity'] = $this->language->get('entry_quantity'); 32 | $this->data['entry_priority'] = $this->language->get('entry_priority'); 33 | $this->data['entry_flush_product'] = $this->language->get('entry_flush_product'); 34 | $this->data['entry_flush_category'] = $this->language->get('entry_flush_category'); 35 | $this->data['entry_flush_manufacturer'] = $this->language->get('entry_flush_manufacturer'); 36 | $this->data['entry_flush_quantity'] = $this->language->get('entry_flush_quantity'); 37 | $this->data['entry_flush_attribute'] = $this->language->get('entry_flush_attribute'); 38 | $this->data['entry_fill_parent_cats'] = $this->language->get('entry_fill_parent_cats'); 39 | $this->data['entry_seo_url'] = $this->language->get('entry_seo_url'); 40 | $this->data['entry_seo_url_deadcow'] = $this->language->get('entry_seo_url_deadcow'); 41 | $this->data['entry_seo_url_translit'] = $this->language->get('entry_seo_url_translit'); 42 | $this->data['entry_full_log'] = $this->language->get('entry_full_log'); 43 | $this->data['entry_apply_watermark'] = $this->language->get('entry_apply_watermark'); 44 | $this->data['no_image'] = $this->model_tool_image->resize('no_image.jpg', 100, 100); 45 | $this->data['text_image_manager'] = $this->language->get('text_image_manager'); 46 | $this->data['text_browse'] = $this->language->get('text_browse'); 47 | $this->data['text_clear'] = $this->language->get('text_clear'); 48 | $this->data['entry_name'] = $this->language->get('entry_name'); 49 | $this->data['entry_image'] = $this->language->get('entry_image'); 50 | 51 | $this->data['entry_relatedoptions'] = $this->language->get('entry_relatedoptions'); 52 | $this->data['entry_relatedoptions_help'] = $this->language->get('entry_relatedoptions_help'); 53 | $this->data['entry_order_status_to_exchange'] = $this->language->get('entry_order_status_to_exchange'); 54 | $this->data['entry_order_status_to_exchange_not'] = $this->language->get('entry_order_status_to_exchange_not'); 55 | $this->data['entry_dont_use_artsync'] = $this->language->get('entry_dont_use_artsync'); 56 | 57 | $this->data['text_yes'] = $this->language->get('text_yes'); 58 | $this->data['text_no'] = $this->language->get('text_no'); 59 | $this->data['text_enabled'] = $this->language->get('text_enabled'); 60 | $this->data['text_disabled'] = $this->language->get('text_disabled'); 61 | $this->data['text_tab_general'] = $this->language->get('text_tab_general'); 62 | $this->data['text_tab_product'] = $this->language->get('text_tab_product'); 63 | $this->data['text_tab_order'] = $this->language->get('text_tab_order'); 64 | $this->data['text_tab_manual'] = $this->language->get('text_tab_manual'); 65 | $this->data['text_empty'] = $this->language->get('text_empty'); 66 | $this->data['text_max_filesize'] = sprintf($this->language->get('text_max_filesize'), @ini_get('max_file_uploads')); 67 | $this->data['text_homepage'] = $this->language->get('text_homepage'); 68 | $this->data['source_code'] = $this->language->get('source_code'); 69 | $this->data['entry_status'] = $this->language->get('entry_status'); 70 | $this->data['entry_order_status'] = $this->language->get('entry_order_status'); 71 | $this->data['entry_order_currency'] = $this->language->get('entry_order_currency'); 72 | $this->data['entry_order_notify'] = $this->language->get('entry_order_notify'); 73 | $this->data['entry_upload'] = $this->language->get('entry_upload'); 74 | $this->data['button_upload'] = $this->language->get('button_upload'); 75 | 76 | $this->data['button_save'] = $this->language->get('button_save'); 77 | $this->data['button_cancel'] = $this->language->get('button_cancel'); 78 | $this->data['button_insert'] = $this->language->get('button_insert'); 79 | $this->data['button_remove'] = $this->language->get('button_remove'); 80 | 81 | if (isset($this->error['warning'])) { 82 | $this->data['error_warning'] = $this->error['warning']; 83 | } 84 | else { 85 | $this->data['error_warning'] = ''; 86 | } 87 | 88 | if (isset($this->error['image'])) { 89 | $this->data['error_image'] = $this->error['image']; 90 | } else { 91 | $this->data['error_image'] = ''; 92 | } 93 | 94 | if (isset($this->error['exchange1c_username'])) { 95 | $this->data['error_exchange1c_username'] = $this->error['exchange1c_username']; 96 | } 97 | else { 98 | $this->data['error_exchange1c_username'] = ''; 99 | } 100 | 101 | if (isset($this->error['exchange1c_password'])) { 102 | $this->data['error_exchange1c_password'] = $this->error['exchange1c_password']; 103 | } 104 | else { 105 | $this->data['error_exchange1c_password'] = ''; 106 | } 107 | 108 | $this->data['breadcrumbs'] = array(); 109 | 110 | $this->data['breadcrumbs'][] = array( 111 | 'text' => $this->language->get('text_home'), 112 | 'href' => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'), 113 | 'separator' => false 114 | ); 115 | 116 | $this->data['breadcrumbs'][] = array( 117 | 'text' => $this->language->get('text_module'), 118 | 'href' => $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'), 119 | 'separator' => ' :: ' 120 | ); 121 | 122 | $this->data['breadcrumbs'][] = array( 123 | 'text' => $this->language->get('heading_title'), 124 | 'href' => $this->url->link('module/exchange1c', 'token=' . $this->session->data['token'], 'SSL'), 125 | 'separator' => ' :: ' 126 | ); 127 | 128 | $this->data['token'] = $this->session->data['token']; 129 | 130 | //$this->data['action'] = HTTPS_SERVER . 'index.php?route=module/exchange1c&token=' . $this->session->data['token']; 131 | $this->data['action'] = $this->url->link('module/exchange1c', 'token=' . $this->session->data['token'], 'SSL'); 132 | 133 | //$this->data['cancel'] = HTTPS_SERVER . 'index.php?route=extension/exchange1c&token=' . $this->session->data['token']; 134 | $this->data['cancel'] = $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'); 135 | 136 | if (isset($this->request->post['exchange1c_username'])) { 137 | $this->data['exchange1c_username'] = $this->request->post['exchange1c_username']; 138 | } 139 | else { 140 | $this->data['exchange1c_username'] = $this->config->get('exchange1c_username'); 141 | } 142 | 143 | if (isset($this->request->post['exchange1c_password'])) { 144 | $this->data['exchange1c_password'] = $this->request->post['exchange1c_password']; 145 | } 146 | else { 147 | $this->data['exchange1c_password'] = $this->config->get('exchange1c_password'); 148 | } 149 | 150 | if (isset($this->request->post['exchange1c_allow_ip'])) { 151 | $this->data['exchange1c_allow_ip'] = $this->request->post['exchange1c_allow_ip']; 152 | } 153 | else { 154 | $this->data['exchange1c_allow_ip'] = $this->config->get('exchange1c_allow_ip'); 155 | } 156 | 157 | if (isset($this->request->post['exchange1c_status'])) { 158 | $this->data['exchange1c_status'] = $this->request->post['exchange1c_status']; 159 | } 160 | else { 161 | $this->data['exchange1c_status'] = $this->config->get('exchange1c_status'); 162 | } 163 | 164 | if (isset($this->request->post['exchange1c_price_type'])) { 165 | $this->data['exchange1c_price_type'] = $this->request->post['exchange1c_price_type']; 166 | } 167 | else { 168 | $this->data['exchange1c_price_type'] = $this->config->get('exchange1c_price_type'); 169 | if(empty($this->data['exchange1c_price_type'])) { 170 | $this->data['exchange1c_price_type'][] = array( 171 | 'keyword' => '', 172 | 'customer_group_id' => 0, 173 | 'quantity' => 0, 174 | 'priority' => 0 175 | ); 176 | } 177 | } 178 | 179 | if (isset($this->request->post['exchange1c_flush_product'])) { 180 | $this->data['exchange1c_flush_product'] = $this->request->post['exchange1c_flush_product']; 181 | } 182 | else { 183 | $this->data['exchange1c_flush_product'] = $this->config->get('exchange1c_flush_product'); 184 | } 185 | 186 | if (isset($this->request->post['exchange1c_flush_category'])) { 187 | $this->data['exchange1c_flush_category'] = $this->request->post['exchange1c_flush_category']; 188 | } 189 | else { 190 | $this->data['exchange1c_flush_category'] = $this->config->get('exchange1c_flush_category'); 191 | } 192 | 193 | if (isset($this->request->post['exchange1c_flush_manufacturer'])) { 194 | $this->data['exchange1c_flush_manufacturer'] = $this->request->post['exchange1c_flush_manufacturer']; 195 | } 196 | else { 197 | $this->data['exchange1c_flush_manufacturer'] = $this->config->get('exchange1c_flush_manufacturer'); 198 | } 199 | 200 | if (isset($this->request->post['exchange1c_flush_quantity'])) { 201 | $this->data['exchange1c_flush_quantity'] = $this->request->post['exchange1c_flush_quantity']; 202 | } 203 | else { 204 | $this->data['exchange1c_flush_quantity'] = $this->config->get('exchange1c_flush_quantity'); 205 | } 206 | 207 | if (isset($this->request->post['exchange1c_flush_attribute'])) { 208 | $this->data['exchange1c_flush_attribute'] = $this->request->post['exchange1c_flush_attribute']; 209 | } 210 | else { 211 | $this->data['exchange1c_flush_attribute'] = $this->config->get('exchange1c_flush_attribute'); 212 | } 213 | 214 | if (isset($this->request->post['exchange1c_fill_parent_cats'])) { 215 | $this->data['exchange1c_fill_parent_cats'] = $this->request->post['exchange1c_fill_parent_cats']; 216 | } 217 | else { 218 | $this->data['exchange1c_fill_parent_cats'] = $this->config->get('exchange1c_fill_parent_cats'); 219 | } 220 | 221 | if (isset($this->request->post['exchange1c_relatedoptions'])) { 222 | $this->data['exchange1c_relatedoptions'] = $this->request->post['exchange1c_relatedoptions']; 223 | } else { 224 | $this->data['exchange1c_relatedoptions'] = $this->config->get('exchange1c_relatedoptions'); 225 | } 226 | if (isset($this->request->post['exchange1c_order_status_to_exchange'])) { 227 | $this->data['exchange1c_order_status_to_exchange'] = $this->request->post['exchange1c_order_status_to_exchange']; 228 | } else { 229 | $this->data['exchange1c_order_status_to_exchange'] = $this->config->get('exchange1c_order_status_to_exchange'); 230 | } 231 | 232 | if (isset($this->request->post['exchange1c_dont_use_artsync'])) { 233 | $this->data['exchange1c_dont_use_artsync'] = $this->request->post['exchange1c_dont_use_artsync']; 234 | } else { 235 | $this->data['exchange1c_dont_use_artsync'] = $this->config->get('exchange1c_dont_use_artsync'); 236 | } 237 | 238 | if (isset($this->request->post['exchange1c_seo_url'])) { 239 | $this->data['exchange1c_seo_url'] = $this->request->post['exchange1c_seo_url']; 240 | } 241 | else { 242 | $this->data['exchange1c_seo_url'] = $this->config->get('exchange1c_seo_url'); 243 | } 244 | 245 | if (isset($this->request->post['exchange1c_full_log'])) { 246 | $this->data['exchange1c_full_log'] = $this->request->post['exchange1c_full_log']; 247 | } 248 | else { 249 | $this->data['exchange1c_full_log'] = $this->config->get('exchange1c_full_log'); 250 | } 251 | 252 | if (isset($this->request->post['exchange1c_apply_watermark'])) { 253 | $this->data['exchange1c_apply_watermark'] = $this->request->post['exchange1c_apply_watermark']; 254 | } 255 | else { 256 | $this->data['exchange1c_apply_watermark'] = $this->config->get('exchange1c_apply_watermark'); 257 | } 258 | 259 | if (isset($this->request->post['exchange1c_watermark'])) { 260 | $this->data['exchange1c_watermark'] = $this->request->post['exchange1c_watermark']; 261 | } 262 | else { 263 | $this->data['exchange1c_watermark'] = $this->config->get('exchange1c_watermark'); 264 | } 265 | 266 | if (isset($this->data['exchange1c_watermark'])) { 267 | $this->data['thumb'] = $this->model_tool_image->resize($this->data['exchange1c_watermark'], 100, 100); 268 | } 269 | else { 270 | $this->data['thumb'] = $this->model_tool_image->resize('no_image.jpg', 100, 100); 271 | } 272 | 273 | if (isset($this->request->post['exchange1c_order_status'])) { 274 | $this->data['exchange1c_order_status'] = $this->request->post['exchange1c_order_status']; 275 | } 276 | else { 277 | $this->data['exchange1c_order_status'] = $this->config->get('exchange1c_order_status'); 278 | } 279 | 280 | if (isset($this->request->post['exchange1c_order_currency'])) { 281 | $this->data['exchange1c_order_currency'] = $this->request->post['exchange1c_order_currency']; 282 | } 283 | else { 284 | $this->data['exchange1c_order_currency'] = $this->config->get('exchange1c_order_currency'); 285 | } 286 | 287 | if (isset($this->request->post['exchange1c_order_notify'])) { 288 | $this->data['exchange1c_order_notify'] = $this->request->post['exchange1c_order_notify']; 289 | } 290 | else { 291 | $this->data['exchange1c_order_notify'] = $this->config->get('exchange1c_order_notify'); 292 | } 293 | 294 | // Группы 295 | $this->load->model('sale/customer_group'); 296 | $this->data['customer_groups'] = $this->model_sale_customer_group->getCustomerGroups(); 297 | 298 | $this->load->model('localisation/order_status'); 299 | 300 | $order_statuses = $this->model_localisation_order_status->getOrderStatuses(); 301 | 302 | foreach ($order_statuses as $order_status) { 303 | $this->data['order_statuses'][] = array( 304 | 'order_status_id' => $order_status['order_status_id'], 305 | 'name' => $order_status['name'] 306 | ); 307 | } 308 | 309 | $this->template = 'module/exchange1c.tpl'; 310 | $this->children = array( 311 | 'common/header', 312 | 'common/footer' 313 | ); 314 | 315 | $this->response->setOutput($this->render(), $this->config->get('config_compression')); 316 | } 317 | 318 | private function validate() { 319 | 320 | if (!$this->user->hasPermission('modify', 'module/exchange1c')) { 321 | $this->error['warning'] = $this->language->get('error_permission'); 322 | } 323 | 324 | if (!$this->error) { 325 | return true; 326 | } 327 | else { 328 | return false; 329 | } 330 | } 331 | 332 | public function install() {} 333 | 334 | public function uninstall() {} 335 | 336 | // --- 337 | public function modeCheckauth() { 338 | 339 | // Проверяем включен или нет модуль 340 | if (!$this->config->get('exchange1c_status')) { 341 | echo "failure\n"; 342 | echo "1c module OFF"; 343 | exit; 344 | } 345 | 346 | // Разрешен ли IP 347 | if ($this->config->get('exchange1c_allow_ip') != '') { 348 | $ip = $_SERVER['REMOTE_ADDR']; 349 | $allow_ips = explode("\r\n", $this->config->get('exchange1c_allow_ip')); 350 | 351 | if (!in_array($ip, $allow_ips)) { 352 | echo "failure\n"; 353 | echo "IP is not allowed"; 354 | exit; 355 | } 356 | } 357 | 358 | // Авторизуем 359 | if (($this->config->get('exchange1c_username') != '') && (@$_SERVER['PHP_AUTH_USER'] != $this->config->get('exchange1c_username'))) { 360 | echo "failure\n"; 361 | echo "error login"; 362 | } 363 | 364 | if (($this->config->get('exchange1c_password') != '') && (@$_SERVER['PHP_AUTH_PW'] != $this->config->get('exchange1c_password'))) { 365 | echo "failure\n"; 366 | echo "error password"; 367 | exit; 368 | } 369 | 370 | echo "success\n"; 371 | echo "key\n"; 372 | echo md5($this->config->get('exchange1c_password')) . "\n"; 373 | } 374 | 375 | public function manualImport() { 376 | $this->load->language('module/exchange1c'); 377 | 378 | $cache = DIR_CACHE . 'exchange1c/'; 379 | $json = array(); 380 | 381 | if (!empty($this->request->files['file']['name'])) { 382 | 383 | $zip = new ZipArchive; 384 | 385 | if ($zip->open($this->request->files['file']['tmp_name']) === true) { 386 | $this->modeCatalogInit(false); 387 | 388 | $zip->extractTo($cache); 389 | $files = scandir($cache); 390 | 391 | foreach ($files as $file) { 392 | if (is_file($cache . $file)) { 393 | $this->modeImport($file); 394 | } 395 | } 396 | 397 | if (is_dir($cache . 'import_files')) { 398 | $images = DIR_IMAGE . 'import_files/'; 399 | 400 | if (is_dir($images)) { 401 | $this->cleanDir($images); 402 | } 403 | 404 | rename($cache . 'import_files/', $images); 405 | } 406 | 407 | } 408 | else { 409 | 410 | // Читаем первые 1024 байт и определяем файл по сигнатуре, ибо мало ли, какое у него имя 411 | $handle = fopen($this->request->files['file']['tmp_name'], 'r'); 412 | $buffer = fread($handle, 1024); 413 | fclose($handle); 414 | 415 | if (strpos($buffer, 'Классификатор')) { 416 | $this->modeCatalogInit(false); 417 | move_uploaded_file($this->request->files['file']['tmp_name'], $cache . 'import.xml'); 418 | $this->modeImport('import.xml'); 419 | 420 | } 421 | else if (strpos($buffer, 'ПакетПредложений')) { 422 | move_uploaded_file($this->request->files['file']['tmp_name'], $cache . 'offers.xml'); 423 | $this->modeImport('offers.xml'); 424 | } 425 | else { 426 | $json['error'] = $this->language->get('text_upload_error'); 427 | exit; 428 | } 429 | } 430 | 431 | $json['success'] = $this->language->get('text_upload_success'); 432 | } 433 | 434 | $this->response->setOutput(json_encode($json)); 435 | } 436 | 437 | public function modeCatalogInit($echo = true) { 438 | 439 | $this->load->model('tool/exchange1c'); 440 | 441 | // чистим кеш, убиваем старые данные 442 | $this->cleanCacheDir(); 443 | 444 | // Проверяем естль ли БД для хранения промежуточных данных. 445 | $this->model_tool_exchange1c->checkDbSheme(); 446 | 447 | // Очищаем таблицы 448 | $this->model_tool_exchange1c->flushDb(array( 449 | 'product' => $this->config->get('exchange1c_flush_product'), 450 | 'category' => $this->config->get('exchange1c_flush_category'), 451 | 'manufacturer' => $this->config->get('exchange1c_flush_manufacturer'), 452 | 'attribute' => $this->config->get('exchange1c_flush_attribute'), 453 | 'full_log' => $this->config->get('exchange1c_full_log'), 454 | 'apply_watermark' => $this->config->get('exchange1c_apply_watermark'), 455 | 'quantity' => $this->config->get('exchange1c_flush_quantity') 456 | )); 457 | 458 | $limit = 100000 * 1024; 459 | 460 | if ($echo) { 461 | echo "zip=no\n"; 462 | echo "file_limit=".$limit."\n"; 463 | } 464 | 465 | } 466 | 467 | public function modeSaleInit() { 468 | $limit = 100000 * 1024; 469 | 470 | echo "zip=no\n"; 471 | echo "file_limit=".$limit."\n"; 472 | } 473 | 474 | public function modeFile() { 475 | 476 | if (!isset($this->request->cookie['key'])) { 477 | return; 478 | } 479 | 480 | if ($this->request->cookie['key'] != md5($this->config->get('exchange1c_password'))) { 481 | echo "failure\n"; 482 | echo "Session error"; 483 | return; 484 | } 485 | 486 | $cache = DIR_CACHE . 'exchange1c/'; 487 | 488 | // Проверяем на наличие имени файла 489 | if (isset($this->request->get['filename'])) { 490 | $uplod_file = $cache . $this->request->get['filename']; 491 | } 492 | else { 493 | echo "failure\n"; 494 | echo "ERROR 10: No file name variable"; 495 | return; 496 | } 497 | 498 | // Проверяем XML или изображения 499 | if (strpos($this->request->get['filename'], 'import_files') !== false) { 500 | $cache = DIR_IMAGE; 501 | $uplod_file = $cache . $this->request->get['filename']; 502 | $this->checkUploadFileTree(dirname($this->request->get['filename']) , $cache); 503 | } 504 | 505 | // Получаем данные 506 | $data = file_get_contents("php://input"); 507 | 508 | if ($data !== false) { 509 | if ($fp = fopen($uplod_file, "wb")) { 510 | $result = fwrite($fp, $data); 511 | 512 | if ($result === strlen($data)) { 513 | echo "success\n"; 514 | 515 | chmod($uplod_file , 0777); 516 | //echo "success\n"; 517 | } 518 | else { 519 | echo "failure\n"; 520 | } 521 | } 522 | else { 523 | echo "failure\n"; 524 | echo "Can not open file: $uplod_file\n"; 525 | echo $cache; 526 | } 527 | } 528 | else { 529 | echo "failure\n"; 530 | echo "No data file\n"; 531 | } 532 | 533 | 534 | } 535 | 536 | public function modeImport($manual = false) { 537 | 538 | $cache = DIR_CACHE . 'exchange1c/'; 539 | 540 | if ($manual) { 541 | $filename = $manual; 542 | $importFile = $cache . $filename; 543 | } 544 | else if (isset($this->request->get['filename'])) { 545 | $filename = $this->request->get['filename']; 546 | $importFile = $cache . $filename; 547 | } 548 | else { 549 | echo "failure\n"; 550 | echo "ERROR 10: No file name variable"; 551 | return 0; 552 | } 553 | 554 | $this->load->model('tool/exchange1c'); 555 | 556 | // Определяем текущую локаль 557 | $language_id = $this->model_tool_exchange1c->getLanguageId($this->config->get('config_language')); 558 | 559 | if (strpos($filename, 'import') !== false) { 560 | 561 | $this->model_tool_exchange1c->parseImport($filename, $language_id); 562 | 563 | if ($this->config->get('exchange1c_fill_parent_cats')) { 564 | $this->model_tool_exchange1c->fillParentsCategories(); 565 | } 566 | // Только если выбран способ deadcow_seo 567 | if ($this->config->get('exchange1c_seo_url') == 1) { 568 | $this->load->model('module/deadcow_seo'); 569 | $this->model_module_deadcow_seo->generateCategories($this->config->get('deadcow_seo_categories_template'), 'Russian'); 570 | $this->model_module_deadcow_seo->generateProducts($this->config->get('deadcow_seo_products_template'), 'Russian'); 571 | $this->model_module_deadcow_seo->generateManufacturers($this->config->get('deadcow_seo_manufacturers_template'), 'Russian'); 572 | } 573 | 574 | if (!$manual) { 575 | echo "success\n"; 576 | } 577 | 578 | } 579 | else if (strpos($filename, 'offers') !== false) { 580 | $exchange1c_price_type = $this->config->get('exchange1c_price_type'); 581 | $this->model_tool_exchange1c->parseOffers($filename, $exchange1c_price_type, $language_id); 582 | 583 | if (!$manual) { 584 | echo "success\n"; 585 | } 586 | } 587 | else { 588 | echo "failure\n"; 589 | echo $filename; 590 | } 591 | 592 | $this->cache->delete('product'); 593 | return; 594 | } 595 | 596 | public function modeQueryOrders() { 597 | if (!isset($this->request->cookie['key'])) { 598 | echo "Cookie fail\n"; 599 | return; 600 | } 601 | 602 | if ($this->request->cookie['key'] != md5($this->config->get('exchange1c_password'))) { 603 | echo "failure\n"; 604 | echo "Session error"; 605 | return; 606 | } 607 | 608 | $this->load->model('tool/exchange1c'); 609 | 610 | $orders = $this->model_tool_exchange1c->queryOrders(array( 611 | 'from_date' => $this->config->get('exchange1c_order_date') 612 | ,'exchange_status' => $this->config->get('exchange1c_order_status_to_exchange') 613 | ,'new_status' => $this->config->get('exchange1c_order_status') 614 | ,'notify' => $this->config->get('exchange1c_order_notify') 615 | ,'currency' => $this->config->get('exchange1c_order_currency') ? $this->config->get('exchange1c_order_currency') : 'руб.' 616 | )); 617 | 618 | echo iconv('utf-8', 'cp1251', $orders); 619 | } 620 | 621 | /** 622 | * Changing order statuses. 623 | */ 624 | public function modeOrdersChangeStatus(){ 625 | if (!isset($this->request->cookie['key'])) { 626 | echo "Cookie fail\n"; 627 | return; 628 | } 629 | 630 | if ($this->request->cookie['key'] != md5($this->config->get('exchange1c_password'))) { 631 | echo "failure\n"; 632 | echo "Session error"; 633 | return; 634 | } 635 | 636 | $this->load->model('tool/exchange1c'); 637 | 638 | $result = $this->model_tool_exchange1c->queryOrdersStatus(array( 639 | 'from_date' => $this->config->get('exchange1c_order_date'), 640 | 'exchange_status' => $this->config->get('exchange1c_order_status_to_exchange'), 641 | 'new_status' => $this->config->get('exchange1c_order_status'), 642 | 'notify' => $this->config->get('exchange1c_order_notify') 643 | )); 644 | 645 | if($result){ 646 | $this->load->model('setting/setting'); 647 | $config = $this->model_setting_setting->getSetting('exchange1c'); 648 | $config['exchange1c_order_date'] = date('Y-m-d H:i:s'); 649 | $this->model_setting_setting->editSetting('exchange1c', $config); 650 | } 651 | 652 | if($result) 653 | echo "success\n"; 654 | else 655 | echo "fail\n"; 656 | } 657 | 658 | 659 | // -- Системные процедуры 660 | private function cleanCacheDir() { 661 | 662 | // Проверяем есть ли директория 663 | if (file_exists(DIR_CACHE . 'exchange1c')) { 664 | if (is_dir(DIR_CACHE . 'exchange1c')) { 665 | return $this->cleanDir(DIR_CACHE . 'exchange1c/'); 666 | } 667 | else { 668 | unlink(DIR_CACHE . 'exchange1c'); 669 | } 670 | } 671 | 672 | mkdir (DIR_CACHE . 'exchange1c'); 673 | 674 | return 0; 675 | } 676 | 677 | private function checkUploadFileTree($path, $curDir = null) { 678 | 679 | if (!$curDir) $curDir = DIR_CACHE . 'exchange1c/'; 680 | 681 | foreach (explode('/', $path) as $name) { 682 | 683 | if (!$name) continue; 684 | 685 | if (file_exists($curDir . $name)) { 686 | if (is_dir( $curDir . $name)) { 687 | $curDir = $curDir . $name . '/'; 688 | continue; 689 | } 690 | 691 | unlink ($curDir . $name); 692 | } 693 | 694 | mkdir ($curDir . $name ); 695 | $curDir = $curDir . $name . '/'; 696 | } 697 | 698 | } 699 | 700 | 701 | private function cleanDir($root, $self = false) { 702 | 703 | $dir = dir($root); 704 | 705 | while ($file = $dir->read()) { 706 | if ($file == '.' || $file == '..') continue; 707 | if (file_exists($root . $file)) { 708 | if (is_file($root . $file)) { unlink($root . $file); continue; } 709 | if (is_dir($root . $file)) { $this->cleanDir($root . $file . '/', true); continue; } 710 | var_dump ($file); 711 | } 712 | var_dump($file); 713 | } 714 | 715 | if ($self) { 716 | if(file_exists($root) && is_dir($root)) { 717 | rmdir($root); return 0; 718 | } 719 | 720 | var_dump($root); 721 | } 722 | return 0; 723 | } 724 | 725 | } 726 | ?> 727 | -------------------------------------------------------------------------------- /upload/admin/model/tool/exchange1c.php: -------------------------------------------------------------------------------- 1 | load->model('sale/order'); 21 | 22 | if ($params['exchange_status'] != 0) { 23 | $query = $this->db->query("SELECT order_id FROM `" . DB_PREFIX . "order` WHERE `order_status_id` = " . $params['exchange_status'] . ""); 24 | } else { 25 | $query = $this->db->query("SELECT order_id FROM `" . DB_PREFIX . "order` WHERE `date_added` >= '" . $params['from_date'] . "'"); 26 | } 27 | 28 | $document = array(); 29 | $document_counter = 0; 30 | 31 | if ($query->num_rows) { 32 | 33 | foreach ($query->rows as $orders_data) { 34 | 35 | $order = $this->model_sale_order->getOrder($orders_data['order_id']); 36 | 37 | $date = date('Y-m-d', strtotime($order['date_added'])); 38 | $time = date('H:i:s', strtotime($order['date_added'])); 39 | 40 | $document['Документ' . $document_counter] = array( 41 | 'Ид' => $order['order_id'] 42 | ,'Номер' => $order['order_id'] 43 | ,'Дата' => $date 44 | ,'Время' => $time 45 | ,'Валюта' => $params['currency'] 46 | ,'Курс' => 1 47 | ,'ХозОперация' => 'Заказ товара' 48 | ,'Роль' => 'Продавец' 49 | ,'Сумма' => $order['total'] 50 | ,'Комментарий' => $order['comment'] 51 | ); 52 | 53 | $document['Документ' . $document_counter]['Контрагенты']['Контрагент'] = array( 54 | 'Ид' => $order['customer_id'] . '#' . $order['email'] 55 | ,'Наименование' => $order['payment_lastname'] . ' ' . $order['payment_firstname'] 56 | ,'Роль' => 'Покупатель' 57 | ,'ПолноеНаименование' => $order['payment_lastname'] . ' ' . $order['payment_firstname'] 58 | ,'Фамилия' => $order['payment_lastname'] 59 | ,'Имя' => $order['payment_firstname'] 60 | ,'Адрес' => array( 61 | 'Представление' => $order['shipping_address_1'].', '.$order['shipping_city'].', '.$order['shipping_postcode'].', '.$order['shipping_country'] 62 | ) 63 | ,'Контакты' => array( 64 | 'Контакт1' => array( 65 | 'Тип' => 'ТелефонРабочий' 66 | ,'Значение' => $order['telephone'] 67 | ) 68 | ,'Контакт2' => array( 69 | 'Тип' => 'Почта' 70 | ,'Значение' => $order['email'] 71 | ) 72 | ) 73 | ); 74 | 75 | // Товары 76 | $products = $this->model_sale_order->getOrderProducts($orders_data['order_id']); 77 | 78 | $product_counter = 0; 79 | foreach ($products as $product) { 80 | $id = $this->get1CProductIdByProductId($product['product_id']); 81 | 82 | $document['Документ' . $document_counter]['Товары']['Товар' . $product_counter] = array( 83 | 'Ид' => $id 84 | ,'Наименование' => $product['name'] 85 | ,'ЦенаЗаЕдиницу' => $product['price'] 86 | ,'Количество' => $product['quantity'] 87 | ,'Сумма' => $product['total'] 88 | ); 89 | 90 | if ($this->config->get('exchange1c_relatedoptions')) { 91 | $this->load->model('module/related_options'); 92 | if ($this->model_module_related_options->get_product_related_options_use($product['product_id'])) { 93 | $order_options = $this->model_sale_order->getOrderOptions($orders_data['order_id'], $product['order_product_id']); 94 | $options = array(); 95 | foreach ($order_options as $order_option) { 96 | $options[$order_option['product_option_id']] = $order_option['product_option_value_id']; 97 | } 98 | if (count($options) > 0) { 99 | $ro = $this->model_module_related_options->get_related_options_set_by_poids($product['product_id'], $options); 100 | if ($ro != FALSE) { 101 | $char_id = $this->model_module_related_options->get_char_id($ro['relatedoptions_id']); 102 | if ($char_id != FALSE) { 103 | $document['Документ' . $document_counter]['Товары']['Товар' . $product_counter]['Ид'] .= "#".$char_id; 104 | } 105 | } 106 | } 107 | 108 | } 109 | 110 | } 111 | 112 | $product_counter++; 113 | } 114 | 115 | $document_counter++; 116 | } 117 | } 118 | 119 | $root = '<КоммерческаяИнформация ВерсияСхемы="2.04" ДатаФормирования="' . date('Y-m-d', time()) . '" />'; 120 | $xml = $this->array_to_xml($document, new SimpleXMLElement($root)); 121 | 122 | return $xml->asXML(); 123 | } 124 | 125 | public function queryOrdersStatus($params){ 126 | 127 | $this->load->model('sale/order'); 128 | 129 | if ($params['exchange_status'] != 0) { 130 | $query = $this->db->query("SELECT order_id FROM `" . DB_PREFIX . "order` WHERE `order_status_id` = " . $params['exchange_status'] . ""); 131 | } else { 132 | $query = $this->db->query("SELECT order_id FROM `" . DB_PREFIX . "order` WHERE `date_added` >= '" . $params['from_date'] . "'"); 133 | } 134 | 135 | if ($query->num_rows) { 136 | foreach ($query->rows as $orders_data) { 137 | $this->model_sale_order->addOrderHistory($orders_data['order_id'], array( 138 | 'order_status_id' => $params['new_status'], 139 | 'comment' => '', 140 | 'notify' => $params['notify'] 141 | )); 142 | } 143 | } 144 | 145 | return true; 146 | } 147 | 148 | 149 | function array_to_xml($data, &$xml) { 150 | 151 | foreach($data as $key => $value) { 152 | if (is_array($value)) { 153 | if (!is_numeric($key)) { 154 | $subnode = $xml->addChild(preg_replace('/\d/', '', $key)); 155 | $this->array_to_xml($value, $subnode); 156 | } 157 | } 158 | else { 159 | $xml->addChild($key, $value); 160 | } 161 | } 162 | 163 | return $xml; 164 | } 165 | 166 | function format($var){ 167 | return preg_replace_callback( 168 | '/\\\u([0-9a-fA-F]{4})/', 169 | create_function('$match', 'return mb_convert_encoding("&#" . intval($match[1], 16) . ";", "UTF-8", "HTML-ENTITIES");'), 170 | json_encode($var) 171 | ); 172 | } 173 | 174 | /** 175 | * Парсит цены и количество 176 | * 177 | * @param string наименование типа цены 178 | */ 179 | public function parseOffers($filename, $config_price_type, $language_id) { 180 | 181 | $importFile = DIR_CACHE . 'exchange1c/' . $filename; 182 | $xml = simplexml_load_file($importFile); 183 | $price_types = array(); 184 | $config_price_type_main = array(); 185 | $enable_log = $this->config->get('exchange1c_full_log'); 186 | $exchange1c_relatedoptions = $this->config->get('exchange1c_relatedoptions'); 187 | 188 | $this->load->model('catalog/option'); 189 | 190 | if ($enable_log) 191 | $this->log->write("Начат разбор файла: " . $filename); 192 | 193 | if (!empty($config_price_type) && count($config_price_type) > 0) { 194 | $config_price_type_main = array_shift($config_price_type); 195 | } 196 | 197 | if ($xml->ПакетПредложений->ТипыЦен->ТипЦены) { 198 | foreach ($xml->ПакетПредложений->ТипыЦен->ТипЦены as $key => $type) { 199 | $price_types[(string)$type->Ид] = (string)$type->Наименование; 200 | if($key == 0 && !isset($config_price_type_main)) { 201 | $config_price_type_main['keyword'] = (string)$type->Наименование; 202 | } 203 | } 204 | } 205 | 206 | // Инициализация массива скидок для оптимизации алгоритма 207 | if (!empty($config_price_type) && count($config_price_type) > 0) { 208 | $discount_price_type = array(); 209 | foreach ($config_price_type as $obj) { 210 | $discount_price_type[$obj['keyword']] = array( 211 | 'customer_group_id' => $obj['customer_group_id'], 212 | 'quantity' => $obj['quantity'], 213 | 'priority' => $obj['priority'] 214 | ); 215 | } 216 | } 217 | 218 | $offer_cnt = 0; 219 | 220 | if ($xml->ПакетПредложений->Предложения->Предложение) { 221 | foreach ($xml->ПакетПредложений->Предложения->Предложение as $offer) { 222 | 223 | $new_product = (!isset($data)); 224 | 225 | $offer_cnt++; 226 | 227 | if (!$exchange1c_relatedoptions || $new_product) { 228 | 229 | $data = array(); 230 | $data['price'] = 0; 231 | 232 | //UUID без номера после # 233 | $uuid = explode("#", $offer->Ид); 234 | $data['1c_id'] = $uuid[0]; 235 | if ($enable_log) 236 | $this->log->write("Товар: [UUID]:" . $data['1c_id']); 237 | 238 | $product_id = $this->getProductIdBy1CProductId ($uuid[0]); 239 | 240 | //Цена за единицу 241 | if ($offer->Цены) { 242 | 243 | // Первая цена по умолчанию - $config_price_type_main 244 | if (!$config_price_type_main['keyword']) { 245 | $data['price'] = (float)$offer->Цены->Цена->ЦенаЗаЕдиницу; 246 | } 247 | else { 248 | if ($offer->Цены->Цена->ИдТипаЦены) { 249 | foreach ($offer->Цены->Цена as $price) { 250 | if ($price_types[(string)$price->ИдТипаЦены] == $config_price_type_main['keyword']) { 251 | $data['price'] = (float)$price->ЦенаЗаЕдиницу; 252 | if ($enable_log) 253 | $this->log->write(" найдена цена > " . $data['price']); 254 | 255 | } 256 | } 257 | } 258 | } 259 | 260 | // Вторая цена и тд - $discount_price_type 261 | if (!empty($discount_price_type) && $offer->Цены->Цена->ИдТипаЦены) { 262 | foreach ($offer->Цены->Цена as $price) { 263 | $key = $price_types[(string)$price->ИдТипаЦены]; 264 | if (isset($discount_price_type[$key])) { 265 | $value = array( 266 | 'customer_group_id' => $discount_price_type[$key]['customer_group_id'], 267 | 'quantity' => $discount_price_type[$key]['quantity'], 268 | 'priority' => $discount_price_type[$key]['priority'], 269 | 'price' => (float)$price->ЦенаЗаЕдиницу, 270 | 'date_start' => '0000-00-00', 271 | 'date_end' => '0000-00-00' 272 | ); 273 | $data['product_discount'][] = $value; 274 | unset($value); 275 | } 276 | } 277 | } 278 | } 279 | 280 | //Количество 281 | $data['quantity'] = isset($offer->Количество) ? (int)$offer->Количество : 0; 282 | } 283 | 284 | //Характеристики 285 | if ($offer->ХарактеристикиТовара->ХарактеристикаТовара) { 286 | 287 | $product_option_value_data = array(); 288 | $product_option_data = array(); 289 | 290 | $lang_id = (int)$this->config->get('config_language_id'); 291 | $count = count($offer->ХарактеристикиТовара->ХарактеристикаТовара); 292 | 293 | foreach ($offer->ХарактеристикиТовара->ХарактеристикаТовара as $i => $opt) { 294 | $name_1c = (string)$opt->Наименование; 295 | $value_1c = (string)$opt->Значение; 296 | 297 | if (!empty($name_1c) && !empty($value_1c)) { 298 | 299 | if ($exchange1c_relatedoptions) { 300 | $uuid = explode("#", $offer->Ид); 301 | if (!isset($char_id) || $char_id != $uuid[1]) { 302 | $char_id = $uuid[1]; 303 | if ($enable_log) $this->log->write("Характеристика: ".$char_id); 304 | } 305 | } 306 | 307 | if ($enable_log) $this->log->write(" Найдены характеристики: " . $name_1c . " -> " . $value_1c); 308 | 309 | $option_id = $this->setOption($name_1c); 310 | 311 | $option_value_id = $this->setOptionValue($option_id, $value_1c); 312 | 313 | $product_option_value_data[] = array( 314 | 'option_value_id' => (int) $option_value_id, 315 | 'product_option_value_id' => '', 316 | 'quantity' => isset($data['quantity']) ? (int)$data['quantity'] : 0, 317 | 'subtract' => 0, 318 | 'price' => isset($data['price']) ? (int)$data['price'] : 0, 319 | 'price_prefix' => '+', 320 | 'points' => 0, 321 | 'points_prefix' => '+', 322 | 'weight' => 0, 323 | 'weight_prefix' => '+' 324 | ); 325 | 326 | $product_option_data[] = array( 327 | 'product_option_id' => '', 328 | 'name' => (string)$name_1c, 329 | 'option_id' => (int) $option_id, 330 | 'type' => 'select', 331 | 'required' => 1, 332 | 'product_option_value' => $product_option_value_data 333 | ); 334 | 335 | if ($exchange1c_relatedoptions) { 336 | 337 | if ( !isset($data['relatedoptions'])) { 338 | $data['relatedoptions'] = array(); 339 | $data['related_options_variant_search'] = TRUE; 340 | $data['related_options_use'] = TRUE; 341 | } 342 | 343 | $ro_found = FALSE; 344 | foreach ($data['relatedoptions'] as $ro_num => $relatedoptions) { 345 | if ($relatedoptions['char_id'] == $char_id) { 346 | $data['relatedoptions'][$ro_num]['options'][$option_id] = $option_value_id; 347 | $ro_found = TRUE; 348 | break; 349 | } 350 | } 351 | if (!$ro_found) { 352 | $data['relatedoptions'][] = array('char_id' => $char_id, 'quantity' => (isset($offer->Количество) ? (int)$offer->Количество : 0), 'options' => array($option_id => $option_value_id)); 353 | } 354 | 355 | } else { 356 | $data['product_option'] = $product_option_data; 357 | } 358 | } 359 | } 360 | } 361 | 362 | if (!$exchange1c_relatedoptions || $new_product) { 363 | 364 | if ($offer->СкидкиНаценки) { 365 | $value = array(); 366 | foreach ($offer->СкидкиНаценки->СкидкаНаценка as $discount) { 367 | $value = array( 368 | 'customer_group_id' => 1 369 | ,'priority' => isset($discount->Приоритет) ? (int)$discount->Приоритет : 0 370 | ,'price' => (int)(($data['price'] * (100 - (float)str_replace(',', '.', (string)$discount->Процент))) / 100) 371 | ,'date_start' => isset($discount->ДатаНачала) ? (string)$discount->ДатаНачала : '' 372 | ,'date_end' => isset($discount->ДатаОкончания) ? (string)$discount->ДатаОкончания : '' 373 | ,'quantity' => 0 374 | ); 375 | 376 | $data['product_discount'][] = $value; 377 | 378 | if ($discount->ЗначениеУсловия) { 379 | $value['quantity'] = (int)$discount->ЗначениеУсловия; 380 | } 381 | 382 | unset($value); 383 | } 384 | } 385 | 386 | $data['status'] = 1; 387 | } 388 | 389 | if (!$exchange1c_relatedoptions || $offer_cnt == count($xml->ПакетПредложений->Предложения->Предложение) 390 | || $data['1c_id'] != substr($xml->ПакетПредложений->Предложения->Предложение[$offer_cnt]->Ид, 0, strlen($data['1c_id'])) ) { 391 | 392 | $this->updateProduct($data, $product_id, $language_id); 393 | unset($data); 394 | } 395 | 396 | 397 | 398 | } 399 | } 400 | 401 | $this->cache->delete('product'); 402 | 403 | if ($enable_log) 404 | $this->log->write("Окончен разбор файла: " . $filename ); 405 | 406 | } 407 | 408 | private function setOption($name){ 409 | $lang_id = (int)$this->config->get('config_language_id'); 410 | 411 | $query = $this->db->query("SELECT option_id FROM ". DB_PREFIX ."option_description WHERE name='". $this->db->escape($name) ."'"); 412 | 413 | if ($query->num_rows > 0) { 414 | $option_id = $query->row['option_id']; 415 | } 416 | else { 417 | //Нет такой опции 418 | $this->db->query("INSERT INTO `" . DB_PREFIX . "option` SET type = 'select', sort_order = '0'"); 419 | $option_id = $this->db->getLastId(); 420 | $this->db->query("INSERT INTO " . DB_PREFIX . "option_description SET option_id = '" . $option_id . "', language_id = '" . $lang_id . "', name = '" . $this->db->escape($name) . "'"); 421 | } 422 | return $option_id; 423 | } 424 | 425 | private function setOptionValue($option_id, $value) { 426 | $lang_id = (int)$this->config->get('config_language_id'); 427 | 428 | $query = $this->db->query("SELECT option_value_id FROM ". DB_PREFIX ."option_value_description WHERE name='". $this->db->escape($value) ."' AND option_id='". $option_id ."'"); 429 | 430 | if ($query->num_rows > 0) { 431 | $option_value_id = $query->row['option_value_id']; 432 | } 433 | else { 434 | //Добавляем значение опции, только если нет в базе 435 | $this->db->query("INSERT INTO " . DB_PREFIX . "option_value SET option_id = '" . $option_id . "', image = '', sort_order = '0'"); 436 | $option_value_id = $this->db->getLastId(); 437 | $this->db->query("INSERT INTO " . DB_PREFIX . "option_value_description SET option_value_id = '".$option_value_id."', language_id = '" . $lang_id . "', option_id = '" . $option_id . "', name = '" . $this->db->escape($value) . "'"); 438 | } 439 | return $option_value_id; 440 | } 441 | 442 | /** 443 | * Парсит товары и категории 444 | */ 445 | public function parseImport($filename, $language_id) { 446 | 447 | $importFile = DIR_CACHE . 'exchange1c/' . $filename; 448 | 449 | $enable_log = $this->config->get('exchange1c_full_log'); 450 | $apply_watermark = $this->config->get('exchange1c_apply_watermark'); 451 | 452 | $xml = simplexml_load_file($importFile); 453 | $data = array(); 454 | 455 | // Группы 456 | if($xml->Классификатор->Группы) $this->insertCategory($xml->Классификатор->Группы->Группа, 0, $language_id); 457 | 458 | // Свойства 459 | if ($xml->Классификатор->Свойства) $this->insertAttribute($xml->Классификатор->Свойства->Свойство); 460 | 461 | $this->load->model('catalog/manufacturer'); 462 | 463 | // Товары 464 | if ($xml->Каталог->Товары->Товар) { 465 | foreach ($xml->Каталог->Товары->Товар as $product) { 466 | 467 | $uuid = explode('#', (string)$product->Ид); 468 | $data['1c_id'] = $uuid[0]; 469 | 470 | $data['model'] = $product->Артикул? (string)$product->Артикул : 'не задана'; 471 | $data['name'] = $product->Наименование? (string)$product->Наименование : 'не задано'; 472 | $data['weight'] = $product->Вес? (float)$product->Вес : null; 473 | $data['sku'] = $product->Артикул? (string)$product->Артикул : ''; 474 | 475 | if ($enable_log) 476 | $this->log->write("Найден товар:" . $data['name'] . " арт: " . $data['sku'] . "1C UUID: " . $data['1c_id']); 477 | 478 | if ($product->Картинка) { 479 | $data['image'] = $apply_watermark ? $this->applyWatermark((string)$product->Картинка[0]) : (string)$product->Картинка[0]; 480 | unset($product->Картинка[0]); 481 | foreach ($product->Картинка as $image) { 482 | $data['product_image'][] =array( 483 | 'image' => $apply_watermark ? $this->applyWatermark((string)$image) : (string)$image, 484 | 'sort_order' => 0 485 | ); 486 | } 487 | } 488 | 489 | if($product->ХарактеристикиТовара){ 490 | 491 | $count_options = count($product->ХарактеристикиТовара->ХарактеристикаТовара); 492 | $option_desc = ''; 493 | 494 | foreach($product->ХарактеристикиТовара->ХарактеристикаТовара as $option ) { 495 | $option_desc .= (string)$option->Наименование . ': ' . (string)$option->Значение . ';'; 496 | } 497 | $option_desc .= ";\n"; 498 | 499 | } 500 | 501 | if ($product->Группы) $data['category_1c_id'] = $product->Группы->Ид; 502 | if ($product->Описание) $data['description'] = (string)$product->Описание; 503 | if ($product->Статус) $data['status'] = (string)$product->Статус; 504 | 505 | // Свойства продукта 506 | if ($product->ЗначенияСвойств) { 507 | if ($enable_log) 508 | $this->log->write(" загружаются свойства... "); 509 | foreach ($product->ЗначенияСвойств->ЗначенияСвойства as $property) { 510 | if (isset($this->PROPERTIES[(string)$property->Ид]['name'])) { 511 | 512 | $attribute = $this->PROPERTIES[(string)$property->Ид]; 513 | 514 | if (isset($attribute['values'][(string)$property->Значение])) { 515 | $attribute_value = str_replace("'", "'", (string)$attribute['values'][(string)$property->Значение]); 516 | } 517 | else if ((string)$property->Значение != '') { 518 | $attribute_value = str_replace("'", "'", (string)$property->Значение); 519 | } 520 | else { 521 | continue; 522 | } 523 | if ($enable_log) 524 | $this->log->write(" > " . $attribute_value); 525 | 526 | switch ($attribute['name']) { 527 | 528 | case 'Производитель': 529 | $manufacturer_name = $attribute_value; 530 | $query = $this->db->query("SELECT manufacturer_id FROM ". DB_PREFIX ."manufacturer WHERE name='". $manufacturer_name ."'"); 531 | 532 | if ($query->num_rows) { 533 | $data['manufacturer_id'] = $query->row['manufacturer_id']; 534 | } 535 | else { 536 | $data_manufacturer = array( 537 | 'name' => $manufacturer_name, 538 | 'keyword' => '', 539 | 'sort_order' => 0, 540 | 'manufacturer_store' => array(0 => 0) 541 | ); 542 | 543 | $data_manufacturer['manufacturer_description'] = array( 544 | $language_id => array( 545 | 'meta_keyword' => '', 546 | 'meta_description' => '', 547 | 'description' => '', 548 | 'seo_title' => '', 549 | 'seo_h1' => '' 550 | ), 551 | ); 552 | 553 | $manufacturer_id = $this->model_catalog_manufacturer->addManufacturer($data_manufacturer); 554 | $data['manufacturer_id'] = $manufacturer_id; 555 | 556 | //только если тип 'translit' 557 | if ($this->config->get('exchange1c_seo_url') == 2) { 558 | $man_name = "brand-" . $manufacturer_name; 559 | $this->setSeoURL('manufacturer_id', $manufacturer_id, $man_name); 560 | } 561 | } 562 | break; 563 | 564 | case 'oc.seo_h1': 565 | $data['seo_h1'] = $attribute_value; 566 | break; 567 | 568 | case 'oc.seo_title': 569 | $data['seo_title'] = $attribute_value; 570 | break; 571 | 572 | case 'oc.sort_order': 573 | $data['sort_order'] = $attribute_value; 574 | break; 575 | 576 | default: 577 | $data['product_attribute'][] = array( 578 | 'attribute_id' => $attribute['id'], 579 | 'product_attribute_description' => array( 580 | $language_id => array( 581 | 'text' => $attribute_value 582 | ) 583 | ) 584 | ); 585 | 586 | 587 | } 588 | } 589 | } 590 | if ($enable_log) 591 | $this->log->write(" свойства загружены... "); 592 | } 593 | 594 | // Реквизиты продукта 595 | if($product->ЗначенияРеквизитов) { 596 | foreach ($product->ЗначенияРеквизитов->ЗначениеРеквизита as $requisite){ 597 | switch ($requisite->Наименование){ 598 | case 'Вес': 599 | $data['weight'] = $requisite->Значение ? (float)$requisite->Значение : 0; 600 | break; 601 | 602 | case 'ОписаниеВФорматеHTML': 603 | $data['description'] = $requisite->Значение ? (string)$requisite->Значение : ''; 604 | break; 605 | } 606 | } 607 | } 608 | 609 | $this->setProduct($data, $language_id); 610 | unset($data); 611 | } 612 | } 613 | 614 | unset($xml); 615 | if ($enable_log) 616 | $this->log->write("Окончен разбор файла: " . $filename ); 617 | } 618 | 619 | 620 | /** 621 | * Инициализируем данные для категории дабы обновлять данные, а не затирать 622 | * 623 | * @param array старые данные 624 | * @param int id родительской категории 625 | * @param array новые данные 626 | * @return array 627 | */ 628 | private function initCategory($category, $parent, $data = array(), $language_id) { 629 | 630 | $result = array( 631 | 'status' => isset($data['status']) ? $data['status'] : 1 632 | ,'top' => isset($data['top']) ? $data['top'] : 1 633 | ,'parent_id' => $parent 634 | ,'category_store' => isset($data['category_store']) ? $data['category_store'] : array(0) 635 | ,'keyword' => isset($data['keyword']) ? $data['keyword'] : '' 636 | ,'image' => (isset($category->Картинка)) ? (string)$category->Картинка : ((isset($data['image'])) ? $data['image'] : '') 637 | ,'sort_order' => (isset($category->Сортировка)) ? (int)$category->Сортировка : ((isset($data['sort_order'])) ? $data['sort_order'] : 0) 638 | ,'column' => 1 639 | ); 640 | 641 | $result['category_description'] = array( 642 | $language_id => array( 643 | 'name' => (string)$category->Наименование 644 | ,'meta_keyword' => (isset($data['category_description'][$language_id]['meta_keyword'])) ? $data['category_description'][$language_id]['meta_keyword'] : '' 645 | ,'meta_description' => (isset($data['category_description'][$language_id]['meta_description'])) ? $data['category_description'][$language_id]['meta_description'] : '' 646 | ,'description' => (isset($category->Описание)) ? (string)$category->Описание : ((isset($data['category_description'][$language_id]['description'])) ? $data['category_description'][$language_id]['description'] : '') 647 | ,'seo_title' => (isset($data['category_description'][$language_id]['seo_title'])) ? $data['category_description'][$language_id]['seo_title'] : '' 648 | ,'seo_h1' => (isset($data['category_description'][$language_id]['seo_h1'])) ? $data['category_description'][$language_id]['seo_h1'] : '' 649 | ), 650 | ); 651 | 652 | return $result; 653 | } 654 | 655 | 656 | /** 657 | * Функция добавляет корневую категорию и всех детей 658 | * 659 | * @param SimpleXMLElement 660 | * @param int 661 | */ 662 | private function insertCategory($xml, $parent = 0, $language_id) { 663 | 664 | $this->load->model('catalog/category'); 665 | 666 | foreach ($xml as $category){ 667 | 668 | if (isset($category->Ид) && isset($category->Наименование) ){ 669 | $id = (string)$category->Ид; 670 | 671 | $data = array(); 672 | 673 | $query = $this->db->query('SELECT * FROM `' . DB_PREFIX . 'category_to_1c` WHERE `1c_category_id` = "' . $this->db->escape($id) . '"'); 674 | 675 | if ($query->num_rows) { 676 | $category_id = (int)$query->row['category_id']; 677 | $data = $this->model_catalog_category->getCategory($category_id); 678 | $data['category_description'] = $this->model_catalog_category->getCategoryDescriptions($category_id); 679 | $data = $this->initCategory($category, $parent, $data, $language_id); 680 | $this->model_catalog_category->editCategory($category_id, $data); 681 | } 682 | else { 683 | $data = $this->initCategory($category, $parent, array(), $language_id); 684 | //$category_id = $this->getCategoryIdByName($data['category_description'][1]['name']) ? $this->getCategoryIdByName($data['category_description'][1]['name']) : $this->model_catalog_category->addCategory($data); 685 | $category_id = $this->model_catalog_category->addCategory($data); 686 | $this->db->query('INSERT INTO `' . DB_PREFIX . 'category_to_1c` SET category_id = ' . (int)$category_id . ', `1c_category_id` = "' . $this->db->escape($id) . '"'); 687 | } 688 | 689 | $this->CATEGORIES[$id] = $category_id; 690 | } 691 | 692 | //только если тип 'translit' 693 | if ($this->config->get('exchange1c_seo_url') == 2) { 694 | $cat_name = "category-" . $data['parent_id'] . "-" . $data['category_description'][$language_id]['name']; 695 | $this->setSeoURL('category_id', $category_id, $cat_name); 696 | } 697 | 698 | if ($category->Группы) $this->insertCategory($category->Группы->Группа, $category_id, $language_id); 699 | } 700 | 701 | unset($xml); 702 | } 703 | 704 | 705 | /** 706 | * Создает атрибуты из свойств 707 | * 708 | * @param SimpleXMLElement 709 | */ 710 | private function insertAttribute($xml) { 711 | $this->load->model('catalog/attribute'); 712 | $this->load->model('catalog/attribute_group'); 713 | $lang_id = (int)$this->config->get('config_language_id'); 714 | 715 | $attribute_group = $this->model_catalog_attribute_group->getAttributeGroup(1); 716 | 717 | if (!$attribute_group) { 718 | 719 | $attribute_group_description[$lang_id] = array ( 720 | 'name' => 'Свойства' 721 | ); 722 | 723 | $data = array ( 724 | 'sort_order' => 0, 725 | 'attribute_group_description' => $attribute_group_description 726 | ); 727 | 728 | $this->model_catalog_attribute_group->addAttributeGroup($data); 729 | } 730 | 731 | foreach ($xml as $attribute) { 732 | $id = (string)$attribute->Ид; 733 | $name = (string)$attribute->Наименование; 734 | $values = array(); 735 | 736 | if ((string)$attribute->ВариантыЗначений) { 737 | if ((string)$attribute->ТипЗначений == 'Справочник') { 738 | foreach($attribute->ВариантыЗначений->Справочник as $option_value){ 739 | if ((string)$option_value->Значение != '') { 740 | $values[(string)$option_value->ИдЗначения] = (string)$option_value->Значение; 741 | } 742 | } 743 | } 744 | } 745 | 746 | $data = array ( 747 | 'attribute_group_id' => 1, 748 | 'sort_order' => 0, 749 | ); 750 | 751 | $data['attribute_description'][$lang_id]['name'] = (string)$name; 752 | 753 | // Если атрибут уже был добавлен, то возвращаем старый id, если атрибута нет, то создаем его и возвращаем его id 754 | $current_attribute = $this->db->query('SELECT attribute_id FROM ' . DB_PREFIX . 'attribute_to_1c WHERE 1c_attribute_id = "' . $id . '"'); 755 | if (!$current_attribute->num_rows) { 756 | $attribute_id = $this->model_catalog_attribute->addAttribute($data); 757 | $this->db->query('INSERT INTO `' . DB_PREFIX . 'attribute_to_1c` SET attribute_id = ' . (int)$attribute_id . ', `1c_attribute_id` = "' . $id . '"'); 758 | } 759 | else { 760 | $data = $current_attribute->row; 761 | $attribute_id = $data['attribute_id']; 762 | } 763 | 764 | $this->PROPERTIES[$id] = array( 765 | 'id' => $attribute_id, 766 | 'name' => $name, 767 | 'values' => $values 768 | ); 769 | 770 | } 771 | 772 | unset($xml); 773 | } 774 | 775 | 776 | /** 777 | * Функция работы с продуктом 778 | * @param int 779 | * @return array 780 | */ 781 | 782 | private function getProductWithAllData($product_id) { 783 | $this->load->model('catalog/product'); 784 | $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) WHERE p.product_id = '" . (int)$product_id . "' AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "'"); 785 | 786 | $data = array(); 787 | 788 | if ($query->num_rows) { 789 | 790 | $data = $query->row; 791 | 792 | $data = array_merge($data, array('product_description' => $this->model_catalog_product->getProductDescriptions($product_id))); 793 | $data = array_merge($data, array('product_option' => $this->model_catalog_product->getProductOptions($product_id))); 794 | 795 | $data['product_image'] = array(); 796 | 797 | $results = $this->model_catalog_product->getProductImages($product_id); 798 | 799 | foreach ($results as $result) { 800 | $data['product_image'][] = array( 801 | 'image' => $result['image'], 802 | 'sort_order' => $result['sort_order'] 803 | ); 804 | } 805 | 806 | if (method_exists($this->model_catalog_product, 'getProductMainCategoryId')) { 807 | $data = array_merge($data, array('main_category_id' => $this->model_catalog_product->getProductMainCategoryId($product_id))); 808 | } 809 | 810 | $data = array_merge($data, array('product_discount' => $this->model_catalog_product->getProductDiscounts($product_id))); 811 | $data = array_merge($data, array('product_special' => $this->model_catalog_product->getProductSpecials($product_id))); 812 | $data = array_merge($data, array('product_download' => $this->model_catalog_product->getProductDownloads($product_id))); 813 | $data = array_merge($data, array('product_category' => $this->model_catalog_product->getProductCategories($product_id))); 814 | $data = array_merge($data, array('product_store' => $this->model_catalog_product->getProductStores($product_id))); 815 | $data = array_merge($data, array('product_related' => $this->model_catalog_product->getProductRelated($product_id))); 816 | $data = array_merge($data, array('product_attribute' => $this->model_catalog_product->getProductAttributes($product_id))); 817 | 818 | if (VERSION == '1.5.3.1') { 819 | $data = array_merge($data, array('product_tag' => $this->model_catalog_product->getProductTags($product_id))); 820 | } 821 | } 822 | 823 | $query = $this->db->query('SELECT * FROM ' . DB_PREFIX . 'url_alias WHERE query LIKE "product_id='.$product_id.'"'); 824 | if ($query->num_rows) $data['keyword'] = $query->row['keyword']; 825 | 826 | return $data; 827 | } 828 | 829 | /** 830 | * Обновляет массив с информацией о продукте 831 | * 832 | * @param array новые данные 833 | * @param array обновляемые данные 834 | * @return array 835 | */ 836 | private function initProduct($product, $data = array(), $language_id) { 837 | 838 | $this->load->model('tool/image'); 839 | 840 | $result = array( 841 | 'product_description' => array() 842 | ,'model' => (isset($product['model'])) ? $product['model'] : (isset($data['model']) ? $data['model']: '') 843 | ,'sku' => (isset($product['sku'])) ? $product['sku'] : (isset($data['sku']) ? $data['sku']: '') 844 | ,'upc' => (isset($product['upc'])) ? $product['upc'] : (isset($data['upc']) ? $data['upc']: '') 845 | ,'ean' => (isset($product['ean'])) ? $product['ean'] : (isset($data['ean']) ? $data['ean']: '') 846 | ,'jan' => (isset($product['jan'])) ? $product['jan'] : (isset($data['jan']) ? $data['jan']: '') 847 | ,'isbn' => (isset($product['isbn'])) ? $product['isbn'] : (isset($data['isbn']) ? $data['isbn']: '') 848 | ,'mpn' => (isset($product['mpn'])) ? $product['mpn'] : (isset($data['mpn']) ? $data['mpn']: '') 849 | 850 | ,'location' => (isset($product['location'])) ? $product['location'] : (isset($data['location']) ? $data['location']: '') 851 | ,'price' => (isset($product['price'])) ? $product['price'] : (isset($data['price']) ? $data['price']: 0) 852 | ,'tax_class_id' => (isset($product['tax_class_id'])) ? $product['tax_class_id'] : (isset($data['tax_class_id']) ? $data['tax_class_id']: 0) 853 | ,'quantity' => (isset($product['quantity'])) ? $product['quantity'] : (isset($data['quantity']) ? $data['quantity']: 0) 854 | ,'minimum' => (isset($product['minimum'])) ? $product['minimum'] : (isset($data['minimum']) ? $data['minimum']: 1) 855 | ,'subtract' => (isset($product['subtract'])) ? $product['subtract'] : (isset($data['subtract']) ? $data['subtract']: 1) 856 | ,'stock_status_id' => $this->config->get('config_stock_status_id') 857 | ,'shipping' => (isset($product['shipping'])) ? $product['shipping'] : (isset($data['shipping']) ? $data['shipping']: 1) 858 | ,'keyword' => (isset($product['keyword'])) ? $product['keyword'] : (isset($data['keyword']) ? $data['keyword']: '') 859 | ,'image' => (isset($product['image'])) ? $product['image'] : (isset($data['image']) ? $data['image']: '') 860 | ,'date_available' => date('Y-m-d', time() - 86400) 861 | ,'length' => (isset($product['length'])) ? $product['length'] : (isset($data['length']) ? $data['length']: '') 862 | ,'width' => (isset($product['width'])) ? $product['width'] : (isset($data['width']) ? $data['width']: '') 863 | ,'height' => (isset($product['height'])) ? $product['height'] : (isset($data['height']) ? $data['height']: '') 864 | ,'length_class_id' => (isset($product['length_class_id'])) ? $product['length_class_id'] : (isset($data['length_class_id']) ? $data['length_class_id']: 1) 865 | ,'weight' => (isset($product['weight'])) ? $product['weight'] : (isset($data['weight']) ? $data['weight']: 0) 866 | ,'weight_class_id' => (isset($product['weight_class_id'])) ? $product['weight_class_id'] : (isset($data['weight_class_id']) ? $data['weight_class_id']: 1) 867 | ,'status' => (isset($product['status'])) ? $product['status'] : (isset($data['status']) ? $data['status']: 1) 868 | ,'sort_order' => (isset($product['sort_order'])) ? $product['sort_order'] : (isset($data['sort_order']) ? $data['sort_order']: 1) 869 | ,'manufacturer_id' => (isset($product['manufacturer_id'])) ? $product['manufacturer_id'] : (isset($data['manufacturer_id']) ? $data['manufacturer_id']: 0) 870 | ,'main_category_id' => 0 871 | ,'product_store' => array(0) 872 | ,'product_option' => array() 873 | ,'points' => (isset($product['points'])) ? $product['points'] : (isset($data['points']) ? $data['points']: 0) 874 | ,'product_image' => (isset($product['product_image'])) ? $product['product_image'] : (isset($data['product_image']) ? $data['product_image']: array()) 875 | ,'preview' => $this->model_tool_image->resize('no_image.jpg', 100, 100) 876 | ,'cost' => (isset($product['cost'])) ? $product['cost'] : (isset($data['cost']) ? $data['cost']: 0) 877 | ,'product_discount' => (isset($product['product_discount'])) ? $product['product_discount'] : (isset($data['product_discount']) ? $data['product_discount']: array()) 878 | ,'product_special' => (isset($product['product_special'])) ? $product['product_special'] : (isset($data['product_special']) ? $data['product_special']: array()) 879 | ,'product_download' => (isset($product['product_download'])) ? $product['product_download'] : (isset($data['product_download']) ? $data['product_download']: array()) 880 | ,'product_related' => (isset($product['product_related'])) ? $product['product_related'] : (isset($data['product_related']) ? $data['product_related']: array()) 881 | ,'product_attribute' => (isset($product['product_attribute'])) ? $product['product_attribute'] : (isset($data['product_attribute']) ? $data['product_attribute']: array()) 882 | ); 883 | 884 | if (VERSION == '1.5.3.1') { 885 | $result['product_tag'] = (isset($product['product_tag'])) ? $product['product_tag'] : (isset($data['product_tag']) ? $data['product_tag']: array()); 886 | } 887 | 888 | $result['product_description'] = array( 889 | $language_id => array( 890 | 'name' => isset($product['name']) ? $product['name'] : (isset($data['product_description'][$language_id]['name']) ? $data['product_description'][$language_id]['name']: 'Имя не задано') 891 | ,'seo_h1' => isset($product['seo_h1']) ? $product['seo_h1']: (isset($data['product_description'][$language_id]['seo_h1']) ? $data['product_description'][$language_id]['seo_h1']: '') 892 | ,'seo_title' => isset($product['seo_title']) ? $product['seo_title']: (isset($data['product_description'][$language_id]['seo_title']) ? $data['product_description'][$language_id]['seo_title']: '') 893 | ,'meta_keyword' => isset($product['meta_keyword']) ? trim($product['meta_keyword']): (isset($data['product_description'][$language_id]['meta_keyword']) ? $data['product_description'][$language_id]['meta_keyword']: '') 894 | ,'meta_description' => isset($product['meta_description']) ? trim($product['meta_description']): (isset($data['product_description'][$language_id]['meta_description']) ? $data['product_description'][$language_id]['meta_description']: '') 895 | ,'description' => isset($product['description']) ? nl2br($product['description']): (isset($data['product_description'][$language_id]['description']) ? $data['product_description'][$language_id]['description']: '') 896 | ,'tag' => isset($product['tag']) ? $product['tag']: (isset($data['product_description'][$language_id]['tag']) ? $data['product_description'][$language_id]['tag']: '') 897 | ), 898 | ); 899 | 900 | if (isset($product['product_option'])) { 901 | $product['product_option_id'] = ''; 902 | $product['name'] = ''; 903 | if(!empty($product['product_option']) && isset($product['product_option'][0]['type'])){ 904 | $result['product_option'] = $product['product_option']; 905 | if(!empty($data['product_option'])){ 906 | $result['product_option'][0]['product_option_value'] = array_merge($product['product_option'][0]['product_option_value'],$data['product_option'][0]['product_option_value']); 907 | } 908 | } 909 | else { 910 | $result['product_option'] = $data['product_option']; 911 | } 912 | } 913 | else { 914 | $product['product_option'] = array(); 915 | } 916 | 917 | if (isset($product['category_1c_id'])) { 918 | if (is_object($product['category_1c_id'])) { 919 | foreach ($product['category_1c_id'] as $category_item) { 920 | if (isset($this->CATEGORIES[(string)$category_item])) { 921 | $result['product_category'][] = (int)$this->CATEGORIES[(string)$category_item]; 922 | $result['main_category_id'] = 0; 923 | } 924 | } 925 | } else { 926 | $product['category_1c_id'] = (string)$product['category_1c_id']; 927 | if (isset($this->CATEGORIES[$product['category_1c_id']])) { 928 | $result['product_category'] = array((int)$this->CATEGORIES[$product['category_1c_id']]); 929 | $result['main_category_id'] = (int)$this->CATEGORIES[$product['category_1c_id']]; 930 | } else { 931 | $result['product_category'] = isset($data['product_category']) ? $data['product_category'] : array(0); 932 | $result['main_category_id'] = isset($data['main_category_id']) ? $data['main_category_id'] : 0; 933 | } 934 | } 935 | } 936 | 937 | if (!isset($result['product_category']) && isset($data['product_category'])) { 938 | $result['product_category'] = $data['product_category']; 939 | } 940 | 941 | if (isset($product['related_options_use'])) { 942 | $result['related_options_use'] = $product['related_options_use']; 943 | } 944 | if (isset($product['related_options_variant_search'])) { 945 | $result['related_options_variant_search'] = $product['related_options_variant_search']; 946 | } 947 | if (isset($product['relatedoptions'])) { 948 | $result['relatedoptions'] = $product['relatedoptions']; 949 | } 950 | 951 | return $result; 952 | } 953 | 954 | 955 | 956 | /** 957 | * Функция работы с продуктом 958 | * 959 | * @param array $product 960 | * @param int $language_id 961 | * @internal param $array 962 | * @return bool 963 | */ 964 | private function setProduct($product, $language_id) { 965 | 966 | if (!$product) return false; 967 | 968 | // Проверяем, связан ли 1c_id с product_id 969 | $product_id = $this->getProductIdBy1CProductId($product['1c_id']); 970 | $data = $this->initProduct($product, array(), $language_id); 971 | 972 | if ($product_id) { 973 | $this->updateProduct($product, $product_id, $language_id); 974 | } 975 | else { 976 | 977 | if ($this->config->get('exchange1c_dont_use_artsync') || empty($data['sku'])) { 978 | $this->load->model('catalog/product'); 979 | $product_id = $this->model_catalog_product->addProduct($data); 980 | } else { 981 | // Проверяем, существует ли товар с тем-же артикулом 982 | // Если есть, то обновляем его 983 | $product_id = $this->getProductBySKU($data['sku']); 984 | if ($product_id !== false) { 985 | $this->updateProduct($product, $product_id, $language_id); 986 | } 987 | // Если нет, то создаем новый 988 | else { 989 | $this->load->model('catalog/product'); 990 | $this->model_catalog_product->addProduct($data); 991 | $product_id = $this->getProductBySKU($data['sku']); 992 | } 993 | } 994 | 995 | // Добавляем линк 996 | if ($product_id){ 997 | $this->db->query('INSERT INTO `' . DB_PREFIX . 'product_to_1c` SET product_id = ' . (int)$product_id . ', `1c_id` = "' . $this->db->escape($product['1c_id']) . '"'); 998 | } 999 | } 1000 | // Устанавливаем SEO URL 1001 | if ($product_id){ 1002 | //только если тип 'translit' 1003 | if ($this->config->get('exchange1c_seo_url') == 2) { 1004 | $this->setSeoURL('product_id', $product_id, $product['name']); 1005 | } 1006 | } 1007 | return true; 1008 | } 1009 | 1010 | /** 1011 | * Обновляет продукт 1012 | * 1013 | * @param array $product 1014 | * @param bool $product_id 1015 | * @param int $language_id 1016 | * @internal param $array 1017 | * @internal param $int 1018 | */ 1019 | private function updateProduct($product, $product_id = false, $language_id) { 1020 | 1021 | // Проверяем что обновлять? 1022 | if ($this->config->get('exchange1c_relatedoptions')) { 1023 | if ($product_id == false) { 1024 | $this->setProduct($product, $language_id); 1025 | return; 1026 | } 1027 | } else { 1028 | if ($product_id !== false) { 1029 | $product_id = $this->getProductIdBy1CProductId($product['1c_id']); 1030 | } 1031 | } 1032 | 1033 | // Обновляем описание продукта 1034 | $product_old = $this->getProductWithAllData($product_id); 1035 | 1036 | // Работаем с ценой на разные варианты товаров. 1037 | if(!empty($product['product_option'][0])){ 1038 | if(isset($product_old['price']) && (float) $product_old['price'] > 0){ 1039 | 1040 | $price = (float) $product_old['price'] - (float) $product['product_option'][0]['product_option_value'][0]['price']; 1041 | 1042 | $product['product_option'][0]['product_option_value'][0]['price_prefix'] = ($price > 0) ? '-':'+'; 1043 | $product['product_option'][0]['product_option_value'][0]['price'] = abs($price); 1044 | 1045 | $product['price'] = (float) $product_old['price']; 1046 | 1047 | } 1048 | else{ 1049 | $product['product_option'][0]['product_option_value'][0]['price'] = 0; 1050 | } 1051 | 1052 | } 1053 | 1054 | $this->load->model('catalog/product'); 1055 | 1056 | $product_old = $this->initProduct($product, $product_old, $language_id); 1057 | 1058 | //Редактируем продукт 1059 | $product_id = $this->model_catalog_product->editProduct($product_id, $product_old); 1060 | 1061 | } 1062 | 1063 | /** 1064 | * Устанавливает SEO URL (ЧПУ) для заданного товара 1065 | * 1066 | * @param inf 1067 | * @param string 1068 | */ 1069 | private function setSeoURL($url_type, $element_id, $element_name) { 1070 | $this->db->query("DELETE FROM `" . DB_PREFIX . "url_alias` WHERE `query` = '" . $url_type . "=" . $element_id . "'"); 1071 | $this->db->query("INSERT INTO `" . DB_PREFIX . "url_alias` SET `query` = '" . $url_type . "=" . $element_id ."', `keyword`='" . $this->transString($element_name) . "'"); 1072 | } 1073 | 1074 | /** 1075 | * Транслиетрирует RUS->ENG 1076 | * @param string $aString 1077 | * @return string type 1078 | */ 1079 | private function transString($aString) { 1080 | $rus = array(" ", "/", "*", "-", "+", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", "[", "]", "{", "}", "~", ";", ":", "'", "\"", "<", ">", ",", ".", "?", "А", "Б", "В", "Г", "Д", "Е", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ъ", "Ы", "Ь", "Э", "а", "б", "в", "г", "д", "е", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ъ", "ы", "ь", "э", "ё", "ж", "ц", "ч", "ш", "щ", "ю", "я", "Ё", "Ж", "Ц", "Ч", "Ш", "Щ", "Ю", "Я"); 1081 | $lat = array("-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "a", "b", "v", "g", "d", "e", "z", "i", "y", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "h", "", "i", "", "e", "a", "b", "v", "g", "d", "e", "z", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "h", "", "i", "", "e", "yo", "zh", "ts", "ch", "sh", "sch", "yu", "ya", "yo", "zh", "ts", "ch", "sh", "sch", "yu", "ya"); 1082 | 1083 | $string = str_replace($rus, $lat, $aString); 1084 | 1085 | while (mb_strpos($string, '--')) { 1086 | $string = str_replace('--', '-', $string); 1087 | } 1088 | 1089 | $string = strtolower(trim($string, '-')); 1090 | 1091 | return $string; 1092 | } 1093 | 1094 | /** 1095 | * Получает product_id по артикулу 1096 | * 1097 | * @param string 1098 | * @return int|bool 1099 | */ 1100 | private function getProductBySKU($sku) { 1101 | 1102 | $query = $this->db->query("SELECT product_id FROM `" . DB_PREFIX . "product` WHERE `sku` = '" . $this->db->escape($sku) . "'"); 1103 | 1104 | if ($query->num_rows) { 1105 | return $query->row['product_id']; 1106 | } 1107 | else { 1108 | return false; 1109 | } 1110 | } 1111 | 1112 | /** 1113 | * Получает 1c_id из product_id 1114 | * 1115 | * @param int 1116 | * @return string|bool 1117 | */ 1118 | private function get1CProductIdByProductId($product_id) { 1119 | $query = $this->db->query('SELECT 1c_id FROM ' . DB_PREFIX . 'product_to_1c WHERE `product_id` = ' . $product_id); 1120 | 1121 | if ($query->num_rows) { 1122 | return $query->row['1c_id']; 1123 | } 1124 | else { 1125 | return false; 1126 | } 1127 | } 1128 | 1129 | /** 1130 | * Получает product_id из 1c_id 1131 | * 1132 | * @param string 1133 | * @return int|bool 1134 | */ 1135 | private function getProductIdBy1CProductId($product_id) { 1136 | if(is_null($this->PRODUCT_IDS)){ 1137 | $this->PRODUCT_IDS = array(); 1138 | $query = $this->db->query('SELECT product_id, 1c_id FROM ' . DB_PREFIX . 'product_to_1c'); 1139 | foreach($query->rows as $product){ 1140 | $this->PRODUCT_IDS[$product['1c_id']] = $product['product_id']; 1141 | } 1142 | } 1143 | 1144 | return isset($this->PRODUCT_IDS[$product_id]) ? $this->PRODUCT_IDS[$product_id] : false; 1145 | } 1146 | 1147 | private function getCategoryIdByName($name) { 1148 | $query = $this->db->query("SELECT category_id FROM `" . DB_PREFIX . "category_description` WHERE `name` = '" . $name . "'"); 1149 | if ($query->num_rows) { 1150 | return $query->row['category_id']; 1151 | } 1152 | else { 1153 | return false; 1154 | } 1155 | } 1156 | 1157 | /** 1158 | * Получает путь к картинке и накладывает водяные знаки 1159 | * 1160 | * @param string 1161 | * @return string 1162 | */ 1163 | private function applyWatermark($filename) { 1164 | if (!empty($filename)) { 1165 | $info = pathinfo($filename); 1166 | $wmfile = DIR_IMAGE . $this->config->get('exchange1c_watermark'); 1167 | if (is_file($wmfile)) { 1168 | $extension = $info['extension']; 1169 | $minfo = getimagesize($wmfile); 1170 | $image = new Image(DIR_IMAGE . $filename); 1171 | $image->watermark($wmfile, 'center', $minfo['mime']); 1172 | $new_image = utf8_substr($filename, 0, utf8_strrpos($filename, '.')) . '_watermark.' . $extension; 1173 | $image->save(DIR_IMAGE . $new_image); 1174 | return $new_image; 1175 | } 1176 | else { 1177 | return $filename; 1178 | } 1179 | } 1180 | else { 1181 | return 'no_image.jpg'; 1182 | } 1183 | } 1184 | 1185 | /** 1186 | * Заполняет продуктами родительские категории 1187 | */ 1188 | public function fillParentsCategories() { 1189 | $this->load->model('catalog/product'); 1190 | if (!method_exists($this->model_catalog_product, 'getProductMainCategoryId')) { 1191 | $this->log->write(" !!!: Заполнение родительскими категориями отменено. Отсутствует main_category_id."); 1192 | return; 1193 | } 1194 | 1195 | $this->db->query('DELETE FROM `' .DB_PREFIX . 'product_to_category` WHERE `main_category` = 0'); 1196 | $query = $this->db->query('SELECT * FROM `' . DB_PREFIX . 'product_to_category` WHERE `main_category` = 1'); 1197 | 1198 | if ($query->num_rows) { 1199 | foreach ($query->rows as $row) { 1200 | $parents = $this->findParentsCategories($row['category_id']); 1201 | foreach ($parents as $parent) { 1202 | if ($row['category_id'] != $parent && $parent != 0) { 1203 | $this->db->query('INSERT INTO `' .DB_PREFIX . 'product_to_category` SET `product_id` = ' . $row['product_id'] . ', `category_id` = ' . $parent . ', `main_category` = 0'); 1204 | } 1205 | } 1206 | } 1207 | } 1208 | } 1209 | 1210 | /** 1211 | * Ищет все родительские категории 1212 | * 1213 | * @param int 1214 | * @return array 1215 | */ 1216 | private function findParentsCategories($category_id) { 1217 | $query = $this->db->query('SELECT * FROM `'.DB_PREFIX.'category` WHERE `category_id` = "'.$category_id.'"'); 1218 | if (isset($query->row['parent_id'])) { 1219 | $result = $this->findParentsCategories($query->row['parent_id']); 1220 | } 1221 | $result[] = $category_id; 1222 | return $result; 1223 | } 1224 | 1225 | /** 1226 | * Получает language_id из code (ru, en, etc) 1227 | * Как ни странно, подходящей функции в API не нашлось 1228 | * 1229 | * @param string 1230 | * @return int 1231 | */ 1232 | public function getLanguageId($lang) { 1233 | $query = $this->db->query('SELECT `language_id` FROM `' . DB_PREFIX . 'language` WHERE `code` = "'.$lang.'"'); 1234 | return $query->row['language_id']; 1235 | } 1236 | 1237 | 1238 | /** 1239 | * Очищает таблицы магазина 1240 | */ 1241 | public function flushDb($params) { 1242 | 1243 | $enable_log = $this->config->get('exchange1c_full_log'); 1244 | // Удаляем товары 1245 | if ($params['product']) { 1246 | if ($enable_log) 1247 | $this->log->write("Очистка таблиц товаров: "); 1248 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product`'); 1249 | if ($enable_log) 1250 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product`'); 1251 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_attribute`'); 1252 | if ($enable_log) 1253 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_attribute`'); 1254 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_description`'); 1255 | if ($enable_log) 1256 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_description`'); 1257 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_discount`'); 1258 | if ($enable_log) 1259 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_discount`'); 1260 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_image`'); 1261 | if ($enable_log) 1262 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_image`'); 1263 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_option`'); 1264 | if ($enable_log) 1265 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_option`'); 1266 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_option_value`'); 1267 | if ($enable_log) 1268 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_option_value`'); 1269 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_related`'); 1270 | if ($enable_log) 1271 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_related`'); 1272 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_reward`'); 1273 | if ($enable_log) 1274 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_reward`'); 1275 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_special`'); 1276 | if ($enable_log) 1277 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_special`'); 1278 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_1c`'); 1279 | if ($enable_log) 1280 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_1c`'); 1281 | 1282 | if ($this->config->get('exchange1c_relatedoptions')) { 1283 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_to_char`'); 1284 | if ($enable_log) $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_to_char`'); 1285 | 1286 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions`'); 1287 | if ($enable_log) $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions`'); 1288 | 1289 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_option`'); 1290 | if ($enable_log) $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_option`'); 1291 | 1292 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_variant`'); 1293 | if ($enable_log) $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_variant`'); 1294 | 1295 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_variant_option`'); 1296 | if ($enable_log) $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_variant_option`'); 1297 | 1298 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_variant_product`'); 1299 | if ($enable_log) $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'relatedoptions_variant_product`'); 1300 | } 1301 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_category`'); 1302 | if ($enable_log) 1303 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_category`'); 1304 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_download`'); 1305 | if ($enable_log) 1306 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_download`'); 1307 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_layout`'); 1308 | if ($enable_log) 1309 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_layout`'); 1310 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_store`'); 1311 | if ($enable_log) 1312 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_store`'); 1313 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'option_value_description`'); 1314 | if ($enable_log) 1315 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'option_value_description`'); 1316 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'option_description`'); 1317 | if ($enable_log) 1318 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'option_description`'); 1319 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'option_value`'); 1320 | if ($enable_log) 1321 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'option_value`'); 1322 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'order_option`'); 1323 | if ($enable_log) 1324 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'order_option`'); 1325 | $this->db->query('TRUNCATE TABLE `' . DB_PREFIX . 'option`'); 1326 | if ($enable_log) 1327 | $this->log->write('TRUNCATE TABLE `' . DB_PREFIX . 'option`'); 1328 | $this->db->query('DELETE FROM ' . DB_PREFIX . 'url_alias WHERE query LIKE "%product_id=%"'); 1329 | if ($enable_log) 1330 | $this->log->write('DELETE FROM ' . DB_PREFIX . 'url_alias WHERE query LIKE "%product_id=%"'); 1331 | } 1332 | 1333 | // Очищает таблицы категорий 1334 | if ($params['category']) { 1335 | if ($enable_log) 1336 | $this->log->write("Очистка таблиц категорий:"); 1337 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'category'); 1338 | if ($enable_log) 1339 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'category'); 1340 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_description'); 1341 | if ($enable_log) 1342 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'category_description'); 1343 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_store'); 1344 | if ($enable_log) 1345 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_store'); 1346 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_layout'); 1347 | if ($enable_log) 1348 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'category_path'); 1349 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_path'); 1350 | if ($enable_log) 1351 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_layout'); 1352 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_1c'); 1353 | if ($enable_log) 1354 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_1c'); 1355 | $this->db->query('DELETE FROM ' . DB_PREFIX . 'url_alias WHERE query LIKE "%category_id=%"'); 1356 | if ($enable_log) 1357 | $this->log->write('DELETE FROM ' . DB_PREFIX . 'url_alias WHERE query LIKE "%category_id=%"'); 1358 | } 1359 | 1360 | // Очищает таблицы от всех производителей 1361 | if ($params['manufacturer']) { 1362 | if ($enable_log) 1363 | $this->log->write("Очистка таблиц производителей:"); 1364 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer'); 1365 | if ($enable_log) 1366 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer'); 1367 | 1368 | $query = $this->db->query("SHOW TABLES FROM " . DB_DATABASE . " LIKE '" . DB_PREFIX . "manufacturer_description'"); 1369 | if ($query->num_rows) { 1370 | if ($enable_log) { 1371 | $this->log->write("Очистка таблиц описания производителей:"); 1372 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer_description'); 1373 | } 1374 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer_description'); 1375 | } 1376 | 1377 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer_to_store'); 1378 | if ($enable_log) 1379 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer_to_store'); 1380 | $this->db->query('DELETE FROM ' . DB_PREFIX . 'url_alias WHERE query LIKE "%manufacturer_id=%"'); 1381 | if ($enable_log) 1382 | $this->log->write('DELETE FROM ' . DB_PREFIX . 'url_alias WHERE query LIKE "%manufacturer_id=%"'); 1383 | } 1384 | 1385 | // Очищает атрибуты 1386 | if ($params['attribute']) { 1387 | if ($enable_log) 1388 | $this->log->write("Очистка таблиц атрибутов:"); 1389 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'attribute'); 1390 | if ($enable_log) 1391 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'attribute'); 1392 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_description'); 1393 | if ($enable_log) 1394 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_description'); 1395 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_to_1c'); 1396 | if ($enable_log) 1397 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_to_1c'); 1398 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_group'); 1399 | if ($enable_log) 1400 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_group'); 1401 | $this->db->query('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_group_description'); 1402 | if ($enable_log) 1403 | $this->log->write('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_group_description'); 1404 | } 1405 | 1406 | // Выставляем кол-во товаров в 0 1407 | if($params['quantity']) { 1408 | $this->db->query('UPDATE ' . DB_PREFIX . 'product ' . 'SET quantity = 0'); 1409 | } 1410 | 1411 | } 1412 | 1413 | /** 1414 | * Создает таблицы, нужные для работы 1415 | */ 1416 | public function checkDbSheme() { 1417 | 1418 | $query = $this->db->query('SHOW TABLES LIKE "' . DB_PREFIX . 'product_to_1c"'); 1419 | 1420 | if(!$query->num_rows) { 1421 | $this->db->query( 1422 | 'CREATE TABLE 1423 | `' . DB_PREFIX . 'product_to_1c` ( 1424 | `product_id` int(11) NOT NULL, 1425 | `1c_id` varchar(255) NOT NULL, 1426 | KEY (`product_id`), 1427 | KEY `1c_id` (`1c_id`), 1428 | FOREIGN KEY (product_id) REFERENCES '. DB_PREFIX .'product(product_id) ON DELETE CASCADE 1429 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8' 1430 | ); 1431 | } 1432 | 1433 | $query = $this->db->query('SHOW TABLES LIKE "' . DB_PREFIX . 'category_to_1c"'); 1434 | 1435 | if(!$query->num_rows) { 1436 | $this->db->query( 1437 | 'CREATE TABLE 1438 | `' . DB_PREFIX . 'category_to_1c` ( 1439 | `category_id` int(11) NOT NULL, 1440 | `1c_category_id` varchar(255) NOT NULL, 1441 | KEY (`category_id`), 1442 | KEY `1c_id` (`1c_category_id`), 1443 | FOREIGN KEY (category_id) REFERENCES '. DB_PREFIX .'category(category_id) ON DELETE CASCADE 1444 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8' 1445 | ); 1446 | } 1447 | 1448 | $query = $this->db->query('SHOW TABLES LIKE "' . DB_PREFIX . 'attribute_to_1c"'); 1449 | 1450 | if(!$query->num_rows) { 1451 | $this->db->query( 1452 | 'CREATE TABLE 1453 | `' . DB_PREFIX . 'attribute_to_1c` ( 1454 | `attribute_id` int(11) NOT NULL, 1455 | `1c_attribute_id` varchar(255) NOT NULL, 1456 | KEY (`attribute_id`), 1457 | KEY `1c_id` (`1c_attribute_id`), 1458 | FOREIGN KEY (attribute_id) REFERENCES '. DB_PREFIX .'attribute(attribute_id) ON DELETE CASCADE 1459 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8' 1460 | ); 1461 | } 1462 | } 1463 | 1464 | } 1465 | --------------------------------------------------------------------------------