diff options
author | Bharat Mediratta <bharat@menalto.com> | 2008-11-04 21:24:42 +0000 |
---|---|---|
committer | Bharat Mediratta <bharat@menalto.com> | 2008-11-04 21:24:42 +0000 |
commit | 605d2de336eac8c8f80b916d30989b347d813e94 (patch) | |
tree | 1e33c92d4b3eedd9f4b3c31e21e11a9f36bcd8b2 /core/libraries | |
parent | ade1650846605d648da2565994e309414d908ac5 (diff) |
Lots of new stuff!
Replace theme HTML with *almost* the latest stuff from the
mockups. (it doesn't include r18467 yet).
Our theme format is now modelled after WordPress / Habari's style
where you have one entry point per type (eg: album.php) which can
load up whatever parts it needs (eg: $theme->display("header"))
Created album and photo helpers which have create() functions
that form the base of our new API, along with tests for them.
Created our own version of the ORM_MPTT since the existing
versions were too buggy and unsupported to depend upon. Only has
a minimal implementation so far, and the tests are not yet
committed.
Added path(), thumbnail_path() and resize_path() to Item_Model
Extended the scaffolding to allow you to add lots of
photos/albums into your hierarchy.
Deleted modules/mptt -- we're not going to use this anymore.
Diffstat (limited to 'core/libraries')
-rw-r--r-- | core/libraries/ORM_MPTT.php | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/core/libraries/ORM_MPTT.php b/core/libraries/ORM_MPTT.php new file mode 100644 index 00000000..6d3478ad --- /dev/null +++ b/core/libraries/ORM_MPTT.php @@ -0,0 +1,142 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2008 Bharat Mediratta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ +/** + * Implement Modified Preorder Tree Traversal on top of ORM. + * + * MPTT is an efficient way to store and retrieve hierarchical data in a single database table. + * For a good description, read http://www.sitepoint.com/article/hierarchical-data-database/3/ + * + * This code was heavily influenced by code from: + * - http://code.google.com/p/kohana-mptt/ + * - http://code.google.com/p/kohana-mptt/wiki/Documentation + * - http://code.google.com/p/s7ncms/source/browse/trunk/modules/s7ncms/libraries/ORM_MPTT.php + * + * Unfortunately that code was not ready for production and I did not want to absorb their code + * and licensing issues so I've reimplemented just the features that we need. + */ +class ORM_MPTT_Core extends ORM { + private $model_name = null; + private $parent = null; + private $parents = null; + private $children = null; + + function __construct($id=null) { + parent::__construct($id); + $this->model_name = inflector::singular($this->table_name); + } + + /** + * Add this node as a child of the parent provided. + * + * @param integer $parent_id the id of the parent node + * @return ORM + */ + function add_to_parent($parent_id) { + $this->_lock(); + + try { + $parent = ORM::factory($this->model_name, $parent_id); + $parent->_grow(); + $this->left = $parent->right - 2; + $this->right = $parent->right - 1; + $this->parent_id = $parent->id; + $this->level = $parent->level + 1; + $this->save(); + } catch (Exception $e) { + $this->_unlock(); + throw $e; + } + + $this->_unlock(); + return $this; + } + + /** + * Return the parent of this node + * + * @return ORM + */ + function parent() { + if (!isset($this->parent)) { + $this->parent = + ORM::factory($this->model_name)->where("id", $this->parent_id)->find(); + } + return $this->parent; + } + + /** + * Return all the parents of this node, in order from root to leaf. + * + * @return array ORM + */ + function parents() { + if (!isset($this->parents)) { + $this->parents = $this->where("`left` <= {$this->left}") + ->where("`right` >= {$this->right}") + ->orderby("left", "ASC") + ->find_all(); + } + return $this->parents; + } + + /** + * Return all of the children of this node, unordered. + * + * @return array ORM + */ + function children() { + if (!isset($this->children)) { + $this->children = + $this->where("parent_id", $this->id)->find_all(); + } + return $this->children; + } + + /** + * Grow this node's space enough to make room for 1 or more new nodes. + * + * @param integer $count the number of new nodes to add + */ + private function _grow($count=1) { + $size = $count * 2; + $this->db->query( + "UPDATE `{$this->table_name}` SET `left` = `left` + $size WHERE `left` >= {$this->right}"); + $this->db->query( + "UPDATE `{$this->table_name}` SET `right` = `right` + $size WHERE `right` >= {$this->right}"); + $this->right += 2; + } + + /** + * Lock the tree to prevent concurrent modification. + */ + private function _lock() { + $result = $this->db->query("SELECT GET_LOCK('{$this->table_name}', 1) AS L")->current(); + if (empty($result->L)) { + throw new Exception("@todo UNABLE_TO_LOCK_EXCEPTION"); + } + } + + /** + * Unlock the tree. + */ + private function _unlock() { + $this->db->query("SELECT RELEASE_LOCK('{$this->table_name}')"); + } +} |