_restParams) { $alias = reset($this->_restParams); if (!in_array($alias, $this->_getProvidersAliases())) { $this->_do404(); return $this; } $this->_provider = $this->_getProviderByAlias($alias); $this->_defaultAction = 'providerList'; } return parent::exec(); } /** * @return mixed * @throws \Qs_Exception */ protected function _getProviders() { if (null === $this->_providers) { $this->_providers = $this->getConfig('providers')->toArray(); if (!$this->_providers || !is_array($this->_providers)) { throw new \Qs_Exception('Search data providers are not defined.'); } } return $this->_providers; } /** * @return array * @throws \Qs_Exception */ protected function _getProvidersAliases() { if (null === $this->_providersAliases) { $this->_providersAliases = \Qs_Array::fetchCol($this->_getProviders(), 'fullResultsAlias'); if (!$this->_providersAliases || !is_array($this->_providersAliases)) { throw new \Qs_Exception('Search data providers declaration is wrong.'); } } return $this->_providersAliases; } /** * @param string $alias * @return array|bool */ protected function _getProviderByAlias($alias) { $providers = $this->_getProviders(); /** @var array $provider */ foreach ($providers as $provider) { if ($alias == $provider['fullResultsAlias']) { return $provider; } } return false; } /** * @return array */ protected function _getFilterFormOptions() { $options = array( 'method' => 'get' ); return $options; } /** * @return View|\Qs_ViewController */ protected function _addFilterItem() { if ($this->_hasFilter) { $form = $this->_getFilterForm(); if ($form->isSubmitted() && $form->validate()) { $this->_filter = $form->getValues(); } $this->_addFormItem($form); } return $this; } /** * @return array */ protected function _getListOptions() { $options = array( 'restParams' => $this->getRestParams(), 'templatePath' => $this->_getTemplatePath(), 'idItem' => $this->getIdItem(), ); return $options; } /** * @param array $provider * @return \Qs_Db_Obj * @throws \Qs_Exception */ protected function _getProviderDataObj(array $provider) { if (class_exists($provider['dataObjClass'])) { /** @var \Qs_Db_Obj $dataObj */ $dataObj = new $provider['dataObjClass']; $dataObj->addFilter($this->_filter); if (!empty($provider['filterFields'])) { $dataObj->setFilterFields($provider['filterFields']); } } else { throw new \Qs_Exception('Search provider with class ' . $provider['dataObjClass'] . ' is not found.'); } return $dataObj; } /** * @param array $provider * @return array */ protected function _getProviderTemplatePath(array $provider) { /** @var array $paths */ $paths = $this->_getTemplatePath(); $dir = preg_split('/[^a-zA-Z0-9]+/', $provider['fullResultsAlias']); array_walk($dir, function (&$value, $key) { $value = ucfirst($value); }); $dir = implode('', $dir); $providerPath = reset($paths) . '/Provider/' . $dir; array_unshift($paths, $providerPath); return $paths; } /** * @param array $provider * @return \Qs_ViewController_List */ protected function _getProviderList(array $provider) { $className = $this->_getClassName('List', substr($provider['dataObjClass'], 0, -3)); if (!class_exists($className)) { $className = 'Qs_ViewController_List'; } /** @var \Qs_ViewController_List $list */ $list = new $className($this->_getListOptions()); $list->addUrlVariables(array('query')); return $list; } /** * @return View */ protected function _addPartialListItem() { $emptyResults = true; foreach ($this->_getProviders() as $provider) { $dataObj = $this->_getProviderDataObj($provider); $list = $this->_getProviderList($provider); $list->setIpp(\Qs_Array::get($provider, 'shortResultsLimit', $this->getConfig('shortResultsLimit'))); $list->setList($dataObj->setSelectOptions($list->getSelectOptions())->getSearchList($provider)); $list->setListSelect($dataObj->getListSelect()); $item = $list->toArray(); if (empty($item['list'])) { continue; } else { $emptyResults = false; } $item['provider'] = $provider; $item['baseUrl'] = constant('BASE_URL') . '/' . constant('CURRENT_PAGE_FINAL'); $item['filterString'] = http_build_query($this->_filter); $item['templatePath'] = $this->_getProviderTemplatePath($provider); $item['tpl'] = \Qs_SiteMap::getTemplate('partialList.tpl', $item['templatePath']); $this->_doc->addItem($item); if ($this->_doc->isGtmEnabled() && $dataObj instanceof \App_ECommerce_Product_Search_Obj) { $this->_addGtmValues($item['list'], $list); } } if ($emptyResults) { $this->_addItem(array('tpl' => $this->getTemplate('empty-results.tpl'))); } return $this; } /** * @return View * @throws \Qs_Exception */ protected function _addProviderListItem() { if ($this->_provider) { $dataObj = $this->_getProviderDataObj($this->_provider); $list = $this->_getProviderList($this->_provider); $list->setList($dataObj->setSelectOptions($list->getSelectOptions())->getSearchList($this->_provider)); $list->setListSelect($dataObj->getListSelect()); $item = $list->toArray(); $item['baseUrl'] = constant('BASE_URL') . '/' . constant('CURRENT_PAGE_FINAL'); $item['filterString'] = http_build_query($this->_filter); $item['providerTitle'] = $this->_provider['providerTitle']; $item['partialSearchUrl'] = BASE_URL_LANGUAGE . '/' . CURRENT_PAGE_FINAL . '?' . http_build_query($this->_filter); $item['templatePath'] = $this->_getProviderTemplatePath($this->_provider); $item['tpl'] = \Qs_SiteMap::getTemplate('providerList.tpl', $item['templatePath']); $this->_doc->addItem($item); if ($this->_doc->isGtmEnabled() && $dataObj instanceof \App_ECommerce_Product_Search_Obj) { $this->_addGtmValues($item['list'], $list); } } else { throw new \Qs_Exception('Search data provider is not defined'); } return $this; } protected function _addGtmValues(array $products, \Qs_ViewController_List $list) { $products = array_combine(\Qs_Array::fetchCol($products, 'id'), $products); foreach ($products as &$product) { $product['title'] = strip_tags($product['title']); } $listTitle = 'Search Results'; $pageNumber = (int) $list->getPageNumber(); $ipp = (int) $this->_getList()->getIpp(); $startPosition = --$pageNumber * $ipp; $this->_doc->addGtmValues(\Qs_Gtm::eeGetProductImpressions($products, null, $listTitle, $startPosition)); $options = [ 'products' => \Qs_Gtm::eeGetProducts($products, \Qs_Gtm::DATASET_CLICK, [], true), 'actionField' => ['list' => $listTitle] ]; $this->_doc->addInitObject('lib.Gtm', [$options]); } /** * @return View */ protected function _doPartialList() { $this->_addFilterItem(); if ('' != $this->_filter['query']) { $this->_addPartialListItem(); $this->_log(); } else { $this->_addItem(array('tpl' => $this->getTemplate('empty-query.tpl'))); } return $this; } /** * @return View */ protected function _doProviderList() { $this->_addFilterItem(); if (!empty($this->_filter['query'])) { $this->_addProviderListItem(); $this->_log(); } else { $this->_addItem(array('tpl' => $this->getTemplate('empty-query.tpl'))); } return $this; } /** * @return View|\Qs_ViewController */ protected function _log() { if ($this->_hasLog && \Qs_ViewController_Log::getEnabled()) { $this->_getLog()->write($this->_action, $this->_getObjectInfo()); } return $this; } protected function _getObjectInfo() { $info = array(); $info['itemName'] = $this->getConfig('itemName'); $info['itemsName'] = $this->getConfig('itemsName'); if ($this->_provider) { $info = array_merge($info, $this->_provider); } $info = array_merge($info, $this->_filter); return $info; } protected function _getLog() { if (null === $this->_log) { parent::_getLog(); if (\Qs_Array::get($this->_filter, 'query')) { $this->_log->addIgnoredControllers('App_Cms_View'); $this->_log->setAction('partialList', 'Made a site search. Keyword(s): "%query%"'); $this->_log->setAction('providerList', 'Made a site search. Category: %providerTitle%; Keyword(s): "%query%"'); } else { $this->_log->removeIgnoredController('App_Cms_View'); } } return $this->_log; } }