public function rotate($id, $dir) { access::verify_csrf(); $item = model_cache::get("item", $id); access::required("view", $item); access::required("edit", $item); $degrees = 0; switch ($dir) { case "ccw": $degrees = -90; break; case "cw": $degrees = 90; break; } if ($degrees) { $tmpfile = tempnam(TMPPATH, "rotate") . "." . pathinfo($item->file_path(), PATHINFO_EXTENSION); gallery_graphics::rotate($item->file_path(), $tmpfile, array("degrees" => $degrees)); $item->set_data_file($tmpfile); $item->save(); unlink($tmpfile); } if (Input::instance()->get("page_type") == "collection") { json::reply(array("src" => $item->thumb_url(), "width" => $item->thumb_width, "height" => $item->thumb_height)); } else { json::reply(array("src" => $item->resize_url(), "width" => $item->resize_width, "height" => $item->resize_height)); } }
static function rotate_item($item) { // Only try to rotate photos based on EXIF if ($item->is_photo() && $item->mime_type == "image/jpeg") { require_once MODPATH . "exif/lib/exif.php"; $exif_raw = read_exif_data_raw($item->file_path(), false); if (isset($exif_raw['ValidEXIFData'])) { $orientation = $exif_raw["IFD0"]["Orientation"]; $degrees = 0; if ($orientation == '3: Upside-down') { $degrees = 180; } else { if ($orientation == '8: 90 deg CW') { $degrees = -90; } else { if ($orientation == '6: 90 deg CCW') { $degrees = 90; } } } if ($degrees) { $tmpfile = tempnam(TMPPATH, "rotate"); gallery_graphics::rotate($item->file_path(), $tmpfile, array("degrees" => $degrees)); $item->set_data_file($tmpfile); $item->save(); unlink($tmpfile); } } } return; }
static function item_before_create($item) { $max_size = module::get_var("max_size", "max_size", 600); if ($item->is_photo()) { list($width, $height, $mime_type) = photo::get_file_metadata($item->data_file); if ($width > $max_size || $height > $max_size) { $tempnam = tempnam(TMPPATH, "size"); $tmpfile = $tempnam . "." . pathinfo($item->data_file, PATHINFO_EXTENSION); gallery_graphics::resize($item->data_file, $tmpfile, array("width" => $max_size, "height" => $max_size, "master" => Image::AUTO)); rename($tmpfile, $item->data_file); unlink($tempnam); } } }
static function rotate_item($item) { require_once MODPATH . 'autorotate/lib/pel/PelDataWindow.php'; require_once MODPATH . 'autorotate/lib/pel/PelJpeg.php'; require_once MODPATH . 'autorotate/lib/pel/PelTiff.php'; // Only try to rotate photos based on EXIF if ($item->is_photo() && $item->mime_type == "image/jpeg") { require_once MODPATH . "exif/lib/exif.php"; $exif_raw = read_exif_data_raw($item->file_path(), false); if (isset($exif_raw['ValidEXIFData'])) { $orientation = $exif_raw["IFD0"]["Orientation"]; $degrees = 0; if ($orientation == '3: Upside-down') { $degrees = 180; } else { if ($orientation == '8: 90 deg CW') { $degrees = -90; } else { if ($orientation == '6: 90 deg CCW') { $degrees = 90; } } } if ($degrees) { $tmpfile = tempnam(TMPPATH, "rotate"); gallery_graphics::rotate($item->file_path(), $tmpfile, array("degrees" => $degrees)); // Update EXIF info $data = new PelDataWindow(file_get_contents($tmpfile)); if (PelJpeg::isValid($data)) { $jpeg = $file = new PelJpeg(); $jpeg->load($data); $exif = $jpeg->getExif(); if ($exif !== null) { $tiff = $exif->getTiff(); $ifd0 = $tiff->getIfd(); $orientation = $ifd0->getEntry(PelTag::ORIENTATION); $orientation->setValue(1); file_put_contents($tmpfile, $file->getBytes()); } } $item->set_data_file($tmpfile); $item->save(); unlink($tmpfile); } } } return; }
public function generate_album_cover_from_png_test() { $input_file = MODPATH . "gallery/tests/test.jpg"; $output_file = TMPPATH . test::random_name() . ".png"; gallery_graphics::resize($input_file, $output_file, null, null); $album = test::random_album(); $photo = test::random_photo_unsaved($album); $photo->set_data_file($output_file); $photo->name = "album_cover_from_png.png"; $photo->save(); $album->reload(); // Check that the image was correctly resized and converted to jpg $this->assert_equal(array(200, 150, "image/jpeg", "jpg"), photo::get_file_metadata($album->thumb_path())); // Check that the items table got updated $this->assert_equal(array(200, 150), array($album->thumb_width, $album->thumb_height)); // Check that the image is not marked dirty $this->assert_equal(0, $album->thumb_dirty); }
public function rotate($id, $dir) { access::verify_csrf(); $item = model_cache::get("item", $id); access::required("view", $item); access::required("edit", $item); $degrees = 0; switch ($dir) { case "ccw": $degrees = -90; break; case "cw": $degrees = 90; break; } if ($degrees) { gallery_graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); $parent = $item->parent(); // @todo: this is an inadequate way to regenerate the parent's thumbnail after rotation. if ($parent->album_cover_item_id == $item->id) { copy($item->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item->thumb_width; $parent->thumb_height = $item->thumb_height; $parent->save(); } } if (Input::instance()->get("page_type") == "collection") { print json_encode(array("src" => $item->thumb_url() . "?rnd=" . rand(), "width" => $item->thumb_width, "height" => $item->thumb_height)); } else { print json_encode(array("src" => $item->resize_url() . "?rnd=" . rand(), "width" => $item->resize_width, "height" => $item->resize_height)); } }
public function resize_bad_jpg_test() { // Input is a garbled jpg, output is jpg autofit to 300x300 $input_file = TMPPATH . test::random_name() . ".jpg"; $output_file = TMPPATH . test::random_name() . ".jpg"; $options = array("width" => 300, "height" => 300, "master" => Image::AUTO); file_put_contents($input_file, test::lorem_ipsum(200)); // Should get passed to Image library and throw an exception try { gallery_graphics::resize($input_file, $output_file, $options, null); $this->assert_true(false, "Shouldn't get here"); } catch (Exception $e) { // pass } }
public function rotate($id, $dir) { access::verify_csrf(); $item = model_cache::get("item", $id); access::required("view", $item); access::required("edit", $item); $degrees = 0; switch ($dir) { case "ccw": $degrees = -90; break; case "cw": $degrees = 90; break; } if ($degrees) { gallery_graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); $parent = $item->parent(); if ($parent->album_cover_item_id == $item->id) { copy($item->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item->thumb_width; $parent->thumb_height = $item->thumb_height; $parent->save(); } } print json_encode(self::child_json_encode($item)); }
private static function _replace_image_with_placeholder($item, $target) { if ($item->is_album() && !$item->album_cover_item_id) { $input_path = MODPATH . "gallery/images/missing_album_cover.jpg"; } else { if ($item->is_movie() || $item->is_album() && $item->album_cover()->is_movie()) { $input_path = MODPATH . "gallery/images/missing_movie.jpg"; } else { $input_path = MODPATH . "gallery/images/missing_photo.jpg"; } } if ($target == "thumb") { $output_path = $item->thumb_path(); $size = module::get_var("gallery", "thumb_size", 200); } else { $output_path = $item->resize_path(); $size = module::get_var("gallery", "resize_size", 640); } $options = array("width" => $size, "height" => $size, "master" => Image::AUTO); try { // Copy/convert/resize placeholder as needed. gallery_graphics::resize($input_path, $output_path, $options, null); } catch (Exception $e) { // Copy/convert/resize didn't work. Add to the log and copy the jpg version (which could have // a non-jpg extension). This is less than ideal, but it's better than putting nothing // there and causing theme views to act strangely because a file is missing. // @todo we should handle this better. Kohana_Log::add("error", "Caught exception converting placeholder for missing image: " . $item->title . "\n" . $e->getMessage() . "\n" . $e->getTraceAsString()); copy($input_path, $output_path); } if (!file_exists($output_path)) { // Copy/convert/resize didn't throw an exception, but still didn't work - do the same as above. // @todo we should handle this better. Kohana_Log::add("error", "Failed to convert placeholder for missing image: {$item->title}"); copy($input_path, $output_path); } }
/** * 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; }
public function p_rotate($item, $dir) { $degrees = 0; switch ($dir) { case "ccw": $degrees = -90; break; case "cw": $degrees = 90; break; } if ($degrees) { gallery_graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); $parent = $item->parent(); if ($parent->album_cover_item_id == $item->id) { copy($item->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item->thumb_width; $parent->thumb_height = $item->thumb_height; $parent->save(); } } return $item; }
/** * Send the ecard. */ public function send($id) { $item = ORM::factory("item", $id); access::required("view", $item); if (!ecard::can_send_ecard()) { access::forbidden(); } $form = ecard::get_send_form($item); try { $valid = $form->validate(); } catch (ORM_Validation_Exception $e) { // Translate ORM validation errors into form error messages foreach ($e->validation->errors() as $key => $error) { $form->edit_item->inputs[$key]->add_error($error, 1); } $valid = false; } if ($valid) { $to_array = explode(",", $form->send_ecard->inputs["to_email"]->value); foreach ($to_array as $to) { $v = new View("ecard_email.html"); $v->item = $item; $v->subject = module::get_var("ecard", "subject"); $from_name = $form->send_ecard->from_name->value; $bcc = module::get_var("ecard", "bcc"); if ($form->send_ecard->send_to_self->checked == true) { $cc = $form->send_ecard->inputs["from_email"]->value; } $v->message = t(module::get_var("ecard", "message"), array("fromname" => $from_name)); $v->custom_message = $form->send_ecard->text->value; $v->image = $item->name; $from = $form->send_ecard->inputs["from_email"]->value; $headers = array("from" => $from_name . "<" . $from . ">", "to" => $to, "subject" => module::get_var("ecard", "subject")); require_once MODPATH . "ecard/lib/mime.php"; $mime = new Mail_mime("\n"); $mime->setHTMLBody($v->render()); if ($form->send_ecard->send_fresh->checked == true) { $tmpfile = tempnam(TMPPATH, "clean"); if ($form->send_ecard->send_thumbnail->checked == true) { $options = array("width" => module::get_var("gallery", "thumb_size"), "height" => module::get_var("gallery", "thumb_size"), "master" => Image::AUTO); gallery_graphics::resize($item->file_path(), $tmpfile, $options); $mime->addHTMLImage($tmpfile, $item->mime_type, $item->name); } else { $options = array("width" => module::get_var("gallery", "resize_size"), "height" => module::get_var("gallery", "resize_size"), "master" => Image::AUTO); gallery_graphics::resize($item->file_path(), $tmpfile, $options); $mime->addHTMLImage($tmpfile, $item->mime_type, $item->name); } } else { if ($form->send_ecard->send_thumbnail->checked == true) { $mime->addHTMLImage($item->thumb_path(), $item->mime_type, $item->name); } else { $mime->addHTMLImage($item->resize_path(), $item->mime_type, $item->name); } } $body = $mime->get(array('html_charset' => 'UTF-8', 'text_charset' => 'UTF-8', 'text_encoding' => '8bit', 'head_charset' => 'UTF-8')); self::_notify($headers['to'], $headers['from'], $headers['subject'], $item, $body, $mime->headers(), $bcc, $cc); } unlink($tmpfile); message::success("eCard successfully sent"); json::reply(array("result" => "success")); } else { json::reply(array("result" => "error", "html" => (string) $form)); } }
static function do_embossing($id, $image_id, $overlay_id) { $gravity = module::get_var('emboss', 'gravity'); $transparency = module::get_var('emboss', 'transparency'); $item = ORM::factory('item')->where('id', '=', $image_id)->find(); $path = $item->file_path() . $name; $orig = str_replace(VARPATH . 'albums/', VARPATH . 'originals/', $path); @unlink($path); if ($overlay_id < 0) { log::info('emboss', 'Remove embossing from ' . $item->name); @copy($orig, $path); } else { $overlay = ORM::factory('emboss_overlay')->where('id', '=', $overlay_id)->find(); $overlay_path = VARPATH . 'modules/emboss/' . $overlay->name; $opts['file'] = $overlay_path; $opts['position'] = $gravity; $opts['transparency'] = 100 - $transparency; log::info('emboss', 'Embossing ' . $item->name . ' with ' . $overlay->name); gallery_graphics::composite($orig, $path, $opts); } $item->thumb_dirty = 1; $item->resize_dirty = 1; $item->save(); graphics::generate($item); db::build()->update('emboss_mappings')->where('id', '=', $id)->set('cur_overlay_id', $overlay_id)->set('cur_gravity', $gravity)->set('cur_transparency', $transparency)->execute(); }
static function build_resize($input_file, $output_file, $options) { gallery_graphics::resize($input_file, $output_file, $options); }
public function create($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); $form = embed_videos::get_add_form($album); $temp_filename = ""; // TODO: Add admin page options for these. $maxwidth = 650; $maxheight = 480; // Yes, this is a mess. $youtubeUrlPattern = "youtube"; $youtubeThumbnailUrl = "http://img.youtube.com/vi/"; $vimeoUrlPattern = "vimeo.com"; // End mess batch::start(); try { $valid = $form->validate(); if ($form->add_embedded_video->inputs['video_url']->value != "") { $title = $form->add_embedded_video->inputs['title']->value; $description = $form->add_embedded_video->inputs['description']->value; $valid_url = false; $embedded_video = ORM::factory("embedded_video"); $item = ORM::factory("item"); $item->type = "photo"; $url = $form->add_embedded_video->inputs['video_url']->value; if (preg_match("/{$youtubeUrlPattern}/", $url)) { $video_id = 0; if (preg_match("/watch\\?v=(.*?)(&\\S+=\\S+)/", $url, $matches)) { $video_id = $matches[1]; } else { if (preg_match("/watch\\?v=(.*)/", $url, $matches)) { $video_id = $matches[1]; } else { if (preg_match("/v\\/(.*)/", $url, $matches)) { $video_id = $matches[1]; } } } if ($video_id) { $video_id = $matches[1]; $embedded_video->embed_code = '<iframe class="youtube-player" type="text/html" width="' . $maxwidth . '" height="' . $maxheight . '" src="http://www.youtube.com/embed/' . $video_id . '" frameborder="0"></iframe>'; $embedded_video->source = "YouTube"; $content = file_get_contents("http://img.youtube.com/vi/" . $video_id . "/0.jpg"); $itemname = "youtube_" . $video_id . ".jpg"; $temp_filename = VARPATH . "tmp/{$itemname}"; if ($content) { $valid_url = true; $sxml = simplexml_load_file("http://gdata.youtube.com/feeds/api/videos/{$video_id}"); if ($sxml) { if ($title == '') { $title = (string) $sxml->title; } if ($description == '') { $description = (string) $sxml->content; } } } } } else { if (preg_match("/{$vimeoUrlPattern}/", $url)) { if (preg_match("/{$vimeoUrlPattern}\\/(.*)/", $url, $matches)) { $video_id = $matches[1]; if ($video_id) { $sxml = simplexml_load_file("http://vimeo.com/api/v2/video/{$video_id}.xml"); if ($sxml) { if ($title == '') { $title = (string) $sxml->video->title; } if ($description == '') { $description = strip_tags((string) $sxml->video->description); } $embedded_video->source = "Vimeo"; $content = file_get_contents((string) $sxml->video->thumbnail_large); $itemname = "vimeo_" . $video_id . ".jpg"; $temp_filename = VARPATH . "tmp/{$itemname}"; $width = min((int) $sxml->video->width, $maxwidth); $height = min((int) $sxml->video->height, $maxheight); $embedded_video->embed_code = '<iframe src="http://player.vimeo.com/video/' . $video_id . '" width="' . (string) $width . '" height="' . (string) $height . '" frameborder="0"></iframe>'; $valid_url = true; } } } } } //$item->validate(); //$content = file_get_contents("http://img.youtube.com/vi/" . $form->add_embedded_video->inputs['name']->value . "/0.jpg"); if ($valid_url) { $file = fopen($temp_filename, "wb"); fwrite($file, $content); fclose($file); gallery_graphics::composite($temp_filename, $temp_filename, array("file" => "modules/embed_videos/images/embed_video_icon.png", "position" => "center", "transparency" => 95)); $item->set_data_file($temp_filename); $item->name = basename($itemname); $item->title = $title; $item->parent_id = $album->id; $item->description = $description; $item->slug = $form->add_embedded_video->inputs['slug']->value; $path_info = @pathinfo($temp_filename); $item->save(); $embedded_video->item_id = $item->id; $embedded_video->validate(); $embedded_video->save(); log::success("content", t("Added a embedded video"), html::anchor("embeds/{$item->id}", t("view video"))); module::event("add_event_form_completed", $item, $form); } else { $form->add_embedded_video->inputs['video_url']->add_error('invalid_id', 1); $valid = false; } } else { $form->add_embedded_video->inputs['video_url']->add_error('invalid_id', 1); $valid = false; } } catch (Exception $e) { // Lame error handling for now. Just record the exception and move on Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); // Ugh. I hate to use instanceof, But this beats catching the exception separately since // we mostly want to treat it the same way as all other exceptions if ($e instanceof ORM_Validation_Exception) { Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); foreach ($e->validation->errors() as $key => $error) { $form->add_embed->inputs[$key]->add_error($error, 1); } $valid = false; } if (file_exists($temp_filename)) { unlink($temp_filename); } } if (file_exists($temp_filename)) { unlink($temp_filename); } batch::stop(); if ($valid) { //print json_encode(array("result" => "success")); json::reply(array("result" => "success", "location" => $item->url())); } else { //json::reply(array("result" => "error", "form" => (string)$form)); print $form; } }