Всем привет.
Кто пользуется сильно тегами Zoo - просьба протестировать данных хак Zoo.
Предыстория: теги Zoo просто дико сделаны, если коротко - чем больше айтемов/тегов - тем больше памяти будет сжирать сайт. У меня начались проблемы с 7-10к айтемов на тег (съедало > 256 мб), решалось повышением памяти - но это заплатка, а не решение проблемы. Проанализировал проблему и вроде сделал верное решение:
До оптимизации (7к айтемов на 1 тег) - Zoo теги: 225 MB

После оптимизации: 19.23 MB

В файле: item.php мы изменяем функцию: getByTag и добавляем также еще новую: getByTagCountAll
/administrator/components/com_zoo/tables/item.php
public function getByTag($application_id, $tag, $published = false, $user = null, $orderby = "", $offset = 0, $limit = 0, $ignore_order_priority = false, $limitStart, $items_per_page) {
// var_dump($limitStart);
// var_dump($items_per_page);
// get database
$db = $this->database;
// get dates
$date = $this->app->date->create();
$now = $db->Quote($date->toSQL());
$null = $db->Quote($db->getNullDate());
// get item ordering
list($join, $order) = $this->_getItemOrder($orderby, $ignore_order_priority);
$query = "SELECT a.id"
." FROM ".$this->name." AS a "
." LEFT JOIN ".ZOO_TABLE_TAG." AS b ON a.id = b.item_id"
.($join ? $join : "")
." WHERE a.application_id = ".(int) $application_id
." AND b.name = '".$db->escape($tag)."'"
." AND a.".$this->app->user->getDBAccessString($user)
.($published == true ? " AND a.state = 1"
." AND (a.publish_up = ".$null." OR a.publish_up <= ".$now.")"
." AND (a.publish_down = ".$null." OR a.publish_down >= ".$now.")": "")
." GROUP BY a.id"
." ORDER BY a.id DESC"; // perfomance huge hack
// ." LIMIT ".$items_per_page; // perfomance huge hack
// .($order ? " ORDER BY " . $order : "")
// .($limit ? " LIMIT ".(int) $offset.",".(int) $limit : "");
$list = $this->app->database->queryAssocList($query);
$itemOrig = array_reduce($list, function($acc, $item){
$acc[] = $item['id'];
return $acc;
}, []);
$itemOrig = array_slice($itemOrig, $limitStart, $items_per_page);
// $list = JBModelItem::model()->getZooItemsByIds($itemOrigOpt);
// $list = $this->app->jbarray->sortByArray($list, $itemOrigOpt);
$list = JBModelItem::model()->getZooItemsByIds($itemOrig);
$list = $this->app->jbarray->sortByArray($list, $itemOrig);
return $list;
}
public function getByTagCountAll($application_id, $tag, $published = false, $user = null, $orderby = "", $offset = 0, $limit = 0, $ignore_order_priority = false) {
// get database
$db = $this->database;
// get dates
$date = $this->app->date->create();
$now = $db->Quote($date->toSQL());
$null = $db->Quote($db->getNullDate());
// get item ordering
list($join, $order) = $this->_getItemOrder($orderby, $ignore_order_priority);
$query = "SELECT a.id"
." FROM ".$this->name." AS a "
." LEFT JOIN ".ZOO_TABLE_TAG." AS b ON a.id = b.item_id"
.($join ? $join : "")
." WHERE a.application_id = ".(int) $application_id
." AND b.name = '".$db->escape($tag)."'"
." AND a.".$this->app->user->getDBAccessString($user)
.($published == true ? " AND a.state = 1"
." AND (a.publish_up = ".$null." OR a.publish_up <= ".$now.")"
." AND (a.publish_down = ".$null." OR a.publish_down >= ".$now.")": "")
." GROUP BY a.id"
." ORDER BY a.id DESC" // perfomance huge hack
// .($order ? " ORDER BY " . $order : "")
.($limit ? " LIMIT ".(int) $offset.",".(int) $limit : "");
$list = count($this->app->database->queryAssocList($query));
// $itemOrig = array_reduce($list, function($acc, $item){
// $acc[] = $item['id'];
// return $acc;
// }, []);
return $list;
}
В файле default.php мы правим глобальную функцию tag
/components/com_zoo/controllers/default.php
public function tag() {
// get request vars
$page = $this->app->request->getInt('page', 1);
$this->tag = $this->app->request->getString('tag', '');
// raise 404 if tag does not exist
if (!$this->app->table->tag->getAll($this->application->id, $this->tag)) {
return $this->app->error->raiseError(404, JText::_('Tag not found'));
}
// get params
$params = $this->application->getParams('site');
$items_per_page = $params->get('config.items_per_page', 15);
$this->item_order = $params->get('config.item_order');
$ignore_priority = $params->get('config.ignore_item_priority', false);
// get categories and items
$this->categories = $this->application->getCategoryTree(true);
// $this->items = $this->app->table->item->getByTag($this->application->id, $this->tag, true, null, $this->item_order, 0, 0, $ignore_priority);
$this->itemsCountAll = $this->app->table->item->getByTagCountAll($this->application->id, $this->tag, true, null, $this->item_order, 0, 0, $ignore_priority);
// get item pagination
$this->pagination = $this->app->pagination->create($this->itemsCountAll, $page, $items_per_page, 'page', 'app');
$this->pagination->setShowAll($items_per_page == 0);
$this->pagination_link = $this->app->route->tag($this->application->id, $this->tag);
// slice out items
if (!$this->pagination->getShowAll()) {
$this->items = $this->app->table->item->getByTag($this->application->id, $this->tag, true, null, $this->item_order, 0, 0, $ignore_priority, $this->pagination->limitStart(), $items_per_page);
}
else {
$this->items = $this->app->table->item->getByTag($this->application->id, $this->tag, true, null, $this->item_order, 0, 0, $ignore_priority, null, null);
}
// set alphaindex
if ($params->get('template.show_alpha_index')) {
$this->alpha_index = $this->_getAlphaindex();
}
// set metadata
$this->app->document->setTitle($this->app->zoo->buildPageTitle($this->tag));
// create pathway
$this->pathway->addItem(JText::_('Tags').': '.$this->tag, JRoute::_($this->app->route->tag($this->application->id, $this->tag)));
// get template and params
if (!$this->template = $this->application->getTemplate()) {
return $this->app->error->raiseError(500, JText::_('No template selected'));
}
$this->params = $params;
// set renderer
$this->renderer = $this->app->renderer->create('item')->addPath(array($this->app->path->path('component.site:'), $this->template->getPath()));
// display view
$this->getView('tag')->addTemplatePath($this->template->getPath())->setLayout('tag')->display();
}
Если объяснить по простому:

Вначале получаем просто кол-во, а далее уже прокидываем (!!!) offset и кол-во айтемов
Можно и переписать решение немного по другому, но не суть.
Прикрепляю файлы, но кроме этих правок там могут быть и другие.
item.php 26.94К
242 Количество загрузок:
default.php 22.55К
251 Количество загрузок:















