<?php

/**
 * This Software is the property of Data Development and is protected
 * by copyright law - it is NOT Freeware.
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 * http://www.shopmodule.com
 *
 * @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
 * @author    D3 Data Development - Daniel Seifert <support@shopmodule.com>
 * @link      http://www.oxidmodule.com
 */

class d3_oxlocator_extsearch extends d3_oxlocator_extsearch_parent
{
    /** @var oxarticle */
    protected $_oNextProduct = null;

    /** @var oxarticle */
    protected $_oBackProduct = null;

    /** @var array */
    protected $_aD3Params = array();

    private $_sModId = 'd3_extsearch';

    /**
     * @param d3_ext_search $oLocatorTarget
     * @param oxarticle $oCurrArticle
     *
     * @return null|void
     */
    protected function _setListLocatorData($oLocatorTarget, $oCurrArticle)
    {
        parent::_setListLocatorData($oLocatorTarget, $oCurrArticle);

        /** @var $oCategory oxcategory */
        if ($this->_d3ExtSearchNeedExtensionForCurrentLocator()
            && ($oCategory = $oLocatorTarget->getActiveCategory())
        ) {
            // loading data for article navigation
            /** @var $oIdList d3_oxarticlelist_extsearch */
            $oIdList = oxNew('oxarticlelist');

            if ($oLocatorTarget->showSorting()) {
                $oLocatorTarget->getSorting($this->d3GetSortIdent($oLocatorTarget));
                $oIdList->setCustomSorting($oLocatorTarget->getSortingSql($this->d3GetSortIdent($oLocatorTarget)));
            }

            if ($oCategory->isPriceCategory()) {
                $oIdList->loadPriceIds($oCategory->oxcategories__oxpricefrom->value, $oCategory->oxcategories__oxpriceto->value);
            } else {
                $sActCat = $oCategory->getId();
                $oIdList->loadCategoryIds($sActCat, oxRegistry::getSession()->getVariable('session_attrfilter'));
            }

            //page number
            $iPage = $this->_findActPageNumber($oLocatorTarget->getActPage(), $oIdList, $oCurrArticle);

            $sAddSearch = $this->_d3GetSearchUrlAdd();

            // setting product position in list, amount of articles etc
            $oCategory->iCntOfProd = $oIdList->count();
            $oCategory->iProductPos = $this->_getProductPos($oCurrArticle, $oIdList, $oLocatorTarget);

            $sPageNr = $this->_getPageNumber($iPage);
            $oCategory->toListLink =
                $this->_makeLink($oCategory->link, $sPageNr . ($sPageNr ? '&amp;' : '') . $sAddSearch);
            $oCategory->nextProductLink =
                $this->_oNextProduct ? $this->_makeLink($this->_oNextProduct->getLink(), $sAddSearch) : null;
            $oCategory->prevProductLink =
                $this->_oBackProduct ? $this->_makeLink($this->_oBackProduct->getLink(), $sAddSearch) : null;

            $sFormat = oxRegistry::getLang()->translateString('searchResult');
            $oLocatorTarget->setSearchTitle(sprintf($sFormat, $this->_d3GetParamForSearch('searchparam', true)));
            // for compatibility reasons for a while. will be removed in future
            $oLocatorTarget->addTplParam('sSearchTitle', $oLocatorTarget->getSearchTitle());

            if ($this->_d3GetRawUrlParamForSearch('searchparam')) {
                $oLocatorTarget->addTplParam('searchparam', $this->_d3GetRawUrlParamForSearch('searchparam'));
            }
            if ($this->_d3GetRawUrlParamForSearch('searchcnid')) {
                $oLocatorTarget->addTplParam('searchcnid', $this->_d3GetRawUrlParamForSearch('searchcnid'));
            }
            if ($this->_d3GetRawUrlParamForSearch('searchvendor')) {
                $oLocatorTarget->addTplParam('searchvendor', $this->_d3GetRawUrlParamForSearch('searchvendor'));
            }

            if ($this->_d3GetRawUrlParamForSearch('d3searchvendormultiselector')) {
                $oLocatorTarget->addTplParam('d3searchvendormultiselector', $this->_d3GetRawUrlParamForSearch('d3searchvendormultiselector'));

                if ($this->_d3GetParamForSearch('d3searchvendormulti', false) //
                    && ($aVendorMulti = $this->_d3GetParamForSearch('d3searchvendormulti', false))
                ) {
                    if (isset($aVendorMulti) && is_array($aVendorMulti)) {
                        foreach ($aVendorMulti as $sKey => $sValue) {
                            if (strlen(trim($sValue))) {
                                $oLocatorTarget->addTplParam('d3searchvendormulti[' . $sKey . ']', urlencode($sValue));
                            }
                        };
                    }
                }
            }

            if ($this->_d3GetRawUrlParamForSearch('searchmanufacturer')) {
                $oLocatorTarget->addTplParam(
                    'searchmanufacturer',
                    $this->_d3GetRawUrlParamForSearch('searchmanufacturer')
                );
            }

            if ($this->_d3GetRawUrlParamForSearch('d3searchmanufacturermultiselector')) {
                $oLocatorTarget->addTplParam('d3searchmanufacturermultiselector', $this->_d3GetRawUrlParamForSearch('d3searchmanufacturermultiselector'));

                if ($this->_d3GetParamForSearch('d3searchmanufacturermulti', false) //
                    && ($aVendorMulti = $this->_d3GetParamForSearch('d3searchmanufacturermulti', false))
                ) {
                    if (isset($aVendorMulti) && is_array($aVendorMulti)) {
                        foreach ($aVendorMulti as $sKey => $sValue) {
                            if (strlen(trim($sValue))) {
                                $oLocatorTarget->addTplParam('d3searchmanufacturermulti[' . $sKey . ']', urlencode($sValue));
                            }
                        };
                    }
                }
            }

            if ($this->_d3GetParamForSearch('searchparam', true)) {
                $oLocatorTarget->addTplParam('searchparamforhtml', $this->_d3GetParamForSearch('searchparam', true));
            }
            if ($this->_d3GetParamForSearch('d3searchlike', false)) {
                $oLocatorTarget->addTplParam(
                    'aD3OwnFormFieldsLike',
                    $this->_d3GetParamForSearch('d3searchlike', false)
                );
            }
            if ($this->_d3GetParamForSearch('d3searchis', false)) {
                $oLocatorTarget->addTplParam('aD3OwnFormFieldsIs', $this->_d3GetParamForSearch('d3searchis', false));
            }
            if ($this->_d3GetParamForSearch('filterparam', false)) {
                $oLocatorTarget->addTplParam('filterparam', $this->_d3GetParamForSearch('filterparam', false));
            }
            $oLocatorTarget->addTplParam('d3searchattribparam', '');
            $oLocatorTarget->addTplParam('isextseach', oxRegistry::getConfig()->getRequestParameter('isextsearch'));

            $oCategory->toListLink = $oCategory->toListLink . '&amp;d3avoiddirectshow=1';

            $oLocatorTarget->setActiveCategory($oCategory);
            // for compatibility reasons for a while. will be removed in future
            $oLocatorTarget->addTplParam('actCategory', $oLocatorTarget->getActiveCategory());
        }
    }

    /**
     * @param oxUBase   $oLocatorTarget
     * @param oxArticle $oCurrArticle
     */
    protected function _setVendorLocatorData($oLocatorTarget, $oCurrArticle)
    {
        parent::_setManufacturerLocatorData($oLocatorTarget, $oCurrArticle);

        if ($this->_d3ExtSearchNeedExtensionForCurrentLocator()
            && ($oVendor = $oLocatorTarget->getActVendor())
        ) {
            $sVendorId = $oVendor->getId();

            // loading data for article navigation
            $oIdList = oxNew("oxArticleList");
            if ($oLocatorTarget->showSorting()) {
                $oIdList->setCustomSorting($oLocatorTarget->getSortingSql($oLocatorTarget->getSortIdent()));
            }
            $oIdList->loadVendorIds($sVendorId);

            //page number
            $iPage = $this->_findActPageNumber($oLocatorTarget->getActPage(), $oIdList, $oCurrArticle);

            $sAddSearch = $this->_d3GetSearchUrlAdd();

            // setting product position in list, amount of articles etc
            $oVendor->iCntOfProd = $oIdList->count();
            $oVendor->iProductPos = $this->_getProductPos($oCurrArticle, $oIdList, $oLocatorTarget);

            $oVendor->toListLink =
                $this->_makeLink($oVendor->getLink(), $this->_getPageNumber($iPage) . $sAddSearch);
            $oVendor->nextProductLink =
                $this->_oNextProduct ? $this->_makeLink($this->_oNextProduct->getLink(), $sAddSearch) : null;
            $oVendor->prevProductLink =
                $this->_oBackProduct ? $this->_makeLink($this->_oBackProduct->getLink(), $sAddSearch) : null;

            $oLocatorTarget->setActiveCategory($oVendor);
        }
    }

    /**
     * @param oxubase   $oLocatorTarget
     * @param oxarticle $oCurrArticle
     */
    protected function _setManufacturerLocatorData($oLocatorTarget, $oCurrArticle)
    {
        parent::_setManufacturerLocatorData($oLocatorTarget, $oCurrArticle);

        /** @var $oManufacturer oxManufacturer */
        if ($this->_d3ExtSearchNeedExtensionForCurrentLocator()
            && ($oManufacturer = $oLocatorTarget->getActManufacturer())
        ) {
            $sManufacturerId = $oManufacturer->getId();

            // loading data for article navigation
            $oIdList = oxNew("oxarticlelist");
            if ($oLocatorTarget->showSorting()) {
                $oIdList->setCustomSorting($oLocatorTarget->getSortingSql($oLocatorTarget->getSortIdent()));
            }
            $oIdList->loadManufacturerIds($sManufacturerId);

            //page number
            $iPage = $this->_findActPageNumber($oLocatorTarget->getActPage(), $oIdList, $oCurrArticle);

            $sAddSearch = $this->_d3GetSearchUrlAdd();

            // setting product position in list, amount of articles etc
            $oManufacturer->iCntOfProd = $oIdList->count();
            $oManufacturer->iProductPos = $this->_getProductPos($oCurrArticle, $oIdList, $oLocatorTarget);

            $oManufacturer->toListLink =
                $this->_makeLink($oManufacturer->getLink(), $this->_getPageNumber($iPage). $sAddSearch);
            $oManufacturer->nextProductLink =
                $this->_oNextProduct ? $this->_makeLink($this->_oNextProduct->getLink(), $sAddSearch) : null;
            $oManufacturer->prevProductLink =
                $this->_oBackProduct ? $this->_makeLink($this->_oBackProduct->getLink(), $sAddSearch) : null;

            // active Manufacturer
            $oLocatorTarget->setActiveCategory($oManufacturer);
        }
    }

    /**
     * @param d3_ext_search $oLocatorTarget
     * @param oxarticle $oCurrArticle
     *
     * @return null|void
     */
    protected function _setSearchLocatorData($oLocatorTarget, $oCurrArticle)
    {
        /** @var $oSearchCat oxcategory|stdClass */
        $oSearchCat = $oLocatorTarget->getActSearch();
        if ($oSearchCat) {
            // loading data for article navigation
            /** @var $oIdList oxarticlelist */
            $oIdList = oxNew('oxarticlelist');

            if ($oLocatorTarget->showSorting()) {
                $oLocatorTarget->getSorting($this->d3GetSortIdent($oLocatorTarget));
                $oIdList->setCustomSorting($oLocatorTarget->getSortingSql($this->d3GetSortIdent($oLocatorTarget)));
            }

            $oIdList->loadSearchIds(
                $this->_d3GetParamForSearch('searchparam', false),
                $this->_d3GetRawUrlParamForSearch('searchcnid'),
                $this->_d3GetRawUrlParamForSearch('searchvendor'),
                $this->_d3GetRawUrlParamForSearch('searchmanufacturer')
            );

            //page number
            $iPage = $this->_findActPageNumber($oLocatorTarget->getActPage(), $oIdList, $oCurrArticle);

            $sAddSearch = $this->_d3GetSearchUrlAdd();

            // setting product position in list, amount of articles etc
            $oSearchCat->iCntOfProd = $oIdList->count();
            $oSearchCat->iProductPos = $this->_getProductPos($oCurrArticle, $oIdList, $oLocatorTarget);

            $sPageNr = $this->_getPageNumber($iPage);
            $oSearchCat->toListLink =
                $this->_makeLink($oSearchCat->link, $sPageNr . ($sPageNr ? '&amp;' : '') . $sAddSearch);
            $oSearchCat->nextProductLink =
                $this->_oNextProduct ? $this->_makeLink($this->_oNextProduct->getLink(), $sAddSearch) : null;
            $oSearchCat->prevProductLink =
                $this->_oBackProduct ? $this->_makeLink($this->_oBackProduct->getLink(), $sAddSearch) : null;

            $sFormat = oxRegistry::getLang()->translateString('searchResult');
            $oLocatorTarget->setSearchTitle(sprintf($sFormat, $this->_d3GetParamForSearch('searchparam', true)));
            // for compatibility reasons for a while. will be removed in future
            $oLocatorTarget->addTplParam('sSearchTitle', $oLocatorTarget->getSearchTitle());

            if ($this->_d3GetRawUrlParamForSearch('searchparam')) {
                $oLocatorTarget->addTplParam('searchparam', $this->_d3GetRawUrlParamForSearch('searchparam'));
            }
            if ($this->_d3GetRawUrlParamForSearch('searchcnid')) {
                $oLocatorTarget->addTplParam('searchcnid', $this->_d3GetRawUrlParamForSearch('searchcnid'));
            }
            if ($this->_d3GetRawUrlParamForSearch('searchvendor')) {
                $oLocatorTarget->addTplParam('searchvendor', $this->_d3GetRawUrlParamForSearch('searchvendor'));
            }
            if ($this->_d3GetRawUrlParamForSearch('searchmanufacturer')) {
                $oLocatorTarget->addTplParam(
                    'searchmanufacturer',
                    $this->_d3GetRawUrlParamForSearch('searchmanufacturer')
                );
            }
            if ($this->_d3GetParamForSearch('searchparam', true)) {
                $oLocatorTarget->addTplParam('searchparamforhtml', $this->_d3GetParamForSearch('searchparam', true));
            }
            if ($this->_d3GetParamForSearch('d3searchlike', false)) {
                $oLocatorTarget->addTplParam(
                    'aD3OwnFormFieldsLike',
                    $this->_d3GetParamForSearch('d3searchlike', false)
                );
            }
            if ($this->_d3GetParamForSearch('d3searchis', false)) {
                $oLocatorTarget->addTplParam('aD3OwnFormFieldsIs', $this->_d3GetParamForSearch('d3searchis', false));
            }
            if ($this->_d3GetParamForSearch('filterparam', false)) {
                $oLocatorTarget->addTplParam('filterparam', $this->_d3GetParamForSearch('filterparam', false));
            }
            $oLocatorTarget->addTplParam('d3searchattribparam', '');

            $oSearchCat->toListLink = $oSearchCat->toListLink . '&amp;d3avoiddirectshow=1';

            $oLocatorTarget->setActiveCategory($oSearchCat);
            // for compatibility reasons for a while. will be removed in future
            $oLocatorTarget->addTplParam('actCategory', $oLocatorTarget->getActiveCategory());
        }
    }

    /**
     * @param $oLocatorTarget
     *
     * @return string
     */
    public function d3GetSortIdent($oLocatorTarget)
    {
        if (method_exists($oLocatorTarget, 'getSortIdent')) {
            return $oLocatorTarget->getSortIdent();
        }

        return 'alist';
    }

    /**
     * @param      $sParamName
     * @param bool $blFormParam
     *
     * @return mixed
     */
    protected function _d3GetParamForSearch($sParamName, $blFormParam = false)
    {
        if (!$this->_aD3Params[$sParamName . $blFormParam]) {
            $this->_aD3Params[$sParamName . $blFormParam] = oxRegistry::getConfig()->getRequestParameter(
                $sParamName,
                $blFormParam
            );
        }

        return $this->_aD3Params[$sParamName . $blFormParam];
    }

    /**
     * @param $sParamName
     *
     * @return string
     */
    protected function _d3GetRawUrlParamForSearch($sParamName)
    {
        return rawurldecode($this->_d3GetParamForSearch($sParamName));
    }

    /**
     * @return string
     */
    protected function _d3GetSearchUrlAdd()
    {
        $sAddSearch = "searchparam=" . $this->_d3GetRawUrlParamForSearch('searchparam');
        $sAddSearch .= "&amp;listtype=" . $this->_sType;
        if ($this->_d3GetRawUrlParamForSearch('searchcnid')) {
            $sAddSearch .= "&amp;searchcnid=" . $this->_d3GetRawUrlParamForSearch('searchcnid');
        }

        if ($this->_d3GetRawUrlParamForSearch('searchvendor')) {
            $sAddSearch .= "&amp;searchvendor=" . $this->_d3GetRawUrlParamForSearch('searchvendor');
        }

        if ($this->_d3GetRawUrlParamForSearch('d3searchvendormultiselector')) {
            $sAddSearch .= "&amp;d3searchvendormultiselector=" . $this->_d3GetRawUrlParamForSearch('d3searchvendormultiselector');

            if ($this->_d3GetParamForSearch('d3searchvendormulti', false) //
                && ($aVendorMulti = $this->_d3GetParamForSearch('d3searchvendormulti', false))
            ) {
                if (isset($aVendorMulti) && is_array($aVendorMulti)) {
                    foreach ($aVendorMulti as $sKey => $sValue) {
                        if (strlen(trim($sValue))) {
                            $sAddSearch .= "&amp;d3searchvendormulti[" . $sKey . "]=" . urlencode($sValue);
                        }
                    };
                }
            }
        }

        if ($this->_d3GetRawUrlParamForSearch('searchmanufacturer')) {
            $sAddSearch .= "&amp;searchmanufacturer=" . $this->_d3GetRawUrlParamForSearch('searchmanufacturer');
        }

        if ($this->_d3GetRawUrlParamForSearch('d3searchmanufacturermultiselector')) {
            $sAddSearch .= "&amp;d3searchmanufacturermultiselector=" . $this->_d3GetRawUrlParamForSearch('d3searchmanufacturermultiselector');

            if ($this->_d3GetParamForSearch('d3searchmanufacturermulti', false) //
                && ($aManufacturerMulti = $this->_d3GetParamForSearch('d3searchmanufacturermulti', false))
            ) {
                if (isset($aManufacturerMulti) && is_array($aManufacturerMulti)) {
                    foreach ($aManufacturerMulti as $sKey => $sValue) {
                        if (strlen(trim($sValue))) {
                            $sAddSearch .= "&amp;d3searchmanufacturermulti[" . $sKey . "]=" . urlencode($sValue);
                        }
                    };
                }
            }
        }

        if ($this->_d3GetParamForSearch('d3searchlike', false)) {
            foreach ($this->_d3GetParamForSearch('d3searchlike', false) as $key => $value) {
                $sAddSearch .= "&amp;d3searchlike[$key]=" . urlencode($value);
            }
        }

        if ($this->_d3GetParamForSearch('d3searchis', false)) {
            foreach ($this->_d3GetParamForSearch('d3searchis', false) as $key => $value) {
                $sAddSearch .= "&amp;d3searchis[$key]=" . urlencode($value);
            }
        }

        if ($this->_d3GetParamForSearch('filterparam', false)) {
            $sAddSearch .= "&amp;filterparam=" . $this->_d3GetParamForSearch('filterparam', false);
        }

        // price selectors original values
        if ($this->_d3GetParamForSearch('priceselector', false) //
            && ($aPSOV = $this->_d3GetParamForSearch('d3psov', false))
        ) {
            if (isset($aPSOV) && is_array($aPSOV)) {
                foreach ($aPSOV as $sKey => $sValue) {
                    $sAddSearch .= "&amp;d3psov[".$sKey."]=" . urlencode($sValue);
                };
            }
        }

        if ($this->_d3GetParamForSearch('priceselector', false)) {
            $sAddSearch .= "&amp;priceselector=" . $this->_d3GetParamForSearch('priceselector', false);
        }

        if ($this->_d3GetParamForSearch('d3searchattrib', false)) {
            foreach ($this->_d3GetParamForSearch('d3searchattrib', false) as $key => $value) {
                if ($value) {
                    $sAddSearch .= "&amp;d3searchattrib[$key]=" . urlencode($value);
                }
            }
        }

        $sAddSearch .= "&amp;isextsearch=".oxRegistry::getConfig()->getRequestParameter('isextsearch');

        return $sAddSearch;
    }

    /**
     * @return string
     */
    private function _d3getModId()
    {
        return $this->_sModId;
    }

    /**
     * @return d3_cfg_mod
     */
    protected function _d3GetSet()
    {
        return d3_cfg_mod::get($this->_d3getModId());
    }

    /**
     * @return bool
     */
    private function _d3UseAlistFilters()
    {
        return $this->_d3GetSet()->getLicenseConfigData('blUseFilterInArticleLists', false) //
            && $this->_d3GetSet()->getValue('blExtSearch_useAListFilter');
    }

    /**
     * @return bool
     */
    protected function _d3ExtSearchNeedExtensionForCurrentLocator ()
    {
        if (false == $this->_d3GetSet()->isActive() //
            || false == method_exists(oxRegistry::getConfig()->getActiveView(), 'getListType')
            || ( //
                false == $this->_d3UseAlistFilters() //
                && oxRegistry::getConfig()->getActiveView()->getListType() != 'search' //
            ) //
        ) {
            return false;
        }

        return true;
    }
}
