Version Notes
Release
Download this release
Release Info
Developer | FACTFinder |
Extension | Flagbit_Factfinder |
Version | 4.1.10 |
Comparing to | |
See all releases |
Code changes from version 4.1.9 to 4.1.10
- app/code/community/FACTFinder/Campaigns/Model/Handler/Abstract.php +3 -1
- app/code/community/FACTFinder/Core/Helper/Export.php +75 -0
- app/code/community/FACTFinder/Core/Model/Export/Product.php +117 -227
- app/code/community/FACTFinder/Core/Model/Facade.php +0 -20
- app/code/community/FACTFinder/Core/Model/Handler/Search.php +6 -1
- app/code/community/FACTFinder/Core/Model/Resource/Export.php +302 -0
- app/code/community/FACTFinder/Core/etc/system.xml +10 -1
- app/code/community/FACTFinder/Recommendation/Helper/Data.php +2 -0
- app/code/community/FACTFinder/Suggest/Helper/Data.php +31 -0
- app/code/community/FACTFinder/Tracking/Block/Click.php +8 -0
- app/design/frontend/base/default/template/factfinder/suggest/advancedsuggest.phtml +2 -2
- app/locale/de_DE/FACTFinder_Suggest.csv +4 -0
- app/locale/en_US/FACTFinder_Suggest.csv +4 -0
- lib/FACTFinder/Adapter/AbstractAdapter.php +5 -0
- lib/FACTFinder/Adapter/Compare.php +6 -36
- lib/FACTFinder/Adapter/ConfigurableResponse.php +53 -0
- lib/FACTFinder/Adapter/PersonalisedResponse.php +52 -0
- lib/FACTFinder/Adapter/ProductCampaign.php +35 -27
- lib/FACTFinder/Adapter/Recommendation.php +7 -56
- lib/FACTFinder/Adapter/Search.php +3 -40
- lib/FACTFinder/Adapter/SimilarRecords.php +8 -48
- lib/FACTFinder/Adapter/Tracking.php +33 -9
- lib/FACTFinder/Core/AbstractConfiguration.php +3 -0
- lib/FACTFinder/Data/SearchParameters.php +11 -2
- package.xml +6 -6
- skin/frontend/base/default/css/factfinder_suggest.css +17 -0
app/code/community/FACTFinder/Campaigns/Model/Handler/Abstract.php
CHANGED
@@ -92,7 +92,9 @@ abstract class FACTFinder_Campaigns_Model_Handler_Abstract extends FACTFinder_Co
|
|
92 |
$params['do'] = $this->_getDoParam();
|
93 |
$params['productNumber'] = $this->_getProductNumberParam();
|
94 |
$params['idsOnly'] = 'true';
|
95 |
-
|
|
|
|
|
96 |
$this->_getFacade()->configureProductCampaignAdapter($params);
|
97 |
}
|
98 |
|
92 |
$params['do'] = $this->_getDoParam();
|
93 |
$params['productNumber'] = $this->_getProductNumberParam();
|
94 |
$params['idsOnly'] = 'true';
|
95 |
+
if(Mage::getStoreConfigFlag('factfinder/config/personalization')) {
|
96 |
+
$params['sid'] = Mage::helper('factfinder_tracking')->getSessionId();
|
97 |
+
}
|
98 |
$this->_getFacade()->configureProductCampaignAdapter($params);
|
99 |
}
|
100 |
|
app/code/community/FACTFinder/Core/Helper/Export.php
CHANGED
@@ -24,6 +24,10 @@ class FACTFinder_Core_Helper_Export extends Mage_Core_Helper_Abstract
|
|
24 |
const IMPORT_DELAY_KEY = 'factfinder_import_delay';
|
25 |
const ARCHIVE_PATTERN = 'store_%s_export.zip';
|
26 |
const EXPORT_TRIGGER_DELAY = 90;
|
|
|
|
|
|
|
|
|
27 |
|
28 |
/**
|
29 |
* @var int
|
@@ -271,4 +275,75 @@ class FACTFinder_Core_Helper_Export extends Mage_Core_Helper_Abstract
|
|
271 |
}
|
272 |
|
273 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
}
|
24 |
const IMPORT_DELAY_KEY = 'factfinder_import_delay';
|
25 |
const ARCHIVE_PATTERN = 'store_%s_export.zip';
|
26 |
const EXPORT_TRIGGER_DELAY = 90;
|
27 |
+
const EXPORT_IMAGE_SIZE = 'suggest_image_size';
|
28 |
+
const EXPORT_IMAGE_TYPE = 'suggest_image_type';
|
29 |
+
const EXPORT_URLS_IMAGES = 'urls';
|
30 |
+
const OUT_OF_STOCK_PRODUCTS = 'out_of_stock_products';
|
31 |
|
32 |
/**
|
33 |
* @var int
|
275 |
}
|
276 |
|
277 |
|
278 |
+
/**
|
279 |
+
* Get width of product images exported
|
280 |
+
*
|
281 |
+
* @param int $storeId
|
282 |
+
*
|
283 |
+
* @return null|string
|
284 |
+
*/
|
285 |
+
public function getExportImageWidth($storeId = 0)
|
286 |
+
{
|
287 |
+
$width = $this->getExportConfigValue(self::EXPORT_IMAGE_SIZE, $storeId);
|
288 |
+
$width = array_shift(explode('x', $width));
|
289 |
+
|
290 |
+
return $width;
|
291 |
+
}
|
292 |
+
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Get height of images exported. If not set use width
|
296 |
+
*
|
297 |
+
* @param int $storeId
|
298 |
+
*
|
299 |
+
* @return null|string
|
300 |
+
*/
|
301 |
+
public function getExportImageHeight($storeId = 0)
|
302 |
+
{
|
303 |
+
$height = $this->getExportConfigValue(self::EXPORT_IMAGE_SIZE, $storeId);
|
304 |
+
$height = array_pop(explode('x', $height));
|
305 |
+
|
306 |
+
return $height ? $height : $this->getExportImageWidth();
|
307 |
+
}
|
308 |
+
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Get type of product image to export
|
312 |
+
*
|
313 |
+
* @param int $storeId
|
314 |
+
*
|
315 |
+
* @return null|string
|
316 |
+
*/
|
317 |
+
public function getExportImageType($storeId = 0)
|
318 |
+
{
|
319 |
+
return $this->getExportConfigValue(self::EXPORT_IMAGE_TYPE, $storeId);
|
320 |
+
}
|
321 |
+
|
322 |
+
|
323 |
+
/**
|
324 |
+
* Check if images and deeplinks should be exported
|
325 |
+
*
|
326 |
+
* @param int $storeId
|
327 |
+
*
|
328 |
+
* @return null|string
|
329 |
+
*/
|
330 |
+
public function shouldExportImagesAndDeeplinks($storeId = 0)
|
331 |
+
{
|
332 |
+
return $this->getExportConfigValue(self::EXPORT_URLS_IMAGES, $storeId);
|
333 |
+
}
|
334 |
+
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Check if out of stock products should be exported
|
338 |
+
*
|
339 |
+
* @param int $storeId
|
340 |
+
*
|
341 |
+
* @return null|string
|
342 |
+
*/
|
343 |
+
public function shouldExportOutOfStock($storeId = 0)
|
344 |
+
{
|
345 |
+
return $this->getExportConfigValue(self::OUT_OF_STOCK_PRODUCTS, $storeId);
|
346 |
+
}
|
347 |
+
|
348 |
+
|
349 |
}
|
app/code/community/FACTFinder/Core/Model/Export/Product.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
|
24 |
* @link http://www.flagbit.de
|
25 |
*/
|
26 |
-
class FACTFinder_Core_Model_Export_Product extends
|
27 |
{
|
28 |
|
29 |
const FILENAME_PATTERN = 'store_%s_product.csv';
|
@@ -90,6 +90,22 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
90 |
'numerical_attributes',
|
91 |
);
|
92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
/**
|
95 |
* Add row to csv
|
@@ -128,7 +144,7 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
128 |
*/
|
129 |
public function getExportDirectory()
|
130 |
{
|
131 |
-
return
|
132 |
}
|
133 |
|
134 |
|
@@ -314,14 +330,14 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
314 |
$dynamicFields = $this->_getDynamicFields();
|
315 |
|
316 |
// status and visibility filter
|
317 |
-
$visibility = $this->
|
318 |
-
$status = $this->
|
319 |
$visibilityVals = Mage::getSingleton('catalog/product_visibility')->getVisibleInSearchIds();
|
320 |
$statusVals = Mage::getSingleton('catalog/product_status')->getVisibleStatusIds();
|
321 |
|
322 |
$lastProductId = 0;
|
323 |
while (true) {
|
324 |
-
$products = $this->
|
325 |
if (!$products) {
|
326 |
break;
|
327 |
}
|
@@ -331,7 +347,8 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
331 |
foreach ($products as $productData) {
|
332 |
$lastProductId = $productData['entity_id'];
|
333 |
$productAttributes[$productData['entity_id']] = $productData['entity_id'];
|
334 |
-
$productChildren = $this->
|
|
|
335 |
$productRelations[$productData['entity_id']] = $productChildren;
|
336 |
if ($productChildren) {
|
337 |
foreach ($productChildren as $productChild) {
|
@@ -340,7 +357,8 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
340 |
}
|
341 |
}
|
342 |
|
343 |
-
$productAttributes = $this->
|
|
|
344 |
foreach ($products as $productData) {
|
345 |
if (!isset($productAttributes[$productData['entity_id']])) {
|
346 |
continue;
|
@@ -396,7 +414,7 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
396 |
$this->_formatAttributes('searchable', $productAttr, $storeId),
|
397 |
$this->_formatAttributes('numerical', $productAttr, $storeId),
|
398 |
);
|
399 |
-
if ($this->
|
400 |
//dont need to add image and deeplink to child product, just add empty values
|
401 |
$subProductIndex[] = '';
|
402 |
$subProductIndex[] = '';
|
@@ -528,79 +546,6 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
528 |
}
|
529 |
|
530 |
|
531 |
-
/**
|
532 |
-
* Retrieve Searchable attributes
|
533 |
-
*
|
534 |
-
* @param string $backendType
|
535 |
-
* @param string $type possible Types: system, sortable, filterable, searchable
|
536 |
-
* @param int $storeId
|
537 |
-
*
|
538 |
-
* @return array
|
539 |
-
*/
|
540 |
-
protected function _getSearchableAttributes($backendType = null, $type = null, $storeId = null)
|
541 |
-
{
|
542 |
-
if ($this->_searchableAttributes === null) {
|
543 |
-
$this->_searchableAttributes = array();
|
544 |
-
$entityType = $this->getEavConfig()->getEntityType('catalog_product');
|
545 |
-
$entity = $entityType->getEntity();
|
546 |
-
|
547 |
-
$userDefinedAttributes = array_keys(Mage::helper('factfinder/backend')
|
548 |
-
->unserializeFieldValue(Mage::getStoreConfig('factfinder/export/attributes', $storeId)));
|
549 |
-
|
550 |
-
$whereCond = array(
|
551 |
-
$this->_getWriteAdapter()->quoteInto('additional_table.is_searchable=?', 1),
|
552 |
-
$this->_getWriteAdapter()->quoteInto('additional_table.is_filterable=?', 1),
|
553 |
-
$this->_getWriteAdapter()->quoteInto('additional_table.used_for_sort_by=?', 1),
|
554 |
-
$this->_getWriteAdapter()->quoteInto(
|
555 |
-
'main_table.attribute_code IN(?)',
|
556 |
-
array_merge(array('status', 'visibility'), $userDefinedAttributes)
|
557 |
-
)
|
558 |
-
);
|
559 |
-
|
560 |
-
$select = $this->_getWriteAdapter()->select()
|
561 |
-
->from(array('main_table' => $this->getTable('eav/attribute')))
|
562 |
-
->join(
|
563 |
-
array('additional_table' => $this->getTable('catalog/eav_attribute')),
|
564 |
-
'additional_table.attribute_id = main_table.attribute_id'
|
565 |
-
)
|
566 |
-
->where('main_table.entity_type_id=?', $entityType->getEntityTypeId())
|
567 |
-
->where(join(' OR ', $whereCond))
|
568 |
-
->order('main_table.attribute_id', 'asc');
|
569 |
-
|
570 |
-
$attributesData = $this->_getWriteAdapter()->fetchAll($select);
|
571 |
-
$this->getEavConfig()->importAttributesData($entityType, $attributesData);
|
572 |
-
|
573 |
-
foreach ($attributesData as $attributeData) {
|
574 |
-
$attributeCode = $attributeData['attribute_code'];
|
575 |
-
$attribute = $this->getEavConfig()->getAttribute($entityType, $attributeCode);
|
576 |
-
$attribute->setEntity($entity);
|
577 |
-
$this->_searchableAttributes[$attribute->getId()] = $attribute;
|
578 |
-
}
|
579 |
-
}
|
580 |
-
|
581 |
-
if ($type !== null || $backendType !== null) {
|
582 |
-
$attributes = array();
|
583 |
-
foreach ($this->_searchableAttributes as $attribute) {
|
584 |
-
if ($backendType !== null
|
585 |
-
&& $attribute->getBackendType() != $backendType
|
586 |
-
) {
|
587 |
-
continue;
|
588 |
-
}
|
589 |
-
|
590 |
-
if ($this->_checkIfSkipAttribute($attribute, $type)) {
|
591 |
-
continue;
|
592 |
-
}
|
593 |
-
|
594 |
-
$attributes[$attribute->getId()] = $attribute;
|
595 |
-
}
|
596 |
-
|
597 |
-
return $attributes;
|
598 |
-
}
|
599 |
-
|
600 |
-
return $this->_searchableAttributes;
|
601 |
-
}
|
602 |
-
|
603 |
-
|
604 |
/**
|
605 |
* Get Category Path by Product ID
|
606 |
*
|
@@ -613,11 +558,11 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
613 |
{
|
614 |
|
615 |
if ($this->_categoryNames === null) {
|
616 |
-
$this->
|
617 |
}
|
618 |
|
619 |
if ($this->_productsToCategoryPath === null) {
|
620 |
-
$this->
|
621 |
}
|
622 |
|
623 |
$value = '';
|
@@ -647,43 +592,6 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
647 |
}
|
648 |
|
649 |
|
650 |
-
/**
|
651 |
-
* Return all product children ids
|
652 |
-
*
|
653 |
-
* @param int $productId Product Entity Id
|
654 |
-
* @param string $typeId Super Product Link Type
|
655 |
-
*
|
656 |
-
* @return array
|
657 |
-
*/
|
658 |
-
protected function _getProductChildIds($productId, $typeId)
|
659 |
-
{
|
660 |
-
$typeInstance = $this->_getProductTypeInstance($typeId);
|
661 |
-
$relation = $typeInstance->isComposite()
|
662 |
-
? $typeInstance->getRelationInfo()
|
663 |
-
: false;
|
664 |
-
|
665 |
-
if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()) {
|
666 |
-
$select = $this->_getReadAdapter()->select()
|
667 |
-
->from(
|
668 |
-
array('main' => $this->getTable($relation->getTable())),
|
669 |
-
array($relation->getChildFieldName()))
|
670 |
-
->join(
|
671 |
-
array('e' => $this->getTable('catalog/product')),
|
672 |
-
'main.' . $relation->getChildFieldName() . '=e.entity_id',
|
673 |
-
array('entity_id', 'type_id', 'sku')
|
674 |
-
)
|
675 |
-
->where("{$relation->getParentFieldName()}=?", $productId);
|
676 |
-
if ($relation->getWhere() !== null) {
|
677 |
-
$select->where($relation->getWhere());
|
678 |
-
}
|
679 |
-
|
680 |
-
return $this->_getReadAdapter()->fetchAll($select);
|
681 |
-
}
|
682 |
-
|
683 |
-
return null;
|
684 |
-
}
|
685 |
-
|
686 |
-
|
687 |
/**
|
688 |
* Retrieve attribute source value for search
|
689 |
* This method is mostly copied from Mage_CatalogSearch_Model_Resource_Fulltext,
|
@@ -697,7 +605,7 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
697 |
*/
|
698 |
protected function _getAttributeValue($attributeId, $value, $storeId)
|
699 |
{
|
700 |
-
$attribute = $this->
|
701 |
if (!$attribute->getIsSearchable() && $attribute->getAttributeCode() == 'visibility') {
|
702 |
return $value;
|
703 |
}
|
@@ -882,53 +790,26 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
882 |
*/
|
883 |
protected function _exportImageAndDeepLink($productIndex, $productData, $storeId)
|
884 |
{
|
885 |
-
|
886 |
-
$baseAdminUrl = Mage::app()->getStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
|
887 |
-
if ($storeId !== null) {
|
888 |
-
$currentBaseUrl = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
|
889 |
-
}
|
890 |
-
|
891 |
-
$imageType = Mage::getStoreConfig('factfinder/export/suggest_image_type', $storeId);
|
892 |
-
$imageSize = Mage::getStoreConfig('factfinder/export/suggest_image_size', $storeId);
|
893 |
-
|
894 |
-
$product = Mage::getModel('catalog/product');
|
895 |
-
$product->setStoreId($storeId);
|
896 |
-
$product->load($productData['entity_id']);
|
897 |
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
}
|
902 |
-
|
903 |
-
$image = (string) $image;
|
904 |
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
|
909 |
-
|
910 |
-
|
911 |
|
912 |
-
|
913 |
-
|
914 |
|
915 |
return $productIndex;
|
916 |
}
|
917 |
|
918 |
|
919 |
-
/**
|
920 |
-
* Check of image and deep links should be exported
|
921 |
-
*
|
922 |
-
* @param int $storeId
|
923 |
-
*
|
924 |
-
* @return bool
|
925 |
-
*/
|
926 |
-
protected function _getIfExportImageAndDeeplink($storeId)
|
927 |
-
{
|
928 |
-
return Mage::getStoreConfigFlag('factfinder/export/urls', $storeId);
|
929 |
-
}
|
930 |
-
|
931 |
-
|
932 |
/**
|
933 |
* Get array of dynamic fields to use in csv
|
934 |
*
|
@@ -1008,102 +889,111 @@ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Reso
|
|
1008 |
|
1009 |
|
1010 |
/**
|
1011 |
-
*
|
1012 |
*
|
1013 |
-
* @
|
1014 |
-
*
|
1015 |
-
* @return $this
|
1016 |
*/
|
1017 |
-
protected function
|
1018 |
{
|
1019 |
-
|
1020 |
-
$statusAttribute = $this->_getCategoryStatusAttribute();
|
1021 |
-
|
1022 |
-
$select = $this->_getReadAdapter()->select()
|
1023 |
-
->from(
|
1024 |
-
array('main' => $nameAttribute->getBackendTable()),
|
1025 |
-
array('entity_id', 'value')
|
1026 |
-
)
|
1027 |
-
->join(
|
1028 |
-
array('e' => $statusAttribute->getBackendTable()),
|
1029 |
-
'main.entity_id=e.entity_id AND (e.store_id = 0 OR e.store_id = ' . $storeId
|
1030 |
-
. ') AND e.attribute_id=' . $statusAttribute->getAttributeId(),
|
1031 |
-
null
|
1032 |
-
)
|
1033 |
-
->where('main.attribute_id=?', $nameAttribute->getAttributeId())
|
1034 |
-
->where('e.value=?', '1')
|
1035 |
-
->where('main.store_id = 0 OR main.store_id = ?', $storeId);
|
1036 |
-
|
1037 |
-
$this->_categoryNames = $this->_getReadAdapter()->fetchPairs($select);
|
1038 |
-
|
1039 |
-
return $this;
|
1040 |
}
|
1041 |
|
1042 |
|
1043 |
/**
|
1044 |
-
*
|
1045 |
*
|
1046 |
-
* @
|
|
|
|
|
|
|
1047 |
*/
|
1048 |
-
protected function
|
1049 |
{
|
1050 |
-
$
|
1051 |
-
|
1052 |
-
->
|
|
|
|
|
|
|
|
|
1053 |
|
1054 |
-
return $
|
1055 |
}
|
1056 |
|
1057 |
|
1058 |
/**
|
1059 |
-
* Get
|
1060 |
*
|
1061 |
-
* @
|
|
|
|
|
|
|
1062 |
*/
|
1063 |
-
protected function
|
1064 |
{
|
1065 |
-
$
|
1066 |
-
$categoryAttributeCollection->addFieldToFilter('attribute_code', array('eq' => 'is_active'))
|
1067 |
-
->getSelect()->limit(1);
|
1068 |
|
1069 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1070 |
}
|
1071 |
|
1072 |
|
1073 |
/**
|
1074 |
-
*
|
1075 |
*
|
1076 |
-
* @param
|
|
|
|
|
1077 |
*
|
1078 |
-
* @return
|
1079 |
*/
|
1080 |
-
protected function
|
1081 |
{
|
1082 |
-
$
|
1083 |
-
->from(
|
1084 |
-
array('main' => $this->getTable('catalog/category_product_index')),
|
1085 |
-
array('product_id')
|
1086 |
-
)
|
1087 |
-
->join(
|
1088 |
-
array('e' => $this->getTable('catalog/category')),
|
1089 |
-
'main.category_id=e.entity_id',
|
1090 |
-
null
|
1091 |
-
)
|
1092 |
-
->columns(array('e.path' => new Zend_Db_Expr('GROUP_CONCAT(e.path)')))
|
1093 |
-
->where(
|
1094 |
-
'main.visibility IN(?)',
|
1095 |
-
array(
|
1096 |
-
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH,
|
1097 |
-
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH
|
1098 |
-
)
|
1099 |
-
)
|
1100 |
-
->where('main.store_id = ?', $storeId)
|
1101 |
-
->where('e.path LIKE \'1/' . Mage::app()->getStore($storeId)->getRootCategoryId() . '/%\'')
|
1102 |
-
->group('main.product_id');
|
1103 |
-
|
1104 |
-
$this->_productsToCategoryPath = $this->_getReadAdapter()->fetchPairs($select);
|
1105 |
|
1106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1107 |
}
|
1108 |
|
1109 |
|
23 |
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
|
24 |
* @link http://www.flagbit.de
|
25 |
*/
|
26 |
+
class FACTFinder_Core_Model_Export_Product extends Mage_Core_Model_Abstract
|
27 |
{
|
28 |
|
29 |
const FILENAME_PATTERN = 'store_%s_product.csv';
|
90 |
'numerical_attributes',
|
91 |
);
|
92 |
|
93 |
+
/**
|
94 |
+
* @var
|
95 |
+
*/
|
96 |
+
protected $_engine;
|
97 |
+
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Init resource model
|
101 |
+
*
|
102 |
+
*/
|
103 |
+
protected function _construct()
|
104 |
+
{
|
105 |
+
$this->_init('factfinder/export');
|
106 |
+
$this->_engine = Mage::helper('catalogsearch')->getEngine();
|
107 |
+
}
|
108 |
+
|
109 |
|
110 |
/**
|
111 |
* Add row to csv
|
144 |
*/
|
145 |
public function getExportDirectory()
|
146 |
{
|
147 |
+
return $this->getHelper()->getExportDirectory();
|
148 |
}
|
149 |
|
150 |
|
330 |
$dynamicFields = $this->_getDynamicFields();
|
331 |
|
332 |
// status and visibility filter
|
333 |
+
$visibility = $this->getResource()->getSearchableAttribute('visibility');
|
334 |
+
$status = $this->getResource()->getSearchableAttribute('status');
|
335 |
$visibilityVals = Mage::getSingleton('catalog/product_visibility')->getVisibleInSearchIds();
|
336 |
$statusVals = Mage::getSingleton('catalog/product_status')->getVisibleStatusIds();
|
337 |
|
338 |
$lastProductId = 0;
|
339 |
while (true) {
|
340 |
+
$products = $this->getResource()->getSearchableProducts($storeId, $staticFields, $lastProductId);
|
341 |
if (!$products) {
|
342 |
break;
|
343 |
}
|
347 |
foreach ($products as $productData) {
|
348 |
$lastProductId = $productData['entity_id'];
|
349 |
$productAttributes[$productData['entity_id']] = $productData['entity_id'];
|
350 |
+
$productChildren = $this->getResource()
|
351 |
+
->getProductChildIds($productData['entity_id'], $productData['type_id']);
|
352 |
$productRelations[$productData['entity_id']] = $productChildren;
|
353 |
if ($productChildren) {
|
354 |
foreach ($productChildren as $productChild) {
|
357 |
}
|
358 |
}
|
359 |
|
360 |
+
$productAttributes = $this->getResource()
|
361 |
+
->getProductAttributes($storeId, array_keys($productAttributes), $dynamicFields);
|
362 |
foreach ($products as $productData) {
|
363 |
if (!isset($productAttributes[$productData['entity_id']])) {
|
364 |
continue;
|
414 |
$this->_formatAttributes('searchable', $productAttr, $storeId),
|
415 |
$this->_formatAttributes('numerical', $productAttr, $storeId),
|
416 |
);
|
417 |
+
if ($this->getHelper()->shouldExportImagesAndDeeplinks($storeId)) {
|
418 |
//dont need to add image and deeplink to child product, just add empty values
|
419 |
$subProductIndex[] = '';
|
420 |
$subProductIndex[] = '';
|
546 |
}
|
547 |
|
548 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
549 |
/**
|
550 |
* Get Category Path by Product ID
|
551 |
*
|
558 |
{
|
559 |
|
560 |
if ($this->_categoryNames === null) {
|
561 |
+
$this->_categoryNames = $this->getResource()->getCategoryNames($storeId);
|
562 |
}
|
563 |
|
564 |
if ($this->_productsToCategoryPath === null) {
|
565 |
+
$this->_productsToCategoryPath = $this->getResource()->getCategoryPaths($storeId);
|
566 |
}
|
567 |
|
568 |
$value = '';
|
592 |
}
|
593 |
|
594 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
595 |
/**
|
596 |
* Retrieve attribute source value for search
|
597 |
* This method is mostly copied from Mage_CatalogSearch_Model_Resource_Fulltext,
|
605 |
*/
|
606 |
protected function _getAttributeValue($attributeId, $value, $storeId)
|
607 |
{
|
608 |
+
$attribute = $this->getResource()->getSearchableAttribute($attributeId);
|
609 |
if (!$attribute->getIsSearchable() && $attribute->getAttributeCode() == 'visibility') {
|
610 |
return $value;
|
611 |
}
|
790 |
*/
|
791 |
protected function _exportImageAndDeepLink($productIndex, $productData, $storeId)
|
792 |
{
|
793 |
+
$helper = $this->getHelper();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
794 |
|
795 |
+
if (!$helper->shouldExportImagesAndDeeplinks($storeId)) {
|
796 |
+
return $productIndex;
|
797 |
+
}
|
|
|
|
|
|
|
798 |
|
799 |
+
// emulate store
|
800 |
+
$oldStore = Mage::app()->getStore()->getId();
|
801 |
+
Mage::app()->setCurrentStore($storeId);
|
802 |
|
803 |
+
$productIndex[] = $this->getProductImageUrl($productData['entity_id'], $storeId);
|
804 |
+
$productIndex[] = $this->getProductUrl($productData['entity_id'], $storeId);
|
805 |
|
806 |
+
// finish emulation
|
807 |
+
Mage::app()->setCurrentStore($oldStore);
|
808 |
|
809 |
return $productIndex;
|
810 |
}
|
811 |
|
812 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
813 |
/**
|
814 |
* Get array of dynamic fields to use in csv
|
815 |
*
|
889 |
|
890 |
|
891 |
/**
|
892 |
+
* Get export helper
|
893 |
*
|
894 |
+
* @return FACTFinder_Core_Helper_Export
|
|
|
|
|
895 |
*/
|
896 |
+
protected function getHelper()
|
897 |
{
|
898 |
+
return Mage::helper('factfinder/export');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
899 |
}
|
900 |
|
901 |
|
902 |
/**
|
903 |
+
* Gte product URL for store
|
904 |
*
|
905 |
+
* @param int $productId
|
906 |
+
* @param int $storeId
|
907 |
+
*
|
908 |
+
* @return string
|
909 |
*/
|
910 |
+
protected function getProductUrl($productId, $storeId)
|
911 |
{
|
912 |
+
$productUrl = Mage::getModel('catalog/product')
|
913 |
+
->getCollection()
|
914 |
+
->addAttributeToFilter('entity_id', $productId)
|
915 |
+
->setStoreId($storeId)
|
916 |
+
->addUrlRewrite()
|
917 |
+
->getFirstItem()
|
918 |
+
->getProductUrl();
|
919 |
|
920 |
+
return $productUrl;
|
921 |
}
|
922 |
|
923 |
|
924 |
/**
|
925 |
+
* Get image URL for product
|
926 |
*
|
927 |
+
* @param int $productId
|
928 |
+
* @param int $storeId
|
929 |
+
*
|
930 |
+
* @return string
|
931 |
*/
|
932 |
+
protected function getProductImageUrl($productId, $storeId)
|
933 |
{
|
934 |
+
$helper = $this->getHelper();
|
|
|
|
|
935 |
|
936 |
+
$imageType = $helper->getExportImageType();
|
937 |
+
$imageBaseFile = Mage::getResourceSingleton('catalog/product')
|
938 |
+
->getAttributeRawValue($productId, $imageType, $storeId);
|
939 |
+
|
940 |
+
/** @var Mage_Catalog_Model_Product_Image $imageModel */
|
941 |
+
$imageModel = Mage::getModel('catalog/product_image');
|
942 |
+
|
943 |
+
// if size was set
|
944 |
+
if ($helper->getExportImageWidth($storeId)) {
|
945 |
+
$imageModel
|
946 |
+
->setWidth($helper->getExportImageWidth($storeId))
|
947 |
+
->setHeight($helper->getExportImageHeight($storeId));
|
948 |
+
}
|
949 |
+
|
950 |
+
$imageModel
|
951 |
+
->setDestinationSubdir($imageType)
|
952 |
+
->setBaseFile($imageBaseFile);
|
953 |
+
|
954 |
+
// if no cache image was generated we should create one
|
955 |
+
if (!$imageModel->isCached()) {
|
956 |
+
$imageModel
|
957 |
+
->resize()
|
958 |
+
->saveFile();
|
959 |
+
}
|
960 |
+
|
961 |
+
return $imageModel->getUrl();
|
962 |
}
|
963 |
|
964 |
|
965 |
/**
|
966 |
+
* Get searchable attributes by type
|
967 |
*
|
968 |
+
* @param null $backendType Backend type of the attributes
|
969 |
+
* @param string $type Possible Types: system, sortable, filterable, searchable
|
970 |
+
* @param int $storeId
|
971 |
*
|
972 |
+
* @return array
|
973 |
*/
|
974 |
+
protected function _getSearchableAttributes($backendType = null, $type = null, $storeId = 0)
|
975 |
{
|
976 |
+
$attributes = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
977 |
|
978 |
+
if ($type !== null || $backendType !== null) {
|
979 |
+
foreach ($this->getResource()->getSearchableAttributes($storeId) as $attribute) {
|
980 |
+
if ($backendType !== null
|
981 |
+
&& $attribute->getBackendType() != $backendType
|
982 |
+
) {
|
983 |
+
continue;
|
984 |
+
}
|
985 |
+
|
986 |
+
if ($this->_checkIfSkipAttribute($attribute, $type)) {
|
987 |
+
continue;
|
988 |
+
}
|
989 |
+
|
990 |
+
$attributes[$attribute->getId()] = $attribute;
|
991 |
+
}
|
992 |
+
} else {
|
993 |
+
$attributes = $this->getResource()->getSearchableAttributes($storeId);
|
994 |
+
}
|
995 |
+
|
996 |
+
return $attributes;
|
997 |
}
|
998 |
|
999 |
|
app/code/community/FACTFinder/Core/Model/Facade.php
CHANGED
@@ -619,26 +619,6 @@ class FACTFinder_Core_Model_Facade
|
|
619 |
}
|
620 |
|
621 |
|
622 |
-
/**
|
623 |
-
* Create a new results object
|
624 |
-
*
|
625 |
-
* @param array $records
|
626 |
-
* @param string $refKey
|
627 |
-
* @param int $foundRecordsCount
|
628 |
-
*
|
629 |
-
* @return \FACTFinder\Data\Result
|
630 |
-
*/
|
631 |
-
public function getNewResultObject($records, $refKey, $foundRecordsCount)
|
632 |
-
{
|
633 |
-
return FF::getInstance(
|
634 |
-
'Data\Result',
|
635 |
-
$records,
|
636 |
-
$refKey,
|
637 |
-
$foundRecordsCount
|
638 |
-
);
|
639 |
-
}
|
640 |
-
|
641 |
-
|
642 |
/**
|
643 |
* Get paging object (collection)
|
644 |
*
|
619 |
}
|
620 |
|
621 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
622 |
/**
|
623 |
* Get paging object (collection)
|
624 |
*
|
app/code/community/FACTFinder/Core/Model/Handler/Search.php
CHANGED
@@ -28,6 +28,9 @@ class FACTFinder_Core_Model_Handler_Search extends FACTFinder_Core_Model_Handler
|
|
28 |
{
|
29 |
|
30 |
const SEARCH_STATUS_REGISTRY_KEY = 'ff_search_status';
|
|
|
|
|
|
|
31 |
|
32 |
protected $_searchResult;
|
33 |
protected $_searchResultCount;
|
@@ -182,7 +185,9 @@ class FACTFinder_Core_Model_Handler_Search extends FACTFinder_Core_Model_Handler
|
|
182 |
array(
|
183 |
'similarity' => $record->getSimilarity(),
|
184 |
'position' => $record->getPosition(),
|
185 |
-
'original_position' => $record->getField
|
|
|
|
|
186 |
)
|
187 |
);
|
188 |
}
|
28 |
{
|
29 |
|
30 |
const SEARCH_STATUS_REGISTRY_KEY = 'ff_search_status';
|
31 |
+
const ORIGINAL_POSITION_FIELD = '__ORIG_POSITION__';
|
32 |
+
const CAMPAIGN_NAME_FIELD = '__FFCampaign__';
|
33 |
+
const INSTOREADS_PRODUCT_FIELD = '__FFInstoreAds__';
|
34 |
|
35 |
protected $_searchResult;
|
36 |
protected $_searchResultCount;
|
185 |
array(
|
186 |
'similarity' => $record->getSimilarity(),
|
187 |
'position' => $record->getPosition(),
|
188 |
+
'original_position' => $record->getField(self::ORIGINAL_POSITION_FIELD),
|
189 |
+
'campaign' => $record->getField(self::CAMPAIGN_NAME_FIELD),
|
190 |
+
'instore_ads' => $record->getField(self::INSTOREADS_PRODUCT_FIELD)
|
191 |
)
|
192 |
);
|
193 |
}
|
app/code/community/FACTFinder/Core/Model/Resource/Export.php
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* FACTFinder_Core
|
4 |
+
*
|
5 |
+
* @category Mage
|
6 |
+
* @package FACTFinder_Core
|
7 |
+
* @author Flagbit Magento Team <magento@flagbit.de>
|
8 |
+
* @copyright Copyright (c) 2016 Flagbit GmbH & Co. KG
|
9 |
+
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
|
10 |
+
* @link http://www.flagbit.de
|
11 |
+
*
|
12 |
+
*/
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Model class
|
16 |
+
*
|
17 |
+
* This class provides db access to the export model
|
18 |
+
*
|
19 |
+
* @category Mage
|
20 |
+
* @package FACTFinder_Core
|
21 |
+
* @author Flagbit Magento Team <magento@flagbit.de>
|
22 |
+
* @copyright Copyright (c) 2016 Flagbit GmbH & Co. KG (http://www.flagbit.de)
|
23 |
+
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
|
24 |
+
* @link http://www.flagbit.de
|
25 |
+
*/
|
26 |
+
class FACTFinder_Core_Model_Resource_Export extends Mage_CatalogSearch_Model_Resource_Fulltext
|
27 |
+
{
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Retrieve searchable products per store
|
32 |
+
*
|
33 |
+
* @param int $storeId
|
34 |
+
* @param array $staticFields
|
35 |
+
* @param int $lastProductId
|
36 |
+
* @param int $limit
|
37 |
+
*
|
38 |
+
* @return array
|
39 |
+
*/
|
40 |
+
public function getSearchableProducts($storeId, array $staticFields, $lastProductId = 0, $limit = 100)
|
41 |
+
{
|
42 |
+
$websiteId = Mage::app()->getStore($storeId)->getWebsiteId();
|
43 |
+
$readConnection = $this->getReadConnection();
|
44 |
+
|
45 |
+
$select = $readConnection->select()
|
46 |
+
->useStraightJoin(true)
|
47 |
+
->from(
|
48 |
+
array('e' => $this->getTable('catalog/product')),
|
49 |
+
array_merge(array('entity_id', 'type_id'), $staticFields)
|
50 |
+
)
|
51 |
+
->join(
|
52 |
+
array('website' => $this->getTable('catalog/product_website')),
|
53 |
+
$readConnection->quoteInto(
|
54 |
+
'website.product_id=e.entity_id AND website.website_id=?',
|
55 |
+
$websiteId
|
56 |
+
),
|
57 |
+
array()
|
58 |
+
)
|
59 |
+
->join(
|
60 |
+
array('stock_status' => $this->getTable('cataloginventory/stock_status')),
|
61 |
+
$readConnection->quoteInto(
|
62 |
+
'stock_status.product_id=e.entity_id AND stock_status.website_id=?',
|
63 |
+
$websiteId
|
64 |
+
),
|
65 |
+
array('in_stock' => 'stock_status')
|
66 |
+
);
|
67 |
+
|
68 |
+
$select->where('e.entity_id>?', $lastProductId)
|
69 |
+
->limit($limit)
|
70 |
+
->order('e.entity_id');
|
71 |
+
|
72 |
+
if (!Mage::helper('factfinder/export')->shouldExportOutOfStock($storeId)) {
|
73 |
+
Mage::getSingleton('cataloginventory/stock_status')
|
74 |
+
->prepareCatalogProductIndexSelect(
|
75 |
+
$select,
|
76 |
+
new Zend_Db_Expr('e.entity_id'),
|
77 |
+
new Zend_Db_Expr('website.website_id')
|
78 |
+
);
|
79 |
+
}
|
80 |
+
|
81 |
+
$result = $readConnection->fetchAll($select);
|
82 |
+
|
83 |
+
return $result;
|
84 |
+
}
|
85 |
+
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Retrieve Searchable attributes
|
89 |
+
*
|
90 |
+
* @param int $storeId
|
91 |
+
*
|
92 |
+
* @return array
|
93 |
+
*/
|
94 |
+
public function getSearchableAttributes($storeId = null)
|
95 |
+
{
|
96 |
+
if ($this->_searchableAttributes === null) {
|
97 |
+
$this->_searchableAttributes = array();
|
98 |
+
$entityType = $this->getEavConfig()->getEntityType('catalog_product');
|
99 |
+
$entity = $entityType->getEntity();
|
100 |
+
|
101 |
+
$userDefinedAttributes = Mage::getStoreConfig('factfinder/export/attributes', $storeId);
|
102 |
+
$userDefinedAttributes = array_keys(
|
103 |
+
Mage::helper('factfinder/backend')->unserializeFieldValue($userDefinedAttributes)
|
104 |
+
);
|
105 |
+
|
106 |
+
$whereCond = array(
|
107 |
+
$this->_getWriteAdapter()->quoteInto('additional_table.is_searchable=?', 1),
|
108 |
+
$this->_getWriteAdapter()->quoteInto('additional_table.is_filterable=?', 1),
|
109 |
+
$this->_getWriteAdapter()->quoteInto('additional_table.used_for_sort_by=?', 1),
|
110 |
+
$this->_getWriteAdapter()->quoteInto(
|
111 |
+
'main_table.attribute_code IN(?)',
|
112 |
+
array_merge(array('status', 'visibility'), $userDefinedAttributes)
|
113 |
+
)
|
114 |
+
);
|
115 |
+
|
116 |
+
$select = $this->_getWriteAdapter()->select()
|
117 |
+
->from(array('main_table' => $this->getTable('eav/attribute')))
|
118 |
+
->join(
|
119 |
+
array('additional_table' => $this->getTable('catalog/eav_attribute')),
|
120 |
+
'additional_table.attribute_id = main_table.attribute_id'
|
121 |
+
)
|
122 |
+
->where('main_table.entity_type_id=?', $entityType->getEntityTypeId())
|
123 |
+
->where(join(' OR ', $whereCond))
|
124 |
+
->order('main_table.attribute_id', 'asc');
|
125 |
+
|
126 |
+
$attributesData = $this->_getWriteAdapter()->fetchAll($select);
|
127 |
+
$this->getEavConfig()->importAttributesData($entityType, $attributesData);
|
128 |
+
|
129 |
+
foreach ($attributesData as $attributeData) {
|
130 |
+
$attributeCode = $attributeData['attribute_code'];
|
131 |
+
$attribute = $this->getEavConfig()->getAttribute($entityType, $attributeCode);
|
132 |
+
$attribute->setEntity($entity);
|
133 |
+
$this->_searchableAttributes[$attribute->getId()] = $attribute;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
return $this->_searchableAttributes;
|
138 |
+
}
|
139 |
+
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Get products to category paths
|
143 |
+
*
|
144 |
+
* @param int $storeId
|
145 |
+
*
|
146 |
+
* @return array
|
147 |
+
*/
|
148 |
+
public function getCategoryPaths($storeId)
|
149 |
+
{
|
150 |
+
$select = $this->_getReadAdapter()->select()
|
151 |
+
->from(
|
152 |
+
array('main' => $this->getTable('catalog/category_product_index')),
|
153 |
+
array('product_id')
|
154 |
+
)
|
155 |
+
->join(
|
156 |
+
array('e' => $this->getTable('catalog/category')),
|
157 |
+
'main.category_id=e.entity_id',
|
158 |
+
null
|
159 |
+
)
|
160 |
+
->columns(array('e.path' => new Zend_Db_Expr('GROUP_CONCAT(e.path)')))
|
161 |
+
->where(
|
162 |
+
'main.visibility IN(?)',
|
163 |
+
array(
|
164 |
+
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH,
|
165 |
+
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH
|
166 |
+
)
|
167 |
+
)
|
168 |
+
->where('main.store_id = ?', $storeId)
|
169 |
+
->where('e.path LIKE \'1/' . Mage::app()->getStore($storeId)->getRootCategoryId() . '/%\'')
|
170 |
+
->group('main.product_id');
|
171 |
+
|
172 |
+
return $this->_getReadAdapter()->fetchPairs($select);
|
173 |
+
}
|
174 |
+
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Get category names
|
178 |
+
*
|
179 |
+
* @param int $storeId
|
180 |
+
*
|
181 |
+
* @return $this
|
182 |
+
*/
|
183 |
+
public function getCategoryNames($storeId)
|
184 |
+
{
|
185 |
+
$nameAttribute = $this->_getCategoryNameAttribute();
|
186 |
+
$statusAttribute = $this->_getCategoryStatusAttribute();
|
187 |
+
|
188 |
+
$select = $this->_getReadAdapter()->select()
|
189 |
+
->from(
|
190 |
+
array('main' => $nameAttribute->getBackendTable()),
|
191 |
+
array('entity_id', 'value')
|
192 |
+
)
|
193 |
+
->join(
|
194 |
+
array('e' => $statusAttribute->getBackendTable()),
|
195 |
+
'main.entity_id=e.entity_id AND (e.store_id = 0 OR e.store_id = ' . $storeId
|
196 |
+
. ') AND e.attribute_id=' . $statusAttribute->getAttributeId(),
|
197 |
+
null
|
198 |
+
)
|
199 |
+
->where('main.attribute_id=?', $nameAttribute->getAttributeId())
|
200 |
+
->where('e.value=?', '1')
|
201 |
+
->where('main.store_id = 0 OR main.store_id = ?', $storeId);
|
202 |
+
|
203 |
+
return $this->_getReadAdapter()->fetchPairs($select);
|
204 |
+
}
|
205 |
+
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Get category name attribute model
|
209 |
+
*
|
210 |
+
* @return mixed
|
211 |
+
*/
|
212 |
+
protected function _getCategoryNameAttribute()
|
213 |
+
{
|
214 |
+
$categoryAttributeCollection = Mage::getResourceModel('catalog/category_attribute_collection');
|
215 |
+
$categoryAttributeCollection->addFieldToFilter('attribute_code', array('eq' => 'name'))
|
216 |
+
->getSelect()->limit(1);
|
217 |
+
|
218 |
+
return $categoryAttributeCollection->getFirstItem();
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Get category status attribute model (is_active)
|
224 |
+
*
|
225 |
+
* @return mixed
|
226 |
+
*/
|
227 |
+
protected function _getCategoryStatusAttribute()
|
228 |
+
{
|
229 |
+
$categoryAttributeCollection = Mage::getResourceModel('catalog/category_attribute_collection');
|
230 |
+
$categoryAttributeCollection->addFieldToFilter('attribute_code', array('eq' => 'is_active'))
|
231 |
+
->getSelect()->limit(1);
|
232 |
+
|
233 |
+
return $categoryAttributeCollection->getFirstItem();
|
234 |
+
}
|
235 |
+
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Return all product children ids
|
239 |
+
*
|
240 |
+
* @param int $productId Product Entity Id
|
241 |
+
* @param string $typeId Super Product Link Type
|
242 |
+
*
|
243 |
+
* @return array
|
244 |
+
*/
|
245 |
+
public function getProductChildIds($productId, $typeId)
|
246 |
+
{
|
247 |
+
$typeInstance = $this->_getProductTypeInstance($typeId);
|
248 |
+
$relation = $typeInstance->isComposite()
|
249 |
+
? $typeInstance->getRelationInfo()
|
250 |
+
: false;
|
251 |
+
|
252 |
+
if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()) {
|
253 |
+
$select = $this->_getReadAdapter()->select()
|
254 |
+
->from(
|
255 |
+
array('main' => $this->getTable($relation->getTable())),
|
256 |
+
array($relation->getChildFieldName()))
|
257 |
+
->join(
|
258 |
+
array('e' => $this->getTable('catalog/product')),
|
259 |
+
'main.' . $relation->getChildFieldName() . '=e.entity_id',
|
260 |
+
array('entity_id', 'type_id', 'sku')
|
261 |
+
)
|
262 |
+
->where("{$relation->getParentFieldName()}=?", $productId);
|
263 |
+
if ($relation->getWhere() !== null) {
|
264 |
+
$select->where($relation->getWhere());
|
265 |
+
}
|
266 |
+
|
267 |
+
return $this->_getReadAdapter()->fetchAll($select);
|
268 |
+
}
|
269 |
+
|
270 |
+
return null;
|
271 |
+
}
|
272 |
+
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Retrieve searchable attribute by Id or code
|
276 |
+
*
|
277 |
+
* @param int|string $attribute
|
278 |
+
*
|
279 |
+
* @return Mage_Eav_Model_Entity_Attribute
|
280 |
+
*/
|
281 |
+
public function getSearchableAttribute($attribute)
|
282 |
+
{
|
283 |
+
return $this->_getSearchableAttribute($attribute);
|
284 |
+
}
|
285 |
+
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Load product(s) attributes
|
289 |
+
*
|
290 |
+
* @param int $storeId
|
291 |
+
* @param array $productIds
|
292 |
+
* @param array $attributeTypes
|
293 |
+
*
|
294 |
+
* @return array
|
295 |
+
*/
|
296 |
+
public function getProductAttributes($storeId, array $productIds, array $attributeTypes)
|
297 |
+
{
|
298 |
+
return $this->_getProductAttributes($storeId, $productIds, $attributeTypes);
|
299 |
+
}
|
300 |
+
|
301 |
+
|
302 |
+
}
|
app/code/community/FACTFinder/Core/etc/system.xml
CHANGED
@@ -189,11 +189,20 @@
|
|
189 |
<label>Export products without categories</label>
|
190 |
<frontend_type>select</frontend_type>
|
191 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
192 |
-
<sort_order>
|
193 |
<show_in_default>1</show_in_default>
|
194 |
<show_in_website>1</show_in_website>
|
195 |
<show_in_store>1</show_in_store>
|
196 |
</products_without_categories>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
<remove_tags translate="label">
|
198 |
<label>Remove html entities and tags</label>
|
199 |
<frontend_type>select</frontend_type>
|
189 |
<label>Export products without categories</label>
|
190 |
<frontend_type>select</frontend_type>
|
191 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
192 |
+
<sort_order>10</sort_order>
|
193 |
<show_in_default>1</show_in_default>
|
194 |
<show_in_website>1</show_in_website>
|
195 |
<show_in_store>1</show_in_store>
|
196 |
</products_without_categories>
|
197 |
+
<out_of_stock_products>
|
198 |
+
<label>Export out of stock products</label>
|
199 |
+
<frontend_type>select</frontend_type>
|
200 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
201 |
+
<sort_order>15</sort_order>
|
202 |
+
<show_in_default>1</show_in_default>
|
203 |
+
<show_in_website>1</show_in_website>
|
204 |
+
<show_in_store>1</show_in_store>
|
205 |
+
</out_of_stock_products>
|
206 |
<remove_tags translate="label">
|
207 |
<label>Remove html entities and tags</label>
|
208 |
<frontend_type>select</frontend_type>
|
app/code/community/FACTFinder/Recommendation/Helper/Data.php
CHANGED
@@ -57,7 +57,9 @@ class FACTFinder_Recommendation_Helper_Data extends Mage_Core_Helper_Abstract
|
|
57 |
{
|
58 |
$exportHelper = Mage::helper('factfinder/export');
|
59 |
$channel = Mage::helper('factfinder')->getPrimaryChannel($storeId);
|
|
|
60 |
$facade = Mage::getModel('factfinder_recommendation/facade');
|
|
|
61 |
$download = !$exportHelper->useFtp($storeId);
|
62 |
$delay = $exportHelper->getImportDelay(self::IMPORT_TYPE);
|
63 |
|
57 |
{
|
58 |
$exportHelper = Mage::helper('factfinder/export');
|
59 |
$channel = Mage::helper('factfinder')->getPrimaryChannel($storeId);
|
60 |
+
/** @var FACTFinder_Recommendation_Model_Facade $facade */
|
61 |
$facade = Mage::getModel('factfinder_recommendation/facade');
|
62 |
+
$facade->setStoreId($storeId);
|
63 |
$download = !$exportHelper->useFtp($storeId);
|
64 |
$delay = $exportHelper->getImportDelay(self::IMPORT_TYPE);
|
65 |
|
app/code/community/FACTFinder/Suggest/Helper/Data.php
CHANGED
@@ -47,6 +47,9 @@ class FACTFinder_Suggest_Helper_Data extends Mage_Core_Helper_Abstract
|
|
47 |
if (Mage::app()->getStore()->isCurrentlySecure()) {
|
48 |
$url = preg_replace('/^http:/', 'https:', $url);
|
49 |
}
|
|
|
|
|
|
|
50 |
}
|
51 |
|
52 |
// avoid specifying the default port for http
|
@@ -95,7 +98,9 @@ class FACTFinder_Suggest_Helper_Data extends Mage_Core_Helper_Abstract
|
|
95 |
{
|
96 |
$exportHelper = Mage::helper('factfinder/export');
|
97 |
$channel = Mage::helper('factfinder')->getPrimaryChannel($storeId);
|
|
|
98 |
$facade = Mage::getModel('factfinder_suggest/facade');
|
|
|
99 |
$download = !$exportHelper->useFtp($storeId);
|
100 |
$delay = $exportHelper->getImportDelay(self::IMPORT_TYPE);
|
101 |
|
@@ -112,4 +117,30 @@ class FACTFinder_Suggest_Helper_Data extends Mage_Core_Helper_Abstract
|
|
112 |
}
|
113 |
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
47 |
if (Mage::app()->getStore()->isCurrentlySecure()) {
|
48 |
$url = preg_replace('/^http:/', 'https:', $url);
|
49 |
}
|
50 |
+
|
51 |
+
// remove all parameters except for channel
|
52 |
+
$url = $this->removeUrlParams($url, array('channel'));
|
53 |
}
|
54 |
|
55 |
// avoid specifying the default port for http
|
98 |
{
|
99 |
$exportHelper = Mage::helper('factfinder/export');
|
100 |
$channel = Mage::helper('factfinder')->getPrimaryChannel($storeId);
|
101 |
+
/** @var FACTFinder_Suggest_Model_Facade $facade */
|
102 |
$facade = Mage::getModel('factfinder_suggest/facade');
|
103 |
+
$facade->setStoreId($storeId);
|
104 |
$download = !$exportHelper->useFtp($storeId);
|
105 |
$delay = $exportHelper->getImportDelay(self::IMPORT_TYPE);
|
106 |
|
117 |
}
|
118 |
|
119 |
|
120 |
+
/**
|
121 |
+
* Remove all parameters from url except for specified
|
122 |
+
*
|
123 |
+
* @param string $url
|
124 |
+
* @param array $exclude
|
125 |
+
*
|
126 |
+
* @return string
|
127 |
+
*/
|
128 |
+
protected function removeUrlParams($url, $exclude = array())
|
129 |
+
{
|
130 |
+
$excludeParams = array();
|
131 |
+
|
132 |
+
foreach ($exclude as $paramName) {
|
133 |
+
preg_match("/[&|?]{$paramName}=([^&]*)&?/", $url, $values);
|
134 |
+
if (isset($values[1])) {
|
135 |
+
$excludeParams[$paramName] = $values[1];
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
$url = array_shift(explode('?', $url));
|
140 |
+
$query = http_build_query($excludeParams);
|
141 |
+
|
142 |
+
return $url . '?' . $query;
|
143 |
+
}
|
144 |
+
|
145 |
+
|
146 |
}
|
app/code/community/FACTFinder/Tracking/Block/Click.php
CHANGED
@@ -56,6 +56,14 @@ class FACTFinder_Tracking_Block_Click extends FACTFinder_Tracking_Block_Abstract
|
|
56 |
'title' => $product->getName()
|
57 |
);
|
58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
return $data;
|
60 |
|
61 |
}
|
56 |
'title' => $product->getName()
|
57 |
);
|
58 |
|
59 |
+
if ($product->getCampaign() !== null) {
|
60 |
+
$data['campaign'] = $product->getCampaign();
|
61 |
+
}
|
62 |
+
|
63 |
+
if ($product->getInstoreAds() !== null) {
|
64 |
+
$data['instoreAds'] = $product->getInstoreAds();
|
65 |
+
}
|
66 |
+
|
67 |
return $data;
|
68 |
|
69 |
}
|
app/design/frontend/base/default/template/factfinder/suggest/advancedsuggest.phtml
CHANGED
@@ -38,13 +38,13 @@
|
|
38 |
<?php if (Mage::helper('factfinder')->isEnabled('suggest')): ?>
|
39 |
searchForm = new FactFinderSuggest(
|
40 |
'search_mini_form', 'search',
|
41 |
-
'<?php echo
|
42 |
<?php echo $this->getTranslationsAsJson(); ?>,
|
43 |
'<?php echo Mage::getStoreConfig('factfinder/search/channel'); ?>'
|
44 |
);
|
45 |
<?php else: ?>
|
46 |
searchForm = new Varien.searchForm('search_mini_form', 'search',
|
47 |
-
'<?php echo
|
48 |
);
|
49 |
<?php endif; ?>
|
50 |
|
38 |
<?php if (Mage::helper('factfinder')->isEnabled('suggest')): ?>
|
39 |
searchForm = new FactFinderSuggest(
|
40 |
'search_mini_form', 'search',
|
41 |
+
'<?php echo addslashes($this->__('Search entire store here...')); ?>',
|
42 |
<?php echo $this->getTranslationsAsJson(); ?>,
|
43 |
'<?php echo Mage::getStoreConfig('factfinder/search/channel'); ?>'
|
44 |
);
|
45 |
<?php else: ?>
|
46 |
searchForm = new Varien.searchForm('search_mini_form', 'search',
|
47 |
+
'<?php echo addslashes($this->__('Search entire shop here...')); ?>'
|
48 |
);
|
49 |
<?php endif; ?>
|
50 |
|
app/locale/de_DE/FACTFinder_Suggest.csv
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
"ff_searchTerm","Suchbegriffe"
|
2 |
+
"ff_category","Kategorien"
|
3 |
+
"ff_productName","Produkte"
|
4 |
+
"ff_brand","Marken"
|
app/locale/en_US/FACTFinder_Suggest.csv
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
"ff_searchTerm","Searchterms"
|
2 |
+
"ff_category","Categories"
|
3 |
+
"ff_productName","Products"
|
4 |
+
"ff_brand","Brands"
|
lib/FACTFinder/Adapter/AbstractAdapter.php
CHANGED
@@ -39,6 +39,11 @@ abstract class AbstractAdapter
|
|
39 |
*/
|
40 |
protected $urlBuilder;
|
41 |
|
|
|
|
|
|
|
|
|
|
|
42 |
/**
|
43 |
* @var \FACTFinder\Util\ContentProcessorInterface
|
44 |
*/
|
39 |
*/
|
40 |
protected $urlBuilder;
|
41 |
|
42 |
+
/**
|
43 |
+
* @var bool
|
44 |
+
*/
|
45 |
+
protected $upToDate = false;
|
46 |
+
|
47 |
/**
|
48 |
* @var \FACTFinder\Util\ContentProcessorInterface
|
49 |
*/
|
lib/FACTFinder/Adapter/Compare.php
CHANGED
@@ -3,7 +3,7 @@ namespace FACTFinder\Adapter;
|
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
-
class Compare extends
|
7 |
{
|
8 |
/**
|
9 |
* @var FACTFinder\Util\LoggerInterface
|
@@ -21,18 +21,6 @@ class Compare extends AbstractAdapter
|
|
21 |
*/
|
22 |
private $comparedRecords;
|
23 |
|
24 |
-
/**
|
25 |
-
* @var bool
|
26 |
-
*/
|
27 |
-
private $attributesUpToDate = false;
|
28 |
-
private $recordsUpToDate = false;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* @var bool
|
32 |
-
*/
|
33 |
-
private $comparableAttributesOnly = false;
|
34 |
-
|
35 |
-
|
36 |
public function __construct(
|
37 |
$loggerClass,
|
38 |
\FACTFinder\Core\ConfigurationInterface $configuration,
|
@@ -60,25 +48,7 @@ class Compare extends AbstractAdapter
|
|
60 |
{
|
61 |
$parameters = $this->request->getParameters();
|
62 |
$parameters['ids'] = implode(';', $productIDs);
|
63 |
-
$this->
|
64 |
-
$this->recordsUpToDate = false;
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Set this to true to only retrieve those attributes that have been used
|
69 |
-
* for comparison instead of full Record objects.
|
70 |
-
*
|
71 |
-
* @param $comparableAttributesOnly bool
|
72 |
-
*/
|
73 |
-
public function setComparableAttributesOnly($comparableAttributesOnly)
|
74 |
-
{
|
75 |
-
// Reset the compared products, if more detail is wanted than before
|
76 |
-
if($this->comparableAttributesOnly && !$comparableAttributesOnly)
|
77 |
-
$this->recordsUpToDate = false;
|
78 |
-
|
79 |
-
$this->comparableAttributesOnly = $comparableAttributesOnly;
|
80 |
-
$parameters = $this->request->getParameters();
|
81 |
-
$parameters['idsOnly'] = $comparableAttributesOnly ? 'true' : 'false';
|
82 |
}
|
83 |
|
84 |
/**
|
@@ -92,10 +62,10 @@ class Compare extends AbstractAdapter
|
|
92 |
public function getComparableAttributes()
|
93 |
{
|
94 |
if (is_null($this->comparableAttributes)
|
95 |
-
|| !$this->
|
96 |
) {
|
97 |
$this->comparableAttributes = $this->createComparableAttributes();
|
98 |
-
$this->
|
99 |
}
|
100 |
|
101 |
return $this->comparableAttributes;
|
@@ -136,10 +106,10 @@ class Compare extends AbstractAdapter
|
|
136 |
public function getComparedRecords()
|
137 |
{
|
138 |
if (is_null($this->comparedRecords)
|
139 |
-
|| !$this->
|
140 |
) {
|
141 |
$this->comparedRecords = $this->createComparedRecords();
|
142 |
-
$this->
|
143 |
}
|
144 |
|
145 |
return $this->comparedRecords;
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
+
class Compare extends ConfigurableResponse
|
7 |
{
|
8 |
/**
|
9 |
* @var FACTFinder\Util\LoggerInterface
|
21 |
*/
|
22 |
private $comparedRecords;
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
public function __construct(
|
25 |
$loggerClass,
|
26 |
\FACTFinder\Core\ConfigurationInterface $configuration,
|
48 |
{
|
49 |
$parameters = $this->request->getParameters();
|
50 |
$parameters['ids'] = implode(';', $productIDs);
|
51 |
+
$this->upToDate = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
}
|
53 |
|
54 |
/**
|
62 |
public function getComparableAttributes()
|
63 |
{
|
64 |
if (is_null($this->comparableAttributes)
|
65 |
+
|| !$this->upToDate
|
66 |
) {
|
67 |
$this->comparableAttributes = $this->createComparableAttributes();
|
68 |
+
$this->upToDate = true;
|
69 |
}
|
70 |
|
71 |
return $this->comparableAttributes;
|
106 |
public function getComparedRecords()
|
107 |
{
|
108 |
if (is_null($this->comparedRecords)
|
109 |
+
|| !$this->upToDate
|
110 |
) {
|
111 |
$this->comparedRecords = $this->createComparedRecords();
|
112 |
+
$this->upToDate = true;
|
113 |
}
|
114 |
|
115 |
return $this->comparedRecords;
|
lib/FACTFinder/Adapter/ConfigurableResponse.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace FACTFinder\Adapter;
|
3 |
+
|
4 |
+
use FACTFinder\Loader as FF;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Base class for all adapters which support the response of records with ids only.
|
8 |
+
*/
|
9 |
+
abstract class ConfigurableResponse extends AbstractAdapter
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* @var bool
|
13 |
+
*/
|
14 |
+
protected $idsOnly = false;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param string $loggerClass Class name of logger to use. The class should
|
18 |
+
* implement FACTFinder\Util\LoggerInterface.
|
19 |
+
* @param \FACTFinder\Core\ConfigurationInterface $configuration
|
20 |
+
* Configuration object to use.
|
21 |
+
* @param \FACTFinder\Core\Server\Request $request The request object from
|
22 |
+
* which to obtain the server data.
|
23 |
+
* @param \FACTFinder\Core\Client\UrlBuilder $urlBuilder
|
24 |
+
* Client URL builder object to use.
|
25 |
+
* @param \FACTFinder\Core\encodingConverter $encodingConverter
|
26 |
+
* Encoding converter object to use
|
27 |
+
*/
|
28 |
+
public function __construct(
|
29 |
+
$loggerClass,
|
30 |
+
\FACTFinder\Core\ConfigurationInterface $configuration,
|
31 |
+
\FACTFinder\Core\Server\Request $request,
|
32 |
+
\FACTFinder\Core\Client\UrlBuilder $urlBuilder,
|
33 |
+
\FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
|
34 |
+
) {
|
35 |
+
parent::__construct($loggerClass, $configuration, $request,
|
36 |
+
$urlBuilder, $encodingConverter);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Set this to true to only retrieve the IDs of products instead
|
41 |
+
* of full Record objects.
|
42 |
+
* @param $idsOnly bool
|
43 |
+
*/
|
44 |
+
public function setIdsOnly($idsOnly)
|
45 |
+
{
|
46 |
+
if($this->idsOnly && !$idsOnly)
|
47 |
+
$this->upToDate = false;
|
48 |
+
|
49 |
+
$this->idsOnly = $idsOnly;
|
50 |
+
$parameters = $this->request->getParameters();
|
51 |
+
$parameters['idsOnly'] = $idsOnly ? 'true' : 'false';
|
52 |
+
}
|
53 |
+
}
|
lib/FACTFinder/Adapter/PersonalisedResponse.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace FACTFinder\Adapter;
|
3 |
+
|
4 |
+
use FACTFinder\Loader as FF;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Base class for all adapters which support the personalisation.
|
8 |
+
*/
|
9 |
+
abstract class PersonalisedResponse extends ConfigurableResponse
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* @var string
|
13 |
+
*/
|
14 |
+
protected $sid = false;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param string $loggerClass Class name of logger to use. The class should
|
18 |
+
* implement FACTFinder\Util\LoggerInterface.
|
19 |
+
* @param \FACTFinder\Core\ConfigurationInterface $configuration
|
20 |
+
* Configuration object to use.
|
21 |
+
* @param \FACTFinder\Core\Server\Request $request The request object from
|
22 |
+
* which to obtain the server data.
|
23 |
+
* @param \FACTFinder\Core\Client\UrlBuilder $urlBuilder
|
24 |
+
* Client URL builder object to use.
|
25 |
+
* @param \FACTFinder\Core\encodingConverter $encodingConverter
|
26 |
+
* Encoding converter object to use
|
27 |
+
*/
|
28 |
+
public function __construct(
|
29 |
+
$loggerClass,
|
30 |
+
\FACTFinder\Core\ConfigurationInterface $configuration,
|
31 |
+
\FACTFinder\Core\Server\Request $request,
|
32 |
+
\FACTFinder\Core\Client\UrlBuilder $urlBuilder,
|
33 |
+
\FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
|
34 |
+
) {
|
35 |
+
parent::__construct($loggerClass, $configuration, $request,
|
36 |
+
$urlBuilder, $encodingConverter);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Set the session id for personalization.
|
41 |
+
*
|
42 |
+
* @param string $sessionId session id
|
43 |
+
*/
|
44 |
+
public function setSid($sessionId)
|
45 |
+
{
|
46 |
+
if (strcmp($sessionId, $this->sid) !== 0) {
|
47 |
+
$this->sid = $sessionId;
|
48 |
+
$this->parameters['sid'] = $this->sid;
|
49 |
+
$this->upToDate = false;
|
50 |
+
}
|
51 |
+
}
|
52 |
+
}
|
lib/FACTFinder/Adapter/ProductCampaign.php
CHANGED
@@ -3,7 +3,7 @@ namespace FACTFinder\Adapter;
|
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
-
class ProductCampaign extends
|
7 |
{
|
8 |
/**
|
9 |
* @var FACTFinder\Util\LoggerInterface
|
@@ -18,13 +18,8 @@ class ProductCampaign extends AbstractAdapter
|
|
18 |
/**
|
19 |
* @var bool
|
20 |
*/
|
21 |
-
protected $isShoppingCartCampaign = false;
|
22 |
-
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @var bool
|
26 |
-
*/
|
27 |
-
private $idsOnly = false;
|
28 |
|
29 |
public function __construct(
|
30 |
$loggerClass,
|
@@ -57,7 +52,7 @@ class ProductCampaign extends AbstractAdapter
|
|
57 |
{
|
58 |
$parameters = $this->request->getParameters();
|
59 |
$parameters['productNumber'] = $productNumbers;
|
60 |
-
$this->
|
61 |
}
|
62 |
|
63 |
/**
|
@@ -70,23 +65,19 @@ class ProductCampaign extends AbstractAdapter
|
|
70 |
{
|
71 |
$parameters = $this->request->getParameters();
|
72 |
$parameters->add('productNumber', $productNumbers);
|
73 |
-
$this->
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
-
* Set
|
78 |
-
*
|
79 |
-
*
|
80 |
-
* @param $idsOnly bool
|
81 |
*/
|
82 |
-
public function
|
83 |
{
|
84 |
-
if($this->idsOnly && !$idsOnly)
|
85 |
-
$this->campaignsUpToDate = false;
|
86 |
-
|
87 |
-
$this->idsOnly = $idsOnly;
|
88 |
$parameters = $this->request->getParameters();
|
89 |
-
$parameters
|
|
|
90 |
}
|
91 |
|
92 |
/**
|
@@ -95,7 +86,8 @@ class ProductCampaign extends AbstractAdapter
|
|
95 |
public function makeProductCampaign()
|
96 |
{
|
97 |
$this->isShoppingCartCampaign = false;
|
98 |
-
$this->
|
|
|
99 |
$this->parameters['do'] = 'getProductCampaigns';
|
100 |
}
|
101 |
|
@@ -105,9 +97,20 @@ class ProductCampaign extends AbstractAdapter
|
|
105 |
public function makeShoppingCartCampaign()
|
106 |
{
|
107 |
$this->isShoppingCartCampaign = true;
|
108 |
-
$this->
|
|
|
109 |
$this->parameters['do'] = 'getShoppingCartCampaigns';
|
110 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
|
112 |
/**
|
113 |
* Returns campaigns for IDs previously specified. If no IDs have been
|
@@ -118,11 +121,11 @@ class ProductCampaign extends AbstractAdapter
|
|
118 |
public function getCampaigns()
|
119 |
{
|
120 |
if (is_null($this->campaigns)
|
121 |
-
|| !$this->
|
122 |
) {
|
123 |
$this->request->resetLoaded();
|
124 |
$this->campaigns = $this->createCampaigns();
|
125 |
-
$this->
|
126 |
}
|
127 |
|
128 |
return $this->campaigns;
|
@@ -131,15 +134,20 @@ class ProductCampaign extends AbstractAdapter
|
|
131 |
private function createCampaigns()
|
132 |
{
|
133 |
$campaigns = array();
|
134 |
-
|
135 |
-
if
|
|
|
|
|
|
|
|
|
|
|
136 |
{
|
137 |
$this->log->warn('Product campaigns cannot be loaded without a product ID. '
|
138 |
. 'Use setProductIDs() or addProductIDs() first.');
|
139 |
}
|
140 |
else
|
141 |
{
|
142 |
-
if ($this->isShoppingCartCampaign)
|
143 |
{
|
144 |
$jsonData = $this->getResponseContent();
|
145 |
}
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
+
class ProductCampaign extends PersonalisedResponse
|
7 |
{
|
8 |
/**
|
9 |
* @var FACTFinder\Util\LoggerInterface
|
18 |
/**
|
19 |
* @var bool
|
20 |
*/
|
21 |
+
protected $isShoppingCartCampaign = false;
|
22 |
+
protected $isLandingPageCampaign = false;
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
public function __construct(
|
25 |
$loggerClass,
|
52 |
{
|
53 |
$parameters = $this->request->getParameters();
|
54 |
$parameters['productNumber'] = $productNumbers;
|
55 |
+
$this->upToDate = false;
|
56 |
}
|
57 |
|
58 |
/**
|
65 |
{
|
66 |
$parameters = $this->request->getParameters();
|
67 |
$parameters->add('productNumber', $productNumbers);
|
68 |
+
$this->upToDate = false;
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
+
* Set the page id to get landing page campaigns.
|
73 |
+
*
|
74 |
+
* @param string $pageId The id which determines the campaigns for a page.
|
|
|
75 |
*/
|
76 |
+
public function setPageId($pageId)
|
77 |
{
|
|
|
|
|
|
|
|
|
78 |
$parameters = $this->request->getParameters();
|
79 |
+
$parameters->add('pageId', $pageId);
|
80 |
+
$this->upToDate = false;
|
81 |
}
|
82 |
|
83 |
/**
|
86 |
public function makeProductCampaign()
|
87 |
{
|
88 |
$this->isShoppingCartCampaign = false;
|
89 |
+
$this->isLandingPageCampaign = false;
|
90 |
+
$this->upToDate = false;
|
91 |
$this->parameters['do'] = 'getProductCampaigns';
|
92 |
}
|
93 |
|
97 |
public function makeShoppingCartCampaign()
|
98 |
{
|
99 |
$this->isShoppingCartCampaign = true;
|
100 |
+
$this->isLandingPageCampaign = false;
|
101 |
+
$this->upToDate = false;
|
102 |
$this->parameters['do'] = 'getShoppingCartCampaigns';
|
103 |
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Sets the adapter up for fetching campaigns on landing pages
|
107 |
+
*/
|
108 |
+
public function makePageCampaign()
|
109 |
+
{
|
110 |
+
$this->isLandingPageCampaign = true;
|
111 |
+
$this->upToDate = false;
|
112 |
+
$this->parameters['do'] = 'getPageCampaigns';
|
113 |
+
}
|
114 |
|
115 |
/**
|
116 |
* Returns campaigns for IDs previously specified. If no IDs have been
|
121 |
public function getCampaigns()
|
122 |
{
|
123 |
if (is_null($this->campaigns)
|
124 |
+
|| !$this->upToDate
|
125 |
) {
|
126 |
$this->request->resetLoaded();
|
127 |
$this->campaigns = $this->createCampaigns();
|
128 |
+
$this->upToDate = true;
|
129 |
}
|
130 |
|
131 |
return $this->campaigns;
|
134 |
private function createCampaigns()
|
135 |
{
|
136 |
$campaigns = array();
|
137 |
+
|
138 |
+
if ($this->isLandingPageCampaign && !isset($this->parameters['pageId']))
|
139 |
+
{
|
140 |
+
$this->log->warn('Page campaigns cannot be loaded without a page ID. '
|
141 |
+
. 'Use setPageId() first.');
|
142 |
+
}
|
143 |
+
else if (!$this->isLandingPageCampaign && !isset($this->parameters['productNumber']))
|
144 |
{
|
145 |
$this->log->warn('Product campaigns cannot be loaded without a product ID. '
|
146 |
. 'Use setProductIDs() or addProductIDs() first.');
|
147 |
}
|
148 |
else
|
149 |
{
|
150 |
+
if ($this->isShoppingCartCampaign || $this->isLandingPageCampaign)
|
151 |
{
|
152 |
$jsonData = $this->getResponseContent();
|
153 |
}
|
lib/FACTFinder/Adapter/Recommendation.php
CHANGED
@@ -3,7 +3,7 @@ namespace FACTFinder\Adapter;
|
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
-
class Recommendation extends
|
7 |
{
|
8 |
/**
|
9 |
* @var FACTFinder\Util\LoggerInterface
|
@@ -15,17 +15,6 @@ class Recommendation extends AbstractAdapter
|
|
15 |
*/
|
16 |
private $recommendations;
|
17 |
|
18 |
-
/**
|
19 |
-
* @var bool
|
20 |
-
*/
|
21 |
-
private $recommendationsUpToDate = false;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @var bool
|
25 |
-
*/
|
26 |
-
private $idsOnly = false;
|
27 |
-
|
28 |
-
|
29 |
public function __construct(
|
30 |
$loggerClass,
|
31 |
\FACTFinder\Core\ConfigurationInterface $configuration,
|
@@ -68,7 +57,7 @@ class Recommendation extends AbstractAdapter
|
|
68 |
}
|
69 |
// Make sure that the recommendations are fetched again. In theory,
|
70 |
// we only have to do this when recordCount increases.
|
71 |
-
$this->
|
72 |
}
|
73 |
|
74 |
/**
|
@@ -81,7 +70,7 @@ class Recommendation extends AbstractAdapter
|
|
81 |
{
|
82 |
$parameters = $this->request->getParameters();
|
83 |
$parameters['id'] = $productIDs;
|
84 |
-
$this->
|
85 |
}
|
86 |
|
87 |
/**
|
@@ -94,34 +83,7 @@ class Recommendation extends AbstractAdapter
|
|
94 |
{
|
95 |
$parameters = $this->request->getParameters();
|
96 |
$parameters->add('id', $productIDs);
|
97 |
-
$this->
|
98 |
-
}
|
99 |
-
|
100 |
-
/**
|
101 |
-
* Set this to true to only retrieve the IDs of recommended products instead
|
102 |
-
* of full Record objects.
|
103 |
-
* @param $idsOnly bool
|
104 |
-
*/
|
105 |
-
public function setIdsOnly($idsOnly)
|
106 |
-
{
|
107 |
-
// Reset the recommendations, if more detail is wanted than before
|
108 |
-
if($this->idsOnly && !$idsOnly)
|
109 |
-
$this->recommendationsUpToDate = false;
|
110 |
-
|
111 |
-
$this->idsOnly = $idsOnly;
|
112 |
-
$parameters = $this->request->getParameters();
|
113 |
-
$parameters['idsOnly'] = $idsOnly ? 'true' : 'false';
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Set value for parameter sid for personalization.
|
118 |
-
*
|
119 |
-
* @param string $sid session id
|
120 |
-
*/
|
121 |
-
public function setSid($sid)
|
122 |
-
{
|
123 |
-
$this->parameters['sid'] = $sid;
|
124 |
-
$this->recommendationsUpToDate = false;
|
125 |
}
|
126 |
|
127 |
/**
|
@@ -133,11 +95,11 @@ class Recommendation extends AbstractAdapter
|
|
133 |
public function getRecommendations()
|
134 |
{
|
135 |
if (is_null($this->recommendations)
|
136 |
-
|| !$this->
|
137 |
) {
|
138 |
$this->request->resetLoaded();
|
139 |
$this->recommendations = $this->createRecommendations();
|
140 |
-
$this->
|
141 |
}
|
142 |
|
143 |
return $this->recommendations;
|
@@ -165,10 +127,7 @@ class Recommendation extends AbstractAdapter
|
|
165 |
$position = 1;
|
166 |
foreach($recommenderData as $recordData)
|
167 |
{
|
168 |
-
|
169 |
-
$records[] = $this->createSparseRecord($recordData);
|
170 |
-
else
|
171 |
-
$records[] = $this->createRecord($recordData, $position++);
|
172 |
}
|
173 |
}
|
174 |
}
|
@@ -181,14 +140,6 @@ class Recommendation extends AbstractAdapter
|
|
181 |
);
|
182 |
}
|
183 |
|
184 |
-
private function createSparseRecord($recordData)
|
185 |
-
{
|
186 |
-
return FF::getInstance(
|
187 |
-
'Data\Record',
|
188 |
-
(string)$recordData['id']
|
189 |
-
);
|
190 |
-
}
|
191 |
-
|
192 |
private function createRecord($recordData, $position)
|
193 |
{
|
194 |
return FF::getInstance(
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
+
class Recommendation extends PersonalisedResponse
|
7 |
{
|
8 |
/**
|
9 |
* @var FACTFinder\Util\LoggerInterface
|
15 |
*/
|
16 |
private $recommendations;
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
public function __construct(
|
19 |
$loggerClass,
|
20 |
\FACTFinder\Core\ConfigurationInterface $configuration,
|
57 |
}
|
58 |
// Make sure that the recommendations are fetched again. In theory,
|
59 |
// we only have to do this when recordCount increases.
|
60 |
+
$this->upToDate = false;
|
61 |
}
|
62 |
|
63 |
/**
|
70 |
{
|
71 |
$parameters = $this->request->getParameters();
|
72 |
$parameters['id'] = $productIDs;
|
73 |
+
$this->upToDate = false;
|
74 |
}
|
75 |
|
76 |
/**
|
83 |
{
|
84 |
$parameters = $this->request->getParameters();
|
85 |
$parameters->add('id', $productIDs);
|
86 |
+
$this->upToDate = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
}
|
88 |
|
89 |
/**
|
95 |
public function getRecommendations()
|
96 |
{
|
97 |
if (is_null($this->recommendations)
|
98 |
+
|| !$this->upToDate
|
99 |
) {
|
100 |
$this->request->resetLoaded();
|
101 |
$this->recommendations = $this->createRecommendations();
|
102 |
+
$this->upToDate = true;
|
103 |
}
|
104 |
|
105 |
return $this->recommendations;
|
127 |
$position = 1;
|
128 |
foreach($recommenderData as $recordData)
|
129 |
{
|
130 |
+
$records[] = $this->createRecord($recordData, $position++);
|
|
|
|
|
|
|
131 |
}
|
132 |
}
|
133 |
}
|
140 |
);
|
141 |
}
|
142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
private function createRecord($recordData, $position)
|
144 |
{
|
145 |
return FF::getInstance(
|
lib/FACTFinder/Adapter/Search.php
CHANGED
@@ -3,7 +3,7 @@ namespace FACTFinder\Adapter;
|
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
-
class Search extends
|
7 |
{
|
8 |
|
9 |
/**
|
@@ -55,16 +55,6 @@ class Search extends AbstractAdapter
|
|
55 |
* @var FACTFinder\Data\CampaignIterator
|
56 |
*/
|
57 |
private $campaigns;
|
58 |
-
|
59 |
-
/**
|
60 |
-
* @var bool
|
61 |
-
*/
|
62 |
-
private $recordsUpToDate = false;
|
63 |
-
|
64 |
-
/**
|
65 |
-
* @var bool
|
66 |
-
*/
|
67 |
-
private $idsOnly = false;
|
68 |
|
69 |
public function __construct(
|
70 |
$loggerClass,
|
@@ -92,43 +82,16 @@ class Search extends AbstractAdapter
|
|
92 |
{
|
93 |
$this->parameters['query'] = $query;
|
94 |
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Set value for parameter sid for personalization.
|
98 |
-
*
|
99 |
-
* @param string $sid session id
|
100 |
-
*/
|
101 |
-
public function setSid($sid)
|
102 |
-
{
|
103 |
-
$this->parameters['sid'] = $sid;
|
104 |
-
$this->recordsUpToDate = false;
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Set this to true to only retrieve the IDs of products instead
|
109 |
-
* of full Record objects.
|
110 |
-
*
|
111 |
-
* @param $idsOnly bool
|
112 |
-
*/
|
113 |
-
public function setIDsOnly($idsOnly)
|
114 |
-
{
|
115 |
-
if($this->idsOnly && !$idsOnly)
|
116 |
-
$this->recordsUpToDate = false;
|
117 |
-
|
118 |
-
$this->idsOnly = $idsOnly;
|
119 |
-
$parameters = $this->request->getParameters();
|
120 |
-
$parameters['idsOnly'] = $idsOnly ? 'true' : 'false';
|
121 |
-
}
|
122 |
|
123 |
/**
|
124 |
* @return \FACTFinder\Data\Result
|
125 |
*/
|
126 |
public function getResult()
|
127 |
{
|
128 |
-
if (is_null($this->result) || !$this->
|
129 |
$this->request->resetLoaded();
|
130 |
$this->result = $this->createResult();
|
131 |
-
$this->
|
132 |
}
|
133 |
|
134 |
return $this->result;
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
+
class Search extends PersonalisedResponse
|
7 |
{
|
8 |
|
9 |
/**
|
55 |
* @var FACTFinder\Data\CampaignIterator
|
56 |
*/
|
57 |
private $campaigns;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
59 |
public function __construct(
|
60 |
$loggerClass,
|
82 |
{
|
83 |
$this->parameters['query'] = $query;
|
84 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
|
86 |
/**
|
87 |
* @return \FACTFinder\Data\Result
|
88 |
*/
|
89 |
public function getResult()
|
90 |
{
|
91 |
+
if (is_null($this->result) || !$this->upToDate) {
|
92 |
$this->request->resetLoaded();
|
93 |
$this->result = $this->createResult();
|
94 |
+
$this->upToDate = true;
|
95 |
}
|
96 |
|
97 |
return $this->result;
|
lib/FACTFinder/Adapter/SimilarRecords.php
CHANGED
@@ -3,7 +3,7 @@ namespace FACTFinder\Adapter;
|
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
-
class SimilarRecords extends
|
7 |
{
|
8 |
/**
|
9 |
* @var FACTFinder\Util\LoggerInterface
|
@@ -21,18 +21,6 @@ class SimilarRecords extends AbstractAdapter
|
|
21 |
*/
|
22 |
private $similarRecords;
|
23 |
|
24 |
-
/**
|
25 |
-
* @var bool
|
26 |
-
*/
|
27 |
-
private $attributesUpToDate = false;
|
28 |
-
private $recordsUpToDate = false;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* @var bool
|
32 |
-
*/
|
33 |
-
private $idsOnly = false;
|
34 |
-
|
35 |
-
|
36 |
public function __construct(
|
37 |
$loggerClass,
|
38 |
\FACTFinder\Core\ConfigurationInterface $configuration,
|
@@ -74,7 +62,7 @@ class SimilarRecords extends AbstractAdapter
|
|
74 |
}
|
75 |
// Make sure that the records are fetched again. In principle, we only
|
76 |
// have to do this when recordCount increases.
|
77 |
-
$this->
|
78 |
}
|
79 |
|
80 |
/**
|
@@ -86,24 +74,7 @@ class SimilarRecords extends AbstractAdapter
|
|
86 |
{
|
87 |
$parameters = $this->request->getParameters();
|
88 |
$parameters['id'] = $productID;
|
89 |
-
$this->
|
90 |
-
$this->recordsUpToDate = false;
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Set this to true to only retrieve the IDs of similar products instead
|
95 |
-
* of full Record objects.
|
96 |
-
* @param $idsOnly bool
|
97 |
-
*/
|
98 |
-
public function setIDsOnly($idsOnly)
|
99 |
-
{
|
100 |
-
// Reset the similar records, if more detail is wanted than before
|
101 |
-
if($this->idsOnly && !$idsOnly)
|
102 |
-
$this->recordsUpToDate = false;
|
103 |
-
|
104 |
-
$this->idsOnly = $idsOnly;
|
105 |
-
$parameters = $this->request->getParameters();
|
106 |
-
$parameters['idsOnly'] = $idsOnly ? 'true' : 'false';
|
107 |
}
|
108 |
|
109 |
/**
|
@@ -117,10 +88,10 @@ class SimilarRecords extends AbstractAdapter
|
|
117 |
public function getSimilarAttributes()
|
118 |
{
|
119 |
if (is_null($this->similarAttributes)
|
120 |
-
|| !$this->
|
121 |
) {
|
122 |
$this->similarAttributes = $this->createSimilarAttributes();
|
123 |
-
$this->
|
124 |
}
|
125 |
|
126 |
return $this->similarAttributes;
|
@@ -161,11 +132,11 @@ class SimilarRecords extends AbstractAdapter
|
|
161 |
public function getSimilarRecords()
|
162 |
{
|
163 |
if (is_null($this->similarRecords)
|
164 |
-
|| !$this->
|
165 |
) {
|
166 |
$this->request->resetLoaded();
|
167 |
$this->similarRecords = $this->createSimilarRecords();
|
168 |
-
$this->
|
169 |
}
|
170 |
|
171 |
return $this->similarRecords;
|
@@ -189,10 +160,7 @@ class SimilarRecords extends AbstractAdapter
|
|
189 |
{
|
190 |
foreach($jsonData['records'] as $recordData)
|
191 |
{
|
192 |
-
|
193 |
-
$records[] = $this->createSparseRecord($recordData);
|
194 |
-
else
|
195 |
-
$records[] = $this->createRecord($recordData, $position++);
|
196 |
}
|
197 |
}
|
198 |
}
|
@@ -205,14 +173,6 @@ class SimilarRecords extends AbstractAdapter
|
|
205 |
);
|
206 |
}
|
207 |
|
208 |
-
private function createSparseRecord($recordData)
|
209 |
-
{
|
210 |
-
return FF::getInstance(
|
211 |
-
'Data\Record',
|
212 |
-
(string)$recordData['id']
|
213 |
-
);
|
214 |
-
}
|
215 |
-
|
216 |
private function createRecord($recordData, $position)
|
217 |
{
|
218 |
return FF::getInstance(
|
3 |
|
4 |
use FACTFinder\Loader as FF;
|
5 |
|
6 |
+
class SimilarRecords extends ConfigurableResponse
|
7 |
{
|
8 |
/**
|
9 |
* @var FACTFinder\Util\LoggerInterface
|
21 |
*/
|
22 |
private $similarRecords;
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
public function __construct(
|
25 |
$loggerClass,
|
26 |
\FACTFinder\Core\ConfigurationInterface $configuration,
|
62 |
}
|
63 |
// Make sure that the records are fetched again. In principle, we only
|
64 |
// have to do this when recordCount increases.
|
65 |
+
$this->upToDate = false;
|
66 |
}
|
67 |
|
68 |
/**
|
74 |
{
|
75 |
$parameters = $this->request->getParameters();
|
76 |
$parameters['id'] = $productID;
|
77 |
+
$this->upToDate = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}
|
79 |
|
80 |
/**
|
88 |
public function getSimilarAttributes()
|
89 |
{
|
90 |
if (is_null($this->similarAttributes)
|
91 |
+
|| !$this->upToDate
|
92 |
) {
|
93 |
$this->similarAttributes = $this->createSimilarAttributes();
|
94 |
+
$this->upToDate = true;
|
95 |
}
|
96 |
|
97 |
return $this->similarAttributes;
|
132 |
public function getSimilarRecords()
|
133 |
{
|
134 |
if (is_null($this->similarRecords)
|
135 |
+
|| !$this->upToDate
|
136 |
) {
|
137 |
$this->request->resetLoaded();
|
138 |
$this->similarRecords = $this->createSimilarRecords();
|
139 |
+
$this->upToDate = true;
|
140 |
}
|
141 |
|
142 |
return $this->similarRecords;
|
160 |
{
|
161 |
foreach($jsonData['records'] as $recordData)
|
162 |
{
|
163 |
+
$records[] = $this->createRecord($recordData, $position++);
|
|
|
|
|
|
|
164 |
}
|
165 |
}
|
166 |
}
|
173 |
);
|
174 |
}
|
175 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
private function createRecord($recordData, $position)
|
177 |
{
|
178 |
return FF::getInstance(
|
lib/FACTFinder/Adapter/Tracking.php
CHANGED
@@ -88,6 +88,8 @@ class Tracking extends AbstractAdapter
|
|
88 |
* @param int $pageSize size of the page where the product was found (optional - is 12 by default)
|
89 |
* @param int $origPageSize original size of the page before the user could have changed it (optional - is set equals to $page by default)
|
90 |
* @param string $userId id of user (optional if modul personalisation is not used)
|
|
|
|
|
91 |
* @return boolean $success
|
92 |
*/
|
93 |
public function trackClick(
|
@@ -103,10 +105,12 @@ class Tracking extends AbstractAdapter
|
|
103 |
$title = '',
|
104 |
$pageSize = 12,
|
105 |
$origPageSize = -1,
|
106 |
-
$userId = null
|
|
|
|
|
107 |
) {
|
108 |
$this->setupClickTracking($id, $query, $pos, $masterId, $sid, $cookieId, $origPos, $page,
|
109 |
-
$simi, $title, $pageSize, $origPageSize, $userId);
|
110 |
return $this->applyTracking();
|
111 |
}
|
112 |
|
@@ -128,7 +132,9 @@ class Tracking extends AbstractAdapter
|
|
128 |
$title = '',
|
129 |
$pageSize = 12,
|
130 |
$origPageSize = -1,
|
131 |
-
$userId = null
|
|
|
|
|
132 |
) {
|
133 |
if (strlen($sid) == 0) $sid = session_id();
|
134 |
if ($origPos == -1) $origPos = $pos;
|
@@ -150,6 +156,8 @@ class Tracking extends AbstractAdapter
|
|
150 |
if (strlen($userId) > 0) $params['userId'] = $userId;
|
151 |
if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
|
152 |
if (strlen($masterId) > 0) $params['masterId'] = $masterId;
|
|
|
|
|
153 |
|
154 |
$this->parameters->clear();
|
155 |
$this->parameters->setAll($params);
|
@@ -167,6 +175,8 @@ class Tracking extends AbstractAdapter
|
|
167 |
* @param int $count number of items purchased for each product (optional - default 1)
|
168 |
* @param float $price this is the single unit price (optional)
|
169 |
* @param string $userId id of user (optional if modul personalisation is not used)
|
|
|
|
|
170 |
* @return boolean $success
|
171 |
*/
|
172 |
public function trackCart(
|
@@ -178,9 +188,11 @@ class Tracking extends AbstractAdapter
|
|
178 |
$cookieId = null,
|
179 |
$count = 1,
|
180 |
$price = null,
|
181 |
-
$userId = null
|
|
|
|
|
182 |
) {
|
183 |
-
$this->setupCartTracking($id, $masterId, $title, $query, $sid, $cookieId, $count, $price, $userId);
|
184 |
return $this->applyTracking();
|
185 |
}
|
186 |
|
@@ -198,7 +210,9 @@ class Tracking extends AbstractAdapter
|
|
198 |
$cookieId = null,
|
199 |
$count = 1,
|
200 |
$price = null,
|
201 |
-
$userId = null
|
|
|
|
|
202 |
) {
|
203 |
if (strlen($sid) == 0) $sid = session_id();
|
204 |
$params = array(
|
@@ -214,6 +228,8 @@ class Tracking extends AbstractAdapter
|
|
214 |
if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
|
215 |
if (strlen($masterId) > 0) $params['masterId'] = $masterId;
|
216 |
if (strlen($query) > 0) $params['query'] = $query;
|
|
|
|
|
217 |
|
218 |
$this->parameters->clear();
|
219 |
$this->parameters->setAll($params);
|
@@ -231,6 +247,8 @@ class Tracking extends AbstractAdapter
|
|
231 |
* @param int $count number of items purchased for each product (optional - default 1)
|
232 |
* @param float $price this is the single unit price (optional)
|
233 |
* @param string $userId id of user (optional if modul personalisation is not used)
|
|
|
|
|
234 |
* @return boolean $success
|
235 |
*/
|
236 |
public function trackCheckout(
|
@@ -242,9 +260,11 @@ class Tracking extends AbstractAdapter
|
|
242 |
$cookieId = null,
|
243 |
$count = 1,
|
244 |
$price = null,
|
245 |
-
$userId = null
|
|
|
|
|
246 |
) {
|
247 |
-
$this->setupCheckoutTracking($id, $masterId, $title, $query, $sid, $cookieId, $count, $price, $userId);
|
248 |
return $this->applyTracking();
|
249 |
}
|
250 |
|
@@ -262,7 +282,9 @@ class Tracking extends AbstractAdapter
|
|
262 |
$cookieId = null,
|
263 |
$count = 1,
|
264 |
$price = null,
|
265 |
-
$userId = null
|
|
|
|
|
266 |
) {
|
267 |
if (strlen($sid) == 0) $sid = session_id();
|
268 |
$params = array(
|
@@ -279,6 +301,8 @@ class Tracking extends AbstractAdapter
|
|
279 |
if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
|
280 |
if (strlen($query) > 0) $params['query'] = $query;
|
281 |
if (strlen($masterId) > 0) $params['masterId'] = $masterId;
|
|
|
|
|
282 |
|
283 |
$this->parameters->clear();
|
284 |
$this->parameters->setAll($params);
|
88 |
* @param int $pageSize size of the page where the product was found (optional - is 12 by default)
|
89 |
* @param int $origPageSize original size of the page before the user could have changed it (optional - is set equals to $page by default)
|
90 |
* @param string $userId id of user (optional if modul personalisation is not used)
|
91 |
+
* @param string $campaign campaign name (optional)
|
92 |
+
* @param boolean $instoreAds determines whether it's a sponsered product (optional)
|
93 |
* @return boolean $success
|
94 |
*/
|
95 |
public function trackClick(
|
105 |
$title = '',
|
106 |
$pageSize = 12,
|
107 |
$origPageSize = -1,
|
108 |
+
$userId = null,
|
109 |
+
$campaign = null,
|
110 |
+
$instoreAds = false
|
111 |
) {
|
112 |
$this->setupClickTracking($id, $query, $pos, $masterId, $sid, $cookieId, $origPos, $page,
|
113 |
+
$simi, $title, $pageSize, $origPageSize, $userId, $campaign, $instoreAds);
|
114 |
return $this->applyTracking();
|
115 |
}
|
116 |
|
132 |
$title = '',
|
133 |
$pageSize = 12,
|
134 |
$origPageSize = -1,
|
135 |
+
$userId = null,
|
136 |
+
$campaign = null,
|
137 |
+
$instoreAds = false
|
138 |
) {
|
139 |
if (strlen($sid) == 0) $sid = session_id();
|
140 |
if ($origPos == -1) $origPos = $pos;
|
156 |
if (strlen($userId) > 0) $params['userId'] = $userId;
|
157 |
if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
|
158 |
if (strlen($masterId) > 0) $params['masterId'] = $masterId;
|
159 |
+
if (strlen($campaign) > 0) $params['campaign'] = $campaign;
|
160 |
+
if ($instoreAds) $params['instoreAds'] = 'true';
|
161 |
|
162 |
$this->parameters->clear();
|
163 |
$this->parameters->setAll($params);
|
175 |
* @param int $count number of items purchased for each product (optional - default 1)
|
176 |
* @param float $price this is the single unit price (optional)
|
177 |
* @param string $userId id of user (optional if modul personalisation is not used)
|
178 |
+
* @param string $campaign campaign name (optional)
|
179 |
+
* @param boolean $instoreAds determines whether it's a sponsered product (optional)
|
180 |
* @return boolean $success
|
181 |
*/
|
182 |
public function trackCart(
|
188 |
$cookieId = null,
|
189 |
$count = 1,
|
190 |
$price = null,
|
191 |
+
$userId = null,
|
192 |
+
$campaign = null,
|
193 |
+
$instoreAds = false
|
194 |
) {
|
195 |
+
$this->setupCartTracking($id, $masterId, $title, $query, $sid, $cookieId, $count, $price, $userId, $campaign, $instoreAds);
|
196 |
return $this->applyTracking();
|
197 |
}
|
198 |
|
210 |
$cookieId = null,
|
211 |
$count = 1,
|
212 |
$price = null,
|
213 |
+
$userId = null,
|
214 |
+
$campaign = null,
|
215 |
+
$instoreAds = false
|
216 |
) {
|
217 |
if (strlen($sid) == 0) $sid = session_id();
|
218 |
$params = array(
|
228 |
if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
|
229 |
if (strlen($masterId) > 0) $params['masterId'] = $masterId;
|
230 |
if (strlen($query) > 0) $params['query'] = $query;
|
231 |
+
if (strlen($campaign) > 0) $params['campaign'] = $campaign;
|
232 |
+
if ($instoreAds) $params['instoreAds'] = 'true';
|
233 |
|
234 |
$this->parameters->clear();
|
235 |
$this->parameters->setAll($params);
|
247 |
* @param int $count number of items purchased for each product (optional - default 1)
|
248 |
* @param float $price this is the single unit price (optional)
|
249 |
* @param string $userId id of user (optional if modul personalisation is not used)
|
250 |
+
* @param string $campaign campaign name (optional)
|
251 |
+
* @param boolean $instoreAds determines whether it's a sponsered product (optional)
|
252 |
* @return boolean $success
|
253 |
*/
|
254 |
public function trackCheckout(
|
260 |
$cookieId = null,
|
261 |
$count = 1,
|
262 |
$price = null,
|
263 |
+
$userId = null,
|
264 |
+
$campaign = null,
|
265 |
+
$instoreAds = false
|
266 |
) {
|
267 |
+
$this->setupCheckoutTracking($id, $masterId, $title, $query, $sid, $cookieId, $count, $price, $userId, $campaign, $instoreAds);
|
268 |
return $this->applyTracking();
|
269 |
}
|
270 |
|
282 |
$cookieId = null,
|
283 |
$count = 1,
|
284 |
$price = null,
|
285 |
+
$userId = null,
|
286 |
+
$campaign = null,
|
287 |
+
$instoreAds = false
|
288 |
) {
|
289 |
if (strlen($sid) == 0) $sid = session_id();
|
290 |
$params = array(
|
301 |
if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
|
302 |
if (strlen($query) > 0) $params['query'] = $query;
|
303 |
if (strlen($masterId) > 0) $params['masterId'] = $masterId;
|
304 |
+
if (strlen($campaign) > 0) $params['campaign'] = $campaign;
|
305 |
+
if ($instoreAds) $params['instoreAds'] = 'true';
|
306 |
|
307 |
$this->parameters->clear();
|
308 |
$this->parameters->setAll($params);
|
lib/FACTFinder/Core/AbstractConfiguration.php
CHANGED
@@ -190,6 +190,7 @@ abstract class AbstractConfiguration implements ConfigurationInterface
|
|
190 |
'/^substringFilter.*/' => true,
|
191 |
'advisorStatus' => true,
|
192 |
'callback' => true,
|
|
|
193 |
'catalog' => true,
|
194 |
'channel' => true,
|
195 |
'cookieId' => true,
|
@@ -202,6 +203,7 @@ abstract class AbstractConfiguration implements ConfigurationInterface
|
|
202 |
'ids' => true,
|
203 |
'idsOnly' => true,
|
204 |
'ignoreForCache' => true,
|
|
|
205 |
'isArticleNumber' => true,
|
206 |
'log' => true,
|
207 |
'mainId' => true,
|
@@ -222,6 +224,7 @@ abstract class AbstractConfiguration implements ConfigurationInterface
|
|
222 |
'query' => true,
|
223 |
'queryFromSuggest' => true,
|
224 |
'searchField' => true,
|
|
|
225 |
'sid' => true,
|
226 |
'simi' => true,
|
227 |
'title' => true,
|
190 |
'/^substringFilter.*/' => true,
|
191 |
'advisorStatus' => true,
|
192 |
'callback' => true,
|
193 |
+
'campaign' => true,
|
194 |
'catalog' => true,
|
195 |
'channel' => true,
|
196 |
'cookieId' => true,
|
203 |
'ids' => true,
|
204 |
'idsOnly' => true,
|
205 |
'ignoreForCache' => true,
|
206 |
+
'instoreAds' => true,
|
207 |
'isArticleNumber' => true,
|
208 |
'log' => true,
|
209 |
'mainId' => true,
|
224 |
'query' => true,
|
225 |
'queryFromSuggest' => true,
|
226 |
'searchField' => true,
|
227 |
+
'seoPath' => true,
|
228 |
'sid' => true,
|
229 |
'simi' => true,
|
230 |
'title' => true,
|
lib/FACTFinder/Data/SearchParameters.php
CHANGED
@@ -12,7 +12,8 @@ class SearchParameters
|
|
12 |
/**
|
13 |
* @var string
|
14 |
*/
|
15 |
-
private $query;
|
|
|
16 |
private $channel;
|
17 |
private $advisorStatus;
|
18 |
|
@@ -43,6 +44,8 @@ class SearchParameters
|
|
43 |
) {
|
44 |
$this->query = isset($parameters['query']) ? $parameters['query'] : '';
|
45 |
|
|
|
|
|
46 |
// Properly prepared server parameters will always have a channel set
|
47 |
$this->channel = $parameters['channel'];
|
48 |
|
@@ -78,7 +81,13 @@ class SearchParameters
|
|
78 |
}
|
79 |
}
|
80 |
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
|
83 |
/**
|
84 |
* @return string
|
12 |
/**
|
13 |
* @var string
|
14 |
*/
|
15 |
+
private $query;
|
16 |
+
private $seoPath;
|
17 |
private $channel;
|
18 |
private $advisorStatus;
|
19 |
|