getName(); } public function getFullPath() { return sfAssetsLibraryTools::getMediaDir(true).$this->getRelativePath(); } /** * Folder physically exists * * @return bool */ public function exists() { return is_dir(sfAssetsLibraryTools::fixPath($this->getRelativePath())) && is_writable(sfAssetsLibraryTools::fixPath($this->getRelativePath())); } /** * Checks if a name already exists in the list of subfolders to a folder * * @param string $name A folder name * @return bool */ public function hasSubFolder($name) { $c = new Criteria(); $c->add(sfAssetFolderPeer::NAME, $name); $c->add(sfAssetFolderPeer::TREE_PARENT, $this->getId()); return sfAssetFolderPeer::doCount($c) > 0 ? true : false; } /** * Physically creates folder * * @return bool succes */ public function create() { list ($base, $name ) = sfAssetsLibraryTools::splitPath($this->getRelativePath()); return sfAssetsLibraryTools::mkdir($name, $base); } public function hasAsset($asset_name) { $c = new Criteria(); $c->add(sfAssetPeer::FILENAME, $asset_name); return $this->countsfAssets($c) > 0; } public function getAssetsWithFilenames() { $c = new Criteria(); $c->add(sfAssetPeer::FOLDER_ID, $this->getId()); $assets = sfAssetPeer::doSelect($c); $filenames = array(); foreach ($assets as $asset) { $filenames[$asset->getFilename()] = $asset; } return $filenames; } public function getSubfoldersWithFolderNames() { $c = new Criteria(); $c->add(sfAssetFolderPeer::TREE_PARENT, $this->getId()); $folders = sfAssetFolderPeer::doSelect($c); $foldernames = array(); foreach ($folders as $folder) { $foldernames[$folder->getName()] = $folder; } return $foldernames; } /** * Synchronize with a physical folder * * @param string $base_folder base folder path * @param Boolean $verbose If true, every file or database operation will issue an alert in STDOUT * @param Boolean $removeOrphanAssets If true, database assets with no associated file are removed * @param Boolean $removeOrphanFolders If true, database folders with no associated directory are removed */ public function synchronizeWith($base_folder, $verbose = true, $removeOrphanAssets = false, $removeOrphanFolders = false) { if (!is_dir($base_folder)) { throw new sfAssetException(sprintf('%s is not a directory', $base_folder)); } $files = sfFinder::type('file')->maxdepth(0)->ignore_version_control()->in($base_folder); $assets = $this->getAssetsWithFilenames(); foreach ($files as $file) { if (!array_key_exists(basename($file), $assets)) { // File exists, asset does not exist: create asset $sfAsset = new sfAsset(); $sfAsset->setFolderId($this->getId()); $sfAsset->create($file, false); $sfAsset->save(); if ($verbose) { sfAssetsLibraryTools::log(sprintf("Importing file %s", $file), 'green'); } } else { // File exists, asset exists: do nothing unset($assets[basename($file)]); } } foreach ($assets as $name => $asset) { if ($removeOrphanAssets) { // File does not exist, asset exists: delete asset $asset->delete(); if ($verbose) { sfAssetsLibraryTools::log(sprintf("Deleting asset %s", $asset->getUrl()), 'yellow'); } } else { if ($verbose) { sfAssetsLibraryTools::log(sprintf("Warning: No file for asset %s", $asset->getUrl()), 'red'); } } } $dirs = sfFinder::type('dir')->maxdepth(0)->discard(sfConfig::get('app_sfAssetsLibrary_thumbnail_dir', 'thumbnail'))->ignore_version_control()->in($base_folder); $folders = $this->getSubfoldersWithFolderNames(); foreach ($dirs as $dir) { list(, $name) = sfAssetsLibraryTools::splitPath($dir); if (!array_key_exists($name, $folders)) { // dir exists in filesystem, not in database: create folder in database $sfAssetFolder = new sfAssetFolder(); $sfAssetFolder->insertAsLastChildOf($this->reload()); $sfAssetFolder->setName($name); $sfAssetFolder->save(); if ($verbose) { sfAssetsLibraryTools::log(sprintf("Importing directory %s", $dir), 'green'); } } else { // dir exists in filesystem and database: look inside $sfAssetFolder = $folders[$name]; unset($folders[$name]); } $sfAssetFolder->synchronizeWith($dir, $verbose, $removeOrphanAssets, $removeOrphanFolders); } foreach ($folders as $name => $folder) { if ($removeOrphanFolders) { $folder->delete(null, true); if ($verbose) { sfAssetsLibraryTools::log(sprintf("Deleting folder %s", $folder->getRelativePath()), 'yellow'); } } else { if ($verbose) { sfAssetsLibraryTools::log(sprintf("Warning: No directory for folder %s", $folder->getRelativePath()), 'red'); } } } } /** * Recursively move assets and folders from $old_path to $new_path * * @param string $old_path * @param string $new_path * @return bool success */ static public function movePhysically($old_path, $new_path) { $old_path = sfAssetsLibraryTools::fixPath($old_path); $new_path = sfAssetsLibraryTools::fixPath($new_path); if (!is_dir($new_path) || !is_writable($new_path)) { // $old = umask(0); mkdir($new_path, 0755); // umask($old); } $files = sfFinder::type('file')->maxdepth(0)->relative()->in($old_path); $success = true; foreach ($files as $file) { $success = rename($old_path.DIRECTORY_SEPARATOR.$file, $new_path.DIRECTORY_SEPARATOR.$file) && $success; $old = umask(0); chmod($new_path.DIRECTORY_SEPARATOR.$file, 0644); umask($old); } if ($success) { $folders = sfFinder::type('dir')->maxdepth(0)->relative()->in($old_path); foreach ($folders as $folder) { $success = self::movePhysically($old_path.DIRECTORY_SEPARATOR.$folder, $new_path.DIRECTORY_SEPARATOR.$folder) && $success; } } $success = rmdir($old_path) && $success; return $success; } /** * Move under a new parent * * @param sfAssetFolder $new_parent */ public function move(sfAssetFolder $new_parent) { // controls if ($this->isRoot()) { throw new sfAssetException('The root folder cannot be moved'); } else if ($new_parent->hasSubFolder($this->getName())) { throw new sfAssetException('The target folder "%folder%" already contains a folder named "%name%". The folder has not been moved.', array('%folder%' => $new_parent, '%name%' => $this->getName())); } else if ($new_parent->isDescendantOf($this)) { throw new sfAssetException('The target folder cannot be a subfolder of moved folder. The folder has not been moved.'); } else if ($this->getTreeParent() !== $new_parent->getId()) { $descendants = $this->getDescendants(); $old_path = $this->getFullPath(); $this->moveToLastChildOf($new_parent); $this->save(); // move its assets self::movePhysically($old_path, $this->getFullPath()); foreach ($descendants as $descendant) { // Update relative path $descendant->save(); } } // else: nothing to do } /** * Change folder name * * @param string $name */ public function rename($name) { if ($this->getParent()->hasSubFolder($name)) { throw new sfAssetException('The parent folder already contains a folder named "%name%". The folder has not been renamed.', array('%name%' => $name)); } else if ($name !== $this->getName()) { if (sfAssetsLibraryTools::sanitizeName($name) != $name) { throw new sfAssetException('The target folder name "%name%" contains incorrect characters. The folder has not be renamed.', array('%name%' => $name)); } $old_path = $this->getFullPath(); $this->setName($name); $this->save(); // move its assets self::movePhysically($old_path, $this->getFullPath()); foreach ($this->getDescendants() as $descendant) { $descendant->save(); } } // else: nothing to do } /** * Also delete all contents * * @param Connection $con * @param Boolean $force If true, do not throw an exception if the physical directories cannot be removed */ public function delete($con = null, $force = true, $for = 'product') { foreach ($this->getsfAssets() as $asset) { $success = $asset->delete($con, $for) && $success; } return parent::delete($con); } public function getParentPath() { if ($this->isRoot()) { throw new sfException('Root node has no parent path'); } $path = $this->getRelativePath(); return trim(substr($path, 0, strrpos($path, '/')), '/'); } public function save($con = null) { if (!$this->isColumnModified(sfAssetFolderPeer::RELATIVE_PATH)) { if ($this->getParent()) { $this->setRelativePath($this->getParent()->getRelativePath().'/'.$this->getName()); } else { $this->setRelativePath($this->getName()); } } // physical existence if (!$this->exists()) { if (!$this->create()) { throw new sfAssetException('Impossible to create folder "%name%"', array('%name%' => $this->getRelativePath())); } } return parent::save($con); } public function setFillinFromPath($path, $depth = 0) { $path = sfAssetFolderPeer::cleanPath($path); list($parent_path, $name) = sfAssetsLibraryTools::splitPath($path); if (!$parent_folder = sfAssetFolderPeer::retrieveByPath($parent_path)) { $parent_folder = $this->setFillinFromPath($parent_path, $depth + 1); $parent_folder->save(); } if ($depth > 0) { $folder = new sfAssetFolder(); $folder->setName($name); $folder->setRelativePath($path); $folder->insertAsLastChildOf($parent_folder); $folder->save(); return $folder; } else { $this->setName($name); $this->setRelativePath($path); $this->insertAsLastChildOf($parent_folder); } } } sfPropelBehavior::add('sfAssetFolder', array('actasnestedset' => array('columns' => array( 'left' => sfAssetFolderPeer::TREE_LEFT, 'right' => sfAssetFolderPeer::TREE_RIGHT, 'parent' => sfAssetFolderPeer::TREE_PARENT, 'scope' => sfAssetFolderPeer::STATIC_SCOPE, 'depth' => sfAssetFolderPeer::TREE_DEPTH, ))));