static function fix_internet_addresses($task)
 {
     $start = microtime(true);
     $total = $task->get("total");
     if (empty($total)) {
         $task->set("total", $total = db::build()->count_records("items"));
         $task->set("last_id", 0);
         $task->set("completed", 0);
     }
     $last_id = $task->get("last_id");
     $completed = $task->get("completed");
     foreach (ORM::factory("item")->where("id", ">", $last_id)->find_all(100) as $item) {
         $item->slug = item::convert_filename_to_slug($item->slug);
         $item->save();
         $last_id = $item->id;
         $completed++;
         if ($completed == $total || microtime(true) - $start > 1.5) {
             break;
         }
     }
     $task->set("completed", $completed);
     $task->set("last_id", $last_id);
     if ($total == $completed) {
         $task->done = true;
         $task->state = "success";
         $task->percent_complete = 100;
         db::build()->update("items")->set("relative_path_cache", null)->set("relative_url_cache", null)->execute();
     } else {
         $task->percent_complete = round(100 * $completed / $total);
     }
     $task->status = t2("One row updated", "%count / %total rows updated", $completed, array("total" => $total));
 }
 public function convert_filename_to_slug_test()
 {
     $this->assert_equal("foo", item::convert_filename_to_slug("{[foo]}"));
     $this->assert_equal("foo-bar", item::convert_filename_to_slug("{[foo!@#!\$@#^\$@(\$!(@bar]}"));
     $this->assert_equal("english-text", item::convert_filename_to_slug("english text"));
     $this->assert_equal("new-line", item::convert_filename_to_slug("new \n line"));
     $this->assert_equal("foo-and-bar", item::convert_filename_to_slug("foo&bar"));
     $this->assert_equal("special", item::convert_filename_to_slug("šṗëçîąļ"));
 }
Beispiel #3
0
 /**
  * Create a new album.
  * @param integer $parent_id id of parent album
  * @param string  $name the name of this new album (it will become the directory name on disk)
  * @param integer $title the title of the new album
  * @param string  $description (optional) the longer description of this album
  * @param string  $slug (optional) the url component for this photo
  * @return Item_Model
  */
 static function create($parent, $name, $title, $description = null, $owner_id = null, $slug = null)
 {
     if (!$parent->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");
     }
     if (empty($slug)) {
         $slug = item::convert_filename_to_slug($name);
     }
     $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->slug = $slug;
     $album->rand_key = (double) mt_rand() / (double) mt_getrandmax();
     $album->sort_column = "created";
     $album->sort_order = "ASC";
     // Randomize the name or slug if there's a conflict
     // @todo Improve this.  Random numbers are not user friendly
     while (ORM::factory("item")->where("parent_id", $parent->id)->open_paren()->where("name", $album->name)->orwhere("slug", $album->slug)->close_paren()->find()->id) {
         $rand = rand();
         $album->name = "{$name}-{$rand}";
         $album->slug = "{$slug}-{$rand}";
     }
     $album = $album->add_to_parent($parent);
     mkdir($album->file_path());
     mkdir(dirname($album->thumb_path()));
     mkdir(dirname($album->resize_path()));
     // @todo: publish this from inside Item_Model::save() when we refactor to the point where
     // there's only one save() happening here.
     module::event("item_created", $album);
     return $album;
 }
Beispiel #4
0
 static function upgrade($version)
 {
     $db = Database::instance();
     if ($version == 1) {
         module::set_var("gallery", "date_format", "Y-M-d");
         module::set_var("gallery", "date_time_format", "Y-M-d H:i:s");
         module::set_var("gallery", "time_format", "H:i:s");
         module::set_version("gallery", $version = 2);
     }
     if ($version == 2) {
         module::set_var("gallery", "show_credits", 1);
         module::set_version("gallery", $version = 3);
     }
     if ($version == 3) {
         $db->query("CREATE TABLE {caches} (\n                 `id` varchar(255) NOT NULL,\n                 `tags` varchar(255),\n                 `expiration` int(9) NOT NULL,\n                 `cache` text,\n                 PRIMARY KEY (`id`),\n                 KEY (`tags`))\n                 DEFAULT CHARSET=utf8;");
         module::set_version("gallery", $version = 4);
     }
     if ($version == 4) {
         Cache::instance()->delete_all();
         $db->query("ALTER TABLE {caches} MODIFY COLUMN `cache` LONGBLOB");
         module::set_version("gallery", $version = 5);
     }
     if ($version == 5) {
         Cache::instance()->delete_all();
         $db->query("ALTER TABLE {caches} DROP COLUMN `id`");
         $db->query("ALTER TABLE {caches} ADD COLUMN `key` varchar(255) NOT NULL");
         $db->query("ALTER TABLE {caches} ADD COLUMN `id` int(9) NOT NULL auto_increment PRIMARY KEY");
         module::set_version("gallery", $version = 6);
     }
     if ($version == 6) {
         module::clear_var("gallery", "version");
         module::set_version("gallery", $version = 7);
     }
     if ($version == 7) {
         $groups = identity::groups();
         $permissions = ORM::factory("permission")->find_all();
         foreach ($groups as $group) {
             foreach ($permissions as $permission) {
                 // Update access intents
                 $db->query("ALTER TABLE {access_intents} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) DEFAULT NULL");
                 // Update access cache
                 if ($permission->name === "view") {
                     $db->query("ALTER TABLE {items} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) DEFAULT FALSE");
                 } else {
                     $db->query("ALTER TABLE {access_caches} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) NOT NULL DEFAULT FALSE");
                 }
             }
         }
         module::set_version("gallery", $version = 8);
     }
     if ($version == 8) {
         $db->query("ALTER TABLE {items} CHANGE COLUMN `left`  `left_ptr`  INT(9) NOT NULL;");
         $db->query("ALTER TABLE {items} CHANGE COLUMN `right` `right_ptr` INT(9) NOT NULL;");
         module::set_version("gallery", $version = 9);
     }
     if ($version == 9) {
         $db->query("ALTER TABLE {items} ADD KEY `weight` (`weight` DESC);");
         module::set_version("gallery", $version = 10);
     }
     if ($version == 10) {
         module::set_var("gallery", "image_sharpen", 15);
         module::set_version("gallery", $version = 11);
     }
     if ($version == 11) {
         $db->query("ALTER TABLE {items} ADD COLUMN `relative_url_cache` varchar(255) DEFAULT NULL");
         $db->query("ALTER TABLE {items} ADD COLUMN `slug` varchar(255) DEFAULT NULL");
         // This is imperfect since some of the slugs may contain invalid characters, but it'll do
         // for now because we don't want a lengthy operation here.
         $db->query("UPDATE {items} SET `slug` = `name`");
         // Flush all path caches because we're going to start urlencoding them.
         $db->query("UPDATE {items} SET `relative_url_cache` = NULL, `relative_path_cache` = NULL");
         module::set_version("gallery", $version = 12);
     }
     if ($version == 12) {
         if (module::get_var("gallery", "active_site_theme") == "default") {
             module::set_var("gallery", "active_site_theme", "wind");
         }
         if (module::get_var("gallery", "active_admin_theme") == "admin_default") {
             module::set_var("gallery", "active_admin_theme", "admin_wind");
         }
         module::set_version("gallery", $version = 13);
     }
     if ($version == 13) {
         // Add rules for generating our thumbnails and resizes
         Database::instance()->query("UPDATE {graphics_rules} SET `operation` = CONCAT('gallery_graphics::', `operation`);");
         module::set_version("gallery", $version = 14);
     }
     if ($version == 14) {
         $sidebar_blocks = block_manager::get_active("site_sidebar");
         if (empty($sidebar_blocks)) {
             $available_blocks = block_manager::get_available_site_blocks();
             foreach (array_keys(block_manager::get_available_site_blocks()) as $id) {
                 $sidebar_blocks[] = explode(":", $id);
             }
             block_manager::set_active("site_sidebar", $sidebar_blocks);
         }
         module::set_version("gallery", $version = 15);
     }
     if ($version == 15) {
         module::set_var("gallery", "identity_provider", "user");
         module::set_version("gallery", $version = 16);
     }
     // Convert block keys to an md5 hash of the module and block name
     if ($version == 16) {
         foreach (array("dashboard_sidebar", "dashboard_center", "site_sidebar") as $location) {
             $blocks = block_manager::get_active($location);
             $new_blocks = array();
             foreach ($blocks as $block) {
                 $new_blocks[md5("{$block[0]}:{$block[1]}")] = $block;
             }
             block_manager::set_active($location, $new_blocks);
         }
         module::set_version("gallery", $version = 17);
     }
     // We didn't like md5 hashes so convert block keys back to random keys to allow duplicates.
     if ($version == 17) {
         foreach (array("dashboard_sidebar", "dashboard_center", "site_sidebar") as $location) {
             $blocks = block_manager::get_active($location);
             $new_blocks = array();
             foreach ($blocks as $block) {
                 $new_blocks[random::int()] = $block;
             }
             block_manager::set_active($location, $new_blocks);
         }
         module::set_version("gallery", $version = 18);
     }
     // Rename blocks_site.sidebar to blocks_site_sidebar
     if ($version == 18) {
         $blocks = block_manager::get_active("site.sidebar");
         block_manager::set_active("site_sidebar", $blocks);
         module::clear_var("gallery", "blocks_site.sidebar");
         module::set_version("gallery", $version = 19);
     }
     // Set a default for the number of simultaneous uploads
     // Version 20 was reverted in 57adefc5baa7a2b0dfcd3e736e80c2fa86d3bfa2, so skip it.
     if ($version == 19 || $version == 20) {
         module::set_var("gallery", "simultaneous_upload_limit", 5);
         module::set_version("gallery", $version = 21);
     }
     // Update the graphics rules table so that the maximum height for resizes is 640 not 480.
     // Fixes ticket #671
     if ($version == 21) {
         $resize_rule = ORM::factory("graphics_rule")->where("id", "=", "2")->find();
         // make sure it hasn't been changed already
         $args = unserialize($resize_rule->args);
         if ($args["height"] == 480 && $args["width"] == 640) {
             $args["height"] = 640;
             $resize_rule->args = serialize($args);
             $resize_rule->save();
         }
         module::set_version("gallery", $version = 22);
     }
     // Update slug values to be legal.  We should have done this in the 11->12 upgrader, but I was
     // lazy.  Mea culpa!
     if ($version == 22) {
         foreach (db::build()->from("items")->select("id", "slug")->where(db::expr("`slug` REGEXP '[^_A-Za-z0-9-]'"), "=", 1)->execute() as $row) {
             $new_slug = item::convert_filename_to_slug($row->slug);
             if (empty($new_slug)) {
                 $new_slug = random::int();
             }
             db::build()->update("items")->set("slug", $new_slug)->set("relative_url_cache", null)->where("id", "=", $row->id)->execute();
         }
         module::set_version("gallery", $version = 23);
     }
     if ($version == 23) {
         $db->query("CREATE TABLE {failed_logins} (\n                  `id` int(9) NOT NULL auto_increment,\n                  `count` int(9) NOT NULL,\n                  `name` varchar(255) NOT NULL,\n                  `time` int(9) NOT NULL,\n                  PRIMARY KEY (`id`))\n                  DEFAULT CHARSET=utf8;");
         module::set_version("gallery", $version = 24);
     }
     if ($version == 24) {
         foreach (array("logs", "tmp", "uploads") as $dir) {
             self::_protect_directory(VARPATH . $dir);
         }
         module::set_version("gallery", $version = 25);
     }
     if ($version == 25) {
         db::build()->update("items")->set("title", db::expr("`name`"))->and_open()->where("title", "IS", null)->or_where("title", "=", "")->close()->execute();
         module::set_version("gallery", $version = 26);
     }
     if ($version == 26) {
         if (in_array("failed_logins", Database::instance()->list_tables())) {
             $db->query("RENAME TABLE {failed_logins} TO {failed_auths}");
         }
         module::set_version("gallery", $version = 27);
     }
     if ($version == 27) {
         // Set the admin area timeout to 90 minutes
         module::set_var("gallery", "admin_area_timeout", 90 * 60);
         module::set_version("gallery", $version = 28);
     }
     if ($version == 28) {
         module::set_var("gallery", "credits", "Powered by <a href=\"%url\">%gallery_version</a>");
         module::set_version("gallery", $version = 29);
     }
     if ($version == 29) {
         $db->query("ALTER TABLE {caches} ADD KEY (`key`);");
         module::set_version("gallery", $version = 30);
     }
     if ($version == 30) {
         module::set_var("gallery", "maintenance_mode", 0);
         module::set_version("gallery", $version = 31);
     }
     if ($version == 31) {
         $db->query("ALTER TABLE {modules} ADD COLUMN `weight` int(9) DEFAULT NULL");
         $db->query("ALTER TABLE {modules} ADD KEY (`weight`)");
         db::update("modules")->set("weight", db::expr("`id`"))->execute();
         module::set_version("gallery", $version = 32);
     }
     if ($version == 32) {
         $db->query("ALTER TABLE {items} ADD KEY (`left_ptr`)");
         module::set_version("gallery", $version = 33);
     }
     if ($version == 33) {
         $db->query("ALTER TABLE {access_caches} ADD KEY (`item_id`)");
         module::set_version("gallery", $version = 34);
     }
     if ($version == 34) {
         module::set_var("gallery", "visible_title_length", 15);
         module::set_version("gallery", $version = 35);
     }
     if ($version == 35) {
         module::set_var("gallery", "favicon_url", "lib/images/favicon.ico");
         module::set_version("gallery", $version = 36);
     }
     if ($version == 36) {
         module::set_var("gallery", "email_from", "*****@*****.**");
         module::set_var("gallery", "email_reply_to", "*****@*****.**");
         module::set_var("gallery", "email_line_length", 70);
         module::set_var("gallery", "email_header_separator", serialize("\n"));
         module::set_version("gallery", $version = 37);
     }
     // Changed our minds and decided that the initial value should be empty
     // But don't just reset it blindly, only do it if the value is version 37 default
     if ($version == 37) {
         $email = module::get_var("gallery", "email_from", "");
         if ($email == "*****@*****.**") {
             module::set_var("gallery", "email_from", "");
         }
         $email = module::get_var("gallery", "email_reply_to", "");
         if ($email == "*****@*****.**") {
             module::set_var("gallery", "email_reply_to", "");
         }
         module::set_version("gallery", $version = 38);
     }
     if ($version == 38) {
         module::set_var("gallery", "show_user_profiles_to", "registered_users");
         module::set_version("gallery", $version = 39);
     }
     if ($version == 39) {
         module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin");
         module::set_version("gallery", $version = 40);
     }
     if ($version == 40) {
         module::clear_var("gallery", "_cache");
         module::set_version("gallery", $version = 41);
     }
     if ($version == 41) {
         $db->query("TRUNCATE TABLE {caches}");
         $db->query("ALTER TABLE {caches} DROP INDEX `key`, ADD UNIQUE `key` (`key`)");
         module::set_version("gallery", $version = 42);
     }
     if ($version == 42) {
         $db->query("ALTER TABLE {items} CHANGE `description` `description` text DEFAULT NULL");
         module::set_version("gallery", $version = 43);
     }
     if ($version == 43) {
         $db->query("ALTER TABLE {items} CHANGE `rand_key` `rand_key` DECIMAL(11, 10)");
         module::set_version("gallery", $version = 44);
     }
     if ($version == 44) {
         $db->query("ALTER TABLE {messages} CHANGE `value` `value` text default NULL");
         module::set_version("gallery", $version = 45);
     }
     if ($version == 45) {
         // Splice the upgrade_checker block into the admin dashboard at the top
         // of the page, but under the welcome block if it's in the first position.
         $blocks = block_manager::get_active("dashboard_center");
         $index = count($blocks) && current($blocks) == array("gallery", "welcome") ? 1 : 0;
         array_splice($blocks, $index, 0, array(random::int() => array("gallery", "upgrade_checker")));
         block_manager::set_active("dashboard_center", $blocks);
         module::set_var("gallery", "upgrade_checker_auto_enabled", true);
         module::set_version("gallery", $version = 46);
     }
     if ($version == 46) {
         module::set_var("gallery", "apple_touch_icon_url", "lib/images/apple-touch-icon.png");
         module::set_version("gallery", $version = 47);
     }
     if ($version == 47 || $version == 48) {
         // Add configuration variable to set timezone.  Defaults to the currently
         // used timezone (from PHP configuration).  Note that in v48 we were
         // setting this value incorrectly, so we're going to stomp this value for v49.
         module::set_var("gallery", "timezone", null);
         module::set_version("gallery", $version = 49);
     }
     if ($version == 49) {
         // In v49 we changed the Item_Model validation code to disallow files with two dots in them,
         // but we didn't rename any files which fail to validate, so as soon as you do anything to
         // change those files (eg. as a side effect of getting the url or file path) it fails to
         // validate.  Fix those here.  This might be slow, but if it times out it can just pick up
         // where it left off.
         foreach (db::build()->from("items")->select("id")->where("type", "<>", "album")->where(db::expr("`name` REGEXP '\\\\..*\\\\.'"), "=", 1)->order_by("id", "asc")->execute() as $row) {
             set_time_limit(30);
             $item = ORM::factory("item", $row->id);
             $item->name = legal_file::smash_extensions($item->name);
             $item->save();
         }
         module::set_version("gallery", $version = 50);
     }
     if ($version == 50) {
         // In v51, we added a lock_timeout variable so that administrators could edit the time out
         // from 1 second to a higher variable if their system runs concurrent parallel uploads for
         // instance.
         module::set_var("gallery", "lock_timeout", 1);
         module::set_version("gallery", $version = 51);
     }
     if ($version == 51) {
         // In v52, we added functions to the legal_file helper that map photo and movie file
         // extensions to their mime types (and allow extension of the list by other modules).  During
         // this process, we correctly mapped m4v files to video/x-m4v, correcting a previous error
         // where they were mapped to video/mp4.  This corrects the existing items.
         db::build()->update("items")->set("mime_type", "video/x-m4v")->where("name", "REGEXP", "\\.m4v\$")->execute();
         module::set_version("gallery", $version = 52);
     }
     if ($version == 52) {
         // In v53, we added the ability to change the default time used when extracting frames from
         // movies.  Previously we hard-coded this at 3 seconds, so we use that as the default.
         module::set_var("gallery", "movie_extract_frame_time", 3);
         module::set_version("gallery", $version = 53);
     }
     if ($version == 53) {
         // In v54, we changed how we check for name and slug conflicts in Item_Model.  Previously,
         // we checked the whole filename.  As a result, "foo.jpg" and "foo.png" were not considered
         // conflicting if their slugs were different (a rare case in practice since server_add and
         // uploader would give them both the same slug "foo").  Now, we check the filename without its
         // extension.  This upgrade stanza fixes any conflicts where they were previously allowed.
         // This might be slow, but if it times out it can just pick up where it left off.
         // Find and loop through each conflict (e.g. "foo.jpg", "foo.png", and "foo.flv" are one
         // conflict; "bar.jpg", "bar.png", and "bar.flv" are another)
         foreach (db::build()->select_distinct(array("parent_base_name" => db::expr("CONCAT(`parent_id`, ':', LOWER(SUBSTR(`name`, 1, LOCATE('.', `name`) - 1)))")))->select(array("C" => "COUNT(\"*\")"))->from("items")->where("type", "<>", "album")->having("C", ">", 1)->group_by("parent_base_name")->execute() as $conflict) {
             list($parent_id, $base_name) = explode(":", $conflict->parent_base_name, 2);
             $base_name_escaped = Database::escape_for_like($base_name);
             // Loop through the items for each conflict
             foreach (db::build()->from("items")->select("id")->where("type", "<>", "album")->where("parent_id", "=", $parent_id)->where("name", "LIKE", "{$base_name_escaped}.%")->limit(1000000)->offset(1)->execute() as $row) {
                 set_time_limit(30);
                 $item = ORM::factory("item", $row->id);
                 $item->name = $item->name;
                 // this will force Item_Model to check for conflicts on save
                 $item->save();
             }
         }
         module::set_version("gallery", $version = 54);
     }
     if ($version == 54) {
         $db->query("ALTER TABLE {items} ADD KEY `relative_path_cache` (`relative_path_cache`)");
         module::set_version("gallery", $version = 55);
     }
     if ($version == 55) {
         // In v56, we added the ability to change the default behavior regarding movie uploads.  It
         // can be set to "always", "never", or "autodetect" to match the previous behavior where they
         // are allowed only if FFmpeg is found.
         module::set_var("gallery", "movie_allow_uploads", "autodetect");
         module::set_version("gallery", $version = 56);
     }
     if ($version == 56) {
         // Cleanup possible instances where resize_dirty of albums or movies was set to 0.  This is
         // unlikely to have occurred, and doesn't currently matter much since albums and movies don't
         // have resize images anyway.  However, it may be useful to be consistent here going forward.
         db::build()->update("items")->set("resize_dirty", 1)->where("type", "<>", "photo")->execute();
         module::set_version("gallery", $version = 57);
     }
     if ($version == 57) {
         // In v58 we changed the Item_Model validation code to disallow files or directories with
         // backslashes in them, and we need to fix any existing items that have them.  This is
         // pretty unlikely, as having backslashes would have probably already caused other issues for
         // users, but we should check anyway.  This might be slow, but if it times out it can just
         // pick up where it left off.
         foreach (db::build()->from("items")->select("id")->where(db::expr("`name` REGEXP '\\\\\\\\'"), "=", 1)->order_by("id", "asc")->execute() as $row) {
             set_time_limit(30);
             $item = ORM::factory("item", $row->id);
             $item->name = str_replace("\\", "_", $item->name);
             $item->save();
         }
         module::set_version("gallery", $version = 58);
     }
 }
Beispiel #5
0
 static function upgrade($version)
 {
     $db = Database::instance();
     if ($version == 1) {
         module::set_var("gallery", "date_format", "Y-M-d");
         module::set_var("gallery", "date_time_format", "Y-M-d H:i:s");
         module::set_var("gallery", "time_format", "H:i:s");
         module::set_version("gallery", $version = 2);
     }
     if ($version == 2) {
         module::set_var("gallery", "show_credits", 1);
         module::set_version("gallery", $version = 3);
     }
     if ($version == 3) {
         $db->query("CREATE TABLE {caches} (\n                 `id` varchar(255) NOT NULL,\n                 `tags` varchar(255),\n                 `expiration` int(9) NOT NULL,\n                 `cache` text,\n                 PRIMARY KEY (`id`),\n                 KEY (`tags`))\n                 DEFAULT CHARSET=utf8;");
         module::set_version("gallery", $version = 4);
     }
     if ($version == 4) {
         Cache::instance()->delete_all();
         $db->query("ALTER TABLE {caches} MODIFY COLUMN `cache` LONGBLOB");
         module::set_version("gallery", $version = 5);
     }
     if ($version == 5) {
         Cache::instance()->delete_all();
         $db->query("ALTER TABLE {caches} DROP COLUMN `id`");
         $db->query("ALTER TABLE {caches} ADD COLUMN `key` varchar(255) NOT NULL");
         $db->query("ALTER TABLE {caches} ADD COLUMN `id` int(9) NOT NULL auto_increment PRIMARY KEY");
         module::set_version("gallery", $version = 6);
     }
     if ($version == 6) {
         module::clear_var("gallery", "version");
         module::set_version("gallery", $version = 7);
     }
     if ($version == 7) {
         $groups = identity::groups();
         $permissions = ORM::factory("permission")->find_all();
         foreach ($groups as $group) {
             foreach ($permissions as $permission) {
                 // Update access intents
                 $db->query("ALTER TABLE {access_intents} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) DEFAULT NULL");
                 // Update access cache
                 if ($permission->name === "view") {
                     $db->query("ALTER TABLE {items} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) DEFAULT FALSE");
                 } else {
                     $db->query("ALTER TABLE {access_caches} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) NOT NULL DEFAULT FALSE");
                 }
             }
         }
         module::set_version("gallery", $version = 8);
     }
     if ($version == 8) {
         $db->query("ALTER TABLE {items} CHANGE COLUMN `left`  `left_ptr`  INT(9) NOT NULL;");
         $db->query("ALTER TABLE {items} CHANGE COLUMN `right` `right_ptr` INT(9) NOT NULL;");
         module::set_version("gallery", $version = 9);
     }
     if ($version == 9) {
         $db->query("ALTER TABLE {items} ADD KEY `weight` (`weight` DESC);");
         module::set_version("gallery", $version = 10);
     }
     if ($version == 10) {
         module::set_var("gallery", "image_sharpen", 15);
         module::set_version("gallery", $version = 11);
     }
     if ($version == 11) {
         $db->query("ALTER TABLE {items} ADD COLUMN `relative_url_cache` varchar(255) DEFAULT NULL");
         $db->query("ALTER TABLE {items} ADD COLUMN `slug` varchar(255) DEFAULT NULL");
         // This is imperfect since some of the slugs may contain invalid characters, but it'll do
         // for now because we don't want a lengthy operation here.
         $db->query("UPDATE {items} SET `slug` = `name`");
         // Flush all path caches becuase we're going to start urlencoding them.
         $db->query("UPDATE {items} SET `relative_url_cache` = NULL, `relative_path_cache` = NULL");
         module::set_version("gallery", $version = 12);
     }
     if ($version == 12) {
         if (module::get_var("gallery", "active_site_theme") == "default") {
             module::set_var("gallery", "active_site_theme", "wind");
         }
         if (module::get_var("gallery", "active_admin_theme") == "admin_default") {
             module::set_var("gallery", "active_admin_theme", "admin_wind");
         }
         module::set_version("gallery", $version = 13);
     }
     if ($version == 13) {
         // Add rules for generating our thumbnails and resizes
         Database::instance()->query("UPDATE {graphics_rules} SET `operation` = CONCAT('gallery_graphics::', `operation`);");
         module::set_version("gallery", $version = 14);
     }
     if ($version == 14) {
         $sidebar_blocks = block_manager::get_active("site_sidebar");
         if (empty($sidebar_blocks)) {
             $available_blocks = block_manager::get_available_site_blocks();
             foreach (array_keys(block_manager::get_available_site_blocks()) as $id) {
                 $sidebar_blocks[] = explode(":", $id);
             }
             block_manager::set_active("site_sidebar", $sidebar_blocks);
         }
         module::set_version("gallery", $version = 15);
     }
     if ($version == 15) {
         module::set_var("gallery", "identity_provider", "user");
         module::set_version("gallery", $version = 16);
     }
     // Convert block keys to an md5 hash of the module and block name
     if ($version == 16) {
         foreach (array("dashboard_sidebar", "dashboard_center", "site_sidebar") as $location) {
             $blocks = block_manager::get_active($location);
             $new_blocks = array();
             foreach ($blocks as $block) {
                 $new_blocks[md5("{$block[0]}:{$block[1]}")] = $block;
             }
             block_manager::set_active($location, $new_blocks);
         }
         module::set_version("gallery", $version = 17);
     }
     // We didn't like md5 hashes so convert block keys back to random keys to allow duplicates.
     if ($version == 17) {
         foreach (array("dashboard_sidebar", "dashboard_center", "site_sidebar") as $location) {
             $blocks = block_manager::get_active($location);
             $new_blocks = array();
             foreach ($blocks as $block) {
                 $new_blocks[random::int()] = $block;
             }
             block_manager::set_active($location, $new_blocks);
         }
         module::set_version("gallery", $version = 18);
     }
     // Rename blocks_site.sidebar to blocks_site_sidebar
     if ($version == 18) {
         $blocks = block_manager::get_active("site.sidebar");
         block_manager::set_active("site_sidebar", $blocks);
         module::clear_var("gallery", "blocks_site.sidebar");
         module::set_version("gallery", $version = 19);
     }
     // Set a default for the number of simultaneous uploads
     // Version 20 was reverted in 57adefc5baa7a2b0dfcd3e736e80c2fa86d3bfa2, so skip it.
     if ($version == 19 || $version == 20) {
         module::set_var("gallery", "simultaneous_upload_limit", 5);
         module::set_version("gallery", $version = 21);
     }
     // Update the graphics rules table so that the maximum height for resizes is 640 not 480.
     // Fixes ticket #671
     if ($version == 21) {
         $resize_rule = ORM::factory("graphics_rule")->where("id", "=", "2")->find();
         // make sure it hasn't been changed already
         $args = unserialize($resize_rule->args);
         if ($args["height"] == 480 && $args["width"] == 640) {
             $args["height"] = 640;
             $resize_rule->args = serialize($args);
             $resize_rule->save();
         }
         module::set_version("gallery", $version = 22);
     }
     // Update slug values to be legal.  We should have done this in the 11->12 upgrader, but I was
     // lazy.  Mea culpa!
     if ($version == 22) {
         foreach (db::build()->from("items")->select("id", "slug")->where(db::expr("`slug` REGEXP '[^_A-Za-z0-9-]'"), "=", 1)->execute() as $row) {
             $new_slug = item::convert_filename_to_slug($row->slug);
             if (empty($new_slug)) {
                 $new_slug = random::int();
             }
             db::build()->update("items")->set("slug", $new_slug)->set("relative_url_cache", null)->where("id", "=", $row->id)->execute();
         }
         module::set_version("gallery", $version = 23);
     }
     if ($version == 23) {
         $db->query("CREATE TABLE {failed_logins} (\n                  `id` int(9) NOT NULL auto_increment,\n                  `count` int(9) NOT NULL,\n                  `name` varchar(255) NOT NULL,\n                  `time` int(9) NOT NULL,\n                  PRIMARY KEY (`id`))\n                  DEFAULT CHARSET=utf8;");
         module::set_version("gallery", $version = 24);
     }
     if ($version == 24) {
         foreach (array("logs", "tmp", "uploads") as $dir) {
             self::_protect_directory(VARPATH . $dir);
         }
         module::set_version("gallery", $version = 25);
     }
     if ($version == 25) {
         db::build()->update("items")->set("title", db::expr("`name`"))->and_open()->where("title", "IS", null)->or_where("title", "=", "")->close()->execute();
         module::set_version("gallery", $version = 26);
     }
     if ($version == 26) {
         if (in_array("failed_logins", Database::instance()->list_tables())) {
             $db->query("RENAME TABLE {failed_logins} TO {failed_auths}");
         }
         module::set_version("gallery", $version = 27);
     }
     if ($version == 27) {
         // Set the admin area timeout to 90 minutes
         module::set_var("gallery", "admin_area_timeout", 90 * 60);
         module::set_version("gallery", $version = 28);
     }
     if ($version == 28) {
         module::set_var("gallery", "credits", "Powered by <a href=\"%url\">%gallery_version</a>");
         module::set_version("gallery", $version = 29);
     }
     if ($version == 29) {
         $db->query("ALTER TABLE {caches} ADD KEY (`key`);");
         module::set_version("gallery", $version = 30);
     }
     if ($version == 30) {
         module::set_var("gallery", "maintenance_mode", 0);
         module::set_version("gallery", $version = 31);
     }
     if ($version == 31) {
         $db->query("ALTER TABLE {modules} ADD COLUMN `weight` int(9) DEFAULT NULL");
         $db->query("ALTER TABLE {modules} ADD KEY (`weight`)");
         db::update("modules")->set("weight", db::expr("`id`"))->execute();
         module::set_version("gallery", $version = 32);
     }
     if ($version == 32) {
         $db->query("ALTER TABLE {items} ADD KEY (`left_ptr`)");
         module::set_version("gallery", $version = 33);
     }
     if ($version == 33) {
         $db->query("ALTER TABLE {access_caches} ADD KEY (`item_id`)");
         module::set_version("gallery", $version = 34);
     }
     if ($version == 34) {
         module::set_var("gallery", "visible_title_length", 15);
         module::set_version("gallery", $version = 35);
     }
     if ($version == 35) {
         module::set_var("gallery", "favicon_url", "lib/images/favicon.ico");
         module::set_version("gallery", $version = 36);
     }
     if ($version == 36) {
         module::set_var("gallery", "email_from", "*****@*****.**");
         module::set_var("gallery", "email_reply_to", "*****@*****.**");
         module::set_var("gallery", "email_line_length", 70);
         module::set_var("gallery", "email_header_separator", serialize("\n"));
         module::set_version("gallery", $version = 37);
     }
     // Changed our minds and decided that the initial value should be empty
     // But don't just reset it blindly, only do it if the value is version 37 default
     if ($version == 37) {
         $email = module::get_var("gallery", "email_from", "");
         if ($email == "*****@*****.**") {
             module::set_var("gallery", "email_from", "");
         }
         $email = module::get_var("gallery", "email_reply_to", "");
         if ($email == "*****@*****.**") {
             module::set_var("gallery", "email_reply_to", "");
         }
         module::set_version("gallery", $version = 38);
     }
     if ($version == 38) {
         module::set_var("gallery", "show_user_profiles_to", "registered_users");
         module::set_version("gallery", $version = 39);
     }
     if ($version == 39) {
         module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin");
         module::set_version("gallery", $version = 40);
     }
     if ($version == 40) {
         module::clear_var("gallery", "_cache");
         module::set_version("gallery", $version = 41);
     }
     if ($version == 41) {
         $db->query("TRUNCATE TABLE {caches}");
         $db->query("ALTER TABLE {caches} DROP INDEX `key`, ADD UNIQUE `key` (`key`)");
         module::set_version("gallery", $version = 42);
     }
     if ($version == 42) {
         $db->query("ALTER TABLE {items} CHANGE `description` `description` text DEFAULT NULL");
         module::set_version("gallery", $version = 43);
     }
     if ($version == 43) {
         $db->query("ALTER TABLE {items} CHANGE `rand_key` `rand_key` DECIMAL(11, 10)");
         module::set_version("gallery", $version = 44);
     }
     if ($version == 44) {
         $db->query("ALTER TABLE {messages} CHANGE `value` `value` text default NULL");
         module::set_version("gallery", $version = 45);
     }
     if ($version == 45) {
         // Splice the upgrade_checker block into the admin dashboard at the top
         // of the page, but under the welcome block if it's in the first position.
         $blocks = block_manager::get_active("dashboard_center");
         $index = count($blocks) && current($blocks) == array("gallery", "welcome") ? 1 : 0;
         array_splice($blocks, $index, 0, array(random::int() => array("gallery", "upgrade_checker")));
         block_manager::set_active("dashboard_center", $blocks);
         module::set_var("gallery", "upgrade_checker_auto_enabled", true);
         module::set_version("gallery", $version = 46);
     }
 }
Beispiel #6
0
 /**
  * Handle any business logic necessary to create or modify an item.
  * @see ORM::save()
  *
  * @return ORM Item_Model
  */
 public function save()
 {
     $significant_changes = $this->changed;
     unset($significant_changes["view_count"]);
     unset($significant_changes["relative_url_cache"]);
     unset($significant_changes["relative_path_cache"]);
     if (!empty($this->changed) && $significant_changes || isset($this->data_file)) {
         $this->updated = time();
         if (!$this->loaded()) {
             // Create a new item.
             module::event("item_before_create", $this);
             // Set a weight if it's missing.  We don't do this in the constructor because it's not a
             // simple assignment.
             if (empty($this->weight)) {
                 $this->weight = item::get_max_weight();
             }
             // Make an url friendly slug from the name, if necessary
             if (empty($this->slug)) {
                 $this->slug = item::convert_filename_to_slug(pathinfo($this->name, PATHINFO_FILENAME));
                 // If the filename is all invalid characters, then the slug may be empty here.  Pick a
                 // random value.
                 if (empty($this->slug)) {
                     $this->slug = (string) rand(1000, 9999);
                 }
             }
             // Get the width, height and mime type from our data file for photos and movies.
             if ($this->is_photo() || $this->is_movie()) {
                 if ($this->is_photo()) {
                     list($this->width, $this->height, $this->mime_type, $extension) = photo::get_file_metadata($this->data_file);
                 } else {
                     if ($this->is_movie()) {
                         list($this->width, $this->height, $this->mime_type, $extension) = movie::get_file_metadata($this->data_file);
                     }
                 }
                 // Force an extension onto the name if necessary
                 $pi = pathinfo($this->data_file);
                 if (empty($pi["extension"])) {
                     $this->name = "{$this->name}.{$extension}";
                 }
             }
             $this->_randomize_name_or_slug_on_conflict();
             parent::save();
             // Build our url caches, then save again.  We have to do this after it's already been
             // saved once because we use only information from the database to build the paths.  If we
             // could depend on a save happening later we could defer this 2nd save.
             $this->_build_relative_caches();
             parent::save();
             // Take any actions that we can only do once all our paths are set correctly after saving.
             switch ($this->type) {
                 case "album":
                     mkdir($this->file_path());
                     mkdir(dirname($this->thumb_path()));
                     mkdir(dirname($this->resize_path()));
                     break;
                 case "photo":
                 case "movie":
                     // The thumb or resize may already exist in the case where a movie and a photo generate
                     // a thumbnail of the same name (eg, foo.flv movie and foo.jpg photo will generate
                     // foo.jpg thumbnail).  If that happens, randomize and save again.
                     if (file_exists($this->resize_path()) || file_exists($this->thumb_path())) {
                         $pi = pathinfo($this->name);
                         $this->name = $pi["filename"] . "-" . random::int() . "." . $pi["extension"];
                         parent::save();
                     }
                     copy($this->data_file, $this->file_path());
                     break;
             }
             // This will almost definitely trigger another save, so put it at the end so that we're
             // tail recursive.  Null out the data file variable first, otherwise the next save will
             // trigger an item_updated_data_file event.
             $this->data_file = null;
             module::event("item_created", $this);
         } else {
             // Update an existing item
             module::event("item_before_update", $item);
             // If any significant fields have changed, load up a copy of the original item and
             // keep it around.
             $original = ORM::factory("item", $this->id);
             // Preserve the extension of the data file. Many helpers, (e.g. ImageMagick), assume
             // the MIME type from the extension. So when we adopt the new data file, it's important
             // to adopt the new extension. That ensures that the item's extension is always
             // appropriate for its data. We don't try to preserve the name of the data file, though,
             // because the name is typically a temporary randomly-generated name.
             if (isset($this->data_file)) {
                 $extension = pathinfo($this->data_file, PATHINFO_EXTENSION);
                 $new_name = pathinfo($this->name, PATHINFO_FILENAME) . ".{$extension}";
                 if (!empty($extension) && strcmp($this->name, $new_name)) {
                     $this->name = $new_name;
                 }
                 if ($this->is_photo()) {
                     list($this->width, $this->height, $this->mime_type, $extension) = photo::get_file_metadata($this->data_file);
                 } else {
                     if ($this->is_movie()) {
                         list($this->width, $this->height, $this->mime_type, $extension) = movie::get_file_metadata($this->data_file);
                     }
                 }
             }
             if (array_intersect($this->changed, array("parent_id", "name", "slug"))) {
                 $original->_build_relative_caches();
                 $this->relative_path_cache = null;
                 $this->relative_url_cache = null;
             }
             $this->_randomize_name_or_slug_on_conflict();
             parent::save();
             // Now update the filesystem and any database caches if there were significant value
             // changes.  If anything past this point fails, then we'll have an inconsistent database
             // so this code should be as robust as we can make it.
             // Update the MPTT pointers, if necessary.  We have to do this before we generate any
             // cached paths!
             if ($original->parent_id != $this->parent_id) {
                 parent::move_to($this->parent());
             }
             if ($original->parent_id != $this->parent_id || $original->name != $this->name) {
                 $this->_build_relative_caches();
                 // If there is a data file, then we want to preserve both the old data and the new data.
                 // (Third-party event handlers would like access to both). The old data file will be
                 // accessible via the $original item, and the new one via $this item. But in that case,
                 // we don't want to rename the original as below, because the old data would end up being
                 // clobbered by the new data file. Also, the rename isn't necessary, because the new item
                 // data is coming from the data file anyway. So we only perform the rename if there isn't
                 // a data file. Another way to solve this would be to copy the original file rather than
                 // conditionally rename it, but a copy would cost far more than the rename.
                 if (!isset($this->data_file)) {
                     @rename($original->file_path(), $this->file_path());
                 }
                 // Move all of the items associated data files
                 if ($this->is_album()) {
                     @rename(dirname($original->resize_path()), dirname($this->resize_path()));
                     @rename(dirname($original->thumb_path()), dirname($this->thumb_path()));
                 } else {
                     @rename($original->resize_path(), $this->resize_path());
                     @rename($original->thumb_path(), $this->thumb_path());
                 }
                 if ($original->parent_id != $this->parent_id) {
                     // This will result in 2 events since we'll still fire the item_updated event below
                     module::event("item_moved", $this, $original->parent());
                 }
             }
             // Changing the name, slug or parent ripples downwards
             if ($this->is_album() && ($original->name != $this->name || $original->slug != $this->slug || $original->parent_id != $this->parent_id)) {
                 db::build()->update("items")->set("relative_url_cache", null)->set("relative_path_cache", null)->where("left_ptr", ">", $this->left_ptr)->where("right_ptr", "<", $this->right_ptr)->execute();
             }
             // Replace the data file, if requested.
             if ($this->data_file && ($this->is_photo() || $this->is_movie())) {
                 copy($this->data_file, $this->file_path());
                 // Get the width, height and mime type from our data file for photos and movies.
                 if ($this->is_photo()) {
                     list($this->width, $this->height) = photo::get_file_metadata($this->file_path());
                 } else {
                     if ($this->is_movie()) {
                         list($this->width, $this->height) = movie::get_file_metadata($this->file_path());
                     }
                 }
                 $this->thumb_dirty = 1;
                 $this->resize_dirty = 1;
             }
             module::event("item_updated", $original, $this);
             if ($this->data_file) {
                 // Null out the data file variable here, otherwise this event will trigger another
                 // save() which will think that we're doing another file move.
                 $this->data_file = null;
                 if ($original->file_path() != $this->file_path()) {
                     @unlink($original->file_path());
                 }
                 module::event("item_updated_data_file", $this);
             }
         }
     } else {
         if (!empty($this->changed)) {
             // Insignificant changes only.  Don't fire events or do any special checking to try to keep
             // this lightweight.
             parent::save();
         }
     }
     return $this;
 }
Beispiel #7
0
 /**
  * Create a new photo.
  * @param integer $parent_id id of parent album
  * @param string  $filename path to the photo file on disk
  * @param string  $name the filename to use for this photo in the album
  * @param integer $title the title of the new photo
  * @param string  $description (optional) the longer description of this photo
  * @param string  $slug (optional) the url component for this photo
  * @return Item_Model
  */
 static function create($parent, $filename, $name, $title, $description = null, $owner_id = null, $slug = null)
 {
     if (!$parent->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");
     }
     if (filesize($filename) == 0) {
         throw new Exception("@todo EMPTY_INPUT_FILE");
     }
     $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"];
     }
     if (empty($slug)) {
         $slug = item::convert_filename_to_slug($name);
     }
     $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->slug = $slug;
     $photo->rand_key = (double) mt_rand() / (double) mt_getrandmax();
     // Randomize the name or slug if there's a conflict
     // @todo Improve this.  Random numbers are not user friendly
     while (ORM::factory("item")->where("parent_id", $parent->id)->open_paren()->where("name", $photo->name)->orwhere("slug", $photo->slug)->close_paren()->find()->id) {
         $rand = rand();
         $photo->name = "{$name}.{$rand}.{$pi['extension']}";
         $photo->slug = "{$slug}-{$rand}";
     }
     // 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());
     // @todo: publish this from inside Item_Model::save() when we refactor to the point where
     // there's only one save() happening here.
     module::event("item_created", $photo);
     // Build our thumbnail/resizes.  If we fail to build thumbnail/resize we assume that the image
     // is bad in some way and discard it.
     try {
         graphics::generate($photo);
     } catch (Exception $e) {
         $photo->delete();
         throw $e;
     }
     // 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;
 }
Beispiel #8
0
 /**
  * Create a new movie.
  * @param integer $parent_id id of parent album
  * @param string  $filename path to the photo file on disk
  * @param string  $name the filename to use for this photo in the album
  * @param integer $title the title of the new photo
  * @param string  $description (optional) the longer description of this photo
  * @param string  $slug (optional) the url component for this photo
  * @return Item_Model
  */
 static function create($parent, $filename, $name, $title, $description = null, $owner_id = null, $slug = null)
 {
     if (!$parent->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");
     }
     try {
         $movie_info = movie::getmoviesize($filename);
     } catch (Exception $e) {
         // Assuming this is MISSING_FFMPEG for now
         $movie_info = getimagesize(MODPATH . "gallery/images/missing_movie.png");
     }
     // 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"];
     }
     if (empty($slug)) {
         $slug = item::convert_filename_to_slug($name);
     }
     $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->slug = $slug;
     $movie->rand_key = (double) mt_rand() / (double) mt_getrandmax();
     // Randomize the name if there's a conflict
     // @todo Improve this.  Random numbers are not user friendly
     while (ORM::factory("item")->where("parent_id", $parent->id)->open_paren()->where("name", $movie->name)->orwhere("slug", $movie->slug)->close_paren()->find()->id) {
         $rand = rand();
         $movie->name = "{$name}.{$rand}.{$pi['extension']}";
         $movie->slug = "{$slug}-{$rand}";
     }
     // 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());
     // @todo: publish this from inside Item_Model::save() when we refactor to the point where
     // there's only one save() happening here.
     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;
 }
Beispiel #9
0
 /**
  * Handle any business logic necessary to create or modify an item.
  * @see ORM::save()
  *
  * @return ORM Item_Model
  */
 public function save()
 {
     $significant_changes = $this->changed;
     foreach (array("view_count", "relative_url_cache", "relative_path_cache", "resize_width", "resize_height", "resize_dirty", "thumb_width", "thumb_height", "thumb_dirty") as $key) {
         unset($significant_changes[$key]);
     }
     if (!empty($this->changed) && $significant_changes || isset($this->data_file)) {
         $this->updated = time();
         if (!$this->loaded()) {
             // Create a new item.
             module::event("item_before_create", $this);
             // Set a weight if it's missing.  We don't do this in the constructor because it's not a
             // simple assignment.
             if (empty($this->weight)) {
                 $this->weight = item::get_max_weight();
             }
             if ($this->is_album()) {
                 // Sanitize the album name.
                 $this->name = legal_file::sanitize_dirname($this->name);
             } else {
                 // Process the data file info.  This also sanitizes the item name.
                 if (isset($this->data_file)) {
                     $this->_process_data_file_info();
                 } else {
                     // New photos and movies must have a data file.
                     $this->data_file_error = true;
                 }
             }
             // Make an url friendly slug from the name, if necessary
             if (empty($this->slug)) {
                 $this->slug = item::convert_filename_to_slug(pathinfo($this->name, PATHINFO_FILENAME));
                 // If the filename is all invalid characters, then the slug may be empty here.  We set a
                 // generic name ("photo", "movie", or "album") based on its type, then rely on
                 // check_and_fix_conflicts to ensure it doesn't conflict with another name.
                 if (empty($this->slug)) {
                     $this->slug = $this->type;
                 }
             }
             $this->_check_and_fix_conflicts();
             parent::save();
             // Build our url caches, then save again.  We have to do this after it's already been
             // saved once because we use only information from the database to build the paths.  If we
             // could depend on a save happening later we could defer this 2nd save.
             $this->_build_relative_caches();
             parent::save();
             // Take any actions that we can only do once all our paths are set correctly after saving.
             switch ($this->type) {
                 case "album":
                     mkdir($this->file_path());
                     mkdir(dirname($this->thumb_path()));
                     mkdir(dirname($this->resize_path()));
                     break;
                 case "photo":
                 case "movie":
                     copy($this->data_file, $this->file_path());
                     break;
             }
             // This will almost definitely trigger another save, so put it at the end so that we're
             // tail recursive.  Null out the data file variable first, otherwise the next save will
             // trigger an item_updated_data_file event.
             $this->data_file = null;
             module::event("item_created", $this);
         } else {
             // Update an existing item
             module::event("item_before_update", $this);
             // If any significant fields have changed, load up a copy of the original item and
             // keep it around.
             $original = ORM::factory("item", $this->id);
             // If we have a new data file, process its info.  This will get its metadata and
             // preserve the extension of the data file. Many helpers, (e.g. ImageMagick), assume
             // the MIME type from the extension. So when we adopt the new data file, it's important
             // to adopt the new extension. That ensures that the item's extension is always
             // appropriate for its data. We don't try to preserve the name of the data file, though,
             // because the name is typically a temporary randomly-generated name.
             if (isset($this->data_file)) {
                 $this->_process_data_file_info();
             } else {
                 if (!$this->is_album() && array_key_exists("name", $this->changed)) {
                     // There's no new data file, but the name changed.  If it's a photo or movie,
                     // make sure the new name still agrees with the file type.
                     $this->name = legal_file::sanitize_filename($this->name, pathinfo($original->name, PATHINFO_EXTENSION), $this->type);
                 }
             }
             // If an album's name changed, sanitize it.
             if ($this->is_album() && array_key_exists("name", $this->changed)) {
                 $this->name = legal_file::sanitize_dirname($this->name);
             }
             // If an album's cover has changed (or been removed), delete any existing album cover,
             // reset the thumb metadata, and mark the thumb as dirty.
             if (array_key_exists("album_cover_item_id", $this->changed) && $this->is_album()) {
                 @unlink($original->thumb_path());
                 $this->thumb_dirty = 1;
                 $this->thumb_height = 0;
                 $this->thumb_width = 0;
             }
             if (array_intersect($this->changed, array("parent_id", "name", "slug"))) {
                 $original->_build_relative_caches();
                 $this->relative_path_cache = null;
                 $this->relative_url_cache = null;
             }
             $this->_check_and_fix_conflicts();
             parent::save();
             // Now update the filesystem and any database caches if there were significant value
             // changes.  If anything past this point fails, then we'll have an inconsistent database
             // so this code should be as robust as we can make it.
             // Update the MPTT pointers, if necessary.  We have to do this before we generate any
             // cached paths!
             if ($original->parent_id != $this->parent_id) {
                 parent::move_to($this->parent());
             }
             if ($original->parent_id != $this->parent_id || $original->name != $this->name) {
                 $this->_build_relative_caches();
                 // If there is a data file, then we want to preserve both the old data and the new data.
                 // (Third-party event handlers would like access to both). The old data file will be
                 // accessible via the $original item, and the new one via $this item. But in that case,
                 // we don't want to rename the original as below, because the old data would end up being
                 // clobbered by the new data file. Also, the rename isn't necessary, because the new item
                 // data is coming from the data file anyway. So we only perform the rename if there isn't
                 // a data file. Another way to solve this would be to copy the original file rather than
                 // conditionally rename it, but a copy would cost far more than the rename.
                 if (!isset($this->data_file)) {
                     @rename($original->file_path(), $this->file_path());
                 }
                 // Move all of the items associated data files
                 if ($this->is_album()) {
                     @rename(dirname($original->resize_path()), dirname($this->resize_path()));
                     @rename(dirname($original->thumb_path()), dirname($this->thumb_path()));
                 } else {
                     @rename($original->resize_path(), $this->resize_path());
                     @rename($original->thumb_path(), $this->thumb_path());
                 }
             }
             // Changing the name, slug or parent ripples downwards
             if ($this->is_album() && ($original->name != $this->name || $original->slug != $this->slug || $original->parent_id != $this->parent_id)) {
                 db::build()->update("items")->set("relative_url_cache", null)->set("relative_path_cache", null)->where("left_ptr", ">", $this->left_ptr)->where("right_ptr", "<", $this->right_ptr)->execute();
             }
             // Replace the data file, if requested.
             if ($this->data_file && ($this->is_photo() || $this->is_movie())) {
                 copy($this->data_file, $this->file_path());
                 $this->thumb_dirty = 1;
                 $this->resize_dirty = 1;
             }
             if ($original->parent_id != $this->parent_id) {
                 // This will result in 2 events since we'll still fire the item_updated event below
                 module::event("item_moved", $this, $original->parent());
             }
             module::event("item_updated", $original, $this);
             if ($this->data_file) {
                 // Null out the data file variable here, otherwise this event will trigger another
                 // save() which will think that we're doing another file move.
                 $this->data_file = null;
                 if ($original->file_path() != $this->file_path()) {
                     @unlink($original->file_path());
                 }
                 module::event("item_updated_data_file", $this);
             }
         }
     } else {
         if (!empty($this->changed)) {
             // Insignificant changes only.  Don't fire events or do any special checking to try to keep
             // this lightweight.
             parent::save();
         }
     }
     return $this;
 }
Beispiel #10
0
 static function upgrade($version)
 {
     $db = Database::instance();
     if ($version == 1) {
         module::set_var("gallery", "date_format", "Y-M-d");
         module::set_var("gallery", "date_time_format", "Y-M-d H:i:s");
         module::set_var("gallery", "time_format", "H:i:s");
         module::set_version("gallery", $version = 2);
     }
     if ($version == 2) {
         module::set_var("gallery", "show_credits", 1);
         module::set_version("gallery", $version = 3);
     }
     if ($version == 3) {
         $db->query("CREATE TABLE {caches} (\n                 `id` varchar(255) NOT NULL,\n                 `tags` varchar(255),\n                 `expiration` int(9) NOT NULL,\n                 `cache` text,\n                 PRIMARY KEY (`id`),\n                 KEY (`tags`))\n                 DEFAULT CHARSET=utf8;");
         module::set_version("gallery", $version = 4);
     }
     if ($version == 4) {
         Cache::instance()->delete_all();
         $db->query("ALTER TABLE {caches} MODIFY COLUMN `cache` LONGBLOB");
         module::set_version("gallery", $version = 5);
     }
     if ($version == 5) {
         Cache::instance()->delete_all();
         $db->query("ALTER TABLE {caches} DROP COLUMN `id`");
         $db->query("ALTER TABLE {caches} ADD COLUMN `key` varchar(255) NOT NULL");
         $db->query("ALTER TABLE {caches} ADD COLUMN `id` int(9) NOT NULL auto_increment PRIMARY KEY");
         module::set_version("gallery", $version = 6);
     }
     if ($version == 6) {
         module::clear_var("gallery", "version");
         module::set_version("gallery", $version = 7);
     }
     if ($version == 7) {
         $groups = identity::groups();
         $permissions = ORM::factory("permission")->find_all();
         foreach ($groups as $group) {
             foreach ($permissions as $permission) {
                 // Update access intents
                 $db->query("ALTER TABLE {access_intents} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) DEFAULT NULL");
                 // Update access cache
                 if ($permission->name === "view") {
                     $db->query("ALTER TABLE {items} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) DEFAULT FALSE");
                 } else {
                     $db->query("ALTER TABLE {access_caches} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) NOT NULL DEFAULT FALSE");
                 }
             }
         }
         module::set_version("gallery", $version = 8);
     }
     if ($version == 8) {
         $db->query("ALTER TABLE {items} CHANGE COLUMN `left`  `left_ptr`  INT(9) NOT NULL;");
         $db->query("ALTER TABLE {items} CHANGE COLUMN `right` `right_ptr` INT(9) NOT NULL;");
         module::set_version("gallery", $version = 9);
     }
     if ($version == 9) {
         $db->query("ALTER TABLE {items} ADD KEY `weight` (`weight` DESC);");
         module::set_version("gallery", $version = 10);
     }
     if ($version == 10) {
         module::set_var("gallery", "image_sharpen", 15);
         module::set_version("gallery", $version = 11);
     }
     if ($version == 11) {
         $db->query("ALTER TABLE {items} ADD COLUMN `relative_url_cache` varchar(255) DEFAULT NULL");
         $db->query("ALTER TABLE {items} ADD COLUMN `slug` varchar(255) DEFAULT NULL");
         // This is imperfect since some of the slugs may contain invalid characters, but it'll do
         // for now because we don't want a lengthy operation here.
         $db->query("UPDATE {items} SET `slug` = `name`");
         // Flush all path caches becuase we're going to start urlencoding them.
         $db->query("UPDATE {items} SET `relative_url_cache` = NULL, `relative_path_cache` = NULL");
         module::set_version("gallery", $version = 12);
     }
     if ($version == 12) {
         if (module::get_var("gallery", "active_site_theme") == "default") {
             module::set_var("gallery", "active_site_theme", "wind");
         }
         if (module::get_var("gallery", "active_admin_theme") == "admin_default") {
             module::set_var("gallery", "active_admin_theme", "admin_wind");
         }
         module::set_version("gallery", $version = 13);
     }
     if ($version == 13) {
         // Add rules for generating our thumbnails and resizes
         Database::instance()->query("UPDATE {graphics_rules} SET `operation` = CONCAT('gallery_graphics::', `operation`);");
         module::set_version("gallery", $version = 14);
     }
     if ($version == 14) {
         $sidebar_blocks = block_manager::get_active("site_sidebar");
         if (empty($sidebar_blocks)) {
             $available_blocks = block_manager::get_available_site_blocks();
             foreach (array_keys(block_manager::get_available_site_blocks()) as $id) {
                 $sidebar_blocks[] = explode(":", $id);
             }
             block_manager::set_active("site_sidebar", $sidebar_blocks);
         }
         module::set_version("gallery", $version = 15);
     }
     if ($version == 15) {
         module::set_var("gallery", "identity_provider", "user");
         module::set_version("gallery", $version = 16);
     }
     // Convert block keys to an md5 hash of the module and block name
     if ($version == 16) {
         foreach (array("dashboard_sidebar", "dashboard_center", "site_sidebar") as $location) {
             $blocks = block_manager::get_active($location);
             $new_blocks = array();
             foreach ($blocks as $block) {
                 $new_blocks[md5("{$block[0]}:{$block[1]}")] = $block;
             }
             block_manager::set_active($location, $new_blocks);
         }
         module::set_version("gallery", $version = 17);
     }
     // We didn't like md5 hashes so convert block keys back to random keys to allow duplicates.
     if ($version == 17) {
         foreach (array("dashboard_sidebar", "dashboard_center", "site_sidebar") as $location) {
             $blocks = block_manager::get_active($location);
             $new_blocks = array();
             foreach ($blocks as $block) {
                 $new_blocks[rand()] = $block;
             }
             block_manager::set_active($location, $new_blocks);
         }
         module::set_version("gallery", $version = 18);
     }
     // Rename blocks_site.sidebar to blocks_site_sidebar
     if ($version == 18) {
         $blocks = block_manager::get_active("site.sidebar");
         block_manager::set_active("site_sidebar", $blocks);
         module::clear_var("gallery", "blocks_site.sidebar");
         module::set_version("gallery", $version = 19);
     }
     // Set a default for the number of simultaneous uploads
     // Version 20 was reverted in 57adefc5baa7a2b0dfcd3e736e80c2fa86d3bfa2, so skip it.
     if ($version == 19 || $version == 20) {
         module::set_var("gallery", "simultaneous_upload_limit", 5);
         module::set_version("gallery", $version = 21);
     }
     // Update the graphics rules table so that the maximum height for resizes is 640 not 480.
     // Fixes ticket #671
     if ($version == 21) {
         $resize_rule = ORM::factory("graphics_rule")->where("id", "=", "2")->find();
         // make sure it hasn't been changed already
         $args = unserialize($resize_rule->args);
         if ($args["height"] == 480 && $args["width"] == 640) {
             $args["height"] = 640;
             $resize_rule->args = serialize($args);
             $resize_rule->save();
         }
         module::set_version("gallery", $version = 22);
     }
     // Update slug values to be legal.  We should have done this in the 11->12 upgrader, but I was
     // lazy.  Mea culpa!
     if ($version == 22) {
         foreach (db::build()->from("items")->select("id", "slug")->where(new Database_Expression("`slug` REGEXP '[^_A-Za-z0-9-]'"), "=", 1)->execute() as $row) {
             $new_slug = item::convert_filename_to_slug($row->slug);
             if (empty($new_slug)) {
                 $new_slug = rand();
             }
             db::build()->update("items")->set("slug", $new_slug)->set("relative_url_cache", null)->where("id", "=", $row->id)->execute();
         }
         module::set_version("gallery", $version = 23);
     }
     if ($version == 23) {
         $db->query("CREATE TABLE {failed_logins} (\n                  `id` int(9) NOT NULL auto_increment,\n                  `count` int(9) NOT NULL,\n                  `name` varchar(255) NOT NULL,\n                  `time` int(9) NOT NULL,\n                  PRIMARY KEY (`id`))\n                  DEFAULT CHARSET=utf8;");
         module::set_version("gallery", $version = 24);
     }
     if ($version == 24) {
         foreach (array("logs", "tmp", "uploads") as $dir) {
             self::_protect_directory(VARPATH . $dir);
         }
         module::set_version("gallery", $version = 25);
     }
     if ($version == 25) {
         db::build()->update("items")->set("title", new Database_Expression("`name`"))->and_open()->where("title", "IS", null)->or_where("title", "=", "")->close()->execute();
         module::set_version("gallery", $version = 26);
     }
     if ($version == 26) {
         $db->query("RENAME TABLE {failed_logins} TO {failed_auths}");
         module::set_version("gallery", $version = 27);
     }
     if ($version == 27) {
         // Set the admin area timeout to 90 minutes
         module::set_var("gallery", "admin_area_timeout", 90 * 60);
         module::set_version("gallery", $version = 28);
     }
     if ($version == 28) {
         module::set_var("gallery", "credits", "Powered by <a href=\"%url\">%gallery_version</a>");
         module::set_version("gallery", $version = 29);
     }
     if ($version == 29) {
         $db->query("ALTER TABLE {caches} ADD KEY (`key`);");
         module::set_version("gallery", $version = 30);
     }
 }
Beispiel #11
0
 public function convert_filename_to_slug_test()
 {
     $this->assert_equal("foo", item::convert_filename_to_slug("{[foo]}"));
     $this->assert_equal("foo-bar", item::convert_filename_to_slug("{[foo!@#!\$@#^\$@(\$!(@bar]}"));
 }
 private function _add_item(&$input, &$reply)
 {
     $album = trim($input->post('set_albumName'));
     $userfilename = $this->decode($input->post('userfile_name'));
     $title = $this->decode($input->post('caption'));
     $forcefilename = $this->decode($input->post('force_filename'));
     $autorotate = trim($input->post('auto_rotate'));
     if ($album == '0') {
         $parent = item::root();
     } else {
         $parent = ORM::factory("item")->where("id", "=", $album)->find();
     }
     if (isset($parent) && $parent->loaded() && $parent->id != '') {
         if (function_exists('mime_content_type')) {
             $type = mime_content_type($_FILES['userfile']['tmp_name']);
         } else {
             $type = self::get_mime_type($_FILES['userfile']['name']);
         }
         /* <any ugly idea is welcome here> */
         if ($type == '') {
             if (function_exists('getimagesize')) {
                 $size = getimagesize($_FILES['userfile']['tmp_name']);
                 $type = $size['mime'];
             } else {
                 if (function_exists('exif_imagetype') && function_exists('image_type_to_mime_type')) {
                     $type = image_type_to_mime_type(exif_imagetype($_FILES['userfile']['tmp_name']));
                 }
             }
         }
         /* </any ugly idea is welcome here> */
         if ($type != '' && !in_array($type, array('image/jpeg', 'image/gif', 'image/png'))) {
             $reply->set('status_text', t("'%path' is an unsupported image type '%type'", array('path' => $_FILES['userfile']['tmp_name'], 'type' => $type)));
             $reply->send(gallery_remote::UPLOAD_PHOTO_FAIL);
             return;
         }
         if ($forcefilename != '') {
             $filename = $forcefilename;
         } else {
             if ($userfilename != '') {
                 $filename = $userfilename;
             } else {
                 $filename = $_FILES['userfile']['name'];
             }
         }
         $slug = $filename;
         $pos = strpos($slug, '.');
         if ($pos !== false) {
             $slug = substr($slug, 0, $pos);
         }
         //*/ fix for a gallery remote bug...
         $filename = str_replace('.JPG.jpeg', '.jpeg', $filename);
         //*/
         //*/ suddenly gallery fails because the uploaded(!) file (of cause!) doesn't contain a file extension
         if (strpos($_FILES['userfile']['tmp_name'], '.') === false) {
             $moveto = $_FILES['userfile']['tmp_name'] . '.' . substr($type, strpos($type, '/') + 1);
             rename($_FILES['userfile']['tmp_name'], $moveto);
             $_FILES['userfile']['tmp_name'] = $moveto;
         }
         //*/
         try {
             $item = ORM::factory('item');
             $item->type = 'photo';
             $item->parent_id = $parent->id;
             $item->set_data_file($_FILES['userfile']['tmp_name']);
             $item->name = $filename;
             $item->slug = item::convert_filename_to_slug($slug);
             $item->mime_type = $type;
             $item->title = $title;
             $item->title or $item->title = ' ';
             //don't use $item->name as this clutters up the UI
             //$item->description =
             $item->view_count = 0;
             try {
                 $item->validate();
                 try {
                     $item->save();
                     $reply->set('item_name', $item->id);
                     $reply->set('status_text', 'New item created successfuly.');
                     $reply->send();
                 } catch (ORM_Validation_Exception $e) {
                     $validation = $e->validation;
                     //print_r($validation->errors()); exit;
                     $reply->set('status_text', t('Failed to validate item %item: %errors', array('item' => $filename, 'errors' => str_replace("\n", ' ', print_r($validation->errors(), true)))));
                     $reply->send(gallery_remote::UPLOAD_PHOTO_FAIL);
                     //FIXME gallery remote ignores this return value and continues to wait
                 } catch (Exception $e) {
                     $reply->set('status_text', t('Failed to add item %item.', array('item' => $filename)));
                     $reply->send(gallery_remote::UPLOAD_PHOTO_FAIL);
                     //FIXME gallery remote ignores this return value and continues to wait
                 }
             } catch (ORM_Validation_Exception $e) {
                 $validation = $e->validation;
                 //print_r($validation->errors()); exit;
                 $reply->set('status_text', t('Failed to validate item %item: %errors', array('item' => $filename, 'errors' => str_replace("\n", ' ', print_r($validation->errors(), true)))));
                 $reply->send(gallery_remote::UPLOAD_PHOTO_FAIL);
                 //FIXME gallery remote ignores this return value and continues to wait
             }
         } catch (Exception $e) {
             $reply->set('status_text', t("Corrupt image '%path'", array('path' => $_FILES['userfile']['tmp_name'])));
             $reply->send(gallery_remote::UPLOAD_PHOTO_FAIL);
             //FIXME gallery remote ignores this return value and continues to wait
         }
     } else {
         $reply->set('status_text', t('Failed to load album with name %name.', array('name' => $album)));
         $reply->send(gallery_remote::UPLOAD_PHOTO_FAIL);
         //FIXME gallery remote ignores this return value and continues to wait
     }
 }
 /**
  * Import a single photo or movie.
  */
 static function import_item(&$queue)
 {
     $messages = array();
     if (count($queue) == 0) {
         $messages[] = t('Empty item queue');
         return $messages;
     }
     $item_id = array_shift($queue);
     g1_import::debug(t('Now importing item %item', array('item' => $item_id)));
     // Item names come in as FolderX/ItemX
     $pos = strrpos($item_id, '/');
     if ($pos === false) {
         return $messages;
     }
     // Get ItemX into g1_item
     $g1_item = substr($item_id, $pos + 1);
     // Get FolderX into g1_item
     $g1_album = substr($item_id, 0, $pos);
     if (self::map($g1_album, $g1_item, 'item')) {
         return $messages;
     }
     $album_id = self::map($g1_album, '', 'album');
     if (!$album_id) {
         $messages[] = t('Album %name not found', array('name' => $g1_album));
         return $messages;
     }
     $album_item = null;
     $albumDir = self::$album_dir;
     if (substr($albumDir, -1) != DIRECTORY_SEPARATOR) {
         $albumDir .= DIRECTORY_SEPARATOR;
     }
     require_once 'Gallery1DataParser.php';
     list($result, $items) = Gallery1DataParser::getPhotos($albumDir . $g1_album . DIRECTORY_SEPARATOR);
     if ($result == null) {
         foreach ($items as $object) {
             if (isset($object->image) && is_a($object->image, 'G1Img') && isset($object->image->name) && $object->image->name == $g1_item) {
                 $album_item = $object;
             }
         }
     }
     if ($album_item == null) {
         $messages[] = t('Failed to import Gallery 1 item: %item', array('item' => $item_id));
         return $messages;
     }
     $corrupt = 0;
     self::$current_g1_item = array($item_id => $album_item);
     $g1_path = $albumDir . $g1_album . DIRECTORY_SEPARATOR . $album_item->image->name . '.' . $album_item->image->type;
     $parent = ORM::factory('item', $album_id);
     switch ($album_item->image->type) {
         case 'jpg':
         case 'jpeg':
         case 'gif':
         case 'png':
             $g1_type = 'GalleryPhotoItem';
             break;
         case 'wmv':
         case '3gp':
         case 'avi':
         case 'mp4':
         case 'mov':
         case 'flv':
             $g1_type = 'GalleryMovieItem';
             break;
         default:
             $g1_type = 'GalleryPhotoItem';
             break;
     }
     if (!file_exists($g1_path)) {
         // If the Gallery 1 source image isn't available, this operation is going to fail.  That can
         // happen in cases where there's corruption in the source Gallery 1.  In that case, fall
         // back on using a broken image.  It's important that we import *something* otherwise
         // anything that refers to this item in Gallery 1 will have a dangling pointer in Gallery 3
         //
         // Note that this will change movies to be photos, if there's a broken movie.  Hopefully
         // this case is rare enough that we don't need to take any heroic action here.
         g1_import::log(t('%path missing in import; replacing it with a placeholder', array('path' => $g1_path)));
         $g1_path = MODPATH . 'g1_import/data/broken-image.gif';
         $g1_type = 'GalleryPhotoItem';
         $corrupt = 1;
     }
     $item = null;
     switch ($g1_type) {
         case 'GalleryPhotoItem':
             if (function_exists('mime_content_type')) {
                 $type = mime_content_type($g1_path);
             } else {
                 $type = self::get_mime_type($g1_path);
             }
             if ($type != '' && !in_array($type, array('image/jpeg', 'image/gif', 'image/png'))) {
                 Kohana_Log::add('alert', "{$g1_path} is an unsupported image type {$type}; using a placeholder gif");
                 $messages[] = t("'%path' is an unsupported image type '%type', using a placeholder", array('path' => $g1_path, 'type' => $type));
                 $g1_path = MODPATH . 'g1_import/data/broken-image.gif';
                 $corrupt = 1;
             }
             try {
                 $item = ORM::factory('item');
                 $item->type = 'photo';
                 $item->parent_id = $album_id;
                 $item->set_data_file($g1_path);
                 $item->name = $g1_item . '.' . $album_item->image->type;
                 $item->slug = item::convert_filename_to_slug($g1_item);
                 $item->mime_type = $type;
                 $item->title = utf8_encode(self::_decode_html_special_chars(trim($album_item->caption)));
                 $item->title or $item->title = ' ';
                 //don't use $item->name as this clutters up the UI
                 if (isset($album_item->description) && $album_item->description != '') {
                     $item->description = utf8_encode(self::_decode_html_special_chars(trim($album_item->description)));
                 }
                 //$item->owner_id = self::map($g1_item->getOwnerId());
                 try {
                     $item->view_count = (int) $album_item->clicks;
                 } catch (Exception $e) {
                     $item->view_count = 1;
                 }
                 if (strlen($item->title) > 255) {
                     if (strlen($item->description) == 0) {
                         $item->description = $item->title;
                     }
                     $item->title = substr($item->title, 0, 252) . '...';
                 }
             } catch (Exception $e) {
                 $exception_info = (string) new G1_Import_Exception(t("Corrupt image '%path'", array('path' => $g1_path)), $e, $messages);
                 Kohana_Log::add('alert', "Corrupt image {$g1_path}\n" . $exception_info);
                 $messages[] = $exception_info;
                 $corrupt = 1;
                 $item = null;
                 return $messages;
             }
             try {
                 $item->validate();
             } catch (ORM_Validation_Exception $e) {
                 $exception_info = (string) new G1_Import_Exception(t('Failed to validate Gallery 1 item %item.', array('item' => $item_id)), $e, $messages);
                 Kohana_Log::add('alert', "Failed to validate Gallery 1 item {$item_id}.\n" . $exception_info);
                 $messages[] = $exception_info;
                 $corrupt = 1;
                 $item = null;
                 return $messages;
             }
             try {
                 $item->save();
             } catch (Exception $e) {
                 $exception_info = (string) new G1_Import_Exception(t('Failed to import Gallery 1 item %item.', array('item' => $item_id)), $e, $messages);
                 Kohana_Log::add('alert', "Failed to import Gallery 1 item {$item_id}.\n" . $exception_info);
                 $messages[] = $exception_info;
                 $corrupt = 1;
                 $item = null;
             }
             break;
         case 'GalleryMovieItem':
             // @todo we should transcode other types into FLV
             if (function_exists('mime_content_type')) {
                 $type = mime_content_type($g1_path);
             } else {
                 $type = self::get_mime_type($g1_path);
             }
             if ($type == '' || in_array($type, array('video/mp4', 'video/x-flv'))) {
                 try {
                     $item = ORM::factory('item');
                     $item->type = 'movie';
                     $item->parent_id = $album_id;
                     $item->set_data_file($g1_path);
                     $item->name = $g1_item . '.' . $album_item->image->type;
                     $item->slug = item::convert_filename_to_slug($g1_item);
                     $item->mime_type = $type;
                     $item->title = utf8_encode(self::_decode_html_special_chars(trim($album_item->caption)));
                     $item->title or $item->title = ' ';
                     //$item->name;
                     if (isset($album_item->description) && $album_item->description != '') {
                         $item->description = utf8_encode(self::_decode_html_special_chars(trim($album_item->description)));
                     }
                     //$item->owner_id = self::map($g1_item->getOwnerId());
                     try {
                         $item->view_count = (int) $album_item->clicks;
                     } catch (Exception $e) {
                         $item->view_count = 1;
                     }
                 } catch (Exception $e) {
                     $exception_info = (string) new G1_Import_Exception(t("Corrupt movie '%path'", array("path" => $g1_path)), $e, $messages);
                     Kohana_Log::add('alert', "Corrupt movie {$g1_path}\n" . $exception_info);
                     $messages[] = $exception_info;
                     $corrupt = 1;
                     $item = null;
                     return $messages;
                 }
                 try {
                     $item->validate();
                 } catch (ORM_Validation_Exception $e) {
                     $exception_info = (string) new G1_Import_Exception(t('Failed to validate Gallery 1 item %item.', array('item' => $item_id)), $e, $messages);
                     Kohana_Log::add('alert', "Failed to validate Gallery 1 item {$item_id}.\n" . $exception_info);
                     $messages[] = $exception_info;
                     $corrupt = 1;
                     $item = null;
                     return $messages;
                 }
                 try {
                     $item->save();
                 } catch (Exception $e) {
                     $exception_info = (string) new G1_Import_Exception(t('Failed to import Gallery 1 item %item.', array('item' => $item_id)), $e, $messages);
                     Kohana_Log::add('alert', "Failed to import Gallery 1 item {$item_id}.\n" . $exception_info);
                     $messages[] = $exception_info;
                     $corrupt = 1;
                     $item = null;
                 }
             } else {
                 Kohana_Log::add('alert', "{$g1_path} is an unsupported movie type {$type}");
                 $messages[] = t("'%path' is an unsupported movie type '%type'", array('path' => $g1_path, 'type' => $type));
                 $corrupt = 1;
             }
             break;
         default:
             // Ignore
             break;
     }
     if (isset($item)) {
         self::set_map($item->id, $g1_album, $g1_item, 'item');
         if (isset($album_item->keywords) && $album_item->keywords != '') {
             $keywords = utf8_encode(self::_decode_html_special_chars(trim($album_item->keywords)));
             if ($keywords != '') {
                 self::import_keywords_as_tags($keywords, $item);
             }
         }
     }
     if ($corrupt) {
         $title = utf8_encode(self::_decode_html_special_chars(trim($album_item->caption)));
         $title or $title = $g1_item;
         if (!empty($item)) {
             $messages[] = t('<a href="%g1_url">%title</a> from Gallery 1 could not be processed; (imported as <a href="%g3_url">%title</a>)', array('g1_url' => $gallery_url . '/' . $item_id, 'g3_url' => $item->url(), 'title' => $title));
         } else {
             $messages[] = t('<a href="%g1_url">%title</a> from Gallery 1 could not be processed', array('g1_url' => $gallery_url . '/' . $item_id, 'title' => $title));
         }
     }
     self::$current_g1_item = null;
     return $messages;
 }