From dd0ece2cba948ff7fd77b326275642393eaee254 Mon Sep 17 00:00:00 2001 From: pafnuty Date: Sat, 22 Feb 2020 19:16:43 +0400 Subject: [PATCH 1/5] 6.0.0 First iteration --- CHANGELOG.md | 9 +- README.md | 15 +- blockpro.xml | 24 + blockpro_install.php | 1537 ----------------- bp_check.php | 262 --- engine/inc/blockpro.php | 2 +- engine/modules/base/blockpro.php | 23 +- engine/modules/base/core/base.php | 1096 ++++++------ engine/modules/base/core/bpModifiers.php | 1140 ++++++------ templates/Default/blockpro/css/index.htm | 8 - templates/Default/blockpro/index.htm | 8 - templates/Default/blockpro/js/blockpro.js | 64 +- templates/Default/blockpro/js/blockpro_new.js | 197 --- templates/Default/blockpro/js/index.htm | 8 - 14 files changed, 1252 insertions(+), 3141 deletions(-) create mode 100644 blockpro.xml delete mode 100644 blockpro_install.php delete mode 100644 bp_check.php delete mode 100644 templates/Default/blockpro/css/index.htm delete mode 100644 templates/Default/blockpro/index.htm delete mode 100644 templates/Default/blockpro/js/blockpro_new.js delete mode 100644 templates/Default/blockpro/js/index.htm diff --git a/CHANGELOG.md b/CHANGELOG.md index 9646de7..a2a4a11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ +# 6.0.0 +- Теперь модуль не гарантирует совместимость со версиями DLE ниже, чем 13.x и скоро будет убрана их поддержка полностью. +- Установка в виде плагина. +- Исправлена ошибка с вариантом сортировки `randomLight`, когда новости не найдены. +- Добавлен новый модификатор `sentence`, позволяющий вывести заданное количество предложений (до точки). Например `{$el.short_story|sentence:'2'}` - выведет два первых предложения из краткой новости. +- Небольшие изменения и улучшения в коде. + # 5.1.5 - Исправлена ошибка `Error: Syntax error, unrecognized expression: Deprecated: Array and string offset access syntax with curly braces is deprecated` (#159) -- Добавлен модификатор jsonDecode для более удобного перобразования кода в JSON (Используйте его, если не работает json_decode) +- Добавлен модификатор `jsonDecode` для более удобного перобразования кода в JSON (Используйте его, если не работает json_decode) # 5.1.4 - Исправлена работа постраничной навигации при `catId=this` (#144) diff --git a/README.md b/README.md index 10254bf..9170fe2 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ # DLE-BlockPro — тот самый модуль для вывода новостей! -![version](https://img.shields.io/badge/version-5.1.5-red.svg?style=flat-square "Version") -![DLE](https://img.shields.io/badge/DLE-10.x-green.svg?style=flat-square "DLE Version") +![version](https://img.shields.io/badge/version-6.0.0-red.svg?style=flat-square "Version") +![DLE](https://img.shields.io/badge/DLE-13.x-green.svg?style=flat-square "DLE Version") [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/dle-modules/DLE-BlockPro/blob/master/LICENSE) -- **ВНИМАНИЕ!** **Работа модуля в кодировке windows-1251 не гарантируется** - Краткая информация о шаблонных тега прописана в шаблоне **{THEME}/blockpro/blockpro.tpl**, расширенный пример **{THEME}/blockpro/fullexample.tpl** - Более детальная информация по используемому шаблонизатору модуля находится в [документации по шаблонизатору](https://github.com/bzick/fenom/blob/master/docs/ru/readme.md) - Официальный сайт: [bp.pafnuty.name](http://bp.pafnuty.name/) @@ -11,5 +10,11 @@ - [История изменений](https://github.com/dle-modules/DLE-BlockPro/blob/master/CHANGELOG.md) ## Установка модуля -1. Залить содержимое папки **upload** в корень сайта. -2. Запустить **/blockpro_install.php** и следовать инструкции. + +1. Устанавливаем как обычный плагин, файл **blockpro_plugin.zip** содержит всё необходимое для автоматической установки. +2. Открыть файл `/templates/Default/main.tpl` +3. Добавить после `{AJAX}` или после `{jsfiles}`: +`` +4. Добавить после `{AJAX}` или после `{jsfiles}`: +`` + diff --git a/blockpro.xml b/blockpro.xml new file mode 100644 index 0000000..d44b29d --- /dev/null +++ b/blockpro.xml @@ -0,0 +1,24 @@ + + + BlockPro + Модуль BlockPro предназначен для пользовательского вывода новостей на сайте под управлением CMS DataLife Engine и позиционируется как альтернатива {custom}, {top}, {related-news}. + engine/skins/images/blockpro.png + 6.0.0 + 10.2 + greater + http://blockpro.loc/check_updates.php + 1 + + + + + + \ No newline at end of file diff --git a/blockpro_install.php b/blockpro_install.php deleted file mode 100644 index 2c268c0..0000000 --- a/blockpro_install.php +++ /dev/null @@ -1,1537 +0,0 @@ - 'blockpro', - // Название модуля - показывается как в установщике, так и в админке. - 'moduleTitle' => 'BlockPro', - // Описание модуля, для установщика и админки. - 'moduleDescr' => 'Модуль вывода новостей для DLE', - // Версия модуля, для установщика - 'moduleVersion' => '5.1.5', - // Дата выпуска модуля, для установщика - 'moduleDate' => '01.12.2019', - // Версии DLE, поддержваемые модулем, для установщика - 'dleVersion' => '10.x', - // ID групп, для которых доступно управление модулем в админке. - 'allowGroups' => '1', - // Массив с запросами, которые будут выполняться при установке - 'queries' => [ - 1 => 'CREATE TABLE IF NOT EXISTS `' . PREFIX . '_blockpro_blocks` ( - `id` tinyint(6) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `block_id` varchar(100) NOT NULL, - `params` mediumtext NOT NULL, - `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - KEY `block_id` (`block_id`) -) ENGINE=MyISAM;', - ], - // Устанавливать админку (true/false). Включает показ кнопки установки и удаления админки. - 'installAdmin' => true, - // Отображать шаги утановки модуля - 'steps' => true, - // Показывать лицензионное соглашение? - 'showLicense' => true, - -]; - -// Определяем кодировку. -$fileCharset = chasetConflict($cfg); - -// Лицензионное соглашение - -$licenseText = '

MIT License

Copyright (c) 2017 Модули для DataLife Engine

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

'; - -// Лицензионное соглашение -// Шаги установки модуля -/** @var array $config */ -$steps = <<Редактирование файлов -
    -
  1. - Открыть файл /templates/{$config['skin']}/main.tpl -
  2. -
  3. - Добавить после {AJAX} или после {jsfiles}: - -
  4. -
  5. - Добавить после {AJAX} или после {jsfiles}: - - или - - если хотите использовать возможность навигации по стрелкам браузера при ajax-переключении страниц модуля. -
  6. -
  7. Выполнить установку админчасти и таблиц модуля (кнопка ниже).
  8. -
-HTML; - - -function installer() { - global $config, $dle_api, $cfg, $steps, $fileCharset, $licenseText; - - $output = $queriesTxt = ''; - - $queries = (count($cfg['queries'])) ? true : false; - $adminInstalled = false; - if ($cfg['installAdmin']) { - $aq = $dle_api->db->super_query("SELECT name FROM " . PREFIX . "_admin_sections WHERE name = '{$cfg['moduleName']}'"); - - $adminInstalled = ($aq['name'] == $cfg['moduleName']) ? true : false; - - } - if (isset($_POST['notaccept']) && $cfg['showLicense'] && !$adminInstalled) { - $output = << -
-
- Вы отказались от установки модуля.
Не забудьте удалить загруженные файлы. -
-
- -HTML; - } elseif (empty($_POST['accept']) && $cfg['showLicense'] && !$adminInstalled) { - $output = << -
-
- $licenseText -
-
- - -
-
- -HTML; - } else { - if ($queries) { - foreach ($cfg['queries'] as $qq) { - $queriesTxt .= ''; - } - } - - - // Если через $_POST передаётся параметр install, производим инсталляцию, согласно параметрам - if (!empty($_POST['install'])) { - // Выводим результаты установки модуля - $output .= '
'; - $output .= '
Не забудьте удалить файлы установщика (blockpro_install.php и bp_check.php)!
'; - /** @var bool $install_admin */ - if ($cfg['installAdmin'] && $install_admin) { - $output .= '

Настройка модуля


'; - } - - } // Если через $_POST передаётся параметр remove, производим удаление админчасти модуля - elseif (!empty($_POST['remove'])) { - $dle_api->uninstall_admin_module($cfg['moduleName']); - $output .= '

Админчасть модуля удалена

'; - $output .= '
Не забудьте удалить файл установщика!
'; - } // Если через $_POST ничего не передаётся, выводим форму для установки модуля - else { - // Выводим кнопку удаления модуля - if ($cfg['installAdmin'] && $adminInstalled) { - $uninstallForm = << -
-
Удаление админчасти модуля
-
- - - -
-
-HTML; - } - // Выводим кнопку установки модуля с допзпросами - if ($queries) { - $installForm = << -
- - - - Какие запросы будут выполнены? -
- -
-
- $queriesTxt -
-
-HTML; - } // Выводим кнопку установки админчасти модуля - else { - if (!$adminInstalled) { - $installForm = << -
Установка админчасти
-
-
- - -
-
- -HTML; - } - } - - // Вывод - if ($cfg['steps']) { - $output .= $steps; - } - /** @var string $installForm */ - /** @var string $uninstallForm */ - $output .= <<Перед установкой модуля обязательно сделайте бэкап БД!

-
-

Установка таблиц модуля и админчасти

- - $installForm - $uninstallForm -
-HTML; - - - } - - } - - - // Если руки пользователя кривые, или он просто забыл перекодировать файлы - скажем ему об этом. - if ($fileCharset['conflict']) { - $output = '

Ошибка!

Кодировка файла установщика (' . $fileCharset['charset'] . ') не совпадает с кодировкой сайта (' . $config['charset'] . ').
Установка не возможна.
Перекодируйте все php файлы модуля и запустите установщик ещё раз.


'; - } - - // Функция возвращает то, что должно быть выведено - return $output; -} - -/** - * Отлавливаем данные о кодировке файла (utf-8 или windows-1251); - * - * @param string $string - строка (или массив), в которой требуется определить кодировку. - * - * @return array - возвращает массив с определением конфликта кодировки строки и сайта, а так же сму кодировку - * строки. - */ -function chasetConflict($string) { - global $config; - if (is_array($string)) { - $string = implode(' ', $string); - } - $detect = preg_match('%(?: - [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte - |\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs - |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte - |\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates - |\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 - |[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 - |\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 - )+%xs', $string); - $stringCharset = ($detect == '1') ? 'utf-8' : 'windows-1251'; - $config['charset'] = strtolower($config['charset']); - $return = []; - $return['conflict'] = ($stringCharset == $config['charset']) ? false : true; - $return['charset'] = $stringCharset; - - return $return; -} - -?> - - - - - <?php echo $cfg['moduleTitle'] ?> - - - - - -
-
-
-
- -
-
-
-
-
-
-

v. - от

-
Установка модуля
-
-
-
-
-
-
-
- -
-
-
- -
-
-
-
- Контакты для связи и техподдержки:
- BlockPro — техподдержка
- bp.pafnuty.name — документация
-
-
-
- - -
- - - diff --git a/bp_check.php b/bp_check.php deleted file mode 100644 index 4323024..0000000 --- a/bp_check.php +++ /dev/null @@ -1,262 +0,0 @@ - 'Версия DLE', - 'req' => '10.0', - 'check' => ($config['version_id'] < 10.0) ? '' . $config['version_id'] . '' : $config['version_id'], - ), - array( - 'name' => 'Кодировка', - 'req' => 'utf-8', - 'check' => ($config['charset'] != 'utf-8') ? '' . $config['charset'] . '' : $config['charset'], - ), - array( - 'name' => 'Версия php', - 'req' => '5.6 и выше', - 'check' => (phpversion() < 5.6) ? '' . phpversion() . '' : phpversion(), - ) - -); - -function checkIonCube() { - if (function_exists('ioncube_loader_version')) { - return ioncube_loader_version(); - } else { - return 'не найдено'; - } -} - -function checkShortOpenTag() { - if (ini_get('short_open_tag')) { - return 'On'; - } else { - return 'Off'; - } - -} - -?> - - - - - BlockPro Checker - - -
-
-
-

Проверка совместимости текущего сайта и модуля BlockPro

-
-
- -
- - - - - - - $check): ?> - - - - - - -
ПараметрТребованиеНаличие
-

- Если один или несколько пунктов отмечены красным цветом — модуль не - запустится на вашем сайте при текущих настройках. Необходимо исправить несоответсвия. -

- -

- Если всё в порядке — можно смело устанавливать модуль! -

-
-
- -
- - - diff --git a/engine/inc/blockpro.php b/engine/inc/blockpro.php index d355082..1587b36 100644 --- a/engine/inc/blockpro.php +++ b/engine/inc/blockpro.php @@ -29,7 +29,7 @@ define('MODULE_DIR', ENGINE_DIR . '/modules/base/admin/blockpro/'); $moduleName = 'blockpro'; -$moduleVersion = '5.1.5'; +$moduleVersion = '6.0.0'; $moderate = $_REQUEST['moderate']; $moderate_checked = ($moderate) ? 'checked' : ''; diff --git a/engine/modules/base/blockpro.php b/engine/modules/base/blockpro.php index 0f8db25..e092d66 100644 --- a/engine/modules/base/blockpro.php +++ b/engine/modules/base/blockpro.php @@ -893,16 +893,19 @@ classic: << Первая < 1 [2] 3 > Последняя >> shuffle($randDiapazone); // Возьмём только нужное количество элементов $randIds = array_slice($randDiapazone, 0, $base->cfg['limit']); - $randIds = implode(',', $randIds); - // Удалим из памяти ненужное - unset($randDiapazone); - unset($randWhere); - // Сбрасываем ненужные условия выборки - $wheres = []; - // Задаём условие выборки по предварительно полученным ID - $wheres[] = 'id IN (' . $randIds . ')'; - // И выводим в том порядке, в ктором сформировались ID - $orderArr = ['FIELD (p.id, ' . $randIds . ')']; + // Удалим из памяти ненужное + unset($randDiapazone); + unset($randWhere); + // Если вдруг не получится набрать элементы в принципе + if (count($randIds)) { + $randIds = implode(',', $randIds); + // Сбрасываем ненужные условия выборки + $wheres = []; + // Задаём условие выборки по предварительно полученным ID + $wheres[] = 'id IN (' . $randIds . ')'; + // И выводим в том порядке, в ктором сформировались ID + $orderArr = ['FIELD (p.id, ' . $randIds . ')']; + } } // Складываем условия diff --git a/engine/modules/base/core/base.php b/engine/modules/base/core/base.php index c44447e..d864f6c 100644 --- a/engine/modules/base/core/base.php +++ b/engine/modules/base/core/base.php @@ -12,435 +12,450 @@ */ if (!defined('DATALIFEENGINE')) { - header( "HTTP/1.1 403 Forbidden" ); - header ( 'Location: ../../' ); - die( "Hacking attempt!" ); + header("HTTP/1.1 403 Forbidden"); + header('Location: ../../'); + die("Hacking attempt!"); } -define('BASE_DIR', ENGINE_DIR . '/modules/base'); +define('BASE_DIR', ENGINE_DIR.'/modules/base'); -require_once(BASE_DIR . '/core/Fenom.php'); -\Fenom::registerAutoload(BASE_DIR . '/core/'); +require_once(BASE_DIR.'/core/Fenom.php'); +Fenom::registerAutoload(BASE_DIR.'/core/'); -include_once ENGINE_DIR . '/plugins/loader/loader.php'; +include_once ENGINE_DIR.'/plugins/loader/loader.php'; -require_once(DLEPlugins::Check(ENGINE_DIR . '/modules/functions.php')); +require_once(DLEPlugins::Check(ENGINE_DIR.'/modules/functions.php')); /** * BaseClass */ class base { - public $result; - - public $dle_config = []; - public $cfg = []; - public $tplOptions = []; - public $tpl; - public $db; - const ROOT_DIR = ROOT_DIR; - const ENGINE_DIR = ENGINE_DIR; - const BASE_DIR = BASE_DIR; - - function __construct() { - - // Подключаем конфиг DLE - $this->dle_config = $this->getDleConfig(); - - // Подключаем конфиг blockpro - $this->bpConfig = $this->getBpConfig(); - - // Подключаем класс для работы с БД - $this->db = $this->getDb(); - - } - - public static function getDb() { - return SafeMySQL::getInstanse( - [ - 'host' => DBHOST, - 'user' => DBUSER, - 'pass' => DBPASS, - 'db' => DBNAME, - 'charset' => COLLATE, - ] - ); - } - - public function getTemplater($tplOptions) { - $this->tpl = Fenom::factory( - ROOT_DIR . '/templates/' . $this->dle_config['skin'] . '/', - ENGINE_DIR . '/cache/', - $tplOptions - ); - // Добавляем модификаторы - $this->addModifiers(); - } - - public function setConfig($cfg = []) { - return $cfg; - } - - /** - * @return mixed - */ - public static function getDleConfig() { - include(ENGINE_DIR . '/data/config.php'); - - /** @var array $config */ - return $config; - } - - /** - * @return mixed - */ - public static function getBpConfig() { - include(ENGINE_DIR . '/data/blockpro.php'); - - /** @var array $bpConfig */ - return $bpConfig; - } - - /** - * - */ - public function addModifiers() { - - $config = $this->dle_config; - $db = $this->db; - $configForResizer = $this->bpConfig; - $configForResizer['http_home_url'] = $this->dle_config['http_home_url']; - - // Добавляем свой модификатор в шаблонизатор для ограничения кол-ва символов в тексте - $this->tpl->addModifier( - 'limit', function ($data, $limit, $etc = '…', $wordcut = false) use ($config) { - return bpModifiers::textLimit($data, $limit, $etc, $wordcut, $config['charset']); - } - ); - - // Добавляем свой модификатор в шаблонизатор для вывода картинок - $this->tpl->addModifier( - 'image', function ($data, $noimage = '', $imageType = 'small', $number = 1, $size, $quality = '100', $resizeType = 'auto', $grabRemote = true, $showSmall = false, $subdir = false) use ($configForResizer) { - return bpModifiers::getImage($data, $noimage, $imageType, $number, $size, $quality, $resizeType, $grabRemote, $showSmall, $subdir, $configForResizer); - } - ); - - // Добавляем свой модификатор в шаблонизатор для вывода картинок через tinypng - $this->tpl->addModifier( - 'tinypng', function ($data, $noimage = '', $imageType = 'small', $number = 1, $size, $quality = '100', $resizeType = 'fit', $grabRemote = true, $showSmall = false, $subdir = false) use ($configForResizer) { - return bpModifiers::getImage($data, $noimage, $imageType, $number, $size, $quality, $resizeType, $grabRemote, $showSmall, $subdir, $configForResizer, 'tinypng'); - } - ); - - // Добавляем свой модификатор в шаблонизатор для вывода картинок через kraken - $this->tpl->addModifier( - 'kraken', function ($data, $noimage = '', $imageType = 'small', $number = 1, $size, $quality = '100', $resizeType = 'auto', $grabRemote = true, $showSmall = false, $subdir = false) use ($configForResizer) { - return bpModifiers::getImage($data, $noimage, $imageType, $number, $size, $quality, $resizeType, $grabRemote, $showSmall, $subdir, $configForResizer, 'kraken'); - } - ); - - // Добавляем свой модификатор в шаблонизатор для вывода print_r - $this->tpl->addModifier( - 'dump', function ($data) { - return bpModifiers::dump($data); - } - ); - - // Добавляем модификатор для получения списка пользователей - $this->tpl->addModifier( - 'getAuthors', function ($data, $fields = false) use ($db) { - return bpModifiers::getAuthors($data, $fields, $db); - } - ); - - // Добавляем свой модификатор в шаблонизатор для вывода картинок - $this->tpl->addModifier( - 'declination', function ($n, $word) { - return bpModifiers::declinationWords($n, $word); - } - ); - - // Добавляем свой модификатор в шаблонизатор для вывода форматированной даты - $this->tpl->addModifier( - 'dateformat', function ($data, $_f = false) { - return formateDate($data, $_f); - } - ); - - // Добавляем свой модификатор в шаблонизатор для вывода информации о категории новости - $this->tpl->addModifier( - 'catinfo', function ($data, $info = false, $noicon = false) { - return getCatInfo($data, $info, $noicon); - } - ); - - // Добавляем свой модификатор в шаблонизатор для реализации preg_match_all - $this->tpl->addModifier( - 'ematch_all', function ($data, $pattern) { - preg_match_all($pattern, $data, $arReturn); - $arReturn = array_filter($arReturn); - return $arReturn; - } - ); - - // Добавляем свой модификатор в шаблонизатор для вывода даты в формате "time ago". - $this->tpl->addModifier( - 'timeago', function ($data, $precision = 2) { - return bpModifiers::timeAgo($data, $precision); - } - ); - - // Добавляем свой модификатор в шаблонизатор для конвертации текста в json. - $this->tpl->addModifier( - 'jsonDecode', function ($data) { - return bpModifiers::jsonDecode($data); - }); - } - - /** - * @param $data - массив с информацией о статье - * - * @return string URL для категории - */ - - public function getPostUrl($data) { - - $data['date'] = strtotime($data['date']); - - if ($this->dle_config['allow_alt_url'] && $this->dle_config['allow_alt_url'] != 'no') { - if ( - ($this->dle_config['version_id'] < 9.6 && $this->dle_config['seo_type']) - || - ($this->dle_config['version_id'] >= 9.6 && ($this->dle_config['seo_type'] == 1 || $this->dle_config['seo_type'] == 2)) - ) { - if (intval($data['category']) && $this->dle_config['seo_type'] == 2) { - $url = $this->dle_config['http_home_url'] . get_url(intval($data['category'])) . '/' . $data['id'] . '-' . $data['alt_name'] . '.html'; - } else { - $url = $this->dle_config['http_home_url'] . $data['id'] . '-' . $data['alt_name'] . '.html'; - } - } else { - $url = $this->dle_config['http_home_url'] . date('Y/m/d/', $data['date']) . $data['alt_name'] . '.html'; - } - } else { - $url = $this->dle_config['http_home_url'] . 'index.php?newsid=' . $data['id']; - } - - return $url; - } - - /** - * Получение диапазона между двумя цифрами, и не только - * - * @param bool $diapazone - * @param bool $subcats - * - * @return string - * @author Elkhan I. Isaev - */ - - public function getDiapazone($diapazone = false, $subcats = false) { - if ($diapazone !== false) { - $diapazone = str_replace(" ", "", $diapazone); - - if (strpos($diapazone, ',') !== false) { - $diapazoneArray = explode(',', $diapazone); - $diapazoneArray = array_diff($diapazoneArray, [NULL]); - - foreach ($diapazoneArray as $v) { - if (strpos($v, '-') !== false) { - preg_match("#(\d+)-(\d+)#i", $v, $test); - - $diapazone = !empty($diapazone) && is_array($diapazone) ? - array_merge($diapazone, (!empty ($test) ? range($test[1], $test[2]) : [])) - : (!empty ($test) ? range($test[1], $test[2]) : []); - - } else { - $diapazone = !empty($diapazone) && is_array($diapazone) ? - array_merge($diapazone, (!empty ($v) ? [(int)$v] : [])) - : (!empty ($v) ? [(int)$v] : []); - } - } - - } elseif (strpos($diapazone, '-') !== false) { - - preg_match("#(\d+)-(\d+)#i", $diapazone, $test); - $diapazone = !empty ($test) ? range($test[1], $test[2]) : []; - - } else { - $diapazone = [(int)$diapazone]; - } - if (!empty($diapazone)) { - if ($subcats && function_exists('get_sub_cats')) { - foreach ($diapazone as $d) { - $_sc = explode('|', get_sub_cats($d)); - foreach ($_sc as $v) { - array_push($diapazone, $v); - } - } - } - $diapazone = array_unique($diapazone); - } else { - $diapazone = []; - } - - $diapazone = implode(',', $diapazone); - } - - return $diapazone; - - } - - /** - * Формируем ссылки с тегами - * - * @param string $tags строка с тегами - * - * @return string строка с сылками - */ - - public function tagsLink($tags) { - $showTags = ''; - if ($this->dle_config['allow_tags'] && $tags) { - $showTagsArr = []; - $tags = explode(",", $tags); - - foreach ($tags as $value) { - $value = trim($value); - if ($this->dle_config['allow_alt_url'] && $this->dle_config['allow_alt_url'] != 'no') { - $showTagsArr[] = "dle_config['http_home_url'] . "tags/" . urlencode($value) . "/\">" . $value . ""; - } else { - $showTagsArr[] = "dle_config['http_home_url'] . "?do=tags&tag=" . urlencode($value) . "\">" . $value . ""; - } - - $showTags = implode(', ', $showTagsArr); - } - } - - return $showTags; - } - - /** - * Получаем несколько уникальных случайных чисел в заданном диапазоне - * - * @param integer $from от - * @param integer $to до - * @param integer $count кол-во чисел - * - * @return array массив с числами - */ - public function getRand($from = 1, $to = 2000, $count = 15) { - $arNumbers = $tmp = []; - for ($i = 0; $i < $count; $i++) { - do { - $a = mt_rand($from, $to); - } while (isset($tmp[$a])); - $tmp[$a] = $from; - $arNumbers[] = $a; - } - unset($tmp); - - return $arNumbers; - } - - /** - * Получаем готовую строку для вставки в запрос из условий фильтрации - * - * Пример использования в строке подключения - * setFilter=p.full_story|SEARCH|text1|OR|p.full_story|SEARCH|text2 - * - * @param string $setFilterStr строка с условиями фильтрации - * - * @return string Строка для использования в качестве части заброса в БД - */ - public function prepareFilterQuery($setFilterStr='') { - if(!$setFilterStr || $setFilterStr === '') { - return false; - } - - // Разбиваем строку на условия "OR", если есть. - $filterItems = explode('|OR|', $setFilterStr); - - - $hasOrCondition = count($filterItems) > 1; - - $queryParts = []; - - foreach ($filterItems as $strItem) { - - // Разбиваем на части запроса - $arFItem = explode('|', $strItem, 3); - - $field = $arFItem[0]; - $operator = ''; - - // Т.к. DLE не позволяет передавать напрямую символы '>' и '<', приходится изобретать собственный велосипед. - switch ($arFItem[1]) { - case '-': - case 'lt': - $operator = ' < '; - break; - - case '+': - case 'gt': - $operator = ' > '; - break; - - case '=': - case 'eq': - $operator = ' = '; - break; - - case '+=': - case 'gte': - $operator = ' >= '; - break; - - case '-=': - case 'lte': - $operator = ' <= '; - break; - - case '+-': - case '-+': - case 'not': - $operator = ' != '; - break; - - case 'SEARCH': - $operator = ' LIKE '; - break; - - case 'NOT_SEARCH': - $operator = ' NOT LIKE '; - break; - } - - - if ($arFItem[2] == 'NOW()') { - // Если нужно отобрать "сейчас" - $itemVal = 'NOW()'; - } elseif ($arFItem[1] == 'SEARCH' || $arFItem[1] == 'NOT_SEARCH') { - // Реализация поиска - $itemVal = $this->db->parse('?s', '%' . $arFItem[2] . '%'); - } else { - // В противном случае фильтруем. - $_op = (is_numeric($arFItem[2])) ? '?i' : '?s'; - $itemVal = $this->db->parse($_op, $arFItem[2]); - } - - if ($operator !== '') { - $queryParts[] = $field . $operator . $itemVal; - } - } - - $strAueryPart = implode(' OR ', $queryParts); - - if ($hasOrCondition) { - $strAueryPart = '(' . $strAueryPart . ')'; - } - - return $strAueryPart; - } + const ROOT_DIR = ROOT_DIR; + const ENGINE_DIR = ENGINE_DIR; + const BASE_DIR = BASE_DIR; + public $result; + public $dle_config = []; + public $cfg = []; + public $tplOptions = []; + public $tpl; + public $db; + + function __construct() { + + // Подключаем конфиг DLE + $this->dle_config = $this->getDleConfig(); + + // Подключаем конфиг blockpro + $this->bpConfig = $this->getBpConfig(); + + // Подключаем класс для работы с БД + $this->db = $this->getDb(); + + } + + /** + * @return mixed + */ + public static function getDleConfig() { + include(ENGINE_DIR.'/data/config.php'); + + /** @var array $config */ + return $config; + } + + /** + * @return mixed + */ + public static function getBpConfig() { + include(ENGINE_DIR.'/data/blockpro.php'); + + /** @var array $bpConfig */ + return $bpConfig; + } + + public static function getDb() { + return SafeMySQL::getInstanse([ + 'host' => DBHOST, + 'user' => DBUSER, + 'pass' => DBPASS, + 'db' => DBNAME, + 'charset' => COLLATE, + ]); + } + + public function getTemplater($tplOptions) { + $this->tpl = Fenom::factory(ROOT_DIR.'/templates/'.$this->dle_config['skin'].'/', ENGINE_DIR.'/cache/', + $tplOptions); + // Добавляем модификаторы + $this->addModifiers(); + } + + /** + * + */ + public function addModifiers() { + + $config = $this->dle_config; + $db = $this->db; + $configForResizer = $this->bpConfig; + $configForResizer['http_home_url'] = $this->dle_config['http_home_url']; + + // Добавляем свой модификатор в шаблонизатор для ограничения кол-ва символов в тексте + $this->tpl->addModifier('limit', function ($data, $limit, $etc = '…', $wordcut = false) use ($config) { + return bpModifiers::textLimit($data, $limit, $etc, $wordcut, $config['charset']); + }); + + // Добавляем свой модификатор в шаблонизатор для ограничения кол-ва предложений + $this->tpl->addModifier('sentence', function ($data, $limit) { + return bpModifiers::sentenceLimit($data, $limit); + }); + + // Добавляем свой модификатор в шаблонизатор для вывода картинок + $this->tpl->addModifier('image', function ( + $data, + $noimage = '', + $imageType = 'small', + $number = 1, + $size, + $quality = '100', + $resizeType = 'auto', + $grabRemote = true, + $showSmall = false, + $subdir = false + ) use ($configForResizer) { + return bpModifiers::getImage($data, $noimage, $imageType, $number, $size, $quality, $resizeType, + $grabRemote, $showSmall, $subdir, $configForResizer); + }); + + // Добавляем свой модификатор в шаблонизатор для вывода картинок через tinypng + $this->tpl->addModifier('tinypng', function ( + $data, + $noimage = '', + $imageType = 'small', + $number = 1, + $size, + $quality = '100', + $resizeType = 'fit', + $grabRemote = true, + $showSmall = false, + $subdir = false + ) use ($configForResizer) { + return bpModifiers::getImage($data, $noimage, $imageType, $number, $size, $quality, $resizeType, + $grabRemote, $showSmall, $subdir, $configForResizer, 'tinypng'); + }); + + // Добавляем свой модификатор в шаблонизатор для вывода картинок через kraken + $this->tpl->addModifier('kraken', function ( + $data, + $noimage = '', + $imageType = 'small', + $number = 1, + $size, + $quality = '100', + $resizeType = 'auto', + $grabRemote = true, + $showSmall = false, + $subdir = false + ) use ($configForResizer) { + return bpModifiers::getImage($data, $noimage, $imageType, $number, $size, $quality, $resizeType, + $grabRemote, $showSmall, $subdir, $configForResizer, 'kraken'); + }); + + // Добавляем свой модификатор в шаблонизатор для вывода print_r + $this->tpl->addModifier('dump', function ($data) { + return bpModifiers::dump($data); + }); + + // Добавляем модификатор для получения списка пользователей + $this->tpl->addModifier('getAuthors', function ($data, $fields = false) use ($db) { + return bpModifiers::getAuthors($data, $fields, $db); + }); + + // Добавляем свой модификатор в шаблонизатор для вывода картинок + $this->tpl->addModifier('declination', function ($n, $word) { + return bpModifiers::declinationWords($n, $word); + }); + + // Добавляем свой модификатор в шаблонизатор для вывода форматированной даты + $this->tpl->addModifier('dateformat', function ($data, $_f = false) { + return formateDate($data, $_f); + }); + + // Добавляем свой модификатор в шаблонизатор для вывода информации о категории новости + $this->tpl->addModifier('catinfo', function ($data, $info = false, $noicon = false) { + return getCatInfo($data, $info, $noicon); + }); + + // Добавляем свой модификатор в шаблонизатор для реализации preg_match_all + $this->tpl->addModifier('ematch_all', function ($data, $pattern) { + preg_match_all($pattern, $data, $arReturn); + $arReturn = array_filter($arReturn); + + return $arReturn; + }); + + // Добавляем свой модификатор в шаблонизатор для вывода даты в формате "time ago". + $this->tpl->addModifier('timeago', function ($data, $precision = 2) { + return bpModifiers::timeAgo($data, $precision); + }); + + // Добавляем свой модификатор в шаблонизатор для конвертации текста в json. + $this->tpl->addModifier('jsonDecode', function ($data) { + return bpModifiers::jsonDecode($data); + }); + } + + public function setConfig($cfg = []) { + return $cfg; + } + + /** + * @param $data - массив с информацией о статье + * + * @return string URL для категории + */ + + public function getPostUrl($data) { + + $data['date'] = strtotime($data['date']); + + if ($this->dle_config['allow_alt_url'] && $this->dle_config['allow_alt_url'] != 'no') { + if (($this->dle_config['version_id'] < 9.6 && $this->dle_config['seo_type']) + || ($this->dle_config['version_id'] >= 9.6 + && ($this->dle_config['seo_type'] == 1 + || $this->dle_config['seo_type'] == 2)) + ) { + if (intval($data['category']) && $this->dle_config['seo_type'] == 2) { + $url = $this->dle_config['http_home_url'].get_url(intval($data['category'])).'/'.$data['id'].'-' + .$data['alt_name'].'.html'; + } else { + $url = $this->dle_config['http_home_url'].$data['id'].'-'.$data['alt_name'].'.html'; + } + } else { + $url = $this->dle_config['http_home_url'].date('Y/m/d/', $data['date']).$data['alt_name'].'.html'; + } + } else { + $url = $this->dle_config['http_home_url'].'index.php?newsid='.$data['id']; + } + + return $url; + } + + /** + * Получение диапазона между двумя цифрами, и не только + * + * @param bool $diapazone + * @param bool $subcats + * + * @return string + * @author Elkhan I. Isaev + */ + + public function getDiapazone($diapazone = false, $subcats = false) { + if ($diapazone !== false) { + $diapazone = str_replace(" ", "", $diapazone); + + if (strpos($diapazone, ',') !== false) { + $diapazoneArray = explode(',', $diapazone); + $diapazoneArray = array_diff($diapazoneArray, [null]); + + foreach ($diapazoneArray as $v) { + if (strpos($v, '-') !== false) { + preg_match("#(\d+)-(\d+)#i", $v, $test); + + $diapazone = !empty($diapazone) && is_array($diapazone) ? array_merge($diapazone, + (!empty ($test) ? range($test[1], $test[2]) : [])) + : (!empty ($test) ? range($test[1], $test[2]) : []); + + } else { + $diapazone = !empty($diapazone) && is_array($diapazone) ? array_merge($diapazone, + (!empty ($v) ? [(int)$v] : [])) : (!empty ($v) ? [(int)$v] : []); + } + } + + } elseif (strpos($diapazone, '-') !== false) { + + preg_match("#(\d+)-(\d+)#i", $diapazone, $test); + $diapazone = !empty ($test) ? range($test[1], $test[2]) : []; + + } else { + $diapazone = [(int)$diapazone]; + } + if (!empty($diapazone)) { + if ($subcats && function_exists('get_sub_cats')) { + foreach ($diapazone as $d) { + $_sc = explode('|', get_sub_cats($d)); + foreach ($_sc as $v) { + array_push($diapazone, $v); + } + } + } + $diapazone = array_unique($diapazone); + } else { + $diapazone = []; + } + + $diapazone = implode(',', $diapazone); + } + + return $diapazone; + + } + + /** + * Формируем ссылки с тегами + * + * @param string $tags строка с тегами + * + * @return string строка с сылками + */ + + public function tagsLink($tags) { + $showTags = ''; + if ($this->dle_config['allow_tags'] && $tags) { + $showTagsArr = []; + $tags = explode(",", $tags); + + foreach ($tags as $value) { + $value = trim($value); + if ($this->dle_config['allow_alt_url'] && $this->dle_config['allow_alt_url'] != 'no') { + $showTagsArr[] = "dle_config['http_home_url']."tags/".urlencode($value)."/\">" + .$value.""; + } else { + $showTagsArr[] = "dle_config['http_home_url']."?do=tags&tag=" + .urlencode($value)."\">".$value.""; + } + + $showTags = implode(', ', $showTagsArr); + } + } + + return $showTags; + } + + /** + * Получаем несколько уникальных случайных чисел в заданном диапазоне + * + * @param integer $from от + * @param integer $to до + * @param integer $count кол-во чисел + * + * @return array массив с числами + */ + public function getRand($from = 1, $to = 2000, $count = 15) { + $arNumbers = $tmp = []; + for ($i = 0; $i < $count; $i++) { + do { + $a = mt_rand($from, $to); + } while (isset($tmp[$a])); + $tmp[$a] = $from; + $arNumbers[] = $a; + } + unset($tmp); + + return $arNumbers; + } + + /** + * Получаем готовую строку для вставки в запрос из условий фильтрации + * + * Пример использования в строке подключения + * setFilter=p.full_story|SEARCH|text1|OR|p.full_story|SEARCH|text2 + * + * @param string $setFilterStr строка с условиями фильтрации + * + * @return string Строка для использования в качестве части заброса в БД + */ + public function prepareFilterQuery($setFilterStr = '') { + if (!$setFilterStr || $setFilterStr === '') { + return false; + } + + // Разбиваем строку на условия "OR", если есть. + $filterItems = explode('|OR|', $setFilterStr); + + + $hasOrCondition = count($filterItems) > 1; + + $queryParts = []; + + foreach ($filterItems as $strItem) { + + // Разбиваем на части запроса + $arFItem = explode('|', $strItem, 3); + + $field = $arFItem[0]; + $operator = ''; + + // Т.к. DLE не позволяет передавать напрямую символы '>' и '<', приходится изобретать собственный велосипед. + switch ($arFItem[1]) { + case '-': + case 'lt': + $operator = ' < '; + break; + + case '+': + case 'gt': + $operator = ' > '; + break; + + case '=': + case 'eq': + $operator = ' = '; + break; + + case '+=': + case 'gte': + $operator = ' >= '; + break; + + case '-=': + case 'lte': + $operator = ' <= '; + break; + + case '+-': + case '-+': + case 'not': + $operator = ' != '; + break; + + case 'SEARCH': + $operator = ' LIKE '; + break; + + case 'NOT_SEARCH': + $operator = ' NOT LIKE '; + break; + } + + + if ($arFItem[2] == 'NOW()') { + // Если нужно отобрать "сейчас" + $itemVal = 'NOW()'; + } elseif ($arFItem[1] == 'SEARCH' || $arFItem[1] == 'NOT_SEARCH') { + // Реализация поиска + $itemVal = $this->db->parse('?s', '%'.$arFItem[2].'%'); + } else { + // В противном случае фильтруем. + $_op = (is_numeric($arFItem[2])) ? '?i' : '?s'; + $itemVal = $this->db->parse($_op, $arFItem[2]); + } + + if ($operator !== '') { + $queryParts[] = $field.$operator.$itemVal; + } + } + + $strAueryPart = implode(' OR ', $queryParts); + + if ($hasOrCondition) { + $strAueryPart = '('.$strAueryPart.')'; + } + + return $strAueryPart; + } } // base Class @@ -449,134 +464,137 @@ public function prepareFilterQuery($setFilterStr='') { /** * Форматируем дату * - * @param string $date дата - * @param bool|false $_f + * @param string $date дата + * @param bool|false $_f * * @return string отформатированная дата */ function formateDate($date, $_f = false) { - global $lang, $config, $langdate; + global $lang, $config, $langdate; - if (!$lang['charset']) { - include_once(DLEPlugins::Check(ROOT_DIR . '/language/' . $config['langs'] . '/website.lng')); - } + if (!$lang['charset']) { + include_once(DLEPlugins::Check(ROOT_DIR.'/language/'.$config['langs'].'/website.lng')); + } - $date = strtotime($date); + $date = strtotime($date); - if (!$_f) { + if (!$_f) { - if (date('Ymd', $date) == date('Ymd')) { - $showDate = $lang['time_heute'] . langdate(', H:i', $date); - } elseif (date('Ymd', $date) == date('Ymd') - 1) { - $showDate = $lang['time_gestern'] . langdate(', H:i', $date); - } else { - $showDate = langdate($config['timestamp_active'], $date); - } - } else { - $showDate = langdate($_f, $date); - } + if (date('Ymd', $date) == date('Ymd')) { + $showDate = $lang['time_heute'].langdate(', H:i', $date); + } elseif (date('Ymd', $date) == date('Ymd') - 1) { + $showDate = $lang['time_gestern'].langdate(', H:i', $date); + } else { + $showDate = langdate($config['timestamp_active'], $date); + } + } else { + $showDate = langdate($_f, $date); + } - return $showDate; + return $showDate; } /** * @param $category - * @param bool $info - * @param bool $noicon + * @param bool $info + * @param bool $noicon * * @return array|string */ function getCatInfo($category, $info = false, $noicon = false) { - global $cat_info, $config; + global $cat_info, $config; - $my_cat = []; - $my_cat_icon = []; - $my_cat_link = []; - $cat_return = []; + $my_cat = []; + $my_cat_icon = []; + $my_cat_link = []; + $cat_return = []; - $separator = ($config['category_separator']) ? $config['category_separator'] : ', '; + $separator = ($config['category_separator']) ? $config['category_separator'] : ', '; - $cat_list = explode(',', $category); + $cat_list = explode(',', $category); - foreach ($cat_list as $cat) { - if (isset($cat_info[$cat])) { + foreach ($cat_list as $cat) { + if (isset($cat_info[$cat])) { - $my_cat[] = $cat_info[$cat]['name']; - if ($cat_info[$cat]['icon']) { - $my_cat_icon[] = '' . $cat_info[$cat]['name'] . ''; - } else { - $my_cat_icon[] = (!$noicon) ? false : '' . $cat_info[$cat]['name'] . ''; - } - if ($config['allow_alt_url'] && $config['allow_alt_url'] != 'no') { - $my_cat_link[] = '' . $cat_info[$cat]['name'] . ''; - } else { - $my_cat_link[] = '' . $cat_info[$cat]['name'] . ''; - } - } - } + $my_cat[] = $cat_info[$cat]['name']; + if ($cat_info[$cat]['icon']) { + $my_cat_icon[] = ''.$cat_info[$cat]['name'].''; + } else { + $my_cat_icon[] = (!$noicon) ? false : ''.$cat_info[$cat]['name'].''; + } + if ($config['allow_alt_url'] && $config['allow_alt_url'] != 'no') { + $my_cat_link[] = '' + .$cat_info[$cat]['name'].''; + } else { + $my_cat_link[] = ''.$cat_info[$cat]['name'].''; + } + } + } - $cat_return['name'] = implode($separator, $my_cat); - $cat_return['icon'] = implode(' ', $my_cat_icon); - $cat_return['link'] = implode($separator, $my_cat_link); - $cat_return['url'] = ($category) ? $config['http_home_url'] . get_url(intval($category)) . '/' : '/'; + $cat_return['name'] = implode($separator, $my_cat); + $cat_return['icon'] = implode(' ', $my_cat_icon); + $cat_return['link'] = implode($separator, $my_cat_link); + $cat_return['url'] = ($category) ? $config['http_home_url'].get_url(intval($category)).'/' : '/'; - switch ($info) { - case 'name': - return $cat_return['name']; - break; + switch ($info) { + case 'name': + return $cat_return['name']; + break; - case 'icon': - return $cat_return['icon']; - break; + case 'icon': + return $cat_return['icon']; + break; - case 'link': - return $cat_return['link']; - break; + case 'link': + return $cat_return['link']; + break; - case 'url': - return $cat_return['url']; - break; + case 'url': + return $cat_return['url']; + break; - default: - return $cat_return; - break; - } + default: + return $cat_return; + break; + } } /** - * Показ рейтинга через модуль. Функция переписана из стандартной т.к. стандартная имела ID, конфликтующие с самими собой. + * Показ рейтинга через модуль. Функция переписана из стандартной т.к. стандартная имела ID, конфликтующие с самими + * собой. * - * @param integer $id ID новости - * @param integer $rating значение рейтинга - * @param integer $vote_num кол-во голосов - * @param boolean $allow доступность рейтинга для юзера + * @param integer $id ID новости + * @param integer $rating значение рейтинга + * @param integer $vote_num кол-во голосов + * @param boolean $allow доступность рейтинга для юзера * * @return mixed */ function baseShowRating($id, $rating, $vote_num, $allow = true) { - global $lang, $config; + global $lang, $config; - if (!$config['rating_type']) { + if (!$config['rating_type']) { - if ($rating AND $vote_num) { - $rating = round(($rating / $vote_num), 0); - } else { - $rating = 0; - } + if ($rating AND $vote_num) { + $rating = round(($rating / $vote_num), 0); + } else { + $rating = 0; + } - if ($rating < 0) { - $rating = 0; - } + if ($rating < 0) { + $rating = 0; + } - $rating = $rating * 20; + $rating = $rating * 20; - if (!$allow) { + if (!$allow) { - $rated = <<
  • {$rating}
  • @@ -584,12 +602,12 @@ function baseShowRating($id, $rating, $vote_num, $allow = true) { HTML; - return $rated; - } - $jsRAteFunctionName = ($config['version_id'] >= 13) ? 'base_rate13' : 'base_rate'; + return $rated; + } + $jsRAteFunctionName = ($config['version_id'] >= 13) ? 'base_rate13' : 'base_rate'; - $rated = <<
      @@ -604,54 +622,56 @@ function baseShowRating($id, $rating, $vote_num, $allow = true) {
    HTML; - return $rated; + return $rated; - } elseif ($config['rating_type'] == "1") { + } elseif ($config['rating_type'] == "1") { - if ($rating < 0) { - $rating = 0; - } + if ($rating < 0) { + $rating = 0; + } - if ($allow) { - $rated = "{$rating}"; - } else { - $rated = "{$rating}"; - } + if ($allow) { + $rated + = "{$rating}"; + } else { + $rated = "{$rating}"; + } - return $rated; + return $rated; - } elseif ($config['rating_type'] == "2") { + } elseif ($config['rating_type'] == "2") { - $extraclass = "ratingzero"; + $extraclass = "ratingzero"; - if ($rating < 0) { - $extraclass = "ratingminus"; - } + if ($rating < 0) { + $extraclass = "ratingminus"; + } - if ($rating > 0) { - $extraclass = "ratingplus"; - $rating = "+" . $rating; - } + if ($rating > 0) { + $extraclass = "ratingplus"; + $rating = "+".$rating; + } - if ($allow) { - $rated = "{$rating}"; - } else { - $rated = "{$rating}"; - } + if ($allow) { + $rated + = "{$rating}"; + } else { + $rated = "{$rating}"; + } - return $rated; + return $rated; - } + } - return true; + return true; } function stripSlashesInArray($data) { - if (is_array($data)) { - $data = array_map('stripSlashesInArray', $data); - } else { - $data = stripslashes($data); - } + if (is_array($data)) { + $data = array_map('stripSlashesInArray', $data); + } else { + $data = stripslashes($data); + } - return $data; + return $data; } \ No newline at end of file diff --git a/engine/modules/base/core/bpModifiers.php b/engine/modules/base/core/bpModifiers.php index 90ef478..573ee3c 100644 --- a/engine/modules/base/core/bpModifiers.php +++ b/engine/modules/base/core/bpModifiers.php @@ -14,514 +14,638 @@ class bpModifiers extends base { - /** - * @param $data - контент - * @param $limit - * @param string $etc - Окончание обрезанного текста - * @param bool $wordcut - жесткое ограничение символов - * @param string $charset - * - * @return string $data - обрезанный результат - */ - public static function textLimit($data, $limit, $etc = '…', $wordcut = false, $charset = 'utf-8') { - $data = strip_tags($data, '
    '); - $data = trim(str_replace(['
    ', '
    '], ' ', $data)); - - if ($limit && dle_strlen($data, $charset) > $limit) { - $data = dle_substr($data, 0, $limit, $charset) . $etc; - if (!$wordcut && ($word_pos = dle_strrpos($data, ' ', $charset))) { - $data = dle_substr($data, 0, $word_pos, $charset) . $etc; - } - - } - - return $data; - } - - /** - * Функция ресайза картинок - * - * @param string $data Строка, из которой будем выдёргивать картинку - * @param string $noimage Картинка-заглушка - * @param string $imageType Тип картинки (small/original/intext) - для получения соответствующей картинки или массива картинок - * @param integer /string $number Номер картинки в контенте или all для вывода всех картинок - * @param string $size Размер картики (например 100 или 100x150) - * @param string $quality Качество картинки (0-100) - * @param string $resizeType Тип ресайза (exact, portrait, landscape, auto, crop) - * @param boolean $grabRemote Грабить сторонние картинки к себе (true/false) - * @param boolean $showSmall Обрабатывать уменьшенную копию, если есть - * @param boolean $subdir Подпапка для картинок (иногда бывает нужно) - * @param array $config Массив с конфигом DLE - * @param string $service Сервис, серез который будем делать ресайз (local/tinypng/kraken) - * - * @return string Путь к уменьшенной или оригинальной картнке - */ - - public static function getImage($data, $noimage = '', $imageType = 'small', $number, $size, $quality, $resizeType = 'auto', $grabRemote = true, $showSmall = false, $subdir = false, $config = [], $service = 'local') { - - $resizeType = ($resizeType == '' || !$resizeType) ? 'auto' : $resizeType; - $quality = ($quality == '' || !$quality) ? '100' : $quality; - $noimage = str_replace($config['http_home_url'] . '/', $config['http_home_url'], $noimage); - - // Удалим из адреса сайта последний слеш. - $config['http_home_url'] = (substr($config['http_home_url'], -1, 1) == '/') ? substr($config['http_home_url'], 0, -1) : $config['http_home_url']; - - // Задаём папку для загрзки картинок по умолчанию. - $uploadDir = '/uploads/base/'; - - // Задаём подпапку при необходимости - if ($subdir) { - // Если subdir начнается со слеша - значит это папка от корня сайта, а не подпапака в base. - if (substr($subdir, 0, 1) == '/') { - $uploadDir = $subdir; - } else { - $uploadDir = $uploadDir . $subdir . '/'; - } - } - - // Задаём папку для картинок - $imageDir = $uploadDir . $size . '/'; - - $dir = ROOT_DIR . $imageDir; - - $data = stripslashes($data); - $arImages = []; - - if (preg_match_all('/]*?)?\\bsrc\\s*=\\s*(?|"([^"]*)"|\'([^\']*)\'|([^<>\'"\\s]*))[^<>]*>/i', $data, $m)) { - - $i = 1; // Счётчик - // Если регулярка нашла картинку — работаем. - if (isset($m[1])) { - foreach ($m[1] as $key => $url) { - // Если это смайлик или спойлер — пропускаем. - if (stripos($url, 'dleimages') !== false || stripos($url, 'engine/data/emoticons') !== false) { - continue; - } - // Если номер картинки меньше, чем требуется — проходим мимо. - if ($number != 'all' && $i < (int)$number) { - // Не забываем прибавить счётчик. - $i++; - continue; - } - /** @var string $imageItem */ - $imageItem = $imgResized = ''; - - // Если в настройках вызова указано выдёргивание оригинала — отдадим оригинал. - if ($imageType == 'original') { - $imageItem = str_ireplace(['/thumbs', '/medium'], '', $url); - } - // Если intext — отдадим то, что получили в тексте. - if ($imageType == 'intext') { - $imageItem = $url; - } - // Если small — то будем работать с картинкой. - if ($imageType == 'small') { - // Выдёргиваем оригинал, на случай если уменьшить надо до размеров больше, чем thumb или medium в новости и если это не запрещено в настройках. - $imageItem = ($showSmall) ? $url : str_ireplace(['/thumbs', '/medium'], '', $url); - - // Удаляем текущий домен (в т.ч. с www) из строки. - $urlShort = str_ireplace(['http://' . $_SERVER['HTTP_HOST'], 'http://www.' . $_SERVER['HTTP_HOST'], 'https://' . $_SERVER['HTTP_HOST'], 'https://www.' . $_SERVER['HTTP_HOST']], '', $imageItem); - - // Проверяем наша картинка или чужая. - $isRemote = (preg_match('~^http(s)?://~', $urlShort)) ? true : false; - - // Проверяем разрешено ли тянуть сторонние картинки. - $grabRemoteOn = ($grabRemote) ? true : false; - - // Отдаём заглушку, если ничего нет. - if (!$urlShort) { - /** @var string $imageItem */ - $imageItem = $noimage; - continue; - } - - // Если внешняя картинка и запрещего грабить картинки к себе — возвращаем её. - if ($isRemote && !$grabRemoteOn) { - /** @var string $imgResized */ - $imgResized = $urlShort; - continue; - } - - // Работаем с картинкой - // Если есть параметр size — включаем ресайз картинок - if ($size) { - // Создаём и назначаем права, если нет таковых - if (!is_dir($dir)) { - @mkdir($dir, 0755, true); - @chmod($dir, 0755); - } - if (!chmod($dir, 0755)) { - @chmod($dir, 0755); - } - - // Присваиваем переменной значение картинки (в т.ч. если это внешняя картинка) - $imgResized = $urlShort; - - // Если не внешняя картинка — подставляем корневю дирректорию, чтоб ресайзер понял что ему дают. - if (!$isRemote) { - $imgResized = ROOT_DIR . $urlShort; - } - - if ($service == 'tinypng' && $config['tinypng_key'] == '') { - $service = 'local'; - } - if ($service == 'kraken' && $config['kraken_key'] == '') { - $service = 'local'; - } - - // Определяем новое имя файла - $fileName = md5($size . '_' . $resizeType . '_' . $imgResized) . '_' . $service . '.' . pathinfo($imgResized, PATHINFO_EXTENSION); - - $newFile = $dir . $fileName; - // Если картинки нет в папке обработанных картинок, то попробуем её получить. - if (!file_exists($newFile)) { - // Если картинка локальная, или картинка внешняя, но разрешено её стянуть — работаем. - if (!$isRemote || ($grabRemoteOn && $isRemote)) { - self::getImageWith($service, $imgResized, $newFile, $size, $resizeType, $quality, $config); - } - } - - $imgResized = (file_exists($newFile)) ? $config['http_home_url'] . $imageDir . $fileName : $noimage; - - } else { - // Если параметра imgSize нет - отдаём исходную картинку - $imgResized = $urlShort; - } - - // Отдаём дальше результат обработки. - $imageItem = $imgResized; - - } // if($imageType == 'small') - $arImages[$i] = $imageItem; - if ($number == $i) { - break; - } - $i++; - } - - } - - } else { - // Если регулярка не нашла картинку - отдадим заглушку - $arImages[$number] = $noimage; - } - - // Если хотим все картинки — не вопрос, получим массив. - if ($number == 'all') { - - return $arImages; - } - - // По умолчанию возвращаем отдну картинку (понимаю, что метод должен возвращать всегда один тип данных, но это сделано из-за совместимости версий) - return $arImages[$number]; - - } - - /** - * @param string $service - * @param $originalFile - * @param $newFile - * @param $size - * @param $method - * @param string $quality - * @param array $config - */ - public static function getImageWith($service = 'local', $originalFile, $newFile, $size, $method, $quality = '100', $config = []) { - // Разделяем высоту и ширину - $imgSize = explode('x', $size); - - // Если указана только одна величина - присваиваем второй первую, будет квадрат для exact, auto и crop, иначе класс ресайза жестоко тупит, ожидая вторую переменную. - if (count($imgSize) == '1') { - $imgSize[1] = $imgSize[0]; - } - - switch ($service) { - // Тянем картинку через встроенный класс ресайза - case 'local': - // Определяемся с возможными методами уменьшения картинок. - $arMethods = ['exact', 'portrait', 'landscape', 'auto', 'crop']; - $resizeType = (in_array($method, $arMethods)) ? $method : 'auto'; - - // Подрубаем локальный класс для картинок - $resizeImg = new resize($originalFile); - $resizeImg->resizeImage( // Создание уменьшенной копии - $imgSize[0], // Размер картинки по ширине - $imgSize[1], // Размер картинки по высоте - $resizeType // Метод уменьшения (exact, portrait, landscape, auto, crop) - ); - $resizeImg->saveImage($newFile, $quality); // Сохраняем картинку в заданную папку - break; - - // Тянем картинку через tinyPNG - case 'tinypng': - - // Подключаем необходимые классы (да, без composer в DLE тяжело живётся). - require_once ENGINE_DIR . '/modules/base/resizers/tinypng/Tinify.php'; - require_once ENGINE_DIR . '/modules/base/resizers/tinypng/Tinify/Client.php'; - require_once ENGINE_DIR . '/modules/base/resizers/tinypng/Tinify/Exception.php'; - require_once ENGINE_DIR . '/modules/base/resizers/tinypng/Tinify/ResultMeta.php'; - require_once ENGINE_DIR . '/modules/base/resizers/tinypng/Tinify/Source.php'; - require_once ENGINE_DIR . '/modules/base/resizers/tinypng/Tinify/Result.php'; - - // Определяемся с возможными методами уменьшения картинок. - $arMethods = ['portrait', 'landscape', 'auto', 'crop']; - $resizeType = (in_array($method, $arMethods)) ? $method : 'auto'; - - // Определяемся с опциями обработки картинки - $imgSize[0] = (int)$imgSize[0]; - $imgSize[1] = (int)$imgSize[1]; - - $arTinyOptions = []; - - switch ($resizeType) { - case 'portrait': - $arTinyOptions = [ - 'method' => 'scale', - 'height' => $imgSize[1], - ]; - break; - - case 'landscape': - $arTinyOptions = [ - 'method' => 'scale', - 'width' => $imgSize[0], - ]; - break; - - case 'auto': - $arTinyOptions = [ - 'method' => 'fit', - 'width' => $imgSize[0], - 'height' => $imgSize[1], - ]; - break; - - case 'crop': - $arTinyOptions = [ - 'method' => 'cover', - 'width' => $imgSize[0], - 'height' => $imgSize[1], - ]; - break; - } - - // Вызываем класс и обрабатываем картинку - \Tinify\setKey($config['tinypng_key']); - - $source = \Tinify\fromFile($originalFile); - $resized = $source->resize($arTinyOptions); - $resized->toFile($newFile); - - unset($source, $resized); - - break; - - // Тянем картинку через Kraken - case 'kraken': - // Определяемся с возможными методами уменьшения картинок. - $arMethods = ['exact', 'portrait', 'landscape', 'auto', 'crop']; - $resizeType = (in_array($method, $arMethods)) ? $method : 'auto'; - // У Kraken есть свой метод crop, но нам нужен fit - if ($method == 'crop') { - $resizeType = 'fit'; - } - - // Подключаем класс Kraken. - require_once ENGINE_DIR . '/modules/base/resizers/kraken/Kraken.php'; - - $kraken = new Kraken($config['kraken_key'], $config['kraken_secret']); - - // Проверяем наша картинка или чужая. Нужно для корректной передачи данных в kraken - $isRemote = (preg_match('~^http(s)?://~', $originalFile)) ? true : false; - - // Параметры ресайза - $krakenResize = [ - 'width' => $imgSize[0], - 'height' => $imgSize[1], - 'strategy' => $resizeType, - ]; - - if ($isRemote) { - // Если картинка сторонняя - $krakenParams = [ - 'url' => $originalFile, - 'wait' => true, - 'resize' => $krakenResize, - ]; - - $krakenData = $kraken->url($krakenParams); - } else { - // Если картинка наша - $krakenParams = [ - 'file' => $originalFile, - 'wait' => true, - 'resize' => $krakenResize, - ]; - - $krakenData = $kraken->upload($krakenParams); - } - - if ($krakenData['success']) { - $newImg = self::curlGet($krakenData['kraked_url']); - file_put_contents($newFile, $newImg); - } - - break; - - // Тянем картинку через tinyPNG - } - } - - public static function curlGet($url) { - $ch = curl_init(); - $default_curlopt = [ - CURLOPT_TIMEOUT => 15, - CURLOPT_RETURNTRANSFER => 1, - // CURLOPT_FOLLOWLOCATION => 1, - CURLOPT_SSL_VERIFYPEER => false, - CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0", - ]; - $curlopt = [CURLOPT_URL => $url] + $default_curlopt; - curl_setopt_array($ch, $curlopt); - $response = curl_exec($ch); - if ($response === false) { - trigger_error(curl_error($ch)); - } - - curl_close($ch); - - return $response; - } - - - /** - * Функция для правильного склонения слов - * - * @param int $n - число, для которого будет расчитано окончание - * @param string $words - варианты окончаний для (1 комментарий, 2 комментария, 100 комментариев) - * - * @return string - слово с правильным окончанием - */ - public static function declinationWords($n = 0, $words) { - $words = explode('|', $words); - $n = abs((int) $n); // abs на случай отрицательного значения - - return $n % 10 == 1 && $n % 100 != 11 ? $words[0] . $words[1] : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? $words[0] . $words[2] : $words[0] . $words[3]); - } - - /** - * Функция для вывода print_r в шаблон - * - * @param mixed $var входящие данные - * - * @return string print_r - */ - public static function dump($var) { - return print_r($var, true); - } - - /** - * @param $array - * @param bool|false $fields - * @param $db - * - * @return mixed - */ - public static function getAuthors($array, $fields = false, $db) { - - $array = array_unique($array); - if ($fields) { - $fields = trim($fields); - } else { - $fields = '*'; - } - if (count($array) == 1) { - $select = 'SELECT ?p FROM ?n WHERE name = ?s'; - $array = $array[0]; - } else { - $select = 'SELECT ?p FROM ?n WHERE name IN(?a)'; - } - - $_result = $db->getAll($select, $fields, USERPREFIX . '_users', $array); - - foreach ($_result as $key => $user) { - unset($user['password']); - $result[$user['name']] = $user; - } - - /** @var array $result */ - return $result; - } - - /** - * Функция для вывода даты в формате "time ago" - * - * - * @param string $date Дата новости - * @param integer $precision Кол-во частей - * - * @return string отформатированная строка - */ - public static function timeAgo($date, $precision = 2) { - $precision = ($precision === 0 || $precision === 1) ? 1 : $precision; - $times = [ - 31536000 => '|год|года|лет', - 2592000 => 'месяц||а|ев', - 604800 => 'недел|ю|и|ь', - 86400 => '|день|дня|дней', - 3600 => 'час||а|ов', - 60 => 'минут|у|ы|', - ]; - - $timeDiff = time() - strtotime($date); - - if ($timeDiff < 60) { - $output = 'меньше минуты'; - } else { - $output = []; - $precisionCount = 0; - - foreach ($times as $period => $name) { - - if ($precisionCount >= $precision || ($precisionCount > 0 && $period < 1)) { - break; - } - $result = floor($timeDiff / $period); - - if ($result > 0) { - $output[] = $result . ' ' . self::declinationWords($result, $name); - - $timeDiff -= $result * $period; - $precisionCount++; - } else { - if ($precisionCount > 0) { - $precisionCount++; - } - } - } - - $last = array_slice($output, -1); - $first = join(', ', array_slice($output, 0, -1)); - $both = array_filter(array_merge([$first], $last), 'strlen'); - $outputFormatted = join(' и ', $both); - - - $output = $outputFormatted; - } - - return $output . ' назад'; - } - - /** - * Функция для конфертации строки в json на случай, если не работает модификатор json_decode - * @param string $var "{"one":"val"}" - * - * @return array json-массив - */ - public static function jsonDecode($var) { - $decoded = html_entity_decode($var, ENT_COMPAT); - return json_decode($decoded, true); - } + /** + * @param $data - контент + * @param $limit + * @param string $etc - Окончание обрезанного текста + * @param bool $wordcut - жесткое ограничение символов + * @param string $charset + * + * @return string $data - обрезанный результат + */ + public static function textLimit( + $data, + $limit, + $etc = '…', + $wordcut = false, + $charset = 'utf-8' + ) { + $data = bpModifiers::cleanTextContent($data); + + if ($limit && dle_strlen($data, $charset) > $limit) { + $data = dle_substr($data, 0, $limit, $charset).$etc; + if (!$wordcut && ($word_pos = dle_strrpos($data, ' ', $charset))) { + $data = dle_substr($data, 0, $word_pos, $charset).$etc; + } + + } + + return $data; + } + + /** + * Функция для очистки контента от лишнего текста + * + * @param string $data + * + * @return string $text + */ + public static function cleanTextContent($data = '') { + $data = preg_replace('/\[attachment=(.*?)]/is', '', $data); + $data = preg_replace('/\[hide(.*?)](.+?)\[\/hide]/is', '', $data); + $data = preg_replace('//is', '', $data); + $data + = preg_replace('/(.+?)/is', '', $data); + + $data = str_replace('><', '> <', $data); + $data = strip_tags($data, '
    '); + + $search = ['
    ', '
    ', "\n", "\r"]; + $replace = [' ', ' ', ' ', '']; + $data = trim(str_replace($search, $replace, $data)); + + $text = preg_replace('/\s+/u', ' ', $data); + + return $text; + } + + /** + * Функция для обрезки текста до заданного количества предложений (до точки) + * + * @param string $data - контент + * @param string $limit + * + * @return string $strSentences - обрезанный результат + */ + public static function sentenceLimit($data, $limit) { + $text = bpModifiers::cleanTextContent($data); + + $text = str_replace(['...', '..'], ['.', '.'], $text); + + $splitShortStory = explode('. ', $text); + + $sentences = []; + + foreach ($splitShortStory as $key => $sentence) { + if (($limit - 1) >= $key) { + $sentences[] = trim($sentence).'.'; + } else { + break; + } + } + + $strSentences = implode(' ', $sentences); + $strSentences = str_replace('..', '.', $strSentences); + + return $strSentences; + } + + /** + * Функция ресайза картинок + * + * @param string $data Строка, из которой будем выдёргивать картинку + * @param string $noimage Картинка-заглушка + * @param string $imageType Тип картинки (small/original/intext) - для получения соответствующей картинки или + * массива картинок + * @param integer|string $number Номер картинки в контенте или all для вывода всех картинок + * @param string $size Размер картики (например 100 или 100x150) + * @param string $quality Качество картинки (0-100) + * @param string $resizeType Тип ресайза (exact, portrait, landscape, auto, crop) + * @param boolean $grabRemote Грабить сторонние картинки к себе (true/false) + * @param boolean $showSmall Обрабатывать уменьшенную копию, если есть + * @param boolean $subdir Подпапка для картинок (иногда бывает нужно) + * @param array $config Массив с конфигом DLE + * @param string $service Сервис, серез который будем делать ресайз (local/tinypng/kraken) + * + * @return string Путь к уменьшенной или оригинальной картнке + */ + public static function getImage( + $data, + $noimage = '', + $imageType = 'small', + $number, + $size, + $quality, + $resizeType = 'auto', + $grabRemote = true, + $showSmall = false, + $subdir = false, + $config = [], + $service = 'local' + ) { + + $resizeType = ($resizeType == '' || !$resizeType) ? 'auto' : $resizeType; + $quality = ($quality == '' || !$quality) ? '100' : $quality; + $noimage = str_replace($config['http_home_url'].'/', $config['http_home_url'], $noimage); + + // Удалим из адреса сайта последний слеш. + $config['http_home_url'] = (substr($config['http_home_url'], -1, 1) == '/') ? substr($config['http_home_url'], + 0, -1) : $config['http_home_url']; + + // Задаём папку для загрзки картинок по умолчанию. + $uploadDir = '/uploads/base/'; + + // Задаём подпапку при необходимости + if ($subdir) { + // Если subdir начнается со слеша - значит это папка от корня сайта, а не подпапака в base. + if (substr($subdir, 0, 1) == '/') { + $uploadDir = $subdir; + } else { + $uploadDir = $uploadDir.$subdir.'/'; + } + } + + // Задаём папку для картинок + $imageDir = $uploadDir.$size.'/'; + + $dir = ROOT_DIR.$imageDir; + + $data = stripslashes($data); + $arImages = []; + + if (preg_match_all('/]*?)?\\bsrc\\s*=\\s*(?|"([^"]*)"|\'([^\']*)\'|([^<>\'"\\s]*))[^<>]*>/i', + $data, $m) + ) { + + $i = 1; // Счётчик + // Если регулярка нашла картинку — работаем. + if (isset($m[1])) { + foreach ($m[1] as $key => $url) { + // Если это смайлик или спойлер — пропускаем. + if (stripos($url, 'dleimages') !== false + || stripos($url, 'engine/data/emoticons') !== false + ) { + continue; + } + // Если номер картинки меньше, чем требуется — проходим мимо. + if ($number != 'all' && $i < (int)$number) { + // Не забываем прибавить счётчик. + $i++; + continue; + } + /** @var string $imageItem */ + $imageItem = $imgResized = ''; + + // Если в настройках вызова указано выдёргивание оригинала — отдадим оригинал. + if ($imageType == 'original') { + $imageItem = str_ireplace(['/thumbs', '/medium'], '', $url); + } + // Если intext — отдадим то, что получили в тексте. + if ($imageType == 'intext') { + $imageItem = $url; + } + // Если small — то будем работать с картинкой. + if ($imageType == 'small') { + // Выдёргиваем оригинал, на случай если уменьшить надо до размеров больше, чем thumb или medium в новости и если это не запрещено в настройках. + $imageItem = ($showSmall) ? $url : str_ireplace(['/thumbs', '/medium'], '', $url); + + // Удаляем текущий домен (в т.ч. с www) из строки. + $urlShort = str_ireplace([ + 'http://'.$_SERVER['HTTP_HOST'], + 'http://www.'.$_SERVER['HTTP_HOST'], + 'https://'.$_SERVER['HTTP_HOST'], + 'https://www.'.$_SERVER['HTTP_HOST'], + ], '', $imageItem); + + // Проверяем наша картинка или чужая. + $isRemote = (preg_match('~^http(s)?://~', $urlShort)) ? true : false; + + // Проверяем разрешено ли тянуть сторонние картинки. + $grabRemoteOn = ($grabRemote) ? true : false; + + // Отдаём заглушку, если ничего нет. + if (!$urlShort) { + /** @var string $imageItem */ + $imageItem = $noimage; + continue; + } + + // Если внешняя картинка и запрещего грабить картинки к себе — возвращаем её. + if ($isRemote && !$grabRemoteOn) { + /** @var string $imgResized */ + $imgResized = $urlShort; + continue; + } + + // Работаем с картинкой + // Если есть параметр size — включаем ресайз картинок + if ($size) { + // Создаём и назначаем права, если нет таковых + if (!is_dir($dir)) { + @mkdir($dir, 0755, true); + @chmod($dir, 0755); + } + if (!chmod($dir, 0755)) { + @chmod($dir, 0755); + } + + // Присваиваем переменной значение картинки (в т.ч. если это внешняя картинка) + $imgResized = $urlShort; + + // Если не внешняя картинка — подставляем корневю дирректорию, чтоб ресайзер понял что ему дают. + if (!$isRemote) { + $imgResized = ROOT_DIR.$urlShort; + } + + if ($service == 'tinypng' + && $config['tinypng_key'] == '' + ) { + $service = 'local'; + } + if ($service == 'kraken' + && $config['kraken_key'] == '' + ) { + $service = 'local'; + } + + // Определяем новое имя файла + $fileName = md5($size.'_'.$resizeType.'_'.$imgResized).'_'.$service.'.' + .pathinfo($imgResized, PATHINFO_EXTENSION); + + $newFile = $dir.$fileName; + // Если картинки нет в папке обработанных картинок, то попробуем её получить. + if (!file_exists($newFile)) { + // Если картинка локальная, или картинка внешняя, но разрешено её стянуть — работаем. + if (!$isRemote + || ($grabRemoteOn + && $isRemote) + ) { + self::getImageWith($service, $imgResized, $newFile, $size, $resizeType, $quality, + $config); + } + } + + $imgResized = (file_exists($newFile)) ? $config['http_home_url'].$imageDir.$fileName + : $noimage; + + } else { + // Если параметра imgSize нет - отдаём исходную картинку + $imgResized = $urlShort; + } + + // Отдаём дальше результат обработки. + $imageItem = $imgResized; + + } // if($imageType == 'small') + $arImages[$i] = $imageItem; + if ($number == $i) { + break; + } + $i++; + } + + } + + } else { + // Если регулярка не нашла картинку - отдадим заглушку + $arImages[$number] = $noimage; + } + + // Если хотим все картинки — не вопрос, получим массив. + if ($number == 'all') { + + return $arImages; + } + + // По умолчанию возвращаем отдну картинку (понимаю, что метод должен возвращать всегда один тип данных, но это сделано из-за совместимости версий) + return $arImages[$number]; + + } + + /** + * @param string $service + * @param $originalFile + * @param $newFile + * @param $size + * @param $method + * @param string $quality + * @param array $config + */ + public static function getImageWith( + $service = 'local', + $originalFile, + $newFile, + $size, + $method, + $quality = '100', + $config = [] + ) { + // Разделяем высоту и ширину + $imgSize = explode('x', $size); + + // Если указана только одна величина - присваиваем второй первую, будет квадрат для exact, auto и crop, иначе класс ресайза жестоко тупит, ожидая вторую переменную. + if (count($imgSize) == '1') { + $imgSize[1] = $imgSize[0]; + } + + switch ($service) { + // Тянем картинку через встроенный класс ресайза + case 'local': + // Определяемся с возможными методами уменьшения картинок. + $arMethods = [ + 'exact', + 'portrait', + 'landscape', + 'auto', + 'crop', + ]; + $resizeType = (in_array($method, $arMethods)) ? $method : 'auto'; + + // Подрубаем локальный класс для картинок + $resizeImg = new resize($originalFile); + $resizeImg->resizeImage( // Создание уменьшенной копии + $imgSize[0], // Размер картинки по ширине + $imgSize[1], // Размер картинки по высоте + $resizeType // Метод уменьшения (exact, portrait, landscape, auto, crop) + ); + $resizeImg->saveImage($newFile, $quality); // Сохраняем картинку в заданную папку + break; + + // Тянем картинку через tinyPNG + case 'tinypng': + + // Подключаем необходимые классы (да, без composer в DLE тяжело живётся). + require_once ENGINE_DIR.'/modules/base/resizers/tinypng/Tinify.php'; + require_once ENGINE_DIR.'/modules/base/resizers/tinypng/Tinify/Client.php'; + require_once ENGINE_DIR.'/modules/base/resizers/tinypng/Tinify/Exception.php'; + require_once ENGINE_DIR.'/modules/base/resizers/tinypng/Tinify/ResultMeta.php'; + require_once ENGINE_DIR.'/modules/base/resizers/tinypng/Tinify/Source.php'; + require_once ENGINE_DIR.'/modules/base/resizers/tinypng/Tinify/Result.php'; + + // Определяемся с возможными методами уменьшения картинок. + $arMethods = ['portrait', 'landscape', 'auto', 'crop']; + $resizeType = (in_array($method, $arMethods)) ? $method : 'auto'; + + // Определяемся с опциями обработки картинки + $imgSize[0] = (int)$imgSize[0]; + $imgSize[1] = (int)$imgSize[1]; + + $arTinyOptions = []; + + switch ($resizeType) { + case 'portrait': + $arTinyOptions = [ + 'method' => 'scale', + 'height' => $imgSize[1], + ]; + break; + + case 'landscape': + $arTinyOptions = [ + 'method' => 'scale', + 'width' => $imgSize[0], + ]; + break; + + case 'auto': + $arTinyOptions = [ + 'method' => 'fit', + 'width' => $imgSize[0], + 'height' => $imgSize[1], + ]; + break; + + case 'crop': + $arTinyOptions = [ + 'method' => 'cover', + 'width' => $imgSize[0], + 'height' => $imgSize[1], + ]; + break; + } + + // Вызываем класс и обрабатываем картинку + setKey($config['tinypng_key']); + + $source = fromFile($originalFile); + $resized = $source->resize($arTinyOptions); + $resized->toFile($newFile); + + unset($source, $resized); + + break; + + // Тянем картинку через Kraken + case 'kraken': + // Определяемся с возможными методами уменьшения картинок. + $arMethods = [ + 'exact', + 'portrait', + 'landscape', + 'auto', + 'crop', + ]; + $resizeType = (in_array($method, $arMethods)) ? $method : 'auto'; + // У Kraken есть свой метод crop, но нам нужен fit + if ($method == 'crop') { + $resizeType = 'fit'; + } + + // Подключаем класс Kraken. + require_once ENGINE_DIR.'/modules/base/resizers/kraken/Kraken.php'; + + $kraken = new Kraken($config['kraken_key'], $config['kraken_secret']); + + // Проверяем наша картинка или чужая. Нужно для корректной передачи данных в kraken + $isRemote = (preg_match('~^http(s)?://~', $originalFile)) ? true : false; + + // Параметры ресайза + $krakenResize = [ + 'width' => $imgSize[0], + 'height' => $imgSize[1], + 'strategy' => $resizeType, + ]; + + if ($isRemote) { + // Если картинка сторонняя + $krakenParams = [ + 'url' => $originalFile, + 'wait' => true, + 'resize' => $krakenResize, + ]; + + $krakenData = $kraken->url($krakenParams); + } else { + // Если картинка наша + $krakenParams = [ + 'file' => $originalFile, + 'wait' => true, + 'resize' => $krakenResize, + ]; + + $krakenData = $kraken->upload($krakenParams); + } + + if ($krakenData['success']) { + $newImg = self::curlGet($krakenData['kraked_url']); + file_put_contents($newFile, $newImg); + } + + break; + + // Тянем картинку через tinyPNG + } + } + + public static function curlGet($url) { + $ch = curl_init(); + $default_curlopt = [ + CURLOPT_TIMEOUT => 15, + CURLOPT_RETURNTRANSFER => 1, + // CURLOPT_FOLLOWLOCATION => 1, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0", + ]; + $curlopt = [CURLOPT_URL => $url] + $default_curlopt; + curl_setopt_array($ch, $curlopt); + $response = curl_exec($ch); + if ($response === false) { + trigger_error(curl_error($ch)); + } + + curl_close($ch); + + return $response; + } + + /** + * Функция для вывода print_r в шаблон + * + * @param mixed $var входящие данные + * + * @return string print_r + */ + public static function dump($var) { + return print_r($var, true); + } + + /** + * @param $array + * @param bool|false $fields + * @param $db + * + * @return mixed + */ + public static function getAuthors($array, $fields = false, $db) { + + $array = array_unique($array); + if ($fields) { + $fields = trim($fields); + } else { + $fields = '*'; + } + if (count($array) == 1) { + $select = 'SELECT ?p FROM ?n WHERE name = ?s'; + $array = $array[0]; + } else { + $select = 'SELECT ?p FROM ?n WHERE name IN(?a)'; + } + + $_result = $db->getAll($select, $fields, USERPREFIX.'_users', $array); + + foreach ($_result as $key => $user) { + unset($user['password']); + $result[$user['name']] = $user; + } + + /** @var array $result */ + return $result; + } + + /** + * Функция для вывода даты в формате "time ago" + * + * + * @param string $date Дата новости + * @param integer $precision Кол-во частей + * + * @return string отформатированная строка + */ + public static function timeAgo($date, $precision = 2) { + $precision = ($precision === 0 || $precision === 1) ? 1 : $precision; + $times = [ + 31536000 => '|год|года|лет', + 2592000 => 'месяц||а|ев', + 604800 => 'недел|ю|и|ь', + 86400 => '|день|дня|дней', + 3600 => 'час||а|ов', + 60 => 'минут|у|ы|', + ]; + + $timeDiff = time() - strtotime($date); + + if ($timeDiff < 60) { + $output = 'меньше минуты'; + } else { + $output = []; + $precisionCount = 0; + + foreach ($times as $period => $name) { + + if ($precisionCount >= $precision + || ($precisionCount > 0 + && $period < 1) + ) { + break; + } + $result = floor($timeDiff / $period); + + if ($result > 0) { + $output[] = $result.' '.self::declinationWords($result, $name); + + $timeDiff -= $result * $period; + $precisionCount++; + } else { + if ($precisionCount > 0) { + $precisionCount++; + } + } + } + + $last = array_slice($output, -1); + $first = join(', ', array_slice($output, 0, -1)); + $both = array_filter(array_merge([$first], $last), 'strlen'); + $outputFormatted = join(' и ', $both); + + + $output = $outputFormatted; + } + + return $output.' назад'; + } + + /** + * Функция для правильного склонения слов + * + * @param int $n - число, для которого будет расчитано окончание + * @param string $words - варианты окончаний для (1 комментарий, 2 + * комментария, 100 комментариев) + * + * @return string - слово с правильным окончанием + */ + public static function declinationWords($n = 0, $words) { + $words = explode('|', $words); + $n = abs((int)$n); // abs на случай отрицательного значения + + return $n % 10 == 1 && $n % 100 != 11 + ? $words[0].$words[1] : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? $words[0] + .$words[2] + : $words[0].$words[3]); + } + + /** + * Функция для конфертации строки в json на случай, если не работает + * модификатор json_decode + * + * @param string $var "{"one":"val"}" + * + * @return array json-массив + */ + public static function jsonDecode($var) { + $decoded = html_entity_decode($var, ENT_COMPAT); + + return json_decode($decoded, true); + } } // bpModifiers diff --git a/templates/Default/blockpro/css/index.htm b/templates/Default/blockpro/css/index.htm deleted file mode 100644 index 7d13843..0000000 --- a/templates/Default/blockpro/css/index.htm +++ /dev/null @@ -1,8 +0,0 @@ - - - - -Error!!! - -Error!!! - diff --git a/templates/Default/blockpro/index.htm b/templates/Default/blockpro/index.htm deleted file mode 100644 index 7d13843..0000000 --- a/templates/Default/blockpro/index.htm +++ /dev/null @@ -1,8 +0,0 @@ - - - - -Error!!! - -Error!!! - diff --git a/templates/Default/blockpro/js/blockpro.js b/templates/Default/blockpro/js/blockpro.js index 4e9b3e5..af4a239 100644 --- a/templates/Default/blockpro/js/blockpro.js +++ b/templates/Default/blockpro/js/blockpro.js @@ -37,29 +37,16 @@ $(document) action = $this.data('action'); ShowLoading(''); - $.get(dle_root + 'engine/ajax/favorites.php', { + $.get(dle_root + 'engine/ajax/controller.php', { fav_id: fav_id, action: action, - skin: dle_skin + skin: dle_skin, + mod: 'favorites', + alert: 1, + user_hash: dle_login_hash || '' }, function (data) { HideLoading(''); - var $img = $(data), - src = $img.prop('src'), - title = $img.prop('title'), - imgAction = (action === 'plus') ? 'minus' : 'plus', - l = src.split(imgAction).length; - if (l === 2) { - $('[data-favorite-id=' + fav_id + ']') - .prop({ - alt: title, - title: title, - src: src - }) - .data({ - action: imgAction, - favoriteId: fav_id - }); - } + DLEalert(data, dle_info); }); }); @@ -87,45 +74,6 @@ function base_loader(id, method, className) { } } -/** - * Функция выставления рейтинга в модуле blockpro - * - * @author ПафНутиЙ - * - * - * @return string Результат обработки рейтинга - * @param rate - * @param id - */ -function base_rate(rate, id) { - ShowLoading(''); - - $.get(dle_root + 'engine/ajax/rating.php', { - go_rate: rate, - news_id: id, - skin: dle_skin, - user_hash: dle_login_hash || '' - }, function (data) { - HideLoading(''); - if (data.success) { - var rating = data.rating; - - rating = rating.replace(/</g, '<'); - rating = rating.replace(/>/g, '>'); - rating = rating.replace(/&/g, '&'); - - $('[data-rating-layer="' + id + '"]').html(rating); - $('[data-vote-num-id="' + id + '"]').html(data.votenum); - - $('#ratig-layer-' + id).html(rating); - $('#vote-num-id-' + id).html(data.votenum); - } else if (data.error) { - DLEalert(data.errorinfo, dle_info); - } - - }, 'json'); -} - /** * Выставление рейтинга для DLE 13 * @see base_rate diff --git a/templates/Default/blockpro/js/blockpro_new.js b/templates/Default/blockpro/js/blockpro_new.js deleted file mode 100644 index 6288399..0000000 --- a/templates/Default/blockpro/js/blockpro_new.js +++ /dev/null @@ -1,197 +0,0 @@ -/*!https://github.com/Mikhus/jsurl/blob/master/url.js*/ -var Url=function(){"use strict";var t={protocol:"protocol",host:"hostname",port:"port",path:"pathname",query:"search",hash:"hash"},r={ftp:21,gopher:70,http:80,https:443,ws:80,wss:443},o=function(o,e){var a=document,i=a.createElement("a"),e=e||a.location.href,n=e.match(/\/\/(.*?)(?::(.*?))?@/)||[];i.href=e;for(var h in t)o[h]=i[t[h]]||"";if(o.protocol=o.protocol.replace(/:$/,""),o.query=o.query.replace(/^\?/,""),o.hash=o.hash.replace(/^#/,""),o.user=n[1]||"",o.pass=n[2]||"",o.port=r[o.protocol]==o.port||0==o.port?"":o.port,o.protocol||/^([a-z]+:)?\/\//.test(e))o.path=o.path.replace(/^\/?/,"/");else{var p=new Url(a.location.href.match(/(.*\/)/)[0]),c=p.path.split("/"),f=o.path.split("/");c.pop();for(var h=0,u=["protocol","user","pass","host","port"],l=u.length;l>h;h++)o[u[h]]=p[u[h]];for(;".."==f[0];)c.pop(),f.shift();o.path=("/"!=e.substring(0,1)?c.join("/"):"")+"/"+f.join("/")}s(o)},e=function(t){return t=t.replace(/\+/g," "),t=t.replace(/%([ef][0-9a-f])%([89ab][0-9a-f])%([89ab][0-9a-f])/gi,function(t,r,o,e){var s=parseInt(r,16)-224,a=parseInt(o,16)-128;if(0==s&&32>a)return t;var i=parseInt(e,16)-128,n=(s<<12)+(a<<6)+i;return n>65535?t:String.fromCharCode(n)}),t=t.replace(/%([cd][0-9a-f])%([89ab][0-9a-f])/gi,function(t,r,o){var e=parseInt(r,16)-192;if(2>e)return t;var s=parseInt(o,16)-128;return String.fromCharCode((e<<6)+s)}),t=t.replace(/%([0-7][0-9a-f])/gi,function(t,r){return String.fromCharCode(parseInt(r,16))})},s=function(t){var r=t.query;t.query=new function(t){for(var r,o=/([^=&]+)(=([^&]*))?/g;r=o.exec(t);){var s=decodeURIComponent(r[1].replace(/\+/g," ")),a=r[3]?e(r[3]):"";null!=this[s]?(this[s]instanceof Array||(this[s]=[this[s]]),this[s].push(a)):this[s]=a}this.clear=function(){for(s in this)this[s]instanceof Function||delete this[s]},this.toString=function(){var t="",r=encodeURIComponent;for(var o in this)if(!(this[o]instanceof Function))if(this[o]instanceof Array){var e=this[o].length;if(e)for(var s=0;e>s;s++)t+=t?"&":"",t+=r(o)+"="+r(this[o][s]);else t+=(t?"&":"")+r(o)+"="}else t+=t?"&":"",t+=r(o)+"="+r(this[o]);return t}}(r)};return function(t){this.toString=function(){return(this.protocol&&this.protocol+"://")+(this.user&&this.user+(this.pass&&":"+this.pass)+"@")+(this.host&&this.host)+(this.port&&":"+this.port)+(this.path&&this.path)+(this.query.toString()&&"?"+this.query)+(this.hash&&"#"+this.hash)},o(this,t)}}(); - -var thisUrl = window.location.pathname; - -$(document) - .on('click touchstart browserNavigation', '[data-page-num]', function (event) { - var $this = $(this), - blockId = $this.parent().data('blockId'), - pageNum = $this.data('pageNum'), - $block = $('#' + blockId), - u = new Url, - url; - - u.query.bid = blockId; - u.query.p = pageNum; - url = u; - - base_loader(blockId, 'start'); - - $.ajax({ - url: dle_root + 'engine/ajax/blockpro.php', - dataType: 'html', - data: { - pageNum: pageNum, - blockId: blockId, - thisUrl: thisUrl - } - }) - .done(function (data) { - $block.html($(data).html()); - if (history.pushState && event.type !== 'browserNavigation') { - window.history.pushState(null, null, url); - } - }) - .fail(function () { - base_loader(blockId, 'stop'); - console.log("error"); - }) - .always(function () { - base_loader(blockId, 'stop'); - }); - - }) - .on('click touchstart', '[data-favorite-id]', function (event) { - event.preventDefault(); - var $this = $(this), - fav_id = $this.data('favoriteId'), - action = $this.data('action'); - - ShowLoading(''); - $.get(dle_root + 'engine/ajax/favorites.php', { - fav_id: fav_id, - action: action, - skin: dle_skin - }, function (data) { - HideLoading(''); - var $img = $(data), - src = $img.prop('src'), - title = $img.prop('title'), - imgAction = (action === 'plus') ? 'minus' : 'plus', - l = src.split(imgAction).length; - if (l === 2) { - $('[data-favorite-id=' + fav_id + ']') - .prop({ - alt: title, - title: title, - src: src - }) - .data({ - action: imgAction, - favoriteId: fav_id - }); - } - }); - - }); - -$(window).on('popstate', function () { - browseTrigger(); -}); - -jQuery(document).ready(function () { - browseTrigger(); -}); - -/** - * Переход к нужной странице навигации блока модуля blockpro - */ -function browseTrigger() { - var u = new Url(location.href); - if (u.query.bid) { - $('#' + u.query.bid).find('[data-page-num="' + u.query.p + '"]:first').trigger('browserNavigation'); - } -} - -/** - * Простейшая функция для реализации эффекта загрузки блока - * Добавляет/удаляет заданный класс для заданного блока - * вся работа по оформлению ложится на css - * - * @author ПафНутиЙ - * - * @param id - * @param method - * @param className - */ -function base_loader(id, method, className) { - var $block = $('#' + id), - cname = (className) ? className : 'base-loader'; - if (method === 'start') { - $block.addClass(cname); - } - - if (method === 'stop') { - $block.removeClass(cname); - } -} - -/** - * Функция выставления рейтинга в модуле blockpro - * - * @author ПафНутиЙ - * - * - * @return string Результат обработки рейтинга - * @param rate - * @param id - */ -function base_rate(rate, id) { - ShowLoading(''); - - $.get(dle_root + 'engine/ajax/rating.php', { - go_rate: rate, - news_id: id, - skin: dle_skin, - user_hash: dle_login_hash || '' - }, function (data) { - HideLoading(''); - if (data.success) { - var rating = data.rating; - - rating = rating.replace(/</g, '<'); - rating = rating.replace(/>/g, '>'); - rating = rating.replace(/&/g, '&'); - - $('[data-rating-layer="' + id + '"]').html(rating); - $('[data-vote-num-id="' + id + '"]').html(data.votenum); - - $('#ratig-layer-' + id).html(rating); - $('#vote-num-id-' + id).html(data.votenum); - } else if (data.error) { - DLEalert(data.errorinfo, dle_info); - } - - }, 'json'); -} - -/** - * Выставление рейтинга для DLE 13 - * @see base_rate - * @param rate - * @param id - */ -function base_rate13(rate, id) { - ShowLoading(''); - $.get(dle_root + 'engine/ajax/controller.php?mod=rating', { - go_rate: rate, - news_id: id, - skin: dle_skin, - user_hash: dle_login_hash || '' - }, function(data){ - - HideLoading(''); - - if (data.success) { - var rating = data.rating; - - rating = rating.replace(/</g, '<'); - rating = rating.replace(/>/g, '>'); - rating = rating.replace(/&/g, '&'); - - $('[data-rating-layer="' + id + '"]').html(rating); - $('[data-vote-num-id="' + id + '"]').html(data.votenum); - - $('#ratig-layer-' + id).html(rating); - $('#vote-num-id-' + id).html(data.votenum); - - $('#likes-id-' + id).html(data.likes); - $('#dislikes-id-' + id).html(data.dislikes); - - } else if (data.error) { - DLEalert(data.errorinfo, dle_info); - } - - }, "json"); -} \ No newline at end of file diff --git a/templates/Default/blockpro/js/index.htm b/templates/Default/blockpro/js/index.htm deleted file mode 100644 index 7d13843..0000000 --- a/templates/Default/blockpro/js/index.htm +++ /dev/null @@ -1,8 +0,0 @@ - - - - -Error!!! - -Error!!! - From a671372d728caf0a2fd2533856db14ed3af17f67 Mon Sep 17 00:00:00 2001 From: pafnuty Date: Sat, 22 Feb 2020 21:23:18 +0400 Subject: [PATCH 2/5] =?UTF-8?q?6.0.0=20=D0=9F=D0=B5=D1=80=D0=B5=D0=BC?= =?UTF-8?q?=D0=B5=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=83=D1=8E=20=D0=BF=D0=B0=D0=BF=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/{Default => {THEME}}/blockpro/.htaccess | 0 .../{Default => {THEME}}/blockpro/base-loader.gif | Bin .../{Default => {THEME}}/blockpro/blockpro.tpl | 0 templates/{Default => {THEME}}/blockpro/bp1.tpl | 0 .../{Default => {THEME}}/blockpro/bp_comments.tpl | 2 +- .../{Default => {THEME}}/blockpro/cachevars.tpl | 0 .../{Default => {THEME}}/blockpro/css/.htaccess | 0 .../{Default => {THEME}}/blockpro/css/blockpro.css | 0 .../{Default => {THEME}}/blockpro/external.tpl | 0 .../{Default => {THEME}}/blockpro/fullexample.tpl | 0 .../{Default => {THEME}}/blockpro/getuserinfo.tpl | 0 templates/{Default => {THEME}}/blockpro/group.tpl | 0 templates/{Default => {THEME}}/blockpro/iframe.tpl | 0 .../{Default => {THEME}}/blockpro/js/.htaccess | 0 .../{Default => {THEME}}/blockpro/js/blockpro.js | 4 ++-- templates/{Default => {THEME}}/blockpro/list.tpl | 0 templates/{Default => {THEME}}/blockpro/noimage.png | Bin .../{Default => {THEME}}/blockpro/noimage_big.png | Bin templates/{Default => {THEME}}/blockpro/rss.tpl | 0 .../blockpro/template_inner.tpl | 0 .../blockpro/template_wrapper.tpl | 0 21 files changed, 3 insertions(+), 3 deletions(-) rename templates/{Default => {THEME}}/blockpro/.htaccess (100%) rename templates/{Default => {THEME}}/blockpro/base-loader.gif (100%) rename templates/{Default => {THEME}}/blockpro/blockpro.tpl (100%) rename templates/{Default => {THEME}}/blockpro/bp1.tpl (100%) rename templates/{Default => {THEME}}/blockpro/bp_comments.tpl (89%) rename templates/{Default => {THEME}}/blockpro/cachevars.tpl (100%) rename templates/{Default => {THEME}}/blockpro/css/.htaccess (100%) rename templates/{Default => {THEME}}/blockpro/css/blockpro.css (100%) rename templates/{Default => {THEME}}/blockpro/external.tpl (100%) rename templates/{Default => {THEME}}/blockpro/fullexample.tpl (100%) rename templates/{Default => {THEME}}/blockpro/getuserinfo.tpl (100%) rename templates/{Default => {THEME}}/blockpro/group.tpl (100%) rename templates/{Default => {THEME}}/blockpro/iframe.tpl (100%) rename templates/{Default => {THEME}}/blockpro/js/.htaccess (100%) rename templates/{Default => {THEME}}/blockpro/js/blockpro.js (96%) rename templates/{Default => {THEME}}/blockpro/list.tpl (100%) rename templates/{Default => {THEME}}/blockpro/noimage.png (100%) rename templates/{Default => {THEME}}/blockpro/noimage_big.png (100%) rename templates/{Default => {THEME}}/blockpro/rss.tpl (100%) rename templates/{Default => {THEME}}/blockpro/template_inner.tpl (100%) rename templates/{Default => {THEME}}/blockpro/template_wrapper.tpl (100%) diff --git a/templates/Default/blockpro/.htaccess b/templates/{THEME}/blockpro/.htaccess similarity index 100% rename from templates/Default/blockpro/.htaccess rename to templates/{THEME}/blockpro/.htaccess diff --git a/templates/Default/blockpro/base-loader.gif b/templates/{THEME}/blockpro/base-loader.gif similarity index 100% rename from templates/Default/blockpro/base-loader.gif rename to templates/{THEME}/blockpro/base-loader.gif diff --git a/templates/Default/blockpro/blockpro.tpl b/templates/{THEME}/blockpro/blockpro.tpl similarity index 100% rename from templates/Default/blockpro/blockpro.tpl rename to templates/{THEME}/blockpro/blockpro.tpl diff --git a/templates/Default/blockpro/bp1.tpl b/templates/{THEME}/blockpro/bp1.tpl similarity index 100% rename from templates/Default/blockpro/bp1.tpl rename to templates/{THEME}/blockpro/bp1.tpl diff --git a/templates/Default/blockpro/bp_comments.tpl b/templates/{THEME}/blockpro/bp_comments.tpl similarity index 89% rename from templates/Default/blockpro/bp_comments.tpl rename to templates/{THEME}/blockpro/bp_comments.tpl index eed6b15..060faef 100644 --- a/templates/Default/blockpro/bp_comments.tpl +++ b/templates/{THEME}/blockpro/bp_comments.tpl @@ -32,7 +32,7 @@ {/foreach} {else}
    - Этот шаблон следует вызывать подключать внутри цикла, используя такую конструкцию: + Этот шаблон следует подключать внутри цикла, используя такую конструкцию:
    {ignore}{include '/blockpro/bp_comments.tpl' postId=$el.id limit=5}{/ignore}
    {/if} diff --git a/templates/Default/blockpro/cachevars.tpl b/templates/{THEME}/blockpro/cachevars.tpl similarity index 100% rename from templates/Default/blockpro/cachevars.tpl rename to templates/{THEME}/blockpro/cachevars.tpl diff --git a/templates/Default/blockpro/css/.htaccess b/templates/{THEME}/blockpro/css/.htaccess similarity index 100% rename from templates/Default/blockpro/css/.htaccess rename to templates/{THEME}/blockpro/css/.htaccess diff --git a/templates/Default/blockpro/css/blockpro.css b/templates/{THEME}/blockpro/css/blockpro.css similarity index 100% rename from templates/Default/blockpro/css/blockpro.css rename to templates/{THEME}/blockpro/css/blockpro.css diff --git a/templates/Default/blockpro/external.tpl b/templates/{THEME}/blockpro/external.tpl similarity index 100% rename from templates/Default/blockpro/external.tpl rename to templates/{THEME}/blockpro/external.tpl diff --git a/templates/Default/blockpro/fullexample.tpl b/templates/{THEME}/blockpro/fullexample.tpl similarity index 100% rename from templates/Default/blockpro/fullexample.tpl rename to templates/{THEME}/blockpro/fullexample.tpl diff --git a/templates/Default/blockpro/getuserinfo.tpl b/templates/{THEME}/blockpro/getuserinfo.tpl similarity index 100% rename from templates/Default/blockpro/getuserinfo.tpl rename to templates/{THEME}/blockpro/getuserinfo.tpl diff --git a/templates/Default/blockpro/group.tpl b/templates/{THEME}/blockpro/group.tpl similarity index 100% rename from templates/Default/blockpro/group.tpl rename to templates/{THEME}/blockpro/group.tpl diff --git a/templates/Default/blockpro/iframe.tpl b/templates/{THEME}/blockpro/iframe.tpl similarity index 100% rename from templates/Default/blockpro/iframe.tpl rename to templates/{THEME}/blockpro/iframe.tpl diff --git a/templates/Default/blockpro/js/.htaccess b/templates/{THEME}/blockpro/js/.htaccess similarity index 100% rename from templates/Default/blockpro/js/.htaccess rename to templates/{THEME}/blockpro/js/.htaccess diff --git a/templates/Default/blockpro/js/blockpro.js b/templates/{THEME}/blockpro/js/blockpro.js similarity index 96% rename from templates/Default/blockpro/js/blockpro.js rename to templates/{THEME}/blockpro/js/blockpro.js index af4a239..4fbe95c 100644 --- a/templates/Default/blockpro/js/blockpro.js +++ b/templates/{THEME}/blockpro/js/blockpro.js @@ -75,12 +75,12 @@ function base_loader(id, method, className) { } /** - * Выставление рейтинга для DLE 13 + * Выставление рейтинга * @see base_rate * @param rate * @param id */ -function base_rate13(rate, id) { +function base_rate(rate, id) { ShowLoading(''); $.get(dle_root + 'engine/ajax/controller.php?mod=rating', { go_rate: rate, diff --git a/templates/Default/blockpro/list.tpl b/templates/{THEME}/blockpro/list.tpl similarity index 100% rename from templates/Default/blockpro/list.tpl rename to templates/{THEME}/blockpro/list.tpl diff --git a/templates/Default/blockpro/noimage.png b/templates/{THEME}/blockpro/noimage.png similarity index 100% rename from templates/Default/blockpro/noimage.png rename to templates/{THEME}/blockpro/noimage.png diff --git a/templates/Default/blockpro/noimage_big.png b/templates/{THEME}/blockpro/noimage_big.png similarity index 100% rename from templates/Default/blockpro/noimage_big.png rename to templates/{THEME}/blockpro/noimage_big.png diff --git a/templates/Default/blockpro/rss.tpl b/templates/{THEME}/blockpro/rss.tpl similarity index 100% rename from templates/Default/blockpro/rss.tpl rename to templates/{THEME}/blockpro/rss.tpl diff --git a/templates/Default/blockpro/template_inner.tpl b/templates/{THEME}/blockpro/template_inner.tpl similarity index 100% rename from templates/Default/blockpro/template_inner.tpl rename to templates/{THEME}/blockpro/template_inner.tpl diff --git a/templates/Default/blockpro/template_wrapper.tpl b/templates/{THEME}/blockpro/template_wrapper.tpl similarity index 100% rename from templates/Default/blockpro/template_wrapper.tpl rename to templates/{THEME}/blockpro/template_wrapper.tpl From 0b12bd7f089689bc2d721f5d215d0c1722e6c007 Mon Sep 17 00:00:00 2001 From: pafnuty Date: Sat, 22 Feb 2020 21:23:48 +0400 Subject: [PATCH 3/5] =?UTF-8?q?6.0.0=20=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BB=D0=B8=D1=88=D0=BD=D0=B8=D0=B5=20=20=D0=B8?= =?UTF-8?q?=20=D1=83=D1=81=D1=82=D0=B0=D1=80=D0=B5=D0=B2=D1=88=D0=B8=D0=B5?= =?UTF-8?q?=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine/ajax/base/check_status.php | 63 --- engine/ajax/base/check_updates.php | 86 ---- .../base/admin/blockpro/less/.htaccess | 7 - .../admin/blockpro/less/00-variables.less | 64 --- .../base/admin/blockpro/less/01-mixins.less | 79 ---- .../base/admin/blockpro/less/02-grid.less | 275 ------------ .../admin/blockpro/less/10-normalize.less | 1 - .../base/admin/blockpro/less/11-buttons.less | 194 -------- .../base/admin/blockpro/less/12-icons.less | 33 -- .../base/admin/blockpro/less/13-forms.less | 212 --------- .../base/admin/blockpro/less/14-tables.less | 187 -------- .../base/admin/blockpro/less/20-base.less | 162 ------- .../base/admin/blockpro/less/21-carousel.less | 130 ------ .../admin/blockpro/less/22-jcarousel.less | 288 ------------ .../admin/blockpro/less/23-breadcrumb.less | 37 -- .../admin/blockpro/less/24-arcticmodal.less | 74 ---- .../admin/blockpro/less/25-magnificpopup.less | 350 --------------- .../base/admin/blockpro/less/26-slider.less | 418 ------------------ .../base/admin/blockpro/less/27-topnavi.less | 80 ---- .../base/admin/blockpro/less/28-ladda.less | 399 ----------------- .../base/admin/blockpro/less/29-tabs.less | 196 -------- .../base/admin/blockpro/less/30-chosen.less | 329 -------------- .../base/admin/blockpro/less/80-main.less | 304 ------------- .../base/admin/blockpro/less/90-helpers.less | 204 --------- .../less/datepicker/dp_base.date.less | 296 ------------- .../blockpro/less/datepicker/dp_base.less | 53 --- .../less/datepicker/dp_default.date.less | 9 - .../blockpro/less/datepicker/dp_default.less | 243 ---------- .../blockpro/less/datepicker/dp_main.less | 5 - .../less/datepicker/dp_variables.less | 205 --------- .../blockpro/less/formstyler/checkbox.less | 49 -- .../admin/blockpro/less/formstyler/file.less | 80 ---- .../blockpro/less/formstyler/formstyler.less | 17 - .../blockpro/less/formstyler/inputs.less | 63 --- .../admin/blockpro/less/formstyler/radio.less | 40 -- .../blockpro/less/formstyler/select.less | 231 ---------- .../blockpro/less/formstyler/variables.less | 55 --- .../base/admin/blockpro/less/main.less | 61 --- .../less/selectize/plugins/drag_drop.less | 16 - .../selectize/plugins/dropdown_header.less | 20 - .../selectize/plugins/optgroup_columns.less | 17 - .../less/selectize/plugins/remove_button.less | 37 -- .../less/selectize/selectize.bootstrap2.less | 161 ------- .../less/selectize/selectize.bootstrap3.less | 150 ------- .../less/selectize/selectize.default.less | 84 ---- .../less/selectize/selectize.legacy.less | 75 ---- .../blockpro/less/selectize/selectize.less | 298 ------------- 47 files changed, 6437 deletions(-) delete mode 100644 engine/ajax/base/check_status.php delete mode 100644 engine/ajax/base/check_updates.php delete mode 100644 engine/modules/base/admin/blockpro/less/.htaccess delete mode 100644 engine/modules/base/admin/blockpro/less/00-variables.less delete mode 100644 engine/modules/base/admin/blockpro/less/01-mixins.less delete mode 100644 engine/modules/base/admin/blockpro/less/02-grid.less delete mode 100644 engine/modules/base/admin/blockpro/less/10-normalize.less delete mode 100644 engine/modules/base/admin/blockpro/less/11-buttons.less delete mode 100644 engine/modules/base/admin/blockpro/less/12-icons.less delete mode 100644 engine/modules/base/admin/blockpro/less/13-forms.less delete mode 100644 engine/modules/base/admin/blockpro/less/14-tables.less delete mode 100644 engine/modules/base/admin/blockpro/less/20-base.less delete mode 100644 engine/modules/base/admin/blockpro/less/21-carousel.less delete mode 100644 engine/modules/base/admin/blockpro/less/22-jcarousel.less delete mode 100644 engine/modules/base/admin/blockpro/less/23-breadcrumb.less delete mode 100644 engine/modules/base/admin/blockpro/less/24-arcticmodal.less delete mode 100644 engine/modules/base/admin/blockpro/less/25-magnificpopup.less delete mode 100644 engine/modules/base/admin/blockpro/less/26-slider.less delete mode 100644 engine/modules/base/admin/blockpro/less/27-topnavi.less delete mode 100644 engine/modules/base/admin/blockpro/less/28-ladda.less delete mode 100644 engine/modules/base/admin/blockpro/less/29-tabs.less delete mode 100644 engine/modules/base/admin/blockpro/less/30-chosen.less delete mode 100644 engine/modules/base/admin/blockpro/less/80-main.less delete mode 100644 engine/modules/base/admin/blockpro/less/90-helpers.less delete mode 100644 engine/modules/base/admin/blockpro/less/datepicker/dp_base.date.less delete mode 100644 engine/modules/base/admin/blockpro/less/datepicker/dp_base.less delete mode 100644 engine/modules/base/admin/blockpro/less/datepicker/dp_default.date.less delete mode 100644 engine/modules/base/admin/blockpro/less/datepicker/dp_default.less delete mode 100644 engine/modules/base/admin/blockpro/less/datepicker/dp_main.less delete mode 100644 engine/modules/base/admin/blockpro/less/datepicker/dp_variables.less delete mode 100644 engine/modules/base/admin/blockpro/less/formstyler/checkbox.less delete mode 100644 engine/modules/base/admin/blockpro/less/formstyler/file.less delete mode 100644 engine/modules/base/admin/blockpro/less/formstyler/formstyler.less delete mode 100644 engine/modules/base/admin/blockpro/less/formstyler/inputs.less delete mode 100644 engine/modules/base/admin/blockpro/less/formstyler/radio.less delete mode 100644 engine/modules/base/admin/blockpro/less/formstyler/select.less delete mode 100644 engine/modules/base/admin/blockpro/less/formstyler/variables.less delete mode 100644 engine/modules/base/admin/blockpro/less/main.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/plugins/drag_drop.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/plugins/dropdown_header.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/plugins/optgroup_columns.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/plugins/remove_button.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/selectize.bootstrap2.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/selectize.bootstrap3.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/selectize.default.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/selectize.legacy.less delete mode 100644 engine/modules/base/admin/blockpro/less/selectize/selectize.less diff --git a/engine/ajax/base/check_status.php b/engine/ajax/base/check_status.php deleted file mode 100644 index ad65b1c..0000000 --- a/engine/ajax/base/check_status.php +++ /dev/null @@ -1,63 +0,0 @@ - 9.6) { - dle_session(); -} else { - @session_start(); -} - - -$user_group = get_vars("usergroup"); -if (!$user_group) { - $user_group = []; - $db->query("SELECT * FROM " . USERPREFIX . "_usergroups ORDER BY id ASC"); - while ($row = $db->get_row()) { - $user_group[$row['id']] = []; - foreach ($row as $key => $value) $user_group[$row['id']][$key] = stripslashes($value); - } - set_vars("usergroup", $user_group); - $db->free(); -} -require_once ENGINE_DIR . '/modules/sitelogin.php'; - - -/** - * Основной код файла - */ -/** @var array $member_id */ -if ($member_id['user_group'] == '1') { - - die ('Free license'); - -} else { - die ('Access denied'); -} \ No newline at end of file diff --git a/engine/ajax/base/check_updates.php b/engine/ajax/base/check_updates.php deleted file mode 100644 index 05592da..0000000 --- a/engine/ajax/base/check_updates.php +++ /dev/null @@ -1,86 +0,0 @@ - 9.6) { - dle_session(); -} else { - @session_start(); -} - - -$user_group = get_vars("usergroup"); -if (!$user_group) { - $user_group = []; - $db->query("SELECT * FROM " . USERPREFIX . "_usergroups ORDER BY id ASC"); - while ($row = $db->get_row()) { - $user_group[$row['id']] = []; - foreach ($row as $key => $value) $user_group[$row['id']][$key] = stripslashes($value); - } - set_vars("usergroup", $user_group); - $db->free(); -} -require_once ENGINE_DIR . '/modules/sitelogin.php'; -require_once ENGINE_DIR . '/modules/base/core/checkUpdates.php'; - - -/** - * Основной код файла - */ - - -/** @var array $member_id */ -if ($member_id['user_group'] == '1') { - - - $checkArr = [ - 'n' => $_REQUEST['name'], - 'currentVersion' => $_REQUEST['currentVersion'], - ]; - - $check = new checkUpdates($checkArr); - - $go = $check->getResult(); - - if ($go) { - $updates = '
    Доступно обновление v' . $go['currentVersion'] . ' от ' . $go['date'] . '!
    '; - } else { - $updates = '
    Обновлений нет
    '; - } - - $checkShow = ''; - - die ($checkShow); - -} else { - die ('Access denied'); -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/.htaccess b/engine/modules/base/admin/blockpro/less/.htaccess deleted file mode 100644 index e1e23cb..0000000 --- a/engine/modules/base/admin/blockpro/less/.htaccess +++ /dev/null @@ -1,7 +0,0 @@ -Order allow,deny -Deny from all - - - Order deny,allow - Allow from all - \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/00-variables.less b/engine/modules/base/admin/blockpro/less/00-variables.less deleted file mode 100644 index 08a2cda..0000000 --- a/engine/modules/base/admin/blockpro/less/00-variables.less +++ /dev/null @@ -1,64 +0,0 @@ - - -// Colors - -@green: #50bd98; // green -@greenDark: darken(@green, 10%); // greenDark -@green1: #1b9998; // green1 -@green1Dark: darken(@green1, 10%); // green1Dark -@blue: #4a9fc5; // blue -@blueDark: #4e9cb5; // blueDark -@violet: #9b59b6; // violet -@violetDark: darken(@violet, 10%); // violetDark -@asphalt: #3c4043; // asphalt -@asphaltDark: darken(@asphalt, 10%); // asphaltDark -@yellow: #f1c40f; // yellow -@yellowDark: darken(@yellow, 10%); // yellowDark -@orange: #e67e22; // orange -@orangeDark: darken(@orange, 10%); // orangeDark -@red: #c70000; // red -@redDark: darken(@red, 10%); // redDark -@gray: #f3f6f7; // gray -@grayDark: darken(@gray, 10%); // grayDark -@gray1: #a3aaba; // gray1 -@gray1Dark: darken(@gray1, 10%); // gray1Dark -@white: #ffffff; // white -@black: #000000; // black - - - -// ////// Именованные цвета ////////// // - -@bodyColor: @white; // bodyColor -@textColor: darken(@gray1Dark, 20%); // textColor -@selectionColor: @blueDark; // selectionColor -@linkColor: @blue; // linkColor -@linkHoverColor: @green; // linkHoverColor -@placeholderText: @grayDark; // placeholderText - - -// Forms -// ------------------------- - -@btnBg: @blue; -@btnColor: @white; -@btnHoverBg: @green; -@btnHoverColor: @btnColor; -@btnActiveBg: @red; -@btnActiveColor: @btnColor; -@btnFontWeight: normal; -@btnDisableColor: @gray; - - - -@baseFontSize: 14px; // baseFontSize -@baseLineHeight: 20px; // baseLineHeight -@inputBorderRadius: 3px; // inputBorderRadius - -@inputBackground: @white; -@inputBorder: @gray1Dark; -@inputFocusBorder: @blue; -@inputDisabledBackground: @grayDark; -@formActionsBackground: @gray; -@inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border - diff --git a/engine/modules/base/admin/blockpro/less/01-mixins.less b/engine/modules/base/admin/blockpro/less/01-mixins.less deleted file mode 100644 index afdf7e9..0000000 --- a/engine/modules/base/admin/blockpro/less/01-mixins.less +++ /dev/null @@ -1,79 +0,0 @@ -// Сюда пишем основные классы, включаемые внутри - -@Arial: Arial, Helvetica, sans-serif; // Arial -@Tahoma: Tahoma, sans-serif; // Tahoma -@Verdana: Verdana, Geneva, Arial, Helvetica, sans-serif; // Verdana -@Trebuchet: "Trebuchet MS", Tahoma, sans-serif; // Trebuchet -@OpenSans: "Open Sans Condensed", Tahoma, sans-serif; // OpenSans -@PTSans: "PT Sans Narrow", PTsansNarrow, Arial, sans-serif; // PTSans - - - -.after() { - position: absolute; - content: ""; -} - -.border-radius(@radius: 10px) { - -webkit-border-radius: @radius; - -moz-border-radius: @radius; - border-radius: @radius; -} - -.box-shadow(@shadow : 0 0 10px rgba(0, 0, 0, 0.4)) { - -webkit-box-shadow: @shadow; - -moz-box-shadow: @shadow; - box-shadow: @shadow; -} - -.box-sizing(@type : border-box) { - -webkit-box-sizing: @type; - -moz-box-sizing: @type; - box-sizing: @type; -} -.text-shadow(@a : 0 1px 1px rgba(0, 0, 0, 0.4)) { - text-shadow: @a; -} - -.transition(@transition : all ease .3s) { - -webkit-transition: @transition; - -moz-transition: @transition; - -o-transition: @transition; - transition: @transition; -} -.user-select(@select : none) { - -webkit-user-select: @select; - -moz-user-select: @select; - -ms-user-select: @select; - user-select: @select; -} - -.rotate (@deg : -45deg) { - -webkit-transform: rotate(@deg); - -ms-transform: rotate(@deg); - transform: rotate(@deg); -} - -// Webkit-style focus -// ------------------ -.tab-focus() { - // Default - outline: thin dotted #333; - // Webkit - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -// Placeholder text -// ------------------------- -.placeholder(@color: @placeholderText) { - &:-moz-placeholder { - color: @color; - } - &:-ms-input-placeholder { - color: @color; - } - &::-webkit-input-placeholder { - color: @color; - } -} diff --git a/engine/modules/base/admin/blockpro/less/02-grid.less b/engine/modules/base/admin/blockpro/less/02-grid.less deleted file mode 100644 index 99469a6..0000000 --- a/engine/modules/base/admin/blockpro/less/02-grid.less +++ /dev/null @@ -1,275 +0,0 @@ -// Config - -// .content - обёртка для колонок -// .col - общий класс для всех колонок -// X - чисто от 1 до 12 -// .col-mb-X - мобильники и выше -// .col-X - планшеты и выше -// .col-td-X - десктопы -// .col-ld-X - большие десктопы - -// Grid - -@columns: 12; -@gutterWidth: 20px; - -// Column size - -@columnWidth: 100%/@columns; - -// Break-points - -@screenPhone: 480px; // screenPhone -@screenTablet: 768px; // screenTablet -@screenDesktop: 992px; // screenDesktop -@screenLarge: 1200px; // screenLarge - -@screenPhoneMax: (@screenTablet - 1); // screenPhoneMax -@screenTabletMax: (@screenDesktop - 1); // screenTabletMax -@screenDesktopMax: (@screenLarge - 1); // screenDesktopMax - - - - - -// Mobile and up - - -.content { - .center-block(); - .clearfix(); - - .content { - margin-left: -@gutterWidth / 2; - margin-right: -@gutterWidth / 2; - } -} - -.col { - padding-left: @gutterWidth / 2; - padding-right: @gutterWidth / 2; - min-height: 1px; - float: left; - .box-sizing(); -} - - -// Columns - -.columns (@index) when (@index > 0) { - .col-mb-@{index} { - width: @columnWidth * @index; - // float: left; - // padding-right: @gutterWidth / 2; - // padding-left: @gutterWidth / 2; - } - .columns(@index - 1); -} -.columns (0) {} -.columns (@columns); - - -// Tablet and up - -@media (min-width: @screenTablet) { - - .content { - max-width: @screenTablet - (@gutterWidth * 2); - } - - // Columns - .col { - float: left; - } - .columns (@index) when (@index > 0) { - .col-@{index} { - width: @columnWidth * @index; - } - .columns(@index - 1); - } - .columns (0) {} - .columns (@columns); - - - // // Offset - - // .offset (@index) when (@index > -1) { - // .col-offset-@{index} { - // margin-left: @columnWidth * @index; - // } - // .offset(@index - 1); - // } - // .offset (0) {} - // .offset (@columns); - - - // // Pull - - // .pull (@index) when (@index > -1) { - // .col-pull-@{index} { - // right: @columnWidth * @index; - // } - // .pull(@index - 1); - // } - // .pull (0) {} - // .pull (@columns); - - - // // Push - - // .push (@index) when (@index > -1) { - // .col-push-@{index} { - // left: @columnWidth * @index; - // } - // .push(@index - 1); - // } - // .push (0) {} - // .push (@columns); - - - // Groups - - // .content { - // margin-right: @gutterWidth / -2; - // margin-left: @gutterWidth / -2; - // .clearfix(); - // } - -} - -// Desktop and up - - -@media (min-width: @screenDesktop) { - - .content { - max-width: @screenDesktop - (@gutterWidth * 2); - // .center-block(); - } - - // Columns - .col { - float: left; - } - .columns (@index) when (@index > 0) { - .col-dt-@{index} { - width: @columnWidth * @index; - } - .columns(@index - 1); - } - .columns (0) {} - .columns (@columns); - - - // // Offset - - // .offset (@index) when (@index > -1) { - // .col-dt-offset-@{index} { - // margin-left: @columnWidth * @index; - // } - // .offset(@index - 1); - // } - // .offset (0) {} - // .offset (@columns); - - - // // Pull - - // .pull (@index) when (@index > -1) { - // .col-dt-pull-@{index} { - // right: @columnWidth * @index; - // } - // .pull(@index - 1); - // } - // .pull (0) {} - // .pull (@columns); - - - // // Push - - // .push (@index) when (@index > -1) { - // .col-dt-push-@{index} { - // left: @columnWidth * @index; - // } - // .push(@index - 1); - // } - // .push (0) {} - // .push (@columns); - -} - - -// Large desktop and up - - -@media (min-width: @screenLarge) { - - .content { - max-width: @screenLarge - (@gutterWidth * 2); - // .center-block(); - } - - // Columns - .col { - float: left; - } - .columns (@index) when (@index > 0) { - .col-ld-@{index} { - width: @columnWidth * @index; - } - .columns(@index - 1); - } - .columns (0) {} - .columns (@columns); - - - // // Offset - - // .offset (@index) when (@index > -1) { - // .col-ld-offset-@{index} { - // margin-left: @columnWidth * @index; - // } - // .offset(@index - 1); - // } - // .offset (0) {} - // .offset (@columns); - - - // // Pull - - // .pull (@index) when (@index > -1) { - // .col-ld-pull-@{index} { - // right: @columnWidth * @index; - // } - // .pull(@index - 1); - // } - // .pull (0) {} - // .pull (@columns); - - - // // Push - - // .push (@index) when (@index > -1) { - // .col-ld-push-@{index} { - // left: @columnWidth * @index; - // } - // .push(@index - 1); - // } - // .push (0) {} - // .push (@columns); - -} - - -// Other - - -// Positioning - -.center-block { - margin: 0 auto; -} -.col-center { - float: none; - margin: 0 auto; -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/10-normalize.less b/engine/modules/base/admin/blockpro/less/10-normalize.less deleted file mode 100644 index be9fde3..0000000 --- a/engine/modules/base/admin/blockpro/less/10-normalize.less +++ /dev/null @@ -1 +0,0 @@ -/*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/11-buttons.less b/engine/modules/base/admin/blockpro/less/11-buttons.less deleted file mode 100644 index 7f50007..0000000 --- a/engine/modules/base/admin/blockpro/less/11-buttons.less +++ /dev/null @@ -1,194 +0,0 @@ - -// Button sizes -// ------------------------- -.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { - padding: @padding-vertical @padding-horizontal; - font-size: @font-size; - line-height: @line-height; - border-radius: @border-radius; -} - -// -// Buttons -// -------------------------------------------------- - - -// Base styles -// -------------------------------------------------- - -// Core styles -.btn { - display: inline-block; - color: @btnColor; - margin-bottom: 0; // For input.btn - font-weight: @btnFontWeight; - text-align: center; - vertical-align: middle; - cursor: pointer; - background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 - background: @btnBg; - border: 0; - text-decoration: none; - white-space: nowrap; - .button-size(~"10px 15px", 8px, 18px, @baseLineHeight, @inputBorderRadius); - .user-select(); - .transition; - .box-shadow(~"0 2px 0"darken(@btnBg, 10%)); - - &:focus { - .tab-focus(); - } - - &:hover, - &:focus { - color: @btnColor; - background: @btnHoverBg; - text-decoration: none; - .box-shadow(~"0 2px 0"darken(@btnHoverBg, 10%)); - } - - &:active, - &.active { - outline: 0; - .box-shadow(~"0 2px 0" @btnHoverBg); - } - - &.disabled, - &[disabled], - fieldset[disabled] & { - cursor: not-allowed; - pointer-events: none; // Future-proof disabling of clicks - opacity: .65; - .box-shadow(~"0 2px 0" @btnBg); - } - - &-red { - background: @red; - .box-shadow(~"0 2px 0"darken(@red, 10%)); - - &:hover, - &:focus { - background: @redDark; - .box-shadow(~"0 2px 0"darken(@redDark, 10%)); - } - - &:active, - &.active { - background: @redDark; - .box-shadow(~"0 2px 0" @redDark); - } - } //.btn-red - - - &-white { - background: @white; - color: @textColor; - .box-shadow(~"0 2px 0"darken(@white, 10%)); - - &:hover, - &:focus { - color: @white; - background: @gray1; - text-decoration: none; - .box-shadow(~"0 2px 0"darken(@gray1, 10%)); - } - - &:active, - &.active { - background: @gray1; - .box-shadow(~"0 2px 0" @gray1); - } - } //.btn-red - - &-small { - .button-size(~"5px 8px", 3px, 12px, @baseLineHeight, @inputBorderRadius); - margin-bottom: 2px; - } //.btn-small - -} //.btn - - -// Link buttons -// ------------------------- - -// Make a button look and behave like a link -.btn-link { - color: @linkColor; - font-weight: normal; - cursor: pointer; - border-radius: 0; - background-color: transparent; - - &, - &:active, - &[disabled], - fieldset[disabled] & { - .box-shadow(none); - background: transparent; - } - - &:hover, - &:focus { - color: @linkHoverColor; - text-decoration: underline; - background: transparent; - .box-shadow(none); - } - &[disabled], - fieldset[disabled] & { - &:hover, - &:focus { - color: @btnDisableColor; - text-decoration: none; - } - } -} - -.btn-super { - padding: 15px; - text-transform: uppercase; - font-size: 22px; -} -.btn-big { - font-size: 18px; - padding: 10px 20px; - small { - display: block; - margin-top: -5px; - font-size: 12px; - } -} - -.btn-square { - .border-radius(0); -} - - -// Block button -// -------------------------------------------------- - -.btn-block { - display: block; - width: 100%; - padding-left: 0; - padding-right: 0; - .box-sizing(); -} - -// Vertically space out multiple block buttons -.btn-block + .btn-block { - margin-top: 5px; -} - -// Specificity overrides -input[type="submit"], -input[type="reset"], -input[type="button"] { - &.btn-block { - width: 100%; - } -} - - - - diff --git a/engine/modules/base/admin/blockpro/less/12-icons.less b/engine/modules/base/admin/blockpro/less/12-icons.less deleted file mode 100644 index 91e9bd8..0000000 --- a/engine/modules/base/admin/blockpro/less/12-icons.less +++ /dev/null @@ -1,33 +0,0 @@ -/* ========================================================================== - Иконки сайта */ -/* ========================================================================== */ - - - .icon { - // Основные стили для иконок - display: inline-block; - overflow: hidden; - width: 20px; - height: 20px; - vertical-align: text-top; - background: url(/local/codenails/images/all-icons.png) 0 0 no-repeat; - - // Не нужно писать &.icon-xxx т.к. это создаёт лишний код в css - &-small { - width: 14px; - height: 14px; - } //.icon-small - &-medium { - width: 26px; - } //.icon-medium - &-fw { - margin-right: 5px; - } //.icon-fw - - &-expamle { - background-position: -20px -20px; - } //.icon-expamle - - } //.icon - - diff --git a/engine/modules/base/admin/blockpro/less/13-forms.less b/engine/modules/base/admin/blockpro/less/13-forms.less deleted file mode 100644 index 28ca4aa..0000000 --- a/engine/modules/base/admin/blockpro/less/13-forms.less +++ /dev/null @@ -1,212 +0,0 @@ -/* ========================================================================== - FORMS */ -/* ========================================================================== */ - - .input { - display: inline-block; - height: @baseLineHeight + 10px; - padding: 0 10px; - position: relative; - margin-bottom: @baseLineHeight / 2; - font-size: 16px; - color: @textColor; - vertical-align: middle; - border: solid 1px @inputBorder; - outline: none; - background-color: @inputBackground; - -webkit-appearance: none; - .box-shadow(none); - .transition; - .box-sizing; - - &:focus { - outline: none; - border-color: @inputFocusBorder; - .box-shadow(~"0 0 0 2px" fadeout(@inputFocusBorder, 50%)); - } - textarea& { - height: auto; - border: solid 1px @inputBorder; - background: @inputBackground; - &:focus { - background: @white; - border-color: @inputFocusBorder; - } - } - &[type="number"] { - width: 80px; - padding-right: 0; - } - &.input-short { - width: 80px; - } //.input-short - } - .input-block-level, - .input-block { - width: 100%; - .box-sizing; - } - - .checkbox { - position: absolute; - left: -999px; - - + label { - cursor: pointer; - margin-top: 4px; - display: inline-block; - .user-select; - - span { - display: inline-block; - width: 18px; - height: 18px; - margin: -2px 4px 0 0; - vertical-align: middle; - background: @inputBackground; - cursor: pointer; - border: solid 1px @inputBorder; - position: relative; - } - } - &:hover, - &:focus { - + label span { - border-color: @inputFocusBorder; - .box-shadow(~"0 0 0 2px" fadeout(@inputFocusBorder, 50%)); - } - } - - &:checked + label span { - border-color: @inputFocusBorder; - - &:before { - content: ' '; - position: absolute; - border: solid @black; - border-width: 0 0 2px 2px; - height: 5px; - width: 11px; - left: 3px; - top: 4px; - .rotate; - } - } - } - - .radio { - position: absolute; - left: -999px; - - + label { - cursor: pointer; - margin-top: 4px; - display: inline-block; - .user-select; - - span { - display: inline-block; - width: 18px; - height: 18px; - margin: -2px 4px 0 0; - vertical-align: middle; - background: @white; - cursor: pointer; - border: solid 1px @inputBorder; - position: relative; - .border-radius(10px); - } - } - &:hover, - &:focus { - + label span { - border-color: @inputFocusBorder; - .box-shadow(~"0 0 0 2px" fadeout(@inputFocusBorder, 50%)); - } - } - - &:checked + label span { - border-color: @inputFocusBorder; - - &:before { - content: ' '; - position: absolute; - height: 8px; - width: 8px; - background: @black; - left: 5px; - top: 5px; - .border-radius(4px); - } - } - } - - .quont-input { - width: 40px; - } - - - .form-control { - margin-bottom: 20px; - } - - .form-label { - padding-top: 5px; - text-align: left; - font-weight: bold; - - @media (min-width: @screenTablet) { - text-align: right; - } - &-small { - width: 180px; - padding-right: 10px; - display: inline-block; - + .input { - margin-bottom: 0; - } - } //.form-label-small - } - .form-control { - .input { - margin-bottom: 0; - width: 360px; - max-width: 100%; - &.input-short { - width: 80px; - } - } - } - -textarea.code { - width: 100%; - margin: 10px 0; - vertical-align: top; - -webkit-transition: height 0.2s; - -moz-transition: height 0.2s; - transition: height 0.2s; - outline: none; - display: block; - color: @red; - padding: 5px 10px; - font: normal 14px/20px Consolas, 'Courier New', monospace; - background-color: @gray; - white-space: pre; - white-space: pre-wrap; - word-break: break-all; - word-wrap: break-word; - text-shadow: none; - border: none; - border-left: solid 3px @red; - box-sizing: border-box; - - &:focus { - background: @grayDark; - border-color: @blue; - // color:#2c3e50; - } -} - - - - diff --git a/engine/modules/base/admin/blockpro/less/14-tables.less b/engine/modules/base/admin/blockpro/less/14-tables.less deleted file mode 100644 index 80ecc65..0000000 --- a/engine/modules/base/admin/blockpro/less/14-tables.less +++ /dev/null @@ -1,187 +0,0 @@ -/* ========================================================================== - TABLES */ -/* ========================================================================== */ - - table { - max-width: 100%; - background-color: transparent; - border-collapse: collapse; - border-spacing: 0; - } - .table { - width: 100%; - margin-bottom: 20px; - } - .table th, - .table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid @gray; - } - .table th { - font-weight: bold; - background: @gray; - } - - .table thead th { - vertical-align: bottom; - } - .table caption + thead tr:first-child th, - .table caption + thead tr:first-child td, - .table colgroup + thead tr:first-child th, - .table colgroup + thead tr:first-child td, - .table thead:first-child tr:first-child th, - .table thead:first-child tr:first-child td { - border-top: 0; - } - .table tbody + tbody { - border-top: 2px solid @gray; - } - .table .table { - background-color: lighten(@gray, 3%); - .text-shadow(~"0 1px 0 " @white); - } - .table-condensed th, - .table-condensed td { - padding: 4px 5px; - } - .table-bordered { - border: 1px solid @gray; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - } - .table-bordered th, - .table-bordered td { - border-left: 1px solid @gray; - } - .table-bordered caption + thead tr:first-child th, - .table-bordered caption + tbody tr:first-child th, - .table-bordered caption + tbody tr:first-child td, - .table-bordered colgroup + thead tr:first-child th, - .table-bordered colgroup + tbody tr:first-child th, - .table-bordered colgroup + tbody tr:first-child td, - .table-bordered thead:first-child tr:first-child th, - .table-bordered tbody:first-child tr:first-child th, - .table-bordered tbody:first-child tr:first-child td { - border-top: 0; - } - - .table-striped tbody > tr:nth-child(odd) > td, - .table-striped tbody > tr:nth-child(odd) > th { - background-color: lighten(@gray, 5); - } - .table-hover tbody tr:hover > td, - .table-hover tbody tr:hover > th { - background-color: @gray; - } - .table-noborder th, - .table-noborder td { - border: 0; - } - table td[class*="span"], - table th[class*="span"], - .row-fluid table td[class*="span"], - .row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; - } - .table td.span1, - .table th.span1 { - float: none; - width: 44px; - margin-left: 0; - } - .table td.span2, - .table th.span2 { - float: none; - width: 124px; - margin-left: 0; - } - .table td.span3, - .table th.span3 { - float: none; - width: 204px; - margin-left: 0; - } - .table td.span4, - .table th.span4 { - float: none; - width: 284px; - margin-left: 0; - } - .table td.span5, - .table th.span5 { - float: none; - width: 364px; - margin-left: 0; - } - .table td.span6, - .table th.span6 { - float: none; - width: 444px; - margin-left: 0; - } - .table td.span7, - .table th.span7 { - float: none; - width: 524px; - margin-left: 0; - } - .table td.span8, - .table th.span8 { - float: none; - width: 604px; - margin-left: 0; - } - .table td.span9, - .table th.span9 { - float: none; - width: 684px; - margin-left: 0; - } - .table td.span10, - .table th.span10 { - float: none; - width: 764px; - margin-left: 0; - } - .table td.span11, - .table th.span11 { - float: none; - width: 844px; - margin-left: 0; - } - .table td.span12, - .table th.span12 { - float: none; - width: 924px; - margin-left: 0; - } - .table tbody tr.success > td { - background-color: lighten(@green, 40); - } - .table tbody tr.error > td { - background-color: lighten(@red, 40); - } - .table tbody tr.warning > td { - background-color: lighten(@yellow, 40); - } - .table tbody tr.info > td { - background-color: lighten(@blue, 40); - } - .table-hover tbody tr.success:hover > td { - background-color: lighten(@green, 30); - } - .table-hover tbody tr.error:hover > td { - background-color: lighten(@red, 30); - } - .table-hover tbody tr.warning:hover > td { - background-color: lighten(@yellow, 30); - } - .table-hover tbody tr.info:hover > td { - background-color: lighten(@blue, 30); - } diff --git a/engine/modules/base/admin/blockpro/less/20-base.less b/engine/modules/base/admin/blockpro/less/20-base.less deleted file mode 100644 index 35ea317..0000000 --- a/engine/modules/base/admin/blockpro/less/20-base.less +++ /dev/null @@ -1,162 +0,0 @@ -// Прижимем footer к низу окна браузера -// Структура html должна быть такой: -// -//
    -// -// - -html {height: 100%;} -* html body {height: 100%;} -body { - height: auto !important; - height: 100%; - min-height: 100%; - position: relative; - -} -@footerHeight: 130px; // footerHeight - -.body-wrapper { - // padding-bottom: @footerHeight + 20; // Отступ снизу = высота футера + 20px - // @media (max-width: @screen-tablet) { - // padding-bottom: 160px; - // } -} -.footer-wrapper { - // position: absolute; - // bottom: 0; - // left: 0; - // right: 0; - // height: @footerHeight; // высота футера - - // @media (max-width: @screen-tablet) { - // height: 150px; - // } -} -// Прижимем footer к низу окна браузера - -/* ========================================================================== - Основы */ -/* ========================================================================== */ - - - html, - button, - input, - select, - textarea { - color: @textColor; - } - - body { - font-size: 14px; - line-height: 1.4; - font-family: @Arial; - color: @textColor; - background: @bodyColor; - } - - ::-moz-selection { - background: @selectionColor; - color: @white; - text-shadow: none; - .text-shadow(); - } - - ::selection { - background: @selectionColor; - color: @white; - text-shadow: none; - .text-shadow(); - } - - hr { - display: block; - height: 1px; - border: 0; - border-top: 1px solid @grayDark; - // background: rgba(255,255,255,0.6); - margin: 1em 0; - padding: 0; - } - - img { - vertical-align: middle; - max-width: 100%; - .bxedtaskbarset & { - max-width: none; - } - .bx-yandex-view-map & { - max-width: inherit; - } - } - - fieldset { - border: 0; - margin: 0; - padding: 0; - } - - - textarea { - resize: vertical; - } - - a, - .pseudolink { //pseudolink - класс для псевдо-ссылок - color: @linkColor; - text-decoration: underline; - &:hover, &.active { - color: @linkHoverColor; - text-decoration: none; - } - } - *[data-target-self], - *[data-target-blank], - .pseudolink { - cursor: pointer; - } - - h1, .h1 { - font: normal 36px @Arial; - margin-top: 0; - color: @blue; - } - .detail-header { - font-size: 32px; - } - h2, .h2 { - font: normal 26px @Arial; - color: @blueDark; - - a { - text-decoration: none; - color: @black; - .transition; - &:hover { - color: @red; - } - } - } - h3, .h3 { } - h4, .h4 { } - h5, .h5 { } - h6, .h6 { } - .arial { - font-family: @Arial; - font-weight: normal; - } - @media (max-width: @screenPhone) { - .hide-phone { - display: none; - } - } - - .dashed-link { - display: inline-block; - border-bottom: dashed 1px; - text-decoration: none; - &:hover { - border-bottom: solid 1px; - } - } \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/21-carousel.less b/engine/modules/base/admin/blockpro/less/21-carousel.less deleted file mode 100644 index c4c4b02..0000000 --- a/engine/modules/base/admin/blockpro/less/21-carousel.less +++ /dev/null @@ -1,130 +0,0 @@ -/* ========================================================================== - CAROUSEL */ -/* ========================================================================== */ - - .carousel { - position: relative; - margin-bottom: 20px; - line-height: 1; - } - .carousel-inner { - overflow: hidden; - width: 100%; - position: relative; - } - .carousel-inner > .item { - display: none; - position: relative; - -webkit-transition: 0.6s ease-in-out left; - -moz-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; - } - .carousel-inner > .item > img, - .carousel-inner > .item > a > img { - display: block; - line-height: 1; - } - .carousel-inner > .active, - .carousel-inner > .next, - .carousel-inner > .prev { - display: block; - } - .carousel-inner > .active { - left: 0; - } - .carousel-inner > .next, - .carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; - } - .carousel-inner > .next { - left: 100%; - } - .carousel-inner > .prev { - left: -100%; - } - .carousel-inner > .next.left, - .carousel-inner > .prev.right { - left: 0; - } - .carousel-inner > .active.left { - left: -100%; - } - .carousel-inner > .active.right { - left: 100%; - } - .carousel-control { - position: absolute; - top: 40%; - left: 15px; - width: 40px; - height: 40px; - margin-top: -20px; - font-size: 60px; - font-weight: 100; - line-height: 30px; - color: #fff; - text-align: center; - background: #222; - border: 3px solid #fff; - -webkit-border-radius: 23px; - -moz-border-radius: 23px; - border-radius: 23px; - opacity: 0.5; - filter: alpha(opacity=50); - } - .carousel-control.right { - left: auto; - right: 15px; - } - .carousel-control:hover, - .carousel-control:focus { - color: #fff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); - } - .carousel-indicators { - position: absolute; - top: 15px; - right: 15px; - z-index: 5; - margin: 0; - list-style: none; - } - .carousel-indicators li { - display: block; - float: left; - width: 10px; - height: 10px; - margin-left: 5px; - text-indent: -999px; - background-color: #ccc; - background-color: rgba(255, 255, 255, 0.25); - border-radius: 5px; - } - .carousel-indicators .active { - background-color: #fff; - } - .carousel-caption { - position: absolute; - left: 0; - right: 0; - bottom: 0; - padding: 15px; - background: #333; - background: rgba(0, 0, 0, 0.75); - } - .carousel-caption h4, - .carousel-caption p { - color: #fff; - line-height: 20px; - } - .carousel-caption h4 { - margin: 0 0 5px; - } - .carousel-caption p { - margin-bottom: 0; - } diff --git a/engine/modules/base/admin/blockpro/less/22-jcarousel.less b/engine/modules/base/admin/blockpro/less/22-jcarousel.less deleted file mode 100644 index e2a5e89..0000000 --- a/engine/modules/base/admin/blockpro/less/22-jcarousel.less +++ /dev/null @@ -1,288 +0,0 @@ -/* ========================================================================== - Карусель */ -/* ========================================================================== */ - - -/** Stage container **/ - -.connected-carousels .stage, -.small-carousel { - width: 920px; - margin: 0 auto; - position: relative; -} - -.connected-carousels .photo-credits { - position: absolute; - right: 15px; - bottom: 0; - font-size: 13px; - color: @white; - text-shadow: 0 0 1px rgba(0, 0, 0, 0.85); - opacity: .66; -} - -.connected-carousels .photo-credits a { - color: @white; -} - -/** Navigation container **/ - -.connected-carousels .navigation-wrap { - width: 908px; - border: solid 1px @black; - border-top: 0; - padding: 15px; - margin: 11px -11px; - background: @gray1Dark url(images/slider_bg.jpg) repeat; -} -.connected-carousels .navigation { - width: 680px; - margin: 0 auto 0; - position: relative; -} - -/** Shared carousel styles **/ - -.connected-carousels .carousel, -.small-carousel { - position: relative; - overflow: hidden; -} -.small-carousel { - height: 265px; -} - -.connected-carousels .carousel ul, -.small-carousel ul { - width: 20000em; - position: absolute; - list-style: none; - margin: 0; - padding: 0; -} - -.connected-carousels .carousel li, -.small-carousel li { - float: left; - width: 920px; - height: 400px; - position: relative; -} -.small-carousel li { - height: 265px; -} -.connected-carousels .img-caption { - color: @white; - position: absolute; - bottom: -94px; - left: 0; - right: 0; - height: 76px; - background: #000; - background: rgba(0,0,0,0.7); - padding: 10px; - .clearfix; - .text-shadow; - z-index: 150; - border-top: solid 6px @yellowDark; - .box-shadow(inset 0 5px 4px -4px rgba(0,0,0,0.8)); - - - h4 { - margin: 0; - padding: 0 10px; - text-align: center; - float: left; - width: 280px; - font: bold 20px/76px @OpenSans; - border-right: solid 1px @gray1; - border-right: solid 1px rgba(255, 255, 255, 0.5); - margin-right: 20px; - .box-shadow(1px 0 0 0 rgba(0, 0, 0, 0.8)); - } - a { - display: inline-block; - margin-left: 20px; - padding: 0 5px; - color: @yellowDark; - &:hover { - background: @yellowDark; - color: @red; - text-decoration: none; - } - } - .expand { - position: absolute; - top: -30px; - left: 50%; - width: 20px; - height: 20px; - border: solid 3px @yellowDark; - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; - margin-left: -13px; - background: @yellowDark url(images/all_icons.png) no-repeat -20px -60px; - cursor: pointer; - - &:hover { - background-position: -20px -61px; - } - &.expanded { - background-position: -20px -80px; - &:hover { - background-position: -20px -79px; - } - } - } -} - -/** Stage carousel specific styles **/ - -.connected-carousels .carousel-stage { - height: 400px; -} - -/** Navigation carousel specific styles **/ - -.connected-carousels .carousel-navigation { - height: 96px; - width: 680px; -} - -.connected-carousels .carousel-navigation li { - cursor: pointer; - width: 150px; - height: 90px; - margin: 0 7px; - overflow: hidden; - .border-radius(3px); - border: solid 3px transparent; - &:hover { - border-color: @yellowDark; - } - &.active { - border-color: @yellowDark; - } -} - -.connected-carousels .carousel-navigation li img { - display: block; - // .box-sizing; -} - -.connected-carousels .carousel-navigation li.active img { -} - -/** Stage carousel controls **/ - -.connected-carousels .prev-stage, -.connected-carousels .next-stage, -.prev-small-carousel, -.next-small-carousel { - display: block; - position: absolute; - top: 0; - width: 459px; - height: 400px; - color: @white; -} -.prev-small-carousel, -.next-small-carousel { - height: 265px; -} - -.connected-carousels .prev-stage, -.prev-small-carousel { - left: 0; -} - -.connected-carousels .next-stage, -.next-small-carousel { - right: 0; -} - -.connected-carousels .prev-stage.inactive, -.connected-carousels .next-stage.inactive, -.prev-small-carousel.inactive, -.next-small-carousel.inactive { - display: none; -} - -.connected-carousels .prev-stage span, -.connected-carousels .next-stage span, -.prev-small-carousel span, -.next-small-carousel span { - display: none; - position: absolute; - top: 50%; - width: 30px; - height: 30px; - margin-top: -15px; - text-align: center; - background: @gray1Dark; - color: @white; - text-decoration: none; - .text-shadow; - font: 24px/27px @Arial; - .border-radius; -} - -.connected-carousels .prev-stage span, -.prev-small-carousel span { - left: 20px; -} - -.connected-carousels .next-stage span, -.next-small-carousel span { - right: 20px; -} - -.connected-carousels .prev-stage:hover span, -.connected-carousels .next-stage:hover span, -.prev-small-carousel:hover span, -.next-small-carousel:hover span { - display: block; -} - -/** Navigation carousel controls **/ - -.connected-carousels .prev-navigation, -.connected-carousels .next-navigation { - display: block; - position: absolute; - top: 50%; - margin-top: -10px; - width: 20px; - height: 20px; - color: @white; - text-decoration: none; - background: url(images/all_icons.png) no-repeat 0 -100px; - .text-shadow; - &:hover { - background-position: 0 -120px; - } -} - -.connected-carousels .prev-navigation { - left: -65px; -} - -.connected-carousels .prev-navigation.inactive, -.connected-carousels .next-navigation.inactive { - opacity: 0.5; - cursor: default; - background-position: 0 -100px; -} -.connected-carousels .next-navigation { - right: -65px; - background-position: -20px -100px; - &:hover { - background-position: -20px -120px; - } - &.inactive, &.inactive:hover { - background-position: -20px -100px; - } -} - diff --git a/engine/modules/base/admin/blockpro/less/23-breadcrumb.less b/engine/modules/base/admin/blockpro/less/23-breadcrumb.less deleted file mode 100644 index de63db8..0000000 --- a/engine/modules/base/admin/blockpro/less/23-breadcrumb.less +++ /dev/null @@ -1,37 +0,0 @@ -/* Breadcrumb ------------------------------------------------------------------------------*/ -.breadcrumb { - .clearfix; - ul { - margin: 10px 0 15px 0; - padding: 0; - list-style: digits; - list-style-position: inside; - li { - padding-left: 12px; - float: left; - color: @linkColor; - - &:first-child { - list-style: none; - padding-left: 0; - } - - a { - color: @linkColor; - - &:hover { - color: @linkHoverColor; - } - } - - span { - // display: inline-block; - padding: 0 8px; - // overflow: hidden; - // text-indent: -9999px; - // background: url(images/gray_dot_arr.png) no-repeat 50% 50%; - } - } - } -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/24-arcticmodal.less b/engine/modules/base/admin/blockpro/less/24-arcticmodal.less deleted file mode 100644 index b5d4cb3..0000000 --- a/engine/modules/base/admin/blockpro/less/24-arcticmodal.less +++ /dev/null @@ -1,74 +0,0 @@ - -.arcticmodal-overlay, -.arcticmodal-container { position: fixed; left: 0; top: 0; right: 0; bottom: 0; z-index: 1000; } -.arcticmodal-container { overflow: auto; margin: 0; padding: 0; border: 0; border-collapse: collapse; } -*:first-child+html .arcticmodal-container { height: 100% } -.arcticmodal-container_i { height: 100%; margin: 0 auto; } -.arcticmodal-container_i2 { padding: 24px; margin: 0; border: 0; vertical-align: middle; } -.arcticmodal-error { padding: 20px; border-radius: 10px; background: #fff; } -.arcticmodal-loading { width: 110px; height: 10px; border-radius: 10px; padding: 10px; background: #fff url(/res/images/loading.gif) no-repeat 50% 50%; .box-shadow(); } - - -.cn-modal { - position: relative; - background: @brown; - max-width: 700px; - margin: 0 auto; - padding: 20px; - border: solid 1px #fae8c8; - .box-sizing(); - .box-shadow(~"inset 45px 0 40px -45px rgba(0,0,0,.3), inset -45px 0 40px -45px rgba(0,0,0,.3), 0 7px 10px rgba(0,0,0,.3)"); - .small & { - max-width: 340px; - } - .medium & { - max-width: 450px; - } -} -.cn-modal-close { - cursor: pointer; - color: @green1; - line-height: 16px; - text-align: right; - position: absolute; - top: 24px; - right: 20px; - span { - display: inline-block; - border-bottom: solid 1px; - .transition(); - - } - &:hover { - color: #b24100; - span { - border-bottom-color: transparent; - } - } -} -.cn-modal-msg { - padding: 10px; - color: @red; - background: rgba(0,0,0,.04); - margin: 10px 0; - .box-shadow(~"inset 0 2px 8px rgba(0,0,0,.2), 0 1px 0 rgba(255,255,255,.3)"); -} - -.cn-modal-header { - margin: 0; - font: 22px/28px @Trebuchet; - text-transform: uppercase; - padding-right: 100px; -} - -.cn-modal-left-small { - width: 80px; - float: left; - padding-top: 18px; -} -.cn-modal-right-big { - // overflow: hidden; - // float: left; - padding-left: 80px; - -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/25-magnificpopup.less b/engine/modules/base/admin/blockpro/less/25-magnificpopup.less deleted file mode 100644 index 1cb57c6..0000000 --- a/engine/modules/base/admin/blockpro/less/25-magnificpopup.less +++ /dev/null @@ -1,350 +0,0 @@ -/* Magnific Popup CSS */ -.mfp-bg { - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1042; - overflow: hidden; - position: fixed; - background: #0b0b0b; - opacity: 0.8; - filter: alpha(opacity=80); } - -.mfp-wrap { - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1043; - position: fixed; - outline: none !important; - -webkit-backface-visibility: hidden; } - -.mfp-container { - text-align: center; - position: absolute; - width: 100%; - height: 100%; - left: 0; - top: 0; - padding: 0 8px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; } - -.mfp-container:before { - content: ''; - display: inline-block; - height: 100%; - vertical-align: middle; } - -.mfp-align-top .mfp-container:before { - display: none; } - -.mfp-content { - position: relative; - display: inline-block; - vertical-align: middle; - margin: 0 auto; - text-align: left; - z-index: 1045; } - -.mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content { - width: 100%; - cursor: auto; } - -.mfp-ajax-cur { - cursor: progress; } - -.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { - cursor: -moz-zoom-out; - cursor: -webkit-zoom-out; - cursor: zoom-out; } - -.mfp-zoom { - cursor: pointer; - cursor: -webkit-zoom-in; - cursor: -moz-zoom-in; - cursor: zoom-in; } - -.mfp-auto-cursor .mfp-content { - cursor: auto; } - -.mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter { - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; } - -.mfp-loading.mfp-figure { - display: none; } - -.mfp-hide { - display: none !important; } - -.mfp-preloader { - color: #cccccc; - position: absolute; - top: 50%; - width: auto; - text-align: center; - margin-top: -0.8em; - left: 8px; - right: 8px; - z-index: 1044; } - .mfp-preloader a { - color: #cccccc; } - .mfp-preloader a:hover { - color: white; } - -.mfp-s-ready .mfp-preloader { - display: none; } - -.mfp-s-error .mfp-content { - display: none; } - -button.mfp-close, button.mfp-arrow { - overflow: visible; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; - display: block; - outline: none; - padding: 0; - z-index: 1046; - -webkit-box-shadow: none; - box-shadow: none; } -button::-moz-focus-inner { - padding: 0; - border: 0; } - -.mfp-close { - width: 44px; - height: 44px; - line-height: 44px; - position: absolute; - right: 0; - top: 0; - text-decoration: none; - text-align: center; - opacity: 0.65; - filter: alpha(opacity=65); - padding: 0 0 18px 10px; - color: white; - font-style: normal; - font-size: 28px; - font-family: Arial, Baskerville, monospace; } - .mfp-close:hover, .mfp-close:focus { - opacity: 1; - filter: alpha(opacity=100); } - .mfp-close:active { - top: 1px; } - -.mfp-close-btn-in .mfp-close { - color: #333333; } - -.mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close { - color: white; - right: -6px; - text-align: right; - padding-right: 6px; - width: 100%; } - -.mfp-counter { - position: absolute; - top: 0; - right: 0; - color: #cccccc; - font-size: 12px; - line-height: 18px; } - -.mfp-arrow { - position: absolute; - opacity: 0.65; - filter: alpha(opacity=65); - margin: 0; - top: 50%; - margin-top: -55px; - padding: 0; - width: 90px; - height: 110px; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } - .mfp-arrow:active { - margin-top: -54px; } - .mfp-arrow:hover, .mfp-arrow:focus { - opacity: 1; - filter: alpha(opacity=100); } - .mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a { - content: ''; - display: block; - width: 0; - height: 0; - position: absolute; - left: 0; - top: 0; - margin-top: 35px; - margin-left: 35px; - border: medium inset transparent; } - .mfp-arrow:after, .mfp-arrow .mfp-a { - border-top-width: 13px; - border-bottom-width: 13px; - top: 8px; } - .mfp-arrow:before, .mfp-arrow .mfp-b { - border-top-width: 21px; - border-bottom-width: 21px; } - -.mfp-arrow-left { - left: 0; } - .mfp-arrow-left:after, .mfp-arrow-left .mfp-a { - border-right: 17px solid white; - margin-left: 31px; } - .mfp-arrow-left:before, .mfp-arrow-left .mfp-b { - margin-left: 25px; - border-right: 27px solid #3f3f3f; } - -.mfp-arrow-right { - right: 0; } - .mfp-arrow-right:after, .mfp-arrow-right .mfp-a { - border-left: 17px solid white; - margin-left: 39px; } - .mfp-arrow-right:before, .mfp-arrow-right .mfp-b { - border-left: 27px solid #3f3f3f; } - -.mfp-iframe-holder { - padding-top: 40px; - padding-bottom: 40px; } - .mfp-iframe-holder .mfp-content { - line-height: 0; - width: 100%; - max-width: 900px; } - .mfp-iframe-holder .mfp-close { - top: -40px; } - -.mfp-iframe-scaler { - width: 100%; - height: 0; - overflow: hidden; - padding-top: 56.25%; } - .mfp-iframe-scaler iframe { - position: absolute; - display: block; - top: 0; - left: 0; - width: 100%; - height: 100%; - box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); - background: black; } - -/* Main image in popup */ -img.mfp-img { - width: auto; - max-width: 100%; - height: auto; - display: block; - line-height: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 40px 0 40px; - margin: 0 auto; } - -/* The shadow behind the image */ -.mfp-figure { - line-height: 0; } - .mfp-figure:after { - content: ''; - position: absolute; - left: 0; - top: 40px; - bottom: 40px; - display: block; - right: 0; - width: auto; - height: auto; - z-index: -1; - box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); - background: #444444; } - .mfp-figure small { - color: #bdbdbd; - display: block; - font-size: 12px; - line-height: 14px; } - .mfp-figure figure { - margin: 0; } - -.mfp-bottom-bar { - margin-top: -36px; - position: absolute; - top: 100%; - left: 0; - width: 100%; - cursor: auto; } - -.mfp-title { - text-align: left; - line-height: 18px; - color: #f3f3f3; - word-wrap: break-word; - padding-right: 36px; } - -.mfp-image-holder .mfp-content { - max-width: 100%; } - -.mfp-gallery .mfp-image-holder .mfp-figure { - cursor: pointer; } - -@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { - /** - * Remove all paddings around the image on small screen - */ - .mfp-img-mobile .mfp-image-holder { - padding-left: 0; - padding-right: 0; } - .mfp-img-mobile img.mfp-img { - padding: 0; } - .mfp-img-mobile .mfp-figure:after { - top: 0; - bottom: 0; } - .mfp-img-mobile .mfp-figure small { - display: inline; - margin-left: 5px; } - .mfp-img-mobile .mfp-bottom-bar { - background: rgba(0, 0, 0, 0.6); - bottom: 0; - margin: 0; - top: auto; - padding: 3px 5px; - position: fixed; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; } - .mfp-img-mobile .mfp-bottom-bar:empty { - padding: 0; } - .mfp-img-mobile .mfp-counter { - right: 5px; - top: 3px; } - .mfp-img-mobile .mfp-close { - top: 0; - right: 0; - width: 35px; - height: 35px; - line-height: 35px; - background: rgba(0, 0, 0, 0.6); - position: fixed; - text-align: center; - padding: 0; } } - -@media all and (max-width: 900px) { - .mfp-arrow { - -webkit-transform: scale(0.75); - transform: scale(0.75); } - .mfp-arrow-left { - -webkit-transform-origin: 0; - transform-origin: 0; } - .mfp-arrow-right { - -webkit-transform-origin: 100%; - transform-origin: 100%; } - .mfp-container { - padding-left: 6px; - padding-right: 6px; } } diff --git a/engine/modules/base/admin/blockpro/less/26-slider.less b/engine/modules/base/admin/blockpro/less/26-slider.less deleted file mode 100644 index ceed737..0000000 --- a/engine/modules/base/admin/blockpro/less/26-slider.less +++ /dev/null @@ -1,418 +0,0 @@ -/*********************************************************************** -* -* Liquid Slider -* Kevin Batdorf -* -* http://liquidslider.com -* -* GPL license -* -************************************************************************/ - -/****************************************************** -* No JavaScript -* Use this to apply styles when Javascript is disabled, -* and be sure to include the ".no-js" class in your html -* markup. -*******************************************************/ -.no-js .liquid-slider { - height:350px; - overflow:scroll; -} - -/****************************************************** -* Preloader -* Use this to apply styles when Javascript is disabled, -* and be sure to include the ".no-js" class in your html -* markup. -*******************************************************/ -.ls-wrapper .ls-preloader { - background: url(../img/loading.gif) #f2f2f2 no-repeat center 75px; - opacity:1; - /* Do not edit below this line */ - width:100%; - height:100%; - position:absolute; - top:0; - left:0; - z-index:2; -} - -/****************************************************************** -* Base Styles -* The styles here will apply to everything. I recommend you keep -* the styles in here specific to mobile defices, then use -* the media queries at the bottom to define further styles for larger -* screen-sizes. Think Mobile First. But be cautious of how -* your site will look in older IE browsers. -* -* Additional media queries are at the bottom of this document -******************************************************************/ -.ls-wrapper { - margin:0 auto; - /* Do not edit below this line */ - clear: both; - overflow: auto; - position: relative; -} - -/****************************************************** -* Main Container -* This is the main container (minus the navigation). -* Be sure to match the width with the .panel class, -* or it won't work properly. Also, width only applies -* if you are not using the responsive setting. -* -* The responsive slider will interpret the width as the -* max width instead -*******************************************************/ -.ls-wrapper .liquid-slider { - // background: #f2f2f2; - width: 1030px; - /* Do not edit below this line */ - float: left; - overflow: hidden; - position: relative; -} -.ls-wrapper .panel-container { - /* Do not edit below this line */ - position: relative; - -} -.ls-wrapper .liquid-slider .panel-container .fade { - /* Do not edit below this line */ - position: absolute; - top: 0; - left: 0; - display: block; -} - -/****************************************************** -* Panels -* This is for the panels. If you are using the -* responsive setting, this will act as the max-width -* for the entire slider. -*******************************************************/ -.ls-wrapper .liquid-slider .panel { - width: 1030px; - /* Do not edit below this line */ - display: block; - float: left; -} - -/****************************************************** -* These provide a base starting point for images and -* video. However, you will have to add more rules -* based on the content you use. Use the @media queries -* at the bottom of this file. -*******************************************************/ -.ls-wrapper .liquid-slider .panel img{ - /* - width:100%; - height:auto; - margin:0 5px; - */ -} - -.ls-wrapper .liquid-slider .panel video { - /* - width:100%; - height:auto; - */ -} - -/****************************************************** -* This is mainly used to adjust the padding inside each -* panel. If you are using the responsive setting, you -* need to use the settings below as this will not apply. -*******************************************************/ -.ls-wrapper .liquid-slider .panel-wrapper { - padding: 20px; - /* Do not edit below this line */ - position:relative; -} - -/***************************************************** -* This will adjust styles for all navigation tabs -* less of course the select box used for mobile -* navigation. The .current styles will apply only to -* the current tab. -* -* You may use this section to create navigation for -* mobile devices if you set mobileNavigation: false -* Be sure to edit media queries for larger devices below -* I have included an example below in comments. -* -* .currentCrossLink refers to external crosslinking. -*******************************************************/ -.ls-wrapper .ls-nav a { - background: #d8d8d8; - color: #333333; - margin-right: 1px; - padding: 10px 15px; -} -.ls-wrapper .ls-nav a:hover { - background: #f2f2f2; - color: #333333; - text-shadow: none; -} -.ls-wrapper .ls-nav .current { - background: #f2f2f2; -} -.currentCrossLink { - font-weight: bold; -} -.ls-wrapper .ls-nav ul { - padding:0; - /* Do not edit below this line */ - clear: both; - display: block; - margin: auto; - overflow: hidden; -} -.ls-wrapper .ls-nav ul li { - /* Do not edit below this line */ - display: inline; -} -.ls-wrapper .ls-nav ul li a { - - /* Do not edit below this line */ - display: block; - float: left; - text-decoration: none; -} -/***************************************************** -* Mobile Menu -* This will adjust styles for selectbox styles. I have -* included a simple example to create a custom select -* box. -*******************************************************/ -.ls-wrapper .ls-nav { - overflow:hidden; - clear:both; -} -.ls-wrapper .ls-select-box { - /* Delete these if you want the standard select box. - Also delete the rules below */ - - width: 100%; - height: 35px; - overflow: hidden; - // background: url(../img/menu.png) no-repeat right #ddd; - -} -.ls-wrapper .ls-select-box select { - /* If you want the standard select box, use - width:100% - And delete the rest of the styling here */ - - width: 150%; - -webkit-appearance: none; - -moz-appearance: none; - appearance:none; - background: transparent; - padding: 5px; - font-size: 110%; - border: none; - height: 35px; - cursor:pointer; - outline: 0; -} - -/****************************************************** -* Arrows -* This section refers to both the non-graphical and -* graphical navigation arrows. -* -* Some settings will be overwritten when using the -* responsive setting. -*******************************************************/ -.ls-wrapper .ls-nav-left, .ls-wrapper .ls-nav-right { - /* Do not edit below this line */ - float: left; -} -.ls-wrapper .ls-nav-left a, .ls-wrapper .ls-nav-right a { - /* non-graphical arrows */ - // background: #000; - color: #fff; - padding: 5px; - width: 100px; - /* Do not edit below this line */ - display: block; - text-align: center; - text-decoration: none; -} -.ls-wrapper .ls-nav-left-arrow, .ls-wrapper .ls-nav-right-arrow { - cursor: pointer; - /* Do not edit below this line */ - float: left; -} -.ls-wrapper .ls-nav-left-arrow a, .ls-wrapper .ls-nav-right-arrow a { - /* Do not edit below this line */ - display: block; -} -.ls-wrapper .ls-nav-left, .ls-wrapper .ls-nav-left-arrow { - /* Do not edit below this line */ - clear: both; -} -.ls-wrapper .ls-nav-right-arrow { - width: 25px; - height: 25px; - background: url(/res/images/all-icons.png) no-repeat -40px -100px; - margin-top: 50px; - margin-right: 5px; - /* Do not edit below this line */ - position:relative; -} -.ls-wrapper .ls-nav-left-arrow { - width: 25px; - height: 25px; - background: url(/res/images/all-icons.png) no-repeat -40px -40px; - margin-top: 50px; - margin-left: 5px; - /* Do not edit below this line */ - position:relative; -} -.ls-wrapper .ls-nav-left-arrow:hover { - /* Left graphical arrows hover */ - background-position: -40px -70px; -} -.ls-wrapper .ls-nav-left-arrow:active { - /* Left graphical arrows click */ -} -.ls-wrapper .ls-nav-right-arrow:hover { - /* Right graphical arrows hover */ - background-position: -40px -130px; -} -.ls-wrapper .ls-nav-right-arrow:active { - /* Right graphical arrows click */ -} -.arrows .liquid-slider { - /* Margin between slider and arrows */ - margin: 0 10px; -} - -/****************************************************** -* Responsive Styles -* Here are the main responsive styles. This mostly -* covers the arrows, and most of the settings can be -* applied above. -*******************************************************/ -.ls-responsive .liquid-slider { - /* Do not edit below this line */ - width: 100%; - margin: 0; -} -.ls-responsive .liquid-slider .panel .panel-wrapper { - padding: 10px; -} -.ls-responsive .ls-nav-left { - /* Left non-graphical arrows */ - /* Do not edit below this line */ - position: absolute; - left: 0; - z-index: 2; -} -.ls-responsive .ls-nav-left a { - /* Left non-graphical arrows */ - background: #9A9A9A; - width: 80px; -} -.ls-responsive .ls-nav-left a:hover { - /* Left non-graphical hover */ - background: #747474; -} -.ls-responsive .ls-nav-right { - /* Right non-graphical arrows */ - /* Do not edit below this line */ - position: absolute; - right: 0; - z-index: 2; -} -.ls-responsive .ls-nav-right a { - /* Right non-graphical arrows */ - background: #9A9A9A; - width: 80px; -} -.ls-responsive .ls-nav-right a:hover { - /* Right non-graphical arrows hover */ - background: #747474; -} -.ls-responsive .ls-nav-left-arrow { - /* Do not edit below this line */ - position: absolute; - left: 0; - z-index: 2; -} -.ls-responsive .ls-nav-right-arrow { - /* Do not edit below this line */ - position: absolute; - right: 0; - z-index: 2; -} - -/****************************************************************** -* Larger Mobile Devices -* This is for devices like the Galaxy Note or something that's -* larger than an iPhone but smaller than a tablet. -******************************************************************/ -@media only screen and (min-width: 481px) { - .ls-wrapper .liquid-slider .panel img{ - /* Example */ - /* - width:24%; - margin:2px; - */ - } - -} - -/****************************************************************** -* Tablet & Smaller Laptops -* This will include tablets and some netbooks. -******************************************************************/ -@media only screen and (min-width: 768px) { - .ls-wrapper .liquid-slider .panel img{ - /* Example */ - /* - width:24%; - */ - } - .ls-responsive .liquid-slider .panel .panel-wrapper { - padding: 20px 35px 0; - } -} - -/****************************************************************** -* DESKTOP -* This is the average viewing window. So Desktops, Laptops, and -* in general anyone not viewing on a mobile device. Here's where -* you can add resource intensive styles. -******************************************************************/ -@media only screen and (min-width: 1030px) { - - -} - -/****************************************************************** -* LARGE VIEWING SIZE -* This is for the larger monitors and possibly full screen viewers. -******************************************************************/ -@media only screen and (min-width: 1240px) { - - -} - -/****************************************************************** -* RETINA (2x RESOLUTION DEVICES) -* This applies to the retina iPhone (4s) and iPad (2,3) along with -* other displays with a 2x resolution. You can also create a media -* query for retina AND a certain size if you want. Go Nuts. -******************************************************************/ - -@media only screen and (-webkit-min-device-pixel-ratio: 1.5), - only screen and (min--moz-device-pixel-ratio: 1.5), - only screen and (min-device-pixel-ratio: 1.5) { - - -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/27-topnavi.less b/engine/modules/base/admin/blockpro/less/27-topnavi.less deleted file mode 100644 index b034385..0000000 --- a/engine/modules/base/admin/blockpro/less/27-topnavi.less +++ /dev/null @@ -1,80 +0,0 @@ - /* ========================================================================== - TOPNAVI */ - /* ========================================================================== */ - - .topnavi, - .topnavi li { - margin: 0; - padding: 0; - list-style: none; - } - .topnavi { - background: @gray; - margin: 20px 0; - .clearfix(); - @media (max-width: @screenTablet) { - padding-bottom: 10px; - } - li { - a { - font: normal 18px/20px @Arial; - text-decoration: none; - color: @black; - display: block; - padding: 5px 15px 3px 30px; - } - @media (min-width: @screenPhone) and (max-width: @screenTabletMax) { - width: 50%; - float: left; - } - @media (min-width: @screenDesktop) { - float: left; - a { - font-size: 16px; - border-left: solid 1px @gray; - padding: 5px 15px; - text-transform: uppercase; - .transition(); - &:hover { - color: @red; - background: @gray1Dark; - } - - } - &:first-child a { - border: 0; - } - } - } - @media (min-width: @screenTabletMax) { - display: table; - width: 100%; - li { - display: table-cell; - // position: relative; - float: none; - vertical-align: middle; - - a { - .transition(); - } - } - @-moz-document url-prefix() { - - display: block; - - li { - display: block; - float: left; - } - } - li { - text-align: left; - } - > li { - text-align: center; - } - } - - } //.topnavi - diff --git a/engine/modules/base/admin/blockpro/less/28-ladda.less b/engine/modules/base/admin/blockpro/less/28-ladda.less deleted file mode 100644 index 255b29e..0000000 --- a/engine/modules/base/admin/blockpro/less/28-ladda.less +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Ladda - * http://lab.hakim.se/ladda - * MIT licensed - * - * Copyright (C) 2014 Hakim El Hattab, http://hakim.se - */ -/************************************* - * CONFIG - */ -/************************************* - * MIXINS - */ -/************************************* - * BUTTON BASE - */ -.ladda-button { - position: relative; -} - -/* Spinner animation */ -.ladda-button .ladda-spinner { - position: absolute; - z-index: 2; - display: inline-block; - width: 32px; - height: 32px; - top: 50%; - margin-top: -16px; - opacity: 0; - pointer-events: none; -} - -/* Button label */ -.ladda-button .ladda-label { - position: relative; - z-index: 3; -} - -/* Progress bar */ -.ladda-button .ladda-progress { - position: absolute; - width: 0; - height: 100%; - left: 0; - top: 0; - background: rgba(0, 0, 0, 0.2); - visibility: hidden; - opacity: 0; - -webkit-transition: 0.1s linear all !important; - -moz-transition: 0.1s linear all !important; - -ms-transition: 0.1s linear all !important; - -o-transition: 0.1s linear all !important; - transition: 0.1s linear all !important; -} - -.ladda-button[data-loading] .ladda-progress { - opacity: 1; - visibility: visible; -} - -/************************************* - * EASING - */ -.ladda-button, -.ladda-button .ladda-spinner, -.ladda-button .ladda-label { - -webkit-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important; - -moz-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important; - -ms-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important; - -o-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important; - transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important; -} - -.ladda-button[data-style=zoom-in], -.ladda-button[data-style=zoom-in] .ladda-spinner, -.ladda-button[data-style=zoom-in] .ladda-label, -.ladda-button[data-style=zoom-out], -.ladda-button[data-style=zoom-out] .ladda-spinner, -.ladda-button[data-style=zoom-out] .ladda-label { - -webkit-transition: 0.3s ease all !important; - -moz-transition: 0.3s ease all !important; - -ms-transition: 0.3s ease all !important; - -o-transition: 0.3s ease all !important; - transition: 0.3s ease all !important; -} - -/************************************* - * EXPAND LEFT - */ -.ladda-button[data-style=expand-right] .ladda-spinner { - right: 14px; -} -.ladda-button[data-style=expand-right][data-size="s"] .ladda-spinner, .ladda-button[data-style=expand-right][data-size="xs"] .ladda-spinner { - right: 4px; -} -.ladda-button[data-style=expand-right][data-loading] { - padding-right: 56px; -} -.ladda-button[data-style=expand-right][data-loading] .ladda-spinner { - opacity: 1; -} -.ladda-button[data-style=expand-right][data-loading][data-size="s"], .ladda-button[data-style=expand-right][data-loading][data-size="xs"] { - padding-right: 40px; -} - -/************************************* - * EXPAND RIGHT - */ -.ladda-button[data-style=expand-left] .ladda-spinner { - left: 14px; -} -.ladda-button[data-style=expand-left][data-size="s"] .ladda-spinner, .ladda-button[data-style=expand-left][data-size="xs"] .ladda-spinner { - left: 4px; -} -.ladda-button[data-style=expand-left][data-loading] { - padding-left: 56px; -} -.ladda-button[data-style=expand-left][data-loading] .ladda-spinner { - opacity: 1; -} -.ladda-button[data-style=expand-left][data-loading][data-size="s"], .ladda-button[data-style=expand-left][data-loading][data-size="xs"] { - padding-left: 40px; -} - -/************************************* - * EXPAND UP - */ -.ladda-button[data-style=expand-up] { - overflow: hidden; -} -.ladda-button[data-style=expand-up] .ladda-spinner { - top: -32px; - left: 50%; - margin-left: -16px; -} -.ladda-button[data-style=expand-up][data-loading] { - padding-top: 54px; -} -.ladda-button[data-style=expand-up][data-loading] .ladda-spinner { - opacity: 1; - top: 14px; - margin-top: 0; -} -.ladda-button[data-style=expand-up][data-loading][data-size="s"], .ladda-button[data-style=expand-up][data-loading][data-size="xs"] { - padding-top: 32px; -} -.ladda-button[data-style=expand-up][data-loading][data-size="s"] .ladda-spinner, .ladda-button[data-style=expand-up][data-loading][data-size="xs"] .ladda-spinner { - top: 4px; -} - -/************************************* - * EXPAND DOWN - */ -.ladda-button[data-style=expand-down] { - overflow: hidden; -} -.ladda-button[data-style=expand-down] .ladda-spinner { - top: 62px; - left: 50%; - margin-left: -16px; -} -.ladda-button[data-style=expand-down][data-size="s"] .ladda-spinner, .ladda-button[data-style=expand-down][data-size="xs"] .ladda-spinner { - top: 40px; -} -.ladda-button[data-style=expand-down][data-loading] { - padding-bottom: 54px; -} -.ladda-button[data-style=expand-down][data-loading] .ladda-spinner { - opacity: 1; -} -.ladda-button[data-style=expand-down][data-loading][data-size="s"], .ladda-button[data-style=expand-down][data-loading][data-size="xs"] { - padding-bottom: 32px; -} - -/************************************* - * SLIDE LEFT - */ -.ladda-button[data-style=slide-left] { - overflow: hidden; -} -.ladda-button[data-style=slide-left] .ladda-label { - position: relative; -} -.ladda-button[data-style=slide-left] .ladda-spinner { - left: 100%; - margin-left: -16px; -} -.ladda-button[data-style=slide-left][data-loading] .ladda-label { - opacity: 0; - left: -100%; -} -.ladda-button[data-style=slide-left][data-loading] .ladda-spinner { - opacity: 1; - left: 50%; -} - -/************************************* - * SLIDE RIGHT - */ -.ladda-button[data-style=slide-right] { - overflow: hidden; -} -.ladda-button[data-style=slide-right] .ladda-label { - position: relative; -} -.ladda-button[data-style=slide-right] .ladda-spinner { - right: 100%; - margin-left: -16px; -} -.ladda-button[data-style=slide-right][data-loading] .ladda-label { - opacity: 0; - left: 100%; -} -.ladda-button[data-style=slide-right][data-loading] .ladda-spinner { - opacity: 1; - left: 50%; -} - -/************************************* - * SLIDE UP - */ -.ladda-button[data-style=slide-up] { - overflow: hidden; -} -.ladda-button[data-style=slide-up] .ladda-label { - position: relative; -} -.ladda-button[data-style=slide-up] .ladda-spinner { - left: 50%; - margin-left: -16px; - margin-top: 1em; -} -.ladda-button[data-style=slide-up][data-loading] .ladda-label { - opacity: 0; - top: -1em; -} -.ladda-button[data-style=slide-up][data-loading] .ladda-spinner { - opacity: 1; - margin-top: -16px; -} - -/************************************* - * SLIDE DOWN - */ -.ladda-button[data-style=slide-down] { - overflow: hidden; -} -.ladda-button[data-style=slide-down] .ladda-label { - position: relative; -} -.ladda-button[data-style=slide-down] .ladda-spinner { - left: 50%; - margin-left: -16px; - margin-top: -2em; -} -.ladda-button[data-style=slide-down][data-loading] .ladda-label { - opacity: 0; - top: 1em; -} -.ladda-button[data-style=slide-down][data-loading] .ladda-spinner { - opacity: 1; - margin-top: -16px; -} - -/************************************* - * ZOOM-OUT - */ -.ladda-button[data-style=zoom-out] { - overflow: hidden; -} - -.ladda-button[data-style=zoom-out] .ladda-spinner { - left: 50%; - margin-left: -16px; - -webkit-transform: scale(2.5); - -moz-transform: scale(2.5); - -ms-transform: scale(2.5); - -o-transform: scale(2.5); - transform: scale(2.5); -} - -.ladda-button[data-style=zoom-out] .ladda-label { - position: relative; - display: inline-block; -} - -.ladda-button[data-style=zoom-out][data-loading] .ladda-label { - opacity: 0; - -webkit-transform: scale(0.5); - -moz-transform: scale(0.5); - -ms-transform: scale(0.5); - -o-transform: scale(0.5); - transform: scale(0.5); -} - -.ladda-button[data-style=zoom-out][data-loading] .ladda-spinner { - opacity: 1; - -webkit-transform: none; - -moz-transform: none; - -ms-transform: none; - -o-transform: none; - transform: none; -} - -/************************************* - * ZOOM-IN - */ -.ladda-button[data-style=zoom-in] { - overflow: hidden; -} - -.ladda-button[data-style=zoom-in] .ladda-spinner { - left: 50%; - margin-left: -16px; - -webkit-transform: scale(0.2); - -moz-transform: scale(0.2); - -ms-transform: scale(0.2); - -o-transform: scale(0.2); - transform: scale(0.2); -} - -.ladda-button[data-style=zoom-in] .ladda-label { - position: relative; - display: inline-block; -} - -.ladda-button[data-style=zoom-in][data-loading] .ladda-label { - opacity: 0; - -webkit-transform: scale(2.2); - -moz-transform: scale(2.2); - -ms-transform: scale(2.2); - -o-transform: scale(2.2); - transform: scale(2.2); -} - -.ladda-button[data-style=zoom-in][data-loading] .ladda-spinner { - opacity: 1; - -webkit-transform: none; - -moz-transform: none; - -ms-transform: none; - -o-transform: none; - transform: none; -} - -/************************************* - * CONTRACT - */ -.ladda-button[data-style=contract] { - overflow: hidden; - width: 100px; -} - -.ladda-button[data-style=contract] .ladda-spinner { - left: 50%; - margin-left: -16px; -} - -.ladda-button[data-style=contract][data-loading] { - border-radius: 50%; - width: 52px; -} - -.ladda-button[data-style=contract][data-loading] .ladda-label { - opacity: 0; -} - -.ladda-button[data-style=contract][data-loading] .ladda-spinner { - opacity: 1; -} - -/************************************* - * OVERLAY - */ -.ladda-button[data-style=contract-overlay] { - overflow: hidden; - width: 100px; - box-shadow: 0px 0px 0px 2000px transparent; -} - -.ladda-button[data-style=contract-overlay] .ladda-spinner { - left: 50%; - margin-left: -16px; -} - -.ladda-button[data-style=contract-overlay][data-loading] { - border-radius: 50%; - width: 52px; - /*outline: 10000px solid rgba( 0, 0, 0, 0.5 );*/ - box-shadow: 0px 0px 0px 2000px rgba(0, 0, 0, 0.8); -} - -.ladda-button[data-style=contract-overlay][data-loading] .ladda-label { - opacity: 0; -} - -.ladda-button[data-style=contract-overlay][data-loading] .ladda-spinner { - opacity: 1; -} diff --git a/engine/modules/base/admin/blockpro/less/29-tabs.less b/engine/modules/base/admin/blockpro/less/29-tabs.less deleted file mode 100644 index da9827e..0000000 --- a/engine/modules/base/admin/blockpro/less/29-tabs.less +++ /dev/null @@ -1,196 +0,0 @@ -ul.resp-tabs-list { - margin: 0px; - padding: 0px; -} - -.resp-tabs-list li { - font-size: 15px; - display: inline-block; - padding: 10px 15px 9px; - margin: 0 3px -1px 0; - list-style: none; - cursor: pointer; - float: left; - border-top: solid 2px transparent; - border-bottom: solid 1px transparent; - .border-radius(~"5px 5px 0 0"); - &:hover { - background: @gray; - border-top: solid 2px @gray1; - border-bottom: solid 1px @grayDark; - } -} - -.resp-tabs-container { - padding: 0px; - background-color: #fff; - clear: left; -} - -h2.resp-accordion { - cursor: pointer; - padding: 5px; - display: none; -} - -.resp-tab-content { - display: none; - padding: 15px; -} - -.resp-tabs-list li.resp-tab-active { - color: @blue; - border: 1px solid @grayDark; - border-top: solid 2px @blue; - border-bottom: none; - margin-bottom: -1px !important; - padding: 10px 14px 10px 14px !important; - &:hover { - background: @white !important; - } -} - -.resp-tab-active { - border-bottom: none; - background-color: #fff; -} - -.resp-content-active, .resp-accordion-active { - display: block; -} - -.resp-tab-content { - border: 1px solid @grayDark; -} - -h2.resp-accordion { - font-size: 13px; - border: 1px solid @grayDark; - border-top: 0px solid @grayDark; - margin: 0px; - padding: 10px 15px; -} - -h2.resp-tab-active { - border-bottom: 0px solid @grayDark !important; - margin-bottom: 0px !important; - padding: 10px 15px !important; -} - -h2.resp-tab-title:last-child { - border-bottom: 12px solid @grayDark !important; - background: blue; -} -/*-----------Vertical tabs-----------*/ -.resp-vtabs ul.resp-tabs-list { - float: left; - width: 30%; -} - -.resp-vtabs .resp-tabs-list li { - display: block; - padding: 15px 15px !important; - margin: 0; - cursor: pointer; - float: none; -} - -.resp-vtabs .resp-tabs-container { - padding: 0px; - background-color: #fff; - border: 1px solid @grayDark; - float: left; - width: 68%; - min-height: 250px; - border-radius: 4px; - clear: none; -} - -.resp-vtabs .resp-tab-content { - border: none; -} - -.resp-vtabs li.resp-tab-active { - border: 1px solid @grayDark; - border-right: none; - background-color: #fff; - position: relative; - z-index: 1; - margin-right: -1px !important; - padding: 14px 15px 15px 14px !important; -} - -.resp-arrow { - width: 0; - height: 0; - float: right; - margin-top: 3px; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-top: 12px solid @grayDark; -} - -h2.resp-tab-active span.resp-arrow { - border: none; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 12px solid @white; -} - -/*-----------Accordion styles-----------*/ -h2.resp-tab-active { - color: @white; - background: @blue !important; -} -.resp-easy-accordion h2.resp-accordion { - display: block; -} -.resp-easy-accordion .resp-tab-content { - border: 1px solid @grayDark; -} - -.resp-easy-accordion .resp-tab-content:last-child { - border-bottom: 1px solid @grayDark !important; -} - -.resp-jfit { - width: 100%; - margin: 0px; -} - -.resp-tab-content-active { - display: block; -} - -h2.resp-accordion:first-child { - border-top: 1px solid @grayDark !important; -} - -/*Here your can change the breakpoint to set the accordion, when screen resolution changed*/ -@media only screen and (max-width: 768px) { - ul.resp-tabs-list { - display: none; - } - - h2.resp-accordion { - display: block; - } - - .resp-vtabs .resp-tab-content { - border: 1px solid @grayDark; - } - - .resp-vtabs .resp-tabs-container { - border: none; - float: none; - width: 100%; - min-height: initial; - clear: none; - } - .resp-accordion-closed { - display:none !important; - } - .resp-vtabs .resp-tab-content:last-child { - border-bottom: 1px solid @grayDark !important; - } -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/30-chosen.less b/engine/modules/base/admin/blockpro/less/30-chosen.less deleted file mode 100644 index 117ca70..0000000 --- a/engine/modules/base/admin/blockpro/less/30-chosen.less +++ /dev/null @@ -1,329 +0,0 @@ -/* -Chosen, a Select Box Enhancer for jQuery and Prototype -by Patrick Filler for Harvest, http://getharvest.com - -Version 1.3.0 -Full source at https://github.com/harvesthq/chosen -Copyright (c) 2011-2014 Harvest http://getharvest.com - -MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md -This file is generated by `grunt build`, do not edit it by hand. -*/ - -/* @group Base */ -.chosen-container { - position: relative; - display: inline-block; - vertical-align: middle; - font-size: 16px; - zoom: 1; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; -} -.chosen-container * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.chosen-container .chosen-drop { - position: absolute; - top: 100%; - left: -9999px; - z-index: 1010; - width: 100%; - border: 1px solid @inputBorder; - border-top: 0; - background: #fff; -} -.chosen-container.chosen-with-drop .chosen-drop { - left: 0; -} -.chosen-container a { - cursor: pointer; -} - -/* @end */ -/* @group Single Chosen */ -.chosen-container-single .chosen-single { - position: relative; - display: block; - overflow: hidden; - padding: 0 0 0 8px; - height: 30px; - border: 1px solid @inputBorder; - background-color: #fff; - color: #444; - text-decoration: none; - white-space: nowrap; - line-height: 24px; -} -.chosen-container-single .chosen-default { - color: #999; -} -.chosen-container-single .chosen-single span { - display: block; - overflow: hidden; - margin-right: 26px; - text-overflow: ellipsis; - white-space: nowrap; - line-height: 28px; -} -.chosen-container-single .chosen-single-with-deselect span { - margin-right: 38px; -} -.chosen-container-single .chosen-single abbr { - position: absolute; - top: 6px; - right: 26px; - display: block; - width: 12px; - height: 12px; - background: url('../images/chosen-sprite.png') -42px 1px no-repeat; - font-size: 1px; -} -.chosen-container-single .chosen-single abbr:hover { - background-position: -42px -10px; -} -.chosen-container-single.chosen-disabled .chosen-single abbr:hover { - background-position: -42px -10px; -} -.chosen-container-single .chosen-single div { - position: absolute; - top: 0; - right: 0; - display: block; - width: 18px; - height: 100%; -} -.chosen-container-single .chosen-single div b { - display: block; - width: 100%; - height: 100%; - background: url('../images/chosen-sprite.png') no-repeat 0px 4px; -} -.chosen-container-single .chosen-search { - position: relative; - z-index: 1010; - margin: 0; - padding: 3px 4px; - white-space: nowrap; -} -.chosen-container-single .chosen-search input[type="text"] { - margin: 1px 0; - padding: 4px 20px 4px 5px; - width: 100%; - height: auto; - outline: 0; - border: 1px solid @inputBorder; - background: url('../images/chosen-sprite.png') no-repeat 100% -20px; - font-size: 1em; - font-family: sans-serif; - line-height: normal; -} -.chosen-container-single .chosen-drop { - margin-top: -1px; - background-clip: padding-box; -} -.chosen-container-single.chosen-container-single-nosearch .chosen-search { - position: absolute; - left: -9999px; -} - -/* @end */ -/* @group Results */ -.chosen-container .chosen-results { - color: #444; - position: relative; - overflow-x: hidden; - overflow-y: auto; - margin: 0 4px 4px 0; - padding: 0 0 0 4px; - max-height: 240px; - -webkit-overflow-scrolling: touch; -} -.chosen-container .chosen-results li { - display: none; - margin: 0; - padding: 5px 6px; - list-style: none; - line-height: 20px; - word-wrap: break-word; - -webkit-touch-callout: none; -} -.chosen-container .chosen-results li.active-result { - display: list-item; - cursor: pointer; -} -.chosen-container .chosen-results li.disabled-result { - display: list-item; - color: #ccc; - cursor: default; -} -.chosen-container .chosen-results li.highlighted { - background-color: @blue; - color: #fff; -} -.chosen-container .chosen-results li.no-results { - color: #777; - display: list-item; - background: #f4f4f4; -} -.chosen-container .chosen-results li.group-result { - display: list-item; - font-weight: bold; - cursor: default; -} -.chosen-container .chosen-results li.group-option { - padding-left: 20px; -} -.chosen-container .chosen-results li em { - font-style: normal; - text-decoration: underline; -} - -/* @end */ -/* @group Multi Chosen */ -.chosen-container-multi .chosen-choices { - position: relative; - overflow: hidden; - margin: 0; - padding: 1px 10px 0; - width: 100%; - height: auto !important; - height: 1%; - border: 1px solid @inputBorder; - background-color: #fff; - cursor: text; -} -.chosen-container-multi .chosen-choices li { - float: left; - list-style: none; -} -.chosen-container-multi .chosen-choices li.search-field { - margin: 0; - padding: 0; - white-space: nowrap; -} -.chosen-container-multi .chosen-choices li.search-field input[type="text"] { - margin: 1px 0; - padding: 0; - height: 25px; - outline: 0; - border: 0 !important; - background: transparent !important; - color: #999; - font-size: 100%; - font-family: sans-serif; - line-height: normal; -} -.chosen-container-multi .chosen-choices li.search-choice { - position: relative; - margin: 3px 5px 3px 0; - padding: 3px 20px 3px 5px; - border: 1px solid @blue; - max-width: 100%; - background-color: @blue; - background-size: 100% 19px; - background-repeat: repeat-x; - background-clip: padding-box; - color: @white; - line-height: 13px; - font-size: 14px; - cursor: default; -} -.chosen-container-multi .chosen-choices li.search-choice span { - word-wrap: break-word; -} -.chosen-container-multi .chosen-choices li.search-choice .search-choice-close { - position: absolute; - top: 4px; - right: 3px; - display: block; - width: 12px; - height: 12px; - background: url('../images/chosen-sprite.png') -42px 1px no-repeat; - font-size: 1px; -} -.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover { - background-position: -42px -10px; -} -.chosen-container-multi .chosen-choices li.search-choice-disabled { - padding-right: 5px; - border: 1px solid #ccc; - background-color: #e4e4e4; - color: #666; -} -.chosen-container-multi .chosen-choices li.search-choice-focus { - background: #d4d4d4; -} -.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close { - background-position: -42px -10px; -} -.chosen-container-multi .chosen-results { - margin: 0; - padding: 0; -} -.chosen-container-multi .chosen-drop .result-selected { - display: list-item; - color: #ccc; - cursor: default; -} - -/* @end */ -/* @group Active */ -.chosen-container-active .chosen-single { - border: 1px solid @inputFocusBorder; - .box-shadow(~"0 0 0 2px" fadeout(@inputFocusBorder, 50%)); -} -.chosen-container-active.chosen-with-drop .chosen-single { - border: 1px solid @inputBorder; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.chosen-container-active.chosen-with-drop .chosen-single div { - border-left: none; - background: transparent; -} -.chosen-container-active.chosen-with-drop .chosen-single div b { - background-position: -18px 2px; -} -.chosen-container-active .chosen-choices { - border: 1px solid @inputFocusBorder; - .box-shadow(~"0 0 0 2px" fadeout(@inputFocusBorder, 50%)); -} -.chosen-container-active .chosen-choices li.search-field input[type="text"] { - color: #222 !important; -} - -/* @end */ -/* @group Disabled Support */ -.chosen-disabled { - opacity: 0.5 !important; - cursor: default; -} -.chosen-disabled .chosen-single { - cursor: default; -} -.chosen-disabled .chosen-choices .search-choice .search-choice-close { - cursor: default; -} - -/* @end */ - - -/* @end */ -/* @group Retina compatibility */ -@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) { - .chosen-rtl .chosen-search input[type="text"], - .chosen-container-single .chosen-single abbr, - .chosen-container-single .chosen-single div b, - .chosen-container-single .chosen-search input[type="text"], - .chosen-container-multi .chosen-choices .search-choice .search-choice-close, - .chosen-container .chosen-results-scroll-down span, - .chosen-container .chosen-results-scroll-up span { - background-size: 52px 37px !important; - background-repeat: no-repeat !important; - } -} -/* @end */ diff --git a/engine/modules/base/admin/blockpro/less/80-main.less b/engine/modules/base/admin/blockpro/less/80-main.less deleted file mode 100644 index a3d12d4..0000000 --- a/engine/modules/base/admin/blockpro/less/80-main.less +++ /dev/null @@ -1,304 +0,0 @@ -/* ========================================================================== - Основное */ -/* ========================================================================== */ - body { - // padding: 0 20px; - } - .container { - padding: 20px 0; - &.container-dark { - background: @gray1Dark; - color: @white; - } - - &.container-blue { - background: @blue; - color: @white; - } - - @media (max-width: @screenTablet) { - padding: 20px 10px; - } - } - header { - .btn { - margin: 0 5px 8px 0; - } - } - - .modal-white { - position: relative; - background: @white; - padding: 20px 10px 10px 10px; - .border-radius(5px); - .box-shadow(~"0 0 10px rgba(0,0,0,.5)"); - } - .modal-header { - margin-top: -10px; - padding: 0 30px 0 10px; - font-size: 16px; - color: @blue; - } - .modal-content { - margin-top: 20px; - } - .popup-modal-dismiss { - position: absolute; - top: 5px; - right: 5px; - width: 26px; - text-align: center; - cursor: pointer; - // height: 20px; - font-size: 32px; - line-height: 32px; - - } - - .chosen-container { - max-width: 360px; - } - - .alert { - border: solid 1px @yellow; - background: fadeout(@yellow, 90%); - color: darken(@yellow, 25%); - padding: 10px; - margin: 10px 0; - p { - &:first-child { - margin-top: 0; - } - &:last-child { - margin-bottom: 0; - } - } - - &-info { - color: darken(@blueDark, 10%); - background: fadeout(@blue, 90%); - border-color: @blue; - } //.alert-info - } - - .widget-item { - padding: 20px 0; - border-top: solid 1px @grayDark; - - h3, - .h3 { - a { - text-decoration: none; - &:hover { - text-decoration: underline; - } - } - } - &:first-child { - border-top: 0; - } - - textarea.code { - margin-bottom: 0; - } - } -/* ========================================================================== - Навигация blockpro */ -/* ========================================================================== */ - - .bp-pager:before, - .bp-pager:after { - content: " "; - display: table; - } - .bp-pager:after { - clear: both; - } - .bp-pager [data-page-num], - .bp-pager .current { - display: inline-block; - color: #ffffff; - margin-bottom: 0; - font-weight: normal; - text-align: center; - vertical-align: middle; - cursor: pointer; - background-image: none; - background: #4a9fc5; - border: 0; - text-decoration: none; - white-space: nowrap; - padding: 10px 15px 8px; - font-size: 18px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-transition: all ease 0.3s; - -moz-transition: all ease 0.3s; - -o-transition: all ease 0.3s; - transition: all ease 0.3s; - -webkit-box-shadow: 0 2px 0 #3584a7; - -moz-box-shadow: 0 2px 0 #3584a7; - box-shadow: 0 2px 0 #3584a7; - padding: 5px 8px 3px; - font-size: 12px; - line-height: 20px; - border-radius: 3px; - margin-bottom: 7px; - } - .bp-pager [data-page-num]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; - } - .bp-pager [data-page-num]:hover, - .bp-pager [data-page-num]:focus { - color: #ffffff; - background: #50bd98; - text-decoration: none; - -webkit-box-shadow: 0 2px 0 #3c9e7d; - -moz-box-shadow: 0 2px 0 #3c9e7d; - box-shadow: 0 2px 0 #3c9e7d; - } - .bp-pager [data-page-num]:active { - outline: 0; - -webkit-box-shadow: 0 2px 0 #50bd98; - -moz-box-shadow: 0 2px 0 #50bd98; - box-shadow: 0 2px 0 #50bd98; - } - - .bp-pager .current { - cursor: default; - background: #c70000; - -webkit-box-shadow: 0 2px 0 #940000; - -moz-box-shadow: 0 2px 0 #940000; - box-shadow: 0 2px 0 #940000; - } - /** - * .base-loader - класс, добавляемый к блоку при аякс-загрузке - */ - .base-loader { - position: relative; - } - .base-loader:after { - position: absolute; - content: ""; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1; - background: rgba(255, 255, 255, 0.9) url(../images/base-loader.gif) 50% 50% no-repeat; - -webkit-transition: all ease 0.3s; - -moz-transition: all ease 0.3s; - -o-transition: all ease 0.3s; - transition: all ease 0.3s; - } - .loading { - min-height: 80px; - } - - /** - * [data-favorite-id] - селектор favorites - */ - - [data-favorite-id] { - cursor: pointer; - } - -/* ========================================================================== - RATING */ -/* ========================================================================== */ - - - .rating { - width: 85px; - height: 17px; - font-size: 0.9em; - } - - .unit-rating { - list-style: none; - margin: 0; - padding: 0; - width: 85px; - height: 17px; - position: relative; - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAzCAMAAABG1xP1AAABDlBMVEUAAAD5+fn09fX8/Pzj5OTIy8vLzs7Hycnj5OT5+fnQ0tL////////v8PDq6+vf4ODV19fFx8jl5ufa29zFyMj8/PzFyMj////8/Pz////FyMfa3Nvl5+bJzMz8/PzFxcW8vb3y8/Po6el81/9f3LGNk5Za163AwcF01P9R16m4ubqAh4va29xF1aSgpKaqra7Q0dLV1td20Pk5mXhhzPxrpL1OlrY1pH/f4OC1tbVp0f/D3NhDkLNZyv060p9apoxPw5x4gIQsk3DN3uZInsVPoshnsJdTxPdMteSjv7Whxtauwcp7sMhpwOdeved/sqGNssOoxbsxvI1DwJaSxbRqwuk2zJlSo4i2zs2wxc4UBcBMAAAAHXRSTlMAS+3YEjZI2wn+7W/edcnqdW/qxqs5qKs2qG/G6pCU6tMAAAF0SURBVHjavdDXcoJAGIZhjb23VJW4kixIVxCwY+9dY+L930h2IRBPkslMMvnO/ndgGB7XTxdM3QYC16mgE3wBwlzA9xH8BMFCjoMsQfjN4A2XRSgBIEGxHPbikqwACApooEdXkrhkeCihm6ZpCfIZXBI1DuAAAMvVErikSVTMUO+RaVzipCgVzCBCMo5LrFiGgEZB6lWKMfPrV0UWSvW6yLHFK68Lzx0K8SLHiXwo5HZZu/c8mvPcfP5p5CEavYsEv4D4W7GFqmnq4kJsO1rJ8mq4dcTOI/kJTW6dbTH1Bd2lUmmt2mKajEOjUW3ZYqigUK22W7YYeguFdnuq2mLNkYzLpDVwxObDdXUyHc4vxAZLTVsO/kcsi8Wy34vNDEUxZhdiG71LUV1944jtdOoZjenvLLEcb3TRTVHM4ZXPWWIKhQLDCIJiieVJVMzQ6ZN5S2zcRUXodPaGLfamm0+c+k1H7KgfhNNeP16INceKMm7+Ruwd+WZIyYlmY7AAAAAASUVORK5CYII=") repeat-x; - } - - .unit-rating li { - text-indent: -90000px; - padding: 0; - margin: 0; - float: left; - } - - .unit-rating li a { - display: block; - width: 17px; - height: 17px; - text-decoration: none; - text-indent: -9000px; - z-index: 17; - position: absolute; - padding: 0; - } - - .unit-rating li a:hover { - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAzCAMAAABG1xP1AAABDlBMVEUAAAD5+fn09fX8/Pzj5OTIy8vLzs7Hycnj5OT5+fnQ0tL////////v8PDq6+vf4ODV19fFx8jl5ufa29zFyMj8/PzFyMj////8/Pz////FyMfa3Nvl5+bJzMz8/PzFxcW8vb3y8/Po6el81/9f3LGNk5Za163AwcF01P9R16m4ubqAh4va29xF1aSgpKaqra7Q0dLV1td20Pk5mXhhzPxrpL1OlrY1pH/f4OC1tbVp0f/D3NhDkLNZyv060p9apoxPw5x4gIQsk3DN3uZInsVPoshnsJdTxPdMteSjv7Whxtauwcp7sMhpwOdeved/sqGNssOoxbsxvI1DwJaSxbRqwuk2zJlSo4i2zs2wxc4UBcBMAAAAHXRSTlMAS+3YEjZI2wn+7W/edcnqdW/qxqs5qKs2qG/G6pCU6tMAAAF0SURBVHjavdDXcoJAGIZhjb23VJW4kixIVxCwY+9dY+L930h2IRBPkslMMvnO/ndgGB7XTxdM3QYC16mgE3wBwlzA9xH8BMFCjoMsQfjN4A2XRSgBIEGxHPbikqwACApooEdXkrhkeCihm6ZpCfIZXBI1DuAAAMvVErikSVTMUO+RaVzipCgVzCBCMo5LrFiGgEZB6lWKMfPrV0UWSvW6yLHFK68Lzx0K8SLHiXwo5HZZu/c8mvPcfP5p5CEavYsEv4D4W7GFqmnq4kJsO1rJ8mq4dcTOI/kJTW6dbTH1Bd2lUmmt2mKajEOjUW3ZYqigUK22W7YYeguFdnuq2mLNkYzLpDVwxObDdXUyHc4vxAZLTVsO/kcsi8Wy34vNDEUxZhdiG71LUV1944jtdOoZjenvLLEcb3TRTVHM4ZXPWWIKhQLDCIJiieVJVMzQ6ZN5S2zcRUXodPaGLfamm0+c+k1H7KgfhNNeP16INceKMm7+Ruwd+WZIyYlmY7AAAAAASUVORK5CYII=") 0 -17px; - z-index: 2; - left: 0; - } - - .unit-rating a.r1-unit { - left: 0; - } - - .unit-rating a.r1-unit:hover { - width:17px; - } - - .unit-rating a.r2-unit { - left: 17px; - } - - .unit-rating a.r2-unit:hover { - width: 34px; - } - - .unit-rating a.r3-unit { - left: 34px; - } - - .unit-rating a.r3-unit:hover { - width: 51px; - } - - .unit-rating a.r4-unit { - left: 51px; - } - - .unit-rating a.r4-unit:hover { - width: 68px; - } - - .unit-rating a.r5-unit { - left: 68px; - } - - .unit-rating a.r5-unit:hover { - width: 85px; - } - - .unit-rating li.current-rating { - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAzCAMAAABG1xP1AAABDlBMVEUAAAD5+fn09fX8/Pzj5OTIy8vLzs7Hycnj5OT5+fnQ0tL////////v8PDq6+vf4ODV19fFx8jl5ufa29zFyMj8/PzFyMj////8/Pz////FyMfa3Nvl5+bJzMz8/PzFxcW8vb3y8/Po6el81/9f3LGNk5Za163AwcF01P9R16m4ubqAh4va29xF1aSgpKaqra7Q0dLV1td20Pk5mXhhzPxrpL1OlrY1pH/f4OC1tbVp0f/D3NhDkLNZyv060p9apoxPw5x4gIQsk3DN3uZInsVPoshnsJdTxPdMteSjv7Whxtauwcp7sMhpwOdeved/sqGNssOoxbsxvI1DwJaSxbRqwuk2zJlSo4i2zs2wxc4UBcBMAAAAHXRSTlMAS+3YEjZI2wn+7W/edcnqdW/qxqs5qKs2qG/G6pCU6tMAAAF0SURBVHjavdDXcoJAGIZhjb23VJW4kixIVxCwY+9dY+L930h2IRBPkslMMvnO/ndgGB7XTxdM3QYC16mgE3wBwlzA9xH8BMFCjoMsQfjN4A2XRSgBIEGxHPbikqwACApooEdXkrhkeCihm6ZpCfIZXBI1DuAAAMvVErikSVTMUO+RaVzipCgVzCBCMo5LrFiGgEZB6lWKMfPrV0UWSvW6yLHFK68Lzx0K8SLHiXwo5HZZu/c8mvPcfP5p5CEavYsEv4D4W7GFqmnq4kJsO1rJ8mq4dcTOI/kJTW6dbTH1Bd2lUmmt2mKajEOjUW3ZYqigUK22W7YYeguFdnuq2mLNkYzLpDVwxObDdXUyHc4vxAZLTVsO/kcsi8Wy34vNDEUxZhdiG71LUV1944jtdOoZjenvLLEcb3TRTVHM4ZXPWWIKhQLDCIJiieVJVMzQ6ZN5S2zcRUXodPaGLfamm0+c+k1H7KgfhNNeP16INceKMm7+Ruwd+WZIyYlmY7AAAAAASUVORK5CYII=") 0 -34px; - position: absolute; - height: 17px; - display: block; - text-indent: -9000px; - z-index: 1; - } - - diff --git a/engine/modules/base/admin/blockpro/less/90-helpers.less b/engine/modules/base/admin/blockpro/less/90-helpers.less deleted file mode 100644 index 97ef035..0000000 --- a/engine/modules/base/admin/blockpro/less/90-helpers.less +++ /dev/null @@ -1,204 +0,0 @@ -/* ========================================================================== - Helper classes */ -/* ========================================================================== */ - ol.unstyled, - ul.unstyled { - margin: 0; - padding: 0; - list-style: none; - } - .ta-center, - .table th.ta-center, - .table td.ta-center {text-align: center;} - - - .ta-left, - .table th.ta-left, - .table td.ta-left { - text-align: left; - } - .ta-right, - .table th.ta-right, - .table td.ta-right { - text-align: right; - } - - .td-n {text-decoration: none;} - .td-u {text-decoration: underline;} - .tt-u {text-transform: uppercase;} - - .hide {display: none;} - - .show, - .d-b {display: block;} - - .inline-block, - .d-ib {display: inline-block;} - - .inline, - .d-i {display: inline;} - - - .invisible {visibility: hidden;} - - .verdana {font-family: Verdana, sans-serif;} - .tahoma {font-family: Tahoma, sans-serif;} - .arial {font-family: Arial, sans-serif;} - - .p-r, - .pos-r {position: relative;} - .p-a, - .pos-a {position: absolute;} - .p-f, - .pos-f {position: fixed;} - - .ir { - background-color: transparent; - border: 0; - overflow: hidden; - *text-indent: -9999px; - - &:before { - content: ""; - display: block; - width: 0; - height: 100%; - } - } - - - .hidden { - display: none !important; - visibility: hidden; - } - - .visuallyhidden { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; - } - - .visuallyhidden.focusable:active, - .visuallyhidden.focusable:focus { - clip: auto; - height: auto; - margin: 0; - overflow: visible; - position: static; - width: auto; - } - - .invisible, - .viz-h {visibility: hidden;} - - - .p0 {padding: 0;} - .p10 {padding: 10px;} - .p20 {padding: 20px;} - .p30 {padding: 30px;} - .p40 {padding: 40px;} - - .pt0 {padding-top: 0;} - .pt10 {padding-top: 10px;} - .pt20 {padding-top: 20px;} - .pt30 {padding-top: 30px;} - .pt40 {padding-top: 40px;} - - .pr0 {padding-right: 0;} - .pr10 {padding-right: 10px;} - .pr20 {padding-right: 20px;} - .pr30 {padding-right: 30px;} - .pr40 {padding-right: 40px;} - - .pb0 {padding-bottom: 0;} - .pb10 {padding-bottom: 10px;} - .pb20 {padding-bottom: 20px;} - .pb30 {padding-bottom: 30px;} - .pb40 {padding-bottom: 40px;} - - .pl0 {padding-left: 0;} - .pl10 {padding-left: 10px;} - .pl20 {padding-left: 20px;} - .pl30 {padding-left: 30px;} - .pl40 {padding-left: 40px;} - - - .m0 {margin: 0;} - .m10 {margin: 10px;} - .m20 {margin: 20px;} - .m30 {margin: 30px;} - .m40 {margin: 40px;} - - .mt0 {margin-top: 0;} - .mt10 {margin-top: 10px;} - .mt20 {margin-top: 20px;} - .mt30 {margin-top: 30px;} - .mt40 {margin-top: 40px;} - - .mr0 {margin-right: 0;} - .mr10 {margin-right: 10px;} - .mr20 {margin-right: 20px;} - .mr30 {margin-right: 30px;} - .mr40 {margin-right: 40px;} - - .mb0 {margin-bottom: 0;} - .mb10 {margin-bottom: 10px;} - .mb20 {margin-bottom: 20px;} - .mb30 {margin-bottom: 30px;} - .mb40 {margin-bottom: 40px;} - - .ml0 {margin-left: 0;} - .ml10 {margin-left: 10px;} - .ml20 {margin-left: 20px;} - .ml30 {margin-left: 30px;} - .ml40 {margin-left: 40px;} - - - .text-muted {color: lighten(@textColor, 30%);} - .text-red {color: @red;} - .text-orange {color: @orange;} - .text-yellow {color: @yellow;} - .text-green {color: @green;} - .text-blue {color: @blue;} - - .fz12 {font-size: 12px;} - .fz14 {font-size: 14px;} - .fz16 {font-size: 16px;} - .fz18 {font-size: 18px;} - .fz20 {font-size: 20px;} - .fz22 {font-size: 22px;} - .fz24 {font-size: 24px;} - .fz26 {font-size: 26px;} - .fz30 {font-size: 30px;} - - .lh14 {line-height: 1.4;} - - .clearfix { - &:before, - &:after { - content: " "; - display: table; - } - - &:after { - clear: both; - } - } - - .clr {clear: both; height: 0; overflow: hidden;} - .fleft {float: left;} - .fright {float: right;} - - img[align="right"] {padding: 0 0 20px 20px;} - img[align="left"] {padding: 0 20px 20px 0;} - - img.ta-center, - img[align="center"] { - display: block; - margin: 0 auto; - } diff --git a/engine/modules/base/admin/blockpro/less/datepicker/dp_base.date.less b/engine/modules/base/admin/blockpro/less/datepicker/dp_base.date.less deleted file mode 100644 index 042a5d2..0000000 --- a/engine/modules/base/admin/blockpro/less/datepicker/dp_base.date.less +++ /dev/null @@ -1,296 +0,0 @@ - -/* ========================================================================== - $BASE-DATE-PICKER - ========================================================================== */ - -@import "dp_variables.less"; - - -/** - * The picker box. - */ -.picker__box { - padding: 0 1em; -} - - -/** - * The header containing the month and year stuff. - */ -.picker__header { - text-align: center; - position: relative; - margin-top: .75em; -} - - -/** - * The month and year labels. - */ -.picker__month, -.picker__year { - font-weight: 500; - display: inline-block; - margin-left: .25em; - margin-right: .25em; -} -.picker__year { - color: @year-weekday-label; - font-size: .8em; - font-style: italic; -} - - -/** - * The month and year selectors. - */ -.picker__select--month, -.picker__select--year { - font-size: .8em; - border: 1px solid @border-select; - height: 2.5em; - padding: .5em .25em; // For firefox - margin-left: .25em; - margin-right: .25em; - - // Select menus are big.. move ‘em up a bit. - margin-top: -.5em; -} -.picker__select--month { - width: 35%; -} -.picker__select--year { - width: 22.5%; -} -.picker__select--month:focus, -.picker__select--year:focus { - border-color: @dp_blue; -} - - -/** - * The month navigation buttons. - */ -.picker__nav--prev, -.picker__nav--next { - position: absolute; - top: -.33em; - padding: .5em 1.33em; - width: 1em; - height: 1em; -} -.picker__nav--prev { - left: -1em; - padding-right: 1.5em; -} -.picker__nav--next { - right: -1em; - padding-left: 1.5em; -} -.picker__nav--prev:before, -.picker__nav--next:before { - content: " "; - border-top: .5em solid transparent; - border-bottom: .5em solid transparent; - border-right: .75em solid @dp_black; - width: 0; - height: 0; - display: block; - margin: 0 auto; -} -.picker__nav--next:before { - border-right: 0; - border-left: .75em solid @dp_black; -} - -// Hovered date picker items. -.picker__nav--prev:hover, -.picker__nav--next:hover { - .picker-item-hovered; -} - -// Disabled month nav. -.picker__nav--disabled, -.picker__nav--disabled:hover, -.picker__nav--disabled:before, -.picker__nav--disabled:before:hover { - cursor: default; - background: none; - border-right-color: @disabled-things-bg; - border-left-color: @disabled-things-bg; -} - - - - -/** - * The calendar table of dates - */ -.picker__table { - text-align: center; - border-collapse: collapse; - border-spacing: 0; - table-layout: fixed; - font-size: inherit; - width: 100%; - margin-top: .75em; - margin-bottom: .5em; - - // For `small` screens, increase the spacing a tad. - @media ( min-height: @breakpoint-small ) { - margin-bottom: .75em; - } -} - -// Remove browser stylings on a table cell. -.picker__table td { - margin: 0; - padding: 0; -} - - -/** - * The weekday labels - */ -.picker__weekday { - width: 14.285714286%; // 100/7 - font-size: .75em; - padding-bottom: .25em; - color: @year-weekday-label; - font-weight: 500; - - /* Increase the spacing a tad */ - @media ( min-height: @breakpoint-small ) { - padding-bottom: .5em; - } -} - - -/** - * The days on the calendar - */ -.picker__day { - padding: .3125em 0; - font-weight: 200; - border: 1px solid transparent; -} - -// Today. -.picker__day--today { - color: @dp_blue; - position: relative; -} -.picker__day--today:before { - content: " "; - position: absolute; - top: 2px; - right: 2px; - width: 0; - height: 0; - border-top: .5em solid @dp_blue-tag; - border-left: .5em solid transparent; -} - -// Selected day. -.picker__day--selected, -.picker__day--selected:hover { - .picker-item-selected; -} - -// Highlighted day. -.picker__day--highlighted { - background: @dp_blue-hover; -} - -// Disabled day. -.picker__day--disabled:before { - border-top-color: @disabled-tag; -} - -// Out of focus days. -.picker__day--outfocus { - color: @disabled-things-text; -} - -// Hovered date picker items. -.picker__day--infocus:hover, -.picker__day--outfocus:hover { - .picker-item-hovered; -} - -// Highlighted and hovered/focused dates. -.picker__day--highlighted:hover, -.picker--focused .picker__day--highlighted { - .picker-item-highlighted; -} - -// Disabled dates. -.picker__day--disabled, -.picker__day--disabled:hover { - .picker-item-disabled; -} - -// Disabled and highlighted dates. -.picker__day--highlighted.picker__day--disabled, -.picker__day--highlighted.picker__day--disabled:hover { - background: @disabled-highlighted-things-bg; -} - - -/** - * The footer containing the "today" and "clear" buttons. - */ -.picker__footer { - text-align: center; -} - -// Today and clear buttons. -.picker__button--today, -.picker__button--clear { - border: 1px solid @dp_white; - background: @dp_white; - font-size: .8em; - padding: .66em 0; - font-weight: bold; - width: 50%; - display: inline-block; - vertical-align: bottom; -} -.picker__button--today:hover, -.picker__button--clear:hover { - .picker-item-hovered; - border-bottom-color: @dp_blue-hover; -} -.picker__button--today:focus, -.picker__button--clear:focus { - background: @dp_blue-hover; - border-color: @dp_blue; - outline: none; -} - -// Today and clear “indicators”. -.picker__button--today:before, -.picker__button--clear:before { - position: relative; - display: inline-block; - height: 0; -} -.picker__button--today:before { - content: " "; - margin-right: .45em; - top: -.05em; - width: 0; - border-top: .66em solid @dp_blue-tag; - border-left: .66em solid transparent; -} -.picker__button--clear:before { - content: "\D7"; // × - margin-right: .35em; - top: -.1em; - color: @clear-red; - vertical-align: top; - font-size: 1.1em; -} - - - diff --git a/engine/modules/base/admin/blockpro/less/datepicker/dp_base.less b/engine/modules/base/admin/blockpro/less/datepicker/dp_base.less deleted file mode 100644 index 1d79e79..0000000 --- a/engine/modules/base/admin/blockpro/less/datepicker/dp_base.less +++ /dev/null @@ -1,53 +0,0 @@ - -/* ========================================================================== - $BASE-PICKER - ========================================================================== */ - - -/** - * Note: the root picker element should *NOT* be styled more than what’s here. - */ -.picker { - - // The base font stylings. - font-size: @base-font-size; - text-align: left; - line-height: @base-line-height; - color: @dp_black; - - // The picker shouldn’t affect or be affected by elements around it. - position: absolute; - z-index: @picker-z-index; - - // The picker shouldn’t be selectable. - .user-select( none ); -} - - -/** - * The picker input element. - */ -.picker__input { - cursor: default; -} - - -/** - * When the picker is opened, the input element is “activated”. - */ -.picker__input.picker__input--active { - border-color: @input-active-border; -} - - -/** - * The holder is the only “scrollable” top-level container element. - */ -.picker__holder { - width: 100%; - overflow-y: auto; - -webkit-overflow-scrolling: touch; -} - - - diff --git a/engine/modules/base/admin/blockpro/less/datepicker/dp_default.date.less b/engine/modules/base/admin/blockpro/less/datepicker/dp_default.date.less deleted file mode 100644 index c438b9b..0000000 --- a/engine/modules/base/admin/blockpro/less/datepicker/dp_default.date.less +++ /dev/null @@ -1,9 +0,0 @@ - -/* ========================================================================== - $DEFAULT-DATE-PICKER - ========================================================================== */ - -@import "dp_variables.less"; - - - diff --git a/engine/modules/base/admin/blockpro/less/datepicker/dp_default.less b/engine/modules/base/admin/blockpro/less/datepicker/dp_default.less deleted file mode 100644 index 4b730f9..0000000 --- a/engine/modules/base/admin/blockpro/less/datepicker/dp_default.less +++ /dev/null @@ -1,243 +0,0 @@ -/*! - * Default mobile-first, responsive styling for pickadate.js - * Demo: http://amsul.github.io/pickadate.js - */ - -@import "dp_variables.less"; - - -/** - * Note: the root picker element should *NOT* be styled more than what’s here. - */ -.picker {} - - -/** - * Make the holder and frame fullscreen. - */ -.picker__holder, -.picker__frame { - bottom: 0; - left: 0; - right: 0; - - // Nudge everything off-screen to begin with. - top: 100%; -} - - -/** - * The holder should overlay the entire screen. - */ -.picker__holder { - - // Fill the screen and fix the position. - position: fixed; - - // Fade out the background, then immediately shift the holder out of view. - @transition: background @speed-animate-in ease-out, top 0s @speed-animate-in; - .transition( @transition ); -} - - - -/** - * The frame that bounds the box contents of the picker. - */ -.picker__frame { - - position: absolute; - - // Specify the min & max widths and center align it. - margin: 0 auto; - min-width: @picker-min-width; - max-width: @picker-max-width; - width: 100%; // For IE9 & 10 to keep it centered. - - // Hide it to begin with. - .opacity( 0 ); - - // Animate the frame in and out of view. - .transition( all @speed-animate-in ease-out ); - - // For `small` screens... - @media ( min-height: @breakpoint-small ) { - - // Reveal what’s beyond to allow drop shadows, et al. - overflow: visible; - - // Align to the bottom edge instead of top. - top: auto; - bottom: -100%; - - // Prevent it from overflowing over the top edge. - max-height: 80%; - } - - // For `medium` screens... - @media ( min-height: @breakpoint-medium ) { - - // Move away from the bottom edge. - margin-bottom: 7.5%; - } -} - -/** - * The wrapper sets the stage to vertically align the box contents. - */ -.picker__wrap { - display: table; - width: 100%; - height: 100%; - - // For `small` screens, remove the “middle-aligned” styling - @media ( min-height: @breakpoint-small ) { - display: block; - } -} - - - -/** - * The box contains all the picker contents. - */ -.picker__box { - background: @bg-white; - - // To start with, vertically align to center - display: table-cell; - vertical-align: middle; - - // For `tiny` screens, increase the font size a bit - @media ( min-height: @breakpoint-tiny ) { - font-size: 1.25em; - } - - // For `small` screens... - @media ( min-height: @breakpoint-small ) { - - // Remove the “middle-aligned” styling - display: block; - - // Increase the font size a bit more - font-size: 1.33em; - - // Add the borders except the bottom one - border: 1px solid @border-grey; - border-top-color: lighten( @border-grey, 7% ); - border-bottom-width: 0; - - // Make ‘em rounded at the top corners - .border-radius( @picker-border-radius @picker-border-radius 0 0 ); - - // And finally, add a nice shadow - .box-shadow( @picker-box-shadow ); - } - - // For `medium` screens... - @media ( min-height: @breakpoint-medium ) { - - // Increase the font size. - font-size: 1.5em; - - // Reveal all borders and round all corners. - border-bottom-width: 1px; - .border-radius( @picker-border-radius ); - } -} - - -/** - * When the picker opens... - */ -.picker--opened { - - // Immediately move the holder to the top edge then fade in an overlay - .picker__holder { - - // Move it to the top edge - top: 0; - - // Show a translucent black background (order is important for IE) - background: transparent; - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)"; // IE8 - zoom: 1; - background: rgba(0,0,0,.32); // Normal browsers - - // Animate in the background - @transition: background @speed-animate-in ease-out; - .transition( @transition ); - } - - - // Smoothly move the content to the top edge while fading it in - .picker__frame { - - // Move to the top edge - top: 0; - - // Ånd then reveal the content - .opacity( 1 ); - - // For `small` screens, move to the bottom edge instead - @media ( min-height: @breakpoint-small ) { - top: auto; - bottom: 0; - } - } -} - - - - - - -/** - * For `large` screens, transform into an inline picker. - */ -// @include min-screen( large ) { - -// .picker { -// width: 100%; -// } - -// .picker__holder, -// .picker--opened .picker__holder { -// background: @dp_white; -// @include prefix( transition, all @speed-animate-in ease-out ); -// } - -// .picker__holder { -// font-size: 12px; -// position: relative; -// max-height: 0; -// border: 1px solid transparent; -// @include prefix( border-radius, @picker-border-radius ); -// @include prefix( box-sizing, border-box ); -// } -// .picker--opened .picker__holder { -// @include picker-holder-open; -// @include prefix( box-shadow, @picker-box-shadow-light ); -// } - -// .picker__frame, -// .picker--opened .picker__frame { -// max-width: none !important; -// } - -// .picker__frame { -// position: initial; -// margin: 0; -// @include opacity( 1 ); -// } - -// .picker__box { -// border: 0; -// margin-top: 0; -// @include prefix( border-radius, 0 ); -// @include prefix( box-shadow, none ); -// } -// } - - - diff --git a/engine/modules/base/admin/blockpro/less/datepicker/dp_main.less b/engine/modules/base/admin/blockpro/less/datepicker/dp_main.less deleted file mode 100644 index b8f5912..0000000 --- a/engine/modules/base/admin/blockpro/less/datepicker/dp_main.less +++ /dev/null @@ -1,5 +0,0 @@ -@import "dp_variables.less"; -@import "dp_base.less"; -@import "dp_base.date.less"; -@import "dp_default.less"; -@import "dp_default.date.less"; \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/datepicker/dp_variables.less b/engine/modules/base/admin/blockpro/less/datepicker/dp_variables.less deleted file mode 100644 index be0a06f..0000000 --- a/engine/modules/base/admin/blockpro/less/datepicker/dp_variables.less +++ /dev/null @@ -1,205 +0,0 @@ - -// ========================================================================== -// $VARIABLES -// ========================================================================== - - -// -// Base colors -// -@dp_blue: @green1; -@dp_blue-hover: @cream; -@dp_black: #000; -@dp_white: #fff; - - -// -// Backgrounds -// -@bg-white: @dp_white; -@bg-grey-light: #f2f2f2; - - -// -// Borders -// -@border-grey: #777; -@border-grey-light: #ddd; -@border-select: darken( @border-grey-light, 15% ); - - -// -// Buttons -// -@clear-red: #e20; - - - - - -// -// Picker base -// - -// Make sure nothing is above the picker. -@picker-z-index: 10000; - -// Animation speeds. -@speed-animate-in: .15s; - -// Focused input border color. -@input-active-border: @dp_blue; - -// Typography. -@base-font-size: 16px; -@base-line-height: 1.2; - -// Corners. -@picker-border-radius: 5px; - -// Drop shadows. -@picker-box-shadow: 0 12px 36px 16px rgba(0,0,0,.24); -@picker-box-shadow-light: 0 6px 18px 1px rgba(0,0,0,.12); - -// Breakpoints. -@breakpoint-tiny: 26.5em; // 424px @ 16px -@breakpoint-small: 33.875em; // 542px @ 16px -@breakpoint-medium: 40.125em; // 642px @ 16px -@breakpoint-large: 46.75em; // 748px @ 16px - - - - -// -// Date picker options -// - -// The year and weekday labels. -@year-weekday-label: #999; - -// “Today” tag indicators. -@dp_blue-tag: darken(@green1, 5%); -@disabled-tag: #aaa; - -// Disabled things.. such as days, month nav, etc. -@disabled-things-bg: #f5f5f5; -@disabled-things-text: #ddd; -@disabled-highlighted-things-bg: #bbb; - - - - - -// -// Theme configurations -// - -// The “default” min & max widths. -@picker-min-width: 256px; -@picker-max-width: 666px; - -// The time picker min & max widths. -@time-min-width: @picker-min-width; -@time-max-width: 320px; - -// The “classic” theme settings. -@classic-max-width: @picker-max-width - 200px; -@classic-min-width: @picker-min-width - 80px; -@classic-max-height: 25em; -@classic-box-shadow: 0 6px 18px 1px rgba(0,0,0,.12); - - - - - - - - -// ========================================================================== -// $MIXINS -// ========================================================================== - - -// -// Common picker item states -// - -// Highlighted. -.picker-item-highlighted () { - background: @dp_blue; - color: @dp_white; -} - -// Hovered. -.picker-item-hovered () { - cursor: pointer; - color: @dp_black; - background: @dp_blue-hover; -} - -// Selected. -.picker-item-selected () { - border-color: @dp_blue; -} - -// Disabled. -.picker-item-disabled () { - background: @disabled-things-bg; - border-color: @disabled-things-bg; - color: @disabled-things-text; - cursor: default; -} - - - - -// -// Opacity -// -.opacity( @decimal ) { - @percent: @decimal * 100; - -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=@{percent})"; - filter: ~"alpha(opacity=@{percent})"; - -moz-opacity: @decimal; - opacity: @decimal; -} - - - -// -// Vendor prefixes -// -// .box-shadow ( @rest... ) { -// -webkit-box-shadow: @rest; -// -moz-box-shadow: @rest; -// box-shadow: @rest; -// } -// .box-sizing ( @rest... ) { -// -webkit-box-sizing: @rest; -// -moz-box-sizing: @rest; -// box-sizing: @rest; -// } -// .border-radius ( @rest... ) { -// -webkit-border-radius: @rest; -// -moz-border-radius: @rest; -// border-radius: @rest; -// } -// .transition ( ... ) { -// -webkit-transition: @arguments; -// -moz-transition: @arguments; -// transition: @arguments; -// } -.transform ( @rest... ) { - -webkit-transform: @rest; - -moz-transform: @rest; - transform: @rest; -} -// .user-select ( @rest... ) { -// -webkit-user-select: @rest; -// -moz-user-select: @rest; -// -ms-user-select: @rest; -// user-select: @rest; -// } - - - diff --git a/engine/modules/base/admin/blockpro/less/formstyler/checkbox.less b/engine/modules/base/admin/blockpro/less/formstyler/checkbox.less deleted file mode 100644 index ce2061c..0000000 --- a/engine/modules/base/admin/blockpro/less/formstyler/checkbox.less +++ /dev/null @@ -1,49 +0,0 @@ -/* ========================================================================== - Чекбоксы */ -/* ========================================================================== */ - - - .jq-checkbox { - .square(@checkboxSize); - border-radius: @radius; - background: transparent; - border: solid 2px @bgColor; - vertical-align: middle; - cursor: pointer; - - &:hover, - label:hover & { - border-color: @bgColorHover; - &.checked .jq-checkbox__div:before { - border-color: @bgColorHover; - } - } - - &.checked { - .jq-checkbox__div { - &:before { - content: ' '; - position: absolute; - border: solid @dotColor; - border-width: 0 0 3px 3px; - height: 3px; - width: 7px; - left: (@checkboxSize / 2) - (@dotSize / 2) - 1; - top: (@checkboxSize / 2) - (@dotSize / 2); - transform: rotate(-45deg); - } - } - - - } - - &.focused { - box-shadow: 0 0 0 2px fadeout(@focusColor, 30%); - } - - &.disabled { - opacity: 0.55; - filter: alpha(opacity=55); - } - - } //.jq-checkbox diff --git a/engine/modules/base/admin/blockpro/less/formstyler/file.less b/engine/modules/base/admin/blockpro/less/formstyler/file.less deleted file mode 100644 index 7f004d0..0000000 --- a/engine/modules/base/admin/blockpro/less/formstyler/file.less +++ /dev/null @@ -1,80 +0,0 @@ -/* ========================================================================== - Файловые инпуты */ -/* ========================================================================== */ - - .jq-file { - width: @fileWidth; - border-radius: @radius; - - input { - cursor: pointer; - height: auto; - line-height: 1em; - } - - &:hover .jq-file__browse, - &:active .jq-file__browse { - background: @bgColorHover; - border-color: @bgColorHover; - } - &:hover .jq-file__name, - &:active .jq-file__name { - border-color: @bgColorHover; - } - - &.disabled { - color: @disabledColor; - border-color: @disabledColor; - - .jq-file__name { - color: @disabledColor; - border-color: @disabledColor; - } - - &:hover .jq-file__browse, - &:active .jq-file__browse { - background: @disabledColor; - border-color: @disabledColor; - } - - .jq-file__browse { - border-color: @disabledColor; - background: @disabledColor; - color: @lightColor; - } - } - - } - - .jq-file__name { - box-sizing: border-box; - width: 100%; - height: @inputHeight; - padding: 0 80px 0 10px; - color: @bgColor; - font: @fz~"/"(@inputHeight - 4) @ff; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - border: solid 2px @bgColor; - border-radius: @radius; - - - .focused & { - border-color: @bgColorHover; - } - - } - - .jq-file__browse { - position: absolute; - top: 0; - right: 0; - color: @lightColor; - font: @fz~"/"(@inputHeight) @ff; - padding: 0 10px; - border-left: solid 2px @bgColor; - border-radius: 0 @radius @radius 0; - background: @bgColor; - - } diff --git a/engine/modules/base/admin/blockpro/less/formstyler/formstyler.less b/engine/modules/base/admin/blockpro/less/formstyler/formstyler.less deleted file mode 100644 index 1821235..0000000 --- a/engine/modules/base/admin/blockpro/less/formstyler/formstyler.less +++ /dev/null @@ -1,17 +0,0 @@ -// Подключаем переменые для конкретной темы оформления -@import "variables"; - -// Чекбоксы -// @import "checkbox"; - -// Радиокнопки -// @import "radio"; - -// Файловые инпуты -// @import "file"; - -// Селекты -@import "select"; - -// Прочие интпуты -// @import "inputs"; diff --git a/engine/modules/base/admin/blockpro/less/formstyler/inputs.less b/engine/modules/base/admin/blockpro/less/formstyler/inputs.less deleted file mode 100644 index bc24fc0..0000000 --- a/engine/modules/base/admin/blockpro/less/formstyler/inputs.less +++ /dev/null @@ -1,63 +0,0 @@ - - -.styler { - padding: 7px 9px; - border: solid 2px @bgColor; - border-radius: @radius; - color: @textColor; - font: @fz~"/"@lh @ff; - box-sizing: border-box; - transition: all ease .3s; - - &:hover, - &:focus { - border-color: @bgColorHover; - outline: none; - } -} -input[type="search"].styler { - -webkit-appearance: none; -} -textarea.styler { - overflow: auto; -} - -button.styler, -input[type="button"].styler, -input[type="submit"].styler, -input[type="reset"].styler { - overflow: visible; - padding: 5px 11px; - outline: none; - border: 2px solid @bgColor; - border-radius: @radius; - background: @bgColor; - color: @lightColor; - cursor: pointer; - box-shadow: none; - text-shadow: none; - - &::-moz-focus-inner { - padding: 0; - border: 0; - } - - &:hover, - &:focus { - background: @bgColorHover; - color: @lightColorHover; - border-color: @bgColorHover; - } - &:active { - background: @bgColor; - color: @lightColor; - border-color: @bgColor; - } - -} - -button.styler:after { - content: ''; -} - - diff --git a/engine/modules/base/admin/blockpro/less/formstyler/radio.less b/engine/modules/base/admin/blockpro/less/formstyler/radio.less deleted file mode 100644 index 2d01dd2..0000000 --- a/engine/modules/base/admin/blockpro/less/formstyler/radio.less +++ /dev/null @@ -1,40 +0,0 @@ - -/* ========================================================================== - Радиокнопки */ -/* ========================================================================== */ - - - .jq-radio { - .square; - cursor: pointer; - border: solid 2px @bgColor; - background: transparent; - vertical-align: middle; - border-radius: 50%; - - &:hover, - label:hover & { - border-color: @bgColorHover; - &.checked .jq-radio__div { - background: @bgColorHover; - } - } - - &.checked { - .jq-radio__div { - .square(@dotSize); - margin: (@radioSize / 2) - (@dotSize / 2) ~"0 0" (@radioSize / 2) - (@dotSize / 2); - border-radius: 50%; - background: @dotColor; - } - } - - &.focused { - box-shadow: 0 0 0 2px fadeout(@focusColor, 30%); - } - - &.disabled { - opacity: 0.55; - filter: alpha(opacity=55); - } - } //.jq-radio \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/formstyler/select.less b/engine/modules/base/admin/blockpro/less/formstyler/select.less deleted file mode 100644 index 0b4ae56..0000000 --- a/engine/modules/base/admin/blockpro/less/formstyler/select.less +++ /dev/null @@ -1,231 +0,0 @@ -/* ========================================================================== - Селекты */ -/* ========================================================================== */ - - .jq-selectbox { - vertical-align: middle; - cursor: pointer; - border: solid 1px @inputBorder; - - &.dropdown { - border-color: @inputFocusBorder; - } - - &.disabled .jq-selectbox__select { - background: @disabledColor; - color: @lightColor; - } - - &:hover .jq-selectbox__trigger-arrow { - opacity: 1; - filter: alpha(opacity=100); - } - &.disabled .jq-selectbox__trigger-arrow { - opacity: 0.3; - filter: alpha(opacity=30); - } - - & ul { - margin: 0; - padding: 0; - } - & li { - min-height: @lh; - padding: 5px 10px 6px; - color: @lightColor; - border-radius: @radius; - - &.sel { - background-color: @selectedColor; - color: @lightColor; - } - &:hover { - background-color: @darkColorHover; - color: @lightColorHover; - } - &.disabled { - color: @disabledColor; - &:hover { - background: none; - } - } - &.optgroup { - font-weight: bold; - - &:hover { - background: none; - color: @lightColor; - cursor: default; - } - } - &.option { - padding-left: 25px; - } - } - - } //.jq-selectbox - - .jq-selectbox__select { - height: @inputHeight + 2; - padding: 0 45px 0 10px; - border-radius: @radius; - background: @bgColor; - color: @lightColor; - font: @fz~"/"(@inputHeight + 2) @ff; - - &:hover, - &:active { - background-color: @bgColorHover; - } - - } - - .jq-selectbox__select-text { - display: block; - width: 100%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .jq-selectbox__trigger { - position: absolute; - top: 0; - right: 0; - width: 34px; - height: 100%; - // border-left: solid 1px fade(@lightColor, 50%); - } - .jq-selectbox__trigger-arrow { - position: absolute; - top: 14px; - right: 12px; - width: 0; - height: 0; - overflow: hidden; - border-top: 5px solid @lightColor; - border-right: 5px solid transparent; - border-left: 5px solid transparent; - } - - .jq-selectbox__dropdown { - top: @inputHeight + 2; - width: 100%; - margin: 0; - padding: 0; - font: @fz~"/"@lh @ff; - background: @white; - .box-shadow(~"0 0 0 1px " @darkColorHover); - border-radius: @radius + (@radius / 2); - .box-sizing; - - // &:before { - // content: ' '; - // position: absolute; - // top: -11px; - // left: 6px; - // width: 0; - // height: 0; - // overflow: hidden; - // border-bottom: 10px solid @darkColor; - // border-right: 10px solid transparent; - // border-left: 10px solid transparent; - // } - - } - .jq-selectbox__search { - margin: 5px; - border: solid 1px @grayDark; - - & input { - -moz-box-sizing: border-box; - box-sizing: border-box; - width: 100%; - margin: 0; - padding: 5px 27px 6px 18px; - outline: none; - border: solid 2px @bgColor; - border-radius: @radius; - background: #fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAO1JREFUeNqU078LAXEYx/FzYfNzk5TJaFNKYjFYSQZ/hvwBsvg1UCY2xT9gM8hukQGThWRjkcFw3pdnujhfT736Xn2fPvfc3fd07V0OFDDFAnM0ENYsZRiGLSc9OpqIYIA9fMhhjCrW2h9VlMlcH/aymMGtOqEugX08PwQucUZKdTozMIqdTc9WepQD7wjY9ARx+ydwhfyXfS+S0qMcOEQJGcueB3VccFINdMgal6NzkmPjRwJXxDBB7/2RDdtAp6wb+dpphHDASG5QQ0V6u2aoSqBZD/lDrNWRJynLK2qpBn4rc6K2XB9/Nb8EGABtf1thzY6X2AAAAABJRU5ErkJggg==) no-repeat 100% 50%; - color: @textColor; - -webkit-appearance: textfield; - - &::-webkit-search-cancel-button, - &::-webkit-search-decoration { - -webkit-appearance: none; - } - } - } - .jq-selectbox__not-found { - margin: 5px; - padding: 5px 8px 6px; - color: @lightColor; - font-size: @fz - 2; - } - - - - .jq-select-multiple { - // padding: 1px; - border: solid 2px @bgColor; - border-radius: @radius; - background: @lightColor; - color: @textColor; - font: @fz~"/"@lh @ff; - cursor: default; - box-sizing: border-box; - transition: all ease .3s; - - &.focused { - border-color: @focusColor; - } - &.disabled { - border-color: @disabledColor; - background: @disabledColor; - box-shadow: none; - color: textColor; - } - - &.disabled li.selected, - li.selected.disabled, - li.disabled, - li.disabled:hover { - background: @disabledColor; - color: @textColor; - } - - & ul { - margin: 0; - padding: 0; - } - & li { - padding: 3px 9px 4px; - list-style: none; - transition: all ease .3s; - - &:first-child { - border-radius: (@radius - 2) (@radius - 2) 0 0; - } - &:last-child { - border-radius: 0 0 (@radius - 2) (@radius - 2); - } - &.selected, - &:hover { - background: @bgColor; - color: @lightColor; - } - &.disabled { - color: @textColor; - } - &.optgroup { - font-weight: bold; - &:hover { - background: @lightColor; - color: @textColor; - } - } - &.option { - padding-left: 25px; - } - } - - } //.jq-select-multiple \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/formstyler/variables.less b/engine/modules/base/admin/blockpro/less/formstyler/variables.less deleted file mode 100644 index 5429936..0000000 --- a/engine/modules/base/admin/blockpro/less/formstyler/variables.less +++ /dev/null @@ -1,55 +0,0 @@ -// Общие переменные -// @textColor: darken(@gray1Dark, 40%);; // textColor -@textColorHover: @blue; // textColorHover - -@bgColor: @white; // bgColor -@bgColorHover: @white; // bgColorHover - -@disabledColor: @gray1; // disabledColor - -@lightColor: @textColor; // lightColor -@lightColorHover: @white; // lightColorHover - -@darkColor: @gray; // darkColor -@darkColorHover: @blue; // darkColorHover - - -@focusColor: @blue; // focusColor - - -@ff: @Arial; // ff -@fz: 16px; // fz -@lh: 20px ; // lh - -@radius: 0; // radius - -@inputHeight: 28px; // inputHeight - - -@dotSize: @fz / 2; // dotSize -@dotColor: @bgColor; // dotColor - -// Чекбоксы -@checkboxSize: @fz; // checkboxSize - -// Радиокнопки -@radioSize: @fz; // radioSize - -// Файловые инпуты -@fileWidth: 270px; // fileWidth - -// Селекты -@selectedColor: fadeout(@blue, 60%); // selectedColor - - - - -// -------------------------- -// Миксины -// -------------------------- - -.square(@size: @fz) { - width: @size; - height: @size; -} - diff --git a/engine/modules/base/admin/blockpro/less/main.less b/engine/modules/base/admin/blockpro/less/main.less deleted file mode 100644 index a634e95..0000000 --- a/engine/modules/base/admin/blockpro/less/main.less +++ /dev/null @@ -1,61 +0,0 @@ -// Принципы формирования имён файлов: -// Имя файла следует начинать с двухзначной цифры, после которой идёт тире и пояснительное название файла, понятное для человека. -// Это даст в будущем возможность нормального восприятия структуры файлов и возможно автоподхват файлов по аналогии с автолоадером. -// -// Пояснения к цифрам: -// 00-09 — файлы, которые не попадают в результирующий CSS (миксины, переменные и т.д.) -// 10-19 — файлы, которые обязательно должны присутствовать, задают костяк шаблона (сетка, кнопки, иконки, формы и т.д.) и оформляют стандартные элементы html. -// 20-79 — различные дополнительные файлы, отвечающие за оформление конкретных кусков вёрстки (меню, модальные окна, слайдеры, хлебные крошки, каталог и т.д.) -// 80-main.less - основной файл стилей сайта, сюда как правило пишется всё, что относится к конкретному сайту, это уникальный для каждого проекта файл, если куски кода кочуют в этом файле из проекта в проект - значит надо выносить их в отдельный файлы в пределах имён 20-79. - - -// Ну и не забываем ставить своё имя в этом файле для опознания -// Это поможет идентивицировать автора сего безобразия :) - -/*! Автор: Павел Белоусов (http://pafnuty.name) */ -/* ========================================================================== */ - - -// Миксины и прочее -@import "00-variables"; -@import "01-mixins"; -@import "02-grid"; - -// сброс стилей и прочие обязательные вещи -@import "10-normalize"; -@import "11-buttons"; -@import "12-icons"; -@import "13-forms"; -@import "14-tables"; - -// не совсем обязательные слили, но нужные - -@import "20-base"; -// @import "21-carousel"; -// @import "22-jcarousel"; -// @import "23-breadcrumb"; -// @import "24-arcticmodal"; -@import "25-magnificpopup"; -// @import "26-slider"; -// @import "27-topnavi"; -@import "28-ladda"; -@import "29-tabs"; -@import "30-chosen"; - -// @import "datepicker/dp_main.less"; -// @import "formstyler/formstyler.less"; -// @import "selectize/selectize.less"; - - - - - - - -// Основные стили сайта -@import "80-main"; - -// Различные хелперы типа .clearfix и прочие стили -// подгрузка которых должна происходить после основных -@import "90-helpers"; - diff --git a/engine/modules/base/admin/blockpro/less/selectize/plugins/drag_drop.less b/engine/modules/base/admin/blockpro/less/selectize/plugins/drag_drop.less deleted file mode 100644 index 9d42e4a..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/plugins/drag_drop.less +++ /dev/null @@ -1,16 +0,0 @@ -.selectize-control.plugin-drag_drop { - &.multi > .selectize-input > div.ui-sortable-placeholder { - visibility: visible !important; - background: #f2f2f2 !important; - background: rgba(0,0,0,0.06) !important; - border: 0 none !important; - .selectize-box-shadow(inset 0 0 12px 4px #fff); - } - .ui-sortable-placeholder::after { - content: '!'; - visibility: hidden; - } - .ui-sortable-helper { - .selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2)); - } -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/selectize/plugins/dropdown_header.less b/engine/modules/base/admin/blockpro/less/selectize/plugins/dropdown_header.less deleted file mode 100644 index c3e777e..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/plugins/dropdown_header.less +++ /dev/null @@ -1,20 +0,0 @@ -.selectize-dropdown-header { - position: relative; - padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; - border-bottom: 1px solid @selectize-color-border; - background: mix(@selectize-color-dropdown, @selectize-color-border, 85%); - .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); -} -.selectize-dropdown-header-close { - position: absolute; - right: @selectize-padding-dropdown-item-x; - top: 50%; - color: @selectize-color-text; - opacity: 0.4; - margin-top: -12px; - line-height: 20px; - font-size: 20px !important; -} -.selectize-dropdown-header-close:hover { - color: darken(@selectize-color-text, 25%); -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/selectize/plugins/optgroup_columns.less b/engine/modules/base/admin/blockpro/less/selectize/plugins/optgroup_columns.less deleted file mode 100644 index 5c72d7a..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/plugins/optgroup_columns.less +++ /dev/null @@ -1,17 +0,0 @@ -.selectize-dropdown.plugin-optgroup_columns { - .optgroup { - border-right: 1px solid #f2f2f2; - border-top: 0 none; - float: left; - .selectize-box-sizing(border-box); - } - .optgroup:last-child { - border-right: 0 none; - } - .optgroup:before { - display: none; - } - .optgroup-header { - border-top: 0 none; - } -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/selectize/plugins/remove_button.less b/engine/modules/base/admin/blockpro/less/selectize/plugins/remove_button.less deleted file mode 100644 index c478cd4..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/plugins/remove_button.less +++ /dev/null @@ -1,37 +0,0 @@ -.selectize-control.plugin-remove_button { - [data-value] { - position: relative; - padding-right: 24px !important; - } - [data-value] .remove { - z-index: 1; /* fixes ie bug (see #392) */ - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 17px; - text-align: center; - font-weight: bold; - font-size: 12px; - color: inherit; - text-decoration: none; - vertical-align: middle; - display: inline-block; - padding: @selectize-padding-item-y 0 0 0; - border-left: 1px solid @selectize-color-item-border; - .selectize-border-radius(0 2px 2px 0); - .selectize-box-sizing(border-box); - } - [data-value] .remove:hover { - background: rgba(0,0,0,0.05); - } - [data-value].active .remove { - border-left-color: @selectize-color-item-active-border; - } - .disabled [data-value] .remove:hover { - background: none; - } - .disabled [data-value] .remove { - border-left-color: lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); - } -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/selectize/selectize.bootstrap2.less b/engine/modules/base/admin/blockpro/less/selectize/selectize.bootstrap2.less deleted file mode 100644 index 72f8b02..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/selectize.bootstrap2.less +++ /dev/null @@ -1,161 +0,0 @@ -/** - * selectize.bootstrap2.css (v0.11.1) - Bootstrap 2 Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-family: @baseFontFamily; -@selectize-font-size: @baseFontSize; -@selectize-line-height: @baseLineHeight; - -@selectize-color-text: @textColor; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-input: @inputBackground; -@selectize-color-input-full: @inputBackground; -@selectize-color-disabled: @inputBackground; -@selectize-color-item: @btnBackgroundHighlight; -@selectize-color-item-border: @btnBorder; -@selectize-color-item-active: @dropdownLinkBackgroundHover; -@selectize-color-item-active-text: @dropdownLinkColorHover; -@selectize-color-item-active-border: darken(@selectize-color-item-active, 5%); -@selectize-color-optgroup: @dropdownBackground; -@selectize-color-optgroup-text: @grayLight; -@selectize-color-optgroup-border: @dropdownDividerTop; -@selectize-color-dropdown: @dropdownBackground; -@selectize-color-dropdown-border: @inputBorder; -@selectize-color-dropdown-border-top: @dropdownDividerTop; -@selectize-color-dropdown-item-active: @dropdownLinkBackgroundHover; -@selectize-color-dropdown-item-active-text: @dropdownLinkColorHover; -@selectize-color-dropdown-item-create-active-text: @dropdownLinkColorHover; -@selectize-lighten-disabled-item: 8%; -@selectize-lighten-disabled-item-text: 8%; -@selectize-lighten-disabled-item-border: 8%; -@selectize-opacity-disabled: 0.5; -@selectize-shadow-input: none; -@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); -@selectize-border-radius: @inputBorderRadius; - -@selectize-padding-x: 10px; -@selectize-padding-y: 7px; -@selectize-padding-dropdown-item-x: @selectize-padding-x; -@selectize-padding-dropdown-item-y: 3px; -@selectize-padding-item-x: 3px; -@selectize-padding-item-y: 1px; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; -@selectize-caret-margin: 0; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: @black; -@selectize-arrow-offset: @selectize-padding-x + 5px; - -@selectize-width-item-border: 1px; - -.selectize-dropdown { - margin: 2px 0 0 0; - z-index: @zindexDropdown; - border: 1px solid @dropdownBorder; - border-radius: @baseBorderRadius; - .box-shadow(0 5px 10px rgba(0,0,0,.2)); - - .optgroup-header { - font-size: 11px; - font-weight: bold; - text-shadow: 0 1px 0 rgba(255,255,255,.5); - text-transform: uppercase; - } - .optgroup:first-child:before { - display: none; - } - .optgroup:before { - content: ' '; - display: block; - .nav-divider(); - margin-left: @selectize-padding-dropdown-item-x * -1; - margin-right: @selectize-padding-dropdown-item-x * -1; - } - - [data-selectable].active { - #gradient > .vertical(@dropdownLinkBackgroundHover, darken(@dropdownLinkBackgroundHover, 5%)); - } -} - -.selectize-dropdown-content { - padding: 5px 0; -} - -.selectize-dropdown-header { - padding: @selectize-padding-dropdown-item-y * 2 @selectize-padding-dropdown-item-x; -} - -.selectize-input { - .transition(~"border linear .2s, box-shadow linear .2s"); - - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius); - } - &.dropdown-active::before { - display: none; - } - &.input-active, &.input-active:hover, .selectize-control.multi &.focus { - background: @selectize-color-input !important; - border-color: rgba(82,168,236,.8) !important; - outline: 0 !important; - outline: thin dotted \9 !important; - .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)") !important; - } -} - -.selectize-control { - &.single { - .selectize-input { - .buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); - .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); - &:hover { - color: @grayDark; - text-decoration: none; - background-position: 0 -15px; - .transition(background-position .1s linear); - } - &.disabled { - background: @btnBackgroundHighlight !important; - .box-shadow(none); - } - } - } - &.multi { - .selectize-input { - .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - &.has-items { - @padding-x: @selectize-padding-x - @selectize-padding-item-x; - padding-left: @padding-x; - padding-right: @padding-x; - } - } - .selectize-input > div { - .gradientBar(@btnBackground, @btnBackgroundHighlight, @selectize-color-item-text, none); - *background-color: @selectize-color-item; - border: @selectize-width-item-border solid @selectize-color-item-border; - .border-radius(@baseBorderRadius); - .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); - &.active { - .box-shadow(~"0 1px 2px rgba(0,0,0,.05)"); - .gradientBar(@selectize-color-item-active, @selectize-color-item-active-border, @selectize-color-item-active-text, none); - *background-color: @selectize-color-item-active; - border: @selectize-width-item-border solid @dropdownLinkBackgroundHover; - } - } - } -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/selectize/selectize.bootstrap3.less b/engine/modules/base/admin/blockpro/less/selectize/selectize.bootstrap3.less deleted file mode 100644 index 20a1c97..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/selectize.bootstrap3.less +++ /dev/null @@ -1,150 +0,0 @@ -/** - * selectize.bootstrap3.css (v0.11.1) - Bootstrap 3 Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-family: @font-family-base; -@selectize-font-size: @font-size-base; -@selectize-line-height: @line-height-computed; - -@selectize-color-text: @text-color; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-input: @input-bg; -@selectize-color-input-full: @input-bg; -@selectize-color-input-error: @state-danger-text; -@selectize-color-input-error-focus: darken(@selectize-color-input-error, 10%); -@selectize-color-disabled: @input-bg; -@selectize-color-item: #efefef; -@selectize-color-item-border: rgba(0,0,0,0); -@selectize-color-item-active: @component-active-bg; -@selectize-color-item-active-text: #fff; -@selectize-color-item-active-border: rgba(0,0,0,0); -@selectize-color-optgroup: @dropdown-bg; -@selectize-color-optgroup-text: @dropdown-header-color; -@selectize-color-optgroup-border: @dropdown-divider-bg; -@selectize-color-dropdown: @dropdown-bg; -@selectize-color-dropdown-border-top: mix(@input-border, @input-bg, 0.8); -@selectize-color-dropdown-item-active: @dropdown-link-hover-bg; -@selectize-color-dropdown-item-active-text: @dropdown-link-hover-color; -@selectize-color-dropdown-item-create-active-text: @dropdown-link-hover-color; -@selectize-opacity-disabled: 0.5; -@selectize-shadow-input: none; -@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); -@selectize-shadow-input-error: inset 0 1px 1px rgba(0, 0, 0, .075); -@selectize-shadow-input-error-focus: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px lighten(@selectize-color-input-error, 20%); -@selectize-border: 1px solid @input-border; -@selectize-border-radius: @input-border-radius; - -@selectize-width-item-border: 0; -@selectize-padding-x: @padding-base-horizontal; -@selectize-padding-y: @padding-base-vertical; -@selectize-padding-dropdown-item-x: @padding-base-horizontal; -@selectize-padding-dropdown-item-y: 3px; -@selectize-padding-item-x: 3px; -@selectize-padding-item-y: 1px; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; -@selectize-caret-margin: 0; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: @selectize-color-text; -@selectize-arrow-offset: @selectize-padding-x + 5px; - -.selectize-dropdown, .selectize-dropdown.form-control { - height: auto; - padding: 0; - margin: 2px 0 0 0; - z-index: @zindex-dropdown; - background: @selectize-color-dropdown; - border: 1px solid @dropdown-fallback-border; - border: 1px solid @dropdown-border; - .selectize-border-radius(@border-radius-base); - .selectize-box-shadow(0 6px 12px rgba(0,0,0,.175)); -} - -.selectize-dropdown { - .optgroup-header { - font-size: @font-size-small; - line-height: @line-height-base; - } - .optgroup:first-child:before { - display: none; - } - .optgroup:before { - content: ' '; - display: block; - .nav-divider(); - margin-left: @selectize-padding-dropdown-item-x * -1; - margin-right: @selectize-padding-dropdown-item-x * -1; - } -} - -.selectize-dropdown-content { - padding: 5px 0; -} - -.selectize-dropdown-header { - padding: @selectize-padding-dropdown-item-y * 2 @selectize-padding-dropdown-item-x; -} - -.selectize-input { - min-height: @input-height-base; - - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius); - } - &.dropdown-active::before { - display: none; - } - &.focus { - @color: @input-border-focus; - @color-rgba: rgba(red(@color), green(@color), blue(@color), .6); - border-color: @color; - outline: 0; - .selectize-box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}"); - } -} - -.has-error .selectize-input { - border-color: @selectize-color-input-error; - .selectize-box-shadow(@selectize-shadow-input-error); - - &:focus { - border-color: @selectize-color-input-error-focus; - .selectize-box-shadow(@selectize-shadow-input-error-focus); - } -} - -.selectize-control { - &.multi { - .selectize-input.has-items { - padding-left: @selectize-padding-x - @selectize-padding-item-x; - padding-right: @selectize-padding-x - @selectize-padding-item-x; - } - .selectize-input > div { - .selectize-border-radius(@selectize-border-radius - 1px); - } - } -} - -.form-control.selectize-control { - padding: 0; - height: auto; - border: none; - background: none; - .selectize-box-shadow(none); - .selectize-border-radius(0); -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/selectize/selectize.default.less b/engine/modules/base/admin/blockpro/less/selectize/selectize.default.less deleted file mode 100644 index ffd9b06..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/selectize.default.less +++ /dev/null @@ -1,84 +0,0 @@ -/** - * selectize.default.css (v0.11.1) - Default Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-color-item: #1da7ee; -@selectize-color-item-text: #fff; -@selectize-color-item-active-text: #fff; -@selectize-color-item-border: #0073bb; -@selectize-color-item-active: #92c836; -@selectize-color-item-active-border: #00578d; -@selectize-width-item-border: 1px; -@selectize-caret-margin: 0 1px; - -.selectize-control { - &.multi { - .selectize-input { - &.has-items { - @padding-x: @selectize-padding-x - 3px; - padding-left: @padding-x; - padding-right: @padding-x; - } - &.disabled [data-value] { - color: #999; - text-shadow: none; - background: none; - .selectize-box-shadow(none); - - &, .remove { - border-color: #e6e6e6; - } - .remove { - background: none; - } - } - [data-value] { - text-shadow: 0 1px 0 rgba(0,51,83,0.3); - .selectize-border-radius(3px); - .selectize-vertical-gradient(#1da7ee, #178ee9); - .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03)"); - &.active { - .selectize-vertical-gradient(#008fd8, #0075cf); - } - } - } - } - &.single { - .selectize-input { - .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8)"); - .selectize-vertical-gradient(#fefefe, #f2f2f2); - } - } -} - -.selectize-control.single .selectize-input, .selectize-dropdown.single { - border-color: #b8b8b8; -} - -.selectize-dropdown { - .optgroup-header { - padding-top: @selectize-padding-dropdown-item-y + 2px; - font-weight: bold; - font-size: 0.85em; - } - .optgroup { - border-top: 1px solid @selectize-color-dropdown-border-top; - &:first-child { - border-top: 0 none; - } - } -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/selectize/selectize.legacy.less b/engine/modules/base/admin/blockpro/less/selectize/selectize.legacy.less deleted file mode 100644 index c1e952a..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/selectize.legacy.less +++ /dev/null @@ -1,75 +0,0 @@ -/** - * selectize.legacy.css (v0.11.1) - Default Theme - * Copyright (c) 2013 Brian Reavis & contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. You may obtain a copy of the License at: - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF - * ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - * - * @author Brian Reavis - */ - -@import "selectize"; - -@selectize-font-size: 13px; -@selectize-line-height: 20px; - -@selectize-color-input-full: #f2f2f2; -@selectize-color-item: #b8e76f; -@selectize-color-item-text: #3d5d18; -@selectize-color-item-border: #74b21e; -@selectize-color-item-active: #92c836; -@selectize-color-item-active-border: #6f9839; -@selectize-color-highlight: rgba(255,237,40,0.4); -@selectize-color-dropdown-item-active: #fffceb; -@selectize-color-dropdown-item-active-text: @selectize-color-text; -@selectize-color-optgroup: #f8f8f8; -@selectize-color-optgroup-text: @selectize-color-text; -@selectize-width-item-border: 1px; - -@selectize-padding-x: 10px; -@selectize-padding-y: 10px; -@selectize-padding-item-x: 5px; -@selectize-padding-item-y: 1px; -@selectize-padding-dropdown-item-x: 10px; -@selectize-padding-dropdown-item-y: 7px; -@selectize-margin-item-x: 4px; -@selectize-margin-item-y: 4px; - -.selectize-control { - &.multi { - .selectize-input [data-value] { - text-shadow: 0 1px 0 rgba(255,255,255,0.1); - .selectize-border-radius(3px); - .selectize-vertical-gradient(#b8e76f, #a9e25c); - .selectize-box-shadow(0 1px 1px rgba(0,0,0,0.1)); - &.active { - .selectize-vertical-gradient(#92c836, #7abc2c); - } - } - } - &.single { - .selectize-input { - .selectize-box-shadow(~"inset 0 1px 0 rgba(255,255,255,0.8), 0 2px 0 #e0e0e0, 0 3px 0 #c8c8c8, 0 4px 1px rgba(0,0,0,0.1)"); - .selectize-vertical-gradient(#f5f5f5, #efefef); - } - } -} - -.selectize-control.single .selectize-input, .selectize-dropdown.single { - border-color: #b8b8b8; -} - -.selectize-dropdown { - .optgroup-header { - font-weight: bold; - font-size: 0.8em; - border-bottom: 1px solid @selectize-color-dropdown-border-top; - border-top: 1px solid @selectize-color-dropdown-border-top; - } -} \ No newline at end of file diff --git a/engine/modules/base/admin/blockpro/less/selectize/selectize.less b/engine/modules/base/admin/blockpro/less/selectize/selectize.less deleted file mode 100644 index 1fc4a69..0000000 --- a/engine/modules/base/admin/blockpro/less/selectize/selectize.less +++ /dev/null @@ -1,298 +0,0 @@ -@import "plugins/drag_drop"; -@import "plugins/dropdown_header"; -@import "plugins/optgroup_columns"; -@import "plugins/remove_button"; - -// base styles - -@selectize-font-family: inherit; -@selectize-font-smoothing: inherit; -@selectize-font-size: 14px; -@selectize-line-height: 20px; - -@selectize-color-text: @textColor; -@selectize-color-border: @blue; -@selectize-color-highlight: fadeout(@blue, 50%); -@selectize-color-input: #fff; -@selectize-color-input-full: @selectize-color-input; -@selectize-color-disabled: #fafafa; -@selectize-color-item: #f2f2f2; -@selectize-color-item-text: @selectize-color-text; -@selectize-color-item-border: #d0d0d0; -@selectize-color-item-active: #e8e8e8; -@selectize-color-item-active-text: @selectize-color-text; -@selectize-color-item-active-border: #cacaca; -@selectize-color-dropdown: #fff; -@selectize-color-dropdown-border: @selectize-color-border; -@selectize-color-dropdown-border-top: #f0f0f0; -@selectize-color-dropdown-item-active: fadeout(@blue, 20%); -@selectize-color-dropdown-item-active-text: @white; -@selectize-color-dropdown-item-create-text: rgba(red(@selectize-color-text), green(@selectize-color-text), blue(@selectize-color-text), 0.5); -@selectize-color-dropdown-item-create-active-text: @selectize-color-dropdown-item-active-text; -@selectize-color-optgroup: fadeout(@gray, 50%); -@selectize-color-optgroup-text: $gray; -@selectize-lighten-disabled-item: 30%; -@selectize-lighten-disabled-item-text: 30%; -@selectize-lighten-disabled-item-border: 30%; -@selectize-opacity-disabled: 0.5; - -@selectize-shadow-input: none; -@selectize-shadow-input-focus: none; -@selectize-border: 1px solid @selectize-color-border; -@selectize-border-radius: 0; - -@selectize-width-item-border: 0; -@selectize-max-height-dropdown: 200px; - -@selectize-padding-x: 10px; -@selectize-padding-y: 10px; -@selectize-padding-item-x: 10px; -@selectize-padding-item-y: 10px; -@selectize-padding-dropdown-item-x: @selectize-padding-x; -@selectize-padding-dropdown-item-y: @selectize-padding-item-y; -@selectize-margin-item-x: 3px; -@selectize-margin-item-y: 3px; - -@selectize-arrow-size: 5px; -@selectize-arrow-color: #808080; -@selectize-arrow-offset: 15px; - -@selectize-caret-margin: 0 2px 0 0; -@selectize-caret-margin-rtl: 0 4px 0 -2px; - -.selectize-border-radius (@radii) { - -webkit-border-radius: @radii; - -moz-border-radius: @radii; - border-radius: @radii; -} -.selectize-unselectable () { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.selectize-box-shadow (@shadow) { - -webkit-box-shadow: @shadow; - box-shadow: @shadow; -} -.selectize-box-sizing (@type: border-box) { - -webkit-box-sizing: @type; - -moz-box-sizing: @type; - box-sizing: @type; -} -.selectize-vertical-gradient (@color-top, @color-bottom) { - background-color: mix(@color-top, @color-bottom, 60%); - background-image: -moz-linear-gradient(top, @color-top, @color-bottom); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@color-top), to(@color-bottom)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, @color-top, @color-bottom); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(top, @color-top, @color-bottom); // Opera 11.10 - background-image: linear-gradient(to bottom, @color-top, @color-bottom); // Standard, IE10 - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@color-top),argb(@color-bottom))); // IE9 and down -} - -.selectize-control { - position: relative; -} - -.selectize-dropdown, .selectize-input, .selectize-input input { - color: @selectize-color-text; - font-family: @selectize-font-family; - font-size: @selectize-font-size; - line-height: @selectize-line-height; - -webkit-font-smoothing: @selectize-font-smoothing; -} - -.selectize-input, .selectize-control.single .selectize-input.input-active { - background: @selectize-color-input; - cursor: text; - display: inline-block; -} - -.selectize-input { - border: @selectize-border; - padding: @selectize-padding-y @selectize-padding-x; - display: inline-block; - width: 100%; - overflow: hidden; - position: relative; - z-index: 1; - .selectize-box-sizing(border-box); - .selectize-box-shadow(@selectize-shadow-input); - .selectize-border-radius(@selectize-border-radius); - - .selectize-control.multi &.has-items { - @padding-x: @selectize-padding-x; - @padding-top: @selectize-padding-y - @selectize-padding-item-y - @selectize-width-item-border; - @padding-bottom: @selectize-padding-y - @selectize-padding-item-y - @selectize-margin-item-y - @selectize-width-item-border; - padding: @padding-top @padding-x @padding-bottom; - } - - &.full { - background-color: @selectize-color-input-full; - } - &.disabled, &.disabled * { - cursor: default !important; - } - &.focus { - .selectize-box-shadow(@selectize-shadow-input-focus); - } - &.dropdown-active { - .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); - } - - > * { - vertical-align: baseline; - display: -moz-inline-stack; - display: inline-block; - zoom: 1; - *display: inline; - } - .selectize-control.multi & > div { - cursor: pointer; - margin: 0 @selectize-margin-item-x @selectize-margin-item-y 0; - padding: @selectize-padding-item-y @selectize-padding-item-x; - background: @selectize-color-item; - color: @selectize-color-item-text; - border: @selectize-width-item-border solid @selectize-color-item-border; - - &.active { - background: @selectize-color-item-active; - color: @selectize-color-item-active-text; - border: @selectize-width-item-border solid @selectize-color-item-active-border; - } - } - .selectize-control.multi &.disabled > div { - &, &.active { - color: lighten(desaturate(@selectize-color-item-text, 100%), @selectize-lighten-disabled-item-text); - background: lighten(desaturate(@selectize-color-item, 100%), @selectize-lighten-disabled-item); - border: @selectize-width-item-border solid lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); - } - } - > input { - &::-ms-clear { - display: none; - } - display: inline-block !important; - padding: 0 !important; - min-height: 0 !important; - max-height: none !important; - max-width: 100% !important; - margin: @selectize-caret-margin !important; - text-indent: 0 !important; - border: 0 none !important; - background: none !important; - line-height: inherit !important; - -webkit-user-select: auto !important; - .selectize-box-shadow(none) !important; - &:focus { outline: none !important; } - } -} - -.selectize-input::after { - content: ' '; - display: block; - clear: left; -} - -.selectize-input.dropdown-active::before { - content: ' '; - display: block; - position: absolute; - background: @selectize-color-dropdown-border-top; - height: 1px; - bottom: 0; - left: 0; - right: 0; -} - -.selectize-dropdown { - position: absolute; - z-index: 10; - border: @selectize-border; - background: @selectize-color-dropdown; - margin: -1px 0 0 0; - border-top: 0 none; - .selectize-box-sizing(border-box); - .selectize-box-shadow(0 1px 3px rgba(0,0,0,0.1)); - .selectize-border-radius(0 0 @selectize-border-radius @selectize-border-radius); - - [data-selectable] { - cursor: pointer; - overflow: hidden; - .highlight { - background: @selectize-color-highlight; - .selectize-border-radius(1px); - } - } - [data-selectable], .optgroup-header { - padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; - } - .optgroup:first-child .optgroup-header { - border-top: 0 none; - } - .optgroup-header { - color: @selectize-color-optgroup-text; - background: @selectize-color-optgroup; - cursor: default; - font-size: 16px; - font-weight: bold; - text-align: center; - border-top: solid 1px @grayDark; - } - .active { - background-color: @selectize-color-dropdown-item-active; - color: @selectize-color-dropdown-item-active-text; - &.create { - color: @selectize-color-dropdown-item-create-active-text; - } - } - .create { - color: @selectize-color-dropdown-item-create-text; - } -} - -.selectize-dropdown-content { - overflow-y: auto; - overflow-x: hidden; - max-height: @selectize-max-height-dropdown; -} - -.selectize-control.single .selectize-input { - &, input { cursor: pointer; } - &.input-active, &.input-active input { cursor: text; } - - &:after { - content: ' '; - display: block; - position: absolute; - top: 50%; - right: @selectize-arrow-offset; - margin-top: round(-1 * @selectize-arrow-size / 2); - width: 0; - height: 0; - border-style: solid; - border-width: @selectize-arrow-size @selectize-arrow-size 0 @selectize-arrow-size; - border-color: @selectize-arrow-color transparent transparent transparent; - } - &.dropdown-active:after { - margin-top: @selectize-arrow-size * -0.8; - border-width: 0 @selectize-arrow-size @selectize-arrow-size @selectize-arrow-size; - border-color: transparent transparent @selectize-arrow-color transparent; - } -} - -.selectize-control.rtl { - &.single .selectize-input:after { - left: @selectize-arrow-offset; - right: auto; - } - .selectize-input > input { - margin: @selectize-caret-margin-rtl !important; - } -} - -.selectize-control .selectize-input.disabled { - opacity: @selectize-opacity-disabled; - background-color: @selectize-color-disabled; -} From 3f1230d58386533a6fcebdaf2ca39440e31d1f35 Mon Sep 17 00:00:00 2001 From: pafnuty Date: Sat, 22 Feb 2020 21:41:05 +0400 Subject: [PATCH 4/5] 6.0.0 Done --- .gitignore | 3 - CHANGELOG.md | 8 +- blockpro.php | 8 +- engine/ajax/base/save_block_pro.php | 1 - engine/ajax/blockpro.php | 10 +- engine/inc/blockpro.php | 62 +- engine/modules/base/admin/blockpro/config.php | 1 - .../modules/base/admin/blockpro/generator.php | 37 +- engine/modules/base/admin/blockpro/js/main.js | 1 - .../modules/base/admin/blockpro/vidgets.php | 1 - engine/modules/base/blockpro.php | 2136 ++++++++--------- engine/modules/base/core/base.php | 26 +- engine/modules/base/core/bpModifiers.php | 1 - engine/modules/base/core/config.php | 179 ++ engine/modules/base/core/resize.php | 529 ++-- 15 files changed, 1589 insertions(+), 1414 deletions(-) create mode 100644 engine/modules/base/core/config.php diff --git a/.gitignore b/.gitignore index e59471f..ba493cb 100644 --- a/.gitignore +++ b/.gitignore @@ -241,8 +241,5 @@ !/engine/ajax/blockpro.php !/engine/inc/blockpro.php !/engine/skins/images/blockpro.png -!/templates/Default/blockpro/ !/blockpro.php -!/blockpro_install.php -!/bp_check.php !/CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a2a4a11..d4d5c99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,14 @@ # 6.0.0 -- Теперь модуль не гарантирует совместимость со версиями DLE ниже, чем 13.x и скоро будет убрана их поддержка полностью. +- Теперь модуль не гарантирует совместимость с версиями DLE ниже, чем 13.x и скоро будет убрана их поддержка полностью. - Установка в виде плагина. - Исправлена ошибка с вариантом сортировки `randomLight`, когда новости не найдены. - Добавлен новый модификатор `sentence`, позволяющий вывести заданное количество предложений (до точки). Например `{$el.short_story|sentence:'2'}` - выведет два первых предложения из краткой новости. +- Добавлена поддержка модуля MultiLanguage от japing.pw. +- Добавлен новый тег `{$langVariant}`. Тег выводит код текущего языка сайта, если он отличается от языка по умолчнию. Тег нужен при использовании модуля MultiLanguage. +- Исправлена ошибка при добавлении новости в избранное в DLE 13 и 14 версий (#165) +- Исправлен некорректый вывод новостей при выводе по тегам в определённых ситуациях (#160) +- Исправлена ошибка `PHP Fatal error: imagecreatefromjpeg()` (#150) +- Добавлена поддержка ресайза `.webp` картинок - Небольшие изменения и улучшения в коде. # 5.1.5 diff --git a/blockpro.php b/blockpro.php index 6fb5ec0..297bd9a 100644 --- a/blockpro.php +++ b/blockpro.php @@ -6,7 +6,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ @@ -45,11 +44,8 @@ check_xss(); -if (function_exists('dle_session')) { - dle_session(); -} else { - @session_start(); -} +dle_session(); + $is_logged = false; $member_id = []; diff --git a/engine/ajax/base/save_block_pro.php b/engine/ajax/base/save_block_pro.php index 5e8dbd2..c3bfdd1 100644 --- a/engine/ajax/base/save_block_pro.php +++ b/engine/ajax/base/save_block_pro.php @@ -6,7 +6,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ diff --git a/engine/ajax/blockpro.php b/engine/ajax/blockpro.php index 0f23b65..0bf1ac7 100644 --- a/engine/ajax/blockpro.php +++ b/engine/ajax/blockpro.php @@ -6,7 +6,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ @@ -42,11 +41,8 @@ require_once(DLEPlugins::Check(ENGINE_DIR . '/data/dbconfig.php')); require_once(DLEPlugins::Check(ENGINE_DIR . '/modules/functions.php')); -if (function_exists('dle_session')) { - dle_session(); -} else { - @session_start(); -} +dle_session(); + $is_logged = false; $member_id = []; @@ -70,7 +66,7 @@ $thisUrl = (isset($_REQUEST['thisUrl'])) ? (string)$_REQUEST['thisUrl'] : false; $cashe_tmp = $config['allow_cache']; -$config['allow_cache'] = 'yes'; // 'yes' для совместимости со старыми версиями dle, т.к. там проверяется значение, а не наличие значения переменной. +$config['allow_cache'] = 1; $_cr = dle_cache($blockId); $config['allow_cache'] = $cashe_tmp; diff --git a/engine/inc/blockpro.php b/engine/inc/blockpro.php index 1587b36..09216e0 100644 --- a/engine/inc/blockpro.php +++ b/engine/inc/blockpro.php @@ -6,7 +6,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ @@ -89,60 +88,11 @@ $setFilter = $_REQUEST['setFilter']; $experiment = $_REQUEST['experiment']; $experiment_checked = ($experiment) ? 'checked' : ''; +$multiLang = $_REQUEST['multiLang']; +$multiLang_checked = ($multiLang) ? 'checked' : ''; +$langList = $_REQUEST['langList']; - -$cfg = [ - 'moderate' => !empty($moderate) ? $moderate : false, - 'template' => !empty($template) ? $template : 'blockpro/blockpro', - 'cachePrefix' => !empty($cachePrefix) ? $cachePrefix : 'news', - 'cacheSuffixOff' => !empty($cacheSuffixOff) ? true : false, - 'cacheNameAddon' => '', - 'nocache' => !empty($nocache) ? $nocache : false, - 'cacheLive' => (!empty($cacheLive) && !$mcache) ? $cacheLive : false, - 'startFrom' => !empty($startFrom) ? $startFrom : '0', - 'limit' => !empty($limit) ? $limit : '10', - 'fixed' => !empty($fixed) ? $fixed : 'yes', - 'allowMain' => !empty($allowMain) ? $allowMain : 'yes', - 'postId' => !empty($postId) ? $postId : '', - 'notPostId' => !empty($notPostId) ? $notPostId : '', - 'author' => !empty($author) ? $author : '', - 'notAuthor' => !empty($notAuthor) ? $notAuthor : '', - 'xfilter' => !empty($xfilter) ? $xfilter : '', - 'notXfilter' => !empty($notXfilter) ? $notXfilter : '', - 'xfSearch' => !empty($xfSearch) ? $xfSearch : false, - 'notXfSearch' => !empty($notXfSearch) ? $notXfSearch : false, - 'xfSearchLogic' => !empty($xfSearchLogic) ? $xfSearchLogic : 'OR', - 'catId' => !empty($catId) ? $catId : '', - 'subcats' => !empty($subcats) ? $subcats : false, - 'notCatId' => !empty($notCatId) ? $notCatId : '', - 'notSubcats' => !empty($notSubcats) ? $notSubcats : false, - 'thisCatOnly' => !empty($thisCatOnly) ? $thisCatOnly : false, - 'tags' => !empty($tags) ? $tags : '', - 'notTags' => !empty($notTags) ? $notTags : '', - 'day' => !empty($day) ? $day : false, - 'dayCount' => !empty($dayCount) ? $dayCount : false, - 'sort' => !empty($sort) ? $sort : 'top', - 'xfSortType' => !empty($xfSortType) ? $xfSortType : 'int', - 'order' => !empty($order) ? $order : 'new', - 'avatar' => !empty($avatar) ? $avatar : false, - 'showstat' => !empty($showstat) ? $showstat : false, - 'related' => !empty($related) ? $related : false, - 'saveRelated' => !empty($saveRelated) ? $saveRelated : false, - 'showNav' => !empty($showNav) ? $showNav : false, - 'navDefaultGet' => !empty($navDefaultGet) ? $navDefaultGet : false, - 'pageNum' => !empty($pageNum) ? $pageNum : '1', - 'navStyle' => !empty($navStyle) ? $navStyle : 'classic', - 'options' => !empty($options) ? $options : false, - 'notOptions' => !empty($notOptions) ? $notOptions : false, - 'future' => !empty($future) ? $future : false, - 'cacheVars' => !empty($cacheVars) ? $cacheVars : false, - 'symbols' => !empty($symbols) ? $symbols : false, - 'notSymbols' => !empty($notSymbols) ? $notSymbols : false, - 'fields' => !empty($fields) ? $fields : false, - 'setFilter' => !empty($setFilter) ? $setFilter : '', - 'experiment' => !empty($experiment) ? $experiment : false, - -]; +include ENGINE_DIR . '/modules/base/core/config.php'; /** * var array $bpConfig @@ -434,6 +384,10 @@ class="btn btn-small btn-red"> unset($cfg['xfSortType']); } + if ($cfg['langList'] == 'en') { + unset($cfg['langList']); + } + $filteredCfg = array_filter($cfg); if (count($filteredCfg) > 0) { $moduleUrl .= '?'; diff --git a/engine/modules/base/admin/blockpro/config.php b/engine/modules/base/admin/blockpro/config.php index 91592da..5595abe 100644 --- a/engine/modules/base/admin/blockpro/config.php +++ b/engine/modules/base/admin/blockpro/config.php @@ -6,7 +6,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ diff --git a/engine/modules/base/admin/blockpro/generator.php b/engine/modules/base/admin/blockpro/generator.php index d967914..dba57ec 100644 --- a/engine/modules/base/admin/blockpro/generator.php +++ b/engine/modules/base/admin/blockpro/generator.php @@ -6,7 +6,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ @@ -282,6 +281,42 @@ function showXFields($configname, $prefix = false, $inOptGroup = false) { +
    +
    + Поддержка модуля MultiLanguage от japing.pw +
    +
    + > +
    +
    + При включении параметра и если модуль MultiLanguage включен, то: +
      +
    • + Будут учитываться настройки фильтрации новостей в соответсвии с настройками модуля MultiLanguage +
    • +
    • + Будет корректно формироваться ссылка на полную новость с учётом языка сайта +
    • +
    • + Заголовок, полная и краткая новость будет браться в соответствии с настройками модуля MultiLanguage +
    • +
    +
    +
    +
    + +
    + Языки, добавленные в модуле MultiLanguage от japing.pw +
    +
    + +
    +
    + Коды языков, добавленный в модуле MultiLanguage.
    Язык по умолчанию указывать не нужно, нужны только те языки, которые были добавлены дополнительно (указывать через запятую, если я зыков несколько). +
    +
    +
    +
    diff --git a/engine/modules/base/admin/blockpro/js/main.js b/engine/modules/base/admin/blockpro/js/main.js index 50f286b..36c05c3 100644 --- a/engine/modules/base/admin/blockpro/js/main.js +++ b/engine/modules/base/admin/blockpro/js/main.js @@ -5,7 +5,6 @@ BlockPro Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ diff --git a/engine/modules/base/admin/blockpro/vidgets.php b/engine/modules/base/admin/blockpro/vidgets.php index 9afd9d0..feb1b77 100644 --- a/engine/modules/base/admin/blockpro/vidgets.php +++ b/engine/modules/base/admin/blockpro/vidgets.php @@ -6,7 +6,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ diff --git a/engine/modules/base/blockpro.php b/engine/modules/base/blockpro.php index e092d66..db42196 100644 --- a/engine/modules/base/blockpro.php +++ b/engine/modules/base/blockpro.php @@ -6,15 +6,14 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ if (!defined('DATALIFEENGINE')) { - header( "HTTP/1.1 403 Forbidden" ); - header ( 'Location: ../../' ); - die( "Hacking attempt!" ); + header("HTTP/1.1 403 Forbidden"); + header('Location: ../../'); + die("Hacking attempt!"); } /** @@ -27,8 +26,8 @@ /** @var bool $showstat */ if ($showstat) { - $start = microtime(true); - $dbStat = ''; + $start = microtime(true); + $dbStat = ''; } /** * Конфиг модуля @@ -36,139 +35,13 @@ * @global array $isAjaxConfig */ if ($isAjaxConfig) { - /** @var array $ajaxConfigArr */ - $cfg = $ajaxConfigArr; + /** @var array $ajaxConfigArr */ + $cfg = $ajaxConfigArr; } else { - $cfg = [ - 'moderate' => !empty($moderate) ? $moderate : false, - // Показывать только новости на модерации - - 'template' => !empty($template) ? $template : 'blockpro/blockpro', - // Название шаблона (без расширения) - - 'cachePrefix' => !empty($cachePrefix) ? $cachePrefix : 'news', - // Префикс кеша - 'cacheSuffixOff' => !empty($cacheSuffixOff) ? true : false, - // Отключить суффикс кеша (будет создаваться один кеш-файл для всех пользователей). По умолчанию включен, т.е. для каждой группы пользователей будет создаваться свой кеш (на случай разного отображения контента разным юзерам). - - 'cacheNameAddon' => '', - // Назначаем дополнение к имени кеша, если имеются переменные со значениями this, они будут дописаны в имя кеша, иначе для разных мест будет создаваться один и тот же файл кеша - - 'nocache' => !empty($nocache) ? $nocache : false, - // Не использовать кеш - 'cacheLive' => (!empty($cacheLive) && !$mcache) ? $cacheLive : false, - // Время жизни кеша в минутах - - 'startFrom' => !empty($startFrom) ? $startFrom : '0', - // C какой новости начать вывод - 'limit' => !empty($limit) ? $limit : '10', - // Количество новостей в блоке - 'fixed' => !empty($fixed) ? $fixed : 'yes', - // Обработка фиксированных новостей (yes/only/without показ всех/только фиксированных/только обычных новостей) - 'allowMain' => !empty($allowMain) ? $allowMain : 'yes', - // Обработка новостей, опубликованных на главной (yes/only/without показ всех/только на главной/только не на главной) - 'postId' => !empty($postId) ? $postId : '', - // ID новостей для вывода в блоке (через запятую, или черточку) - 'notPostId' => !empty($notPostId) ? $notPostId : '', - // ID игнорируемых новостей (через запятую, или черточку) - - 'author' => !empty($author) ? $author : '', - // Логины авторов, для показа их новостей в блоке (через запятую) - 'notAuthor' => !empty($notAuthor) ? $notAuthor : '', - // Логины игнорируемых авторов (через запятую) - - 'xfilter' => !empty($xfilter) ? $xfilter : '', - // Имена дополнительных полей для фильтрации новостей по ним (через запятую) - 'notXfilter' => !empty($notXfilter) ? $notXfilter : '', - // Имена дополнительных полей для игнорирования показа новостей (через запятую) - - 'xfSearch' => !empty($xfSearch) ? $xfSearch : false, - // синтаксис передачи данных: &xfSearch=имя_поля|значение||имя_поля|значение - 'notXfSearch' => !empty($notXfSearch) ? $notXfSearch : false, - // синтаксис передачи данных: ¬XfSearch=имя_поля|значение||имя_поля|значение - 'xfSearchLogic' => !empty($xfSearchLogic) ? $xfSearchLogic : 'OR', - // Принимает OR или AND (по умолчанию OR) - - 'catId' => !empty($catId) ? $catId : '', - // Категории для показа (через запятую, или черточку) - 'subcats' => !empty($subcats) ? $subcats : false, - // Выводить подкатегории указанных категорий (&subcats=y), работает и с диапазонами. - 'notCatId' => !empty($notCatId) ? $notCatId : '', - // Игнорируемые категории (через запятую, или черточку) - 'notSubcats' => !empty($notSubcats) ? $notSubcats : false, - // Игнорировать подкатегории игнорируемых категорий (¬Subcats=y), работает и с диапазонами. - 'thisCatOnly' => !empty($thisCatOnly) ? $thisCatOnly : false, - // Показывать новости ТОЛЬКО из текущей категории (имеет смысл при выводе похожих новостей и использоваии мультикатегорий). - - 'tags' => !empty($tags) ? $tags : '', - // Теги из облака тегов для показа новостей, содержащих их (через запятую) - 'notTags' => !empty($notTags) ? $notTags : '', - // Игнорируемые теги (через запятую) - - 'day' => !empty($day) ? $day : false, - // Временной период для отбора новостей - 'dayCount' => !empty($dayCount) ? $dayCount : false, - // Интервал для отбора (т.е. к примеру выбираем новости за прошлую недею так: &day=14&dayCount=7 ) - 'sort' => !empty($sort) ? $sort : 'top', - // Сортировка (top, date, comms, rating, views, title, hit, random, randomLight, download, symbol, editdate или xf|xfieldname где xfieldname - имя дополнительного поля, field|p.name где p.name — кастомное поле) - 'xfSortType' => !empty($xfSortType) ? $xfSortType : 'int', - // Тип сортировки по допполю (string, int) - для корректной сортировки по строке используем string, по умолчанию сортируется как число (для цен полезно). - 'order' => !empty($order) ? $order : 'new', - // Направление сортировки (new, old, asis) - - 'avatar' => !empty($avatar) ? $avatar : false, - // Вывод аватарки пользователя (немного усложнит запрос). - - 'showstat' => !empty($showstat) ? $showstat : false, - // Показывать время и статистику по блоку - - 'related' => !empty($related) ? $related : false, - // Включить режим вывода похожих новостей (по умолчанию нет) - 'saveRelated' => !empty($saveRelated) ? $saveRelated : false, - // Включить запись похожих новостей в БД - 'showNav' => !empty($showNav) ? $showNav : false, - // Включить постраничную навигацию - 'navDefaultGet' => !empty($navDefaultGet) ? $navDefaultGet : false, - // Слушать дефолтный get-параметр постраничной навигации - 'pageNum' => !empty($pageNum) ? $pageNum : '1', - // Текущая страница при постраничной конфигурации - 'navStyle' => !empty($navStyle) ? $navStyle : 'classic', - // Стиль навигации. Возможны следующие стили: - /* - classic: << Первая < 1 [2] 3 > Последняя >> - digg: << Назад 1 2 ... 5 6 7 8 9 [10] 11 12 13 14 ... 25 26 Вперёд >> - extended: << Назад | Страница 2 из 11 | Показаны новости 6-10 из 52 | Вперёд >> - punbb: 1 ... 4 5 [6] 7 8 ... 15 - arrows: << Назад Вперёд >> - */ - /** - * @todo реализовать функционал с options и notOptions - */ - 'options' => !empty($options) ? $options : false, - // Опции, публикации новости для показа (Публиковать на главной, Разрешить рейтинг статьи, Разрешить комментарии, Запретить индексацию страницы для поисковиков, Зафиксировать новость) main|rating|comments|noindex - 'notOptions' => !empty($notOptions) ? $notOptions : false, - // Опции, публикации новости для исключения (Публиковать на главной, Разрешить рейтинг статьи, Разрешить комментарии, Запретить индексацию страницы для поисковиков, Зафиксировать новость) main|rating|comments|noindex - - 'future' => !empty($future) ? $future : false, - // Выводить только новости, дата публикации которых не наступила (Полезно для афиш) &future=y - 'cacheVars' => !empty($cacheVars) ? $cacheVars : false, - // Значимые переменные в формировании кеша блока на случай разного вывода в зависимости от условий расположения модуля. Сюда можно передавать ключи, доступные через $_REQUEST или значения переменной $dle_module - 'symbols' => !empty($symbols) ? $symbols : false, - // Символьные коды для фильтрации по символьному каталогу. Перечисляем через запятую. - 'notSymbols' => !empty($notSymbols) ? $notSymbols : false, - // Символьные коды для исключающей фильтрации по символьному каталогу. Перечисляем через запятую или пишем this для текущего символьного кода - 'fields' => !empty($fields) ? $fields : false, - // Дополнение к выборке полей из БД (p.field,e.field) - // setFilter=p.full_story|SEARCH|dle_media_begin|OR|p.full_story|SEARCH|dle_video_begin - // setFilter=e.news_read|+|100||p.comm_num|-|20 - 'setFilter' => !empty($setFilter) ? $setFilter : '', - // Собственная фильтрация полей БД - 'experiment' => !empty($experiment) ? $experiment : false, - // Включить экспериментальные функции - ]; + include ENGINE_DIR.'/modules/base/core/config.php'; } -include ENGINE_DIR . '/data/blockpro.php'; +include ENGINE_DIR.'/data/blockpro.php'; // Объединяем массивы конфигов /** @var array $bpConfig */ @@ -176,88 +49,132 @@ classic: << Первая < 1 [2] 3 > Последняя >> // Получаем id текущей категории при AJAX навигации if ($isAjaxConfig && ($cfg['catId'] == 'this' || $cfg['notCatId'] == 'this')) { - /** - * @var string $thisUrl - * @see engine/ajax/blockpro.php - */ - if (substr($thisUrl, -1, 1) == '/') { - $thisUrl = substr($thisUrl, 0, -1); - } - $arThisUrl = explode('/', $thisUrl); - $thisCatName = end($arThisUrl); - if (trim($thisCatName) != '') { - $category_id = get_ID($cat_info, $thisCatName); - } + /** + * @var string $thisUrl + * @see engine/ajax/blockpro.php + */ + if (substr($thisUrl, -1, 1) == '/') { + $thisUrl = substr($thisUrl, 0, -1); + } + $arThisUrl = explode('/', $thisUrl); + $thisCatName = end($arThisUrl); + if (trim($thisCatName) != '') { + $category_id = get_ID($cat_info, $thisCatName); + } } // Сохраняем текущее значение переменной, если она задана (fix #142) $startCacheNameAddon = $cfg['cacheNameAddon']; -$cfg['cacheNameAddon'] = []; +$cfg['cacheNameAddon'] = []; $cfg['cacheNameAddon'][] = $startCacheNameAddon; // Если имеются переменные со значениями this, изменяем значение переменной cacheNameAddon if ($cfg['catId'] == 'this') { - $cfg['cacheNameAddon'][] = $category_id . 'cId_'; + $cfg['cacheNameAddon'][] = $category_id.'cId_'; } if ($cfg['notCatId'] == 'this') { - $cfg['cacheNameAddon'][] = $category_id . 'nCId_'; + $cfg['cacheNameAddon'][] = $category_id.'nCId_'; } if ($cfg['postId'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['newsid'] . 'pId_'; + $cfg['cacheNameAddon'][] = $_REQUEST['newsid'].'pId_'; } if ($cfg['notPostId'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['newsid'] . 'nPId_'; + $cfg['cacheNameAddon'][] = $_REQUEST['newsid'].'nPId_'; } if ($cfg['author'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['user'] . 'a_'; + $cfg['cacheNameAddon'][] = $_REQUEST['user'].'a_'; } if ($cfg['notAuthor'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['user'] . 'nA_'; + $cfg['cacheNameAddon'][] = $_REQUEST['user'].'nA_'; } if ($cfg['tags'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['tag'] . 't_'; + $cfg['cacheNameAddon'][] = $_REQUEST['tag'].'t_'; } if ($cfg['notTags'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['tag'] . 'nT_'; + $cfg['cacheNameAddon'][] = $_REQUEST['tag'].'nT_'; } if ($cfg['symbols'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['catalog'] . 's_'; + $cfg['cacheNameAddon'][] = $_REQUEST['catalog'].'s_'; } if ($cfg['notSymbols'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['catalog'] . 'nS_'; + $cfg['cacheNameAddon'][] = $_REQUEST['catalog'].'nS_'; } if ($cfg['related'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['newsid'] . 'r_'; + $cfg['cacheNameAddon'][] = $_REQUEST['newsid'].'r_'; } if ($cfg['xfilter'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['xf'] . 'xf_'; + $cfg['cacheNameAddon'][] = $_REQUEST['xf'].'xf_'; } if ($cfg['notXfilter'] == 'this') { - $cfg['cacheNameAddon'][] = $_REQUEST['xf'] . 'nXf_'; + $cfg['cacheNameAddon'][] = $_REQUEST['xf'].'nXf_'; } if ($cfg['navDefaultGet']) { - $cfg['cacheNameAddon'][] = $_REQUEST['cstart'] . 'cs_'; + $cfg['cacheNameAddon'][] = $_REQUEST['cstart'].'cs_'; } if ($cfg['cacheVars']) { - // Если установлена переменная, добавим в имя кеша требуемые дополнения - // Убираем пробелы, на всякий пожарный - $cfg['cacheVars'] = str_replace(' ', '', $cfg['cacheVars']); - // Разбиваем строку на массив - $arCacheVars = explode(',', $cfg['cacheVars']); - foreach ($arCacheVars as $cacheVar) { - // Сверяем данные из массива с данными, доступными на странице - if (isset($_REQUEST[$cacheVar])) { - $cfg['cacheNameAddon'][] = $_REQUEST[$cacheVar] . $cacheVar . '_'; - } - if ($dle_module == $cacheVar) { - $cfg['cacheNameAddon'][] = $dle_module . '_'; - } - } + // Если установлена переменная, добавим в имя кеша требуемые дополнения + // Убираем пробелы, на всякий пожарный + $cfg['cacheVars'] = str_replace(' ', '', $cfg['cacheVars']); + // Разбиваем строку на массив + $arCacheVars = explode(',', $cfg['cacheVars']); + foreach ($arCacheVars as $cacheVar) { + // Сверяем данные из массива с данными, доступными на странице + if (isset($_REQUEST[$cacheVar])) { + $cfg['cacheNameAddon'][] = $_REQUEST[$cacheVar].$cacheVar.'_'; + } + if ($dle_module == $cacheVar) { + $cfg['cacheNameAddon'][] = $dle_module.'_'; + } + } + +} + +// Поддержка модуля multiLang +$multiLangEnabled = false; +// По умолчанию язык пустой +$langVariant = ''; +// Задаём пустой массив для конфига модуля MultiLanguage +$lang_config = []; +// Получаем список доступных языков в виде массива +$langList = explode('|', $cfg['langList']); +$multiLangAdditionalFields = $multiLangNewsFields = []; + +if ($cfg['multiLang'] && isset($_REQUEST['lang'])) { + $requestLang = trim($_REQUEST['lang']); + + // Если язык доступен, работаем + if (in_array($requestLang, $langList)) { + // Импортируем конфиг модуля MultiLanguage + include ENGINE_DIR.'/data/multilanguage_config.php'; + + // Если модуль включен, работаем + if ($lang_config['mod_on']) { + // Добавляем параметры в кеш + $cfg['cacheNameAddon'][] = 'multiLang_'.$_REQUEST['lang'].'_'; + // Устанавливаем нужный язык для дальнейшего использования в запросах + $langVariant = $requestLang; + $multiLangEnabled = true; + + $multiLangAdditionalFields = [ + '1' => 'p.title_'.$langVariant, + '2' => 'p.short_story_'.$langVariant, + '3' => 'p.full_story_'.$langVariant, + ]; + + $multiLangNewsFields = [ + '1' => [0 => 'title', 1 => 'title_'.$langVariant], + '2' => [0 => 'short_story', 1 => 'short_story_'.$langVariant], + '3' => [0 => 'full_story', 1 => 'full_story_'.$langVariant], + ]; + + $multiLngEnabledFields = explode(',', $lang_config['fields_news']); + } + } } $cfg['cacheNameAddon'] = array_filter($cfg['cacheNameAddon']); @@ -266,921 +183,985 @@ classic: << Первая < 1 [2] 3 > Последняя >> $cfg['cacheNameAddon'] = implode('_', $cfg['cacheNameAddon']); if ($cfg['cacheLive']) { - // Меняем префикс кеша для того, чтобы он не чистился автоматически, если указано время жизни кеша. - $cfg['cachePrefix'] = 'base'; + // Меняем префикс кеша для того, чтобы он не чистился автоматически, если указано время жизни кеша. + $cfg['cachePrefix'] = 'base'; } // Определяемся с шаблоном сайта // Проверим куку пользователя и наличие параметра skin в реквесте. -$currentSiteSkin = (isset($_COOKIE['dle_skin'])) ? trim(totranslit($_COOKIE['dle_skin'], false, false)) : ((isset($_REQUEST['skin'])) ? trim(totranslit($_REQUEST['skin'], false, false)) : $config['skin']); +$currentSiteSkin = (isset($_COOKIE['dle_skin'])) ? trim(totranslit($_COOKIE['dle_skin'], false, false)) + : ((isset($_REQUEST['skin'])) ? trim(totranslit($_REQUEST['skin'], false, false)) : $config['skin']); // Если итоге пусто — назначим опять шаблон из конфига. if ($currentSiteSkin == '') { - $currentSiteSkin = $config['skin']; + $currentSiteSkin = $config['skin']; } // Если парки с шаблоном нет — дальше не работаем. -if (!@is_dir(ROOT_DIR . '/templates/' . $currentSiteSkin)) { - die('no_skin'); +if (!@is_dir(ROOT_DIR.'/templates/'.$currentSiteSkin)) { + die('no_skin'); } // Формируем имя кеша -$cacheName = implode('_', $cfg) . $currentSiteSkin; +$cacheName = implode('_', $cfg).$currentSiteSkin; // Определяем необходимость создания кеша для разных групп $cacheSuffix = ($cfg['cacheSuffixOff']) ? false : true; $clear_time_cache = false; // Если установлено время жизни кеша if ($cfg['cacheLive']) { - // Формируем имя кеш-файла в соответствии с правилами формирования тагового стандартными средствами DLE, для последующей проверки на существование этого файла. - $_end_file = (!$cfg['cacheSuffixOff']) ? ($is_logged) ? '_' . $member_id['user_group'] : '_0' : false; - $filedate = ENGINE_DIR . '/cache/' . $cfg['cachePrefix'] . '_' . md5($cacheName) . $_end_file . '.tmp'; - - // Определяем в чём измеять время жизни кеша, в минутах или секундах - $cacheLiveTimer = (strpos($cfg['cacheLive'], 's')) ? (int)$cfg['cacheLive'] : $cfg['cacheLive'] * 60; - - if (@file_exists($filedate)) { - $cache_time = time() - @filemtime($filedate); - } else { - $cache_time = $cacheLiveTimer; - } - if ($cache_time >= $cacheLiveTimer) { - $clear_time_cache = true; - } + // Формируем имя кеш-файла в соответствии с правилами формирования такового стандартными средствами DLE, для последующей проверки на существование этого файла. + $_end_file = (!$cfg['cacheSuffixOff']) ? ($is_logged) ? '_'.$member_id['user_group'] : '_0' : false; + $filedate = ENGINE_DIR.'/cache/'.$cfg['cachePrefix'].'_'.md5($cacheName).$_end_file.'.tmp'; + + // Определяем в чём измеять время жизни кеша, в минутах или секундах + $cacheLiveTimer = (strpos($cfg['cacheLive'], 's')) ? (int)$cfg['cacheLive'] : $cfg['cacheLive'] * 60; + + if (@file_exists($filedate)) { + $cache_time = time() - @filemtime($filedate); + } else { + $cache_time = $cacheLiveTimer; + } + if ($cache_time >= $cacheLiveTimer) { + $clear_time_cache = true; + } } $output = false; // Массив для записи возникающих ошибок $outputLog = [ - 'errors' => [], - 'info' => [] + 'errors' => [], + 'info' => [], ]; // Если nocache не установлен - пытаемся вывести данные из кеша. if (!$cfg['nocache']) { - $output = dle_cache($cfg['cachePrefix'], $cacheName, $cacheSuffix); + $output = dle_cache($cfg['cachePrefix'], $cacheName, $cacheSuffix); } // Сбрасываем данные, если истекло время жизни кеша if ($clear_time_cache) { - $output = false; + $output = false; } if (!$output) { - // Подключаем всё необходимое - include_once 'core/base.php'; + // Подключаем всё необходимое + include_once 'core/base.php'; - // Вызываем ядро - $base = new base(); + // Вызываем ядро + $base = new base(); - // Назначаем конфиг модуля - $base->cfg = $base->setConfig($cfg); + // Назначаем конфиг модуля + $base->cfg = $base->setConfig($cfg); - // Назначаем текущий шаблон сайта - $base->dle_config['skin'] = $currentSiteSkin; + // Назначаем текущий шаблон сайта + $base->dle_config['skin'] = $currentSiteSkin; - // Пустой массив для конфга шаблонизатора. - $tplOptions = []; + // Пустой массив для конфга шаблонизатора. + $tplOptions = []; - // Если кеширование блока отключено - будем автоматически проверять скомпилированный шаблон на изменения. - if ($base->cfg['nocache']) { - $tplOptions['auto_reload'] = true; - } + // Если кеширование блока отключено - будем автоматически проверять скомпилированный шаблон на изменения. + if ($base->cfg['nocache']) { + $tplOptions['auto_reload'] = true; + } - // Подключаем опции шаблонизатора - $base->tplOptions = $base->setConfig($tplOptions); - // Подключаем шаблонизатор - $base->getTemplater($base->tplOptions); + // Подключаем опции шаблонизатора + $base->tplOptions = $base->setConfig($tplOptions); + // Подключаем шаблонизатор + $base->getTemplater($base->tplOptions); - // Добавляем глобавльный тег $.blockPro - $base->tpl->addAccessorSmart('blockPro', 'block_pro', Fenom::ACCESSOR_PROPERTY); - $base->tpl->block_pro = $base; + // Добавляем глобавльный тег $.blockPro + $base->tpl->addAccessorSmart('blockPro', 'block_pro', Fenom::ACCESSOR_PROPERTY); + $base->tpl->block_pro = $base; - // Определяем начало сегодняшнего дня и дату "прямо вот сейчас". - if ($base->dle_config['version_id'] > 10.2) { - date_default_timezone_set($base->dle_config['date_adjust']); - $today = date('Y-m-d H:i:s', (mktime(0, 0, 0) + 86400)); - $rightNow = date('Y-m-d H:i:s', time()); - } else { - $today = date('Y-m-d H:i:s', (mktime(0, 0, 0) + 86400 + $base->dle_config['date_adjust'] * 60)); - $rightNow = date('Y-m-d H:i:s', (time() + $base->dle_config['date_adjust'] * 60)); - } - - if ($base->cfg['navDefaultGet']) { - $base->cfg['pageNum'] = (isset($_GET['cstart']) && (int)$_GET['cstart'] > 0) ? (int)$_GET['cstart'] : 1; - } - - // Массив с условиями запроса - $wheres = []; - - // По умолчанию имеем пустые дополнения в запрос. - $ext_query_fields = $ext_query = ''; - - // По умолчанию группировки нет (она нам понадобится при фильтрации по аттачментам). - $groupBy = ''; - - // Условие для отображения только постов, прошедших модерацию или находящихся на модерации - $wheres[] = ($base->cfg['moderate']) ? 'approve = 0' : 'approve'; - - // Добавляем пользовательскую фильтрацию - if ($base->cfg['setFilter'] != '') { - - $arFilter = []; - - if (strpos($base->cfg['setFilter'], '||')) { - $arFilter = explode('||', $base->cfg['setFilter']); - } else { - $arFilter[] = $base->cfg['setFilter']; - } - - - if (!empty($arFilter)) { - foreach ($arFilter as $strItem) { - $queryItem = $base->prepareFilterQuery($strItem); - - if($queryItem) { - $wheres[] = $queryItem; - } - - } - } - } - - // Определяем в какую сторону направлена сортировка - $ordering = ($base->cfg['order'] == 'new') ? 'DESC' : 'ASC'; - - // Если без сортировки - сбрасываем направление - if ($base->cfg['sort'] == 'none') { - $ordering = false; - } - // Массив, куда будем записывать сортировки - $orderArr = []; - - // Учёт фиксированных новостей - switch ($base->cfg['fixed']) { - case 'only': - $wheres[] = 'fixed = 1'; - break; - - case 'without': - $wheres[] = 'fixed = 0'; - break; - - case 'ignore': - $wheres[] = ''; - break; - - default: - // Если включен режим афиши и установлена сортировка по убыванию даты, фиксированные новости должны отображаться в начале списка. - $fixedNewsOrdering = ($base->cfg['future'] && $base->cfg['sort'] != 'new') ? 'DESC' : $ordering; - - if ($base->cfg['sort'] != 'random' && $base->cfg['sort'] != 'randomLight' && $base->cfg['sort'] != 'none' && $base->cfg['sort'] != 'editdate') { - $orderArr[] = 'fixed ' . $fixedNewsOrdering; - } - break; - } - - // Учёт новостей на главной - switch ($base->cfg['allowMain']) { - case 'only': - $wheres[] = 'allow_main = 1'; - break; - - case 'without': - $wheres[] = 'allow_main = 0'; - break; - - default: - // по умолчанию показываем все - break; - } - // Зададим произвольное имя для несуществующей сортировки - $xfSortName = 'blockpro_undefined_sort_xfields'; - if (strpos($base->cfg['sort'], 'xf|') !== false) { - // Если задана сортировка по значению допполя - то присвоим переменной имя этого поля и подкорректируем данные для swich - $xfSortName = str_replace('xf|', '', $base->cfg['sort']); - } - - $fieldSortName = 'blockpro_undefined_sort_field'; - - if (strpos($base->cfg['sort'], 'field|') !== false) { - // Если задана сортировка по кастомном полю - то присвоим переменной имя этого поля и подкорректируем данные для swich - $fieldSortName = str_replace('field|', '', $base->cfg['sort']); - } - - // Определяем тип сортировки - switch ($base->cfg['sort']) { - case 'none': // Не сортировать (можно использовать для вывода похожих новостей, аналогично стандарту DLE) - // $orderArr[] = false; - break; - - case 'date': // Дата - $orderArr[] = 'p.date ' . $ordering; - break; - - case 'rating': // Рейтинг - $orderArr[] = 'e.rating ' . $ordering; - break; - - case 'comms': // Комментарии - $orderArr[] = 'p.comm_num ' . $ordering; - break; - - case 'views': // Просмотры - $orderArr[] = 'e.news_read ' . $ordering; - break; - - case 'random': // Случайные - $orderArr[] = 'RAND()'; - // randomLight ниже т.к. у него отдельный алгоритм - break; - - case 'title': // По алфавиту - $orderArr[] = 'p.title ' . $ordering; - break; - - case 'download': // По количеству скачиваний - $orderArr[] = 'dcount ' . $ordering; - break; - - case 'symbol': // По символьному коду - $orderArr[] = 'p.symbol ' . $ordering; - break; - - case 'hit': // Правильный топ - $wheres[] = 'e.rating > 0'; - $orderArr[] = '(e.rating*100+p.comm_num*10+e.news_read) ' . $ordering; - break; - - case 'top': // Топ как в DLE (сортировка по умолчанию) - $orderArr[] = 'e.rating ' . $ordering . ', p.comm_num ' . $ordering . ', e.news_read ' . $ordering; - break; - - case 'editdate': // По дате редактрования - $orderArr[] = 'e.editdate ' . $ordering; - $wheres[] = 'e.editdate > 0'; - break; - - case 'xf|' . $xfSortName: // Сортировка по значению дополнительного поля - if ($base->cfg['xfSortType'] == 'string') { - $orderArr[] = 'sort_xfield ' . $ordering; - } else { - $orderArr[] = 'CAST(sort_xfield AS DECIMAL(12,2)) ' . $ordering; - } - $ext_query_fields .= ", SUBSTRING_INDEX(SUBSTRING_INDEX(p.xfields, '{$xfSortName}|', -1 ) , '||', 1 ) as sort_xfield "; - break; - - case 'field|' . $fieldSortName: // Сортировка по кастомному полю - $orderArr[] = $fieldSortName . ' ' . $ordering; - break; - - } - - // Необходимо учитывать категорию для вывода похожих новостей, если категорию не задал пользователь. - // https://github.com/dle-modules/DLE-BlockPro/issues/155 - if (!$base->cfg['catId'] && $base->cfg['related'] && $base->dle_config['related_only_cats']) { - $base->cfg['catId'] = 'this'; - } - - // Эти переменные потребуются ниже, что бы корректно сформировать имя кеша, когда переданы - // &catId=this или notCatId=this - $isCatIdThis = false; - $isNotCatIdThis = false; - - // Фильтрация КАТЕГОРИЙ по их ID - if ($base->cfg['catId'] == 'this' && $category_id) { - $isCatIdThis = true; - /** - * @see https://github.com/dle-modules/DLE-BlockPro/issues/159 - */ - $base->cfg['catId'] = $category_id; - if($base->cfg['subcats']) { - $base->cfg['catId'] = get_sub_cats($category_id); - } elseif ($base->cfg['thisCatOnly']) { - $base->cfg['catId'] = (int)$category_id; - } - } - if ($base->cfg['notCatId'] == 'this' && $category_id) { - $isNotCatIdThis = true; - /** - * @see https://github.com/dle-modules/DLE-BlockPro/issues/159 - */ - $base->cfg['notCatId'] = $category_id; - if ($base->cfg['notSubcats']) { - $base->cfg['notCatId'] = get_sub_cats($category_id); - } elseif($base->cfg['thisCatOnly']) { - $base->cfg['notCatId'] = (int)$category_id; - } - } - // Дублирование кода вызвано необходимостью сочетания параметра notCatId и catId - // Например: catId=this¬CatId=3 - if ($base->cfg['notCatId']) { - $notCatArr = $base->getDiapazone($base->cfg['notCatId'], $base->cfg['notSubcats']); - if ($notCatArr[0] > 0) { - if ($base->dle_config['allow_multi_category'] && !$base->cfg['thisCatOnly']) { - $notCatQPart = 'category regexp "[[:<:]](' . str_replace(',', '|', $notCatArr) . ')[[:>:]]"'; - } else { - $notCatQPart = 'category IN (\'' . str_replace(',', "','", $notCatArr) . '\')'; - } - - $wheres[] = 'NOT ' . $notCatQPart; - } - } - - if ($base->cfg['catId']) { - $catArr = $base->getDiapazone($base->cfg['catId'], $base->cfg['subcats']); - if ($catArr[0] > 0) { - if ($base->dle_config['allow_multi_category'] && !$base->cfg['thisCatOnly']) { - $catQPart = 'category regexp "[[:<:]](' . str_replace(',', '|', $catArr) . ')[[:>:]]"'; - } else { - $catQPart = 'category IN (\'' . str_replace(',', "','", $catArr) . '\')'; - } - - $wheres[] = $catQPart; - } - } - - // Фильтрация НОВОСТЕЙ по их ID - if ($base->cfg['postId'] == 'this' && $_REQUEST['newsid']) { - $base->cfg['postId'] = $_REQUEST['newsid']; - } - if ($base->cfg['notPostId'] == 'this' && $_REQUEST['newsid']) { - $base->cfg['notPostId'] = $_REQUEST['newsid']; - } - - if ($base->cfg['notPostId']) { - $notPostsArr = $base->getDiapazone($base->cfg['notPostId']); - if ($notPostsArr !== '0') { - $wheres[] = 'id NOT IN (' . $notPostsArr . ')'; - } - } - - if ($base->cfg['postId'] && $base->cfg['related'] == '') { - $postsArr = $base->getDiapazone($base->cfg['postId']); - if ($postsArr !== '0') { - $wheres[] = 'id IN (' . $postsArr . ')'; - } - } - - // Фильтрация новостей по АВТОРАМ - if ($base->cfg['author'] == 'this' && isset($_REQUEST['user'])) { - $base->cfg['author'] = $_REQUEST['user']; - } - if ($base->cfg['notAuthor'] == 'this' && isset($_REQUEST['user'])) { - $base->cfg['notAuthor'] = $_REQUEST['user']; - } - if ($base->cfg['author'] || $base->cfg['notAuthor']) { - $ignoreAuthors = ($base->cfg['notAuthor']) ? 'NOT ' : ''; - $authorsArr = ($base->cfg['notAuthor']) ? $base->cfg['notAuthor'] : $base->cfg['author']; - if ($authorsArr !== 'this') { - // Если в строке подключения &author=this и мы просматриваем страницу юзера, то сюда уже попадёт логин пользователя - $authorsArr = explode(',', $authorsArr); - $wheres[] = (count($authorsArr) === 1) ? $ignoreAuthors . 'autor = ' . $base->db->parse('?s', $authorsArr[0]) : $ignoreAuthors . 'autor regexp "[[:<:]](' . implode('|', $authorsArr) . ')[[:>:]]"'; - } - } - - // Фильтрация новостей по ДОПОЛНИТЕЛЬНЫМ ПОЛЯМ (проверяется только на заполненность) - $_currentXfield = false; - if ($base->cfg['xfilter'] == 'this' && isset($_REQUEST['xf'])) { - $base->cfg['xfilter'] = $base->db->parse('?s', '%' . $_REQUEST['xf'] . '%'); - $_currentXfield = true; - } - if ($base->cfg['notXfilter'] == 'this' && isset($_REQUEST['xf'])) { - $base->cfg['notXfilter'] = $base->db->parse('?s', '%' . $_REQUEST['xf'] . '%'); - $_currentXfield = true; - } - - if ($base->cfg['xfilter'] || $base->cfg['notXfilter']) { - $ignoreXfilters = ($base->cfg['notXfilter']) ? 'NOT ' : ''; - $xfiltersArr = ($base->cfg['notXfilter']) ? $base->cfg['notXfilter'] : $base->cfg['xfilter']; - - if ($xfiltersArr !== 'this') { - // Если в строке подключения &xfilter=this и мы просматриваем страницу допполя, то сюда уже попадёт имя этого поля - $wheres[] = ($_currentXfield) ? $ignoreXfilters . 'xfields LIKE ' . $xfiltersArr : $ignoreXfilters . 'p.xfields regexp "[[:<:]](' . str_replace(',', '|', $xfiltersArr) . ')[[:>:]]"'; - } - } - - // Фильтрация по ЗНАЧЕНИЮ ДОПОЛНИТЕЛЬНЫХ ПОЛЕЙ - if ($base->cfg['xfSearch'] || $base->cfg['notXfSearch']) { - - // Массив для составления подзапроса - $xfWheres = []; - - // Защита логики построения запроса от кривых рук (если прописать неправильно - будет логика OR) - $_xfSearchLogic = (strtolower($base->cfg['xfSearchLogic']) == 'and') ? ' AND ' : ' OR '; - - // Определяем масивы с данными по фильтрации - $xfSearchArray = ($base->cfg['xfSearch']) ? explode('||', $base->cfg['xfSearch']) : []; - $notXfSearchArray = ($base->cfg['notXfSearch']) ? explode('||', $base->cfg['notXfSearch']) : []; - - $bXfNotResult = true; - if ($base->dle_config['version_id'] >= '11' && $base->cfg['experiment']) { - // Если версия DLE 11 и более и включена экспериментальная функция, то для увеличения скорости выборки запросим данные по допполям из отдельной таблицы. - - // Пробегаем по сформированным массивам - foreach ($xfSearchArray as $xf) { - $_xf = explode('|', $xf); - $xfWheres[] = $base->db->parse('(tagname=?s AND tagvalue=?s)', $_xf[0], $_xf[1]); - } - foreach ($notXfSearchArray as $xf) { - $_xf = explode('|', $xf); - $xfWheres[] = $base->db->parse('(tagname=?s AND NOT tagvalue=?s)', $_xf[0], $_xf[1]); - } - // Подготавливаем запрос. - $xfSearchQuery = implode($_xfSearchLogic, $xfWheres); - - // Получаем ID новостей - $xfSearchIDs = $base->db->getCol('SELECT news_id FROM ?n WHERE ?p', PREFIX . '_xfsearch', $xfSearchQuery); - // Если запрос вернул ID новостей — работаем. - if (count($xfSearchIDs)) { - // Оставляем только уникальные - $xfSearchIDs = array_unique($xfSearchIDs); - - // Добавляем полученные данные в основной массив, формирующий запрос - $wheres[] = 'p.id IN (' . implode(',', $xfSearchIDs) . ')'; - - $bXfNotResult = false; - } else { - // Если ничего не найдено — сбросим массив с условиями т.к. строка подключения возможно содержит дополнительные условия выборки. - $xfWheres = []; - } - } - - if ($bXfNotResult) { - // Пробегаем по сформированным массивам - // str_replace('|', '|%', $xf) необходимо для случаев, когда значение допполя идёт не первым в списке - foreach ($xfSearchArray as $xf) { - $xfWheres[] = $base->db->parse('p.xfields LIKE ?s', '%' . str_replace('|', '|%', $xf) . '%'); - } - foreach ($notXfSearchArray as $xf) { - $xfWheres[] = $base->db->parse('p.xfields NOT LIKE ?s', '%' . str_replace('|', '|%', $xf) . '%'); - } - - // Добавляем полученные данные (и логику) в основной массив, формирующий запрос - $wheres[] = '(' . implode($_xfSearchLogic, $xfWheres) . ')'; - } - } - - // Фильтрация новостей по ТЕГАМ - $_currentTag = false; - if ($base->cfg['tags'] == 'this' && isset($_REQUEST['tag']) && $_REQUEST['tag'] != '') { - $base->cfg['tags'] = $base->db->parse('?s', $_REQUEST['tag']); - $_currentTag = true; - } - if ($base->cfg['notTags'] == 'this' && isset($_REQUEST['tag']) && $_REQUEST['tag'] != '') { - $base->cfg['notTags'] = $base->db->parse('?s', $_REQUEST['tag']); - $_currentTag = true; - } - - // Фильтрация новостей по тегам текущей новости, когда в строке подключения прописано &tags=thisNewsTags и мы просматриваем полную новость - if ((int)$_REQUEST['newsid'] > 0) { - if ($base->cfg['tags'] == 'thisNewsTags' || $base->cfg['notTags'] == 'thisNewsTags') { - $curTagNewsId = $base->db->getRow('SELECT tags FROM ?n WHERE id=?i', PREFIX . '_post', $_REQUEST['newsid']); - if (!empty($curTagNewsId['tags'])) { - if ($base->cfg['tags'] == 'thisNewsTags') { - // Заменяем запятую и пробел на просто запятую, иначе будет ошибка. - $base->cfg['tags'] = str_replace(', ', ',', $curTagNewsId['tags']); - } - if ($base->cfg['notTags'] == 'thisNewsTags') { - // Заменяем запятую и пробел на просто запятую, иначе будет ошибка. - $base->cfg['notTags'] = str_replace(', ', ',', $curTagNewsId['notTags']); - } - } - } - } - - if ($base->cfg['tags'] || $base->cfg['notTags']) { - $ignoreTags = ($base->cfg['notTags']) ? 'NOT ' : ''; - $tagsArr = ($base->cfg['notTags']) ? $base->cfg['notTags'] : $base->cfg['tags']; - - - if ($tagsArr !== 'this') { - // Если в строке подключения &tags=this и мы просматриваем страницу тегов, то сюда уже попадёт название тега - $wherTag = ($_currentTag) ? $ignoreTags . 'tag = ' . $tagsArr : $ignoreTags . 'tag regexp "[[:<:]](' . str_replace(',', '|', $tagsArr) . ')[[:>:]]"'; - // Делаем запрос на получение ID новостей, содержащих требуемые теги - $tagNews = $base->db->getCol('SELECT news_id FROM ?n WHERE ?p', PREFIX . '_tags', $wherTag); - $tagNews = array_unique($tagNews); - - if (count($tagNews)) { - $wheres[] = 'id ' . $ignoreTags . ' IN (' . implode(',', $tagNews) . ')'; - } - - } - } - - // Фильтрация новостей по символьным кодам - $_currentSymbol = false; - if ($base->cfg['symbols'] == 'this' && isset($_REQUEST['catalog'])) { - $base->cfg['symbols'] = $base->db->parse('?s', $_REQUEST['catalog']); - $_currentSymbol = true; - } - if ($base->cfg['notSymbols'] == 'this' && isset($_REQUEST['catalog'])) { - $base->cfg['notSymbols'] = $base->db->parse('?s', $_REQUEST['catalog']); - $_currentSymbol = true; - } - - if ($base->cfg['symbols'] || $base->cfg['notSymbols']) { - $ignoreSymbols = ($base->cfg['notSymbols']) ? 'NOT ' : ''; - $symbolsArr = ($base->cfg['notSymbols']) ? $base->cfg['notSymbols'] : $base->cfg['symbols']; - if ($symbolsArr !== 'this') { - // Если в строке подключения &symbols=this и мы просматриваем страницу буквенного каталога, то сюда уже попадёт название буквы - $wheres[] = ($_currentSymbol) ? $ignoreSymbols . 'symbol = ' . $symbolsArr : $ignoreSymbols . 'symbol regexp "[[:<:]](' . str_replace(',', '|', $symbolsArr) . ')[[:>:]]"'; - } - } - - // Если включен режим вывода похожих новостей: - $reltedFirstShow = false; - if ($base->cfg['related']) { - if ($base->cfg['related'] == 'this' && $_REQUEST['newsid'] == '') { - $outputLog['errors'][] = 'Переменная related=this работает только в полной новости и не работает с ЧПУ 3 типа.'; - } else { - - $relatedId = ($base->cfg['related'] == 'this') ? $_REQUEST['newsid'] : $base->cfg['related']; - $relatedRows = 'p.title, p.short_story, p.full_story, p.xfields'; - $relatedIdParsed = $base->db->parse('id = ?i', $relatedId); - - $relatedBody = $base->db->getRow('SELECT id, ?p FROM ?n p LEFT JOIN ?n e ON (p.id=e.news_id) WHERE ?p', 'p.title, p.short_story, p.full_story, p.xfields, e.related_ids', PREFIX . '_post', PREFIX . '_post_extras', $relatedIdParsed); - // Фикс https://github.com/dle-modules/DLE-BlockPro/issues/78 - if ($relatedBody['id']) { - /** @var bool $saveRelated */ - if ($relatedBody['related_ids'] && $saveRelated) { - // Если есть запись id похожих новостей — добавим в условие запроса эти новости. - $wheres[] = 'id IN(' . $relatedBody['related_ids'] . ')'; - // Отсортируем новости в том порядке, в котором они записаны в БД - $orderArr = ['FIELD (p.id, ' . $relatedBody['related_ids'] . ')']; - } else { - // Если похожие новости не записывались — отберём их. - $reltedFirstShow = true; - $bodyToRelated = (dle_strlen($relatedBody['full_story'], $base->dle_config['charset']) < dle_strlen($relatedBody['short_story'], $base->dle_config['charset'])) ? $relatedBody['short_story'] : $relatedBody['full_story']; - - $bodyToRelated = strip_tags(stripslashes($relatedBody['title'] . ' ' . $bodyToRelated)); - - // Фикс для https://github.com/pafnuty/BlockPro/issues/79 - // @see /engine/modules/show.full.php - if (dle_strlen($bodyToRelated, $base->dle_config['charset']) > 1000) { - $bodyToRelated = dle_substr($bodyToRelated, 0, 1000, $base->dle_config['charset']); - } - - $bodyToRelated = $base->db->parse('?s', $bodyToRelated); - - // Добавляем улучшенный алгоритм поиска похожих новостей из DLE 13 - $ext_query_fields .= ', MATCH (p.title, p.short_story, p.full_story, p.xfields) AGAINST (' . $bodyToRelated . ') as score'; - $orderArr = ['score DESC']; - - // Формируем условие выборки - $wheres[] = 'MATCH (' . $relatedRows . ') AGAINST (' . $bodyToRelated . ') AND id !=' . $relatedBody['id']; - } - } else { - $outputLog['errors'][] = 'Новость с ID ' . $relatedIdParsed . ' не найдена в базе данных.'; - } - } - - - } - - // Определяем переменные, чтоб сто раз не писать одно и тоже - $bDay = (int)$base->cfg['day']; - $bDayCount = (int)$base->cfg['dayCount']; - - // Если в bDay и bDayCount передано '-1', значит требуется вывести новости только за сегодня. - // Это обработка случая, когда включен вывод новостей на ненаступившую дату и надо вывести за сегодня - // https://pafnuty.omnidesk.ru/staff/cases/record/181-466935/ - if ($bDay === -1 && $bDayCount === -1) { - // Формируем вывод новостей только за сегодня - $wheres[] = 'p.date >= "' . $today . '" - INTERVAL 1 DAY'; - $wheres[] = 'p.date < "' . $today . '"'; - } else { - // Если future задан, то интервал не вычитаем, а прибавляем к текущему началу дня - $intervalOperator = ($base->cfg['future']) ? ' + ' : ' - '; - - // Если режим афиши включен - выводим новости, дата которых ещё не наступила. - if ($base->cfg['future'] && (!$bDay && !$bDayCount)) { - $wheres[] = 'p.date > "' . $rightNow . '"'; - } - - // Если включен вывод новостей на ненаступившую дату в настройках DLE - // и режим афиши не используется, то нельзя выводить новости дата которых не наступила до текущей секунды - if (!$base->cfg['future'] && ($base->dle_config['news_future'] && $base->dle_config['news_future'] !== 'no')) { - $wheres[] = 'p.date <= "' . $rightNow . '"'; - } - - // Разбираемся с временными рамками отбора новостей, если кол-во дней указано - ограничиваем выборку, если нет - выводим без ограничения даты - if ($bDay) { - $wheres[] = 'p.date >= "' . $today . '" ' . $intervalOperator . ' INTERVAL ' . (($base->cfg['future']) ? ($bDay - $bDayCount) : $bDay) . ' DAY'; - } - // Если задана переменная dayCount и day, а так же day больше dayCount - отбираем новости за указанный интервал от указанного периода - if ($bDay && $bDayCount && ($bDayCount <= $bDay)) { - $wheres[] = 'p.date < "' . $today . '" ' . $intervalOperator . ' INTERVAL ' . (($base->cfg['future']) ? $bDay : ($bDay - $bDayCount)) . ' DAY'; - } else { - // Условие для отображения только тех постов, дата публикации которых уже наступила - $wheres[] = ($base->dle_config['no_date'] && !$base->dle_config['news_future'] && !$base->cfg['future']) ? 'p.date < "' . $rightNow . '"' : ''; - } - - } - - // Подчистим массив от пустых значений - $wheres = array_filter($wheres); - - // Когда выбран вариант вывода случайных новостей (Лёгкий режим) - if ($base->cfg['sort'] == 'randomLight') { - - // Складываем условия выборки для рандомных новостей - $randWhere = (count($wheres)) ? ' WHERE ' . implode(' AND ', $wheres) : ''; - // Получим массив с id новостей - $randDiapazone = $base->db->getCol('SELECT id FROM ?n AS p ?p', PREFIX . '_post', $randWhere); - // Перемешаем - shuffle($randDiapazone); - // Возьмём только нужное количество элементов - $randIds = array_slice($randDiapazone, 0, $base->cfg['limit']); + // Определяем начало сегодняшнего дня и дату "прямо вот сейчас". + if ($base->dle_config['version_id'] > 10.2) { + date_default_timezone_set($base->dle_config['date_adjust']); + $today = date('Y-m-d H:i:s', (mktime(0, 0, 0) + 86400)); + $rightNow = date('Y-m-d H:i:s', time()); + } else { + $today = date('Y-m-d H:i:s', (mktime(0, 0, 0) + 86400 + $base->dle_config['date_adjust'] * 60)); + $rightNow = date('Y-m-d H:i:s', (time() + $base->dle_config['date_adjust'] * 60)); + } + + if ($base->cfg['navDefaultGet']) { + $base->cfg['pageNum'] = (isset($_GET['cstart']) && (int)$_GET['cstart'] > 0) ? (int)$_GET['cstart'] : 1; + } + + // Массив с условиями запроса + $wheres = []; + + // По умолчанию имеем пустые дополнения в запрос. + $ext_query_fields = $ext_query = ''; + + // По умолчанию группировки нет (она нам понадобится при фильтрации по аттачментам). + $groupBy = ''; + + // Условие для отображения только постов, прошедших модерацию или находящихся на модерации + $wheres[] = ($base->cfg['moderate']) ? 'approve = 0' : 'approve'; + + // Добавляем пользовательскую фильтрацию + if ($base->cfg['setFilter'] != '') { + + $arFilter = []; + + if (strpos($base->cfg['setFilter'], '||')) { + $arFilter = explode('||', $base->cfg['setFilter']); + } else { + $arFilter[] = $base->cfg['setFilter']; + } + + + if (!empty($arFilter)) { + foreach ($arFilter as $strItem) { + $queryItem = $base->prepareFilterQuery($strItem); + + if ($queryItem) { + $wheres[] = $queryItem; + } + + } + } + } + + // Определяем в какую сторону направлена сортировка + $ordering = ($base->cfg['order'] == 'new') ? 'DESC' : 'ASC'; + + // Если без сортировки - сбрасываем направление + if ($base->cfg['sort'] == 'none') { + $ordering = false; + } + // Массив, куда будем записывать сортировки + $orderArr = []; + + // Учёт фиксированных новостей + switch ($base->cfg['fixed']) { + case 'only': + $wheres[] = 'fixed = 1'; + break; + + case 'without': + $wheres[] = 'fixed = 0'; + break; + + case 'ignore': + $wheres[] = ''; + break; + + default: + // Если включен режим афиши и установлена сортировка по убыванию даты, фиксированные новости должны отображаться в начале списка. + $fixedNewsOrdering = ($base->cfg['future'] && $base->cfg['sort'] != 'new') ? 'DESC' : $ordering; + + if ($base->cfg['sort'] != 'random' && $base->cfg['sort'] != 'randomLight' && $base->cfg['sort'] != 'none' + && $base->cfg['sort'] != 'editdate' + ) { + $orderArr[] = 'fixed '.$fixedNewsOrdering; + } + break; + } + + // Учёт новостей на главной + switch ($base->cfg['allowMain']) { + case 'only': + $wheres[] = 'allow_main = 1'; + break; + + case 'without': + $wheres[] = 'allow_main = 0'; + break; + + default: + // по умолчанию показываем все + break; + } + // Зададим произвольное имя для несуществующей сортировки + $xfSortName = 'blockpro_undefined_sort_xfields'; + if (strpos($base->cfg['sort'], 'xf|') !== false) { + // Если задана сортировка по значению допполя - то присвоим переменной имя этого поля и подкорректируем данные для swich + $xfSortName = str_replace('xf|', '', $base->cfg['sort']); + } + + $fieldSortName = 'blockpro_undefined_sort_field'; + + if (strpos($base->cfg['sort'], 'field|') !== false) { + // Если задана сортировка по кастомном полю - то присвоим переменной имя этого поля и подкорректируем данные для swich + $fieldSortName = str_replace('field|', '', $base->cfg['sort']); + } + + // Определяем тип сортировки + switch ($base->cfg['sort']) { + case 'none': // Не сортировать (можно использовать для вывода похожих новостей, аналогично стандарту DLE) + // $orderArr[] = false; + break; + + case 'date': // Дата + $orderArr[] = 'p.date '.$ordering; + break; + + case 'rating': // Рейтинг + $orderArr[] = 'e.rating '.$ordering; + break; + + case 'comms': // Комментарии + $orderArr[] = 'p.comm_num '.$ordering; + break; + + case 'views': // Просмотры + $orderArr[] = 'e.news_read '.$ordering; + break; + + case 'random': // Случайные + $orderArr[] = 'RAND()'; + // randomLight ниже т.к. у него отдельный алгоритм + break; + + case 'title': // По алфавиту + $orderArr[] = 'p.title '.$ordering; + break; + + case 'download': // По количеству скачиваний + $orderArr[] = 'dcount '.$ordering; + break; + + case 'symbol': // По символьному коду + $orderArr[] = 'p.symbol '.$ordering; + break; + + case 'hit': // Правильный топ + $wheres[] = 'e.rating > 0'; + $orderArr[] = '(e.rating*100+p.comm_num*10+e.news_read) '.$ordering; + break; + + case 'top': // Топ как в DLE (сортировка по умолчанию) + $orderArr[] = 'e.rating '.$ordering.', p.comm_num '.$ordering.', e.news_read '.$ordering; + break; + + case 'editdate': // По дате редактрования + $orderArr[] = 'e.editdate '.$ordering; + $wheres[] = 'e.editdate > 0'; + break; + + case 'xf|'.$xfSortName: // Сортировка по значению дополнительного поля + if ($base->cfg['xfSortType'] == 'string') { + $orderArr[] = 'sort_xfield '.$ordering; + } else { + $orderArr[] = 'CAST(sort_xfield AS DECIMAL(12,2)) '.$ordering; + } + $ext_query_fields .= ", SUBSTRING_INDEX(SUBSTRING_INDEX(p.xfields, '{$xfSortName}|', -1 ) , '||', 1 ) as sort_xfield "; + break; + + case 'field|'.$fieldSortName: // Сортировка по кастомному полю + $orderArr[] = $fieldSortName.' '.$ordering; + break; + + } + + // Необходимо учитывать категорию для вывода похожих новостей, если категорию не задал пользователь. + // https://github.com/dle-modules/DLE-BlockPro/issues/155 + if (!$base->cfg['catId'] && $base->cfg['related'] && $base->dle_config['related_only_cats']) { + $base->cfg['catId'] = 'this'; + } + + // Эти переменные потребуются ниже, что бы корректно сформировать имя кеша, когда переданы + // &catId=this или notCatId=this + $isCatIdThis = false; + $isNotCatIdThis = false; + + // Фильтрация КАТЕГОРИЙ по их ID + if ($base->cfg['catId'] == 'this' && $category_id) { + $isCatIdThis = true; + /** + * @see https://github.com/dle-modules/DLE-BlockPro/issues/159 + */ + $base->cfg['catId'] = $category_id; + if ($base->cfg['subcats']) { + $base->cfg['catId'] = get_sub_cats($category_id); + } elseif ($base->cfg['thisCatOnly']) { + $base->cfg['catId'] = (int)$category_id; + } + } + if ($base->cfg['notCatId'] == 'this' && $category_id) { + $isNotCatIdThis = true; + /** + * @see https://github.com/dle-modules/DLE-BlockPro/issues/159 + */ + $base->cfg['notCatId'] = $category_id; + if ($base->cfg['notSubcats']) { + $base->cfg['notCatId'] = get_sub_cats($category_id); + } elseif ($base->cfg['thisCatOnly']) { + $base->cfg['notCatId'] = (int)$category_id; + } + } + // Дублирование кода вызвано необходимостью сочетания параметра notCatId и catId + // Например: catId=this¬CatId=3 + if ($base->cfg['notCatId']) { + $notCatArr = $base->getDiapazone($base->cfg['notCatId'], $base->cfg['notSubcats']); + if ($notCatArr[0] > 0) { + if ($base->dle_config['allow_multi_category'] && !$base->cfg['thisCatOnly']) { + $notCatQPart = 'category regexp "[[:<:]]('.str_replace(',', '|', $notCatArr).')[[:>:]]"'; + } else { + $notCatQPart = 'category IN (\''.str_replace(',', "','", $notCatArr).'\')'; + } + + $wheres[] = 'NOT '.$notCatQPart; + } + } + + if ($base->cfg['catId']) { + $catArr = $base->getDiapazone($base->cfg['catId'], $base->cfg['subcats']); + if ($catArr[0] > 0) { + if ($base->dle_config['allow_multi_category'] && !$base->cfg['thisCatOnly']) { + $catQPart = 'category regexp "[[:<:]]('.str_replace(',', '|', $catArr).')[[:>:]]"'; + } else { + $catQPart = 'category IN (\''.str_replace(',', "','", $catArr).'\')'; + } + + $wheres[] = $catQPart; + } + } + + // Фильтрация НОВОСТЕЙ по их ID + if ($base->cfg['postId'] == 'this' && $_REQUEST['newsid']) { + $base->cfg['postId'] = $_REQUEST['newsid']; + } + if ($base->cfg['notPostId'] == 'this' && $_REQUEST['newsid']) { + $base->cfg['notPostId'] = $_REQUEST['newsid']; + } + + if ($base->cfg['notPostId']) { + $notPostsArr = $base->getDiapazone($base->cfg['notPostId']); + if ($notPostsArr !== '0') { + $wheres[] = 'id NOT IN ('.$notPostsArr.')'; + } + } + + if ($base->cfg['postId'] && $base->cfg['related'] == '') { + $postsArr = $base->getDiapazone($base->cfg['postId']); + if ($postsArr !== '0') { + $wheres[] = 'id IN ('.$postsArr.')'; + } + } + + // Фильтрация новостей по АВТОРАМ + if ($base->cfg['author'] == 'this' && isset($_REQUEST['user'])) { + $base->cfg['author'] = $_REQUEST['user']; + } + if ($base->cfg['notAuthor'] == 'this' && isset($_REQUEST['user'])) { + $base->cfg['notAuthor'] = $_REQUEST['user']; + } + if ($base->cfg['author'] || $base->cfg['notAuthor']) { + $ignoreAuthors = ($base->cfg['notAuthor']) ? 'NOT ' : ''; + $authorsArr = ($base->cfg['notAuthor']) ? $base->cfg['notAuthor'] : $base->cfg['author']; + if ($authorsArr !== 'this') { + // Если в строке подключения &author=this и мы просматриваем страницу юзера, то сюда уже попадёт логин пользователя + $authorsArr = explode(',', $authorsArr); + $wheres[] = (count($authorsArr) === 1) ? $ignoreAuthors.'autor = '.$base->db->parse('?s', $authorsArr[0]) + : $ignoreAuthors.'autor regexp "[[:<:]]('.implode('|', $authorsArr).')[[:>:]]"'; + } + } + + // Фильтрация новостей по ДОПОЛНИТЕЛЬНЫМ ПОЛЯМ (проверяется только на заполненность) + $_currentXfield = false; + if ($base->cfg['xfilter'] == 'this' && isset($_REQUEST['xf'])) { + $base->cfg['xfilter'] = $base->db->parse('?s', '%'.$_REQUEST['xf'].'%'); + $_currentXfield = true; + } + if ($base->cfg['notXfilter'] == 'this' && isset($_REQUEST['xf'])) { + $base->cfg['notXfilter'] = $base->db->parse('?s', '%'.$_REQUEST['xf'].'%'); + $_currentXfield = true; + } + + if ($base->cfg['xfilter'] || $base->cfg['notXfilter']) { + $ignoreXfilters = ($base->cfg['notXfilter']) ? 'NOT ' : ''; + $xfiltersArr = ($base->cfg['notXfilter']) ? $base->cfg['notXfilter'] : $base->cfg['xfilter']; + + if ($xfiltersArr !== 'this') { + // Если в строке подключения &xfilter=this и мы просматриваем страницу допполя, то сюда уже попадёт имя этого поля + $wheres[] = ($_currentXfield) ? $ignoreXfilters.'xfields LIKE '.$xfiltersArr + : $ignoreXfilters.'p.xfields regexp "[[:<:]]('.str_replace(',', '|', $xfiltersArr).')[[:>:]]"'; + } + } + + // Фильтрация по ЗНАЧЕНИЮ ДОПОЛНИТЕЛЬНЫХ ПОЛЕЙ + if ($base->cfg['xfSearch'] || $base->cfg['notXfSearch']) { + + // Массив для составления подзапроса + $xfWheres = []; + + // Защита логики построения запроса от кривых рук (если прописать неправильно - будет логика OR) + $_xfSearchLogic = (strtolower($base->cfg['xfSearchLogic']) == 'and') ? ' AND ' : ' OR '; + + // Определяем масивы с данными по фильтрации + $xfSearchArray = ($base->cfg['xfSearch']) ? explode('||', $base->cfg['xfSearch']) : []; + $notXfSearchArray = ($base->cfg['notXfSearch']) ? explode('||', $base->cfg['notXfSearch']) : []; + + $bXfNotResult = true; + if ($base->dle_config['version_id'] >= '11' && $base->cfg['experiment']) { + // Если версия DLE 11 и более и включена экспериментальная функция, то для увеличения скорости выборки запросим данные по допполям из отдельной таблицы. + + // Пробегаем по сформированным массивам + foreach ($xfSearchArray as $xf) { + $_xf = explode('|', $xf); + $xfWheres[] = $base->db->parse('(tagname=?s AND tagvalue=?s)', $_xf[0], $_xf[1]); + } + foreach ($notXfSearchArray as $xf) { + $_xf = explode('|', $xf); + $xfWheres[] = $base->db->parse('(tagname=?s AND NOT tagvalue=?s)', $_xf[0], $_xf[1]); + } + // Подготавливаем запрос. + $xfSearchQuery = implode($_xfSearchLogic, $xfWheres); + + // Получаем ID новостей + $xfSearchIDs = $base->db->getCol('SELECT news_id FROM ?n WHERE ?p', PREFIX.'_xfsearch', $xfSearchQuery); + // Если запрос вернул ID новостей — работаем. + if (count($xfSearchIDs)) { + // Оставляем только уникальные + $xfSearchIDs = array_unique($xfSearchIDs); + + // Добавляем полученные данные в основной массив, формирующий запрос + $wheres[] = 'p.id IN ('.implode(',', $xfSearchIDs).')'; + + $bXfNotResult = false; + } else { + // Если ничего не найдено — сбросим массив с условиями т.к. строка подключения возможно содержит дополнительные условия выборки. + $xfWheres = []; + } + } + + if ($bXfNotResult) { + // Пробегаем по сформированным массивам + // str_replace('|', '|%', $xf) необходимо для случаев, когда значение допполя идёт не первым в списке + foreach ($xfSearchArray as $xf) { + $xfWheres[] = $base->db->parse('p.xfields LIKE ?s', '%'.str_replace('|', '|%', $xf).'%'); + } + foreach ($notXfSearchArray as $xf) { + $xfWheres[] = $base->db->parse('p.xfields NOT LIKE ?s', '%'.str_replace('|', '|%', $xf).'%'); + } + + // Добавляем полученные данные (и логику) в основной массив, формирующий запрос + $wheres[] = '('.implode($_xfSearchLogic, $xfWheres).')'; + } + } + + // Фильтрация новостей по ТЕГАМ + $_currentTag = false; + if ($base->cfg['tags'] == 'this' && isset($_REQUEST['tag']) && $_REQUEST['tag'] != '') { + $base->cfg['tags'] = $base->db->parse('?s', $_REQUEST['tag']); + $_currentTag = true; + } + if ($base->cfg['notTags'] == 'this' && isset($_REQUEST['tag']) && $_REQUEST['tag'] != '') { + $base->cfg['notTags'] = $base->db->parse('?s', $_REQUEST['tag']); + $_currentTag = true; + } + + // Фильтрация новостей по тегам текущей новости, когда в строке подключения прописано &tags=thisNewsTags и мы просматриваем полную новость + if ((int)$_REQUEST['newsid'] > 0) { + if ($base->cfg['tags'] == 'thisNewsTags' || $base->cfg['notTags'] == 'thisNewsTags') { + $curTagNewsId = $base->db->getRow('SELECT tags FROM ?n WHERE id=?i', PREFIX.'_post', $_REQUEST['newsid']); + if (!empty($curTagNewsId['tags'])) { + if ($base->cfg['tags'] == 'thisNewsTags') { + // Заменяем запятую и пробел на просто запятую, иначе будет ошибка. + $base->cfg['tags'] = str_replace(', ', ',', $curTagNewsId['tags']); + } + if ($base->cfg['notTags'] == 'thisNewsTags') { + // Заменяем запятую и пробел на просто запятую, иначе будет ошибка. + $base->cfg['notTags'] = str_replace(', ', ',', $curTagNewsId['notTags']); + } + } + } + } + + if ($base->cfg['tags'] || $base->cfg['notTags']) { + $ignoreTags = ($base->cfg['notTags']) ? 'NOT ' : ''; + $tagsArr = ($base->cfg['notTags']) ? $base->cfg['notTags'] : $base->cfg['tags']; + + + if ($tagsArr !== 'this') { + // Если в строке подключения &tags=this и мы просматриваем страницу тегов, то сюда уже попадёт название тега + $wherTag = ($_currentTag) ? $ignoreTags.'tag = '.$tagsArr + : $ignoreTags.'tag regexp "[[:<:]]('.str_replace(',', '|', $tagsArr).')[[:>:]]"'; + // Делаем запрос на получение ID новостей, содержащих требуемые теги + $tagNews = $base->db->getCol('SELECT news_id FROM ?n WHERE ?p', PREFIX.'_tags', $wherTag); + $tagNews = array_unique($tagNews); + + if (count($tagNews)) { + $wheres[] = 'id '.$ignoreTags.' IN ('.implode(',', $tagNews).')'; + } else { + // Fix #160 + $wheres[] = 'id = 0'; + } + + } + } + + // Фильтрация новостей по символьным кодам + $_currentSymbol = false; + if ($base->cfg['symbols'] == 'this' && isset($_REQUEST['catalog'])) { + $base->cfg['symbols'] = $base->db->parse('?s', $_REQUEST['catalog']); + $_currentSymbol = true; + } + if ($base->cfg['notSymbols'] == 'this' && isset($_REQUEST['catalog'])) { + $base->cfg['notSymbols'] = $base->db->parse('?s', $_REQUEST['catalog']); + $_currentSymbol = true; + } + + if ($base->cfg['symbols'] || $base->cfg['notSymbols']) { + $ignoreSymbols = ($base->cfg['notSymbols']) ? 'NOT ' : ''; + $symbolsArr = ($base->cfg['notSymbols']) ? $base->cfg['notSymbols'] : $base->cfg['symbols']; + if ($symbolsArr !== 'this') { + // Если в строке подключения &symbols=this и мы просматриваем страницу буквенного каталога, то сюда уже попадёт название буквы + $wheres[] = ($_currentSymbol) ? $ignoreSymbols.'symbol = '.$symbolsArr + : $ignoreSymbols.'symbol regexp "[[:<:]]('.str_replace(',', '|', $symbolsArr).')[[:>:]]"'; + } + } + + // Если включен режим вывода похожих новостей: + $reltedFirstShow = false; + if ($base->cfg['related']) { + if ($base->cfg['related'] == 'this' && $_REQUEST['newsid'] == '') { + $outputLog['errors'][] + = 'Переменная related=this работает только в полной новости и не работает с ЧПУ 3 типа.'; + } else { + + $relatedId = ($base->cfg['related'] == 'this') ? $_REQUEST['newsid'] : $base->cfg['related']; + $relatedRows = 'p.title, p.short_story, p.full_story, p.xfields'; + $relatedIdParsed = $base->db->parse('id = ?i', $relatedId); + + $relatedBody = $base->db->getRow('SELECT id, ?p FROM ?n p LEFT JOIN ?n e ON (p.id=e.news_id) WHERE ?p', + 'p.title, p.short_story, p.full_story, p.xfields, e.related_ids', PREFIX.'_post', PREFIX.'_post_extras', + $relatedIdParsed); + // Фикс https://github.com/dle-modules/DLE-BlockPro/issues/78 + if ($relatedBody['id']) { + /** @var bool $saveRelated */ + if ($relatedBody['related_ids'] && $saveRelated) { + // Если есть запись id похожих новостей — добавим в условие запроса эти новости. + $wheres[] = 'id IN('.$relatedBody['related_ids'].')'; + // Отсортируем новости в том порядке, в котором они записаны в БД + $orderArr = ['FIELD (p.id, '.$relatedBody['related_ids'].')']; + } else { + // Если похожие новости не записывались — отберём их. + $reltedFirstShow = true; + $bodyToRelated = (dle_strlen($relatedBody['full_story'], $base->dle_config['charset']) + < dle_strlen($relatedBody['short_story'], $base->dle_config['charset'])) + ? $relatedBody['short_story'] : $relatedBody['full_story']; + + $bodyToRelated = strip_tags(stripslashes($relatedBody['title'].' '.$bodyToRelated)); + + // Фикс для https://github.com/pafnuty/BlockPro/issues/79 + // @see /engine/modules/show.full.php + if (dle_strlen($bodyToRelated, $base->dle_config['charset']) > 1000) { + $bodyToRelated = dle_substr($bodyToRelated, 0, 1000, $base->dle_config['charset']); + } + + $bodyToRelated = $base->db->parse('?s', $bodyToRelated); + + // Добавляем улучшенный алгоритм поиска похожих новостей из DLE 13 + $ext_query_fields .= ', MATCH (p.title, p.short_story, p.full_story, p.xfields) AGAINST (' + .$bodyToRelated.') as score'; + $orderArr = ['score DESC']; + + // Формируем условие выборки + $wheres[] = 'MATCH ('.$relatedRows.') AGAINST ('.$bodyToRelated.') AND id !='.$relatedBody['id']; + } + } else { + $outputLog['errors'][] = 'Новость с ID '.$relatedIdParsed.' не найдена в базе данных.'; + } + } + + + } + + // Определяем переменные, чтоб сто раз не писать одно и тоже + $bDay = (int)$base->cfg['day']; + $bDayCount = (int)$base->cfg['dayCount']; + + // Если в bDay и bDayCount передано '-1', значит требуется вывести новости только за сегодня. + // Это обработка случая, когда включен вывод новостей на ненаступившую дату и надо вывести за сегодня + // https://pafnuty.omnidesk.ru/staff/cases/record/181-466935/ + if ($bDay === -1 && $bDayCount === -1) { + // Формируем вывод новостей только за сегодня + $wheres[] = 'p.date >= "'.$today.'" - INTERVAL 1 DAY'; + $wheres[] = 'p.date < "'.$today.'"'; + } else { + // Если future задан, то интервал не вычитаем, а прибавляем к текущему началу дня + $intervalOperator = ($base->cfg['future']) ? ' + ' : ' - '; + + // Если режим афиши включен - выводим новости, дата которых ещё не наступила. + if ($base->cfg['future'] && (!$bDay && !$bDayCount)) { + $wheres[] = 'p.date > "'.$rightNow.'"'; + } + + // Если включен вывод новостей на ненаступившую дату в настройках DLE + // и режим афиши не используется, то нельзя выводить новости дата которых не наступила до текущей секунды + if (!$base->cfg['future'] && ($base->dle_config['news_future'] && $base->dle_config['news_future'] !== 'no')) { + $wheres[] = 'p.date <= "'.$rightNow.'"'; + } + + // Разбираемся с временными рамками отбора новостей, если кол-во дней указано - ограничиваем выборку, если нет - выводим без ограничения даты + if ($bDay) { + $wheres[] = 'p.date >= "'.$today.'" '.$intervalOperator.' INTERVAL '.(($base->cfg['future']) ? ($bDay + - $bDayCount) : $bDay).' DAY'; + } + // Если задана переменная dayCount и day, а так же day больше dayCount - отбираем новости за указанный интервал от указанного периода + if ($bDay && $bDayCount && ($bDayCount <= $bDay)) { + $wheres[] = 'p.date < "'.$today.'" '.$intervalOperator.' INTERVAL '.(($base->cfg['future']) ? $bDay + : ($bDay - $bDayCount)).' DAY'; + } else { + // Условие для отображения только тех постов, дата публикации которых уже наступила + $wheres[] = ($base->dle_config['no_date'] && !$base->dle_config['news_future'] && !$base->cfg['future']) + ? 'p.date < "'.$rightNow.'"' : ''; + } + + } + + // Подчистим массив от пустых значений + $wheres = array_filter($wheres); + + // Когда выбран вариант вывода случайных новостей (Лёгкий режим) + if ($base->cfg['sort'] == 'randomLight') { + + // Складываем условия выборки для рандомных новостей + $randWhere = (count($wheres)) ? ' WHERE '.implode(' AND ', $wheres) : ''; + // Получим массив с id новостей + $randDiapazone = $base->db->getCol('SELECT id FROM ?n AS p ?p', PREFIX.'_post', $randWhere); + // Перемешаем + shuffle($randDiapazone); + // Возьмём только нужное количество элементов + $randIds = array_slice($randDiapazone, 0, $base->cfg['limit']); // Удалим из памяти ненужное unset($randDiapazone); unset($randWhere); - // Если вдруг не получится набрать элементы в принципе - if (count($randIds)) { - $randIds = implode(',', $randIds); - // Сбрасываем ненужные условия выборки - $wheres = []; - // Задаём условие выборки по предварительно полученным ID - $wheres[] = 'id IN (' . $randIds . ')'; - // И выводим в том порядке, в ктором сформировались ID - $orderArr = ['FIELD (p.id, ' . $randIds . ')']; - } - - } - // Складываем условия - $where = (count($wheres)) ? ' WHERE ' . implode(' AND ', $wheres) : ''; - - // Если нужен вывод аватарок - добавляем дополнительные условия в запрос - if ($base->cfg['avatar']) { - $ext_query_fields .= ', u.name, u.user_group, u.foto '; - $ext_query .= $base->db->parse(' LEFT JOIN ?n u ON (p.autor=u.name) ', USERPREFIX . '_users'); - } - - // Если выбрана сортировка по кол-ву скачиваний прикрепленных файлов - if ($base->cfg['sort'] == 'download') { - $ext_query_fields .= ', d.news_id, sum(d.dcount) as dcount '; - $ext_query .= $base->db->parse(' LEFT JOIN ?n d ON (p.id=d.news_id) ', PREFIX . '_files'); - - // Группируем новости по ID т.к. иначе появятся дубликаты при нескольких атачметах в новости. - $groupBy = ' GROUP BY p.id '; - } - - if ($base->cfg['fields']) { - $customFields = ', ' . trim($base->cfg['fields']); - } else { - $customFields = ''; - } - - // Поля, выбираемые из БД - $selectRows = 'p.id, p.autor, p.date, p.short_story, p.full_story, p.xfields, p.title, p.category, p.alt_name, p.allow_comm, p.comm_num, p.fixed, p.allow_main, p.symbol, p.tags, e.news_read, e.allow_rate, e.rating, e.vote_num, e.votes, e.related_ids, e.view_edit, e.editdate, e.editor, e.reason' . $customFields . $ext_query_fields; - - /** @var array $postsArr */ - if ($base->cfg['order'] == 'asis' && $base->cfg['postId'] && $postsArr) { - $orderArr = ['FIELD (p.id, ' . $postsArr . ')']; - } - // Определяем необходимость и данные для сортировки - $orderBy = (count($orderArr)) ? 'ORDER BY ' . implode(', ', $orderArr) : ''; - - // Запрос в БД (данные фильтруются в классе для работы с БД, так что можно не переживать), главное правильно сконструировать запрос. - $query = 'SELECT ?p FROM ?n p LEFT JOIN ?n e ON (p.id=e.news_id) ?p ' . $groupBy . ' ' . $orderBy . ' LIMIT ?i, ?i'; - - // Определяем с какой страницы начинать вывод (при постраничке, или если указано в строке). - $_startFrom = ($base->cfg['pageNum'] >= 1) ? ($base->cfg['limit'] * $base->cfg['pageNum'] - $base->cfg['limit'] + $base->cfg['startFrom']) : 0; - - // Получаем новости - $list = $base->db->getAll($query, $selectRows, PREFIX . '_post', PREFIX . '_post_extras', $ext_query . $where, $_startFrom, $base->cfg['limit']); - - // Обрабатываем данные функцией stripslashes рекурсивно. - $list = stripSlashesInArray($list); - - // Путь к папке с текущим шаблоном - $tplArr['theme'] = $base->dle_config['http_home_url'] . 'templates/' . $base->dle_config['skin']; - - // Делаем доступным конфиг DLE внутри шаблона - $tplArr['dleConfig'] = $base->dle_config; - - // Делаем доступной переменную $dle_module в шаблоне - $tplArr['dleModule'] = $dle_module; - - // Делаем доступной переменную $lang в шаблоне - $tplArr['lang'] = $lang; - $tplArr['cacheName'] = $cacheName; - $tplArr['category_id'] = $category_id; - $tplArr['cfg'] = $cfg; - // Массив для аттачей и похожих новостей. - $attachments = $relatedIds = []; - - // Обрабатываем данные в массиве. - foreach ($list as $key => &$newsItem) { - // Плучаем обработанные допполя. - $newsItem['xfields'] = stripSlashesInArray(xfieldsdataload($newsItem['xfields'])); - // Собираем массив вложений - $attachments[] = $relatedIds[] = $newsItem['id']; - - // Массив данных для формирования ЧПУ - $urlArr = [ - 'category' => $newsItem['category'], - 'id' => $newsItem['id'], - 'alt_name' => $newsItem['alt_name'], - 'date' => $newsItem['date'], - ]; - // Записываем сформированный URL статьи в массив - $newsItem['url'] = $base->getPostUrl($urlArr); - - // Добавляем тег edit - if ($is_logged and (($member_id['name'] == $newsItem['autor'] and $user_group[$member_id['user_group']]['allow_edit']) or $user_group[$member_id['user_group']]['allow_all_edit'])) { - $_SESSION['referrer'] = $_SERVER['REQUEST_URI']; - $newsItem['allow_edit'] = true; - $newsItem['editOnclick'] = 'onclick="return dropdownmenu(this, event, MenuNewsBuild(\'' . $newsItem['id'] . '\', \'short\'), \'170px\')"'; - - } else { - $newsItem['allow_edit'] = false; - $newsItem['editOnclick'] = ''; - } - - // Записываем сформированные теги в массив - $newsItem['tags'] = $base->tagsLink($newsItem['tags']); - - // Записываем в массив ссылку на аватар - $newsItem['avatar'] = $tplArr['theme'] . '/dleimages/noavatar.png'; - // А если у юзера есть фотка - выводим её, или граватар. - if ($newsItem['foto']) { - $userFoto = $newsItem['foto']; - if (count(explode('@', $userFoto)) == 2) { - $newsItem['avatar'] = '//www.gravatar.com/avatar/' . md5(trim($userFoto)) . '?s=' . intval($user_group[$newsItem['user_group']]['max_foto']); - } else { - $userFotoWHost = (strpos($userFoto, '//') === 0) ? 'http:' . $userFoto : $userFoto; - $arUserFoto = parse_url($userFotoWHost); - if ($arUserFoto['host']) { - $newsItem['avatar'] = $userFoto; - } else { - $newsItem['avatar'] = $base->dle_config['http_home_url'] . 'uploads/fotos/' . $userFoto; - } - unset($arUserFoto, $userFotoWHost); - } - } - - // Разбираемся с рейтингом - $newsItem['showRating'] = ''; - $newsItem['showRatingCount'] = ''; - if ($newsItem['allow_rate']) { - $newsItem['showRatingCount'] = '' . $newsItem['vote_num'] . ''; - $jsRAteFunctionName = ($base->dle_config['version_id'] >= 13) ? 'base_rate13' : 'base_rate'; - - if ($base->dle_config['short_rating'] and $user_group[$member_id['user_group']]['allow_rating']) { - $newsItem['showRating'] = baseShowRating($newsItem['id'], $newsItem['rating'], $newsItem['vote_num'], 1); - - $newsItem['ratingOnclickPlus'] = 'onclick="' . $jsRAteFunctionName .'(\'plus\', \'' . $newsItem['id'] . '\'); return false;"'; - $newsItem['ratingOnclickMinus'] = 'onclick="' . $jsRAteFunctionName .'(\'minus\', \'' . $newsItem['id'] . '\'); return false;"'; - - } else { - $newsItem['showRating'] = baseShowRating($newsItem['id'], $newsItem['rating'], $newsItem['vote_num'], 0); - - $newsItem['ratingOnclickPlus'] = ''; - $newsItem['ratingOnclickMinus'] = ''; - } - } - // Разбираемся с избранным - $newsItem['favorites'] = ''; - if ($is_logged) { - $fav_arr = explode(',', $member_id['favorites']); - - if (!in_array($newsItem['id'], $fav_arr) || $base->dle_config['allow_cache']) { - $newsItem['favorites'] = 'Добавить в свои закладки на сайте'; - } else { - $newsItem['favorites'] = 'Удалить из закладок'; - } - } - } - - // Полученный массив с данными для обработки в шаблоне - $tplArr['list'] = $list; - - // Определяем группу пользователя - $tplArr['member_group_id'] = $member_id['user_group']; - - // Устанавливаем пустое значение для постранички по умолчанию. - $tplArr['pages'] = ''; - // Общее кол-во новостей без постранички. - $tplArr['totalCount'] = count($list); - - if ($base->cfg['showNav']) { - // Получаем общее количество новостей по заданным параметрам отбора - $totalCount = $base->db->getOne('SELECT COUNT(*) as count FROM ?n as p LEFT JOIN ?n e ON (p.id=e.news_id) ?p', PREFIX . '_post', PREFIX . '_post_extras', $where); - // Вычитаем переменную startFrom для корректного значения кол-ва новостей - $totalCount = $totalCount - $base->cfg['startFrom']; - - // Общее кол-во новостей с постраничкой. - $tplArr['totalCount'] = $totalCount; - - // Меняем для кеша id категории на this если параметр catId или notCatId равен this - if ($isCatIdThis) { - $base->cfg['catId'] = 'this'; - } - if ($isNotCatIdThis) { - $base->cfg['notCatId'] = 'this'; - } - - // Формируем имя кеш-файла с конфигом - $pageCacheName = $base->cfg; - // Удаляем номер страницы для того, что бы не создавался новый кеш для каждого блока постранички - unset($pageCacheName['pageNum']); - - // Сокращаем немного имя файла :) - $pageCacheName = 'bpa_' . crc32(implode('_', $pageCacheName)); - - // Включаем кеширование DLE принудительно - $cache_tmp = $base->dle_config['allow_cache']; - $config['allow_cache'] = 'yes'; // 'yes' для совместимости со старыми версиями dle, т.к. там проверяется значение, а не наличие значения переменной. - - // Проверяем есть ли кеш с указанным именем - $ajaxCache = dle_cache($pageCacheName); - // Если кеша нет - if (!$ajaxCache) { - // Сериализуем конфиг для последующей записи в кеш - $pageCacheText = serialize($base->cfg); - // Создаём кеш - create_cache($pageCacheName, $pageCacheText); - } - - // Возвращаем значение кеша DLE обратно - $config['allow_cache'] = $cache_tmp; - - // Массив с конфигурацией для формирования постранички - $pagerConfig = [ - 'block_id' => $pageCacheName, - 'total_items' => $totalCount, - 'items_per_page' => $base->cfg['limit'], - 'style' => $base->cfg['navStyle'], - 'current_page' => $base->cfg['pageNum'], - ]; - if ($base->cfg['navDefaultGet']) { - $pagerConfig['is_default_dle_get'] = true; - $pagerConfig['query_string'] = 'cstart'; - $pagerConfig['link_tag'] = ':name'; - $pagerConfig['current_tag'] = ':name'; - $pagerConfig['prev_tag'] = ''; - $pagerConfig['prev_text_tag'] = '‹ Назад'; - $pagerConfig['next_tag'] = ''; - $pagerConfig['next_text_tag'] = 'Далее ›'; - $pagerConfig['first_tag'] = 'Первая «'; - $pagerConfig['last_tag'] = '» Последняя'; - $pagerConfig['extended_pageof'] = 'Страница :current_page из :total_pages'; - $pagerConfig['extended_itemsof'] = 'Показаны новости :current_first_item — :current_last_item из :total_items'; - } - // Если более 1 страницы - if ($totalCount > $base->cfg['limit']) { - $pagination = new Pager($pagerConfig); - - // Сформированный блок с постраничкой - $tplArr['pages'] = $pagination->render(); - // Уникальный ID для вывода в шаблон - } - $tplArr['block_id'] = $pagerConfig['block_id']; - - } else { - // Устанавливаем уникальный ID для блока по умолчанию - $tplArr['block_id'] = 'bp_' . crc32(implode('_', $base->cfg)); - } - - // Результат обработки шаблона - try { - $output = $base->tpl->fetch($base->cfg['template'] . '.tpl', $tplArr); - } catch (Exception $e) { - $outputLog['errors'][] = $e->getMessage(); - $base->cfg['nocache'] = true; - } - - // Записываем в БД id похожих новостей, если требуется - if ($reltedFirstShow && $saveRelated) { - /** @var integer $relatedId */ - $base->db->query('UPDATE ?n SET related_ids=?s WHERE news_id=?i', PREFIX . '_post_extras', implode(',', $relatedIds), $relatedId); - } - - // Если есть ошбки и включен вывод статистики — оключаем кеш. - if (count($outputLog['errors']) > 0 && $cfg['showstat']) { - $base->cfg['nocache'] = true; - } - - // Формируем данные о запросах для статистики, если требуется - if ($base->cfg['showstat'] && $user_group[$member_id['user_group']]['allow_all_edit']) { - $stat = $base->db->getStats(); - $statQ = []; - - foreach ($stat as $i => $q) { - $statQ['q'] .= '
    ' . '[' . ($i + 1) . '] ' . $q['query'] . '
    [' . ($i + 1) . ' время:] ' . $q['timer'] . ''; - $statQ['t'] += $q['timer']; - } - $dbStat = 'Запрос(ы): ' . $statQ['q'] . '
    Время выполнения запросов: ' . $statQ['t'] . '
    '; - - unset($stat); - } - - // Создаём кеш, если требуется - if (!$base->cfg['nocache']) { - create_cache($base->cfg['cachePrefix'], $output, $cacheName, $cacheSuffix); - } + // Если вдруг не получится набрать элементы в принципе + if (count($randIds)) { + $randIds = implode(',', $randIds); + // Сбрасываем ненужные условия выборки + $wheres = []; + // Задаём условие выборки по предварительно полученным ID + $wheres[] = 'id IN ('.$randIds.')'; + // И выводим в том порядке, в ктором сформировались ID + $orderArr = ['FIELD (p.id, '.$randIds.')']; + } + + } + + // Добавлем условия выборки для новостей на другом языке при включении поддержки MultiLanguage + if ($multiLangEnabled) { + if ($lang_config['hide_news_on']) { + foreach ($multiLngEnabledFields as $enabledField) { + $wheres[] = $multiLangAdditionalFields[$enabledField].' <> \'\''; + } + } + } + + // Складываем условия + $where = (count($wheres)) ? ' WHERE '.implode(' AND ', $wheres) : ''; + + // Если нужен вывод аватарок - добавляем дополнительные условия в запрос + if ($base->cfg['avatar']) { + $ext_query_fields .= ', u.name, u.user_group, u.foto '; + $ext_query .= $base->db->parse(' LEFT JOIN ?n u ON (p.autor=u.name) ', USERPREFIX.'_users'); + } + + // Если выбрана сортировка по кол-ву скачиваний прикрепленных файлов + if ($base->cfg['sort'] == 'download') { + $ext_query_fields .= ', d.news_id, sum(d.dcount) as dcount '; + $ext_query .= $base->db->parse(' LEFT JOIN ?n d ON (p.id=d.news_id) ', PREFIX.'_files'); + + // Группируем новости по ID т.к. иначе появятся дубликаты при нескольких атачметах в новости. + $groupBy = ' GROUP BY p.id '; + } + + $customFields = ''; + if ($base->cfg['fields']) { + $customFields = ', '.trim($base->cfg['fields']); + } + + // Добавляем дополнительные поля в запрос при включении поддержки MultiLanguage + if ($multiLangEnabled) { + $customFields = ', '.implode(', ', $multiLangAdditionalFields); + } + + // Поля, выбираемые из БД + $selectRows + = 'p.id, p.autor, p.date, p.short_story, p.full_story, p.xfields, p.title, p.category, p.alt_name, p.allow_comm, p.comm_num, p.fixed, p.allow_main, p.symbol, p.tags, e.news_read, e.allow_rate, e.rating, e.vote_num, e.votes, e.related_ids, e.view_edit, e.editdate, e.editor, e.reason' + .$customFields.$ext_query_fields; + + /** @var array $postsArr */ + if ($base->cfg['order'] == 'asis' && $base->cfg['postId'] && $postsArr) { + $orderArr = ['FIELD (p.id, '.$postsArr.')']; + } + // Определяем необходимость и данные для сортировки + $orderBy = (count($orderArr)) ? 'ORDER BY '.implode(', ', $orderArr) : ''; + + // Запрос в БД (данные фильтруются в классе для работы с БД, так что можно не переживать), главное правильно сконструировать запрос. + $query = 'SELECT ?p FROM ?n p LEFT JOIN ?n e ON (p.id=e.news_id) ?p '.$groupBy.' '.$orderBy.' LIMIT ?i, ?i'; + + // Определяем с какой страницы начинать вывод (при постраничке, или если указано в строке). + $_startFrom = ($base->cfg['pageNum'] >= 1) ? ($base->cfg['limit'] * $base->cfg['pageNum'] - $base->cfg['limit'] + + $base->cfg['startFrom']) : 0; + + // Получаем новости + $list = $base->db->getAll($query, $selectRows, PREFIX.'_post', PREFIX.'_post_extras', $ext_query.$where, + $_startFrom, $base->cfg['limit']); + + // Обрабатываем данные функцией stripslashes рекурсивно. + $list = stripSlashesInArray($list); + + // Путь к папке с текущим шаблоном + $tplArr['theme'] = $base->dle_config['http_home_url'].'templates/'.$base->dle_config['skin']; + + // Делаем доступным конфиг DLE внутри шаблона + $tplArr['dleConfig'] = $base->dle_config; + + // Делаем доступной переменную $dle_module в шаблоне + $tplArr['dleModule'] = $dle_module; + + // Делаем доступной переменную $lang в шаблоне + $tplArr['lang'] = $lang; + $tplArr['cacheName'] = $cacheName; + $tplArr['category_id'] = $category_id; + $tplArr['cfg'] = $cfg; + $tplArr['langVariant'] = $langVariant; + // Массив для аттачей и похожих новостей. + $attachments = $relatedIds = []; + + // Обрабатываем данные в массиве. + foreach ($list as $key => &$newsItem) { + // Плучаем обработанные допполя. + $newsItem['xfields'] = stripSlashesInArray(xfieldsdataload($newsItem['xfields'])); + // Собираем массив вложений + $attachments[] = $relatedIds[] = $newsItem['id']; + + // Массив данных для формирования ЧПУ + $urlArr = [ + 'category' => $newsItem['category'], + 'id' => $newsItem['id'], + 'alt_name' => $newsItem['alt_name'], + 'date' => $newsItem['date'], + ]; + // Записываем сформированный URL статьи в массив + $newsItem['url'] = $base->getPostUrl($urlArr, $langVariant); + + // Присваиваем полям необходимые значения в зависимости от языка + if ($multiLangEnabled) { + foreach ($multiLngEnabledFields as $enabledField) { + $newsItem[$multiLangNewsFields[$enabledField][0]] = $newsItem[$multiLangNewsFields[$enabledField][1]]; + } + } + + // Добавляем тег edit + if ($is_logged and (($member_id['name'] == $newsItem['autor'] + and $user_group[$member_id['user_group']]['allow_edit']) + or $user_group[$member_id['user_group']]['allow_all_edit']) + ) { + $_SESSION['referrer'] = $_SERVER['REQUEST_URI']; + $newsItem['allow_edit'] = true; + $newsItem['editOnclick'] = 'onclick="return dropdownmenu(this, event, MenuNewsBuild(\''.$newsItem['id'] + .'\', \'short\'), \'170px\')"'; + + } else { + $newsItem['allow_edit'] = false; + $newsItem['editOnclick'] = ''; + } + + // Записываем сформированные теги в массив + $newsItem['tags'] = $base->tagsLink($newsItem['tags']); + + // Записываем в массив ссылку на аватар + $newsItem['avatar'] = $tplArr['theme'].'/dleimages/noavatar.png'; + // А если у юзера есть фотка - выводим её, или граватар. + if ($newsItem['foto']) { + $userFoto = $newsItem['foto']; + if (count(explode('@', $userFoto)) == 2) { + $newsItem['avatar'] = '//www.gravatar.com/avatar/'.md5(trim($userFoto)).'?s=' + .intval($user_group[$newsItem['user_group']]['max_foto']); + } else { + $userFotoWHost = (strpos($userFoto, '//') === 0) ? 'http:'.$userFoto : $userFoto; + $arUserFoto = parse_url($userFotoWHost); + if ($arUserFoto['host']) { + $newsItem['avatar'] = $userFoto; + } else { + $newsItem['avatar'] = $base->dle_config['http_home_url'].'uploads/fotos/'.$userFoto; + } + unset($arUserFoto, $userFotoWHost); + } + } + + // Разбираемся с рейтингом + $newsItem['showRating'] = ''; + $newsItem['showRatingCount'] = ''; + if ($newsItem['allow_rate']) { + $newsItem['showRatingCount'] = '' + .$newsItem['vote_num'].''; + $jsRAteFunctionName = 'base_rate'; + + if ($base->dle_config['short_rating'] and $user_group[$member_id['user_group']]['allow_rating']) { + $newsItem['showRating'] = baseShowRating($newsItem['id'], $newsItem['rating'], $newsItem['vote_num'], + 1); + + $newsItem['ratingOnclickPlus'] = 'onclick="'.$jsRAteFunctionName.'(\'plus\', \''.$newsItem['id'] + .'\'); return false;"'; + $newsItem['ratingOnclickMinus'] = 'onclick="'.$jsRAteFunctionName.'(\'minus\', \''.$newsItem['id'] + .'\'); return false;"'; + + } else { + $newsItem['showRating'] = baseShowRating($newsItem['id'], $newsItem['rating'], $newsItem['vote_num'], + 0); + + $newsItem['ratingOnclickPlus'] = ''; + $newsItem['ratingOnclickMinus'] = ''; + } + } + // Разбираемся с избранным + $newsItem['favorites'] = ''; + if ($is_logged) { + $fav_arr = explode(',', $member_id['favorites']); + + if (!in_array($newsItem['id'], $fav_arr) || $base->dle_config['allow_cache']) { + $newsItem['favorites'] = 'Добавить в свои закладки на сайте'; + } else { + $newsItem['favorites'] = 'Удалить из закладок'; + } + } + } + + // Полученный массив с данными для обработки в шаблоне + $tplArr['list'] = $list; + + // Определяем группу пользователя + $tplArr['member_group_id'] = $member_id['user_group']; + + // Устанавливаем пустое значение для постранички по умолчанию. + $tplArr['pages'] = ''; + // Общее кол-во новостей без постранички. + $tplArr['totalCount'] = count($list); + + if ($base->cfg['showNav']) { + // Получаем общее количество новостей по заданным параметрам отбора + $totalCount = $base->db->getOne('SELECT COUNT(*) as count FROM ?n as p LEFT JOIN ?n e ON (p.id=e.news_id) ?p', + PREFIX.'_post', PREFIX.'_post_extras', $where); + // Вычитаем переменную startFrom для корректного значения кол-ва новостей + $totalCount = $totalCount - $base->cfg['startFrom']; + + // Общее кол-во новостей с постраничкой. + $tplArr['totalCount'] = $totalCount; + + // Меняем для кеша id категории на this если параметр catId или notCatId равен this + if ($isCatIdThis) { + $base->cfg['catId'] = 'this'; + } + if ($isNotCatIdThis) { + $base->cfg['notCatId'] = 'this'; + } + + // Формируем имя кеш-файла с конфигом + $pageCacheName = $base->cfg; + // Удаляем номер страницы для того, что бы не создавался новый кеш для каждого блока постранички + unset($pageCacheName['pageNum']); + + // Сокращаем немного имя файла :) + $pageCacheName = 'bpa_'.crc32(implode('_', $pageCacheName)); + + // Включаем кеширование DLE принудительно + $cache_tmp = $base->dle_config['allow_cache']; + $config['allow_cache'] + = 'yes'; // 'yes' для совместимости со старыми версиями dle, т.к. там проверяется значение, а не наличие значения переменной. + + // Проверяем есть ли кеш с указанным именем + $ajaxCache = dle_cache($pageCacheName); + // Если кеша нет + if (!$ajaxCache) { + // Сериализуем конфиг для последующей записи в кеш + $pageCacheText = serialize($base->cfg); + // Создаём кеш + create_cache($pageCacheName, $pageCacheText); + } + + // Возвращаем значение кеша DLE обратно + $config['allow_cache'] = $cache_tmp; + + // Массив с конфигурацией для формирования постранички + $pagerConfig = [ + 'block_id' => $pageCacheName, + 'total_items' => $totalCount, + 'items_per_page' => $base->cfg['limit'], + 'style' => $base->cfg['navStyle'], + 'current_page' => $base->cfg['pageNum'], + ]; + if ($base->cfg['navDefaultGet']) { + $pagerConfig['is_default_dle_get'] = true; + $pagerConfig['query_string'] = 'cstart'; + $pagerConfig['link_tag'] = ':name'; + $pagerConfig['current_tag'] = ':name'; + $pagerConfig['prev_tag'] = ''; + $pagerConfig['prev_text_tag'] = '‹ Назад'; + $pagerConfig['next_tag'] = ''; + $pagerConfig['next_text_tag'] = 'Далее ›'; + $pagerConfig['first_tag'] = 'Первая «'; + $pagerConfig['last_tag'] = '» Последняя'; + $pagerConfig['extended_pageof'] = 'Страница :current_page из :total_pages'; + $pagerConfig['extended_itemsof'] + = 'Показаны новости :current_first_item — :current_last_item из :total_items'; + } + // Если более 1 страницы + if ($totalCount > $base->cfg['limit']) { + $pagination = new Pager($pagerConfig); + + // Сформированный блок с постраничкой + $tplArr['pages'] = $pagination->render(); + // Уникальный ID для вывода в шаблон + } + $tplArr['block_id'] = $pagerConfig['block_id']; + + } else { + // Устанавливаем уникальный ID для блока по умолчанию + $tplArr['block_id'] = 'bp_'.crc32(implode('_', $base->cfg)); + } + + // Результат обработки шаблона + try { + $output = $base->tpl->fetch($base->cfg['template'].'.tpl', $tplArr); + } catch (Exception $e) { + $outputLog['errors'][] = $e->getMessage(); + $base->cfg['nocache'] = true; + } + + // Записываем в БД id похожих новостей, если требуется + if ($reltedFirstShow && $saveRelated) { + /** @var integer $relatedId */ + $base->db->query('UPDATE ?n SET related_ids=?s WHERE news_id=?i', PREFIX.'_post_extras', + implode(',', $relatedIds), $relatedId); + } + + // Если есть ошбки и включен вывод статистики — оключаем кеш. + if (count($outputLog['errors']) > 0 && $cfg['showstat']) { + $base->cfg['nocache'] = true; + } + + // Формируем данные о запросах для статистики, если требуется + if ($base->cfg['showstat'] && $user_group[$member_id['user_group']]['allow_all_edit']) { + $stat = $base->db->getStats(); + $statQ = []; + + foreach ($stat as $i => $q) { + $statQ['q'] .= '
    '.'['.($i + 1).'] '.$q['query'].'
    ['.($i + 1).' время:] '.$q['timer'] + .''; + $statQ['t'] += $q['timer']; + } + $dbStat = 'Запрос(ы): '.$statQ['q'].'
    Время выполнения запросов: '.$statQ['t'].'
    '; + + unset($stat); + } + + // Создаём кеш, если требуется + if (!$base->cfg['nocache']) { + create_cache($base->cfg['cachePrefix'], $output, $cacheName, $cacheSuffix); + } } @@ -1188,50 +1169,53 @@ classic: << Первая < 1 [2] 3 > Последняя >> // Обрабатываем вложения /** @var $base */ if ($base->dle_config['files_allow']) { - if (strpos($output, '[attachment=') !== false) { - /** @var array $attachments */ - $output = show_attach($output, $attachments); - } + if (strpos($output, '[attachment=') !== false) { + /** @var array $attachments */ + $output = show_attach($output, $attachments); + } } else { - $output = preg_replace("'\[attachment=(.*?)\]'si", '', $output); + $output = preg_replace("'\[attachment=(.*?)\]'si", '', $output); } if ($user_group[$member_id['user_group']]['allow_hide']) { - $output = str_ireplace('[hide]', '', str_ireplace('[/hide]', '', $output)); + $output = str_ireplace('[hide]', '', str_ireplace('[/hide]', '', $output)); } else { - $output = preg_replace('#\[hide\](.+?)\[/hide\]#ims', '', $output); + $output = preg_replace('#\[hide\](.+?)\[/hide\]#ims', '', $output); } // Результат работы модуля /** @var boolean $external */ if (!$external) { - // Если блок не является внешним - выводим на печать - if (count($outputLog['errors']) > 0) { - // Выводим ошибки, если они есть - $outputErrors = []; - $outputErrors[] = '
      '; - - foreach ($outputLog['errors'] as $errorText) { - $outputErrors[] = '
    • ' . $errorText . '
    • '; - } - $outputErrors[] = '
    '; - - $outputErrors = implode('', $outputErrors); - - echo $outputErrors; - } else { - // Если нет ошибок - выводим результат аботы модуля - echo $output; - } + // Если блок не является внешним - выводим на печать + if (count($outputLog['errors']) > 0) { + // Выводим ошибки, если они есть + $outputErrors = []; + $outputErrors[] + = '
      '; + + foreach ($outputLog['errors'] as $errorText) { + $outputErrors[] = '
    • '.$errorText.'
    • '; + } + $outputErrors[] = '
    '; + + $outputErrors = implode('', $outputErrors); + + echo $outputErrors; + } else { + // Если нет ошибок - выводим результат аботы модуля + echo $output; + } } // Показываем стстаистику выполнения скрипта, если требуется if ($cfg['showstat'] && $user_group[$member_id['user_group']]['allow_all_edit']) { - // Информация об оперативке - $mem_usg = (function_exists('memory_get_peak_usage')) ? '
    Расход памяти: ' . round(memory_get_peak_usage() / (1024 * 1024), 2) . 'Мб ' : ''; - // Вывод статистики - /** @var integer $start */ - /** @var string $dbStat */ - echo '
    ' . $dbStat . 'Время выполнения скрипта: ' . round((microtime(true) - $start), 6) . ' c.' . $mem_usg . '
    '; + // Информация об оперативке + $mem_usg = (function_exists('memory_get_peak_usage')) ? '
    Расход памяти: '.round(memory_get_peak_usage() + / (1024 * 1024), 2).'Мб ' : ''; + // Вывод статистики + /** @var integer $start */ + /** @var string $dbStat */ + echo '
    '.$dbStat + .'Время выполнения скрипта: '.round((microtime(true) - $start), 6).' c.'.$mem_usg.'
    '; } diff --git a/engine/modules/base/core/base.php b/engine/modules/base/core/base.php index d864f6c..b5d7efb 100644 --- a/engine/modules/base/core/base.php +++ b/engine/modules/base/core/base.php @@ -6,7 +6,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ @@ -212,31 +211,30 @@ public function setConfig($cfg = []) { /** * @param $data - массив с информацией о статье + * @param $langVariant string - информация о я зыке сайта * * @return string URL для категории + * */ - - public function getPostUrl($data) { + public function getPostUrl($data, $langVariant = '') { $data['date'] = strtotime($data['date']); + $langUrlPrefix = $langVariant ? $langVariant . '/' : ''; - if ($this->dle_config['allow_alt_url'] && $this->dle_config['allow_alt_url'] != 'no') { - if (($this->dle_config['version_id'] < 9.6 && $this->dle_config['seo_type']) - || ($this->dle_config['version_id'] >= 9.6 - && ($this->dle_config['seo_type'] == 1 - || $this->dle_config['seo_type'] == 2)) - ) { + if ($this->dle_config['allow_alt_url']) { + if ($this->dle_config['seo_type'] == 1 OR $this->dle_config['seo_type'] == 2) { if (intval($data['category']) && $this->dle_config['seo_type'] == 2) { - $url = $this->dle_config['http_home_url'].get_url(intval($data['category'])).'/'.$data['id'].'-' - .$data['alt_name'].'.html'; + $url = $this->dle_config['http_home_url'].$langUrlPrefix.get_url(intval($data['category'])).'/' + .$data['id'].'-'.$data['alt_name'].'.html'; } else { - $url = $this->dle_config['http_home_url'].$data['id'].'-'.$data['alt_name'].'.html'; + $url = $this->dle_config['http_home_url'].$langUrlPrefix.$data['id'].'-'.$data['alt_name'].'.html'; } } else { - $url = $this->dle_config['http_home_url'].date('Y/m/d/', $data['date']).$data['alt_name'].'.html'; + $url = $this->dle_config['http_home_url'].$langUrlPrefix.date('Y/m/d/', $data['date']).$data['alt_name'] + .'.html'; } } else { - $url = $this->dle_config['http_home_url'].'index.php?newsid='.$data['id']; + $url = $this->dle_config['http_home_url'].$langUrlPrefix.'index.php?newsid='.$data['id']; } return $url; diff --git a/engine/modules/base/core/bpModifiers.php b/engine/modules/base/core/bpModifiers.php index 573ee3c..6fae665 100644 --- a/engine/modules/base/core/bpModifiers.php +++ b/engine/modules/base/core/bpModifiers.php @@ -7,7 +7,6 @@ Автор: ПафНутиЙ URL: http://pafnuty.name/ twitter: https://twitter.com/pafnuty_name -google+: http://gplus.to/pafnuty email: pafnuty10@gmail.com ============================================================================= */ diff --git a/engine/modules/base/core/config.php b/engine/modules/base/core/config.php new file mode 100644 index 0000000..cee9b8f --- /dev/null +++ b/engine/modules/base/core/config.php @@ -0,0 +1,179 @@ + !empty($moderate) ? $moderate : false, + + // Название шаблона (без расширения) + 'template' => !empty($template) ? $template : 'blockpro/blockpro', + + // Префикс кеша + 'cachePrefix' => !empty($cachePrefix) ? $cachePrefix : 'news', + + // Отключить суффикс кеша (будет создаваться один кеш-файл для всех пользователей). По умолчанию включен, т.е. для каждой группы пользователей будет создаваться свой кеш (на случай разного отображения контента разным юзерам). + 'cacheSuffixOff' => !empty($cacheSuffixOff) ? true : false, + + // Назначаем дополнение к имени кеша, если имеются переменные со значениями this, они будут дописаны в имя кеша, иначе для разных мест будет создаваться один и тот же файл кеша + 'cacheNameAddon' => '', + + // Не использовать кеш + 'nocache' => !empty($nocache) ? $nocache : false, + + // Время жизни кеша в минутах + 'cacheLive' => (!empty($cacheLive) && !$mcache) ? $cacheLive : false, + + // C какой новости начать вывод + 'startFrom' => !empty($startFrom) ? $startFrom : '0', + + // Количество новостей в блоке + 'limit' => !empty($limit) ? $limit : '10', + + // Обработка фиксированных новостей (yes/only/without показ всех/только фиксированных/только обычных новостей) + 'fixed' => !empty($fixed) ? $fixed : 'yes', + + // Обработка новостей, опубликованных на главной (yes/only/without показ всех/только на главной/только не на главной) + 'allowMain' => !empty($allowMain) ? $allowMain : 'yes', + + // ID новостей для вывода в блоке (через запятую, или черточку) + 'postId' => !empty($postId) ? $postId : '', + + // ID игнорируемых новостей (через запятую, или черточку) + 'notPostId' => !empty($notPostId) ? $notPostId : '', + + // Логины авторов, для показа их новостей в блоке (через запятую) + 'author' => !empty($author) ? $author : '', + + // Логины игнорируемых авторов (через запятую) + 'notAuthor' => !empty($notAuthor) ? $notAuthor : '', + + // Имена дополнительных полей для фильтрации новостей по ним (через запятую) + 'xfilter' => !empty($xfilter) ? $xfilter : '', + + // Имена дополнительных полей для игнорирования показа новостей (через запятую) + 'notXfilter' => !empty($notXfilter) ? $notXfilter : '', + + // синтаксис передачи данных: &xfSearch=имя_поля|значение||имя_поля|значение + 'xfSearch' => !empty($xfSearch) ? $xfSearch : false, + + // синтаксис передачи данных: ¬XfSearch=имя_поля|значение||имя_поля|значение + 'notXfSearch' => !empty($notXfSearch) ? $notXfSearch : false, + + // Принимает OR или AND (по умолчанию OR) + 'xfSearchLogic' => !empty($xfSearchLogic) ? $xfSearchLogic : 'OR', + + // Категории для показа (через запятую, или черточку) + 'catId' => !empty($catId) ? $catId : '', + + // Выводить подкатегории указанных категорий (&subcats=y), работает и с диапазонами. + 'subcats' => !empty($subcats) ? $subcats : false, + + // Игнорируемые категории (через запятую, или черточку) + 'notCatId' => !empty($notCatId) ? $notCatId : '', + + // Игнорировать подкатегории игнорируемых категорий (¬Subcats=y), работает и с диапазонами. + 'notSubcats' => !empty($notSubcats) ? $notSubcats : false, + + // Показывать новости ТОЛЬКО из текущей категории (имеет смысл при выводе похожих новостей и использоваии мультикатегорий). + 'thisCatOnly' => !empty($thisCatOnly) ? $thisCatOnly : false, + + // Теги из облака тегов для показа новостей, содержащих их (через запятую) + 'tags' => !empty($tags) ? $tags : '', + + // Игнорируемые теги (через запятую) + 'notTags' => !empty($notTags) ? $notTags : '', + + // Временной период для отбора новостей + 'day' => !empty($day) ? $day : false, + + // Интервал для отбора (т.е. к примеру выбираем новости за прошлую недею так: &day=14&dayCount=7 ) + 'dayCount' => !empty($dayCount) ? $dayCount : false, + + // Сортировка (top, date, comms, rating, views, title, hit, random, randomLight, download, symbol, editdate или xf|xfieldname где xfieldname - имя дополнительного поля, field|p.name где p.name — кастомное поле) + 'sort' => !empty($sort) ? $sort : 'top', + + // Тип сортировки по допполю (string, int) - для корректной сортировки по строке используем string, по умолчанию сортируется как число (для цен полезно). + 'xfSortType' => !empty($xfSortType) ? $xfSortType : 'int', + + // Направление сортировки (new, old, asis) + 'order' => !empty($order) ? $order : 'new', + + // Вывод аватарки пользователя (немного усложнит запрос). + 'avatar' => !empty($avatar) ? $avatar : false, + + // Показывать время и статистику по блоку + 'showstat' => !empty($showstat) ? $showstat : false, + + // Включить режим вывода похожих новостей (по умолчанию нет) + 'related' => !empty($related) ? $related : false, + + // Включить запись похожих новостей в БД + 'saveRelated' => !empty($saveRelated) ? $saveRelated : false, + + // Включить постраничную навигацию + 'showNav' => !empty($showNav) ? $showNav : false, + + // Слушать дефолтный get-параметр постраничной навигации + 'navDefaultGet' => !empty($navDefaultGet) ? $navDefaultGet : false, + + // Текущая страница при постраничной конфигурации + 'pageNum' => !empty($pageNum) ? $pageNum : '1', + + /** + * Стиль навигации. Возможны следующие стили: + * classic: << Первая < 1 [2] 3 > Последняя >> + * digg: << Назад 1 2 ... 5 6 7 8 9 [10] 11 12 13 14 ... 25 26 Вперёд >> + * extended: << Назад | Страница 2 из 11 | Показаны новости 6-10 из 52 | Вперёд >> + * punbb: 1 ... 4 5 [6] 7 8 ... 15 + * arrows: << Назад Вперёд >> + */ + 'navStyle' => !empty($navStyle) ? $navStyle : 'classic', + /** + * @todo реализовать функционал с options и notOptions + * Опции, публикации новости для показа (Публиковать на главной, Разрешить рейтинг статьи, Разрешить комментарии, Запретить индексацию страницы для поисковиков, Зафиксировать новость) main|rating|comments|noindex + */ + 'options' => !empty($options) ? $options : false, + + // Опции, публикации новости для исключения (Публиковать на главной, Разрешить рейтинг статьи, Разрешить комментарии, Запретить индексацию страницы для поисковиков, Зафиксировать новость) main|rating|comments|noindex + 'notOptions' => !empty($notOptions) ? $notOptions : false, + + // Выводить только новости, дата публикации которых не наступила (Полезно для афиш) &future=y + 'future' => !empty($future) ? $future : false, + + // Значимые переменные в формировании кеша блока на случай разного вывода в зависимости от условий расположения модуля. Сюда можно передавать ключи, доступные через $_REQUEST или значения переменной $dle_module + 'cacheVars' => !empty($cacheVars) ? $cacheVars : false, + + // Символьные коды для фильтрации по символьному каталогу. Перечисляем через запятую. + 'symbols' => !empty($symbols) ? $symbols : false, + + // Символьные коды для исключающей фильтрации по символьному каталогу. Перечисляем через запятую или пишем this для текущего символьного кода + 'notSymbols' => !empty($notSymbols) ? $notSymbols : false, + + /** + * Дополнение к выборке полей из БД (p.field,e.field) + * setFilter=p.full_story|SEARCH|dle_media_begin|OR|p.full_story|SEARCH|dle_video_begin + * setFilter=e.news_read|+|100||p.comm_num|-|20 + */ + 'fields' => !empty($fields) ? $fields : false, + + // Собственная фильтрация полей БД + 'setFilter' => !empty($setFilter) ? $setFilter : '', + + // Включить экспериментальные функции + 'experiment' => !empty($experiment) ? $experiment : false, + + // Включить поддержку модуля MultiLanguage от japing.pw + 'multiLang' => !empty($multiLang) ? $multiLang : false, + + // Список языков, добавленных в модуль MultiLanguage (из модуля без запросов в БД эту информацию получить нельзя) + 'langList' => !empty($langList) ? $langList : 'en', +]; \ No newline at end of file diff --git a/engine/modules/base/core/resize.php b/engine/modules/base/core/resize.php index 865569d..bb82044 100644 --- a/engine/modules/base/core/resize.php +++ b/engine/modules/base/core/resize.php @@ -1,7 +1,7 @@ image = $this->openImageWithCurl($fileName); - } else { - $this->image = $this->openImage($fileName); - } - - // Get width and height - $this->width = imagesx($this->image); - $this->height = imagesy($this->image); - } - - ## -------------------------------------------------------- - - private function openImage($file) { - $extension = strtolower(strrchr($file, '.')); - $this->extension = $extension == '.jpg' ? '.jpeg' : $extension; - $func = 'imagecreatefrom' . substr($this->extension, 1); - if (!function_exists($func)) { - return false; - } - - return $func($file); - } - - ## -------------------------------------------------------- - - private function openImageWithCurl($url) { - $extension = strtolower(strrchr($url, '.')); - $this->extension = $extension == '.jpg' ? '.jpeg' : $extension; - - $file = $this->curlRequest($url); - if ($file == '') { - return false; - } - - return imagecreatefromstring($file); - } - - ## -------------------------------------------------------- - - private function curlRequest($url) { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20120403211507 Firefox/12.0'); - $contents = curl_exec($ch); - curl_close($ch); - - return $contents; - } - - ## -------------------------------------------------------- - - /** - * @param $newWidth - * @param $newHeight - * @param string $option - */ - public function resizeImage($newWidth, $newHeight, $option = "auto") { - // Get optimal width and height - based on $option - $optionArray = $this->getDimensions($newWidth, $newHeight, $option); - - $optimalWidth = $optionArray['optimalWidth']; - $optimalHeight = $optionArray['optimalHeight']; - - // Resample - create image canvas of x, y size - $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight); - - if ($this->extension == '.png' || $this->extension == '.gif') { - imagecolortransparent($this->imageResized, imagecolorallocatealpha($this->imageResized, 0, 0, 0, 127)); - imagealphablending($this->imageResized, false); - imagesavealpha($this->imageResized, true); - } - /** @var string $this */ - imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height); - // if option is 'crop', then crop too - if ($option == 'crop') { - $this->cropImage($optimalWidth, $optimalHeight, $newWidth, $newHeight); - } - } - - ## -------------------------------------------------------- - - /** - * @param $newWidth - * @param $newHeight - * @param $option - * - * @return array - */ - private function getDimensions($newWidth, $newHeight, $option) { - $optimalWidth = $newWidth; - $optimalHeight = $newHeight; - switch ($option) { - case 'exact': - $optimalWidth = $newWidth; - $optimalHeight = $newHeight; - break; - case 'portrait': - $optimalWidth = $this->getSizeByFixedHeight($newHeight); - $optimalHeight = $newHeight; - break; - case 'landscape': - $optimalWidth = $newWidth; - $optimalHeight = $this->getSizeByFixedWidth($newWidth); - break; - case 'auto': - $optionArray = $this->getSizeByAuto($newWidth, $newHeight); - $optimalWidth = $optionArray['optimalWidth']; - $optimalHeight = $optionArray['optimalHeight']; - break; - case 'crop': - $optionArray = $this->getOptimalCrop($newWidth, $newHeight); - $optimalWidth = $optionArray['optimalWidth']; - $optimalHeight = $optionArray['optimalHeight']; - break; - } - - return ['optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight]; - } - - ## -------------------------------------------------------- - - private function getSizeByFixedHeight($newHeight) { - $ratio = $this->width / $this->height; - $newWidth = $newHeight * $ratio; - - return $newWidth; - } - - private function getSizeByFixedWidth($newWidth) { - $ratio = $this->height / $this->width; - $newHeight = $newWidth * $ratio; - - return $newHeight; - } - - private function getSizeByAuto($newWidth, $newHeight) { - if ($this->height < $this->width) // Image to be resized is wider (landscape) - { - $optimalWidth = $newWidth; - $optimalHeight = $this->getSizeByFixedWidth($newWidth); - } elseif ($this->height > $this->width) // Image to be resized is taller (portrait) - { - $optimalWidth = $this->getSizeByFixedHeight($newHeight); - $optimalHeight = $newHeight; - } else // Image to be resizerd is a square - { - if ($newHeight < $newWidth) { - $optimalWidth = $newWidth; - $optimalHeight = $this->getSizeByFixedWidth($newWidth); - } else { - if ($newHeight > $newWidth) { - $optimalWidth = $this->getSizeByFixedHeight($newHeight); - $optimalHeight = $newHeight; - } else { - // Sqaure being resized to a square - $optimalWidth = $newWidth; - $optimalHeight = $newHeight; - } - } - } - - return ['optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight]; - } - - ## -------------------------------------------------------- - - private function getOptimalCrop($newWidth, $newHeight) { - - $heightRatio = $this->height / $newHeight; - $widthRatio = $this->width / $newWidth; - - if ($heightRatio < $widthRatio) { - $optimalRatio = $heightRatio; - } else { - $optimalRatio = $widthRatio; - } - - $optimalHeight = $this->height / $optimalRatio; - $optimalWidth = $this->width / $optimalRatio; - - return ['optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight]; - } - - ## -------------------------------------------------------- - - /** - * @param $optimalWidth - * @param $optimalHeight - * @param $newWidth - * @param $newHeight - */ - private function cropImage($optimalWidth, $optimalHeight, $newWidth, $newHeight) { - // Find center - this will be used for the crop - $cropStartX = ($optimalWidth / 2) - ($newWidth / 2); - $cropStartY = ($optimalHeight / 2) - ($newHeight / 2); - - $crop = $this->imageResized; - //imagedestroy($this->imageResized); - - // Now crop from center to exact requested size - $this->imageResized = imagecreatetruecolor($newWidth, $newHeight); - - if ($this->extension == '.png' || $this->extension == '.gif') { - imagecolortransparent($this->imageResized, imagecolorallocatealpha($this->imageResized, 0, 0, 0, 127)); - imagealphablending($this->imageResized, false); - imagesavealpha($this->imageResized, true); - } - imagecopyresampled($this->imageResized, $crop, 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight, $newWidth, $newHeight); - } - - ## -------------------------------------------------------- - - public function saveImage($savePath, $imageQuality = "100") { - $save = 'image' . substr($this->extension, 1); - if (!function_exists($save)) //хотя проверка в принципе не нужна, т.к. уже была при открытии - { - return false; - } - - ($this->extension == '.gif') - ? $save($this->imageResized, $savePath) - : $save( - $this->imageResized, - $savePath, - ($this->extension == '.png' ? (9 - round(($imageQuality / 100) * 9)) : $imageQuality) - ); - imagedestroy($this->imageResized); - - return true; - } - - ## -------------------------------------------------------- + // Class variables + private $image; + private $width; + private $height; + private $imageResized; + private $extension; + + function __construct($fileName) { + // Если $fileName начинается с http:// или https:// - открываем ее с Curl + if (preg_match('~^http(s)?://~', $fileName)) { + $this->image = $this->openImageWithCurl($fileName); + } else { + $this->image = $this->openImage($fileName); + } + + // Get width and height + $this->width = imagesx($this->image); + $this->height = imagesy($this->image); + } + + ## -------------------------------------------------------- + + private function openImageWithCurl($url) { + $extension = strtolower(strrchr($url, '.')); + $this->extension = $extension == '.jpg' ? '.jpeg' : $extension; + + $file = $this->curlRequest($url); + if ($file == '') { + return false; + } + + return imagecreatefromstring($file); + } + + + ## -------------------------------------------------------- + + private function curlRequest($url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20120403211507 Firefox/12.0'); + $contents = curl_exec($ch); + curl_close($ch); + + return $contents; + } + + ## -------------------------------------------------------- + + private function openImage($file) { + $extension = strtolower(strrchr($file, '.')); + $this->extension = $extension == '.jpg' ? '.jpeg' : $extension; + $image = false; + + switch ($this->extension) { + case '.jpeg': + $image = @imagecreatefromjpeg($file); + break; + case '.png': + $image = @imagecreatefrompng($file); + break; + case '.gif': + $image = @imagecreatefromgif($file); + break; + case '.webp': + $image = @imagecreatefromwebp($file); + break; + default: + break; + + } + + return $image; + } + + ## -------------------------------------------------------- + + /** + * @param $newWidth + * @param $newHeight + * @param string $option + */ + public function resizeImage($newWidth, $newHeight, $option = "auto") { + // Get optimal width and height - based on $option + $optionArray = $this->getDimensions($newWidth, $newHeight, $option); + + $optimalWidth = $optionArray['optimalWidth']; + $optimalHeight = $optionArray['optimalHeight']; + + // Resample - create image canvas of x, y size + $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight); + + if ($this->extension == '.png' || $this->extension == '.gif') { + imagecolortransparent($this->imageResized, imagecolorallocatealpha($this->imageResized, 0, 0, 0, 127)); + imagealphablending($this->imageResized, false); + imagesavealpha($this->imageResized, true); + } + /** @var string $this */ + imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, + $this->height); + // if option is 'crop', then crop too + if ($option == 'crop') { + $this->cropImage($optimalWidth, $optimalHeight, $newWidth, $newHeight); + } + } + + ## -------------------------------------------------------- + + /** + * @param $newWidth + * @param $newHeight + * @param $option + * + * @return array + */ + private function getDimensions($newWidth, $newHeight, $option) { + $optimalWidth = $newWidth; + $optimalHeight = $newHeight; + switch ($option) { + case 'exact': + $optimalWidth = $newWidth; + $optimalHeight = $newHeight; + break; + case 'portrait': + $optimalWidth = $this->getSizeByFixedHeight($newHeight); + $optimalHeight = $newHeight; + break; + case 'landscape': + $optimalWidth = $newWidth; + $optimalHeight = $this->getSizeByFixedWidth($newWidth); + break; + case 'auto': + $optionArray = $this->getSizeByAuto($newWidth, $newHeight); + $optimalWidth = $optionArray['optimalWidth']; + $optimalHeight = $optionArray['optimalHeight']; + break; + case 'crop': + $optionArray = $this->getOptimalCrop($newWidth, $newHeight); + $optimalWidth = $optionArray['optimalWidth']; + $optimalHeight = $optionArray['optimalHeight']; + break; + } + + return ['optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight]; + } + + ## -------------------------------------------------------- + + private function getSizeByFixedHeight($newHeight) { + $ratio = $this->width / $this->height; + $newWidth = $newHeight * $ratio; + + return $newWidth; + } + + private function getSizeByFixedWidth($newWidth) { + $ratio = $this->height / $this->width; + $newHeight = $newWidth * $ratio; + + return $newHeight; + } + + private function getSizeByAuto($newWidth, $newHeight) { + if ($this->height < $this->width) // Image to be resized is wider (landscape) + { + $optimalWidth = $newWidth; + $optimalHeight = $this->getSizeByFixedWidth($newWidth); + } elseif ($this->height > $this->width) // Image to be resized is taller (portrait) + { + $optimalWidth = $this->getSizeByFixedHeight($newHeight); + $optimalHeight = $newHeight; + } else // Image to be resizerd is a square + { + if ($newHeight < $newWidth) { + $optimalWidth = $newWidth; + $optimalHeight = $this->getSizeByFixedWidth($newWidth); + } else { + if ($newHeight > $newWidth) { + $optimalWidth = $this->getSizeByFixedHeight($newHeight); + $optimalHeight = $newHeight; + } else { + // Sqaure being resized to a square + $optimalWidth = $newWidth; + $optimalHeight = $newHeight; + } + } + } + + return ['optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight]; + } + + ## -------------------------------------------------------- + + private function getOptimalCrop($newWidth, $newHeight) { + + $heightRatio = $this->height / $newHeight; + $widthRatio = $this->width / $newWidth; + + if ($heightRatio < $widthRatio) { + $optimalRatio = $heightRatio; + } else { + $optimalRatio = $widthRatio; + } + + $optimalHeight = $this->height / $optimalRatio; + $optimalWidth = $this->width / $optimalRatio; + + return ['optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight]; + } + + ## -------------------------------------------------------- + + /** + * @param $optimalWidth + * @param $optimalHeight + * @param $newWidth + * @param $newHeight + */ + private function cropImage($optimalWidth, $optimalHeight, $newWidth, $newHeight) { + // Find center - this will be used for the crop + $cropStartX = ($optimalWidth / 2) - ($newWidth / 2); + $cropStartY = ($optimalHeight / 2) - ($newHeight / 2); + + $crop = $this->imageResized; + //imagedestroy($this->imageResized); + + // Now crop from center to exact requested size + $this->imageResized = imagecreatetruecolor($newWidth, $newHeight); + + if ($this->extension == '.png' || $this->extension == '.gif') { + imagecolortransparent($this->imageResized, imagecolorallocatealpha($this->imageResized, 0, 0, 0, 127)); + imagealphablending($this->imageResized, false); + imagesavealpha($this->imageResized, true); + } + imagecopyresampled($this->imageResized, $crop, 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight, $newWidth, + $newHeight); + } + + ## -------------------------------------------------------- + + /** + * @param string $savePath + * @param string $imageQuality + * + * @return bool + */ + public function saveImage($savePath, $imageQuality = "100") { + + switch ($this->extension) { + case '.jpeg': + imagejpeg($this->imageResized, $savePath, $imageQuality); + break; + case '.png': + $quality = (9 - round(($imageQuality / 100) * 9)); + imagealphablending($this->imageResized, false); + imagesavealpha($this->imageResized, true); + imagepng($this->imageResized, $savePath, $quality); + break; + case '.gif': + imagegif($this->imageResized, $savePath); + break; + case '.webp': + imagealphablending($this->imageResized, false); + imagesavealpha($this->imageResized, true); + imagewebp($this->imageResized, $savePath, $imageQuality); + break; + default: + break; + + } + + imagedestroy($this->imageResized); + + return true; + } + + ## -------------------------------------------------------- } \ No newline at end of file From 92eaaad537e14172f30620de7808b7130d731eb4 Mon Sep 17 00:00:00 2001 From: pafnuty Date: Sat, 22 Feb 2020 21:50:53 +0400 Subject: [PATCH 5/5] =?UTF-8?q?6.0.0=20=D0=A1=D0=BE=D0=B2=D0=BC=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D1=8C=20c=20DLE=2014?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +++- blockpro.xml | 23 ++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index ba493cb..db0558d 100644 --- a/.gitignore +++ b/.gitignore @@ -225,7 +225,6 @@ /language/English/website.lng # DLE 13 sources - /engine/ajax/controller.php /engine/ajax/plugins.php /engine/classes/plugins.class.php @@ -234,6 +233,9 @@ /engine/inc/upgrade.php /engine/inc/upgrade +# DLE 14 sources +/engine/classes/tinify/ + # BlockPro !/engine/modules/base/ !/engine/data/blockpro.php diff --git a/blockpro.xml b/blockpro.xml index d44b29d..4136dfa 100644 --- a/blockpro.xml +++ b/blockpro.xml @@ -1,13 +1,15 @@ BlockPro - Модуль BlockPro предназначен для пользовательского вывода новостей на сайте под управлением CMS DataLife Engine и позиционируется как альтернатива {custom}, {top}, {related-news}. + Модуль предназначен для удобного вывода новостей на сайте engine/skins/images/blockpro.png 6.0.0 - 10.2 + 13 greater - http://blockpro.loc/check_updates.php - 1 + https://updates.pafnuty.name/check-bp.php + 0 + + 1 - - - + + + + + + + + + Release notes]]> \ No newline at end of file