1
0
Fork 0
cl-content-allocation/classes/class.content_allocation_tr...

558 Zeilen
18 KiB
PHP

<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* Stores and handles content allocation management
*
* Requirements:
* @con_php_req 5.0
*
*
* @package Contenido Backend plugins
* @version 0.10.1
* @author Marco Jahn
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
* @since file available since contenido release <= 4.6
*
* {@internal
* created unknown
* modified 2008-07-02, Frederic Schneider, add security fix
*
* $Id: class.content_allocation_tree.php 128 2019-07-03 11:58:28Z oldperl $:
* }}
*
*/
if (!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
/**
* Todo
* addslashes to all string db inserts
* check if default language exists if new entry is added (otherwise)
*/
class pApiTree {
/**
*
*/
var $db = null;
/**
*
*/
var $table = null;
/**
*
*/
var $lang = 1;
/**
*
*/
var $client = 1;
/**
*
*/
var $defaultLang = 1;
/**
*
*/
var $logger = null;
/**
*
*/
var $user = null;
/**
*
*/
var $treeStatus = array();
/**
*
*/
var $uuid = null;
/**
*
*/
var $_arrInFilters = array('urlencode', 'clHtmlSpecialChars', 'addslashes');
/**
*
*/
var $_arrOutFilters = array('stripslashes', 'htmldecode', 'urldecode');
public function __construct($uuid) {
global $db, $cfg, $lang, $client, $auth;
$this->db = new DB_ConLite;
$this->table = $cfg['tab'];
$this->lang = $lang;
$this->client = $client;
$this->bDebug = false;
$this->uuid = $uuid;
$this->user = new cApiUser($auth->auth["uid"]);
$this->loadTreeStatus();
}
/**
*
* @param mixed $parentId
* @param int $level
* @param boolean $bUseTreeStatus (if true use expand/collapsed status of the tree, otherwise not)
* @modified 27.10.2005 Willi Man
*/
function fetchTree($parentId = false, $level = 0, $bUseTreeStatus = true) {
// fetch current lang category
$sql = "SELECT
tree.idpica_alloc, tree.parentid, tree.sortorder
FROM
" . $this->table['pica_alloc'] . " as tree";
if ($parentId === false) { // fetch from root node
$sql .= " WHERE tree.parentid = '0'";
} else { // fetch by given id
$sql .= " WHERE tree.parentid = " . Contenido_Security::toInteger($parentId);
}
$sql .= " ORDER BY sortorder ASC";
$this->db->query($sql);
$result_tmp = array(); // tmp result array
while ($this->db->next_record()) { // walk resultset
$item = $this->_fetchItemNameLang($this->db->f('idpica_alloc'));
$itemStatus = 'expanded';
if ($bUseTreeStatus) { # modified 27.10.2005
if (is_array($this->treeStatus) && array_key_exists($this->db->f('idpica_alloc'), $this->treeStatus)) {
$itemStatus = 'collapsed';
}
}
$rs = array(
'idpica_alloc' => $this->db->f('idpica_alloc'),
'parentid' => ($this->db->f('parentid') == NULL) ? false : $this->db->f('parentid'),
'sortorder' => $this->db->f('sortorder'),
'name' => $this->_outFilter($item['name']),
'idlang' => $item['idlang'],
'level' => $level,
'status' => $itemStatus,
'online' => $item['online']
);
array_push($result_tmp, $rs); // append recordset
}
if (count($result_tmp) > 0) {
$result = array(); // result array
foreach ($result_tmp as $rs) { // run results
$children = $this->fetchTree($rs['idpica_alloc'], $level + 1, $bUseTreeStatus);
if ($children !== false && $rs['status'] == 'expanded') {
$rs['children'] = $children;
}
array_push($result, $rs);
}
return $result;
} else {
return false;
}
}
/**
* Fetch content allocation tree
* Consider offline/online status
*
* @created 21.11.2005 Willi Man
*
* @param mixed $parentId
* @param int $level
* @return array with content allocation id's
*/
function fetchTreeIds($parentId = false, $level = 0, $showOffline = false) {
// fetch current lang category
$sql = "SELECT
tree.idpica_alloc, tree.parentid, tree.sortorder
FROM
" . $this->table['pica_alloc'] . " as tree";
if ($parentId === false) { // fetch from root node
$sql .= " WHERE tree.parentid IS NULL";
} else { // fetch by given id
$sql .= " WHERE tree.parentid = " . Contenido_Security::toInteger($parentId);
}
$sql .= " ORDER BY sortorder ASC";
if ($this->bDebug) {
print "<!-- ";
print $sql;
print " -->";
}
$this->db->query($sql);
$result_tmp = array(); // tmp result array
while ($this->db->next_record()) { // walk resultset
$item = $this->_fetchItemNameLang($this->db->f('idpica_alloc'));
if ($this->bDebug) {
print "<!-- ";
print_r($item);
print " -->";
}
if ($showOffline OR $item['online'] == 1) {
$rs = array(
'idpica_alloc' => $this->db->f('idpica_alloc')
);
array_push($result_tmp, $rs); // append recordset
}
}
if (count($result_tmp) > 0) {
$result = array(); // result array
foreach ($result_tmp as $rs) { // run results
$children = $this->fetchTreeIds($rs['idpica_alloc'], $level + 1, $bUseTreeStatus);
if ($children !== false) {
$rs['children'] = $children;
}
array_push($result, $rs);
}
return $result;
} else {
return false;
}
}
function setTreeStatus($idpica_alloc) {
if (is_array($this->treeStatus) && array_key_exists($idpica_alloc, $this->treeStatus)) { // expand
unset($this->treeStatus[$idpica_alloc]);
} else { // collapse
$this->treeStatus[$idpica_alloc] = true;
}
$this->user->setProperty("expandstate", $this->_uuid, serialize($this->treeStatus));
}
function loadTreeStatus() {
$status = $this->user->getProperty("expandstate", $this->_uuid);
if ($status !== false) {
$this->treeStatus = unserialize($status);
}
}
function fetchParent($idpica_alloc) {
$sql = "SELECT idpica_alloc FROM " . $this->table['pica_alloc'] . " WHERE parentId = " . Contenido_Security::toInteger($idpica_alloc);
$this->db->query($sql);
if ($this->db->next_record()) {
return $this->fetchItem($this->db->f('idpica_alloc'));
} else {
return false;
}
}
function fetchParents() {
}
function fetchLevel($parentId = false, $showOffline = false) {
// fetch current lang category
$sql = "SELECT
tree.idpica_alloc, tree.parentid, tree.sortorder
FROM
" . $this->table['pica_alloc'] . " as tree
LEFT JOIN " . $this->table['pica_lang'] . " as treelang USING (idpica_alloc)";
if ($parentId === false) { // fetch from root node
$sql .= " WHERE tree.parentid IS NULL";
} else { // fetch by given id
$sql .= " WHERE tree.parentid = " . Contenido_Security::toInteger($parentId);
}
if ($showOffline === false) {
$sql .= " AND treelang.online = 1";
}
$sql .= " ORDER BY sortorder ASC";
$this->db->query($sql);
$result_tmp = array(); // tmp result array
while ($this->db->next_record()) { // walk resultset
$item = $this->_fetchItemNameLang($this->db->f('idpica_alloc'));
$itemStatus = 'expanded';
if (is_array($this->treeStatus) && array_key_exists($this->db->f('idpica_alloc'), $this->treeStatus)) {
$itemStatus = 'collapsed';
}
$rs = array(
'idpica_alloc' => $this->db->f('idpica_alloc'),
'parentid' => ($this->db->f('parentid') == NULL) ? false : $this->db->f('parentid'),
'sortorder' => $this->db->f('sortorder'),
'name' => $this->_outFilter($item['name']),
'idlang' => $item['idlang'],
'level' => 0,
'status' => $itemStatus,
'online' => $item['online']
);
array_push($result_tmp, $rs); // append recordset
}
return $result_tmp;
}
function storeItem($treeItem) {
if (!$treeItem['idpica_alloc']) { // insert
$treeItem['idpica_alloc'] = $this->db->nextid($this->table['pica_alloc']);
$treeItem['sortorder'] = $this->_fetchMaxOrder($treeItem['parentid']) + 1;
if ($treeItem['parentid'] == 'root') {
$treeItem['parentid'] = 'NULL';
}
$treeItem['name'] = $this->_inFilter($treeItem['name']);
$sql = "INSERT INTO " . $this->table['pica_alloc'] . "
(idpica_alloc, parentid, sortorder)
VALUES
(" . Contenido_Security::toInteger($treeItem['idpica_alloc']) . ", " . Contenido_Security::toInteger($treeItem['parentid']) . ", " . Contenido_Security::toInteger($treeItem['sortorder']) . ")";
$this->db->query($sql);
$sql = "INSERT INTO " . $this->table['pica_lang'] . "
(idpica_alloc, idlang, name)
VALUES
(" . Contenido_Security::toInteger($treeItem['idpica_alloc']) . ", " . Contenido_Security::toInteger($this->lang) . ", '" . Contenido_Security::escapeDB($treeItem['name'], $this->db) . "')";
$this->db->query($sql);
} else { // update
$treeItem['name'] = $this->_inFilter($treeItem['name']);
$sql = "SELECT * FROM " . $this->table['pica_lang'] . " WHERE idpica_alloc = " . Contenido_Security::toInteger($treeItem['idpica_alloc']) . " AND idlang = " . Contenido_Security::toInteger($this->lang);
$this->db->query($sql);
if ($this->db->num_rows() > 0) {
#Update existing translation
$sql = "UPDATE " . $this->table['pica_lang'] . " SET name = '" . Contenido_Security::escapeDB($treeItem['name'], $this->db) . "' WHERE idpica_alloc = " . Contenido_Security::toInteger($treeItem['idpica_alloc']) . "
AND idlang = " . Contenido_Security::toInteger($this->lang);
} else {
#Get current online status for item
$sql = "SELECT * FROM " . $this->table['pica_lang'] . " WHERE idpica_alloc = " . $treeItem['idpica_alloc'] . " ORDER BY idlang";
$this->db->query($sql);
if ($this->db->next_record()) {
$online_status = $this->db->f('online');
} else {
$online_status = 0;
}
#Insert new translation
$sql = "INSERT INTO " . $this->table['pica_lang'] . "(idpica_alloc, idlang, name, online) VALUES ( " . Contenido_Security::toInteger($treeItem['idpica_alloc']) . ", " . Contenido_Security::toInteger($this->lang) . ",
'" . Contenido_Security::escapeDB($treeItem['name'], $this->db) . "', " . Contenido_Security::toInteger($online_status) . ")";
}
$this->db->query($sql);
}
return $treeItem;
}
function setOnline($idpica_alloc) {
$this->_switchOnOffline($idpica_alloc, 1);
}
function setOffline($idpica_alloc) {
$this->_switchOnOffline($idpica_alloc, 0);
}
function _switchOnOffline($idpica_alloc, $status) {
$sql = "UPDATE " . $this->table['pica_lang'] . " SET online = " . Contenido_Security::toInteger($status) . " WHERE idpica_alloc = " . Contenido_Security::toInteger($idpica_alloc) . "
AND idlang = " . Contenido_Security::toInteger($this->lang);
$this->db->query($sql);
}
function itemMoveUp($idpica_alloc) {
$treeItem = $this->fetchItem($idpica_alloc);
$treeItem_old = $treeItem;
$treeItem['sortorder'] --;
if ($treeItem['sortorder'] < $treeItem_old['sortorder']) {
if ($treeItem['sortorder'] >= 1) {
$this->_decreaseOrder($treeItem['parentid'], $treeItem_old['sortorder']);
$this->_increaseOrder($treeItem['parentid'], $treeItem['sortorder']);
} else {
$treeItem['sortorder'] = $treeItem_old['sortorder'];
}
}
$sql = "UPDATE " . $this->table['pica_alloc'] . " SET sortorder = " . $treeItem['sortorder'] . " WHERE idpica_alloc = " . Contenido_Security::toInteger($idpica_alloc);
$this->db->query($sql);
}
function itemMoveDown() {
}
function deleteItem($idpica_alloc) {
$sql = "DELETE FROM " . $this->table['pica_alloc'] . " WHERE idpica_alloc = " . Contenido_Security::toInteger($idpica_alloc);
$this->db->query($sql);
$sql = "DELETE FROM " . $this->table['pica_lang'] . " WHERE idpica_alloc = " . Contenido_Security::toInteger($idpica_alloc);
$this->db->query($sql);
$sql = "DELETE FROM " . $this->table['pica_alloc_con'] . " WHERE idpica_alloc = " . Contenido_Security::toInteger($idpica_alloc);
$this->db->query($sql);
}
function fetchItem($idpica_alloc) {
$sql = "SELECT parentid, sortorder FROM " . $this->table['pica_alloc'] . " WHERE idpica_alloc = " . $idpica_alloc;
$this->db->query($sql);
$item = $this->_fetchItemNameLang($idpica_alloc);
if ($this->db->next_record()) {
$row = array(
'idpica_alloc' => $idpica_alloc,
'parentid' => ($this->db->f('parentid') == NULL) ? false : $this->db->f('parentid'),
'sortorder' => $this->db->f('sortorder'),
'name' => $item['name'],
'idlang' => $item['idlang'],
'online' => $item['online']
);
return $row;
} else {
return false;
}
}
function _fetchItemNameLang($idpica_alloc) {
$oDB = new DB_ConLite; // temp instance
$sSQL = "SELECT name, idlang, online FROM " . $this->table['pica_lang'] . " WHERE idpica_alloc = " . Contenido_Security::toInteger($idpica_alloc) . " AND idlang = " . Contenido_Security::toInteger($this->lang);
$oDB->query($sSQL);
$aResult = array();
if ($oDB->next_record()) { // item found for this language
$aResult['name'] = $this->_outFilter($oDB->f('name'));
$aResult['idlang'] = $oDB->f('idlang');
$aResult['online'] = $oDB->f('online');
} else { // no item in this language found
// fetch alternative language name
// HerrB, 2008-04-21: Get all translations, try to use defaultLang translation, use
// first available, otherwise. Only using defaultLang results in "ghost" elements, if
// created in a non-default language. See CON-110 for details.
$sSQL = "SELECT name, idlang, online FROM " . $this->table['pica_lang'] . " WHERE idpica_alloc = " . Contenido_Security::toInteger($idpica_alloc) . " ORDER BY idlang";
$oDB->query($sSQL);
$aNames = array();
while ($oDB->next_record()) {
$sKey = "k" . $oDB->f('idlang');
$aNames[$sKey] = array();
$aNames[$sKey]['name'] = $this->_outFilter($oDB->f('name'));
$aNames[$sKey]['idlang'] = $oDB->f('idlang');
$aNames[$sKey]['online'] = $oDB->f('online');
}
if ($aNames["k" . $this->defaultLang]) {
// defaultLang translation available
$aResult = $aNames["k" . $this->defaultLang];
} else {
// no defaultLang translation available, use first in line (reset returns first element)
$aResult = reset($aNames);
}
}
unset($oDB);
unset($aNames);
return $aResult;
}
function _fetchMaxOrder($parentId = false) {
if ($parentId == 'root') {
$parentId = false;
}
$sql = "SELECT MAX(sortorder) as max FROM " . $this->table['pica_alloc'];
if ($parentId === false) {
$sql .= " WHERE parentid = 0";
} else {
$sql .= " WHERE parentid = " . Contenido_Security::toInteger($parentId);
}
$this->db->query($sql);
if ($this->db->next_record()) {
return $this->db->f('max');
} else {
return 0;
}
}
function _decreaseOrder($parentId = false, $fromOrder) {
$sql = "UPDATE " . $this->table['pica_alloc'] . " SET sortorder = sortorder - 1 WHERE sortorder >= " . Contenido_Security::toInteger($fromOrder);
if ($parentId === false) {
$sql .= " AND parentid IS NULL";
} else {
$sql .= " AND parentid = " . Contenido_Security::toInteger($parentId);
}
$this->db->query($sql);
}
function _increaseOrder($parentId = false, $fromOrder) {
$sql = "UPDATE " . $this->table['pica_alloc'] . " SET sortorder = sortorder + 1 WHERE sortorder >= " . Contenido_Security::toInteger($fromOrder);
if ($parentId === false) {
$sql .= " AND parentid IS NULL";
} else {
$sql .= " AND parentid = " . Contenido_Security::toInteger($parentId);
}
$this->db->query($sql);
}
function setFilters($arrInFilters = array(), $arrOutFilters = array()) {
$this->_arrInFilters = $arrInFilters;
$this->_arrOutFilters = $arrOutFilters;
}
function _inFilter($data) {
foreach ($this->_arrInFilters as $_function) {
if (function_exists($_function)) {
$data = $_function($data);
}
}
return $data;
}
function _outFilter($data) {
foreach ($this->_arrOutFilters as $_function) {
if (function_exists($_function)) {
$data = $_function($data);
}
}
return $data;
}
}
?>