_parentIdField) && array_key_exists($this->_parentIdField, $this->_cols) && !empty($this->_nameField) && array_key_exists($this->_nameField, $this->_cols)) { return true; } return false; } public function getParentIdField() { return $this->_parentIdField; } public function setParentIdField($parentIdField) { if (array_key_exists($parentIdField, $this->_cols)) { $this->_parentIdField = $parentIdField; return true; } return false; } public function setSortField($sortFld) { if (array_key_exists($sortFld, $this->_cols)) { $this->_sortField = $sortFld; return true; } return false; } public function hasSortField() { return !empty($this->_sortField); } public function getNameField() { return $this->_nameField; } public function setNameField($nameField) { if (array_key_exists($nameField, $this->_cols)) { $this->_nameField = $nameField; return true; } return false; } private function _parseSqlWhere($params) { $sql_where = ''; $sql_where_and = array(); foreach ($params as $k => $v) { if ($k == '_rawSql') { foreach ($v as $rawSql) { $sql_where_and[] = $rawSql; } } else if (strlen($k) > 3 && substr($k, 0, 2) == 'f_') { $sql_where_and[] = "t.`" . substr($k, 2) . "` like '" . DB::_($v) . "'"; } else if (strlen($k) > 4 && substr($k, 0, 3) == 'sf_') { $sqlFltr = $this->_parseSpecialFilter(substr($k, 3), $v); if (!empty($sqlFltr)) { $sql_where_and[] = $sqlFltr; } } } if (!empty($sql_where_and)) { $sql_where = implode(" and ", $sql_where_and); } if (!$sql_where) $sql_where = "1=1"; return $sql_where; } public function getTreeNodes($parentID, $params = array()) { $DBG = ('1' == V::get('DBG_DS', '', $_REQUEST)); $nodes = array(); if (!$this->isValidTree()) return $nodes; $params['_rawSql'][] = "t.`{$this->_parentIdField}` = {$parentID}"; //$sql_limit = V::get('limit', $this->_default_sql_limit, $params, 'int'); //$sql_offset = V::get('limitstart', 0, $params, 'int'); $sql_order_by = V::get('order_by', '', $params); if ($sql_order_by) { $sql_order_dir = V::get('order_dir', '', $params); // prevent from sorting by special columns if (!array_key_exists($sql_order_by, $this->_cols)) { $sql_order_by = null; $sql_order_dir = null; } } if ($sql_order_by) { $sql_order_by = "order by t.`{$sql_order_by}`"; if ($sql_order_dir) { $sql_order_by = "{$sql_order_by} {$sql_order_dir}"; } } $sql_cols = $this->_get_sql_cols(); $sql_where = $this->_parseSqlWhere($params); $sql = "select {$sql_cols} from {$this->_tbl} as t where {$sql_where} {$sql_order_by} "; // limit {$sql_limit} offset {$sql_offset} if($DBG){echo'
sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'';}
$res = $this->_db->query($sql);
while ($r = $this->_db->fetch($res)) {
$node = new stdClass();
$node->id = $r->ID;
$node->parent_id = (int)$r->{$this->_parentIdField};
$node->type = 'folder';
$node->data = $r;
$node->name = $r->{$this->_nameField};
$nodes[$r->ID] = $node;
}
return $nodes;
}
public function getTreeNode($id, $params = array()) {
$DBG = ('1' == V::get('DBG_DS', '', $_REQUEST));
if (!$this->isValidTree()) return null;
$params['_rawSql'][] = "t.`ID`={$id}";
$sql_cols = $this->_get_sql_cols();
$sql_where = $this->_parseSqlWhere($params);
$sql = "select {$sql_cols}
from {$this->_tbl} as t
where {$sql_where}
limit 1
";
if($DBG){echo'sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'';}
$res = $this->_db->query($sql);
if ($r = $this->_db->fetch($res)) {
$node = new stdClass();
$node->id = $r->ID;
$node->parent_id = (int)$r->{$this->_parentIdField};
$node->type = 'folder';
$node->data = $r;
$node->name = $r->{$this->_nameField};
return $node;
}
return null;
}
private function _isOnPathRec($id, $nodeId, $limit = 10) {
//trigger_error('TODO: _isOnPathRec('.$id.', '.$nodeId.', '.$limit.')', E_USER_NOTICE);
$sql = "select t.`ID`, t.`{$this->_parentIdField}`
from `{$this->_tbl}` as t
where t.`ID`={$nodeId}
";
$res = $this->_db->query($sql);
if ($r = $this->_db->fetch($res)) {
$p_id = (int)$r->{$this->_parentIdField};
if ($p_id > 0) {
if ($p_id == $id) {
//trigger_error('TODO: return true '.$id.' == '.$p_id.'', E_USER_NOTICE);
return true;
}
if ($limit--) {
return $this->_isOnPathRec($id, $p_id, $limit);
}
}
}
return false;
}
/**
* Check if $id is on path between root to $nodeId
*/
public function isOnPath($id, $nodeId) {
//trigger_error('TODO: isOnPath('.$id.', '.$nodeId.')', E_USER_NOTICE);
return $this->_isOnPathRec($id, $nodeId);
}
/**
* Try to move $id under $p_id
*
* $p_id cant be under $id - check path
*/
public function moveTreeNode($id, $p_id) {
$DBG = ('1' == V::get('DBG_DS', '', $_REQUEST));
if (!$this->isValidTree()) return false;
if ($p_id == $id) return false;
$node = $this->_db->get_by_id($this->_tbl, $id);
if (!$node) return false;
if ($p_id == (int)$node->P_ID) return false;
if ($this->isOnPath($id, $p_id)) return false;
$sqlObj = new stdClass();
$sqlObj->ID = $id;
$sqlObj->{$this->_parentIdField} = $p_id;
$affected = $this->_db->UPDATE_OBJ($this->_tbl, $sqlObj);
if ($this->_db->has_errors()) {
return false;
}
return ($affected > 0);
}
/**
* Change order - put $id before $p_id
*/
public function moveTreeNodeSort($id, $destId, $destDir) {
if ($id < 0 || $destId < 0 || $id == $destId) return false;
if (!$this->_sortField) return false;
if (!$this->isValidTree()) return false;
$DBG = ('1' == V::get('DBG_DS', '', $_REQUEST));
$node = $this->_db->get_by_id($this->_tbl, $id);
$destItem = $this->_db->get_by_id($this->_tbl, $destId);
if (!$node || !$destItem) return false;
if ($node->{$this->_parentIdField} < 0 || $node->{$this->_parentIdField} != $destItem->{$this->_parentIdField}) return false;
$rows = array();
// $sql->order_by = "order by t.`SORT_PRIO` asc, t.`ID` asc";
$sql = "select t.`ID`, t.`{$this->_parentIdField}`, t.`{$this->_sortField}`
from `{$this->_tbl}` as t
where t.`{$this->_parentIdField}`='{$node->{$this->_parentIdField}}'
order by t.`{$this->_sortField}`
";
if($DBG){echo'sql (dir:'.$destDir.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'';}
$res = $this->_db->query($sql);
while ($r = $this->_db->fetch($res)) {
if ($r->ID == $node->ID) continue;
$rows[$r->ID] = $r->{$this->_sortField};
}
if($DBG){echo'rows (dir:'.$destDir.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($rows);echo'';}
$foundDestId = false;
$prevSortPrio = 0;
$changeArr = array();
foreach ($rows as $id => $sortPrio) {
if (!$foundDestId && $id == $destId) {
$foundDestId = true;
if ($destDir == 'before') {
$prevSortPrio = $sortPrio;
$changeArr[$node->ID] = $prevSortPrio;
$prevSortPrio++;
$changeArr[$id] = $prevSortPrio;
}
else if ($destDir == 'after') {
$prevSortPrio = $sortPrio;
$prevSortPrio++;
$changeArr[$node->ID] = $prevSortPrio;
}
}
else if ($foundDestId) {
$prevSortPrio++;
if ($prevSortPrio > $sortPrio) {
$changeArr[$id] = $prevSortPrio;
} else {
$prevSortPrio = $sortPrio;
}
}
}
if($DBG){echo'changeArr (dir:'.$destDir.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($changeArr);echo'';}
if (!empty($changeArr)) {
foreach ($changeArr as $id => $sortPrio) {
$sqlObj = new stdClass();
$sqlObj->ID = $id;
$sqlObj->{$this->_sortField} = $sortPrio;
$affected = $this->_db->UPDATE_OBJ($this->_tbl, $sqlObj);
}
}
return true;
}
public function moveTreeNodeSortBefore($id, $beforeId) {
return $this->moveTreeNodeSort($id, $beforeId, 'after');
}
/**
* Change order - put $id after $p_id
*/
public function moveTreeNodeSortAfter($id, $afterId) {
return $this->moveTreeNodeSort($id, $afterId, 'before');
}
}