Новости Joomla

Вышли релизы Joomla 6.0.3 и Joomla 5.4.3

Релиз Joomla 6.0.3 и Joomla 5.4.3

Проект Joomla рад сообщить о выпуске Joomla 6.0.3 и Joomla 5.4.3. Это релиз исправлений ошибок и улучшений для серии Joomla 6.0 и Joomla 5.4.

👩‍💻 События плагинов и порядок их срабатывания при работе с пользовательскими полями Joomla и использовании FieldsHelper.

👩‍💻 События плагинов и порядок их срабатывания при работе с пользовательскими полями Joomla и использовании FieldsHelper.

В процессе работы с Joomla бывает необходимо работать с пользовательским интерфейсом более тонко, чем обычно. Все формы Joomla состоят из стандартных полей, содержанием, стилем отображения, состоянием (включено/выключено, доступно для редактирования или нет и т.д.) можно управлять с помощью плагинов. Да и для нестандартных проектов хорошей практикой является создание одного системного или нескольких плагинов групп "под проект", в которых храниться весь "нестандарт".

В этой статье описаны все триггеры, которые вызываются через Event Dispatcher из administrator/components/com_fields/src/Helper/FieldsHelper.php, с привязкой к жизненному циклу (порядку этапов работы запроса), аргументам, изменяемым данным и дальнейшему распространению по Joomla. Это поможет вам работать с Joomla свободнее и не опасаясь при этом потерять изменения при очередном обновлении движка.

Подходы, описанные в статье, полезны в тех случаях, когда вы работаете с данными в com_fields - механизме создания и редактирования пользовательских полей ядра Joomla и при использовании FieldsHelper. Многие сторонние компоненты не используют эту возможность, поэтому данная статья будет полезна лишь частично.

🏆 Открыто голосование за Joomla в премии CMS Critic People’s Choice Awards 2025

🏆 Открыто голосование за Joomla в  премии CMS Critic People’s Choice Awards 2025

🗓 Голосование продлится до 27 февраля 2026 года.

👩‍💻 Проголосовать! 👩‍💻

Номинации, в которых можно проголосовать за Joomla:
⭐️ Best Free CMS
⭐️ Best Open Source CMS
⭐️ Best Enterprise CMS

Также в номинации Best e-Commerce Solution участвуют компоненты интернет-магазинов для Joomla:
⭐️ HikaShop
⭐️ Virtuemart

В номинации Best Website Builder оказались:
⭐️ YooTheme
⭐️ SP Page Builder

Что такое CMS Critic Awards?
С 2012 года премия CMS Critic Awards занимает особое место в сообществе систем управления контентом (CMS). Это единственный в своем роде сайт, который составляет рейтинг системы управления контентом и связанных с ними решений на рынке — от малого до крупного и подчеркивает их инновации и услуги.

Каждый год награда CMS Critic Awards присуждается одному победителю в различных отраслевых категориях, таких как: «Лучшая облачная CMS», «Лучший DXP», «Лучшая Headless CMS и других. Затем результаты оглашаются через СМИ вместе с выбором редакции CMS Critic.
В этом году премия вернулась к своим традициям и только TOP-5 движков по количеству номинаций попали в 2-й этап - голосование.

@joomlafeed

0 Пользователей и 1 Гость просматривают эту тему.
  • 548 Ответов
  • 30121 Просмотров
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #150 : 13.10.2015, 23:14:26 »
Разбираемся с собственно кодом плагина. Перечитали очень много информации за всё это время.
Пишем сейчас функцию на событие onContentPrepareData. Взяли за основу плагин Профиля пользователя.

Столкнулись с тем, что не знаем, какой параметр нам нужно брать для объекта object($data). Вот кусок кода плагина plugchmos.php с непонятным для нас местом:

public function onContentPrepareData($context, $data)
   {
      
      if (is_object($data))
      {
         $userId = isset($data->id)? $data->id : 0;    - вот это место непонятно. В плагине профиль пользователя стоит userId, а нам что нужно брать? Просто Id?
Ну userId наверное Вам нужен будет. Вы же собираетесь список сборников получать учитывая пользовательские сборники, так?

Код
$userId = JFactory::getUser()->get('id');
*

AlekVolsk

  • Гуру
  • 6913
  • 416 / 4
Re: Создание папок из фронтенда
« Ответ #151 : 14.10.2015, 09:08:31 »
AlekVolsk, спасибо за ссылку и пояснение.
пожалуйста

Нет, ребята, так не пойдет: чтобы самому что-то писать и понять, что он написал, человек должен сам освоить какие-то азы.
Потратьте пару часов и дайте человеку готовый вариант - так вы сэкономите и свое и его время.
так дали уже, b2z им набросал основу, на которой они двигаются дальше, + ссылки на кучу доки м примерами и образцами

Тема кстати - идеальный кейс как выпросить бесплатное написание компонента.
voland, все троллишь? ))

Ну userId наверное Вам нужен будет. Вы же собираетесь список сборников получать учитывая пользовательские сборники, так?

Код
$userId = JFactory::getUser()->get('id');
для наглядности, можно сократить так:
Код
$userId = JFactory::getUser()->id;
Мила, если вы не знаете о том, почему это работает и куда девается функция get(), настоятельно рекомендую проштудировать учебники по ООП
« Последнее редактирование: 14.10.2015, 09:26:52 от AlekVolsk »
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #152 : 14.10.2015, 10:53:18 »
Хм, получается, наш код на событие onContentPrepareData фактически повторяет код Профиля пользователя на это же событие (меняются только строки с !JHtml::isRegistered, как мы поняли)?
Посмотрите, пожалуйста:

Код
public function onContentPrepareData($context, $data)
{

if (is_object($data))
{
$userId = isset($data->id)? $data->id : 0;
if (!isset($data->profile) and $userId > 0)
{
// Load the profile data from the database.
$db = JFactory::getDbo();
$db->setQuery(
'SELECT profile_key, profile_value FROM #__user_profiles' .
' WHERE user_id = ' . (int) $userId . " AND profile_key LIKE 'profile.%'" .
' ORDER BY ordering'
);
try
{
$results = $db->loadRowList();
}
catch (RuntimeException $e)
{
$this->_subject->setError($e->getMessage());
return false;
}
// Merge the profile data.
$data->profile = array();
foreach ($results as $v)
{
$k = str_replace('profile.', '', $v[0]);
$data->profile[$k] = json_decode($v[1], true);
if ($data->profile[$k] === null)
{
$data->profile[$k] = $v[1];
}
}
}
if (!JHtml::isRegistered('users.compilations'))
{
JHtml::register('users.compilations', array(__CLASS__, 'compilations'));
}

}
return true;
}
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #153 : 14.10.2015, 11:01:04 »
 Мы вычитали, что эти строки (!JHtml::isRegistered('users.compilations')) проверяют наличие переменной сборников и, если ее нет, устанавливают ее функцией compilations... Правильно ли мы разобрались, нужно ли нам ещё что-то прописывать в этом событии?

*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #154 : 14.10.2015, 11:11:06 »
Нет, вы все неправильно поняли. Плагин профиля я вам дал в качестве примера (структуры и примерной схемы прочесса), но код на 80% будет другой. Вы не улавливаете суть:
onContentPrepareData - получить данные для вставки в форму (список сборников)
onContentPrepareForm - вставить нужный элемент в форму (поле сборников)
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #155 : 15.10.2015, 10:40:08 »
b2z, хорошо, мы поняли, кажется.
Продолжаем работать с onContentPrepareData
Вы пишите, что нам нужно "получить данные для вставки в форму (список сборников)". Мы нагуглили информацию о том, как извлекать данные из таблиц БД.

Скажите, пожалуйста, правильно ли мы составили обращение к БД:
Код
$db = JFactory::getDbo();
$db->setQuery(
'SELECT title FROM #__chmos_compilations' .
' WHERE user_id = ' . (int) $created_by .
' ORDER BY ordering'
);
try
{
$results = $db->loadRowList();
}
catch (RuntimeException $e)
{
$this->_subject->setError($e->getMessage());
return false;
}

С помощью данного кода мы выполнили запрос в БД, в таблицу chmos_compilations (в ней хранятся созданные пользователями сборники).
Но нам не нужны все данные из таблицы. Нам нужно только одно поле - с названиями сборников (это поле называется title), и в этом поле нам нужны только те сборники, которые создал текущий пользователь.
Значит, нам нужно сделать сортировку по id пользователя....

Теперь правильно?

*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #156 : 15.10.2015, 10:56:44 »
Что касается работы с базой данных, лучше использовать JDatabaseQuery Вот материалы на тему базы данных, там есть все.

Что касается запроса, то почти верно: поля user_id по моему в chmos_compilations нет, я уже не помню. Вроде было поле created_by. И выбирать нужно id, title - иначе данных для списка будет недостаточно. Он строится как <option name="id">title</option>.

Но я тут подумал, что onContentPrepareData в данном случае не понадобится, так как у нас список из базы выбирается. А значит стандартный тип поля "list" использовать нельзя, придется написать свой тип поля. Вот здесь есть как раз то, что нужно. Назовите тип поля как Compilations.

Файлик с полем кидаете в папку /fields плагина, а в конструктор плагина добавляете:
Код: php
JFormHelper::addFieldPath(__DIR__ . '/fields');

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

Файл формы compilations.xml:
Спойлер
[свернуть]

Файл формы кидаете в папку /forms плагина и добавляете в форму:
Код: php
JForm::addFormPath(__DIR__ . '/forms ');
$form->loadFile('compilations', false);
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #157 : 15.10.2015, 18:04:08 »
b2z, Вас поняли. Разбираемся сейчас с написанием собственного типа поля.

На данный момент имеем:
1. chmosplugin.xml - файл манифеста
Спойлер
[свернуть]
2. chmosplugin.php
Спойлер
[свернуть]
3. forms - папка, в которой содержится compilations.xml
Спойлер
[свернуть]
4. fields - папка, в которую мы положим compilations.php, с которым сейчас разбираемся.

Всё верно пока?
...С Вашей помощью уже начинаем чувствовать себя настоящими программистами. Можно теперь небрежно так говорить своим знакомым, что мы тут правкой кода занимаемся на досуге... =)
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #159 : 16.10.2015, 18:15:01 »
b2z, написали compilations.php, пользуясь указанной Вами ссылкой, и разместили его в папке fields плагина.
Спойлер
[свернуть]

Получается, плагин готов?
---------------------------
Прикрепляем на всякий случай то, что у нас есть на данный момент.
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #160 : 17.10.2015, 21:14:11 »
В принципе готов, только Вы в запросе не учли текущего пользователя. Или Вы хотите отображать все сборники?
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #161 : 17.10.2015, 23:33:28 »
b2z,  нет, мы хотим отображать только сборники текущего пользователя.
Подскажите, пожалуйста, как бы нам его учесть в запросе? Это нам нужно фильтр по ID пользователя ставить, да?
То есть нам нужно добавить к запросу вот эту строку?

->Where('userid')

------------------------------

И ещё - мы установили плагин на сайт, активировали его, но никаких изменений не обнаружили... Никаких полей (с выпадающим списком названий сборников) при публикации материала нет... Вообще ничего нет... Или мы пока поторопились?
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #162 : 19.10.2015, 09:21:03 »
b2z,  нет, мы хотим отображать только сборники текущего пользователя.
Подскажите, пожалуйста, как бы нам его учесть в запросе? Это нам нужно фильтр по ID пользователя ставить, да?
То есть нам нужно добавить к запросу вот эту строку?

->Where('userid')
Да, только поле в таблице было не userid, а кажется created_by:
Код: php
->from('#__chmos_compilations')
->where('created_by = ' . (int) JFactory::getUser()->get('id'));

И ещё - мы установили плагин на сайт, активировали его, но никаких изменений не обнаружили... Никаких полей (с выпадающим списком названий сборников) при публикации материала нет... Вообще ничего нет... Или мы пока поторопились?
А вот это странно. Я поставил плагин, проверил. Он инициализируется (конструктор отрабатывает), а вот onContentPrepareForm почему-то не отрабатывает. Пока теряюсь в догадках...
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #163 : 19.10.2015, 12:24:45 »
b2z, да, поле в таблице created_by. Строку фильтрации добавили.

Обнаружили ошибку в зазипованном архиве плагина, который мы скинули: в папке fields кроме файла compilations.php находится ещё случайно затесавшийся файл compilations.xml, который нужно удалить.

Мы все эти манипуляции проделали (строку фильтрации добавили, лишний файл удалили), плагин установили, активировали, пошли создавать материал - и опять ничего. У нас даже конструктор не срабатывает почему-то. У нас Joomla 3.3.3 , - может, в этом дело?

Прикрепляем скрин с менеджера материалов. Мы ещё раз пробежались по всем вкладкам - и конструктор нигде не обнаружили... Он у Вас где находится?
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #164 : 19.10.2015, 12:32:31 »
И прикрепляем архив плагина с внесёнными исправлениями (добавление строки фильтрации и удаление лишнего файла).
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #166 : 19.10.2015, 13:46:37 »
b2z, извините, пожалуйста, мы немножко не поняли: "Конструктор в плагине - constructor", - это Вы о  том,  как у Вас конструктор в плагине отображается? Отдельной вкладкой? Или о том, что у нас название функции конструктора неправильное?
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #167 : 19.10.2015, 13:55:17 »
Не constructor, а construct - неверно написал.

Код: php
public function __construct(& $subject, $config)
{
   JFormHelper::addFieldPath(__DIR__ . '/fields');
}

Я сюда добавлял echo 'test'; и слово test выводилось на форме создания материала. Значит конструктор отрабатывает.
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #168 : 19.10.2015, 14:11:28 »
b2z, мы сейчас сделали, как Вы сказали - проверили - у нас тоже конструктор срабатывает!
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #169 : 19.10.2015, 14:28:09 »
Уху, только это ничего не дает. onContentPrepareForm молчит :( По всем правилам должен отрабатывать, потому что его вызывает dispatcher в модели.

1. Модель ContentModelArticle в методе getForm() вызывает loadForm()
https://github.com/joomla/joomla-cms/blob/staging/administrator/components/com_content/models/article.php#L334

Код: php
// Get the form.
$form = $this->loadForm('com_content.article', 'article', array('control' => 'jform', 'load_data' => $loadData));

2. Метод loadForm() вызывает preprocessForm()
https://github.com/joomla/joomla-cms/blob/staging/libraries/legacy/model/form.php#L196

Код: php
// Allow for additional modification of the form, and events to be triggered.
// We pass the data because plugins may require it.
$this->preprocessForm($form, $data);

3. Метод preprocessForm() вызывает событие onContentPrepareForm()
https://github.com/joomla/joomla-cms/blob/staging/libraries/legacy/model/form.php#L274

Код: php
// Get the dispatcher.
$dispatcher = JEventDispatcher::getInstance();

// Trigger the form preparation event.
$results = $dispatcher->trigger('onContentPrepareForm', array($form, $data));

И вот тут должен срабатывать метод onContentPrepareForm() плагина, который почему-то не срабатывает...
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #170 : 19.10.2015, 14:55:07 »
b2z, мы мало что поняли из того, что Вы написали, но тоже в большом недоумении. )
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #171 : 19.10.2015, 15:01:18 »
b2z, может быть, Вы нам дадите какое-то задание? Может быть, мы можем поискать в интернете какую-то конкретную информацию?
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #172 : 19.10.2015, 15:19:50 »
Да нечего пока давать... Вечером посмотрю, где может быть проблема.
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #173 : 19.10.2015, 15:33:40 »
b2z, хорошо, поняли.
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #174 : 19.10.2015, 21:02:06 »
Так, проверил все еще раз и нашел ошибки в коде.

1. В конструкторе не хватало строки
Код: php
parent::__construct($subject, $config);
2. В классе поля была ошибка - она назывался JFormFieldCompilation, а должен был JFormFieldCompilations

Я еще добавил проверку, что мы изменяем форму материала. Также убрал из файла поля fields и fieldset - не нужны, вполне хватает field.

Ну и самое главное, почему не отрабатывал onContentPrepareForm - на самом деле все отрабатывало, но стандартные макеты формы материала компонента com_content не выводят подряд все поля из файла формы, поэтому надо вручную добавить. Например, переопределяем макет форма фронта /components/com_content/views/form/tmpl/edit.php и после
Код: php
<?php echo $this->form->renderField('catid'); ?>
добавляем вывод поля compilations
Код: php
<?php echo $this->form->renderField('compilations'); ?>

Плагин приложил
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #175 : 20.10.2015, 16:40:06 »
b2z, мы вчера весь вечер дежурили у компьютера и ждали Вашего сообщения. И очень обрадовались, когда увидели Ваш ответ. Сразу же, пользуясь Вашей ссылкой, пошли разбираться, как делать переопределение макета формы фронта, затем переустановили плагин и ....
=)


 
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #176 : 20.10.2015, 17:16:35 »
Ну вот, прогресс. Не мешало бы еще добавить языковые файлы. Ну и самое главное - получить в плагине сборник, который выбрал пользователь. Событие onContentBeforeSave Вам в помощь.
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #177 : 20.10.2015, 17:24:29 »
Мы создали сборник через форму добавления сборника - и он благополучно отразился в выпадающем списке в менеджере материалов. Ура!
b2z, спасибо Вам! Мы очень ценим то, что Вы нам помогаете. Без Вас, без Ваших замечательных статей, без Вашей помощи, без помощи этого форума мы не смогли бы осуществить то, что сделали вместе.
------------------------
Плагин работает. Теперь нужно довести его до ума - сделать перевод (на картинках выше видно, что отображение названия плагина во фронте некорректно - нужно заменить английские слова)
Сейчас мы этим занимаемся.

После этого будем доводить до ума сам компонент (сейчас сборники, созданные пользователем, выводятся некликабельным списком. Нужно, чтобы этот список сборников отображался вместе с материалами, которые в нём содержатся. А также был кликабельным). Будем очень признательны, если Вы подскажете, где нам искать информацию на тему того, как добавить отображение материалов в этот список.
Сам список сейчас выглядит так:
*

mila_serdnaya

  • Захожу иногда
  • 432
  • 3 / 0
Re: Создание папок из фронтенда
« Ответ #178 : 20.10.2015, 17:34:18 »
b2z, пока писали своё сообщение, пропустили Ваше. ) Да, сегодня мы добавим языковые файлы. Ваша ссылка очень кстати.

После этого будем получать в плагине сборник, который выбрал пользователь (правда, мы пока до конца не понимаем, что это означает). Будем признательны, если Вы поясните, что именно Вы имели в виду.
« Последнее редактирование: 20.10.2015, 17:38:12 от mila_serdnaya »
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Re: Создание папок из фронтенда
« Ответ #179 : 20.10.2015, 21:49:34 »
Добавить отображение материалов - нужно в модели Compliations изменить запрос к базе данных.

Будем получать в плагине сборник - это значит, что Вам нужно сборник связать с пользователем. Для этого используйте onContentBeforeSave - получите данные, которые придут из формы. В них должен быть ID сборника. Потом сохраняете его в таблицу compilations_articles вместе с ID материала.
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Создание релиза компонента средствами GitHub

Автор SkyAn

Ответов: 4
Просмотров: 1291
Последний ответ 01.11.2019, 17:42:04
от Septdir
[Решено] Создание контент плагина

Автор IvanTopor

Ответов: 4
Просмотров: 1944
Последний ответ 26.02.2016, 13:10:37
от IvanTopor
Создание динамических полей в своем компоненте

Автор NeuroZ

Ответов: 14
Просмотров: 1876
Последний ответ 18.08.2015, 11:17:59
от b2z
Создание таблиц средствами компонента

Автор spirit1086

Ответов: 3
Просмотров: 1624
Последний ответ 18.08.2015, 10:17:09
от spirit1086
Создание изображений PHP и GD

Автор vita1971

Ответов: 6
Просмотров: 1351
Последний ответ 10.05.2015, 13:10:38
от vita1971