Функции хелперы для MODX


Друзья, поздравляю всех с наступающим Новым годом! Надеюсь, в новом году мы преодолеем все трудности и нам всем улыбнётся удача!


Ещё я хочу представить новую разработку в сфере улучшения процесса разработки — функции для работы с MODX.


Это глобальные функции, которые можно использовать в любом месте — и в сниппетах, и в классах, и даже в чанках и шаблонах, если установлен Fenom. В данный момент доступно около 50 функций:
  • url() — генерирует url.
  • redirect() — переадресация на указанный url или страницу, если указан id.
  • forward() — выводит указанную страницу без изменения url.
  • abort() — переадресация на страницу ошибки.
  • config() — работа с массивом настроек.
  • session() — работа с сессией.
  • cache() — управляет кэшем.
  • parents() — возвращает массив родителей указанного ресурса.
  • children() — возвращает массив дочерних ресурсов.
  • pls() — чтение/установка прейсхолдеров.
  • pls_delete() — используется для удаления плейсхолдеров.
  • lang() — для работы с лексиконом.
  • email() — отправка почты.
  • email_user() — отправка почты пользователю.
  • quote() — экранирует строку.
  • esc() — оборачивает спец. символом драйвера базы данных.
  • css() — подключает стили.
  • script() — подключает скрипты.
  • html() — подключает HTML разметку.
  • chunk() — вызывает указанный чанк.
  • snippet() — вызывает указанный сниппет.
  • processor() — вызывает процессор.
  • is_auth() — проверяет, авторизован ли пользователь в указанном контексте.
  • is_guest() — проверка, является ли пользователь гостем.
  • can() — проверка прав.
  • resource_id() — получает id текущего ресурса.
  • template_id() — получает id шаблона текущего ресурса.
  • user_id() — получает id текущего пользователя.
  • tv() — получает TV текущего ресурса.
  • object() — функция для работы с объектами MODX.
  • collection() — функция для работы с коллекциями объектов MODX.
  • resource() — функция для работы с ресурсами MODX.
  • resources() — функция для работы с коллекцией ресурсов MODX.
  • user() — функция для работы с пользователями MODX.
  • users() — функция для работы с коллекцией пользователей MODX.
  • object_exists() — проверка существования объекта с указанными свойствами.
  • resource_exists() — проверка существования ресурсов.
  • user_exists() — проверка существования пользователей.
  • str_clean() — очищает строку от указанных символов.
  • table_name() — выводит название таблицы класса.
  • columns() — выводит список полей таблицы класса.
  • is_url() — проверка валидности url.
  • is_email() — проверка валидности email.
  • log_error() — запись в журнал ошибок для уровня логирования ERROR.
  • log_warn() — запись в журнал ошибок для уровня логирования WARN.
  • log_info() — запись в журнал ошибок для уровня логирования INFO.
  • log_debug() — запись в журнал ошибок для уровня логирования DEBUG.
  • context() — Выводит указанное свойство текущего контента. По-умолчанию это ключ.
  • query() — для работы с сырыми SQL запросами.
  • memory() — выводит отформатированную строку используемой памяти.
  • img() — формирует HTML тэг img.
  • faker() — создает фейковые данные.

Немного примеров

# Проверка существования пользователя по email
if (user_exists(['email'=>'admin@mail.ru']) {
    // Пользователь с таким email существует
}

# Получить данные из кэша
$value = cache('key', 'my_data');
// Альтернативный вариант
$value = cache()->get('key', 'my_data');

# Отправка почты
email('pupsik@mail.ru', 'Тема','Содержание письма');
// Пользователю
email_user('admin', $subject, $content);

# Получить последний ресурс.
$resourceObject = resource()->last(); // Объект ресурса
$resourceArray = resource()->last()->toArray(); // Массив с данными ресурса

# Последние 10 ресурсов.
$resObjects = resources()->last(10); 

# Массив с заголовками ресурсов родителя с id=20. Можно использовать для формирования селекта.
$titles= resources()->where(['parent'=>20])->get('pagetitle'); // array('pagetitle 1', 'pagetitle 2', 'pagetitle 3')

# Записать значение в сессию
session('key1.key2', 'value'); // => $_SESSION['key1']['key2'] = $value;
//# Получить значение из сессии
$value = session('key1.key2');  // $value = $_SESSION['key1']['key2']

# Проверить авторизован ли пользователь
if (is_auth) {}  // альтернатива $modx->user->isAuthenticated($modx->context->key)

# Проверить валидность email
if (is_email($_POST['email'])) {
   // Почта валидная
}

# Переместить ресурсы от одного родителя другому и установить другой шаблон
resources()->where(['parent'=>20])->set(['parent'=>5, 'tempate'=>1]);

# Удалить дочерние ресурсы родителя с id = 20
collection('modResource')->where(['parent'=>20])->remove();
// Для ресурсов есть своя функция
resources()->where(['parent'=>20])->remove();

# Получить количество заблокированных пользователей
$count = users()->profile()->where(['Profile.blocked'=>1])->count();

# Получить количество пользователей с подготовкой запроса
$userArray = query('select * from ' . table_name('modUser'). ' WHERE id < ?')->execute(10);
// или так
$userArray = query('select * from ' . table_name('modUser'). ' WHERE id < ?')->bind(10)->execute();
// или так   // $_POST['email'] = 'user@mail.ru'
$userArray = query('select * from ' . table_name('modUser'). ' WHERE id < :email')->bind($_POST)->execute();

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

Проект на GitHub.

П.С. Друзья, есть мнение, что это никому не нужная и бесполезная вещь. Просьба ко всем кто не согласен с данным мнением поставить звёздочку у проекта на гитхабе. Ну и здесь плюсик важен. Хочу понять объективную потребность.
31 december 2016, 11:57    Сергей Шлоков   G+  
21    1145 +26

Comments (46)

  1. Konstantin 31 december 2016, 13:47 # 0
    чем то WordPress стало напоминать
    1. Василий Наумкин 31 december 2016, 14:06 # +1
      Скорее уж тогда Laravel — laravel.com/docs/5.3/helpers
      1. Сергей Шлоков 31 december 2016, 14:11 # +2
        Совершенно верно. Вдохновлён Laravel.
    2. Николай Ланец 31 december 2016, 14:13 # +1
      Сорри, что вмешиваюсь, но все-таки… Зачем все это? Нет, ну серьезно? user_id() чтобы вернуть $modx->user->id? Не проще ли просто запомнить $modx->user->id? Даже тело функции как бы намекает…
      return isset($modx->user) ? $modx->user->id : false;
      Вероятность того, что объект $modx->user будет отсутствовать — практически нулевая, потому что при инициализации MODX в любом случае создает этот объект, даже если пользователь не авторизован. А если этого не произойдет, то все развалится нафиг фатальной ошибкой.

      children() как альтернатива $modx->getChildIds()? И прочее в том же духе? Это все напоминает попытки русских отучить от вилки и ложки, потому что палочками тоже можно кушать. Еще раз сорри, но более бесполезного материала не видел давно. Ты же способен на большее. Зачем писать такое?

      P.S. Здесь одинарные кавычки явно лишние.
      1. Сергей Шлоков 31 december 2016, 14:21 # +6
        Это библиотека. Хочешь ставить, не хочешь не ставь.
        С юзером знаю. Перестраховка.
        За найденный баг с кавычками спасибо.
        1. Николай Ланец 03 january 2017, 10:01 # +1
          Почитал мнения остальных. Могу ошибаться, но в целом они сходятся в том, что полезно для подсматривания (откуда что берется), и документацию почитать полезно. Так вот, может тебе все-таки не хелперы эти писать, а все-таки статьи и документацию по работе с API. Вот серьезно. Смотри, вот ты пишешь:
          parents()
          Выводит id родителей ресурса для указанного уровня в виде массива.
          $id = 10; 
          $height = 3;
          $parents = parents($id, $height);
          А теперь то же самое на чистом MODX:
          $modx->getParentIds()
          Выводит id родителей ресурса для указанного уровня в виде массива.
          $id = 10; 
          $height = 3;
          $parents = $modx->getParentIds($id, $height);
          Во-первых, люди будут больше понимать основы MODX-а.
          Во-вторых, это работать будет везде, без установки всяких дополнительных библиотек. Да, на своем частном проекте можно поставить допбиблиотеку. А если вопрос стоит в переносимости кода? Написать свой компонент и требовать, чтобы все ставили допкомпонент для его работы? Я понимаю это в случае с pdoTools и modxSite компонентами, там код обширный. Но просто ради синтаксического сахара, согласись, оно того не стоит.

          А покопать MODX было бы и тебе полезно (и наверняка интересно). К примеру, ты знал, что ::getOption() есть не только у MODx, но и у xPDOObject? У любого. Это очень полезный механизм. Зачем это бывает нужно? Например, в одном сниппете установил $modx->resource->setOption($key, $value), а в другом перехватил $modx->resource->getOption($key, $value). И точно знаешь, что это нигде больше не перехватится и не перетрется. А то бывает в одном сниппете устанавливаешь $modx->setPlaceholder(), и тут же где-то в другом месте его перетирают, просто потому что это слишком глобально и имя переменной не уникальное использовал.

          Ну и согласись, просто из-за того, что API слишком обширное, лень тобою обуяла, и ты местами просто не в полной мере функционал поддержал. К примеру, config(). Ты не стал здесь расширять MODx-метод, мы просто переписал на свой лад, дав возможность получать только текущие конфиги объекта $modx. Но родной MODx-овый метод поддерживает 4 параметра. Один из них — «значение по умолчанию», поддержку которого ты не перенес в свой метод. Таким образом ты не только добавил лишние сущности, но и обеднил функционал. Не надо так.

          Функцию email() вообще практически как есть взял из modUser::sendEmail(). Знаешь как я иногда делаю, когда хочу отправить мыло на произвольные емейл?
          $modx->user->Profile->email = "email@some.host";
          $modx->user->sendEmail("Hello!");
          И никаких лишних библиотек.

          В общем, это мое личное мнение. Понятно дело, тебе решать что делать, и народу решать что принимать и что изучать. Скажу только, напоследок, что я вижу много ненужных сторонних псевдотехнологий, и очень мало, касающегося самого MODX-а. То, что ты написал, не будет работать без самого MODX-а. То есть прежде, чем написать это, ты изучал MODX. Но вместо того, чтобы научить других полученным знаниям, ты придумываешь и впариваешь всем вот этот свой синтаксический сахар. И все это для того, чтобы всеобщее внимание сосредотачивалось на тебе. Почему ты все оцениваешь в количестве скаченных твоих компонентов? Зачем? Если никто не будет качать твои компоненты, то у тебя самооценка понизится? Мои компоненты практически никто сейчас не качает. Ну и что? Я все равно знаю больше тебя в MODX. Не хочешь ли и ты реально знать больше в MODX, вместо того, чтобы писать компоненты, которые и скачают только те, кто знает значительно меньше тебя. Я говорил тебе подобное больше года назад, и вот опять говорю. Подумай над этим.
          1. Сергей Шлоков 03 january 2017, 11:49 # +3
            Что-то мне это напоминает. Вторая часть Марлезонского балета? Василий тогда уже всё сказал. Повторяться не буду.

            По последнему абзацу… Чем же тебе помочь, брат? Может тебе отдыхать нужно побольше? Отвлекись. Найди что-ли девушку. Сходите в кафе или театр. Вокруг столько интересного.
            Подумай на этим.
            1. Николай Ланец 03 january 2017, 11:52 # +2
              Не надо на девушек переходить и т.п. Поверь, у меня с этим нормально. И отдыхал я целых три дня.
              Я тоже все сказал. И не говорю, что ты должен поступить именно так. Тебе решать. Я просто высказал свое мнение. А высказал, просто потому что жалко, что имеющийся потенциал идет немного не в том русле. Но может ты когда-нибудь поймешь это.
              1. Николай Ланец 04 january 2017, 13:52 # +6
                Что-то мне это напоминает. Вторая часть Марлезонского балета? Василий тогда уже всё сказал. Повторяться не буду.
                Я бы тебе советовал это перечитать, и еще не раз. Вот я там писал:
                Нафига вот так вот переписывать всю систему?
                А еще я, было дело, спрашивал «Нафига в минишопе контроллеры так все переписывать?».

                Короче, ты тоже, смотрю, любитель все попереписывать. Вот в админтулс ты нафига вот это переписал вот этим.

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

                Знаешь к чему я это все? Ты вот кичишься своим гениальным кодом, и совершенно никого не слушаешь. Написал что-то лично свое, что ломает работу других компонентов. Вот очередная жалоба поступила. Ты считаешь, это профессионально?
                Вот так выглядел диалог по этой проблеме:


                Ты не ориентируйся на количество здесь плюсов тебе и минусов мне. Я не на своем поле. Глобально же большинство твоих компонентов вызывают у нормальных программистов реакцию от легкой усмешки до дикого ржача. Сколько раз я слышал «Коля, перепиши ты этот oneBooking! Там под капотом ппц! А альтернативы пока не написали».

                В общем, если ты в кафе или театре, возвращайся, больше учись, а то так и будешь писать код для новичков. А ведь наверняка мечтаешь о признании и среди опытных программистов.

                P.S. отправил тебе PR.

                P.P.S. хочешь ответить? Лучше отправь мне парочку ответных годных PR куда-нибудь.
                1. Сергей Шлоков 04 january 2017, 15:38 # +2
                  Постараюсь ответить вежливо.
                  Вот в админтулс ты нафига вот это переписал вот этим.
                  Если ты не понял зачем, может тогда ты себя переоцениваешь? За PR спасибо, но так как ты не понял смысла, то соответственно он ломает задуманный функционал. За $this->modx->smarty->get_template_vars() тоже благодарность, возьму на вооружение.
                  Написал что-то лично свое, что ломает работу других компонентов. Вот очередная жалоба поступила. Ты считаешь, это профессионально?
                  А чё не сотая, тысячная, миллионная для драматизма? Конфликты приложений существовали до меня и будут существовать после. А профессиональным я считаю дать знать автору о проблеме.
                  а то так и будешь писать код для новичков. А ведь наверняка мечтаешь о признании и среди опытных программистов.
                  Перечитай мою страничку. Я не вижу ничего позорного писать для новичков.

                  П.С. PR не приму по описанной выше причине.
                  П.П.С. Я один раз имел неосторожность обратить внимание на твой robots.txt. Твоими «благовониями» все браузеры пропахли. На те же грабли наступать не собираюсь.

                  У меня только единственное к тебе пожелание — «Коля, перепиши ты этот oneBooking!»
                  1. Николай Ланец 04 january 2017, 18:57 # +2
                    Если ты не понял зачем, может тогда ты себя переоцениваешь?
                    Нет, это я тебя переоценил. Не думал, что ты до такого еще более мощного хардкода дойдешь… Все это ради того, чтобы добавить возможность регион в ExtJS-лейауте менять и кастомные JS-ки добавлять? Не кажется, что это слишком? Нельзя такое оправдывать словами «Конфликты приложений существовали до меня и будут существовать после». Не кажется, что надо все-таки какое-то более мягкое решение искать?

                    Ладно, это лирика. Я так понял, подмену в контроллере ты делаешь для того, чтобы можно было дерево документов справа выводить через кастомный JS-layout?
                    ОК, тогда такое решение, для примера:
                    # $scripts .= $this->getBaseManagerPageScripts();
                    $scripts .= $this->modx->smarty->get_template_vars('maincssjs');

                    $compressJs = $this->modx->getOption('compress_js', null);
                    if (!$compressJs) {
                    $layout_src = $this->getOption('jsUrl') .'mgr/core/modx.layout.js';
                    $scripts = preg_replace("/<script .+?assets\/modext\/core\/modx.layout.js.*?><\/script>/", "", $scripts);
                    }
                    Замена через регулярки, конечно, жестко, но в твоем случае это меньший хардкод, чем было. И в таком случае дерево справа выводится, и modxSDK работает.


                    А теперь интересное: я так понял, при включенной JS-компрессии в админке у тебя эта штука не работает? Ведь ты вклиниваешься только в блоке отключенной компрессии. Поэтому я и добавил проверку включена ли компрессия. Включаем компрессию, и уже кастомный JS отсутствует, и функционал не работает.


                    Не работает и без моих модификаций (без них только еще и modxSDK работать перестает).


                    Правда тут сложнее становится? Надо в компрессированный JS-файл вклиниться, а это уже гораздо сложнее и простой регулярочкой сложно, а главное — глупо. Поэтому ищем более правильное решение, а именно расширение самого MODx.Layout. Вот тебе такой расширяющий Layout.

                    Согласись, 90 строк лучше 420-ти?

                    А в классе твоем итоговый код будет таким:
                    # $scripts .= $this->getBaseManagerPageScripts();
                    $scripts .= $this->modx->smarty->get_template_vars('maincssjs');
                    
                    $layout_src = $this->getOption('jsUrl') .'mgr/core/modx.layout.js';
                    $scripts .= "<script type=\"text/javascript\" src=\"{$layout_src}\"></script>";
                    И здесь сразу несколько плюсов:
                    1. Это работает теперь в том числе и на включенной компрессии.
                    2. Это не перетирает чужие кастомные скрипты.
                    3. Это не ломает чужие лейауты (сейчас, если кто-то переопределит на свой лад modx-layout, свой код его затрет).
                    4. Гораздо меньше кода (что обслуживать легче).
                    5. БОльшая обратная совместимость (не придется отслеживать версию MODX-а в случае, если в новой версии MODX-а будут изменения на уровне твоего текущего переопределенного блока контроллера).

                    В общем, если ты хочешь писать правильные компоненты, во-первых, меньше огрызайся и больше слушай других, а во-вторых, научись хотеть писать правильный код. У тебя есть мышление, но нет правильного взгляда на такие вещи.

                    P.S. А еще лучше пуллреквест бы в MODX отправил. Там вопрос в двух строчках.
                    1. Сергей Шлоков 04 january 2017, 19:56 # +2
                      Согласись, 90 строк лучше 420-ти?
                      И здесь сразу несколько плюсов:
                      1. Это работает теперь в том числе и на включенной компрессии.
                      2. Это не перетирает чужие кастомные скрипты.
                      3. Это не ломает чужие лейауты (сейчас, если кто-то переопределит на свой лад modx-layout, свой код его затрет).
                      4. Гораздо меньше кода (что обслуживать легче).
                      5. БОльшая обратная совместимость (не придется отслеживать версию MODX-а в случае, если в новой версии MODX-а будут изменения на уровне твоего текущего переопределенного блока контроллера).
                      Согласен со всеми пунктами. Поэтому, если ты не против, я твой код использую.
                      Честно говоря был уверен, что в лейауты админки никто не лазит.

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

                      P.S. А еще лучше пуллреквест бы в MODX отправил. Там вопрос в двух строчках.
                      Они мой безобидный PR для отображения используемой памяти принять уже год не могут. А уж про PR с лейаутом и мечтать нечего. Они только критические PR принимают. Видимо интереса ко второй ветке у них уже нет.
                      1. Николай Ланец 04 january 2017, 20:18 # +2
                        Поэтому, если ты не против, я твой код использую.
                        Когда я был против использования своего кода?

                        Слушать что, бесконечные оскорбления и фантазии? Это первый комментарий, где ты как более опытный товарищ помог решить проблему.
                        Это уже кто что хочет видеть и что видит. Я много раз тебе писал годные советы (можешь пробежаться по старым комментам, сейчас у тебя опыта больше, ты можешь заметить то, чего раньше не замечал).
                        И я много раз говорил: меньше обращайте внимания на эмоции, больше на суть. Ребят в своей команде я еще не так отчитываю.

                        Они мой безобидный PR для отображения используемой памяти принять уже год не могут. А уж про PR с лейаутом и мечтать нечего. Они только критические PR принимают. Видимо интереса ко второй ветке у них уже нет.
                        У меня тоже 3 открытых PR и больше половины из трех десятков закрытых не принято (хотя есть критичные, баги с которым до сих пор проявляются). А что делать? Все равно приходится отправлять.
                        1. Николай Ланец 04 january 2017, 20:36 # +2
                          Честно говоря был уверен, что в лейауты админки никто не лазит.
                          Я лазил, когда хотел в админке сделать трехколоночную сетку, еще почти 4 года назад.


                          Ту же самую ошибку допустил. Тогда меня с этим разве что danyaPostfactum мог поправить, он всегда в JS был очень силен.
                      2. haron 04 january 2017, 22:05 # -5
                        Вклинюсь в Ваш диалог, заодно обращу внимание на свой вопрос
                        Написал что-то лично свое, что ломает работу других компонентов.
                        Для того тесты пишут, и собственно сам вопрос тут — modx.pro/help/10813/
            2. Sem 31 december 2016, 14:15 # 0
              Прикольная либа, ещё бы к функции script() добавить третий параметр добавления атрибутов: defer и async и было бы вообще шикарно, а то родные методы этого не умеют.
              1. Сергей Шлоков 31 december 2016, 14:20 # +1
                Всё в наших руках. :)
                1. Сергей Шлоков 31 december 2016, 17:12 # +1
                  Сделано. Добавил четвёртый строковый параметр, в котором можно указать нужный атрибут. Метод магический. Этот параметр можно указывать и вторым и третьим и четвертым.
                  // Загрузка файла скрипта в конец страницы
                  script('/path/to/script.js', 'acync'); // <script acync type="text/javascript" src="/path/to/script.js"></script>
                  
                  // Загрузка файла скрипта в секцию head
                  script('/path/to/script.js', true, 'deffer'); // <script deffer type="text/javascript" src="/path/to/script.js"></script>
                  
                  1. Дмитрий Суворов 31 december 2016, 17:14 # +1
                    новый год на носу, а где-то уже наступил) А Вы все трудитесь и трудитесь на всеобщее благо) Спасибо!
                    1. Сергей Шлоков 31 december 2016, 17:18 # +1
                      Да мы уже должны были в гости уехать, но у жены резко поднялась высокая температура, да ещё у ребёнка недомогание. Явно тоже заболевает. Пришлось распрягать коней и все 100 пакетов и пакетиков обратно заносить домой. Будем отмечать дома в одиночестве. Поэтому и сижу скучаю. :)
                      П.С. Ещё и 1-е и 2-е освободилось.
                      1. Дмитрий Суворов 31 december 2016, 17:21 # +4
                        ну Вы вовсе не в одиночестве — вас как минимум трое и это самое главное, чтобы семья была в сборе в Новый Год)
                    2. Sem 31 december 2016, 17:16 # +1
                      Круто!!! Вот и подарок к Новому Году!!! Всех с наступающим!!! Сергей, а Вам спасибо отдельное за оперативную доработку библиотеки.
                      1. Сергей Шлоков 31 december 2016, 17:22 # +2
                        На здоровье!
                  2. bustep.ru 31 december 2016, 14:50 # 0
                    phpStorm есть Live Templates — через который можно запомнить быстрые команды и через TAB разворачивать их
                    это к таму чтобы не запоминать длинные названия и не выдумывать новый функции.
                    Реально кто поймет откуда эти функции запускаются
                    Кроме того на некоторых хостингах $users = users()->profile()->select('User.username, Profile.email')->where(['Profile.blocked'=>true])->get(); Таки конструкции будут ошибку выдавать в случае если попробуешь вывести массив.
                    1. Роман Садоян 31 december 2016, 16:42 # +1
                      Кроме того на некоторых хостингах $users = users()->profile()->select('User.username, Profile.email')->where(['Profile.blocked'=>true])->get(); Таки конструкции будут ошибку выдавать в случае если попробуешь вывести массив.
                      Почему? Уже «без пяти минут» 2017 год, нужно сажать клиентов на правильные хостинги или переводить на VPS (при цене ~200 руб в месяц)
                    2. Василий Столейков 01 january 2017, 08:24 # +2
                      Спасибо!
                      Понравились функции проверка на существовани юзера и отправки почты!
                      И за документацию развёрнутую спасибо!
                      1. Сергей Шлоков 01 january 2017, 12:49 # +2
                        Пожалуйста!
                        Вот и ты пополнил ряды любителей бесполезных вещей. :)
                        1. Евгений 01 january 2017, 15:12 # +3
                          Очень полезная вещь, даже без самих функций очень полезная документация.
                          А если подключалось бы в виде приложения еще круче было бы.
                          1. Сергей Шлоков 01 january 2017, 15:35 # +4
                            Рад что хоть документация пригодилась. Только слабо понимаю чем.
                            А если подключалось бы в виде приложения еще круче было бы.
                            Документация занимает в разы больше времени, чем разработка. А чтобы сделать в виде пакета, нужно перевести её на английский. Мне легче застрелиться. Могу сделать только для ru сегмента в modstore.
                            1. Василий Наумкин 01 january 2017, 16:16 # +1
                              Есть мнение, что бесплатные приложения пусть сами иностранцы переводят через Google Translate — а мы отредактируем.

                              Ну а для платных, да — английские доки в этом году будут обязательны, если автор захочет продавать их на весь мир.
                              1. Сергей Шлоков 01 january 2017, 16:33 # +2
                                Поддерживаю такое мнение.
                                если автор захочет продавать их на весь мир.
                                Т.е. в modstore будет опция кому продавать пакет?
                                1. Василий Наумкин 01 january 2017, 16:54 # +1
                                  Да.

                                  Будет английская версия магазина и выбор — выставлять ли в ней своё дополнение. Для этого нужно будет перевести свою документацию на англ. язык и мочь отвечать на вопросы иностранцев.

                                  Сейчас это всё в разработке, в первом квартале очень надеюсь запустить.
                      2. Константин Ильин 01 january 2017, 12:55 # +3
                        Для меня не столь как библиотека хороша, а столько как пример подсмотреть — что, откуда и как.
                        А описание каждой функции отличное, это меня прям подкупило))
                        1. Сергей Шлоков 01 january 2017, 18:36 # +5
                          Запулил в оба репозитория. В официальном уже. В модсторе ждем конца праздников.
                          1. Евгений 01 january 2017, 19:39 # +4
                            Спасибо. Хорошее начало года.
                              1. Илья Уткин 09 january 2017, 11:16 # +3
                                Оффтоп.

                                Где-то читал, что разработчики MODX просят не использовать в названии компонентов приставку mod. Типа и так ясно, что дополнение для MODX — и без приставки.

                                А в ядре эта приставка отделяет собственно MODX от остального:
                                class modAccessibleObject extends xPDOObject

                                Может, сделать это неписанным правилом магазина и предлагать разработчикам поменять такое название? Например, сделать просто Helpers — нормальное название для компонента. Понятно, что в самом коде поменять название будет сложнее, но в репозитории будет отображаться нормально.
                                1. Leonid Krylov 09 january 2017, 11:20 # +2
                                  Спасибо за замечание, Илья! А есть ли пруф? Было бы интересно.
                                  1. Илья Уткин 09 january 2017, 11:30 # +3
                                    Я это либо прочёл в каком-то из чатов, либо вообще услышал от кого-то на минском митапе. Хотя, может быть, мне это приснилось. Но дополнение simpleUpdater я сначала назвал modUpdater, а потом переименовал из-за этой информации )))
                                    1. Николай Ланец 09 january 2017, 21:57 # +2
                                      Подтверждаю. Пруфф вряд ли найду (на сколько помню, это на старом официальном MODX-форуме обсуждалось), но об этом действительно говорили. Кстати, в своей практике имел конфликт своего modRedirect с Redirector Шона МакКормика, он так же использовал класс modRedirect. К фатальным ошибкам это не привело, а вот логических схватил с лихвой (когда писаться все стало совсем в другую таблицу).
                                      Ну и еще в своей практике по-моему с modEvent сконфликтовал.

                                      P.S. Сорри, да, я тоже этим грешу. Но пытаюсь исправляться.
                              2. Сергей Шлоков 02 january 2017, 00:40 # +6
                                Добавил 4 метода логирования (error(), warn(), info() и debug()) и несколько функций для коллекций и объектов — обновление, удаление, подсчет количества (см. последний примеры).
                                Думаю пока хватит. Жду ваших предложений. Одна голова хорошо…
                                1. Сергей Шлоков 14 january 2017, 13:13 # +4
                                  Обновил библиотеку. В основном доработки коснулись менеджера коллекции — добавлено несколько методов и возможность использовать callback функции.
                                  // Получение списка с заголовками с использованием callback функции.
                                  return resources()->where(['id:IN'=>children(5)])->each(function($resource, $idx){ return "<li>{$idx}. ".$resource['pagetitle']."</li>";});
                                  // Получение массива заголовков дочерних элементов ресурса 5 с использованием UNION.
                                  $array = resources()
                                              ->where(['id:IN'=>children(5)])
                                              ->union('select pagetitle from ' . table_name('modResource') . ' WHERE id = 1')
                                              ->union(['pagetitle'=>'New pagetitle'])
                                              ->get('pagetitle');
                                  // Получаем всех пользователей группы "Managers"
                                  $usersArray = users()->members('Managers')->toArray();
                                  
                                  1. Григорий Коленько 18 january 2017, 14:21 # +3
                                    За вот это:
                                    email('pupsik@mail.ru', 'Тема','Содержание письма');
                                    // Пользователю
                                    email_user('admin', $subject, $content);
                                    Мега респект.
                                    1. Сергей Шлоков 18 january 2017, 17:59 # +2
                                      Prego, amico!
                                    2. Андрей 18 january 2017, 18:51 # +1
                                      Можно и вложения к письмам добавить, там пару строк всего.
                                      1. Сергей Шлоков 18 january 2017, 22:04 # +1
                                        В новой версии будет. А ещё будет специальный класс, который позволяет работать с цепочками
                                        // Вызываем функцию без аргументов и используем цепочки
                                        email()
                                        	->to('user1@mail.ru')
                                        	->toUser(5)
                                        	->cc('user2@mail.ru')
                                        	->subject('Тема письма')
                                        	->content('тело сообщения')
                                        	->from('Администратор')
                                        	->replyTo('admin@gmail.com')
                                        	->attach('file1.jpg')
                                        	->attach('file2.png')
                                        	->send();
                                        
                                      You need to login to create comments.