protected bool
recursiveUpdatePublishedColumn
(mixed $pk, mixed $newState = null)
/**
* Method to recursive update published column for children rows.
*
* @param integer $pk Id number of row which published column was changed.
* @param integer $newState An optional value for published column of row identified by $pk.
*
* @return boolean True on success.
*
* @since 3.7.0
* @throws \RuntimeException on database error.
*/
protected function recursiveUpdatePublishedColumn($pk, $newState = null)
{
$query = $this->_db->getQuery(true);
$table = $this->_db->quoteName($this->_tbl);
$key = $this->_db->quoteName($this->_tbl_key);
$published = $this->_db->quoteName($this->getColumnAlias('published'));
if ($newState !== null) {
// Use a new published state in changed row.
$newState = "(CASE WHEN p2.{$key} = " . (int) $pk . " THEN " . (int) $newState . " ELSE p2.{$published} END)";
} else {
$newState = "p2.{$published}";
}
/**
* We have to calculate the correct value for c2.published
* based on p2.published and own c2.published column,
* where (p2) is parent category is and (c2) current category
*
* p2.published <= c2.published AND p2.published > 0 THEN c2.published
* 2 <= 2 THEN 2 (If archived in archived then archived)
* 1 <= 2 THEN 2 (If archived in published then archived)
* 1 <= 1 THEN 1 (If published in published then published)
*
* p2.published > c2.published AND c2.published > 0 THEN p2.published
* 2 > 1 THEN 2 (If published in archived then archived)
*
* p2.published > c2.published THEN c2.published ELSE p2.published
* 2 > -2 THEN -2 (If trashed in archived then trashed)
* 2 > 0 THEN 0 (If unpublished in archived then unpublished)
* 1 > 0 THEN 0 (If unpublished in published then unpublished)
* 0 > -2 THEN -2 (If trashed in unpublished then trashed)
* ELSE
* 0 <= 2 THEN 0 (If archived in unpublished then unpublished)
* 0 <= 1 THEN 0 (If published in unpublished then unpublished)
* 0 <= 0 THEN 0 (If unpublished in unpublished then unpublished)
* -2 <= -2 THEN -2 (If trashed in trashed then trashed)
* -2 <= 0 THEN -2 (If unpublished in trashed then trashed)
* -2 <= 1 THEN -2 (If published in trashed then trashed)
* -2 <= 2 THEN -2 (If archived in trashed then trashed)
*/
// Find node and all children keys
$query->select("c.{$key}")->from("{$table} AS node")->leftJoin("{$table} AS c ON node.lft <= c.lft AND c.rgt <= node.rgt")->where("node.{$key} = " . (int) $pk);
$pks = $this->_db->setQuery($query)->loadColumn();
// Prepare a list of correct published states.
$subquery = (string) $query->clear()->select("c2.{$key} AS newId")->select("CASE WHEN MIN({$newState}) > 0 THEN MAX({$newState}) ELSE MIN({$newState}) END AS newPublished")->from("{$table} AS c2")->innerJoin("{$table} AS p2 ON p2.lft <= c2.lft AND c2.rgt <= p2.rgt")->where("c2.{$key} IN (" . implode(',', $pks) . ")")->group("c2.{$key}");
// Update and cascade the publishing state.
$query->clear()->update($table)->innerJoin("({$subquery}) AS c2")->set("{$published} = " . $this->_db->quoteName("c2.newpublished"))->where("{$key} = c2.newId")->where("{$key} IN (" . implode(',', $pks) . ")");
$this->_runQuery($query, 'JLIB_DATABASE_ERROR_STORE_FAILED');
return true;
}