├── Api
├── ConfigProviderInterface.php
├── Data
│ ├── Dcc
│ │ ├── CatalogData
│ │ │ ├── CatalogProduct
│ │ │ │ ├── CategoryPathBuilderInterface.php
│ │ │ │ ├── CategoryPathInterface.php
│ │ │ │ ├── FamilyBuilderInterface.php
│ │ │ │ └── FamilyInterface.php
│ │ │ ├── CatalogProductBuilderInterface.php
│ │ │ └── CatalogProductInterface.php
│ │ ├── CatalogDataBuilderInterface.php
│ │ └── CatalogDataInterface.php
│ └── IndexInterface.php
├── DccInterface.php
├── IndexRepositoryInterface.php
└── StringFormatterInterface.php
├── Block
├── Adminhtml
│ └── System
│ │ └── Config
│ │ └── Sftp
│ │ └── TestConnection.php
└── System
│ └── Config
│ └── Button.php
├── Console
└── Command
│ ├── Index.php
│ ├── Product.php
│ ├── Purchase.php
│ └── PurchaseTest.php
├── Controller
├── Adminhtml
│ ├── Bvfeed
│ │ ├── Rebuildproduct.php
│ │ ├── Runproduct.php
│ │ └── Runpurchase.php
│ ├── Bvindex
│ │ └── Index.php
│ └── Config
│ │ └── Sftp
│ │ └── TestConnection.php
├── Index.php
├── Pixel
│ └── Test.php
└── Submission
│ └── Container.php
├── LICENSE.md
├── Logger
├── Handler.php
└── Logger.php
├── Model
├── BVSEOSDK
│ ├── BV.php
│ ├── BVFooter.php
│ ├── BVUtility.php
│ ├── Base.php
│ ├── CHANGELOG.md
│ ├── ExampleQuestionsGetContent.php
│ ├── ExampleReviewsGetAggregateRating.php
│ ├── ExampleReviewsGetContent.php
│ ├── ExampleReviewsGetReviews.php
│ ├── ExampleSEOGetContent.php
│ ├── ExampleSellerratingsGetContent.php
│ ├── ExampleSpotlightsGetContent.php
│ ├── ExampleStoriesGetContent.php
│ ├── LICENSE
│ ├── OWNERS
│ ├── Questions.php
│ ├── README.md
│ ├── Reviews.php
│ ├── SellerRatings.php
│ ├── Spotlights.php
│ ├── Stories.php
│ ├── archive-assembly.xml
│ └── pom.xml
├── Backend
│ └── Remote.php
├── Config
│ └── Version.php
├── ConfigProvider.php
├── Cron.php
├── CurrentProductProvider.php
├── Dcc.php
├── Dcc
│ ├── CatalogData.php
│ ├── CatalogData
│ │ ├── CatalogProduct.php
│ │ ├── CatalogProduct
│ │ │ ├── CategoryPath.php
│ │ │ ├── CategoryPathBuilder.php
│ │ │ ├── Family.php
│ │ │ └── FamilyBuilder.php
│ │ └── CatalogProductBuilder.php
│ └── CatalogDataBuilder.php
├── Feed
│ ├── Feed.php
│ ├── Product
│ │ ├── Brand.php
│ │ ├── Category.php
│ │ └── Product.php
│ ├── ProductFeed.php
│ └── PurchaseFeed.php
├── Filesystem
│ └── Io
│ │ └── Sftp.php
├── Index.php
├── IndexRepository.php
├── Indexer
│ ├── Eav.php
│ ├── Flat.php
│ └── Indexer.php
├── Notification.php
├── ResourceModel
│ ├── Index.php
│ └── Index
│ │ └── Collection.php
├── SeoContent.php
├── Source
│ ├── Category.php
│ ├── Environment.php
│ ├── ProductAttribute.php
│ ├── ProductList.php
│ ├── Scope.php
│ ├── SftpHost.php
│ └── Trigger.php
├── StringFormatter.php
└── XMLWriter.php
├── OWNERS
├── Observer
└── Config.php
├── Plugin
├── Disable.php
└── ProductList
│ ├── Category.php
│ ├── Crosssell.php
│ ├── Item.php
│ ├── NewProductsWidget.php
│ ├── Related.php
│ ├── Search.php
│ ├── Upsell.php
│ └── Widget.php
├── README.md
├── Setup
├── Patch
│ └── Data
│ │ ├── InstallBvAttribute.php
│ │ └── UpgradeBvDataAtttribute.php
└── Uninstall.php
├── Test
└── Unit
│ └── Model
│ └── DccTest.php
├── Ui
├── Component
│ └── Listing
│ │ ├── Column
│ │ ├── Bvproductindex
│ │ │ └── PageActions.php
│ │ ├── Json.php
│ │ └── Thumbnail.php
│ │ └── DataProviders
│ │ └── Bv
│ │ └── Product
│ │ └── Index.php
└── ReviewStaging
│ └── Review.php
├── ViewModel
├── Header.php
├── Pixel.php
├── Product.php
├── Questions.php
└── Reviews.php
├── composer.json
├── etc
├── acl.xml
├── adminhtml
│ ├── di.xml
│ ├── menu.xml
│ ├── routes.xml
│ └── system.xml
├── config.xml
├── crontab.xml
├── csp_whitelist.xml
├── db_schema.xml
├── di.xml
├── events.xml
├── frontend
│ └── routes.xml
├── indexer.xml
├── module.xml
├── mview.xml
└── webapi.xml
├── phpdox.xml
├── phpunit.xml
├── registration.php
└── view
├── adminhtml
├── layout
│ └── adminhtml_bvindex_index.xml
├── requirejs-config.js
├── templates
│ └── system
│ │ └── config
│ │ └── testconnection.phtml
├── ui_component
│ └── bv_product_index.xml
└── web
│ └── js
│ └── testconnection.js
└── frontend
├── layout
├── bazaarvoice_pixel_test.xml
├── bazaarvoice_submission_container.xml
├── catalog_product_view.xml
├── checkout_onepage_success.xml
├── customer_account.xml
└── default.xml
└── templates
├── checkout
└── onepage
│ └── success
│ └── bvpixel.phtml
├── header.phtml
├── productheader.phtml
├── qa
└── questions.phtml
└── rr
├── reviews.phtml
└── summary.phtml
/Api/Data/Dcc/CatalogData/CatalogProduct/CategoryPathBuilderInterface.php:
--------------------------------------------------------------------------------
1 | setTemplate('Bazaarvoice_Connector::system/config/testconnection.phtml');
12 | return $this;
13 | }
14 |
15 | public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
16 | {
17 | $element = clone $element;
18 | $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
19 | return parent::render($element);
20 | }
21 |
22 | protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
23 | {
24 | $originalData = $element->getOriginalData();
25 | $this->addData(
26 | [
27 | 'button_label' => __($originalData['button_label']),
28 | 'html_id' => $element->getHtmlId(),
29 | 'ajax_url' => $this->_urlBuilder->getUrl('adminhtml/config_sftp/testconnection'),
30 | 'field_mapping' => str_replace('"', '\\"', json_encode($this->_getFieldMapping()))
31 | ]
32 | );
33 |
34 | return $this->_toHtml();
35 | }
36 |
37 | protected function _getFieldMapping()
38 | {
39 | return [
40 | 'username' => 'bazaarvoice_feeds_sftp_username',
41 | 'password' => 'bazaarvoice_feeds_sftp_password',
42 | 'host' => 'bazaarvoice_feeds_sftp_host_name'
43 | ];
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/Block/System/Config/Button.php:
--------------------------------------------------------------------------------
1 | getForm()->getLayout()->createBlock(\Magento\Backend\Block\Widget\Button::class);
33 |
34 | $originalData = $element->getOriginalData();
35 |
36 | $buttonLabel = !empty($originalData['button_label']) ? $originalData['button_label'] : __('Run Feed');
37 | $buttonId = !empty($originalData['id']) ? $originalData['id'] : 'bv_export';
38 | $url = !empty($originalData['button_url']) ? $originalData['button_url'] : '*/bvfeed/runpurchase';
39 | $url = $this->getUrl($url);
40 |
41 | $data = [
42 | 'id' => $buttonId,
43 | 'label' => $buttonLabel,
44 | 'onclick' => "window.open('".$url."')",
45 | ];
46 |
47 | $html = $buttonBlock->setData($data)->toHtml();
48 |
49 | return $html;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Console/Command/Index.php:
--------------------------------------------------------------------------------
1 | indexer = $indexer;
39 | }
40 |
41 | protected function configure()
42 | {
43 | $this->setName('bv:index')->setDescription('Clear Bazaarvoice Product Feed Index.');
44 | }
45 |
46 | /**
47 | * @param \Symfony\Component\Console\Input\InputInterface $input
48 | * @param \Symfony\Component\Console\Output\OutputInterface $output
49 | *
50 | * @return int|void|null
51 | */
52 | protected function execute(InputInterface $input, OutputInterface $output)
53 | {
54 | $returnValue = Cli::RETURN_SUCCESS;
55 | try {
56 | $this->indexer->executeFull();
57 | } catch (Exception $e) {
58 | print_r($e->getMessage()."\n".$e->getTraceAsString());
59 | $returnValue = Cli::RETURN_FAILURE;
60 | }
61 | return $returnValue;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Console/Command/Product.php:
--------------------------------------------------------------------------------
1 | _productFeed = $productFeed;
38 | }
39 |
40 | protected function configure()
41 | {
42 | $this->setName('bv:product')->setDescription('Generates Bazaarvoice Product Feed.');
43 | }
44 |
45 | /**
46 | * @param \Symfony\Component\Console\Input\InputInterface $input
47 | * @param \Symfony\Component\Console\Output\OutputInterface $output
48 | *
49 | * @return int|void|null
50 | */
51 | protected function execute(InputInterface $input, OutputInterface $output)
52 | {
53 | print_r("\n".'Memory usage: '.memory_get_usage()."\n");
54 | try {
55 | $this->_productFeed->generateFeed();
56 | } catch (Exception $e) {
57 | print_r($e->getMessage()."\n".$e->getTraceAsString());
58 | }
59 | print_r("\n".'Memory usage: '.memory_get_usage()."\n");
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Console/Command/Purchase.php:
--------------------------------------------------------------------------------
1 | _purchaseFeed = $purchaseFeed;
37 | }
38 |
39 | protected function configure()
40 | {
41 | $this->setName('bv:purchase')->setDescription('Generates Bazaarvoice Purchase Feed.');
42 | }
43 |
44 | /**
45 | * @param \Symfony\Component\Console\Input\InputInterface $input
46 | * @param \Symfony\Component\Console\Output\OutputInterface $output
47 | *
48 | * @return int|void|null
49 | */
50 | protected function execute(InputInterface $input, OutputInterface $output)
51 | {
52 | print_r("\n".'Memory usage: '.memory_get_usage()."\n");
53 | $this->_purchaseFeed->generateFeed();
54 | print_r("\n".'Memory usage: '.memory_get_usage()."\n");
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Console/Command/PurchaseTest.php:
--------------------------------------------------------------------------------
1 | _purchaseFeed = $purchaseFeed;
37 | }
38 |
39 | protected function configure()
40 | {
41 | $this->setName('bv:purchasetest')->setDescription('Generates Bazaarvoice Test Purchase Feed.');
42 | }
43 |
44 | /**
45 | * @param \Symfony\Component\Console\Input\InputInterface $input
46 | * @param \Symfony\Component\Console\Output\OutputInterface $output
47 | *
48 | * @return int|void|null
49 | */
50 | protected function execute(InputInterface $input, OutputInterface $output)
51 | {
52 | print_r("\n".'Memory usage: '.memory_get_usage()."\n");
53 | $this->_purchaseFeed->setTest(true)->generateFeed();
54 | print_r("\n".'Memory usage: '.memory_get_usage()."\n");
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Bvfeed/Rebuildproduct.php:
--------------------------------------------------------------------------------
1 | indexer = $indexer;
33 | }
34 |
35 | /**
36 | * @return void
37 | * @throws \Exception
38 | */
39 | public function execute()
40 | {
41 | try {
42 | $this->indexer->executeFull();
43 | $this->messageManager->addSuccessMessage(__('Product Feed Index is being rebuilt.'));
44 | } catch (Exception $e) {
45 | $this->messageManager->addErrorMessage($e->__toString());
46 | }
47 |
48 | $this->_redirect('adminhtml/bvindex/index');
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Bvfeed/Runproduct.php:
--------------------------------------------------------------------------------
1 | productFeed = $productFeed;
36 | parent::__construct($context);
37 | }
38 |
39 | /**
40 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void
41 | */
42 | public function execute()
43 | {
44 | print_r('
');
45 | $force = (bool) $this->getRequest()->getParam('force', false);
46 | $this->productFeed->setForce($force)->generateFeed();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Bvfeed/Runpurchase.php:
--------------------------------------------------------------------------------
1 | purchaseFeed = $purchaseFeed;
38 | }
39 |
40 | /**
41 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void
42 | */
43 | public function execute()
44 | {
45 | print_r('');
46 | $this->purchaseFeed->setForce(true)->generateFeed();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Bvindex/Index.php:
--------------------------------------------------------------------------------
1 | _scopeConfig = $scopeConfig;
44 | $this->_resultPageFactory = $resultPageFactory;
45 | parent::__construct($context);
46 | }
47 |
48 | /**
49 | * Index action
50 | *
51 | * @return \Magento\Backend\Model\View\Result\Page
52 | */
53 | public function execute()
54 | {
55 | /**
56 | * @var Page $resultPage
57 | */
58 | $resultPage = $this->_resultPageFactory->create();
59 | $resultPage->setActiveMenu('Magento_Catalog::inventory');
60 | $resultPage->getConfig()->getTitle()->prepend(__('Bazaarvoice Product Feed'));
61 |
62 | return $resultPage;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Config/Sftp/TestConnection.php:
--------------------------------------------------------------------------------
1 | sftp = $sftp;
73 | $this->storeManager = $storeManager;
74 |
75 | $this->configProvider = $configProvider;
76 | $this->resultJsonFactory = $resultJsonFactory;
77 | $this->tagFilter = $tagFilter;
78 |
79 | parent::__construct($context);
80 | }
81 |
82 | public function execute()
83 | {
84 | $result = [
85 | 'success' => false,
86 | 'errorMessage' => '',
87 | ];
88 |
89 | $options = $this->getRequest()->getParams();
90 |
91 | try {
92 | if(empty($options['username']) || empty($options['password']) || empty($options['host'])) {
93 | throw new \Magento\Framework\Exception\LocalizedException(
94 | __('Missing SFTP credentials.')
95 | );
96 | }
97 |
98 | $params = [
99 | 'host' => $this->configProvider->getSftpHost($this->storeManager->getStore()->getId(), ScopeInterface::SCOPE_STORE, $options['host']),
100 | 'username' => $options['username'],
101 | 'password' => $this->configProvider->getSftpPassword($this->storeManager->getStore()->getId())
102 | ];
103 |
104 | if($options['password'] != '******') {
105 | $params['password'] = $options['password'];
106 | }
107 |
108 | $this->sftp->open($params);
109 | $this->sftp->close();
110 |
111 | $result['success'] = true;
112 |
113 | }catch (\Magento\Framework\Exception\LocalizedException $e) {
114 | $result['errorMessage'] = $e->getMessage();
115 | } catch (\Exception $e) {
116 | $message = __($e->getMessage());
117 | $result['errorMessage'] = $this->tagFilter->filter($message);
118 | }
119 |
120 |
121 | /**
122 | * @var \Magento\Framework\Controller\Result\Json $resultJson
123 | */
124 | $resultJson = $this->resultJsonFactory->create();
125 | return $resultJson->setData($result);
126 | }
127 |
128 | }
--------------------------------------------------------------------------------
/Controller/Index.php:
--------------------------------------------------------------------------------
1 | _pageFactory = $pageFactory;
36 |
37 | return parent::__construct($context);
38 | }
39 |
40 | /**
41 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Page
42 | */
43 | public function execute()
44 | {
45 | $page = $this->_pageFactory->create();
46 |
47 | return $page;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Controller/Pixel/Test.php:
--------------------------------------------------------------------------------
1 | getRequest()->getParam('order_increment_id');
26 | $orderId = $this->getRequest()->getParam('order_id');
27 | $session = $this->getOnepage()->getCheckout();
28 | $session->setLastRealOrderId($orderIncrementId);
29 | $session->setLastOrderId($orderId);
30 | $session->setLastSuccessQuoteId('dummy_value');
31 | $session->setLastQuoteId('dummy_value');
32 | return parent::execute();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Controller/Submission/Container.php:
--------------------------------------------------------------------------------
1 | _view->loadLayout();
26 | $this->_view->renderLayout();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2019 Bazaarvoice, Inc.
2 |
3 | Bazaarvoice copyright materials may not be reproduced in whole or in part by
4 | persons, organizations or corporations other than Bazaarvoice, Inc., its
5 | affiliates and divisions without the prior written permission of the Legal
6 | Department at Bazaarvoice, Inc.
7 |
--------------------------------------------------------------------------------
/Logger/Handler.php:
--------------------------------------------------------------------------------
1 | filesystem = $filesystem;
52 | parent::__construct($filesystem);
53 | $this->setFormatter(new LineFormatter($this->_format, null, true));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Logger/Logger.php:
--------------------------------------------------------------------------------
1 | admin = $state->getAreaCode() === 'adminhtml';
51 | } catch (Exception $e) {
52 | }
53 | parent::__construct($name, $handlers);
54 | $this->configProvider = $configProvider;
55 | /** @codingStandardsIgnoreEnd */
56 | }
57 |
58 | /**
59 | * @param string|array $message
60 | * @param array $context
61 | *
62 | * @return bool
63 | */
64 | public function debug($message, array $context = []): void
65 | {
66 | if ($this->configProvider->isDebugEnabled()) {
67 | if (is_array($message)) {
68 | $message = json_encode($message);
69 | }
70 | $this->addRecord(static::DEBUG, strval($message),$context);
71 | }
72 | }
73 |
74 | /**
75 | * @param int $level
76 | * @param string $message
77 | * @param array $context
78 | * @return bool
79 | */
80 | public function addRecord(int $level, string $message, array $context = [], DateTimeImmutable $datetime = null): bool
81 | {
82 | if (is_array($message)) {
83 | $message = print_r($message, $return = true);
84 | }
85 |
86 | if (php_sapi_name() == "cli" || $this->admin) {
87 | print_r($message."\n");
88 | }
89 |
90 | return parent::addRecord($level, $message, $context);
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/BVFooter.php:
--------------------------------------------------------------------------------
1 | base = $base;
43 | $this->access_method = $access_method;
44 | $this->msg = $msg;
45 | }
46 |
47 | /**
48 | * buildSDKFooter
49 | *
50 | * Returns hidden SDK footer.
51 | *
52 | * @access public
53 | * @return string Html formatted footer.
54 | */
55 | public function buildSDKFooter()
56 | {
57 | $method_type = !empty($this->base->config['internal_file_path']) ? 'LOCAL' : 'CLOUD';
58 | $access_method = $this->access_method;
59 | $time_end = microtime(true);
60 |
61 | if (!empty($this->base->start_time)) {
62 | $exec_time = round(($time_end - $this->base->start_time) * 1000, 2);
63 | } else {
64 | $exec_time = 0;
65 | }
66 | $content_type = mb_strtoupper($this->base->config['content_type']);
67 | $subject_type = mb_strtoupper($this->base->config['subject_type']);
68 |
69 | $footer = "\n".'
';
77 |
78 | return $footer;
79 | }
80 |
81 | /**
82 | * buildSDKDebugFooter
83 | *
84 | * Returns hidden SDK debug footer.
85 | *
86 | * @access public
87 | * @return string Html formatted debug footer.
88 | */
89 | public function buildSDKDebugFooter()
90 | {
91 | $staging = !empty($this->base->config['staging']) ? 'TRUE' : 'FALSE';
92 | $testing = !empty($this->base->config['testing']) ? 'TRUE' : 'FALSE';
93 | $sdk_enabled = !empty($this->base->config['seo_sdk_enabled']) ? 'TRUE' : 'FALSE';
94 | $ssl_enabled = !empty($this->base->config['ssl_enabled']) ? 'TRUE' : 'FALSE';
95 | $proxy_host = !empty($this->base->config['proxy_host']) ? $this->base->config['proxy_host'] : 'none';
96 | $proxy_port = !empty($this->base->config['proxy_port']) ? $this->base->config['proxy_port'] : '0';
97 | $local_seo_file_root = (!empty($this->base->config['load_seo_files_locally']))
98 | ? $this->base->config['local_seo_file_root'] : 'FALSE';
99 | $content_type = mb_strtoupper($this->base->config['content_type']);
100 | $subject_type = mb_strtoupper($this->base->config['subject_type']);
101 | if (!empty($this->base->config['page_params']['subject_id'])
102 | && !empty($this->base->config['page_params']['content_type'])
103 | && $this->base->config['page_params']['content_type'] == $this->base->config['content_type']) {
104 | $subject_id = $this->base->config['page_params']['subject_id'];
105 | } else {
106 | $subject_id = $this->base->config['subject_id'];
107 | }
108 |
109 | $footer = "\n".'';
110 |
111 | $footer .= "\n".' - '.$staging.'
';
112 | $footer .= "\n".' - '.$testing.'
';
113 | $footer .= "\n".' - '.$sdk_enabled.'
';
114 | if (!isset($this->base->config['subject_type']) || $this->base->config['subject_type'] != 'seller') {
115 | $footer .= "\n".' - '.$this->base->bv_config['seo-domain']['staging']
116 | .'
';
117 | $footer .= "\n".' - '
118 | .$this->base->bv_config['seo-domain']['production'].'
';
119 | $footer .= "\n".' - '
120 | .$this->base->bv_config['seo-domain']['testing_staging'].'
';
121 | $footer .= "\n".' - '
122 | .$this->base->bv_config['seo-domain']['testing_production'].'
';
123 | }
124 | $footer .= "\n".' - '.$proxy_host.'
';
125 | $footer .= "\n".' - '.$proxy_port.'
';
126 | $footer .= "\n".' - '
127 | .$this->base->config['execution_timeout_bot'].'
';
128 | $footer .= "\n".' - '.$this->base->config['execution_timeout']
129 | .'
';
130 | $footer .= "\n".' - '.$local_seo_file_root.'
';
131 | $footer .= "\n".' - '.$this->base->config['cloud_key'].'
';
132 | $footer .= "\n".' - '.$this->base->config['bv_root_folder'].'
';
133 | $footer .= "\n".' - '.$this->base->config['charset'].'
';
134 | $footer .= "\n".' - '.$ssl_enabled.'
';
135 | $footer .= "\n".' - '.$this->base->config['crawler_agent_pattern'].'
';
136 | $footer .= "\n".' - '.urlencode($subject_id).'
';
137 |
138 |
139 | $footer .= "\n".' - '.$sdk_enabled.'
';
140 | $footer .= "\n".' - bvseo-'.$this->base->config['page'].'
';
141 | $footer .= "\n".' - '.$_SERVER['HTTP_USER_AGENT'].'
';
142 | $footer .= "\n".' - '.$this->base->config['page_url'].'
';
143 | $footer .= "\n".' - '.$this->base->config['base_url'].'
';
144 | $footer .= "\n".' - '.$content_type.'
';
145 | $footer .= "\n".' - '.$subject_type.'
';
146 | if (!empty($this->base->seo_url)) {
147 | $footer .= "\n".' - '.$this->base->seo_url.'
';
148 | }
149 |
150 | $footer .= "\n".'
';
151 |
152 | return $footer;
153 | }
154 |
155 | }
156 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 3.2.1
4 | * Removed tick_timer function as timeouts are handled via curl options.
5 | * Switched to CURLOPT_TIMEOUT_MS option for better granularity.
6 |
7 | ## 3.2.0
8 |
9 | * Pass-through of User Agent to gather statistics.
10 |
11 | ## 3.1.0
12 |
13 | * Seller Ratings support.
14 |
15 | ## 3.0.0
16 | * Security updates:
17 | * No longer infer page or base URL.
18 | * Sanitize pagination links.
19 | * Adopt semver versioning.
20 |
21 | ## 2.4.0.0
22 |
23 | * Fix sp_mt metadata value and incorrect variable names.
24 |
25 | ## 2.3.0.1
26 |
27 | * Support gzip htm(html) download.
28 | * bvstate support, with fragment support.
29 | * Support for multi-byte urls.
30 | * Fix getAggregateRating and getReviews when botnet is detected.
31 |
32 | ## 2.2.0.2
33 |
34 | * Spotlights support.
35 | * PHP SDK refactoring and consistent variable naming.
36 | * Stories support.
37 | * Charset support.
38 | * Botnet support with configuration for timeouts for botnet requests and non-botnet requests.
39 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/ExampleQuestionsGetContent.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'subject_id' => '',
12 | 'cloud_key' => '',
13 | 'page_url' => '',
14 | ]
15 | );
16 | ?>
17 |
18 |
19 | BV SDK PHP Example - Questions: GetContent
20 |
21 |
22 | This is a test page for Questions: getContent
23 | This will return questions and answers content
24 |
25 |
26 | questions->getContent()); ?>
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/ExampleReviewsGetAggregateRating.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'subject_id' => '',
12 | 'cloud_key' => '',
13 | 'page_url' => '',
14 | ]
15 | );
16 | ?>
17 |
18 |
19 | BV SDK PHP Example - getAggregateRating
20 |
21 |
22 | This is a test page for Reviews: getAggregateRating()
23 | This will return aggregate rating content
24 |
25 | reviews->getAggregateRating()); ?>
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/ExampleReviewsGetContent.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'subject_id' => '',
12 | 'cloud_key' => '',
13 | 'page_url' => '',
14 | ]
15 | );
16 | ?>
17 |
18 |
19 | BV SDK PHP Example - GetContent
20 |
21 |
22 | This is a test page for Reviews: getContent()
23 | GetContent() will return reviews and aggregate content
24 |
25 |
26 | reviews->getContent()); ?>
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/ExampleReviewsGetReviews.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'subject_id' => '',
12 | 'cloud_key' => '',
13 | 'page_url' => '',
14 | ]
15 | );
16 | ?>
17 |
18 |
19 | BV SDK PHP Example - getReviews
20 |
21 |
22 | This is a test page for Reviews: getReviews()
23 | This will return review content
24 |
25 |
26 | reviews->getReviews()); ?>
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/ExampleSEOGetContent.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'subject_id' => '',
12 | 'cloud_key' => '',
13 | 'content_type' => 'questions',
14 | 'subject_type' => 'category',
15 | 'staging' => true,
16 | ]
17 | );
18 | ?>
19 |
20 |
21 | BV SDK PHP Example - SEO: GetContent
22 |
23 |
24 | This is a test page for SEO getContent
25 | This will return questions and answers content
26 |
27 |
28 | SEO->getContent()); ?>
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/ExampleSellerratingsGetContent.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'cloud_key' => '',
12 | 'page_url' => '',
13 | 'subject_id' => 'seller',
14 | ]
15 | );
16 | ?>
17 |
18 |
19 | BV SDK PHP Example - GetContent
20 |
21 |
22 | This is a test page for SellerRatings: getContent()
23 | GetContent() will return seller ratings content
24 |
25 |
26 | sellerratings->getContent()); ?>
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/ExampleSpotlightsGetContent.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'subject_id' => '',
12 | 'cloud_key' => '',
13 | 'page_url' => '',
14 | ]
15 | );
16 | ?>
17 |
18 |
19 | BV SDK PHP Example - GetContent
20 |
21 |
22 | This is a test page for Spotlights: getContent()
23 | GetContent() will return spotlights content
24 |
25 |
26 | spotlights->getContent()); ?>
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/ExampleStoriesGetContent.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'subject_id' => '',
12 | 'cloud_key' => '',
13 | // either STORIES_LIST or STORIES_GRID
14 | 'content_sub_type' => 'stories_grid',
15 | 'staging' => true,
16 | ]
17 | );
18 | ?>
19 |
20 |
21 | BV SDK PHP Example - GetContent
22 |
23 |
24 | This is a test page for Stories: getContent()
25 | GetContent() will return stories_grid content
26 |
27 |
28 | stories->getContent()); ?>
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/LICENSE:
--------------------------------------------------------------------------------
1 | copyright 2015 Bazaarvoice, Inc.
2 |
3 | Bazaarvoice copyright materials may not be reproduced in whole or in part by
4 | persons, organizations or corporations other than Bazaarvoice, Inc., its
5 | affiliates and divisions without the prior written permission of the Legal
6 | Department at Bazaarvoice, Inc.
7 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/OWNERS:
--------------------------------------------------------------------------------
1 | # Owning team.
2 | seo-sdk-owners@bazaarvoice.com
3 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/Questions.php:
--------------------------------------------------------------------------------
1 | config['content_type'] = 'questions';
29 | }
30 |
31 | public function getContent()
32 | {
33 | $payload = $this->_renderSEO('getContent');
34 | if (!empty($this->config['page_params']['subject_id']) && $this->_checkBVStateContentType()) {
35 | $subject_id = $this->config['page_params']['subject_id'];
36 | } else {
37 | $subject_id = $this->config['subject_id'];
38 | }
39 | // if they want to power display integration as well
40 | // then we need to include the JS integration code
41 | if ($this->config['include_display_integration_code']) {
42 |
43 | $payload .= '
44 |
49 | ';
50 | }
51 |
52 | return $payload;
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/README.md:
--------------------------------------------------------------------------------
1 | # Bazaarvoice SEO SDK for PHP
2 |
3 | This repository contains the codebase for the Bazaarvoice SEO SDK for PHP. Find
4 | out more about Bazaarvoice SEO at [Bazaarvoice Knowledge][1].
5 |
6 | ## Documentation and Packaged Releases
7 |
8 | The latest SDK documentation and links to releases are available at
9 | [Bazaarvoice Knowledge][1].
10 |
11 | [1]: http://knowledge.bazaarvoice.com/bvseo/
12 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/Reviews.php:
--------------------------------------------------------------------------------
1 | config['content_type'] = 'reviews';
29 |
30 | // for reviews subject type will always
31 | // need to be product
32 | $this->config['subject_type'] = 'product';
33 | }
34 |
35 | public function getAggregateRating()
36 | {
37 | return $this->_renderAggregateRating();
38 | }
39 |
40 | public function getReviews()
41 | {
42 | return $this->_renderReviews();
43 | }
44 |
45 | public function getContent()
46 | {
47 | $payload = $this->_renderSEO('getContent');
48 |
49 | if (!empty($this->config['page_params']['subject_id']) && $this->_checkBVStateContentType()) {
50 | $subject_id = $this->config['page_params']['subject_id'];
51 | } else {
52 | $subject_id = $this->config['subject_id'];
53 | }
54 | // if they want to power display integration as well
55 | // then we need to include the JS integration code
56 | if ($this->config['include_display_integration_code']) {
57 | $payload .= '
58 |
63 | ';
64 | }
65 |
66 | return $payload;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/SellerRatings.php:
--------------------------------------------------------------------------------
1 | config['content_type'] = 'reviews';
25 |
26 | // for seller rating subject type will always
27 | // need to be seller
28 | $this->config['subject_type'] = 'seller';
29 |
30 | }
31 |
32 | public function getContent()
33 | {
34 | return $this->_renderSEO('getContent');
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/Spotlights.php:
--------------------------------------------------------------------------------
1 | config['content_type'] = 'spotlights';
24 |
25 | // for spotlights subject type will always
26 | // need to be category
27 | $this->config['subject_type'] = 'category';
28 | }
29 |
30 | public function getContent()
31 | {
32 | return $this->_renderSEO('getContent');
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/Stories.php:
--------------------------------------------------------------------------------
1 | config['content_type'] = 'stories';
29 |
30 | // for stories subject type will always
31 | // need to be product
32 | $this->config['subject_type'] = 'product';
33 |
34 | // for stories we have to set content sub type
35 | // the sub type is configured as either STORIES_LIST or STORIES_GRID
36 | // the folder names are "stories" and "storiesgrid" respectively.
37 | if (isset($this->config['content_sub_type'])
38 | && $this->config['content_sub_type'] == "stories_grid") {
39 | $this->config['content_sub_type'] = "storiesgrid";
40 | } else {
41 | $this->config['content_sub_type'] = "stories";
42 | }
43 | }
44 |
45 | public function getContent()
46 | {
47 | $payload = $this->_renderSEO('getContent');
48 | if (!empty($this->config['page_params']['subject_id']) && $this->_checkBVStateContentType()) {
49 | $subject_id = $this->config['page_params']['subject_id'];
50 | } else {
51 | $subject_id = $this->config['subject_id'];
52 | }
53 | // if they want to power display integration as well
54 | // then we need to include the JS integration code
55 | if ($this->config['include_display_integration_code']) {
56 | $payload .= '
57 |
62 | ';
63 | }
64 |
65 | return $payload;
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/archive-assembly.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | assembly
8 |
9 | zip
10 |
11 |
15 | false
16 |
17 |
18 | \
19 |
22 |
23 | target/
24 | .gitignore
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Model/BVSEOSDK/pom.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | 4.0.0
8 | com.bazaarvoice
9 | bv-seo-sdk-php
10 | 3.2.1
11 | bv-seo-sdk-php
12 | Bazaarvoice SEO SDK for PHP.
13 |
14 |
19 | ${scm.connection.url}
20 |
21 |
22 |
23 |
24 |
25 |
26 | org.apache.maven.scm
27 | maven-scm-provider-gitexe
28 | 1.9.2
29 |
30 |
31 |
32 |
33 |
36 |
37 | org.apache.maven.plugins
38 | maven-deploy-plugin
39 | 2.7
40 |
41 | true
42 |
43 |
44 |
49 |
50 | maven-assembly-plugin
51 | 2.5.4
52 |
53 |
54 | archive-assembly.xml
55 |
56 |
57 |
58 |
62 |
63 | com.bazaarvoice.maven.plugins
64 | s3-upload-maven-plugin
65 | 1.4
66 |
67 |
68 | deploy
69 |
70 | s3-upload
71 |
72 |
73 | ${destination.bucket}
74 |
75 | ${artifact.source}/${project.name}-${project.version}-assembly.zip
76 |
77 |
78 | ${s3.repo.path}/php_v${project.version}.zip
79 |
80 | false
81 |
82 |
83 |
84 |
85 |
89 |
90 | org.apache.maven.plugins
91 | maven-scm-plugin
92 | 1.9.2
93 |
94 | connection
95 | Release_v${project.version}
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Model/Backend/Remote.php:
--------------------------------------------------------------------------------
1 | getPath() == 'bazaarvoice/feeds/product_filename') {
27 | $value = 'productfeed.xml';
28 | } elseif ($this->getPath() == 'bazaarvoice/feeds/product_path') {
29 | $value = '/import-inbox';
30 | }
31 | }
32 |
33 | return parent::setValue($value);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Model/Config/Version.php:
--------------------------------------------------------------------------------
1 | componentRegistrar = $componentRegistrar;
48 | $this->readFactory = $readFactory;
49 | parent::__construct(
50 | $context,
51 | $registry,
52 | $config,
53 | $cacheTypeList,
54 | $resource,
55 | $resourceCollection,
56 | $data
57 | );
58 | }
59 |
60 | /**
61 | * Get current module version from composer.json
62 | *
63 | * @return string
64 | * @throws \Magento\Framework\Exception\FileSystemException
65 | */
66 | public function getModuleVersion()
67 | {
68 | /**
69 | * @var string $composerJsonData
70 | */
71 |
72 | /**
73 | * @var string[] $data
74 | */
75 |
76 | /**
77 | * @var ReadInterface $directoryRead
78 | */
79 |
80 | /**
81 | * @var null|string $path
82 | */
83 |
84 | /**
85 | * @var string $version
86 | */
87 |
88 | $path = $this->componentRegistrar->getPath(
89 | \Magento\Framework\Component\ComponentRegistrar::MODULE,
90 | 'Bazaarvoice_Connector'
91 | );
92 | $directoryRead = $this->readFactory->create($path);
93 | $composerJsonData = $directoryRead->readFile('composer.json');
94 | $data = json_decode($composerJsonData);
95 | if (!empty($data->version)) {
96 | $version = $data->version;
97 | }
98 |
99 | return $version ?? __('Could not retrieve extension version.');
100 | }
101 |
102 | /**
103 | * @return void
104 | * @throws \Magento\Framework\Exception\FileSystemException
105 | */
106 | public function afterLoad()
107 | {
108 | $version = $this->getModuleVersion();
109 | $this->setValue($version);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/Model/Cron.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
57 | $this->configProvider = $configProvider;
58 | $this->purchaseFeed = $purchaseFeed;
59 | $this->productFeed = $productFeed;
60 | }
61 |
62 | public function sendPurchaseFeed()
63 | {
64 | $this->logger->info('Begin Purchase Feed Cron');
65 | $this->purchaseFeed->generateFeed();
66 |
67 | $this->logger->info('End Purchase Feed Cron');
68 | }
69 |
70 | public function sendProductFeed()
71 | {
72 | $this->logger->info('Begin Product Feed Cron');
73 | $this->productFeed->generateFeed();
74 | $this->logger->info('End Product Feed Cron');
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Model/CurrentProductProvider.php:
--------------------------------------------------------------------------------
1 | registry = $registry;
51 | $this->productRepository = $productRepository;
52 | $this->bvLogger = $bvLogger;
53 | }
54 |
55 | /**
56 | * Get current product. Currently uses the registry, which has been deprecated since Magento 2.3.
57 | * Will be modified when Magento implements the replacement.
58 | *
59 | * @return bool|\Magento\Catalog\Model\Product|\Magento\Catalog\Api\Data\ProductInterface
60 | */
61 | public function getProduct()
62 | {
63 | if (empty($this->currentProduct)) {
64 | try {
65 | $product = $this->registry->registry('product');
66 | if ($product === null) {
67 | throw new NoSuchEntityException();
68 | }
69 | $this->currentProduct = $this->productRepository->getById($product->getId());
70 | } catch (Exception $e) {
71 | $this->bvLogger->critical($e->getMessage()."\n".$e->getTraceAsString());
72 |
73 | return false;
74 | }
75 | }
76 |
77 | return $this->currentProduct;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Model/Dcc.php:
--------------------------------------------------------------------------------
1 | stringFormatter = $stringFormatter;
64 | $this->logger = $logger;
65 | $this->productRepository = $productRepository;
66 | $this->currentProductProvider = $currentProductProvider;
67 | $this->catalogDataBuilder = $catalogDataBuilder;
68 | parent::__construct($data);
69 | }
70 |
71 | /**
72 | * @param int|null $productId
73 | * @param int|null $storeId
74 | *
75 | * @return string
76 | */
77 | public function getJson($productId = null, $storeId = null)
78 | {
79 | $product = $this->getProduct($productId, $storeId);
80 | if ($product) {
81 | $this->build($product);
82 | return $this->stringFormatter->jsonEncode($this->getData());
83 | }
84 |
85 | return '';
86 | }
87 |
88 | /**
89 | * @param \Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product $product
90 | *
91 | * @return $this
92 | */
93 | private function build($product)
94 | {
95 | $dccCatalogData = $this->catalogDataBuilder->build($product);
96 | $this->setCatalogData($dccCatalogData->getData());
97 |
98 | return $this;
99 | }
100 |
101 | /**
102 | * @param int|null $productId
103 | * @param int|null $storeId
104 | *
105 | * @return bool|\Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product
106 | */
107 | private function getProduct($productId = null, $storeId = null)
108 | {
109 | try {
110 | if ($productId && $storeId) {
111 | return $this->productRepository->getById($productId, $editMode = false, $storeId);
112 | }
113 |
114 | return $this->currentProductProvider->getProduct();
115 | } catch (NoSuchEntityException $e) {
116 | $this->logger->critical(
117 | "Product does not exist. ID: $productId and store: $storeId. "
118 | ."Error: {$e->getTraceAsString()}"
119 | );
120 | }
121 |
122 | return false;
123 | }
124 |
125 | /**
126 | * @return \Bazaarvoice\Connector\Api\Data\Dcc\CatalogDataInterface
127 | */
128 | private function getCatalogData()
129 | {
130 | return $this->getData('catalogData');
131 | }
132 |
133 | /**
134 | * @param \Bazaarvoice\Connector\Api\Data\Dcc\CatalogDataInterface $catalogData
135 | *
136 | * @return \Bazaarvoice\Connector\Model\Dcc
137 | */
138 | private function setCatalogData($catalogData)
139 | {
140 | return $this->setData('catalogData', $catalogData);
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/Model/Dcc/CatalogData.php:
--------------------------------------------------------------------------------
1 | getData('catalogProducts');
27 | }
28 |
29 | /**
30 | * @param array $catalogProducts
31 | *
32 | * @return \Bazaarvoice\Connector\Api\Data\Dcc\CatalogDataInterface|\Bazaarvoice\Connector\Model\Dcc\CatalogData
33 | */
34 | public function setCatalogProducts(array $catalogProducts)
35 | {
36 | return $this->setData('catalogProducts', $catalogProducts);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Model/Dcc/CatalogData/CatalogProduct.php:
--------------------------------------------------------------------------------
1 | getData('productId');
34 | }
35 |
36 | /**
37 | * @param string $productId
38 | *
39 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
40 | */
41 | public function setProductId(string $productId = null): CatalogProduct
42 | {
43 | return $this->setData('productId', $productId);
44 | }
45 |
46 | /**
47 | * @return string|null
48 | */
49 | public function getProductName()
50 | {
51 | return $this->getData('productName');
52 | }
53 |
54 | /**
55 | * @param string $productName
56 | *
57 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
58 | */
59 | public function setProductName(string $productName = null): CatalogProduct
60 | {
61 | return $this->setData('productName', $productName);
62 | }
63 |
64 | /**
65 | * @return string|null
66 | */
67 | public function getProductDescription()
68 | {
69 | return $this->getData('productDescription');
70 | }
71 |
72 | /**
73 | * @param string $productDescription
74 | *
75 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
76 | */
77 | public function setProductDescription(string $productDescription = null): CatalogProduct
78 | {
79 | return $this->setData('productDescription', $productDescription);
80 | }
81 |
82 | /**
83 | * @return string|null
84 | */
85 | public function getProductImageURL()
86 | {
87 | return $this->getData('productImageURL');
88 | }
89 |
90 | /**
91 | * @param string $productImageURL
92 | *
93 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
94 | */
95 | public function setProductImageURL(string $productImageURL = null): CatalogProduct
96 | {
97 | return $this->setData('productImageURL', $productImageURL);
98 | }
99 |
100 | /**
101 | * @return string|null
102 | */
103 | public function getProductPageURL()
104 | {
105 | return $this->getData('productPageURL');
106 | }
107 |
108 | /**
109 | * @param string $productPageUrl
110 | *
111 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
112 | */
113 | public function setProductPageURL(string $productPageUrl = null): CatalogProduct
114 | {
115 | return $this->setData('productPageURL', $productPageUrl);
116 | }
117 |
118 | /**
119 | * @return string|null
120 | */
121 | public function getBrandId()
122 | {
123 | return $this->getData('brandId');
124 | }
125 |
126 | /**
127 | * @param string $brandId
128 | *
129 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
130 | */
131 | public function setBrandId($brandId): CatalogProduct
132 | {
133 | return $this->setData('brandId', $brandId);
134 | }
135 |
136 | /**
137 | * @return string|null
138 | */
139 | public function getBrandName()
140 | {
141 | return $this->getData('brandName');
142 | }
143 |
144 | /**
145 | * @param string $brandName
146 | *
147 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
148 | */
149 | public function setBrandName($brandName): CatalogProduct
150 | {
151 | return $this->setData('brandName', $brandName);
152 | }
153 |
154 | /**
155 | * @return array|null
156 | */
157 | public function getCategoryPath()
158 | {
159 | return $this->getData('categoryPath');
160 | }
161 |
162 | /**
163 | * @param array $categoryPath
164 | *
165 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
166 | */
167 | public function setCategoryPath(array $categoryPath = null): CatalogProduct
168 | {
169 | return $this->setData('categoryPath', $categoryPath);
170 | }
171 |
172 | /**
173 | * @return array|null
174 | */
175 | public function getManufacturerPartNumbers()
176 | {
177 | return $this->getData('manufacturerPartNumbers');
178 | }
179 |
180 | /**
181 | * @param array $categoryPath
182 | *
183 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
184 | */
185 | public function setManufacturerPartNumbers(array $categoryPath = null): CatalogProduct
186 | {
187 | return $this->setData('manufacturerPartNumbers', $categoryPath);
188 | }
189 |
190 | /**
191 | * @return array|null
192 | */
193 | public function getModelNumbers()
194 | {
195 | return $this->getData('modelNumbers');
196 | }
197 |
198 | /**
199 | * @param array $categoryPath
200 | *
201 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
202 | */
203 | public function setModelNumbers(array $categoryPath = null): CatalogProduct
204 | {
205 | return $this->setData('modelNumbers', $categoryPath);
206 | }
207 |
208 | /**
209 | * @return bool|null
210 | */
211 | public function getInactive()
212 | {
213 | return $this->getData('inactive');
214 | }
215 |
216 | /**
217 | * @param bool $inactive
218 | *
219 | * @return \Bazaarvoice\Connector\Model\Dcc\CatalogData\CatalogProduct
220 | */
221 | public function setInactive(bool $inactive): CatalogProduct
222 | {
223 | return $this->setData('inactive', $inactive);
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/Model/Dcc/CatalogData/CatalogProduct/CategoryPath.php:
--------------------------------------------------------------------------------
1 | stringFormatter = $stringFormatter;
55 | $this->escaper = $escaper;
56 | $this->dccCategoryPathFactory = $dccCategoryPathFactory;
57 | $this->configProvider = $configProvider;
58 | }
59 |
60 | /**
61 | * @param \Magento\Catalog\Api\Data\CategoryInterface|\Magento\Catalog\Model\Category $category
62 | *
63 | * @return \Bazaarvoice\Connector\Api\Data\Dcc\CatalogData\CatalogProduct\CategoryPathInterface
64 | */
65 | public function build($category)
66 | {
67 | $dccCategoryPath = $this->dccCategoryPathFactory->create();
68 | $dccCategoryPath->setId($this->getCategoryId($category));
69 | $dccCategoryPath->setName($this->getCategoryName($category));
70 | return $dccCategoryPath;
71 | }
72 |
73 | /**
74 | * @param \Magento\Catalog\Api\Data\CategoryInterface|\Magento\Catalog\Model\Category $category
75 | *
76 | * @return string
77 | */
78 | private function getCategoryId($category): string
79 | {
80 | $prefix = $this->configProvider->getCategoryPrefix($category->getStoreId());
81 | return $prefix . $this->stringFormatter->getFormattedCategoryPath($category);
82 | }
83 |
84 | /**
85 | * @param \Magento\Catalog\Api\Data\CategoryInterface|\Magento\Catalog\Model\Category $category
86 | *
87 | * @return string
88 | */
89 | private function getCategoryName($category): string
90 | {
91 | $prefix = $this->configProvider->getCategoryPrefix($category->getStoreId());
92 | return $prefix . $this->escaper->escapeHtml($category->getName());
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Model/Dcc/CatalogData/CatalogProduct/Family.php:
--------------------------------------------------------------------------------
1 | stringFormatter = $stringFormatter;
47 | $this->configProvider = $configProvider;
48 | $this->dccFamilyFactory = $dccFamilyFactory;
49 | }
50 |
51 | /**
52 | * @param null|\Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product $product
53 | * @param string $familyCode
54 | *
55 | * @return \Bazaarvoice\Connector\Api\Data\Dcc\CatalogData\CatalogProduct\FamilyInterface
56 | */
57 | public function build($product, $familyCode)
58 | {
59 | $dccFamily = $this->dccFamilyFactory->create();
60 | $dccFamily->setId($familyCode);
61 | $dccFamily->setExpand($this->configProvider->isFamiliesExpandEnabled($product->getStoreId()));
62 | $dccFamily->setMembers([$this->getFamilyMember($product)]);
63 |
64 | return $dccFamily;
65 | }
66 |
67 | /**
68 | * @param \Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product $product
69 | *
70 | * @return string
71 | */
72 | private function getFamilyMember($product): string
73 | {
74 | $prefix = '';
75 | if ($this->configProvider->isProductPrefixEnabled($product->getStoreId())) {
76 | $prefix = $this->configProvider->getPrefix($product->getStoreId());
77 | }
78 | return $prefix . $this->stringFormatter->getFormattedProductSku($product->getSku());
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Model/Dcc/CatalogDataBuilder.php:
--------------------------------------------------------------------------------
1 | configProvider = $configProvider;
60 | $this->stringFormatter = $stringFormatter;
61 | $this->catalogProductBuilder = $catalogProductBuilder;
62 | $this->catalogDataFactory = $catalogDataFactory;
63 | }
64 |
65 | /**
66 | * @param \Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product $product
67 | *
68 | * @return \Bazaarvoice\Connector\Api\Data\Dcc\CatalogDataInterface
69 | */
70 | public function build($product)
71 | {
72 | $dccCatalogData = $this->catalogDataFactory->create();
73 | $dccCatalogData->setLocale($this->configProvider->getLocale($product->getStoreId()));
74 | $dccCatalogData->setCatalogProducts($this->getCatalogProducts($product));
75 | return $dccCatalogData;
76 | }
77 |
78 | /**
79 | * @param \Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product $parentProduct
80 | *
81 | * @return array|null
82 | */
83 | private function getCatalogProducts($parentProduct)
84 | {
85 | $parentData = $this->getCatalogProduct($parentProduct);
86 | $productData = [$parentData];
87 | if ($parentProduct->getTypeId() == Configurable::TYPE_CODE
88 | && $this->configProvider->isFamiliesEnabled($parentProduct->getStoreId())
89 | ) {
90 | $children = $parentProduct->getTypeInstance()->getUsedProducts($parentProduct);
91 | foreach ($children as $childProduct) {
92 | $childData = $this->getCatalogProduct($childProduct, $parentProduct);
93 | $productData[] = $childData;
94 | }
95 | }
96 |
97 | return $productData;
98 | }
99 |
100 | /**
101 | * @param \Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product $product
102 | * @param null|\Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product $parentProduct
103 | *
104 | * @return array
105 | */
106 | private function getCatalogProduct($product, $parentProduct = null)
107 | {
108 | $dccCatalogProduct = $this->catalogProductBuilder->build($product, $parentProduct);
109 |
110 | return $this->prepareOutput($dccCatalogProduct);
111 | }
112 |
113 | /**
114 | * @param $object
115 | *
116 | * @return array
117 | */
118 | private function prepareOutput($object)
119 | {
120 | /**
121 | * @var \Magento\Framework\Model\AbstractModel $object
122 | */
123 | return $this->stringFormatter->stripEmptyValues($object->getData());
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/Model/Filesystem/Io/Sftp.php:
--------------------------------------------------------------------------------
1 | _connection->put($filename, $source, $mode);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Model/Indexer/Indexer.php:
--------------------------------------------------------------------------------
1 | eavIndexer = $eavIndexer;
48 | $this->flatIndexer = $flatIndexer;
49 | $this->scopeConfig = $scopeConfig;
50 | }
51 |
52 | /**
53 | * @throws \Exception
54 | */
55 | public function executeFull()
56 | {
57 | if ($this->useFlatIndexer()) {
58 | $this->flatIndexer->executeFull();
59 | } else {
60 | $this->eavIndexer->executeFull();
61 | }
62 | }
63 |
64 | /**
65 | * @param array $ids
66 | *
67 | * @throws \Exception
68 | */
69 | public function execute($ids = [])
70 | {
71 | if ($this->useFlatIndexer()) {
72 | $this->flatIndexer->execute($ids);
73 | } else {
74 | $this->eavIndexer->execute($ids);
75 | }
76 | }
77 |
78 | /**
79 | * @param array|\int[] $ids
80 | *
81 | * @return mixed
82 | */
83 | public function executeList(array $ids)
84 | {
85 | return true;
86 | }
87 |
88 | /**
89 | * @param int $id
90 | *
91 | * @return mixed
92 | */
93 | public function executeRow($id)
94 | {
95 | return true;
96 | }
97 |
98 | /**
99 | * @return bool
100 | */
101 | protected function useFlatIndexer(): bool
102 | {
103 | return $this->scopeConfig->getValue('catalog/frontend/flat_catalog_product')
104 | && $this->scopeConfig->getValue('catalog/frontend/flat_catalog_category');
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/Model/Notification.php:
--------------------------------------------------------------------------------
1 | _scheduleFactory = $scheduleFactory;
34 | }
35 |
36 | /**
37 | * @return mixed
38 | */
39 | public function getIdentity()
40 | {
41 | return hash('sha256', 'bazaarvoice_cron');
42 | }
43 |
44 | /**
45 | * @return mixed
46 | */
47 | public function isDisplayed()
48 | {
49 | /**
50 | * TODO: Cron schedule does not keep long enough records
51 | * for this to be reliable. Find another way to track it.
52 | */
53 | return false;
54 | }
55 |
56 | /**
57 | * @return mixed
58 | */
59 | public function getText()
60 | {
61 | return __(
62 | 'Bazaarvoice PIE Feed doesn\'t appear to be running, please make sure your Magento cron job is running.',
63 | 'http://devdocs.magento.com/guides/v2.0/config-guide/cli/config-cli-subcommands-cron.html#config-cli-cron-bkg'
64 | );
65 | }
66 |
67 | /**
68 | * @return mixed
69 | */
70 | public function getSeverity()
71 | {
72 | return MessageInterface::SEVERITY_MAJOR;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Model/ResourceModel/Index.php:
--------------------------------------------------------------------------------
1 | _init('bazaarvoice_index_product', 'entity_id');
23 | }
24 |
25 | /**
26 | * @param array $attributes
27 | *
28 | * @return array
29 | * @throws \Magento\Framework\Exception\LocalizedException
30 | */
31 | public function loadBy($attributes)
32 | {
33 | $adapter = $this->_resources->getConnection('core_read');
34 | $where = [];
35 | foreach ($attributes as $attributeCode => $value) {
36 | $where[] = sprintf('%s=:%s', $attributeCode, $attributeCode);
37 | }
38 |
39 | $select = $adapter->select()
40 | ->from($this->getMainTable())
41 | ->where(implode(' AND ', $where));
42 |
43 | $binds = $attributes;
44 |
45 | return $adapter->fetchRow($select, $binds);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Model/ResourceModel/Index/Collection.php:
--------------------------------------------------------------------------------
1 | addFieldToFilter('store_id', $store->getId());
28 |
29 | return $this;
30 | }
31 |
32 | protected function _construct()
33 | {
34 | $this->_init(IndexModel::class, IndexResourceModel::class);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Model/Source/Category.php:
--------------------------------------------------------------------------------
1 | categoryCollection = $categoryCollection;
40 | }
41 |
42 | /**
43 | * @param int|string $value
44 | *
45 | * @return bool|string
46 | */
47 | public function getOptionText($value)
48 | {
49 | return $value;
50 | }
51 |
52 | /**
53 | * @return array
54 | */
55 | public function toOptionArray()
56 | {
57 | return array_merge([['value' => '', 'label' => __('-- Please Select --')]], $this->getCategories());
58 | }
59 |
60 | /**
61 | * @return array
62 | */
63 | public function getAllOptions()
64 | {
65 | return $this->toOptionArray();
66 | }
67 |
68 | /**
69 | * @return array
70 | */
71 | public function getFlatColumns()
72 | {
73 | return [
74 | ProductFeed::CATEGORY_EXTERNAL_ID => [
75 | 'unsigned' => false,
76 | 'default' => null,
77 | 'extra' => null,
78 | 'type' => Table::TYPE_INTEGER,
79 | 'nullable' => true,
80 | 'comment' => 'Bazaarvoice Category ID',
81 | ],
82 | ];
83 | }
84 |
85 | /**
86 | * @return array
87 | * @throws \Magento\Framework\Exception\LocalizedException
88 | */
89 | private function getCategories()
90 | {
91 | if (!$this->categories) {
92 | $this->categories = [];
93 | $this->categoryCollection->addAttributeToSelect('name');
94 | $this->categoryCollection->addAttributeToFilter('level', ['gt' => 1]);
95 | /**
96 | * @var \Magento\Catalog\Model\Category $category
97 | */
98 | foreach ($this->categoryCollection as $category) {
99 | $names = [];
100 | foreach ($category->getParentCategories() as $parent) {
101 | $names[$parent->getId()] = $parent->getName();
102 | }
103 | $names[$category->getId()] = $category->getName();
104 | $name = implode('/', $names);
105 | $this->categories[] = [
106 | 'value' => $category->getId(),
107 | 'label' => $name,
108 | ];
109 | }
110 | }
111 |
112 | return $this->categories;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/Model/Source/Environment.php:
--------------------------------------------------------------------------------
1 | self::STAGING,
29 | 'label' => __('Staging'),
30 | ],
31 | [
32 | 'value' => self::PRODUCTION,
33 | 'label' => __('Production'),
34 | ],
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Model/Source/ProductAttribute.php:
--------------------------------------------------------------------------------
1 | productAttributeCollectionFactory = $attributeCollectionFactory;
34 | }
35 |
36 | /**
37 | * @param bool $isMultiselect
38 | *
39 | * @return array
40 | */
41 | public function toOptionArray($isMultiselect = false)
42 | {
43 | $attributeOptions = [];
44 | if (!$isMultiselect) {
45 | $attributeOptions[] = [
46 | 'label' => __('-- Please Select --'),
47 | 'value' => ''
48 | ];
49 | }
50 |
51 | /**
52 | * @var AttributeCollection $attributes
53 | */
54 | $attributes = $this->productAttributeCollectionFactory->create();
55 | $attributes->addFieldToFilter('used_in_product_listing', '1');
56 |
57 | /**
58 | * @var Attribute $attribute
59 | */
60 | foreach ($attributes as $attribute) {
61 | $attributeOptions[] = [
62 | 'label' => $attribute->getFrontendLabel(),
63 | 'value' => $attribute->getAttributeCode(),
64 | ];
65 | }
66 |
67 | return $attributeOptions;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Model/Source/ProductList.php:
--------------------------------------------------------------------------------
1 | '',
38 | 'label' => __('None'),
39 | ],
40 | [
41 | 'value' => self::CATEGORY,
42 | 'label' => __('Category and Search Result Pages'),
43 | ],
44 | [
45 | 'value' => self::UPSELL,
46 | 'label' => __('Up-Sell Products on Product Pages'),
47 | ],
48 | [
49 | 'value' => self::RELATED,
50 | 'label' => __('Related Products on Product Pages'),
51 | ],
52 | [
53 | 'value' => self::CROSSSELL,
54 | 'label' => __('Cross-Sell Products on Cart Page'),
55 | ],
56 | [
57 | 'value' => self::CATALOG_PRODUCTS_LIST_WIDGET,
58 | 'label' => __('Product List Widget'),
59 | ],
60 | [
61 | 'value' => self::CATALOG_NEW_PRODUCTS_LIST_WIDGET,
62 | 'label' => __('Product New List Widget'),
63 | ],
64 | ];
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Model/Source/Scope.php:
--------------------------------------------------------------------------------
1 | self::SCOPE_GLOBAL,
31 | 'label' => __('Global'),
32 | ],
33 | [
34 | 'value' => self::WEBSITE,
35 | 'label' => __('Magento Website'),
36 | ],
37 | [
38 | 'value' => self::STORE_GROUP,
39 | 'label' => __('Magento Store / Store Group'),
40 | ],
41 | [
42 | 'value' => self::STORE_VIEW,
43 | 'label' => __('Magento Store View'),
44 | ],
45 | ];
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Model/Source/SftpHost.php:
--------------------------------------------------------------------------------
1 | self::BASE,
29 | 'label' => __('Non-European Clients (C1-C6)'),
30 | ],
31 | [
32 | 'value' => self::EUROPE,
33 | 'label' => __('European Clients (C7)'),
34 | ],
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Model/Source/Trigger.php:
--------------------------------------------------------------------------------
1 | self::SHIPPING,
29 | 'label' => __('Shipping'),
30 | ],
31 | [
32 | 'value' => self::PURCHASE,
33 | 'label' => __('Purchase'),
34 | ],
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Model/StringFormatter.php:
--------------------------------------------------------------------------------
1 | configProvider = $configProvider;
34 | }
35 |
36 | /**
37 | * This unique ID can only contain alphanumeric characters (letters and numbers
38 | * only) and also the asterisk, hyphen, and underscore characters. If your
39 | * product IDs contain invalid characters, simply replace them with an alternate
40 | * character like an underscore. This will only be used in the feed and not for
41 | * any customer facing purpose.
42 | *
43 | * @param string $rawId
44 | *
45 | * @return mixed
46 | */
47 | public function replaceIllegalCharacters($rawId)
48 | {
49 | /**
50 | * Customizations go here
51 | */
52 | $rawProductId = preg_replace_callback(
53 | '/\./s', function ($match) {
54 | return "_bv".ord($match[0])."_";
55 | }, $rawId
56 | );
57 | /**
58 | * No further customizations after this
59 | */
60 |
61 | /**
62 | * We need to use a reversible replacement so that we can reconstruct the original ID later.
63 | * Example rawId = qwerty$%@#asdf
64 | * Example encoded = qwerty_bv36__bv37__bv64__bv35_asdf
65 | */
66 | return preg_replace_callback(
67 | '/[^\w\d\*\-_]/s', function ($match) {
68 | return "_bv".ord($match[0])."_";
69 | }, $rawProductId
70 | );
71 | }
72 |
73 | /**
74 | * Get the uniquely identifying category ID for a catalog category.
75 | *
76 | * This is the unique, category or subcategory ID (duplicates are unacceptable).
77 | * This ID should be stable: it should not change for the same logical category even
78 | * if the category's name changes.
79 | *
80 | * @param \Magento\Catalog\Api\Data\CategoryInterface|\Magento\Catalog\Model\Category $category
81 | * @param int $storeId
82 | *
83 | * @return string The unique category ID to be used with Bazaarvoice
84 | */
85 | public function getFormattedCategoryId($category, $storeId = null)
86 | {
87 | if ($this->configProvider->isCategoryIdUseUrlPathEnabled($storeId)) {
88 | $rawCategoryId = $category->getUrlPath();
89 | $rawCategoryId = str_replace('/', '-', $rawCategoryId);
90 | $rawCategoryId = str_replace('.html', '', $rawCategoryId);
91 | return $this->replaceIllegalCharacters($rawCategoryId);
92 | } else {
93 | return $this->configProvider->getCategoryPrefix($storeId) . $category->getId();
94 | }
95 | }
96 |
97 | /**
98 | * @param \Magento\Catalog\Api\Data\CategoryInterface|\Magento\Catalog\Model\Category $category
99 | *
100 | * @return mixed
101 | */
102 | public function getFormattedCategoryPath($category)
103 | {
104 | return str_replace('/', '-', $category->getPath());
105 | }
106 |
107 | /**
108 | * Get the uniquely identifying product ID for a catalog product.
109 | *
110 | * This is the unique, product family-level id (duplicates are unacceptable).
111 | * If a product has its own page, this is its product ID. It is not necessarily
112 | * the SKU ID, as we do not collect separate Ratings & Reviews for different
113 | * styles of product - i.e. the 'Blue' vs. 'Red Widget'.
114 | *
115 | * @param mixed $product a reference to a catalog product object
116 | *
117 | * @return string The unique product ID to be used with Bazaarvoice
118 | */
119 | public function getFormattedProductSku($product)
120 | {
121 | if (is_object($product)) {
122 | $rawProductId = $product->getSku();
123 | } else {
124 | $rawProductId = $product;
125 | }
126 |
127 | return $this->replaceIllegalCharacters($rawProductId);
128 | }
129 |
130 | /**
131 | * @param mixed $value
132 | *
133 | * @return string
134 | */
135 | public function jsonEncode($value)
136 | {
137 | return json_encode($value, $options = JSON_UNESCAPED_UNICODE);
138 | }
139 |
140 | /**
141 | * json decode, sends original data if error
142 | *
143 | * @param $value
144 | *
145 | * @return mixed
146 | */
147 | public function jsonDecode($value)
148 | {
149 | $result = json_decode($value, $assoc = true);
150 | if (json_last_error() != JSON_ERROR_NONE) {
151 | return $value;
152 | }
153 |
154 | return $result;
155 | }
156 |
157 | /**
158 | * @param string $delimeter
159 | * @param string $string
160 | *
161 | * @return array
162 | */
163 | public function explodeAndTrim($delimeter, $string)
164 | {
165 | $data = explode($delimeter, $string);
166 | foreach ($data as $k => $v) {
167 | $data[$k] = trim($v);
168 | }
169 |
170 | return $data;
171 | }
172 |
173 | /**
174 | * @param array $data
175 | *
176 | * @return array
177 | */
178 | public function stripEmptyValues($data)
179 | {
180 | return array_filter(
181 | $data, function ($a) {
182 | return !empty($a) || $a === false; //send false values
183 | }
184 | );
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/Model/XMLWriter.php:
--------------------------------------------------------------------------------
1 | startElement($name);
30 | $this->writeCdata($content);
31 | $this->endElement();
32 | return true;
33 | } else {
34 | parent::writeElement($name, $content);
35 | return true;
36 | }
37 | }
38 |
39 | /**
40 | * @param null $content
41 | * @param bool $cdata
42 | *
43 | * @return bool|void
44 | */
45 | public function writeRaw($content = null, $cdata = false): bool
46 | {
47 | $content = trim((string)$content);
48 | if ($cdata) {
49 | $this->writeCdata($content);
50 | return true;
51 | } else {
52 | parent::writeRaw($content);
53 | return true;
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/OWNERS:
--------------------------------------------------------------------------------
1 | partner-admin@bazaarvoice.com
--------------------------------------------------------------------------------
/Observer/Config.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
48 | $this->indexer = $indexer;
49 | $this->messageManger = $messageManager;
50 | }
51 |
52 | /**
53 | * @param EventObserver $observer
54 | */
55 | public function execute(EventObserver $observer)
56 | {
57 | $this->messageManger->addNoticeMessage(__('Some configuration changes may require rebuilding the Bazaarvoice Product Feed Index. This can be done by running the bv:index magento command or clicking Rebuild Index in Catalog > Bazaarvoice Product Feed'));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Plugin/Disable.php:
--------------------------------------------------------------------------------
1 | configProvider = $configProvider;
34 | }
35 |
36 | /**
37 | * Prevents default Magento review functionality from displaying
38 | *
39 | * @param $subject
40 | * @param $result
41 | *
42 | * @return false|string
43 | */
44 | public function afterToHtml($subject, $result)
45 | {
46 | if ($this->configProvider->isBvEnabled()) {
47 | return '';
48 | }
49 |
50 | return $result;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Plugin/ProductList/Category.php:
--------------------------------------------------------------------------------
1 | configProvider = $configProvider;
47 | $this->stringFormatter = $stringFormatter;
48 | }
49 |
50 | /**
51 | * @param $subject
52 | * @param $product
53 | */
54 | public function beforeGetProductPrice(
55 | /** @noinspection PhpUnusedParameterInspection */
56 | // @codingStandardsIgnoreLine Squiz.Functions.MultiLineFunctionDeclaration.FirstParamSpacing
57 | $subject,
58 | $product
59 | ) {
60 | //todo: Combine with afterGetProductPrice into an around plugin?
61 | if ($this->isHostedInlineRatingsEnabled()) {
62 | $this->product = $product;
63 | }
64 | }
65 |
66 | /**
67 | * @return bool
68 | */
69 | public function isHostedInlineRatingsEnabled()
70 | {
71 | if (!$this->configProvider->isRrEnabled()) {
72 | return false;
73 | }
74 |
75 | $inlineRatings = $this->configProvider->getInlineRatings();
76 |
77 | if (!$inlineRatings) {
78 | return false;
79 | }
80 |
81 | $typesEnabled = explode(',', $inlineRatings);
82 |
83 | return in_array($this->type, $typesEnabled);
84 | }
85 |
86 | /**
87 | * @param $subject
88 | * @param $result
89 | *
90 | * @return string
91 | */
92 | public function afterGetProductPrice(
93 | /** @noinspection PhpUnusedParameterInspection */
94 | // @codingStandardsIgnoreLine Squiz.Functions.MultiLineFunctionDeclaration.FirstParamSpacing
95 | $subject,
96 | $result
97 | ) {
98 | //todo: Combine with afterGetProductPrice into an around plugin?
99 | if ($this->isHostedInlineRatingsEnabled()) {
100 | $productIdentifier = $this->stringFormatter->getFormattedProductSku($this->product);
101 | $productUrl = $this->product->getProductUrl();
102 | $result = '
103 |
104 | '.$result;
108 | }
109 |
110 | return $result;
111 | }
112 |
113 | /**
114 | * @return string
115 | */
116 | protected function getExtensionInjectionMessage()
117 | {
118 | return $this->configProvider->getExtensionInjectionMessage();
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/Plugin/ProductList/NewProductsWidget.php:
--------------------------------------------------------------------------------
1 | isHostedInlineRatingsEnabled()) {
36 | $this->product = $product;
37 | }
38 | }
39 |
40 | /**
41 | * @param $subject
42 | * @param $result
43 | *
44 | * @return string
45 | */
46 | public function afterGetProductPriceHtml(
47 | /** @noinspection PhpUnusedParameterInspection */
48 | // @codingStandardsIgnoreLine Squiz.Functions.MultiLineFunctionDeclaration.FirstParamSpacing
49 | $subject,
50 | $result
51 | ) {
52 | if ($this->isHostedInlineRatingsEnabled()) {
53 | $productIdentifier = $this->stringFormatter->getFormattedProductSku($this->product);
54 | $productUrl = $this->product->getProductUrl();
55 | $result = '
56 |
57 | '.$result;
61 | }
62 |
63 | return $result;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Plugin/ProductList/Related.php:
--------------------------------------------------------------------------------
1 | isHostedInlineRatingsEnabled()) {
36 | $this->product = $product;
37 | }
38 | }
39 |
40 | /**
41 | * @param $subject
42 | * @param $result
43 | *
44 | * @return string
45 | */
46 | public function afterGetProductPriceHtml(
47 | /** @noinspection PhpUnusedParameterInspection */
48 | // @codingStandardsIgnoreLine Squiz.Functions.MultiLineFunctionDeclaration.FirstParamSpacing
49 | $subject,
50 | $result
51 | ) {
52 | if ($this->isHostedInlineRatingsEnabled()) {
53 | $productIdentifier = $this->stringFormatter->getFormattedProductSku($this->product);
54 | $productUrl = $this->product->getProductUrl();
55 | $result = '
56 |
57 | '.$result;
61 | }
62 |
63 | return $result;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Bazaarvoice Magento 2 Integration Extension
2 | =============================================
3 |
4 | [](https://packagist.org/packages/bazaarvoice/bazaarvoice-magento2-ext)
5 | [](https://packagist.org/packages/bazaarvoice/bazaarvoice-magento2-ext)
6 | [](https://packagist.org/packages/bazaarvoice/bazaarvoice-magento2-ext)
7 | [](https://packagist.org/packages/bazaarvoice/bazaarvoice-magento2-ext)
8 |
9 | This is the official Magento 2 extension for Bazaarvoice.
10 |
11 | ## Getting Started
12 |
13 | Please visit our Bazaarvoice Knowledge website and start with our step-by-step integration guide for Magento 2: https://knowledge.bazaarvoice.com/wp-content/partnerintegrations/en_US/ecommerce.html#magento-2
14 |
15 | ## Installation via Composer
16 |
17 | You can install our Bazaarvoice Magento 2 extension via [Composer](http://getcomposer.org/). Please run these commands at the root of your Magento install:
18 | ```bash
19 | composer require bazaarvoice/bazaarvoice-magento2-ext
20 | php bin/magento module:enable Bazaarvoice_Connector
21 | php bin/magento setup:upgrade
22 | ```
23 |
24 | ## Compatibility
25 | This extension is compatible with the newer Bazaarvoice Conversations offering. There is currently no extension available for the Magento 2 platform that is compatible with the older legacy Bazaarvoice Conversations PRR offering.
26 |
27 | Please go to https://knowledge.bazaarvoice.com/wp-content/partnerintegrations/en_US/ecommerce.html#magento-1x if you are looking for the Bazaarvoice Magento extension compatible with the older Magento 1 platform.
28 |
--------------------------------------------------------------------------------
/Setup/Patch/Data/InstallBvAttribute.php:
--------------------------------------------------------------------------------
1 | salesSetupFactory = $salesSetupFactory;
51 | $this->moduleDataSetup = $moduleDataSetup;
52 | $this->eavSetupFactory = $eavSetupFactory;
53 | $this->categorySetupFactory = $categorySetupFactory;
54 | }
55 |
56 | /**
57 | * {@inheritdoc}
58 | */
59 | public function apply()
60 | {
61 | $this->moduleDataSetup->getConnection()->startSetup();
62 | /** @var SalesSetup $eavSetup */
63 | $eavSetup = $this->salesSetupFactory->create(['setup' => $this->moduleDataSetup]);
64 |
65 | $eavSetup->addAttribute(
66 | Order::ENTITY,
67 | Connector\Model\Feed\PurchaseFeed::ALREADY_SENT_IN_FEED_FLAG,
68 | [
69 | 'type' => Table::TYPE_INTEGER,
70 | 'visible' => false,
71 | 'required' => false,
72 | 'default' => 0,
73 | ]
74 | );
75 |
76 | /** @var CategorySetup $eavSetup */
77 | $eavSetup = $this->categorySetupFactory->create(['setup' => $this->moduleDataSetup]);
78 |
79 | $eavSetup->addAttribute(
80 | Product::ENTITY,
81 | Connector\Model\Feed\ProductFeed::INCLUDE_IN_FEED_FLAG,
82 | [
83 | 'group' => 'Product Details',
84 | 'type' => 'int',
85 | 'frontend' => '',
86 | 'label' => 'Send in Bazaarvoice Product Feed',
87 | 'input' => 'boolean',
88 | 'class' => '',
89 | 'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean',
90 | 'global' => ScopedAttributeInterface::SCOPE_STORE,
91 | 'visible' => true,
92 | 'required' => false,
93 | 'user_defined' => false,
94 | 'default' => Boolean::VALUE_YES,
95 | 'apply_to' => '',
96 | 'visible_on_front' => false,
97 | 'is_used_in_grid' => true,
98 | 'is_visible_in_grid' => false,
99 | 'is_filterable_in_grid' => false,
100 | 'used_in_product_listing' => true
101 | ]
102 | );
103 |
104 | $groupName = 'Autosettings';
105 | $entityTypeId = $eavSetup->getEntityTypeId(Product::ENTITY);
106 | $attributeSetId = $eavSetup->getAttributeSetId($entityTypeId, 'Default');
107 |
108 | $attribute = $eavSetup->getAttribute($entityTypeId, Connector\Model\Feed\ProductFeed::INCLUDE_IN_FEED_FLAG);
109 | if ($attribute && $attributeSetId) {
110 | $eavSetup->addAttributeToGroup(
111 | $entityTypeId,
112 | $attributeSetId,
113 | $groupName,
114 | $attribute['attribute_id'],
115 | 60
116 | );
117 | }
118 |
119 | if ($attributeSetId && !$eavSetup->getAttributesNumberInGroup($entityTypeId, $attributeSetId, 'Product Details')) {
120 | $eavSetup->removeAttributeGroup($entityTypeId, $attributeSetId, 'Product Details');
121 | }
122 | $this->moduleDataSetup->getConnection()->endSetup();
123 | }
124 |
125 | /**
126 | * {@inheritdoc}
127 | */
128 | public static function getDependencies()
129 | {
130 | return [];
131 | }
132 |
133 | /**
134 | * {@inheritdoc}
135 | */
136 | public function getAliases()
137 | {
138 | return [];
139 | }
140 |
141 | /**
142 | * {@inheritdoc}
143 | */
144 | public static function getVersion()
145 | {
146 | return '9.0.0';
147 | }
148 | }
--------------------------------------------------------------------------------
/Setup/Uninstall.php:
--------------------------------------------------------------------------------
1 | categorySetupFactory = $categorySetupFactory;
43 | $this->salesSetupFactory = $salesSetupFactory;
44 | }
45 |
46 | /**
47 | * Module uninstall code
48 | *
49 | * @param \Magento\Framework\Setup\SchemaSetupInterface $setup
50 | * @param \Magento\Framework\Setup\ModuleContextInterface $context
51 | *
52 | * @return void
53 | */
54 | public function uninstall(
55 | SchemaSetupInterface $setup,
56 | ModuleContextInterface $context
57 | ) {
58 | $setup->startSetup();
59 |
60 | $salesSetup = $this->salesSetupFactory->create();
61 | $salesSetup->removeAttribute(
62 | Order::ENTITY,
63 | Connector\Model\Feed\PurchaseFeed::ALREADY_SENT_IN_FEED_FLAG
64 | );
65 |
66 | $catalogSetup = $this->categorySetupFactory->create();
67 | $entityTypeId = $catalogSetup->getEntityTypeId(Product::ENTITY);
68 |
69 | if ($catalogSetup->getAttribute($entityTypeId, 'bv_feed_exclude')) {
70 | $catalogSetup->removeAttribute($entityTypeId, 'bv_feed_exclude');
71 | }
72 |
73 | if ($catalogSetup->getAttribute($entityTypeId, ProductFeed::INCLUDE_IN_FEED_FLAG)) {
74 | $catalogSetup->removeAttribute($entityTypeId, ProductFeed::INCLUDE_IN_FEED_FLAG);
75 | }
76 |
77 | if ($catalogSetup->getAttribute($entityTypeId, ProductFeed::CATEGORY_EXTERNAL_ID)) {
78 | $catalogSetup->removeAttribute($entityTypeId, ProductFeed::CATEGORY_EXTERNAL_ID);
79 | }
80 |
81 | $setup->endSetup();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Test/Unit/Model/DccTest.php:
--------------------------------------------------------------------------------
1 | objectManager->getConstructArguments($className);
36 | $dcc = $this->objectManager->getObject($className, $arguments);
37 | $result = $dcc->getJson();
38 |
39 | $this->assertEmpty($result);
40 | }
41 |
42 | public function testBuildProductExistsSomeResult()
43 | {
44 | /**
45 | * @var \Bazaarvoice\Connector\Model\Dcc $dcc
46 | */
47 |
48 | $currentProductProviderMock = $this->createPartialMock(CurrentProductProvider::class, ['getProduct']);
49 | $productMock = $this->getMockBuilder(ProductInterface::class)
50 | ->disableOriginalConstructor()
51 | ->getMockForAbstractClass();
52 | $currentProductProviderMock->method('getProduct')->willReturn($productMock);
53 |
54 | $dccCatalogDataMock = $this->createPartialMock(CatalogData::class, ['getData']);
55 | $dccCatalogDataMock->method('getData')->willReturn('{}');
56 |
57 | $dccCatalogDataBuilderMock = $this->createPartialMock(CatalogDataBuilder::class, ['build']);
58 | $dccCatalogDataBuilderMock->method('build')->willReturn($dccCatalogDataMock);
59 |
60 | $stringFormatterMock = $this->createPartialMock(StringFormatter::class, ['jsonEncode']);
61 | $stringFormatterMock->method('jsonEncode')->willReturn('{}');
62 |
63 | $arguments = $this->objectManager->getConstructArguments(Dcc::class);
64 | $arguments['currentProductProvider'] = $currentProductProviderMock;
65 | $arguments['catalogDataBuilder'] = $dccCatalogDataBuilderMock;
66 | $arguments['stringFormatter'] = $stringFormatterMock;
67 | $dcc = $this->objectManager->getObject(Dcc::class, $arguments);
68 | $result = $dcc->getJson();
69 |
70 | $this->assertNotEmpty($result);
71 | }
72 |
73 | protected function setUp()
74 | {
75 | $this->objectManager = new ObjectManager($this);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Ui/Component/Listing/Column/Bvproductindex/PageActions.php:
--------------------------------------------------------------------------------
1 | getData('name');
28 | $id = 'X';
29 | if (isset($item['entity_id'])) {
30 | $id = $item['entity_id'];
31 | }
32 | $item[$name]['view'] = [
33 | 'href' => $this->getContext()->getUrl(
34 | 'adminhtml/bv_product_index/viewlog',
35 | ['id' => $id]
36 | ),
37 | 'label' => __('Edit'),
38 | ];
39 | }
40 | }
41 |
42 | return $dataSource;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Ui/Component/Listing/Column/Json.php:
--------------------------------------------------------------------------------
1 | stringFormatter = $stringFormatter;
43 | parent::__construct($context, $uiComponentFactory, $components, $data);
44 | }
45 |
46 | /**
47 | * Prepare Data Source
48 | *
49 | * @param array $dataSource
50 | *
51 | * @return array
52 | */
53 | public function prepareDataSource(array $dataSource)
54 | {
55 | if (isset($dataSource['data']['items'])) {
56 | $fieldName = $this->getData('name');
57 | foreach ($dataSource['data']['items'] as & $item) {
58 | if (empty($item[$fieldName])) {
59 | continue;
60 | }
61 | $valueData = $this->stringFormatter->jsonDecode($item[$fieldName]);
62 | if (is_object($valueData) == true
63 | || is_array($valueData) == true
64 | ) {
65 | $html = '';
66 | foreach ($valueData as $key => $value) {
67 | if (!is_numeric($key)) {
68 | $html .= "$key: ";
69 | }
70 | $html .= $this->truncate($value).'
';
71 | }
72 | $item[$fieldName] = $html;
73 | }
74 | }
75 | }
76 |
77 | return $dataSource;
78 | }
79 |
80 | /**
81 | * @param $string
82 | *
83 | * @return string
84 | */
85 | private function truncate($string)
86 | {
87 | if (strlen($string) > 45 && substr($string, 0, 4) != 'http') {
88 | $string = substr($string, 0, 45).'...';
89 | }
90 |
91 | return $string;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Ui/Component/Listing/Column/Thumbnail.php:
--------------------------------------------------------------------------------
1 | getData('name');
29 | foreach ($dataSource['data']['items'] as & $item) {
30 | $value = $item[$fieldName];
31 | if ($value) {
32 | $item[$fieldName.'_src'] = $value;
33 | $item[$fieldName.'_alt'] = $fieldName;
34 | $item[$fieldName.'_link'] = $value;
35 | $item[$fieldName.'_orig_src'] = $value;
36 | }
37 | }
38 | }
39 |
40 | return $dataSource;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Ui/Component/Listing/DataProviders/Bv/Product/Index.php:
--------------------------------------------------------------------------------
1 | collection = $collectionFactory->create();
38 | parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Ui/ReviewStaging/Review.php:
--------------------------------------------------------------------------------
1 | bvLogger = $bvLogger;
49 | $this->stringFormatter = $stringFormatter;
50 | $this->configProvider = $configProvider;
51 | }
52 |
53 | /**
54 | * @return ConfigProviderInterface
55 | */
56 | public function getConfigProvider()
57 | {
58 | return $this->configProvider;
59 | }
60 |
61 | /**
62 | * @return mixed
63 | */
64 | public function isBvEnabled()
65 | {
66 | return $this->configProvider->isBvEnabled();
67 | }
68 |
69 | /**
70 | * @return mixed|string|null
71 | */
72 | public function getExtensionInjectionMessage()
73 | {
74 | return $this->configProvider->getExtensionInjectionMessage();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/ViewModel/Questions.php:
--------------------------------------------------------------------------------
1 | bvLogger = $bvLogger;
63 | $this->configProvider = $configProvider;
64 | $this->stringFormatter = $stringFormatter;
65 | $this->seoContent = $seoContent;
66 | $this->currentProductProvider = $currentProductProvider;
67 | }
68 |
69 | /**
70 | * @return string
71 | */
72 | public function getSeoContent()
73 | {
74 | return $this->seoContent->getQuestionAnswerSeoContent();
75 | }
76 |
77 | /**
78 | * @return string
79 | */
80 | public function getProductSku()
81 | {
82 | $currentProduct = $this->currentProductProvider->getProduct();
83 | if ($currentProduct) {
84 | return $this->stringFormatter->getFormattedProductSku($currentProduct->getSku());
85 | }
86 |
87 | return null;
88 | }
89 |
90 | /**
91 | * @return bool
92 | */
93 | public function canShow()
94 | {
95 | return $this->configProvider->isQaEnabled();
96 | }
97 |
98 | /**
99 | * @return string
100 | */
101 | public function getExtensionInjectionMessage()
102 | {
103 | return $this->configProvider->getExtensionInjectionMessage();
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/ViewModel/Reviews.php:
--------------------------------------------------------------------------------
1 | bvLogger = $bvLogger;
63 | $this->configProvider = $configProvider;
64 | $this->stringFormatter = $stringFormatter;
65 | $this->seoContent = $seoContent;
66 | $this->currentProductProvider = $currentProductProvider;
67 | }
68 |
69 | /**
70 | * @return string
71 | */
72 | public function getAggregateSEOContent()
73 | {
74 | return $this->seoContent->getAggregateSeoContent();
75 | }
76 |
77 | /**
78 | * @return bool
79 | */
80 | public function canShow()
81 | {
82 | return $this->configProvider->isRrEnabled();
83 | }
84 |
85 | /**
86 | * @return false|string
87 | */
88 | public function getSeoContent()
89 | {
90 | return $this->seoContent->getRatingsReviewsSeoContent();
91 | }
92 |
93 | /**
94 | * @return string
95 | */
96 | public function getProductSku()
97 | {
98 | $currentProduct = $this->currentProductProvider->getProduct();
99 | if ($currentProduct) {
100 | return $this->stringFormatter->getFormattedProductSku($currentProduct->getSku());
101 | }
102 |
103 | return null;
104 | }
105 |
106 | /**
107 | * @return string
108 | */
109 | public function getExtensionInjectionMessage()
110 | {
111 | return $this->configProvider->getExtensionInjectionMessage();
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bazaarvoice/bazaarvoice-magento2-ext",
3 | "description": "Bazaarvoice Magento 2 Integration Extension.",
4 | "type": "magento2-module",
5 | "license": [
6 | "MIT"
7 | ],
8 | "version": "9.1.8",
9 | "autoload": {
10 | "files": [
11 | "registration.php"
12 | ],
13 | "psr-4": {
14 | "Bazaarvoice\\Connector\\": ""
15 | }
16 | },
17 | "require": {
18 | "php": "~7.0||~8.1.0||~8.2.0||~8.3.0" ,"magento/framework": "~100.1|~101.0|~102.0|~103.0|~104.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/etc/acl.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/etc/adminhtml/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | - Bazaarvoice\Connector\Model\Notification
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/etc/adminhtml/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/etc/adminhtml/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 | main_site
12 | 1
13 | 0
14 |
15 |
16 | 1
17 | category,search
18 | 1
19 |
20 |
21 | 1
22 |
23 |
24 | 1
25 | purchase
26 | 30
27 | website
28 | productfeed.xml
29 | /import-inbox
30 | 1
31 | 1
32 | 0
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/etc/crontab.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 | 30 2 * * 6
11 |
12 |
13 | 0 1 * * *
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/etc/csp_whitelist.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
10 |
11 |
12 | apps.bazaarvoice.com
13 | apps.nexus.bazaarvoice.com
14 | apps-stg.nexus.bazaarvoice.com
15 | analytics-static.ugc.bazaarvoice.com
16 | network.bazaarvoice.com
17 | network-stg.bazaarvoice.com
18 | display.ugc.bazaarvoice.com
19 | api.bazaarvoice.com
20 | stg.api.bazaarvoice.com
21 | mpsnare.iesnare.com
22 |
23 |
24 |
25 |
26 | api.bazaarvoice.com
27 | stg.api.bazaarvoice.com
28 | apps.bazaarvoice.com
29 | network.bazaarvoice.com
30 | network-stg.bazaarvoice.com
31 |
32 |
33 |
34 |
35 | display.ugc.bazaarvoice.com
36 | network.bazaarvoice.com
37 | network-stg.bazaarvoice.com
38 | network-a.bazaarvoice.com
39 | network-stg-a.bazaarvoice.com
40 | photos-uat-us.bazaarvoice.com
41 | img.youtube.com
42 |
43 |
44 |
45 |
46 | display.ugc.bazaarvoice.com
47 |
48 |
49 |
50 |
51 | display.ugc.bazaarvoice.com
52 | api.bazaarvoice.com
53 | stg.api.bazaarvoice.com
54 |
55 |
56 |
57 |
58 | api.bazaarvoice.com
59 | stg.api.bazaarvoice.com
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/etc/db_schema.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/etc/events.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/etc/frontend/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/etc/indexer.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 | Bazaarvoice Product Feed Index
10 | Indexed data for Bazaarvoice Product Feed
11 |
12 |
13 |
--------------------------------------------------------------------------------
/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/etc/mview.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/etc/webapi.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/phpdox.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 | tests
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | .
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/registration.php:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/view/adminhtml/requirejs-config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright © Magento, Inc. All rights reserved.
3 | * See COPYING.txt for license details.
4 | */
5 |
6 | var config = {
7 | map: {
8 | '*': {
9 | sftpTestConnection: 'Bazaarvoice_Connector/js/testconnection'
10 | }
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/view/adminhtml/templates/system/config/testconnection.phtml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
--------------------------------------------------------------------------------
/view/adminhtml/web/js/testconnection.js:
--------------------------------------------------------------------------------
1 |
2 | define(
3 | [
4 | 'jquery',
5 | 'Magento_Ui/js/modal/alert',
6 | 'jquery/ui'
7 | ], function ($, alert) {
8 | 'use strict';
9 |
10 | $.widget(
11 | 'mage.testConnection', {
12 | options: {
13 | url: '',
14 | elementId: '',
15 | successText: '',
16 | failedText: '',
17 | fieldMapping: ''
18 | },
19 |
20 | /**
21 | * Bind handlers to events
22 | */
23 | _create: function () {
24 | this._on(
25 | {
26 | 'click': $.proxy(this._connect, this)
27 | }
28 | );
29 | },
30 |
31 | /**
32 | * Method triggers an AJAX request to check SFTP connection
33 | *
34 | * @private
35 | */
36 | _connect: function () {
37 | var result = this.options.failedText,
38 | element = $('#' + this.options.elementId),
39 | self = this,
40 | params = {},
41 | msg = '',
42 | fieldToCheck = this.options.fieldToCheck || 'success';
43 |
44 | element.removeClass('success').addClass('fail');
45 | console.log($.parseJSON(this.options.fieldMapping));
46 | $.each(
47 | $.parseJSON(this.options.fieldMapping), function (key, el) {
48 | params[key] = $('#' + el).val();
49 | }
50 | );
51 | console.log(params);
52 | $.ajax(
53 | {
54 | url: this.options.url,
55 | showLoader: true,
56 | data: params,
57 | headers: this.options.headers || {}
58 | }
59 | ).done(
60 | function (response) {
61 | if (response[fieldToCheck]) {
62 | element.removeClass('fail').addClass('success');
63 | result = self.options.successText;
64 | } else {
65 | msg = response.errorMessage;
66 |
67 | if (msg) {
68 | alert(
69 | {
70 | content: msg
71 | }
72 | );
73 | }
74 | }
75 | }
76 | ).always(
77 | function () {
78 | $('#' + self.options.elementId + '_result').text(result);
79 | }
80 | );
81 | }
82 | }
83 | );
84 |
85 | return $.mage.testConnection;
86 | }
87 | );
88 |
--------------------------------------------------------------------------------
/view/frontend/layout/bazaarvoice_pixel_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/view/frontend/layout/bazaarvoice_submission_container.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/view/frontend/layout/catalog_product_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Bazaarvoice\Connector\ViewModel\Product
13 |
14 |
15 |
16 |
17 |
18 |
19 | Bazaarvoice\Connector\ViewModel\Reviews
20 |
21 |
22 |
23 |
24 |
25 |
26 | Bazaarvoice\Connector\ViewModel\Reviews
27 | Reviews
28 | 100
29 |
30 |
31 |
32 |
33 | Bazaarvoice\Connector\ViewModel\Questions
34 | Questions
35 | 110
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/view/frontend/layout/checkout_onepage_success.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Bazaarvoice\Connector\ViewModel\Pixel
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/view/frontend/layout/customer_account.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/view/frontend/layout/default.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Bazaarvoice\Connector\ViewModel\Header
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/view/frontend/templates/checkout/onepage/success/bvpixel.phtml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | getViewModel(); ?>
11 |
12 | getBvPixelEnabled()) : ?>
13 |
14 | canShowDebugDetails()) : ?>
15 |
16 |
17 |
23 |
24 |
--------------------------------------------------------------------------------
/view/frontend/templates/header.phtml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | getViewModel(); ?>
11 |
12 | isBvEnabled()): ?>
13 | getConfigProvider()->getBvApiHostUrl(); ?>
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/view/frontend/templates/productheader.phtml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | getViewModel(); ?>
11 |
12 | isBvEnabled() && $viewModel->getProduct()): ?>
13 |
14 | isConfigurable() && $viewModel->getConfigProvider()->isRrChildrenEnabled()): ?>
15 |
46 |
47 | isDccEnabled()) : ?>
48 | getDccConfig(); ?>
49 | canShowDebugDetails()) : ?>
50 |
51 |
52 |
53 |
79 |
80 |
--------------------------------------------------------------------------------
/view/frontend/templates/qa/questions.phtml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | getViewModel(); ?>
11 |
12 | canShow()) : ?>
13 |
14 | getSeoContent(); ?>
15 |
16 | = $seoContent ?>
17 |
18 |
7 |
8 |
9 |
10 | getViewModel(); ?>
11 |
12 | canShow()) : ?>
13 |
14 | getSeoContent(); ?>
15 |
16 | = $seoContent ?>
17 |
18 |
7 |
8 |
9 |
10 | getViewModel(); ?>
11 |
12 | canShow()) : ?>
13 |
14 |
16 | = $viewModel->getAggregateSEOContent() ?>
17 |
18 |