Новости Joomla

SW JProjects v.2.5.0 - компонент каталога цифровых проектов на Joomla

SW JProjects v.2.5.0 - компонент каталога цифровых проектов на Joomla

👩‍💻 SW JProjects v.2.5.0 - компонент каталога цифровых проектов на Joomla.Компонент - менеджер цифровых проектов для Joomla! CMS. Компонент обеспечивает создание каталога цифровых проектов и предоставляет возможность скачивания, в том числе с использованием лицензионных ключей.👩‍💻 v.2.5.0. Что нового?Схемы структур данных для серверов обновлений. Теперь с SW JProjects вы может создавать сервер обновлений не только для расширений Joomla, но и свои собственные. Например, вам нужно, чтобы структура данных сервера обновлений была другая и формат должен быть, например, не XML, а JSON. Формирование структуры данных для сервера обновлений расширений Joomla вынесено в отдельный плагин. Вы можете создать свой собственный плагин и реализовать в нём нужную вам структуру данных, добавив или наоборот исключив отображаемые данные. Сервер обновлений в компоненте по-прежнему отображает информацию о списке проектов и их версиях, о конкретном проекте и его changelog.Можно выбрать схему данных сервера обновлений глобально для всего компонента, выбрать другую схему данных для категории проектов, а так же выбрать схему в каждом проекте.

Разработчикам в качестве образца можно посмотреть плагин схемы данных для Joomla в составе компонента или же плагин-образец JSON-схемы на GitHub.
Группа плагинов swjprojects. Для нужд компонента создана группа плагинов swjprojects. В частности, в этой группе находится плагин структуры данных Joomla расширений для сервера обновлений.Изменение языковых констант. Изменены некоторые языковые константы в панели администратора. Если вы делали переопределение констант - переопределите их снова.👩‍💻 Joomla 6. Внесены изменения для корректной установки и работы компонента на Joomla 6. Компонент успешно протестирован на Joomla 6-beta2.Минимальная версия Joomla - 5. Подняты минимальные системные требования: Joomla 5.0.0 и PHP 8.1.
- Страница расширения👉 Плагин-образец кастомной JSON-схемы данных для сервера обновлений на GitHub.- GitHub расширения- Документация на GitHub- Joomla Extensions Directory#joomla #расширения

Как триггерить события для плагинов на манер Joomla 5+?В Joomla 6 должны удалить метод...

Как триггерить события для плагинов на манер Joomla 5+?В Joomla 6 должны удалить метод...

👩‍💻 Как триггерить события для плагинов на манер Joomla 5+?В Joomla 6 должны удалить метод triggerEvent(), с помощью которого раньше вызывались события для плагинов. Теперь чтобы в своём коде вызвать событие для плагина и получить от него результаты нужно:- создать объект класса события- передать в него параметры

use Joomla\CMS\Event\AbstractEvent;use Joomla\CMS\Factory;use Joomla\CMS\Plugin\PluginHelper;// Грузим плагины нужных группPluginHelper::importPlugin('system');// Создаём объект события$event = AbstractEvent::create('onAfterInitUniverse', [    'subject' => $this,    'data'    => $data, // какие-то данные    'article' => $article, // ещё материал вдовесок    'product' => $product, // и товаров подвезли]);// Триггерим событиеFactory::getApplication()->getDispatcher()->dispatch(    $event->getName(), // Тут можно строку передать 'onAfterInitUniverse'    $event);// Получаем результаты// В случае с AbstractEvent это может быть не 'result',// а что-то ещё - куда сами отдадите данные.// 2-й аргумент - значение по умолчанию, // если не получены результаты$results = $event->getArgument('result', []);
Плюсы такого подхода - вам не нужно запоминать порядок аргументов и проверять их наличие. Если вы написали свой класс события, то в плагине можно получать аргументы с помощью методов $event->getArticle(), $event->getData(), $event->getProduct() и подобными - реализуете сами под свои нужды. Если такой класс события написали, то создаёте экземпляр своего класса события и укажите его явно в аргументе eventClass
use Joomla\Component\MyComponent\Administrator\Event\MyCoolEvent;$event = MyCoolEvent::create('onAfterInitUniverse', [    'subject'    => $this,    'eventClass' => MyCoolEvent::class, // ваш класс события    'data'       => $data, // какие-то данные    'article'    => $article, // ещё материал вдовесок    'product'    => $product, // и товаров подвезли]);
Ожидаемо, что класс вашего события будет расширять AbsractEvent или другие классы событий Joomla.🙁 Есть неприятный нюанс - нельзя просто так вызывать событие и ничего не передать в аргументы. Аргумент subject обязательный. Но если вы всё-таки не хотите туда ничего передавать - передайте туда пустой stdClass или объект Joomla\registry\Registry.
@joomlafeed#joomla #php #webdev

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

dremora

  • Захожу иногда
  • 461
  • 48 / 12
Есть мысль вывести select c опцией педжинации. И возможно, некоторые другие свои фильтры.

Я так понимаю, нужно добавлять в модель?
Всё что не анархия, то фашизм...
*

SmokerMan

  • Гуру
  • 5290
  • 720 / 26
Re: как добавить фильтр в com_content?
« Ответ #1 : 17.01.2011, 12:47:08 »
да в модель здесь немного об этом есть
А так кто мешает взять любой стандартный компонент и посмотреть как там это реализовано.
*

dremora

  • Захожу иногда
  • 461
  • 48 / 12
Re: как добавить фильтр в com_content?
« Ответ #2 : 18.01.2011, 13:49:22 »
Так и не понял... Это для админ. части или для фронта. Мне бы нужно для фронта, добавить фильтры...

Например, добавить порядок вывода ASC и DESC
Добавить фильтр по автору. Показать конкретного автора или всех.

И мне бы очень хотелось взять из таблицы JComments и отобразить самые комментируемые. Наверное нужно делать через LIFT JOIN.

Может, что нибудь другое в будущем...
Всё что не анархия, то фашизм...
*

SmokerMan

  • Гуру
  • 5290
  • 720 / 26
Re: как добавить фильтр в com_content?
« Ответ #3 : 18.01.2011, 13:52:57 »
Так и не понял... Это для админ. части или для фронта.
и в чем разница то?
Или на фронте используется другой фреймворк? :)
*

dremora

  • Захожу иногда
  • 461
  • 48 / 12
Re: как добавить фильтр в com_content?
« Ответ #4 : 20.01.2011, 11:43:36 »
А можно доработать так, что-бы не только шаблон назначать, но и модель? Или хотя-бы часть кода модели?

Хотя бы вот:

Код
function getListQuery()
{
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true);

// Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
'a.id, a.title, a.alias, a.title_alias, a.introtext, ' .
'a.catid, a.created, a.created_by, a.created_by_alias, ' .
// use created if modified is 0
'CASE WHEN a.modified = 0 THEN a.created ELSE a.modified END as modified, ' .
'a.modified_by, uam.name as modified_by_name,' .
// use created if publish_up is 0
'CASE WHEN a.publish_up = 0 THEN a.created ELSE a.publish_up END as publish_up, ' .
'a.publish_down, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, '.
'a.hits, a.xreference, a.featured,'.' LENGTH(a.fulltext) AS readmore '
)
);

// Process an Archived Article layout
if ($this->getState('filter.published') == 2) {
// If badcats is not null, this means that the article is inside an unpublished category
// In this case, the state is set to 0 to indicate Unpublished (even if the article state is Published)
$query->select($this->getState('list.select','CASE WHEN badcats.id is null THEN a.state ELSE 2 END AS state'));
}
else {
// Process non-archived layout
// If badcats is not null, this means that the article is inside an unpublished category
// In this case, the state is set to 0 to indicate Unpublished (even if the article state is Published)
$query->select($this->getState('list.select','CASE WHEN badcats.id is not null THEN 0 ELSE a.state END AS state'));
}

$query->from('#__content AS a');

// Join over the frontpage articles.
if ($this->context != 'com_content.featured') {
$query->join('LEFT', '#__content_frontpage AS fp ON fp.content_id = a.id');
}

// Join over the categories.
$query->select('c.title AS category_title, c.path AS category_route, c.access AS category_access, c.alias AS category_alias');
$query->join('LEFT', '#__categories AS c ON c.id = a.catid');

// Join over the users for the author and modified_by names.
$query->select("CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author");
$query->select("ua.email AS author_email");

$query->join('LEFT', '#__users AS ua ON ua.id = a.created_by');
$query->join('LEFT', '#__users AS uam ON uam.id = a.modified_by');

// Join on contact table
$query->select('contact.id as contactid' ) ;
$query->join('LEFT','#__contact_details AS contact on contact.user_id = a.created_by');

// Join over the categories to get parent category titles
$query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias');
$query->join('LEFT', '#__categories as parent ON parent.id = c.parent_id');

// Join on voting table
$query->select('ROUND( v.rating_sum / v.rating_count ) AS rating, v.rating_count as rating_count');
$query->join('LEFT', '#__content_rating AS v ON a.id = v.content_id');

// Join to check for category published state in parent categories up the tree
$query->select('c.published, CASE WHEN badcats.id is null THEN c.published ELSE 0 END AS parents_published');
$subquery = 'SELECT cat.id as id FROM #__categories AS cat JOIN #__categories AS parent ';
$subquery .= 'ON cat.lft BETWEEN parent.lft AND parent.rgt ';
$subquery .= 'WHERE parent.extension = ' . $db->quote('com_content');

if ($this->getState('filter.published') == 2) {
// Find any up-path categories that are archived
// If any up-path categories are archived, include all children in archived layout
$subquery .= ' AND parent.published = 2 GROUP BY cat.id ';
// Set effective state to archived if up-path category is archived
$publishedWhere = 'CASE WHEN badcats.id is null THEN a.state ELSE 2 END';
}
else {
// Find any up-path categories that are not published
// If all categories are published, badcats.id will be null, and we just use the article state
$subquery .= ' AND parent.published != 1 GROUP BY cat.id ';
// Select state to unpublished if up-path category is unpublished
$publishedWhere = 'CASE WHEN badcats.id is null THEN a.state ELSE 0 END';
}
$query->join('LEFT OUTER', '(' . $subquery . ') AS badcats ON badcats.id = c.id');

// Filter by access level.
if ($access = $this->getState('filter.access')) {
$user = JFactory::getUser();
$groups = implode(',', $user->getAuthorisedViewLevels());
$query->where('a.access IN ('.$groups.')');
}

// Filter by published state
$published = $this->getState('filter.published');

if (is_numeric($published)) {
// Use article state if badcats.id is null, otherwise, force 0 for unpublished
$query->where($publishedWhere . ' = ' . (int) $published);
}
else if (is_array($published)) {
JArrayHelper::toInteger($published);
$published = implode(',', $published);
// Use article state if badcats.id is null, otherwise, force 0 for unpublished
$query->where($publishedWhere . ' IN ('.$published.')');
}

// Filter by featured state
$featured = $this->getState('filter.featured');
switch ($featured)
{
case 'hide':
$query->where('a.featured = 0');
break;

case 'only':
$query->where('a.featured = 1');
break;

case 'show':
default:
// Normally we do not discriminate
// between featured/unfeatured items.
break;
}

// Filter by a single or group of articles.
$articleId = $this->getState('filter.article_id');

if (is_numeric($articleId)) {
$type = $this->getState('filter.article_id.include', true)? '= ' : '<> ';
$query->where('a.id '.$type.(int) $articleId);
}
else if (is_array($articleId)) {
JArrayHelper::toInteger($articleId);
$articleId = implode(',', $articleId);
$type = $this->getState('filter.article_id.include', true)? 'IN' : 'NOT IN';
$query->where('a.id '.$type.' ('.$articleId.')');
}

// Filter by a single or group of categories
$categoryId = $this->getState('filter.category_id');

if (is_numeric($categoryId)) {
$type = $this->getState('filter.category_id.include', true)? '= ' : '<> ';

// Add subcategory check
$includeSubcategories = $this->getState('filter.subcategories', false);
$categoryEquals = 'a.catid '.$type.(int) $categoryId;

if ($includeSubcategories) {
$levels = (int) $this->getState('filter.max_category_levels', '1');
// Create a subquery for the subcategory list
$subQuery = $db->getQuery(true);
$subQuery->select('sub.id');
$subQuery->from('#__categories as sub');
$subQuery->join('INNER', '#__categories as this ON sub.lft > this.lft AND sub.rgt < this.rgt');
$subQuery->where('this.id = '.(int) $categoryId);
if ($levels >= 0) {
$subQuery->where('sub.level <= this.level + '.$levels);
}

// Add the subquery to the main query
$query->where('('.$categoryEquals.' OR a.catid IN ('.$subQuery->__toString().'))');
}
else {
$query->where($categoryEquals);
}
}
else if (is_array($categoryId) && (count($categoryId) > 0)) {
JArrayHelper::toInteger($categoryId);
$categoryId = implode(',', $categoryId);
if (!empty($categoryId)) {
$type = $this->getState('filter.category_id.include', true)? 'IN' : 'NOT IN';
$query->where('a.catid '.$type.' ('.$categoryId.')');
}
}

// Filter by author
$authorId = $this->getState('filter.author_id');
$authorWhere = '';

if (is_numeric($authorId)) {
$type = $this->getState('filter.author_id.include', true)? '= ' : '<> ';
$authorWhere = 'a.created_by '.$type.(int) $authorId;
}
else if (is_array($authorId)) {
JArrayHelper::toInteger($authorId);
$authorId = implode(',', $authorId);

if ($authorId) {
$type = $this->getState('filter.author_id.include', true)? 'IN' : 'NOT IN';
$authorWhere = 'a.created_by '.$type.' ('.$authorId.')';
}
}

// Filter by author alias
$authorAlias = $this->getState('filter.author_alias');
$authorAliasWhere = '';

if (is_string($authorAlias)) {
$type = $this->getState('filter.author_alias.include', true)? '= ' : '<> ';
$authorAliasWhere = 'a.created_by_alias '.$type.$db->Quote($authorAlias);
}
else if (is_array($authorAlias)) {
$first = current($authorAlias);

if (!empty($first)) {
JArrayHelper::toString($authorAlias);

foreach ($authorAlias as $key => $alias)
{
$authorAlias[$key] = $db->Quote($alias);
}

$authorAlias = implode(',', $authorAlias);

if ($authorAlias) {
$type = $this->getState('filter.author_alias.include', true)? 'IN' : 'NOT IN';
$authorAliasWhere = 'a.created_by_alias '.$type.' ('.$authorAlias .
')';
}
}
}

if (!empty($authorWhere) && !empty($authorAliasWhere)) {
$query->where('('.$authorWhere.' OR '.$authorAliasWhere.')');
}
else if (empty($authorWhere) && empty($authorAliasWhere)) {
// If both are empty we don't want to add to the query
}
else {
// One of these is empty, the other is not so we just add both
$query->where($authorWhere.$authorAliasWhere);
}

// Filter by start and end dates.
$nullDate = $db->Quote($db->getNullDate());
$nowDate = $db->Quote(JFactory::getDate()->toMySQL());

$query->where('(a.publish_up = '.$nullDate.' OR a.publish_up <= '.$nowDate.')');
$query->where('(a.publish_down = '.$nullDate.' OR a.publish_down >= '.$nowDate.')');

// Filter by Date Range or Relative Date
$dateFiltering = $this->getState('filter.date_filtering', 'off');
$dateField = $this->getState('filter.date_field', 'a.created');

switch ($dateFiltering)
{
case 'range':
$startDateRange = $db->Quote($this->getState('filter.start_date_range', $nullDate));
$endDateRange = $db->Quote($this->getState('filter.end_date_range', $nullDate));
$query->where('('.$dateField.' >= '.$startDateRange.' AND '.$dateField .
' <= '.$endDateRange.')');
break;

case 'relative':
$relativeDate = (int) $this->getState('filter.relative_date', 0);
$query->where($dateField.' >= DATE_SUB('.$nowDate.', INTERVAL ' .
$relativeDate.' DAY)');
break;

case 'off':
default:
break;
}

// process the filter for list views with user-entered filters
$params = $this->getState('params');

if ((is_object($params)) && ($params->get('filter_field')!= 'hide') && ($filter = $this->getState('list.filter'))) {
// clean filter variable
$filter = JString::strtolower($filter);
$hitsFilter = intval($filter);
$filter = $db->Quote('%'.$db->getEscaped($filter, true).'%', false);

switch ($params->get('filter_field'))
{
case 'author':
$query->where(
'LOWER( CASE WHEN a.created_by_alias > '.$db->quote(' ').
' THEN a.created_by_alias ELSE ua.name END ) LIKE '.$filter.' '
);
break;

case 'hits':
$query->where('a.hits >= '.$hitsFilter.' ');
break;

case 'title':
default: // default to 'title' if parameter is not valid
$query->where('LOWER( a.title ) LIKE '.$filter);
break;
}
}

// Filter by language
if ($this->getState('filter.language')) {
$query->where('a.language in ('.$db->quote(JFactory::getLanguage()->getTag()).','.$db->quote('*').')');
}

// Add the list ordering clause.
$query->order($this->getState('list.ordering', 'a.ordering').' '.$this->getState('list.direction', 'ASC'));

return $query;
}

Метод getListQuery разбиваем на внешние файлы и ставим переключатель. Файл модели берётся по названию присвоенного шаблона. Например, на блог категории у меня - advsearch.php. То в моделях создаём папку lib и туда кидаем файлы и этот advsearch.php.

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

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Re: как добавить фильтр в com_content?
« Ответ #5 : 28.01.2011, 10:51:17 »
SmokerMan - чего-то я не до конца понял, что значит вот это в "Публикация элемента из списка":
Цитировать
Что бы все работало, без внесения каких-либо изменений

Имеется ввиду, что если у меня в таблице есть колонка published, то я могу не добавлять никаких спец. методов для публикации записи?
*

SmokerMan

  • Гуру
  • 5290
  • 720 / 26
Re: как добавить фильтр в com_content?
« Ответ #6 : 28.01.2011, 11:01:35 »
SmokerMan - чего-то я не до конца понял, что значит вот это в "Публикация элемента из списка":
это я так назвал кнопочку с иконкой, опубликовать и снять с публикации :)
Имеется ввиду, что если у меня в таблице есть колонка published, то я могу не добавлять никаких спец. методов для публикации записи?
имеется ввиду, что если это поле так будет называться, то тебе не надо будет переопределять метод publish в таблице (JTable)
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Re: как добавить фильтр в com_content?
« Ответ #7 : 28.01.2011, 11:07:11 »
это я так назвал кнопочку с иконкой, опубликовать и снять с публикации :)имеется ввиду, что если это поле так будет называться, то тебе не надо будет переопределять метод publish в таблице (JTable)
Хы, блин - спасибо. Я как раз уже переопределил :) Будем исправлять ^^
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

[dev] Как добавить поддержку табов из Joomla 3.0 в Joomla 2.5?

Автор smart

Ответов: 17
Просмотров: 3543
Последний ответ 12.06.2013, 02:14:36
от smart
com_content дополнительное поле

Автор art-apple

Ответов: 13
Просмотров: 2172
Последний ответ 19.12.2012, 00:05:07
от rigin
Фильтр (выборка)

Автор valerasvs

Ответов: 5
Просмотров: 2408
Последний ответ 18.02.2011, 19:52:22
от Arkadiy
Как в настройках добавить свой тип поля.

Автор Toreador

Ответов: 2
Просмотров: 2016
Последний ответ 18.01.2011, 14:42:25
от Toreador