GalleryDataItem * @g2 GalleryItem * @g2 * @g2 1 * @g2 0 * @g2 * @g2 * * @package GalleryCore * @subpackage Classes * @author Bharat Mediratta * @version $Revision: 17580 $ */ class GalleryDataItem extends GalleryItem { /** * The mime type of the data file * @var string * * @g2 * @g2 mimeType * @g2 STRING * @g2 MEDIUM * @g2 * @g2 READ * @g2 */ var $mimeType; /** * The byte size of the data file * @var int * * @g2 * @g2 size * @g2 INTEGER * @g2 * @g2 READ * @g2 */ var $size; /** * Data items that can be viewed inline (photos, movies, etc) should return true. * Items that can't be viewed inline (word documents, text, etc) should return false. * * Classes that return true for this query must implement getWidth() and getHeight() * * @return boolean true if this data item can be viewed inline */ function canBeViewedInline() { return $this->_canBeViewedInline(); } /** * Helper function to check renderer and list of mime types for canBeViewedInline. * * @param array $mimeList (optional) list of mime types that render() will support * @return boolean true if this data item can be viewed inline * @access protected */ function _canBeViewedInline($mimeList=null) { $renderer = $this->getRenderer(); if (!empty($renderer)) { list ($ret, $renderer) = GalleryCoreApi::newFactoryInstanceById('GalleryRenderer', $renderer); if (!$ret && isset($renderer)) { return $renderer->canBeViewedInline($this); } } if (isset($mimeList) && in_array($this->getMimeType(), $mimeList)) { return true; } return false; } /** * Create a new instance of this type in the persistent store. * * @param int $parentId the id of the parent GalleryItem * @param string $inputFileName the path to a data file to be contained * @param string $mimeType the mime type of the new item * @param string $targetName (optional) the desired name of the new item * @param boolean $symlink (optional) a boolean true if we should symlink instead * of copy (default is false). * @return GalleryStatus a status code */ function create($parentId, $inputFileName, $mimeType, $targetName=null, $symlink=false) { global $gallery; $platform =& $gallery->getPlatform(); /* Validate the input file */ if (empty($inputFileName)) { return GalleryCoreApi::error(ERROR_BAD_PARAMETER); } if (!$platform->is_uploaded_file($inputFileName) && !$platform->file_exists($inputFileName)) { return GalleryCoreApi::error(ERROR_BAD_PATH); } /* * The parent must be read locked at this point to make sure that it's * not going to be moved around while we're adding stuff to it. */ if (!GalleryCoreApi::isReadLocked($parentId)) { return GalleryCoreApi::error(ERROR_LOCK_REQUIRED); } /* Set the mime type before we call the parent so that it can use this info if necessary */ $this->setMimeType($mimeType); $baseName = !empty($targetName) ? $targetName : basename($inputFileName); $ret = parent::create($parentId, $baseName); if ($ret) { return $ret; } /* Figure out the new location for this file */ list ($ret, $parent) = GalleryCoreApi::loadEntitiesById($parentId, 'GalleryItem'); if ($ret) { return $ret; } list ($ret, $parentPath) = $parent->fetchContainerPath(); if ($ret) { return $ret; } /* * Grab the new name from the path component, since GalleryFileSystemEntity * may adapt the newName to avoid conflicts */ $newFileName = $parentPath . $this->getPathComponent(); /* * XXX: Race condition here! It's possible for two threads to be * adding a file with the same name to the container at the same time. * We have to write lock the container to be sure that this doesn't happen. */ if ($symlink) { if (!$platform->isSymlinkSupported()) { return GalleryCoreApi::error(ERROR_UNSUPPORTED_OPERATION); } if (!$platform->symlink($inputFileName, $newFileName)) { return GalleryCoreApi::error(ERROR_PLATFORM_FAILURE); } } else { /* Copy the file to its new location */ if (!$platform->copy($inputFileName, $newFileName)) { return GalleryCoreApi::error(ERROR_PLATFORM_FAILURE); } } /* Set my file size */ $this->setSize($platform->filesize($newFileName)); return null; } /** * @see GalleryEntity::detachLink */ function detachLink() { global $gallery; /* Stash the linked entity because the super class is going to get rid of it */ $linkedEntity = $this->getLinkedEntity(); $ret = parent::detachLink(); if ($ret) { return $ret; } $platform =& $gallery->getPlatform(); list ($ret, $sourcePath) = $linkedEntity->fetchPath(); if ($ret) { return $ret; } list ($ret, $parent) = $this->fetchParent(); if ($ret) { return $ret; } list ($ret, $newPathBase) = $parent->fetchContainerPath(); if ($ret) { return $ret; } /* This path should already be legal, unless we screwed up elsewhere */ $newPath = $newPathBase . $this->getPathComponent(); if (!$platform->copy($sourcePath, $newPath)) { return GalleryCoreApi::error(ERROR_PLATFORM_FAILURE); } return null; } /** * Delete this GalleryEntity * @return GalleryStatus a status code */ function delete() { global $gallery; /* Delete myself */ $ret = parent::delete(); if ($ret) { return $ret; } /* Delete our source file, if we're not a link */ if (!$this->isLinked()) { list ($ret, $path) = $this->fetchPath(); if ($ret) { return $ret; } $platform =& $gallery->getPlatform(); if ($platform->file_exists($path) && !$platform->unlink($path)) { return GalleryCoreApi::error(ERROR_BAD_PATH, __FILE__, __LINE__, "Could not delete $path"); } } /* Delete the fast-download cache if it exists */ GalleryCoreApi::deleteFastDownloadFileById($this->getId()); return null; } /** * Scan this item's data for changes. * @return GalleryStatus a status code */ function rescan() { global $gallery; $platform =& $gallery->getPlatform(); list ($ret, $path) = $this->fetchPath(); if ($ret) { return $ret; } $this->setSize($platform->filesize($path)); GalleryCoreApi::deleteFastDownloadFileById($this->getId()); return null; } /** * Rename this DataItem * * @param string $newName the path component * @return GalleryStatus a status code */ function rename($newName) { global $gallery; if ($newName == $this->getPathComponent()) { return null; } /* Read lock the parent so that we don't have a race condition below */ list ($ret, $lockId) = GalleryCoreApi::acquireReadLock($this->getParentId()); if ($ret) { return $ret; } $platform =& $gallery->getPlatform(); /* Get the current path before we let the superclass do the rename */ list ($ret, $currentPath) = $this->fetchPath(); if ($ret) { return $ret; } /* * Set the new path in the database. If that succeeds then we should be ok in general. * Jump through hoops to make sure that we release our locks at the end. */ $error = null; $ret = parent::rename($newName); if ($ret) { $error = $ret; } /* Only rename the filesystem entity if we're not a link */ if (!$this->isLinked()) { /* * Grab the new name from the path component, since GalleryFileSystemEntity * may adapt the newName to avoid conflicts */ $newName = $this->getPathComponent(); if (!isset($error)) { $newPath = dirname($currentPath) . '/' . $newName; /* Check to see if the desired path exists */ if ($platform->file_exists($newPath)) { $error = GalleryCoreApi::error(ERROR_COLLISION); } } if (!isset($error)) { if (!$platform->rename($currentPath, $newPath)) { $error = GalleryCoreApi::error(ERROR_BAD_PATH); } } } /* Release locks */ $ret = GalleryCoreApi::releaseLocks($lockId); if ($ret) { return $ret; } if (isset($error)) { return $error; } return null; } /** * Get the full path to the data file. * * @return array GalleryStatus a status code, * string a path where children can store their data files */ function fetchPath() { global $gallery; /* * Source files in the item's directory. But the parent may be an item that doesn't have * its own directory, so we need to get the path of the nearest parent who is a container * (eg an AlbumItem), because a container has a directory for the items it contains. */ if ($this->isLinked()) { $target = $this->getLinkedEntity(); } else { $target = $this; } list ($ret, $containerPath) = $target->fetchContainerPath(); if ($ret) { return array($ret, null); } return array(null, $containerPath . $target->getPathComponent()); } /** * @see GalleryRenderer::render * * @todo Change this API to match that of GalleryRenderer::render() * on the next major GalleryModule API bump. */ function render($format, $params) { return null; } /** * @see GalleryEntity::getClassName */ function getClassName() { return 'GalleryDataItem'; } function getMimeType() { return $this->mimeType; } function setMimeType($mimeType) { $this->mimeType = $mimeType; } function getSize() { return $this->size; } function setSize($size) { $this->size = $size; } } ?>