Skip to content

Commit b8e8ac6

Browse files
Merge pull request #22 from NicolasBarbey/fix/compatibility
Fix compatibility with old SQL versions
2 parents af2b36f + 4630156 commit b8e8ac6

File tree

10 files changed

+234
-26
lines changed

10 files changed

+234
-26
lines changed

Config/module.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<language>en_US</language>
1414
<language>fr_FR</language>
1515
</languages>
16-
<version>3.0.0</version>
16+
<version>3.0.1</version>
1717
<authors>
1818
<author>
1919
<name>Bertrand TOURLONIAS</name>

Config/routing.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
<default key="_controller">GoogleShoppingXml\Controller\GoogleFieldAssociationController::setEanRuleAction</default>
6666
</route>
6767

68+
<route id="googleshoppingxml.advanced.compatibility-sql" path="/admin/module/googleshoppingxml/advanced/compatibility-sql" methods="POST">
69+
<default key="_controller">GoogleShoppingXml\Controller\GoogleFieldAssociationController::setCompatibilitySqlAction</default>
70+
</route>
71+
6872

6973
<!-- XML ERROR LOG -->
7074
<route id="googleshoppingxml.log.get" path="/admin/module/googleshoppingxml/log/get" methods="GET">

Controller/GoogleFieldAssociationController.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
namespace GoogleShoppingXml\Controller;
44

5+
use GoogleShoppingXml\Form\CompatibilitySqlForm;
56
use GoogleShoppingXml\GoogleShoppingXml;
67
use GoogleShoppingXml\Model\GoogleshoppingxmlGoogleFieldAssociation;
78
use GoogleShoppingXml\Model\GoogleshoppingxmlGoogleFieldAssociationQuery;
89
use Thelia\Controller\Admin\BaseAdminController;
910
use Thelia\Core\HttpFoundation\Request;
1011
use Thelia\Core\Security\AccessManager;
1112
use Thelia\Core\Security\Resource\AdminResources;
13+
use Thelia\Core\Template\ParserContext;
1214
use Thelia\Core\Translation\Translator;
15+
use Thelia\Log\Tlog;
1316

1417
class GoogleFieldAssociationController extends BaseAdminController
1518
{
@@ -232,4 +235,28 @@ public function setEanRuleAction(Request $httpRequest)
232235

233236
return $this->generateRedirectFromRoute("admin.module.configure", array(), $redirectParameters);
234237
}
238+
239+
public function setCompatibilitySqlAction(ParserContext $parserContext)
240+
{
241+
$form = $this->createForm(CompatibilitySqlForm::getName());
242+
243+
try {
244+
$compatibilityForm = $this->validateForm($form);
245+
246+
GoogleShoppingXml::setConfigValue(GoogleShoppingXml::ENABLE_SQL_8_COMPATIBILITY, $compatibilityForm->get('enable_optimisation')->getData());
247+
248+
return $this->generateSuccessRedirect($form);
249+
}catch (\Exception $exception) {
250+
Tlog::getInstance()->error($exception->getMessage());
251+
252+
$form->setErrorMessage($exception->getMessage());
253+
254+
$parserContext
255+
->addForm($form)
256+
->setGeneralError($exception->getMessage())
257+
;
258+
259+
return $this->generateErrorRedirect($form);
260+
}
261+
}
235262
}

Form/CompatibilitySqlForm.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace GoogleShoppingXml\Form;
4+
5+
use GoogleShoppingXml\GoogleShoppingXml;
6+
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
7+
use Thelia\Core\Translation\Translator;
8+
use Thelia\Form\BaseForm;
9+
10+
class CompatibilitySqlForm extends BaseForm
11+
{
12+
protected function buildForm()
13+
{
14+
$this->formBuilder
15+
->add(
16+
'enable_optimisation',
17+
CheckboxType::class,
18+
[
19+
'label' => Translator::getInstance()->trans("Enable sql 8 optimisations"),
20+
'label_attr' => array(
21+
'for' => 'enable_sql_8'
22+
),
23+
'data' => (bool)GoogleShoppingXml::getConfigValue(GoogleShoppingXml::ENABLE_SQL_8_COMPATIBILITY),
24+
'required'=> false
25+
]
26+
);
27+
}
28+
29+
}

GoogleShoppingXml.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class GoogleShoppingXml extends BaseModule
1717
/* @var string */
1818
const UPDATE_PATH = __DIR__ . DS . 'Config' . DS . 'update';
1919

20+
const ENABLE_SQL_8_COMPATIBILITY = 'enable_sql_8_compatibility';
21+
2022
public function preActivation(ConnectionInterface $con = null)
2123
{
2224
if (!$this->getConfigValue('is_initialized', false)) {

Service/GoogleModel/GoogleProductModel.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ public function setPrice(float $price): GoogleProductModel
207207
* @param string $item_group_id
208208
* @return GoogleProductModel
209209
*/
210-
public function setItemGroupId(string $item_group_id): GoogleProductModel
210+
public function setItemGroupId(?string $item_group_id): GoogleProductModel
211211
{
212212
$this->item_group_id = $item_group_id;
213213
return $this;
@@ -217,7 +217,7 @@ public function setItemGroupId(string $item_group_id): GoogleProductModel
217217
* @param string $brand
218218
* @return GoogleProductModel
219219
*/
220-
public function setBrand(string $brand): GoogleProductModel
220+
public function setBrand(?string $brand): GoogleProductModel
221221
{
222222
$this->brand = $brand;
223223
return $this;
@@ -227,7 +227,7 @@ public function setBrand(string $brand): GoogleProductModel
227227
* @param string $google_product_category
228228
* @return GoogleProductModel
229229
*/
230-
public function setGoogleProductCategory(string $google_product_category): GoogleProductModel
230+
public function setGoogleProductCategory(?string $google_product_category): GoogleProductModel
231231
{
232232
$this->google_product_category = $google_product_category;
233233
return $this;
@@ -247,7 +247,7 @@ public function setCondition($condition = null): GoogleProductModel
247247
* @param string $product_type
248248
* @return GoogleProductModel
249249
*/
250-
public function setProductType(string $product_type): GoogleProductModel
250+
public function setProductType(?string $product_type): GoogleProductModel
251251
{
252252
$this->product_type = $product_type;
253253
return $this;
@@ -257,7 +257,7 @@ public function setProductType(string $product_type): GoogleProductModel
257257
* @param array $shipping
258258
* @return GoogleProductModel
259259
*/
260-
public function setshipping(array $shipping): GoogleProductModel
260+
public function setshipping(?array $shipping): GoogleProductModel
261261
{
262262
$this->shipping = $shipping;
263263
return $this;
@@ -266,7 +266,7 @@ public function setshipping(array $shipping): GoogleProductModel
266266
/**
267267
* @param int $imageId
268268
*/
269-
public function setImageLink(int $imageId): void
269+
public function setImageLink(?int $imageId): void
270270
{
271271
$this->image_link = URL::getInstance()->absoluteUrl("legacy-image-library/product_image_$imageId/full/max/0/default.jpg");
272272
}

Service/Provider/ProductProvider.php

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@
22

33
namespace GoogleShoppingXml\Service\Provider;
44

5+
use GoogleShoppingXml\GoogleShoppingXml;
6+
use OpenApi\Model\Api\Product;
57
use PDO;
68
use Generator;
79
use GoogleShoppingXml\Model\GoogleshoppingxmlFeed;
810
use GoogleShoppingXml\Service\GoogleModel\GoogleProductModel;
911
use GoogleShoppingXml\Service\ShippingService;
1012
use Propel\Runtime\Exception\PropelException;
1113
use Symfony\Component\HttpFoundation\RequestStack;
14+
use Thelia\Core\Template\Loop\ProductSaleElementsImage;
15+
use Thelia\Model\Base\ProductQuery;
16+
use Thelia\Model\Category;
17+
use Thelia\Model\CategoryQuery;
1218
use Thelia\Model\ConfigQuery;
19+
use Thelia\Model\ProductImageQuery;
20+
use Thelia\Model\ProductSaleElementsProductImageQuery;
1321
use Thelia\Model\TaxRuleQuery;
1422
use Thelia\TaxEngine\Calculator;
1523
use Thelia\Tools\MoneyFormat;
@@ -55,18 +63,66 @@ public function getDataGenerator(GoogleshoppingxmlFeed $feed, MoneyFormat $money
5563

5664
$taxCalculator = new Calculator();
5765
$taxeRules = $this->getTaxeRules();
66+
$shipping = $this->shipingService->buildShippingArray($feed, $moneyFormat);
67+
68+
$optimisation = GoogleShoppingXml::getConfigValue(GoogleShoppingXml::ENABLE_SQL_8_COMPATIBILITY);
5869

5970
/** @var $resultStatement */
60-
$resultStatement = $this->sqlQueryService->getPses($locale);
61-
$shipping = $this->shipingService->buildShippingArray($feed, $moneyFormat);
71+
72+
if ($optimisation) {
73+
$resultStatement = $this->sqlQueryService->getPsesWithSqlOptimisation($locale);
74+
} else {
75+
$resultStatement = $this->sqlQueryService->getPses($locale);
76+
}
6277

6378
while ($row = $resultStatement->fetch(PDO::FETCH_ASSOC)) {
6479
$taxCalculator->loadTaxRuleWithoutProduct($taxeRules[$row['TAX_RULE_ID']], $feed->getCountry());
6580

81+
$row['title'] = $row['product_title'];
82+
83+
if (null !== $row['attrib_title']) {
84+
$row['title'] .= ' - '.$row['attrib_title'];
85+
}
86+
87+
if (!$optimisation) {
88+
89+
$pseImage = ProductSaleElementsProductImageQuery::create()
90+
->filterByProductSaleElementsId($row['id'])
91+
->findOne();
92+
93+
$productImage = ProductImageQuery::create()
94+
->useProductQuery()
95+
->useProductSaleElementsQuery()
96+
->filterById($row['id'])
97+
->endUse()
98+
->endUse()
99+
->orderByPosition()
100+
->findOne();
101+
102+
$row['image_link'] = $pseImage ? $pseImage->getProductImageId() : $productImage?->getId();
103+
104+
$path = $this->getCategories(CategoryQuery::create()->findPk($row['default_category_id']), $locale);
105+
106+
$row['product_type'] = implode(' > ', $path);
107+
}
108+
66109
yield (new GoogleProductModel($taxCalculator, $moneyFormat, $shipping, $feed->getCurrency(), 'g:'))->build($row);
67110
}
68111
}
69112

113+
private function getCategories(Category $category, $locale)
114+
{
115+
if ($category->getParent() !== 0){
116+
$parentCategory = CategoryQuery::create()->findPk($category->getParent());
117+
$path = $this->getCategories($parentCategory, $locale);
118+
}
119+
120+
$category->setLocale($locale);
121+
$path[] = $category->getTitle();
122+
123+
return $path;
124+
}
125+
70126
/**
71127
* @return array
72128
*/

Service/Provider/SQLQueryService.php

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
namespace GoogleShoppingXml\Service\Provider;
44

55
use Propel\Runtime\Propel;
6+
use Thelia\Model\Map\ProductSaleElementsTableMap;
7+
use Thelia\Model\ProductSaleElementsQuery;
68
use Thelia\Tools\URL;
79

810
class SQLQueryService
911
{
1012
/**
1113
* @param string $locale
1214
*/
13-
public function getPses(string $locale)
15+
public function getPsesWithSqlOptimisation(string $locale)
1416
{
1517
$baseUrl = URL::getInstance()->absoluteUrl('/');
1618

@@ -30,9 +32,9 @@ public function getPses(string $locale)
3032
), attribute_title AS (
3133
SELECT ac.product_sale_elements_id AS id, GROUP_CONCAT(DISTINCT avi.title ORDER BY a.id SEPARATOR " - ") AS title
3234
from attribute_combination AS ac
33-
JOIN attribute a ON a.id = ac.attribute_id
34-
JOIN attribute_av av ON ac.attribute_av_id = av.id
35-
JOIN attribute_av_i18n avi ON av.id = avi.id
35+
LEFT JOIN attribute a ON a.id = ac.attribute_id
36+
LEFT JOIN attribute_av av ON ac.attribute_av_id = av.id
37+
LEFT JOIN attribute_av_i18n avi ON av.id = avi.id
3638
WHERE avi.locale=:p1
3739
GROUP BY ac.product_sale_elements_id
3840
@@ -52,7 +54,8 @@ public function getPses(string $locale)
5254
5355
SELECT
5456
pse.id AS "id",
55-
CONCAT(pi.title," - ", attrib.title) AS "title",
57+
pi.title AS "product_title",
58+
attrib.title AS "attrib_title",
5659
pi.description AS "description",
5760
IF(pse.quantity>0, "in stock", "out of stock") AS "availability",
5861
CONCAT(@BASEURL := "' . $baseUrl . '",rurl.url) AS "link",
@@ -69,19 +72,19 @@ public function getPses(string $locale)
6972
7073
FROM `product_sale_elements`AS pse
7174
72-
JOIN product AS p ON pse.product_id = p.id
73-
JOIN product_i18n AS pi ON p.id = pi.id
74-
JOIN attribute_title AS attrib ON attrib.id = pse.id
75-
JOIN rewriting_url AS rurl ON rurl.view = "product" AND rurl.view_id = p.id
76-
JOIN product_price AS pp ON pp.product_sale_elements_id = pse.id
77-
JOIN brand AS b ON b.id = p.brand_id
78-
JOIN brand_i18n AS bi ON b.id = bi.id
79-
JOIN product_category AS pc ON pc.product_id=p.id AND pc.default_category=1
80-
JOIN product_images_query AS pimgs ON pimgs.pid=p.id
75+
LEFT JOIN product AS p ON pse.product_id = p.id
76+
LEFT JOIN product_i18n AS pi ON p.id = pi.id
77+
LEFT JOIN attribute_title AS attrib ON attrib.id = pse.id
78+
LEFT JOIN rewriting_url AS rurl ON rurl.view = "product" AND rurl.view_id = p.id
79+
LEFT JOIN product_price AS pp ON pp.product_sale_elements_id = pse.id
80+
LEFT JOIN brand AS b ON b.id = p.brand_id
81+
LEFT JOIN brand_i18n AS bi ON b.id = bi.id
82+
LEFT JOIN product_category AS pc ON pc.product_id=p.id AND pc.default_category=1
83+
LEFT JOIN product_images_query AS pimgs ON pimgs.pid=p.id
8184
LEFT JOIN pse_images_query AS pseimgs ON pseimgs.pseid=pse.id
82-
JOIN category AS c ON c.id=pc.category_id
83-
JOIN googleshoppingxml_taxonomy AS gt ON gt.thelia_category_id = c.id
84-
JOIN category_path cp ON cp.id = pc.category_id
85+
LEFT JOIN category AS c ON c.id=pc.category_id
86+
LEFT JOIN googleshoppingxml_taxonomy AS gt ON gt.thelia_category_id = c.id
87+
LEFT JOIN category_path cp ON cp.id = pc.category_id
8588
8689
WHERE
8790
@@ -110,4 +113,69 @@ public function getPses(string $locale)
110113

111114
return $stmt;
112115
}
116+
117+
public function getPses(string $locale)
118+
{
119+
$baseUrl = URL::getInstance()->absoluteUrl('/');
120+
121+
$sql = '
122+
SELECT
123+
pse.id AS "id",
124+
pi.title AS "product_title",
125+
GROUP_CONCAT(DISTINCT avi.title ORDER BY a.id SEPARATOR " - ") AS "attrib_title",
126+
pi.description AS "description",
127+
IF(pse.quantity>0, "in stock", "out of stock") AS "availability",
128+
CONCAT(@BASEURL := "' . $baseUrl . '",rurl.url) AS "link",
129+
IF(pse.promo=1, pp.promo_price, pp.price) AS "price",
130+
bi.title AS "brand",
131+
IF(pse.ean_code!="", "yes", "no") AS "identifier_exists",
132+
pse.ean_code AS "gtin",
133+
p.ref AS "item_group_id",
134+
gt.google_category AS "google_product_category",
135+
"new" AS "condition",
136+
p.tax_rule_id AS "TAX_RULE_ID",
137+
c.id AS "default_category_id"
138+
139+
FROM `product_sale_elements`AS pse
140+
141+
LEFT JOIN product AS p ON pse.product_id = p.id
142+
LEFT JOIN product_i18n AS pi ON p.id = pi.id
143+
LEFT JOIN attribute_combination AS ac ON ac.product_sale_elements_id = pse.id
144+
LEFT JOIN attribute AS a ON a.id = ac.attribute_id
145+
LEFT JOIN attribute_av AS av ON ac.attribute_av_id = av.id
146+
LEFT JOIN attribute_av_i18n AS avi ON av.id = avi.id
147+
LEFT JOIN rewriting_url AS rurl ON rurl.view = "product" AND rurl.view_id = p.id
148+
LEFT JOIN product_price AS pp ON pp.product_sale_elements_id = pse.id
149+
LEFT JOIN brand AS b ON b.id = p.brand_id
150+
LEFT JOIN brand_i18n AS bi ON b.id = bi.id
151+
LEFT JOIN product_category AS pc ON pc.product_id=p.id AND pc.default_category=1
152+
LEFT JOIN category AS c ON c.id=pc.category_id
153+
LEFT JOIN googleshoppingxml_taxonomy AS gt ON gt.thelia_category_id = c.id
154+
155+
WHERE
156+
157+
pi.locale=:p2
158+
AND rurl.view_locale=:p3
159+
AND bi.locale=:p4
160+
AND p.visible=1
161+
AND pi.title!=""
162+
AND pi.description!=""
163+
164+
GROUP BY pse.id';
165+
166+
$con = Propel::getConnection();
167+
168+
/** @var PDOStatement $stmt */
169+
$stmt = $con->prepare($sql);
170+
171+
//$stmt->bindValue(':p1', $locale);
172+
$stmt->bindValue(':p2', $locale);
173+
$stmt->bindValue(':p3', $locale);
174+
$stmt->bindValue(':p4', $locale);
175+
176+
$stmt->execute();
177+
178+
return $stmt;
179+
180+
}
113181
}

0 commit comments

Comments
 (0)