/** * 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; }
/** * Move this item to the specified target. * @chainable * @param Item_Model $target Target item (must be an album) * @return ORM_MPTT */ function move_to($target) { if (!$target->is_album()) { throw new Exception("@todo INVALID_MOVE_TYPE {$target->type}"); } if ($this->id == 1) { throw new Exception("@todo INVALID_SOURCE root album"); } $original_path = $this->file_path(); $original_resize_path = $this->resize_path(); $original_thumb_path = $this->thumb_path(); $original_parent = $this->parent(); parent::move_to($target, true); model_cache::clear(); $this->relative_path_cache = null; rename($original_path, $this->file_path()); if ($this->is_album()) { @rename(dirname($original_resize_path), dirname($this->resize_path())); @rename(dirname($original_thumb_path), dirname($this->thumb_path())); Database::instance()->update("items", array("relative_path_cache" => null), array("left_ptr >" => $this->left_ptr, "right_ptr <" => $this->right_ptr)); } else { @rename($original_resize_path, $this->resize_path()); @rename($original_thumb_path, $this->thumb_path()); } module::event("item_moved", $this, $original_parent); return $this; }
/** * 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; }
/** * 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)) { $tmp = pathinfo($this->name, PATHINFO_FILENAME); $tmp = preg_replace("/[^A-Za-z0-9-_]+/", "-", $tmp); $this->slug = trim($tmp, "-"); // 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); 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) { // Move all of the items associated data files @rename($original->file_path(), $this->file_path()); 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. // @todo: we don't handle the case where you swap in a file of a different mime type // should we prevent that in validation? or in set_data_file() 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; 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; }
/** * 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) { $this->updated = time(); if (!$this->loaded()) { // Create a new item. // 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)) { $tmp = pathinfo($this->name, PATHINFO_FILENAME); $tmp = preg_replace("/[^A-Za-z0-9-_]+/", "-", $tmp); $this->slug = trim($tmp, "-"); } // Get the width, height and mime type from our data file for photos and movies. if ($this->is_movie() || $this->is_photo()) { $pi = pathinfo($this->data_file); if ($this->is_photo()) { $image_info = getimagesize($this->data_file); $this->width = $image_info[0]; $this->height = $image_info[1]; $this->mime_type = $image_info["mime"]; // Force an extension onto the name if necessary if (empty($pi["extension"])) { $pi["extension"] = image_type_to_extension($image_info[2], false); $this->name .= "." . $pi["extension"]; } } else { list($this->width, $this->height) = movie::getmoviesize($this->data_file); // No extension? Assume FLV. if (empty($pi["extension"])) { $pi["extension"] = "flv"; $this->name .= "." . $pi["extension"]; } $this->mime_type = strtolower($pi["extension"]) == "mp4" ? "video/mp4" : "video/x-flv"; } } // Randomize the name or slug if there's a conflict. Preserve the extension. // @todo Improve this. Random numbers are not user friendly $base_name = pathinfo($this->name, PATHINFO_FILENAME); $base_ext = pathinfo($this->name, PATHINFO_EXTENSION); $base_slug = $this->slug; while (ORM::factory("item")->where("parent_id", "=", $this->parent_id)->and_open()->where("name", "=", $this->name)->or_where("slug", "=", $this->slug)->close()->find()->id) { $rand = rand(); if ($base_ext) { $this->name = "{$base_name}-{$rand}.{$base_ext}"; } else { $this->name = "{$base_name}-{$rand}"; } $this->slug = "{$base_slug}-{$rand}"; } 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"] . "-" . rand() . "." . $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. module::event("item_created", $this); } else { // Update an existing 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); if (array_intersect($this->changed, array("parent_id", "name", "slug"))) { $original->_build_relative_caches(); $this->relative_path_cache = null; $this->relative_url_cache = null; } 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) { // Move all of the items associated data files @rename($original->file_path(), $this->file_path()); 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(); } module::event("item_updated", $original, $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; }
/** * Move this item to the specified target. * * @chainable * @param Item_Model $target Target item (must be an album * @return ORM_MTPP */ function move_to($target) { $original_path = $this->file_path(); $original_resize_path = $this->resize_path(); $original_thumb_path = $this->thumb_path(); parent::move_to($target, true); $this->relative_path = null; rename($original_path, $this->file_path()); 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()); } return $this; }
/** * Move this item to the specified target. * @chainable * @param Item_Model $target Target item (must be an album) * @return ORM_MPTT */ function move_to($target) { if (!$target->is_album()) { throw new Exception("@todo INVALID_MOVE_TYPE {$target->type}"); } if (file_exists($target_file = "{$target->file_path()}/{$this->name}")) { throw new Exception("@todo INVALID_MOVE_TARGET_EXISTS: {$target_file}"); } if ($this->id == 1) { throw new Exception("@todo INVALID_SOURCE root album"); } $original_path = $this->file_path(); $original_resize_path = $this->resize_path(); $original_thumb_path = $this->thumb_path(); $original_parent = $this->parent(); parent::move_to($target, true); model_cache::clear(); $this->relative_path_cache = null; rename($original_path, $this->file_path()); if ($this->is_album()) { @rename(dirname($original_resize_path), dirname($this->resize_path())); @rename(dirname($original_thumb_path), dirname($this->thumb_path())); db::build()->update("items")->set("relative_path_cache", null)->set("relative_url_cache", null)->where("left_ptr", ">", $this->left_ptr)->where("right_ptr", "<", $this->right_ptr)->execute(); } else { @rename($original_resize_path, $this->resize_path()); @rename($original_thumb_path, $this->thumb_path()); } module::event("item_moved", $this, $original_parent); return $this; }