diff options
author | Nathan Kinkade <nkinkade@nkinka.de> | 2010-12-06 16:14:26 +0000 |
---|---|---|
committer | Nathan Kinkade <nkinkade@nkinka.de> | 2010-12-06 16:14:26 +0000 |
commit | cf1965957c48b1c88a3913f8167688d03d191cec (patch) | |
tree | 9da9e719c68f4428771c9b70389b93f7a1bafd26 | |
parent | 1659e487a26ef0460926376b7b8b40aaba0c0577 (diff) | |
parent | c3ef8921260db8e39b6d2a7b4708e3d19f35f8b5 (diff) |
Merge branch 'master' of git://github.com/gallery/gallery3
73 files changed, 478 insertions, 432 deletions
diff --git a/installer/installer.php b/installer/installer.php index 53a5e3db..9a957b43 100644 --- a/installer/installer.php +++ b/installer/installer.php @@ -229,6 +229,10 @@ class installer { $errors[] = "Gallery requires <a href=\"http://php.net/manual/en/ini.core.php\">short_open_tag</a> to be on. Please enable it in your php.ini."; } + if (!function_exists("ctype_alpha")) { + $errors[] = "Gallery requires the <a href=\"http://php.net/manual/en/book.ctype.php\">PHP Ctype</a> extension. Please install it."; + } + return @$errors; } diff --git a/modules/comment/models/comment.php b/modules/comment/models/comment.php index 772e8b60..8f860a7b 100644 --- a/modules/comment/models/comment.php +++ b/modules/comment/models/comment.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Comment_Model extends ORM { +class Comment_Model_Core extends ORM { function item() { return ORM::factory("item", $this->item_id); } diff --git a/modules/digibug/models/digibug_proxy.php b/modules/digibug/models/digibug_proxy.php index 0ce21649..2bff6ddb 100644 --- a/modules/digibug/models/digibug_proxy.php +++ b/modules/digibug/models/digibug_proxy.php @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Digibug_Proxy_Model extends ORM { +class Digibug_Proxy_Model_Core extends ORM { protected $belongs_to = array("item"); } diff --git a/modules/exif/models/exif_key.php b/modules/exif/models/exif_key.php index 3e9784ac..8ca63ada 100644 --- a/modules/exif/models/exif_key.php +++ b/modules/exif/models/exif_key.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Exif_Key_Model extends ORM { +class Exif_Key_Model_Core extends ORM { } diff --git a/modules/exif/models/exif_record.php b/modules/exif/models/exif_record.php index 8f87f6bc..03b8c982 100644 --- a/modules/exif/models/exif_record.php +++ b/modules/exif/models/exif_record.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Exif_Record_Model extends ORM { +class Exif_Record_Model_Core extends ORM { } diff --git a/modules/g2_import/helpers/g2_import.php b/modules/g2_import/helpers/g2_import.php index 515eb73d..8de5ce44 100644 --- a/modules/g2_import/helpers/g2_import.php +++ b/modules/g2_import/helpers/g2_import.php @@ -157,6 +157,7 @@ class g2_import_Core { $ret = GalleryEmbed::init(); if ($ret) { + Kohana_Log::add("error", "Gallery 2 call failed with: " . $ret->getAsText()); return false; } @@ -1199,6 +1200,11 @@ class g2_import_Core { $g2_map->g3_id = $g3_id; $g2_map->g2_id = $g2_id; $g2_map->resource_type = $resource_type; + + if (strpos($g2_url, self::$g2_base_url) === 0) { + $g2_url = substr($g2_url, strlen(self::$g2_base_url)); + } + $g2_map->g2_url = $g2_url; $g2_map->save(); self::$map[$g2_id] = $g3_id; @@ -1211,13 +1217,12 @@ class g2_import_Core { static function g2_url($params) { global $gallery; - $url = $gallery->getUrlGenerator()->generateUrl( + return $gallery->getUrlGenerator()->generateUrl( $params, array("forceSessionId" => false, "htmlEntities" => false, "urlEncode" => false, "useAuthToken" => false)); - return str_replace(self::$g2_base_url, "", $url); } static function lower_error_reporting() { diff --git a/modules/g2_import/models/g2_map.php b/modules/g2_import/models/g2_map.php index a20f48d6..8b96050d 100644 --- a/modules/g2_import/models/g2_map.php +++ b/modules/g2_import/models/g2_map.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class G2_Map_Model extends ORM { +class G2_Map_Model_Core extends ORM { } diff --git a/modules/g2_import/views/admin_g2_import.html.php b/modules/g2_import/views/admin_g2_import.html.php index 564bea9f..cb13363a 100644 --- a/modules/g2_import/views/admin_g2_import.html.php +++ b/modules/g2_import/views/admin_g2_import.html.php @@ -89,6 +89,7 @@ Options +FollowSymLinks RewriteEngine On RewriteBase <?= html::clean(g2_import::$g2_base_url) ?> + RewriteRule ^(.*)$ <?= url::site("g2/map?path=\$1") ?> [QSA,L,R=301] </IfModule></textarea> </div> diff --git a/modules/gallery/helpers/MY_html.php b/modules/gallery/helpers/MY_html.php index cf130401..d15bd816 100644 --- a/modules/gallery/helpers/MY_html.php +++ b/modules/gallery/helpers/MY_html.php @@ -26,7 +26,7 @@ class html extends html_Core { * unescaped HTML which is assumed to be safe. * * Example:<pre> - * <div><?= html::clean($php_var) ?> + * <div><?= html::clean($php_var) ?> * </pre> */ static function clean($html) { @@ -39,7 +39,7 @@ class html extends html_Core { * only non-malicious HTML. * * Example:<pre> - * <div><?= html::purify($item->title) ?> + * <div><?= html::purify($item->title) ?> * </pre> */ static function purify($html) { @@ -86,6 +86,6 @@ class html extends html_Core { * @return the string escaped for use in HTML attributes. */ static function clean_attribute($string) { - return self::clean($string)->for_html_attr(); + return html::clean($string)->for_html_attr(); } } diff --git a/modules/gallery/helpers/MY_remote.php b/modules/gallery/helpers/MY_remote.php index 05341330..a1d2a3d1 100644 --- a/modules/gallery/helpers/MY_remote.php +++ b/modules/gallery/helpers/MY_remote.php @@ -24,7 +24,7 @@ class remote extends remote_Core { /* Read the web page into a buffer */ list ($response_status, $response_headers, $response_body) = - self::do_request($url, 'POST', $extra_headers, $post_data_raw); + remote::do_request($url, 'POST', $extra_headers, $post_data_raw); return array($response_body, $response_status, $response_headers); } diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php index 1a448e4a..0b0dcbc1 100644 --- a/modules/gallery/helpers/access.php +++ b/modules/gallery/helpers/access.php @@ -79,7 +79,7 @@ class access_Core { * @return boolean */ static function can($perm_name, $item) { - return self::user_can(identity::active_user(), $perm_name, $item); + return access::user_can(identity::active_user(), $perm_name, $item); } /** @@ -102,7 +102,7 @@ class access_Core { $resource = $perm_name == "view" ? $item : model_cache::get("access_cache", $item->id, "item_id"); foreach ($user->groups() as $group) { - if ($resource->__get("{$perm_name}_{$group->id}") === self::ALLOW) { + if ($resource->__get("{$perm_name}_{$group->id}") === access::ALLOW) { return true; } } @@ -117,12 +117,12 @@ class access_Core { * @return boolean */ static function required($perm_name, $item) { - if (!self::can($perm_name, $item)) { + if (!access::can($perm_name, $item)) { if ($perm_name == "view") { // Treat as if the item didn't exist, don't leak any information. throw new Kohana_404_Exception(); } else { - self::forbidden(); + access::forbidden(); } } } @@ -138,7 +138,7 @@ class access_Core { static function group_can($group, $perm_name, $item) { $resource = $perm_name == "view" ? $item : model_cache::get("access_cache", $item->id, "item_id"); - return $resource->__get("{$perm_name}_{$group->id}") === self::ALLOW; + return $resource->__get("{$perm_name}_{$group->id}") === access::ALLOW; } /** @@ -168,14 +168,14 @@ class access_Core { return null; } - // For view permissions, if any parent is self::DENY, then those parents lock this one. + // For view permissions, if any parent is access::DENY, then those parents lock this one. // Return $lock = ORM::factory("item") ->where("left_ptr", "<=", $item->left_ptr) ->where("right_ptr", ">=", $item->right_ptr) ->where("items.id", "<>", $item->id) ->join("access_intents", "items.id", "access_intents.item_id") - ->where("access_intents.view_$group->id", "=", self::DENY) + ->where("access_intents.view_$group->id", "=", access::DENY) ->order_by("level", "DESC") ->limit(1) ->find(); @@ -222,7 +222,7 @@ class access_Core { self::_update_access_non_view_cache($group, $perm_name, $album); } - self::update_htaccess_files($album, $group, $perm_name, $value); + access::update_htaccess_files($album, $group, $perm_name, $value); model_cache::clear(); } @@ -414,7 +414,7 @@ class access_Core { static function verify_csrf() { $input = Input::instance(); if ($input->post("csrf", $input->get("csrf", null)) !== Session::instance()->get("csrf")) { - self::forbidden(); + access::forbidden(); } } @@ -437,7 +437,7 @@ class access_Core { * @return string */ static function csrf_form_field() { - return "<input type=\"hidden\" name=\"csrf\" value=\"" . self::csrf_token() . "\"/>"; + return "<input type=\"hidden\" name=\"csrf\" value=\"" . access::csrf_token() . "\"/>"; } /** @@ -488,7 +488,7 @@ class access_Core { "ALTER TABLE {access_intents} ADD `$field` BINARY DEFAULT NULL"); db::build() ->update("access_intents") - ->set($field, self::DENY) + ->set($field, access::DENY) ->where("item_id", "=", 1) ->execute(); model_cache::clear(); @@ -517,12 +517,12 @@ class access_Core { // DENY and this ALLOW cannot be obeyed. So in that case, back up the tree and find any // non-DEFAULT and non-ALLOW parent and propagate from there. If we can't find a matching // item, then its safe to propagate from here. - if ($access->$field !== self::DENY) { + if ($access->$field !== access::DENY) { $tmp_item = ORM::factory("item") ->where("left_ptr", "<", $item->left_ptr) ->where("right_ptr", ">", $item->right_ptr) ->join("access_intents", "access_intents.item_id", "items.id") - ->where("access_intents.$field", "=", self::DENY) + ->where("access_intents.$field", "=", access::DENY) ->order_by("left_ptr", "DESC") ->limit(1) ->find(); @@ -537,7 +537,7 @@ class access_Core { // that we can tell which permissions have been changed, and which ones need to be updated. db::build() ->update("items") - ->set($field, self::UNKNOWN) + ->set($field, access::UNKNOWN) ->where("left_ptr", ">=", $item->left_ptr) ->where("right_ptr", "<=", $item->right_ptr) ->execute(); @@ -548,20 +548,20 @@ class access_Core { ->where("left_ptr", ">=", $item->left_ptr) ->where("right_ptr", "<=", $item->right_ptr) ->where("type", "=", "album") - ->where("access_intents.$field", "IS NOT", self::INHERIT) + ->where("access_intents.$field", "IS NOT", access::INHERIT) ->order_by("level", "DESC") ->find_all(); foreach ($query as $row) { - if ($row->$field == self::ALLOW) { + if ($row->$field == access::ALLOW) { // Propagate ALLOW for any row that is still UNKNOWN. db::build() ->update("items") ->set($field, $row->$field) - ->where($field, "IS", self::UNKNOWN) // UNKNOWN is NULL so we have to use IS + ->where($field, "IS", access::UNKNOWN) // UNKNOWN is NULL so we have to use IS ->where("left_ptr", ">=", $row->left_ptr) ->where("right_ptr", "<=", $row->right_ptr) ->execute(); - } else if ($row->$field == self::DENY) { + } else if ($row->$field == access::DENY) { // DENY overwrites everything below it db::build() ->update("items") @@ -577,8 +577,8 @@ class access_Core { // the hierarchy, and all of those are safe to change to ALLOW. db::build() ->update("items") - ->set($field, self::ALLOW) - ->where($field, "IS", self::UNKNOWN) // UNKNOWN is NULL so we have to use IS + ->set($field, access::ALLOW) + ->where($field, "IS", access::UNKNOWN) // UNKNOWN is NULL so we have to use IS ->where("left_ptr", ">=", $item->left_ptr) ->where("right_ptr", "<=", $item->right_ptr) ->execute(); @@ -605,12 +605,12 @@ class access_Core { // // @todo To optimize this, we wouldn't need to propagate from the parent, we could just // propagate from here with the parent's intent. - if ($access->$field === self::INHERIT) { + if ($access->$field === access::INHERIT) { $tmp_item = ORM::factory("item") ->join("access_intents", "items.id", "access_intents.item_id") ->where("left_ptr", "<", $item->left_ptr) ->where("right_ptr", ">", $item->right_ptr) - ->where($field, "IS NOT", self::UNKNOWN) // UNKNOWN is NULL so we have to use IS NOT + ->where($field, "IS NOT", access::UNKNOWN) // UNKNOWN is NULL so we have to use IS NOT ->order_by("left_ptr", "DESC") ->limit(1) ->find(); @@ -626,11 +626,11 @@ class access_Core { ->join("items", "items.id", "access_intents.item_id") ->where("left_ptr", ">=", $item->left_ptr) ->where("right_ptr", "<=", $item->right_ptr) - ->where($field, "IS NOT", self::INHERIT) + ->where($field, "IS NOT", access::INHERIT) ->order_by("level", "ASC") ->find_all(); foreach ($query as $row) { - $value = ($row->$field === self::ALLOW) ? true : false; + $value = ($row->$field === access::ALLOW) ? true : false; db::build() ->update("access_caches") ->set($field, $value) @@ -683,7 +683,7 @@ class access_Core { } foreach ($dirs as $dir) { - if ($value === self::DENY) { + if ($value === access::DENY) { $fp = fopen("$dir/.htaccess", "w+"); fwrite($fp, "<IfModule mod_rewrite.c>\n"); fwrite($fp, " RewriteEngine On\n"); diff --git a/modules/gallery/helpers/auth.php b/modules/gallery/helpers/auth.php index 48b5fc32..fa6242b9 100644 --- a/modules/gallery/helpers/auth.php +++ b/modules/gallery/helpers/auth.php @@ -74,13 +74,13 @@ class auth_Core { } static function validate_too_many_failed_logins($name_input) { - if (self::too_many_failures($name_input->value)) { + if (auth::too_many_failures($name_input->value)) { $name_input->add_error("too_many_failed_logins", 1); } } static function validate_too_many_failed_auth_attempts($form_input) { - if (self::too_many_failures(identity::active_user()->name)) { + if (auth::too_many_failures(identity::active_user()->name)) { $form_input->add_error("too_many_failed_auth_attempts", 1); } } diff --git a/modules/gallery/helpers/block_manager.php b/modules/gallery/helpers/block_manager.php index 4dcd6c32..2237b702 100644 --- a/modules/gallery/helpers/block_manager.php +++ b/modules/gallery/helpers/block_manager.php @@ -27,10 +27,10 @@ class block_manager_Core { } static function add($location, $module_name, $block_id) { - $blocks = self::get_active($location); + $blocks = block_manager::get_active($location); $blocks[rand()] = array($module_name, $block_id); - self::set_active($location, $blocks); + block_manager::set_active($location, $blocks); } static function activate_blocks($module_name) { @@ -38,25 +38,25 @@ class block_manager_Core { if (method_exists($block_class, "get_site_list")) { $blocks = call_user_func(array($block_class, "get_site_list")); foreach (array_keys($blocks) as $block_id) { - self::add("site_sidebar", $module_name, $block_id); + block_manager::add("site_sidebar", $module_name, $block_id); } } } static function remove($location, $block_id) { - $blocks = self::get_active($location); + $blocks = block_manager::get_active($location); unset($blocks[$block_id]); - self::set_active($location, $blocks); + block_manager::set_active($location, $blocks); } static function remove_blocks_for_module($location, $module_name) { - $blocks = self::get_active($location); + $blocks = block_manager::get_active($location); foreach ($blocks as $key => $block) { if ($block[0] == $module_name) { unset($blocks[$key]); } } - self::set_active($location, $blocks); + block_manager::set_active($location, $blocks); } static function deactivate_blocks($module_name) { @@ -64,14 +64,14 @@ class block_manager_Core { if (method_exists($block_class, "get_site_list")) { $blocks = call_user_func(array($block_class, "get_site_list")); foreach (array_keys($blocks) as $block_id) { - self::remove_blocks_for_module("site_sidebar", $module_name); + block_manager::remove_blocks_for_module("site_sidebar", $module_name); } } if (method_exists($block_class, "get_admin_list")) { $blocks = call_user_func(array($block_class, "get_admin_list")); foreach (array("dashboard_sidebar", "dashboard_center") as $location) { - self::remove_blocks_for_module($location, $module_name); + block_manager::remove_blocks_for_module($location, $module_name); } } } @@ -99,7 +99,7 @@ class block_manager_Core { } static function get_html($location, $theme=null) { - $active = self::get_active($location); + $active = block_manager::get_active($location); $result = ""; foreach ($active as $id => $desc) { if (method_exists("$desc[0]_block", "get")) { diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php index ac51e2a6..2bb55ccb 100644 --- a/modules/gallery/helpers/gallery.php +++ b/modules/gallery/helpers/gallery.php @@ -51,6 +51,7 @@ class gallery_Core { if (Router::$controller != "login" && Router::$controller != "combined" && Router::$controller != "digibug" && + Router::$controller != "rest" && identity::active_user()->guest && !access::user_can(identity::guest(), "view", item::root()) && php_sapi_name() != "cli") { diff --git a/modules/gallery/helpers/gallery_block.php b/modules/gallery/helpers/gallery_block.php index cb28cbcd..1d92d66d 100644 --- a/modules/gallery/helpers/gallery_block.php +++ b/modules/gallery/helpers/gallery_block.php @@ -70,12 +70,6 @@ class gallery_block_Core { $block->css_id = "g-platform"; $block->title = t("Platform information"); $block->content = new View("admin_block_platform.html"); - if (@is_readable("/proc/loadavg") && $first_line = current(@file("/proc/loadavg"))) { - $block->content->load_average = - join(" ", array_slice(explode(" ", $first_line), 0, 3)); - } else { - $block->content->load_average = t("Unavailable"); - } break; case "project_news": @@ -88,7 +82,7 @@ class gallery_block_Core { case "block_adder": $block->css_id = "g-block-adder"; $block->title = t("Dashboard content"); - $block->content = self::get_add_block_form(); + $block->content = gallery_block::get_add_block_form(); break; case "language": diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php index d56edabb..e69ff91a 100644 --- a/modules/gallery/helpers/gallery_task.php +++ b/modules/gallery/helpers/gallery_task.php @@ -71,7 +71,12 @@ class gallery_task_Core { static function rebuild_dirty_images($task) { $errors = array(); try { - $result = graphics::find_dirty_images_query()->select("id")->execute(); + // Choose the dirty images in a random order so that if we run this task multiple times + // concurrently each task is rebuilding different images simultaneously. + $result = graphics::find_dirty_images_query()->select("id") + ->select(new Database_Expression("RAND() as r")) + ->order_by("r", "ASC") + ->execute(); $total_count = $task->get("total_count", $result->count()); $mode = $task->get("mode", "init"); if ($mode == "init") { diff --git a/modules/gallery/helpers/gallery_theme.php b/modules/gallery/helpers/gallery_theme.php index 0d7cc44a..978c69a6 100644 --- a/modules/gallery/helpers/gallery_theme.php +++ b/modules/gallery/helpers/gallery_theme.php @@ -93,7 +93,7 @@ class gallery_theme_Core { } // Redirect to the root album when the admin session expires. - $admin_session_redirect_check = '<script type="text/javascript"> + $content = '<script type="text/javascript"> var adminReauthCheck = function() { $.ajax({url: "' . url::site("admin?reauth_check=1") . '", dataType: "json", @@ -105,11 +105,11 @@ class gallery_theme_Core { }; setInterval("adminReauthCheck();", 60 * 1000); </script>'; - print $admin_session_redirect_check; if ($session->get("l10n_mode", false)) { - return L10n_Client_Controller::l10n_form(); + $content .= "\n" . L10n_Client_Controller::l10n_form(); } + return $content; } static function credits() { diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index dd521d84..edba6b76 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -50,7 +50,7 @@ class graphics_Core { $rule->active = true; $rule->save(); - self::mark_dirty($target == "thumb", $target == "resize"); + graphics::mark_dirty($target == "thumb", $target == "resize"); } /** @@ -67,7 +67,7 @@ class graphics_Core { ->where("operation", "=", $operation) ->execute(); - self::mark_dirty($target == "thumb", $target == "resize"); + graphics::mark_dirty($target == "thumb", $target == "resize"); } /** @@ -80,7 +80,7 @@ class graphics_Core { ->where("module_name", "=", $module_name) ->execute(); if (count($status)) { - self::mark_dirty(true, true); + graphics::mark_dirty(true, true); } } @@ -252,7 +252,7 @@ class graphics_Core { $db->execute(); } - $count = self::find_dirty_images_query()->count_records(); + $count = graphics::find_dirty_images_query()->count_records(); if ($count) { site_status::warning( t2("One of your photos is out of date. <a %attrs>Click here to fix it</a>", diff --git a/modules/gallery/helpers/identity.php b/modules/gallery/helpers/identity.php index 5ca024e9..f45f72c3 100644 --- a/modules/gallery/helpers/identity.php +++ b/modules/gallery/helpers/identity.php @@ -61,7 +61,7 @@ class identity_Core { $session = Session::instance(); if (!($user = $session->get("user"))) { - self::set_active_user($user = self::guest()); + identity::set_active_user($user = identity::guest()); } // The installer cannot set a user into the session, so it just sets an id which we should @@ -69,6 +69,7 @@ class identity_Core { // @todo set the user name into the session instead of 2 and then use it to get the // user object if ($user === 2) { + $session->delete("user"); // delete it so that identity code isn't confused by the integer auth::login(IdentityProvider::instance()->admin_user()); } @@ -127,7 +128,7 @@ class identity_Core { $session = Session::instance(); $session->set("user", $user); $session->delete("group_ids"); - self::load_user(); + identity::load_user(); } /** diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php index 092904a5..052b1c8e 100644 --- a/modules/gallery/helpers/item.php +++ b/modules/gallery/helpers/item.php @@ -218,7 +218,13 @@ class item_Core { } /** - * Return a query to get a random Item_Model, with optional filters + * Return a query to get a random Item_Model, with optional filters. + * Usage: item::random_query()->execute(); + * + * Note: You can add your own ->where() clauses but if your Gallery is + * small or your where clauses are over-constrained you may wind up with + * no item. You should try running this a few times in a loop if you + * don't get an item back. */ static function random_query() { // Pick a random number and find the item that's got nearest smaller number. diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php index 10f9e16a..a8bc36ad 100644 --- a/modules/gallery/helpers/item_rest.php +++ b/modules/gallery/helpers/item_rest.php @@ -23,18 +23,19 @@ class item_rest_Core { * query the collection. You can specify them in any combination. * * scope=direct - * only return items that are immediately under this one + * Only return items that are immediately under this one * scope=all - * return items anywhere under this one + * Return items anywhere under this one * * name=<substring> - * only return items where the name contains this substring + * Only return items where the name contains this substring * * random=true - * return a single random item + * Return a single random item * * type=<comma separate list of photo, movie or album> - * limit the type to types in this list. eg, "type=photo,movie" + * Limit the type to types in this list, eg: "type=photo,movie". + * Also limits the types returned in the member collections (same behaviour as item_rest). */ static function get($request) { $item = rest::resolve($request->url); diff --git a/modules/gallery/helpers/items_rest.php b/modules/gallery/helpers/items_rest.php index f0b68d63..08aa3279 100644 --- a/modules/gallery/helpers/items_rest.php +++ b/modules/gallery/helpers/items_rest.php @@ -25,31 +25,34 @@ class items_rest_Core { * filter the results based on the specified type. Using the type parameter with the * ancestors_for parameter makes no sense and will be ignored. * - * urls=url1,url2,url3 - * return items that match the specified urls. Typically used to return the member detail + * urls=["url1","url2","url3"] + * Return items that match the specified urls. Typically used to return the member detail * * ancestors_for=url - * return the ancestors of the specified item + * Return the ancestors of the specified item * * type=<comma separate list of photo, movie or album> - * limit the type to types in this list. eg, "type=photo,movie" + * Limit the type to types in this list, eg: "type=photo,movie". + * Also limits the types returned in the member collections (same behaviour as item_rest). + * Ignored if ancestors_for is set. */ static function get($request) { $items = array(); + $types = array(); + if (isset($request->params->urls)) { + if (isset($request->params->type)) { + $types = explode(",", $request->params->type); + } + foreach (json_decode($request->params->urls) as $url) { - if (isset($request->params->type)) { - $types = explode(",", $request->params->type); - } $item = rest::resolve($url); - if (access::can("view", $item)) { - if (isset($types)) { - if (in_array($item->type, $types)) { - $items[] = items_rest::_format_restful_item($item); - } - } else { - $items[] = items_rest::_format_restful_item($item); - } + if (!access::can("view", $item)) { + continue; + } + + if (empty($types) || in_array($item->type, $types)) { + $items[] = items_rest::_format_restful_item($item, $types); } } } else if (isset($request->params->ancestors_for)) { @@ -57,9 +60,9 @@ class items_rest_Core { if (!access::can("view", $item)) { throw new Kohana_404_Exception(); } - $items[] = items_rest::_format_restful_item($item); + $items[] = items_rest::_format_restful_item($item, $types); while (($item = $item->parent()) != null) { - array_unshift($items, items_rest::_format_restful_item($item)); + array_unshift($items, items_rest::_format_restful_item($item, $types)); }; } @@ -74,14 +77,16 @@ class items_rest_Core { return $item; } - private static function _format_restful_item($item) { + private static function _format_restful_item($item, $types) { $item_rest = array("url" => rest::url("item", $item), "entity" => $item->as_restful_array(), "relationships" => rest::relationships("item", $item)); if ($item->type == "album") { $members = array(); foreach ($item->viewable()->children() as $child) { - $members[] = rest::url("item", $child); + if (empty($types) || in_array($child->type, $types)) { + $members[] = rest::url("item", $child); + } } $item_rest["members"] = $members; } diff --git a/modules/gallery/helpers/l10n_client.php b/modules/gallery/helpers/l10n_client.php index 43cc2036..8c2685a8 100644 --- a/modules/gallery/helpers/l10n_client.php +++ b/modules/gallery/helpers/l10n_client.php @@ -40,14 +40,14 @@ class l10n_client_Core { } static function server_uid($api_key=null) { - $api_key = $api_key == null ? self::api_key() : $api_key; + $api_key = $api_key == null ? l10n_client::api_key() : $api_key; $parts = explode(":", $api_key); return empty($parts) ? 0 : $parts[0]; } private static function _sign($payload, $api_key=null) { - $api_key = $api_key == null ? self::api_key() : $api_key; - return md5($api_key . $payload . self::client_token()); + $api_key = $api_key == null ? l10n_client::api_key() : $api_key; + return md5($api_key . $payload . l10n_client::client_token()); } static function validate_api_key($api_key) { @@ -57,9 +57,9 @@ class l10n_client_Core { list ($response_data, $response_status) = remote::post( $url, array("version" => $version, - "client_token" => self::client_token(), + "client_token" => l10n_client::client_token(), "signature" => $signature, - "uid" => self::server_uid($api_key))); + "uid" => l10n_client::server_uid($api_key))); if (!remote::success($response_status)) { return false; } @@ -215,9 +215,9 @@ class l10n_client_Core { list ($response_data, $response_status) = remote::post( $url, array("data" => $request_data, - "client_token" => self::client_token(), + "client_token" => l10n_client::client_token(), "signature" => $signature, - "uid" => self::server_uid())); + "uid" => l10n_client::server_uid())); if (!remote::success($response_status)) { throw new Exception("@todo TRANSLATIONS_SUBMISSION_FAILED " . $response_status); diff --git a/modules/gallery/helpers/locales.php b/modules/gallery/helpers/locales.php index d1e72260..565e9da8 100644 --- a/modules/gallery/helpers/locales.php +++ b/modules/gallery/helpers/locales.php @@ -62,11 +62,14 @@ class locales_Core { } // @todo Might want to add a localizable language name as well. + // ref: http://cldr.unicode.org/ + // ref: http://cldr.unicode.org/index/cldr-spec/picking-the-right-language-code private static function _init_language_data() { $l["af_ZA"] = "Afrikaans"; // Afrikaans $l["ar_SA"] = "العربية"; // Arabic $l["be_BY"] = "Беларускі"; // Belarusian $l["bg_BG"] = "български"; // Bulgarian + $l["bn_BD"] = "বাংলা"; // Bengali $l["ca_ES"] = "Catalan"; // Catalan $l["cs_CZ"] = "čeština"; // Czech $l["da_DK"] = "Dansk"; // Danish @@ -92,6 +95,7 @@ class locales_Core { $l["ko_KR"] = "한국어"; // Korean $l["lt_LT"] = "Lietuvių"; // Lithuanian $l["lv_LV"] = "Latviešu"; // Latvian + $l["ms_MY"] = "Bahasa Melayu"; // Malay $l["mk_MK"] = "Македонски јазик"; // Macedonian $l["nl_NL"] = "Nederlands"; // Dutch $l["no_NO"] = "Norsk bokmål"; // Norwegian @@ -208,7 +212,7 @@ class locales_Core { } private static function _locale_match_score($requested_locale, $qvalue, $adjustment_factor) { - $installed = self::installed(); + $installed = locales::installed(); if (isset($installed[$requested_locale])) { return array($requested_locale, $qvalue); } @@ -223,14 +227,14 @@ class locales_Core { static function set_request_locale() { // 1. Check the session specific preference (cookie) - $locale = self::cookie_locale(); + $locale = locales::cookie_locale(); // 2. Check the user's preference if (!$locale) { $locale = identity::active_user()->locale; } // 3. Check the browser's / OS' preference if (!$locale) { - $locale = self::locale_from_http_request(); + $locale = locales::locale_from_http_request(); } // If we have any preference, override the site's default locale if ($locale) { diff --git a/modules/gallery/helpers/log.php b/modules/gallery/helpers/log.php index 26f70480..37154522 100644 --- a/modules/gallery/helpers/log.php +++ b/modules/gallery/helpers/log.php @@ -30,7 +30,7 @@ class log_Core { * @param string $html an html snippet presented alongside the log message to aid the admin */ static function success($category, $message, $html="") { - self::_add($category, $message, $html, self::SUCCESS); + self::_add($category, $message, $html, log::SUCCESS); } /** @@ -40,7 +40,7 @@ class log_Core { * @param string $html an html snippet presented alongside the log message to aid the admin */ static function info($category, $message, $html="") { - self::_add($category, $message, $html, self::INFO); + self::_add($category, $message, $html, log::INFO); } /** @@ -50,7 +50,7 @@ class log_Core { * @param string $html an html snippet presented alongside the log message to aid the admin */ static function warning($category, $message, $html="") { - self::_add($category, $message, $html, self::WARNING); + self::_add($category, $message, $html, log::WARNING); } /** @@ -60,7 +60,7 @@ class log_Core { * @param string $html an html snippet presented alongside the log message to aid the admin */ static function error($category, $message, $html="") { - self::_add($category, $message, $html, self::ERROR); + self::_add($category, $message, $html, log::ERROR); } /** @@ -92,16 +92,16 @@ class log_Core { */ static function severity_class($severity) { switch($severity) { - case self::SUCCESS: + case log::SUCCESS: return "g-success"; - case self::INFO: + case log::INFO: return "g-info"; - case self::WARNING: + case log::WARNING: return "g-warning"; - case self::ERROR: + case log::ERROR: return "g-error"; } } diff --git a/modules/gallery/helpers/message.php b/modules/gallery/helpers/message.php index 1f69e2a9..64dd703c 100644 --- a/modules/gallery/helpers/message.php +++ b/modules/gallery/helpers/message.php @@ -28,7 +28,7 @@ class message_Core { * @param string $msg a detailed message */ static function success($msg) { - self::_add($msg, self::SUCCESS); + self::_add($msg, message::SUCCESS); } /** @@ -36,7 +36,7 @@ class message_Core { * @param string $msg a detailed message */ static function info($msg) { - self::_add($msg, self::INFO); + self::_add($msg, message::INFO); } /** @@ -44,7 +44,7 @@ class message_Core { * @param string $msg a detailed message */ static function warning($msg) { - self::_add($msg, self::WARNING); + self::_add($msg, message::WARNING); } /** @@ -52,7 +52,7 @@ class message_Core { * @param string $msg a detailed message */ static function error($msg) { - self::_add($msg, self::ERROR); + self::_add($msg, message::ERROR); } /** @@ -79,7 +79,7 @@ class message_Core { $messages = Session::instance()->get_once("messages", array()); foreach ($messages as $msg) { $msg[0] = str_replace("__CSRF__", access::csrf_token(), $msg[0]); - $buf[] = "<li class=\"" . self::severity_class($msg[1]) . "\">$msg[0]</li>"; + $buf[] = "<li class=\"" . message::severity_class($msg[1]) . "\">$msg[0]</li>"; } if ($buf) { return "<ul id=\"g-action-status\" class=\"g-message-block\">" . implode("", $buf) . "</ul>"; @@ -93,16 +93,16 @@ class message_Core { */ static function severity_class($severity) { switch($severity) { - case self::SUCCESS: + case message::SUCCESS: return "g-success"; - case self::INFO: + case message::INFO: return "g-info"; - case self::WARNING: + case message::WARNING: return "g-warning"; - case self::ERROR: + case message::ERROR: return "g-error"; } } diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php index 64d0d1d6..2b446daa 100644 --- a/modules/gallery/helpers/module.php +++ b/modules/gallery/helpers/module.php @@ -35,7 +35,7 @@ class module_Core { * @param integer $version */ static function set_version($module_name, $version) { - $module = self::get($module_name); + $module = module::get($module_name); if (!$module->loaded()) { $module->name = $module_name; $module->active = $module_name == "gallery"; // only gallery is active by default @@ -62,7 +62,7 @@ class module_Core { * not found */ static function info($module_name) { - $module_list = self::available(); + $module_list = module::available(); return isset($module_list->$module_name) ? $module_list->$module_name : false; } @@ -94,10 +94,10 @@ class module_Core { $modules->$module_name = new ArrayObject(parse_ini_file($file), ArrayObject::ARRAY_AS_PROPS); $m =& $modules->$module_name; - $m->installed = self::is_installed($module_name); - $m->active = self::is_active($module_name); + $m->installed = module::is_installed($module_name); + $m->active = module::is_active($module_name); $m->code_version = $m->version; - $m->version = self::get_version($module_name); + $m->version = module::get_version($module_name); $m->locked = false; if ($m->active && $m->version != $m->code_version) { @@ -107,7 +107,7 @@ class module_Core { // Lock certain modules $modules->gallery->locked = true; - $identity_module = self::get_var("gallery", "identity_provider", "user"); + $identity_module = module::get_var("gallery", "identity_provider", "user"); $modules->$identity_module->locked = true; $modules->ksort(); self::$available = $modules; @@ -258,7 +258,7 @@ class module_Core { call_user_func_array(array($installer_class, "activate"), array()); } - $module = self::get($module_name); + $module = module::get($module_name); if ($module->loaded()) { $module->active = true; $module->save(); @@ -285,7 +285,7 @@ class module_Core { call_user_func_array(array($installer_class, "deactivate"), array()); } - $module = self::get($module_name); + $module = module::get($module_name); if ($module->loaded()) { $module->active = false; $module->save(); @@ -312,7 +312,7 @@ class module_Core { } graphics::remove_rules($module_name); - $module = self::get($module_name); + $module = module::get($module_name); if ($module->loaded()) { $module->delete(); } @@ -503,13 +503,25 @@ class module_Core { * @param string $name */ static function clear_var($module_name, $name) { - $var = ORM::factory("var") + db::build() + ->delete("vars") ->where("module_name", "=", $module_name) ->where("name", "=", $name) - ->find(); - if ($var->loaded()) { - $var->delete(); - } + ->execute(); + + Cache::instance()->delete("var_cache"); + self::$var_cache = null; + } + + /** + * Remove all variables for this module. + * @param string $module_name + */ + static function clear_all_vars($module_name) { + db::build() + ->delete("vars") + ->where("module_name", "=", $module_name) + ->execute(); Cache::instance()->delete("var_cache"); self::$var_cache = null; @@ -520,6 +532,6 @@ class module_Core { * @param string $module_name */ static function get_version($module_name) { - return self::get($module_name)->version; + return module::get($module_name)->version; } } diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 78358b6b..0895c5f4 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -58,7 +58,7 @@ class movie_Core { } static function extract_frame($input_file, $output_file) { - $ffmpeg = self::find_ffmpeg(); + $ffmpeg = movie::find_ffmpeg(); if (empty($ffmpeg)) { throw new Exception("@todo MISSING_FFMPEG"); } @@ -103,7 +103,7 @@ class movie_Core { * Return the width, height, mime_type and extension of the given movie file. */ static function get_file_metadata($file_path) { - $ffmpeg = self::find_ffmpeg(); + $ffmpeg = movie::find_ffmpeg(); if (empty($ffmpeg)) { throw new Exception("@todo MISSING_FFMPEG"); } diff --git a/modules/gallery/helpers/site_status.php b/modules/gallery/helpers/site_status.php index 13c42dda..85f30dba 100644 --- a/modules/gallery/helpers/site_status.php +++ b/modules/gallery/helpers/site_status.php @@ -101,7 +101,7 @@ class site_status_Core { $buf = array(); foreach (ORM::factory("message")->find_all() as $msg) { $value = str_replace("__CSRF__", access::csrf_token(), $msg->value); - $buf[] = "<li class=\"" . self::severity_class($msg->severity) . "\">$value</li>"; + $buf[] = "<li class=\"" . site_status::severity_class($msg->severity) . "\">$value</li>"; } if ($buf) { @@ -116,16 +116,16 @@ class site_status_Core { */ static function severity_class($severity) { switch($severity) { - case self::SUCCESS: + case site_status::SUCCESS: return "g-success"; - case self::INFO: + case site_status::INFO: return "g-info"; - case self::WARNING: + case site_status::WARNING: return "g-warning"; - case self::ERROR: + case site_status::ERROR: return "g-error"; } } diff --git a/modules/gallery/libraries/ORM_MPTT.php b/modules/gallery/libraries/ORM_MPTT.php index d8d88e4e..f20fafa0 100644 --- a/modules/gallery/libraries/ORM_MPTT.php +++ b/modules/gallery/libraries/ORM_MPTT.php @@ -96,12 +96,16 @@ class ORM_MPTT_Core extends ORM { $item->reload()->delete(); } - // Deleting children has affected this item - $this->reload(); + // Deleting children has affected this item, but we'll reload it below. } $this->lock(); $this->reload(); // Assume that the prior lock holder may have changed this entry + if (!$this->loaded()) { + // Concurrent deletes may result in this item already being gone. Ignore it. + return; + } + try { db::build() ->update($this->table_name) diff --git a/modules/gallery/models/access_cache.php b/modules/gallery/models/access_cache.php index af1b5c6c..e730f25c 100644 --- a/modules/gallery/models/access_cache.php +++ b/modules/gallery/models/access_cache.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Access_Cache_Model extends ORM { +class Access_Cache_Model_Core extends ORM { } diff --git a/modules/gallery/models/access_intent.php b/modules/gallery/models/access_intent.php index e71f8c46..31711014 100644 --- a/modules/gallery/models/access_intent.php +++ b/modules/gallery/models/access_intent.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Access_Intent_Model extends ORM { +class Access_Intent_Model_Core extends ORM { } diff --git a/modules/gallery/models/cache.php b/modules/gallery/models/cache.php index 4a7e37f6..1c464d51 100644 --- a/modules/gallery/models/cache.php +++ b/modules/gallery/models/cache.php @@ -17,4 +17,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Cache_Model extends ORM {} +class Cache_Model_Core extends ORM {} diff --git a/modules/gallery/models/failed_auth.php b/modules/gallery/models/failed_auth.php index a541f435..649e4bc9 100644 --- a/modules/gallery/models/failed_auth.php +++ b/modules/gallery/models/failed_auth.php @@ -17,4 +17,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Failed_Auth_Model extends ORM {} +class Failed_Auth_Model_Core extends ORM {} diff --git a/modules/gallery/models/graphics_rule.php b/modules/gallery/models/graphics_rule.php index 49036b9c..09410af0 100644 --- a/modules/gallery/models/graphics_rule.php +++ b/modules/gallery/models/graphics_rule.php @@ -17,5 +17,5 @@ * 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_Rule_Model extends ORM { +class Graphics_Rule_Model_Core extends ORM { } diff --git a/modules/gallery/models/incoming_translation.php b/modules/gallery/models/incoming_translation.php index 45340c30..ff6a7160 100644 --- a/modules/gallery/models/incoming_translation.php +++ b/modules/gallery/models/incoming_translation.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Incoming_Translation_Model extends ORM { +class Incoming_Translation_Model_Core extends ORM { } diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 07f781d1..9016a04a 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -20,7 +20,7 @@ class Item_Model_Core extends ORM_MPTT { protected $children = "items"; protected $sorting = array(); - protected $data_file = null; + public $data_file = null; public function __construct($id=null) { parent::__construct($id); @@ -71,6 +71,11 @@ class Item_Model_Core extends ORM_MPTT { } public function delete($ignored_id=null) { + if (!$this->loaded()) { + // Concurrent deletes may result in this item already being gone. Ignore it. + return; + } + if ($this->id == 1) { $v = new Validation(array("id")); $v->add_error("id", "cant_delete_root_album"); @@ -166,8 +171,9 @@ class Item_Model_Core extends ORM_MPTT { */ public function file_url($full_uri=false) { $relative_path = "var/albums/" . $this->relative_path(); + $cache_buster = $this->_cache_buster($this->file_path()); return ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)) - . "?m={$this->updated}"; + . $cache_buster; } /** @@ -198,7 +204,7 @@ class Item_Model_Core extends ORM_MPTT { * photo: http://example.com/gallery3/var/albums/album1/photo.thumb.jpg */ public function thumb_url($full_uri=false) { - $cache_buster = "?m={$this->updated}"; + $cache_buster = $this->_cache_buster($this->thumb_path()); $relative_path = "var/thumbs/" . $this->relative_path(); $base = ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)); if ($this->is_photo()) { @@ -227,9 +233,9 @@ class Item_Model_Core extends ORM_MPTT { */ public function resize_url($full_uri=false) { $relative_path = "var/resizes/" . $this->relative_path(); + $cache_buster = $this->_cache_buster($this->resize_path()); return ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)) . - ($this->is_album() ? "/.album.jpg" : "") - . "?m={$this->updated}"; + ($this->is_album() ? "/.album.jpg" : "") . $cache_buster; } /** @@ -320,6 +326,7 @@ class Item_Model_Core extends ORM_MPTT { $this->updated = time(); if (!$this->loaded()) { // Create a new item. + module::event("item_before_create", $this); // Set a weight if it's missing. We don't do this in the constructor because it's not a // simple assignment. @@ -398,6 +405,7 @@ class Item_Model_Core extends ORM_MPTT { module::event("item_created", $this); } else { // Update an existing item + module::event("item_before_update", $item); // If any significant fields have changed, load up a copy of the original item and // keep it around. @@ -628,7 +636,7 @@ class Item_Model_Core extends ORM_MPTT { list ($height, $width) = $this->scale_dimensions($max); if ($center_vertically && $max) { // The constant is divide by 2 to calculate the file and 10 to convert to em - $margin_top = ($max - $height) / 20; + $margin_top = (int)(($max - $height) / 20); $extra_attrs["style"] = "margin-top: {$margin_top}em"; $extra_attrs["title"] = $this->title; } @@ -656,10 +664,10 @@ class Item_Model_Core extends ORM_MPTT { if ($height) { if (isset($max)) { if ($width > $height) { - $height = (int)($max * ($height / $width)); + $height = (int)($max * $height / $width); $width = $max; } else { - $width = (int)($max * ($width / $height)); + $width = (int)($max * $width / $height); $height = $max; } } @@ -700,10 +708,10 @@ class Item_Model_Core extends ORM_MPTT { $height = $this->height; if ($width > $max_size || $height > $max_size) { if ($width > $height) { - $height *= $max_size / $width; + $height = (int)($height * $max_size / $width); $width = $max_size; } else { - $width *= $max_size / $height; + $width = (int)($width * $max_size / $height); $height = $max_size; } } @@ -1022,4 +1030,8 @@ class Item_Model_Core extends ORM_MPTT { } return $data; } + + private function _cache_buster($path) { + return "?m=" . (string)(file_exists($path) ? filemtime($path) : 0); + } } diff --git a/modules/gallery/models/log.php b/modules/gallery/models/log.php index aa1a37ed..5d065313 100644 --- a/modules/gallery/models/log.php +++ b/modules/gallery/models/log.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Log_Model extends ORM { +class Log_Model_Core extends ORM { /** * @see ORM::__get() */ diff --git a/modules/gallery/models/message.php b/modules/gallery/models/message.php index 994d0cdb..3f84efd0 100644 --- a/modules/gallery/models/message.php +++ b/modules/gallery/models/message.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Message_Model extends ORM { +class Message_Model_Core extends ORM { } diff --git a/modules/gallery/models/module.php b/modules/gallery/models/module.php index dc181849..e54613d1 100644 --- a/modules/gallery/models/module.php +++ b/modules/gallery/models/module.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Module_Model extends ORM { +class Module_Model_Core extends ORM { } diff --git a/modules/gallery/models/outgoing_translation.php b/modules/gallery/models/outgoing_translation.php index 43f56dce..cd580bed 100644 --- a/modules/gallery/models/outgoing_translation.php +++ b/modules/gallery/models/outgoing_translation.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Outgoing_Translation_Model extends ORM { +class Outgoing_Translation_Model_Core extends ORM { } diff --git a/modules/gallery/models/permission.php b/modules/gallery/models/permission.php index b6b544d5..51bd95e7 100644 --- a/modules/gallery/models/permission.php +++ b/modules/gallery/models/permission.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Permission_Model extends ORM { +class Permission_Model_Core extends ORM { } diff --git a/modules/gallery/models/task.php b/modules/gallery/models/task.php index 4888a734..4d435101 100644 --- a/modules/gallery/models/task.php +++ b/modules/gallery/models/task.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Task_Model extends ORM { +class Task_Model_Core extends ORM { public function get($key, $default=null) { $context = unserialize($this->context); if (array_key_exists($key, $context)) { diff --git a/modules/gallery/models/theme.php b/modules/gallery/models/theme.php index 523542f9..50fd04fd 100644 --- a/modules/gallery/models/theme.php +++ b/modules/gallery/models/theme.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Theme_Model extends ORM { +class Theme_Model_Core extends ORM { }
\ No newline at end of file diff --git a/modules/gallery/models/var.php b/modules/gallery/models/var.php index a79d0048..f21486ee 100644 --- a/modules/gallery/models/var.php +++ b/modules/gallery/models/var.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Var_Model extends ORM { +class Var_Model_Core extends ORM { } diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php index 90c54e3c..264a2128 100644 --- a/modules/gallery/tests/Item_Model_Test.php +++ b/modules/gallery/tests/Item_Model_Test.php @@ -406,6 +406,29 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { return; // pass } $this->assert_true(false, "Shouldn't get here"); + } + + public function urls_test() { + $photo = test::random_photo(); + $this->assert_true( + preg_match("|http://./var/resizes/name_\d+\.jpg\?m=\d+|", $photo->resize_url()), + $photo->resize_url() . " is malformed"); + $this->assert_true( + preg_match("|http://./var/thumbs/name_\d+\.jpg\?m=\d+|", $photo->thumb_url()), + $photo->thumb_url() . " is malformed"); + $this->assert_true( + preg_match("|http://./var/albums/name_\d+\.jpg\?m=\d+|", $photo->file_url()), + $photo->file_url() . " is malformed"); + // Albums have special thumbnails. Empty album has cachebuster of 0 since it has no thumbnail + $album = test::random_album(); + $this->assert_true( + preg_match("|http://./var/thumbs/name_\d+/\.album\.jpg\?m=0|", $album->thumb_url()), + $album->thumb_url() . " is malformed"); + + $photo = test::random_photo($album); + $this->assert_true( + preg_match("|http://./var/thumbs/name_\d+/\.album\.jpg\?m=\d+|", $album->thumb_url()), + $album->thumb_url() . " is malformed"); } } diff --git a/modules/gallery/tests/Var_Test.php b/modules/gallery/tests/Var_Test.php index b3492c71..292fe2f1 100644 --- a/modules/gallery/tests/Var_Test.php +++ b/modules/gallery/tests/Var_Test.php @@ -19,31 +19,37 @@ */ class Var_Test extends Gallery_Unit_Test_Case { public function add_parameter_test() { - module::set_var("gallery", "Parameter", "original value"); - $this->assert_equal("original value", module::get_var("gallery", "Parameter")); + module::set_var("Var_Test", "Parameter", "original value"); + $this->assert_equal("original value", module::get_var("Var_Test", "Parameter")); - module::set_var("gallery", "Parameter", "updated value"); - $this->assert_equal("updated value", module::get_var("gallery", "Parameter")); + module::set_var("Var_Test", "Parameter", "updated value"); + $this->assert_equal("updated value", module::get_var("Var_Test", "Parameter")); } public function clear_parameter_test() { - module::set_var("gallery", "Parameter", "original value"); - $this->assert_equal("original value", module::get_var("gallery", "Parameter")); + module::set_var("Var_Test", "Parameter", "original value"); + module::clear_var("Var_Test", "Parameter"); + $this->assert_equal(null, module::get_var("Var_Test", "Parameter")); + } - module::clear_var("gallery", "Parameter"); - $this->assert_equal(null, module::get_var("gallery", "Parameter")); + public function clear_all_module_parameters_test() { + module::set_var("Var_Test", "Parameter1", "original value"); + module::set_var("Var_Test", "Parameter2", "original value"); + module::clear_all_vars("Var_Test"); + $this->assert_equal(null, module::get_var("Var_Test", "Parameter1")); + $this->assert_equal(null, module::get_var("Var_Test", "Parameter2")); } public function incr_parameter_test() { - module::set_var("gallery", "Parameter", "original value"); - module::incr_var("gallery", "Parameter"); - $this->assert_equal("1", module::get_var("gallery", "Parameter")); + module::set_var("Var_Test", "Parameter", "original value"); + module::incr_var("Var_Test", "Parameter"); + $this->assert_equal("1", module::get_var("Var_Test", "Parameter")); - module::set_var("gallery", "Parameter", "2"); - module::incr_var("gallery", "Parameter", "9"); - $this->assert_equal("11", module::get_var("gallery", "Parameter")); + module::set_var("Var_Test", "Parameter", "2"); + module::incr_var("Var_Test", "Parameter", "9"); + $this->assert_equal("11", module::get_var("Var_Test", "Parameter")); - module::incr_var("gallery", "NonExistent", "9"); - $this->assert_equal(null, module::get_var("gallery", "NonExistent")); + module::incr_var("Var_Test", "NonExistent", "9"); + $this->assert_equal(null, module::get_var("Var_Test", "NonExistent")); } }
\ No newline at end of file diff --git a/modules/gallery/tests/selenium/Add_Album.html b/modules/gallery/tests/selenium/Add_Album.html deleted file mode 100644 index ccd4d0b7..00000000 --- a/modules/gallery/tests/selenium/Add_Album.html +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>AddAlbum</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">AddAlbum</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/index.php/albums/1</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>link=Add album</td> - <td></td> -</tr> -<tr> - <td>type</td> - <td>name</td> - <td>seleniumtest</td> -</tr> -<tr> - <td>type</td> - <td>title</td> - <td>Selenium Test Album</td> -</tr> -<tr> - <td>type</td> - <td>description</td> - <td>Test</td> -</tr> -<tr> - <td>click</td> - <td>//button[@type='button']</td> - <td></td> -</tr> -<tr> - <td>assertTextPresent</td> - <td>Selenium Test Album</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/modules/gallery/tests/selenium/Add_Comment.html b/modules/gallery/tests/selenium/Add_Comment.html deleted file mode 100644 index 054e7597..00000000 --- a/modules/gallery/tests/selenium/Add_Comment.html +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>Add comment</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">Add comment</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/index.php/albums/1</td> - <td></td> -</tr> -<tr> - <td>clickAndWait</td> - <td>g-photo-id-2</td> - <td></td> -</tr> -<tr> - <td>type</td> - <td>g-author</td> - <td>Test</td> -</tr> -<tr> - <td>type</td> - <td>g-email</td> - <td>test@gmail.com</td> -</tr> -<tr> - <td>type</td> - <td>g-text</td> - <td>This is a selenium test comment.</td> -</tr> -<tr> - <td>click</td> - <td>//button[@type='submit']</td> - <td></td> -</tr> -<tr> - <td>assertTextPresent</td> - <td>This is a selenium test comment.</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/modules/gallery/tests/selenium/Add_Item.html b/modules/gallery/tests/selenium/Add_Item.html deleted file mode 100644 index 741dff65..00000000 --- a/modules/gallery/tests/selenium/Add_Item.html +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>AddItem</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">AddItem</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/index.php/albums/1</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>link=Add an item</td> - <td></td> -</tr> -<tr> - <td>type</td> - <td>name</td> - <td>seleniumitem.jpg</td> -</tr> -<tr> - <td>type</td> - <td>title</td> - <td>Selenium Item</td> -</tr> -<tr> - <td>type</td> - <td>description</td> - <td>Test item</td> -</tr> -<tr> - <td>type</td> - <td>file</td> - <td>/Users/ckieffer/Sites/gallery3.0/core/tests/images/DSC_0003.jpg</td> -</tr> -<tr> - <td>click</td> - <td>//button[@type='button']</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>link=X</td> - <td></td> -</tr> -<tr> - <td>assertTextPresent</td> - <td>Selenium Item</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/modules/gallery/tests/selenium/Login.html b/modules/gallery/tests/selenium/Login.html deleted file mode 100644 index d2e45c63..00000000 --- a/modules/gallery/tests/selenium/Login.html +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>Login</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">Login</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/index.php/albums/1</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>g-login-link</td> - <td></td> -</tr> -<tr> - <td>type</td> - <td>g-name</td> - <td>admin</td> -</tr> -<tr> - <td>type</td> - <td>g-password</td> - <td>admin</td> -</tr> -<tr> - <td>clickAndWait</td> - <td>//button[@type='button']</td> - <td></td> -</tr> -<tr> - <td>clickAndWait</td> - <td>g-user-profile-link</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/modules/gallery/views/admin_advanced_settings.html.php b/modules/gallery/views/admin_advanced_settings.html.php index edaeecaf..d4f646f8 100644 --- a/modules/gallery/views/admin_advanced_settings.html.php +++ b/modules/gallery/views/admin_advanced_settings.html.php @@ -9,6 +9,7 @@ <li class="g-warning"><?= t("Change these values at your own risk!") ?></li> </ul> + <?= t("Filter:") ?> <input id="g-admin-advanced-settings-filter" type="text"></input> <div class="g-block-content"> <table> <tr> @@ -17,7 +18,7 @@ <th> <?= t("Value") ?></th> </tr> <? foreach ($vars as $var): ?> - <tr class="<?= text::alternate("g-odd", "g-even") ?>"> + <tr class="setting-row <?= text::alternate("g-odd", "g-even") ?>"> <td> <?= $var->module_name ?> </td> <td> <?= html::clean($var->name) ?> </td> <td> @@ -35,4 +36,22 @@ <? endforeach ?> </table> </div> + + <script> + $(document).ready(function() { + $("#g-admin-advanced-settings-filter").keyup(function() { + var filter = $(this).attr("value"); + if (filter) { + $("tr.setting-row").fadeOut("fast"); + $("tr.setting-row td:contains(" + filter + "), tr.setting-row td a:contains(" + filter + ")").each(function() { + if ($(this).children().length < 1) { + $(this).closest("tr").stop().show(); + } + }); + } else { + $("tr.setting-row").show(); + } + }); + }); + </script> </div> diff --git a/modules/gallery/views/admin_block_platform.html.php b/modules/gallery/views/admin_block_platform.html.php index 379ab0aa..9a594fa5 100644 --- a/modules/gallery/views/admin_block_platform.html.php +++ b/modules/gallery/views/admin_block_platform.html.php @@ -16,7 +16,7 @@ <?= t("MySQL: %mysql_version", array("mysql_version" => Database::instance()->query("SELECT version() as v")->current()->v)) ?> </li> <li> - <?= t("Server load: %load_average", array("load_average" => $load_average)) ?> + <?= t("Server load: %load_average", array("load_average" => join(" ", sys_getloadavg()))) ?> </li> <li> <?= t("Graphics toolkit: %toolkit", array("toolkit" => module::get_var("gallery", "graphics_toolkit"))) ?> diff --git a/modules/gallery_unit_test/controllers/gallery_unit_test.php b/modules/gallery_unit_test/controllers/gallery_unit_test.php index e241e1dd..c4a891ba 100644 --- a/modules/gallery_unit_test/controllers/gallery_unit_test.php +++ b/modules/gallery_unit_test/controllers/gallery_unit_test.php @@ -132,6 +132,7 @@ class Gallery_Unit_Test_Controller extends Controller { graphics::choose_default_toolkit(); $filter = count($_SERVER["argv"]) > 2 ? $_SERVER["argv"][2] : null; + set_time_limit(300); print new Unit_Test($modules, $filter); } catch (ORM_Validation_Exception $e) { print "Validation Exception: {$e->getMessage()}\n"; diff --git a/modules/image_block/helpers/image_block_block.php b/modules/image_block/helpers/image_block_block.php index da6e8782..0a53672c 100644 --- a/modules/image_block/helpers/image_block_block.php +++ b/modules/image_block/helpers/image_block_block.php @@ -29,16 +29,24 @@ class image_block_block_Core { // The random_query approach is flawed and doesn't always return a // result when there actually is one. Retry a *few* times. // @todo Consider another fallback if further optimizations are necessary. - $attempts = 0; - do { - $item = item::random_query()->where("type", "!=", "album")->find_all(1)->current(); - } while (!$item && $attempts++ < 3); - if ($item && $item->loaded()) { + $image_count = module::get_var("image_block", "image_count"); + $items = array(); + for ($i = 0; $i < $image_count; $i++) { + $attempts = 0; + $item = null; + do { + $item = item::random_query()->where("type", "!=", "album")->find_all(1)->current(); + } while (!$item && $attempts++ < 3); + if ($item) { + $items[] = $item; + } + } + if ($items) { $block = new Block(); $block->css_id = "g-image-block"; $block->title = t("Random image"); $block->content = new View("image_block_block.html"); - $block->content->item = $item; + $block->content->items = $items; } break; } diff --git a/modules/image_block/helpers/image_block_installer.php b/modules/image_block/helpers/image_block_installer.php new file mode 100644 index 00000000..62c38ba4 --- /dev/null +++ b/modules/image_block/helpers/image_block_installer.php @@ -0,0 +1,34 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2010 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 image_block_installer { + + static function install() { + module::set_var("image_block", "image_count", "1"); + module::set_version("image_block", $version = 2); + } + + static function upgrade($version) { + $db = Database::instance(); + if ($version == 1) { + module::set_var("image_block", "image_count", "1"); + module::set_version("image_block", $version = 2); + } + } +} diff --git a/modules/image_block/module.info b/modules/image_block/module.info index e6d85048..b92b83df 100644 --- a/modules/image_block/module.info +++ b/modules/image_block/module.info @@ -1,3 +1,3 @@ name = "Image Block" description = "Display a random image in the sidebar" -version = 1 +version = 2 diff --git a/modules/image_block/views/image_block_block.html.php b/modules/image_block/views/image_block_block.html.php index 68d5fa89..2a57c395 100644 --- a/modules/image_block/views/image_block_block.html.php +++ b/modules/image_block/views/image_block_block.html.php @@ -1,6 +1,8 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> +<? foreach ($items as $item): ?> <div class="g-image-block"> <a href="<?= $item->url() ?>"> <?= $item->thumb_img(array("class" => "g-thumbnail")) ?> </a> </div> +<? endforeach ?> diff --git a/modules/notification/models/pending_notification.php b/modules/notification/models/pending_notification.php index c447620e..5857ce8c 100644 --- a/modules/notification/models/pending_notification.php +++ b/modules/notification/models/pending_notification.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Pending_Notification_Model extends ORM { +class Pending_Notification_Model_Core extends ORM { }
\ No newline at end of file diff --git a/modules/notification/models/subscription.php b/modules/notification/models/subscription.php index 043de45c..273b6ad9 100644 --- a/modules/notification/models/subscription.php +++ b/modules/notification/models/subscription.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Subscription_Model extends ORM { +class Subscription_Model_Core extends ORM { }
\ No newline at end of file diff --git a/modules/rest/controllers/rest.php b/modules/rest/controllers/rest.php index a721ff2b..c4e0fda4 100644 --- a/modules/rest/controllers/rest.php +++ b/modules/rest/controllers/rest.php @@ -86,6 +86,9 @@ class Rest_Controller extends Controller { } $request->url = url::abs_current(true); + if ($suffix = Kohana::config('core.url_suffix')) { + $request->url = substr($request->url, 0, strlen($request->url) - strlen($suffix)); + } rest::set_active_user($request->access_key); diff --git a/modules/rest/helpers/rest.php b/modules/rest/helpers/rest.php index d5ed0452..58943700 100644 --- a/modules/rest/helpers/rest.php +++ b/modules/rest/helpers/rest.php @@ -122,7 +122,12 @@ class rest_Core { * @return mixed the corresponding object (usually a model of some kind) */ static function resolve($url) { - $relative_url = substr($url, strlen(url::abs_site("rest"))); + if ($suffix = Kohana::config('core.url_suffix')) { + $relative_url = substr($url, strlen(url::abs_site("rest")) - strlen($suffix)); + } else { + $relative_url = substr($url, strlen(url::abs_site("rest"))); + } + $path = parse_url($relative_url, PHP_URL_PATH); $components = explode("/", $path, 3); diff --git a/modules/rest/models/user_access_key.php b/modules/rest/models/user_access_key.php index 1da0f5eb..93c3cf7f 100644 --- a/modules/rest/models/user_access_key.php +++ b/modules/rest/models/user_access_key.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class User_Access_Key_Model extends ORM { +class User_Access_Key_Model_Core extends ORM { } diff --git a/modules/search/models/search_record.php b/modules/search/models/search_record.php index fe9b758f..77290903 100644 --- a/modules/search/models/search_record.php +++ b/modules/search/models/search_record.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Search_Record_Model extends ORM { +class Search_Record_Model_Core extends ORM { function item() { return model_cache::get("item", $this->item_id); } diff --git a/modules/server_add/models/server_add_file.php b/modules/server_add/models/server_add_file.php index 83bde344..92b9f6de 100644 --- a/modules/server_add/models/server_add_file.php +++ b/modules/server_add/models/server_add_file.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Server_Add_File_Model extends ORM { +class Server_Add_File_Model_Core extends ORM { } diff --git a/modules/tag/controllers/admin_tags.php b/modules/tag/controllers/admin_tags.php index 0c82579b..99743a8e 100644 --- a/modules/tag/controllers/admin_tags.php +++ b/modules/tag/controllers/admin_tags.php @@ -52,7 +52,6 @@ class Admin_Tags_Controller extends Admin_Controller { $form = tag::get_delete_form($tag); if ($form->validate()) { $name = $tag->name; - db::build()->delete("items_tags")->where("tag_id", "=", $tag->id)->execute(); $tag->delete(); message::success(t("Deleted tag %tag_name", array("tag_name" => $name))); log::success("tags", t("Deleted tag %tag_name", array("tag_name" => $name))); diff --git a/modules/tag/helpers/tag_event.php b/modules/tag/helpers/tag_event.php index 0cc2170c..829089c4 100644 --- a/modules/tag/helpers/tag_event.php +++ b/modules/tag/helpers/tag_event.php @@ -62,6 +62,12 @@ class tag_event_Core { static function item_deleted($item) { tag::clear_all($item); + if (!batch::in_progress()) { + tag::compact(); + } + } + + static function batch_complete() { tag::compact(); } @@ -88,6 +94,7 @@ class tag_event_Core { tag::add($item, trim($tag_name)); } } + module::event("item_related_update", $item); tag::compact(); } @@ -109,7 +116,7 @@ class tag_event_Core { if (!isset($group->uploadify)) { return; } - + $group = $form->add_photos; $group->input("tags") ->label(t("Add tags to all uploaded files")) @@ -132,7 +139,7 @@ class tag_event_Core { if (!isset($group->uploadify)) { return; } - + foreach (explode(",", $form->add_photos->tags->value) as $tag_name) { $tag_name = trim($tag_name); if ($tag_name) { diff --git a/modules/tag/helpers/tag_task.php b/modules/tag/helpers/tag_task.php new file mode 100644 index 00000000..7bf50546 --- /dev/null +++ b/modules/tag/helpers/tag_task.php @@ -0,0 +1,97 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2010 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 tag_task_Core { + + static function available_tasks() { + $tasks[] = Task_Definition::factory() + ->callback("tag_task::clean_up_tags") + ->name(t("Clean up tags")) + ->description(t("Correct tag counts and remove tags with no items")) + ->severity(log::SUCCESS); + return $tasks; + } + + /** + * Fix up tag counts and delete any tags that have no associated items. + * @param Task_Model the task + */ + static function clean_up_tags($task) { + $errors = array(); + try { + $start = microtime(true); + $last_tag_id = $task->get("last_tag_id", null); + $current = 0; + $total = 0; + + switch ($task->get("mode", "init")) { + case "init": + $task->set("total", ORM::factory("tag")->count_all()); + $task->set("mode", "clean_up_tags"); + $task->set("completed", 0); + $task->set("last_tag_id", 0); + + case "clean_up_tags": + $completed = $task->get("completed"); + $total = $task->get("total"); + $last_tag_id = $task->get("last_tag_id"); + $tags = ORM::factory("tag")->where("id", ">", $last_tag_id)->find_all(25); + Kohana_Log::add("error",print_r(Database::instance()->last_query(),1)); + while ($current < $total && microtime(true) - $start < 1 && $tag = $tags->current()) { + $last_tag_id = $tag->id; + $real_count = $tag->items_count(); + if ($tag->count != $real_count) { + $tag->count = $real_count; + if ($tag->count) { + $task->log( + "Fixing count for tag {$tag->name} (id: {$tag->id}, new count: {$tag->count})"); + $tag->save(); + } else { + $task->log("Deleting empty tag {$tag->name} ({$tag->id})"); + $tag->delete(); + } + } + + $completed++; + $tags->next(); + } + $task->percent_complete = $completed / $total * 100; + $task->set("completed", $completed); + $task->set("last_tag_id", $last_tag_id); + } + + $task->status = t2("Examined %count tag", "Examined %count tags", $completed); + + if ($completed == $total) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + } + } catch (Exception $e) { + Kohana_Log::add("error",(string)$e); + $task->done = true; + $task->state = "error"; + $task->status = $e->getMessage(); + $errors[] = (string)$e; + } + if ($errors) { + $task->log($errors); + } + } +}
\ No newline at end of file diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php index b5bb857f..44a4c904 100644 --- a/modules/tag/models/tag.php +++ b/modules/tag/models/tag.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Tag_Model extends ORM { +class Tag_Model_Core extends ORM { protected $has_and_belongs_to_many = array("items"); /** @@ -58,8 +58,7 @@ class Tag_Model extends ORM { /** * Overload ORM::save() to trigger an item_related_update event for all items that are related - * to this tag. Since items can be added or removed as part of the save, we need to trigger an - * event for the union of all related items before and after the save. + * to this tag. */ public function save() { $related_item_ids = array(); @@ -71,20 +70,16 @@ class Tag_Model extends ORM { $related_item_ids[$row->item_id] = 1; } - $result = parent::save(); - - foreach (db::build() - ->select("item_id") - ->from("items_tags") - ->where("tag_id", "=", $this->id) - ->execute() as $row) { - $related_item_ids[$row->item_id] = 1; + if (isset($this->changed_relations["items"])) { + $changed = array_merge( + array_diff($this->changed_relations["items"], $this->object_relations["items"]), + array_diff($this->object_relations["items"], $this->changed_relations["items"])); } - if ($related_item_ids) { - foreach (ORM::factory("item") - ->where("id", "IN", array_keys($related_item_ids)) - ->find_all() as $item) { + $result = parent::save(); + + if (!empty($changed)) { + foreach (ORM::factory("item")->where("id", "IN", $changed)->find_all() as $item) { module::event("item_related_update", $item); } } @@ -94,7 +89,7 @@ class Tag_Model extends ORM { /** * Overload ORM::delete() to trigger an item_related_update event for all items that are - * related to this tag. + * related to this tag, and delete all items_tags relationships. */ public function delete($ignored_id=null) { $related_item_ids = array(); @@ -106,6 +101,7 @@ class Tag_Model extends ORM { $related_item_ids[$row->item_id] = 1; } + db::build()->delete("items_tags")->where("tag_id", "=", $this->id)->execute(); $result = parent::delete(); if ($related_item_ids) { diff --git a/modules/user/models/group.php b/modules/user/models/group.php index b27c7250..17d9320b 100644 --- a/modules/user/models/group.php +++ b/modules/user/models/group.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Group_Model extends ORM implements Group_Definition { +class Group_Model_Core extends ORM implements Group_Definition { protected $has_and_belongs_to_many = array("users"); /** diff --git a/modules/user/models/user.php b/modules/user/models/user.php index b28288be..55bb3d6a 100644 --- a/modules/user/models/user.php +++ b/modules/user/models/user.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class User_Model extends ORM implements User_Definition { +class User_Model_Core extends ORM implements User_Definition { protected $has_and_belongs_to_many = array("groups"); protected $password_length = null; diff --git a/system/libraries/ORM.php b/system/libraries/ORM.php index 4dd2eaf0..eb34221c 100644 --- a/system/libraries/ORM.php +++ b/system/libraries/ORM.php @@ -1002,7 +1002,11 @@ class ORM_Core { */ public function reload() { - return $this->find($this->object[$this->primary_key]); + if ($this->_loaded) { + return $this->find($this->object[$this->primary_key]); + } else { + return $this->clear(); + } } /** diff --git a/system/libraries/drivers/Image/ImageMagick.php b/system/libraries/drivers/Image/ImageMagick.php index 31862f75..55c0ba24 100644 --- a/system/libraries/drivers/Image/ImageMagick.php +++ b/system/libraries/drivers/Image/ImageMagick.php @@ -133,7 +133,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // Set the IM geometry based on the properties $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -crop '.$geometry.'! '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; |