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