Новости Joomla

Человек на GitHub ускорил Joomla в 600 раз на объёме 150к+ материалов в 1700+ категориях

Человек на GitHub ускорил Joomla в 600 раз на объёме 150к+ материалов в 1700+ категориях

👩‍💻 Человек на GitHub ускорил Joomla в 600 раз на объёме 150к+ материалов в 1700+ категориях. На старте его сайт на Joomla 3 вообще не смог обновиться на Joomla 5. Пришлось делать экспорт/импорт материалов. Проделав всё это он запустил-таки этот объём данных на Joomla 5. Тестовый скрипт грузил 200 материалов из этого объёма всего за 94 секунды ))) А главная страница с категориями грузилась 20 секунд. Добавив индекс для таблицы #__content

CREATE INDEX idx_catid_state ON #__content (catid, state);
он сократил время загрузки категорий до 1 секунды. Затем наш герой решил поковырять SQL-запрос в ArticleModel, который отвечает за выборку материалов. И решил заменить тип JOIN на STRAIGHT_JOIN для категорий.
// ->from($db->quoteName('#__content', 'a'))->from(    $db->quoteName('#__content', 'a')    . ' STRAIGHT_JOIN ' . $db->quoteName('#__categories', 'c')    . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid'))// ->join('LEFT', $db->quoteName('#__categories', 'c'), $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid'))
Что сократило загрузку 200 материалов из 150к с 94 секунд до 5. К слову сказать, боевой сайт на Joomla 3 крутится на 12CPU 64GB рамы. А все манипуляции с кодом он делает на базовом 1CPU 1GB сервере и замеры скорости даны именно для базового сервера. Но это всё в дискуссии, хотя в идеале должно вылиться в Pull Requests. Мы - Open Source сообщество, где никто никому ничего не должен. Джунгли. Но человек ищет пути оптимизации Joomla и предлагает решения. Если оказать поддержку и предложить помощь хотя бы с тестированием самых разнообразных сценариев, то возможно эти улучшения смогут войти в ядро. Пусть не быстро, пусть через несколько лет, пусть не все, но войдут. Достаточно предложить руку помощи и приложить немного усилий.
Дискуссию на GitHub можно почитать здесь.@joomlafeed#joomla #community #php

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

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Фильтр на странице всех записей - это обыкновенный селект, который чаще всего является типом поля.
Вопрос: Как можно использовать тип поля, в роли фильтра.
Допустим у меня есть свой тип поля city(JFormFieldCity), как я могу получить его возвращаемое содержимое в виде(например view.html) компонента.
Вызвать напрямую конечно же не могу(JFormFieldCity::getOptions()).

Так же попробовал добавить в типе поля public метод:
Код: php
public function getSelect()
{
     return $this->getOptions();
}
При попытке вызова её возвращает 500 ошибку:
Код: php
$city = new JFormFieldCity();
$this->filter_city = $city->getSelect();
Код: php
$this->filter_city = JFormFieldCity::getSelect();

Если я не могу повторно использовать этот класс, то понт от файлов "тип поля" нет никакого. С таким же успехом я мог бы создать абстрактный класс, который будет возвращать мне этот гребаный селект.
Хотя возможно просто не понимаю специфику обращения к классам в Joomla.
« Последнее редактирование: 31.07.2013, 10:03:10 от xchesh »
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
А если вызвать JFormFieldCity:getInput()?

У Вас этот типа поля вообще что возвращает? Код поля в студию  ::)
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
А если вызвать JFormFieldCity:getInput()?

У Вас этот типа поля вообще что возвращает? Код поля в студию  ::)

Спасибо что ответили, мне подумалось что это сообщение проигнорируют.
JFormFieldCity::getInput() Так же возвращает 500 ошибку.
Тип поля возвращает список городов, он работает. Но вот вызвать где-то еще, не представляется возможности.
Код: php
<?php
defined('_JEXEC') or die;

jimport('joomla.form.helper');
JFormHelper::loadFieldClass('list');

class JFormFieldCity extends JFormFieldList
{
protected $type = 'City';
 
protected function getOptions()
{
$db = JFactory::getDBO();

$query = $db->getQuery(true);
$query->select('id, title')
->from('#__city');
$db->setQuery($query);
$cities = $db->loadObjectList();

$options = array();
if ($cities)
{
foreach($cities as $city)
{
$options[] = JHtml::_('select.option', $city->id, $city->title);
}
}
$options = array_merge(parent::getOptions(), $options);

return $options;
}
}

Для меня немного непонятен ООП в Joomla. Нельзя получить экземпляр класса, которого захочу, нельзя вызвать метод класса, который нужен. Постоянно требуется переписывать один и тот же код.
« Последнее редактирование: 31.07.2013, 10:12:45 от xchesh »
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Чтобы код JFormFieldCity::getSelect() сработал, вероятно нужно дать понять Joomla, что есть такой класс. Сомневаюсь, что он попадает в автозагрузку. Попробуйте добавить в точку входа компонента строку:
Код: php
JLoader::discover('JForm', JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Сорри, поправка:
Код: php
JLoader::discover('JFormField', JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');

Соответственно типа поля city (класс JFormFieldCity) должен находится в файле city.php.

Здесь можно почитать про регистрацию классов.
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Сорри, поправка:
Код: php
JLoader::discover('JFormField', JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');

Соответственно типа поля city (класс JFormFieldCity) должен находится в файле city.php.

Здесь можно почитать про регистрацию классов.

Ну конечно, в city.php, спасибо за попытку, но и это не работает.
Спасибо за ссылку, почитаю, м.б. что-то извлеку.
Пока все попытки безуспешны.
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Вы писали про ошибку 500 - в логах что пишет? Вообще лучше включить отображение ошибок на максимум - сразу будет понятно, где затык.
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Вы писали про ошибку 500 - в логах что пишет? Вообще лучше включить отображение ошибок на максимум - сразу будет понятно, где затык.
Хм... Спасибо что напомнили про максимум ошибок, режим отладки включил, а все сообщения php не вывел.
Fatal error: Class 'JFormFieldCity' not found in /var/www/vhosts.....и_тут_путь_до_файла_в_котором_вызывается_метод
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
А где хранятся fields? Обычно это administrator/com_component/models/fields. Но если у Вас в просто com_component/models/fields, то поменяйте JPATH_COMPONENT_ADMINISTRATOR на JPATH_COMPONENT.

У меня класс находит:
Код: php
JLoader::discover('JFormField', JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');
$result = JFormFieldHelloWorld::getOptions();

Цитировать
Fatal error: Call to protected method JFormFieldHelloWorld::getOptions()...
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Все верно, уже исправил, подключается файл, но уже другие ошибки
Код: php
static function getSelect()
{
     return $this->getOptions();
}
Fatal error: Using $this when not in object context in /var/www/vhosts/сайт/httpdocs/administrator/components/com_компонент/models/fields/city.php on line 36

getInput()  возвращает ошибку:
Fatal error: Call to protected method JFormFieldList::getInput() from context ...
« Последнее редактирование: 31.07.2013, 10:49:44 от xchesh »
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Попробуйте поменять $this->getOptions(); на self::getOptions(); - у нас объект же не создается.

Или вызывать так:
Код: php
$city = new JFormFieldCity();
$this->filter_city = $city->getSelect();
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Или вызывать так:
Код: php
$city = new JFormFieldCity();
$this->filter_city = $city->getSelect();
Согласен, именно так нужно было вызвать, но теперь все гораздо интереснее.
Метод getOptions() срабатывает родительский, не переопределенный мной, а именно родительский.
Конечно же это вызывает ошибку, т.к. никаких данных нету.
Код
Fatal error: Call to a member function children() on a non-object in /var/www/vhosts/сайт/httpdocs/libraries/joomla/form/fields/list.php on line 89
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Ну да, у нас же вызывается родительский через parent::getOptions(), поэтому и ошибка.
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Ну да, у нас же вызывается родительский через parent::getOptions(), поэтому и ошибка.
Отлично, пришли с чего начинали. Итог - невозможно использовать класс повторно.
Собственно проще создать абстрактный класс и наплодить там пару методов, которые смогу вызывать где угодно.
« Последнее редактирование: 31.07.2013, 11:20:16 от xchesh »
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Почему? Уберите:
Код: php
$options = array_merge(parent::getOptions(), $options);
Метод будет возвращать массив.
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Почему? Уберите:
Код: php
$options = array_merge(parent::getOptions(), $options);
Метод будет возвращать массив.
Да, но тогда тип поля перестанет работать. Смысл в том, чтобы вернуть select.
*

prometheus

  • Захожу иногда
  • 84
  • 7 / 0
И не нужно его использовать как фильтр это логически Неправильно. Я бы делал так: логику из getOptions реализовал в моделе, соответственно из getOptions вызывал бы метод модели, а в нужном месте view тоже вызывать эту модель
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
И не нужно его использовать как фильтр это логически Неправильно. Я бы делал так: логику из getOptions реализовал в моделе, соответственно из getOptions вызывал бы метод модели, а в нужном месте view тоже вызывать эту модель
Почему не логично? Мне нужен фильтр по городам, у меня есть такой тип поля возвращающий список городов. И то и то является select'ом. Что нелогичного в том, чтобы не писать один и тот же код 2 раза?
И да, можно реализовать логику в модели, но как Вы в getOptions() вызовете метод модели?
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
И не нужно его использовать как фильтр это логически Неправильно. Я бы делал так: логику из getOptions реализовал в моделе, соответственно из getOptions вызывал бы метод модели, а в нужном месте view тоже вызывать эту модель
Почему же? Это поле - элемент верстки. Почему бы его не использовать повторно в качестве фильтра? Просто в Joomla эти поля плотно связаны с JForm и моделью, поэтому приходится немного костылить.

Да, но тогда тип поля перестанет работать. Смысл в том, чтобы вернуть select.
Будет. getOptions() просто дают Вам массив, который потом нужно засунуть в JHtml::_('select.genericlist'). Это обычно делается в методе getInput(). Посмотрите на реализацию поля list.

Вы же можете сделать что-то вроде:
Код: php
public function getSelectList()
{
return JHtml::_('select.genericlist', $this->getOptions(), 'city');
}
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Почему же? Это поле - элемент верстки. Почему бы его не использовать повторно в качестве фильтра? Просто в Joomla эти поля плотно связаны с JForm и моделью, поэтому приходится немного костылить.
Будет. getOptions() просто дают Вам массив, который потом нужно засунуть в JHtml::_('select.genericlist'). Это обычно делается в методе getInput(). Посмотрите на реализацию поля list.

Вы же можете сделать что-то вроде:
Код: php
public function getSelectList()
{
return JHtml::_('select.genericlist', $this->getOptions(), 'city');
}
Это все костыли.
Как то не юзабельно получается.
Сделаю ка я абстрактный класс для всех селектов, и буду его вызвать где нужно.
Динамично и просто. Два метода, один возвращает селект, второй массив. Никаких костылей и танцов с бубном.
Всем спасибо.
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Ну да, так просто не получается... Все таки типы полей очень тесно связаны с JForm и отдельно их тяжело использовать.

Я себе тоже делал отдельный helper для фильтров под JHtml. Потом в коде нужный фильтр вызываю как
Код: php
JHtml::_('eshtml.filters.имяфильтра')

Соответственно класс abstract class EsHtmlFilters и внутри методы типа public static имяфильтра(). Класс лежит в /helpers/html/filters.php и регистрируется через:
Код: php
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1

Ну да, так просто не получается... Все таки типы полей очень тесно связаны с JForm и отдельно их тяжело использовать.

Я себе тоже делал отдельный helper для фильтров под JHtml. Потом в коде нужный фильтр вызываю как
Код: php
JHtml::_('eshtml.filters.имяфильтра')

Соответственно класс abstract class EsHtmlFilters и внутри методы типа public static имяфильтра(). Класс лежит в /helpers/html/filters.php и регистрируется через:
Код: php
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
Точно так же собирался сделать :)
Когда уже урок на Joomlablog.ru будет по фильтрам?) М.б. что-то интересное почитаю.
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Только я немного не так.
Создаю абстрактный класс в /helpers/html/filters.php
А регистрирую его через
Код: php
JLoader::register('SelectReturn', JPATH_COMPONENT_ADMINISTRATOR . '/helpers/html/filters.php');

Класс просто возвращает либо масив, либо select

Вызов можно сделать с в любом месте компоннета SelectReturn::getSelect();
Тип поля получается:
Код: php
protected function getOptions() 
{
    $options = SelectReturn::getSelect(false, 'city', array('id','title'));
    $options = array_merge(parent::getOptions(), $options);
                
    return $options;
}
А вот сам класс совсем простой. Минимум затрат и 100% возврат списка.
Код: php
<?php
// No direct access to this file
defined('_JEXEC') or die;

abstract class SelectReturn
{
public static function getData($table = 'city', $param = array('id', 'title'))
{
            $db = JFactory::getDBO();
            $query = $db->getQuery(true);
            $query->select($param[0].','.$param[1])->from('#__'.$table);
            $db->setQuery($query);
            $return = $db->loadAssocList();
            return $return;
}

public static function getSelect($data = false, $table = 'city', $param = array('id', 'title'))
{
   if(!$data)
            {
                $data = self::getData($table, $param);
            }
            $options = array();
            foreach($data as $item)
            {
                    $options[] = JHtml::_('select.option', $item[$param[0]], $item[$param[1]]);
            }
            return $options;
}
}
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Хороший вариант. И главное универсальный с минимум кода.

Статья по фильтрам планируется в части 16 (но не уверен, что Вы найдете для себя что-то новое). Но сначала будет часть 15 по добавлению состояния записи.
*

xchesh

  • Захожу иногда
  • 277
  • 10 / 1
Хороший вариант. И главное универсальный с минимум кода.

Статья по фильтрам планируется в части 16 (но не уверен, что Вы найдете для себя что-то новое). Но сначала будет часть 15 по добавлению состояния записи.
Спасибо за похвалу. :)
Состояние заблокирована ли запись? Это было бы хорошо, как-то никогда не реализовывал блокировку.
*

b2z

  • Глобальный модератор
  • 7287
  • 778 / 0
  • Разраблю понемногу
Состояние заблокирована ли запись? Это было бы хорошо, как-то никогда не реализовывал блокировку.
Нет, про поле state - опубликовано/неопубликовано.

Эту тему пока оставлю открытой, может кто-то подскажет способ использования типов полей ::) Мало ли  ^-^
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Доработать плагин импорта полей CFI от joomline

Автор R31rus

Ответов: 1
Просмотров: 607
Последний ответ 21.12.2022, 10:40:11
от R31rus
Использование Masked text box в Joomla

Автор stels009

Ответов: 14
Просмотров: 1553
Последний ответ 12.09.2014, 20:24:58
от stels009
Не переключаются страницы после использования фильтров

Автор DimkaJack

Ответов: 41
Просмотров: 4063
Последний ответ 16.04.2014, 11:08:53
от b2z
Динамическое добавление полей по кнопке "добавить"

Автор navyzet

Ответов: 3
Просмотров: 3186
Последний ответ 14.12.2013, 21:00:14
от varX
Динамическое изменение количества полей в админке Joomla 2.5

Автор GooG2e

Ответов: 0
Просмотров: 1138
Последний ответ 23.09.2013, 22:31:18
от GooG2e