<?php
/**
 * Page Cache powered by Jpresta (jpresta . com)
 *
 *    @author    Jpresta
 *    @copyright Jpresta
 *    @license   You are just allowed to modify this copy for your own use. You must not redistribute it. License
 *               is permitted for one Prestashop instance only but you can install it on your test instances.
 */

class FrontController extends FrontControllerCore
{
    protected function displayAjax()
    {
        if (!Tools::getIsset('page_cache_dynamics_mods')) {
            if (is_callable('parent::displayAjax')) {
                // The displayAjax is overrided, we call it
                return parent::displayAjax();
            }
            else {
                return;
            }
        }
        $this->initHeader();
        $this->assignGeneralPurposeVariables();
        require_once _PS_MODULE_DIR_ . 'pagecache/pagecache.php';
        $result = PageCache::execDynamicHooks($this);
        if (Tools::version_compare(_PS_VERSION_,'1.6','>')) {
            $this->context->smarty->assign(array(
                'js_def' => PageCache::getJsDef($this),
            ));
            $result['js'] = $this->context->smarty->fetch(_PS_ALL_THEMES_DIR_.'javascript.tpl');
        }
        $this->context->cookie->write();
        header('Content-Type: application/json');
        header('Cache-Control: no-cache');
        header('X-Robots-Tag: noindex');
        die(Tools::jsonEncode($result));
    }

    protected function smartyOutputContent($content)
    {
        if (Module::isEnabled('pagecache') && !($this instanceof ModuleFrontControllerCore)) {
            $pagecacheInstance = Module::getInstanceByName('pagecache');
            if ($pagecacheInstance && $pagecacheInstance->canBeCached()) {
                $this->context->cookie->write();

                $html = '';
                $js_tag = 'js_def';
                $this->context->smarty->assign($js_tag, $js_tag);

                if (is_array($content)) {
                    foreach ($content as $tpl) {
                        $html .= $this->context->smarty->fetch($tpl, null, $this->getLayout());
                    }
                } else {
                    $html = $this->context->smarty->fetch($content, null, $this->getLayout());
                }

                $html = trim($html);

                // Save the generated HTML into a file and display it => create a cache
                $pagecacheInstance->cacheThis($html, $this->getLayout());

                echo $html;
            } else {
                // Standard way
                return parent::smartyOutputContent($content);
            }
        } else {
            // Standard way
            return parent::smartyOutputContent($content);
        }
    }

    public function geolocationManagementPublic($defaultCountry)
    {
        if (!in_array(Tools::getRemoteAddr(), array('localhost', '127.0.0.1', '::1'))) {
            /* Check if Maxmind Database exists */
            if (@filemtime(_PS_GEOIP_DIR_ . _PS_GEOIP_CITY_FILE_)) {
                if (!isset($this->context->cookie->iso_code_country) || (isset($this->context->cookie->iso_code_country) && !in_array(Tools::strtoupper($this->context->cookie->iso_code_country), explode(';', Configuration::get('PS_ALLOWED_COUNTRIES'))))) {
                    $reader = new GeoIp2\Database\Reader(_PS_GEOIP_DIR_ . _PS_GEOIP_CITY_FILE_);
                    try {
                        $record = $reader->city(Tools::getRemoteAddr());
                    } catch (\GeoIp2\Exception\AddressNotFoundException $e) {
                        $record = null;
                    }
                    if (is_object($record) && Validate::isLanguageIsoCode($record->country->isoCode) && (int) Country::getByIso(Tools::strtoupper($record->country->isoCode)) != 0) {
                        if (!in_array(Tools::strtoupper($record->country->isoCode), explode(';', Configuration::get('PS_ALLOWED_COUNTRIES'))) && !FrontController::isInWhitelistForGeolocation()) {
                            if (Configuration::get('PS_GEOLOCATION_BEHAVIOR') == _PS_GEOLOCATION_NO_CATALOG_) {
                                $this->restrictedCountry = Country::GEOLOC_FORBIDDEN;
                            } elseif (Configuration::get('PS_GEOLOCATION_BEHAVIOR') == _PS_GEOLOCATION_NO_ORDER_) {
                                $this->restrictedCountry = Country::GEOLOC_CATALOG_MODE;
                                $this->warning[] = $this->trans('You cannot place a new order from your country (%s).', array($record->country->name), 'Shop.Notifications.Warning');
                            }
                        } else {
                            $hasBeenSet = !isset($this->context->cookie->iso_code_country);
                            $this->context->cookie->iso_code_country = Tools::strtoupper($record->country->isoCode);
                        }
                    }
                }
                if (isset($this->context->cookie->iso_code_country) && $this->context->cookie->iso_code_country && !Validate::isLanguageIsoCode($this->context->cookie->iso_code_country)) {
                    $this->context->cookie->iso_code_country = Country::getIsoById(Configuration::get('PS_COUNTRY_DEFAULT'));
                }
                if (isset($this->context->cookie->iso_code_country) && ($idCountry = (int) Country::getByIso(Tools::strtoupper($this->context->cookie->iso_code_country)))) {
                    /* Update defaultCountry */
                    if ($defaultCountry->iso_code != $this->context->cookie->iso_code_country) {
                        $defaultCountry = new Country($idCountry);
                    }
                    if (isset($hasBeenSet) && $hasBeenSet) {
                        $this->context->cookie->id_currency = (int) ($defaultCountry->id_currency ? (int) $defaultCountry->id_currency : (int) Configuration::get('PS_CURRENCY_DEFAULT'));
                    }
                    return $defaultCountry;
                } elseif (Configuration::get('PS_GEOLOCATION_NA_BEHAVIOR') == _PS_GEOLOCATION_NO_CATALOG_ && !FrontController::isInWhitelistForGeolocation()) {
                    $this->restrictedCountry = Country::GEOLOC_FORBIDDEN;
                } elseif (Configuration::get('PS_GEOLOCATION_NA_BEHAVIOR') == _PS_GEOLOCATION_NO_ORDER_ && !FrontController::isInWhitelistForGeolocation()) {
                    $this->restrictedCountry = Country::GEOLOC_CATALOG_MODE;
                    $countryName = $this->trans('Undefined', array(), 'Shop.Theme.Global');
                    if (isset($record->country->name) && $record->country->name) {
                        $countryName = $record->country->name;
                    }
                    $this->warning[] = $this->trans(
                        'You cannot place a new order from your country (%s).',
                        array($countryName),
                        'Shop.Notifications.Warning'
                    );
                }
            }
        }
        return $defaultCountry;
    }

    public function isRestrictedCountry()
    {
        return $this->restrictedCountry;
    }

    public static function getCurrentCustomerGroups()
    {
        if (!is_array(self::$currentCustomerGroups))
        {
            if (!Group::isFeatureActive())
            {
                self::$currentCustomerGroups = array();
            }
            else
            {
                $context = Context::getContext();
                if (!isset($context->customer) || !$context->customer->id)
                {
                    self::$currentCustomerGroups = Customer::getGroupsStatic(null);
                }
                else
                {
                    self::$currentCustomerGroups = array();
                    $result = Db::getInstance()->executeS('SELECT id_group FROM '._DB_PREFIX_.'customer_group WHERE id_customer = '.(int)$context->customer->id);
                    foreach ($result as $row)
                        self::$currentCustomerGroups[] = $row['id_group'];
                }
            }
        }
        return self::$currentCustomerGroups;
    }

}
