diff options
author | Bharat Mediratta <bharat@menalto.com> | 2008-12-23 04:14:07 +0000 |
---|---|---|
committer | Bharat Mediratta <bharat@menalto.com> | 2008-12-23 04:14:07 +0000 |
commit | 2502240ce4ad25e9fb60ee2468764e25346d2917 (patch) | |
tree | 3dab839d1a15b7cfa75dbbc208aef18ad5613845 /core/helpers | |
parent | 608d0996698716c488318411e10b880796c58805 (diff) |
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.
Diffstat (limited to 'core/helpers')
-rw-r--r-- | core/helpers/album.php | 2 | ||||
-rw-r--r-- | core/helpers/core_installer.php | 29 | ||||
-rw-r--r-- | core/helpers/graphics.php | 121 | ||||
-rw-r--r-- | core/helpers/module.php | 11 | ||||
-rw-r--r-- | core/helpers/photo.php | 22 |
5 files changed, 163 insertions, 22 deletions
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 @@ +<?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 graphics_Core { + /** + * Add a new graphics rule. + * + * Rules are applied to targets (thumbnails and resizes) in priority order. Rules are functions + * in the graphics class. So for example, the following rule: + * + * graphics::add_rule("core", "thumb", "resize", array(200, 200, Image::AUTO), 100); + * + * Specifies that "core" is adding a rule to resize thumbnails down to a max of 200px on + * the longest side. The core module adds default rules at a priority of 100. You can set + * higher and lower priorities to perform operations before or after this fires. + * + * @param string $module_name the module that added the rule + * @param string $target the target for this operation ("thumb" or "resize") + * @param string $operation the name of the operation + * @param array $args arguments to the operation + * @param integer $priority the priority for this function (lower priorities are run first) + */ + public static function add_rule($module_name, $target, $operation, $args, $priority) { + $rule = ORM::factory("graphics_rule"); + $rule->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) { |