abushyk

Модераторы
  • Публикации

    4036
  • Зарегистрирован

  • Посещение

  • Days Won

    269

Изменения репутации

  1. Like
    abushyk изменил репутацию soctell в Новый загрузчик   
    kupikuban.ru
  2. Like
    abushyk получил репутацию от Дмитрий Кондин в Приложения   
    Excel Free - обмен данными внутрь-наружу сайта из\в формат Excel
     
    GeoData - приложение для работы с картографией - вывод элемента типа geodata  в формах, геокодинг принудительный и на лету.
     
    Mailbox - посылка и прием сообщений с карточки на автора-владельца объявления
     
    RSS новостей сайта - выгрузка новостей и объявлений в rss-потоки для рсс-читалок
     
    SEO-Оптимизация - приложение для работы с видами отображений урлов+малеха дополнительный автоопраций
     
    SiteMap - карта сайта, ее генератор в xml (кажется)
     
    TLocation - специфичній єлемент для работы с геоданными(страна, город, регион) в виде единого комплекса. Не совместим с некоторыми приложениями. Подлежит эвтаназии.
     
    Авторизация через соц.сети - как следует из названия. Кажется в следующем обновлении будет доступна авторизация по ВК, ОК, ФБ, гугль и твиттер аккаунтам
     
    Баннеры - приложение для создания кусков разметки-баннеров, расставив метки которых в шаблоне, можно получить их отображение. Что-то типо модуля HTML-огрызка из Джумлы.
     
    Выгрузка Яндекс.Недвижимость - приложение для выгрузки объявлений и их параметров в формат Yandex.Недвижимость
     
    Галерея - организация альбомчиков картинок
     
    Заявки на аренду - сборщик зхаявок клиентов связанных с потребностью в аренде. Типа как подача объявления, только вместо объявления заявка.
     
    Клиенты - квазиуниверсальный сборщик самых разнообразных заявок+автоформирователь и обработчик произвольных форм на основе модели из Редактора Форм
     
    Менеджер валют - коллектор настроек связанных с валютой цены
     
    Менеджер настроек - Settings
     
    Новости - управление новостями
     
    Обновления - центр обновлений системы. отображает, что можно обновить и в каком состояниии в данный момент находятся приложения.
     
    Редактор форм - сердце сайтбилля)
     
    Редактор шаблонов - для тех, кто не освоил фтп и человедружественный редактор файлов есть возможность быстро и сердито подправить шаблончик. Очень ограничен в правах доступа к файлам даже в папке шаблона. Не говоря уже о том, что выше ее вообще не пустит.
     
    Статичные страницы - Некие странички, меняющиеся раз в сто лет и которые редко кто читает - типа лицензионного сообщения, хотя могут быть варианты)
     
    Управление кешем - забудьте, что вы его видели. А если еще и включили, то выключьте)
  3. Like
    abushyk получил репутацию от XTRO в Хлебные крошки   
    1. Базовый файл /apps/system/lib/frontend/view/kvartira_view.php
    2. Делаем /template/frontend/имя_шаблона/main/view/kvartira_view.php с содержимым
    class Local_Kvartira_View extends Kvartira_View {} 3. В /template/frontend/realia/main/main.php
    находим двоестрочия
    require_once(SITEBILL_DOCUMENT_ROOT.'/apps/system/lib/frontend/view/kvartira_view.php'); $kvartira_view = new Kvartira_View(); и заменяем их на require_once(SITEBILL_DOCUMENT_ROOT.'/apps/system/lib/frontend/view/kvartira_view.php'); require_once(SITEBILL_DOCUMENT_ROOT.'/template/frontend/'.$this->getConfigValue('theme').'/main/view/local_kvartira_view.php'); $kvartira_view = new Local_Kvartira_View();  
    4. Теперь мы имеем свой локальный обработчик просмотра карточки.
    5. Из базового файла (п.1) тянем в свой файл (п.2) функцию 
    protected function getBreadcrumbs($params){    require_once(SITEBILL_DOCUMENT_ROOT.'/apps/system/lib/admin/structure/structure_manager.php');    $Structure_Manager = new Structure_Manager();    $category_structure = $Structure_Manager->loadCategoryStructure();    return $this->get_category_breadcrumbs( $params, $category_structure, SITEBILL_MAIN_URL.'/' );} 6. И вот тут уже изголяемся. Можем придумать свой алгоритм ХК, можем использовать то, что есть.
    Например
    protected function getBreadcrumbs($params){     require_once(SITEBILL_DOCUMENT_ROOT.'/apps/system/lib/admin/structure/structure_manager.php');     $Structure_Manager = new Structure_Manager();     $category_structure = $Structure_Manager->loadCategoryStructure();     $bcstr=$this->get_category_breadcrumbs( $params, $category_structure, SITEBILL_MAIN_URL.'/' );$bcarray=explode(' / ', $bcstr);return implode('*', $bcarray);} В результате ХК склеенные звездочкой. Не самый оптимальный путь, но довольно быстрый.
     
    В целом, думаю, направление понятное.
  4. Like
    abushyk получил репутацию от Chernetskiy в Безопасность сайта   
    Это уже вроде бы не актуальная проблема. Конкретно по ид=1, насколько я помню, нет вообще обращений. Т.е. просто сносим пользователя с ид=1 и создаем своего в группе админов. Ну и данные, которые висят на старом было бы не плохо не забыть перенести.
     
    Относительно имени администратора вида "admin". Тоже не критично. Администратор может теперь иметь любое имя-логин. Бывают некоторые глюки, если использовать не admin, а что-то другое, но, большинство известных мне мест мы уже поправили. А если какие и остались, то поправим.
     
    В целом: для администратора сайта важно быть только в группе Администраторов.
     
    Есть только одно НО. Для некоторых аякс-операций и функций сообщений, как-то подача заявки, если на сайте несколько админов, самым "настоящим" будет считаться тот, который был добавлен первым. Самый яркий пример - невозможность сменить закладку расположения элемента формы в Редакторе форм прямо со списка элементов модели (даблкликом). Но войдя в редактирование элемента это уже возможно. Так же и с посылкой сообщений. При двух админах, сообщение уйдет первому из них. В некоторых модулях, которые не шибко популярны, либо не обновлены, сообщения могут перестать приходить, именно из-за ориентировки на имя админка в виде "admin".
  5. Like
    abushyk получил репутацию от Realtor в Cтраница с объектами агента /userХХ.html   
    Базовое решение.
     
    На примере шаблона agency
     
    1. /template/frontend/agency/main/main.php
    ищем строку
    if(!$has_result && preg_match('/user(\d+).html/', $_SERVER['REQUEST_URI'], $matches)){ которая открывает блок, где у нас рисуется сетка объявлений пользователя.
    После 
    $this->setRequestValue('user_id', (int)$matches[1]); делаем дополнение
    $DBC=DBC::getInstance();$query='SELECT fio, phone FROM '.DB_PREFIX.'_user WHERE user_id=?';$stmt=$DBC->query($query, array((int)$matches[1]));if($stmt){$ar=$DBC->fetch($stmt);$this->template->assert('grid_user_info', $ar);} Этот блок выбирает данные из таблицы юзеров. Список fio, phone можно расширить нужными вам именами из модели user. Не делаете 'SELECT * ', что бы не выхватывать пароли-явки. Только нужные поля.
     
    Теперь в переменной {$grid_user_info} шаблона у нас есть данные.
     
    2. /template/frontend/agency/realty_grid.tpl
    В этом шаблоне, в месте где должен быть вывод данных юзера, делаем проверку
    {if isset($grid_user_info)}...{/if} так как этот файл выводит все сетки, поэтому удостоверяемся, что данные есть.
    А внутри этогой проверки делаем нужный нам формат вывода. Например {if isset($grid_user_info)}<b>имя</b> {$grid_user_info.fio}{/if} В итоге, и в систему не влезли, и данные получили.
  6. Like
    abushyk получил репутацию от XTRO в Помещать изображения в подпапку   
    Проблема не в том, что бы разложить по папкам, а в том, что потом с ними делать и как эти картинки оттуда вынимать для шаблонов списков, просмотров, выводов в колонках, всяких экспортах в эксели, пдфы и хмл. Это ведь тоже надо прописать, что бы код знал КАК сформировать путь к файлу с картинкой. И что бы знал как удалить все картинки, привязанные к данному объявлению.
    А просто по папкам кинуть - это да, делается быстро.
  7. Like
    abushyk получил репутацию от Xlebosolniy в Некорректно работает watermark   
    Меню поддерживают только линейную структуру в один уровень. Так, что бы дерево в одно меню заложить не выйдет.
     
    Название подпункта(en) - это англоязычное название этого же пункта.
     
    Насчет текста и лого, скажите какой шаблон.
  8. Like
    abushyk получил репутацию от Xlebosolniy в Некорректно работает watermark   
    Все, о чем спрашивали, исправили?
  9. Like
    abushyk получил репутацию от Xlebosolniy в Некорректно работает watermark   
    Эти кнопочки, в 90% случаев заводятся через Контент - Меню. Смотрите в админке в левой боковой панельке.
    Скорее всего это либо Правое меню, либо Верхнее меню. Выберите кнопку Структура напротив него и вы получите доступ к его элементам - фактически этим кнопочкам. Там же сможете и добавить новый пункт.
    Если же надо добавить что-то более индивидуальное, то /template/frontend/agency/top_fixed_menu.tpl.html - это шаблон этой верхней полоски для агенси. Манипуляции с его разметкой могут дать более широкое поле для творчества. А само меню в нем выводится в
    {section name=i loop=$right_menu}<li><a href="{$right_menu[i].url}">{$right_menu[i].name}</a></li>{/section}
  10. Like
    abushyk изменил репутацию XTRO в Безопасность сайта   
    ещё как вариант (jquery) и капча вообще не нужна.
    Поскольку бот не умеет думать:
    -если submit завязан на GET, то при загрузке страницы дефолтную кнопку Отправить (type="submit") прячем жабой (append), добавляем жабой новый input (bind), но уже type="button", но него вешаем событие Save (ajax), в котором ещё добавляем флаг (немного избыточно, но не помешает) для проверки потом этого флага, но уже в  POST.
    В скрипте на входе смотрим: Если не POST или нет флага - досвидос.
  11. Like
    abushyk получил репутацию от Xlebosolniy в Некорректно работает watermark   
    Либо заверстать все это сразу в шаблоне.
    Либо создать два аггрегатора пунктов по типу Верхнее меню, вывести их в одном месте шаблона и с помощью стилей опять таки заверстать выпадалку. По сути будет, что все пункты одного меню будут играть роль пунктов в выпадающем списке.
  12. Like
    abushyk получил репутацию от Xlebosolniy в Отбражение на карте объекта   
    1. Не понял о какой именно карте речь, поэтому привожу два варианта
     
    /template/frontend/agency/map.tpl
    строка zoom: 16, измените 16 на меньшее число. 16 - это максимум
     
    /template/frontend/agency/realty_grid.tpl
    аналогично предыдущему.
     
    2. Не меняете его там! Делаете копию в свой шаблон с соблюдением пути. т.е. если папок /apps/admin нет, просто содайте их. Потом в них положите скопированный файл. И только тогда начинайте его править - тот, что вы скопировали себе в шаблон.
  13. Like
    abushyk получил репутацию от Xlebosolniy в Отбражение на карте объекта   
    Какой шаблон? И какая это карта? Та, что выводится на главной?
     
     
     
    Берем файл /apps/admin/admin/template/realty_grid.tpl
    Делаем его точную копию в 
    /template/frontend/имя_вашего_шаблона/apps/admin/template/realty_grid.tpl
    и уже в нем убираем строки
    <td width=13% class="row_title">{$L_CITY} <a href="{$url}&order=city&asc=asc">↓</a> <a href="{$url}&order=city&asc=desc">↑</a></td> и
    <td>{$grid_items[i].city}</td>
  14. Like
    abushyk получил репутацию от Александр Лубянский в Монетизация с помощью списков просмотров   
    Суть
     
    Разрешить просмотр контактных данных объявления для пользователей, которые подключили и оплатили некоторый список просмотра (СП). Список просмотра регламентирует количество дней на протяжении которых доступен просмотр контактов и стоимость данного периода.
    Подключение СП проходит через раздел Личного кабинета (ЛК), а оплата списка производится из ЛК посредством Робокассы.
    Намеренно исключаю возможность задания СП при регистрации, когда вместе с регистрационными данными пользователь должен выбрать конкретный вариант СП, что бы унифицировать процедуру пользования СП для обычных пользователей и пользователей регистрирующихся через соцсети.
    Пример будет приведен на базе шаблона realia, но для любого другого шаблона принцип будет аналогичен.
     
    Приницип работы
     
    При загрузке страницы происходит извлечение СП для текущего пользователя. Если есть в наличии хоть один активный для данного момента времени СП в переменную сессии сохраняется состояние "открыто". Этот параметр проверяется в местах, где необходим вывод контактны данных и средствами шаблона принимается решение - выводить или скрыть блок с контактными данными.
     
    Задействованные приложения
     
    registersms - приложение используется формально. Находится в выключенном состоянии и служит для хранения настроки соотношения периода СП и цены за этот период. В принципе не критично и может быть реализовано отдельной настройкой
    watchlistmanager - приложение-хранилище функционала для работы СП. Должно быть, быть включенным и установленным.
    настройки Робокассы - must have
     
    Необходимые файлы
     
    Набор вспомогательных файлов можно скачать тут
    Файлы в архиве расфасованы согласно структуре шаблона. Т.е. то, что находится в папке main должно лечь в папку main вашего шаблона etc.
     
    Изменения
     
    В файле main.php
     
    Внутри class frontend_main extends SiteBill_Krascap {...} добавляем функцию getViewOptions, которая загружает СП для пользователя. Код функции копируем из http://pastebin.com/8rMZNU4U
     
    В функции main() производим вызов вставленной выше функции и загрузку цен на СП из конфигурации. Общий код изменений тут
    Блок А вставляем после строк
    $work_subcontroller='';$has_result=false;$undetected_url=false; Блоком Б заменяем блок
    if ( !$has_result && preg_match('/\/robox/', $_SERVER['REQUEST_URI']) ) {...} Блоком В дополняем ветвистость 
    if ( preg_match('/^account\/profile/', $REQUESTURIPATH) ) { перед последним }else{
     
    В файле header.tpl
     
    Добавляем кусочек, заносящий цены в переменные скриптов
    {literal}<script type="text/javascript">var _costs={/literal}{if $_costs ne ''}{$_costs}{else}[]{/if}{literal};</script>{/literal} Блок ставится в любом месте между тегами <head> и </head>
     
    В файле realty_view.tpl
     
    Фактически основные функциональные изменения, которые скрывают контактные данные.
    Находим блок, отображающий контактные данные и обрамляем его конструкцией 
    {if $smarty.session.viewOptions.mode=='opened'}<!--Тут собственно контактные данные-->{else}Оплатите доступ к данным или другая информация{/if} Настройка
     
    Руководящими настройками для работы СП являются настройка цен. Соответствие цен и длительности периодов указывается в переменной Настройки - Регистрация через SMS - Стоимость категорий (apps.registersms.costs_array). Значения задаются в виде строки
    {N1:P1}{N2:P2}{N3:P3}{N4:P4}{N5:P5} - где N- длительность периода. По-умолчанию в днях. Р- стоимость этого периода.
    Например:
    {1:70}{2:100}{3:150} мы предусматриваем открытие просмотров контактов в вариантах на 1, 2 или 3 дня с соответствующими стоимостями 70, 100 и 150 рублей.
     
    Кроме этого места необходимо еще указать допустимые периоды (продублировать) в обработчике СП - /template/frontend/шаблон/main/local_watchlistmanager.php. В этом файле необходимо найти функцию getWLModel() и в ней изменить строку 
    $form_data['period']['grade_values'] = array('1', '2', '3', '7', '31'); где указать наш перечень периодов
    $form_data['period']['grade_values'] = array('1', '2', '3'); Замечание
     
    Шаблон realia оборудован плагином-украшателем ezMark, который, не смотря на свою красивость, доказал несостоятельность при работе с элементами типа radio - кружочки с точечками в форме. Поскольку форма добавления СП использует именно такие элементы, а в остальных формах мы практически не используем их, то рекомендую сузить область работы этого плагина только элементами типа checkbox.
    Для этого в файле /template/frontend/realia/js/realia.js в функции InitEzmark() следует закомментировать строку
    $('input[type="radio"]').ezMark();
  15. Like
    abushyk получил репутацию от tazam в Монетизация с помощью списков просмотров   
    Суть
     
    Разрешить просмотр контактных данных объявления для пользователей, которые подключили и оплатили некоторый список просмотра (СП). Список просмотра регламентирует количество дней на протяжении которых доступен просмотр контактов и стоимость данного периода.
    Подключение СП проходит через раздел Личного кабинета (ЛК), а оплата списка производится из ЛК посредством Робокассы.
    Намеренно исключаю возможность задания СП при регистрации, когда вместе с регистрационными данными пользователь должен выбрать конкретный вариант СП, что бы унифицировать процедуру пользования СП для обычных пользователей и пользователей регистрирующихся через соцсети.
    Пример будет приведен на базе шаблона realia, но для любого другого шаблона принцип будет аналогичен.
     
    Приницип работы
     
    При загрузке страницы происходит извлечение СП для текущего пользователя. Если есть в наличии хоть один активный для данного момента времени СП в переменную сессии сохраняется состояние "открыто". Этот параметр проверяется в местах, где необходим вывод контактны данных и средствами шаблона принимается решение - выводить или скрыть блок с контактными данными.
     
    Задействованные приложения
     
    registersms - приложение используется формально. Находится в выключенном состоянии и служит для хранения настроки соотношения периода СП и цены за этот период. В принципе не критично и может быть реализовано отдельной настройкой
    watchlistmanager - приложение-хранилище функционала для работы СП. Должно быть, быть включенным и установленным.
    настройки Робокассы - must have
     
    Необходимые файлы
     
    Набор вспомогательных файлов можно скачать тут
    Файлы в архиве расфасованы согласно структуре шаблона. Т.е. то, что находится в папке main должно лечь в папку main вашего шаблона etc.
     
    Изменения
     
    В файле main.php
     
    Внутри class frontend_main extends SiteBill_Krascap {...} добавляем функцию getViewOptions, которая загружает СП для пользователя. Код функции копируем из http://pastebin.com/8rMZNU4U
     
    В функции main() производим вызов вставленной выше функции и загрузку цен на СП из конфигурации. Общий код изменений тут
    Блок А вставляем после строк
    $work_subcontroller='';$has_result=false;$undetected_url=false; Блоком Б заменяем блок
    if ( !$has_result && preg_match('/\/robox/', $_SERVER['REQUEST_URI']) ) {...} Блоком В дополняем ветвистость 
    if ( preg_match('/^account\/profile/', $REQUESTURIPATH) ) { перед последним }else{
     
    В файле header.tpl
     
    Добавляем кусочек, заносящий цены в переменные скриптов
    {literal}<script type="text/javascript">var _costs={/literal}{if $_costs ne ''}{$_costs}{else}[]{/if}{literal};</script>{/literal} Блок ставится в любом месте между тегами <head> и </head>
     
    В файле realty_view.tpl
     
    Фактически основные функциональные изменения, которые скрывают контактные данные.
    Находим блок, отображающий контактные данные и обрамляем его конструкцией 
    {if $smarty.session.viewOptions.mode=='opened'}<!--Тут собственно контактные данные-->{else}Оплатите доступ к данным или другая информация{/if} Настройка
     
    Руководящими настройками для работы СП являются настройка цен. Соответствие цен и длительности периодов указывается в переменной Настройки - Регистрация через SMS - Стоимость категорий (apps.registersms.costs_array). Значения задаются в виде строки
    {N1:P1}{N2:P2}{N3:P3}{N4:P4}{N5:P5} - где N- длительность периода. По-умолчанию в днях. Р- стоимость этого периода.
    Например:
    {1:70}{2:100}{3:150} мы предусматриваем открытие просмотров контактов в вариантах на 1, 2 или 3 дня с соответствующими стоимостями 70, 100 и 150 рублей.
     
    Кроме этого места необходимо еще указать допустимые периоды (продублировать) в обработчике СП - /template/frontend/шаблон/main/local_watchlistmanager.php. В этом файле необходимо найти функцию getWLModel() и в ней изменить строку 
    $form_data['period']['grade_values'] = array('1', '2', '3', '7', '31'); где указать наш перечень периодов
    $form_data['period']['grade_values'] = array('1', '2', '3'); Замечание
     
    Шаблон realia оборудован плагином-украшателем ezMark, который, не смотря на свою красивость, доказал несостоятельность при работе с элементами типа radio - кружочки с точечками в форме. Поскольку форма добавления СП использует именно такие элементы, а в остальных формах мы практически не используем их, то рекомендую сузить область работы этого плагина только элементами типа checkbox.
    Для этого в файле /template/frontend/realia/js/realia.js в функции InitEzmark() следует закомментировать строку
    $('input[type="radio"]').ezMark();
  16. Like
    abushyk получил репутацию от Дмитрий Кондин в Видеоблог   
    Суслики - это класс) Живенькое такое)
  17. Like
    abushyk получил репутацию от Xlebosolniy в Улица прописью   
    В редакторе форм в таблице data выберите поле street_id, откройте его на редактирование и в разделе параметры добавьте пераметр autocomplete=1

    и посмотрите в форме это ли имелось в виду.
  18. Like
    abushyk получил репутацию от Realtor в Предложения для будущих версий.   
    Это уже второй запрос на подобную опцию. Видать придется делать)
  19. Like
    abushyk получил репутацию от YUR@ в добавить новые поля в поиск (template_search и др.)   
    Итак, мы имеем набор полей:
     
    is_wifi Наличие интернета - поле типа checkbox. На форме присутствует в сиде чекбокса.
    floor_type Тип покрытия пола - select_box с вариантами {0~~не указано}{1~~плитка}{2~~дерево}{3~~ламинат} - отображается в виде выпадающего списка
    sea_distance Расстояние до моря. Тип safe_string, но отмеченный как is_ranged=1, что бы в форме поиска выводилось в виде двух полей - макс. и мин. значения.
     
    Мы добавили эти поля в модель, каким-то образом разместили их на формах поиска. Теперь главная задача - заставить движек обработать их.
    Для этого существует файл шаблонного поиска, который размещается в /template/frontend/имя_шаблона/main/ и носит имя template_search.php и не иначе.
    При наличии этого файла движек автоматически обратится к нему и запросит данные для осуществления выборки.
    В минимальной комплектации этот файл состоит из класса и двух функций:
    http://pastebin.com/TmBSS9q8
     
    Задача функции getParams забрать данные из запроса и подумать, стоит ли их передавать дальше.
    А функции run, к которой обращается движек за данными, решить каким образом следует сравнить\обработать полученные параметры для формирования нужной выборки данных.
     
    Итак, поехали.
    1
    Начнем с самого простого - чекбокса is_wifi. Чекбоксы отличаются тем, что в запросе они либо приходят, либо нет.
    Из запроса берем его функцией $this->getRequestValue('is_wifi'), которая возвращает значение NULL, если такого параметра не существует.
    if(NULL!==$this->getRequestValue('is_wifi')){
    $params['is_wifi'] = 1;
    }
     
    Проверили, не пусто ли, если нет, значит чекбокс отметили и мы записываем его в $params  в виде утвердительной единицы. Единицы потому, что в принципе больше нам инфы не нужно, достаточно знать, что параметр запрошен.
     
    Дальше floor_type. Этот тип передается в запрос в виде ключа своих значений. Т.е. выбрав "дерево" в запрос у нас приедет "2". Значит мы знаем, что будет целая цифра.
    if(0!==(int)$this->getRequestValue('floor_type')){
    $params['floor_type'] = (int)$this->getRequestValue('floor_type');
    }
     
    Мы гарантированно делаем из значения параметра целое число с помощью (int) и сравниваем его с 0 - нашим значением никакого значения. Если оно не равно нулю, значит пользователь запросил конкретный тип покрытия и мы сохраняем его значение в $params['floor_type']. Но сохраняем уже конкретным начением, таккак, в отличии от чекбокса, тут нам важно само значение, а не его наличие.
     
    sea_distance. При использовании пользовательских форм, которые енерирует движек на основе ваших выборок это поле представится в виде двух полей с именами созданными по принципу sea_distance_min и sea_distance_max. Соотв. и дву переменные прийдут в запросе. Каждую ловим отдельно.
    Для простоты допустим, что мы готовы обработать целые расстояния до моря: 1, 5, 100.
    if(0!==(int)$this->getRequestValue('sea_distance_min')){
    $params['sea_distance_min'] = (int)$this->getRequestValue('sea_distance_min');
    }
    if(0!==(int)$this->getRequestValue('sea_distance_max')){
    $params['sea_distance_max'] = (int)$this->getRequestValue('sea_distance_max');
    }
    Принцип прост. Мы приводим значение к целому. Если пользователь вписал в поле не число, а "аврцуоац" строку, она приведется к нулю. И сравниваем все это с нулем. Искать по нулевому значению смысла нет, поэтому мы сохраняем только те значения, которые от него отличны. Разницы между мин и макс значением в момент их забора из запроса мы не делаем. Она не важна сейчас, но будет важна в следующей функции.
     
    2
    Переходим к функции run()
     
    Методика ее работы такая
    1. взять параметр
    2. создать кусочек запроса.
     
    Для чекбокса
    if(isset($params['is_wifi']) && isset($data_model_array['is_wifi'])){ $where_array[]=DB_PREFIX.'_data.is_wifi=1'; } Расшифровка. Проверяем, есть ли в параметрах запроса переменная is_wifi  и есть ли в нашей модели поле с таким именем (так как условие может быть, а поле мы давно погасили за ненадобностью). Если все эти условия выполнены, мы указываем, что хотим дополнить условия нашего запроса сравнением, которое выберет записи, где is_wifi равно1, т.е. при сохранении записи был отмечен чекбокс.   Для floor_type if(isset($params['floor_type']) && isset($data_model_array['floor_type'])){ $where_array[]=DB_PREFIX.'_data.floor_type='.$params['floor_type']; } Все аналогично предыдущему за исключением того, что тут мы просим сравнить поле floor_type записи, которое хранит ключ указанного типа покрытия, с переданным в запросе.
     
    Для ранжированного sea_distance
    if(isset($params['sea_distance_min']) && isset($data_model_array['sea_distance'])){ $where_array[]=DB_PREFIX.'_data.sea_distance*1>='.$params['sea_distance_min']; } if(isset($params['sea_distance_max']) && isset($data_model_array['sea_distance'])){ $where_array[]=DB_PREFIX.'_data.sea_distance*1<='.$params['sea_distance_max']; } И тут почти без изменений. Главное отличие - мы устанавливаем условия в зависимости от того _max или _min параметр мы хотим сравнить. Обратите внимание на DB_PREFIX.'_data.sea_distance*1. В неоптимизированных БД сайтбилля поля под safe_string имеют строковой тип. Поэтому, что бы не было строкового сравнения, где строковое "2" больше строкового "100", мы принудительно делаем значение поля числом перед сравнением. И тогда уже будет натуральное сравнение, где 2<100.
     
    и вот примерно вот так http://pastebin.com/8jX7WEEH все єто будет выглядеть в конце.
  20. Like
    abushyk получил репутацию от Дмитрий Кондин в добавить новые поля в поиск (template_search и др.)   
    Итак, мы имеем набор полей:
     
    is_wifi Наличие интернета - поле типа checkbox. На форме присутствует в сиде чекбокса.
    floor_type Тип покрытия пола - select_box с вариантами {0~~не указано}{1~~плитка}{2~~дерево}{3~~ламинат} - отображается в виде выпадающего списка
    sea_distance Расстояние до моря. Тип safe_string, но отмеченный как is_ranged=1, что бы в форме поиска выводилось в виде двух полей - макс. и мин. значения.
     
    Мы добавили эти поля в модель, каким-то образом разместили их на формах поиска. Теперь главная задача - заставить движек обработать их.
    Для этого существует файл шаблонного поиска, который размещается в /template/frontend/имя_шаблона/main/ и носит имя template_search.php и не иначе.
    При наличии этого файла движек автоматически обратится к нему и запросит данные для осуществления выборки.
    В минимальной комплектации этот файл состоит из класса и двух функций:
    http://pastebin.com/TmBSS9q8
     
    Задача функции getParams забрать данные из запроса и подумать, стоит ли их передавать дальше.
    А функции run, к которой обращается движек за данными, решить каким образом следует сравнить\обработать полученные параметры для формирования нужной выборки данных.
     
    Итак, поехали.
    1
    Начнем с самого простого - чекбокса is_wifi. Чекбоксы отличаются тем, что в запросе они либо приходят, либо нет.
    Из запроса берем его функцией $this->getRequestValue('is_wifi'), которая возвращает значение NULL, если такого параметра не существует.
    if(NULL!==$this->getRequestValue('is_wifi')){
    $params['is_wifi'] = 1;
    }
     
    Проверили, не пусто ли, если нет, значит чекбокс отметили и мы записываем его в $params  в виде утвердительной единицы. Единицы потому, что в принципе больше нам инфы не нужно, достаточно знать, что параметр запрошен.
     
    Дальше floor_type. Этот тип передается в запрос в виде ключа своих значений. Т.е. выбрав "дерево" в запрос у нас приедет "2". Значит мы знаем, что будет целая цифра.
    if(0!==(int)$this->getRequestValue('floor_type')){
    $params['floor_type'] = (int)$this->getRequestValue('floor_type');
    }
     
    Мы гарантированно делаем из значения параметра целое число с помощью (int) и сравниваем его с 0 - нашим значением никакого значения. Если оно не равно нулю, значит пользователь запросил конкретный тип покрытия и мы сохраняем его значение в $params['floor_type']. Но сохраняем уже конкретным начением, таккак, в отличии от чекбокса, тут нам важно само значение, а не его наличие.
     
    sea_distance. При использовании пользовательских форм, которые енерирует движек на основе ваших выборок это поле представится в виде двух полей с именами созданными по принципу sea_distance_min и sea_distance_max. Соотв. и дву переменные прийдут в запросе. Каждую ловим отдельно.
    Для простоты допустим, что мы готовы обработать целые расстояния до моря: 1, 5, 100.
    if(0!==(int)$this->getRequestValue('sea_distance_min')){
    $params['sea_distance_min'] = (int)$this->getRequestValue('sea_distance_min');
    }
    if(0!==(int)$this->getRequestValue('sea_distance_max')){
    $params['sea_distance_max'] = (int)$this->getRequestValue('sea_distance_max');
    }
    Принцип прост. Мы приводим значение к целому. Если пользователь вписал в поле не число, а "аврцуоац" строку, она приведется к нулю. И сравниваем все это с нулем. Искать по нулевому значению смысла нет, поэтому мы сохраняем только те значения, которые от него отличны. Разницы между мин и макс значением в момент их забора из запроса мы не делаем. Она не важна сейчас, но будет важна в следующей функции.
     
    2
    Переходим к функции run()
     
    Методика ее работы такая
    1. взять параметр
    2. создать кусочек запроса.
     
    Для чекбокса
    if(isset($params['is_wifi']) && isset($data_model_array['is_wifi'])){ $where_array[]=DB_PREFIX.'_data.is_wifi=1'; } Расшифровка. Проверяем, есть ли в параметрах запроса переменная is_wifi  и есть ли в нашей модели поле с таким именем (так как условие может быть, а поле мы давно погасили за ненадобностью). Если все эти условия выполнены, мы указываем, что хотим дополнить условия нашего запроса сравнением, которое выберет записи, где is_wifi равно1, т.е. при сохранении записи был отмечен чекбокс.   Для floor_type if(isset($params['floor_type']) && isset($data_model_array['floor_type'])){ $where_array[]=DB_PREFIX.'_data.floor_type='.$params['floor_type']; } Все аналогично предыдущему за исключением того, что тут мы просим сравнить поле floor_type записи, которое хранит ключ указанного типа покрытия, с переданным в запросе.
     
    Для ранжированного sea_distance
    if(isset($params['sea_distance_min']) && isset($data_model_array['sea_distance'])){ $where_array[]=DB_PREFIX.'_data.sea_distance*1>='.$params['sea_distance_min']; } if(isset($params['sea_distance_max']) && isset($data_model_array['sea_distance'])){ $where_array[]=DB_PREFIX.'_data.sea_distance*1<='.$params['sea_distance_max']; } И тут почти без изменений. Главное отличие - мы устанавливаем условия в зависимости от того _max или _min параметр мы хотим сравнить. Обратите внимание на DB_PREFIX.'_data.sea_distance*1. В неоптимизированных БД сайтбилля поля под safe_string имеют строковой тип. Поэтому, что бы не было строкового сравнения, где строковое "2" больше строкового "100", мы принудительно делаем значение поля числом перед сравнением. И тогда уже будет натуральное сравнение, где 2<100.
     
    и вот примерно вот так http://pastebin.com/8jX7WEEH все єто будет выглядеть в конце.
  21. Like
    abushyk получил репутацию от XTRO в Пропали объявления   
    В ближайшее время будет обновление где мы избавились от этого досадного глюка - неотображения объявления с неуказанным типом недвижимости.
  22. Like
    abushyk получил репутацию от Realtor в Предложения для будущих версий.   
    1. Делаем заготовку кнопки
    <a href="#" class="btn reset_form">Очистить</a> 2. Открываем /template/frontend/agency/standart_search_form.tpl
    Там описаны две формы - простая и расширенная. Внутри каждой размещаем эту кнопку.
     
    3. Открываем /template/frontend/agency/js/search_form.js
    Внутрь блока 
    $(document).ready(function(){
    ...
    })
     
    добавляем
    $('.reset_form').click(function(e){var form=$(this).parents('form').eq(0);form.find('select').val('');form.find('input').not('[type=hidden]').val('');form.find('textarea').val('');e.preventDeault();});
  23. Like
    abushyk получил репутацию от Realtor в Предложения для будущих версий.   
    Это задача на диссертацию. Потому, что у каждого конкретного случая будет свое понимание того, какое значение в поле считать "установленным", а какое нет. Ведь даже пустое поле при некоторых условиях может расцениваться как "заполненное пустым значением".
  24. Like
    abushyk получил репутацию от InfernoLan в Поиск во вкладках (добавление новых параметров)   
    Вот базовый файл для организации поиска http://pastebin.com/dYmUkjC1
    имя его должно быть template_search.php и располагаться он должен по адресу /template/frontend/имя_вашего_шаблона/main/template_search.php
     
    Обработка состоит из двух этапов.
    1. Перехват параметра.
    строки 6-8
    Вы ловите переменную из запроса, проверяете имеет ли она значение. Так как пустое и нулевое значение вас не интересует, вы апоминаете только отличные от нуля.
    2. Обработка параметра.
    строки 28-30
    Вы берете запомненные переменные и проверяете есть ли такие в ващей модели. Если есть, вы формируете кусочек запроса, который укажет в каком поле базы данных искать это значение. Для параметра is_telephone это будет соттв. поле is_telephone .
     
    После этого движек сам запросит этот файл и получит из него рекомендации, как искать ваши параметры.
     
    Для обработки поля Интернет с такими же параметрами вы делаете дубль строк 6-8 и 28-30 после существующих и меняете имя обрабатываемого параметра с is_telephone на is_internet или как у вас будет системное имя данного поля.
  25. Like
    abushyk получил репутацию от infected1992 в Вывод категорий новостей   
    Функция выборки
    function getMyNewsAssorty(){if(''!=$this->getConfigValue('apps.news.item_alias')){$app_item_alias=$this->getConfigValue('apps.news.item_alias');}else{$app_item_alias='news';}$news=array();$DBC=DBC::getInstance();//Например хотим выбирать из категорий с ид=1 и 2$query='SELECT * FROM '.DB_PREFIX.'_news WHERE `news_topic_id` IN(1,2) ORDER BY `date` DESC'; $stmt=$DBC->query($query);if($stmt){while($ar=$DBC->fetch($stmt)){$ar['href']=SITEBILL_MAIN_URL.'/'.$app_item_alias.$ar['news_id'].'.html';$news[$ar['news_topic_id']][]=$ar;}}return $news;} Должна быть размещена в /template/frontend/имя_вашего_шаблона/main/main.php внутри class frontend_main extends SiteBill_Krascap { }
     
    ПС. Запрос к БД в функции "жадный". Тут можно оптимизировать, если новостей очень много и надо выбрать только по некоторому количеству для каждой категории, то лучше сделать два запроса на конкретные категории и ограничить их с помощью LIMIT.
     
    Вызов
    $this->template->assert('my_news_assorty', $this->getMyNewsAssorty()); размещается в том же файле, но уже внутри функции main(). Не важно в каком месте, но оптимально сразу же после строки global $__site_title, $folder, $smarty;
     
    Вывод (пример)
    <!--Вывод новостей из категории 1-->{if $my_news_assorty[1]|count>0}{foreach from=$my_news_assorty[1] item=mynews1}<a href="{$mynews1.href}">{$mynews1.title}</a>{/foreach}{/if}<!--Вывод новостей из категории 2-->{if $my_news_assorty[2]|count>0}{foreach from=$my_news_assorty[2] item=mynews1}<a href="{$mynews1.href}">{$mynews1.title}</a>{/foreach}{/if} их ставится уже где-то в шаблоне.