Exemple #1
0
 /**
  * Create a merged list of all allowed photo and movie extensions.
  */
 static function get_extensions()
 {
     $extensions = legal_file::get_photo_extensions();
     if (movie::find_ffmpeg()) {
         $extensions = array_merge($extensions, legal_file::get_movie_extensions());
     }
     return $extensions;
 }
 public function get_photo_extensions_test()
 {
     $this->assert_equal(true, legal_file::get_photo_extensions("jpg"));
     // regular
     $this->assert_equal(true, legal_file::get_photo_extensions("JPG"));
     // all caps
     $this->assert_equal(true, legal_file::get_photo_extensions("Png"));
     // some caps
     $this->assert_equal(false, legal_file::get_photo_extensions("php"));
     // invalid
     $this->assert_equal(false, legal_file::get_photo_extensions("php.jpg"));
     // invalid w/ .
     // No extension returns full array
     $this->assert_equal(4, count(legal_file::get_photo_extensions()));
 }
Exemple #3
0
 /**
  * Validate the item name.  It can't conflict with other names, can't contain slashes or
  * trailing periods.
  */
 public function valid_name(Validation $v, $field)
 {
     if (strpos($this->name, "/") !== false) {
         $v->add_error("name", "no_slashes");
         return;
     }
     if (rtrim($this->name, ".") !== $this->name) {
         $v->add_error("name", "no_trailing_period");
         return;
     }
     // Do not accept files with double extensions, they can cause problems on some
     // versions of Apache.
     if (!$this->is_album() && substr_count($this->name, ".") > 1) {
         $v->add_error("name", "illegal_data_file_extension");
     }
     if ($this->is_movie() || $this->is_photo()) {
         $ext = pathinfo($this->name, PATHINFO_EXTENSION);
         if (!$this->loaded() && !$ext) {
             // New items must have an extension
             $v->add_error("name", "illegal_data_file_extension");
             return;
         }
         if ($this->is_photo()) {
             if (!in_array(strtolower($ext), legal_file::get_photo_extensions())) {
                 $v->add_error("name", "illegal_data_file_extension");
             }
         }
         if ($this->is_movie()) {
             if (!in_array(strtolower($ext), legal_file::get_movie_extensions())) {
                 $v->add_error("name", "illegal_data_file_extension");
             }
         }
     }
     if (db::build()->from("items")->where("parent_id", "=", $this->parent_id)->where("name", "=", $this->name)->merge_where($this->id ? array(array("id", "<>", $this->id)) : null)->count_records()) {
         $v->add_error("name", "conflict");
         return;
     }
     if ($this->parent_id == 1 && Kohana::auto_load("{$this->slug}_Controller")) {
         $v->add_error("slug", "reserved");
         return;
     }
 }
Exemple #4
0
 public function add()
 {
     access::verify_csrf();
     $form = watermark::get_add_form();
     if ($form->validate()) {
         $file = $_POST["file"];
         $pathinfo = pathinfo($file);
         // Forge prefixes files with "uploadfile-xxxxxxx" for uniqueness
         $name = preg_replace("/uploadfile-[^-]+-(.*)/", '$1', $pathinfo["basename"]);
         $name = legal_file::smash_extensions($name);
         if (!($image_info = getimagesize($file)) || !in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
             message::error(t("Unable to identify this image file"));
             @unlink($file);
             return;
         }
         if (!in_array($pathinfo["extension"], legal_file::get_photo_extensions())) {
             switch ($image_info[2]) {
                 case IMAGETYPE_GIF:
                     $name = legal_file::change_extension($name, "gif");
                     break;
                 case IMAGETYPE_JPEG:
                     $name = legal_file::change_extension($name, "jpg");
                     break;
                 case IMAGETYPE_PNG:
                     $name = legal_file::change_extension($name, "png");
                     break;
             }
         }
         rename($file, VARPATH . "modules/watermark/{$name}");
         module::set_var("watermark", "name", $name);
         module::set_var("watermark", "width", $image_info[0]);
         module::set_var("watermark", "height", $image_info[1]);
         module::set_var("watermark", "mime_type", $image_info["mime"]);
         module::set_var("watermark", "position", $form->add_watermark->position->value);
         module::set_var("watermark", "transparency", $form->add_watermark->transparency->value);
         $this->_update_graphics_rules();
         @unlink($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);
 }
Exemple #5
0
 /**
  * Validate the item name.  It can return the following error messages:
  * - no_slashes: contains slashes
  * - no_backslashes: contains backslashes
  * - no_trailing_period: has a trailing period
  * - illegal_data_file_extension (non-albums only): has double, no, or illegal extension
  * - conflict: has conflicting name
  */
 public function valid_name(Validation $v, $field)
 {
     if (strpos($this->name, "/") !== false) {
         $v->add_error("name", "no_slashes");
         return;
     }
     if (strpos($this->name, "\\") !== false) {
         $v->add_error("name", "no_backslashes");
         return;
     }
     if (rtrim($this->name, ".") !== $this->name) {
         $v->add_error("name", "no_trailing_period");
         return;
     }
     if ($this->is_movie() || $this->is_photo()) {
         if (substr_count($this->name, ".") > 1) {
             // Do not accept files with double extensions, as they can
             // cause problems on some versions of Apache.
             $v->add_error("name", "illegal_data_file_extension");
         }
         $ext = pathinfo($this->name, PATHINFO_EXTENSION);
         if (!$this->loaded() && !$ext) {
             // New items must have an extension
             $v->add_error("name", "illegal_data_file_extension");
             return;
         }
         if ($this->is_photo() && !legal_file::get_photo_extensions($ext) || $this->is_movie() && !legal_file::get_movie_extensions($ext)) {
             $v->add_error("name", "illegal_data_file_extension");
         }
     }
     if ($this->is_album()) {
         if (db::build()->from("items")->where("parent_id", "=", $this->parent_id)->where("name", "=", $this->name)->merge_where($this->id ? array(array("id", "<>", $this->id)) : null)->count_records()) {
             $v->add_error("name", "conflict");
             return;
         }
     } else {
         if (preg_match("/^(.*)(\\.[^\\.\\/]*?)\$/", $this->name, $matches)) {
             $base_name = $matches[1];
         } else {
             $base_name = $this->name;
         }
         $base_name_escaped = Database::escape_for_like($base_name);
         if (db::build()->from("items")->where("parent_id", "=", $this->parent_id)->where("name", "LIKE", "{$base_name_escaped}.%")->merge_where($this->id ? array(array("id", "<>", $this->id)) : null)->count_records()) {
             $v->add_error("name", "conflict");
             return;
         }
     }
 }
Exemple #6
0
 /**
  * Create a merged list of all allowed photo and movie extensions.
  *
  * @param string $extension (opt.) - return true if allowed; if not given, return complete array
  */
 static function get_extensions($extension = null)
 {
     $extensions = legal_file::get_photo_extensions();
     if (movie::allow_uploads()) {
         $extensions = array_merge($extensions, legal_file::get_movie_extensions());
     }
     if ($extension) {
         // return true if in array, false if not
         return in_array(strtolower($extension), $extensions);
     } else {
         // return complete array
         return $extensions;
     }
 }
Exemple #7
0
 static function cron()
 {
     $owner_id = 2;
     $debug = !empty($_SERVER['argv']) && isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == "debug";
     // Login as Admin
     $debug and print "Starting user session\n";
     $session = Session::instance();
     $session->delete("user");
     auth::login(IdentityProvider::instance()->admin_user());
     // check if some folders are still unprocessed from previous run
     $entry = ORM::factory("folder_sync_entry")->where("is_directory", "=", 1)->where("checked", "=", 0)->order_by("id", "ASC")->find();
     if (!$entry->loaded()) {
         $debug and print "Adding default folders\n";
         $paths = unserialize(module::get_var("folder_sync", "authorized_paths"));
         foreach (array_keys($paths) as $path) {
             if (folder_sync::is_valid_path($path)) {
                 $path = rtrim($path, "/");
                 $debug and print " * {$path}\n";
                 $entry = ORM::factory("folder_sync_entry")->where("is_directory", "=", 1)->where("path", "=", $path)->find();
                 if ($entry && $entry->loaded()) {
                     $entry->checked = 0;
                     $entry->save();
                 } else {
                     $entry = ORM::factory("folder_sync_entry");
                     $entry->path = $path;
                     $entry->is_directory = 1;
                     $entry->parent_id = null;
                     $entry->item_id = module::get_var("folder_sync", "destination_album_id", 1);
                     $entry->md5 = '';
                     $entry->save();
                 }
             }
         }
     }
     // Scan and add files
     $debug and print "Starting the loop\n";
     $done = false;
     $limit = 500;
     while (!$done && $limit > 0) {
         $debug and print "Loop started: Limit = {$limit}\n";
         $entry = ORM::factory("folder_sync_entry")->where("is_directory", "=", 1)->where("checked", "=", 0)->order_by("id", "ASC")->find();
         if ($entry->loaded()) {
             // get the parrent
             $parent = ORM::factory("item", $entry->item_id);
             if (!$parent->loaded()) {
                 $debug and print "Deleting entry #{$entry->id} pointing to missing item #{$entry->item_id}\n";
                 //$entry->delete();
                 //continue;
             }
             $debug and print "Scanning folder: {$entry->path}\n";
             $child_paths = glob(preg_quote($entry->path) . "/*");
             if (!$child_paths) {
                 $child_paths = glob("{$entry->path}/*");
             }
             foreach ($child_paths as $child_path) {
                 $name = basename($child_path);
                 $title = item::convert_filename_to_title($name);
                 $debug and print "Found {$child_path}...";
                 if (is_dir($child_path)) {
                     $debug and print "folder\n";
                     $entry_exists = ORM::factory("folder_sync_entry")->where("is_directory", "=", 1)->where("path", "=", $child_path)->find();
                     if ($entry_exists && $entry_exists->loaded()) {
                         $debug and print "Folder is already imported, marked to re-sync.\n";
                         $entry_exists->checked = 0;
                         $entry_exists->save();
                     } else {
                         $debug and print "Adding new folder.\n";
                         $album = ORM::factory("item");
                         $album->type = "album";
                         $album->parent_id = $parent->id;
                         $album->name = $name;
                         $album->title = $title;
                         $album->owner_id = $owner_id;
                         $album->sort_order = $parent->sort_order;
                         $album->sort_column = $parent->sort_column;
                         $album->save();
                         $child_entry = ORM::factory("folder_sync_entry");
                         $child_entry->path = $child_path;
                         $child_entry->parent_id = $entry->id;
                         $child_entry->item_id = $album->id;
                         $child_entry->is_directory = 1;
                         $child_entry->md5 = "";
                         $child_entry->save();
                     }
                 } else {
                     $debug and print "file\n";
                     $ext = strtolower(pathinfo($child_path, PATHINFO_EXTENSION));
                     if (!in_array($ext, legal_file::get_extensions()) || !filesize($child_path)) {
                         // Not importable, skip it.
                         $debug and print "File is incompatible. Skipping.\n";
                         continue;
                     }
                     // check if file was already imported
                     $entry_exists = ORM::factory("folder_sync_entry")->where("is_directory", "=", 0)->where("path", "=", $child_path)->find();
                     if ($entry_exists && $entry_exists->loaded()) {
                         $debug and print "Image is already imported...";
                         if (empty($entry_exists->added) || empty($entry_exists->md5) || $entry_exists->added != filemtime($child_path) || $entry_exists->md5 != md5_file($child_path)) {
                             $item = ORM::factory("item", $entry_exists->item_id);
                             if ($item->loaded()) {
                                 $item->set_data_file($child_path);
                                 $debug and print "updating.\n";
                                 try {
                                     $item->save();
                                 } catch (ORM_Validation_Exception $e) {
                                     print "Error saving the image (ID = {$item->id}) with the new data file.\n";
                                     exit;
                                 }
                             } else {
                                 $debug and print "deleting.\n";
                                 $entry_exists->delete();
                             }
                         } else {
                             $debug and print "skipping.\n";
                         }
                         // since it's an update, don't count too much towards the limit
                         $limit -= 0.25;
                     } else {
                         if (in_array($ext, legal_file::get_photo_extensions())) {
                             $debug and print "Adding new photo.\n";
                             $item = ORM::factory("item");
                             $item->type = "photo";
                             $item->parent_id = $parent->id;
                             $item->set_data_file($child_path);
                             $item->name = $name;
                             $item->title = $title;
                             $item->owner_id = $owner_id;
                             $item->save();
                         } else {
                             if (in_array($ext, legal_file::get_movie_extensions())) {
                                 $debug and print "Adding new video.\n";
                                 $item = ORM::factory("item");
                                 $item->type = "movie";
                                 $item->parent_id = $parent->id;
                                 $item->set_data_file($child_path);
                                 $item->name = $name;
                                 $item->title = $title;
                                 $item->owner_id = $owner_id;
                                 $item->save();
                             }
                         }
                         $entry_exists = ORM::factory("folder_sync_entry");
                         $entry_exists->path = $child_path;
                         $entry_exists->parent_id = $entry->id;
                         // null if the parent was a staging dir
                         $entry_exists->is_directory = 0;
                         $entry_exists->md5 = md5_file($child_path);
                         $entry_exists->added = filemtime($child_path);
                         $entry_exists->item_id = $item->id;
                         $entry_exists->save();
                         $limit--;
                     }
                 }
                 // Did we hit the limit?
                 if ($limit <= 0) {
                     $debug and print "Reached the limit. Exiting.\n";
                     exit;
                 }
             }
             // We've processed this entry unless we reached a limit.
             if ($limit > 0) {
                 $entry->checked = 1;
                 $entry->save();
             }
         } else {
             $done = true;
             $debug and print "All folders are processed. Exiting.\n";
         }
     }
     // process deletes
     if (module::get_var("folder_sync", "process_deletes", false)) {
         $entries = ORM::factory("folder_sync_entry")->order_by("id", "ASC")->find_all();
         foreach ($entries as $entry) {
             if (!file_exists($entry->path) && $entry->item_id > 1) {
                 $item = ORM::factory("item", $entry->item_id);
                 if ($item->loaded()) {
                     $item->delete();
                 }
             }
         }
     }
     exit;
 }
Exemple #8
0
 /**
  * This is the task code that adds photos and albums.  It first examines all the target files
  * and creates a set of Server_Add_Entry_Models, then runs through the list of models and adds
  * them one at a time.
  */
 static function add($task)
 {
     $mode = $task->get("mode", "init");
     $start = microtime(true);
     switch ($mode) {
         case "init":
             $task->set("mode", "build-file-list");
             $task->set("dirs_scanned", 0);
             $task->percent_complete = 0;
             $task->status = t("Starting up");
             batch::start();
             break;
         case "build-file-list":
             // 0% to 10%
             // We can't fit an arbitrary number of paths in a task, so store them in a separate table.
             // Don't use an iterator here because we can't get enough control over it when we're dealing
             // with a deep hierarchy and we don't want to go over our time quota.
             $paths = unserialize(module::get_var("server_add", "authorized_paths"));
             $dirs_scanned = $task->get("dirs_scanned");
             while (microtime(true) - $start < 0.5) {
                 // Process every directory that doesn't yet have a parent id, these are the
                 // paths that we're importing.
                 $entry = ORM::factory("server_add_entry")->where("task_id", "=", $task->id)->where("is_directory", "=", 1)->where("checked", "=", 0)->order_by("id", "ASC")->find();
                 if ($entry->loaded()) {
                     $child_paths = glob(preg_quote($entry->path) . "/*");
                     if (!$child_paths) {
                         $child_paths = glob("{$entry->path}/*");
                     }
                     foreach ($child_paths as $child_path) {
                         if (!is_dir($child_path)) {
                             $ext = strtolower(pathinfo($child_path, PATHINFO_EXTENSION));
                             if (!legal_file::get_extensions($ext) || !filesize($child_path)) {
                                 // Not importable, skip it.
                                 continue;
                             }
                         }
                         $child_entry = ORM::factory("server_add_entry");
                         $child_entry->task_id = $task->id;
                         $child_entry->path = $child_path;
                         $child_entry->parent_id = $entry->id;
                         // null if the parent was a staging dir
                         $child_entry->is_directory = is_dir($child_path);
                         $child_entry->save();
                     }
                     // We've processed this entry, mark it as done.
                     $entry->checked = 1;
                     $entry->save();
                     $dirs_scanned++;
                 }
             }
             // We have no idea how long this can take because we have no idea how deep the tree
             // hierarchy rabbit hole goes.  Leave ourselves room here for 100 iterations and don't go
             // over 10% in percent_complete.
             $task->set("dirs_scanned", $dirs_scanned);
             $task->percent_complete = min($task->percent_complete + 0.1, 10);
             $task->status = t2("Scanned one directory", "Scanned %count directories", $dirs_scanned);
             if (!$entry->loaded()) {
                 $task->set("mode", "add-files");
                 $task->set("total_files", ORM::factory("server_add_entry")->where("task_id", "=", $task->id)->count_all());
                 $task->percent_complete = 10;
             }
             break;
         case "add-files":
             // 10% to 100%
             $completed_files = $task->get("completed_files", 0);
             $total_files = $task->get("total_files");
             // Ordering by id ensures that we add them in the order that we created the entries, which
             // will create albums first.  Ignore entries which already have an Item_Model attached,
             // they're done.
             $entries = ORM::factory("server_add_entry")->where("task_id", "=", $task->id)->where("item_id", "IS", null)->order_by("id", "ASC")->limit(10)->find_all();
             if ($entries->count() == 0) {
                 // Out of entries, we're done.
                 $task->set("mode", "done");
             }
             $owner_id = identity::active_user()->id;
             foreach ($entries as $entry) {
                 if (microtime(true) - $start > 0.5) {
                     break;
                 }
                 // Look up the parent item for this entry.  By now it should exist, but if none was
                 // specified, then this belongs as a child of the current item.
                 $parent_entry = ORM::factory("server_add_entry", $entry->parent_id);
                 if (!$parent_entry->loaded()) {
                     $parent = ORM::factory("item", $task->get("item_id"));
                 } else {
                     $parent = ORM::factory("item", $parent_entry->item_id);
                 }
                 $name = basename($entry->path);
                 $title = item::convert_filename_to_title($name);
                 if ($entry->is_directory) {
                     $album = ORM::factory("item");
                     $album->type = "album";
                     $album->parent_id = $parent->id;
                     $album->name = $name;
                     $album->title = $title;
                     $album->owner_id = $owner_id;
                     $album->sort_order = $parent->sort_order;
                     $album->sort_column = $parent->sort_column;
                     $album->save();
                     $entry->item_id = $album->id;
                 } else {
                     try {
                         $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION));
                         if (legal_file::get_photo_extensions($extension)) {
                             $photo = ORM::factory("item");
                             $photo->type = "photo";
                             $photo->parent_id = $parent->id;
                             $photo->set_data_file($entry->path);
                             $photo->name = $name;
                             $photo->title = $title;
                             $photo->owner_id = $owner_id;
                             $photo->save();
                             $entry->item_id = $photo->id;
                         } else {
                             if (legal_file::get_movie_extensions($extension)) {
                                 $movie = ORM::factory("item");
                                 $movie->type = "movie";
                                 $movie->parent_id = $parent->id;
                                 $movie->set_data_file($entry->path);
                                 $movie->name = $name;
                                 $movie->title = $title;
                                 $movie->owner_id = $owner_id;
                                 $movie->save();
                                 $entry->item_id = $movie->id;
                             } else {
                                 // This should never happen, because we don't add stuff to the list that we can't
                                 // process.  But just in, case.. set this to a non-null value so that we skip this
                                 // entry.
                                 $entry->item_id = 0;
                                 $task->log("Skipping unknown file type: {$entry->path}");
                             }
                         }
                     } catch (Exception $e) {
                         // This can happen if a photo file is invalid, like a BMP masquerading as a .jpg
                         $entry->item_id = 0;
                         $task->log("Skipping invalid file: {$entry->path}");
                     }
                 }
                 $completed_files++;
                 $entry->save();
             }
             $task->set("completed_files", $completed_files);
             $task->status = t("Adding photos / albums (%completed of %total)", array("completed" => $completed_files, "total" => $total_files));
             $task->percent_complete = $total_files ? 10 + 100 * ($completed_files / $total_files) : 100;
             break;
         case "done":
             batch::stop();
             $task->done = true;
             $task->state = "success";
             $task->percent_complete = 100;
             ORM::factory("server_add_entry")->where("task_id", "=", $task->id)->delete_all();
             message::info(t2("Successfully added one photo / album", "Successfully added %count photos / albums", $task->get("completed_files")));
     }
 }
Exemple #9
0
 /**
  * Add photo or movie from upload.  Once we have a valid file, this generates an item model
  * from it.  It returns the item model on success, and throws an exception and adds log entries
  * on failure.
  * @TODO: consider moving this to a common controller which is extended by various uploaders.
  *
  * @param  int    parent album id
  * @param  string temp file path (analogous to $_FILES[...]["tmp_name"])
  * @param  string filename       (analogous to $_FILES[...]["name"])
  * @return object new item model
  */
 private function _add_item($album_id, $tmp_name, $name)
 {
     $extension = pathinfo($name, PATHINFO_EXTENSION);
     try {
         $item = ORM::factory("item");
         $item->name = $name;
         $item->title = item::convert_filename_to_title($name);
         $item->parent_id = $album_id;
         $item->set_data_file($tmp_name);
         if (!$extension) {
             throw new Exception(t("Uploaded file has no extension"));
         } else {
             if (legal_file::get_photo_extensions($extension)) {
                 $item->type = "photo";
                 $item->save();
                 log::success("content", t("Added a photo"), html::anchor("photos/{$item->id}", t("view photo")));
             } else {
                 if (movie::allow_uploads() && legal_file::get_movie_extensions($extension)) {
                     $item->type = "movie";
                     $item->save();
                     log::success("content", t("Added a movie"), html::anchor("movies/{$item->id}", t("view movie")));
                 } else {
                     throw new Exception(t("Uploaded file has illegal extension"));
                 }
             }
         }
     } catch (Exception $e) {
         // Log errors then re-throw exception.
         Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString());
         // If we have a validation error, add an additional log entry.
         if ($e instanceof ORM_Validation_Exception) {
             Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1));
         }
         throw $e;
     }
     return $item;
 }