Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace progroman\CityManager;
- /**
- * Class Core
- * @package progroman\CityManager
- * @author Roman Shipilov (ProgRoman) <mr.progroman@yandex.ru>
- */
- abstract class Core
- {
- private static $instance = NULL;
- /** @var \Registry; */
- protected $registry = NULL;
- /** @var \Session */
- protected $session = NULL;
- /** @var \Request */
- protected $request = NULL;
- protected $fias_country_id = NULL;
- protected $fias_zone_id = NULL;
- protected $fias_district_id = NULL;
- protected $fias_id = NULL;
- protected $country_id = NULL;
- protected $zone_id = NULL;
- protected $country_name = NULL;
- protected $zone_name = NULL;
- protected $district_name = NULL;
- protected $postcode = NULL;
- protected $city_name = NULL;
- protected $popup_city_name = NULL;
- /** @var string Тип населенного пункта (д., г. и т.д.) */
- protected $prefix_city_name = NULL;
- protected $prefix_district_name = NULL;
- protected $prefix_zone_name = NULL;
- protected $session_key = "prmn.city_manager";
- protected $cookie_prefix = "prmn_";
- protected $is_first_visit = NULL;
- protected $main_domain = NULL;
- protected $dev_mode = NULL;
- protected $settings = NULL;
- protected $messages = NULL;
- protected $redirects = NULL;
- private static $drivers = array();
- const NOMINATIVE = "nc";
- protected function __construct()
- {
- $this->registry = \progroman\Common\Registry::instance()->getRegistry();
- $this->session = $this->registry->get("session");
- $this->request = $this->registry->get("request");
- $this->settings = $this->registry->get("config")->get("module_progroman_citymanager_setting");
- $this->main_domain = !empty($this->settings["main_domain"]) ? $this->settings["main_domain"] : parse_url(HTTPS_SERVER ? HTTPS_SERVER : HTTP_SERVER, PHP_URL_HOST);
- if ($this->dev_mode) {
- $this->logger = new \Log("citymanager");
- }
- $this->is_first_visit = !isset($this->session->data[$this->getSessionKey()]) && empty($this->request->cookie[$this->getCookieKey("fias")]);
- }
- /**
- * @param $registry
- * @return $this|CityManager
- */
- public static function instance()
- {
- if (!static::$instance) {
- static::$instance = new static();
- }
- return static::$instance;
- }
- public function setFias($fias_id)
- {
- if ($fias_id != $this->fias_id && self::checkLicense($this->setting("secret_key"))) {
- $data = $this->getAllFields(array("fias_id" => $fias_id));
- if ($data) {
- $this->log("setFias(" . $fias_id . ")" . print_r($data, true));
- $this->setFields($data);
- $this->setValueInSession("redirected", 0);
- $this->setValueInSession("force_redirect", 1);
- $this->setCurrency(true);
- $this->log("fias_id in SESSION \"" . $this->getValueFromSession("fias_id") . "\"");
- return true;
- }
- }
- return false;
- }
- /**
- * По имеющимся полям вычисляет недостающие
- * @param $fields
- * @return array|bool
- */
- private function getAllFields($fields)
- {
- $model_fias = $this->loadModel("fias");
- if (isset($fields["fias_id"])) {
- $fields["fias_id"] = (int) $fields["fias_id"];
- }
- $fias = false;
- if (!empty($fields["fias_id"])) {
- $fias = $model_fias->getFiasById($fields["fias_id"]);
- } else {
- if (!empty($fields["country_name"])) {
- if (!empty($fields["zone_name"])) {
- $fields["zone_name"] = $this->prepareZoneNameForFias($fields["zone_name"]);
- }
- $fias = $model_fias->getFias($fields);
- }
- }
- if (isset($fields["iso_code_2"])) {
- $country = $model_fias->getCountryByIsoCode($fields["iso_code_2"]);
- if ($country) {
- $fields["country_id"] = $country["country_id"];
- $fields["country_name"] = $country["name"];
- }
- }
- if ($fias) {
- $fields["fias_id"] = $fias["f1_fias_id"];
- if ($fias["f1_level"] == \ModelExtensionModuleProgromanFias::LEVEL_COUNTRY) {
- $this->fillFiasNames("country", $fields, $fias, 1);
- } else {
- $fields["postcode"] = $fias["f1_postalcode"] ? $fias["f1_postalcode"] : "";
- if ($fias["f1_level"] == \ModelExtensionModuleProgromanFias::LEVEL_REGION) {
- $this->fillFiasNames("zone", $fields, $fias, 1);
- $this->fillFiasNames("country", $fields, $fias, 2);
- if ($fias["f1_shortname"] == "г.") {
- $this->fillFiasNames("city", $fields, $fias, 1);
- }
- } else {
- if ($fias["f2_level"] == \ModelExtensionModuleProgromanFias::LEVEL_REGION) {
- $this->fillFiasNames("city", $fields, $fias, 1);
- $this->fillFiasNames("zone", $fields, $fias, 2);
- $this->fillFiasNames("country", $fields, $fias, 3);
- } else {
- if ($fias["f3_level"] == \ModelExtensionModuleProgromanFias::LEVEL_REGION) {
- $this->fillFiasNames("city", $fields, $fias, 1);
- $this->fillFiasNames("district", $fields, $fias, 2);
- $this->fillFiasNames("zone", $fields, $fias, 3);
- $this->fillFiasNames("country", $fields, $fias, 4);
- } else {
- if ($fias["f4_level"] == \ModelExtensionModuleProgromanFias::LEVEL_REGION) {
- $this->fillFiasNames("city", $fields, $fias, 1);
- $this->fillFiasNames("district", $fields, $fias, 3);
- $this->fillFiasNames("zone", $fields, $fias, 4);
- $country_fias = $model_fias->getFiasById($fias["f4_parent_id"]);
- $this->fillFiasNames("country", $fields, $country_fias, 1);
- } else {
- return $fields;
- }
- }
- }
- }
- $fias_to_zone = $model_fias->getFiasToZone();
- if (isset($fias_to_zone[$fields["fias_zone_id"]])) {
- $fields["zone_id"] = $fias_to_zone[$fields["fias_zone_id"]]["zone_id"];
- }
- }
- if (empty($fields["country_id"])) {
- $fias_to_country = $model_fias->getFiasToCountry();
- if (isset($fias_to_country[$fields["fias_country_id"]])) {
- $fields["country_id"] = $fias_to_country[$fields["fias_country_id"]]["country_id"];
- }
- }
- }
- return $fields;
- }
- /**
- * Заполняет однообразые поля zone_name, fias_zone_id, country_name, fias_country_id и т.д.
- * @param string $type Одно из значений: country, zone, district, city
- * @param $fields
- * @param $fias
- * @param $depth
- */
- private function fillFiasNames($type, &$fields, $fias, $depth)
- {
- $fields["fias_" . $type . "_id"] = $fias["f" . $depth . "_fias_id"];
- $fields[$type . "_name"] = $fias["f" . $depth . "_name"];
- if ($type != "country") {
- $fields["prefix_" . $type . "_name"] = $fias["f" . $depth . "_shortname"];
- }
- }
- /**
- * Обрабатывает название региона для поиска его в fias
- * @param $zone_name
- * @return string
- */
- protected function prepareZoneNameForFias($zone_name)
- {
- return trim(str_replace("область", "", $zone_name));
- }
- /**
- * Инициализация полей.
- * @param array $data Значения для инициализации.
- */
- private function setFields($data = array())
- {
- if (!$data) {
- return NULL;
- }
- $fields = array("country_id", "country_name", "zone_id", "zone_name", "prefix_zone_name", "district_name", "prefix_district_name", "city_name", "prefix_city_name", "fias_country_id", "fias_zone_id", "fias_district_id", "fias_id", "postcode");
- if (empty($data["fias_id"])) {
- if (!empty($data["fias_zone_id"])) {
- $data["fias_id"] = $data["fias_zone_id"];
- } else {
- if (!empty($data["fias_country_id"])) {
- $data["fias_id"] = $data["fias_country_id"];
- }
- }
- }
- foreach ($fields as $field) {
- $this->{$field} = !empty($data[$field]) ? trim($data[$field]) : null;
- $this->setValueInSession($field, $this->{$field});
- }
- $this->setValueInSession("short_city_name", $this->setting("use_fullname_city") ? $this->getFullCityName() : $this->getCityName());
- if ($this->fias_id) {
- $this->setCookie($this->getCookieKey("fias"), $this->fias_id);
- }
- }
- public function defineLocation()
- {
- $sources = array("Session", "Cookie", "Drivers", "Config");
- foreach ($sources as $source) {
- if ($data = call_user_func(array($this, "getFrom" . $source))) {
- $this->log(print_r($data, true) . " from " . $source);
- if ($source == "Drivers") {
- if (!$this->checkDefaultCity($data)) {
- break;
- }
- } else {
- break;
- }
- }
- }
- $this->setFields($data);
- $this->checkRedirect();
- }
- private function getFromSession()
- {
- return !empty($this->session->data[$this->getSessionKey()]) ? $this->session->data[$this->getSessionKey()] : false;
- }
- private function getFromCookie()
- {
- if (!empty($this->request->cookie[$this->getCookieKey("fias")])) {
- $data = $this->getAllFields(array("fias_id" => $this->request->cookie[$this->getCookieKey("fias")]));
- if ($data) {
- return $data;
- }
- }
- return false;
- }
- private function getFromDrivers()
- {
- if (self::checkLicense($this->setting("secret_key"))) {
- foreach (self::$drivers as $driver) {
- $data = $driver->getGeoFilter();
- if ($data) {
- return $this->getAllFields($data);
- }
- }
- }
- return false;
- }
- private function getFromConfig()
- {
- return $this->setting("default_city") ? $this->getAllFields(array("fias_id" => $this->setting("default_city"))) : false;
- }
- /**
- * Проверка нужно ли устанавливать город по умолчанию
- * @return bool
- */
- private function checkDefaultCity($data)
- {
- if ($this->setting("default_city")) {
- switch ($this->setting("use_default_city")) {
- case "any_country":
- return empty($data["city_name"]);
- case "one_country":
- if (empty($data["city_name"]) && !empty($data["country_id"])) {
- $default_fias = $this->loadModel("fias")->getFiasById($this->setting("default_city"));
- $default_fias_country_id = 0;
- for ($i = 1; $i <= 4; $i++) {
- if ($default_fias["f" . $i . "_level"] == \ModelExtensionModuleProgromanFias::LEVEL_COUNTRY) {
- $default_fias_country_id = $default_fias["f" . $i . "_fias_id"];
- break;
- }
- }
- $fias_to_country = $this->loadModel("fias")->getFiasToCountry();
- if (isset($fias_to_country[$default_fias_country_id])) {
- return $fias_to_country[$default_fias_country_id]["country_id"] == $data["country_id"];
- }
- }
- break;
- default:
- return empty($data);
- }
- }
- return false;
- }
- public function setCurrency($force = false)
- {
- if ($this->setting("enable_switch_currency")) {
- $key = $this->getCookieKey("currency");
- if ($force || !isset($this->request->cookie[$key])) {
- $code = $this->loadModel("citymanager")->getCurrencyForCountry($this->country_id);
- $current_code = isset($this->session->data["currency"]) ? $this->session->data["currency"] : null;
- if ($code && $current_code != $code) {
- if (version_compare(VERSION, "2.0", "<")) {
- $this->registry->get("currency")->set($code);
- } else {
- $this->session->data["currency"] = $code;
- $this->setCookie("currency", $code);
- }
- $this->setCookie($key, $code);
- }
- }
- }
- }
- protected function setMessages()
- {
- if ($this->setting("enable_switch_messages")) {
- $messages = $this->loadModel("citymanager")->getMessages($this->getFiasIds());
- if (is_array($messages)) {
- $group_messages = array();
- foreach ($messages as $message) {
- $message["value"] = htmlspecialchars_decode($message["value"]);
- $group_messages[$message["key"]][] = $message;
- }
- foreach ($group_messages as $key => $group) {
- foreach ($group as $message) {
- if ($message["fias_id"] == $this->fias_id) {
- $this->messages[$key] = $message["value"];
- break;
- }
- if ($message["fias_id"] == $this->fias_zone_id) {
- $this->messages[$key] = $message["value"];
- } else {
- if ($message["fias_id"] == $this->fias_country_id && !isset($this->messages[$key])) {
- $this->messages[$key] = $message["value"];
- }
- }
- }
- }
- }
- }
- }
- public function getFiasIds()
- {
- $ids = array();
- if ($this->fias_id) {
- $ids[] = $this->fias_id;
- }
- if ($this->fias_zone_id) {
- $ids[] = $this->fias_zone_id;
- }
- if ($this->fias_country_id) {
- $ids[] = $this->fias_country_id;
- }
- return $ids;
- }
- public function getMessages()
- {
- if (is_null($this->messages)) {
- $this->setMessages();
- }
- return $this->messages;
- }
- public function getMessage($key, $default = "")
- {
- $this->getMessages();
- return isset($this->messages[$key]) ? $this->messages[$key] : $default;
- }
- protected function checkRedirect()
- {
- if (!$this->needRedirect()) {
- return NULL;
- }
- if ($redirect_url = $this->getRedirectUrl()) {
- $this->setValueInSession("redirected", 1);
- $location = str_replace(array("&", "\n", "\r"), array("&", "", ""), $redirect_url);
- $this->log("Location: " . $location);
- header("Location: " . $location, true, 302);
- exit;
- }
- }
- protected function getRedirectUrl($request_uri = false)
- {
- if (!$this->setting("enable_switch_redirects")) {
- return false;
- }
- $redirect_url = false;
- foreach ($this->getRedirects() as $redirect) {
- if ($redirect["fias_id"] == $this->fias_id) {
- $redirect_url = $redirect["url"];
- break;
- }
- if ($redirect["fias_id"] == $this->fias_zone_id) {
- $redirect_url = $redirect["url"];
- } else {
- if (!$redirect_url && $redirect["fias_id"] == $this->fias_country_id) {
- $redirect_url = $redirect["url"];
- }
- }
- }
- if (!$redirect_url) {
- $redirect_url = "http" . (\progroman\Util::isSSL() ? "s" : "") . "://" . $this->main_domain . "/";
- }
- if (!$request_uri) {
- $request_uri = $this->request->server["REQUEST_URI"];
- }
- $request_uri = ltrim($request_uri, "/");
- $new_request_uri = $request_uri;
- $paths = $this->getRedirectPaths();
- if ($request_uri && $paths) {
- $new_request_uri = preg_replace("#^(" . implode("|", $paths) . ")(?:/|\$)#iu", "", $request_uri);
- }
- $current_url = preg_replace("#^(www\\.)?#", "", $this->request->server["HTTP_HOST"]) . "/" . $request_uri;
- if (preg_replace("#^http(s)?://(www\\.)?#", "", $redirect_url) . $new_request_uri != $current_url) {
- return $redirect_url . $new_request_uri;
- }
- return false;
- }
- public function getRedirects()
- {
- if (!$this->redirects) {
- $this->redirects = $this->loadModel("citymanager")->getRedirects($this->getFiasIds());
- }
- return $this->redirects;
- }
- /**
- * @return array Список подкаталогов для редиректа, если есть.
- * site.com/spb/, site.com/msc/ => ['spb', 'msc']
- */
- protected function getRedirectPaths()
- {
- $paths = array();
- $regex = "#" . preg_quote($this->main_domain) . "/(.+)/\$#";
- foreach ($this->getRedirects() as $redirect) {
- if (preg_match($regex, $redirect["url"], $matches)) {
- $paths[] = $matches[1];
- }
- }
- return $paths;
- }
- /**
- * Проверка - нужно ли делать редирект
- * @return bool
- */
- protected function needRedirect()
- {
- if ($this->is_first_visit && $this->setting("disable_autoredirect") && !$this->getValueFromSession("force_redirect")) {
- return false;
- }
- if (\progroman\Util::isAjax() || self::isBot()) {
- return false;
- }
- return true;
- }
- /**
- * Проверка ботов ПС
- * @return bool
- */
- protected function isBot()
- {
- if (isset($_SERVER["HTTP_USER_AGENT"])) {
- foreach ($this->getBots() as $bot) {
- if (stripos($_SERVER["HTTP_USER_AGENT"], $bot) !== false) {
- return true;
- }
- }
- }
- return false;
- }
- protected function getBots()
- {
- return array();
- }
- public static function validLicense($license)
- {
- return self::checkLicense($license);
- }
- private static function checkLicense($license)
- {
- if ($license) {
- $settings = \progroman\Common\Registry::instance()->get("config")->get("module_progroman_citymanager_setting");
- $host = !empty($settings["main_domain"]) ? "//" . $settings["main_domain"] : (HTTPS_SERVER ? HTTPS_SERVER : HTTP_SERVER);
- $host = parse_url($host, PHP_URL_HOST);
- foreach (explode("|", $license) as $key) {
- $host_parts = explode(".", $host);
- while (self::verifySecrectKey(implode(".", $host_parts), $key)) {
- return true;
- }
- array_shift($host_parts);
- if (1 < count($host_parts)) {
- }
- }
- }
- return false;
- }
- private static function verifySecrectKey($host, $key)
- {
- $publickey = openssl_get_publickey("file://" . PROGROMAN_CITYMANAGER_DIR . "/public.key");
- return $publickey && openssl_verify($host, base64_decode($key), $publickey, OPENSSL_ALGO_SHA256);
- }
- public function setting($key, $value = NULL)
- {
- if (!is_null($value)) {
- $this->settings[$key] = $value;
- }
- return isset($this->settings[$key]) ? $this->settings[$key] : null;
- }
- /**
- * Загрузка модели
- * @param $model
- * @return ModelCityManager|ModelFias
- */
- protected function loadModel($model)
- {
- if (!isset($this->{"model_" . $model})) {
- $this->registry->get("load")->model("extension/module/progroman/" . $model);
- $this->{"model_" . $model} = $this->registry->get("model_extension_module_progroman_" . $model);
- }
- return $this->{"model_" . $model};
- }
- public function getSessionKey()
- {
- return $this->session_key;
- }
- protected function getValueFromSession($key)
- {
- return isset($this->session->data[$this->getSessionKey()][$key]) ? $this->session->data[$this->getSessionKey()][$key] : null;
- }
- protected function setValueInSession($key, $value)
- {
- if (in_array($key, array("force_redirect", "fias_id"))) {
- $this->session->data[$this->getSessionKey() . "." . $key] = $value;
- }
- $this->session->data[$this->getSessionKey()][$key] = $value;
- }
- public function setCookie($key, $value, $time = 2592000)
- {
- setcookie($key, $value, $time ? time() + $time : null, "/", $this->getCookieDomain());
- }
- public function getCookieKey($key)
- {
- return $this->cookie_prefix . $key;
- }
- protected function getCookieDomain()
- {
- $session_cookie_domain = ini_get("session.cookie_domain");
- $http_host = $this->request->server["HTTP_HOST"];
- if ($session_cookie_domain && strpos($http_host, ltrim($session_cookie_domain, ".")) !== false) {
- return $session_cookie_domain;
- }
- $main_domain = preg_replace("#^(www\\.)?#", "", $this->main_domain, 1);
- if (strpos($http_host, $main_domain) !== false) {
- return "." . $main_domain;
- }
- return "." . preg_replace("#^(www\\.)?#", "", $http_host, 1);
- }
- public static function addDriver($driver)
- {
- self::$drivers[] = $driver;
- }
- protected function log($message)
- {
- if ($this->dev_mode) {
- $this->logger->write($message);
- }
- }
- }
- ?>
Add Comment
Please, Sign In to add comment