From 2502240ce4ad25e9fb60ee2468764e25346d2917 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Tue, 23 Dec 2008 04:14:07 +0000 Subject: Add very simple graphics toolkits. Track a set of rules in Graphics_Rule_Model which specify how we turn original images into thumbnails and resizes. There's one set of rules that applies to every image in the Gallery. Track the state of thumbs and resizes with a "dirty" bit. The new graphics helper manages the rules and can rebuild the thumbs and resizes for any images that are considered "dirty". Introduce the concept of an "album cover" which is an item that an album points to. We'll use that item as the source for the album's thumbnail/resize. Conflated with this change (sorry!) I also changed the Var table to use module_name instead of module_id. This may be marginally less efficient, but it's much easier to follow in the database. --- core/controllers/welcome.php | 1 - core/helpers/album.php | 2 + core/helpers/core_installer.php | 29 ++++++++-- core/helpers/graphics.php | 121 ++++++++++++++++++++++++++++++++++++++++ core/helpers/module.php | 11 ++-- core/helpers/photo.php | 22 ++++---- core/models/graphics_rule.php | 21 +++++++ core/models/item.php | 58 ++++++------------- core/models/module.php | 1 - core/models/var.php | 1 - 10 files changed, 200 insertions(+), 67 deletions(-) create mode 100644 core/helpers/graphics.php create mode 100644 core/models/graphics_rule.php (limited to 'core') diff --git a/core/controllers/welcome.php b/core/controllers/welcome.php index 18ce0c1a..c9415c57 100644 --- a/core/controllers/welcome.php +++ b/core/controllers/welcome.php @@ -233,7 +233,6 @@ class Welcome_Controller extends Template_Controller { $thumb_size = module::get_var("core", "thumb_size"); $parents[] = album::create( $parent->id, "rnd_" . rand(), "Rnd $i", "random album $i", $owner_id) - ->set_thumb(DOCROOT . "core/tests/test.jpg", $thumb_size, $thumb_size) ->save(); $album_count++; } else { diff --git a/core/helpers/album.php b/core/helpers/album.php index faf0fd98..53af0079 100644 --- a/core/helpers/album.php +++ b/core/helpers/album.php @@ -39,6 +39,8 @@ class album_Core { $album->description = $description; $album->name = $name; $album->owner_id = $owner_id; + $album->thumb_dirty = 1; + $album->resize_dirty = 1; while (ORM::factory("item") ->where("parent_id", $parent_id) diff --git a/core/helpers/core_installer.php b/core/helpers/core_installer.php index 225cf330..ee40b07d 100644 --- a/core/helpers/core_installer.php +++ b/core/helpers/core_installer.php @@ -43,7 +43,18 @@ class core_installer { PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + $db->query("CREATE TABLE `graphics_rules` ( + `id` int(9) NOT NULL auto_increment, + `priority` int(9) NOT NULL, + `module_name` varchar(255) NOT NULL, + `target` varchar(32) NOT NULL, + `operation` varchar(64) NOT NULL, + `args` varchar(255) default NULL, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + $db->query("CREATE TABLE `items` ( + `album_cover_item_id` int(9) default NULL, `created` int(9) default NULL, `description` varchar(255) default NULL, `height` int(9) default NULL, @@ -56,9 +67,11 @@ class core_installer { `parent_id` int(9) NOT NULL, `resize_height` int(9) default NULL, `resize_width` int(9) default NULL, + `resize_dirty` BOOLEAN default 1, `right` int(9) NOT NULL, `thumb_height` int(9) default NULL, `thumb_width` int(9) default NULL, + `thumb_dirty` BOOLEAN default 1, `title` varchar(255) default NULL, `type` varchar(32) NOT NULL, `updated` int(9) default NULL, @@ -107,11 +120,11 @@ class core_installer { $db->query("CREATE TABLE `vars` ( `id` int(9) NOT NULL auto_increment, - `module_id` int(9), + `module_name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `value` text, PRIMARY KEY (`id`), - UNIQUE KEY(`module_id`, `name`)) + UNIQUE KEY(`module_name`, `name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); foreach (array("albums", "resizes", "thumbs", "uploads", "modules") as $dir) { @@ -129,18 +142,22 @@ class core_installer { $root->right = 2; $root->parent_id = 0; $root->level = 1; - $root->set_thumb(DOCROOT . "core/tests/test.jpg", 200, 200); + $root->thumb_dirty = 1; + $root->resize_dirty = 1; $root->save(); access::add_item($root); - // Save this before setting vars so that module id is set - module::set_version("core", 1); - module::set_var("core", "active_theme", "default"); module::set_var("core", "active_admin_theme", "admin_default"); module::set_var("core", "page_size", 9); module::set_var("core", "thumb_size", 200); module::set_var("core", "resize_size", 640); + + // Add rules for generating our thumbnails and resizes + graphics::add_rule("core", "thumb", "resize", array(200, 200, Image::AUTO), 100); + graphics::add_rule("core", "resize", "resize", array(640, 640, Image::AUTO), 100); + + module::set_version("core", 1); } } diff --git a/core/helpers/graphics.php b/core/helpers/graphics.php new file mode 100644 index 00000000..b38515fb --- /dev/null +++ b/core/helpers/graphics.php @@ -0,0 +1,121 @@ +module_name = $module_name; + $rule->target = $target; + $rule->operation = $operation; + $rule->priority = $priority; + $rule->args = serialize($args); + $rule->save(); + } + + /** + * Remove all rules for this module + * @param string $module_name + */ + public static function remove_rules($module_name) { + $db = Database::instance(); + $db->query("DELETE FROM `graphics_rules` WHERE `module_name` = '$module_name'"); + } + + /** + * Rebuild the thumb and resize for the given item. + * @param Item_Model $item + */ + public static function generate($item) { + if ($item->type == "album") { + $cover = $item->album_cover(); + if (!$cover) { + return; + } + $input_file = $cover->file_path(); + } else { + $input_file = $item->file_path(); + } + + $ops = array(); + if ($item->thumb_dirty) { + $ops["thumb"] = $item->thumb_path(); + } + if ($item->resize_dirty) { + $ops["resize"] = $item->resize_path(); + } + + if (!$ops) { + return; + } + + foreach (array("thumb" => $item->thumb_path(), + "resize" => $item->resize_path()) as $target => $output_file) { + foreach (ORM::factory("graphics_rule") + ->where("target", $target) + ->orderby("priority", "asc") + ->find_all() as $rule) { + $args = array_merge(array($input_file, $output_file), unserialize($rule->args)); + call_user_func_array(array("graphics", $rule->operation), $args); + } + } + + $dims = getimagesize($item->thumb_path()); + $item->thumb_width = $dims[0]; + $item->thumb_height = $dims[1]; + $item->thumb_dirty = 0; + + $dims = getimagesize($item->resize_path()); + $item->resize_width = $dims[0]; + $item->resize_height = $dims[1]; + $item->resize_dirty = 0; + $item->save(); + } + + /** + * Wrapper around Image::resize + * @param string $input_file + * @param string $output_file + * @param integer $width + * @param integer $height + * @param integer $master Master Dimension constant from the Image class + */ + public static function resize($input_file, $output_file, $width, $height, $master) { + Image::factory($input_file) + ->resize($width, $height, $master) + ->save($output_file); + } +} diff --git a/core/helpers/module.php b/core/helpers/module.php index 0e1f9d44..5dddfa61 100644 --- a/core/helpers/module.php +++ b/core/helpers/module.php @@ -64,7 +64,8 @@ class module_Core { $module->delete(); $db = Database::instance(); - $db->query("DELETE FROM vars WHERE module_id = '{$module->id}';"); + $db->query("DELETE FROM `vars` WHERE `module_name` = '{$module->name}';"); + $db->query("DELETE FROM `graphics_rules` WHERE module_name = '{$module->name}';"); Kohana::log("debug", "$module_name: module deleted"); } @@ -216,9 +217,8 @@ class module_Core { * @return the value */ public function get_var($module_name, $name, $default_value=null) { - $module = model_cache::get("module", $module_name, "name"); $var = ORM::factory("var") - ->where("module_id", $module->id) + ->where("module_name", $module_name) ->where("name", $name) ->find(); return $var->loaded ? $var->value : $default_value; @@ -231,14 +231,13 @@ class module_Core { * @param string $value */ public function set_var($module_name, $name, $value) { - $module = model_cache::get("module", $module_name, "name"); $var = ORM::factory("var") - ->where("module_id", $module->id) + ->where("module_name", $module_name) ->where("name", $name) ->find(); if (!$var->loaded) { $var = ORM::factory("var"); - $var->module_id = $module->id; + $var->module_name = $module_name; $var->name = $name; } $var->value = $value; diff --git a/core/helpers/photo.php b/core/helpers/photo.php index 929f96de..8c826e1c 100644 --- a/core/helpers/photo.php +++ b/core/helpers/photo.php @@ -58,6 +58,8 @@ class photo_Core { $photo->width = $image_info[0]; $photo->height = $image_info[1]; $photo->mime_type = empty($image_info['mime']) ? "application/unknown" : $image_info['mime']; + $photo->thumb_dirty = 1; + $photo->resize_dirty = 1; // Randomize the name if there's a conflict while (ORM::Factory("item") @@ -77,18 +79,18 @@ class photo_Core { $photo->add_to_parent($parent); copy($filename, $photo->file_path()); - // This saves the photo a second time, which is unfortunate but difficult to avoid - // because the ORM_MPTT code needs to do the first save. - $thumb_size = module::get_var("core", "thumb_size"); - $resize_size = module::get_var("core", "resize_size"); - - $result = $photo->set_thumb($filename, $thumb_size, $thumb_size) - ->set_resize($filename, $resize_size, $resize_size) - ->save(); - module::event("photo_created", $photo); - return $result; + // Build our thumbnail/resizes + graphics::generate($photo); + + // If the parent has no cover item, make this it. + $parent = $photo->parent(); + if ($parent->album_cover_item_id == null) { + $parent->album_cover_item_id = $photo->id; + $parent->save(); + graphics::generate($parent); + } } static function get_add_form($parent) { diff --git a/core/models/graphics_rule.php b/core/models/graphics_rule.php new file mode 100644 index 00000000..1554d2fb --- /dev/null +++ b/core/models/graphics_rule.php @@ -0,0 +1,21 @@ +type == "album" ? "/.album.jpg" : ""); } - /** - * Build a thumbnail for this item from the image provided with the - * given width and height - * - * @chainable - * @param string $filename the path to an image - * @param integer $width the desired width of the thumb - * @param integer $height the desired height of the thumb - * @return ORM - */ - public function set_thumb($filename, $width, $height) { - Image::factory($filename) - ->resize($width, $height, Image::AUTO) - ->save($this->thumb_path()); - - $dims = getimagesize($this->thumb_path()); - $this->thumb_width = $dims[0]; - $this->thumb_height = $dims[1]; - return $this; - } - - /** - * Build a resize for this item from the image provided with the - * given width and height - * - * @chainable - * @param string $filename the path to an image - * @param integer $width the desired width of the resize - * @param integer $height the desired height of the resize - * @return ORM - */ - public function set_resize($filename, $width, $height) { - Image::factory($filename) - ->resize($width, $height, Image::AUTO) - ->save($this->resize_path()); - - $dims = getimagesize($this->resize_path()); - $this->resize_width = $dims[0]; - $this->resize_height = $dims[1]; - return $this; - } - /** * Return the relative path to this item's file. * @return string @@ -250,4 +208,20 @@ class Item_Model extends ORM_MPTT { } return parent::save(); } + + /** + * Return the Item_Model representing the cover for this album. + * @return Item_Model or null if there's no cover + */ + public function album_cover() { + if ($this->type != "album") { + return null; + } + + if (empty($this->album_cover_item_id)) { + return null; + } + + return model_cache::get("item", $this->album_cover_item_id); + } } diff --git a/core/models/module.php b/core/models/module.php index da9fb0a1..de4cc43d 100644 --- a/core/models/module.php +++ b/core/models/module.php @@ -18,5 +18,4 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class Module_Model extends ORM { - protected $has_many = array("vars"); } diff --git a/core/models/var.php b/core/models/var.php index d5aa1849..4d7e5ffd 100644 --- a/core/models/var.php +++ b/core/models/var.php @@ -18,5 +18,4 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class Var_Model extends ORM { - protected $belongs_to = array("module"); } -- cgit v1.2.3