/** * Import a single photo or movie. */ static function import_item(&$queue) { $g2_item_id = array_shift($queue); if (self::map($g2_item_id)) { return; } try { self::$current_g2_item = $g2_item = g2(GalleryCoreApi::loadEntitiesById($g2_item_id)); $g2_path = g2($g2_item->fetchPath()); } catch (Exception $e) { return t("Failed to import Gallery 2 item with id: %id\n%exception", array("id" => $g2_item_id, "exception" => (string) $e)); } $parent = ORM::factory("item", self::map($g2_item->getParentId())); $g2_type = $g2_item->getEntityType(); $corrupt = 0; if (!file_exists($g2_path)) { // If the Gallery 2 source image isn't available, this operation is going to fail. That can // happen in cases where there's corruption in the source Gallery 2. 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 2 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. g2_import::log(t("%path missing in import; replacing it with a placeholder", array("path" => $g2_path))); $g2_path = MODPATH . "g2_import/data/broken-image.gif"; $g2_type = "GalleryPhotoItem"; $corrupt = 1; } $messages = array(); switch ($g2_type) { case "GalleryPhotoItem": if (!in_array($g2_item->getMimeType(), array("image/jpeg", "image/gif", "image/png"))) { Kohana_Log::add("alert", "{$g2_path} is an unsupported image type; using a placeholder gif"); $messages[] = t("'%path' is an unsupported image type, using a placeholder", array("path" => $g2_path)); $g2_path = MODPATH . "g2_import/data/broken-image.gif"; $corrupt = 1; } try { $item = ORM::factory("item"); $item->type = "photo"; $item->parent_id = $parent->id; $item->set_data_file($g2_path); $item->name = $g2_item->getPathComponent(); $item->title = self::_decode_html_special_chars($g2_item->getTitle()); $item->title or $item->title = $item->name; $item->description = self::_decode_html_special_chars(self::extract_description($g2_item)); $item->owner_id = self::map($g2_item->getOwnerId()); $item->save(); // If the item has a preferred derivative with a rotation, then rotate this image // accordingly. Should we obey scale rules as well? I vote no because rotation is less // destructive -- you lose too much data from scaling. $g2_preferred = g2(GalleryCoreApi::fetchPreferredSource($g2_item)); if ($g2_preferred && $g2_preferred instanceof GalleryDerivative) { if (preg_match("/rotate\\|(-?\\d+)/", $g2_preferred->getDerivativeOperations(), $matches)) { $tmpfile = tempnam(TMPPATH, "rotate"); gallery_graphics::rotate($item->file_path(), $tmpfile, array("degrees" => $matches[1]), $item); $item->set_data_file($tmpfile); $item->save(); unlink($tmpfile); } } } catch (Exception $e) { $exception_info = (string) new G2_Import_Exception(t("Corrupt image '%path'", array("path" => $g2_path)), $e, $messages); Kohana_Log::add("alert", "Corrupt image {$g2_path}\n" . $exception_info); $messages[] = $exception_info; $corrupt = 1; $item = null; } break; case "GalleryMovieItem": // @todo we should transcode other types into FLV if (in_array($g2_item->getMimeType(), array("video/mp4", "video/x-flv"))) { try { $item = ORM::factory("item"); $item->type = "movie"; $item->parent_id = $parent->id; $item->set_data_file($g2_path); $item->name = $g2_item->getPathComponent(); $item->title = self::_decode_html_special_chars($g2_item->getTitle()); $item->title or $item->title = $item->name; $item->description = self::_decode_html_special_chars(self::extract_description($g2_item)); $item->owner_id = self::map($g2_item->getOwnerId()); $item->save(); } catch (Exception $e) { $exception_info = (string) new G2_Import_Exception(t("Corrupt movie '%path'", array("path" => $g2_path)), $e, $messages); Kohana_Log::add("alert", "Corrupt movie {$g2_path}\n" . $exception_info); $messages[] = $exception_info; $corrupt = 1; $item = null; } } else { Kohana_Log::add("alert", "{$g2_path} is an unsupported movie type"); $messages[] = t("'%path' is an unsupported movie type", array("path" => $g2_path)); $corrupt = 1; } break; default: // Ignore break; } if (!empty($item)) { self::import_keywords_as_tags($g2_item->getKeywords(), $item); } $g2_item_url = self::g2_url(array("view" => "core.ShowItem", "itemId" => $g2_item->getId())); if (isset($item)) { try { $item->view_count = (int) g2(GalleryCoreApi::fetchItemViewCount($g2_item_id)); } catch (Exception $e) { $view_count = 1; } $item->save(); self::set_map($g2_item_id, $item->id, "item", $g2_item_url); self::set_map($g2_item_id, $item->id, "file", self::g2_url(array("view" => "core.DownloadItem", "itemId" => $g2_item_id))); $derivatives = g2(GalleryCoreApi::fetchDerivativesByItemIds(array($g2_item_id))); if (!empty($derivatives[$g2_item_id])) { foreach ($derivatives[$g2_item_id] as $derivative) { switch ($derivative->getDerivativeType()) { case DERIVATIVE_TYPE_IMAGE_THUMBNAIL: $resource_type = "thumbnail"; break; case DERIVATIVE_TYPE_IMAGE_RESIZE: $resource_type = "resize"; break; case DERIVATIVE_TYPE_IMAGE_PREFERRED: $resource_type = "full"; break; } self::set_map($derivative->getId(), $item->id, $resource_type, self::g2_url(array("view" => "core.DownloadItem", "itemId" => $derivative->getId()))); } } } if ($corrupt) { if (!empty($item)) { $title = $g2_item->getTitle(); $title or $title = $g2_item->getPathComponent(); $messages[] = t("<a href=\"%g2_url\">%title</a> from Gallery 2 could not be processed; (imported as <a href=\"%g3_url\">%title</a>)", array("g2_url" => $g2_item_url, "g3_url" => $item->url(), "title" => $title)); } else { $messages[] = t("<a href=\"%g2_url\">%title</a> from Gallery 2 could not be processed", array("g2_url" => $g2_item_url, "title" => $g2_item->getTitle())); } } self::$current_g2_item = null; return $messages; }