From 21feda51e54bfb89f3a2bf205b64e603f4308f5f Mon Sep 17 00:00:00 2001 From: rWatcher Date: Mon, 12 Sep 2011 20:42:49 -0400 Subject: [PATCH 1/3] Initial commit of the Quotas module. --- .../quotas/controllers/admin_quotas.php | 152 ++++++++++++++++++ 3.0/modules/quotas/helpers/quotas_event.php | 110 +++++++++++++ .../quotas/helpers/quotas_installer.php | 47 ++++++ 3.0/modules/quotas/helpers/quotas_task.php | 126 +++++++++++++++ 3.0/modules/quotas/helpers/quotas_theme.php | 35 ++++ 3.0/modules/quotas/models/groups_quota.php | 21 +++ .../quotas/models/users_space_usage.php | 131 +++++++++++++++ 3.0/modules/quotas/module.info | 7 + .../quotas/views/admin_quotas.html.php | 98 +++++++++++ .../quotas/controllers/admin_quotas.php | 152 ++++++++++++++++++ 3.1/modules/quotas/helpers/quotas_event.php | 110 +++++++++++++ .../quotas/helpers/quotas_installer.php | 47 ++++++ 3.1/modules/quotas/helpers/quotas_task.php | 126 +++++++++++++++ 3.1/modules/quotas/helpers/quotas_theme.php | 35 ++++ 3.1/modules/quotas/models/groups_quota.php | 21 +++ .../quotas/models/users_space_usage.php | 131 +++++++++++++++ 3.1/modules/quotas/module.info | 7 + .../quotas/views/admin_quotas.html.php | 98 +++++++++++ 18 files changed, 1454 insertions(+) create mode 100644 3.0/modules/quotas/controllers/admin_quotas.php create mode 100644 3.0/modules/quotas/helpers/quotas_event.php create mode 100644 3.0/modules/quotas/helpers/quotas_installer.php create mode 100644 3.0/modules/quotas/helpers/quotas_task.php create mode 100644 3.0/modules/quotas/helpers/quotas_theme.php create mode 100644 3.0/modules/quotas/models/groups_quota.php create mode 100644 3.0/modules/quotas/models/users_space_usage.php create mode 100644 3.0/modules/quotas/module.info create mode 100644 3.0/modules/quotas/views/admin_quotas.html.php create mode 100644 3.1/modules/quotas/controllers/admin_quotas.php create mode 100644 3.1/modules/quotas/helpers/quotas_event.php create mode 100644 3.1/modules/quotas/helpers/quotas_installer.php create mode 100644 3.1/modules/quotas/helpers/quotas_task.php create mode 100644 3.1/modules/quotas/helpers/quotas_theme.php create mode 100644 3.1/modules/quotas/models/groups_quota.php create mode 100644 3.1/modules/quotas/models/users_space_usage.php create mode 100644 3.1/modules/quotas/module.info create mode 100644 3.1/modules/quotas/views/admin_quotas.html.php diff --git a/3.0/modules/quotas/controllers/admin_quotas.php b/3.0/modules/quotas/controllers/admin_quotas.php new file mode 100644 index 00000000..ac5bf8b5 --- /dev/null +++ b/3.0/modules/quotas/controllers/admin_quotas.php @@ -0,0 +1,152 @@ +page_title = t("Users and groups"); + $view->page_type = "collection"; + $view->page_subtype = "admin_users_quotas"; + $view->content = new View("admin_quotas.html"); + + $page_size = module::get_var("user", "page_size", 10); + $page = Input::instance()->get("page", "1"); + $builder = db::build(); + $user_count = $builder->from("users")->count_records(); + + $view->page = $page; + $view->page_size = $page_size; + $view->children_count = $user_count; + $view->max_pages = ceil($view->children_count / $view->page_size); + + $view->content->pager = new Pagination(); + $view->content->pager->initialize( + array("query_string" => "page", + "total_items" => $user_count, + "items_per_page" => $page_size, + "style" => "classic")); + + if ($page < 1) { + url::redirect(url::merge(array("page" => 1))); + } else if ($page > $view->content->pager->total_pages) { + url::redirect(url::merge(array("page" => $view->content->pager->total_pages))); + } + + $view->content->users = ORM::factory("user") + ->order_by("users.name", "ASC") + ->find_all($page_size, $view->content->pager->sql_offset); + $view->content->groups = ORM::factory("group")->order_by("name", "ASC")->find_all(); + $view->content->quota_options = $this->_get_quota_settings_form(); + print $view; + } + + public function form_group_quota($id) { + // Display the form for setting a quota for the specified group ($id). + $group = ORM::factory("group", $id); + if (empty($group)) { + throw new Kohana_404_Exception(); + } + print $this->_get_edit_group_quota($group); + } + + static function _get_edit_group_quota($group) { + // Generate a form for setting a quota for the specified group ($group). + $record = ORM::factory("groups_quota")->where("group_id", "=", $group->id)->find(); + $form = new Forge( + "admin/quotas/edit_quota/$group->id", "", "post", array("id" => "g-edit-quota-form")); + $group = $form->group("edit_quota")->label(t("Edit group quota")); + $group->input("group_quota")->label(t("Limit (MB)"))->id("g-group_quota")->value($record->storage_limit / 1024 / 1024) + ->error_messages("required", t("A value is required")); + + $group->submit("")->value(t("Save")); + return $form; + } + + public function edit_quota($id) { + // Save the specified quota to the database. + access::verify_csrf(); + + $group = ORM::factory("group", $id); + if (empty($group)) { + throw new Kohana_404_Exception(); + } + + $record = ORM::factory("groups_quota")->where("group_id", "=", $group->id)->find(); + $form = $this->_get_edit_group_quota($group); + try { + $valid = $form->validate(); + $record->group_id = $id; + $record->storage_limit = $form->edit_quota->inputs["group_quota"]->value * 1024 * 1024; + } catch (ORM_Validation_Exception $e) { + // Translate ORM validation errors into form error messages + foreach ($e->validation->errors() as $key => $error) { + $form->edit_quota->inputs[$key]->add_error($error, 1); + } + $valid = false; + } + + if ($valid) { + $record->save(); + message::success(t("Limit for group %group_name set", array("group_name" => $group->name))); + json::reply(array("result" => "success")); + } else { + json::reply(array("result" => "error", "html" => (string) $form)); + } + } + + private function _get_quota_settings_form() { + // Make a new form to allow the admin to specify how the system should calculate a user's quota. + $form = new Forge("admin/quotas/saveprefs", "", "post", + array("id" => "g-quotas-admin-form")); + + // Setup a checkbox for the form. + $quota_options["use_all_sizes"] = array(t("Count resizes and thumbnails towards a users limit?"), module::get_var("quotas", "use_all_sizes")); + $add_links = $form->group("quota_preferences"); + $add_links->checklist("quota_preferences_list") + ->options($quota_options); + + // Add a save button to the form. + $form->submit("save_preferences")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + public function saveprefs() { + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + // Figure out which boxes where checked + $checkboxes_array = Input::instance()->post("quota_preferences_list"); + $use_all_sizes = false; + for ($i = 0; $i < count($checkboxes_array); $i++) { + if ($checkboxes_array[$i] == "use_all_sizes") { + $use_all_sizes = true; + } + } + + // Save Settings. + module::set_var("quotas", "use_all_sizes", $use_all_sizes); + message::success(t("Your Selection Has Been Saved.")); + + // Load Admin page. + url::redirect("admin/quotas"); + } +} diff --git a/3.0/modules/quotas/helpers/quotas_event.php b/3.0/modules/quotas/helpers/quotas_event.php new file mode 100644 index 00000000..aa832fd1 --- /dev/null +++ b/3.0/modules/quotas/helpers/quotas_event.php @@ -0,0 +1,110 @@ +get("content_menu") + ->append(Menu::factory("link") + ->id("quotas") + ->label(t("User quotas")) + ->url(url::site("admin/quotas"))); + } + + static function user_created($user) { + // Set up some default values whenever a new user is created. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $user->id)->find(); + if (!$record->loaded()) { + $record->owner_id = $user->id; + $record->fullsize = 0; + $record->resize = 0; + $record->thumb = 0; + $record->save(); + } + } + + static function user_before_delete($user) { + // When deleting a user, all of that user's items get re-assigned to the admin account, + // so the file sizes need to be reassigned to the admin user as well. + $admin = identity::admin_user(); + $admin_record = ORM::factory("users_space_usage")->where("owner_id", "=", $admin->id)->find(); + $deleted_user_record = ORM::factory("users_space_usage")->where("owner_id", "=", $user->id)->find(); + if ($deleted_user_record->loaded()) { + $admin_record->fullsize = $admin_record->fullsize + $deleted_user_record->fullsize; + $admin_record->resize = $admin_record->resize + $deleted_user_record->resize; + $admin_record->thumb = $admin_record->thumb + $deleted_user_record->thumb; + $admin_record->save(); + $deleted_user_record->delete(); + } + } + + static function item_before_create($item) { + // When creating a new item, make sure it's file size won't put the user over their limit. + // If it does, throw an error, which will prevent gallery from accepting the file. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + if (!$record->loaded()) { + $record->owner_id = $item->owner_id; + } + if ($record->get_usage_limit() == 0) { + return; + } + if ((filesize($item->data_file) + $record->current_usage()) > $record->get_usage_limit()) { + throw new Exception($item->name . " rejected, user #" . $item->owner_id . " over limit."); + } + } + + static function item_created($item) { + // When a new item is created, add it's file size to the users_space_usage table. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + if (!$record->loaded()) { + $record->owner_id = $item->owner_id; + $record->fullsize = 0; + $record->resize = 0; + $record->thumb = 0; + $record->save(); + } + $record->add_item($item); + } + + static function item_before_delete($item) { + // When an item is deleted, remove it's file size from the users_space_usage table. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + $record->remove_item($item); + } + + // I can't monitor the item_before_update / item_updated events to adjust for rotated photos, + // because they fire when a new photo is uploaded (before it's created) and cause all kinds of weirdness. + // So instead, I'm using graphics_rotate to detect a rotate and remove the existing file sizes, and + // item_updated_data_file to add in the new data file sizes. + // Does item_updated_data_file fire for any other reason? (watermarking? renaming/moving/deleting/keeporiginal do not cause updated_data_file.) + static function graphics_rotate($input_file, $output_file, $options) { + // Remove the current item's file size from the quotas table. + $item = item::find_by_path(substr(str_replace(VARPATH, "", $input_file), strpos(str_replace(VARPATH, "", $input_file), "/")+1)); + if ($item->loaded()) { + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + $record->remove_item($item); + } + } + + static function item_updated_data_file($item) { + // Add the current item's file size into the quotas table. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + $record->add_item($item); + } +} diff --git a/3.0/modules/quotas/helpers/quotas_installer.php b/3.0/modules/quotas/helpers/quotas_installer.php new file mode 100644 index 00000000..6eb46f4a --- /dev/null +++ b/3.0/modules/quotas/helpers/quotas_installer.php @@ -0,0 +1,47 @@ +query("CREATE TABLE IF NOT EXISTS {users_space_usages} ( + `id` int(9) NOT NULL auto_increment, + `owner_id` int(9) NOT NULL, + `fullsize` BIGINT UNSIGNED NOT NULL, + `resize` BIGINT UNSIGNED NOT NULL, + `thumb` BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + KEY(`owner_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE IF NOT EXISTS {groups_quotas} ( + `id` int(9) NOT NULL auto_increment, + `group_id` int(9) NOT NULL, + `storage_limit` BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + KEY(`group_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + module::set_var("quotas", "use_all_sizes", true); + + // Set the module version number. + module::set_version("quotas", 1); + } +} diff --git a/3.0/modules/quotas/helpers/quotas_task.php b/3.0/modules/quotas/helpers/quotas_task.php new file mode 100644 index 00000000..4413520b --- /dev/null +++ b/3.0/modules/quotas/helpers/quotas_task.php @@ -0,0 +1,126 @@ +where("users.guest", "=", "0") + ->join("users_space_usages", "users.id", "users_space_usages.owner_id", "LEFT OUTER") + ->and_where("users_space_usages.owner_id", "IS", NULL)->count_all(); + + $tasks = array(); + $tasks[] = Task_Definition::factory() + ->callback("quotas_task::update_quotasdb") + ->name(t("Rebuild user quotas table")) + ->description(t("Recalculates each users space usage.")) + ->severity($missing_users ? log::WARNING : log::SUCCESS); + + return $tasks; + } + + static function update_quotasdb($task) { + // Re-create the users_space_usages table and recalculate all values. + + // Retrieve the total variable. If this is the first time this function has been run, + // total will be empty. + $total = $task->get("total"); + $existing_items = ORM::factory("item")->where("type", "!=", "album")->find_all(); + + if (empty($total)) { + // If this is the first time this function has been run, + // delete and re-create the users_space_usages table, and set up + // some initial variables. + $db = Database::instance(); + $db->query("DROP TABLE IF EXISTS {users_space_usages};"); + $db->query("CREATE TABLE IF NOT EXISTS {users_space_usages} ( + `id` int(9) NOT NULL auto_increment, + `owner_id` int(9) NOT NULL, + `fullsize` BIGINT UNSIGNED NOT NULL, + `resize` BIGINT UNSIGNED NOT NULL, + `thumb` BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + KEY(`owner_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + // Set the initial values for all variables. + $task->set("total", count($existing_items)); + $total = $task->get("total"); + $task->set("last_id", 0); + $task->set("completed_items", 0); + $task->set("total_users", ORM::factory("user")->where("guest", "=", "0")->count_all()); + $task->set("completed_users", 0); + $task->set("last_user_id", 0); + } + + // Retrieve the values for variables from the last time this + // function was run. + $last_id = $task->get("last_id"); + $completed_items = $task->get("completed_items"); + $total_users = $task->get("total_users"); + $completed_users = $task->get("completed_users"); + $last_user_id = $task->get("last_user_id"); + + // First set up default values for all non-guest users. + if ($total_users > $completed_users) { + $one_user = ORM::factory("user") + ->where("guest", "=", "0") + ->where("id", ">", $last_user_id) + ->order_by("id") + ->find_all(1); + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $one_user[0]->id)->find(); + if (!$record->loaded()) { + $record->owner_id = $one_user[0]->id; + $record->fullsize = 0; + $record->resize = 0; + $record->thumb = 0; + $record->save(); + } + $task->set("last_user_id", $one_user[0]->id); + $task->set("completed_users", ++$completed_users); + $task->status = t("Populating quotas table..."); + + } else { + // Loop through each non-album item in Gallery and log its file size to its owner. + $item = ORM::factory("item") + ->where("type", "!=", "album") + ->where("id", ">", $last_id) + ->order_by("id") + ->find_all(1); + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item[0]->owner_id)->find(); + $record->add_item($item[0]); + + // Store the current position and update the status message. + $task->set("last_id", $item[0]->id); + $task->set("completed_items", ++$completed_items); + if ($total == $completed_items) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + $task->status = t("Complete"); + } else { + $task->percent_complete = round(100 * $completed_items / $total); + $task->status = t("Scanning $completed_items of $total files"); + } + } + } +} diff --git a/3.0/modules/quotas/helpers/quotas_theme.php b/3.0/modules/quotas/helpers/quotas_theme.php new file mode 100644 index 00000000..7a4e0916 --- /dev/null +++ b/3.0/modules/quotas/helpers/quotas_theme.php @@ -0,0 +1,35 @@ +guest) { + $record = ORM::factory("users_space_usage")->where("owner_id", "=", identity::active_user()->id)->find(); + if ($record->get_usage_limit() == 0) { + print t("You are using %usage MB", array("usage" => number_format($record->total_usage_mb(), 2))); + } else { + print t("You are using %usage of your %limit MB limit (%percentage%)", + array("usage" => number_format($record->current_usage_mb(), 2), + "limit" => number_format($record->get_usage_limit_mb(), 2), + "percentage" => number_format((($record->current_usage() / $record->get_usage_limit()) * 100), 2))); + } + } + } +} diff --git a/3.0/modules/quotas/models/groups_quota.php b/3.0/modules/quotas/models/groups_quota.php new file mode 100644 index 00000000..25af34e1 --- /dev/null +++ b/3.0/modules/quotas/models/groups_quota.php @@ -0,0 +1,21 @@ +$file_type / 1024 / 1024); + } + + public function total_usage() { + // Return the user's total usage in bytes. + return ($this->fullsize + $this->resize + $this->thumb); + } + + public function total_usage_mb() { + // Return the user's total usage in megabytes. + return (($this->total_usage()) / 1024 / 1024); + } + + public function current_usage() { + // Return the users relevant usage in bytes based on the use_all_sizes setting. + if (module::get_var("quotas", "use_all_sizes") == true) { + return $this->total_usage(); + } else { + return $this->fullsize; + } + } + + public function current_usage_mb() { + // Return the users relevant usage in megabytes based on the use_all_sizes setting. + return ($this->current_usage() / 1024 / 1024); + } + + public function get_usage_limit() { + // Returns a user's maximum limit in bytes. + $user_groups = ORM::factory("group") + ->join("groups_users", "groups_users.group_id", "groups.id") + ->join("groups_quotas", "groups_quotas.group_id", "groups.id") + ->select("groups.id") + ->select("groups_quotas.storage_limit") + ->where("groups_users.user_id", "=", $this->owner_id) + ->order_by("groups_quotas.storage_limit", "DESC") + ->find_all(1); + if (!empty($user_groups)) { + if ($user_groups[0]->storage_limit <= "0") { + return 0; + } else { + return $user_groups[0]->storage_limit; + } + } + return 0; + } + + public function get_usage_limit_mb() { + // Returns a user's maximum limit in megabytes. + return ($this->get_usage_limit() / 1024 / 1024); + } + + public function add_item($item) { + // Adds an item's file size to the table. + if ($item->is_album()) { + return ; + } + + $item_fullsize = 0; + $item_resize = 0; + $item_thumb = 0; + + if (file_exists($item->file_path())) { + $item_fullsize = filesize($item->file_path()); + } + if (file_exists($item->thumb_path())) { + $item_thumb = filesize($item->thumb_path()); + } + if (file_exists($item->resize_path())) { + $item_resize = filesize($item->resize_path()); + } + + $this->fullsize = $this->fullsize + $item_fullsize; + $this->resize = $this->resize + $item_resize; + $this->thumb = $this->thumb + $item_thumb; + $this->save(); + + return ; + } + + public function remove_item($item) { + // Removes an item's file size from the table. + if ($item->is_album()) { + return ; + } + + $item_fullsize = 0; + $item_resize = 0; + $item_thumb = 0; + + if (file_exists($item->file_path())) { + $item_fullsize = filesize($item->file_path()); + } + if (file_exists($item->thumb_path())) { + $item_thumb = filesize($item->thumb_path()); + } + if (file_exists($item->resize_path())) { + $item_resize = filesize($item->resize_path()); + } + + $this->fullsize = $this->fullsize - $item_fullsize; + $this->resize = $this->resize - $item_resize; + $this->thumb = $this->thumb - $item_thumb; + $this->save(); + + return ; + } +} diff --git a/3.0/modules/quotas/module.info b/3.0/modules/quotas/module.info new file mode 100644 index 00000000..11f9f668 --- /dev/null +++ b/3.0/modules/quotas/module.info @@ -0,0 +1,7 @@ +name = "Quotas" +description = "Assign quotas to user groups and track each users space usage." +version = 1 +author_name = "rWatcher" +author_url = "http://codex.gallery2.org/User:RWatcher" +info_url = "http://codex.gallery2.org/Gallery3:Modules:quotas" +discuss_url = "http://gallery.menalto.com/node/103606" diff --git a/3.0/modules/quotas/views/admin_quotas.html.php b/3.0/modules/quotas/views/admin_quotas.html.php new file mode 100644 index 00000000..e1f63763 --- /dev/null +++ b/3.0/modules/quotas/views/admin_quotas.html.php @@ -0,0 +1,98 @@ + +
+

+ +
+ +
+ +

+ +
+ + + + + + + + + + + + $user): ?> + where("owner_id", "=", $user->id)->find(); ?> + g-user admin ? "g-admin" : "" ?>"> + + + + + + + + + +
+ " + alt="name) ?>" + width="20" + height="20" /> + name) ?> + + full_name) ?> + + partial_usage_mb("fullsize"), 2); ?> MB + + partial_usage_mb("resize"), 2); ?> MB + + partial_usage_mb("thumb"), 2); ?> MB + + total_usage_mb(), 2) ?> MB + + get_usage_limit_mb(), 2) ?> MB +
+ +
+ paginator() ?> +
+ +
+
+ +
+

+ + + + + + + $group): ?> + where("group_id", "=", $group->id)->find(); ?> + g-user "> + + + + + +
+ name) ?> + + storage_limit / 1024 / 1024, 2); ?> MB + + id") ?>" + open_text="" + class="g-panel-link g-button ui-state-default ui-corner-all ui-icon-left"> + +
+
+ +
+
+ +
+

+ +
+
+
diff --git a/3.1/modules/quotas/controllers/admin_quotas.php b/3.1/modules/quotas/controllers/admin_quotas.php new file mode 100644 index 00000000..ac5bf8b5 --- /dev/null +++ b/3.1/modules/quotas/controllers/admin_quotas.php @@ -0,0 +1,152 @@ +page_title = t("Users and groups"); + $view->page_type = "collection"; + $view->page_subtype = "admin_users_quotas"; + $view->content = new View("admin_quotas.html"); + + $page_size = module::get_var("user", "page_size", 10); + $page = Input::instance()->get("page", "1"); + $builder = db::build(); + $user_count = $builder->from("users")->count_records(); + + $view->page = $page; + $view->page_size = $page_size; + $view->children_count = $user_count; + $view->max_pages = ceil($view->children_count / $view->page_size); + + $view->content->pager = new Pagination(); + $view->content->pager->initialize( + array("query_string" => "page", + "total_items" => $user_count, + "items_per_page" => $page_size, + "style" => "classic")); + + if ($page < 1) { + url::redirect(url::merge(array("page" => 1))); + } else if ($page > $view->content->pager->total_pages) { + url::redirect(url::merge(array("page" => $view->content->pager->total_pages))); + } + + $view->content->users = ORM::factory("user") + ->order_by("users.name", "ASC") + ->find_all($page_size, $view->content->pager->sql_offset); + $view->content->groups = ORM::factory("group")->order_by("name", "ASC")->find_all(); + $view->content->quota_options = $this->_get_quota_settings_form(); + print $view; + } + + public function form_group_quota($id) { + // Display the form for setting a quota for the specified group ($id). + $group = ORM::factory("group", $id); + if (empty($group)) { + throw new Kohana_404_Exception(); + } + print $this->_get_edit_group_quota($group); + } + + static function _get_edit_group_quota($group) { + // Generate a form for setting a quota for the specified group ($group). + $record = ORM::factory("groups_quota")->where("group_id", "=", $group->id)->find(); + $form = new Forge( + "admin/quotas/edit_quota/$group->id", "", "post", array("id" => "g-edit-quota-form")); + $group = $form->group("edit_quota")->label(t("Edit group quota")); + $group->input("group_quota")->label(t("Limit (MB)"))->id("g-group_quota")->value($record->storage_limit / 1024 / 1024) + ->error_messages("required", t("A value is required")); + + $group->submit("")->value(t("Save")); + return $form; + } + + public function edit_quota($id) { + // Save the specified quota to the database. + access::verify_csrf(); + + $group = ORM::factory("group", $id); + if (empty($group)) { + throw new Kohana_404_Exception(); + } + + $record = ORM::factory("groups_quota")->where("group_id", "=", $group->id)->find(); + $form = $this->_get_edit_group_quota($group); + try { + $valid = $form->validate(); + $record->group_id = $id; + $record->storage_limit = $form->edit_quota->inputs["group_quota"]->value * 1024 * 1024; + } catch (ORM_Validation_Exception $e) { + // Translate ORM validation errors into form error messages + foreach ($e->validation->errors() as $key => $error) { + $form->edit_quota->inputs[$key]->add_error($error, 1); + } + $valid = false; + } + + if ($valid) { + $record->save(); + message::success(t("Limit for group %group_name set", array("group_name" => $group->name))); + json::reply(array("result" => "success")); + } else { + json::reply(array("result" => "error", "html" => (string) $form)); + } + } + + private function _get_quota_settings_form() { + // Make a new form to allow the admin to specify how the system should calculate a user's quota. + $form = new Forge("admin/quotas/saveprefs", "", "post", + array("id" => "g-quotas-admin-form")); + + // Setup a checkbox for the form. + $quota_options["use_all_sizes"] = array(t("Count resizes and thumbnails towards a users limit?"), module::get_var("quotas", "use_all_sizes")); + $add_links = $form->group("quota_preferences"); + $add_links->checklist("quota_preferences_list") + ->options($quota_options); + + // Add a save button to the form. + $form->submit("save_preferences")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + public function saveprefs() { + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + // Figure out which boxes where checked + $checkboxes_array = Input::instance()->post("quota_preferences_list"); + $use_all_sizes = false; + for ($i = 0; $i < count($checkboxes_array); $i++) { + if ($checkboxes_array[$i] == "use_all_sizes") { + $use_all_sizes = true; + } + } + + // Save Settings. + module::set_var("quotas", "use_all_sizes", $use_all_sizes); + message::success(t("Your Selection Has Been Saved.")); + + // Load Admin page. + url::redirect("admin/quotas"); + } +} diff --git a/3.1/modules/quotas/helpers/quotas_event.php b/3.1/modules/quotas/helpers/quotas_event.php new file mode 100644 index 00000000..aa832fd1 --- /dev/null +++ b/3.1/modules/quotas/helpers/quotas_event.php @@ -0,0 +1,110 @@ +get("content_menu") + ->append(Menu::factory("link") + ->id("quotas") + ->label(t("User quotas")) + ->url(url::site("admin/quotas"))); + } + + static function user_created($user) { + // Set up some default values whenever a new user is created. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $user->id)->find(); + if (!$record->loaded()) { + $record->owner_id = $user->id; + $record->fullsize = 0; + $record->resize = 0; + $record->thumb = 0; + $record->save(); + } + } + + static function user_before_delete($user) { + // When deleting a user, all of that user's items get re-assigned to the admin account, + // so the file sizes need to be reassigned to the admin user as well. + $admin = identity::admin_user(); + $admin_record = ORM::factory("users_space_usage")->where("owner_id", "=", $admin->id)->find(); + $deleted_user_record = ORM::factory("users_space_usage")->where("owner_id", "=", $user->id)->find(); + if ($deleted_user_record->loaded()) { + $admin_record->fullsize = $admin_record->fullsize + $deleted_user_record->fullsize; + $admin_record->resize = $admin_record->resize + $deleted_user_record->resize; + $admin_record->thumb = $admin_record->thumb + $deleted_user_record->thumb; + $admin_record->save(); + $deleted_user_record->delete(); + } + } + + static function item_before_create($item) { + // When creating a new item, make sure it's file size won't put the user over their limit. + // If it does, throw an error, which will prevent gallery from accepting the file. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + if (!$record->loaded()) { + $record->owner_id = $item->owner_id; + } + if ($record->get_usage_limit() == 0) { + return; + } + if ((filesize($item->data_file) + $record->current_usage()) > $record->get_usage_limit()) { + throw new Exception($item->name . " rejected, user #" . $item->owner_id . " over limit."); + } + } + + static function item_created($item) { + // When a new item is created, add it's file size to the users_space_usage table. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + if (!$record->loaded()) { + $record->owner_id = $item->owner_id; + $record->fullsize = 0; + $record->resize = 0; + $record->thumb = 0; + $record->save(); + } + $record->add_item($item); + } + + static function item_before_delete($item) { + // When an item is deleted, remove it's file size from the users_space_usage table. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + $record->remove_item($item); + } + + // I can't monitor the item_before_update / item_updated events to adjust for rotated photos, + // because they fire when a new photo is uploaded (before it's created) and cause all kinds of weirdness. + // So instead, I'm using graphics_rotate to detect a rotate and remove the existing file sizes, and + // item_updated_data_file to add in the new data file sizes. + // Does item_updated_data_file fire for any other reason? (watermarking? renaming/moving/deleting/keeporiginal do not cause updated_data_file.) + static function graphics_rotate($input_file, $output_file, $options) { + // Remove the current item's file size from the quotas table. + $item = item::find_by_path(substr(str_replace(VARPATH, "", $input_file), strpos(str_replace(VARPATH, "", $input_file), "/")+1)); + if ($item->loaded()) { + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + $record->remove_item($item); + } + } + + static function item_updated_data_file($item) { + // Add the current item's file size into the quotas table. + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item->owner_id)->find(); + $record->add_item($item); + } +} diff --git a/3.1/modules/quotas/helpers/quotas_installer.php b/3.1/modules/quotas/helpers/quotas_installer.php new file mode 100644 index 00000000..6eb46f4a --- /dev/null +++ b/3.1/modules/quotas/helpers/quotas_installer.php @@ -0,0 +1,47 @@ +query("CREATE TABLE IF NOT EXISTS {users_space_usages} ( + `id` int(9) NOT NULL auto_increment, + `owner_id` int(9) NOT NULL, + `fullsize` BIGINT UNSIGNED NOT NULL, + `resize` BIGINT UNSIGNED NOT NULL, + `thumb` BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + KEY(`owner_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE IF NOT EXISTS {groups_quotas} ( + `id` int(9) NOT NULL auto_increment, + `group_id` int(9) NOT NULL, + `storage_limit` BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + KEY(`group_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + module::set_var("quotas", "use_all_sizes", true); + + // Set the module version number. + module::set_version("quotas", 1); + } +} diff --git a/3.1/modules/quotas/helpers/quotas_task.php b/3.1/modules/quotas/helpers/quotas_task.php new file mode 100644 index 00000000..4413520b --- /dev/null +++ b/3.1/modules/quotas/helpers/quotas_task.php @@ -0,0 +1,126 @@ +where("users.guest", "=", "0") + ->join("users_space_usages", "users.id", "users_space_usages.owner_id", "LEFT OUTER") + ->and_where("users_space_usages.owner_id", "IS", NULL)->count_all(); + + $tasks = array(); + $tasks[] = Task_Definition::factory() + ->callback("quotas_task::update_quotasdb") + ->name(t("Rebuild user quotas table")) + ->description(t("Recalculates each users space usage.")) + ->severity($missing_users ? log::WARNING : log::SUCCESS); + + return $tasks; + } + + static function update_quotasdb($task) { + // Re-create the users_space_usages table and recalculate all values. + + // Retrieve the total variable. If this is the first time this function has been run, + // total will be empty. + $total = $task->get("total"); + $existing_items = ORM::factory("item")->where("type", "!=", "album")->find_all(); + + if (empty($total)) { + // If this is the first time this function has been run, + // delete and re-create the users_space_usages table, and set up + // some initial variables. + $db = Database::instance(); + $db->query("DROP TABLE IF EXISTS {users_space_usages};"); + $db->query("CREATE TABLE IF NOT EXISTS {users_space_usages} ( + `id` int(9) NOT NULL auto_increment, + `owner_id` int(9) NOT NULL, + `fullsize` BIGINT UNSIGNED NOT NULL, + `resize` BIGINT UNSIGNED NOT NULL, + `thumb` BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + KEY(`owner_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + // Set the initial values for all variables. + $task->set("total", count($existing_items)); + $total = $task->get("total"); + $task->set("last_id", 0); + $task->set("completed_items", 0); + $task->set("total_users", ORM::factory("user")->where("guest", "=", "0")->count_all()); + $task->set("completed_users", 0); + $task->set("last_user_id", 0); + } + + // Retrieve the values for variables from the last time this + // function was run. + $last_id = $task->get("last_id"); + $completed_items = $task->get("completed_items"); + $total_users = $task->get("total_users"); + $completed_users = $task->get("completed_users"); + $last_user_id = $task->get("last_user_id"); + + // First set up default values for all non-guest users. + if ($total_users > $completed_users) { + $one_user = ORM::factory("user") + ->where("guest", "=", "0") + ->where("id", ">", $last_user_id) + ->order_by("id") + ->find_all(1); + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $one_user[0]->id)->find(); + if (!$record->loaded()) { + $record->owner_id = $one_user[0]->id; + $record->fullsize = 0; + $record->resize = 0; + $record->thumb = 0; + $record->save(); + } + $task->set("last_user_id", $one_user[0]->id); + $task->set("completed_users", ++$completed_users); + $task->status = t("Populating quotas table..."); + + } else { + // Loop through each non-album item in Gallery and log its file size to its owner. + $item = ORM::factory("item") + ->where("type", "!=", "album") + ->where("id", ">", $last_id) + ->order_by("id") + ->find_all(1); + $record = ORM::factory("users_space_usage")->where("owner_id", "=", $item[0]->owner_id)->find(); + $record->add_item($item[0]); + + // Store the current position and update the status message. + $task->set("last_id", $item[0]->id); + $task->set("completed_items", ++$completed_items); + if ($total == $completed_items) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + $task->status = t("Complete"); + } else { + $task->percent_complete = round(100 * $completed_items / $total); + $task->status = t("Scanning $completed_items of $total files"); + } + } + } +} diff --git a/3.1/modules/quotas/helpers/quotas_theme.php b/3.1/modules/quotas/helpers/quotas_theme.php new file mode 100644 index 00000000..7a4e0916 --- /dev/null +++ b/3.1/modules/quotas/helpers/quotas_theme.php @@ -0,0 +1,35 @@ +guest) { + $record = ORM::factory("users_space_usage")->where("owner_id", "=", identity::active_user()->id)->find(); + if ($record->get_usage_limit() == 0) { + print t("You are using %usage MB", array("usage" => number_format($record->total_usage_mb(), 2))); + } else { + print t("You are using %usage of your %limit MB limit (%percentage%)", + array("usage" => number_format($record->current_usage_mb(), 2), + "limit" => number_format($record->get_usage_limit_mb(), 2), + "percentage" => number_format((($record->current_usage() / $record->get_usage_limit()) * 100), 2))); + } + } + } +} diff --git a/3.1/modules/quotas/models/groups_quota.php b/3.1/modules/quotas/models/groups_quota.php new file mode 100644 index 00000000..25af34e1 --- /dev/null +++ b/3.1/modules/quotas/models/groups_quota.php @@ -0,0 +1,21 @@ +$file_type / 1024 / 1024); + } + + public function total_usage() { + // Return the user's total usage in bytes. + return ($this->fullsize + $this->resize + $this->thumb); + } + + public function total_usage_mb() { + // Return the user's total usage in megabytes. + return (($this->total_usage()) / 1024 / 1024); + } + + public function current_usage() { + // Return the users relevant usage in bytes based on the use_all_sizes setting. + if (module::get_var("quotas", "use_all_sizes") == true) { + return $this->total_usage(); + } else { + return $this->fullsize; + } + } + + public function current_usage_mb() { + // Return the users relevant usage in megabytes based on the use_all_sizes setting. + return ($this->current_usage() / 1024 / 1024); + } + + public function get_usage_limit() { + // Returns a user's maximum limit in bytes. + $user_groups = ORM::factory("group") + ->join("groups_users", "groups_users.group_id", "groups.id") + ->join("groups_quotas", "groups_quotas.group_id", "groups.id") + ->select("groups.id") + ->select("groups_quotas.storage_limit") + ->where("groups_users.user_id", "=", $this->owner_id) + ->order_by("groups_quotas.storage_limit", "DESC") + ->find_all(1); + if (!empty($user_groups)) { + if ($user_groups[0]->storage_limit <= "0") { + return 0; + } else { + return $user_groups[0]->storage_limit; + } + } + return 0; + } + + public function get_usage_limit_mb() { + // Returns a user's maximum limit in megabytes. + return ($this->get_usage_limit() / 1024 / 1024); + } + + public function add_item($item) { + // Adds an item's file size to the table. + if ($item->is_album()) { + return ; + } + + $item_fullsize = 0; + $item_resize = 0; + $item_thumb = 0; + + if (file_exists($item->file_path())) { + $item_fullsize = filesize($item->file_path()); + } + if (file_exists($item->thumb_path())) { + $item_thumb = filesize($item->thumb_path()); + } + if (file_exists($item->resize_path())) { + $item_resize = filesize($item->resize_path()); + } + + $this->fullsize = $this->fullsize + $item_fullsize; + $this->resize = $this->resize + $item_resize; + $this->thumb = $this->thumb + $item_thumb; + $this->save(); + + return ; + } + + public function remove_item($item) { + // Removes an item's file size from the table. + if ($item->is_album()) { + return ; + } + + $item_fullsize = 0; + $item_resize = 0; + $item_thumb = 0; + + if (file_exists($item->file_path())) { + $item_fullsize = filesize($item->file_path()); + } + if (file_exists($item->thumb_path())) { + $item_thumb = filesize($item->thumb_path()); + } + if (file_exists($item->resize_path())) { + $item_resize = filesize($item->resize_path()); + } + + $this->fullsize = $this->fullsize - $item_fullsize; + $this->resize = $this->resize - $item_resize; + $this->thumb = $this->thumb - $item_thumb; + $this->save(); + + return ; + } +} diff --git a/3.1/modules/quotas/module.info b/3.1/modules/quotas/module.info new file mode 100644 index 00000000..11f9f668 --- /dev/null +++ b/3.1/modules/quotas/module.info @@ -0,0 +1,7 @@ +name = "Quotas" +description = "Assign quotas to user groups and track each users space usage." +version = 1 +author_name = "rWatcher" +author_url = "http://codex.gallery2.org/User:RWatcher" +info_url = "http://codex.gallery2.org/Gallery3:Modules:quotas" +discuss_url = "http://gallery.menalto.com/node/103606" diff --git a/3.1/modules/quotas/views/admin_quotas.html.php b/3.1/modules/quotas/views/admin_quotas.html.php new file mode 100644 index 00000000..e1f63763 --- /dev/null +++ b/3.1/modules/quotas/views/admin_quotas.html.php @@ -0,0 +1,98 @@ + +
+

+ +
+ +
+ +

+ +
+ + + + + + + + + + + + $user): ?> + where("owner_id", "=", $user->id)->find(); ?> + g-user admin ? "g-admin" : "" ?>"> + + + + + + + + + +
+ " + alt="name) ?>" + width="20" + height="20" /> + name) ?> + + full_name) ?> + + partial_usage_mb("fullsize"), 2); ?> MB + + partial_usage_mb("resize"), 2); ?> MB + + partial_usage_mb("thumb"), 2); ?> MB + + total_usage_mb(), 2) ?> MB + + get_usage_limit_mb(), 2) ?> MB +
+ +
+ paginator() ?> +
+ +
+
+ +
+

+ + + + + + + $group): ?> + where("group_id", "=", $group->id)->find(); ?> + g-user "> + + + + + +
+ name) ?> + + storage_limit / 1024 / 1024, 2); ?> MB + + id") ?>" + open_text="" + class="g-panel-link g-button ui-state-default ui-corner-all ui-icon-left"> + +
+
+ +
+
+ +
+

+ +
+
+
From d544ed6c095182f5c2a15d547abc75073a2d6599 Mon Sep 17 00:00:00 2001 From: rWatcher Date: Wed, 14 Sep 2011 17:40:30 -0400 Subject: [PATCH 2/3] Updated theme support files. --- .../GreyDragon 3.0.8}/views/calpage.html.php | 51 ++++++++++++------- .../views/paginator.html.php | 3 +- .../GreyDragon 3.0.8}/views/photo.html.php | 6 +-- .../views/tag_albums_album.html.php | 0 .../views/calpage.html.php | 13 +++-- .../GreyDragon 3.0.8}/views/calpage.html.php | 51 ++++++++++++------- .../views/paginator.html.php | 3 +- .../GreyDragon 3.0.8}/views/photo.html.php | 6 +-- .../views/tag_albums_album.html.php | 0 .../views/calpage.html.php | 13 +++-- 10 files changed, 96 insertions(+), 50 deletions(-) rename {3.1/modules/tag_albums/-- Theme Files/greydragon => 3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8}/views/calpage.html.php (92%) rename {3.1/modules/tag_albums/-- Theme Files/greydragon => 3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8}/views/paginator.html.php (98%) rename {3.1/modules/tag_albums/-- Theme Files/greydragon => 3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8}/views/photo.html.php (97%) rename 3.0/modules/tag_albums/-- Theme Files/{greydragon => GreyDragon 3.0.8}/views/tag_albums_album.html.php (100%) rename 3.0/modules/tag_albums/-- Theme Files/{clean_canvas => clean_canvas 1.0.7}/views/calpage.html.php (93%) rename {3.0/modules/tag_albums/-- Theme Files/greydragon => 3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8}/views/calpage.html.php (92%) rename {3.0/modules/tag_albums/-- Theme Files/greydragon => 3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8}/views/paginator.html.php (98%) rename {3.0/modules/tag_albums/-- Theme Files/greydragon => 3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8}/views/photo.html.php (97%) rename 3.1/modules/tag_albums/-- Theme Files/{greydragon => GreyDragon 3.0.8}/views/tag_albums_album.html.php (100%) rename 3.1/modules/tag_albums/-- Theme Files/{clean_canvas => clean_canvas 1.0.7}/views/calpage.html.php (93%) diff --git a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php b/3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/calpage.html.php similarity index 92% rename from 3.1/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php rename to 3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/calpage.html.php index 9d3341de..6d39f820 100644 --- a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php +++ b/3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/calpage.html.php @@ -56,8 +56,8 @@ blendpagetrans): ?> - - + + @@ -124,12 +124,20 @@ -item()): ?> -item(); ?> - - - -body_attributes() ?>show_root_page)? ' id="g-rootpage"' : null; ?> is_rtl)? "class=\"rtl\"" : null; ?> > +item()): + $item = $theme->item(); + else: + $item = item::root(); + endif; + if ($theme->is_rtl): + $body_class = "rtl"; + else: + $body_class = ""; + endif; + if ($theme->viewmode == "mini"): + $body_class .= "viewmode-mini"; + endif; ?> +body_attributes() ?>show_root_page)? ' id="g-rootpage"' : null; ?> > page_top() ?> site_status() ?> guest) or ($theme->show_guest_menu)) and ($theme->mainmenu_position == "bar")): ?> @@ -140,14 +148,15 @@
header_top() ?> - +viewmode != "mini"): ?> + bb2html($header_text, 1) ?> - + - - + + guest) or ($theme->show_guest_menu)) and ($theme->mainmenu_position != "bar")): ?>
site_menu($theme->item() ? "#g-item-id-{$theme->item()->id}" : "") ?> @@ -160,13 +169,18 @@ loginmenu_position == "header"): ?> user_menu() ?> + + breadcrumb_menu($theme, null); ?> +breadcrumb_menu($theme, $parents); ?> + + breadcrumbs_position == "hide"): @@ -193,6 +207,7 @@ // End Edit. ?> + custom_header(); ?>
@@ -281,15 +296,17 @@
page_bottom() ?> diff --git a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php b/3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/paginator.html.php similarity index 98% rename from 3.1/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php rename to 3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/paginator.html.php index 5918299c..cc552628 100644 --- a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php +++ b/3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/paginator.html.php @@ -53,7 +53,7 @@ $siblings = $dynamic_siblings; for ($i = 1; $i <= $total_pages; $i++): if ($page_type == "item") { - $_pagelist[$i] = url::site("tag_albums/show/" . $siblings[$i-1]->id . "/" . $tag_id . "/" . $album_id); + $_pagelist[$i] = url::site("tag_albums/show/" . $siblings[$i-1]->id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($siblings[$i-1]->name)); } elseif ($page_type == "") { } endfor; @@ -91,6 +91,7 @@ $_pagelist[1] = url::site(); break; } + // rWatcher Mod endif; // End rWatcher Mod. diff --git a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php b/3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/photo.html.php similarity index 97% rename from 3.1/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php rename to 3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/photo.html.php index 5d3ede73..70fb4ca8 100644 --- a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php +++ b/3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/photo.html.php @@ -48,7 +48,7 @@

- add_paginator("top"); ?> + add_paginator("top", FALSE); ?> photo_top() ?> photo_descmode == "top") and ($_description)): ?>
@@ -56,7 +56,7 @@
resize_top($item) ?> resize_width; - + // rWatcher Modification. $siblings = ""; if (isset($dynamic_siblings)) { @@ -116,7 +116,7 @@ photo_descmode == "bottom") and ($_description)): ?>
- add_paginator("bottom"); ?> + add_paginator("bottom", FALSE); ?> photo_bottom() ?>
\ No newline at end of file diff --git a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php b/3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/tag_albums_album.html.php similarity index 100% rename from 3.0/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php rename to 3.0/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/tag_albums_album.html.php diff --git a/3.0/modules/tag_albums/-- Theme Files/clean_canvas/views/calpage.html.php b/3.0/modules/tag_albums/-- Theme Files/clean_canvas 1.0.7/views/calpage.html.php similarity index 93% rename from 3.0/modules/tag_albums/-- Theme Files/clean_canvas/views/calpage.html.php rename to 3.0/modules/tag_albums/-- Theme Files/clean_canvas 1.0.7/views/calpage.html.php index 54bb4db8..9b4635ef 100644 --- a/3.0/modules/tag_albums/-- Theme Files/clean_canvas/views/calpage.html.php +++ b/3.0/modules/tag_albums/-- Theme Files/clean_canvas 1.0.7/views/calpage.html.php @@ -132,7 +132,7 @@ header_bottom() ?> - @@ -145,9 +145,14 @@ the immediate parent so that when you go back up a level you're on the right page. --> url) : ?> - title) ?> + + + title, + module::get_var("gallery", "visible_title_length"))) ?> + - title) ?> + title, + module::get_var("gallery", "visible_title_length"))) ?> @@ -156,7 +161,7 @@ - +
diff --git a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php b/3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/calpage.html.php similarity index 92% rename from 3.0/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php rename to 3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/calpage.html.php index 9d3341de..6d39f820 100644 --- a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/calpage.html.php +++ b/3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/calpage.html.php @@ -56,8 +56,8 @@ blendpagetrans): ?> - - + + @@ -124,12 +124,20 @@ -item()): ?> -item(); ?> - - - -body_attributes() ?>show_root_page)? ' id="g-rootpage"' : null; ?> is_rtl)? "class=\"rtl\"" : null; ?> > +item()): + $item = $theme->item(); + else: + $item = item::root(); + endif; + if ($theme->is_rtl): + $body_class = "rtl"; + else: + $body_class = ""; + endif; + if ($theme->viewmode == "mini"): + $body_class .= "viewmode-mini"; + endif; ?> +body_attributes() ?>show_root_page)? ' id="g-rootpage"' : null; ?> > page_top() ?> site_status() ?> guest) or ($theme->show_guest_menu)) and ($theme->mainmenu_position == "bar")): ?> @@ -140,14 +148,15 @@
header_top() ?> - +viewmode != "mini"): ?> + bb2html($header_text, 1) ?> - + - - + + guest) or ($theme->show_guest_menu)) and ($theme->mainmenu_position != "bar")): ?>
site_menu($theme->item() ? "#g-item-id-{$theme->item()->id}" : "") ?> @@ -160,13 +169,18 @@ loginmenu_position == "header"): ?> user_menu() ?> + + breadcrumb_menu($theme, null); ?> +breadcrumb_menu($theme, $parents); ?> + + breadcrumbs_position == "hide"): @@ -193,6 +207,7 @@ // End Edit. ?> + custom_header(); ?>
@@ -281,15 +296,17 @@
page_bottom() ?> diff --git a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php b/3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/paginator.html.php similarity index 98% rename from 3.0/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php rename to 3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/paginator.html.php index 5918299c..cc552628 100644 --- a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/paginator.html.php +++ b/3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/paginator.html.php @@ -53,7 +53,7 @@ $siblings = $dynamic_siblings; for ($i = 1; $i <= $total_pages; $i++): if ($page_type == "item") { - $_pagelist[$i] = url::site("tag_albums/show/" . $siblings[$i-1]->id . "/" . $tag_id . "/" . $album_id); + $_pagelist[$i] = url::site("tag_albums/show/" . $siblings[$i-1]->id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($siblings[$i-1]->name)); } elseif ($page_type == "") { } endfor; @@ -91,6 +91,7 @@ $_pagelist[1] = url::site(); break; } + // rWatcher Mod endif; // End rWatcher Mod. diff --git a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php b/3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/photo.html.php similarity index 97% rename from 3.0/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php rename to 3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/photo.html.php index 5d3ede73..70fb4ca8 100644 --- a/3.0/modules/tag_albums/-- Theme Files/greydragon/views/photo.html.php +++ b/3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/photo.html.php @@ -48,7 +48,7 @@

- add_paginator("top"); ?> + add_paginator("top", FALSE); ?> photo_top() ?> photo_descmode == "top") and ($_description)): ?>
@@ -56,7 +56,7 @@
resize_top($item) ?> resize_width; - + // rWatcher Modification. $siblings = ""; if (isset($dynamic_siblings)) { @@ -116,7 +116,7 @@ photo_descmode == "bottom") and ($_description)): ?>
- add_paginator("bottom"); ?> + add_paginator("bottom", FALSE); ?> photo_bottom() ?>
\ No newline at end of file diff --git a/3.1/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php b/3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/tag_albums_album.html.php similarity index 100% rename from 3.1/modules/tag_albums/-- Theme Files/greydragon/views/tag_albums_album.html.php rename to 3.1/modules/tag_albums/-- Theme Files/GreyDragon 3.0.8/views/tag_albums_album.html.php diff --git a/3.1/modules/tag_albums/-- Theme Files/clean_canvas/views/calpage.html.php b/3.1/modules/tag_albums/-- Theme Files/clean_canvas 1.0.7/views/calpage.html.php similarity index 93% rename from 3.1/modules/tag_albums/-- Theme Files/clean_canvas/views/calpage.html.php rename to 3.1/modules/tag_albums/-- Theme Files/clean_canvas 1.0.7/views/calpage.html.php index 54bb4db8..9b4635ef 100644 --- a/3.1/modules/tag_albums/-- Theme Files/clean_canvas/views/calpage.html.php +++ b/3.1/modules/tag_albums/-- Theme Files/clean_canvas 1.0.7/views/calpage.html.php @@ -132,7 +132,7 @@ header_bottom() ?>
- @@ -145,9 +145,14 @@ the immediate parent so that when you go back up a level you're on the right page. --> url) : ?> - title) ?> + + + title, + module::get_var("gallery", "visible_title_length"))) ?> + - title) ?> + title, + module::get_var("gallery", "visible_title_length"))) ?> @@ -156,7 +161,7 @@ -
+
From 823c73545718066d3ce4d0bed2e9c720eda148c5 Mon Sep 17 00:00:00 2001 From: rWatcher Date: Wed, 14 Sep 2011 17:41:44 -0400 Subject: [PATCH 3/3] And file names and tag names to the end of urls. --- .../tag_albums/controllers/tag_albums.php | 81 ++++++++++--------- 3.0/modules/tag_albums/views/calpage.html.php | 25 +++--- .../tag_albums/controllers/tag_albums.php | 81 ++++++++++--------- 3.1/modules/tag_albums/views/calpage.html.php | 25 +++--- 4 files changed, 118 insertions(+), 94 deletions(-) diff --git a/3.0/modules/tag_albums/controllers/tag_albums.php b/3.0/modules/tag_albums/controllers/tag_albums.php index c4b981d7..566949b8 100644 --- a/3.0/modules/tag_albums/controllers/tag_albums.php +++ b/3.0/modules/tag_albums/controllers/tag_albums.php @@ -44,6 +44,9 @@ class tag_albums_Controller extends Controller { $page_title = $album->title; $page_description = $album->description; + // URL to this page + $str_page_url = "tag_albums/album/" . $id . "/" . urlencode($album->name); + // Determine page sort order. $sort_page_field = $album->sort_column; $sort_page_direction = $album->sort_order; @@ -68,7 +71,7 @@ class tag_albums_Controller extends Controller { $index = $this->_get_position($child->$sort_page_field, $child->id, $tag_ids, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, true); if ($index) { $page = ceil($index / $page_size); - url::redirect("tag_albums/album/" . $id . "/" . urlencode($album->name) . "?page=$page"); + url::redirect($str_page_url . "?page=$page"); } } @@ -79,7 +82,7 @@ class tag_albums_Controller extends Controller { // don't allow the visitor to go below page 1. $page = Input::instance()->get("page", 1); if ($page < 1) { - url::redirect("tag_albums/album/" . $id); + url::redirect($str_page_url); } // First item to display. @@ -90,7 +93,7 @@ class tag_albums_Controller extends Controller { // Don't let the visitor go past the last page. if ($max_pages && $page > $max_pages) { - url::redirect("tag_albums/album/{$id}/?page=$max_pages"); + url::redirect($str_page_url . "/?page=$max_pages"); } // Figure out which items to display on this page and store their details in $children. @@ -110,11 +113,11 @@ class tag_albums_Controller extends Controller { // Set up the previous and next page buttons. if ($page > 1) { $previous_page = $page - 1; - $view->previous_page_link = url::site("tag_albums/album/{$id}/?page={$previous_page}"); + $view->previous_page_link = url::site($str_page_url . "/?page={$previous_page}"); } if ($page < $max_pages) { $next_page = $page + 1; - $view->next_page_link = url::site("tag_albums/album/{$id}/?page={$next_page}"); + $view->next_page_link = url::site($str_page_url . "/?page={$next_page}"); } // Set up breadcrumbs. @@ -132,7 +135,7 @@ class tag_albums_Controller extends Controller { // Set up and display the actual page. $parent_album = ORM::factory("item", $album->parent_id); - $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template = new Theme_View("calpage.html", "collection", "Tag Albums"); $template->page_title = $page_title; $template->set_global("page", $page); $template->set_global("page_size", $page_size); @@ -153,7 +156,7 @@ class tag_albums_Controller extends Controller { // tags whose name begins with $filter. $this->index($id, $filter); } - + public function index($id, $filter) { // Load a page containing sub-albums for each tag in the gallery. @@ -190,14 +193,17 @@ class tag_albums_Controller extends Controller { $album = ""; $page_title = module::get_var("tag_albums", "tag_page_title", "All Tags"); $page_description = ""; + $str_page_url = ""; if ($id == "") { $album = ORM::factory("item", 1); access::required("view", $album); + $str_page_url = "tag_albums/"; } else { $album = ORM::factory("item", $album_tags[0]->album_id); access::required("view", $album); $page_title = $album->title; $page_description = $album->description; + $str_page_url = "tag_albums/album/" . $id . "/" . urlencode($album->title); } // Figure out sort order from module preferences. @@ -233,11 +239,7 @@ class tag_albums_Controller extends Controller { } if ($index) { $page = ceil($index / $page_size); - if ($id == "") { - url::redirect("tag_albums/?page=$page"); - } else { - url::redirect("tag_albums/album/" . $id . "/" . urlencode($album->title) . "?page=$page"); - } + url::redirect("$str_page_url?page=$page"); } } @@ -245,7 +247,7 @@ class tag_albums_Controller extends Controller { // don't allow the visitor to go below page 1. $page = Input::instance()->get("page", 1); if ($page < 1) { - url::redirect("tag_albums/"); + url::redirect($str_page_url); } // First item to display. @@ -274,7 +276,7 @@ class tag_albums_Controller extends Controller { // Don't let the visitor go past the last page. if ($max_pages && $page > $max_pages) { - url::redirect("tag_albums/?page=$max_pages"); + url::redirect("$str_page_url?page=$max_pages"); } // Figure out which items to display on this page. @@ -298,11 +300,11 @@ class tag_albums_Controller extends Controller { // Set up the previous and next page buttons. if ($page > 1) { $previous_page = $page - 1; - $view->previous_page_link = url::site("tag_albums/album/" . $id . "/?page={$previous_page}"); + $view->previous_page_link = url::site($str_page_url . "?page={$previous_page}"); } if ($page < $max_pages) { $next_page = $page + 1; - $view->next_page_link = url::site("tag_albums/album/" . $id . "/?page={$next_page}"); + $view->next_page_link = url::site($str_page_url . "?page={$next_page}"); } // Generate an arry of "fake" items, one for each tag on the page. @@ -346,7 +348,7 @@ class tag_albums_Controller extends Controller { } // Set up and display the actual page. - $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template = new Theme_View("calpage.html", "collection", "Tag Albums"); $template->page_title = $page_title; $template->set_global("page", $page); $template->set_global("page_size", $page_size); @@ -376,10 +378,16 @@ class tag_albums_Controller extends Controller { $album_id = ""; } + // Load the current tag. + $display_tag = ORM::factory("tag", $id); + // Figure out sort order from module preferences. $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + // Figure out the URL to this page. + $str_page_url = "tag_albums/tag/{$id}/{$album_id}/" . urlencode($display_tag->name); + // Figure out how many items to display on each page. $page_size = module::get_var("gallery", "page_size", 9); @@ -390,7 +398,7 @@ class tag_albums_Controller extends Controller { $index = $this->_get_position($child->$sort_page_field, $child->id, Array($id), "items." . $sort_page_field, $sort_page_direction, "OR", true); if ($index) { $page = ceil($index / $page_size); - url::redirect("tag_albums/tag/" . $id . "/" . $album_id . "?page=$page"); + url::redirect($str_page_url . "?page=$page"); } } @@ -398,7 +406,7 @@ class tag_albums_Controller extends Controller { // don't allow the visitor to go below page 1. $page = Input::instance()->get("page", 1); if ($page < 1) { - url::redirect("tag_albums/tag/" . $id . "/" . $album_id); + url::redirect($str_page_url); } // First item to display. @@ -413,7 +421,7 @@ class tag_albums_Controller extends Controller { // Don't let the visitor go past the last page. if ($max_pages && $page > $max_pages) { - url::redirect("tag_albums/tag/{$id}/" . $album_id . "/?page=$max_pages"); + url::redirect($str_page_url . "/?page=$max_pages"); } // Figure out which items to display on this page. @@ -435,16 +443,13 @@ class tag_albums_Controller extends Controller { // Set up the previous and next page buttons. if ($page > 1) { $previous_page = $page - 1; - $view->previous_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$previous_page}"); + $view->previous_page_link = url::site($str_page_url . "/?page={$previous_page}"); } if ($page < $max_pages) { $next_page = $page + 1; - $view->next_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$next_page}"); + $view->next_page_link = url::site($str_page_url . "/?page={$next_page}"); } - // Load the current tag. - $display_tag = ORM::factory("tag", $id); - // Set up breadcrumbs for the page. $tag_album_breadcrumbs = Array(); $parent_url = ""; @@ -480,7 +485,7 @@ class tag_albums_Controller extends Controller { } // Set up and display the actual page. - $template = new Theme_View("calpage.html", "other", "Tag Albums"); + $template = new Theme_View("calpage.html", "collection", "Tag Albums"); $template->page_title = $display_tag->name; $template->set_global("page", $page); $template->set_global("page_size", $page_size); @@ -537,12 +542,12 @@ class tag_albums_Controller extends Controller { if ($position > 1) { $previous_item_object = $this->_get_records(Array($tag_id), 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); if (count($previous_item_object) > 0) { - $previous_item = new Tag_Albums_Item($previous_item_object[0]->title, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + $previous_item = new Tag_Albums_Item($previous_item_object[0]->title, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($previous_item_object[0]->name)), $previous_item_object[0]->type); } } $next_item_object = $this->_get_records(Array($tag_id), 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); if (count($next_item_object) > 0) { - $next_item = new Tag_Albums_Item($next_item_object[0]->title, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + $next_item = new Tag_Albums_Item($next_item_object[0]->title, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($next_item_object[0]->name)), $next_item_object[0]->type); } $dynamic_siblings = $this->_get_records(Array($tag_id), null, null, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); } else { @@ -559,12 +564,12 @@ class tag_albums_Controller extends Controller { if ($position > 1) { $previous_item_object = $this->_get_records($tag_ids, 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); if (count($previous_item_object) > 0) { - $previous_item = new Tag_Albums_Item($previous_item_object[0]->title, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + $previous_item = new Tag_Albums_Item($previous_item_object[0]->title, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($previous_item_object[0]->name)), $previous_item_object[0]->type); } } $next_item_object = $this->_get_records($tag_ids, 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); if (count($next_item_object) > 0) { - $next_item = new Tag_Albums_Item($next_item_object[0]->title, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + $next_item = new Tag_Albums_Item($next_item_object[0]->title, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($next_item_object[0]->name)), $next_item_object[0]->type); } $dynamic_siblings = $this->_get_records($tag_ids, null, null, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); } @@ -575,15 +580,15 @@ class tag_albums_Controller extends Controller { $counter = 0; $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($item->title, ""); if ($album_tags[0]->tags == "*") { - $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id)); + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id . "/" . urlencode($display_tag->name))); } $parent_item = ORM::factory("item", $album_tags[0]->album_id); if ($album_tags[0]->tags == "*") { - $parent_url = url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id); + $parent_url = url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id . "/" . urlencode($display_tag->name)); } else { $parent_url = $parent_item->url(); } - $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, url::site("tag_albums/album/" . $album_id)); + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, url::site("tag_albums/album/" . $album_id . "/" . urlencode($parent_item->name))); $parent_item = ORM::factory("item", $parent_item->parent_id); while ($parent_item->id != 1) { $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); @@ -595,9 +600,9 @@ class tag_albums_Controller extends Controller { } else { $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb(module::get_var("tag_albums", "tag_page_title", "All Tags"), url::site("tag_albums/")); - $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id) . "?show=" . $item->id); + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id . "/" . urlencode($display_tag->name)) . "?show=" . $item->id); $tag_album_breadcrumbs[3] = new Tag_Albums_Breadcrumb($item->title, ""); - $parent_url = url::site("tag_albums/tag/" . $display_tag->id); + $parent_url = url::site("tag_albums/tag/" . $display_tag->id . "/" . urlencode($display_tag->name)); } // Increase the items view count. @@ -780,7 +785,11 @@ class tag_albums_Controller extends Controller { $str_html = "Filter: "; if ($str_filter != "") { if ($album_id > 0) { - $str_html .= "(All) "; + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + $album = ORM::factory("item", $album_tags[0]->album_id); + $str_html .= "name)) . "\">(All) "; } else { $str_html .= "(All) "; } diff --git a/3.0/modules/tag_albums/views/calpage.html.php b/3.0/modules/tag_albums/views/calpage.html.php index 3dab5fc0..c7fdbef0 100644 --- a/3.0/modules/tag_albums/views/calpage.html.php +++ b/3.0/modules/tag_albums/views/calpage.html.php @@ -21,9 +21,10 @@ " type="image/x-icon" /> - + " /> page_type == "collection"): ?> - + thumb_proportion($theme->item())) != 1): ?>