public function __call($function, $args) { try { $input = Input::instance(); $request = new stdClass(); switch ($method = strtolower($input->server("REQUEST_METHOD"))) { case "get": $request->params = (object) $input->get(); break; default: $request->params = (object) $input->post(); if (isset($_FILES["file"])) { $request->file = upload::save("file"); system::delete_later($request->file); } break; } if (isset($request->params->entity)) { $request->params->entity = json_decode($request->params->entity); } if (isset($request->params->members)) { $request->params->members = json_decode($request->params->members); } $request->method = strtolower($input->server("HTTP_X_GALLERY_REQUEST_METHOD", $method)); $request->access_key = $input->server("HTTP_X_GALLERY_REQUEST_KEY"); if (empty($request->access_key) && !empty($request->params->access_key)) { $request->access_key = $request->params->access_key; } $request->url = url::abs_current(true); if ($suffix = Kohana::config('core.url_suffix')) { $request->url = substr($request->url, 0, strlen($request->url) - strlen($suffix)); } rest::set_active_user($request->access_key); $handler_class = "{$function}_rest"; $handler_method = $request->method; if (!class_exists($handler_class) || !method_exists($handler_class, $handler_method)) { throw new Rest_Exception("Bad Request", 400); } $response = call_user_func(array($handler_class, $handler_method), $request); if ($handler_method == "post") { // post methods must return a response containing a URI. header("HTTP/1.1 201 Created"); header("Location: {$response['url']}"); } rest::reply($response); } catch (ORM_Validation_Exception $e) { // Note: this is totally insufficient because it doesn't take into account localization. We // either need to map the result values to localized strings in the application code, or every // client needs its own l10n string set. throw new Rest_Exception("Bad Request", 400, $e->validation->errors()); } catch (Kohana_404_Exception $e) { throw new Rest_Exception("Not Found", 404); } }
public function add_photo($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); // The Flash uploader not call /start directly, so simulate it here for now. if (!batch::in_progress()) { batch::start(); } $form = $this->_get_add_form($album); // Uploadify adds its own field to the form, so validate that separately. $file_validation = new Validation($_FILES); $file_validation->add_rules("Filedata", "upload::valid", "upload::required", "upload::type[" . implode(",", legal_file::get_extensions()) . "]"); if ($form->validate() && $file_validation->validate()) { $temp_filename = upload::save("Filedata"); system::delete_later($temp_filename); try { $item = ORM::factory("item"); $item->name = substr(basename($temp_filename), 10); // Skip unique identifier Kohana adds $item->title = item::convert_filename_to_title($item->name); $item->parent_id = $album->id; $item->set_data_file($temp_filename); $path_info = @pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && legal_file::get_movie_extensions($path_info["extension"])) { $item->type = "movie"; $item->save(); log::success("content", t("Added a movie"), html::anchor("movies/{$item->id}", t("view movie"))); } else { $item->type = "photo"; $item->save(); log::success("content", t("Added a photo"), html::anchor("photos/{$item->id}", t("view photo"))); } module::event("add_photos_form_completed", $item, $form); } catch (Exception $e) { // The Flash uploader has no good way of reporting complex errors, so just keep it simple. 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)); } header("HTTP/1.1 500 Internal Server Error"); print "ERROR: " . $e->getMessage(); return; } print "FILEID: {$item->id}"; } else { header("HTTP/1.1 400 Bad Request"); print "ERROR: " . t("Invalid upload"); } }
/** * Create a file with a unique file name. * This helper is similar to the built-in tempnam. * It allows the caller to specify a prefix and an extension. * It always places the file in TMPPATH. * Unless specified with the $delete_later argument, it will be marked * for deletion at shutdown using system::delete_later. */ static function temp_filename($prefix = "", $extension = "", $delete_later = true) { do { $basename = tempnam(TMPPATH, $prefix); if (!$basename) { return false; } $filename = "{$basename}.{$extension}"; $success = !file_exists($filename) && @rename($basename, $filename); if (!$success) { @unlink($basename); } } while (!$success); if ($delete_later) { system::delete_later($filename); } return $filename; }
public function add() { access::verify_csrf(); $form = watermark::get_add_form(); // For TEST_MODE, we want to simulate a file upload. Because this is not a true upload, Forge's // validation logic will correctly reject it. So, we skip validation when we're running tests. if (TEST_MODE || $form->validate()) { $file = $_POST["file"]; // Forge prefixes files with "uploadfile-xxxxxxx" for uniqueness $name = preg_replace("/uploadfile-[^-]+-(.*)/", '$1', basename($file)); try { list($width, $height, $mime_type, $extension) = photo::get_file_metadata($file); // Sanitize filename, which ensures a valid extension. This renaming prevents the issues // addressed in ticket #1855, where an image that looked valid (header said jpg) with a // php extension was previously accepted without changing its extension. $name = legal_file::sanitize_filename($name, $extension, "photo"); } catch (Exception $e) { message::error(t("Invalid or unidentifiable image file")); system::delete_later($file); return; } rename($file, VARPATH . "modules/watermark/{$name}"); module::set_var("watermark", "name", $name); module::set_var("watermark", "width", $width); module::set_var("watermark", "height", $height); module::set_var("watermark", "mime_type", $mime_type); module::set_var("watermark", "position", $form->add_watermark->position->value); module::set_var("watermark", "transparency", $form->add_watermark->transparency->value); $this->_update_graphics_rules(); system::delete_later($file); message::success(t("Watermark saved")); log::success("watermark", t("Watermark saved")); json::reply(array("result" => "success", "location" => url::site("admin/watermarks"))); } else { // rawurlencode the results because the JS code that uploads the file buffers it in an // iframe which entitizes the HTML and makes it difficult for the JS to process. If we url // encode it now, it passes through cleanly. See ticket #797. json::reply(array("result" => "error", "html" => rawurlencode((string) $form))); } // Override the application/json mime type. The dialog based HTML uploader uses an iframe to // buffer the reply, and on some browsers (Firefox 3.6) it does not know what to do with the // JSON that it gets back so it puts up a dialog asking the user what to do with it. So force // the encoding type back to HTML for the iframe. // See: http://jquery.malsup.com/form/#file-upload header("Content-Type: text/html; charset=" . Kohana::CHARSET); }
public function add() { access::verify_csrf(); $form = watermark::get_add_form(); // For TEST_MODE, we want to simulate a file upload. Because this is not a true upload, Forge's // validation logic will correctly reject it. So, we skip validation when we're running tests. if (TEST_MODE || $form->validate()) { $file = $_POST["file"]; // Forge prefixes files with "uploadfile-xxxxxxx" for uniqueness $name = preg_replace("/uploadfile-[^-]+-(.*)/", '$1', basename($file)); try { list($width, $height, $mime_type, $extension) = photo::get_file_metadata($file); // Sanitize filename, which ensures a valid extension. This renaming prevents the issues // addressed in ticket #1855, where an image that looked valid (header said jpg) with a // php extension was previously accepted without changing its extension. $name = legal_file::sanitize_filename($name, $extension, "photo"); } catch (Exception $e) { message::error(t("Invalid or unidentifiable image file")); system::delete_later($file); return; } rename($file, VARPATH . "modules/watermark/{$name}"); module::set_var("watermark", "name", $name); module::set_var("watermark", "width", $width); module::set_var("watermark", "height", $height); module::set_var("watermark", "mime_type", $mime_type); module::set_var("watermark", "position", $form->add_watermark->position->value); module::set_var("watermark", "transparency", $form->add_watermark->transparency->value); $this->_update_graphics_rules(); system::delete_later($file); message::success(t("Watermark saved")); log::success("watermark", t("Watermark saved")); json::reply(array("result" => "success", "location" => url::site("admin/watermarks"))); } else { json::reply(array("result" => "error", "html" => (string) $form)); } // Override the application/json mime type for iframe compatibility. See ticket #2022. header("Content-Type: text/plain; charset=" . Kohana::CHARSET); }
/** * Process the uploaded file. This handles the interface with Kohana's upload and validation * code, and marks the new temp file for deletion on shutdown. It returns the temp file path * (tmp_name) and filename (name), analogous to their respective $_FILES elements. * If the upload is invalid, it will throw an exception. Note that no type-checking (e.g. jpg, * mp4,...) is performed here. * @TODO: consider moving this to a common controller which is extended by various uploaders. * * @param string name of $_FILES input * @return array array($tmp_name, $name) */ private function _process_upload($file) { // Validate file data. At this point, any file extension is still valid. $file_validation = new Validation($_FILES); $file_validation->add_rules($file, "upload::valid", "upload::required"); if (!$file_validation->validate()) { throw new Exception(t("Invalid upload")); } // Save temp file and mark for deletion when done. $tmp_name = upload::save($file); system::delete_later($tmp_name); // Get uploaded filename. This is different than tmp_name since it hasn't been uniquified. $name = $_FILES[$file]["name"]; return array($tmp_name, $name); }