<?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_cfg_mod_cleaning
{
    protected $_aSQLInstructions;
    protected $_aInstructions;
    protected $_iMaxLanguages;
    protected $_blExecute = false;

    /**
     * @param d3_cfg_mod_update $oUpdateBase
     */
    public function __construct(d3_cfg_mod_update $oUpdateBase)
    {
        $this->oUpdateBase = $oUpdateBase;
    }

    /**
     * @return array
     */
    public function getOldLibIds()
    {
        return array('d3install_lib', 'd3log_lib', 'd3clrtmp_lib');
    }

    public function cleanOldModuleFiles()
    {
        $this->_cleanOldModuleItem('aModuleFiles');
    }

    public function cleanOldModuleTemplates()
    {
        $this->_cleanOldModuleItem('aModuleTemplates');
    }

    public function cleanOldModulePaths()
    {
        $this->_cleanOldModuleItem('aModulePaths');
    }

    public function cleanOldModuleVersions()
    {
        $this->_cleanOldModuleItem('aModuleVersions');
    }

    public function cleanOldModuleEvents()
    {
        $this->_cleanOldModuleItem('aModuleEvents');
    }

    public function deleteOldLibs()
    {
        /** @var d3filesystem $oFS */
        $oFS = oxNew('d3filesystem');

        $sModulePath = $oFS->trailingslashit(
            $oFS->trailingslashit(oxRegistry::getConfig()->getConfigParam('sShopDir')) . 'modules'
        );
        $aModulePaths = oxRegistry::getConfig()->getConfigParam('aModulePaths');

        foreach ($this->getOldLibIds() as $sOldLibId) {
            $sLibPath = $sModulePath.$aModulePaths[$sOldLibId];
            if ($aModulePaths[$sOldLibId] && preg_match("@".str_replace('_lib', '', $sOldLibId)."$@", $sLibPath)) {
                if ($this->_blExecute) {
                    $oFS->del_dir($sLibPath, null, true, true);
                } else {
                    $this->_aInstructions[] = sprintf(
                        oxRegistry::getLang()->translateString('D3_UPDATE_DELETE_DIR'),
                        $sLibPath
                    );
                }
            }
        }

        oxRegistry::getSession()->deleteVariable('d3RemoteLibList');
        oxRegistry::getSession()->deleteVariable('d3RemoteLibs');
    }

    public function cleanOldEnabledModules()
    {
        $oConfig = oxRegistry::getConfig();
        $sCurrentShopId = oxRegistry::getConfig()->getActiveShop()->getId();

        /** @var oxshop $oShop */
        foreach ($this->oUpdateBase->getShopList() as $oShop) {
            $this->_changeToShop($oShop->getId());

            if (method_exists($oConfig, 'getModulesWithExtendedClass')) {
                $aEnabledModules = $oConfig->getModulesWithExtendedClass();
            } else {
                $aEnabledModules = $oConfig->getAllModules();
            }

            $aModulePaths = oxRegistry::getConfig()->getConfigParam('aModulePaths');
            foreach ($this->getOldLibIds() as $sOldLibId) {
                if (false == isset($aModulePaths[$sOldLibId])) {
                    continue;
                }

                $sModulePath = $aModulePaths[$sOldLibId];

                foreach ($aEnabledModules as $sBaseClass => $aExtensionList) {
                    foreach ($aExtensionList as $sExtId => $sExtensionPath) {
                        if (preg_match("@^{$sModulePath}@", $sExtensionPath)) {
                            unset($aEnabledModules[$sBaseClass][$sExtId]);
                            if (empty($aEnabledModules[$sBaseClass])) {
                                unset($aEnabledModules[$sBaseClass]);
                            }
                        }
                    }
                }
            }

            /** @var oxmodulelist $oModuleList */
            $oModuleList = oxNew('oxmodulelist');
            $aModuleList = $oModuleList->buildModuleChains($aEnabledModules);

            $this->oUpdateBase->fixOxconfigVariable(
                'aModules',
                oxRegistry::getConfig()->getActiveShop()->getId(),
                '',
                $aModuleList,
                'aarr'
            );

            if ($this->_blExecute) {
                $oConfig->setConfigParam('aModules', $aModuleList);
            }
        }

        $this->_changeToShop($sCurrentShopId);
    }

    public function cleanOldDisabledModules()
    {
        $this->_cleanOldModuleItem('aDisabledModules');
    }

    public function transferSettings()
    {
        if (false == d3_cfg_mod::isAvailable('d3modcfg_lib')) {
            return;
        }

        $sCurrentShopId = oxRegistry::getConfig()->getActiveShop()->getId();

        /** @var oxshop $oShop */
        foreach ($this->oUpdateBase->getShopList() as $oShop) {
            $this->_changeToShop($oShop->getId());
            for ($iLang = 0; $iLang < $this->oUpdateBase->getMaxLanguages(); $iLang++) {
                $this->_transferLangSettings($iLang);
            }
        }

        $this->_changeToShop($sCurrentShopId);
    }

    /**
     * @param $sNewShopId
     */
    protected function _changeToShop($sNewShopId)
    {
        if (oxRegistry::getConfig()->isMall() && $sNewShopId != oxRegistry::getConfig()->getActiveShop()->getId()) {
            $oActiveView = oxRegistry::getConfig()->getActiveView();

            $oNewConf = new oxConfig();
            $oNewConf->setShopId($sNewShopId);
            $oNewConf->init();
            $oNewConf->setActiveView($oActiveView);

            // only available in mall installations
            oxRegistry::getConfig()->onShopChange();
            oxRegistry::getSession()->setVariable('actshop', $sNewShopId);
            oxRegistry::getSession()->setVariable('currentadminshop', $sNewShopId);
            oxRegistry::getConfig()->setShopId($sNewShopId);
            $this->oUpdateBase->setConfig($oNewConf);
        }
    }

    /**
     * @param $iLang
     */
    protected function _transferLangSettings($iLang)
    {
        $blWrite = false;

        $oModCfg = d3_cfg_mod::get('d3modcfg_lib');
        $oModCfg->setLanguage($iLang);

        foreach ($this->getOldLibIds() as $sLibId) {
            if (d3_cfg_mod::isAvailable($sLibId)) {
                $oLib = d3_cfg_mod::get($sLibId);
                $oLib->setLanguage($iLang);
                if ($oLib->getAllValues()) {
                    foreach ($oLib->getAllValues() as $sKey => $mValue) {
                        $oModCfg->setValue($sKey, $mValue);
                        $blWrite = true;
                    }
                }
            }
        }

        if ($blWrite) {
            if ($this->_blExecute) {
                $oModCfg->saveNoLicenseRefresh();
            } else {
                $sFieldName = $iLang ? 'oxvalue_'.$iLang : 'oxvalue';
                $sSql = "UPDATE {$oModCfg->getViewName()} SET {$sFieldName} = ".
                    oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->quote($oModCfg->getFieldData('oxvalue')).
                    " WHERE oxmodid = ".oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->quote('d3modcfg_lib')." AND".
                    " oxshopid = ".oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->quote(
                        oxRegistry::getConfig()->getActiveShop()->getId()
                    )."; ";
                $this->_aSQLInstructions[] = $sSql;
            }
        }
    }

    public function deleteSettings()
    {
        /** @var d3_cfg_mod $oModCfg */
        $oModCfg = oxNew('d3_cfg_mod');
        $sCurrentShopId = oxRegistry::getConfig()->getActiveShop()->getId();

        /** @var oxshop $oShop */
        foreach ($this->oUpdateBase->getShopList() as $oShop) {
            $this->_changeToShop($oShop->getId());

            foreach ($this->getOldLibIds() as $sLibId) {
                $sSearchSelect = "SELECT 1 FROM {$oModCfg->getViewName()} WHERE oxmodid = ".
                    oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->quote($sLibId)." AND oxshopid = ".
                    oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->quote(oxRegistry::getConfig()->getActiveShop()->getId()).
                    " LIMIT 1";

                if (oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->getOne($sSearchSelect)) {
                    $sQuery = "DELETE FROM {$oModCfg->getViewName()} WHERE oxmodid = ".
                        oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->quote($sLibId)." AND oxshopid = ".
                        oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->quote(
                            oxRegistry::getConfig()->getActiveShop()->getId()
                        ).";";

                    if ($this->_blExecute) {
                        oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->Execute($sQuery);
                    } else {
                        $this->_aSQLInstructions[] = $sQuery;
                    }
                }
            }
        }

        $this->_changeToShop($sCurrentShopId);
    }

    /**
     * @return array
     */
    public function getSql()
    {
        return $this->_aSQLInstructions;
    }

    /**
     * @return array
     */
    public function getInstructions()
    {
        return $this->_aInstructions;
    }

    /**
     * @param $blExecute
     */
    public function setExecute($blExecute)
    {
        $this->_blExecute = $blExecute;
    }

    /**
     * @param $sItemId
     */
    protected function _cleanOldModuleItem($sItemId)
    {
        $oConfig = oxRegistry::getConfig();
        $sCurrentShopId = oxRegistry::getConfig()->getActiveShop()->getId();

        /** @var oxshop $oShop */
        foreach ($this->oUpdateBase->getShopList() as $oShop) {
            $this->_changeToShop($oShop->getId());

            $aModuleInfos = (array) $oConfig->getConfigParam($sItemId);

            foreach ($this->getOldLibIds() as $sOldLibId) {
                unset($aModuleInfos[$sOldLibId]);
            }

            $this->oUpdateBase->fixOxconfigVariable(
                $sItemId,
                oxRegistry::getConfig()->getActiveShop()->getId(),
                '',
                $aModuleInfos,
                'aarr'
            );

            if ($this->_blExecute) {
                $oConfig->setConfigParam($sItemId, $aModuleInfos);
            }
        }

        $this->_changeToShop($sCurrentShopId);
    }

    /**
     * @return bool
     */
    public function hasDisabledD3VendorItem()
    {
        $aModuleInfos = (array) oxRegistry::getConfig()->getConfigParam('aDisabledModules');

        $iIndex = array_search('d3', $aModuleInfos);

        if (false !== $iIndex) {
            return true;
        }

        return false;
    }

    public function cleanD3VendorItem()
    {
        $sItemId = 'aDisabledModules';
        $oConfig = oxRegistry::getConfig();
        $sCurrentShopId = oxRegistry::getConfig()->getActiveShop()->getId();

        if ($this->hasDisabledD3VendorItem()) {
            /** @var oxshop $oShop */
            foreach ($this->oUpdateBase->getShopList() as $oShop) {
                $this->_changeToShop($oShop->getId());

                $aModuleInfos = (array) $oConfig->getConfigParam($sItemId);

                $iIndex = array_search('d3', $aModuleInfos);

                if (false !== $iIndex) {
                    unset($aModuleInfos[$iIndex]);
                }

                $this->oUpdateBase->fixOxconfigVariable(
                    $sItemId,
                    oxRegistry::getConfig()->getActiveShop()->getId(),
                    '',
                    $aModuleInfos,
                    'aarr'
                );

                if ($this->_blExecute) {
                    $oConfig->setConfigParam($sItemId, $aModuleInfos);
                }
            }

            $this->_changeToShop($sCurrentShopId);
        }
    }
}
