. */ namespace Doctrine\ORM\Mapping\Driver; use Doctrine\ORM\Mapping\MappingException; /** * Base driver for file-based metadata drivers. * * A file driver operates in a mode where it loads the mapping files of individual * classes on demand. This requires the user to adhere to the convention of 1 mapping * file per class and the file names of the mapping files must correspond to the full * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'. * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.doctrine-project.com * @since 2.0 * @version $Revision$ * @author Benjamin Eberlei * @author Guilherme Blanco * @author Jonathan H. Wage * @author Roman Borschel */ abstract class AbstractFileDriver implements Driver { /** * The paths where to look for mapping files. * * @var array */ protected $_paths = array(); /** * The file extension of mapping documents. * * @var string */ protected $_fileExtension; /** * Initializes a new FileDriver that looks in the given path(s) for mapping * documents and operates in the specified operating mode. * * @param string|array $paths One or multiple paths where mapping documents can be found. */ public function __construct($paths) { $this->addPaths((array) $paths); } /** * Append lookup paths to metadata driver. * * @param array $paths */ public function addPaths(array $paths) { $this->_paths = array_unique(array_merge($this->_paths, $paths)); } /** * Retrieve the defined metadata lookup paths. * * @return array */ public function getPaths() { return $this->_paths; } /** * Get the file extension used to look for mapping files under * * @return void */ public function getFileExtension() { return $this->_fileExtension; } /** * Set the file extension used to look for mapping files under * * @param string $fileExtension The file extension to set * @return void */ public function setFileExtension($fileExtension) { $this->_fileExtension = $fileExtension; } /** * Get the element of schema meta data for the class from the mapping file. * This will lazily load the mapping file if it is not loaded yet * * @return array $element The element of schema meta data */ public function getElement($className) { $result = $this->_loadMappingFile($this->_findMappingFile($className)); return $result[$className]; } /** * Whether the class with the specified name should have its metadata loaded. * This is only the case if it is either mapped as an Entity or a * MappedSuperclass. * * @param string $className * @return boolean */ public function isTransient($className) { $fileName = str_replace('\\', '.', $className) . $this->_fileExtension; // Check whether file exists foreach ((array) $this->_paths as $path) { if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) { return false; } } return true; } /** * Gets the names of all mapped classes known to this driver. * * @return array The names of all mapped classes known to this driver. */ public function getAllClassNames() { $classes = array(); if ($this->_paths) { foreach ((array) $this->_paths as $path) { if ( ! is_dir($path)) { throw MappingException::driverRequiresConfiguredDirectoryPath(); } $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($iterator as $file) { if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) { continue; } // NOTE: All files found here means classes are not transient! $classes[] = str_replace('.', '\\', $fileName); } } } return $classes; } /** * Finds the mapping file for the class with the given name by searching * through the configured paths. * * @param $className * @return string The (absolute) file name. * @throws MappingException */ protected function _findMappingFile($className) { $fileName = str_replace('\\', '.', $className) . $this->_fileExtension; // Check whether file exists foreach ((array) $this->_paths as $path) { if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) { return $path . DIRECTORY_SEPARATOR . $fileName; } } throw MappingException::mappingFileNotFound($className, $fileName); } /** * Loads a mapping file with the given name and returns a map * from class/entity names to their corresponding elements. * * @param string $file The mapping file to load. * @return array */ abstract protected function _loadMappingFile($file); }