Files
grzanieplus.pl/plugins/sfAssetsLibraryPlugin/lib/model/sfAssetFolder.php
2025-03-12 17:06:23 +01:00

417 lines
12 KiB
PHP

<?php
/**
* Subclass for representing a row from the 'sf_asset_folder' table.
*
*
*
* @package plugins.sfAssetsLibraryPlugin.lib.model
*/
class sfAssetFolder extends BasesfAssetFolder
{
public function __toString()
{
return $this->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,
))));