Example #1
0
 /**
  * @function update - îáíàâëåíèå çàïèñè â òàáëèöå 
  * 
  * @param $data - ìàññèâ äàííûõ
  * 
  * @param $where - óñëîâèÿ ïî êîòîðûì îáíîâëÿòü çàïèñè 
  * 
  */
 public function update($data, $where = null, $setModTime = true)
 {
     $set = array();
     if (count($data)) {
         foreach ($data as $key => $value) {
             // ïðîâåðêà íà íóë, òåïåðü ìîæíî óñòàíàâëèâàòü çíà÷åíèå null â áàçó
             $v = is_null($value) ? 'null' : K_Db_Quote::quote($value);
             $set[] = K_Db_Quote::quoteKey($key) . ' = ' . $v;
         }
     }
     $whereString = '1=1';
     if (!empty($where)) {
         if ($where instanceof K_Db_Select) {
             $whereString = $where->where;
         } elseif (is_array($where)) {
             $select = K_Db_Select::create();
             $whereString = $select->_where(array($where));
         } elseif (is_string($where)) {
             $whereString = $where;
         }
     }
     $sql = 'UPDATE ' . $this->name . ' SET ' . implode(',', $set) . ' WHERE ' . $whereString;
     $this->db->query($sql);
     if ($setModTime) {
         $this->db->_setLastDataChange($this->name);
     }
 }
Example #2
0
 /**
  * Перемещает элемент в новое место дерева. Позиция определяется относительно опорного элемента
  *
  * @throws Exception
  * @param integer $key Ключ (ID или URL) перемещаемого элемента
  * @param integer $base_key Ключ (ID или URL) опорного элемента
  * @param string $position Положение относительно опорного элемента. Возможные значения: bottom, top, before, after
  * @return bool Произошло ли перемещение
  */
 public static function move($key, $base_key, $position = 'top')
 {
     $treeTable = new K_Tree_Model();
     // Получаем информацию о перемещаемом элементе
     $node = self::getNode($key);
     if ($node === FALSE) {
         throw new Exception('Перемещаемого элемента (' . $key . ') не существует');
     }
     if ($node['tree_level'] == 0) {
         throw new Exception('Невозможно переместить элемент нулевого уровня');
     }
     $node_diff = $node['tree_rkey'] - $node['tree_lkey'] + 1;
     // Получаем опорный элемент
     $base = self::getNode($base_key);
     if ($base === FALSE) {
         throw new Exception('Заданного опорного элемента (' . $base_key . ') не существует');
     }
     // Получаем родительский элемент
     $parent = self::_getPositionParent($base, $position);
     // Не пытаемся ли мы переместить элемент в один из вложенных?
     if ($node['tree_lkey'] < $parent['tree_lkey'] and $node['right_key'] > $parent['right_key']) {
         throw new Exception('Невозможно переместить элемент в один из вложенных');
     }
     // Новые значения элемента
     $move = array('tree_lkey' => self::_getPositionLeftKey($base, $parent, $position), 'tree_level' => $parent['tree_level'] + 1, 'tree_name' => $node['tree_name'], 'tree_pid' => $parent['tree_id']);
     if ($node['tree_pid'] == $parent['tree_id']) {
         // Смена порядка внутри одного родителя. Упрощенный алгоритм для ускорения операций
         if ($node['tree_lkey'] == $move['tree_lkey']) {
             // Элемент уже находится в нужной позиции
             return TRUE;
         }
         if ($move['tree_lkey'] > $node['tree_lkey']) {
             // Перемещаем элемент вперед. Все промежуточные сдвигаем назад
             $shift = $move['tree_lkey'] - 1 - $node['tree_rkey'];
             $treeTable->update(array('tree_rkey' => new K_Db_Expr('IF(`tree_lkey` < ' . (int) $node['tree_rkey'] . ', `tree_rkey` + ' . $shift . ', `tree_rkey` - ' . (int) $node_diff . ')'), 'tree_lkey' => new K_Db_Expr('IF(`tree_lkey` < ' . (int) $node['tree_rkey'] . ', `tree_lkey` + ' . $shift . ',  `tree_lkey` - ' . (int) $node_diff . ')')), '`tree_lkey` BETWEEN ' . (int) $node['tree_lkey'] . ' AND ' . ((int) $move['tree_lkey'] - 1));
         } else {
             // Перемещаем элемент назад. Все промежуточные сдвигаем вперед
             $shift = $node['tree_lkey'] - $move['tree_lkey'];
             $treeTable->update(array('tree_rkey' => new K_Db_Expr('IF(`tree_lkey` < ' . (int) $node['tree_lkey'] . ', `tree_rkey` + ' . (int) $node_diff . ', `tree_rkey` - ' . $shift . ')'), 'tree_lkey' => new K_Db_Expr('IF(`tree_lkey` < ' . (int) $node['tree_lkey'] . ', `tree_lkey` + ' . (int) $node_diff . ',  `tree_lkey` - ' . $shift . ')')), '`tree_lkey` BETWEEN ' . (int) $move['tree_lkey'] . ' AND ' . (int) $node['tree_rkey']);
         }
     } else {
         // Перемещение в другой родительский элемент. $move - место элемента, как если бы он вставлялся
         // Проверяем, чтобы URL не повторялся
         $name_occupied = $treeTable->select()->where('`tree_pid` = ' . (int) $parent['tree_id'] . ' AND `tree_name` = ' . K_Db_Quote::quoteKey($move['tree_name']))->fetchArray();
         // Если предлагаемое имя сегмента занято, используем свободное имя
         //var_dump($name_occupied);
         if (count($name_occupied)) {
             // $move['tree_name'] = self::get_available_name($parent['tree_id'], $move['tree_name']);
             $move['tree_name'] = "_" . base_convert(time() + rand(1, 999), 10, 36);
             $move['tree_title'] = "_K";
         }
         if ($move['tree_lkey'] > $node['tree_lkey']) {
             // Перемещаем вперед. Ориентируемся на правый ключ. Область перемещения: $node['tree_lkey'], $move['tree_rkey']
             $move['tree_lkey'] -= $node_diff;
             $move['tree_rkey'] = $move['tree_lkey'] + $node_diff - 1;
             $shift = $move['tree_rkey'] - $node['tree_rkey'];
             $treeTable->update(array('tree_lkey' => new K_Db_Expr('IF(`tree_lkey` < ' . (int) $node['tree_rkey'] . ', IF(`tree_lkey` < ' . (int) $node['tree_lkey'] . ', `tree_lkey`, `tree_lkey` + ' . $shift . '), `tree_lkey` - ' . (int) $node_diff . ')'), 'tree_rkey' => new K_Db_Expr('IF(`tree_rkey` <= ' . (int) $node['tree_rkey'] . ', `tree_rkey` + ' . $shift . ', IF(`tree_rkey` <= ' . (int) $move['tree_rkey'] . ', `tree_rkey` - ' . (int) $node_diff . ', `tree_rkey`))')), '`tree_lkey` BETWEEN ' . (int) $node['tree_lkey'] . ' AND ' . (int) $move['tree_rkey'] . ' OR `tree_rkey` BETWEEN ' . (int) $node['tree_lkey'] . ' AND ' . (int) $move['tree_rkey']);
         } else {
             // Перемещаем назад. Ориентируемся на левый ключ.
             $move['tree_rkey'] = $move['tree_lkey'] + $node_diff - 1;
             $shift = $node['tree_lkey'] - $move['tree_lkey'];
             $treeTable->update(array('tree_lkey' => new K_Db_Expr('IF(`tree_lkey` < ' . (int) $node['tree_lkey'] . ', IF(`tree_lkey` < ' . (int) $move['tree_lkey'] . ', `tree_lkey`, `tree_lkey` + ' . (int) $node_diff . '), `tree_lkey` - ' . $shift . ')'), 'tree_rkey' => new K_Db_Expr('IF(`tree_rkey` <= ' . (int) $node['tree_lkey'] . ', `tree_rkey` + ' . (int) $node_diff . ', IF(`tree_rkey` <= ' . (int) $node['tree_rkey'] . ', `tree_rkey` - ' . $shift . ', `tree_rkey`))')), '`tree_lkey` BETWEEN ' . (int) $move['tree_lkey'] . ' AND ' . (int) $node['tree_rkey'] . ' OR `tree_rkey` BETWEEN ' . (int) $move['tree_lkey'] . ' AND ' . (int) $node['tree_rkey']);
         }
         if ($move['tree_level'] != $node['tree_level']) {
             $level_shift = $node['tree_level'] - $move['tree_level'];
             $treeTable->update(array('tree_level' => new K_Db_Expr('`tree_level` - (' . $level_shift . ')')), '`tree_lkey` BETWEEN ' . (int) $move['tree_lkey'] . ' AND ' . (int) $move['tree_rkey']);
         }
         $treeTable->update($move, '`tree_id`=' . $node['tree_id']);
         $move = array_merge($node, $move);
         self::_fixUrls($move, $parent['tree_link']);
     }
     return true;
 }
Example #3
0
 /**
  * Generate SQL select query
  */
 public function sql()
 {
     $sql = 'SELECT ';
     if (!empty($this->fields)) {
         $sql .= $this->fields;
     } else {
         $sql .= '*';
     }
     if (empty($this->table)) {
         throw 'K_Db_Select: table name is empty';
     }
     if (count($this->table)) {
         $joinsSql = '';
         $currentTables = $this->table;
         $this->buildMultiJoins();
         if (count($this->joins)) {
             $this->buildJoins();
             $currentTables = array_merge($this->table, $this->joinTables);
         }
         foreach ($currentTables as &$tableInfo) {
             if ($tableInfo['type'] == 'table') {
                 $joinsSql .= (!empty($joinsSql) ? ',' : '') . $tableInfo['sql'];
             } elseif ($tableInfo['type'] == 'join') {
                 $joinsSql = '(' . $joinsSql . ')' . $tableInfo['sql'];
             } elseif ($tableInfo['type'] == 'select') {
                 $joinsSql .= (!empty($joinsSql) ? ',' : '') . '(' . $tableInfo['sql'] . ')' . (!empty($tableInfo['name']) ? ' as ' . K_Db_Quote::quoteKey($tableInfo['name']) : '');
             }
         }
         $sql .= ' FROM ' . $joinsSql;
     }
     if (!empty($this->where)) {
         $sql .= ' WHERE ' . $this->where;
     }
     if (!empty($this->group)) {
         $sql .= ' GROUP BY ' . $this->group;
     }
     if (!empty($this->having)) {
         $sql .= ' HAVING ' . $this->having;
     }
     if (!empty($this->order)) {
         $sql .= ' ORDER BY ' . $this->order;
     }
     if (!empty($this->limit)) {
         $sql .= ' LIMIT ' . $this->limit;
     }
     if (!empty($this->offset)) {
         $sql .= ' OFFSET ' . $this->offset;
     }
     return $sql . '';
 }