]> git.mxchange.org Git - core.git/blob - framework/main/classes/file_directories/directory/class_FrameworkDirectoryPointer.php
Continued:
[core.git] / framework / main / classes / file_directories / directory / class_FrameworkDirectoryPointer.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Filesytem\Pointer;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Filesystem\FrameworkDirectory;
7 use Org\Mxchange\CoreFramework\Generic\NullPointerException;
8 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
9
10 // Deprecated imports
11 use Org\Mxchange\CoreFramework\Deprecated\PathIsNoDirectoryException;
12
13 // Import SPL stuff
14 use \DirectoryIterator;
15
16 /**
17  * A class for directory reading and getting its contents, no recursion!
18  *
19  * @author              Roland Haeder <webmaster@shipsimu.org>
20  * @version             0.0.0
21  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
22  * @license             GNU GPL 3.0 or any newer version
23  * @link                http://www.shipsimu.org
24  *
25  * This program is free software: you can redistribute it and/or modify
26  * it under the terms of the GNU General Public License as published by
27  * the Free Software Foundation, either version 3 of the License, or
28  * (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program. If not, see <http://www.gnu.org/licenses/>.
37  */
38 class FrameworkDirectoryPointer extends BaseFrameworkSystem implements FrameworkDirectory {
39         /**
40          * The current path we are working in
41          */
42         private $pathName = '';
43
44         /**
45          * The directory iterator instance
46          */
47         private $iteratorInstance = NULL;
48
49         /**
50          * Protected constructor
51          */
52         protected function __construct () {
53                 // Call parent constructor
54                 parent::__construct(__CLASS__);
55         }
56
57         /**
58          * Destructor for cleaning purposes, etc
59          */
60         public function __destruct() {
61                 // Is there a resource pointer? Then we have to close the directory here!
62                 if ($this->getDirectoryIteratorInstance() instanceof DirectoryIterator) {
63                         // Try to close a directory
64                         $this->closeDirectory();
65                 } // END - if
66
67                 // Call the parent destructor
68                 parent::__destruct();
69         }
70
71         /**
72          * Create a directory pointer based on the given path. The path will also
73          * be verified here.
74          *
75          * @param       $pathName               The path name we shall pass to opendir()
76          * @return      $pointerInstance        A prepared instance of FrameworkDirectoryPointer
77          * @throws      NullPointerException    If the provided path name is null
78          * @throws      InvalidPathStringException      If the provided path name is not a string
79          * @throws      PathIsNoDirectoryException      If the provided path name is not valid
80          * @throws      PathReadProtectedException      If the provided path name is read-protected
81          */
82         public static final function createFrameworkDirectoryPointer ($pathName) {
83                 // Some pre-sanity checks...
84                 if (is_null($pathName)) {
85                         // No pathname given
86                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
87                 } elseif (!is_string($pathName)) {
88                         // Is not a string
89                         throw new InvalidPathStringException(NULL, self::EXCEPTION_INVALID_STRING);
90                 } elseif (!is_dir($pathName)) {
91                         // Not a directory
92                         throw new PathIsNoDirectoryException($pathName, self::EXCEPTION_INVALID_PATH_NAME);
93                 } elseif (!is_readable($pathName)) {
94                         // Not readable
95                         throw new PathReadProtectedException($pathName, self::EXCEPTION_READ_PROTECED_PATH);
96                 }
97
98                 // Create new instance
99                 $pointerInstance = new FrameworkDirectoryPointer();
100
101                 // Get an iterator for the directory
102                 $iteratorInstance = new DirectoryIterator($pathName);
103
104                 // ... and rewind back
105                 $iteratorInstance->rewind();
106
107                 // Set directory pointer and path name
108                 $pointerInstance->setDirectoryIteratorInstance($iteratorInstance);
109                 $pointerInstance->setPathName($pathName);
110
111                 // Return the instance
112                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DIRECTORY-POINTER: Opened pathName=' . $pathName . ' - EXIT!');
113                 return $pointerInstance;
114         }
115
116         /**
117          * Read raw lines of data from a directory pointer and return the data
118          *
119          * @return      $currentEntry   Current entry from encapsulated iterator
120          */
121         public function readRawDirectory () {
122                 // Can the next entry be read?
123                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DIRECTORY-POINTER: CALLED!');
124                 assert($this->getDirectoryIteratorInstance()->valid());
125
126                 // Read data from the directory pointer and return it
127                 $currentEntry = $this->getDirectoryIteratorInstance()->current();
128
129                 // Return found entry
130                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('DIRECTORY-POINTER: currentEntry[%s]=%s - EXIT!', gettype($currentEntry), $currentEntry));
131                 return $currentEntry;
132         }
133
134         /**
135          * Read lines from the current directory pointer except some parts
136          *
137          * @param       $except         Some parts of a directory we want to ignore. Valid: directory and file names, other values will be silently ignored
138          * @return      SplFileInfo             An instance of a SplFileInfo class
139          */
140         public function readDirectoryExcept (array $except = []) {
141                 // No exceptions given?
142                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('DIRECTORY-POINTER: except()=%d - CALLED!', count($except)));
143                 if (count($except) == 0) {
144                         // No exception given, so read all files and directories, but not recursive
145                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DIRECTORY-POINTER: No exceptions given, please use readRawDirectory() instead!');
146                         return $this->readRawDirectory();
147                 } elseif (!$this->getDirectoryIteratorInstance()->valid()) {
148                         // No more left to read
149                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DIRECTORY-POINTER: EOD reached - EXIT!');
150                         return NULL;
151                 }
152
153                 // Init raw line
154                 $fileInfoInstance = NULL;
155
156                 // Read a raw line...
157                 $currentEntry = $this->readRawDirectory();
158
159                 // Shall we exclude directories?
160                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('DIRECTORY-POINTER: currentEntry[]=%s', gettype($currentEntry)));
161                 if (is_object($currentEntry)) {
162                         // Get file name
163                         $fileInfoInstance = $currentEntry;
164
165                         // Is it a dot-directory or excluded?
166                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('DIRECTORY-POINTER: fileInfoInstance->filename=%s,isDot=%d', $fileInfoInstance->getFilename(), intval($this->getDirectoryIteratorInstance()->isDot())));
167                         while ($this->getDirectoryIteratorInstance()->valid() && ($this->getDirectoryIteratorInstance()->isDot() || in_array($fileInfoInstance->getFilename(), $except))) {
168                                 // Update current instance
169                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('DIRECTORY-POINTER: fileInfoInstance->filename=%s,isDot=%d', $fileInfoInstance->getFilename(), intval($this->getDirectoryIteratorInstance()->isDot())));
170                                 $fileInfoInstance = $this->readRawDirectory();
171
172                                 // To next entry
173                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DIRECTORY-POINTER: Invoking directoryIteratorInstance->next() ...');
174                                 $this->getDirectoryIteratorInstance()->next();
175                         } // END - while
176                 } // END - if
177
178                 // Return read line
179                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('DIRECTORY-POINTER: fileInfoInstance[%s]=%s - EXIT!', gettype($fileInfoInstance), $fileInfoInstance));
180                 return $fileInfoInstance;
181         }
182
183         /**
184          * Close a directory source and set it's instance to null and the path name
185          * to empty
186          *
187          * @return      void
188          */
189         public function closeDirectory () {
190                 // Close the directory by unsetting it
191                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DIRECTORY-POINTER: CALLED!');
192                 $this->unsetDirectoryIteratorInstance();
193                 $this->setPathName('');
194         }
195
196         /**
197          * Setter for the directory pointer
198          *
199          * @param       $iteratorInstance       An instanceof a DirectoryIterator class
200          * @return      void
201          */
202         protected final function setDirectoryIteratorInstance (DirectoryIterator $iteratorInstance) {
203                 // Set instance
204                 $this->iteratorInstance = $iteratorInstance;
205         }
206
207         /**
208          * Getter for the directory pointer
209          *
210          * @return      $iteratorInstance       The directory pointer which shall be a valid directory resource
211          */
212         public final function getDirectoryIteratorInstance () {
213                 return $this->iteratorInstance;
214         }
215
216         /**
217          * Remove directory iterator instance (effectively closing it) by setting
218          * it to NULL. This will trigger a call on the destructor which will then
219          * "close" the iterator.
220          *
221          * @param       $iteratorInstance       An instanceof a DirectoryIterator class
222          * @return      void
223          */
224         protected final function unsetDirectoryIteratorInstance () {
225                 // "Unset" the instance
226                 $this->iteratorInstance = NULL;
227         }
228
229         /**
230          * Setter for path name
231          *
232          * @param       $pathName       The new path name
233          * @return      void
234          */
235         protected final function setPathName ($pathName) {
236                 $pathName = (string) $pathName;
237                 $this->pathName = $pathName;
238         }
239
240         /**
241          * Getter for path name
242          *
243          * @return      $pathName       The current path name
244          */
245         public final function getPathName () {
246                 return $this->pathName;
247         }
248
249 }