<?php
/* * ********************************************************************************************
 * 								Open Real Estate
 * 								----------------
 * 	version				:	V1.36.0
 * 	copyright			:	(c) 2016 Monoray
 * 							http://monoray.net
 * 							http://monoray.ru
 *
 * 	website				:	http://open-real-estate.info/en
 *
 * 	contact us			:	http://open-real-estate.info/en/contact-us
 *
 * 	license:			:	http://open-real-estate.info/en/license
 * 							http://open-real-estate.info/ru/license
 *
 * This file is part of Open Real Estate
 *
 * ********************************************************************************************* */

/**
 * This is the model class for table "{{seo_friendly_url}}".
 *
 * The followings are the available columns in table '{{seo_friendly_url}}':
 * @property integer $id
 * @property string $model_name
 * @property integer $model_id
 * @property string $url_ru
 * @property string $url_en
 * @property string $title_ru
 * @property string $title_en
 * @property string $description_ru
 * @property string $description_en
 * @property string $keywords_ru
 * @property string $keywords_en
 */
class SeoFriendlyUrl extends ParentModel
{

    private static $_allActiveCityRoutes;
    private static $_allActiveObjTypesRoutes;

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return SeoFriendlyUrl the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return '{{seo_friendly_url}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        return array(
            array('model_name, model_id', 'required'),
            array('model_id', 'numerical', 'integerOnly' => true),
            array('model_name', 'length', 'max' => 20),
            array($this->i18nRules('url'), 'validUniqueUrl', 'except' => 'image'),
            array($this->i18nRules('url'), 'match', 'pattern' => '#^[-a-zA-Z0-9_+]{1,150}$#', 'message' => tc('It is allowed to use the characters "-a-zA-Z0-9_+" without spaces')), // допускаются любые символы кроме кириллицы
            array($this->i18nRules('url'), 'length', 'max' => 255),
            array($this->i18nRules('description'), 'length', 'max' => 255),
            array($this->i18nRules('keywords'), 'length', 'max' => 255),
            array($this->i18nRules('alt'), 'length', 'max' => 255),
            array($this->getI18nFieldSafe() . ', direct_url', 'safe'),
            array('url', 'i18nRequired', 'except' => 'image'),
            array('url_' . Yii::app()->language, 'uniqInLangs', 'except' => 'image'),
            array('id, model_name, model_id', 'safe', 'on' => 'search'),
        );
    }

    public function uniqInLangs($attribute, $params)
    {
        if (!$this->direct_url) {
            return;
        }

        $activeLangs = Lang::getActiveLangs();

        $allValue = array();
        foreach ($activeLangs as $lang) {
            $field = 'url_' . $lang;
            $allValue[] = $this->$field;
        }

//        if(array_diff_assoc($allValue, array_unique($allValue))){
//            $this->addError('url', tt('The same URL for different languages', 'seo'));
//        }
    }

    public function validUniqueUrl($attribute, $params)
    {
        $reservedUrl = array(
            'sitemap.xml',
            'yandex_export_feed.xml',
            'version',
            'sell',
            'rent',
            'rss',
            'entries',
            'faq',
            'login',
            'admin',
            'register',
            'recover',
            'reviews'
        );

        $langs = Lang::getActiveLangs(true);
        $reservedUrl = CMap::mergeArray($langs, $reservedUrl);

        $label = '';
        if (count($langs) > 1) {
            $ex = explode('_', $attribute);
            if (isset($ex[1]) && array_key_exists($ex[1], $langs)) {
                $label = 'url ' . $langs[$ex[1]]['name'] . ' - ';
            }
        }

        if ($this->direct_url && in_array($this->$attribute, $reservedUrl)) {
            $this->addError($attribute, $label . tt('This url already exists', 'seo'));
            return false;
        }

        $where = $this->isNewRecord ? '' : ' AND id != ' . $this->id;

        $arr = array();
        foreach ($langs as $lang) {
            $arr[] = 'url_' . $lang['name_iso'] . ' = :alias';
        }
        $condition = '(' . implode(' OR ', $arr) . ')';


        if ($this->direct_url) {
            $sql = "SELECT id FROM " . $this->tableName() . " WHERE direct_url=1 AND " . $condition . $where;
            $exist = Yii::app()->db->createCommand($sql)
                ->queryScalar(array(
                    ':alias' => $this->$attribute,
                ));
        } else {
            $sql = "SELECT id FROM " . $this->tableName() . " WHERE model_name=:model_name AND " . $condition . $where;
            $exist = Yii::app()->db->createCommand($sql)
                ->queryScalar(array(
                    ':alias' => $this->$attribute,
                    ':model_name' => $this->model_name,
                ));
        }

        if ($exist) {
            $this->addError($attribute, $label . tt('This url already exists', 'seo'));
            return false;
        }

        $this->clearErrors($attribute);
        return true;
    }

    public function i18nFields()
    {
        return array(
            'url' => 'varchar(255) not null default ""',
            'title' => 'varchar(255) not null default ""',
            'description' => 'varchar(255) not null default ""',
            'keywords' => 'varchar(255) not null default ""',
            'alt' => 'varchar(255) not null default ""',
            'body_text' => 'text null',
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        $relation = array();
        $relation['apartmentImages'] = array(self::BELONGS_TO, 'Images', 'model_id', 'on' => 'model_name="Images"');
        $relation['entriesImages'] = array(self::BELONGS_TO, 'EntriesImage', 'model_id', 'on' => 'model_name="EntriesImage"');
        $relation['objectImage'] = array(self::BELONGS_TO, 'ObjectImage', 'model_id');
        return $relation;
    }

    public function scopes()
    {
        return array(
            'notImages' => array(
                'condition' => $this->getTableAlias() . '.model_name <> "Images" AND ' . $this->getTableAlias() . '.model_name <> "EntriesImage" AND ' . $this->getTableAlias() . '.model_name <> "ObjectImage"',
            ),
            'onlyImages' => array(
                'condition' => $this->getTableAlias() . '.model_name = "Images" OR ' . $this->getTableAlias() . '.model_name = "EntriesImage" OR ' . $this->getTableAlias() . '.model_name = "ObjectImage"',
            ),
            'withNotEmptyAlt' => array(
                'condition' => 'LENGTH(' . $this->getTableAlias() . '.alt_' . Yii::app()->language . ') > 0 ',
            ),
            'locationModuleCity' => array(
                'condition' => $this->getTableAlias() . '.model_name <> "ApartmentCity"',
            ),
            'notLocationModuleCity' => array(
                'condition' => $this->getTableAlias() . '.model_name <> "City"',
            ),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'model_name' => tt('Model Name', 'seo'),
            'model_id' => tt('Model Id', 'seo'),
            'direct_url' => tt('Direct url', 'seo'),
            'body_text' => tt('Body text', 'seo'),
            'title' => tt('Title', 'seo'),
            'description' => tt('Description', 'seo'),
            'url' => tt('URL', 'seo'),
            'keywords' => tt('Keywords', 'seo'),
        );
    }

    public function afterSave()
    {
        if ($this->model_name && isset(SeoFriendlyUrlHistory::$_availableModelSave[$this->model_name])) {
            $modelHistory = new SeoFriendlyUrlHistory;

            foreach ($this->attributes as $attrName => $attrValue) {
                if ($modelHistory->hasAttribute($attrName) && $attrName != 'id') {
                    $modelHistory->setAttribute($attrName, $attrValue);
                }
            }

            $modelHistory->model_name = SeoFriendlyUrlHistory::$_availableModelSave[$this->model_name];
            $modelHistory->model_id = $this->model_id;
            $modelHistory->save(false);
        }

        return parent::afterSave();
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        $criteria = new CDbCriteria;
        $lang = Yii::app()->language;

        $criteria->compare($this->getTableAlias() . '.id', $this->id);
        $criteria->compare($this->getTableAlias() . '.model_name', $this->model_name);
        $criteria->compare($this->getTableAlias() . '.model_id', $this->model_id);

        $criteria->compare($this->getTableAlias() . ".url_{$lang}", $this->{'url_' . $lang}, true);
        $criteria->compare($this->getTableAlias() . ".title_{$lang}", $this->{'title_' . $lang}, true);
        $criteria->compare($this->getTableAlias() . ".alt_{$lang}", $this->{'alt_' . $lang}, true);
        $criteria->compare($this->getTableAlias() . ".body_text_{$lang}", $this->{'body_text_' . $lang}, true);

        $criteria->with = array('apartmentImages', 'apartmentImages.apartment', 'entriesImages', 'entriesImages.entry');

        return new CustomActiveDataProvider($this, array(
            'criteria' => $criteria,
            'sort' => array(
                'defaultOrder' => $this->getTableAlias() . '.id DESC',
            ),
            'pagination' => array(
                'pageSize' => param('adminPaginationPageSize', 20),
            ),
        ));
    }

    public function setDefault($model)
    {
        $this->model_id = $model->id;
        $this->model_name = get_class($model) == 'UserAds' ? 'Apartment' : get_class($model);

        $this->setSeoData($model);

        // проверяем есть ли такой урл, подбираем уникальный 10 раз
        for ($i = 0; $i < 10; $i++) {
            if ($this->validate('url_' . Lang::getDefaultLang())) {
                break;
            }

            $m = microtime(true);
            $tmp = (int)$m + mt_rand(0, 9999999);
            $this->setSeoData($model, $model->id + $tmp);
        }


        return true;
    }

    private function setSeoData($model, $postfix = '')
    {
        $langs = Lang::getActiveLangs();

        $params = CMap::mergeArray(array(
            'fieldTitle' => 'title',
            'fieldDescription' => 'description'
        ), $model->seoFields());

        foreach ($langs as $lang) {
            $fieldTitle = $params['fieldTitle'] . '_' . $lang;
            $fieldDescription = $params['fieldDescription'] . '_' . $lang;

            $fieldSeoTitle = 'title_' . $lang;
            $fieldSeoDescription = 'description_' . $lang;
            $fieldUrl = 'url_' . $lang;

            if (empty($model->$fieldTitle) || !$model->$fieldTitle) {
                return false;
            }

            $translitTitle = translit($model->$fieldTitle) . (param('genUrlWithID', 0) ? '-' . $model->id : '') . $postfix;

            $this->$fieldSeoTitle = $model->$fieldTitle;
            $this->$fieldUrl = $translitTitle;

            if (isset($model->$fieldDescription)) {
                $this->$fieldSeoDescription = mb_substr(trim(strip_tags($model->$fieldDescription)), 0, 255);
            }
        }
    }

    private static $_prefixUrlArray = array(
        'Apartment' => 'property/',
        'EntriesCategory' => '',
        'Entries' => '',
        'Article' => 'faq/',
        'InfoPages' => 'page/',
        'ApartmentObjType' => '',
        'City' => '',
        'ApartmentCity' => '',
    );

    public function getPrefixUrl()
    {
        return isset(self::$_prefixUrlArray[$this->model_name]) && !$this->direct_url ? self::$_prefixUrlArray[$this->model_name] : '';
    }

    public static $seoLangUrls = array();

    /**
     * @param $url
     * @param $modelName
     * @return SeoFriendlyUrl
     */
    public static function getForView($url, $modelName, $addParams = array())
    {
        if (param('urlExtension')) {
            $url = rstrtrim($url, '.html');
        }

        $seo = SeoFriendlyUrl::model()->findByAttributes(array(
            'model_name' => $modelName,
            'url_' . Yii::app()->language => $url
        ));

        # поищем в истории изменений ссылок
        if (!$seo) {
            $seo = SeoFriendlyUrlHistory::getFromHistory($url, $modelName);
        }

        if ($seo) {
            $activeLangs = Lang::getActiveLangs();
            foreach ($activeLangs as $lang) {
                $field = 'url_' . $lang;
                if (isset(self::$_prefixUrlArray[$modelName]) && isset($seo->$field)) {
                    if ($modelName == 'Entries') {
                        $entryModel = Entries::model()->findByPk($seo->model_id);
                        $seoEntriesCategories = SeoFriendlyUrl::model()->findByAttributes(array(
                            'model_name' => 'EntriesCategory',
                            'model_id' => $entryModel->category_id
                        ));

                        if ($seoEntriesCategories && isset($seoEntriesCategories->{'url_' . $lang})) {
                            $prefix = ($lang == Lang::getDefaultLang() ? '' : $lang . '/') . $seoEntriesCategories->{'url_' . $lang} . '/';
                        } elseif ($seo->direct_url) {
                            $prefix = '';
                        } else {
                            $prefix = ($lang == Lang::getDefaultLang() ? '' : $lang . '/') . self::$_prefixUrlArray[$modelName];
                        }
                    } elseif ($modelName == 'ApartmentObjType') {
                        if (isset($addParams['cityId'])) {
                            $cityId = $addParams['cityId'];
                            $searchModelName = (issetModule('location')) ? 'City' : 'ApartmentCity';
                            $seoCityModel = SeoFriendlyUrl::model()->findByAttributes(array(
                                'model_name' => $searchModelName,
                                'model_id' => $cityId
                            ));

                            if ($seoCityModel && isset($seoCityModel->{'url_' . $lang})) {
                                $prefix = ($lang == Lang::getDefaultLang() ? '' : $lang . '/') . $seoCityModel->{'url_' . $lang} . '/';
                            } elseif ($seo->direct_url) {
                                $prefix = '';
                            } else {
                                $prefix = ($lang == Lang::getDefaultLang() ? '' : $lang . '/') . self::$_prefixUrlArray[$modelName];
                            }
                        }
                    } else {
                        $prefix = $seo->direct_url ? '' : ($lang == Lang::getDefaultLang() ? '' : $lang . '/') . self::$_prefixUrlArray[$modelName];
                    }

                    if ($seo->$field) {
                        $prefixUrlExtension = (param('urlExtension') && ($modelName != 'EntriesCategory' && $modelName != 'ApartmentObjType' && $modelName != 'ApartmentCity' && $modelName != 'City')) ? '.html' : '';

                        self::$seoLangUrls[$lang] = Yii::app()->baseUrl . '/' . $prefix . $seo->$field . $prefixUrlExtension;
                    } else {
                        self::$seoLangUrls[$lang] = Yii::app()->baseUrl . '/' . $prefix . $seo->model_id;
                    }

                    //deb(self::$seoLangUrls);
                }
            }
        }

        //exit;
        return $seo;
    }

    private static $_cache;

    public static function getForUrl($id, $modelName)
    {
        if (!isset(self::$_cache[$modelName][$id])) {
            self::$_cache[$modelName][$id] = SeoFriendlyUrl::model()->findByAttributes(array('model_name' => $modelName, 'model_id' => $id));
        }

        return self::$_cache[$modelName][$id];
    }

    public static function getAndCreateForModel($model, $reset = false, $scenario = '')
    {
        if (!issetModule('seo')) {
            return false;
        }

        // костылек
        $modelName = get_class($model) == 'UserAds' ? 'Apartment' : get_class($model);

        $friendlyUrl = SeoFriendlyUrl::model()->findByAttributes(array(
            'model_name' => $modelName,
            'model_id' => $model->id
        ));

        if ($reset && $friendlyUrl) {
            $friendlyUrl->delete();
            $friendlyUrl = null;
        }

        // Если еще нет, создаем
        if (!$friendlyUrl) {
            $friendlyUrl = new SeoFriendlyUrl();
            if ($scenario) {
                $friendlyUrl->scenario = $scenario;
            }

            if ($model->id > 0 && $friendlyUrl->setDefault($model)) {
                $friendlyUrl->save();
            } else {
                $friendlyUrl->model_name = $modelName;
                $friendlyUrl->model_id = $model->id;
            }
        }

        return $friendlyUrl;
    }

    public static function getModelNameList()
    {
        $return = array();
        $return['Apartment'] = tt('Listing', 'seo');
        $return['Entries'] = tt('Entries', 'seo');
        $return['Article'] = tt('Article', 'seo');
        $return['InfoPages'] = tt('InfoPages', 'seo');
        $return['EntriesCategory'] = tt('EntriesCategory', 'seo');
        $return['ApartmentObjType'] = tt('ApartmentObjType', 'seo');
        $return['Images'] = tt('Listing images', 'seo');
        $return['ObjectImage'] = tc('Image');

        if (issetModule('location')) {
            $return['City'] = tt('City', 'seo');
        } else {
            $return['ApartmentCity'] = tt('City', 'seo');
        }

        return $return;
    }

    public static function getModelImagesNameList()
    {
        return array(
            'EntriesImage' => tt('Entries images', 'seo'),
            'Images' => tt('Listing images', 'seo'),
        );
    }

    public function getModelName()
    {
        $list = self::getModelNameList();
        return isset($list[$this->model_name]) ? $list[$this->model_name] : $this->model_name;
    }

    public function getModelImageName()
    {
        $list = self::getModelImagesNameList();
        return isset($list[$this->model_name]) ? $list[$this->model_name] : $this->model_name;
    }

    public function getUrlForTable()
    {
        $url = 'url_' . Yii::app()->language;
        return $this->{$url};
    }

    public function getAlt()
    {
        return $this->getStrByLang('alt');
    }

    public function getImageUrlForParent()
    {
        $return = '?';

        if (isset($this->apartmentImages) && isset($this->apartmentImages->apartment) && $this->apartmentImages->apartment) {
            $return = CHtml::link($this->apartmentImages->apartment->id, $this->apartmentImages->apartment->getUrl(), array('target' => '_blank'));
        } elseif (isset($this->entriesImages) && isset($this->entriesImages->entry) && $this->entriesImages->entry) {
            $return = CHtml::link($this->entriesImages->entry->id, $this->entriesImages->entry->getUrl(), array('target' => '_blank'));
        } elseif (isset($this->objectImage)) {
            $img = CHtml::image($this->objectImage->getSmallThumbLink());
            $return = CHtml::link($img, $this->objectImage->fullHref(), array('target' => '_blank', 'class' => 'fancy'));
        }

        return $return;
    }

    public static function getActiveCityRoute($params = null)
    {
        if (oreInstall::isInstalled()) {
            if (!empty($params)) {
                self::$_allActiveCityRoutes = null;
            }

            if (self::$_allActiveCityRoutes === null) {
                $citiesListModel = SeoFriendlyUrl::getAllActiveCities($params);
                $langs = Lang::getActiveLangs();
                $citiesListArr = array();

                if (!empty($citiesListModel)) {
                    foreach ($citiesListModel as $item) {
                        foreach ($langs as $lang) {
                            $citiesListArr[$item->id][$lang] = array(
                                'cityId' => $item->id,
                                'lang' => $lang,
                                'name' => $item->{'name_' . $lang},
                                //'url' => isset($item->{'url_' . $lang}) ? $item->{'url_' . $lang} : translit($item->{'name_' . $lang})
                                'url' => translit($item->{'name_' . $lang})
                            );
                        }
                    }
                }

                if (!empty($citiesListArr)) {
                    if (issetModule('seo')) {
                        $modelName = (issetModule('location')) ? 'City' : 'ApartmentCity';
                        $citiesSeoFriendlyList = SeoFriendlyUrl::model()->findAllByAttributes(array('model_name' => $modelName, 'model_id' => array_keys($citiesListArr)));
                        if (is_array($citiesSeoFriendlyList) && !empty($citiesSeoFriendlyList)) {
                            foreach ($citiesSeoFriendlyList as $city) {
                                foreach ($langs as $lang) {
                                    if (isset($citiesListArr[$city->model_id][$lang])) {
                                        $citiesListArr[$city->model_id][$lang]['url'] = $city->{'url_' . $lang};
                                    }
                                }
                            }
                        }
                    }
                }

                self::$_allActiveCityRoutes = $citiesListArr;
            }
        }

        return self::$_allActiveCityRoutes;
    }

    public static function getActiveObjTypesRoute($params = null, $onlyShowInSearch = false, $refresh = false)
    {
        if (oreInstall::isInstalled()) {
            if (!empty($params)) {
                self::$_allActiveObjTypesRoutes = null;
            }

            if (self::$_allActiveObjTypesRoutes === null || $refresh) {
                $objTypesListModel = SeoFriendlyUrl::getAllActiveObjTypes($params, $onlyShowInSearch);
                $langs = Lang::getActiveLangs();
                $objTypesListArr = array();

                if (!empty($objTypesListModel)) {
                    foreach ($objTypesListModel as $item) {
                        foreach ($langs as $lang) {
                            $objTypesListArr[$item->id][$lang] = array('objTypeId' => $item->id, 'lang' => $lang, 'name' => $item->{'name_' . $lang}, 'url' => translit($item->{'name_' . $lang}));
                        }
                    }
                }

                if (!empty($objTypesListArr)) {
                    if (issetModule('seo')) {
                        $objTypesSeoFriendlyList = SeoFriendlyUrl::model()->findAllByAttributes(array('model_name' => 'ApartmentObjType'));
                        if (is_array($objTypesSeoFriendlyList) && !empty($objTypesSeoFriendlyList)) {
                            foreach ($objTypesSeoFriendlyList as $objType) {
                                foreach ($langs as $lang) {
                                    if (isset($objTypesListArr[$objType->model_id][$lang])) {
                                        $objTypesListArr[$objType->model_id][$lang]['url'] = $objType->{'url_' . $lang};
                                    }
                                }
                            }
                        }
                    }
                }

                self::$_allActiveObjTypesRoutes = $objTypesListArr;
            }
        }

        return self::$_allActiveObjTypesRoutes;
    }

    public static function sortArrayByArray(array $array, array $orderArray)
    {
        $ordered = array();
        foreach ($array as $key => $value) {
            if (array_key_exists($key, $orderArray)) {
                $ordered[$key] = $orderArray[$key];
                unset($orderArray[$key]);
            }
        }
        return $ordered + $orderArray;
    }

    public static function getAllActiveCities($params = null)
    {
        $useSeasonalPrices = issetModule('seasonalprices');
        $modelName = (issetModule('location')) ? 'City' : 'ApartmentCity';
        $model = CActiveRecord::model($modelName);

        $paramsType = $paramsObjType = null;
        $paramsCountry = $paramsRegion = $paramsCity = null;
        $cityIds = array();

        if (!empty($params)) {
            $paramsCountry = (isset($params['country_id'])) ? $params['country_id'] : null;
            $paramsRegion = (isset($params['region_id'])) ? $params['region_id'] : null;
            $paramsCity = (isset($params['city_id'])) ? $params['city_id'] : null;
            $paramsType = (isset($params['type'])) ? $params['type'] : null;
            $paramsObjType = (isset($params['obj_type_id'])) ? $params['obj_type_id'] : null;
        }

        # объявления
        $criteriaApartments = new CDbCriteria;
        $locationField = (issetModule('location')) ? 'loc_city' : 'city_id';

        $criteriaApartments->select = $locationField;
        $criteriaApartments->group = $locationField;

        $useIndex = 'priceType_halfActive';

        //$criteriaApartments->addInCondition('price_type', array_keys(HApartment::getPriceArray(Apartment::PRICE_SALE, true)));

        $criteriaApartments->addCondition('active = ' . Apartment::STATUS_ACTIVE . '');
        if (param('useUserads')) {
            $criteriaApartments->addCondition('owner_active = ' . Apartment::STATUS_ACTIVE);
            $useIndex = 'priceType_fullActive';
        }

        if (!empty($paramsObjType)) {
            $criteriaApartments->compare('obj_type_id', $paramsObjType);
        }
        if (!empty($paramsType)) {
            if (strpos($paramsType, '-') !== false) {
                $typeArr = explode('-', $paramsType);
                $type = (int)$typeArr[0];
                $priceType = (int)$typeArr[1];
                if ($useSeasonalPrices) {
                    $criteriaApartments->addCondition('( id IN(SELECT apartment_id FROM {{seasonal_prices}} sp WHERE sp.price_type = :price_type ) OR (is_price_poa = 1) )');
                } else {
                    $criteriaApartments->addCondition('price_type = :price_type');
                }
                $criteriaApartments->params[':price_type'] = $priceType;
                $criteriaApartments->addCondition('type = :apType');
                $criteriaApartments->params[':apType'] = $type;
            } else {
                $criteriaApartments->addCondition('type = :apType');
                $criteriaApartments->params[':apType'] = (int)$paramsType;
            }
            $useIndex = 'type_' . $useIndex;
        }

        // hack
        #$criteriaApartments->join = "FORCE INDEX ({$useIndex})";

        $result = Apartment::model()->cache(param('cachingTime', 86400), Apartment::getDependency())->findAll($criteriaApartments);
        if ($result) {
            $cityIds = CHtml::listData($result, $locationField, $locationField);
        }


        // города
        $criteria = new CDbCriteria;
        $criteria->addCondition('t.active=1');

        if (!empty($paramsCountry)) {
            $criteria->compare('t.country_id', $paramsCountry);
        }
        if (!empty($paramsRegion)) {
            $criteria->compare('t.region_id', $paramsRegion);
        }
        if (!empty($paramsCity)) {
            if (is_array($paramsCity)) {
                $criteria->addInCondition('t.id', $paramsCity);
            } else {
                $criteria->compare('t.id', $paramsCity);
            }
        }

        $criteria->addInCondition('t.id', $cityIds);

        $criteria->order = 't.sorter';
        $criteria->group = 't.id';

        return $model->findAll($criteria);
    }

    public static function getAllActiveObjTypes($params = null, $onlyShowInSearch = false)
    {
        $paramsObjType = null;

        $criteria = new CDbCriteria;

        if (!empty($params)) {
            $paramsObjType = (isset($params['obj_type_id'])) ? $params['obj_type_id'] : null;

            if (!empty($paramsObjType)) {
                $criteria->compare('t.id', $paramsObjType);
            }
        }

        if ($onlyShowInSearch) {
            $criteria->compare('t.show_in_search', 1);
        }

        $listExclude = ApartmentObjType::getListExclude('search');
        if ($listExclude) {
            $criteria->addNotInCondition('id', $listExclude);
        }

        $criteria->order = 't.sorter';

        $result = ApartmentObjType::model()->findAll($criteria);

        return $result;
    }

    public static function getCountApartmentsForCategories($params = null)
    {
        $ownerActiveCond = $addCond = '';
        $addJoin = '';
        $addCondArr = array();

        $useSeasonalPrices = issetModule('seasonalprices');

        $paramsType = $paramsObjType = null;
        $paramsCountry = $paramsRegion = $paramsCity = null;

        if (!empty($params)) {
            $paramsCountry = (isset($params['country_id'])) ? $params['country_id'] : null;
            $paramsRegion = (isset($params['region_id'])) ? $params['region_id'] : null;
            $paramsCity = (isset($params['city_id'])) ? $params['city_id'] : null;
            $paramsType = (isset($params['type'])) ? $params['type'] : null;
            $paramsObjType = (isset($params['obj_type_id'])) ? $params['obj_type_id'] : null;
        }

        if (param('useUserads')) {
            $ownerActiveCond = ' AND owner_active = ' . Apartment::STATUS_ACTIVE . ' ';
        }

        if (issetModule('location')) {
            if (!empty($paramsCountry)) {
                $addCondArr[] = 'ap.loc_country = ' . $paramsCountry;
            }
            if (!empty($paramsRegion)) {
                $addCondArr[] = 'ap.loc_region = ' . $paramsRegion;
            }
            if (!empty($paramsCity)) {
                if (is_array($paramsCity)) {
                    $addCondArr[] = 'ap.loc_city IN (' . implode(',', $paramsCity) . ')';
                } else {
                    $addCondArr[] = 'ap.loc_city = ' . $paramsCity;
                }
            }
        } else {
            if (!empty($paramsCity)) {
                if (is_array($paramsCity)) {
                    $addCondArr[] = 'ap.city_id IN (' . implode(',', $paramsCity) . ')';
                } else {
                    $addCondArr[] = 'ap.city_id = ' . $paramsCity;
                }
            }
        }

        if (!empty($paramsObjType)) {
            $addCondArr[] = 'ap.obj_type_id = ' . $paramsObjType;
        }
        if (!empty($paramsType)) {
            if (strpos($paramsType, '-') !== false) {
                $typeArr = explode('-', $paramsType);
                $type = (int)$typeArr[0];
                $priceType = (int)$typeArr[1];
                if ($useSeasonalPrices) {
                    $addCondArr[] = '( ap.id IN(SELECT apartment_id FROM {{seasonal_prices}} sp WHERE sp.price_type = ' . $priceType . ' ) OR (ap.is_price_poa = 1) )';
                } else {
                    $addCondArr[] = 'ap.price_type = ' . $priceType;
                }
                $addCondArr[] = 'ap.type = ' . $type;
            } else {
                $addCondArr[] = 'ap.type = ' . (int)$paramsType;
            }
        }

        if (!empty($addCondArr)) {
            $addCond = implode(' AND ', $addCondArr);
            unset($addCondArr);
        }

        if (!empty($ownerActiveCond)) {
            if (!empty($addCond)) {
                $addCond = ' AND ' . $addCond;
            }
        }

        $locationField = (issetModule('location')) ? 'ap.loc_city' : 'ap.city_id';

        /*$sql = 'SELECT ap.obj_type_id, ' . $locationField . ' AS city, COUNT(ap.id) AS count FROM {{apartment}} ap ' . $addJoin . '
				WHERE ap.price_type IN (' . implode(',', array_keys(HApartment::getPriceArray(Apartment::PRICE_SALE, true))) . ')
				AND ap.obj_type_id IN (' . implode(',', array_keys(ApartmentObjType::getList('for_search'))) . ')
				AND ap.active = ' . Apartment::STATUS_ACTIVE . ' ' . $ownerActiveCond . $addCond . '
				GROUP BY ap.obj_type_id, ' . $locationField;*/
        $sql = 'SELECT ap.obj_type_id, ' . $locationField . ' AS city, COUNT(ap.id) AS count FROM {{apartment}} ap ' . $addJoin . '
				WHERE ap.obj_type_id IN (' . implode(',', array_keys(ApartmentObjType::getList('for_search'))) . ')
				AND ap.active = ' . Apartment::STATUS_ACTIVE . ' ' . $ownerActiveCond . $addCond . '
				GROUP BY ap.obj_type_id, ' . $locationField;
        $result = Yii::app()->db->cache(param('cachingTime', 86400))->createCommand($sql)->queryAll();
        return $result;
    }
}
