├── downloaded
└── .gitkeep
├── etc
├── sql
│ ├── sync.sample.sql
│ ├── dump.sql
│ └── sync.magento.sql
└── mailtemplate.php
├── .gitignore
├── index.php
├── composer.json
├── local
├── bootstrap.php
└── XmlImport
│ ├── Config
│ └── Config.php
│ ├── Helpers
│ ├── VarHelper.php
│ ├── MailHelper.php
│ └── CurlHelper.php
│ ├── Runner
│ └── Runner.php
│ └── Adapters
│ └── AdapterBase.php
├── LICENSE
└── config.sample.php
/downloaded/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/etc/sql/sync.sample.sql:
--------------------------------------------------------------------------------
1 | -- @adapter_id
2 | -- @adapter_name
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/
2 | /vendor/
3 | /local/Zaimoglu/
4 | /config.php
5 | /composer.lock
6 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | start();
7 |
8 | exit($tRunner->exitCode);
9 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eser.ozvataf/xmlimport",
3 | "authors": [
4 | {
5 | "name": "larukedi",
6 | "email": "eser@sent.com"
7 | }
8 | ],
9 | "require": {
10 | "php-objects/query-builder": "dev-master"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/local/bootstrap.php:
--------------------------------------------------------------------------------
1 | addPsr4("", __DIR__ . "/");
15 |
16 | \XmlImport\Config\Config::set($tConfig);
17 |
--------------------------------------------------------------------------------
/etc/mailtemplate.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | XmlImport Error
4 |
13 |
14 |
15 | XmlImport Error
16 |
17 |
18 |
19 | getMessage(); ?>
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Copyright 2015 Eser 'Laroux' Ozvataf
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
--------------------------------------------------------------------------------
/local/XmlImport/Config/Config.php:
--------------------------------------------------------------------------------
1 | array(
3 | "conn" => "mysql:host=localhost;dbname=xmlimport",
4 | "username" => "root",
5 | "password" => ""
6 | ),
7 | "mail" => array(
8 | "from" => "xmlimport@github.com",
9 | "to" => "eser@sent.com",
10 | "headers" => array(
11 | "X-Mailer" => "PHP/" . phpversion()
12 | )
13 | ),
14 | "adapters" => array(
15 | array(
16 | "class" => "Vendor\\XmlAdapters\\Sample",
17 | "config" => array(
18 | "id" => 1,
19 | "name" => "Sample",
20 | "url" => "http://www.domain.com/path/filename.xml",
21 | "sql.sync" => "etc/sql/sync.sample.sql",
22 | "downloads" => "downloaded/"
23 | )
24 | )
25 | )
26 | );
27 |
--------------------------------------------------------------------------------
/local/XmlImport/Helpers/VarHelper.php:
--------------------------------------------------------------------------------
1 | Config::get("mail/from"),
14 | "Reply-To" => Config::get("mail/from"),
15 | "Content-Type" => "text/html; charset=utf-8"
16 | );
17 | $tHeaders += Config::get("mail/headers");
18 |
19 | $tHeadersRaw = "";
20 | foreach ($tHeaders as $tHeaderKey => $tHeaderValue) {
21 | if (strlen($tHeadersRaw) > 0) {
22 | $tHeadersRaw .= PHP_EOL;
23 | }
24 |
25 | $tHeadersRaw .= "{$tHeaderKey}: {$tHeaderValue}";
26 | }
27 |
28 | mail($uTo, $uSubject, $uMessage, $tHeadersRaw);
29 | }
30 |
31 | public static function sendLog($uSubject, $uMessage)
32 | {
33 | static::send(Config::get("mail/to"), $uSubject, $uMessage);
34 | }
35 |
36 | public static function sendException(Exception $uException)
37 | {
38 | // for templating
39 | $exception = $uException;
40 |
41 | ob_start();
42 | require BASE_DIR . "etc/mailtemplate.php";
43 | $tContent = ob_get_clean();
44 |
45 | static::sendLog("XmlImport Error: " . get_class($uException), $tContent);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/local/XmlImport/Runner/Runner.php:
--------------------------------------------------------------------------------
1 | pdo = new PDO(
26 | Config::get("database/conn"),
27 | Config::get("database/username"),
28 | Config::get("database/password")
29 | );
30 |
31 | $this->pdo->exec("SET NAMES 'utf8'");
32 | } catch (PDOException $tEx) {
33 | MailHelper::sendException($tEx);
34 | throw $tEx;
35 | }
36 |
37 | // load adapters
38 | $tAdapterConfigs = Config::get("adapters");
39 |
40 | foreach ($tAdapterConfigs as $tAdapterConfig) {
41 | $this->adapterInstances[] = new $tAdapterConfig["class"] ($this, $tAdapterConfig["config"]);
42 | }
43 |
44 | // download data
45 | foreach ($this->adapterInstances as $tAdapterInstance) {
46 | try {
47 | $tAdapterInstance->start();
48 | } catch (Exception $tEx) {
49 | MailHelper::sendException($tEx);
50 | throw $tEx;
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/local/XmlImport/Helpers/CurlHelper.php:
--------------------------------------------------------------------------------
1 | $uUrl,
24 | CURLOPT_TIMEOUT => 50,
25 | CURLOPT_FILE => $tFilePointer,
26 | CURLOPT_FOLLOWLOCATION => true,
27 | CURLOPT_SSL_VERIFYPEER => false
28 | )
29 | );
30 |
31 | $tLoop = 0;
32 | $tFailed = false;
33 |
34 | while (true) {
35 | curl_exec($tCurl);
36 | $tLoop++;
37 |
38 | $tError = curl_errno($tCurl);
39 | if ($tError !== 0) {
40 | $tHttpStatus = curl_getinfo($tCurl, CURLINFO_HTTP_CODE);
41 |
42 | // HTTP 5xx
43 | if ($tLoop < 3 && ($tHttpStatus >= 500 && $tHttpStatus < 600)) {
44 | echo "* HTTP {$tHttpStatus}, trying again...", PHP_EOL;
45 | // try again after 1 second delay
46 | usleep(1000000);
47 | continue;
48 | }
49 |
50 | echo "* CURL Error No {$tError} w/ HTTP {$tHttpStatus}...", PHP_EOL;
51 | // echo "CURL Error Message: ", curl_error($tCurl), PHP_EOL;
52 | $tFailed = true;
53 | }
54 |
55 | break;
56 | }
57 |
58 | curl_close($tCurl);
59 |
60 | fclose($tFilePointer);
61 |
62 | if ($tFailed) {
63 | unlink($uFile);
64 | return false;
65 | }
66 |
67 | return $uFile;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/etc/sql/dump.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Navicat MariaDB Data Transfer
3 |
4 | Source Server : local-maria
5 | Source Server Version : 50542
6 | Source Host : localhost:3306
7 | Source Database : localhost
8 |
9 | Target Server Type : MariaDB
10 | Target Server Version : 50542
11 | File Encoding : 65001
12 |
13 | Date: 2015-04-22 01:32:36
14 | */
15 |
16 | -- ----------------------------
17 | -- Table structure for XmlImport
18 | -- ----------------------------
19 | DROP TABLE IF EXISTS `XmlImport`;
20 | CREATE TABLE `XmlImport` (
21 | `ItemId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
22 | `AdapterId` int(10) UNSIGNED NOT NULL ,
23 | `Checksum` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
24 | `Status` int(10) UNSIGNED NOT NULL ,
25 | `LastUpdate` datetime NOT NULL ,
26 | `RemoteId` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
27 | `RemoteUrl` varchar(2048) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
28 | `RemoteSKU` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
29 | `RemoteBarcode` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
30 | `Brand` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
31 | `Model` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
32 | `RemoteCategoryId1` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
33 | `RemoteCategoryName1` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
34 | `RemoteCategoryId2` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
35 | `RemoteCategoryName2` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
36 | `RemoteCategoryId3` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
37 | `RemoteCategoryName3` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
38 | `RemoteCategoryId4` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
39 | `RemoteCategoryName4` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
40 | `Name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
41 | `ShortDescription` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
42 | `LongDescription` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
43 | `Price` decimal(10,4) NOT NULL ,
44 | `DiscountedPrice` decimal(10,4) NOT NULL ,
45 | `VAT` int(10) UNSIGNED NOT NULL ,
46 | `Currency` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
47 | `Quantity` int(10) UNSIGNED NOT NULL ,
48 | `Minimum` int(10) UNSIGNED NOT NULL ,
49 | `Images` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
50 | `Options` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
51 | `Attributes` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
52 | `Type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
53 | `AttributeSet` int(10) UNSIGNED NOT NULL ,
54 | `VendorCode` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
55 | `VendorProfile` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
56 | PRIMARY KEY (`ItemId`)
57 | )
58 | ENGINE=InnoDB
59 | DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci;
60 |
61 |
62 | -- ----------------------------
63 | -- Table structure for XmlImportImages
64 | -- ----------------------------
65 | DROP TABLE IF EXISTS `XmlImportImages`;
66 | CREATE TABLE `XmlImportImages` (
67 | `ImageId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
68 | `ItemId` int(10) UNSIGNED NOT NULL ,
69 | `Url` varchar(2048) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
70 | PRIMARY KEY (`ImageId`)
71 | )
72 | ENGINE=InnoDB
73 | DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci;
74 |
--------------------------------------------------------------------------------
/local/XmlImport/Adapters/AdapterBase.php:
--------------------------------------------------------------------------------
1 | runner = $uRunner;
30 |
31 | $this->id = $uConfig["id"];
32 | $this->name = $uConfig["name"];
33 | $this->url = $uConfig["url"];
34 | $this->sqlSyncFile = $uConfig["sql.sync"];
35 | $this->downloadsPath = rtrim($uConfig["downloads"], "/") . "/";
36 |
37 | $this->sqlParameters = array(
38 | ":adapter_id" => $this->id,
39 | ":adapter_name" => $this->name
40 | );
41 | }
42 |
43 | public function start()
44 | {
45 | echo "Adapter {$this->name} is starting...", PHP_EOL;
46 |
47 | echo "- Downloading XML from {$this->url}", PHP_EOL;
48 | $tFile = $this->downloadSource();
49 | if ($tFile === false) {
50 | // TODO throw error
51 | return false;
52 | }
53 |
54 | $this->recordsAdded = 0;
55 | $this->recordsUpdated = 0;
56 | $this->recordsSkipped = 0;
57 | $this->downloads = array();
58 |
59 | echo "- Processing Data", PHP_EOL;
60 | $this->loadPreviousMaps();
61 | $this->processFile($tFile);
62 | echo "-- Completed: {$this->recordsAdded} added. {$this->recordsUpdated} updated. {$this->recordsSkipped} skipped.", PHP_EOL;
63 |
64 | echo "- Syncing SQL", PHP_EOL;
65 | $this->setRedundantsPassive();
66 | $this->syncSql();
67 |
68 | echo "- Downloading Assets", PHP_EOL;
69 | $this->downloadAssets();
70 | echo "-- Completed.", PHP_EOL, PHP_EOL;
71 | }
72 |
73 | public function downloadSource()
74 | {
75 | return CurlHelper::downloadFile($this->url);
76 | }
77 |
78 | public function downloadAssets()
79 | {
80 | foreach ($this->downloads as $tDownload) {
81 | $tLocalDirectory = $this->downloadsPath . $tDownload["directory"];
82 | $tLocalFile = "{$tLocalDirectory}/{$tDownload["file"]}";
83 | if (!is_dir($tLocalDirectory)) {
84 | mkdir($tLocalDirectory, 0777, true);
85 | } else {
86 | if (file_exists($tLocalFile)) {
87 | continue;
88 | }
89 | }
90 |
91 | echo "-- Downloading: {$tDownload["file"]}", PHP_EOL;
92 | CurlHelper::downloadFile($tDownload["url"], $tLocalFile);
93 | }
94 | }
95 |
96 | public function loadPreviousMaps()
97 | {
98 | $tSelectQuery = QueryBuilder::factorySelect()
99 | ->select("ItemId, Checksum, RemoteId")
100 | ->from("XmlImport")
101 | ->where("AdapterId", $this->id)
102 | ->toSql();
103 |
104 | $this->previousRemoteIdMap = array();
105 | $this->previousChecksumMap = array();
106 | $this->recordCheckListMap = array();
107 |
108 | $tRows = $this->runner->pdo->query($tSelectQuery);
109 | foreach ($tRows as $tRow) {
110 | $this->previousRemoteIdMap[$tRow["RemoteId"]] = $tRow["ItemId"];
111 | $this->previousChecksumMap[$tRow["ItemId"]] = $tRow["Checksum"];
112 | $this->recordCheckListMap[$tRow["ItemId"]] = true;
113 | }
114 | }
115 |
116 | public function setRedundantsPassive()
117 | {
118 | if (count($this->recordCheckListMap) > 0) {
119 | $tUpdateQuery = QueryBuilder::update()
120 | ->table("XmlImport")
121 | ->set(array(
122 | "Status" => 0
123 | ))
124 | ->where(array(
125 | "ItemID IN (" . implode(", ", array_keys($this->recordCheckListMap)) . ")",
126 | array("AdapterId", $this->id)
127 | ))
128 | ->toSql();
129 |
130 | $this->runner->pdo->exec($tUpdateQuery);
131 | }
132 | }
133 |
134 | public function syncSql()
135 | {
136 | if (strlen($this->sqlSyncFile) === 0) {
137 | return;
138 | }
139 |
140 | $tPath = BASE_DIR . $this->sqlSyncFile;
141 | $tSql = file_get_contents($tPath);
142 |
143 | $tQuery = $this->runner->pdo->prepare($tSql);
144 | $tQuery->execute($this->sqlParameters);
145 | }
146 |
147 | public function processFile($uFile)
148 | {
149 | $tXml = simplexml_load_file($uFile);
150 | // TODO throw error if it is not loaded
151 | return $this->processXml($tXml);
152 | }
153 |
154 | public abstract function processXml(SimpleXMLElement $uXml);
155 |
156 | protected function addDownload($uAdapterId, $uCategory, $uUrl)
157 | {
158 | $tDownload = array(
159 | "url" => $uUrl,
160 | "directory" => "xmlimport/{$uAdapterId}/{$uCategory}",
161 | "file" => str_replace(
162 | "/",
163 | "_",
164 | parse_url($uUrl, PHP_URL_PATH)
165 | )
166 | );
167 |
168 | $this->downloads[] = $tDownload;
169 |
170 | return $tDownload;
171 | }
172 |
173 | protected function addRecord($uValues, $uImages = array())
174 | {
175 | $tDownload = false;
176 | $tItemId = 0;
177 |
178 | if (isset($this->previousRemoteIdMap[$uValues["RemoteId"]])) {
179 | $tPreviousId = $this->previousRemoteIdMap[$uValues["RemoteId"]];
180 | $tPreviousChecksum = $this->previousChecksumMap[$tPreviousId];
181 |
182 | // update if the record has changed
183 | if ($tPreviousChecksum != $uValues["Checksum"]) {
184 | $tUpdateQuery = QueryBuilder::update()
185 | ->table("XmlImport")
186 | ->set($uValues)
187 | ->where("ItemId", $tPreviousId)
188 | ->limit(1)
189 | ->toSql();
190 |
191 | $this->runner->pdo->exec($tUpdateQuery);
192 |
193 | $this->recordsUpdated++;
194 | } else {
195 | $this->recordsSkipped++;
196 | }
197 |
198 | unset($this->recordCheckListMap[$tPreviousId]);
199 | } else {
200 | $tInsertQuery = QueryBuilder::insert()
201 | ->into("XmlImport")
202 | ->values($uValues)
203 | ->toSql();
204 |
205 | $this->runner->pdo->exec($tInsertQuery);
206 | $tItemId = $this->runner->pdo->lastInsertId();
207 |
208 | $this->recordsAdded++;
209 | $tDownload = true;
210 | }
211 |
212 | if ($tDownload && $uValues["Status"] != 0) {
213 | foreach ($uImages as $tImage) {
214 | $tDownload = $this->addDownload($this->id, "images", $tImage);
215 |
216 | $tInsertImageQuery = QueryBuilder::insert()
217 | ->into("XmlImportImages")
218 | ->values(array(
219 | "ItemId" => $tItemId,
220 | "Url" => "{$tDownload["directory"]}/{$tDownload["file"]}"
221 | ))
222 | ->toSql();
223 |
224 | $this->runner->pdo->exec($tInsertImageQuery);
225 | }
226 | }
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/etc/sql/sync.magento.sql:
--------------------------------------------------------------------------------
1 | -- :adapter_id
2 | -- :adapter_name
3 | -- :attribute_set_id
4 |
5 | SET @adapter_id = :adapter_id;
6 | SET @adapter_name = :adapter_name;
7 | SET @attribute_set_id = :attribute_set_id;
8 |
9 | -- create temp table
10 | DROP TABLE IF EXISTS `XmlImportEntities`;
11 | CREATE TEMPORARY TABLE `XmlImportEntities` (
12 | `LocalId` INT NOT NULL,
13 | `SyncTag` VARCHAR(64) NOT NULL,
14 | `EntityId` INT
15 | -- `xmlsync` INT NOT NULL
16 | );
17 |
18 | INSERT INTO `XmlImportEntities`
19 | SELECT
20 | xi.`ItemId` AS `LocalId`,
21 | COALESCE(p.`sku`, CONCAT(@adapter_name, '_', COALESCE(xi.`RemoteSKU`, xi.`RemoteId`))) AS `SyncTag`,
22 | vendor_product_id.`entity_id`
23 | -- (xml.`value` IS NULL OR xml.`value` IN (6222, 6223)) AS `xmlsync`
24 | FROM
25 | `XmlImport` xi
26 | LEFT JOIN `mwcatalog_product_entity_varchar` vendor_product_id ON xi.`RemoteId`=vendor_product_id.`value` AND vendor_product_id.`attribute_id` = 176 AND vendor_product_id.`store_id` = 0
27 | LEFT JOIN `mwcatalog_product_entity` p ON vendor_product_id.`entity_id`=p.`entity_id` AND p.`attribute_set_id`=@attribute_set_id
28 | LEFT JOIN `mwcatalog_product_entity_int` xml ON p.`entity_id`=xml.`entity_id` AND xml.`attribute_id` = 266 AND xml.`store_id` = 0
29 | WHERE
30 | xi.`Status` = 1 AND
31 | xi.`AdapterId` = @adapter_id AND
32 | (xml.`value` IS NULL OR xml.`value` IN (6222, 6223));
33 |
34 | -- disable existing entities first
35 | UPDATE
36 | `mwcatalog_product_entity_int` ints
37 | INNER JOIN `mwcatalog_product_entity` p ON ints.`entity_id`=p.`entity_id` AND ints.`attribute_id` = 84 AND ints.`store_id` = 0
38 | LEFT JOIN `mwcatalog_product_entity_int` xml ON p.`entity_id`=xml.`entity_id` AND xml.`attribute_id` = 266 AND xml.`store_id` = 0
39 | SET
40 | ints.`value` = 0
41 | WHERE
42 | p.`attribute_set_id`=@attribute_set_id AND
43 | (xml.`value` IS NULL OR xml.`value` IN (6222, 6223));
44 |
45 | -- update existing entities
46 | UPDATE `mwcatalog_product_entity` p
47 | INNER JOIN `XmlImportEntities` xie ON p.`entity_id`=xie.`EntityId`
48 | SET p.`updated_at`=NOW();
49 |
50 | -- insert new entities
51 | INSERT INTO `mwcatalog_product_entity`
52 | SELECT
53 | NULL AS `entity_id`,
54 | 4 AS `entity_type_id`,
55 | @attribute_set_id AS `attribute_set_id`,
56 | 'simple' AS `type_id`,
57 | xie.`SyncTag` AS `sku`,
58 | 0 AS `has_options`,
59 | 0 AS `required_options`,
60 | NOW() AS `created_at`,
61 | NOW() AS `updated_at`
62 | FROM
63 | `XmlImportEntities` xie
64 | WHERE
65 | xie.`EntityId` IS NULL;
66 |
67 | -- set entity_id of inserted entities
68 | UPDATE
69 | `XmlImportEntities` xie
70 | LEFT JOIN `mwcatalog_product_entity` p ON xie.`SyncTag`=p.`sku`
71 | SET
72 | xie.`EntityId`=p.`entity_id`
73 | WHERE
74 | xie.`EntityId` IS NULL;
75 |
76 | -- update quantity
77 | UPDATE
78 | `mwcataloginventory_stock_item` qty
79 | INNER JOIN `XmlImportEntities` xie ON qty.`product_id`=xie.`EntityId`
80 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
81 | SET
82 | qty.`qty`=xi.Quantity,
83 | qty.`is_in_stock`=(xi.Quantity > 0);
84 |
85 | -- insert quantity
86 | INSERT INTO `mwcataloginventory_stock_item`
87 | SELECT
88 | NULL AS `item_id`,
89 | xie.`EntityId` AS `product_id`,
90 | 1 AS `stock_id`,
91 | xi.`Quantity` AS `qty`,
92 | 0 AS `min_qty`,
93 | 1 AS `use_config_min_qty`,
94 | 0 AS `is_qty_decimal`,
95 | 0 AS `backorders`,
96 | 1 AS `use_config_backorders`,
97 | 1 AS `min_sale_qty`,
98 | 0 AS `use_config_min_sale_qty`,
99 | 0 AS `max_sale_qty`,
100 | 1 AS `use_config_max_sale_qty`,
101 | 1 AS `is_in_stock`,
102 | NULL AS `low_stock_date`,
103 | NULL AS `notify_stock_qty`,
104 | 1 AS `use_config_notify_stock_qty`,
105 | 0 AS `manage_stock`,
106 | 1 AS `use_config_manage_stock`,
107 | 0 AS `stock_status_changed_automatically`,
108 | 1 AS `use_config_qty_increments`,
109 | 0 AS `qty_increments`,
110 | 1 AS `use_config_enable_qty_increments`,
111 | 0 AS `use_config_increments`
112 | FROM
113 | `XmlImportEntities` xie
114 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
115 | LEFT JOIN `mwcataloginventory_stock_item` qty ON xie.`EntityId`=qty.`product_id`
116 | WHERE
117 | qty.`product_id` IS NULL;
118 |
119 | -- update ints
120 | UPDATE
121 | `mwcatalog_product_entity_int` ints
122 | INNER JOIN `XmlImportEntities` xie ON ints.`entity_id`=xie.`EntityId`
123 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
124 | SET
125 | ints.`value`=CASE ints.`attribute_id`
126 | WHEN 84 THEN 1
127 | END
128 | WHERE
129 | ints.`attribute_id` IN (84) AND ints.`store_id` = 0;
130 |
131 | -- insert ints: status
132 | INSERT INTO `mwcatalog_product_entity_int`
133 | SELECT
134 | NULL AS `value_id`,
135 | 4 AS `entity_type_id`,
136 | 84 AS `attribute_id`,
137 | 0 AS `store_id`,
138 | xie.`EntityId` AS `entity_id`,
139 | 1 AS `value`
140 | FROM
141 | `XmlImportEntities` xie
142 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
143 | LEFT JOIN `mwcatalog_product_entity_int` ints ON xie.`EntityId`=ints.`entity_id`
144 | WHERE
145 | ints.`value_id` IS NULL;
146 |
147 | -- insert ints: tax class
148 | INSERT INTO `mwcatalog_product_entity_int`
149 | SELECT
150 | NULL AS `value_id`,
151 | 4 AS `entity_type_id`,
152 | 85 AS `attribute_id`,
153 | 0 AS `store_id`,
154 | xie.`EntityId` AS `entity_id`,
155 | 3810 AS `value`
156 | FROM
157 | `XmlImportEntities` xie
158 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
159 | LEFT JOIN `mwcatalog_product_entity_int` ints ON xie.`EntityId`=ints.`entity_id`
160 | WHERE
161 | ints.`value_id` IS NULL;
162 |
163 | -- insert ints: visibility
164 | INSERT INTO `mwcatalog_product_entity_int`
165 | SELECT
166 | NULL AS `value_id`,
167 | 4 AS `entity_type_id`,
168 | 91 AS `attribute_id`,
169 | 0 AS `store_id`,
170 | xie.`EntityId` AS `entity_id`,
171 | 3808 AS `value`
172 | FROM
173 | `XmlImportEntities` xie
174 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
175 | LEFT JOIN `mwcatalog_product_entity_int` ints ON xie.`EntityId`=ints.`entity_id`
176 | WHERE
177 | ints.`value_id` IS NULL;
178 |
179 | -- insert ints: brand
180 | INSERT INTO `mwcatalog_product_entity_int`
181 | SELECT
182 | NULL AS `value_id`,
183 | 4 AS `entity_type_id`,
184 | 159 AS `attribute_id`,
185 | 0 AS `store_id`,
186 | xie.`EntityId` AS `entity_id`,
187 | XmlImportUpsertValue(159, xi.`Brand`) AS `value`
188 | FROM
189 | `XmlImportEntities` xie
190 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
191 | LEFT JOIN `mwcatalog_product_entity_int` ints ON xie.`EntityId`=ints.`entity_id`
192 | WHERE
193 | ints.`value_id` IS NULL;
194 |
195 | -- insert ints: category
196 | INSERT INTO `mwcatalog_product_entity_int`
197 | SELECT
198 | NULL AS `value_id`,
199 | 4 AS `entity_type_id`,
200 | 195 AS `attribute_id`,
201 | 0 AS `store_id`,
202 | xie.`EntityId` AS `entity_id`,
203 | XmlImportUpsertValue(195, xi.`RemoteCategoryName1`) AS `value`
204 | FROM
205 | `XmlImportEntities` xie
206 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
207 | LEFT JOIN `mwcatalog_product_entity_int` ints ON xie.`EntityId`=ints.`entity_id`
208 | WHERE
209 | ints.`value_id` IS NULL;
210 |
211 | -- insert ints: xml_updated
212 | INSERT INTO `mwcatalog_product_entity_int`
213 | SELECT
214 | NULL AS `value_id`,
215 | 4 AS `entity_type_id`,
216 | 266 AS `attribute_id`,
217 | 0 AS `store_id`,
218 | xie.`EntityId` AS `entity_id`,
219 | 6223 AS `value`
220 | FROM
221 | `XmlImportEntities` xie
222 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
223 | LEFT JOIN `mwcatalog_product_entity_int` ints ON xie.`EntityId`=ints.`entity_id`
224 | WHERE
225 | ints.`value_id` IS NULL;
226 |
227 | -- update decimals
228 | UPDATE
229 | `mwcatalog_product_entity_decimal` decimals
230 | INNER JOIN `XmlImportEntities` xie ON decimals.`entity_id`=xie.`EntityId`
231 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
232 | SET
233 | decimals.`value`=CASE decimals.attribute_id
234 | WHEN 64 THEN xi.`Price`
235 | WHEN 65 THEN xi.`DiscountedPrice`
236 | END
237 | WHERE
238 | decimals.`attribute_id` IN (64, 65) AND decimals.`store_id` = 0;
239 |
240 | -- insert decimals: price
241 | INSERT INTO `mwcatalog_product_entity_decimal`
242 | SELECT
243 | NULL AS `value_id`,
244 | 4 AS `entity_type_id`,
245 | 64 AS `attribute_id`,
246 | 0 AS `store_id`,
247 | xie.`EntityId` AS `entity_id`,
248 | xi.`Price` AS `value`
249 | FROM
250 | `XmlImportEntities` xie
251 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
252 | LEFT JOIN `mwcatalog_product_entity_decimal` decimals ON xie.`EntityId`=decimals.`entity_id`
253 | WHERE
254 | decimals.`value_id` IS NULL;
255 |
256 | -- insert decimals: discounted price
257 | INSERT INTO `mwcatalog_product_entity_decimal`
258 | SELECT
259 | NULL AS `value_id`,
260 | 4 AS `entity_type_id`,
261 | 65 AS `attribute_id`,
262 | 0 AS `store_id`,
263 | xie.`EntityId` AS `entity_id`,
264 | xi.`DiscountedPrice` AS `value`
265 | FROM
266 | `XmlImportEntities` xie
267 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
268 | LEFT JOIN `mwcatalog_product_entity_decimal` decimals ON xie.`EntityId`=decimals.`entity_id`
269 | WHERE
270 | decimals.`value_id` IS NULL;
271 |
272 | -- delete decimals: discounted price
273 | DELETE FROM `mwcatalog_product_entity_decimal`
274 | WHERE `attribute_id` = 65 AND `value` = 0 AND `store_id` = 0;
275 |
276 | -- update varchars
277 | UPDATE
278 | `mwcatalog_product_entity_varchar` varchars
279 | INNER JOIN `XmlImportEntities` xie ON varchars.`entity_id`=xie.`EntityId`
280 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
281 | SET
282 | varchars.`value`=CASE varchars.attribute_id
283 | WHEN 181 THEN xi.`RemoteBarcode`
284 | END
285 | WHERE
286 | varchars.`attribute_id` IN (181) AND varchars.`store_id` = 0;
287 |
288 | -- insert varchars: barcode
289 | INSERT INTO `mwcatalog_product_entity_varchar`
290 | SELECT
291 | NULL AS `value_id`,
292 | 4 AS `entity_type_id`,
293 | 181 AS `attribute_id`,
294 | 0 AS `store_id`,
295 | xie.`EntityId` AS `entity_id`,
296 | xi.`RemoteBarcode` AS `value`
297 | FROM
298 | `XmlImportEntities` xie
299 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
300 | LEFT JOIN `mwcatalog_product_entity_varchar` varchars ON xie.`EntityId`=varchars.`entity_id`
301 | WHERE
302 | varchars.`value_id` IS NULL;
303 |
304 | -- insert varchars: images
305 | INSERT INTO `mwcatalog_product_entity_varchar`
306 | SELECT
307 | NULL AS `value_id`,
308 | 4 AS `entity_type_id`,
309 | 74 AS `attribute_id`,
310 | 0 AS `store_id`,
311 | xie.`EntityId` AS `entity_id`,
312 | (SELECT xii.`Url` FROM `XmlImportImages` xii WHERE xii.`ItemId`=xie.`LocalId` ORDER BY xii.`ImageId` ASC LIMIT 0, 1) AS `value`
313 | FROM
314 | `XmlImportEntities` xie
315 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
316 | LEFT JOIN `mwcatalog_product_entity_varchar` varchars ON xie.`EntityId`=varchars.`entity_id`
317 | WHERE
318 | varchars.`value_id` IS NULL;
319 |
320 | -- insert varchars: small images
321 | INSERT INTO `mwcatalog_product_entity_varchar`
322 | SELECT
323 | NULL AS `value_id`,
324 | 4 AS `entity_type_id`,
325 | 75 AS `attribute_id`,
326 | 0 AS `store_id`,
327 | xie.`EntityId` AS `entity_id`,
328 | (SELECT xii.`Url` FROM `XmlImportImages` xii WHERE xii.`ItemId`=xie.`LocalId` ORDER BY xii.`ImageId` ASC LIMIT 0, 1) AS `value`
329 | FROM
330 | `XmlImportEntities` xie
331 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
332 | LEFT JOIN `mwcatalog_product_entity_varchar` varchars ON xie.`EntityId`=varchars.`entity_id`
333 | WHERE
334 | varchars.`value_id` IS NULL;
335 |
336 | -- insert varchars: thumbnails
337 | INSERT INTO `mwcatalog_product_entity_varchar`
338 | SELECT
339 | NULL AS `value_id`,
340 | 4 AS `entity_type_id`,
341 | 76 AS `attribute_id`,
342 | 0 AS `store_id`,
343 | xie.`EntityId` AS `entity_id`,
344 | (SELECT xii.`Url` FROM `XmlImportImages` xii WHERE xii.`ItemId`=xie.`LocalId` ORDER BY xii.`ImageId` ASC LIMIT 0, 1) AS `value`
345 | FROM
346 | `XmlImportEntities` xie
347 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
348 | LEFT JOIN `mwcatalog_product_entity_varchar` varchars ON xie.`EntityId`=varchars.`entity_id`
349 | WHERE
350 | varchars.`value_id` IS NULL;
351 |
352 | -- insert varchars: image labels
353 | INSERT INTO `mwcatalog_product_entity_varchar`
354 | SELECT
355 | NULL AS `value_id`,
356 | 4 AS `entity_type_id`,
357 | 100 AS `attribute_id`,
358 | 0 AS `store_id`,
359 | xie.`EntityId` AS `entity_id`,
360 | xi.`Name` AS `value`
361 | FROM
362 | `XmlImportEntities` xie
363 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
364 | LEFT JOIN `mwcatalog_product_entity_varchar` varchars ON xie.`EntityId`=varchars.`entity_id`
365 | WHERE
366 | varchars.`value_id` IS NULL;
367 |
368 | -- insert varchars: small image labels
369 | INSERT INTO `mwcatalog_product_entity_varchar`
370 | SELECT
371 | NULL AS `value_id`,
372 | 4 AS `entity_type_id`,
373 | 101 AS `attribute_id`,
374 | 0 AS `store_id`,
375 | xie.`EntityId` AS `entity_id`,
376 | xi.`Name` AS `value`
377 | FROM
378 | `XmlImportEntities` xie
379 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
380 | LEFT JOIN `mwcatalog_product_entity_varchar` varchars ON xie.`EntityId`=varchars.`entity_id`
381 | WHERE
382 | varchars.`value_id` IS NULL;
383 |
384 | -- insert varchars: thumbnail labels
385 | INSERT INTO `mwcatalog_product_entity_varchar`
386 | SELECT
387 | NULL AS `value_id`,
388 | 4 AS `entity_type_id`,
389 | 102 AS `attribute_id`,
390 | 0 AS `store_id`,
391 | xie.`EntityId` AS `entity_id`,
392 | xi.`Name` AS `value`
393 | FROM
394 | `XmlImportEntities` xie
395 | INNER JOIN `XmlImport` xi ON xie.`LocalId`=xi.`ItemId` AND xi.`AdapterId`=@adapter_id
396 | LEFT JOIN `mwcatalog_product_entity_varchar` varchars ON xie.`EntityId`=varchars.`entity_id`
397 | WHERE
398 | varchars.`value_id` IS NULL;
399 |
--------------------------------------------------------------------------------