From: Roland Haeder Date: Mon, 12 May 2014 20:48:19 +0000 (+0200) Subject: Improved directory (non-recursive) reading: X-Git-Url: https://git.mxchange.org/?p=core.git;a=commitdiff_plain;h=84daf7f99e1af16ef9496e14f55ddf35f8657dc6 Improved directory (non-recursive) reading: - Refactured FrameworkDirectoryPointer to use DirectoryIterator (SPL). - The use of isDot() makes excluding '.' and '..' obsolete (would be double), so more classes can be improved here. - Also use ObjectFactory instead of direct class name for better flexibility. Signed-off-by: Roland Häder --- diff --git a/inc/classes/main/database/databases/class_LocalFileDatabase.php b/inc/classes/main/database/databases/class_LocalFileDatabase.php index ed849a99..dd1f5b74 100644 --- a/inc/classes/main/database/databases/class_LocalFileDatabase.php +++ b/inc/classes/main/database/databases/class_LocalFileDatabase.php @@ -350,7 +350,7 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { // find the 'table' which is in fact a directory on the server try { // Get a directory pointer instance - $directoryInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName); + $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); // Initialize the result data, this need to be rewritten e.g. if a local file cannot be read $resultData = array( @@ -364,7 +364,7 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { $idx = 1; // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { + while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { // Does the extension match? if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { // Skip this file! @@ -487,7 +487,7 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { // Try all the requests try { // Get a file pointer instance - $directoryInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName); + $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); // Initialize limit/skip $limitFound = 0; @@ -500,7 +500,7 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { $searchInstance = $dataSetInstance->getSearchInstance(); // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { + while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { // Does the extension match? if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { // Debug message diff --git a/inc/classes/main/io/class_FrameworkDirectoryPointer.php b/inc/classes/main/io/class_FrameworkDirectoryPointer.php index a8bf8358..26f2d854 100644 --- a/inc/classes/main/io/class_FrameworkDirectoryPointer.php +++ b/inc/classes/main/io/class_FrameworkDirectoryPointer.php @@ -1,6 +1,6 @@ * @version 0.0.0 @@ -28,9 +28,9 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { private $pathName = ''; /** - * The directory pointer + * The directory iterator instance */ - private $dirPointer = NULL; + private $directoryInstance = NULL; /** * Protected constructor @@ -45,10 +45,10 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { */ public function __destruct() { // Is there a resource pointer? Then we have to close the directory here! - if (is_resource($this->getPointer())) { + if ($this->getDirectoryInstance() instanceof DirectoryIterator) { // Try to close a directory $this->closeDirectory(); - } + } // END - if // Call the parent destructor parent::__destruct(); @@ -65,7 +65,7 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { * @throws InvalidPathStringException If the provided path name is not a string * @throws PathIsNoDirectoryException If the provided path name is not valid * @throws PathReadProtectedException If the provided path name is read-protected - * @throws DirPointerNotOpenedException If opendir() returns not a directory resource + * @todo Get rid of inConstructor, could be old-lost code. */ public static final function createFrameworkDirectoryPointer ($pathName, $inConstructor = FALSE) { // Some pre-sanity checks... @@ -99,22 +99,14 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { } } - // Try to open a handler - $dirPointer = @opendir($pathName); - if (!is_resource($dirPointer)) { - // Something bad happend - if ($inConstructor) { - return NULL; - } else { - throw new DirPointerNotOpenedException($pathName, self::EXCEPTION_DIR_POINTER_INVALID); - } - } + // Get an iterator for the directory + $directoryInstance = new DirectoryIterator($pathName); // Create new instance $pointerInstance = new FrameworkDirectoryPointer(); // Set directory pointer and path name - $pointerInstance->setPointer($dirPointer); + $pointerInstance->setDirectoryInstance($directoryInstance); $pointerInstance->setPathName($pathName); // Return the instance @@ -124,11 +116,26 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { /** * Read raw lines of data from a directory pointer and return the data * - * @return string Directory and/or file names read from the current directory pointer + * @return $current Current entry from encapsulated iterator */ public function readRawDirectory () { - // Read data from the directory pointer and return it - return readdir($this->getPointer()); + // Can the next entry be read? + assert($this->getDirectoryInstance()->valid()); + + // Is it a dot directory? + if ($this->getDirectoryInstance()->isDot()) { + // Then call this method recursive + $current = $this->readRawDirectory(); + } else { + // Read data from the directory pointer and return it + $current = $this->getDirectoryInstance()->current(); + } + + // Advance to next entry + $this->getDirectoryInstance()->next(); + + // Return found entry + return $current; } /** @@ -137,7 +144,8 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { * @param $except Some parts of a directory we want to ignore. Valid: directory and file names, other values will be silently ignored * @return string Directory and/or file names read from the current directory pointer */ - public function readDirectoryExcept (array $except = array('.', '..')) { + public function readDirectoryExcept (array $except = array()) { + // No exceptions given? if (count($except) == 0) { // No exception given, so read all data self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: No exceptions given, please use readRawDirectory() instead!'); @@ -146,20 +154,21 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { // Read a raw line... $rawLine = $this->readRawDirectory(); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawLine[' . gettype($rawLine) . ']=' . $rawLine); // Shall we exclude directories? if ((!is_null($rawLine)) && ($rawLine !== FALSE) && (!in_array($rawLine, $except))) { // Return read data - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawLine[' . gettype($rawLine) . ']=' . $rawLine); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawLine[' . gettype($rawLine) . ']=' . $rawLine); return $rawLine; } elseif ((!is_null($rawLine)) && ($rawLine !== FALSE)) { // Exclude this part - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawline[' . gettype($rawLine) . ']=' . $rawLine . ' - Recursive call!'); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawline[' . gettype($rawLine) . ']=' . $rawLine . ' - Recursive call!'); return $this->readDirectoryExcept($except); } // End pointer reached - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: Returning NULL!'); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: Returning NULL!'); return NULL; } @@ -170,36 +179,29 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { * @return void */ public function closeDirectory () { - // Close the directory pointer and reset the instance variable - @closedir($this->getPointer()); - $this->setPointer(NULL); + // Close the directory by unsetting it + $this->setDirectoryInstance(NULL); $this->setPathName(''); } /** * Setter for the directory pointer * - * @param $dirPointer The directory resource + * @param $directoryInstance An instanceof a DirectoryIterator class or NULL to unset ("close") it. * @return void */ - public final function setPointer ($dirPointer) { - // Sanity-check if pointer is a valid directory resource - if (is_resource($dirPointer) || is_null($dirPointer)) { - // Is a valid resource - $this->dirPointer = $dirPointer; - } else { - // Throw exception - throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE); - } + protected final function setDirectoryInstance (DirectoryIterator $directoryInstance = NULL) { + // Set instance (or NULL) + $this->directoryInstance = $directoryInstance; } /** * Getter for the directory pointer * - * @return $dirPointer The directory pointer which shall be a valid directory resource + * @return $directoryInstance The directory pointer which shall be a valid directory resource */ - public final function getPointer () { - return $this->dirPointer; + public final function getDirectoryInstance () { + return $this->directoryInstance; } /** diff --git a/inc/classes/middleware/compressor/class_CompressorChannel.php b/inc/classes/middleware/compressor/class_CompressorChannel.php index f5fb945b..c2ee4949 100644 --- a/inc/classes/middleware/compressor/class_CompressorChannel.php +++ b/inc/classes/middleware/compressor/class_CompressorChannel.php @@ -57,10 +57,10 @@ class CompressorChannel extends BaseMiddleware implements Registerable { $compressorInstance->getConfigInstance()->getConfigEntry('compressor_base_path'); // Get a directory pointer - $dirPointer = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($baseDir); + $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($baseDir)); - // Read all directories but no sub directories - while ($directoryEntry = $dirPointer->readDirectoryExcept(array('..', '.', '.htaccess', '.svn', 'class_NullCompressor.php'))) { + // Read all directories but no sub directories, .htaccess files and NullCompressor class + while ($directoryEntry = $directoryInstance->readDirectoryExcept(array('.htaccess', 'class_NullCompressor.php'))) { // Is this a class file? if ((substr($directoryEntry, 0, 6) == 'class_') && (substr($directoryEntry, -4, 4) == '.php')) { /* Get the compressor's name. That's why you must name @@ -87,7 +87,7 @@ class CompressorChannel extends BaseMiddleware implements Registerable { } // END - while // Close the directory - $dirPointer->closeDirectory(); + $directoryInstance->closeDirectory(); } // END - if // Check again if there is a compressor diff --git a/inc/config.php b/inc/config.php index 868f53fd..ba05848d 100644 --- a/inc/config.php +++ b/inc/config.php @@ -356,5 +356,8 @@ $cfg->setConfigEntry('hostname_file', '/etc/hostname'); // CFG: DATABASE-CACHE-ENABLED $cfg->setConfigEntry('database_cache_enabled', FALSE); +// CFG: DIRECTORY-CLASS +$cfg->setConfigEntry('directory_class', 'FrameworkDirectoryPointer'); + // [EOF] ?> diff --git a/inc/loader/class_ClassLoader.php b/inc/loader/class_ClassLoader.php index b50f3695..8b48d60a 100644 --- a/inc/loader/class_ClassLoader.php +++ b/inc/loader/class_ClassLoader.php @@ -279,9 +279,9 @@ class ClassLoader { // Get a new iterator //* DEBUG: */ echo "Base path: {$basePath}
\n"; - $iterator = new RecursiveDirectoryIterator($basePath); - $recursive = new RecursiveIteratorIterator($iterator); - foreach ($recursive as $entry) { + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basePath)); + + foreach ($iterator as $entry) { // Get filename from iterator $fileName = $entry->getFileName();