Основной курс по Joomla

Модуль вывода категорий, формирование ссылки

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

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
В модуле есть такая штука
Код: php
echo JRoute::_(ContentHelperRoute::getCategoryRoute($item->id));
Формирует ссылку на текущую категорию.
У меня более 100 категорий, а это 100+ запросов к БД ! crazy!
Есть вариант обойтись без дёрганья базы ?

*

robert

  • Профи
  • ********
  • 4009
  • 371
Почему 100+? Вы выводите сразу все категории? И не всегда делается запрос в БД: информация хранится в течение всей сессии.
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Почему 100+? Вы выводите сразу все категории?
Это список категорий для навигации по ним, так сказать...
И не всегда делается запрос в БД: информация хранится в течение всей сессии.
Ну я что вижу в отладке, то и говорю ! Абсолютно всегда 100+ запросов...

И сразу напишу... плагины отрубал все, компоненты какие отключаются, тоже. Кеш включен.

*

robert

  • Профи
  • ********
  • 4009
  • 371
Ну, во-первых, делайте пагинацию - это один из способов уменьшить время загрузки страницы.
Во-вторых, ссылки имеют SEF-вид? Тогда попробуйте написать просто JRoute::_('index.php?option=com_content&view=category&id=blahblah'), без этих функций helper'а.
Ну я что вижу в отладке, то и говорю ! Абсолютно всегда 100+ запросов...
Куда они делаются?
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Ну, во-первых, делайте пагинацию - это один из способов уменьшить время загрузки страницы.
Так причём тут пагинация, это модуль просто !
Спойлер
[свернуть]

Во-вторых, ссылки имеют SEF-вид? Тогда попробуйте написать просто JRoute::_('index.php?option=com_content&view=category&id=blahblah'), без этих функций helper'а.
Да, ссылки имеют вид /video/165-vecherinki.html
Пробовал так
Код: php
JRoute::_('index.php?option=com_content&view=category&id='.$item->id)
и так
Код: php
JRoute::_('index.php?option=com_content&view=category&id='.$item->slug)
Запросы остаються... Исчезают при комментировании этой строки

Куда они делаются?
Не понял вопроса ?
Сам запрос выглядит так
Код: sql
SELECT c.id, c.asset_id, c.access, c.alias, c.checked_out, c.checked_out_time,
c.created_time, c.created_user_id, c.description, c.extension, c.hits, c.language, c.level,
c.lft, c.metadata, c.metadesc, c.metakey, c.modified_time, c.note, c.params, c.parent_id,
c.path, c.published, c.rgt, c.title, c.modified_user_id, c.version,
  CASE WHEN CHAR_LENGTH(c.alias)!= 0 THEN CONCAT_WS(':', c.id, c.alias) ELSE c.id END as slug

  FROM j_categories as c

  LEFT JOIN j_categories AS s
  ON (s.lft <= c.lft
  AND s.rgt >= c.rgt) OR (s.lft > c.lft
  AND s.rgt < c.rgt)

  LEFT JOIN  (SELECT cat.id as id
  FROM j_categories AS cat JOIN j_categories AS parent
  ON cat.lft BETWEEN parent.lft
  AND parent.rgt
  WHERE parent.extension = 'com_content'
  AND parent.published != 1
  GROUP BY cat.id) AS badcats
  ON badcats.id = c.id

  WHERE (c.extension='com_content' OR c.extension='system')
  AND c.access IN (1,1,2,3,6)
  AND c.published = 1
  AND s.id=153
  AND badcats.id is null

  GROUP BY c.id, c.asset_id, c.access, c.alias, c.checked_out, c.checked_out_time,
c.created_time, c.created_user_id, c.description, c.extension, c.hits, c.language, c.level,
c.lft, c.metadata, c.metadesc, c.metakey, c.modified_time, c.note, c.params, c.parent_id,
c.path, c.published, c.rgt, c.title, c.modified_user_id, c.version

  ORDER BY c.lft
только в этой строке AND s.id=153, id всегда меняется.

Стек вызова
Код
JROOT/libraries/legacy/categories/categories.php:296
JROOT/libraries/legacy/categories/categories.php:184
JROOT/components/com_content/helpers/route.php:80
JROOT/modules/mod_articles_categories/tmpl/default_items.php:22

*

robert

  • Профи
  • ********
  • 4009
  • 371
Так причём тут пагинация, это модуль просто !
И в модуле тоже можно делать пагинацию, по-моему, даже была такая тема.
только в этой строке AND s.id=153, id всегда меняется.
Значит, ваш код не оптимизирован. Не должно быть, чтобы сотни раз снова и снова загружалась одна и та же категория (ID которой - 153).
Спойлер
[свернуть]
Ппц, чем вы занимаетесь?
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Значит, ваш код не оптимизирован. Не должно быть, чтобы сотни раз снова и снова загружалась одна и та же категория (ID которой - 153).
Невнимательно читаете. Я написал что id меняется... т.е...
Код
1й запрос
  AND s.id=22

2й запрос
  AND s.id=23

3й запрос
  AND s.id=24

Nй запрос
  AND s.id=N

И причём тут мой код ? На чистой J тоже самое !

Ппц, чем вы занимаетесь?
Это отношение к делу не имеет ;)

*

robert

  • Профи
  • ********
  • 4009
  • 371
Невнимательно читаете. Я написал что id меняется... т.е...
Sorry, ваша правда, был не внимателен.
И причём тут мой код ? На чистой J тоже самое !
Да, все родное, от Joomla. Вы читали код JCategories::get()?
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Да, все родное, от Joomla. Вы читали код JCategories::get()?
Смотрел функцию. Я не пойму, что не так ? Можно напрямую сказать ?

*

robert

  • Профи
  • ********
  • 4009
  • 371
Спойлер
[свернуть]
Ваш запрос вызывается в функции _load(), там же формируется $this->_nodes[$id]. Вот и думал, что у вас массив $this->_nodes почему-то не сформирован или постоянно стирается.
Вывод: либо это (первый) запуск, либо с кодом что-то не так.
В первом случае можно только ограничить количество запросов, выводя не все категории сразу (что я назвал пагинацией).

P.S. Еще один выход из положения: в helper сделайте 01 запрос, выбрав сразу весь массив IDs (ведь вам нужен только ID, правда?) и далее циклом перебирайте их.
« Последнее редактирование: 17.01.2016, 21:40:21 от robert »
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
либо с кодом что-то не так.
Скачал чистую J 3.4.8 c Joomla.org, подцепил БД, всё теже 100+ запросов при публикации модуля mod_articles_categories. Как может быть не так с моим кодом, если на чистой J тоже самое !

*

robert

  • Профи
  • ********
  • 4009
  • 371
Теперь вы невнимательно читаете: я написал "либо либо". Предыдущий пост обновил.
Интересно, что на чистом Joomla тоже вызывает 100+ запросов?
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Интересно, что на чистом Joomla тоже вызывает 100+ запросов?
Будет плюсом столько запросов, сколько категорий создано(при публикации этого модуля)

*

robert

  • Профи
  • ********
  • 4009
  • 371
P.S. Еще один выход из положения: в helper сделайте 01 запрос, выбрав сразу весь массив IDs (ведь вам нужен только ID, правда?) и далее циклом перебирайте их.
Можно выбрать и другие параметры, кроме ID. Самое главное: уложиться в 1 запросе.
« Последнее редактирование: 17.01.2016, 21:44:56 от robert »
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Можно выбрать и другие параметры, кроме ID. Самое главное: уложиться в 1 запросе.
Можно чуть подробнее ? Я мысль никак уловить не могу

*

robert

  • Профи
  • ********
  • 4009
  • 371
Можно чуть подробнее ? Я мысль никак уловить не могу
Сейчас, как вы написали, для каждой категории делается 1 запрос. Цель - получить ID, название категории, что-то еще. Вам не нравится большое количество запросов. Так сделайте 1 запрос, выбрав сразу всю информацию для всех категорий. Или нужно написать запрос для вас?
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Сейчас, как вы написали, для каждой категории делается 1 запрос. Цель - получить ID, название категории, что-то еще. Вам не нравится большое количество запросов. Так сделайте 1 запрос, выбрав сразу всю информацию для всех категорий. Или нужно написать запрос для вас?
В запросе, по ID выбирается куча всякой ненужно фигни, которая в модуле уже выбрана... Я не знаю почему для формирования ссылки нужно опять лезть в базу и вытаскивать оттуда всякую инфу... slug, path, id есть, для ссылки вроде ничего не нужно, если я правильно понимаю

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Код: php
$link = preg_replace('~\/([A-Za-z0-9_-]+)~siu', '/'.$item->id.'-\\1'.($sef_suffix == true ? '.html' : ''), $item->path);
вот так например можно формировать ссылку которая мне нужна, Но блин это же неправильно !

*

robert

  • Профи
  • ********
  • 4009
  • 371
А $item откуда взять?
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
А $item откуда взять?
Так в tmpl модуля, там всё это есть ! Я про то и говорю, что всё что нужно выбираеться в хелпере модуля... и я до сих пор не могу понять что за бредятина там с роутером.

*

robert

  • Профи
  • ********
  • 4009
  • 371
Какой tmpl? Это всего лишь вывод HTML. Все запросы, которые вам так не нравятся, делаются в helper. А я-то думал, что вы более или менее разбираетесь.
  • Не будь паразитом, сделай что-нибудь самостоятельно!
  • В личке и по Skype не даю советов.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Какой tmpl? Это всего лишь вывод HTML. Все запросы, которые вам так не нравятся, делаются в helper. А я-то думал, что вы более или менее разбираетесь.
Вот код /mod_articles_categories/tmpl/default_item.php
Код: php
<?php
/**
 * @package     Joomla.Site
 * @subpackage  mod_articles_categories
 *
 * @copyright   Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

foreach ($list as $item) : ?>
        <li <?php if ($_SERVER['REQUEST_URI'] == JRoute::_(ContentHelperRoute::getCategoryRoute($item->id))) echo ' class="active"';?>> <?php $levelup = $item->level - $startLevel - 1; ?>
                <h<?php echo $params->get('item_heading') + $levelup; ?>>
                <a href="<?php echo JRoute::_(ContentHelperRoute::getCategoryRoute($item->id)); ?>">
                <?php echo $item->title;?>
                        <?php if ($params->get('numitems')) : ?>
                                (<?php echo $item->numitems; ?>)
                        <?php endif; ?>
                </a>
                </h<?php echo $params->get('item_heading') + $levelup; ?>>

                <?php if ($params->get('show_description', 0)) : ?>
                        <?php echo JHtml::_('content.prepare', $item->description, $item->getParams(), 'mod_articles_categories.content'); ?>
                <?php endif; ?>
                <?php if ($params->get('show_children', 0) && (($params->get('maxlevel', 0) == 0)
                        || ($params->get('maxlevel') >= ($item->level - $startLevel)))
                        && count($item->getChildren())) : ?>
                        <?php echo '<ul>'; ?>
                        <?php $temp = $list; ?>
                        <?php $list = $item->getChildren(); ?>
                        <?php require JModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default'). '_items'); ?>
                        <?php $list = $temp; ?>
                        <?php echo '</ul>'; ?>
                <?php endif; ?>
        </li>
<?php endforeach; ?>

при коментировании этой echo JRoute::_(ContentHelperRoute::getCategoryRoute($item->id)); строки запросы пропадают

*

passer

  • Живу я здесь
  • ******
  • 874
  • 70
Не великий спец в Joomla просто бегло почитал исходники.
com_content/helper/route.php getCategoryRoute()
Если первым параметром передается обьект JCategoryNode используется он, если что-то другое, обьект дергается из JCategories::getInstance('Content')->get($id);
Смотрим что за JCategories - поиск по файлам или перейти к определению если IDE.
/libraries/legacy/categories/categories.php
Угу. JCategories::getInstance('Content')->get($id) дергает обьект из БД через _load().
Ясен пень если в цикле, сколько итераций, столько запросов.
Упс. Класс JCategoryNode тут же. Заглянули. Наследуется от JObject.
Дальше лазить не стал влом.
Предположения:
Код: php
<a href="<?php echo JRoute::_(ContentHelperRoute::getCategoryRoute($item->id)); ?>">
Из постов выше не ясно что в $item.
Если в $item обьект JCategoryNode то просто передать.
Код: php
<a href="<?php echo JRoute::_(ContentHelperRoute::getCategoryRoute($item)); ?>">
Если нет то создать
Код: php
<?php
$node = new JCategoryNode($item);
?>
<a href="<?php echo JRoute::_(ContentHelperRoute::getCategoryRoute($node)); ?>">
Во втором случае есть риск что не создастся (дальше в исходники не полез ибо неизвестно что в $item) или получить Class not found JCategoryNode, тогда подключить.
Не решение, но направление действий.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
var_dump($item);
Код
class JCategoryNode#807 (40) { public $id => string(3) "151" public $asset_id => string(5) "16002" public $parent_id => string(3) "144" public $lft => string(3)..........................................

Код: php
<a href="<?php echo JRoute::_(ContentHelperRoute::getCategoryRoute($item)); ?>">
так я тоже пробовал, запросы остаются (

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Немного в сторону от темы, но по теме...
Чистая J! 3.4.8 Вот знаете что ещё напрягает ?! Везде где нашёл в настройках, указал "Не отображать метки" !
Почему же тогда в блоге категории(отображается 30 материалов) J подтягивает 30 лишних запросов MySQL, прошу заметить, отключенных в настройках.
Код: sql
SELECT `m`.`tag_id`,`t`.*

  FROM `j_contentitem_tag_map` AS m

  INNER JOIN `j_tags` AS t 
  ON `m`.`tag_id` = `t`.`id`

  WHERE `m`.`type_alias` = 'com_content.article'
  AND `m`.`content_item_id` = 27924
  AND `t`.`published` = 1
  AND t.access IN (1,1,2,3,6)
Ведь явно отключено отображение меток ! Не особо вериться в прямоту рук кодеров J !

*

b2z

  • Support Team
  • *****
  • 7452
  • 741
  • Разраблю понемногу
Немного в сторону от темы, но по теме...
Чистая J! 3.4.8 Вот знаете что ещё напрягает ?! Везде где нашёл в настройках, указал "Не отображать метки" !
Почему же тогда в блоге категории(отображается 30 материалов) J подтягивает 30 лишних запросов MySQL, прошу заметить, отключенных в настройках.
Код: sql
SELECT `m`.`tag_id`,`t`.*

  FROM `j_contentitem_tag_map` AS m

  INNER JOIN `j_tags` AS t  
  ON `m`.`tag_id` = `t`.`id`

  WHERE `m`.`type_alias` = 'com_content.article'
  AND `m`.`content_item_id` = 27924
  AND `t`.`published` = 1
  AND t.access IN (1,1,2,3,6)
Ведь явно отключено отображение меток ! Не особо вериться в прямоту рук кодеров J !
Всё просто - сделайте Pull Request и исправьте эту "прямоту" рук ;)

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
Всё просто - сделайте Pull Request и исправьте эту "прямоту" рук ;)
b2z, ну сам посуди, разве это не бред ?!
Что сделать Pull Request, надо перепилить половину папки libraries ! Просто надо было задаваться вопросом производительность в начале писанины тех же меток ! Я, как не пользующийся метками сделал проще...
Код: php
	public function getItemTags($contentType, $id, $getTagData = true)
{
return false;
.....................................
Но это выход только в моём случае...
А потом ещё удивляються, почему хостинги блокируют сайты с J, предлагая взять сервер или более дорогой тариф.

*

b2z

  • Support Team
  • *****
  • 7452
  • 741
  • Разраблю понемногу
А причём тут libraries? getItemTags скорее всего вызывается в парочке встроенных компонентов и всё, а может даже только в com_content и связанных с ним модулях.

*

Wertos

  • Завсегдатай
  • *****
  • 505
  • 21
А причём тут libraries? getItemTags скорее всего вызывается в парочке встроенных компонентов и всё, а может даже только в com_content и связанных с ним модулях.
Сделал так
/component/com_content/views/article/view.html.php
Код: php
Заменил это
$item->tags = new JHelperTags;
$item->tags->getItemTags('com_content.article', $this->item->id);

На это
if($this->params->get('show_tags')!== "0")
{
$item->tags = new JHelperTags;
$item->tags->getItemTags('com_content.article', $this->item->id);
}

/component/com_content/models/article.php
Код: php
Заменил это
// Get the tags
$item->tags = new JHelperTags;
$item->tags->getItemTags('com_content.article', $item->id);
На это
// Get the tags
if($item->params->get('show_cat_tags')!== "0")
{
$item->tags = new JHelperTags;
$item->tags->getItemTags('com_content.article', $item->id);
}
Это решает проблему, метки отображаются только когда включены в настройках, соответственно запросов лишних тоже нет. Но блин это же до первого обновления (((