diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/config/config.php | 1 | ||||
-rw-r--r-- | core/controllers/welcome.php | 27 | ||||
-rw-r--r-- | core/helpers/album.php | 54 | ||||
-rw-r--r-- | core/helpers/core_installer.php | 21 | ||||
-rw-r--r-- | core/helpers/photo.php | 65 | ||||
-rw-r--r-- | core/libraries/ORM_MPTT.php | 142 | ||||
-rw-r--r-- | core/models/item.php | 45 | ||||
-rw-r--r-- | core/tests/Album_Test.php | 47 | ||||
-rw-r--r-- | core/tests/Core_Installer_Test.php | 7 | ||||
-rw-r--r-- | core/tests/File_Structure_Test.php | 1 | ||||
-rw-r--r-- | core/tests/Item_Test.php | 29 | ||||
-rw-r--r-- | core/tests/Photo_Test.php | 57 | ||||
-rw-r--r-- | core/tests/test.jpg | bin | 0 -> 6232 bytes | |||
-rw-r--r-- | core/views/welcome.html.php | 39 |
14 files changed, 473 insertions, 62 deletions
diff --git a/core/config/config.php b/core/config/config.php index 5ab35a0e..de872455 100644 --- a/core/config/config.php +++ b/core/config/config.php @@ -120,7 +120,6 @@ $config['modules'] = array ( MODPATH . 'gallery_unit_test', MODPATH . 'unit_test', - MODPATH . 'mptt', MODPATH . 'forge', THEMEPATH . 'default', diff --git a/core/controllers/welcome.php b/core/controllers/welcome.php index f1201cff..a5719cf0 100644 --- a/core/controllers/welcome.php +++ b/core/controllers/welcome.php @@ -42,6 +42,33 @@ class Welcome_Controller extends Template_Controller { url::redirect("welcome"); } + function add($count) { + srand(time()); + $parents = ORM::factory("item")->where("type", "album")->find_all()->as_array(); + for ($i = 0; $i < $count; $i++) { + $parent = $parents[array_rand($parents)]; + switch(rand(0, 1)) { + case 0: + $album = album::create($parent->id, "rnd_" . rand(), "Rnd $i", "rnd $i"); + $parents[] = $album; + break; + + case 1: + photo::create($parent->id, DOCROOT . "themes/default/images/thumbnail.jpg", + "thumbnail.jpg", "rnd_" . rand(), "sample thumbnail"); + break; + } + + print "$i "; + if (!($i % 100)) { + set_time_limit(30); + } + } + print "<br/>"; + print html::anchor("welcome", "return"); + $this->auto_render = false; + } + private function _get_config_errors() { $errors = array(); if (!file_exists(VARPATH)) { diff --git a/core/helpers/album.php b/core/helpers/album.php new file mode 100644 index 00000000..415e654c --- /dev/null +++ b/core/helpers/album.php @@ -0,0 +1,54 @@ +<?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. + */ + +/** + * This is the API for handling albums. + * + * Note: by design, this class does not do any permission checking. + */ +class Album_Core { + /** + * Create a new album. + * @param integer $parent_id id of parent album + * @param string $name the name of this new album (it will become the directory name on disk) + * @param integer $title the title of the new album + * @param string $description (optional) the longer description of this album + * @return Item_Model + */ + static function create($parent_id, $name, $title, $description=null) { + $album = ORM::factory("item"); + $album->type = "album"; + $album->title = $title; + $album->description = $description; + $album->name = $name; + + while (ORM::Factory("item") + ->where("parent_id", $parent_id) + ->where("name", $album->name) + ->find()->id) { + $album->name = "{$name}-" . rand(); + } + + $album = $album->add_to_parent($parent_id); + mkdir($album->path()); + mkdir($album->thumbnail_path()); + return $album; + } +} diff --git a/core/helpers/core_installer.php b/core/helpers/core_installer.php index 5720976b..d100e0d1 100644 --- a/core/helpers/core_installer.php +++ b/core/helpers/core_installer.php @@ -41,14 +41,14 @@ class core_installer { $db->query("CREATE TABLE `items` ( `id` int(9) NOT NULL auto_increment, - `type` char(32) default NULL, + `type` char(32) NOT NULL, `title` char(255) default NULL, `description` char(255) default NULL, - `path` char(255) default NULL, - `left` int(9) default NULL, - `right` int(9) default NULL, - `parent_id` int(9) default NULL, - `scope` int(9) default NULL, + `name` char(255) default NULL, + `left` int(9) NOT NULL, + `right` int(9) NOT NULL, + `parent_id` int(9) NOT NULL, + `level` int(9) NOT NULL, PRIMARY KEY (`id`), KEY `parent_id` (`parent_id`), KEY `type` (`type`)) @@ -64,9 +64,14 @@ class core_installer { $core->save(); $root = ORM::factory("item"); + $root->type = 'album'; $root->title = "Gallery"; $root->description = "Welcome to your Gallery3"; - $root->make_root(); + $root->left = 1; + $root->right = 2; + $root->parent_id = 0; + $root->level = 1; + $root->save(); } } @@ -74,5 +79,7 @@ class core_installer { $db = Database::instance(); $db->query("DROP TABLE IF EXISTS `items`;"); $db->query("DROP TABLE IF EXISTS `modules`;"); + system("/bin/rm -rf " . VARPATH . "albums"); + system("/bin/rm -rf " . VARPATH . "thumbnails"); } } diff --git a/core/helpers/photo.php b/core/helpers/photo.php new file mode 100644 index 00000000..e796ef03 --- /dev/null +++ b/core/helpers/photo.php @@ -0,0 +1,65 @@ +<?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. + */ + +/** + * This is the API for handling photos. + * + * Note: by design, this class does not do any permission checking. + */ +class Photo_Core { + /** + * Create a new photo. + * @param integer $parent_id id of parent album + * @param string $filename path to the photo file on disk + * @param string $name the filename to use for this photo in the album + * @param integer $title the title of the new photo + * @param string $description (optional) the longer description of this photo + * @return Item_Model + */ + static function create($parent_id, $filename, $name, $title, $description=null) { + $photo = ORM::factory("item"); + $photo->type = "photo"; + $photo->title = $title; + $photo->description = $description; + $photo->name = $name; + + $pi = pathinfo(basename($filename)); + if (empty($pi["extension"])) { + throw new Exception("@todo UNKNOWN_FILE_TYPE"); + } + + while (ORM::Factory("item") + ->where("parent_id", $parent_id) + ->where("name", $photo->name) + ->find()->id) { + $photo->name = rand() . "." . $pi["extension"]; + } + + $photo->add_to_parent($parent_id); + + copy($filename, $photo->path()); + + /** @todo: parameterize these values */ + $image = Image::factory($filename); + $image->resize(200, 140, Image::WIDTH)->save($photo->thumbnail_path()); + $image->resize(800, 600, Image::WIDTH)->save($photo->resize_path()); + return $photo; + } +} 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}')"); + } +} diff --git a/core/models/item.php b/core/models/item.php index 8b08b699..3d5f08a2 100644 --- a/core/models/item.php +++ b/core/models/item.php @@ -17,9 +17,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Item_Model extends MPTT { - protected $left_column = "left"; - protected $right_column = "right"; +class Item_Model extends ORM_MPTT { + protected $children = 'items'; public function is_album() { return $this->type == 'album'; @@ -29,13 +28,39 @@ class Item_Model extends MPTT { return $this->type == 'photo'; } - // MPTT::get_children returns null if there are no children; change that to an empty array for - // consistency. - public function get_children() { - $children = parent::get_children(); - if (empty($children)) { - $children = array(); + private function _get_path() { + $paths = array(); + foreach ($this->parents() as $parent) { + if ($parent->id > 1) { + $paths[] = $parent->name; + } + } + $path = implode($paths, "/"); + if (!$this->saved) { + $path .= $this->name; + } + return $path; + } + + public function path() { + return VARPATH . "albums/{$this->_get_path()}"; + } + + public function thumbnail_path() { + if ($this->is_album()) { + return VARPATH . "thumbnails/{$this->_get_path()}"; + } else { + $pi = pathinfo(VARPATH . "thumbnails/{$this->_get_path()}"); + return "{$pi['dirname']}/{$pi['filename']}_thumb.{$pi['extension']}"; + } + } + + public function resize_path() { + if ($this->is_album()) { + return VARPATH . "thumbnails/{$this->_get_path()}"; + } else { + $pi = pathinfo(VARPATH . "thumbnails/{$this->_get_path()}"); + return "{$pi['dirname']}/{$pi['filename']}_resize.{$pi['extension']}"; } - return $children; } } diff --git a/core/tests/Album_Test.php b/core/tests/Album_Test.php new file mode 100644 index 00000000..52ee4833 --- /dev/null +++ b/core/tests/Album_Test.php @@ -0,0 +1,47 @@ +<?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. + */ +class Album_Test extends Unit_Test_Case { + public function create_album_test() { + $rand = rand(); + $album = album::create(1, $rand, $rand, $rand); + + $this->assert_equal(VARPATH . "albums/$rand", $album->path()); + $this->assert_equal(VARPATH . "thumbnails/$rand", $album->thumbnail_path()); + $this->assert_equal(VARPATH . "thumbnails/$rand", $album->resize_path()); + + $this->assert_true(is_dir($album->path()), "missing path: {$album->path()}"); + $this->assert_true(is_dir($album->resize_path()), "missing path: {$album->resize_path()}"); + + $this->assert_equal(1, $album->parent_id); // MPTT tests will cover other hierarchy checks + $this->assert_equal($rand, $album->name); + $this->assert_equal($rand, $album->title); + $this->assert_equal($rand, $album->description); + + $this->assert_equal($album->parent()->right - 2, $album->left); + $this->assert_equal($album->parent()->right - 1, $album->right); + } + + public function create_conflicting_album_test() { + $rand = rand(); + $album1 = album::create(1, $rand, $rand, $rand); + $album2 = album::create(1, $rand, $rand, $rand); + $this->assert_true($album1->name != $album2->name); + } +} diff --git a/core/tests/Core_Installer_Test.php b/core/tests/Core_Installer_Test.php index 7758f472..4903805b 100644 --- a/core/tests/Core_Installer_Test.php +++ b/core/tests/Core_Installer_Test.php @@ -40,11 +40,14 @@ class Core_Installer_Test extends Unit_Test_Case { } public function install_creates_root_item_test() { + $max_right = + Database::instance()->query("SELECT MAX(`right`) AS `right` FROM items")->current()->right; + $root = ORM::factory('item')->find(1); $this->assert_equal("Gallery", $root->title); $this->assert_equal(1, $root->left); - $this->assert_equal(2, $root->right); + $this->assert_equal($max_right, $root->right); $this->assert_equal(null, $root->parent_id); - $this->assert_equal(1, $root->scope); + $this->assert_equal(1, $root->level); } } diff --git a/core/tests/File_Structure_Test.php b/core/tests/File_Structure_Test.php index 00663bc6..d3f4ae23 100644 --- a/core/tests/File_Structure_Test.php +++ b/core/tests/File_Structure_Test.php @@ -110,6 +110,7 @@ class GalleryCodeFilterIterator extends FilterIterator { strstr($path_name, MODPATH . 'forge') !== false || strstr($path_name, MODPATH . 'unit_test') !== false || strstr($path_name, MODPATH . 'mptt') !== false || + strstr($path_name, MODPATH . 'kodoc') !== false || strstr($path_name, DOCROOT . 'var') !== false || strstr($path_name, DOCROOT . 'test') !== false); } diff --git a/core/tests/Item_Test.php b/core/tests/Item_Test.php deleted file mode 100644 index d077932f..00000000 --- a/core/tests/Item_Test.php +++ /dev/null @@ -1,29 +0,0 @@ -<?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. - */ -class Item_Test extends Unit_Test_Case { - public function create_item_test() { - ORM::factory('item'); - } - - public function create_root_item_test() { - $root = ORM::factory('item')->find(1); - $this->assert_equal("Gallery", $root->title); - } -} diff --git a/core/tests/Photo_Test.php b/core/tests/Photo_Test.php new file mode 100644 index 00000000..8b0a48cc --- /dev/null +++ b/core/tests/Photo_Test.php @@ -0,0 +1,57 @@ +<?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. + */ +class Photo_Test extends Unit_Test_Case { + public function create_photo_test() { + $rand = rand(); + $photo = photo::create(1, DOCROOT . "core/tests/test.jpg", "$rand.jpg", $rand, $rand); + + $this->assert_equal(VARPATH . "albums/$rand.jpg", $photo->path()); + $this->assert_equal(VARPATH . "thumbnails/{$rand}_thumb.jpg", $photo->thumbnail_path()); + $this->assert_equal(VARPATH . "thumbnails/{$rand}_resize.jpg", $photo->resize_path()); + + $this->assert_true(is_file($photo->path()), "missing: {$photo->path()}"); + $this->assert_true(is_file($photo->resize_path()), "missing: {$photo->resize_path()}"); + $this->assert_true(is_file($photo->thumbnail_path()), "missing: {$photo->thumbnail_path()}"); + + $this->assert_equal(1, $photo->parent_id); // MPTT tests will cover other hierarchy checks + $this->assert_equal("$rand.jpg", $photo->name); + $this->assert_equal($rand, $photo->title); + $this->assert_equal($rand, $photo->description); + + $this->assert_equal($photo->parent()->right - 2, $photo->left); + $this->assert_equal($photo->parent()->right - 1, $photo->right); + } + + public function create_conflicting_photo_test() { + $rand = rand(); + $photo1 = photo::create(1, DOCROOT . "core/tests/test.jpg", "$rand.jpg", $rand, $rand); + $photo2 = photo::create(1, DOCROOT . "core/tests/test.jpg", "$rand.jpg", $rand, $rand); + $this->assert_true($photo1->name != $photo2->name); + } + + public function create_photo_with_no_extension_test() { + try { + photo::create(1, "unknown_file", "name", "title", "description"); + $this->assert_false("should fail with an exception"); + } catch (Exception $e) { + // pass + } + } +} diff --git a/core/tests/test.jpg b/core/tests/test.jpg Binary files differnew file mode 100644 index 00000000..1f3525e5 --- /dev/null +++ b/core/tests/test.jpg diff --git a/core/views/welcome.html.php b/core/views/welcome.html.php index b7a290a0..3bc85dc4 100644 --- a/core/views/welcome.html.php +++ b/core/views/welcome.html.php @@ -26,7 +26,7 @@ } p { - margin: 0 0 1em 0; + margin: 0 0 0 0; padding-left: 1em; } @@ -59,6 +59,18 @@ ul { margin-top: -.25em; } + + ul.choices { + padding-top: 0; + padding-left: 1em; + margin: 0px; + } + + ul.choices li { + display: inline; + list-stype-type: none; + padding: 0px; + } </style> </head> <body> @@ -72,24 +84,25 @@ This is a <b><a href="http://www.google.com/images?q=scaffold">scaffold</a></b>: a <i>temporary structure built to support the developers as - they create the real product</i>. - </p> - - <p> - As we flesh out Gallery 3, we'll make it possible for you to - peer inside and see the application taking shape. - Eventually, this page will go away and you'll start in the - application itself. In the meantime, here are some useful - links to get you started. + they create the real product</i>. As we flesh out Gallery 3, + we'll make it possible for you to peer inside and see the + application taking shape. Eventually, this page will go + away and you'll start in the application itself. In the + meantime, here are some useful links to get you started. </p> <h2>System Configuration</h2> <?= $syscheck ?> <h2>Activities</h2> - <p> - <?= html::anchor("album/1", "Browse Gallery") ?> - </p> + <p> <?= html::anchor("album/1", "Browse Gallery") ?> </p> + <ul class="choices"> + <li> add: [</li> + <? foreach (array(1, 10, 50, 100, 500, 1000) as $count): ?> + <li> <?= html::anchor("welcome/add/$count", "$count") ?> </li> + <? endforeach ?> + <li>] photos and albums </li> + </ul> <h2>Documentation</h2> <ul> |