From b245e3475f66c94afb94f8b2287bf0185a343732 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 28 May 2009 06:07:27 +0800 Subject: Restructure things so that the application is now just another module. Kohana makes this type of transition fairly straightforward in that all controllers/helpers/etc are still located in the cascading filesystem without any extra effort, except that I've temporarily added a hack to force modules/gallery into the module path. Rename what's left of "core" to be "application" so that it conforms more closely to the Kohana standard (basically, just application/config/config.php which is the minimal thing that you need in the application directory) There's still considerable work left to be done here. Signed-off-by: Gallery Role Account --- modules/gallery/helpers/MY_remote.php | 163 ++++++++ modules/gallery/helpers/MY_url.php | 81 ++++ modules/gallery/helpers/access.php | 628 +++++++++++++++++++++++++++++ modules/gallery/helpers/album.php | 132 ++++++ modules/gallery/helpers/batch.php | 40 ++ modules/gallery/helpers/block_manager.php | 67 +++ modules/gallery/helpers/core.php | 52 +++ modules/gallery/helpers/core_block.php | 100 +++++ modules/gallery/helpers/core_event.php | 46 +++ modules/gallery/helpers/core_installer.php | 278 +++++++++++++ modules/gallery/helpers/core_menu.php | 162 ++++++++ modules/gallery/helpers/core_search.php | 24 ++ modules/gallery/helpers/core_task.php | 166 ++++++++ modules/gallery/helpers/core_theme.php | 137 +++++++ modules/gallery/helpers/dir.php | 40 ++ modules/gallery/helpers/graphics.php | 387 ++++++++++++++++++ modules/gallery/helpers/item.php | 105 +++++ modules/gallery/helpers/l10n_client.php | 203 ++++++++++ modules/gallery/helpers/l10n_scanner.php | 154 +++++++ modules/gallery/helpers/locale.php | 119 ++++++ modules/gallery/helpers/log.php | 108 +++++ modules/gallery/helpers/message.php | 108 +++++ modules/gallery/helpers/model_cache.php | 46 +++ modules/gallery/helpers/module.php | 357 ++++++++++++++++ modules/gallery/helpers/movie.php | 153 +++++++ modules/gallery/helpers/photo.php | 171 ++++++++ modules/gallery/helpers/rest.php | 116 ++++++ modules/gallery/helpers/site_status.php | 132 ++++++ modules/gallery/helpers/task.php | 83 ++++ modules/gallery/helpers/theme.php | 61 +++ modules/gallery/helpers/xml.php | 35 ++ 31 files changed, 4454 insertions(+) create mode 100644 modules/gallery/helpers/MY_remote.php create mode 100644 modules/gallery/helpers/MY_url.php create mode 100644 modules/gallery/helpers/access.php create mode 100644 modules/gallery/helpers/album.php create mode 100644 modules/gallery/helpers/batch.php create mode 100644 modules/gallery/helpers/block_manager.php create mode 100644 modules/gallery/helpers/core.php create mode 100644 modules/gallery/helpers/core_block.php create mode 100644 modules/gallery/helpers/core_event.php create mode 100644 modules/gallery/helpers/core_installer.php create mode 100644 modules/gallery/helpers/core_menu.php create mode 100644 modules/gallery/helpers/core_search.php create mode 100644 modules/gallery/helpers/core_task.php create mode 100644 modules/gallery/helpers/core_theme.php create mode 100644 modules/gallery/helpers/dir.php create mode 100644 modules/gallery/helpers/graphics.php create mode 100644 modules/gallery/helpers/item.php create mode 100644 modules/gallery/helpers/l10n_client.php create mode 100644 modules/gallery/helpers/l10n_scanner.php create mode 100644 modules/gallery/helpers/locale.php create mode 100644 modules/gallery/helpers/log.php create mode 100644 modules/gallery/helpers/message.php create mode 100644 modules/gallery/helpers/model_cache.php create mode 100644 modules/gallery/helpers/module.php create mode 100644 modules/gallery/helpers/movie.php create mode 100644 modules/gallery/helpers/photo.php create mode 100644 modules/gallery/helpers/rest.php create mode 100644 modules/gallery/helpers/site_status.php create mode 100644 modules/gallery/helpers/task.php create mode 100644 modules/gallery/helpers/theme.php create mode 100644 modules/gallery/helpers/xml.php (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/MY_remote.php b/modules/gallery/helpers/MY_remote.php new file mode 100644 index 00000000..4abf5bf1 --- /dev/null +++ b/modules/gallery/helpers/MY_remote.php @@ -0,0 +1,163 @@ + $value) { + if (!empty($post_data_raw)) { + $post_data_raw .= '&'; + } + $post_data_raw .= urlencode($key) . '=' . urlencode($value); + } + + $extra_headers['Content-Type'] = 'application/x-www-form-urlencoded'; + $extra_headers['Content-Length'] = strlen($post_data_raw); + + return $post_data_raw; + } + + /** + * A single request, without following redirects + * + * @todo: Handle redirects? If so, only for GET (i.e. not for POST), and use G2's WebHelper_simple::_parseLocation logic. + */ + static function do_request($url, $method='GET', $headers=array(), $body='') { + /* Convert illegal characters */ + $url = str_replace(' ', '%20', $url); + + $url_components = self::_parse_url_for_fsockopen($url); + $handle = fsockopen( + $url_components['fsockhost'], $url_components['port'], $errno, $errstr, 5); + if (empty($handle)) { + // log "Error $errno: '$errstr' requesting $url"; + return array(null, null, null); + } + + $header_lines = array('Host: ' . $url_components['host']); + foreach ($headers as $key => $value) { + $header_lines[] = $key . ': ' . $value; + } + + $success = fwrite($handle, sprintf("%s %s HTTP/1.0\r\n%s\r\n\r\n%s", + $method, + $url_components['uri'], + implode("\r\n", $header_lines), + $body)); + if (!$success) { + // Zero bytes written or false was returned + // log "fwrite failed in requestWebPage($url)" . ($success === false ? ' - false' : '' + return array(null, null, null); + } + fflush($handle); + + /* + * Read the status line. fgets stops after newlines. The first line is the protocol + * version followed by a numeric status code and its associated textual phrase. + */ + $response_status = trim(fgets($handle, 4096)); + if (empty($response_status)) { + // 'Empty http response code, maybe timeout' + return array(null, null, null); + } + + /* Read the headers */ + $response_headers = array(); + while (!feof($handle)) { + $line = trim(fgets($handle, 4096)); + if (empty($line)) { + break; + } + + /* Normalize the line endings */ + $line = str_replace("\r", '', $line); + + list ($key, $value) = explode(':', $line, 2); + if (isset($response_headers[$key])) { + if (!is_array($response_headers[$key])) { + $response_headers[$key] = array($response_headers[$key]); + } + $response_headers[$key][] = trim($value); + } else { + $response_headers[$key] = trim($value); + } + } + + /* Read the body */ + $response_body = ''; + while (!feof($handle)) { + $response_body .= fread($handle, 4096); + } + fclose($handle); + + return array($response_status, $response_headers, $response_body); + } + + /** + * Prepare for fsockopen call. + * @param string $url + * @return array url components + * @access private + */ + private static function _parse_url_for_fsockopen($url) { + $url_components = parse_url($url); + if (strtolower($url_components['scheme']) == 'https') { + $url_components['fsockhost'] = 'ssl://' . $url_components['host']; + $default_port = 443; + } else { + $url_components['fsockhost'] = $url_components['host']; + $default_port = 80; + } + if (empty($url_components['port'])) { + $url_components['port'] = $default_port; + } + if (empty($url_components['path'])) { + $url_components['path'] = '/'; + } + $uri = $url_components['path'] + . (empty($url_components['query']) ? '' : '?' . $url_components['query']); + /* Unescape ampersands, since if the url comes from form input it will be escaped */ + $url_components['uri'] = str_replace('&', '&', $uri); + return $url_components; + } +} + diff --git a/modules/gallery/helpers/MY_url.php b/modules/gallery/helpers/MY_url.php new file mode 100644 index 00000000..81dcbe1e --- /dev/null +++ b/modules/gallery/helpers/MY_url.php @@ -0,0 +1,81 @@ +relative_path(); + } + return parent::site($uri . $query, $protocol); + } + + static function parse_url() { + if (Router::$controller) { + return; + } + + $count = count(Router::$segments); + foreach (ORM::factory("item") + ->where("name", html_entity_decode(Router::$segments[$count - 1], ENT_QUOTES)) + ->where("level", $count + 1) + ->find_all() as $match) { + if ($match->relative_path() == html_entity_decode(Router::$current_uri, ENT_QUOTES)) { + $item = $match; + } + } + + if (!empty($item)) { + Router::$controller = "{$item->type}s"; + Router::$controller_path = APPPATH . "controllers/{$item->type}s.php"; + Router::$method = $item->id; + } + } + + /** + * Just like url::file() except that it returns an absolute URI + */ + static function abs_file($path) { + return url::base( + false, (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off') ? 'http' : 'https') . $path; + } + + /** + * Just like url::site() except that it returns an absolute URI and + * doesn't take a protocol parameter. + */ + static function abs_site($path) { + return url::site( + $path, (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off') ? 'http' : 'https'); + } + + /** + * Just like url::current except that it returns an absolute URI + */ + static function abs_current($qs=false) { + return self::abs_site(url::current($qs)); + } +} diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php new file mode 100644 index 00000000..64ce91fa --- /dev/null +++ b/modules/gallery/helpers/access.php @@ -0,0 +1,628 @@ + tuples. It would be inefficient to check + * these tuples every time we want to do a lookup, so we use these intents to create an entire + * table of permissions for easy lookup in the Access_Cache_Model. There's a 1:1 mapping + * between Item_Model and Access_Cache_Model entries. + * + * o For efficiency, we create columns in Access_Intent_Model and Access_Cache_Model for each of + * the possible Group_Model and Permission_Model combinations. This may lead to performance + * issues for very large Gallery installs, but for small to medium sized ones (5-10 groups, 5-10 + * permissions) it's especially efficient because there's a single field value for each + * group/permission/item combination. + * + * o For efficiency, we store the cache columns for view permissions directly in the Item_Model. + * This means that we can filter items by group/permission combination without doing any table + * joins making for an especially efficient permission check at the expense of having to + * maintain extra columns for each item. + * + * o If at any time the Access_Cache_Model becomes invalid, we can rebuild the entire table from + * the Access_Intent_Model + */ +class access_Core { + const DENY = 0; + const ALLOW = 1; + const UNKNOWN = 2; + + /** + * Does the active user have this permission on this item? + * + * @param string $perm_name + * @param Item_Model $item + * @return boolean + */ + static function can($perm_name, $item) { + if (!$item->loaded) { + return false; + } + + if (user::active()->admin) { + return true; + } + + $resource = $perm_name == "view" ? + $item : model_cache::get("access_cache", $item->id, "item_id"); + foreach (user::group_ids() as $id) { + if ($resource->__get("{$perm_name}_$id") === self::ALLOW) { + return true; + } + } + return false; + } + + /** + * If the active user does not have this permission, failed with an access::forbidden(). + * + * @param string $perm_name + * @param Item_Model $item + * @return boolean + */ + static function required($perm_name, $item) { + if (!self::can($perm_name, $item)) { + self::forbidden(); + } + } + + /** + * Does this group have this permission on this item? + * + * @param Group_Model $group + * @param string $perm_name + * @param Item_Model $item + * @return boolean + */ + 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 this group's intent for this permission on this item. + * + * @param Group_Model $group + * @param string $perm_name + * @param Item_Model $item + * @return integer access::ALLOW, access::DENY or null for no intent + */ + static function group_intent($group, $perm_name, $item) { + $intent = model_cache::get("access_intent", $item->id, "item_id"); + return $intent->__get("{$perm_name}_{$group->id}"); + } + + /** + * Is the permission on this item locked by a parent? If so return the nearest parent that + * locks it. + * + * @param Group_Model $group + * @param string $perm_name + * @param Item_Model $item + * @return ORM_Model item that locks this one + */ + static function locked_by($group, $perm_name, $item) { + if ($perm_name != "view") { + return null; + } + + // For view permissions, if any parent is self::DENY, then those parents lock this one. + // Return + $lock = ORM::factory("item") + ->where("`left` <= $item->left") + ->where("`right` >= $item->right") + ->where("items.id <> $item->id") + ->join("access_intents", "items.id", "access_intents.item_id") + ->where("access_intents.view_$group->id", 0) + ->orderby("level", "DESC") + ->limit(1) + ->find(); + + if ($lock->loaded) { + return $lock; + } else { + return null; + } + } + + /** + * Terminate immediately with an HTTP 503 Forbidden response. + */ + static function forbidden() { + throw new Exception("@todo FORBIDDEN", 503); + } + + /** + * Internal method to set a permission + * + * @param Group_Model $group + * @param string $perm_name + * @param Item_Model $item + * @param boolean $value + */ + private static function _set(Group_Model $group, $perm_name, $album, $value) { + if (get_class($group) != "Group_Model") { + throw new Exception("@todo PERMISSIONS_ONLY_WORK_ON_GROUPS"); + } + if (!$album->loaded) { + throw new Exception("@todo INVALID_ALBUM $album->id"); + } + if (!$album->is_album()) { + throw new Exception("@todo INVALID_ALBUM_TYPE not an album"); + } + $access = model_cache::get("access_intent", $album->id, "item_id"); + $access->__set("{$perm_name}_{$group->id}", $value); + $access->save(); + + if ($perm_name == "view") { + self::_update_access_view_cache($group, $album); + } else { + self::_update_access_non_view_cache($group, $perm_name, $album); + } + + self::_update_htaccess_files($album, $group, $perm_name, $value); + } + + /** + * Allow a group to have a permission on an item. + * + * @param Group_Model $group + * @param string $perm_name + * @param Item_Model $item + */ + static function allow($group, $perm_name, $item) { + self::_set($group, $perm_name, $item, self::ALLOW); + } + + /** + * Deny a group the given permission on an item. + * + * @param Group_Model $group + * @param string $perm_name + * @param Item_Model $item + */ + static function deny($group, $perm_name, $item) { + self::_set($group, $perm_name, $item, self::DENY); + } + + /** + * Unset the given permission for this item and use inherited values + * + * @param Group_Model $group + * @param string $perm_name + * @param Item_Model $item + */ + static function reset($group, $perm_name, $item) { + if ($item->id == 1) { + throw new Exception("@todo CANT_RESET_ROOT_PERMISSION"); + } + self::_set($group, $perm_name, $item, null); + } + + /** + * Register a permission so that modules can use it. + * + * @param string $name The internal name for for this permission + * @param string $display_name The internationalized version of the displayable name + * @return void + */ + static function register_permission($name, $display_name) { + $permission = ORM::factory("permission", $name); + if ($permission->loaded) { + throw new Exception("@todo PERMISSION_ALREADY_EXISTS $name"); + } + $permission->name = $name; + $permission->display_name = $display_name; + $permission->save(); + + foreach (self::_get_all_groups() as $group) { + self::_add_columns($name, $group); + } + } + + /** + * Delete a permission. + * + * @param string $perm_name + * @return void + */ + static function delete_permission($name) { + foreach (self::_get_all_groups() as $group) { + self::_drop_columns($name, $group); + } + $permission = ORM::factory("permission")->where("name", $name)->find(); + if ($permission->loaded) { + $permission->delete(); + } + } + + /** + * Add the appropriate columns for a new group + * + * @param Group_Model $group + * @return void + */ + static function add_group($group) { + foreach (ORM::factory("permission")->find_all() as $perm) { + self::_add_columns($perm->name, $group); + } + } + + /** + * Remove a group's permission columns (usually when it's deleted) + * + * @param Group_Model $group + * @return void + */ + static function delete_group($group) { + foreach (ORM::factory("permission")->find_all() as $perm) { + self::_drop_columns($perm->name, $group); + } + } + + /** + * Add new access rows when a new item is added. + * + * @param Item_Model $item + * @return void + */ + static function add_item($item) { + $access_intent = ORM::factory("access_intent", $item->id); + if ($access_intent->loaded) { + throw new Exception("@todo ITEM_ALREADY_ADDED $item->id"); + } + $access_intent = ORM::factory("access_intent"); + $access_intent->item_id = $item->id; + $access_intent->save(); + + // Create a new access cache entry and copy the parents values. + $access_cache = ORM::factory("access_cache"); + $access_cache->item_id = $item->id; + if ($item->id != 1) { + $parent_access_cache = + ORM::factory("access_cache")->where("item_id", $item->parent()->id)->find(); + foreach (self::_get_all_groups() as $group) { + foreach (ORM::factory("permission")->find_all() as $perm) { + $field = "{$perm->name}_{$group->id}"; + if ($perm->name == "view") { + $item->$field = $item->parent()->$field; + } else { + $access_cache->$field = $parent_access_cache->$field; + } + } + } + } + $item->save(); + $access_cache->save(); + } + + /** + * Delete appropriate access rows when an item is deleted. + * + * @param Item_Model $item + * @return void + */ + static function delete_item($item) { + ORM::factory("access_intent")->where("item_id", $item->id)->find()->delete(); + ORM::factory("access_cache")->where("item_id", $item->id)->find()->delete(); + } + + /** + * Verify our Cross Site Request Forgery token is valid, else throw an exception. + */ + static function verify_csrf() { + $input = Input::instance(); + if ($input->post("csrf", $input->get("csrf", null)) !== Session::instance()->get("csrf")) { + self::forbidden(); + } + } + + /** + * Get the Cross Site Request Forgery token for this session. + * @return string + */ + static function csrf_token() { + $session = Session::instance(); + $csrf = $session->get("csrf"); + if (empty($csrf)) { + $csrf = md5(rand()); + $session->set("csrf", $csrf); + } + return $csrf; + } + + /** + * Generate an element containing the Cross Site Request Forgery token for this session. + * @return string + */ + static function csrf_form_field() { + return ""; + } + + /** + * Internal method to get all available groups. + * + * @return ORM_Iterator + */ + private static function _get_all_groups() { + // When we build the core package, it's possible that the user module is not installed yet. + // This is ok at packaging time, so work around it. + if (module::is_active("user")) { + return ORM::factory("group")->find_all(); + } else { + return array(); + } + } + + /** + * Internal method to remove Permission/Group columns + * + * @param Group_Model $group + * @param string $perm_name + * @return void + */ + private static function _drop_columns($perm_name, $group) { + $db = Database::instance(); + $field = "{$perm_name}_{$group->id}"; + $cache_table = $perm_name == "view" ? "items" : "access_caches"; + $db->query("ALTER TABLE {{$cache_table}} DROP `$field`"); + $db->query("ALTER TABLE {access_intents} DROP `$field`"); + ORM::factory("access_intent")->clear_cache(); + } + + /** + * Internal method to add Permission/Group columns + * + * @param Group_Model $group + * @param string $perm_name + * @return void + */ + private static function _add_columns($perm_name, $group) { + $db = Database::instance(); + $field = "{$perm_name}_{$group->id}"; + $cache_table = $perm_name == "view" ? "items" : "access_caches"; + $db->query("ALTER TABLE {{$cache_table}} ADD `$field` SMALLINT NOT NULL DEFAULT 0"); + $db->query("ALTER TABLE {access_intents} ADD `$field` BOOLEAN DEFAULT NULL"); + $db->update("access_intents", array($field => 0), array("item_id" => 1)); + ORM::factory("access_intent")->clear_cache(); + } + + /** + * Update the Access_Cache model based on information from the Access_Intent model for view + * permissions only. + * + * @todo: use database locking + * + * @param Group_Model $group + * @param Item_Model $item + * @return void + */ + private static function _update_access_view_cache($group, $item) { + $access = ORM::factory("access_intent")->where("item_id", $item->id)->find(); + + $db = Database::instance(); + $field = "view_{$group->id}"; + + // With view permissions, deny values in the parent can override allow values in the child, + // so start from the bottom of the tree and work upwards overlaying negative on top of + // positive. + // + // If the item's intent is ALLOW or DEFAULT, it's possible that some ancestor has specified + // 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) { + $tmp_item = ORM::factory("item") + ->where("left <", $item->left) + ->where("right >", $item->right) + ->join("access_intents", "access_intents.item_id", "items.id") + ->where("access_intents.$field", self::DENY) + ->orderby("left", "DESC") + ->limit(1) + ->find(); + if ($tmp_item->loaded) { + $item = $tmp_item; + } + } + + // We will have a problem if we're trying to change a DENY to an ALLOW because the + // access_caches table will already contain DENY values and we won't be able to overwrite + // them according the rule above. So mark every permission below this level as UNKNOWN so + // that we can tell which permissions have been changed, and which ones need to be updated. + $db->update("items", array($field => self::UNKNOWN), + array("left >=" => $item->left, "right <=" => $item->right)); + + $query = ORM::factory("access_intent") + ->select(array("access_intents.$field", "items.left", "items.right", "items.id")) + ->join("items", "items.id", "access_intents.item_id") + ->where("left >=", $item->left) + ->where("right <=", $item->right) + ->where("type", "album") + ->where("access_intents.$field IS NOT", null) + ->orderby("level", "DESC") + ->find_all(); + foreach ($query as $row) { + if ($row->$field == self::ALLOW) { + // Propagate ALLOW for any row that is still UNKNOWN. + $db->update("items", array($field => $row->$field), + array($field => self::UNKNOWN, "left >=" => $row->left, "right <=" => $row->right)); + } else if ($row->$field == self::DENY) { + // DENY overwrites everything below it + $db->update("items", array($field => $row->$field), + array("left >=" => $row->left, "right <=" => $row->right)); + } + } + + // Finally, if our intent is DEFAULT at this point it means that we were unable to find a + // DENY parent in the hierarchy to propagate from. So we'll still have a UNKNOWN values in + // the hierarchy, and all of those are safe to change to ALLOW. + $db->update("items", array($field => self::ALLOW), + array($field => self::UNKNOWN, "left >=" => $item->left, "right <=" => $item->right)); + } + + /** + * Update the Access_Cache model based on information from the Access_Intent model for non-view + * permissions. + * + * @todo: use database locking + * + * @param Group_Model $group + * @param string $perm_name + * @param Item_Model $item + * @return void + */ + private static function _update_access_non_view_cache($group, $perm_name, $item) { + $access = ORM::factory("access_intent")->where("item_id", $item->id)->find(); + + $db = Database::instance(); + $field = "{$perm_name}_{$group->id}"; + + // If the item's intent is DEFAULT, then we need to back up the chain to find the nearest + // parent with an intent and propagate from there. + // + // @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 === null) { + $tmp_item = ORM::factory("item") + ->join("access_intents", "items.id", "access_intents.item_id") + ->where("left <", $item->left) + ->where("right >", $item->right) + ->where("$field IS NOT", null) + ->orderby("left", "DESC") + ->limit(1) + ->find(); + if ($tmp_item->loaded) { + $item = $tmp_item; + } + } + + // With non-view permissions, each level can override any permissions that came above it + // so start at the top and work downwards, overlaying permissions as we go. + $query = ORM::factory("access_intent") + ->select(array("access_intents.$field", "items.left", "items.right")) + ->join("items", "items.id", "access_intents.item_id") + ->where("left >=", $item->left) + ->where("right <=", $item->right) + ->where("$field IS NOT", null) + ->orderby("level", "ASC") + ->find_all(); + foreach ($query as $row) { + $db->query( + "UPDATE {access_caches} SET `$field` = {$row->$field} " . + "WHERE `item_id` IN " . + " (SELECT `id` FROM {items} " . + " WHERE `left` >= $row->left " . + " AND `right` <= $row->right)"); + } + } + + /** + * Maintain .htacccess files to prevent direct access to albums, resizes and thumbnails when we + * apply the view and view_full permissions to guest users. + */ + private static function _update_htaccess_files($album, $group, $perm_name, $value) { + if ($group->id != 1 || !($perm_name == "view" || $perm_name == "view_full")) { + return; + } + + $dirs = array($album->file_path()); + if ($perm_name == "view") { + $dirs[] = dirname($album->resize_path()); + $dirs[] = dirname($album->thumb_path()); + } + + $base_url = url::site("file_proxy"); + foreach ($dirs as $dir) { + if ($value === self::DENY) { + $fp = fopen("$dir/.htaccess", "w+"); + fwrite($fp, "\n"); + fwrite($fp, " RewriteEngine On\n"); + fwrite($fp, " RewriteRule (.*) $base_url/\$1 [L]\n"); + fwrite($fp, "\n"); + fwrite($fp, "\n"); + fwrite($fp, " Order Deny,Allow\n"); + fwrite($fp, " Deny from All\n"); + fwrite($fp, "\n"); + fclose($fp); + } else { + @unlink($dir . "/.htaccess"); + } + } + } + + static function private_key() { + return module::get_var("core", "private_key"); + } + + /** + * Verify that our htaccess based permission system actually works. Create a temporary + * directory containing an .htaccess file that uses mod_rewrite to redirect /verify to + * /success. Then request that url. If we retrieve it successfully, then our redirects are + * working and our permission system works. + */ + static function htaccess_works() { + $success_url = url::file("var/tmp/security_test/success"); + + @mkdir(VARPATH . "tmp/security_test"); + if ($fp = @fopen(VARPATH . "tmp/security_test/.htaccess", "w+")) { + fwrite($fp, "RewriteEngine On\n"); + fwrite($fp, "RewriteRule verify $success_url [L]\n"); + fclose($fp); + } + + if ($fp = @fopen(VARPATH . "tmp/security_test/success", "w+")) { + fwrite($fp, "success"); + fclose($fp); + } + + list ($response) = remote::do_request(url::abs_file("var/tmp/security_test/verify")); + $works = $response == "HTTP/1.1 200 OK"; + @dir::unlink(VARPATH . "tmp/security_test"); + + return $works; + } +} diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php new file mode 100644 index 00000000..362b93d0 --- /dev/null +++ b/modules/gallery/helpers/album.php @@ -0,0 +1,132 @@ +loaded || !$parent->is_album()) { + throw new Exception("@todo INVALID_PARENT"); + } + + if (strpos($name, "/")) { + throw new Exception("@todo NAME_CANNOT_CONTAIN_SLASH"); + } + + // We don't allow trailing periods as a security measure + // ref: http://dev.kohanaphp.com/issues/684 + if (rtrim($name, ".") != $name) { + throw new Exception("@todo NAME_CANNOT_END_IN_PERIOD"); + } + + $album = ORM::factory("item"); + $album->type = "album"; + $album->title = $title; + $album->description = $description; + $album->name = $name; + $album->owner_id = $owner_id; + $album->thumb_dirty = 1; + $album->resize_dirty = 1; + $album->rand_key = ((float)mt_rand()) / (float)mt_getrandmax(); + $album->sort_column = "weight"; + $album->sort_order = "ASC"; + + while (ORM::factory("item") + ->where("parent_id", $parent->id) + ->where("name", $album->name) + ->find()->id) { + $album->name = "{$name}-" . rand(); + } + + $album = $album->add_to_parent($parent); + mkdir($album->file_path()); + mkdir(dirname($album->thumb_path())); + mkdir(dirname($album->resize_path())); + + module::event("item_created", $album); + + return $album; + } + + static function get_add_form($parent) { + $form = new Forge("albums/{$parent->id}", "", "post", array("id" => "gAddAlbumForm")); + $group = $form->group("add_album") + ->label(t("Add an album to %album_title", array("album_title" => $parent->title))); + $group->input("title")->label(t("Title")); + $group->textarea("description")->label(t("Description")); + $group->input("name")->label(t("Directory Name")) + ->callback("item::validate_no_slashes") + ->error_messages("no_slashes", t("The directory name can't contain the \"/\" character")); + $group->hidden("type")->value("album"); + $group->submit("")->value(t("Create")); + $form->add_rules_from(ORM::factory("item")); + return $form; + } + + static function get_edit_form($parent) { + $form = new Forge("albums/{$parent->id}", "", "post", array("id" => "gEditAlbumForm")); + $form->hidden("_method")->value("put"); + $group = $form->group("edit_album")->label(t("Edit Album")); + + $group->input("title")->label(t("Title"))->value($parent->title); + $group->textarea("description")->label(t("Description"))->value($parent->description); + if ($parent->id != 1) { + $group->input("dirname")->label(t("Directory Name"))->value($parent->name) + ->callback("item::validate_no_slashes") + ->error_messages("no_slashes", t("The directory name can't contain a \"/\"")) + ->callback("item::validate_no_trailing_period") + ->error_messages("no_trailing_period", t("The directory name can't end in \".\"")); + } + + $sort_order = $group->group("sort_order", array("id" => "gAlbumSortOrder")) + ->label(t("Sort Order")); + + $sort_order->dropdown("column", array("id" => "gAlbumSortColumn")) + ->label(t("Sort by")) + ->options(array("weight" => t("Default"), + "captured" => t("Capture Date"), + "created" => t("Creation Date"), + "title" => t("Title"), + "updated" => t("Updated Date"), + "view_count" => t("Number of views"), + "rand_key" => t("Random"))) + ->selected($parent->sort_column); + $sort_order->dropdown("direction", array("id" => "gAlbumSortDirection")) + ->label(t("Order")) + ->options(array("ASC" => t("Ascending"), + "DESC" => t("Descending"))) + ->selected($parent->sort_order); + $group->hidden("type")->value("album"); + $group->submit("")->value(t("Modify")); + $form->add_rules_from(ORM::factory("item")); + return $form; + } +} diff --git a/modules/gallery/helpers/batch.php b/modules/gallery/helpers/batch.php new file mode 100644 index 00000000..0faa3369 --- /dev/null +++ b/modules/gallery/helpers/batch.php @@ -0,0 +1,40 @@ +set("batch_level", $session->get("batch_level", 0) + 1); + } + + static function stop() { + $session = Session::instance(); + $batch_level = $session->get("batch_level", 0) - 1; + if ($batch_level > 0) { + $session->set("batch_level", $batch_level); + } else { + $session->delete("batch_level"); + module::event("batch_complete"); + } + } + + static function in_progress() { + return Session::instance()->get("batch_level", 0) > 0; + } +} diff --git a/modules/gallery/helpers/block_manager.php b/modules/gallery/helpers/block_manager.php new file mode 100644 index 00000000..022626e5 --- /dev/null +++ b/modules/gallery/helpers/block_manager.php @@ -0,0 +1,67 @@ +name}_block"; + if (method_exists($class_name, "get_list")) { + foreach (call_user_func(array($class_name, "get_list")) as $id => $title) { + $blocks["{$module->name}:$id"] = $title; + } + } + } + return $blocks; + } + + static function get_html($location) { + $active = self::get_active($location); + $result = ""; + foreach ($active as $id => $desc) { + if (method_exists("$desc[0]_block", "get")) { + $block = call_user_func(array("$desc[0]_block", "get"), $desc[1]); + $block->id = $id; + $result .= $block; + } + } + return $result; + } +} diff --git a/modules/gallery/helpers/core.php b/modules/gallery/helpers/core.php new file mode 100644 index 00000000..63f51f86 --- /dev/null +++ b/modules/gallery/helpers/core.php @@ -0,0 +1,52 @@ +admin) { + Router::$controller = "maintenance"; + Router::$controller_path = APPPATH . "controllers/maintenance.php"; + Router::$method = "index"; + } + } + + /** + * This function is called when the Gallery is fully initialized. We relay it to modules as the + * "gallery_ready" event. Any module that wants to perform an action at the start of every + * request should implement the _event::gallery_ready() handler. + */ + static function ready() { + module::event("gallery_ready"); + } + + /** + * This function is called right before the Kohana framework shuts down. We relay it to modules + * as the "gallery_shutdown" event. Any module that wants to perform an action at the start of + * every request should implement the _event::gallery_shutdown() handler. + */ + static function shutdown() { + module::event("gallery_shutdown"); + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/core_block.php b/modules/gallery/helpers/core_block.php new file mode 100644 index 00000000..0e2e9c54 --- /dev/null +++ b/modules/gallery/helpers/core_block.php @@ -0,0 +1,100 @@ + t("Welcome to Gallery 3!"), + "photo_stream" => t("Photo Stream"), + "log_entries" => t("Log Entries"), + "stats" => t("Gallery Stats"), + "platform_info" => t("Platform Information"), + "project_news" => t("Gallery Project News")); + } + + static function get($block_id) { + $block = new Block(); + switch($block_id) { + case "welcome": + $block->css_id = "gWelcome"; + $block->title = t("Welcome to Gallery3"); + $block->content = new View("admin_block_welcome.html"); + break; + + case "photo_stream": + $block->css_id = "gPhotoStream"; + $block->title = t("Photo Stream"); + $block->content = new View("admin_block_photo_stream.html"); + $block->content->photos = + ORM::factory("item")->where("type", "photo")->orderby("created", "DESC")->find_all(10); + break; + + case "log_entries": + $block->css_id = "gLogEntries"; + $block->title = t("Log Entries"); + $block->content = new View("admin_block_log_entries.html"); + $block->content->entries = ORM::factory("log")->orderby("timestamp", "DESC")->find_all(5); + break; + + case "stats": + $block->css_id = "gStats"; + $block->title = t("Gallery Stats"); + $block->content = new View("admin_block_stats.html"); + $block->content->album_count = ORM::factory("item")->where("type", "album")->count_all(); + $block->content->photo_count = ORM::factory("item")->where("type", "photo")->count_all(); + break; + + case "platform_info": + $block->css_id = "gPlatform"; + $block->title = t("Platform Information"); + $block->content = new View("admin_block_platform.html"); + if (is_readable("/proc/loadavg")) { + $block->content->load_average = + join(" ", array_slice(split(" ", array_shift(file("/proc/loadavg"))), 0, 3)); + } else { + $block->content->load_average = t("Unavailable"); + } + break; + + case "project_news": + $block->css_id = "gProjectNews"; + $block->title = t("Gallery Project News"); + $block->content = new View("admin_block_news.html"); + $block->content->feed = feed::parse("http://gallery.menalto.com/node/feed", 3); + break; + + case "block_adder": + $block->css_id = "gBlockAdder"; + $block->title = t("Dashboard Content"); + $block->content = self::get_add_block_form(); + } + + return $block; + } + + static function get_add_block_form() { + $form = new Forge("admin/dashboard/add_block", "", "post", + array("id" => "gAddDashboardBlockForm")); + $group = $form->group("add_block")->label(t("Add Block")); + $group->dropdown("id")->label("Available Blocks")->options(block_manager::get_available()); + $group->submit("center")->value(t("Add to center")); + $group->submit("sidebar")->value(t("Add to sidebar")); + return $form; + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/core_event.php b/modules/gallery/helpers/core_event.php new file mode 100644 index 00000000..bbb53cc9 --- /dev/null +++ b/modules/gallery/helpers/core_event.php @@ -0,0 +1,46 @@ +admin && module::get_var("core", "choose_default_tookit", null)) { + graphics::choose_default_toolkit(); + module::clear_var("core", "choose_default_tookit"); + } + } +} diff --git a/modules/gallery/helpers/core_installer.php b/modules/gallery/helpers/core_installer.php new file mode 100644 index 00000000..cffcbedb --- /dev/null +++ b/modules/gallery/helpers/core_installer.php @@ -0,0 +1,278 @@ +query("CREATE TABLE {access_caches} ( + `id` int(9) NOT NULL auto_increment, + `item_id` int(9), + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {access_intents} ( + `id` int(9) NOT NULL auto_increment, + `item_id` int(9), + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {graphics_rules} ( + `id` int(9) NOT NULL auto_increment, + `active` BOOLEAN default 0, + `args` varchar(255) default NULL, + `module_name` varchar(64) NOT NULL, + `operation` varchar(64) NOT NULL, + `priority` int(9) NOT NULL, + `target` varchar(32) NOT NULL, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {items} ( + `id` int(9) NOT NULL auto_increment, + `album_cover_item_id` int(9) default NULL, + `captured` int(9) default NULL, + `created` int(9) default NULL, + `description` varchar(2048) default NULL, + `height` int(9) default NULL, + `left` int(9) NOT NULL, + `level` int(9) NOT NULL, + `mime_type` varchar(64) default NULL, + `name` varchar(255) default NULL, + `owner_id` int(9) default NULL, + `parent_id` int(9) NOT NULL, + `rand_key` float default NULL, + `relative_path_cache` varchar(255) default NULL, + `resize_dirty` boolean default 1, + `resize_height` int(9) default NULL, + `resize_width` int(9) default NULL, + `right` int(9) NOT NULL, + `sort_column` varchar(64) default NULL, + `sort_order` char(4) default 'ASC', + `thumb_dirty` boolean default 1, + `thumb_height` int(9) default NULL, + `thumb_width` int(9) default NULL, + `title` varchar(255) default NULL, + `type` varchar(32) NOT NULL, + `updated` int(9) default NULL, + `view_count` int(9) default 0, + `weight` int(9) NOT NULL default 0, + `width` int(9) default NULL, + PRIMARY KEY (`id`), + KEY `parent_id` (`parent_id`), + KEY `type` (`type`), + KEY `random` (`rand_key`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {logs} ( + `id` int(9) NOT NULL auto_increment, + `category` varchar(64) default NULL, + `html` varchar(255) default NULL, + `message` text default NULL, + `referer` varchar(255) default NULL, + `severity` int(9) default 0, + `timestamp` int(9) default 0, + `url` varchar(255) default NULL, + `user_id` int(9) default 0, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {messages} ( + `id` int(9) NOT NULL auto_increment, + `key` varchar(255) default NULL, + `severity` varchar(32) default NULL, + `value` varchar(255) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`key`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {modules} ( + `id` int(9) NOT NULL auto_increment, + `active` BOOLEAN default 0, + `name` varchar(64) default NULL, + `version` int(9) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`name`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {themes} ( + `id` int(9) NOT NULL auto_increment, + `name` varchar(64) default NULL, + `version` int(9) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`name`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {permissions} ( + `id` int(9) NOT NULL auto_increment, + `display_name` varchar(64) default NULL, + `name` varchar(64) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`name`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {incoming_translations} ( + `id` int(9) NOT NULL auto_increment, + `key` char(32) NOT NULL, + `locale` char(10) NOT NULL, + `message` text NOT NULL, + `revision` int(9) DEFAULT NULL, + `translation` text, + PRIMARY KEY (`id`), + UNIQUE KEY(`key`, `locale`), + KEY `locale_key` (`locale`, `key`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {outgoing_translations} ( + `id` int(9) NOT NULL auto_increment, + `base_revision` int(9) DEFAULT NULL, + `key` char(32) NOT NULL, + `locale` char(10) NOT NULL, + `message` text NOT NULL, + `translation` text, + PRIMARY KEY (`id`), + UNIQUE KEY(`key`, `locale`), + KEY `locale_key` (`locale`, `key`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {sessions} ( + `session_id` varchar(127) NOT NULL, + `data` text NOT NULL, + `last_activity` int(10) UNSIGNED NOT NULL, + PRIMARY KEY (`session_id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {tasks} ( + `id` int(9) NOT NULL auto_increment, + `callback` varchar(128) default NULL, + `context` text NOT NULL, + `done` boolean default 0, + `name` varchar(128) default NULL, + `owner_id` int(9) default NULL, + `percent_complete` int(9) default 0, + `state` varchar(32) default NULL, + `status` varchar(255) default NULL, + `updated` int(9) default NULL, + PRIMARY KEY (`id`), + KEY (`owner_id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {vars} ( + `id` int(9) NOT NULL auto_increment, + `module_name` varchar(64) NOT NULL, + `name` varchar(64) NOT NULL, + `value` text, + PRIMARY KEY (`id`), + UNIQUE KEY(`module_name`, `name`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + foreach (array("albums", "logs", "modules", "resizes", "thumbs", "tmp", "uploads") as $dir) { + @mkdir(VARPATH . $dir); + } + + access::register_permission("view", "View"); + access::register_permission("view_full", "View Full Size"); + access::register_permission("edit", "Edit"); + access::register_permission("add", "Add"); + + $root = ORM::factory("item"); + $root->type = "album"; + $root->title = "Gallery"; + $root->description = ""; + $root->left = 1; + $root->right = 2; + $root->parent_id = 0; + $root->level = 1; + $root->thumb_dirty = 1; + $root->resize_dirty = 1; + $root->sort_column = "weight"; + $root->sort_order = "ASC"; + $root->save(); + access::add_item($root); + + module::set_var("core", "active_site_theme", "default"); + module::set_var("core", "active_admin_theme", "admin_default"); + module::set_var("core", "page_size", 9); + module::set_var("core", "thumb_size", 200); + module::set_var("core", "resize_size", 640); + module::set_var("core", "default_locale", "en_US"); + module::set_var("core", "image_quality", 75); + + // Add rules for generating our thumbnails and resizes + graphics::add_rule( + "core", "thumb", "resize", + array("width" => 200, "height" => 200, "master" => Image::AUTO), + 100); + graphics::add_rule( + "core", "resize", "resize", + array("width" => 640, "height" => 480, "master" => Image::AUTO), + 100); + + // Instantiate default themes (site and admin) + foreach (array("default", "admin_default") as $theme_name) { + $theme_info = new ArrayObject(parse_ini_file(THEMEPATH . $theme_name . "/theme.info"), + ArrayObject::ARRAY_AS_PROPS); + $theme = ORM::factory("theme"); + $theme->name = $theme_name; + $theme->version = $theme_info->version; + $theme->save(); + } + + block_manager::add("dashboard_sidebar", "core", "block_adder"); + block_manager::add("dashboard_sidebar", "core", "stats"); + block_manager::add("dashboard_sidebar", "core", "platform_info"); + block_manager::add("dashboard_sidebar", "core", "project_news"); + block_manager::add("dashboard_center", "core", "welcome"); + block_manager::add("dashboard_center", "core", "photo_stream"); + block_manager::add("dashboard_center", "core", "log_entries"); + + module::set_version("core", 1); + module::set_var("core", "version", "3.0 pre-beta svn"); + module::set_var("core", "choose_default_tookit", 1); + } + } + + static function uninstall() { + $db = Database::instance(); + $db->query("DROP TABLE IF EXISTS {access_caches}"); + $db->query("DROP TABLE IF EXISTS {access_intents}"); + $db->query("DROP TABLE IF EXISTS {graphics_rules}"); + $db->query("DROP TABLE IF EXISTS {items}"); + $db->query("DROP TABLE IF EXISTS {logs}"); + $db->query("DROP TABLE IF EXISTS {messages}"); + $db->query("DROP TABLE IF EXISTS {modules}"); + $db->query("DROP TABLE IF EXISTS {themes}"); + $db->query("DROP TABLE IF EXISTS {incoming_translations}"); + $db->query("DROP TABLE IF EXISTS {outgoing_translations}"); + $db->query("DROP TABLE IF EXISTS {permissions}"); + $db->query("DROP TABLE IF EXISTS {sessions}"); + $db->query("DROP TABLE IF EXISTS {tasks}"); + $db->query("DROP TABLE IF EXISTS {vars}"); + foreach (array("albums", "resizes", "thumbs", "uploads", + "modules", "logs", "database.php") as $entry) { + system("/bin/rm -rf " . VARPATH . $entry); + } + } +} diff --git a/modules/gallery/helpers/core_menu.php b/modules/gallery/helpers/core_menu.php new file mode 100644 index 00000000..eb208560 --- /dev/null +++ b/modules/gallery/helpers/core_menu.php @@ -0,0 +1,162 @@ +admin) { + $menu->append($scaffold_menu = Menu::factory("submenu") + ->id("scaffold") + ->label("Scaffold")); + $scaffold_menu->append(Menu::factory("link") + ->id("scaffold_home") + ->label("Dashboard") + ->url(url::site("scaffold"))); + } + + $menu->append(Menu::factory("link") + ->id("home") + ->label(t("Home")) + ->url(url::site("albums/1"))); + + $item = $theme->item(); + + if (user::active()->admin || ($item && access::can("edit", $item))) { + $menu->append($options_menu = Menu::factory("submenu") + ->id("options_menu") + ->label(t("Options"))); + + if ($item && access::can("edit", $item)) { + $options_menu + ->append(Menu::factory("dialog") + ->id("edit_item") + ->label($item->is_album() ? t("Edit album") : t("Edit photo")) + ->url(url::site("form/edit/{$item->type}s/$item->id"))); + + // @todo Move album options menu to the album quick edit pane + // @todo Create resized item quick edit pane menu + if ($item->is_album()) { + $options_menu + ->append(Menu::factory("dialog") + ->id("add_item") + ->label(t("Add a photo")) + ->url(url::site("simple_uploader/app/$item->id"))) + ->append(Menu::factory("dialog") + ->id("add_album") + ->label(t("Add an album")) + ->url(url::site("form/add/albums/$item->id?type=album"))) + ->append(Menu::factory("dialog") + ->id("edit_permissions") + ->label(t("Edit permissions")) + ->url(url::site("permissions/browse/$item->id"))); + } + } + } + + if (user::active()->admin) { + $menu->append($admin_menu = Menu::factory("submenu") + ->id("admin_menu") + ->label(t("Admin"))); + self::admin($admin_menu, $theme); + foreach (module::active() as $module) { + if ($module->name == "core") { + continue; + } + $class = "{$module->name}_menu"; + if (method_exists($class, "admin")) { + call_user_func_array(array($class, "admin"), array(&$admin_menu, $theme)); + } + } + } + } + + static function album($menu, $theme) { + } + + static function photo($menu, $theme) { + if (access::can("view_full", $theme->item())) { + $menu + ->append(Menu::factory("link") + ->id("fullsize") + ->label(t("View full size")) + ->url("#") + ->css_class("gFullSizeLink")); + } + $menu + ->append(Menu::factory("link") + ->id("album") + ->label(t("Return to album")) + ->url($theme->item()->parent()->url("show={$theme->item->id}")) + ->css_id("gAlbumLink")); + } + + static function admin($menu, $theme) { + $menu + ->append(Menu::factory("link") + ->id("dashboard") + ->label(t("Dashboard")) + ->url(url::site("admin"))) + ->append(Menu::factory("submenu") + ->id("settings_menu") + ->label(t("Settings")) + ->append(Menu::factory("link") + ->id("graphics_toolkits") + ->label(t("Graphics")) + ->url(url::site("admin/graphics"))) + ->append(Menu::factory("link") + ->id("languages") + ->label(t("Languages")) + ->url(url::site("admin/languages"))) + ->append(Menu::factory("link") + ->id("l10n_mode") + ->label(Session::instance()->get("l10n_mode", false) + ? t("Stop translating") : t("Start translating")) + ->url(url::site("l10n_client/toggle_l10n_mode?csrf=" . + access::csrf_token()))) + ->append(Menu::factory("link") + ->id("advanced") + ->label("Advanced") + ->url(url::site("admin/advanced_settings")))) + ->append(Menu::factory("link") + ->id("modules") + ->label(t("Modules")) + ->url(url::site("admin/modules"))) + ->append(Menu::factory("submenu") + ->id("content_menu") + ->label(t("Content"))) + ->append(Menu::factory("submenu") + ->id("appearance_menu") + ->label(t("Appearance")) + ->append(Menu::factory("link") + ->id("themes") + ->label(t("Theme Choice")) + ->url(url::site("admin/themes"))) + ->append(Menu::factory("link") + ->id("theme_details") + ->label(t("Theme Options")) + ->url(url::site("admin/theme_details")))) + ->append(Menu::factory("link") + ->id("maintenance") + ->label(t("Maintenance")) + ->url(url::site("admin/maintenance"))) + ->append(Menu::factory("submenu") + ->id("statistics_menu") + ->label(t("Statistics")) + ->url("#")); + } +} diff --git a/modules/gallery/helpers/core_search.php b/modules/gallery/helpers/core_search.php new file mode 100644 index 00000000..9957a493 --- /dev/null +++ b/modules/gallery/helpers/core_search.php @@ -0,0 +1,24 @@ +description, $item->name, $item->title)); + } +} diff --git a/modules/gallery/helpers/core_task.php b/modules/gallery/helpers/core_task.php new file mode 100644 index 00000000..e078192c --- /dev/null +++ b/modules/gallery/helpers/core_task.php @@ -0,0 +1,166 @@ +count(); + $tasks = array(); + $tasks[] = Task_Definition::factory() + ->callback("core_task::rebuild_dirty_images") + ->name(t("Rebuild Images")) + ->description($dirty_count ? + t2("You have one out of date photo", + "You have %count out of date photos", + $dirty_count) + : t("All your photos are up to date")) + ->severity($dirty_count ? log::WARNING : log::SUCCESS); + + $tasks[] = Task_Definition::factory() + ->callback("core_task::update_l10n") + ->name(t("Update translations")) + ->description(t("Download new and updated translated strings")) + ->severity(log::SUCCESS); + + return $tasks; + } + + /** + * Task that rebuilds all dirty images. + * @param Task_Model the task + */ + static function rebuild_dirty_images($task) { + $result = graphics::find_dirty_images_query(); + $remaining = $result->count(); + $completed = $task->get("completed", 0); + + $i = 0; + foreach ($result as $row) { + $item = ORM::factory("item", $row->id); + if ($item->loaded) { + graphics::generate($item); + } + + $completed++; + $remaining--; + + if (++$i == 2) { + break; + } + } + + $task->status = t2("Updated: 1 image. Total: %total_count.", + "Updated: %count images. Total: %total_count.", + $completed, + array("total_count" => ($remaining + $completed))); + + if ($completed + $remaining > 0) { + $task->percent_complete = (int)(100 * $completed / ($completed + $remaining)); + } else { + $task->percent_complete = 100; + } + + $task->set("completed", $completed); + if ($remaining == 0) { + $task->done = true; + $task->state = "success"; + site_status::clear("graphics_dirty"); + } + } + + static function update_l10n(&$task) { + $start = microtime(true); + $dirs = $task->get("dirs"); + $files = $task->get("files"); + $cache = $task->get("cache", array()); + $i = 0; + + switch ($task->get("mode", "init")) { + case "init": // 0% + $dirs = array("core", "modules", "themes", "installer"); + $files = array(); + $task->set("mode", "find_files"); + $task->status = t("Finding files"); + break; + + case "find_files": // 0% - 10% + while (($dir = array_pop($dirs)) && microtime(true) - $start < 0.5) { + if (basename($dir) == "tests") { + continue; + } + + foreach (glob(DOCROOT . "$dir/*") as $path) { + $relative_path = str_replace(DOCROOT, "", $path); + if (is_dir($path)) { + $dirs[] = $relative_path; + } else { + $files[] = $relative_path; + } + } + } + + $task->status = t2("Finding files: found 1 file", + "Finding files: found %count files", count($files)); + + if (!$dirs) { + $task->set("mode", "scan_files"); + $task->set("total_files", count($files)); + $task->status = t("Scanning files"); + $task->percent_complete = 10; + } + break; + + case "scan_files": // 10% - 90% + while (($file = array_pop($files)) && microtime(true) - $start < 0.5) { + $file = DOCROOT . $file; + switch (pathinfo($file, PATHINFO_EXTENSION)) { + case "php": + l10n_scanner::scan_php_file($file, $cache); + break; + + case "info": + l10n_scanner::scan_info_file($file, $cache); + break; + } + } + + $total_files = $task->get("total_files"); + $task->status = t2("Scanning files: scanned 1 file", + "Scanning files: scanned %count files", $total_files - count($files)); + + $task->percent_complete = 10 + 80 * ($total_files - count($files)) / $total_files; + if (empty($files)) { + $task->set("mode", "fetch_updates"); + $task->status = t("Fetching updates"); + $task->percent_complete = 90; + } + break; + + case "fetch_updates": // 90% - 100% + l10n_client::fetch_updates(); + $task->done = true; + $task->state = "success"; + $task->status = t("Translations installed/updated"); + $task->percent_complete = 100; + } + + $task->set("files", $files); + $task->set("dirs", $dirs); + $task->set("cache", $cache); + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/core_theme.php b/modules/gallery/helpers/core_theme.php new file mode 100644 index 00000000..28f544a1 --- /dev/null +++ b/modules/gallery/helpers/core_theme.php @@ -0,0 +1,137 @@ +get("debug")) { + $buf .= ""; + } + if (($theme->page_type == "album" || $theme->page_type == "photo") + && access::can("edit", $theme->item())) { + $buf .= ""; + $buf .= html::script("core/js/quick.js"); + } + if ($theme->page_type == "photo" && access::can("view_full", $theme->item())) { + $buf .= ""; + $buf .= html::script("core/js/fullsize.js"); + } + + if ($session->get("l10n_mode", false)) { + $buf .= ""; + $buf .= html::script("lib/jquery.cookie.js"); + $buf .= html::script("core/js/l10n_client.js"); + } + + return $buf; + } + + static function resize_top($theme, $item) { + if (access::can("edit", $item)) { + $edit_link = url::site("quick/pane/$item->id?page_type=photo"); + return "
"; + } + } + + static function resize_bottom($theme, $item) { + if (access::can("edit", $item)) { + return "
"; + } + } + + static function thumb_top($theme, $child) { + if (access::can("edit", $child)) { + $edit_link = url::site("quick/pane/$child->id?page_type=album"); + return "
"; + } + } + + static function thumb_bottom($theme, $child) { + if (access::can("edit", $child)) { + return "
"; + } + } + + static function admin_head($theme) { + $session = Session::instance(); + $buf = ""; + if ($session->get("debug")) { + $buf .= ""; + } + + if ($session->get("l10n_mode", false)) { + $buf .= ""; + $buf .= html::script("lib/jquery.cookie.js"); + $buf .= html::script("core/js/l10n_client.js"); + } + + return $buf; + } + + static function page_bottom($theme) { + $session = Session::instance(); + if ($session->get("profiler", false)) { + $profiler = new Profiler(); + $profiler->render(); + } + if ($session->get("l10n_mode", false)) { + return L10n_Client_Controller::l10n_form(); + } + + if ($session->get("after_install")) { + $session->delete("after_install"); + return new View("after_install_loader.html"); + } + } + + static function admin_page_bottom($theme) { + $session = Session::instance(); + if ($session->get("profiler", false)) { + $profiler = new Profiler(); + $profiler->render(); + } + if ($session->get("l10n_mode", false)) { + return L10n_Client_Controller::l10n_form(); + } + } + + static function credits() { + return "
  • " . + t("Powered by Gallery %version", + array("url" => "http://gallery.menalto.com", + "version" => module::get_var("core", "version"))) . + "
  • "; + } + + static function admin_credits() { + return core_theme::credits(); + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/dir.php b/modules/gallery/helpers/dir.php new file mode 100644 index 00000000..1717bdd9 --- /dev/null +++ b/modules/gallery/helpers/dir.php @@ -0,0 +1,40 @@ +isDot()) { + unset($resource); + continue; + } else if ($resource->isFile()) { + unlink($resource->getPathName()); + } else if ($resource->isDir()) { + dir::unlink($resource->getRealPath()); + } + unset($resource); + } + return @rmdir($path); + } + return false; + } + + +} diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php new file mode 100644 index 00000000..805a95c0 --- /dev/null +++ b/modules/gallery/helpers/graphics.php @@ -0,0 +1,387 @@ + 200, "height" => 200, "master" => Image::AUTO), 100); + * + * Specifies that "core" is adding a rule to resize thumbnails down to a max of 200px on + * the longest side. The core module adds default rules at a priority of 100. You can set + * higher and lower priorities to perform operations before or after this fires. + * + * @param string $module_name the module that added the rule + * @param string $target the target for this operation ("thumb" or "resize") + * @param string $operation the name of the operation + * @param array $args arguments to the operation + * @param integer $priority the priority for this rule (lower priorities are run first) + */ + static function add_rule($module_name, $target, $operation, $args, $priority) { + $rule = ORM::factory("graphics_rule"); + $rule->module_name = $module_name; + $rule->target = $target; + $rule->operation = $operation; + $rule->priority = $priority; + $rule->args = serialize($args); + $rule->active = true; + $rule->save(); + + self::mark_dirty($target == "thumb", $target == "resize"); + } + + /** + * Remove any matching graphics rules + * @param string $module_name the module that added the rule + * @param string $target the target for this operation ("thumb" or "resize") + * @param string $operation the name of the operation + */ + static function remove_rule($module_name, $target, $operation) { + ORM::factory("graphics_rule") + ->where("module_name", $module_name) + ->where("target", $target) + ->where("operation", $operation) + ->delete_all(); + + self::mark_dirty($target == "thumb", $target == "resize"); + } + + /** + * Remove all rules for this module + * @param string $module_name + */ + static function remove_rules($module_name) { + $status = Database::instance()->delete("graphics_rules", array("module_name" => $module_name)); + if (count($status)) { + self::mark_dirty(true, true); + } + } + + /** + * Activate the rules for this module, typically done when the module itself is deactivated. + * Note that this does not mark images as dirty so that if you deactivate and reactivate a + * module it won't cause all of your images to suddenly require a rebuild. + */ + static function activate_rules($module_name) { + Database::instance() + ->update("graphics_rules",array("active" => true), array("module_name" => $module_name)); + } + + /** + * Deactivate the rules for this module, typically done when the module itself is deactivated. + * Note that this does not mark images as dirty so that if you deactivate and reactivate a + * module it won't cause all of your images to suddenly require a rebuild. + */ + static function deactivate_rules($module_name) { + Database::instance() + ->update("graphics_rules",array("active" => false), array("module_name" => $module_name)); + } + + /** + * Rebuild the thumb and resize for the given item. + * @param Item_Model $item + */ + static function generate($item) { + if ($item->is_album()) { + if (!$cover = $item->album_cover()) { + return; + } + $input_file = $cover->file_path(); + $input_item = $cover; + } else { + $input_file = $item->file_path(); + $input_item = $item; + } + + if ($item->thumb_dirty) { + $ops["thumb"] = $item->thumb_path(); + } + if ($item->resize_dirty && !$item->is_album() && !$item->is_movie()) { + $ops["resize"] = $item->resize_path(); + } + + if (empty($ops)) { + return; + } + + try { + foreach ($ops as $target => $output_file) { + if ($input_item->is_movie()) { + // Convert the movie to a JPG first + $output_file = preg_replace("/...$/", "jpg", $output_file); + movie::extract_frame($input_file, $output_file); + $working_file = $output_file; + } else { + $working_file = $input_file; + } + + foreach (ORM::factory("graphics_rule") + ->where("target", $target) + ->where("active", true) + ->orderby("priority", "asc") + ->find_all() as $rule) { + $args = array($working_file, $output_file, unserialize($rule->args)); + call_user_func_array(array("graphics", $rule->operation), $args); + $working_file = $output_file; + } + } + + if (!empty($ops["thumb"])) { + $dims = getimagesize($item->thumb_path()); + $item->thumb_width = $dims[0]; + $item->thumb_height = $dims[1]; + $item->thumb_dirty = 0; + } + + if (!empty($ops["resize"])) { + $dims = getimagesize($item->resize_path()); + $item->resize_width = $dims[0]; + $item->resize_height = $dims[1]; + $item->resize_dirty = 0; + } + $item->save(); + } catch (Kohana_Exception $e) { + // Something went wrong rebuilding the image. Leave it dirty and move on. + // @todo we should handle this better. + Kohana::log("error", "Caught exception rebuilding image: {$item->title}\n" . + $e->getTraceAsString()); + } + } + + /** + * Resize an image. Valid options are width, height and master. Master is one of the Image + * master dimension constants. + * + * @param string $input_file + * @param string $output_file + * @param array $options + */ + static function resize($input_file, $output_file, $options) { + if (!self::$init) { + self::init_toolkit(); + } + + if (filesize($input_file) == 0) { + throw new Exception("@todo MALFORMED_INPUT_FILE"); + } + + $dims = getimagesize($input_file); + if (max($dims[0], $dims[1]) < min($options["width"], $options["height"])) { + // Image would get upscaled; do nothing + copy($input_file, $output_file); + } else { + Image::factory($input_file) + ->resize($options["width"], $options["height"], $options["master"]) + ->quality(module::get_var("core", "image_quality")) + ->save($output_file); + } + } + + /** + * Rotate an image. Valid options are degrees + * + * @param string $input_file + * @param string $output_file + * @param array $options + */ + static function rotate($input_file, $output_file, $options) { + if (!self::$init) { + self::init_toolkit(); + } + + Image::factory($input_file) + ->quality(module::get_var("core", "image_quality")) + ->rotate($options["degrees"]) + ->save($output_file); + } + + /** + * Overlay an image on top of the input file. + * + * Valid options are: file, mime_type, position, transparency_percent, padding + * + * Valid positions: northwest, north, northeast, + * west, center, east, + * southwest, south, southeast + * + * padding is in pixels + * + * @param string $input_file + * @param string $output_file + * @param array $options + */ + static function composite($input_file, $output_file, $options) { + if (!self::$init) { + self::init_toolkit(); + } + + list ($width, $height) = getimagesize($input_file); + list ($w_width, $w_height) = getimagesize($options["file"]); + + $pad = isset($options["padding"]) ? $options["padding"] : 10; + $top = $pad; + $left = $pad; + $y_center = max($height / 2 - $w_height / 2, $pad); + $x_center = max($width / 2 - $w_width / 2, $pad); + $bottom = max($height - $w_height - $pad, $pad); + $right = max($width - $w_width - $pad, $pad); + + switch ($options["position"]) { + case "northwest": $x = $left; $y = $top; break; + case "north": $x = $x_center; $y = $top; break; + case "northeast": $x = $right; $y = $top; break; + case "west": $x = $left; $y = $y_center; break; + case "center": $x = $x_center; $y = $y_center; break; + case "east": $x = $right; $y = $y_center; break; + case "southwest": $x = $left; $y = $bottom; break; + case "south": $x = $x_center; $y = $bottom; break; + case "southeast": $x = $right; $y = $bottom; break; + } + + Image::factory($input_file) + ->composite($options["file"], $x, $y, $options["transparency"]) + ->quality(module::get_var("core", "image_quality")) + ->save($output_file); + } + + /** + * Return a query result that locates all items with dirty images. + * @return Database_Result Query result + */ + static function find_dirty_images_query() { + return Database::instance()->query( + "SELECT `id` FROM {items} " . + "WHERE ((`thumb_dirty` = 1 AND (`type` <> 'album' OR `album_cover_item_id` IS NOT NULL))" . + " OR (`resize_dirty` = 1 AND `type` = 'photo')) " . + " AND `id` != 1"); + } + + /** + * Mark thumbnails and resizes as dirty. They will have to be rebuilt. + */ + static function mark_dirty($thumbs, $resizes) { + if ($thumbs || $resizes) { + $db = Database::instance(); + $fields = array(); + if ($thumbs) { + $fields["thumb_dirty"] = 1; + } + if ($resizes) { + $fields["resize_dirty"] = 1; + } + $db->update("items", $fields, true); + } + + $count = self::find_dirty_images_query()->count(); + if ($count) { + site_status::warning( + t2("One of your photos is out of date. Click here to fix it", + "%count of your photos are out of date. Click here to fix them", + $count, + array("attrs" => sprintf( + 'href="%s" class="gDialogLink"', + url::site("admin/maintenance/start/core_task::rebuild_dirty_images?csrf=__CSRF__")))), + "graphics_dirty"); + } + } + + /** + * Detect which graphics toolkits are available on this system. Return an array of key value + * pairs where the key is one of gd, imagemagick, graphicsmagick and the value is information + * about that toolkit. For GD we return the version string, and for ImageMagick and + * GraphicsMagick we return the path to the directory containing the appropriate binaries. + */ + static function detect_toolkits() { + $gd = function_exists("gd_info") ? gd_info() : array(); + $exec = function_exists("exec"); + if (!isset($gd["GD Version"])) { + $gd["GD Version"] = false; + } + return array("gd" => $gd, + "imagemagick" => $exec ? dirname(exec("which convert")) : false, + "graphicsmagick" => $exec ? dirname(exec("which gm")) : false); + } + + /** + * This needs to be run once, after the initial install, to choose a graphics toolkit. + */ + static function choose_default_toolkit() { + // Detect a graphics toolkit + $toolkits = graphics::detect_toolkits(); + foreach (array("imagemagick", "graphicsmagick", "gd") as $tk) { + if ($toolkits[$tk]) { + module::set_var("core", "graphics_toolkit", $tk); + module::set_var("core", "graphics_toolkit_path", $tk == "gd" ? "" : $toolkits[$tk]); + break; + } + } + if (!module::get_var("core", "graphics_toolkit")) { + site_status::warning( + t("Graphics toolkit missing! Please choose a toolkit", + array("url" => url::site("admin/graphics"))), + "missing_graphics_toolkit"); + } + } + + /** + * Choose which driver the Kohana Image library uses. + */ + static function init_toolkit() { + switch(module::get_var("core", "graphics_toolkit")) { + case "gd": + Kohana::config_set("image.driver", "GD"); + break; + + case "imagemagick": + Kohana::config_set("image.driver", "ImageMagick"); + Kohana::config_set( + "image.params.directory", module::get_var("core", "graphics_toolkit_path")); + break; + + case "graphicsmagick": + Kohana::config_set("image.driver", "GraphicsMagick"); + Kohana::config_set( + "image.params.directory", module::get_var("core", "graphics_toolkit_path")); + break; + } + + self::$init = 1; + } + + /** + * Verify that a specific graphics function is available with the active toolkit. + * @param string $func (eg rotate, resize) + * @return boolean + */ + static function can($func) { + if (module::get_var("core", "graphics_toolkit") == "gd" && + $func == "rotate" && + !function_exists("imagerotate")) { + return false; + } + + return true; + } +} diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php new file mode 100644 index 00000000..7daaf1e1 --- /dev/null +++ b/modules/gallery/helpers/item.php @@ -0,0 +1,105 @@ +parent(); + if ($parent->album_cover_item_id == $source->id) { + if ($parent->children_count() > 1) { + foreach ($parent->children(2) as $child) { + if ($child->id != $source->id) { + $new_cover_item = $child; + break; + } + } + item::make_album_cover($new_cover_item); + } else { + item::remove_album_cover($parent); + } + } + + $source->move_to($target); + + // If the target has no cover item, make this it. + if ($target->album_cover_item_id == null) { + item::make_album_cover($source); + } + } + + static function make_album_cover($item) { + $parent = $item->parent(); + access::required("edit", $parent); + + model_cache::clear("item", $parent->album_cover_item_id); + $parent->album_cover_item_id = $item->is_album() ? $item->album_cover_item_id : $item->id; + $parent->thumb_dirty = 1; + $parent->save(); + graphics::generate($parent); + $grand_parent = $parent->parent(); + if ($grand_parent && $grand_parent->album_cover_item_id == null) { + item::make_album_cover($parent); + } + } + + static function remove_album_cover($album) { + access::required("edit", $album); + @unlink($album->thumb_path()); + + model_cache::clear("item", $album->album_cover_item_id) ; + $album->album_cover_item_id = null; + $album->thumb_width = 0; + $album->thumb_height = 0; + $album->thumb_dirty = 1; + $album->save(); + graphics::generate($album); + } + + static function validate_no_slashes($input) { + if (strpos($input->value, "/") !== false) { + $input->add_error("no_slashes", 1); + } + } + + static function validate_no_trailing_period($input) { + if (rtrim($input->value, ".") !== $input->value) { + $input->add_error("no_trailing_period", 1); + } + } + + static function validate_no_name_conflict($input) { + $itemid = Input::instance()->post("item"); + if (is_array($itemid)) { + $itemid = $itemid[0]; + } + $item = ORM::factory("item") + ->in("id", $itemid) + ->find(); + if (Database::instance() + ->from("items") + ->where("parent_id", $item->parent_id) + ->where("id <>", $item->id) + ->where("name", $input->value) + ->count_records()) { + $input->add_error("conflict", 1); + } + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/l10n_client.php b/modules/gallery/helpers/l10n_client.php new file mode 100644 index 00000000..ec4c5429 --- /dev/null +++ b/modules/gallery/helpers/l10n_client.php @@ -0,0 +1,203 @@ + $version, + "client_token" => self::client_token(), + "signature" => $signature, + "uid" => self::server_uid($api_key))); + if (!remote::success($response_status)) { + return false; + } + return true; + } + + static function fetch_updates() { + $request->locales = array(); + $request->messages = new stdClass(); + + $locales = locale::installed(); + foreach ($locales as $locale => $locale_data) { + $request->locales[] = $locale; + } + + // @todo Batch requests (max request size) + foreach (Database::instance() + ->select("key", "locale", "revision", "translation") + ->from("incoming_translations") + ->get() + ->as_array() as $row) { + if (!isset($request->messages->{$row->key})) { + $request->messages->{$row->key} = 1; + } + if (!empty($row->revision) && !empty($row->translation)) { + if (!is_object($request->messages->{$row->key})) { + $request->messages->{$row->key} = new stdClass(); + } + $request->messages->{$row->key}->{$row->locale} = $row->revision; + } + } + // @todo Include messages from outgoing_translations? + + $request_data = json_encode($request); + $url = self::_server_url() . "?q=translations/fetch"; + list ($response_data, $response_status) = remote::post($url, array("data" => $request_data)); + if (!remote::success($response_status)) { + throw new Exception("@todo TRANSLATIONS_FETCH_REQUEST_FAILED " . $response_status); + } + if (empty($response_data)) { + log::info("translations", "Translations fetch request resulted in an empty response"); + return; + } + + $response = json_decode($response_data); + + // Response format (JSON payload): + // [{key:, translation: , rev:, locale:}, + // {key:, ...} + // ] + $count = count($response); + log::info("translations", "Installed $count new / updated translation messages"); + + foreach ($response as $message_data) { + // @todo Better input validation + if (empty($message_data->key) || empty($message_data->translation) || + empty($message_data->locale) || empty($message_data->rev)) { + throw new Exception("@todo TRANSLATIONS_FETCH_REQUEST_FAILED: Invalid response data"); + } + $key = $message_data->key; + $locale = $message_data->locale; + $revision = $message_data->rev; + $translation = serialize(json_decode($message_data->translation)); + + // @todo Should we normalize the incoming_translations table into messages(id, key, message) + // and incoming_translations(id, translation, locale, revision)? Or just allow + // incoming_translations.message to be NULL? + $locale = $message_data->locale; + $entry = ORM::factory("incoming_translation") + ->where(array("key" => $key, "locale" => $locale)) + ->find(); + if (!$entry->loaded) { + // @todo Load a message key -> message (text) dict into memory outside of this loop + $root_entry = ORM::factory("incoming_translation") + ->where(array("key" => $key, "locale" => "root")) + ->find(); + $entry->key = $key; + $entry->message = $root_entry->message; + $entry->locale = $locale; + } + $entry->revision = $revision; + $entry->translation = $translation; + $entry->save(); + } + } + + static function submit_translations() { + // Request format (HTTP POST): + // client_token = + // uid = + // signature = md5(user_api_key($uid, $client_token) . $data . $client_token)) + // data = // JSON payload + // + // {: {message: + // translations: {: , + // : ...}}, + // : {...} + // } + + // @todo Batch requests (max request size) + // @todo include base_revision in submission / how to handle resubmissions / edit fights? + foreach (Database::instance() + ->select("key", "message", "locale", "base_revision", "translation") + ->from("outgoing_translations") + ->get() as $row) { + $key = $row->key; + if (!isset($request->{$key})) { + $request->{$key}->message = json_encode(unserialize($row->message)); + } + $request->{$key}->translations->{$row->locale} = json_encode(unserialize($row->translation)); + } + + // @todo reduce memory consumpotion, e.g. free $request + $request_data = json_encode($request); + $url = self::_server_url() . "?q=translations/submit"; + $signature = self::_sign($request_data); + + list ($response_data, $response_status) = remote::post( + $url, array("data" => $request_data, + "client_token" => self::client_token(), + "signature" => $signature, + "uid" => self::server_uid())); + + if (!remote::success($response_status)) { + throw new Exception("@todo TRANSLATIONS_SUBMISSION_FAILED " . $response_status); + } + if (empty($response_data)) { + return; + } + + $response = json_decode($response_data); + // Response format (JSON payload): + // [{key:, locale:, rev:, status:}, + // {key:, ...} + // ] + + // @todo Move messages out of outgoing into incoming, using new rev? + // @todo show which messages have been rejected / are pending? + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/l10n_scanner.php b/modules/gallery/helpers/l10n_scanner.php new file mode 100644 index 00000000..80b6f01c --- /dev/null +++ b/modules/gallery/helpers/l10n_scanner.php @@ -0,0 +1,154 @@ +select("key") + ->from("incoming_translations") + ->where("locale", "root") + ->get() as $row) { + $cache[$row->key] = true; + } + } + + $key = I18n::get_message_key($message); + if (array_key_exists($key, $cache)) { + return $cache[$key]; + } + + $entry = ORM::factory("incoming_translation", array("key" => $key)); + if (!$entry->loaded) { + $entry->key = $key; + $entry->message = serialize($message); + $entry->locale = "root"; + $entry->save(); + } + } + + static function scan_php_file($file, &$cache) { + $code = file_get_contents($file); + $raw_tokens = token_get_all($code); + unset($code); + + $tokens = array(); + $func_token_list = array("t" => array(), "t2" => array()); + $token_number = 0; + // Filter out HTML / whitespace, and build a lookup for global function calls. + foreach ($raw_tokens as $token) { + if ((!is_array($token)) || (($token[0] != T_WHITESPACE) && ($token[0] != T_INLINE_HTML))) { + if (is_array($token)) { + if ($token[0] == T_STRING && in_array($token[1], array("t", "t2"))) { + $func_token_list[$token[1]][] = $token_number; + } + } + $tokens[] = $token; + $token_number++; + } + } + unset($raw_tokens); + + if (!empty($func_token_list["t"])) { + l10n_scanner::_parse_t_calls($tokens, $func_token_list["t"], $cache); + } + if (!empty($func_token_list["t2"])) { + l10n_scanner::_parse_plural_calls($tokens, $func_token_list["t2"], $cache); + } + } + + static function scan_info_file($file, &$cache) { + $code = file_get_contents($file); + if (preg_match("#name\s*?=\s*(.*?)\ndescription\s*?=\s*(.*)\n#", $code, $matches)) { + unset($matches[0]); + foreach ($matches as $string) { + l10n_scanner::process_message($string, $cache); + } + } + } + + private static function _parse_t_calls(&$tokens, &$call_list, &$cache) { + foreach ($call_list as $index) { + $function_name = $tokens[$index++]; + $parens = $tokens[$index++]; + $first_param = $tokens[$index++]; + $next_token = $tokens[$index]; + + if ($parens == "(") { + if (in_array($next_token, array(")", ",")) + && (is_array($first_param) && ($first_param[0] == T_CONSTANT_ENCAPSED_STRING))) { + $message = self::_escape_quoted_string($first_param[1]); + l10n_scanner::process_message($message, $cache); + } else { + // t() found, but inside is something which is not a string literal. + // @todo Call status callback with error filename/line. + } + } + } + } + + private static function _parse_plural_calls(&$tokens, &$call_list, &$cache) { + foreach ($call_list as $index) { + $function_name = $tokens[$index++]; + $parens = $tokens[$index++]; + $first_param = $tokens[$index++]; + $first_separator = $tokens[$index++]; + $second_param = $tokens[$index++]; + $next_token = $tokens[$index]; + + if ($parens == "(") { + if ($first_separator == "," && $next_token == "," + && is_array($first_param) && $first_param[0] == T_CONSTANT_ENCAPSED_STRING + && is_array($second_param) && $second_param[0] == T_CONSTANT_ENCAPSED_STRING) { + $singular = self::_escape_quoted_string($first_param[1]); + $plural = self::_escape_quoted_string($first_param[1]); + l10n_scanner::process_message(array("one" => $singular, "other" => $plural), $cache); + } else { + // t2() found, but inside is something which is not a string literal. + // @todo Call status callback with error filename/line. + } + } + } + } + + /** + * Escape quotes in a strings depending on the surrounding + * quote type used. + * + * @param $str The strings to escape + */ + private static function _escape_quoted_string($str) { + $quo = substr($str, 0, 1); + $str = substr($str, 1, -1); + if ($quo == '"') { + $str = stripcslashes($str); + } else { + $str = strtr($str, array("\\'" => "'", "\\\\" => "\\")); + } + return addcslashes($str, "\0..\37\\\""); + } +} diff --git a/modules/gallery/helpers/locale.php b/modules/gallery/helpers/locale.php new file mode 100644 index 00000000..b707637f --- /dev/null +++ b/modules/gallery/helpers/locale.php @@ -0,0 +1,119 @@ +$code)) { + $installed[$code] = $available[$code]; + } + } + return $installed; + } + + static function update_installed($locales) { + // Ensure that the default is included... + $default = module::get_var("core", "default_locale"); + $locales = array_merge($locales, array($default)); + + module::set_var("core", "installed_locales", join("|", $locales)); + } + + // @todo Might want to add a localizable language name as well. + private static function _init_language_data() { + $l["af_ZA"] = "Afrikaans"; // Afrikaans + $l["ar_SA"] = "العربية"; // Arabic + $l["bg_BG"] = "Български"; // Bulgarian + $l["ca_ES"] = "Catalan"; // Catalan + $l["cs_CZ"] = "Česky"; // Czech + $l["da_DK"] = "Dansk"; // Danish + $l["de_DE"] = "Deutsch"; // German + $l["el_GR"] = "Greek"; // Greek + $l["en_GB"] = "English (UK)"; // English (UK) + $l["en_US"] = "English (US)"; // English (US) + $l["es_AR"] = "Español (AR)"; // Spanish (AR) + $l["es_ES"] = "Español"; // Spanish (ES) + $l["es_MX"] = "Español (MX)"; // Spanish (MX) + $l["et_EE"] = "Eesti"; // Estonian + $l["eu_ES"] = "Euskara"; // Basque + $l["fa_IR"] = "فارسي"; // Farsi + $l["fi_FI"] = "Suomi"; // Finnish + $l["fr_FR"] = "Français"; // French + $l["ga_IE"] = "Gaeilge"; // Irish + $l["he_IL"] = "עברית"; // Hebrew + $l["hu_HU"] = "Magyar"; // Hungarian + $l["is_IS"] = "Icelandic"; // Icelandic + $l["it_IT"] = "Italiano"; // Italian + $l["ja_JP"] = "日本語"; // Japanese + $l["ko_KR"] = "한국말"; // Korean + $l["lt_LT"] = "Lietuvių"; // Lithuanian + $l["lv_LV"] = "Latviešu"; // Latvian + $l["nl_NL"] = "Nederlands"; // Dutch + $l["no_NO"] = "Norsk bokmål"; // Norwegian + $l["pl_PL"] = "Polski"; // Polish + $l["pt_BR"] = "Português Brasileiro"; // Portuguese (BR) + $l["pt_PT"] = "Português"; // Portuguese (PT) + $l["ro_RO"] = "Română"; // Romanian + $l["ru_RU"] = "Русский"; // Russian + $l["sk_SK"] = "Slovenčina"; // Slovak + $l["sl_SI"] = "Slovenščina"; // Slovenian + $l["sr_CS"] = "Srpski"; // Serbian + $l["sv_SE"] = "Svenska"; // Swedish + $l["tr_TR"] = "Türkçe"; // Turkish + $l["uk_UA"] = "Українська"; // Ukrainian + $l["vi_VN"] = "Tiếng Việt"; // Vietnamese + $l["zh_CN"] = "简体中文"; // Chinese (CN) + $l["zh_TW"] = "繁體中文"; // Chinese (TW) + asort($l, SORT_LOCALE_STRING); + self::$locales = $l; + } + + static function display_name($locale=null) { + if (empty(self::$locales)) { + self::_init_language_data(); + } + $locale or $locale = I18n::instance()->locale(); + + return self::$locales["$locale"]; + } + + static function is_rtl($locale) { + return in_array($locale, array("he_IL", "fa_IR", "ar_SA")); + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/log.php b/modules/gallery/helpers/log.php new file mode 100644 index 00000000..451f985a --- /dev/null +++ b/modules/gallery/helpers/log.php @@ -0,0 +1,108 @@ +category = $category; + $log->message = $message; + $log->severity = $severity; + $log->html = $html; + $log->url = substr(url::abs_current(true), 0, 255); + $log->referer = request::referrer(null); + $log->timestamp = time(); + $log->user_id = user::active()->id; + $log->save(); + } + + + /** + * Convert a message severity to a CSS class + * @param integer $severity + * @return string + */ + static function severity_class($severity) { + switch($severity) { + case self::SUCCESS: + return "gSuccess"; + + case self::INFO: + return "gInfo"; + + case self::WARNING: + return "gWarning"; + + case self::ERROR: + return "gError"; + } + } +} diff --git a/modules/gallery/helpers/message.php b/modules/gallery/helpers/message.php new file mode 100644 index 00000000..af3b96cc --- /dev/null +++ b/modules/gallery/helpers/message.php @@ -0,0 +1,108 @@ +get("messages"); + $status[] = array($msg, $severity); + $session->set("messages", $status); + } + + /** + * Get any pending messages. There are two types of messages, transient and permanent. + * Permanent messages are used to let the admin know that there are pending administrative + * issues that need to be resolved. Transient ones are only displayed once. + * @return html text + */ + static function get() { + $buf = array(); + + $messages = Session::instance()->get_once("messages", array()); + foreach ($messages as $msg) { + $buf[] = "
  • $msg[0]
  • "; + } + if ($buf) { + return "
      " . implode("", $buf) . "
    "; + } + } + + /** + * Convert a message severity to a CSS class + * @param integer $severity + * @return string + */ + static function severity_class($severity) { + switch($severity) { + case self::SUCCESS: + return "gSuccess"; + + case self::INFO: + return "gInfo"; + + case self::WARNING: + return "gWarning"; + + case self::ERROR: + return "gError"; + } + } +} diff --git a/modules/gallery/helpers/model_cache.php b/modules/gallery/helpers/model_cache.php new file mode 100644 index 00000000..2649fdbd --- /dev/null +++ b/modules/gallery/helpers/model_cache.php @@ -0,0 +1,46 @@ +$model_name->$field_name->$id)) { + $model = ORM::factory($model_name)->where($field_name, $id)->find(); + if (!$model->loaded) { + throw new Exception("@todo MISSING_MODEL $model_name:$id"); + } + self::$cache->$model_name->$field_name->$id = $model; + } + + return self::$cache->$model_name->$field_name->$id; + } + + static function clear($model_name, $id, $field_name="id") { + if (!empty(self::$cache->$model_name->$field_name->$id)) { + unset(self::$cache->$model_name->$field_name->$id); + } + } + + static function set($model) { + self::$cache->{$model->object_name} + ->{$model->primary_key} + ->{$model->{$model->primary_key}} = $model; + } +} diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php new file mode 100644 index 00000000..a48c89ed --- /dev/null +++ b/modules/gallery/helpers/module.php @@ -0,0 +1,357 @@ +loaded) { + $module->name = $module_name; + $module->active = $module_name == "core"; // only core is active by default + } + $module->version = 1; + $module->save(); + Kohana::log("debug", "$module_name: version is now $version"); + } + + /** + * Load the corresponding Module_Model + * @param string $module_name + */ + static function get($module_name) { + // @todo can't easily use model_cache here because it throw an exception on missing models. + return ORM::factory("module", array("name" => $module_name)); + } + + /** + * Check to see if a module is installed + * @param string $module_name + */ + static function is_installed($module_name) { + return array_key_exists($module_name, self::$modules); + } + + /** + * Check to see if a module is active + * @param string $module_name + */ + static function is_active($module_name) { + return array_key_exists($module_name, self::$modules) && + self::$modules[$module_name]->active; + } + + /** + * Return the list of available modules, including uninstalled modules. + */ + static function available() { + $modules = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS); + foreach (array_merge(array("core/module.info"), glob(MODPATH . "*/module.info")) as $file) { + $module_name = basename(dirname($file)); + $modules->$module_name = new ArrayObject(parse_ini_file($file), ArrayObject::ARRAY_AS_PROPS); + $modules->$module_name->installed = self::is_installed($module_name); + $modules->$module_name->active = self::is_active($module_name); + $modules->$module_name->version = self::get_version($module_name); + $modules->$module_name->locked = false; + } + + // Lock certain modules + $modules->core->locked = true; + $modules->user->locked = true; + $modules->ksort(); + + return $modules; + } + + /** + * Return a list of all the active modules in no particular order. + */ + static function active() { + return self::$active; + } + + /** + * Install a module. This will call _installer::install(), which is responsible for + * creating database tables, setting module variables and and calling module::set_version(). + * Note that after installing, the module must be activated before it is available for use. + * @param string $module_name + */ + static function install($module_name) { + $kohana_modules = Kohana::config("core.modules"); + $kohana_modules[] = MODPATH . $module_name; + Kohana::config_set("core.modules", $kohana_modules); + + $installer_class = "{$module_name}_installer"; + if (method_exists($installer_class, "install")) { + call_user_func_array(array($installer_class, "install"), array()); + } + + // Now the module is installed but inactive, so don't leave it in the active path + array_pop($kohana_modules); + Kohana::config_set("core.modules", $kohana_modules); + + log::success( + "module", t("Installed module %module_name", array("module_name" => $module_name))); + } + + /** + * Activate an installed module. This will call _installer::activate() which should take + * any steps to make sure that the module is ready for use. This will also activate any + * existing graphics rules for this module. + * @param string $module_name + */ + static function activate($module_name) { + $kohana_modules = Kohana::config("core.modules"); + $kohana_modules[] = MODPATH . $module_name; + Kohana::config_set("core.modules", $kohana_modules); + + $installer_class = "{$module_name}_installer"; + if (method_exists($installer_class, "activate")) { + call_user_func_array(array($installer_class, "activate"), array()); + } + + $module = self::get($module_name); + if ($module->loaded) { + $module->active = true; + $module->save(); + } + + self::load_modules(); + graphics::activate_rules($module_name); + log::success( + "module", t("Activated module %module_name", array("module_name" => $module_name))); + } + + /** + * Deactivate an installed module. This will call _installer::deactivate() which + * should take any cleanup steps to make sure that the module isn't visible in any way. + * @param string $module_name + */ + static function deactivate($module_name) { + $installer_class = "{$module_name}_installer"; + if (method_exists($installer_class, "deactivate")) { + call_user_func_array(array($installer_class, "deactivate"), array()); + } + + $module = self::get($module_name); + if ($module->loaded) { + $module->active = false; + $module->save(); + } + + self::load_modules(); + graphics::deactivate_rules($module_name); + log::success( + "module", t("Deactivated module %module_name", array("module_name" => $module_name))); + } + + /** + * Uninstall a deactivated module. This will call _installer::uninstall() which should + * take whatever steps necessary to make sure that all traces of a module are gone. + * @param string $module_name + */ + static function uninstall($module_name) { + $installer_class = "{$module_name}_installer"; + if (method_exists($installer_class, "uninstall")) { + call_user_func(array($installer_class, "uninstall")); + } + + graphics::remove_rule($module_name); + $module = self::get($module_name); + if ($module->loaded) { + $module->delete(); + } + + // We could delete the module vars here too, but it's nice to leave them around + // in case the module gets reinstalled. + + self::load_modules(); + log::success( + "module", t("Uninstalled module %module_name", array("module_name" => $module_name))); + } + + /** + * Load the active modules. This is called at bootstrap time. + */ + static function load_modules() { + // Reload module list from the config file since we'll do a refresh after calling install() + $core = Kohana::config_load("core"); + $kohana_modules = $core["modules"]; + $modules = ORM::factory("module")->find_all(); + + self::$modules = array(); + self::$active = array(); + foreach ($modules as $module) { + self::$modules[$module->name] = $module; + if ($module->active) { + self::$active[] = $module; + } + if ($module->name != "core") { + $kohana_modules[] = MODPATH . $module->name; + } + } + Kohana::config_set("core.modules", $kohana_modules); + } + + /** + * Run a specific event on all active modules. + * @param string $name the event name + * @param mixed $data data to pass to each event handler + */ + static function event($name, &$data=null) { + $args = func_get_args(); + array_shift($args); + $function = str_replace(".", "_", $name); + + foreach (self::$modules as $module) { + if (!$module->active) { + continue; + } + + $class = "{$module->name}_event"; + if (method_exists($class, $function)) { + call_user_func_array(array($class, $function), $args); + } + } + } + + /** + * Get a variable from this module + * @param string $module_name + * @param string $name + * @param string $default_value + * @return the value + */ + static function get_var($module_name, $name, $default_value=null) { + // We cache all vars in core._cache so that we can load all vars at once for + // performance. + if (empty(self::$var_cache)) { + $row = Database::instance() + ->select("value") + ->from("vars") + ->where(array("module_name" => "core", "name" => "_cache")) + ->get() + ->current(); + if ($row) { + self::$var_cache = unserialize($row->value); + } else { + // core._cache doesn't exist. Create it now. + foreach (Database::instance() + ->select("module_name", "name", "value") + ->from("vars") + ->orderby("module_name", "name") + ->get() as $row) { + if ($row->module_name == "core" && $row->name == "_cache") { + // This could happen if there's a race condition + continue; + } + self::$var_cache->{$row->module_name}->{$row->name} = $row->value; + } + $cache = ORM::factory("var"); + $cache->module_name = "core"; + $cache->name = "_cache"; + $cache->value = serialize(self::$var_cache); + $cache->save(); + } + } + + if (isset(self::$var_cache->$module_name->$name)) { + return self::$var_cache->$module_name->$name; + } else { + return $default_value; + } + } + + /** + * Store a variable for this module + * @param string $module_name + * @param string $name + * @param string $value + */ + static function set_var($module_name, $name, $value) { + $var = ORM::factory("var") + ->where("module_name", $module_name) + ->where("name", $name) + ->find(); + if (!$var->loaded) { + $var->module_name = $module_name; + $var->name = $name; + } + $var->value = $value; + $var->save(); + + Database::instance()->delete("vars", array("module_name" => "core", "name" => "_cache")); + self::$var_cache = null; + } + + /** + * Increment the value of a variable for this module + * @param string $module_name + * @param string $name + * @param string $increment (optional, default is 1) + */ + static function incr_var($module_name, $name, $increment=1) { + Database::instance()->query( + "UPDATE {vars} SET `value` = `value` + $increment " . + "WHERE `module_name` = '$module_name' " . + "AND `name` = '$name'"); + + Database::instance()->delete("vars", array("module_name" => "core", "name" => "_cache")); + self::$var_cache = null; + } + + /** + * Remove a variable for this module. + * @param string $module_name + * @param string $name + */ + static function clear_var($module_name, $name) { + $var = ORM::factory("var") + ->where("module_name", $module_name) + ->where("name", $name) + ->find(); + if ($var->loaded) { + $var->delete(); + } + + Database::instance()->delete("vars", array("module_name" => "core", "name" => "_cache")); + self::$var_cache = null; + } + + /** + * Return the version of the installed module. + * @param string $module_name + */ + static function get_version($module_name) { + return self::get($module_name)->version; + } +} diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php new file mode 100644 index 00000000..3293d4ac --- /dev/null +++ b/modules/gallery/helpers/movie.php @@ -0,0 +1,153 @@ +loaded || !$parent->is_album()) { + throw new Exception("@todo INVALID_PARENT"); + } + + if (!is_file($filename)) { + throw new Exception("@todo MISSING_MOVIE_FILE"); + } + + if (strpos($name, "/")) { + throw new Exception("@todo NAME_CANNOT_CONTAIN_SLASH"); + } + + // We don't allow trailing periods as a security measure + // ref: http://dev.kohanaphp.com/issues/684 + if (rtrim($name, ".") != $name) { + throw new Exception("@todo NAME_CANNOT_END_IN_PERIOD"); + } + + $movie_info = movie::getmoviesize($filename); + + // Force an extension onto the name + $pi = pathinfo($filename); + if (empty($pi["extension"])) { + $pi["extension"] = image_type_to_extension($movie_info[2], false); + $name .= "." . $pi["extension"]; + } + + $movie = ORM::factory("item"); + $movie->type = "movie"; + $movie->title = $title; + $movie->description = $description; + $movie->name = $name; + $movie->owner_id = $owner_id ? $owner_id : user::active(); + $movie->width = $movie_info[0]; + $movie->height = $movie_info[1]; + $movie->mime_type = strtolower($pi["extension"]) == "mp4" ? "video/mp4" : "video/x-flv"; + $movie->thumb_dirty = 1; + $movie->resize_dirty = 1; + $movie->sort_column = "weight"; + $movie->rand_key = ((float)mt_rand()) / (float)mt_getrandmax(); + + // Randomize the name if there's a conflict + while (ORM::Factory("item") + ->where("parent_id", $parent->id) + ->where("name", $movie->name) + ->find()->id) { + // @todo Improve this. Random numbers are not user friendly + $movie->name = rand() . "." . $pi["extension"]; + } + + // This saves the photo + $movie->add_to_parent($parent); + + // If the thumb or resize already exists then rename it + if (file_exists($movie->resize_path()) || + file_exists($movie->thumb_path())) { + $movie->name = $pi["filename"] . "-" . rand() . "." . $pi["extension"]; + $movie->save(); + } + + copy($filename, $movie->file_path()); + + module::event("item_created", $movie); + + // Build our thumbnail + graphics::generate($movie); + + // If the parent has no cover item, make this it. + if (access::can("edit", $parent) && $parent->album_cover_item_id == null) { + item::make_album_cover($movie); + } + + return $movie; + } + + static function getmoviesize($filename) { + $ffmpeg = self::find_ffmpeg(); + if (empty($ffmpeg)) { + throw new Exception("@todo MISSING_FFMPEG"); + } + + $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($filename) . " 2>&1"; + $result = `$cmd`; + if (preg_match("/Stream.*?Video:.*?(\d+)x(\d+).*\ +([0-9\.]+) (fps|tb).*/", + $result, $regs)) { + list ($width, $height) = array($regs[1], $regs[2]); + } else { + list ($width, $height) = array(0, 0); + } + return array($width, $height); + } + + static function extract_frame($input_file, $output_file) { + $ffmpeg = self::find_ffmpeg(); + if (empty($ffmpeg)) { + throw new Exception("@todo MISSING_FFMPEG"); + } + + $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($input_file) . + " -an -ss 00:00:03 -an -r 1 -vframes 1" . + " -y -f mjpeg " . escapeshellarg($output_file); + exec($cmd); + } + + static function find_ffmpeg() { + if (!$ffmpeg_path = module::get_var("core", "ffmpeg_path")) { + if (function_exists("exec")) { + $ffmpeg_path = exec("which ffmpeg"); + if ($ffmpeg_path) { + module::set_var("core", "ffmpeg_path", $ffmpeg_path); + } + } + } + return $ffmpeg_path; + } +} diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php new file mode 100644 index 00000000..c1c005f5 --- /dev/null +++ b/modules/gallery/helpers/photo.php @@ -0,0 +1,171 @@ +loaded || !$parent->is_album()) { + throw new Exception("@todo INVALID_PARENT"); + } + + if (!is_file($filename)) { + throw new Exception("@todo MISSING_IMAGE_FILE"); + } + + if (strpos($name, "/")) { + throw new Exception("@todo NAME_CANNOT_CONTAIN_SLASH"); + } + + // We don't allow trailing periods as a security measure + // ref: http://dev.kohanaphp.com/issues/684 + if (rtrim($name, ".") != $name) { + throw new Exception("@todo NAME_CANNOT_END_IN_PERIOD"); + } + + $image_info = getimagesize($filename); + + // Force an extension onto the name + $pi = pathinfo($filename); + if (empty($pi["extension"])) { + $pi["extension"] = image_type_to_extension($image_info[2], false); + $name .= "." . $pi["extension"]; + } + + $photo = ORM::factory("item"); + $photo->type = "photo"; + $photo->title = $title; + $photo->description = $description; + $photo->name = $name; + $photo->owner_id = $owner_id ? $owner_id : user::active(); + $photo->width = $image_info[0]; + $photo->height = $image_info[1]; + $photo->mime_type = empty($image_info['mime']) ? "application/unknown" : $image_info['mime']; + $photo->thumb_dirty = 1; + $photo->resize_dirty = 1; + $photo->sort_column = "weight"; + $photo->rand_key = ((float)mt_rand()) / (float)mt_getrandmax(); + + // Randomize the name if there's a conflict + while (ORM::Factory("item") + ->where("parent_id", $parent->id) + ->where("name", $photo->name) + ->find()->id) { + // @todo Improve this. Random numbers are not user friendly + $photo->name = rand() . "." . $pi["extension"]; + } + + // This saves the photo + $photo->add_to_parent($parent); + + /* + * If the thumb or resize already exists then rename it. We need to do this after the save + * because the resize_path and thumb_path both call relative_path which caches the + * path. Before add_to_parent the relative path will be incorrect. + */ + if (file_exists($photo->resize_path()) || + file_exists($photo->thumb_path())) { + $photo->name = $pi["filename"] . "-" . rand() . "." . $pi["extension"]; + $photo->save(); + } + + copy($filename, $photo->file_path()); + + module::event("item_created", $photo); + + // Build our thumbnail/resizes + graphics::generate($photo); + + // If the parent has no cover item, make this it. + if (access::can("edit", $parent) && $parent->album_cover_item_id == null) { + item::make_album_cover($photo); + } + + return $photo; + } + + static function get_add_form($parent) { + $form = new Forge("albums/{$parent->id}", "", "post", array("id" => "gAddPhotoForm")); + $group = $form->group("add_photo")->label( + t("Add Photo to %album_title", array("album_title" =>$parent->title))); + $group->input("title")->label(t("Title")); + $group->textarea("description")->label(t("Description")); + $group->input("name")->label(t("Filename")); + $group->upload("file")->label(t("File"))->rules("required|allow[jpg,png,gif,flv,mp4]"); + $group->hidden("type")->value("photo"); + $group->submit("")->value(t("Upload")); + $form->add_rules_from(ORM::factory("item")); + return $form; + } + + static function get_edit_form($photo) { + $form = new Forge("photos/$photo->id", "", "post", array("id" => "gEditPhotoForm")); + $form->hidden("_method")->value("put"); + $group = $form->group("edit_photo")->label(t("Edit Photo")); + $group->input("title")->label(t("Title"))->value($photo->title); + $group->textarea("description")->label(t("Description"))->value($photo->description); + $group->input("filename")->label(t("Filename"))->value($photo->name) + ->error_messages("conflict", t("There is already a file with this name")) + ->callback("item::validate_no_slashes") + ->error_messages("no_slashes", t("The photo name can't contain a \"/\"")) + ->callback("item::validate_no_trailing_period") + ->error_messages("no_trailing_period", t("The photo name can't end in \".\"")); + + $group->submit("")->value(t("Modify")); + $form->add_rules_from(ORM::factory("item")); + return $form; + } + + /** + * Return scaled width and height. + * + * @param integer $width + * @param integer $height + * @param integer $max the target size for the largest dimension + * @param string $format the output format using %d placeholders for width and height + */ + static function img_dimensions($width, $height, $max, $format="width=\"%d\" height=\"%d\"") { + if (!$width || !$height) { + return ""; + } + + if ($width > $height) { + $new_width = $max; + $new_height = (int)$max * ($height / $width); + } else { + $new_height = $max; + $new_width = (int)$max * ($width / $height); + } + return sprintf($format, $new_width, $new_height); + } +} diff --git a/modules/gallery/helpers/rest.php b/modules/gallery/helpers/rest.php new file mode 100644 index 00000000..a63b94c8 --- /dev/null +++ b/modules/gallery/helpers/rest.php @@ -0,0 +1,116 @@ +post("_method", $input->get("_method", request::method())))) { + case "put": return "put"; + case "delete": return "delete"; + default: return "post"; + } + } + } + + /** + * Choose an output format based on what the client prefers to accept. + * @return string "html", "xml" or "json" + */ + static function output_format() { + // Pick a format, but let it be overridden. + $input = Input::instance(); + $fmt = $input->get( + "_format", $input->post( + "_format", request::preferred_accept( + array("xhtml", "html", "xml", "json")))); + + // Some browsers (Chrome!) prefer xhtml over html, but we'll normalize this to html for now. + if ($fmt == "xhtml") { + $fmt = "html"; + } + return $fmt; + } + + /** + * Set HTTP response code. + * @param string Use one of the status code constants defined in this class. + */ + static function http_status($status_code) { + header("HTTP/1.1 " . $status_code); + } + + /** + * Set HTTP Location header. + * @param string URL + */ + static function http_location($url) { + header("Location: " . $url); + } + + /** + * Set HTTP Content-Type header. + * @param string content type + */ + static function http_content_type($type) { + header("Content-Type: " . $type); + } +} diff --git a/modules/gallery/helpers/site_status.php b/modules/gallery/helpers/site_status.php new file mode 100644 index 00000000..6d47e565 --- /dev/null +++ b/modules/gallery/helpers/site_status.php @@ -0,0 +1,132 @@ +where("key", $permanent_key) + ->find(); + if (!$message->loaded) { + $message->key = $permanent_key; + } + $message->severity = $severity; + $message->value = $msg; + $message->save(); + } + + /** + * Remove any permanent message by key. + * @param string $permanent_key + */ + static function clear($permanent_key) { + $message = ORM::factory("message")->where("key", $permanent_key)->find(); + if ($message->loaded) { + $message->delete(); + } + } + + /** + * Get any pending messages. There are two types of messages, transient and permanent. + * Permanent messages are used to let the admin know that there are pending administrative + * issues that need to be resolved. Transient ones are only displayed once. + * @return html text + */ + static function get() { + if (!user::active()->admin) { + return; + } + $buf = array(); + foreach (ORM::factory("message")->find_all() as $msg) { + $value = str_replace('__CSRF__', access::csrf_token(), $msg->value); + $buf[] = "
  • severity) . "\">$value
  • "; + } + + if ($buf) { + return "
      " . implode("", $buf) . "
    "; + } + } + + /** + * Convert a message severity to a CSS class + * @param integer $severity + * @return string + */ + static function severity_class($severity) { + switch($severity) { + case self::SUCCESS: + return "gSuccess"; + + case self::INFO: + return "gInfo"; + + case self::WARNING: + return "gWarning"; + + case self::ERROR: + return "gError"; + } + } +} diff --git a/modules/gallery/helpers/task.php b/modules/gallery/helpers/task.php new file mode 100644 index 00000000..a8a004ab --- /dev/null +++ b/modules/gallery/helpers/task.php @@ -0,0 +1,83 @@ +name}_task"; + if (method_exists($class_name, "available_tasks")) { + foreach (call_user_func(array($class_name, "available_tasks")) as $task) { + $tasks[$task->callback] = $task; + } + } + } + + return $tasks; + } + + static function create($task_def, $context) { + $task = ORM::factory("task"); + $task->callback = $task_def->callback; + $task->name = $task_def->name; + $task->percent_complete = 0; + $task->status = ""; + $task->state = "started"; + $task->owner_id = user::active()->id; + $task->context = serialize($context); + $task->save(); + + return $task; + } + + static function cancel($task_id) { + $task = ORM::factory("task", $task_id); + if (!$task->loaded) { + throw new Exception("@todo MISSING_TASK"); + } + $task->done = 1; + $task->state = "cancelled"; + $task->save(); + + return $task; + } + + static function remove($task_id) { + $task = ORM::factory("task", $task_id); + if ($task->loaded) { + $task->delete(); + } + } + + static function run($task_id) { + $task = ORM::factory("task", $task_id); + if (!$task->loaded) { + throw new Exception("@todo MISSING_TASK"); + } + + $task->state = "running"; + call_user_func_array($task->callback, array(&$task)); + $task->save(); + + return $task; + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/theme.php b/modules/gallery/helpers/theme.php new file mode 100644 index 00000000..cbe224db --- /dev/null +++ b/modules/gallery/helpers/theme.php @@ -0,0 +1,61 @@ +"gThemeDetailsForm")); + $group = $form->group("edit_theme"); + $group->input("page_size")->label(t("Items per page"))->id("gPageSize") + ->rules("required|valid_digit") + ->value(module::get_var("core", "page_size")); + $group->input("thumb_size")->label(t("Thumbnail size (in pixels)"))->id("gThumbSize") + ->rules("required|valid_digit") + ->value(module::get_var("core", "thumb_size")); + $group->input("resize_size")->label(t("Resized image size (in pixels)"))->id("gResizeSize") + ->rules("required|valid_digit") + ->value(module::get_var("core", "resize_size")); + $group->textarea("header_text")->label(t("Header text"))->id("gHeaderText") + ->value(module::get_var("core", "header_text")); + $group->textarea("footer_text")->label(t("Footer text"))->id("gFooterText") + ->value(module::get_var("core", "footer_text")); + $group->submit("")->value(t("Save")); + return $form; + } +} + diff --git a/modules/gallery/helpers/xml.php b/modules/gallery/helpers/xml.php new file mode 100644 index 00000000..e734e90c --- /dev/null +++ b/modules/gallery/helpers/xml.php @@ -0,0 +1,35 @@ +\n"; + foreach ($array as $key => $value) { + if (is_array($value)) { + $xml .= xml::to_xml($value, array_slice($element_names, 1)); + } else if (is_object($value)) { + $xml .= xml::to_xml($value->as_array(), array_slice($element_names, 1)); + } else { + $xml .= "<$key>$value\n"; + } + } + $xml .= "\n"; + return $xml; + } +} -- cgit v1.2.3 From 4eedf804e1f26d95de6803e48c608d893c53b7d0 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 28 May 2009 07:15:00 +0800 Subject: Update all references to the core application to now point to the gallery module. This type of mass update is prone to some small bugs. Signed-off-by: Gallery Role Account --- installer/installer.php | 2 +- installer/views/install.html.php | 2 +- modules/g2_import/controllers/admin_g2_import.php | 4 +- modules/g2_import/helpers/g2_import.php | 4 +- modules/gallery/controllers/admin_dashboard.php | 2 +- modules/gallery/controllers/admin_graphics.php | 8 +- modules/gallery/controllers/admin_languages.php | 6 +- .../gallery/controllers/admin_theme_details.php | 22 +- modules/gallery/controllers/admin_themes.php | 8 +- modules/gallery/controllers/albums.php | 6 +- modules/gallery/controllers/scaffold.php | 8 +- modules/gallery/helpers/access.php | 4 +- modules/gallery/helpers/block_manager.php | 4 +- modules/gallery/helpers/core.php | 52 ---- modules/gallery/helpers/core_block.php | 100 -------- modules/gallery/helpers/core_event.php | 46 ---- modules/gallery/helpers/core_installer.php | 278 --------------------- modules/gallery/helpers/core_menu.php | 162 ------------ modules/gallery/helpers/core_search.php | 24 -- modules/gallery/helpers/core_task.php | 166 ------------ modules/gallery/helpers/core_theme.php | 137 ---------- modules/gallery/helpers/gallery.php | 52 ++++ modules/gallery/helpers/gallery_block.php | 100 ++++++++ modules/gallery/helpers/gallery_event.php | 46 ++++ modules/gallery/helpers/gallery_installer.php | 278 +++++++++++++++++++++ modules/gallery/helpers/gallery_menu.php | 162 ++++++++++++ modules/gallery/helpers/gallery_search.php | 24 ++ modules/gallery/helpers/gallery_task.php | 166 ++++++++++++ modules/gallery/helpers/gallery_theme.php | 137 ++++++++++ modules/gallery/helpers/graphics.php | 28 +-- modules/gallery/helpers/l10n_client.php | 4 +- modules/gallery/helpers/locale.php | 8 +- modules/gallery/helpers/module.php | 28 +-- modules/gallery/helpers/movie.php | 4 +- modules/gallery/helpers/theme.php | 15 +- modules/gallery/hooks/init_gallery.php | 6 +- modules/gallery/libraries/Admin_View.php | 10 +- modules/gallery/libraries/I18n.php | 2 +- modules/gallery/libraries/Theme_View.php | 20 +- modules/gallery/tests/Core_Installer_Test.php | 12 +- modules/gallery/tests/File_Structure_Test.php | 2 +- modules/gallery/tests/Movie_Helper_Test.php | 4 +- modules/gallery/tests/Photo_Helper_Test.php | 14 +- modules/gallery/tests/Photos_Controller_Test.php | 4 +- modules/gallery/tests/Var_Test.php | 32 +-- .../gallery/views/admin_advanced_settings.html.php | 2 +- modules/gallery/views/admin_block_stats.html.php | 2 +- modules/gallery/views/admin_graphics_gd.html.php | 2 +- .../views/admin_graphics_graphicsmagick.html.php | 2 +- .../views/admin_graphics_imagemagick.html.php | 2 +- modules/gallery/views/admin_languages.html.php | 2 +- modules/gallery/views/kohana_error_page.php | 5 +- modules/gallery/views/permissions_browse.html.php | 2 +- modules/gallery/views/scaffold.html.php | 2 +- .../controllers/gallery_unit_test.php | 6 +- modules/organize/controllers/organize.php | 2 +- modules/search/controllers/search.php | 2 +- modules/tag/controllers/tags.php | 2 +- themes/default/views/footer.html.php | 2 +- themes/default/views/header.html.php | 2 +- 60 files changed, 1121 insertions(+), 1119 deletions(-) delete mode 100644 modules/gallery/helpers/core.php delete mode 100644 modules/gallery/helpers/core_block.php delete mode 100644 modules/gallery/helpers/core_event.php delete mode 100644 modules/gallery/helpers/core_installer.php delete mode 100644 modules/gallery/helpers/core_menu.php delete mode 100644 modules/gallery/helpers/core_search.php delete mode 100644 modules/gallery/helpers/core_task.php delete mode 100644 modules/gallery/helpers/core_theme.php create mode 100644 modules/gallery/helpers/gallery.php create mode 100644 modules/gallery/helpers/gallery_block.php create mode 100644 modules/gallery/helpers/gallery_event.php create mode 100644 modules/gallery/helpers/gallery_installer.php create mode 100644 modules/gallery/helpers/gallery_menu.php create mode 100644 modules/gallery/helpers/gallery_search.php create mode 100644 modules/gallery/helpers/gallery_task.php create mode 100644 modules/gallery/helpers/gallery_theme.php (limited to 'modules/gallery/helpers') diff --git a/installer/installer.php b/installer/installer.php index 84adc5f9..38fde1fe 100644 --- a/installer/installer.php +++ b/installer/installer.php @@ -122,7 +122,7 @@ class installer { static function create_private_key($config) { $key = md5(uniqid(mt_rand(), true)) . md5(uniqid(mt_rand(), true)); $sql = self::prepend_prefix($config["prefix"], - "INSERT INTO {vars} VALUES(NULL, 'core', 'private_key', '$key')"); + "INSERT INTO {vars} VALUES(NULL, 'gallery', 'private_key', '$key')"); if (mysql_query($sql)) { } else { throw new Exception(mysql_error()); diff --git a/installer/views/install.html.php b/installer/views/install.html.php index c3b9686d..18060219 100644 --- a/installer/views/install.html.php +++ b/installer/views/install.html.php @@ -6,7 +6,7 @@
    - +
    diff --git a/modules/g2_import/controllers/admin_g2_import.php b/modules/g2_import/controllers/admin_g2_import.php index f17660ae..25894291 100644 --- a/modules/g2_import/controllers/admin_g2_import.php +++ b/modules/g2_import/controllers/admin_g2_import.php @@ -32,8 +32,8 @@ class Admin_g2_import_Controller extends Admin_Controller { if (g2_import::is_initialized()) { $view->content->g2_stats = $g2_stats; $view->content->g2_sizes = $g2_sizes; - $view->content->thumb_size = module::get_var("core", "thumb_size"); - $view->content->resize_size = module::get_var("core", "resize_size"); + $view->content->thumb_size = module::get_var("gallery", "thumb_size"); + $view->content->resize_size = module::get_var("gallery", "resize_size"); } print $view; } diff --git a/modules/g2_import/helpers/g2_import.php b/modules/g2_import/helpers/g2_import.php index 37efcad0..dd23d7a0 100644 --- a/modules/g2_import/helpers/g2_import.php +++ b/modules/g2_import/helpers/g2_import.php @@ -481,8 +481,8 @@ class g2_import_Core { $g2_item_id = self::$current_g2_item->getId(); $derivatives = g2(GalleryCoreApi::fetchDerivativesByItemIds(array($g2_item_id))); - $target_thumb_size = module::get_var("core", "thumb_size"); - $target_resize_size = module::get_var("core", "resize_size"); + $target_thumb_size = module::get_var("gallery", "thumb_size"); + $target_resize_size = module::get_var("gallery", "resize_size"); foreach ($derivatives[$g2_item_id] as $derivative) { if ($derivative->getPostFilterOperations()) { // Let's assume for now that this is a watermark operation, which we can't handle. diff --git a/modules/gallery/controllers/admin_dashboard.php b/modules/gallery/controllers/admin_dashboard.php index d2d2f79b..a1090a6d 100644 --- a/modules/gallery/controllers/admin_dashboard.php +++ b/modules/gallery/controllers/admin_dashboard.php @@ -29,7 +29,7 @@ class Admin_Dashboard_Controller extends Admin_Controller { } public function add_block() { - $form = core_block::get_add_block_form(); + $form = gallery_block::get_add_block_form(); if ($form->validate()) { list ($module_name, $id) = explode(":", $form->add_block->id->value); $available = block_manager::get_available(); diff --git a/modules/gallery/controllers/admin_graphics.php b/modules/gallery/controllers/admin_graphics.php index 0b3014f0..7e8ef47c 100644 --- a/modules/gallery/controllers/admin_graphics.php +++ b/modules/gallery/controllers/admin_graphics.php @@ -24,7 +24,7 @@ class Admin_Graphics_Controller extends Admin_Controller { $view->content->available = ""; $tk = new ArrayObject(graphics::detect_toolkits(), ArrayObject::ARRAY_AS_PROPS); - $active = module::get_var("core", "graphics_toolkit", "none"); + $active = module::get_var("gallery", "graphics_toolkit", "none"); foreach (array("gd", "imagemagick", "graphicsmagick", "none") as $id) { if ($id == $active) { $view->content->active = new View("admin_graphics_$id.html"); @@ -43,12 +43,12 @@ class Admin_Graphics_Controller extends Admin_Controller { public function choose($toolkit) { access::verify_csrf(); - if ($toolkit != module::get_var("core", "graphics_toolkit")) { - module::set_var("core", "graphics_toolkit", $toolkit); + if ($toolkit != module::get_var("gallery", "graphics_toolkit")) { + module::set_var("gallery", "graphics_toolkit", $toolkit); $toolkit_info = graphics::detect_toolkits(); if ($toolkit == "graphicsmagick" || $toolkit == "imagemagick") { - module::set_var("core", "graphics_toolkit_path", $toolkit_info[$toolkit]); + module::set_var("gallery", "graphics_toolkit_path", $toolkit_info[$toolkit]); } site_status::clear("missing_graphics_toolkit"); diff --git a/modules/gallery/controllers/admin_languages.php b/modules/gallery/controllers/admin_languages.php index 37d335a3..1dea733c 100644 --- a/modules/gallery/controllers/admin_languages.php +++ b/modules/gallery/controllers/admin_languages.php @@ -33,7 +33,7 @@ class Admin_Languages_Controller extends Admin_Controller { public function save() { $form = $this->_languages_form(); if ($form->validate()) { - module::set_var("core", "default_locale", $form->choose_language->locale->value); + module::set_var("gallery", "default_locale", $form->choose_language->locale->value); locale::update_installed($form->choose_language->installed_locales->value); message::success(t("Settings saved")); } @@ -76,7 +76,7 @@ class Admin_Languages_Controller extends Admin_Controller { message::success(t("Your API key has been saved.")); } - log::success(t("core"), t("l10n_client API key changed.")); + log::success(t("gallery"), t("l10n_client API key changed.")); url::redirect("admin/languages"); } else { // Show the page with form errors @@ -92,7 +92,7 @@ class Admin_Languages_Controller extends Admin_Controller { ->label(t("Language settings")); $group->dropdown("locale") ->options($installed_locales) - ->selected(module::get_var("core", "default_locale")) + ->selected(module::get_var("gallery", "default_locale")) ->label(t("Default language")) ->rules('required'); diff --git a/modules/gallery/controllers/admin_theme_details.php b/modules/gallery/controllers/admin_theme_details.php index 542ec31c..fec1311b 100644 --- a/modules/gallery/controllers/admin_theme_details.php +++ b/modules/gallery/controllers/admin_theme_details.php @@ -28,32 +28,32 @@ class Admin_Theme_Details_Controller extends Admin_Controller { public function save() { $form = theme::get_edit_form_admin(); if ($form->validate()) { - module::set_var("core", "page_size", $form->edit_theme->page_size->value); + module::set_var("gallery", "page_size", $form->edit_theme->page_size->value); $thumb_size = $form->edit_theme->thumb_size->value; $thumb_dirty = false; - if (module::get_var("core", "thumb_size") != $thumb_size) { - graphics::remove_rule("core", "thumb", "resize"); + if (module::get_var("gallery", "thumb_size") != $thumb_size) { + graphics::remove_rule("gallery", "thumb", "resize"); graphics::add_rule( - "core", "thumb", "resize", + "gallery", "thumb", "resize", array("width" => $thumb_size, "height" => $thumb_size, "master" => Image::AUTO), 100); - module::set_var("core", "thumb_size", $thumb_size); + module::set_var("gallery", "thumb_size", $thumb_size); } $resize_size = $form->edit_theme->resize_size->value; $resize_dirty = false; - if (module::get_var("core", "resize_size") != $resize_size) { - graphics::remove_rule("core", "resize", "resize"); + if (module::get_var("gallery", "resize_size") != $resize_size) { + graphics::remove_rule("gallery", "resize", "resize"); graphics::add_rule( - "core", "resize", "resize", + "gallery", "resize", "resize", array("width" => $resize_size, "height" => $resize_size, "master" => Image::AUTO), 100); - module::set_var("core", "resize_size", $resize_size); + module::set_var("gallery", "resize_size", $resize_size); } - module::set_var("core", "header_text", $form->edit_theme->header_text->value); - module::set_var("core", "footer_text", $form->edit_theme->footer_text->value); + module::set_var("gallery", "header_text", $form->edit_theme->header_text->value); + module::set_var("gallery", "footer_text", $form->edit_theme->footer_text->value); message::success(t("Updated theme details")); url::redirect("admin/theme_details"); diff --git a/modules/gallery/controllers/admin_themes.php b/modules/gallery/controllers/admin_themes.php index 05c134d1..aef6c2d1 100644 --- a/modules/gallery/controllers/admin_themes.php +++ b/modules/gallery/controllers/admin_themes.php @@ -21,8 +21,8 @@ class Admin_Themes_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); $view->content = new View("admin_themes.html"); - $view->content->admin = module::get_var("core", "active_admin_theme"); - $view->content->site = module::get_var("core", "active_site_theme"); + $view->content->admin = module::get_var("gallery", "active_admin_theme"); + $view->content->site = module::get_var("gallery", "active_site_theme"); $view->content->themes = $this->_get_themes(); print $view; } @@ -64,11 +64,11 @@ class Admin_Themes_Controller extends Admin_Controller { parse_ini_file(THEMEPATH . "$theme_name/theme.info"), ArrayObject::ARRAY_AS_PROPS); if ($type == "admin" && $info->admin) { - module::set_var("core", "active_admin_theme", $theme_name); + module::set_var("gallery", "active_admin_theme", $theme_name); message::success(t("Successfully changed your admin theme to %theme_name", array("theme_name" => $info->name))); } else if ($type == "site" && $info->site) { - module::set_var("core", "active_site_theme", $theme_name); + module::set_var("gallery", "active_site_theme", $theme_name); message::success(t("Successfully changed your Gallery theme to %theme_name", array("theme_name" => $info->name))); } diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index 5b4d5979..03a64f43 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -32,7 +32,7 @@ class Albums_Controller extends Items_Controller { } } - $page_size = module::get_var("core", "page_size", 9); + $page_size = module::get_var("gallery", "page_size", 9); $show = $this->input->get("show"); if ($show) { @@ -114,7 +114,7 @@ class Albums_Controller extends Items_Controller { } else { print json_encode( array("result" => "error", - "form" => $form->__toString() . html::script("core/js/albums_form_add.js"))); + "form" => $form->__toString() . html::script("gallery/js/albums_form_add.js"))); } } @@ -206,7 +206,7 @@ class Albums_Controller extends Items_Controller { switch ($this->input->get("type")) { case "album": print album::get_add_form($album) . - html::script("core/js/albums_form_add.js"); + html::script("gallery/js/albums_form_add.js"); break; case "photo": diff --git a/modules/gallery/controllers/scaffold.php b/modules/gallery/controllers/scaffold.php index f0063725..8ec1663a 100644 --- a/modules/gallery/controllers/scaffold.php +++ b/modules/gallery/controllers/scaffold.php @@ -94,7 +94,7 @@ class Scaffold_Controller extends Template_Controller { $type = rand(0, 10) ? "photo" : "album"; } if ($type == "album") { - $thumb_size = module::get_var("core", "thumb_size"); + $thumb_size = module::get_var("gallery", "thumb_size"); $parents[] = album::create( $parent, "rnd_" . rand(), "Rnd $i", "random album $i", $owner_id) ->save(); @@ -262,7 +262,7 @@ class Scaffold_Controller extends Template_Controller { } foreach ($to_install as $module_name) { - if ($module_name != "core") { + if ($module_name != "gallery") { require_once(DOCROOT . "modules/${module_name}/helpers/${module_name}_installer.php"); } module::install($module_name); @@ -300,7 +300,7 @@ class Scaffold_Controller extends Template_Controller { srand(0); try { - core_installer::install(true); + gallery_installer::install(true); module::load_modules(); foreach (array("user", "comment", "organize", "info", "rss", @@ -325,7 +325,7 @@ class Scaffold_Controller extends Template_Controller { $db = Database::instance(); $db->query("TRUNCATE {sessions}"); $db->query("TRUNCATE {logs}"); - $db->query("DELETE FROM {vars} WHERE `module_name` = 'core' AND `name` = '_cache'"); + $db->query("DELETE FROM {vars} WHERE `module_name` = 'gallery' AND `name` = '_cache'"); $db->update("users", array("password" => ""), array("id" => 1)); $db->update("users", array("password" => ""), array("id" => 2)); diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php index 64ce91fa..c48f0b79 100644 --- a/modules/gallery/helpers/access.php +++ b/modules/gallery/helpers/access.php @@ -389,7 +389,7 @@ class access_Core { * @return ORM_Iterator */ private static function _get_all_groups() { - // When we build the core package, it's possible that the user module is not installed yet. + // When we build the gallery package, it's possible that the user module is not installed yet. // This is ok at packaging time, so work around it. if (module::is_active("user")) { return ORM::factory("group")->find_all(); @@ -595,7 +595,7 @@ class access_Core { } static function private_key() { - return module::get_var("core", "private_key"); + return module::get_var("gallery", "private_key"); } /** diff --git a/modules/gallery/helpers/block_manager.php b/modules/gallery/helpers/block_manager.php index 022626e5..20b641d4 100644 --- a/modules/gallery/helpers/block_manager.php +++ b/modules/gallery/helpers/block_manager.php @@ -19,11 +19,11 @@ */ class block_manager_Core { static function get_active($location) { - return unserialize(module::get_var("core", "blocks_$location", "a:0:{}")); + return unserialize(module::get_var("gallery", "blocks_$location", "a:0:{}")); } static function set_active($location, $blocks) { - module::set_var("core", "blocks_$location", serialize($blocks)); + module::set_var("gallery", "blocks_$location", serialize($blocks)); } static function add($location, $module_name, $block_id) { diff --git a/modules/gallery/helpers/core.php b/modules/gallery/helpers/core.php deleted file mode 100644 index 63f51f86..00000000 --- a/modules/gallery/helpers/core.php +++ /dev/null @@ -1,52 +0,0 @@ -admin) { - Router::$controller = "maintenance"; - Router::$controller_path = APPPATH . "controllers/maintenance.php"; - Router::$method = "index"; - } - } - - /** - * This function is called when the Gallery is fully initialized. We relay it to modules as the - * "gallery_ready" event. Any module that wants to perform an action at the start of every - * request should implement the _event::gallery_ready() handler. - */ - static function ready() { - module::event("gallery_ready"); - } - - /** - * This function is called right before the Kohana framework shuts down. We relay it to modules - * as the "gallery_shutdown" event. Any module that wants to perform an action at the start of - * every request should implement the _event::gallery_shutdown() handler. - */ - static function shutdown() { - module::event("gallery_shutdown"); - } -} \ No newline at end of file diff --git a/modules/gallery/helpers/core_block.php b/modules/gallery/helpers/core_block.php deleted file mode 100644 index 0e2e9c54..00000000 --- a/modules/gallery/helpers/core_block.php +++ /dev/null @@ -1,100 +0,0 @@ - t("Welcome to Gallery 3!"), - "photo_stream" => t("Photo Stream"), - "log_entries" => t("Log Entries"), - "stats" => t("Gallery Stats"), - "platform_info" => t("Platform Information"), - "project_news" => t("Gallery Project News")); - } - - static function get($block_id) { - $block = new Block(); - switch($block_id) { - case "welcome": - $block->css_id = "gWelcome"; - $block->title = t("Welcome to Gallery3"); - $block->content = new View("admin_block_welcome.html"); - break; - - case "photo_stream": - $block->css_id = "gPhotoStream"; - $block->title = t("Photo Stream"); - $block->content = new View("admin_block_photo_stream.html"); - $block->content->photos = - ORM::factory("item")->where("type", "photo")->orderby("created", "DESC")->find_all(10); - break; - - case "log_entries": - $block->css_id = "gLogEntries"; - $block->title = t("Log Entries"); - $block->content = new View("admin_block_log_entries.html"); - $block->content->entries = ORM::factory("log")->orderby("timestamp", "DESC")->find_all(5); - break; - - case "stats": - $block->css_id = "gStats"; - $block->title = t("Gallery Stats"); - $block->content = new View("admin_block_stats.html"); - $block->content->album_count = ORM::factory("item")->where("type", "album")->count_all(); - $block->content->photo_count = ORM::factory("item")->where("type", "photo")->count_all(); - break; - - case "platform_info": - $block->css_id = "gPlatform"; - $block->title = t("Platform Information"); - $block->content = new View("admin_block_platform.html"); - if (is_readable("/proc/loadavg")) { - $block->content->load_average = - join(" ", array_slice(split(" ", array_shift(file("/proc/loadavg"))), 0, 3)); - } else { - $block->content->load_average = t("Unavailable"); - } - break; - - case "project_news": - $block->css_id = "gProjectNews"; - $block->title = t("Gallery Project News"); - $block->content = new View("admin_block_news.html"); - $block->content->feed = feed::parse("http://gallery.menalto.com/node/feed", 3); - break; - - case "block_adder": - $block->css_id = "gBlockAdder"; - $block->title = t("Dashboard Content"); - $block->content = self::get_add_block_form(); - } - - return $block; - } - - static function get_add_block_form() { - $form = new Forge("admin/dashboard/add_block", "", "post", - array("id" => "gAddDashboardBlockForm")); - $group = $form->group("add_block")->label(t("Add Block")); - $group->dropdown("id")->label("Available Blocks")->options(block_manager::get_available()); - $group->submit("center")->value(t("Add to center")); - $group->submit("sidebar")->value(t("Add to sidebar")); - return $form; - } -} \ No newline at end of file diff --git a/modules/gallery/helpers/core_event.php b/modules/gallery/helpers/core_event.php deleted file mode 100644 index bbb53cc9..00000000 --- a/modules/gallery/helpers/core_event.php +++ /dev/null @@ -1,46 +0,0 @@ -admin && module::get_var("core", "choose_default_tookit", null)) { - graphics::choose_default_toolkit(); - module::clear_var("core", "choose_default_tookit"); - } - } -} diff --git a/modules/gallery/helpers/core_installer.php b/modules/gallery/helpers/core_installer.php deleted file mode 100644 index cffcbedb..00000000 --- a/modules/gallery/helpers/core_installer.php +++ /dev/null @@ -1,278 +0,0 @@ -query("CREATE TABLE {access_caches} ( - `id` int(9) NOT NULL auto_increment, - `item_id` int(9), - PRIMARY KEY (`id`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {access_intents} ( - `id` int(9) NOT NULL auto_increment, - `item_id` int(9), - PRIMARY KEY (`id`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {graphics_rules} ( - `id` int(9) NOT NULL auto_increment, - `active` BOOLEAN default 0, - `args` varchar(255) default NULL, - `module_name` varchar(64) NOT NULL, - `operation` varchar(64) NOT NULL, - `priority` int(9) NOT NULL, - `target` varchar(32) NOT NULL, - PRIMARY KEY (`id`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {items} ( - `id` int(9) NOT NULL auto_increment, - `album_cover_item_id` int(9) default NULL, - `captured` int(9) default NULL, - `created` int(9) default NULL, - `description` varchar(2048) default NULL, - `height` int(9) default NULL, - `left` int(9) NOT NULL, - `level` int(9) NOT NULL, - `mime_type` varchar(64) default NULL, - `name` varchar(255) default NULL, - `owner_id` int(9) default NULL, - `parent_id` int(9) NOT NULL, - `rand_key` float default NULL, - `relative_path_cache` varchar(255) default NULL, - `resize_dirty` boolean default 1, - `resize_height` int(9) default NULL, - `resize_width` int(9) default NULL, - `right` int(9) NOT NULL, - `sort_column` varchar(64) default NULL, - `sort_order` char(4) default 'ASC', - `thumb_dirty` boolean default 1, - `thumb_height` int(9) default NULL, - `thumb_width` int(9) default NULL, - `title` varchar(255) default NULL, - `type` varchar(32) NOT NULL, - `updated` int(9) default NULL, - `view_count` int(9) default 0, - `weight` int(9) NOT NULL default 0, - `width` int(9) default NULL, - PRIMARY KEY (`id`), - KEY `parent_id` (`parent_id`), - KEY `type` (`type`), - KEY `random` (`rand_key`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {logs} ( - `id` int(9) NOT NULL auto_increment, - `category` varchar(64) default NULL, - `html` varchar(255) default NULL, - `message` text default NULL, - `referer` varchar(255) default NULL, - `severity` int(9) default 0, - `timestamp` int(9) default 0, - `url` varchar(255) default NULL, - `user_id` int(9) default 0, - PRIMARY KEY (`id`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {messages} ( - `id` int(9) NOT NULL auto_increment, - `key` varchar(255) default NULL, - `severity` varchar(32) default NULL, - `value` varchar(255) default NULL, - PRIMARY KEY (`id`), - UNIQUE KEY(`key`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {modules} ( - `id` int(9) NOT NULL auto_increment, - `active` BOOLEAN default 0, - `name` varchar(64) default NULL, - `version` int(9) default NULL, - PRIMARY KEY (`id`), - UNIQUE KEY(`name`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {themes} ( - `id` int(9) NOT NULL auto_increment, - `name` varchar(64) default NULL, - `version` int(9) default NULL, - PRIMARY KEY (`id`), - UNIQUE KEY(`name`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {permissions} ( - `id` int(9) NOT NULL auto_increment, - `display_name` varchar(64) default NULL, - `name` varchar(64) default NULL, - PRIMARY KEY (`id`), - UNIQUE KEY(`name`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {incoming_translations} ( - `id` int(9) NOT NULL auto_increment, - `key` char(32) NOT NULL, - `locale` char(10) NOT NULL, - `message` text NOT NULL, - `revision` int(9) DEFAULT NULL, - `translation` text, - PRIMARY KEY (`id`), - UNIQUE KEY(`key`, `locale`), - KEY `locale_key` (`locale`, `key`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {outgoing_translations} ( - `id` int(9) NOT NULL auto_increment, - `base_revision` int(9) DEFAULT NULL, - `key` char(32) NOT NULL, - `locale` char(10) NOT NULL, - `message` text NOT NULL, - `translation` text, - PRIMARY KEY (`id`), - UNIQUE KEY(`key`, `locale`), - KEY `locale_key` (`locale`, `key`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {sessions} ( - `session_id` varchar(127) NOT NULL, - `data` text NOT NULL, - `last_activity` int(10) UNSIGNED NOT NULL, - PRIMARY KEY (`session_id`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {tasks} ( - `id` int(9) NOT NULL auto_increment, - `callback` varchar(128) default NULL, - `context` text NOT NULL, - `done` boolean default 0, - `name` varchar(128) default NULL, - `owner_id` int(9) default NULL, - `percent_complete` int(9) default 0, - `state` varchar(32) default NULL, - `status` varchar(255) default NULL, - `updated` int(9) default NULL, - PRIMARY KEY (`id`), - KEY (`owner_id`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - $db->query("CREATE TABLE {vars} ( - `id` int(9) NOT NULL auto_increment, - `module_name` varchar(64) NOT NULL, - `name` varchar(64) NOT NULL, - `value` text, - PRIMARY KEY (`id`), - UNIQUE KEY(`module_name`, `name`)) - ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - - foreach (array("albums", "logs", "modules", "resizes", "thumbs", "tmp", "uploads") as $dir) { - @mkdir(VARPATH . $dir); - } - - access::register_permission("view", "View"); - access::register_permission("view_full", "View Full Size"); - access::register_permission("edit", "Edit"); - access::register_permission("add", "Add"); - - $root = ORM::factory("item"); - $root->type = "album"; - $root->title = "Gallery"; - $root->description = ""; - $root->left = 1; - $root->right = 2; - $root->parent_id = 0; - $root->level = 1; - $root->thumb_dirty = 1; - $root->resize_dirty = 1; - $root->sort_column = "weight"; - $root->sort_order = "ASC"; - $root->save(); - access::add_item($root); - - module::set_var("core", "active_site_theme", "default"); - module::set_var("core", "active_admin_theme", "admin_default"); - module::set_var("core", "page_size", 9); - module::set_var("core", "thumb_size", 200); - module::set_var("core", "resize_size", 640); - module::set_var("core", "default_locale", "en_US"); - module::set_var("core", "image_quality", 75); - - // Add rules for generating our thumbnails and resizes - graphics::add_rule( - "core", "thumb", "resize", - array("width" => 200, "height" => 200, "master" => Image::AUTO), - 100); - graphics::add_rule( - "core", "resize", "resize", - array("width" => 640, "height" => 480, "master" => Image::AUTO), - 100); - - // Instantiate default themes (site and admin) - foreach (array("default", "admin_default") as $theme_name) { - $theme_info = new ArrayObject(parse_ini_file(THEMEPATH . $theme_name . "/theme.info"), - ArrayObject::ARRAY_AS_PROPS); - $theme = ORM::factory("theme"); - $theme->name = $theme_name; - $theme->version = $theme_info->version; - $theme->save(); - } - - block_manager::add("dashboard_sidebar", "core", "block_adder"); - block_manager::add("dashboard_sidebar", "core", "stats"); - block_manager::add("dashboard_sidebar", "core", "platform_info"); - block_manager::add("dashboard_sidebar", "core", "project_news"); - block_manager::add("dashboard_center", "core", "welcome"); - block_manager::add("dashboard_center", "core", "photo_stream"); - block_manager::add("dashboard_center", "core", "log_entries"); - - module::set_version("core", 1); - module::set_var("core", "version", "3.0 pre-beta svn"); - module::set_var("core", "choose_default_tookit", 1); - } - } - - static function uninstall() { - $db = Database::instance(); - $db->query("DROP TABLE IF EXISTS {access_caches}"); - $db->query("DROP TABLE IF EXISTS {access_intents}"); - $db->query("DROP TABLE IF EXISTS {graphics_rules}"); - $db->query("DROP TABLE IF EXISTS {items}"); - $db->query("DROP TABLE IF EXISTS {logs}"); - $db->query("DROP TABLE IF EXISTS {messages}"); - $db->query("DROP TABLE IF EXISTS {modules}"); - $db->query("DROP TABLE IF EXISTS {themes}"); - $db->query("DROP TABLE IF EXISTS {incoming_translations}"); - $db->query("DROP TABLE IF EXISTS {outgoing_translations}"); - $db->query("DROP TABLE IF EXISTS {permissions}"); - $db->query("DROP TABLE IF EXISTS {sessions}"); - $db->query("DROP TABLE IF EXISTS {tasks}"); - $db->query("DROP TABLE IF EXISTS {vars}"); - foreach (array("albums", "resizes", "thumbs", "uploads", - "modules", "logs", "database.php") as $entry) { - system("/bin/rm -rf " . VARPATH . $entry); - } - } -} diff --git a/modules/gallery/helpers/core_menu.php b/modules/gallery/helpers/core_menu.php deleted file mode 100644 index eb208560..00000000 --- a/modules/gallery/helpers/core_menu.php +++ /dev/null @@ -1,162 +0,0 @@ -admin) { - $menu->append($scaffold_menu = Menu::factory("submenu") - ->id("scaffold") - ->label("Scaffold")); - $scaffold_menu->append(Menu::factory("link") - ->id("scaffold_home") - ->label("Dashboard") - ->url(url::site("scaffold"))); - } - - $menu->append(Menu::factory("link") - ->id("home") - ->label(t("Home")) - ->url(url::site("albums/1"))); - - $item = $theme->item(); - - if (user::active()->admin || ($item && access::can("edit", $item))) { - $menu->append($options_menu = Menu::factory("submenu") - ->id("options_menu") - ->label(t("Options"))); - - if ($item && access::can("edit", $item)) { - $options_menu - ->append(Menu::factory("dialog") - ->id("edit_item") - ->label($item->is_album() ? t("Edit album") : t("Edit photo")) - ->url(url::site("form/edit/{$item->type}s/$item->id"))); - - // @todo Move album options menu to the album quick edit pane - // @todo Create resized item quick edit pane menu - if ($item->is_album()) { - $options_menu - ->append(Menu::factory("dialog") - ->id("add_item") - ->label(t("Add a photo")) - ->url(url::site("simple_uploader/app/$item->id"))) - ->append(Menu::factory("dialog") - ->id("add_album") - ->label(t("Add an album")) - ->url(url::site("form/add/albums/$item->id?type=album"))) - ->append(Menu::factory("dialog") - ->id("edit_permissions") - ->label(t("Edit permissions")) - ->url(url::site("permissions/browse/$item->id"))); - } - } - } - - if (user::active()->admin) { - $menu->append($admin_menu = Menu::factory("submenu") - ->id("admin_menu") - ->label(t("Admin"))); - self::admin($admin_menu, $theme); - foreach (module::active() as $module) { - if ($module->name == "core") { - continue; - } - $class = "{$module->name}_menu"; - if (method_exists($class, "admin")) { - call_user_func_array(array($class, "admin"), array(&$admin_menu, $theme)); - } - } - } - } - - static function album($menu, $theme) { - } - - static function photo($menu, $theme) { - if (access::can("view_full", $theme->item())) { - $menu - ->append(Menu::factory("link") - ->id("fullsize") - ->label(t("View full size")) - ->url("#") - ->css_class("gFullSizeLink")); - } - $menu - ->append(Menu::factory("link") - ->id("album") - ->label(t("Return to album")) - ->url($theme->item()->parent()->url("show={$theme->item->id}")) - ->css_id("gAlbumLink")); - } - - static function admin($menu, $theme) { - $menu - ->append(Menu::factory("link") - ->id("dashboard") - ->label(t("Dashboard")) - ->url(url::site("admin"))) - ->append(Menu::factory("submenu") - ->id("settings_menu") - ->label(t("Settings")) - ->append(Menu::factory("link") - ->id("graphics_toolkits") - ->label(t("Graphics")) - ->url(url::site("admin/graphics"))) - ->append(Menu::factory("link") - ->id("languages") - ->label(t("Languages")) - ->url(url::site("admin/languages"))) - ->append(Menu::factory("link") - ->id("l10n_mode") - ->label(Session::instance()->get("l10n_mode", false) - ? t("Stop translating") : t("Start translating")) - ->url(url::site("l10n_client/toggle_l10n_mode?csrf=" . - access::csrf_token()))) - ->append(Menu::factory("link") - ->id("advanced") - ->label("Advanced") - ->url(url::site("admin/advanced_settings")))) - ->append(Menu::factory("link") - ->id("modules") - ->label(t("Modules")) - ->url(url::site("admin/modules"))) - ->append(Menu::factory("submenu") - ->id("content_menu") - ->label(t("Content"))) - ->append(Menu::factory("submenu") - ->id("appearance_menu") - ->label(t("Appearance")) - ->append(Menu::factory("link") - ->id("themes") - ->label(t("Theme Choice")) - ->url(url::site("admin/themes"))) - ->append(Menu::factory("link") - ->id("theme_details") - ->label(t("Theme Options")) - ->url(url::site("admin/theme_details")))) - ->append(Menu::factory("link") - ->id("maintenance") - ->label(t("Maintenance")) - ->url(url::site("admin/maintenance"))) - ->append(Menu::factory("submenu") - ->id("statistics_menu") - ->label(t("Statistics")) - ->url("#")); - } -} diff --git a/modules/gallery/helpers/core_search.php b/modules/gallery/helpers/core_search.php deleted file mode 100644 index 9957a493..00000000 --- a/modules/gallery/helpers/core_search.php +++ /dev/null @@ -1,24 +0,0 @@ -description, $item->name, $item->title)); - } -} diff --git a/modules/gallery/helpers/core_task.php b/modules/gallery/helpers/core_task.php deleted file mode 100644 index e078192c..00000000 --- a/modules/gallery/helpers/core_task.php +++ /dev/null @@ -1,166 +0,0 @@ -count(); - $tasks = array(); - $tasks[] = Task_Definition::factory() - ->callback("core_task::rebuild_dirty_images") - ->name(t("Rebuild Images")) - ->description($dirty_count ? - t2("You have one out of date photo", - "You have %count out of date photos", - $dirty_count) - : t("All your photos are up to date")) - ->severity($dirty_count ? log::WARNING : log::SUCCESS); - - $tasks[] = Task_Definition::factory() - ->callback("core_task::update_l10n") - ->name(t("Update translations")) - ->description(t("Download new and updated translated strings")) - ->severity(log::SUCCESS); - - return $tasks; - } - - /** - * Task that rebuilds all dirty images. - * @param Task_Model the task - */ - static function rebuild_dirty_images($task) { - $result = graphics::find_dirty_images_query(); - $remaining = $result->count(); - $completed = $task->get("completed", 0); - - $i = 0; - foreach ($result as $row) { - $item = ORM::factory("item", $row->id); - if ($item->loaded) { - graphics::generate($item); - } - - $completed++; - $remaining--; - - if (++$i == 2) { - break; - } - } - - $task->status = t2("Updated: 1 image. Total: %total_count.", - "Updated: %count images. Total: %total_count.", - $completed, - array("total_count" => ($remaining + $completed))); - - if ($completed + $remaining > 0) { - $task->percent_complete = (int)(100 * $completed / ($completed + $remaining)); - } else { - $task->percent_complete = 100; - } - - $task->set("completed", $completed); - if ($remaining == 0) { - $task->done = true; - $task->state = "success"; - site_status::clear("graphics_dirty"); - } - } - - static function update_l10n(&$task) { - $start = microtime(true); - $dirs = $task->get("dirs"); - $files = $task->get("files"); - $cache = $task->get("cache", array()); - $i = 0; - - switch ($task->get("mode", "init")) { - case "init": // 0% - $dirs = array("core", "modules", "themes", "installer"); - $files = array(); - $task->set("mode", "find_files"); - $task->status = t("Finding files"); - break; - - case "find_files": // 0% - 10% - while (($dir = array_pop($dirs)) && microtime(true) - $start < 0.5) { - if (basename($dir) == "tests") { - continue; - } - - foreach (glob(DOCROOT . "$dir/*") as $path) { - $relative_path = str_replace(DOCROOT, "", $path); - if (is_dir($path)) { - $dirs[] = $relative_path; - } else { - $files[] = $relative_path; - } - } - } - - $task->status = t2("Finding files: found 1 file", - "Finding files: found %count files", count($files)); - - if (!$dirs) { - $task->set("mode", "scan_files"); - $task->set("total_files", count($files)); - $task->status = t("Scanning files"); - $task->percent_complete = 10; - } - break; - - case "scan_files": // 10% - 90% - while (($file = array_pop($files)) && microtime(true) - $start < 0.5) { - $file = DOCROOT . $file; - switch (pathinfo($file, PATHINFO_EXTENSION)) { - case "php": - l10n_scanner::scan_php_file($file, $cache); - break; - - case "info": - l10n_scanner::scan_info_file($file, $cache); - break; - } - } - - $total_files = $task->get("total_files"); - $task->status = t2("Scanning files: scanned 1 file", - "Scanning files: scanned %count files", $total_files - count($files)); - - $task->percent_complete = 10 + 80 * ($total_files - count($files)) / $total_files; - if (empty($files)) { - $task->set("mode", "fetch_updates"); - $task->status = t("Fetching updates"); - $task->percent_complete = 90; - } - break; - - case "fetch_updates": // 90% - 100% - l10n_client::fetch_updates(); - $task->done = true; - $task->state = "success"; - $task->status = t("Translations installed/updated"); - $task->percent_complete = 100; - } - - $task->set("files", $files); - $task->set("dirs", $dirs); - $task->set("cache", $cache); - } -} \ No newline at end of file diff --git a/modules/gallery/helpers/core_theme.php b/modules/gallery/helpers/core_theme.php deleted file mode 100644 index 28f544a1..00000000 --- a/modules/gallery/helpers/core_theme.php +++ /dev/null @@ -1,137 +0,0 @@ -get("debug")) { - $buf .= ""; - } - if (($theme->page_type == "album" || $theme->page_type == "photo") - && access::can("edit", $theme->item())) { - $buf .= ""; - $buf .= html::script("core/js/quick.js"); - } - if ($theme->page_type == "photo" && access::can("view_full", $theme->item())) { - $buf .= ""; - $buf .= html::script("core/js/fullsize.js"); - } - - if ($session->get("l10n_mode", false)) { - $buf .= ""; - $buf .= html::script("lib/jquery.cookie.js"); - $buf .= html::script("core/js/l10n_client.js"); - } - - return $buf; - } - - static function resize_top($theme, $item) { - if (access::can("edit", $item)) { - $edit_link = url::site("quick/pane/$item->id?page_type=photo"); - return "
    "; - } - } - - static function resize_bottom($theme, $item) { - if (access::can("edit", $item)) { - return "
    "; - } - } - - static function thumb_top($theme, $child) { - if (access::can("edit", $child)) { - $edit_link = url::site("quick/pane/$child->id?page_type=album"); - return "
    "; - } - } - - static function thumb_bottom($theme, $child) { - if (access::can("edit", $child)) { - return "
    "; - } - } - - static function admin_head($theme) { - $session = Session::instance(); - $buf = ""; - if ($session->get("debug")) { - $buf .= ""; - } - - if ($session->get("l10n_mode", false)) { - $buf .= ""; - $buf .= html::script("lib/jquery.cookie.js"); - $buf .= html::script("core/js/l10n_client.js"); - } - - return $buf; - } - - static function page_bottom($theme) { - $session = Session::instance(); - if ($session->get("profiler", false)) { - $profiler = new Profiler(); - $profiler->render(); - } - if ($session->get("l10n_mode", false)) { - return L10n_Client_Controller::l10n_form(); - } - - if ($session->get("after_install")) { - $session->delete("after_install"); - return new View("after_install_loader.html"); - } - } - - static function admin_page_bottom($theme) { - $session = Session::instance(); - if ($session->get("profiler", false)) { - $profiler = new Profiler(); - $profiler->render(); - } - if ($session->get("l10n_mode", false)) { - return L10n_Client_Controller::l10n_form(); - } - } - - static function credits() { - return "
  • " . - t("Powered by Gallery %version", - array("url" => "http://gallery.menalto.com", - "version" => module::get_var("core", "version"))) . - "
  • "; - } - - static function admin_credits() { - return core_theme::credits(); - } -} \ No newline at end of file diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php new file mode 100644 index 00000000..bf33fa2b --- /dev/null +++ b/modules/gallery/helpers/gallery.php @@ -0,0 +1,52 @@ +admin) { + Router::$controller = "maintenance"; + Router::$controller_path = APPPATH . "controllers/maintenance.php"; + Router::$method = "index"; + } + } + + /** + * This function is called when the Gallery is fully initialized. We relay it to modules as the + * "gallery_ready" event. Any module that wants to perform an action at the start of every + * request should implement the _event::gallery_ready() handler. + */ + static function ready() { + module::event("gallery_ready"); + } + + /** + * This function is called right before the Kohana framework shuts down. We relay it to modules + * as the "gallery_shutdown" event. Any module that wants to perform an action at the start of + * every request should implement the _event::gallery_shutdown() handler. + */ + static function shutdown() { + module::event("gallery_shutdown"); + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/gallery_block.php b/modules/gallery/helpers/gallery_block.php new file mode 100644 index 00000000..abc8a195 --- /dev/null +++ b/modules/gallery/helpers/gallery_block.php @@ -0,0 +1,100 @@ + t("Welcome to Gallery 3!"), + "photo_stream" => t("Photo Stream"), + "log_entries" => t("Log Entries"), + "stats" => t("Gallery Stats"), + "platform_info" => t("Platform Information"), + "project_news" => t("Gallery Project News")); + } + + static function get($block_id) { + $block = new Block(); + switch($block_id) { + case "welcome": + $block->css_id = "gWelcome"; + $block->title = t("Welcome to Gallery3"); + $block->content = new View("admin_block_welcome.html"); + break; + + case "photo_stream": + $block->css_id = "gPhotoStream"; + $block->title = t("Photo Stream"); + $block->content = new View("admin_block_photo_stream.html"); + $block->content->photos = + ORM::factory("item")->where("type", "photo")->orderby("created", "DESC")->find_all(10); + break; + + case "log_entries": + $block->css_id = "gLogEntries"; + $block->title = t("Log Entries"); + $block->content = new View("admin_block_log_entries.html"); + $block->content->entries = ORM::factory("log")->orderby("timestamp", "DESC")->find_all(5); + break; + + case "stats": + $block->css_id = "gStats"; + $block->title = t("Gallery Stats"); + $block->content = new View("admin_block_stats.html"); + $block->content->album_count = ORM::factory("item")->where("type", "album")->count_all(); + $block->content->photo_count = ORM::factory("item")->where("type", "photo")->count_all(); + break; + + case "platform_info": + $block->css_id = "gPlatform"; + $block->title = t("Platform Information"); + $block->content = new View("admin_block_platform.html"); + if (is_readable("/proc/loadavg")) { + $block->content->load_average = + join(" ", array_slice(split(" ", array_shift(file("/proc/loadavg"))), 0, 3)); + } else { + $block->content->load_average = t("Unavailable"); + } + break; + + case "project_news": + $block->css_id = "gProjectNews"; + $block->title = t("Gallery Project News"); + $block->content = new View("admin_block_news.html"); + $block->content->feed = feed::parse("http://gallery.menalto.com/node/feed", 3); + break; + + case "block_adder": + $block->css_id = "gBlockAdder"; + $block->title = t("Dashboard Content"); + $block->content = self::get_add_block_form(); + } + + return $block; + } + + static function get_add_block_form() { + $form = new Forge("admin/dashboard/add_block", "", "post", + array("id" => "gAddDashboardBlockForm")); + $group = $form->group("add_block")->label(t("Add Block")); + $group->dropdown("id")->label("Available Blocks")->options(block_manager::get_available()); + $group->submit("center")->value(t("Add to center")); + $group->submit("sidebar")->value(t("Add to sidebar")); + return $form; + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php new file mode 100644 index 00000000..aa11b7c0 --- /dev/null +++ b/modules/gallery/helpers/gallery_event.php @@ -0,0 +1,46 @@ +admin && module::get_var("gallery", "choose_default_tookit", null)) { + graphics::choose_default_toolkit(); + module::clear_var("gallery", "choose_default_tookit"); + } + } +} diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php new file mode 100644 index 00000000..e3aa403f --- /dev/null +++ b/modules/gallery/helpers/gallery_installer.php @@ -0,0 +1,278 @@ +query("CREATE TABLE {access_caches} ( + `id` int(9) NOT NULL auto_increment, + `item_id` int(9), + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {access_intents} ( + `id` int(9) NOT NULL auto_increment, + `item_id` int(9), + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {graphics_rules} ( + `id` int(9) NOT NULL auto_increment, + `active` BOOLEAN default 0, + `args` varchar(255) default NULL, + `module_name` varchar(64) NOT NULL, + `operation` varchar(64) NOT NULL, + `priority` int(9) NOT NULL, + `target` varchar(32) NOT NULL, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {items} ( + `id` int(9) NOT NULL auto_increment, + `album_cover_item_id` int(9) default NULL, + `captured` int(9) default NULL, + `created` int(9) default NULL, + `description` varchar(2048) default NULL, + `height` int(9) default NULL, + `left` int(9) NOT NULL, + `level` int(9) NOT NULL, + `mime_type` varchar(64) default NULL, + `name` varchar(255) default NULL, + `owner_id` int(9) default NULL, + `parent_id` int(9) NOT NULL, + `rand_key` float default NULL, + `relative_path_cache` varchar(255) default NULL, + `resize_dirty` boolean default 1, + `resize_height` int(9) default NULL, + `resize_width` int(9) default NULL, + `right` int(9) NOT NULL, + `sort_column` varchar(64) default NULL, + `sort_order` char(4) default 'ASC', + `thumb_dirty` boolean default 1, + `thumb_height` int(9) default NULL, + `thumb_width` int(9) default NULL, + `title` varchar(255) default NULL, + `type` varchar(32) NOT NULL, + `updated` int(9) default NULL, + `view_count` int(9) default 0, + `weight` int(9) NOT NULL default 0, + `width` int(9) default NULL, + PRIMARY KEY (`id`), + KEY `parent_id` (`parent_id`), + KEY `type` (`type`), + KEY `random` (`rand_key`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {logs} ( + `id` int(9) NOT NULL auto_increment, + `category` varchar(64) default NULL, + `html` varchar(255) default NULL, + `message` text default NULL, + `referer` varchar(255) default NULL, + `severity` int(9) default 0, + `timestamp` int(9) default 0, + `url` varchar(255) default NULL, + `user_id` int(9) default 0, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {messages} ( + `id` int(9) NOT NULL auto_increment, + `key` varchar(255) default NULL, + `severity` varchar(32) default NULL, + `value` varchar(255) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`key`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {modules} ( + `id` int(9) NOT NULL auto_increment, + `active` BOOLEAN default 0, + `name` varchar(64) default NULL, + `version` int(9) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`name`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {themes} ( + `id` int(9) NOT NULL auto_increment, + `name` varchar(64) default NULL, + `version` int(9) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`name`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {permissions} ( + `id` int(9) NOT NULL auto_increment, + `display_name` varchar(64) default NULL, + `name` varchar(64) default NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(`name`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {incoming_translations} ( + `id` int(9) NOT NULL auto_increment, + `key` char(32) NOT NULL, + `locale` char(10) NOT NULL, + `message` text NOT NULL, + `revision` int(9) DEFAULT NULL, + `translation` text, + PRIMARY KEY (`id`), + UNIQUE KEY(`key`, `locale`), + KEY `locale_key` (`locale`, `key`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {outgoing_translations} ( + `id` int(9) NOT NULL auto_increment, + `base_revision` int(9) DEFAULT NULL, + `key` char(32) NOT NULL, + `locale` char(10) NOT NULL, + `message` text NOT NULL, + `translation` text, + PRIMARY KEY (`id`), + UNIQUE KEY(`key`, `locale`), + KEY `locale_key` (`locale`, `key`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {sessions} ( + `session_id` varchar(127) NOT NULL, + `data` text NOT NULL, + `last_activity` int(10) UNSIGNED NOT NULL, + PRIMARY KEY (`session_id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {tasks} ( + `id` int(9) NOT NULL auto_increment, + `callback` varchar(128) default NULL, + `context` text NOT NULL, + `done` boolean default 0, + `name` varchar(128) default NULL, + `owner_id` int(9) default NULL, + `percent_complete` int(9) default 0, + `state` varchar(32) default NULL, + `status` varchar(255) default NULL, + `updated` int(9) default NULL, + PRIMARY KEY (`id`), + KEY (`owner_id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + $db->query("CREATE TABLE {vars} ( + `id` int(9) NOT NULL auto_increment, + `module_name` varchar(64) NOT NULL, + `name` varchar(64) NOT NULL, + `value` text, + PRIMARY KEY (`id`), + UNIQUE KEY(`module_name`, `name`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + foreach (array("albums", "logs", "modules", "resizes", "thumbs", "tmp", "uploads") as $dir) { + @mkdir(VARPATH . $dir); + } + + access::register_permission("view", "View"); + access::register_permission("view_full", "View Full Size"); + access::register_permission("edit", "Edit"); + access::register_permission("add", "Add"); + + $root = ORM::factory("item"); + $root->type = "album"; + $root->title = "Gallery"; + $root->description = ""; + $root->left = 1; + $root->right = 2; + $root->parent_id = 0; + $root->level = 1; + $root->thumb_dirty = 1; + $root->resize_dirty = 1; + $root->sort_column = "weight"; + $root->sort_order = "ASC"; + $root->save(); + access::add_item($root); + + module::set_var("gallery", "active_site_theme", "default"); + module::set_var("gallery", "active_admin_theme", "admin_default"); + module::set_var("gallery", "page_size", 9); + module::set_var("gallery", "thumb_size", 200); + module::set_var("gallery", "resize_size", 640); + module::set_var("gallery", "default_locale", "en_US"); + module::set_var("gallery", "image_quality", 75); + + // Add rules for generating our thumbnails and resizes + graphics::add_rule( + "gallery", "thumb", "resize", + array("width" => 200, "height" => 200, "master" => Image::AUTO), + 100); + graphics::add_rule( + "gallery", "resize", "resize", + array("width" => 640, "height" => 480, "master" => Image::AUTO), + 100); + + // Instantiate default themes (site and admin) + foreach (array("default", "admin_default") as $theme_name) { + $theme_info = new ArrayObject(parse_ini_file(THEMEPATH . $theme_name . "/theme.info"), + ArrayObject::ARRAY_AS_PROPS); + $theme = ORM::factory("theme"); + $theme->name = $theme_name; + $theme->version = $theme_info->version; + $theme->save(); + } + + block_manager::add("dashboard_sidebar", "gallery", "block_adder"); + block_manager::add("dashboard_sidebar", "gallery", "stats"); + block_manager::add("dashboard_sidebar", "gallery", "platform_info"); + block_manager::add("dashboard_sidebar", "gallery", "project_news"); + block_manager::add("dashboard_center", "gallery", "welcome"); + block_manager::add("dashboard_center", "gallery", "photo_stream"); + block_manager::add("dashboard_center", "gallery", "log_entries"); + + module::set_version("gallery", 1); + module::set_var("gallery", "version", "3.0 pre-beta git"); + module::set_var("gallery", "choose_default_tookit", 1); + } + } + + static function uninstall() { + $db = Database::instance(); + $db->query("DROP TABLE IF EXISTS {access_caches}"); + $db->query("DROP TABLE IF EXISTS {access_intents}"); + $db->query("DROP TABLE IF EXISTS {graphics_rules}"); + $db->query("DROP TABLE IF EXISTS {items}"); + $db->query("DROP TABLE IF EXISTS {logs}"); + $db->query("DROP TABLE IF EXISTS {messages}"); + $db->query("DROP TABLE IF EXISTS {modules}"); + $db->query("DROP TABLE IF EXISTS {themes}"); + $db->query("DROP TABLE IF EXISTS {incoming_translations}"); + $db->query("DROP TABLE IF EXISTS {outgoing_translations}"); + $db->query("DROP TABLE IF EXISTS {permissions}"); + $db->query("DROP TABLE IF EXISTS {sessions}"); + $db->query("DROP TABLE IF EXISTS {tasks}"); + $db->query("DROP TABLE IF EXISTS {vars}"); + foreach (array("albums", "resizes", "thumbs", "uploads", + "modules", "logs", "database.php") as $entry) { + system("/bin/rm -rf " . VARPATH . $entry); + } + } +} diff --git a/modules/gallery/helpers/gallery_menu.php b/modules/gallery/helpers/gallery_menu.php new file mode 100644 index 00000000..215fc420 --- /dev/null +++ b/modules/gallery/helpers/gallery_menu.php @@ -0,0 +1,162 @@ +admin) { + $menu->append($scaffold_menu = Menu::factory("submenu") + ->id("scaffold") + ->label("Scaffold")); + $scaffold_menu->append(Menu::factory("link") + ->id("scaffold_home") + ->label("Dashboard") + ->url(url::site("scaffold"))); + } + + $menu->append(Menu::factory("link") + ->id("home") + ->label(t("Home")) + ->url(url::site("albums/1"))); + + $item = $theme->item(); + + if (user::active()->admin || ($item && access::can("edit", $item))) { + $menu->append($options_menu = Menu::factory("submenu") + ->id("options_menu") + ->label(t("Options"))); + + if ($item && access::can("edit", $item)) { + $options_menu + ->append(Menu::factory("dialog") + ->id("edit_item") + ->label($item->is_album() ? t("Edit album") : t("Edit photo")) + ->url(url::site("form/edit/{$item->type}s/$item->id"))); + + // @todo Move album options menu to the album quick edit pane + // @todo Create resized item quick edit pane menu + if ($item->is_album()) { + $options_menu + ->append(Menu::factory("dialog") + ->id("add_item") + ->label(t("Add a photo")) + ->url(url::site("simple_uploader/app/$item->id"))) + ->append(Menu::factory("dialog") + ->id("add_album") + ->label(t("Add an album")) + ->url(url::site("form/add/albums/$item->id?type=album"))) + ->append(Menu::factory("dialog") + ->id("edit_permissions") + ->label(t("Edit permissions")) + ->url(url::site("permissions/browse/$item->id"))); + } + } + } + + if (user::active()->admin) { + $menu->append($admin_menu = Menu::factory("submenu") + ->id("admin_menu") + ->label(t("Admin"))); + self::admin($admin_menu, $theme); + foreach (module::active() as $module) { + if ($module->name == "gallery") { + continue; + } + $class = "{$module->name}_menu"; + if (method_exists($class, "admin")) { + call_user_func_array(array($class, "admin"), array(&$admin_menu, $theme)); + } + } + } + } + + static function album($menu, $theme) { + } + + static function photo($menu, $theme) { + if (access::can("view_full", $theme->item())) { + $menu + ->append(Menu::factory("link") + ->id("fullsize") + ->label(t("View full size")) + ->url("#") + ->css_class("gFullSizeLink")); + } + $menu + ->append(Menu::factory("link") + ->id("album") + ->label(t("Return to album")) + ->url($theme->item()->parent()->url("show={$theme->item->id}")) + ->css_id("gAlbumLink")); + } + + static function admin($menu, $theme) { + $menu + ->append(Menu::factory("link") + ->id("dashboard") + ->label(t("Dashboard")) + ->url(url::site("admin"))) + ->append(Menu::factory("submenu") + ->id("settings_menu") + ->label(t("Settings")) + ->append(Menu::factory("link") + ->id("graphics_toolkits") + ->label(t("Graphics")) + ->url(url::site("admin/graphics"))) + ->append(Menu::factory("link") + ->id("languages") + ->label(t("Languages")) + ->url(url::site("admin/languages"))) + ->append(Menu::factory("link") + ->id("l10n_mode") + ->label(Session::instance()->get("l10n_mode", false) + ? t("Stop translating") : t("Start translating")) + ->url(url::site("l10n_client/toggle_l10n_mode?csrf=" . + access::csrf_token()))) + ->append(Menu::factory("link") + ->id("advanced") + ->label("Advanced") + ->url(url::site("admin/advanced_settings")))) + ->append(Menu::factory("link") + ->id("modules") + ->label(t("Modules")) + ->url(url::site("admin/modules"))) + ->append(Menu::factory("submenu") + ->id("content_menu") + ->label(t("Content"))) + ->append(Menu::factory("submenu") + ->id("appearance_menu") + ->label(t("Appearance")) + ->append(Menu::factory("link") + ->id("themes") + ->label(t("Theme Choice")) + ->url(url::site("admin/themes"))) + ->append(Menu::factory("link") + ->id("theme_details") + ->label(t("Theme Options")) + ->url(url::site("admin/theme_details")))) + ->append(Menu::factory("link") + ->id("maintenance") + ->label(t("Maintenance")) + ->url(url::site("admin/maintenance"))) + ->append(Menu::factory("submenu") + ->id("statistics_menu") + ->label(t("Statistics")) + ->url("#")); + } +} diff --git a/modules/gallery/helpers/gallery_search.php b/modules/gallery/helpers/gallery_search.php new file mode 100644 index 00000000..2a4029d3 --- /dev/null +++ b/modules/gallery/helpers/gallery_search.php @@ -0,0 +1,24 @@ +description, $item->name, $item->title)); + } +} diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php new file mode 100644 index 00000000..6046bfc4 --- /dev/null +++ b/modules/gallery/helpers/gallery_task.php @@ -0,0 +1,166 @@ +count(); + $tasks = array(); + $tasks[] = Task_Definition::factory() + ->callback("gallery_task::rebuild_dirty_images") + ->name(t("Rebuild Images")) + ->description($dirty_count ? + t2("You have one out of date photo", + "You have %count out of date photos", + $dirty_count) + : t("All your photos are up to date")) + ->severity($dirty_count ? log::WARNING : log::SUCCESS); + + $tasks[] = Task_Definition::factory() + ->callback("gallery_task::update_l10n") + ->name(t("Update translations")) + ->description(t("Download new and updated translated strings")) + ->severity(log::SUCCESS); + + return $tasks; + } + + /** + * Task that rebuilds all dirty images. + * @param Task_Model the task + */ + static function rebuild_dirty_images($task) { + $result = graphics::find_dirty_images_query(); + $remaining = $result->count(); + $completed = $task->get("completed", 0); + + $i = 0; + foreach ($result as $row) { + $item = ORM::factory("item", $row->id); + if ($item->loaded) { + graphics::generate($item); + } + + $completed++; + $remaining--; + + if (++$i == 2) { + break; + } + } + + $task->status = t2("Updated: 1 image. Total: %total_count.", + "Updated: %count images. Total: %total_count.", + $completed, + array("total_count" => ($remaining + $completed))); + + if ($completed + $remaining > 0) { + $task->percent_complete = (int)(100 * $completed / ($completed + $remaining)); + } else { + $task->percent_complete = 100; + } + + $task->set("completed", $completed); + if ($remaining == 0) { + $task->done = true; + $task->state = "success"; + site_status::clear("graphics_dirty"); + } + } + + static function update_l10n(&$task) { + $start = microtime(true); + $dirs = $task->get("dirs"); + $files = $task->get("files"); + $cache = $task->get("cache", array()); + $i = 0; + + switch ($task->get("mode", "init")) { + case "init": // 0% + $dirs = array("gallery", "modules", "themes", "installer"); + $files = array(); + $task->set("mode", "find_files"); + $task->status = t("Finding files"); + break; + + case "find_files": // 0% - 10% + while (($dir = array_pop($dirs)) && microtime(true) - $start < 0.5) { + if (basename($dir) == "tests") { + continue; + } + + foreach (glob(DOCROOT . "$dir/*") as $path) { + $relative_path = str_replace(DOCROOT, "", $path); + if (is_dir($path)) { + $dirs[] = $relative_path; + } else { + $files[] = $relative_path; + } + } + } + + $task->status = t2("Finding files: found 1 file", + "Finding files: found %count files", count($files)); + + if (!$dirs) { + $task->set("mode", "scan_files"); + $task->set("total_files", count($files)); + $task->status = t("Scanning files"); + $task->percent_complete = 10; + } + break; + + case "scan_files": // 10% - 90% + while (($file = array_pop($files)) && microtime(true) - $start < 0.5) { + $file = DOCROOT . $file; + switch (pathinfo($file, PATHINFO_EXTENSION)) { + case "php": + l10n_scanner::scan_php_file($file, $cache); + break; + + case "info": + l10n_scanner::scan_info_file($file, $cache); + break; + } + } + + $total_files = $task->get("total_files"); + $task->status = t2("Scanning files: scanned 1 file", + "Scanning files: scanned %count files", $total_files - count($files)); + + $task->percent_complete = 10 + 80 * ($total_files - count($files)) / $total_files; + if (empty($files)) { + $task->set("mode", "fetch_updates"); + $task->status = t("Fetching updates"); + $task->percent_complete = 90; + } + break; + + case "fetch_updates": // 90% - 100% + l10n_client::fetch_updates(); + $task->done = true; + $task->state = "success"; + $task->status = t("Translations installed/updated"); + $task->percent_complete = 100; + } + + $task->set("files", $files); + $task->set("dirs", $dirs); + $task->set("cache", $cache); + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/gallery_theme.php b/modules/gallery/helpers/gallery_theme.php new file mode 100644 index 00000000..0acccb45 --- /dev/null +++ b/modules/gallery/helpers/gallery_theme.php @@ -0,0 +1,137 @@ +get("debug")) { + $buf .= ""; + } + if (($theme->page_type == "album" || $theme->page_type == "photo") + && access::can("edit", $theme->item())) { + $buf .= ""; + $buf .= html::script("gallery/js/quick.js"); + } + if ($theme->page_type == "photo" && access::can("view_full", $theme->item())) { + $buf .= ""; + $buf .= html::script("gallery/js/fullsize.js"); + } + + if ($session->get("l10n_mode", false)) { + $buf .= ""; + $buf .= html::script("lib/jquery.cookie.js"); + $buf .= html::script("gallery/js/l10n_client.js"); + } + + return $buf; + } + + static function resize_top($theme, $item) { + if (access::can("edit", $item)) { + $edit_link = url::site("quick/pane/$item->id?page_type=photo"); + return "
    "; + } + } + + static function resize_bottom($theme, $item) { + if (access::can("edit", $item)) { + return "
    "; + } + } + + static function thumb_top($theme, $child) { + if (access::can("edit", $child)) { + $edit_link = url::site("quick/pane/$child->id?page_type=album"); + return "
    "; + } + } + + static function thumb_bottom($theme, $child) { + if (access::can("edit", $child)) { + return "
    "; + } + } + + static function admin_head($theme) { + $session = Session::instance(); + $buf = ""; + if ($session->get("debug")) { + $buf .= ""; + } + + if ($session->get("l10n_mode", false)) { + $buf .= ""; + $buf .= html::script("lib/jquery.cookie.js"); + $buf .= html::script("gallery/js/l10n_client.js"); + } + + return $buf; + } + + static function page_bottom($theme) { + $session = Session::instance(); + if ($session->get("profiler", false)) { + $profiler = new Profiler(); + $profiler->render(); + } + if ($session->get("l10n_mode", false)) { + return L10n_Client_Controller::l10n_form(); + } + + if ($session->get("after_install")) { + $session->delete("after_install"); + return new View("after_install_loader.html"); + } + } + + static function admin_page_bottom($theme) { + $session = Session::instance(); + if ($session->get("profiler", false)) { + $profiler = new Profiler(); + $profiler->render(); + } + if ($session->get("l10n_mode", false)) { + return L10n_Client_Controller::l10n_form(); + } + } + + static function credits() { + return "
  • " . + t("Powered by Gallery %version", + array("url" => "http://gallery.menalto.com", + "version" => module::get_var("gallery", "version"))) . + "
  • "; + } + + static function admin_credits() { + return gallery_theme::credits(); + } +} \ No newline at end of file diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index 805a95c0..605b9ff8 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -26,11 +26,11 @@ class graphics_Core { * Rules are applied to targets (thumbnails and resizes) in priority order. Rules are functions * in the graphics class. So for example, the following rule: * - * graphics::add_rule("core", "thumb", "resize", + * graphics::add_rule("gallery", "thumb", "resize", * array("width" => 200, "height" => 200, "master" => Image::AUTO), 100); * - * Specifies that "core" is adding a rule to resize thumbnails down to a max of 200px on - * the longest side. The core module adds default rules at a priority of 100. You can set + * Specifies that "gallery" is adding a rule to resize thumbnails down to a max of 200px on + * the longest side. The gallery module adds default rules at a priority of 100. You can set * higher and lower priorities to perform operations before or after this fires. * * @param string $module_name the module that added the rule @@ -194,7 +194,7 @@ class graphics_Core { } else { Image::factory($input_file) ->resize($options["width"], $options["height"], $options["master"]) - ->quality(module::get_var("core", "image_quality")) + ->quality(module::get_var("gallery", "image_quality")) ->save($output_file); } } @@ -212,7 +212,7 @@ class graphics_Core { } Image::factory($input_file) - ->quality(module::get_var("core", "image_quality")) + ->quality(module::get_var("gallery", "image_quality")) ->rotate($options["degrees"]) ->save($output_file); } @@ -262,7 +262,7 @@ class graphics_Core { Image::factory($input_file) ->composite($options["file"], $x, $y, $options["transparency"]) - ->quality(module::get_var("core", "image_quality")) + ->quality(module::get_var("gallery", "image_quality")) ->save($output_file); } @@ -302,7 +302,7 @@ class graphics_Core { $count, array("attrs" => sprintf( 'href="%s" class="gDialogLink"', - url::site("admin/maintenance/start/core_task::rebuild_dirty_images?csrf=__CSRF__")))), + url::site("admin/maintenance/start/gallery_task::rebuild_dirty_images?csrf=__CSRF__")))), "graphics_dirty"); } } @@ -332,12 +332,12 @@ class graphics_Core { $toolkits = graphics::detect_toolkits(); foreach (array("imagemagick", "graphicsmagick", "gd") as $tk) { if ($toolkits[$tk]) { - module::set_var("core", "graphics_toolkit", $tk); - module::set_var("core", "graphics_toolkit_path", $tk == "gd" ? "" : $toolkits[$tk]); + module::set_var("gallery", "graphics_toolkit", $tk); + module::set_var("gallery", "graphics_toolkit_path", $tk == "gd" ? "" : $toolkits[$tk]); break; } } - if (!module::get_var("core", "graphics_toolkit")) { + if (!module::get_var("gallery", "graphics_toolkit")) { site_status::warning( t("Graphics toolkit missing! Please choose a toolkit", array("url" => url::site("admin/graphics"))), @@ -349,7 +349,7 @@ class graphics_Core { * Choose which driver the Kohana Image library uses. */ static function init_toolkit() { - switch(module::get_var("core", "graphics_toolkit")) { + switch(module::get_var("gallery", "graphics_toolkit")) { case "gd": Kohana::config_set("image.driver", "GD"); break; @@ -357,13 +357,13 @@ class graphics_Core { case "imagemagick": Kohana::config_set("image.driver", "ImageMagick"); Kohana::config_set( - "image.params.directory", module::get_var("core", "graphics_toolkit_path")); + "image.params.directory", module::get_var("gallery", "graphics_toolkit_path")); break; case "graphicsmagick": Kohana::config_set("image.driver", "GraphicsMagick"); Kohana::config_set( - "image.params.directory", module::get_var("core", "graphics_toolkit_path")); + "image.params.directory", module::get_var("gallery", "graphics_toolkit_path")); break; } @@ -376,7 +376,7 @@ class graphics_Core { * @return boolean */ static function can($func) { - if (module::get_var("core", "graphics_toolkit") == "gd" && + if (module::get_var("gallery", "graphics_toolkit") == "gd" && $func == "rotate" && !function_exists("imagerotate")) { return false; diff --git a/modules/gallery/helpers/l10n_client.php b/modules/gallery/helpers/l10n_client.php index ec4c5429..d26739f5 100644 --- a/modules/gallery/helpers/l10n_client.php +++ b/modules/gallery/helpers/l10n_client.php @@ -35,9 +35,9 @@ class l10n_client_Core { static function api_key($api_key=null) { if ($api_key !== null) { - module::set_var("core", "l10n_client_key", $api_key); + module::set_var("gallery", "l10n_client_key", $api_key); } - return module::get_var("core", "l10n_client_key", ""); + return module::get_var("gallery", "l10n_client_key", ""); } static function server_uid($api_key=null) { diff --git a/modules/gallery/helpers/locale.php b/modules/gallery/helpers/locale.php index b707637f..2ba0f255 100644 --- a/modules/gallery/helpers/locale.php +++ b/modules/gallery/helpers/locale.php @@ -37,8 +37,8 @@ class locale_Core { static function installed() { $available = self::available(); - $default = module::get_var("core", "default_locale"); - $codes = explode("|", module::get_var("core", "installed_locales", $default)); + $default = module::get_var("gallery", "default_locale"); + $codes = explode("|", module::get_var("gallery", "installed_locales", $default)); foreach ($codes as $code) { if (isset($available->$code)) { $installed[$code] = $available[$code]; @@ -49,10 +49,10 @@ class locale_Core { static function update_installed($locales) { // Ensure that the default is included... - $default = module::get_var("core", "default_locale"); + $default = module::get_var("gallery", "default_locale"); $locales = array_merge($locales, array($default)); - module::set_var("core", "installed_locales", join("|", $locales)); + module::set_var("gallery", "installed_locales", join("|", $locales)); } // @todo Might want to add a localizable language name as well. diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php index a48c89ed..a6cc87ac 100644 --- a/modules/gallery/helpers/module.php +++ b/modules/gallery/helpers/module.php @@ -37,7 +37,7 @@ class module_Core { $module = self::get($module_name); if (!$module->loaded) { $module->name = $module_name; - $module->active = $module_name == "core"; // only core is active by default + $module->active = $module_name == "gallery"; // only gallery is active by default } $module->version = 1; $module->save(); @@ -75,7 +75,7 @@ class module_Core { */ static function available() { $modules = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS); - foreach (array_merge(array("core/module.info"), glob(MODPATH . "*/module.info")) as $file) { + foreach (array_merge(array("gallery/module.info"), glob(MODPATH . "*/module.info")) as $file) { $module_name = basename(dirname($file)); $modules->$module_name = new ArrayObject(parse_ini_file($file), ArrayObject::ARRAY_AS_PROPS); $modules->$module_name->installed = self::is_installed($module_name); @@ -85,7 +85,7 @@ class module_Core { } // Lock certain modules - $modules->core->locked = true; + $modules->gallery->locked = true; $modules->user->locked = true; $modules->ksort(); @@ -215,10 +215,10 @@ class module_Core { if ($module->active) { self::$active[] = $module; } - if ($module->name != "core") { - $kohana_modules[] = MODPATH . $module->name; - } + $kohana_modules[] = MODPATH . $module->name; + // @todo: force 'gallery' to be at the end } + Kohana::config_set("core.modules", $kohana_modules); } @@ -252,32 +252,32 @@ class module_Core { * @return the value */ static function get_var($module_name, $name, $default_value=null) { - // We cache all vars in core._cache so that we can load all vars at once for + // We cache all vars in gallery._cache so that we can load all vars at once for // performance. if (empty(self::$var_cache)) { $row = Database::instance() ->select("value") ->from("vars") - ->where(array("module_name" => "core", "name" => "_cache")) + ->where(array("module_name" => "gallery", "name" => "_cache")) ->get() ->current(); if ($row) { self::$var_cache = unserialize($row->value); } else { - // core._cache doesn't exist. Create it now. + // gallery._cache doesn't exist. Create it now. foreach (Database::instance() ->select("module_name", "name", "value") ->from("vars") ->orderby("module_name", "name") ->get() as $row) { - if ($row->module_name == "core" && $row->name == "_cache") { + if ($row->module_name == "gallery" && $row->name == "_cache") { // This could happen if there's a race condition continue; } self::$var_cache->{$row->module_name}->{$row->name} = $row->value; } $cache = ORM::factory("var"); - $cache->module_name = "core"; + $cache->module_name = "gallery"; $cache->name = "_cache"; $cache->value = serialize(self::$var_cache); $cache->save(); @@ -309,7 +309,7 @@ class module_Core { $var->value = $value; $var->save(); - Database::instance()->delete("vars", array("module_name" => "core", "name" => "_cache")); + Database::instance()->delete("vars", array("module_name" => "gallery", "name" => "_cache")); self::$var_cache = null; } @@ -325,7 +325,7 @@ class module_Core { "WHERE `module_name` = '$module_name' " . "AND `name` = '$name'"); - Database::instance()->delete("vars", array("module_name" => "core", "name" => "_cache")); + Database::instance()->delete("vars", array("module_name" => "gallery", "name" => "_cache")); self::$var_cache = null; } @@ -343,7 +343,7 @@ class module_Core { $var->delete(); } - Database::instance()->delete("vars", array("module_name" => "core", "name" => "_cache")); + Database::instance()->delete("vars", array("module_name" => "gallery", "name" => "_cache")); self::$var_cache = null; } diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 3293d4ac..15225fe7 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -140,11 +140,11 @@ class movie_Core { } static function find_ffmpeg() { - if (!$ffmpeg_path = module::get_var("core", "ffmpeg_path")) { + if (!$ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) { if (function_exists("exec")) { $ffmpeg_path = exec("which ffmpeg"); if ($ffmpeg_path) { - module::set_var("core", "ffmpeg_path", $ffmpeg_path); + module::set_var("gallery", "ffmpeg_path", $ffmpeg_path); } } } diff --git a/modules/gallery/helpers/theme.php b/modules/gallery/helpers/theme.php index cbe224db..af340db6 100644 --- a/modules/gallery/helpers/theme.php +++ b/modules/gallery/helpers/theme.php @@ -31,10 +31,11 @@ class theme_Core { static function load_themes() { $modules = Kohana::config("core.modules"); if (Router::$controller == "admin") { - array_unshift($modules, THEMEPATH . module::get_var("core", "active_admin_theme")); + array_unshift($modules, THEMEPATH . module::get_var("gallery", "active_admin_theme")); } else { - array_unshift($modules, THEMEPATH . module::get_var("core", "active_site_theme")); + array_unshift($modules, THEMEPATH . module::get_var("gallery", "active_site_theme")); } + Kohana::config_set("core.modules", $modules); } @@ -43,17 +44,17 @@ class theme_Core { $group = $form->group("edit_theme"); $group->input("page_size")->label(t("Items per page"))->id("gPageSize") ->rules("required|valid_digit") - ->value(module::get_var("core", "page_size")); + ->value(module::get_var("gallery", "page_size")); $group->input("thumb_size")->label(t("Thumbnail size (in pixels)"))->id("gThumbSize") ->rules("required|valid_digit") - ->value(module::get_var("core", "thumb_size")); + ->value(module::get_var("gallery", "thumb_size")); $group->input("resize_size")->label(t("Resized image size (in pixels)"))->id("gResizeSize") ->rules("required|valid_digit") - ->value(module::get_var("core", "resize_size")); + ->value(module::get_var("gallery", "resize_size")); $group->textarea("header_text")->label(t("Header text"))->id("gHeaderText") - ->value(module::get_var("core", "header_text")); + ->value(module::get_var("gallery", "header_text")); $group->textarea("footer_text")->label(t("Footer text"))->id("gFooterText") - ->value(module::get_var("core", "footer_text")); + ->value(module::get_var("gallery", "footer_text")); $group->submit("")->value(t("Save")); return $form; } diff --git a/modules/gallery/hooks/init_gallery.php b/modules/gallery/hooks/init_gallery.php index 2c36795a..5735e7dc 100644 --- a/modules/gallery/hooks/init_gallery.php +++ b/modules/gallery/hooks/init_gallery.php @@ -26,11 +26,11 @@ if (!file_exists(VARPATH . "database.php")) { Event::add("system.ready", array("I18n", "instance")); Event::add("system.ready", array("module", "load_modules")); -Event::add("system.ready", array("core", "ready")); +Event::add("system.ready", array("gallery", "ready")); Event::add("system.post_routing", array("theme", "load_themes")); Event::add("system.post_routing", array("url", "parse_url")); -Event::add("system.post_routing", array("core", "maintenance_mode")); -Event::add("system.shutdown", array("core", "shutdown")); +Event::add("system.post_routing", array("gallery", "maintenance_mode")); +Event::add("system.shutdown", array("gallery", "shutdown")); // Override the cookie if we have a session id in the URL. // @todo This should probably be an event callback diff --git a/modules/gallery/libraries/Admin_View.php b/modules/gallery/libraries/Admin_View.php index acc3f8ec..1f976871 100644 --- a/modules/gallery/libraries/Admin_View.php +++ b/modules/gallery/libraries/Admin_View.php @@ -29,15 +29,15 @@ class Admin_View_Core extends View { * @return void */ public function __construct($name) { - $theme_name = module::get_var("core", "active_site_theme"); + $theme_name = module::get_var("gallery", "active_site_theme"); if (!file_exists("themes/$theme_name")) { - module::set_var("core", "active_site_theme", "admin_default"); + module::set_var("gallery", "active_site_theme", "admin_default"); theme::load_themes(); Kohana::log("error", "Unable to locate theme '$theme_name', switching to default theme."); } parent::__construct($name); - $this->theme_name = module::get_var("core", "active_admin_theme"); + $this->theme_name = module::get_var("gallery", "active_admin_theme"); if (user::active()->admin) { $this->theme_name = Input::instance()->get("theme", $this->theme_name); } @@ -57,10 +57,10 @@ class Admin_View_Core extends View { public function admin_menu() { $menu = Menu::factory("root"); - core_menu::admin($menu, $this); + gallery_menu::admin($menu, $this); foreach (module::active() as $module) { - if ($module->name == "core") { + if ($module->name == "gallery") { continue; } $class = "{$module->name}_menu"; diff --git a/modules/gallery/libraries/I18n.php b/modules/gallery/libraries/I18n.php index c936be88..f2801169 100644 --- a/modules/gallery/libraries/I18n.php +++ b/modules/gallery/libraries/I18n.php @@ -62,7 +62,7 @@ class I18n_Core { if (self::$_instance == NULL || isset($config)) { $config = isset($config) ? $config : Kohana::config('locale'); if (empty($config['default_locale'])) { - $config['default_locale'] = module::get_var('core', 'default_locale'); + $config['default_locale'] = module::get_var('gallery', 'default_locale'); } self::$_instance = new I18n_Core($config); } diff --git a/modules/gallery/libraries/Theme_View.php b/modules/gallery/libraries/Theme_View.php index b5b97666..5fcc2943 100644 --- a/modules/gallery/libraries/Theme_View.php +++ b/modules/gallery/libraries/Theme_View.php @@ -30,15 +30,15 @@ class Theme_View_Core extends View { * @return void */ public function __construct($name, $page_type) { - $theme_name = module::get_var("core", "active_site_theme"); + $theme_name = module::get_var("gallery", "active_site_theme"); if (!file_exists("themes/$theme_name")) { - module::set_var("core", "active_site_theme", "default"); + module::set_var("gallery", "active_site_theme", "default"); theme::load_themes(); Kohana::log("error", "Unable to locate theme '$theme_name', switching to default theme."); } parent::__construct($name); - $this->theme_name = module::get_var("core", "active_site_theme"); + $this->theme_name = module::get_var("gallery", "active_site_theme"); if (user::active()->admin) { $this->theme_name = Input::instance()->get("theme", $this->theme_name); } @@ -64,7 +64,7 @@ class Theme_View_Core extends View { public function thumb_proportion() { // @TODO change the 200 to a theme supplied value when and if we come up with an // API to allow the theme to set defaults. - return module::get_var("core", "thumb_size", 200) / 200; + return module::get_var("gallery", "thumb_size", 200) / 200; } public function url($path, $absolute_url=false) { @@ -91,10 +91,10 @@ class Theme_View_Core extends View { public function site_menu() { $menu = Menu::factory("root"); if ($this->page_type != "login") { - core_menu::site($menu, $this); + gallery_menu::site($menu, $this); foreach (module::active() as $module) { - if ($module->name == "core") { + if ($module->name == "gallery") { continue; } $class = "{$module->name}_menu"; @@ -109,10 +109,10 @@ class Theme_View_Core extends View { public function album_menu() { $menu = Menu::factory("root"); - core_menu::album($menu, $this); + gallery_menu::album($menu, $this); foreach (module::active() as $module) { - if ($module->name == "core") { + if ($module->name == "gallery") { continue; } $class = "{$module->name}_menu"; @@ -126,10 +126,10 @@ class Theme_View_Core extends View { public function photo_menu() { $menu = Menu::factory("root"); - core_menu::photo($menu, $this); + gallery_menu::photo($menu, $this); foreach (module::active() as $module) { - if ($module->name == "core") { + if ($module->name == "gallery") { continue; } $class = "{$module->name}_menu"; diff --git a/modules/gallery/tests/Core_Installer_Test.php b/modules/gallery/tests/Core_Installer_Test.php index f7036286..24d24b38 100644 --- a/modules/gallery/tests/Core_Installer_Test.php +++ b/modules/gallery/tests/Core_Installer_Test.php @@ -19,21 +19,21 @@ */ /** - * This test case operates under the assumption that core_installer::install() is called by the + * This test case operates under the assumption that gallery_installer::install() is called by the * test controller before it starts. */ -class Core_Installer_Test extends Unit_Test_Case { +class Gallery_Installer_Test extends Unit_Test_Case { public function install_creates_dirs_test() { $this->assert_true(file_exists(VARPATH . "albums")); $this->assert_true(file_exists(VARPATH . "resizes")); } - public function install_registers_core_module_test() { - $core = ORM::factory("module")->where("name", "core")->find(); - $this->assert_equal("core", $core->name); + public function install_registers_gallery_module_test() { + $gallery = ORM::factory("module")->where("name", "gallery")->find(); + $this->assert_equal("gallery", $gallery->name); // This is probably too volatile to keep for long - $this->assert_equal(1, $core->version); + $this->assert_equal(1, $gallery->version); } public function install_creates_root_item_test() { diff --git a/modules/gallery/tests/File_Structure_Test.php b/modules/gallery/tests/File_Structure_Test.php index 1caa82ba..3b8c754f 100644 --- a/modules/gallery/tests/File_Structure_Test.php +++ b/modules/gallery/tests/File_Structure_Test.php @@ -218,11 +218,11 @@ class GalleryCodeFilterIterator extends FilterIterator { $path_name = $this->getInnerIterator()->getPathName(); return !( strpos($path_name, ".svn") || - strpos($path_name, "core/views/kohana_profiler.php") !== false || strpos($path_name, DOCROOT . "test") !== false || strpos($path_name, DOCROOT . "var") !== false || strpos($path_name, MODPATH . "forge") !== false || strpos($path_name, APPPATH . "views/kohana_error_page.php") !== false || + strpos($path_name, MODPATH . "gallery/views/kohana_profiler.php") !== false || strpos($path_name, MODPATH . "gallery_unit_test/views/kohana_error_page.php") !== false || strpos($path_name, MODPATH . "gallery_unit_test/views/kohana_unit_test_cli.php") !== false || strpos($path_name, MODPATH . "unit_test") !== false || diff --git a/modules/gallery/tests/Movie_Helper_Test.php b/modules/gallery/tests/Movie_Helper_Test.php index b92ef3f8..627651bb 100644 --- a/modules/gallery/tests/Movie_Helper_Test.php +++ b/modules/gallery/tests/Movie_Helper_Test.php @@ -22,7 +22,7 @@ class Movie_Helper_Test extends Unit_Test_Case { $rand = rand(); $root = ORM::factory("item", 1); try { - $movie = movie::create($root, DOCROOT . "core/tests/test.jpg", "$rand/.jpg", $rand, $rand); + $movie = movie::create($root, MODPATH . "gallery/tests/test.jpg", "$rand/.jpg", $rand, $rand); } catch (Exception $e) { // pass return; @@ -35,7 +35,7 @@ class Movie_Helper_Test extends Unit_Test_Case { $rand = rand(); $root = ORM::factory("item", 1); try { - $movie = movie::create($root, DOCROOT . "core/tests/test.jpg", "$rand.jpg.", $rand, $rand); + $movie = movie::create($root, MODPATH . "gallery/tests/test.jpg", "$rand.jpg.", $rand, $rand); } catch (Exception $e) { $this->assert_equal("@todo NAME_CANNOT_END_IN_PERIOD", $e->getMessage()); return; diff --git a/modules/gallery/tests/Photo_Helper_Test.php b/modules/gallery/tests/Photo_Helper_Test.php index deb11bb9..2a6693e1 100644 --- a/modules/gallery/tests/Photo_Helper_Test.php +++ b/modules/gallery/tests/Photo_Helper_Test.php @@ -21,7 +21,7 @@ class Photo_Helper_Test extends Unit_Test_Case { public function create_photo_test() { $rand = rand(); - $filename = DOCROOT . "core/tests/test.jpg"; + $filename = MODPATH . "gallery/tests/test.jpg"; $image_info = getimagesize($filename); $root = ORM::factory("item", 1); @@ -50,8 +50,8 @@ class Photo_Helper_Test extends Unit_Test_Case { public function create_conflicting_photo_test() { $rand = rand(); $root = ORM::factory("item", 1); - $photo1 = photo::create($root, DOCROOT . "core/tests/test.jpg", "$rand.jpg", $rand, $rand); - $photo2 = photo::create($root, DOCROOT . "core/tests/test.jpg", "$rand.jpg", $rand, $rand); + $photo1 = photo::create($root, MODPATH . "gallery/tests/test.jpg", "$rand.jpg", $rand, $rand); + $photo2 = photo::create($root, MODPATH . "gallery/tests/test.jpg", "$rand.jpg", $rand, $rand); $this->assert_true($photo1->name != $photo2->name); } @@ -68,7 +68,7 @@ class Photo_Helper_Test extends Unit_Test_Case { public function thumb_url_test() { $rand = rand(); $root = ORM::factory("item", 1); - $photo = photo::create($root, DOCROOT . "core/tests/test.jpg", "$rand.jpg", $rand, $rand); + $photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "$rand.jpg", $rand, $rand); $this->assert_equal("http://./var/thumbs/{$rand}.jpg", $photo->thumb_url()); } @@ -76,7 +76,7 @@ class Photo_Helper_Test extends Unit_Test_Case { $rand = rand(); $root = ORM::factory("item", 1); $album = album::create($root, $rand, $rand, $rand); - $photo = photo::create($album, DOCROOT . "core/tests/test.jpg", "$rand.jpg", $rand, $rand); + $photo = photo::create($album, MODPATH . "gallery/tests/test.jpg", "$rand.jpg", $rand, $rand); $this->assert_equal("http://./var/resizes/{$rand}/{$rand}.jpg", $photo->resize_url()); } @@ -85,7 +85,7 @@ class Photo_Helper_Test extends Unit_Test_Case { $rand = rand(); $root = ORM::factory("item", 1); try { - $photo = photo::create($root, DOCROOT . "core/tests/test.jpg", "$rand/.jpg", $rand, $rand); + $photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "$rand/.jpg", $rand, $rand); } catch (Exception $e) { // pass return; @@ -98,7 +98,7 @@ class Photo_Helper_Test extends Unit_Test_Case { $rand = rand(); $root = ORM::factory("item", 1); try { - $photo = photo::create($root, DOCROOT . "core/tests/test.jpg", "$rand.jpg.", $rand, $rand); + $photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "$rand.jpg.", $rand, $rand); } catch (Exception $e) { $this->assert_equal("@todo NAME_CANNOT_END_IN_PERIOD", $e->getMessage()); return; diff --git a/modules/gallery/tests/Photos_Controller_Test.php b/modules/gallery/tests/Photos_Controller_Test.php index 71319315..771cc90d 100644 --- a/modules/gallery/tests/Photos_Controller_Test.php +++ b/modules/gallery/tests/Photos_Controller_Test.php @@ -29,7 +29,7 @@ class Photos_Controller_Test extends Unit_Test_Case { public function change_photo_test() { $controller = new Photos_Controller(); $root = ORM::factory("item", 1); - $photo = photo::create($root, DOCROOT . "core/tests/test.jpg", "test.jpeg", "test", "test"); + $photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "test.jpeg", "test", "test"); $orig_name = $photo->name; $_POST["filename"] = "test.jpeg"; @@ -58,7 +58,7 @@ class Photos_Controller_Test extends Unit_Test_Case { public function change_photo_no_csrf_fails_test() { $controller = new Photos_Controller(); $root = ORM::factory("item", 1); - $photo = photo::create($root, DOCROOT . "core/tests/test.jpg", "test", "test", "test"); + $photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "test", "test", "test"); $_POST["name"] = "new name"; $_POST["title"] = "new title"; $_POST["description"] = "new description"; diff --git a/modules/gallery/tests/Var_Test.php b/modules/gallery/tests/Var_Test.php index 82370631..355d94a7 100644 --- a/modules/gallery/tests/Var_Test.php +++ b/modules/gallery/tests/Var_Test.php @@ -19,31 +19,31 @@ */ class Var_Test extends Unit_Test_Case { public function add_parameter_test() { - module::set_var("core", "Parameter", "original value"); - $this->assert_equal("original value", module::get_var("core", "Parameter")); + module::set_var("gallery", "Parameter", "original value"); + $this->assert_equal("original value", module::get_var("gallery", "Parameter")); - module::set_var("core", "Parameter", "updated value"); - $this->assert_equal("updated value", module::get_var("core", "Parameter")); + module::set_var("gallery", "Parameter", "updated value"); + $this->assert_equal("updated value", module::get_var("gallery", "Parameter")); } public function clear_parameter_test() { - module::set_var("core", "Parameter", "original value"); - $this->assert_equal("original value", module::get_var("core", "Parameter")); + module::set_var("gallery", "Parameter", "original value"); + $this->assert_equal("original value", module::get_var("gallery", "Parameter")); - module::clear_var("core", "Parameter"); - $this->assert_equal(null, module::get_var("core", "Parameter")); + module::clear_var("gallery", "Parameter"); + $this->assert_equal(null, module::get_var("gallery", "Parameter")); } public function incr_parameter_test() { - module::set_var("core", "Parameter", "original value"); - module::incr_var("core", "Parameter"); - $this->assert_equal("1", module::get_var("core", "Parameter")); + module::set_var("gallery", "Parameter", "original value"); + module::incr_var("gallery", "Parameter"); + $this->assert_equal("1", module::get_var("gallery", "Parameter")); - module::set_var("core", "Parameter", "2"); - module::incr_var("core", "Parameter", "9"); - $this->assert_equal("11", module::get_var("core", "Parameter")); + module::set_var("gallery", "Parameter", "2"); + module::incr_var("gallery", "Parameter", "9"); + $this->assert_equal("11", module::get_var("gallery", "Parameter")); - module::incr_var("core", "NonExistent", "9"); - $this->assert_equal(null, module::get_var("core", "NonExistent")); + module::incr_var("gallery", "NonExistent", "9"); + $this->assert_equal(null, module::get_var("gallery", "NonExistent")); } } \ No newline at end of file diff --git a/modules/gallery/views/admin_advanced_settings.html.php b/modules/gallery/views/admin_advanced_settings.html.php index 1f3825bd..9f90d671 100644 --- a/modules/gallery/views/admin_advanced_settings.html.php +++ b/modules/gallery/views/admin_advanced_settings.html.php @@ -17,7 +17,7 @@ - module_name == "core" && $var->name == "_cache") continue ?> + module_name == "gallery" && $var->name == "_cache") continue ?> module_name ?> name ?> diff --git a/modules/gallery/views/admin_block_stats.html.php b/modules/gallery/views/admin_block_stats.html.php index 2d975073..395ed71d 100644 --- a/modules/gallery/views/admin_block_stats.html.php +++ b/modules/gallery/views/admin_block_stats.html.php @@ -1,7 +1,7 @@