Форум русской поддержки Joomla!® CMS
11.12.2016, 17:53:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
   
   Начало   Поиск Joomla 3.0 FAQ Joomla 2.5 FAQ Joomla 1.5 FAQ Правила форума Новости Joomla Реклама Войти Регистрация Помощь  
Страниц: [1]   Вниз
  Добавить закладку  |  Печать  
Автор

Ошибка в классе JTableAsset (предложения по решению)

 (Прочитано 164 раз)
0 Пользователей и 1 Гость смотрят эту тему.
nvyush
Новичок
*

Репутация: +0/-0
Offline Offline

Сообщений: 8


« : 17.11.2015, 13:00:52 »

Сообщение напрашивается в раздел "Баги Joomla", но создавать там темы у меня прав нет.
Недавно понадобилось импортировать большой объём данных (категорий и материалов) из другой системы в Joomla! 3.4.5.
Сгенерировать нужные значения для полей `parent_id` и `level` таблиц `#__assets` и `#__categories` труда не составило, а для полей `lft` и `rgt` установил -1 в надежде после импорта перестроить штатными средствами Joomla.
Для таблицы категорий такой инструмент имеется (кнопка "Перестроить" в менеджере категорий), а вот для таблицы `#__assets` пришлось написать свой модуль (бесплатного в сети не нашёл, да и платного тоже). В ходе написания обнаружил, что класс JTableAsset наследуется от класса JTableNested, в котором есть "магический" метод rebuild, который собственно и делает то, что мне нужно. Но в этом методе также перестраиваются пути (поле `path`) используя значения поля `alias`. Ни поля `alias`, ни поля `path` в таблице `#__assets` нет, соответственно, вызов метода rebuild для объекта класса JTableAsset вызывает ошибку.
Для решения данной проблемы написал класс JTableAssetRebuild, наследующий от JTableAsset и переопределяющий метод rebuild. Правильней конечно было бы либо переопределить указанный метод непосредственно в классе JTableAsset, либо переписать всю иерархию классов в части JTableNested и JTableAsset, например, добавить в иерархию класс перед JTableNested с "правильным" rebuild (и другими полями/методами) и наследовать JTableAsset уже от него. [upd] Либо в классе JTableNested имеющийся rebuild переименовать, например, в _rebuildWithAlias и сделать его protected, добавить protected метод _rebuildWithoutAlias с аналогичным кодом, но без обновления путей (код ниже), а также добавить вызывающий их public метод rebuild (код ниже)  [/upd]. Однако влезать в код ядра Joomla не хотел, чтобы не потерять изменения при обновлении. Если у кого-нибудь есть возможность сообщить о данной ошибке разработчикам Joomla!, прошу сделать это.

Вот собственно код метода ([upd]если добавлять его как protected в класс JTableNested, то переименовать в _rebuildWithoutAlias и не забыть про рекурсивный вызов [/upd]):
Код:
/**
* Method to recursively rebuild the whole nested set tree.
*
* @param   integer  $parentId  The root of the tree to rebuild.
* @param   integer  $leftId    The left id to start with in building the tree.
* @param   integer  $level     The level to assign to the current nodes.
*
* @return  integer  1 + value of root rgt on success, false on failure
*
* @throws  RuntimeException on database error.
*/
public function rebuild($parentId = null, $leftId = 0, $level = 0)
{
// If no parent is provided, try to find it.
if ($parentId === null)
{
// Get the root item.
$parentId = $this->getRootId();

if ($parentId === false)
{
return false;
}
}

$query = $this->_db->getQuery(true);

// Build the structure of the recursive query.
if (!isset($this->_cache['rebuild.sql']))
{
$query->clear()
->select($this->_tbl_key)
->from($this->_tbl)
->where('parent_id = %d')
->order('parent_id, lft');

$this->_cache['rebuild.sql'] = (string) $query;
}

// Make a shortcut to database object.

// Assemble the query to find all children of this node.
$this->_db->setQuery(sprintf($this->_cache['rebuild.sql'], (int) $parentId));

$children = $this->_db->loadObjectList();

// The right value of this node is the left value + 1
$rightId = $leftId + 1;

// Execute this function recursively over all children
foreach ($children as $node)
{
/*
* $rightId is the current right value, which is incremented on recursion return.
* Increment the level for the children.
*/
$rightId = $this->rebuild($node->{$this->_tbl_key}, $rightId, $level + 1); //в классе JTableNested заменить на _rebuildWithoutAlias !

// If there is an update failure, return false to break out of the recursion.
if ($rightId === false)
{
return false;
}
}

// We've got the left value, and now that we've processed
// the children of this node we also know the right value.
$query->clear()
->update($this->_tbl)
->set('lft = ' . (int) $leftId)
->set('rgt = ' . (int) $rightId)
->set('level = ' . (int) $level)
->where($this->_tbl_key . ' = ' . (int) $parentId);
$this->_db->setQuery($query)->execute();

// Return the right value of this node + 1.
return $rightId + 1;
}

/**
* код метода rebuild для класса JTableNested
*/
public function rebuild($parentId = null, $leftId = 0, $level = 0, $path = '') {
$fields = $this->getFields();

if (isset($fields['alias'])) {
return $this->_rebuildWithAlias($parentId, $leftId, $level, $path);
} else {
return $this->_rebuildWithoutAlias($parentId, $leftId, $level);
}
}




« Последнее редактирование: 17.11.2015, 17:03:31 от nvyush » Записан
Страниц: [1]   Вверх
  Добавить закладку  |  Печать  
 
Перейти в:  

Powered by SMF 1.1.21 | SMF © 2006, Simple Machines

Joomlaforum.ru is not affiliated with or endorsed by the Joomla! Project or Open Source Matters.
The Joomla! name and logo is used under a limited license granted by Open Source Matters
the trademark holder in the United States and other countries.

LiveInternet