YUR@

Участники
  • Публикации

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

  • Посещение


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

  1. Like
    YUR@ изменил репутацию TopRaN в Стиализуем Checkbox   
    Задача. Наложить стили на обычный Checkbox без js и jquery. использовав только чистый сss3
     
    Решение 
    1. В html (tpl) сам checkbox выглядит следующим образом:
     
    <input type="checkbox" value="" id="" name="">
     
    2. Теперь нам нужно создать групповую разметку 
     
    <div class="squaredThree">
        <input type="checkbox" value="None" id="squaredThree" name="check">
        <label for="squaredThree"></label>
    </div>
     
    3. После того как разметка готова приступаем к написанию стилей.
     
    input[type=checkbox] {
        visibility: hidden;

     
    таким образом мы скрываем к показу стандартный checkbox
     
    4. Создаем стиль для разметки
    .squaredThree {
        width: 20px;    
        margin: 20px auto;
        position: relative;
    }
     
    5. Добавляем метку и фильтры, так же не забываем про обработку в IE
    .squaredThree label {
        cursor: pointer;
        position: absolute;
        width: 20px;
        height: 20px;
        top: 0;
        border-radius: 4px;

        -webkit-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,.4);
        -moz-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,.4);
        box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,.4);

        background: -webkit-linear-gradient(top, #222 0%, #45484d 100%);
        background: -moz-linear-gradient(top, #222 0%, #45484d 100%);
        background: -o-linear-gradient(top, #222 0%, #45484d 100%);
        background: -ms-linear-gradient(top, #222 0%, #45484d 100%);
        background: linear-gradient(top, #222 0%, #45484d 100%);
        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#222', endColorstr='#45484d',GradientType=0 );
    }
    6. Применим к нашем стилям и метки -  After. Псевдоэлемент, который используется для вывода желаемого текста после содержимого элемента
    .squaredThree label:after {
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
        filter: alpha(opacity=0);
        opacity: 0;
        content: '';
        position: absolute;
        width: 9px;
        height: 5px;
        background: transparent;
        top: 4px;
        left: 4px;
        border: 3px solid #fcfff4;
        border-top: none;
        border-right: none;

        -webkit-transform: rotate(-45deg);
        -moz-transform: rotate(-45deg);
        -o-transform: rotate(-45deg);
        -ms-transform: rotate(-45deg);
        transform: rotate(-45deg);
    }
    7. Теперь мы добавляем фильтры псевдоэлементу в режими активности (наведения)
    .squaredThree label:hover::after {
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
        filter: alpha(opacity=30);
        opacity: 0.3;
    }
    8. Компонуем условие отображения.
    .squaredThree input[type=checkbox]:checked + label:after {
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
        filter: alpha(opacity=100);
        opacity: 1;
    }
  2. Like
    YUR@ изменил репутацию Chernetskiy в .htaccess   
    Еще не помещает добавить IP-адреса, с которых лезут любители подбора паролей в админку и достают сайт сутками на автомате.
    На практике получилось вот такое дополнение на 338 адресов:
     
    Order Deny,Allow
    Deny from 1.4.255.41
    Deny from 2.101.106.27
    Deny from 2.139.251.20
    Deny from 2.90.121.116
    Deny from 5.107.116.205
    Deny from 5.13.11.57
    Deny from 5.135.165.206
    Deny from 5.167.3.168
    Deny from 5.19.234.35
    Deny from 5.39.106.19
    Deny from 5.54.152.129
    Deny from 5.9.121.109
    Deny from 23.23.87.178
    Deny from 23.253.90.79
    Deny from 24.114.29.162
    Deny from 27.251.83.10
    Deny from 27.253.71.95
    Deny from 31.168.149.56
    Deny from 31.193.192.184
    Deny from 31.209.208.213
    Deny from 31.25.28.142
    Deny from 36.75.106.15
    Deny from 36.75.56.21
    Deny from 36.76.96.172
    Deny from 37.1.27.104
    Deny from 37.141.77.255
    Deny from 37.187.79.43
    Deny from 37.205.32.122
    Deny from 37.209.251.137
    Deny from 37.248.254.128
    Deny from 37.48.87.44
    Deny from 37.57.200.107
    Deny from 37.59.29.48
    Deny from 37.59.35.4
    Deny from 39.32.159.221
    Deny from 39.45.6.12
    Deny from 39.48.247.132
    Deny from 39.50.184.100
    Deny from 41.13.216.81
    Deny from 41.220.173.112
    Deny from 41.251.80.222
    Deny from 41.66.242.74
    Deny from 46.105.14.54
    Deny from 46.118.127.32
    Deny from 46.118.159.96
    Deny from 46.163.78.167
    Deny from 46.197.172.117
    Deny from 46.219.84.208
    Deny from 46.249.47.194
    Deny from 46.4.20.133
    Deny from 49.145.99.61
    Deny from 50.2.223.207
    Deny from 50.28.80.217
    Deny from 54.207.31.52
    Deny from 54.254.240.147
    Deny from 58.178.132.63
    Deny from 58.27.155.199
    Deny from 59.44.60.161
    Deny from 60.12.119.200
    Deny from 61.6.246.92
    Deny from 62.150.92.182
    Deny from 62.20.171.13
    Deny from 62.21.117.60
    Deny from 62.210.139.80
    Deny from 62.254.165.178
    Deny from 64.15.138.14
    Deny from 64.31.25.60
    Deny from 64.34.173.227
    Deny from 65.124.232.124
    Deny from 66.147.235.81
    Deny from 66.56.185.151
    Deny from 67.227.174.86
    Deny from 69.175.111.218
    Deny from 71.164.231.54
    Deny from 72.229.33.46
    Deny from 72.27.103.65
    Deny from 72.27.208.197
    Deny from 73.177.193.159
    Deny from 73.53.227.16
    Deny from 74.208.184.251
    Deny from 74.86.72.18
    Deny from 76.30.135.93
    Deny from 77.78.12.143
    Deny from 77.89.199.86
    Deny from 78.110.86.152
    Deny from 78.170.194.135
    Deny from 78.184.231.193
    Deny from 78.63.220.46
    Deny from 78.88.25.40
    Deny from 79.115.3.64
    Deny from 79.121.58.136
    Deny from 79.180.112.114
    Deny from 79.254.146.127
    Deny from 80.249.163.1
    Deny from 80.78.71.173
    Deny from 81.134.20.2
    Deny from 81.177.174.70
    Deny from 81.214.1.192
    Deny from 81.29.19.213
    Deny from 82.145.135.130
    Deny from 82.165.143.210
    Deny from 83.39.242.112
    Deny from 83.96.132.85
    Deny from 83.99.139.223
    Deny from 84.108.100.122
    Deny from 84.197.93.180
    Deny from 84.94.64.229
    Deny from 85.112.29.210
    Deny from 85.204.118.142
    Deny from 85.214.50.184
    Deny from 85.214.64.100
    Deny from 85.247.141.160
    Deny from 85.65.3.186
    Deny from 86.124.88.48
    Deny from 86.96.34.163
    Deny from 87.1.127.123
    Deny from 87.236.232.254
    Deny from 87.255.57.169
    Deny from 87.68.254.50
    Deny from 88.151.245.66
    Deny from 88.190.45.37
    Deny from 88.196.133.245
    Deny from 88.249.225.207
    Deny from 89.134.175.163
    Deny from 89.134.74.108
    Deny from 89.152.232.240
    Deny from 89.155.56.39
    Deny from 89.205.114.197
    Deny from 89.35.148.42
    Deny from 89.44.232.27
    Deny from 90.163.13.26
    Deny from 90.165.168.118
    Deny from 90.198.222.171
    Deny from 91.109.14.204
    Deny from 91.109.3.166
    Deny from 91.123.193.54
    Deny from 91.127.94.104
    Deny from 91.192.155.138
    Deny from 91.192.217.199
    Deny from 91.200.12.171
    Deny from 91.200.13.64
    Deny from 91.200.14.72
    Deny from 91.202.25.217
    Deny from 91.207.7.49
    Deny from 91.221.70.208
    Deny from 91.223.223.155
    Deny from 91.73.203.234
    Deny from 92.60.237.170
    Deny from 92.84.14.137
    Deny from 92.99.253.197
    Deny from 93.10.145.26
    Deny from 93.113.20.99
    Deny from 93.118.223.126
    Deny from 93.123.85.15
    Deny from 93.143.189.206
    Deny from 93.159.128.46
    Deny from 93.173.251.69
    Deny from 93.45.245.177
    Deny from 93.86.87.88
    Deny from 93.87.228.126
    Deny from 94.138.219.186
    Deny from 94.23.28.193
    Deny from 94.71.96.14
    Deny from 95.110.145.224
    Deny from 95.134.169.85
    Deny from 95.158.48.96
    Deny from 95.178.186.237
    Deny from 95.236.74.241
    Deny from 95.37.96.253
    Deny from 97.74.197.37
    Deny from 99.43.176.46
    Deny from 103.251.83.6
    Deny from 103.251.90.116
    Deny from 103.9.101.81
    Deny from 105.228.140.226
    Deny from 105.237.48.132
    Deny from 106.187.102.104
    Deny from 107.145.147.157
    Deny from 108.80.204.99
    Deny from 109.100.51.48
    Deny from 109.101.45.167
    Deny from 109.160.244.203
    Deny from 109.184.51.184
    Deny from 109.184.75.45
    Deny from 109.190.37.141
    Deny from 109.229.67.169
    Deny from 109.64.124.115
    Deny from 109.65.2.94
    Deny from 110.44.123.159
    Deny from 111.252.12.90
    Deny from 111.68.47.229
    Deny from 112.210.164.217
    Deny from 112.78.112.237
    Deny from 114.108.237.92
    Deny from 114.113.145.149
    Deny from 115.124.92.14
    Deny from 116.193.173.187
    Deny from 117.102.34.225
    Deny from 117.200.240.205
    Deny from 118.137.248.214
    Deny from 119.159.109.69
    Deny from 120.198.230.11
    Deny from 120.28.253.3
    Deny from 121.179.151.183
    Deny from 121.54.54.131
    Deny from 122.213.243.131
    Deny from 122.55.28.66
    Deny from 123.30.137.219
    Deny from 123.30.208.178
    Deny from 124.109.191.201
    Deny from 124.125.50.104
    Deny from 124.13.125.22
    Deny from 124.43.68.1
    Deny from 124.6.181.54
    Deny from 125.212.220.77
    Deny from 125.253.118.46
    Deny from 125.27.240.253
    Deny from 129.7.242.159
    Deny from 133.242.22.177
    Deny from 139.0.44.143
    Deny from 139.193.143.132
    Deny from 14.52.254.209
    Deny from 141.85.227.117
    Deny from 144.76.180.27
    Deny from 144.76.219.151
    Deny from 146.185.232.226
    Deny from 151.236.247.200
    Deny from 151.236.51.55
    Deny from 153.191.243.147
    Deny from 162.211.82.114
    Deny from 162.42.239.248
    Deny from 163.178.104.96
    Deny from 164.138.92.79
    Deny from 164.138.92.85
    Deny from 166.63.127.244
    Deny from 166.78.169.147
    Deny from 168.167.142.53
    Deny from 172.2.154.177
    Deny from 172.249.162.139
    Deny from 173.214.189.104
    Deny from 175.126.111.78
    Deny from 175.140.89.184
    Deny from 176.102.37.60
    Deny from 176.119.3.46
    Deny from 176.41.254.221
    Deny from 176.9.145.55
    Deny from 177.42.222.125
    Deny from 177.70.21.29
    Deny from 177.81.201.200
    Deny from 177.98.253.251
    Deny from 178.137.212.129
    Deny from 178.137.84.60
    Deny from 178.84.161.81
    Deny from 179.185.46.210
    Deny from 179.216.247.67
    Deny from 180.178.61.194
    Deny from 181.164.35.215
    Deny from 182.160.155.72
    Deny from 182.183.242.34
    Deny from 182.48.191.233
    Deny from 182.58.44.248
    Deny from 184.154.88.18
    Deny from 184.168.112.26
    Deny from 184.171.240.27
    Deny from 184.82.179.101
    Deny from 185.9.157.31
    Deny from 186.207.63.160
    Deny from 186.214.31.150
    Deny from 187.188.128.158
    Deny from 187.189.15.106
    Deny from 187.37.25.76
    Deny from 188.121.62.249
    Deny from 188.132.210.36
    Deny from 188.165.201.137
    Deny from 188.191.53.8
    Deny from 188.229.27.253
    Deny from 188.27.215.130
    Deny from 188.54.32.77
    Deny from 188.77.89.246
    Deny from 188.92.76.98
    Deny from 189.14.2.220
    Deny from 189.166.44.71
    Deny from 189.169.49.171
    Deny from 189.235.138.154
    Deny from 190.167.175.234
    Deny from 190.17.146.152
    Deny from 190.199.253.175
    Deny from 190.230.114.29
    Deny from 190.249.130.16
    Deny from 192.162.241.253
    Deny from 192.187.99.194
    Deny from 192.210.141.184
    Deny from 193.201.224.154
    Deny from 194.247.12.70
    Deny from 195.154.117.65
    Deny from 195.154.178.51
    Deny from 195.154.226.99
    Deny from 195.228.188.6
    Deny from 195.252.96.50
    Deny from 197.148.16.70
    Deny from 197.40.121.199
    Deny from 197.40.92.70
    Deny from 198.23.103.91
    Deny from 198.57.210.25
    Deny from 198.89.122.74
    Deny from 199.201.88.64
    Deny from 199.246.2.94
    Deny from 200.126.81.178
    Deny from 202.177.25.123
    Deny from 202.70.136.15
    Deny from 203.195.184.151
    Deny from 205.186.142.240
    Deny from 207.58.135.162
    Deny from 208.84.244.10
    Deny from 209.59.133.206
    Deny from 209.59.164.209
    Deny from 210.172.144.32
    Deny from 210.210.178.20
    Deny from 211.110.140.70
    Deny from 211.25.228.71
    Deny from 212.48.66.246
    Deny from 212.85.38.92
    Deny from 212.90.60.252
    Deny from 213.125.101.59
    Deny from 213.135.93.46
    Deny from 213.195.162.139
    Deny from 213.229.121.124
    Deny from 216.222.148.52
    Deny from 216.70.90.99
    Deny from 216.97.239.115
    Deny from 216.98.196.14
    Deny from 218.212.224.58
    Deny from 218.39.142.97
    Deny from 219.232.242.210
    Deny from 219.71.100.131
    Deny from 221.132.33.175
    Deny from 222.154.12.212
    Deny from 222.255.29.39

     
  3. Like
    YUR@ изменил репутацию johnsage в .htaccess   
    # Блокируем хитро..ые (Request) запросы через .htaccess
    <ifModule mod_alias.c>
       RedirectMatch 403 /(\$|\*)/?$
       RedirectMatch 403 (?i)(<|>|:|;|\'|\s)
       RedirectMatch 403 (?i)([a-zA-Z0-9]{18})
       RedirectMatch 403 (?i)(https?|ftp|php)\:/
       RedirectMatch 403 (?i)(\"|\.|\_|\&|\&amp)$
       RedirectMatch 403 (?i)(\=\\\'|\=\\%27|/\\\'/?)\.
       RedirectMatch 403 (?i)/(author\-panel|submit\-articles)/?$
       RedirectMatch 403 (?i)/(([0-9]{5})|([0-9]{6}))\-([0-9]{10})\.(gif|jpg|png)
       RedirectMatch 403 (?i)(\,|//|\)\+|/\,/|\{0\}|\(/\(|\.\.|\+\+\+|\||\\\"\\\")
       RedirectMatch 403 (?i)/uploads/([0-9]+)/([0-9]+)/(cache|cached|wp-opt|wp-supercache)\.php
       RedirectMatch 403 (?i)\.(asp|bash|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rar|rdf|well)
       RedirectMatch 403 (?i)/(^$|1|addlink|btn_hover|contact?|dkscsearch|dompdf|easyboard|ezooms|formvars|fotter|fpw|i|imagemanager|index1|install|iprober|legacy\-comments|join|js\-scraper|mapcms|mobiquo|phpinfo|phpspy|pingserver|playing|postgres|product|register|scraper|shell|signup|single\-default|t|sqlpatch|test|textboxes.css|thumb|timthumb|topper|tz|ucp_profile|visit|webring.docs|webshell|wp\-lenks|wp\-links|wp\-plugin|wp\-signup|wpcima|zboard|zzr)\.php
       RedirectMatch 403 (?i)/(\=|\$\&|\_mm|administrator|auth|bytest|cachedyou|cgi\-|cvs|config\.|crossdomain\.xml|dbscripts|e107|etc/passwd|function\.array\-rand|function\.parse\-url|livecalendar|localhost|makefile|muieblackcat|release\-notes|rnd|sitecore|tapatalk|wwwroot)
       RedirectMatch 403 (?i)(\$\(this\)\.attr|\&pws\=0|\&t\=|\&title\=|\%7BshopURL\%7Dimages|\_vti\_|\(null\)|$itemURL|ask/data/ask|com\_crop|document\)\.ready\(fu|echo.*kae|eval\(|fckeditor\.htm|function.parse|function\(\)|gifamp|hilton.ch|index.php\&amp\;quot|jfbswww|monstermmorpg|msnbot\.htm|netdefender/hui|phpMyAdmin/config|proc/self|skin/zero_vote|/spaw2?|text/javascript|this.options)
    </ifModule>
  4. Like
    YUR@ получил репутацию от Лина в Предложения для будущих версий.   
    Было бы неплохо реализовать помимо древовидной, "теговую систему категорий", как у некоторых интернет магазинов. Это даст возможность охватить ОГРОМНЫЙ пул СЧ и НК запросов, а также реализовать более удобную систему построения древовидных категорий.
     
    Например, такой запрос: "Снять посуточно 1 комнатную квартиру от хозяина в центральном районе".....
    З.Ы. Подобные запросы очень часто бывают довольно высокочастотные и вообще безконкурентые.
     
    На данный момент, чтобы найти такие квартиры на сайте, необходимо воспользоваться встроенным фильтром, с установленными, к примеру, чекбоксами.... В результате мы получаем не ЧПУ-шный URL вне индекса, без возможности прописывания мета-тегов. Отсюда, как я писал выше, следует потеря громадного числа очень "жирных" запросов, которые на данный момент, можно продвигать разве-что отдельными статьями.
     
    P.S. Если не совсем понятно, что я имею ввиду, я могу поискать где-то у меня видео, где один сеошник рассказывает о подобной структуре более вменяемым языком)) 
  5. Like
    YUR@ изменил репутацию Дмитрий Кондин в Обновление system 2.9.0   
    Если это не помогает, то можно в 
    /index.php
    и
    /admin/index.php
    прописать
    date_default_timezone_set('Europe/Moscow');ini_set('date.timezone', 'Europe/Moscow'); А если и это не поможет, тогда хостеру пишите. Формулировать нужно так - не устанавливается из скриптов и .htaccess временная зона.
  6. Like
    YUR@ получил репутацию от Дмитрий Кондин в Предложения для будущих версий.   
    По моему мнению, это должно быть одним из первоочередных обновлений! Пусть даже и не оптовой на 1-м этапе!))
    Только я бы дал возможность безвозвратного удаления объекта ТОЛЬКО АДМИНУ! Чтобы обычные пользователи могли только отправлять объявления в архив, указывая при этом метку (например, "Продано" или "Сдано", хотя для последнего архив не нужен, только пометка), которая графически выводилась в том числе и в фронтэнде сайта.
    Это бы нововведение положительно сказалось как на сайт в целом (в глазах поисковиков), так и на удобность для самого пользователя. 
    Приведу такой пример, касаемый пользователя: 
    Есть объект в определённом многоквартирном доме, фото которого представленны только с фасада здания. Объект продаётся и объявленние помещается в архив. Но через неделю у риелтора для продажи появляется ещё один объект в том же доме. Теперь он, в принципе, может достать из архива своё старое объявление и при необходимости чуть подправить его характеристики и описание... Главное, чтобы при этом не сменился УРЛ!)))
    P.S. приведённый мною пример, давольно таки часто встречается, и используется риелторами на других досках объявлений...
  7. Like
    YUR@ изменил репутацию abushyk в Вопросы от новичка 1.0   
    Потому что первая строка там стоит. Которая всегда выводит значение price.
    {$grid_items[i].price|number_format:0:",":" "} ее убрать.
  8. Like
    YUR@ изменил репутацию abushyk в Вопросы от новичка 1.0   
    А вот тут нужно конкрентно знать как и куда выводить. Вариант с соседней колонкой гиблый. Если у вас категория 20-й степени вложенности, то одной "колонкой рядом" не обойдешься.
     
    Самое фастфуд-решение:
    Есть такое значение {$grid_items[i].path} - оно используетися в агенси в выводе сетки иконками, а не таблицей (и должно быть доступно в любой сетке, в том числе и для ЛК), и содержит текстовую цепочку категорий, в которой находится объект. Например 
    [path] => офис / Апартаменты / Квартиры для объекта, который лежит в категории Квартиры, входящей в Апартаменты, которая входит в "офисы".
  9. Like
    YUR@ изменил репутацию Realtor в Предложения для будущих версий.   
    В ЛК разделить таблицу объявлений на Все Активные Архив (неактивные) Корзина 
    с возможностью оптовой Активации, Деактивации, Удаления и Восстановления
  10. Like
    YUR@ изменил репутацию abushyk в Вопросы от новичка 1.0   
    Например добавили мы два поля rental_price и rental_price_day - Месячная и подневная аренда. Добавляем в модель два поля типа price или safe_sring. Дополнительно можем прописать ограничивающие правила http://wiki.sitebill.ru/index.php?title=%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B0_%D0%B2%D0%B0%D0%BB%D0%B8%D0%B4%D0%B0%D1%86%D0%B8%D0%B8_%D0%B4%D0%BB%D1%8F_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8 на целое значение или не пустоту.
    Со вводом закончено.
     
    Для вывода в карточку можно использовать автовывод, который выведет все значения не скрытые от просматриваемого пользователя правилами видимости. Быстро, но не слишком красиво.
    Можем наладить ручной вывод. В массиве {$data_shared} доступны ВСЕ активные элементы модели в формате модели. Т.е. что бы вывести стандартное поле цены, можно запросить {$data_shared.price.value}. Такой подход можно использовать почти ко всем элементам.
     
    Вывод в сетке немного отличается. Там данные сложены простым массивом. Т.е. если в просмотре доступ к rental_price = {$data_shared.rental_price.value}, то в сетке {$grid_items.rental_price}
     
    Конфликтовать элементы могут только в случае одинаковых системных имен. Иного я не припомню.
  11. Like
    YUR@ изменил репутацию abushyk в Вопросы от новичка 1.0   
    Принцип построения меню таков, что некая библиотека берет выжимку из структуры категорий и строит меню. Т.е. процесс происходит вне нашего контроля. Соответственно, наша задача состоит в том, что бы дополнить структуру нужными нам пунктами.
     
    Для агенси рассмотрим на примере purecss-меню. Для slidermenu все будет в принципе аналогично.
     
    За генерирование purecss-меню отвечает файл /apps/system/lib/frontend/menu/purecssmenu.php и все самое интересно происходит в функции get_menu().
     
    1. Тянем файл /apps/system/lib/frontend/menu/purecssmenu.php к себе в шаблон. Например в /template/frontend/имя_шаблона/main/menu/purecssmenu.php и переименовываем его в local_purecssmenu.php
     
    2. Открываем переименованный файл и в его начале строку 
    class PureCSS_Menu extends Structure_Manager { меняем на 
    class Local_PureCSS_Menu extends PureCSS_Menu { 3. Вытираем из этого файла все, кроме злополучной функции get_menu
     
    4. Забор структуры происходит функцией 
    $category_structure = $this->loadCategoryStructure(); с этого момента в $category_structure хранятся данные для построения меню. Тут мы и устроим инжекцию.
     
    5. Для начала нам надо узнать максимально существующее ИД категорий, что бы не накрыть существующий пункт. Для этого, сразу после $category_structure = $this->loadCategoryStructure(); добавляем:
    $max_id=0; //инициализируем переменную$keys=array_keys($category_structure['catalog']); //тащим все ключи пунктов структурыsort($keys); // сортируем их по возрастанию$max_id=end($keys)+1; //берем последний по порядку (т.е. самый большой) и инкрементируем его, что бы получить следующий, больший от самого большого существующего. 6. Втыркиваем наши пункты. Что бы вставить пункт "Дневная аренда" с адресом /?daily_rent=1 нам нужно в структуру вставить
    $category_structure['catalog'][$max_id]['name']='Дневная аренда';$category_structure['catalog'][$max_id]['url']=SITEBILL_MAIN_URL.'?daily_rent=1'; В 'name' название пункта, в 'url' - ссылка.
    Так же нам надо сообщить, что этот пункт будет входить в верхний уровень
    $category_structure['childs'][0][]=$max_id; Эти три строки вписываем после кода, добавленного в пункте 5.
     
    7. Если надо добавить еще пунктов, то еще раз наращиваем $max_id на единицу и повторяем 6-й пункт.
     
    8. Теперь нужно заставить движок вызывать именно наш файл создателя меню.
    Открываем /template/frontend/agency/main/main.php и ищем
    if ( $this->getConfigValue('menu_type') == 'purecss' ) { В этом блоке, где вызывается построитель purecss-меню
    require_once(SITEBILL_DOCUMENT_ROOT.'/apps/system/lib/frontend/menu/purecssmenu.php');$purecssmenu = new PureCSS_Menu();$this->template->assert('slide_menu', $purecssmenu->get_menu()); меняем на
    require_once(SITEBILL_DOCUMENT_ROOT.'/apps/system/lib/frontend/menu/purecssmenu.php');require_once(SITEBILL_DOCUMENT_ROOT.'/template/frontend/имя_шаблона/main/menu/purecssmenu.php');$purecssmenu = new Local_PureCSS_Menu();$this->template->assert('slide_menu', $purecssmenu->get_menu()); Т.е. дополнительно подключили свой файл с генератором. Вызвали именно его, вместо стандартного и все.
  12. Like
    YUR@ изменил репутацию abushyk в Вопросы от новичка 1.0   
    В этом случае мы теряем всю красивость ровно столько, сколько мы будем строить верхнее меню на основании структуры. Но это не является каноном - просто так повелось и устоялось))) Каждый сайт, для успешной работы, требует весьма основательной шлифовки и индивидуального подхода. После установки движка, первичного наполнения и привязки красивостей как раз только и начинается настоящая работа по его оптимизации и продвижению.
  13. Like
    YUR@ изменил репутацию abushyk в добавить новые поля в поиск (template_search и др.)   
    Не буду утверждать, что тормозит из-за этого, но и не буду опровергать.
     
    Попробуйте заменить строку
    $kvartira_model['data'] = $data_model->init_model_data_from_request($kvartira_model['data']); на
    $kvartira_model['data']['daily_rent_id']['value']=(int)$this->getRequestValue('daily_rent_id');
  14. Like
    YUR@ изменил репутацию abushyk в добавить новые поля в поиск (template_search и др.)   
    1-2. Для вставки обычного чекбокса нет надобности наследовать целый Kvartira_Search_Form
    Если уже потянули, то делаем
     
    daily_rent_id - системное имя чекбокса отвечающего за признак Посуточной
    <?phpclass Local_Kvartira_Search_Form extends Kvartira_Search_Form {function main () {parent::main();$data_model = new Data_Model();$kvartira_model = $data_model->get_kvartira_model(true)$kvartira_model['data'] = $data_model->init_model_data_from_request($kvartira_model['data']);$form_generator = new Form_Generator();$this->template->assert('daily_rent_list', $form_generator->get_checkbox($kvartira_model['data']['daily_rent_id']));}} 3. Тут все верно
    4. В шаблон выводится так
    В {$daily_rent_list} лежит уже готовый чекбокс (<input... />). Нужно только вставить в нужное место.
    То, что вывели вы - это как раз вариант без привлечения Local_Kvartira_Search_Form.
     
     
     
    Это не зависит от схемы. Тронули ползунок - сменили лимиты цен - наложилось новое условие фильтрации.
  15. Like
    YUR@ изменил репутацию abushyk в добавить новые поля в поиск (template_search и др.)   
    То просто в шаблоне
    Посуточная аренда <input type="checkbox" name="daily_rent"{if isset($smarty.get.daily_rent)} checked="checked"{/if} value="1" /> или daily_rent заменить на daily_rent_id, смотря какое системное имя у поля.
  16. Like
    YUR@ изменил репутацию abushyk в добавить новые поля в поиск (template_search и др.)   
    после $kvartira_model = $data_model->get_kvartira_model(true) точку с зяпятой поставьте
  17. Like
    YUR@ изменил репутацию Дмитрий Кондин в Дубликаты объявлений   
    В будущих версиях сделаем настройку для определения набора уникальности.
  18. Like
    YUR@ изменил репутацию 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 все єто будет выглядеть в конце.
  19. Like
    YUR@ изменил репутацию abushyk в Вопросы от новичка 1.0   
    Логика такая.
     
    все, что подается гостем (незарегистрированным пользователем) без всяких настроек ставится в неактив. Тут простая логика целесообразности.
     
    если подается с ЛК, то тут возможность активированния можно регулировать. Если доверять авторизированным пользователям, то можно выключить деактивацию до премодерации и вывести чекбокс Публиковать на сайте в доступ всем пользователям, что бы они могли самостоятельно управлять активностью.
    Если пользователей много и не все они знакомы, то лучше перебдеть и ограничить их управление активностью.
     
    Разница между подачей через кнопку и ЛК есть, но она не сильная. Если пользователь авторизирован и нажал на кнопку Подать объявление, то он перенесется в ЛК на функцию подачи объявления из ЛК (в старых версиях шаблонов). В новых лучше предусмотреть в шаблоне спрятывание кнопки Подать объявление для авторизированного.
     
    Разделить по группам срабатывание премодерации без колдовства сейчас не получится.
    А вот отключить подачу неавторизированными можно. Для этого нужно убрать кнопку Подать объявление, а в /template/frontend/agency/main/main.php убрать обработчик подачи объявление, который выглядит как
    if ( !$has_result && preg_match('/^add(\/?)$/', $REQUESTURIPATH) ) {...} Авторегистрация - это такая опция в Общих настройках (Включить авторегистрацию), которая, при подаче объявления гостем, из данных в объявлении (Ваше ФИО, телефон, мейл) создает аккаунт на который привязывает поданное объявление. И подавший может потом воспользоваться входом в него для корректировки или удаления объявления, а так же для подачи нового. 
     
     
    REоффтоп.
    С футболом сложно. Чем ближе расположен стадион, на котором проходит матч, к дому, тем сложнее на него выбраться. Так что на новую арену-львов, которая расположена в пару остановках от дома, я так до сих пор и не выбрался)))
  20. Like
    YUR@ изменил репутацию abushyk в Вопросы от новичка 1.0   
    1) Все объявления поданные с фронта сайта через форму /add/ при отключенной опции авторегистрации привязываются к некоторому абстрактному пользователю с именем Незарегистрированный.
    2) данная опция не дает активировать объявление из ЛК разрешая пуликацию на сат ТОЛЬКО администратору из админпанели. Т.е. даже если владелец отметит Активно в ЛК и сохранит, галочка все-равно будет сброшена и поставить ее сможет только админ после проверки.
    3) а некоторые операции стоит блок-проверка доступности операции для админа. если в одном браузере открыт и фронт и админка. и там и там с залогинившимися пользователями - может наступить момент, что их сессии частично перекроют друг друга, что может привести к некоторым глюкам. Попробуйте закрыть браузер, а после открытия, зайти просто в админку и посмотреть сохранилась ли проблема.
  21. Like
    YUR@ получил репутацию от domprim.ru в Вопросы от новичка 1.0   
    Приветствую! Ну, тут где-то Вы правы... Просто привык, что существуют уже продуманные решения...
    А если говорить о конечной цели, то в принципе, её можно было уловить из моего "потока сознания" выше.)) Вопрос в методах её реализации... Хотя да, перечитав свои посты чуть выше - понял, что это довольно проблематично))) 
    Попробую ещё раз описать то, чего желаю добиться...
     
    Необходимо реализовать посуточную аренду совместно с долгосрочной, не создавая для этого отдельных категории.  Чтобы пользователь при добавлении объявления о сдаче квартиры (как посуточно, так и долгосрочно), выбирал только одну категорию. Например: человек при подаче объявления о сдаче 1 комн. квартиры, которая сдаётся посуточно, но может сдаваться и долгосрочно,  выбирает  только категорию "Аренда 1 комн. квартиры" (а не "Аренда 1 комн. квартиры" вместе с "Посуточной арендой 1 комн. квартиры"), где помимо основной "посуточной цены", он может проставить 2-ю цену за долгосрочную аренду. Для соискателя такой квартиры можно ограничится одним пунктом в "Основом меню" - "Посуточная аренда квартир" (помимо расширенного поиска), откуда ему выведутся все квартиры, сдаваемые посуточно (а там он уже сможет их дополнительно отфильтровать, используя "сетку-фильтр" на Главной). Ну, вот как-то так я себе это всё представляю...)))
     
    Что касается реализации этой схемы, то тут мне видится создание трёх дополнительных колонок:
    1) "Чекбокс о сдаче посуточно" - для последующей выборки таких объектов из таблицы. Хотя, если возможна выборка в зависимости от заполненности поля "Цена в сутки", то этой колонкой можно принебречь
    2) "Цена долгосрочная"
    3) "Цена в сутки"
    Создание именно 2-х новых полей с ценами, позволит не перемешиваться с продаваемыми объектами в поиске по цене.
     
    Далее, необходимо вывести всё это дело:
    1) добавить в Главное меню ссылку вида site.ru/index.php?extended_search=1&topic_id=0&floor_min=&floor_max=&floor_count_min=&floor_count_max=&square_min=&square_max=&price_min=0&price=0&region_id=0&city_id=0&district_id=0&geoautocomplete%5Bstreet_id%5D=&street_id=0&daily_rent=1
    2) Каким-то образом компактно реализовать вывод обоих цен на "предварительном просмотре" и основной карточке объекта
     
    Т.е. мы добиваемся того, что основой будет "Долгосрочная аренда" (под неё и создаются все катеории), а "Посуточная" - дополнительная (её выборка делается посредством фильтра).
     
    P.S. Я ещё полностью не изучил все возможности движка, поэтому может всё это можно реализовать по-другому. Да, и сам я не "супер-проггер"!)))  
  22. Like
    YUR@ изменил репутацию Дмитрий Кондин в Вопросы от новичка 1.0   
    В админке старые адреса, фронт автоматом их редиректит в новые.
     
     
    Честно говоря, из этого потока сознания я понял только то, что вы сами еще не знаете четкой цели.
    Определитесь с целью, то как будет выглядеть на сайте и опишите ваше видение цели, а потом уже можно из этого задания составить план действий.
    У вас сейчас наоборот, сначала делаете действия - а куда прийти не важно получается )
  23. Like
    YUR@ изменил репутацию abushyk в TLocation в картинках   
    Допустимое системное имя элемента этого типа: tlocation (и не иначе)
     
    Этот тип поля не хранится в БД as is. Поэтому галочка Хранить значение поля в таблице должна быть снята.
     
    Задачи компонента
    1) управлять географической структурой адресных полей
    2) реализовывать подбор данных для элементов географии не-tlocation, но с параметров autocomplete=1

    Тип поля модели, отвечающий за адресные данные.
    Содержит в себе 5 встроенных компонентов
    country_id - идентификатор страны из таблицы country
    region_id - идентификатор региона из таблицы region
    city_id - идентификатор города из таблицы city
    district_id - идентификатор района города из таблицы district
    street_id - идентификатор улицы из таблицы street

    Предполагает наличие иерархической зависимости именно в порядке country_id -> region_id -> city_id -> district_id -> street_id
    Есть одно исключение. Если указан параметр link_street_to_city из иерархической цепочки исключается звено district_id, и street_id считается зависимым от city_id.

    Принципиально каждый компонент этого типа не обязана соответствовать буквально своему названию.
    Например city_id может указывать на район области в тот момент, когда region_id указывает на область, если в соответствующих таблицах city и region содержатся данные о областях и районах областей.
    Допустимые параметры:
    visibles - перечень отображаемых компонентов. Указывается в формате компонент1|компонент2|компонент3 Порядок компонентов не важен. При отсутствии этого параметра или его пустом значении будут отображены все компоненты. (Это поведение будет изменено. При отсутствии этого параметра элемент не будет генерироваться. Поэтому лучше явно указывать список выводимых частей) Например region_id|city_id выведет селектбоксы для региона и города.

    Результат


    default_country_id, default_region_id.... - значение по умолчанию. например выбрано для отображения регион и город. Если текущее значение country_id не установлено, список регионов с списке выбора регионов будет установлен соответственно default_country_id, если оно задано и не равно 0. В противном же случае будет выведен список всех регионов из таблицы region


    show_names - признак того, нужно ли выводить возле каждого подэлемента tlocation имена-метки. По умолчанию и при отсутствии данного параметра считается включенным (=1)
     
    Включено


    Выключено


    names - имена отдельных элементов. Задаются в формате имя_подэлемента:имя_метки|имя_подэлемента2:имя_метки2

     
    Обновление вывода.
    С версии system-2.5.25 и tlocation-1.1 генератор формы возвращает tlocation в форму не как обычный эемент (заголовк и кусок хтмл для вставки), а как коллекцию элементов.
    Для тех, кто использует базовый файл /apps/system/lib/frontend/search/kvartira_search.php для генерации форм поиска это изменение учтено. Тепер такие блоки как {$country_list}, {$city_list}, которые находились в шаблоне форму поиска, при наличии элемента tlocation будут заменены соответствующими кусочками элемента tlocation. Но ничто не запрещает присваивать разметку этих элементов другим переменным шаблона и свободно перемещать их в пределах формы.
    Те, кто использовал локальные формы поиска с {$tlocation_form_element_simple.html} столкнутся с багом.
  24. Like
    YUR@ изменил репутацию abushyk в [Песочница] Пользовательские сущности и Связанные элементы   
    Продолжаю отдельными постами, так как исчерпал лимит на картинки в одном сообщении ))
     
    4.1. Секции.
     
    Не буду давать расширенного описания, скажу только, что все идентично как для корпусов.
    Таблица csection и поля csection_id, name, ckorps_id (по таблице ckorps)
    В принципе для секций можно было бы установить двойную зависимость - указывать принадлежность секции к корпусу и к ЖК. Для некоторых случаев это оправдано (особенено если делается полноценное приложение), но в нашем случае, когда необходимо лишь поразграничивать принадлежности и сам корпус и ЖК будет указан в свойствах недвижимости, такая связка будет избыточной.
     
    В итоге
      5. Внедрение в недвижимость   Сущности у нас готовы, можно приступать к привязке их на объявление.   Нам необходимо добавить три свойства в нашу таблицу data - ЖК, Корпус и Секция. Все они будут добавляться полями типа select_by_query, что бы мы могли сформировать их списки в элементах выбора из соответствующих таблиц. Носить имена будут эти элементы czhilcom_id, ckorps_id и csection_id   Если теперь мы перейдем в форму добавления объявления мы увидим, что наши новые три поля уютно прописались в форме в виде привычных списков выбора.   Но если их поразворачивать, то вы увидите, что они вмещают все варианты из своих таблиц и не реагируют на состояние "родительского" элемента. Например выбор ЖК никак не отражается на содержимом списка корпусов.   Приступаем к наладке связей.   6. Связывание   Основой для связывания служит принцип связанных элементов формы - http://wiki.sitebill.ru/index.php?title=%D0%A1%D0%B2%D1%8F%D0%B7%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%8B   Нам необходимо в рамках одной формы указать элементам на какие другие элементы они влияют в форме и от каких зависят.   Например - ЖК. От состояния этого элемента зависит возможный список выбора в элементе Корпуса. Эта зависимость описывается как Это значит, что элемент, в котором мы выбираем название ЖК связан с элементом с системным именем ckorps_id (элемент выбора Корпуса ЖК), а ключем, который внутри Корпуса соответствует жилому корпусу является значение из поля czhilcom_id модели Корпуса. Если взлянете выше, то это значение в модели Корпуса у нас является идентификатором ЖК,  к которому привязан Корпус. Больше ЖК у нас ни на что не влияет, потому и других параметров нет.   Далее Корпус. Корпус, аналогично ЖК влияет на "следующий" элемент - Секцию. Но, кроме этого, он еще должен знать от какого элемента зависит сам - это необходимо для формирования адекватного списка значений элемента Корпус, но не тогда, когда сделан выбор конкретного ЖК, а при загрузке формы. Например, если вы открыли на редактирование объявление в котором ЖК был указан как Элитный, тогда в списке Корпусов вполне ожидаемо окажется уже готовый список корпусо ЖК Элитный.   linked - описывает зависмость когда элемент влияет на что-то. depended - когда что-то влияет на элемент   И, наконец, Секция. Самый простой элемент. Он ни на что не влияет, но на него влияет Корпус. Что и видно из параметров.   Нет ничего страшного, если вы ничего не поняли про связи с первого раза. Это нормально, Я гарантирую это.   Если теперь вы попробуете загрузить форму добавления объявления, вы видите, что у вас доступен на выбор только элемент ЖК, а остальные будут подгружены только после выбора соответствующего родительского.   Для того, что бы увидеть этот эффект в Настройках необходимо включить параметр Настройки - Дополнительно - Off system Ajax   7. Эпилог   Ай, у меня не работают элементы выбора географии. Что делать?...   Тут все ожидаемо. Изначально принцип связанных элементов предназначался как-раз для географических элементов, что бы вывести из кода движка жесткие зависимости Страна-Регион-Город-Район\Улица и иметь более широкую возможность настройки своих связей. А так же, иметь возможность введения промежуточных элементов (Страна-Регион-Субрегион-Город), которые разрывали бы существующие связи, заложенные в код Сайтбилля. Именно поэтому опция Off system Ajax отрубает всю систему заложенных связей.   Возможно это слишком кардинально и стоило бы предусмотреть ступенчатую систему, когда подключение пользовательских связанных элементов регулировалось бы одной настройкой, а отключение привычной связки от Страны к Улице другой. На данный момент четкого мнения у меня пока нет.   Для себя я решил эту проблему навеской связей на географические элементы в виде, аналогичном системным правилам.   Т.е. country_id linked    region_id,country_id   region_id linked    city_id,region_id depended    country_id   city_id linked    street_id,city_id;district_id,city_id depended    region_id   district_id linked    mkrn_id,district_id depended    city_id   street_id depended    city_id   mkrn_id depended    district_id   8. Offtop   С другой стороны, даже этот способ немного избыточен. Если Город является дочерним к Региону, а Регион к Стране, то хранение всех трех значений для объявления - это "лишние" данные, хотя при организации поиска они весьма кстати.   Суть в том, что географические данные вполне возможно хранить в виде, схожем со структурой
      и получать к ним доступ более "человечным" путем Но в этом случае остается так же много вопросов связанных с совместимостью с многими приложениями, принципом организации смой геоструктуры (ведь если заструктурить географию от страны до улиц - это может стать неподъемным грузом, а если закончить городом, то не совсем понятно, как вести связь дальше к улицам, которые должны таки быть привязаны к городам или чему-то наследному от них).   В общем идея у нас полно, была бы возможность все реализовать)
  25. Like
    YUR@ изменил репутацию abushyk в [Песочница] Пользовательские сущности и Связанные элементы   
    1. Предистория
     
    Допустим мы имеем базовый сайт на сайтбилле. У нас есть стандартная модель квартиры-недвижимости со всякими Цена, Площадь и прочими свойствами по вкусу. И вот, в один прекрасный момент, мы решили заняться торговлей квартирами в новостройках. А новостройки эти у нас зачастую представлены не отдельными зданиями, а целыми комплексами зданий, которые в свою очередь разбиты на секции.
     
    2. Анализ.
     
    Сначала разберемся со структурой. Самый простой вариант - мы решили еализовывать каждую квартиру в виде отдельного объекта. Например, если в ЖК "Элитный" у нас есть корпус А, а в нем секция I и в этой секции, грубо говоря, 15 квартир одной планировки, но некоторые на разных этажах, мы будем считать, что каждая квартира, даже одинаковой планировки - является одним объектом. Иными словами, мы не делаем группировок по типам, а ведем каждую квартиру отдельно. Это дает нам некоторую гибкость, так как квартиры на крайних этажах могут иметь меньшую цену в отличии от одноплановых с ними, на остальных этажах. Так же, из плюсов то, что мы можем задать какие-то особенности поквартирно, даже не смотря на то, что они одноплановые. Особенно это касается, когда квартиры продаются не в сыром виде, а меблированные или с финишной отделкой. Либо учесть иные особенности каждой квартиры.
     
    Из минусов такого подхода то, что если секция у нас 9-ти этажная с 4 квартирами на этаж, то на секцию получается 36 объектов. И дальше в геометрической прогрессии в зависимости от количества секций в корпусе и корпусов в ЖК.
     
    Соответственно, логично предположить, что кроме обычных для недвижимости параметров (цена, площадь, этаж,и т.д.) нам придется снабдить модель недвижимости дополнительными параметрами, устанавливающими ее привязку к конкретному положению в разрезе ЖК - конкретный ЖК, корпус ЖК, секция корпуса ЖК. И так же очевидно, что при заполнении формы эти параметры должны бы быть связаны цепочкой, как то при выборе отдельного ЖК, мы должны получить под выбор список корпусов только этого ЖК, что бы не рыскать в длиннющем списке всех корпусов. Аналогино и с секциями.
     
    3. Инструментарий.
     
    Для реализации нам понадобятся свежие приложения system, admin, table, customentity. Привлекать готовые приложения типа "Жилые комплексы" мы не будем.
     
    Из настроек нам будет необходимо включить параметр Настройки - Дополнительно - Off system Ajax. Данная опция выключает автоматические связки между зависимыми элементами и предоставляет нам полный контроль над определением своих зависимостей.
     
    Из почитать - http://wiki.sitebill.ru/index.php?title=%D0%A1%D0%B2%D1%8F%D0%B7%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%8B
     
    4. Подготовка дополнительных сущностей.
     
    Если мы должны иметь возможность выбрать корпус, ЖК и секцию, значит у нас где-то должны быть списки этих значений. В Сайтбилле, для организации списков значений существует два типа полей - select_box и selectbox_by_query.
     
    Первый нам не подходит, так как не поддерживает организацию наследия. Т.е. штатными средствами этого элемента мы можем задать набор его вариантов значений, но не можем указать какие-то связующие ключи с другим элементом.
     
    Второй, поскольку хранится в БД в виде отдельной таблицы, вполне на это способен. Но для его использования необходима соответствующая таблица в БД. В нашем случае таблиц будет три - таблица ЖК, таблица корпусов и секций корпусов. Что бы избавить себя от рутинной работы по наполнению этих данных через phpMyAdmin создадим соответствующие таблицы в Редакторе форм.
     
    4.1. Жилые комплексы.
     
    Для ЖК - это таблица czhilkom с полями czhilcom_id (primary_key) и name (safe_string).

    Создав таблицу и наполнив ее элементами, нажимаем кнопку Создать таблицу.

    Теперь таблица ЖК существует физически в БД.
    Надо наполнить ее какими-то жилыми комплексами.
    Для того, что бы получить доступ к работе с этой сущность через стандартную админку, воспользуемся приложением Пользовательские сущности. Для начала проверим, что приложение установлено. Для этого в админке переходим по адресу 
    /admin/index.php?action=customentity&do=install
     
    При переходе по нему, в случае отсутствия необходимых таблиц для работы приложения, они будут созданы.
    После этого возвращаемся в Редактор форм и в заголовке таблицы czhilkom ищем кнопку со завездочкой

    Эта кнопка отвечает за создание мини-обработчика для сущности, у которой нет штатного обработчика (в виде встроенного модуля или стандартного\стороннего приложения). NB. Попытка создать этой кнопкой обработчик для встроенных сущностей, как Город, Район или для тех у которых есть приложения - Баннеры, Новости - ни к чему не приведет.
     
    После нажатия кнопки Создания обработчика мы увидим следующее окно

    где в поле Название вам нужно ввести вменяемое название для вашего обработчика, что бы вы знали к чему он относится. Введем например Жилой комплекс и нажмем Создать.
    После перезагрузки страницы в верху, возле кнопки раскрытия списка приложений мы получим дополнительную кнопку Пользовательские, а под ней и наше квази приложение Жилой комплекс

    Если перейти по предложенной ссылке, вы получите минималистический инструмент для управления вашими ЖК где вы можете добавить ЖК в список, изменить существующий или удалить ненужный. Приложение не следит за целостностью, т.е. если вы удаляете ЖК, то об удалении соответствующих зависимых корпусов и секций вам так же придется позаботиться самому.
     
    Не надейтесь на возможность реализации таким способом каких-то "творческих вывихов" - это исключительно инструмент для обеспечения удобства. Для полноценной работы с такими сущностями, как разделение их по пользователям с возможностью редактирования последними, организация страницы, например конкретного ЖК, шаблонизация необходимо создавать полноценное приложение.
     
    Для наших целей добавим два ЖК - Элитный и Морской с помощью кнопки Добавить запись
    Процесс, как вы можете заметить, вполне привычный и не должен вызвать трудностей
     
    4.1. Корпуса.
     
    Создание таблицы корпусов абсолютно ничем не отличается от создания таблицы ЖК кроме того, что у корпусов есть зависимость от ЖК. Например ЖК Элитный имеет два корпуса - Корпус А и Корпус Б. Тогда модель корпуса (ckorps) будет состоять из полей

    Поле czhilcom_id является обычным полем селектбокса подбирающим данныеиз внешней таблицы, в данном случае из таблицы czhilcom
    Простыня под спойлером
     
    Дальше все по алгоритму - создали таблицу в Редакторе форм, наполнили полями, создали физическую таблицу, зарегистрировали обработчик. Из Пользовательских переходим в Корпуса  добавляем

    Названия сущностей рекомендую давать расширенные - с включением родительского описания. Так как обработчик весьма прост, то особых способов отличить Корпус А от ЖК Элитный и Корпус А от ЖК Морской у вас не будет.
     
    В результате мы получаем нечто похожее на