История версий

2.14

Исправлена проблема в последних Chrome, из-за которой страница не перезагружалась после её редактирования, а также не закрывалась страница удаления. В последних версиях Chrome не передаёт window.opener при открытии обычных ссылок, поэтому страницы редактирования теперь открываются при помощи window.open().

27.04.2021

2.13.2

Изменено обращение к подстроке с фигурных скобок на квадратные (DEPRECATION ошибка в PHP 7.4)

18.04.2021

2.13.1.1

Методы stub и fetch_column для ActiveRecord

stub возвращает "пустой" элемент ActiveRecord, fetch_column - быстро получает массив значений по одному столбцу.

28.01.2019

2.13.1

Поддержка .ini и .ini.ini файлов в директориях без "mod_" в имени.

12.09.2018

2.13

Новый формат блоков в файлах "*.ini".

Должен начинаться со знака { и заканчиваться на }. Будет сохранен как ассоциативный массив под числовым индексом в предыдущем объявленном блоке ([block]);

Пример: имеем файл mydata.init.ini со следующим содержимым:

[admin.menu.content]
;Можно перемешивать с обычными блоками
pages "Текстовые страницы"
;Разрешены знаки вопроса в значениях
;Разрешены отступы (табуляция и пробел)
{
    link= /admin/?le=1
    title=Управление опциями
},
;Запятая после блока допустима, но не обязательна
;Отступы не обязательны
{
link= /admin/?le=2
title=Управление товарами
}
{
    link= /admin/?le=3
    ;Поддерживается вложенность ключей
    title.usual=Управление Меню
    title.advanced=Управление Конфигурацией
}
;Поддерживается вложенный JSON
{
    content = json: ["a", "b", "c"]
}

Итоговый массив d()->admin (включая опции, заданные в admin.ini), полученный через json_encode(d()->admin , JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE );, будет иметь следующий вид:

{
    "menu": {
        "content": [
            [
                "pages",
                "Текстовые страницы"
            ],
            {
                "link": "\/admin\/?le=1",
                "title": "Управление опциями"
            },
            {
                "link": "\/admin\/?le=2",
                "title": "Управление товарами"
            },
            {
                "link": "\/admin\/?le=3",
                "title": {
                    "usual": "Управление Меню",
                    "advanced": "Управление Конфигурацией"
                }
            },
            {
                "content": [
                    "a",
                    "b",
                    "c"
                ]
            }
        ]
    },
    "editor": {
        "login": [
            "admin",
            "developer"
        ],
        "password": [
            "c4ca4238a0b923820dcc509a6f75849b",
            "c4ca4238a0b923820dcc509a6f75849b"
        ]
    },
    "leftmenu": [
        [
            "pages",
            "Текстовые страницы"
        ]
    ]
}

11.09.2018

2.12.6.1

Метод ActiveRecord->id_or_insert_id. Для нового элемента возвращает insert_id, для существующего - id.

Короткий синоним: ioi

Например:

$news = d()->News->new;
$news->title="Новая запись";
$news->save();
$id = $news->id_or_insert_id;
$id = $news->ioi; //Короткий синоним

31.08.2018

2.12.6

Исправлена невозможность использования функций вида d()->funcname=function(){} в шаблонизаторе, при использовании конструкции {.property|funcname}.

<?php
d()->myfunc = function($x){
    return mb_strtoupper($x);
}
?>
{this.title|myfunc} <!-- Так работало --> <br>
{.title|myfunc} <!--Ранее не так работало--> <br>

30.08.2018

2.12.5.5

Метод save_and_load() ActiveRecord. После сохранения возвращает новый объект с сохранённым id/insert_id.

<?php
$x = d()->News->new;
$x->title = "Новый заголовок";
$result = $x->save_and_load(); //$result - копия класса
print $result->id.' '; //ID новой записи
print $result->title; //Новый заголовок

29.08.2018

2.12.5.4

Параметр inline функции preview превращает путь в base64 строку с изображением. Пример:

<img src="{.image|preview '100', '100', 'inline'=>true}">

29.08.2018

2.12.5.3

Возможность переопределить заголовок вида "Список объектов из таблицы pages" в ini файле. Заготовка есть при генерации ini файла (нужно обновить кеш, т.к. находится в js файле).

Синтаксис:

[admin.titles]
list_title = Текстовые страницы

28.08.2018

2.12.5.2

Скаффолдинг - Миграция схемы теперь умеет сохранить сгенерированный schema.ini в директорию app.

28.08.2018

2.12.5.1

Метод f ActiveRecord, синоним find(), но ищет строго по столбцу id.

28.08.2018

2.12.5

Доработан и исправлен метод Date->ago (склонения слов, правильный подсчёт). Убран мусорный код.

31.07.2018

2.12.4

Добавлено несколько функций и валидатор для работы с сотовыми телефонами.

  • d()->convert_phone($phone) - Приводит номер телефона к форме 79876543210
  • d()->convert_phone_clean($phone) - Приводит номер телефона к форме 9876543210
  • d()->convert_phone_plus($phone) - Приводит номер телефона к форме +79876543210
  • d()->convert_phone_human($phone) - Приводит номер телефона к форме +7(987) 654-32-10
  • validate_phone($phone) - Проверяет телефон на валидность.

Все, кроме последней доступны только через вызов d()->. Её можно использовать в валидаторе:

[validator.registration.phone]
required.message=Вы не ввели телефон
validate_phone.message=Неправильно введён номер телефона

Внимание! Если уже была объявлена функция validate_phone, то при обновлении системы произойдёт коллизия. Необходимо использовать другое имя или написать if(!function_exists('validate_phone')){.

Ряд примеров использования можно найти в файле phonevalidatortest.class.php.

27.03.2018

2.12.3

Исправлен баг предыдущего исправления d()->view. Исправлено "не найден шаблон" и в некоторых случаях зависание страницы.

24.03.2018

2.12.2

Добавлена функция d()->page_not_found() (by @targrik).

При вызове возвращает заголовок 404, очищает предыдущий вывод, выводит шаблон d()->error_404_tpl() в обёртке d()->main_tpl().

20.03.2018

2.12.1

Добавлен компонент admin_eval. Принимает три параметра. Первый - указать id. Не влияет ни на что. Второй - надпись. Третий - PHP строка, которая будет выполнена. На момент выполнения доступна переменная d()->row_data, содержащая текущий объект. Можно применять, чтобы выводить какую-либо строчку. Например, при редактировании варианта товара, привязанному к товару, можно использовать в app/fields/product_variant.ini, как в примере ниже, выведет название товара, к которому привязан вариант товара:

[admin.fields]
eval id "Товар" "d()->row_data->product->title"
eval id "Товар безопасно" "h(d()->row_data->product->title)"
small title "Название" "Например, 2кг"
;.....

Вывод никак не экранируется. Если нужно сделать ссылку, использовать теги, реализовать маленькую фотогалерею или что-то сложнее, можно использовать метод ActiveRecord (или собственноручно написанный компонент).

Примечание: на данный момент система администрирования устроена так, что она запрашивает поле, указанное во втором параметре любого компонента панели администрирования. Например, legend "Это Опции" выполнит d()->row_data->{Это Опции}. В некоторых случаях это приводит к непредсказуемым последствиям, поэтому временно используется поле id в качестве первого параметра.

17.03.2018

2.12

В поддиректориях папки app, cms и так далее, которые не начинаются на mod_, можно включать другие поддиректории. Для этого вложенная поддиректория должна начинаться на "+".

Например, /app/bonjorno/+hello/+world/routes.php. Глубина вложенности неограничена (кроме ограничений файловой системы).

Пример использования (дерево директорий):

/app
    /pages
    /import
        /+source1
        /+source2
            /import.php
        /+source3
            /import.php
            /ImportClass/ImportCore.php

11.03.2018

2.11

Теперь в простых директориях (без mod_) автолоадер также ищет файлы с подчеркиваниями внутри имени файла, в том числе с двойными. Файлы с стандартной PSR-0 схемой загрузки по прежнему поддерживаются и имеют приоритет.

Пример:

/app/bonjorno/Uber__Buber_Class.php:

<?php
class Uber__Buber_Class {
    function yes(){
        return 'Uber__Buber_Class';
    }
}

/app/bonjorno/Uber_Class.php:

<?php
class Uber_Class {
    function yes(){
        return 'Uber_Class';
    }
}

/app/bonjorno/routes.php:

<?php
print d()->Uber__Buber_Class->yes();
print "\n";
print d()->Uber_Class->yes();
exit;

Вывод:

Uber__Buber_Class
Uber_Class

25.02.2018

2.10.2

Возможность добавить свои расширения файлов для загрузки при помощи элемента управления file. Расширения добавляются к дополнительным как часть регулярного выражения. Расширения добны разделяться символом "|". Указываются в опции $_ENV['DOIT_UPLOAD_EXTENSIONS'] в файле config.php:

$_ENV['DOIT_UPLOAD_EXTENSIONS'] = 'css|rar';

20.02.2018

2.10.1

Исправлена вторая ошибка с зависанием d()->view с несуществующими шаблонами. В случае, если в качестве имени шаблона используется строка, начинающаяся на "/", поиск по пути, совпадающем с адресом страницы, не просходит.

18.02.2018

2.10

Пункт 1: исправлена ошибка зависания в одном из случае при отсуствии шаблона.

Теперь если в пути указана папка app, зависание не происходит (например, d()->view->partial("/app/components/custom_pagination.html"););

Внимание! Изменен приоритет и механизм поиска файла шаблонизатором. Теперь если указать "/app", поиск будет работать. Т.е. шаблонизатор ищет файлы не только в папке app в одном из случаев.

Пункт 2: две автогенерируемые переменные d()->paginator_current и d()->paginator_count, содержащие номер страницы и количество соотвественно. Пример:

<div>Страница {paginator_current} из {paginator_count} </div>

Пункт 3: возможность указать любой кастомный шаблон для пагинации.

<?php
d()->Paginator->custom_template("/app/components/custom_pagination.html")->generate($list);

Содержимое файла "custom_pagination.html" с описанием данных:

@ if (  ~paginator_left !== '') {
    <a href="{paginator_left|h}" class="control prev">Назад</a>
@ }

<ul class="pagination">
    <foreach paginator_list>
        <?php /*
            //Доступны следующие данные:
            d()->paginator_left;// - ссылка на предыдущю страницу или пустая строка
            d()->paginator_right;// - ссылка на следующую страницу или пустая строка
            d()->paginator_current;// - номер страницы (страница X из 10)
            d()->paginator_count;// - количество страниц (страница 2 из X)

            d()->this['type'];//"EMPTY" - многоточие, "ACTIVE" - текущая страница,"LINK" - не текущая страница
            d()->this['is_link'];//true - ссылка на страницу, false - многоточие
            d()->this['is_active'];//true - текущая страница активна, false - многоточие или не текущая страница
            d()->this['link'];//ссылка на страницу или пустота для многоточия
            d()->this['title'];//номер текущей страницы или "..." для многоточия
        */ ?>

        @ if (d()->this['type']=="LINK") {
            <li><a href="{.link}">{.title}</a></li>
        @ } 

        @ if (d()->this['type']=="ACTIVE") {
            <li><a class="active" href="{.link}">{.title}</a></li>
        @ } 

        @ if (d()->this['type']=="EMPTY") {
            <li class="disabled"><a href="#">...</a></li>
        @ } 

    </foreach>  
</ul>

@ if (  ~paginator_right !== '') {
    <a href="{paginator_right|h}" class="control next">вперед</a>
@ }

{paginator_current} из {paginator_count} 

18.02.2018

2.9.12.2

Исправлена ошибка при отсутствии папки, указанной в APP_DIRS (by @targrik).

12.12.2017

2.9.12.1

Для developer выводится файл, номер строки и трассировка при получении Exception.

12.12.2017

2.9.12

checkboxes четвертый параметр теперь указывает на имя таблицы, и он обязателен для использования пятого параметра.

06.12.2017

2.9.11

Новые водяные знаки. Больше не создается черный фон при накладывании png на png.

Появилась возможность указывать расположение водяного знака или задать его повторение (по умолчанию "center"), а также задать прозрачность (число от 1 до 100, по умолчанию 100). Указывается так:

<img src="{.image|preview '200', '200' , 'watermark'=> array("/images/watersmall.png", "center-right", 50) }">

Доступные значения для положения:

* repeat - заполнение повторением картинки
* top-left
* left-top
* center-top
* bottom-left
* center-left
* center-center
* center
* и любые другие сочетания двух значений "left", "center", "right" и "top", "center", "bottom" в любом порядке.

Также исправлена проблема, из-за которой конкатенация JS файлов происходила с ошибкой, если один из файлов не оканчивался на ";".

06.12.2017

2.9.10.1

Метод to_json_by_id объектов ActiveRecord аналогичен to_json - возвращает все данные, но в качестве ключей - значение поля id:

d()->News->select('id, title')->to_json_by_id;
//Результат:
{
    "21":{"id":"21","title":"title1","table":"news"},
    "34":{"id":"34","title":"title2","table":"news"},
    "17":{"id":"17","title":"title3","table":"news"}
}

12.11.2017

2.9.10

Функция preview автоматически поворачивает изображение, если в EXIF записан поворот. Исправляет баг "я загрузил картинку, а она повёрнута".

31.10.2017

2.9.9

Функция javascripts для объединения и сжатия js файлов. Обработчиков и компиляторов (например, ES2015) нет, только сжатие и объединение.

Использование:

{{javascripts  '/js/jquery-1.12.4.min.js', '/js/jquery-migrate-1.1.0.js' , '/js/main.js' , 'minify'=>true, 'to'=>'/js/minified_bundle.js'}}

Обратите внимание: для сайтов на HTTP/2 объединение не нужно.

28.09.2017

2.9.8

Поддержка необязательного параметра $_ENV["APP_DIRS"] (указывается в config.php). Можно указать дополнительные директории с кодом, помимо app и cms, например, для собственных наработок компании. МОдули будут переопределять друг друга последовательно. В дополнительных директориях не будет активироваться мультиязычность (app/lang) и статические шаблоны (app/static).

Пример:

<?php
$_ENV["APP_DIRS"]="cms,custom, app";

20.09.2017

2.9.7.4

Поддержка @include "file.scss"; в scss файлах, обрабатываемых функцией stylesheets. Ищет файлы в директории с указанным файлом, для каждого файла независимо.

05.09.2017

2.9.7.3

В элемент управления connected_checkboxes и checkboxes добавлен новый необязательный параметр (четвёртый в connected_checkboxes и третий в checkboxes). В него передается имя метода класса, который будет запрошен у соответствующей таблицы перед выводом списка, для фильтрации данных. Например, для таблицы users, при указанном параметре activated для построения списка галочек будут использоваться данные из списка d()->User->activated;

Внимание: классы Table_Safe не используются, используется обычный ActiveRecord.

Пример:

<?php
class Filial extends ActiveRecord {
    function limites(){
        return $this->limit(2);
    }
}

class Scriptstep extends ActiveRecord {
    function onlyquestions(){
        return $this->only('question');
    }
}


[admin.fields]
small  title "Название"
checkboxes to_filials "Филиалы"  limites
connected_checkboxes connected_question_id_in_script_questions "Следующие вопросы" scriptsteps onlyquestions

04.09.2017

2.9.7.2

Исправлена ошибка, из-за которой системе не удавалось правильно определить название many_to_many таблицы при сообщении об ошибке вида: "Создать столбец XXX в таблице YYY"?

Ошибка возникала, когда в many_to_many таблице отсутствовали столбцы с ID элементов и была попытка прочесть список элементов.

04.09.2017

2.9.7.1

Элемент управления для системы администрирования connected_checkboxes для вывода "галочек" для списка соединенной таблицы. Имеет обязательный для указания параметр (четвёртый).

Нужен только для вывода свойства title из выбранной таблицы.

Примеры:

;scriptsteps
[admin.fields]
small title "Название"
connected_checkboxes connected_question_id_in_script_questions "Связанные ответы" scriptsteps

;users
[admin.fields]
small title "Название"
connected_checkboxes friend_id_in_users_friends "Друзья" users

;products
[admin.fields]
small title "Название"
connected_checkboxes connected_similar_product_id_in_similars "Рекомендуемые товары" products

Для использования элемента управления не обязательно использовать запись connected_*_in_*. Система работает и с обыкновенным текстовым полем, просто записывая в базу данных id через запятую.

;products
[admin.fields]
small title "Название"
connected_checkboxes regionslist "Регионы" regions
connected_checkboxes just_title "ID категорий" categories

04.09.2017

2.9.7

Виртуальное свойство connected_field_in_table в ActiveRecord. Позволяет привязывать списки числовых идентификаторов к элементу таблицы, без указания точной таблицы, в которой эти идентификаторы представляют данные.

Можно использовать, например, для связи many_to_many одной и той же таблицы.

При сохранении принимает строку с идентификаторами, разеделенными запятой, при запросе возвращает её же.

Пример 1:

<?php
d()->product = d()->Product->find(14);
d()->product->connected_similar_product_id_in_similars = "1,2,4";
d()->product->save();
/* ... */
print d()->product->connected_similar_product_id_in_similars; //"1,2,4";

В данном примере в таблице similars появятся строки:

/* таблица similars */
----------------------------------------
| id | product_id | similar_product_id |
|----|------------|--------------------|
| 1  | 14         | 1                  |
| 2  | 14         | 2                  |
| 3  | 14         | 4                  |
----------------------------------------

04.09.2017

2.9.6

Для всех файлов функция stylesheets теперь по умолчанию подставляет дату изменения файла вида /css/compiled.min.css?1504332381. Чтобы выключить это поведение, надо указать параметр "mtime"=>false:

{{stylesheets '/css/style.less', 'minify'=>true, 'mtime'=>false}}

02.09.2017

2.9.5

Автолоадер теперь не создает экземпляры ActiveRecord, если класс начинается с маленькой буквы.

Большое обновление функции stylesheets. Теперь она включает:

* Компилирование SCSS
* Компилярование LESS
* Объединение (конкатенацию) CSS файлов
* Минификацию

Функция автоматически сверяет дату изменения оригинального файла и скомпилированной/сжатой версии.

Для включения минификации нужно указать параметр 'minify'=>true.

Для включения конкатенации нужно указать параметр 'concat'=>true или указать имя файла, которое будет содержать результат: 'to'=>'result.min.css'. Без указания имени будет браться md5 от всех имен файлов.

Если не указан путь, файлы будут искаться в папке css.

Для нормальной работы папке css должны быть переданы права за запись.

Примеры использования.

{{stylesheets '/css/style.scss','/css/style2.less', 'main.css', 'minify'=>true, 'to'=>'/css/result.css'}}
{{stylesheets '/css/style.scss'}}
{{stylesheets '/css/style.less'}}
{{stylesheets '/css/style.less', 'minify'=>true}}

27.08.2017

2.9.4

Элементы управления file и image теперь отображают процент загрузки.

10.08.2017

2.9.3

Объект d()->params теперь отдает правильные значения не только при вызове вида d()->params['email'], но и при вызове вида d()->params->email.

Это позволяет использовать его значение в шаблонах (например, шаблонах писем): {params.email|h}.

Добавлена ссылка на скачивание архивов модулей с сайта системы.

10.08.2017

2.9.1.1beta

Внимание! Beta версия! (см. описание 2.8)

Добавлены три метода: as_date_ru_month - получение строки вида "Май", as_date_day - получение дня в виде числа, as_date_mm_yyyy - получение строки вида "04.2017".

Используется для простого вывода даты в разных местах шаблона:

<div class="review-day">{.created_at_as_date_day}</div> <!-- 8 -->
<div class="review-month">{.created_at_as_date_mm_yyyy}</div> <!-- 07.2017 -->

09.08.2017

2.9.1beta

Внимание! Beta версия! (см. описание 2.8)

Защита от двойной отправки формы при медленном интернете.

Добавлен CSS класс js-disabled. Если этот класс указать для кнопки отправки формы, то она получит HTML свойство disabled сразу до отправки, и потеряет его после получения ответа сервера (но до его фактической интерпретации). Работает полностью автоматически.

Работает только для AJAX форм.

Пример (HTML):

<input type="submit" class="submit-button js-disabled" value="Отправить">

Пример (CSS):

.submit-button[disabled]{
    opacity:0.5;
}

09.08.2017

2.9beta

Внимание! Beta версия! (см. описание 2.8)

Добавлен новый загрузчик плагинов/расширений. Сами расширения хранятся на сервисе github и доступны для дополнения сообществом.

08.08.2017

2.8beta

Внимание! Beta версия!

Появилась конструкция ~ в шаблонизаторе, которая заменяется на d()->

Позволяет городить такие конструкции:

@ ~objects_list = ~Object->order('sort DESC');

{{add 'users', 'category_id'=>~title}}
<?php if(~Auth->id == ~current_user){ /* */ } ?>

Не срабатывает после закрывающихся скобок, для арифметических операций ожидает перед собой пробел. Потенциально безопасна, не должна влиять на работу сайта и пересекаться с другими знаками ~, но без долгого тестирования считается beta версией.

07.08.2017

2.7.7.1

В режиме разработчика выводится база данных, путь к сайту и phpinfo()

27.07.2017

2.7.7

Теперь элемент управления file работает без flash в связи с последними обновлениями браузеров.

29.06.2017

2.7.6.1

Добавлен метод and_select() у ActiveRecord. Добавляет дополнительный параметр к полю SELECT запроса. Параметр является обязательным. Предварительный вызов select() обязателен, иначе запрос будет вида SELECT * , user_id.

Например:

d()->users->select('id');
d()->users->and_select('min(price) as price');
d()->users->and_select('user_id, category_id');
//Будет преобразовано в SELECT id, min(price) as price, user_id, category_id

24.05.2017

2.7.6

Добавлен метод clone у ActiveRecord. Возвращает клон объекта, либо сохраняет именованный клон и возвращает его.

Алиасы: copy(), clone_copy().

Использование:

<?php
d()->objects_list = d()->Object->order('sort DESC');
d()->objects_list->copy; //Клон объекта
d()->objects_list->copy(); //Клон объекта
d()->objects_list->clone; //Клон объекта
d()->objects_list->clone(); //Клон объекта

d()->objects_list->clone_f2->where('user_id = 1');
d()->objects_list->clone_f2; //Сохранённый клон под именем f2
d()->objects_list->clone("f2"); //Сохранённый клон под именем f2
d()->objects_list->copy("f2"); //Сохранённый клон под именем f2

Использование на практике:

<?php 
//Старый вариант
$dp = clone d()->objects_list;
$ss = $dp->select('user_id')->group('user_id')->fast_all_of('user_id');
d()->user_list = d()->User->where('id IN (?)', $ss);
foreach (d()->user_list){ /* ... */ }

//Новый вариант
d()->objects_list->clone_for_users->select('user_id');
foreach (d()->objects_list->clone_for_users->_users){ /* ... */ }

24.05.2017

2.7.5

Трейт Tree для работы с деревьями внутри ActiveRecord.

class Category extends ActiveRecord
{
    use Tree;
}

Добавляет методы для определения наддерева и поддерева: subtree_ids(), subtree, suptree_ids, suptree.

17.04.2017

2.7.4

Новый элемент управления для автотранслита. Пример использования:

[admin.fields]
urltranslit url "Адрес" title "(необязательно)"
small title "Заголовок"

10.01.2017

2.7.3

Исправлена ошибка admin_authorisation : Using $this when not in object context.

29.12.2016

2.7.2

Расширенные опции для оптимизатора изображений (на случай, если необходимо максимальное сжатие). Например, для JPG разница в 75%.

Для использования необходимо установить mozjpeg(https://mozjpeg.codelove.de/binaries.html) и pngquant(https://pngquant.org/), и настроить пути к ним в config.php

Пример (на примере Windows):

$_ENV["DOIT_OPTIMIZE_IMAGES"] = true;
$_ENV["DOIT_OPTIMIZE_IMAGES_EXTEND"]=array(
    'PNG'=>'pngquant --quality=60-90 - < #SOURCE# > #DEST#',
    'JPG'=>'E:\OpenServer\modules\php\PHP-5.6\ext\cjpeg -quality 70 #SOURCE# > #DEST#',
);

Допустимо использовать другие инструменты.

15.12.2016

2.7.1

Оптимизатор изображений, встроенный в функцию preview. Активируется опцией в config.php:

$_ENV["DOIT_OPTIMIZE_IMAGES"] = true;

Для работы необходимы внешние библиотеки, установленные на сервере. В противном случае просто игнорирует задачу Подробнее об оптимизаторах написано тут: https://github.com/psliwa/image-optimizer

Например, для установки оптимизатора для jpeg (jpegtran) для ubuntu/debian необходимо выполнить

apt-get install libjpeg-progs

14.12.2016

2.7beta

Внимание! Beta версия!

Конструкция

{.image|preview "136", "136"}

Теперь всегда делает проверки на is_object по всей длине цепочки.

09.11.2016

2.6.0.3beta

Внимание! Beta версия!

Конструкция

{.image|preview "136", "136"}

Компилировалась в

<?php print  $doit->preview(array(  $doit->this->image ,  "136", "136")) ; ?>

Таким образом, для массивов не работала. Сейчас компилирует в

<?php print  $doit->preview(array(  $doit->this['image'] ,  "136", "136")) ; ?>

Возможны проблемы при вызове методов объектов.

09.11.2016

2.6.0.2

Поддержка подсветки синтаксиса в полях big в админке. Использование следующее:

big text "HTML код" html
;Для обычного текста без подсветки
big text2 "код" text
big text3 "PHP код" php

В ini файл для полей по умолчанию записана закомментированная строка опции сортировки.

;[admin]
;list.sort_field=created_at
;list.sort_direction=desc

27.10.2016

2.6.0.1

Функция or_is_empty(), которая возвращает второе значение, если первое пустое.

Например:

Заработная плата: {.money|h|or_is_empty "не указана"}

21.10.2016

2.6

Поддержка конструкции _as_.

Например,

d()->product->image_as_preview;
d()->product->category_id_as_object_title;
d()->product->category_id_as_title;

При вызове ищет функцию, которая начинается на as_ и вызывает её, передавая три параметра: значение, имя метода (часть перед _as_), и ссылку на объект.

Может использоваться в панели администрирования для удобного вывода значений в списке:

[admin.use_model]
list=yes

[admin.columns]
title=Название
category_id_as_object_title="Категория"
image_as_preview="Картинка"

19.10.2016

2.5.2

Поддержка событий.

Регистрация события:

d()->on('auth',function($id,$method){
    var_dump($id);
    var_dump($method);
});

Вызов события:

d()->emit('auth',12);

01.07.2016

2.5.1

Отныне Doit - PSR-7 совместимый фреймворк.

Внимание: по-прежнему beta-версия.

Поддержка PSR-7 middleware. Завершено внедрение zend-diactaros, внедрение zend-stratigility.

Это позволяет использовать собственные или сторонние middleware стандарта PSR-7.

Кроме этого, открывается новый способ построения веб-приложения вообще без использования контроллеров или роутов микрофреймворка (route, get, post), при помощи одних middlewares.

Пример добавления middleware:

<?php
d()->add(function($request, $response, $next){
    $response->getBody()->write('before');
    $next($request,$response);
    $response->getBody()->write('after');
});

//С привязкой к адресу  
d()->add('/news/',function($request, $response, $next){
    $response->getBody()->write('before');
    $next($request,$response);
    $response->getBody()->write('after');
});

Также можно создать новый MiddlewarePipe при помощи d()->new_pipe(). Полученный объект может сам служить в роли middleware, но при этом сам может при помощи метода pipe() принимать вложенные middleware. Подробнее можно посмотреть по адресу https://github.com/zendframework/zend-stratigility/blob/master/doc/book/executing-middleware.md

Возможности middleware доступны только для PHP версии 5.4.8 и выше. Для более старых версий middleware, request, response не создаются и не используются, использование метода add приведёт к ошибке отсутствия класса. При этом совместимость с другими проектами полностью сохраняется - если не использовать возможности middleware, то всё будет продолжать работать как и раньше на любой версии PHP, старше чем 5.3.

28.04.2016

2.5

PHP 5.4 - минимальная версия PHP для всех возможностей системы. Минимально поддерживаемая версия PHP по прежнему 5.3.

Подключен zend-diactoros. Впоследствии будет включён глубоко в систему. Доступен следующим образом:

d()->http_request->getHeaders();

Для PHP 5.3 не используется. Для использования обязательно иметь PHP 5.4. 5.4 становится минимально совместимой версией системы. На PHP 5.3 система по прежнему работает без сбоев в режиме совместимости, d()->http_request при этом недоступен.

27.04.2016

2.4.2

Короткая запись для правил роутера. Если путь не начинается на "/", то срабатывает автопоиск пути по имени директории:

d()->get(function($url){
    print $url;
});

Также можно указать путь явно при помощи d()->group('/news/');

Если первый параметр функций route(), get(), post() пропущен, то вставляется ":param*" - полный путь, включая пустую строку.

Альтернативная запись:

d()->group('/news/',function(){
    d()->get(':url', function($url){
        print $url;
    });
})

27.04.2016

2.4.1

Поиск шаблонов для d()->view. Новая лицензия (MIT). Методы get() и post() для роутера. Метод via() для роутера.

d()->post('/feedback/send',function(){
    //обработчик формы
});

d()->get('/feedback/',function(){
    //показать форму
});

Класс d()->view теперь может искать файлы шаблонов в текущих директориях для анонимных функций и роутов:

<?php
//для анонимной функции
d()->my_function=function(){
    print d()->view->render('template.html');
};

//для роута
d()->get('/feedback/',function(){
    print d()->view->render('template.html');
});

Новая лицензия (MIT) расширяет возможности по использованию фреймворка в коммерческих целях.

26.04.2016

2.4

Внимание! Beta версия.

Появление composer для пользователя системы. Появление composer внутри системы администрирования. Перевод SwiftMailer внутрь composer.

Для использования необходимо выполнить команду composer require "пакет" - установится composer и появится папка vendor в корне системы.

21.04.2015

2.3

Передача в переменную Closure для дальнейшего запуска через вызов функции. Приоритетнее, чем остальные способы передачи функции. Пример вызова:

d()->summa = function($a,$b){
    return $a + $b;
};

print d()->summa(2,3); //5

Благодаря высокому приоритету может переопределить функцию summ(), даже если она есть. Благодаря этому можно переопределять некоторые внутренние функции системы, заданные в виде PHP функций, например, edit(), не используя возможностей роутера.

05.04.2016

2.2.1

Исправление умного автоподставлятеля символа "=>". Теперь конструкция

{{edit "href"=> "/admin/edit/plugins/name?fields=textblock" }}

не превращается в

<?php print $doit->call("edit",array(array( "href"=> "/admin/edit/plugins/name?fields=>textblock" )));?>

25.01.2016

2.2

Поддержка нотации json в ini-файлах

Синтаксис на данный момент следующий:

[params]
element.title=Метро
element.list=json:["Авиастроительная", "Аметьево", "Горки", "Козья Слобода", "Кремлёвская", "Площадь Тукая", "Проспект Победы", "Северный вокзал", "Суконная слобода","Яшьлек"]

Может использоваться в значениях, переданных через знак =. Строка должна начинаться на :json.

20.11.2015

2.1.5.1

Вывод ошибки при неудаче найти файл шаблона в новом классе view;

19.11.2015

2.1.5

Рекурсивный итератор для шаблонизатора.

<?php  d()->this = d()->Region->where('region_id is null') ;  ?>
<select name="region_id">
    <option value="">-не указано-</option>
    <tree regions>
        <option value="{.id}">
            {level|times "—"} {this.title}
        </option>
    </tree> 
</select>

27.10.2015

2.1.4

Функция times для повтора символов и текста:

<?php d()->level = 5; ?>
{level|times "—"}

26.10.2015

2.1.3

Базовая поддержка постпроцессора CSS. (autoprefixer, cssnano, и т.д.)

Синтаксис следующий:

<head>
{{stylesheets '/css/style.scss'}}
</head>

Компиляция CSS проводится в облаке, соответственно, без подключённого Интернета не работает.

10.08.2015

2.1.2

Новый валидатор, поддержка bootstrap 3 в автоматической подсветке ошибок.

10.08.2015

2.1.1

Запись {{/projects/_one.html}} для отображения партиала для версии 2.0

06.08.2015

2.1.0.beta

Значительно переработан шаблонизатор.

Появились конструкции:

@print 2+2;

{* comment *}

{user.product.source.parent.author|h|preview '200', 'auto'}

07.07.2015

2.0

Требование PHP 5.3.

Появление контейнера объектов. Появление Swift mailer. Появление cms/vendor/

07.07.2015

0.30

Ace Editor в редакторе ini файлов

0.29.9.1

В папке sites теперь можно указывать не полное имя домена, а только поддомен.

05.06.2015

0.29.9

Кнопка "сохранить и добавить ещё" при добавлении объекта демо. Багфиксы.

21.04.2015

0.29.8

Файлы в загрузчике картинок и файлов, включая tinymce, теперь имеют человекопонятные имена.

21.04.2015

0.29.7.1

Поддержка времени в датах, передаваемых в Date()

09.09.2014

0.29.7

Вставка картинок в TinyMCE через CTRL+V;

09.09.2014

0.29.6

Поддержка произвольных HTML в конфигах форм администратора.

Для вставки в fields/tablename.ini надо вписать код:

include "mycontainer"

mycontainer - имя HTML файла, либо метод контроллера, либо функция. Например, допустимо:

include "users#editform"

Для вставки классических элементов в подобные шаблоны можно использовать следующий синтаксис:

{{form_row 'small', 'subtitle', 'Подзаголовок'}}

Может использоваться для вывода инструкций и другой информации прямо в формах администратора, а также для создания элементов управления повышенной сложности.

Поддержка третьего необязательного параметра для container в админке. Указывает на массив доступных модулей (ini) вместо container.ini.

06.09.2014

0.29.5.1

Поддержка названий в контейнерах container. Меняется двойным щелчком.

05.09.2014

0.29.5

Поддержка нескольких получателей события через socket.io.

Используется так:

d()->SocketIO->emit('bb156e7e617ad61894cbdf35481705a0' ,'server_event','Привет1');
d()->SocketIO->emit('7a30bb1f473b2d6dc642c05d83adbb75' ,'server_event','Привет2');
d()->SocketIO->emit(array('7a30bb1f473b2d6dc642c05d83adbb75','bb156e7e617ad61894cbdf35481705a0') ,'server_event','Привет 1 и 2');

В качестве удобства также теперь доступна конструкция d()->Socketio->userid, устанавливаемая по-умолчанию;

02.09.2014

0.29.4

Поддержка строк, массивов любой вложенности при передаче на сервер сообщений (socket.io). Облачный сервер прописан по-умолчанию (если не указывается иной адрес)

29.08.2014

0.29.3

Базовая поддержка Push запросов с сервера через прокси node.js.

29.08.2014

0.29.2

Новое правило автоподставления шаблонов теперь работает только с контроллером pages. С остальными контроллерами поведение старое. Соответственно обратной совместимости стало немного больше.

25.08.2014

0.29.1

Новая версия системы.

Значительные изменения в системе роутинга.

  1. Файл router.init.ini устарел. Все изменения вносятся в файл router.func.php. Для старых проектов можно ничего не делать - всё будет продолжать работать. Также можно удалить router.func.php и всё будет работать по-прежнему. Однако использование правил роутера в виде функций даёт ряд преимуществ: более лаконичный синтаксис, возможность ставить условия, циклы, анонимные функции, поддержка роутеров для ленивых, а в дальнейшем дополнительные фильтры на типы запросов. Пока этот файл удалять не стоит - скаффолдинг использует именного его. Однако сейчас при наличии функции route_allв файле router.func.php галочку "добавить запись в роутер" при использовании скаффолдинга можно не делать.
  2. В файле router.func.php и любых других можно указывать команды route(), которые добавляют правила роутинга. При этом слово content можно игнорировать.
  3. В файле router.func.php по-умолчанию запускается функция route_all(), которая автоматически добавляет правило роутить контроллеры автоматически, например, /news/ на news#. Таким образом, теперь класс NewsController будет доступен по адресу /news/ полностью автоматически. Это не будет активировано для старых проектов (т.к. функция route_all() не запущена. Это правило отменяется для любых адресов, для которых зарегистрировано хотя бы одно правило в роутере.
  4. При определении шаблона метода контроллера проверяется наличие файла. Если мы запрашиваем страницу /users/vasya методом show() и файл _vasya.html существует, то именно он будет использоваться в качестве шаблона. Это может поменять поведение в некоторых случаях! Пример такого случая: для роутинга на /index не создавалось правил вообще, использовался classname# (например, users# или news#), при этом метода index не создавалось (и зря). Использовался шаблон _index.html без вызова метода контроллера. Теперь же метод show() контроллера будет вызван. Эта новая возможность делает работу немного легче. Например, чтобы переопределить шаблон главной страницы, достаточно создать файл _index.html и всё.
  5. Теперь необъявленный класс вида Blabalbacontroller (заканчивающийся на controller) не будет создан автоматически (как ActiveRecord) при обращении к нему.
  6. Функция route может принять на вход анонимную функцию. Это позволяет использовать систему как микрофреймворк, но в данном случае версия PHP должна быть уже 5.3 или выше (5.2 не поддерживает анонимные функции).

25.08.2014

0.29

Новый роутер.

24.08.2014

0.28.2.1

Исправлен баг: delete не очищал кеш ActiveRecord;

21.08.2014

0.28.2

Поддержка ватермарков (водяных знаков) в функции preview. Используется параметр watermark, указывающий на картинку.

Использовать так:

<img src="{.image|preview 'watermark'=>'/images/header_watermark.png', 512,320}" alt="{.title|h}">

Или так:

{{preview d()->this->image, '200', '300', 'watermark'=>'/images/watermark.png'}}

Картинка-watermark помещается по центру. Рекомендуется использовать для картинки-накладки тот же самый размер, что и генерируемая превью.

15.08.2014

0.28.1.3

UniversalSingletoneHelper стал немного универсальнее. Минорное изменение.

06.06.2014

0.28.1.2

Поддержка записи вида {variable|function 'param'}.

06.06.2014

0.28.1.1

Исправлен баг: не генерировались paginator_left и paginator_right на bootstrap режиме пагинатора.

06.06.2014

0.28

Поддержка контейнеров. Контейнер позволяет вставить на страницу множество различных элементов, таких как заголовки, столбцы, картинки, формы. Может использоваться для создания посадочных страниц и богатого оформления заранее заготовленными блоками. Для использования необходимо:

Первое. Создать функцию, которая может быть контейнером. Например, contactform#show, а также другие функции.

Второе. Создать файл container.ini со следующим содержимым (перечислить функции):

[container]
contactform#show=Форма обратной связи
contactform#show1=Первый модуль
contactform#show2=Второй модуль
news#index=Список новостей

Третье. В файле /fields/pages.ini или другом, соответствующем нужной таблице написать строчку:

container text2 "Элементы управления"

Перетащить туда несколько элементов.

Четвёртое. В шаблоне написать {.text2|container}.

Всё. Элемент управления, ini-файл, функция-обработчик - все они называются container. Если привязать контейнер к опциям, можно делать сквозные элементы (которые повторяются по всему сайту).

Внутри кода контейнера доступна переменная d()->plugin_id с уникальным строковым идентификатором, указывающим на конкретный компонент внутри контейнера.

11.05.2014

0.27.2.2

Класс Mail теперь принимает свойство from даже в том случае, если не используется SMTP (вариант отправки через mail() без вложенных файлов).

Использовать, например, так:

d()->Mail->from('Робот сайта <noreply@example.com>');

07.05.2014

0.27.2.1

Исправление AJAX части формы для IE8.

04.04.2014

0.27.2

Полиморфные объекты для linked. Изменения довольно важные и полезные, поэтому будут описаны в отдельном документе. Теперь можно делать похожие товары, аксессуары, друзья, и так далее.

04.04.2014

0.27.1.2

Введён новый метод ActiveRecord->ne, возвращает true, если есть хотя бы один результат.

02.04.2014

0.27.1.1

Введён новый метод ActiveRecord->is_not_empty, возвращает true, если есть хотя бы один результат.

02.04.2014

0.27.1

Новый метод plus

Поддержка метода plus. Позволяет добавить к массиву ещё один. Не переопределяет текущий объект, а создаёт новый.

Например:

d()->goods = d()->Good->where('cost < 100');
d()->goods = d()->goods->plus(12);//12 - ID товара

//Также умеет принимать массив товаров
d()->goods = d()->goods->plus(d()->Good->where('cost > 1000'));

Принимает число, массив чисел, массив ассоциативных массивов с полем id, объект ActiveRecord.

Новый метод all_linked или _all_catalogs

Подержка метода all_linked. Делает linked рекурсивно, пока получается. Не столь явно и универсально, как linked, но зато позволяет получить всё дерево в глубину. Имеет псевдоним _all_*, например, _all_catalogs.

d()->Catalog(3)->_all_catalogs; //Все дочерние каталоги и их дочерние каталоги и т.д. 

Пример получения всех товаров каталога c ID=$id и всех его дочерних каталогов. С постраничной навигацией.

d()->catalog = d()->Catalog($id);
d()->catalog = d()->catalog->_all_catalogs;
d()->catalog->plus($id);
d()->goods = d()->catalog->_goods->paginate(2);

Тоже самое одной строкой:

d()->goods = d()->Catalog($id)->_all_catalogs->plus($id)->_goods->paginate(2);

Допустим, товары дополнительно хранятся в catalogs_to_goods через альтернативную связь many_to_many.

/*
    Данный код получает все каталоги, подкаталоги,
    под-под-каталоги и т.д. каталог с id=$id, 
    затем получает все товары всех этих каталогов,
    в том числе и указанных напрямую через catalog_id,
    и через дополнительную связь many_to_many,
    а также товаров самого каталога $id.
    Полученные товары подвергаются пагинации.
*/
d()->goods = d()->Catalog($id)
    ->_all_catalogs
    ->plus($id)
    ->_goods
    ->plus(d()->Catalog($id)->_all_catalogs->_catalogs_to_goods->_goods)
    ->paginate(2);

Конечно, вот так вот "однострочничать" не рекомендуется.

01.04.2014

0.27

Значительное обновление в ActiveRecord. Появление метода linked, который получает связанные объекты. Для массива каталогов linked('goods') вернёт массив товаров в этих каталогах, для массива товаров linked('catalogs') вернёт массив каталогов этих товаров.

Если товар или каталог один - ничего страшного.

Массивы являются объектами ActiveRecord, поэтому к ним можно применять where, limit, paginate и так далее.

Более удобная сокращённая запись: d()->Good->_catalogs (аналог d()->Good->linked('catalogs')). Предположительно, станет основным инструментом получения данных (обычный способ останется для совместимости).

d()->Catalog(13)->catalogs->_goods; // Вернёт все товары всех подкаталогов каталога 13
d()->Catalog(13)->catalogs->_goods->_users; // Вернёт всех пользователей всех товаров каталога 13

// Вернёт все каталоги, в которых есть товары с ценой меньше 100, с постраничной навигацией
d()->Good->where('cost < 100')->_catalogs->paginate(10);

//Пользователи, которые оставляли комментарии за последний день
d()->Comment->where('created_at > ?',d()->Date('yesterday')->to_mysql)->_users;

Рассмотрим более сложный случай:

  • У нас есть таблица works с портфолио.
  • Есть таблица portfoliodirections с тегами для портфолио (направления работы). Одна работа может иметь несколько направлений.
  • Есть таблица portfoliodirections_to_works, у которой есть столбцы portfoliodirection_id и work_id.

Итого: many_to_many таблица связей.

Мы хотим получить список всех работ по тегу с ID=3, а также всех работ по тегам, ID которых больше 2

Решение:

d()->Portfoliodirection(3)->_portfoliodirections_to_works->_works;
d()->Portfoliodirection->where('id > 2')->_portfoliodirections_to_works->_works;

Кроме того, добавлен метод ActiveRecord для более быстрого получения all_of('ids').

Вызывается так:

d()->Catalog->fast_all_of('id');

Склонять во множественном числе не надо, объекты не создаются, данные берутся напрямую из массива. В некоторых случаях такой вызов на 2-3 порядка быстрее обычного. В любом случае в дальнейшем метод linked должен привести к тому, что all_of просто не пригодится.

Кроме того, оптимизирован where('id IN (?)',$array), который теперь делает array_unique, что на пару процентов ускоряет запрос.

31.03.2014

0.26.12

Отныне d()->Page('') ничего не вернёт (количество записей будет равно нулю).

27.03.2014

0.26.11.1

Поддержка записей вида d()->Page('index'). Ищет по url, является синтаксическим сахаром. Будет использоваться в модуле "меню".

27.03.2014

0.26.11

В роутере теперь проще писать алиасы для html-шаблонов - .html автоматически меняется на _tpl. Например, теперь можно писать так:

/index      main.html       index.html

27.03.2014

0.26.10

Поддержка метода where_equal в ActiveRecord. Первый аттрибут - название поля, второе - значение. Например:

d()->news_list = d()->News->where_equal('title', 12);

Может пригодиться в том случае, когда названия столбцов передаются через переменные. Всё экранирование происходит автоматически.

25.03.2014

0.26.9

Параметр в валидаторе для отображения скрытого поля. Если поле пришло не пустым - валидатор дальше не пустит. Необходимо для защиты от ботов. В валидаторе пишется следующее:

[validator.contactform#send.city]
must_be_empty.message=Возможно, вы робот. Уйдите.

В код формы вставляется примерно следующее:

<div style="display:none">
    <input  type="text" name="city" placeholder="Город" autocomplete="off">
</div>

autocomplete="off" необходимо, чтобы в это поле не вбился автоматически город. Поле city можно изменить на любое подходящее.

Внимание! название поля в виде city, а не data[city] актуально только для форм с 'simple_names'=>true,! Это обычное поле с обычными данными и обычным валидатором, просто работает наоборот.

24.03.2014

0.26.8.1

{{sort_icon}} без параметров берёт опции предыдущего {{add}}. Это сделано потому, что в большинстве случаях (срого говоря, на практике - во всех) параметры этих иконок всегда одинаковы.

23.03.2013

0.26.8

Теперь администратор может сортировать столбики в таблице вывода списка элементов путём щелчка по ним.

22.03.2014

0.26.7

Поддержка записи вида

d()->News(array(12,5,7));
//Идентично следующему
d()->News->where('id IN (?)', array(12,5,7));

21.03.2014

0.26.6.1

Поддержка TRUNCATE в ActiveRecord. Вызывается так:

d()->Konkurs->truncate(true);
d()->Page->truncate(true);

true - обязательный параметр, его не надо настраивать или передавать как переменную. Это сделано для безопасности.

Внимание! Выполнение функции как переменной или вызов без обязательного параметра true приведёт к ошибке. Будьте внимательны и осторожны со своими данными.

19.03.2014

0.26.6

Функция declOfNum (определяющая множественное число) теперь имеет несколько альтернативных синтаксисов:

//Было
d()->declOfNum(81,array('попугай','попугая','попугаев'))
//Теперь ещё можно так
d()->declOfNum(1,'комментарий','комментария','комментариев');
d()->declOfNum(2,'комментарий','комментария','комментариев');

Также теперь можно вовсе не передавать все слова - функция сама попытается определить грамматически правильную форму:

d()->declOfNum(2,'комментарий'); //комментария
d()->declOfNum(20,'новость'); //новостей

Это также работает для английских слов (на всякий случай):

d()->declOfNum(20,'child'); //children

Также шаблонизатор поддерживает конструкцию вида {obj.prop|func "params"}. В итоге, теперь можно писать так:

{news_list.count} {news_list.count|declOfNum "новость"}
{Comment.count} {Comment.count|declOfNum "комментарий"}

Также обновлены тесты для всего этого.

18.03.2014

0.26.5

Обновлён TinyMCE 3.5.6 (2012-07-26) → 3.5.10 (2013-10-24).

17.03.2014

0.26.4

Поддержка татарского языка в датах (мультиязычность). Поддержка обработок дат вида

d()->Date('12 января 2014');
d()->Date('12 гыйнвар 2014');
d()->Date('12 02 2014');

16.03.2014

0.26.3

htmlimage загрузчик картинок теперь поддерживает перетаскивание нескольких файлов одновременно (для multiple=yes).

Модуль image теперь полностью замещён новым загрузчиком. Для старых браузеров автоматически отображается старый вариант на flash.

Таким образом, сейчас основной элемент image для загрузок картинок администратором обновлён, выглядит и работает по другому. Сам механизм и принцип работы остались прежними, в первую очередь добавились удобства - скорость работы, работа на некоторых устройствах без flash (некоторые планшеты и т.д.), появилось перетаскивание файлов в браузер, вставка из буфера обмена, внешний вид.

13.03.2014

0.26.2.3

htmlimage загрузчик картинок теперь поддерживает multiple=yes, позволяя выбрать несколько изображений одновременно.

13.03.2014

0.26.2.2

htmlimage загрузчик картинок теперь может вставлять изображения перетаскиванием файла в браузер.

12.03.2014

0.26.2.1

htmlimage загрузчик картинок теперь может вставлять изображения из буфера обмена (изображения, не файлы изображений) и автоматически загружать их в виде файлов.

12.03.2014

0.26.2

Поддержка автогенерируемого sitemap.xml.

В роутере необходимо прописать

/sitemap.xml    main        show_sitemap

Файлы sitemap.func.php и sitemap.ini должны находиться в папке app (они не создадутся при обновлении). Сами правила описаны в файле sitemap.ini, там перечислены адреса и таблицы, которые должны быть видны в карте сайта.

0.26.1.1

Исправлено поведение загрузчика в IE11.

11.03.2014

0.26.1

Новый тип файлового загрузчика для панели администратора, без использования flash. Вызывается тем же синтаксисом, но называется htmlimage:

htmlimage image "Изображение" galleries 180 auto

Работает немного отзывчивее, чем на основе flash, но работает только начиная с IE9 и Opera 12. (http://caniuse.com/xhr2).

Если опыт покажет положительный результат, обычный image будет заменён на этот, либо в старых браузерах будет подставляться flash-версия.

11.03.2014

0.26

Поддержка пользователей для системы администрирования с правами на разные таблицы.

Для того, чтобы воспользоваться, следует раскомментировать строки в admin.ini (или вписать их):

[admin.users]
enabled=yes

И добавить ссылку на редактирование пользователей.

[admin.leftmenu]
admin_users "Администраторы системы"

Система предложить создать таблицу admin_users. Для создания нового пользователя системы администрирования необходимо указать его логин, пароль и список таблиц, в которые он имеет доступ через запятую, например, pages, news, options.

Все иконки администратора будут автоматически скрываться, если у администратора нет соответствующего доступа.

Доступ закрывается к таблицам, включая иконки, страницы редактирования и списка объектов, а также на сами действия по сохранению, созданию или удалению.

Более подробно будет описано в документации.

11.03.2014

0.25.3

Поддержка нормальных дат.

Наконец появилась возможность задавать даты в админке в поле формата date, а не строки.

Итого, для использования в админке необходимо вписать:

date date_at "Дата"

Если будет передана пустая строка, то дата сохранится как NULL, тоже самое касается класса ActiveRecord в целом.

Внимание! Если вы манипулировали в своих проектах строками вида "0000-00-00 00:00:00", то теперь вместо них будет записываться NULL

Обязательное условие - название поля должно оканчиваться на _at, например, date_at, fired_at, posted_at.

Функция userdate, преобразующая к нормальному виду, по-прежнему работает.

Появилась возможность написать

<?php
d()->Date(d()->this->posted_at)->to_simple(); // "24.03.2014"
d()->Date(d()->this->posted_at)->to_mysql(); // "2014-03-24 12:00:00"

Также обновлены тесты для пагинации и для проверки дат.

10.03.2014

0.25.2

Класс Upload для простой загрузки файлов изображений.

Для самого простого использования:

$filename = d()->Upload->save();

В переменной $filename будет находиться адрес к файлу (в случае картинки - готовой к созданию превью). По-умолчанию пустит только картинки и распространённые файлы.

Параметр upload для формы, указывающий enctype для загрузки файлов.

09.03.2014

0.25.1.1

Вывод текущей версии в админке (только для developer, подвал и страница обновления).

08.03.2014

0.25.1

Оптимизирован код ActiveRecord, убраны некоторые лишние проверки, которые никогда не будут вызваны.

Заведена история версий, которая будет использоваться для определения текущей версии системы (для обновления).

08.03.2014


comments powered by Disqus