@@ -41,28 +41,25 @@ class LogException extends \Exception {
4141}
4242
4343
44- class RecursiveDirectoryIteratorWithoutData extends \RecursiveFilterIterator {
45- public function accept (): bool {
46- $ excludes = [
47- '.rnd ' ,
48- '.well-known ' ,
49- 'data ' ,
50- '.. ' ,
51- ];
44+ class RecursiveDirectoryIteratorFilter extends \RecursiveFilterIterator {
45+ private array $ excludedPaths ;
5246
53- /** @var \SplFileInfo|false */
54- $ current = $ this ->current ();
55- if (!$ current ) {
56- return false ;
57- }
47+ public function __construct (
48+ \RecursiveDirectoryIterator $ iterator ,
49+ array $ excludedPaths = ['data ' ],
50+ ) {
51+ parent ::__construct ($ iterator );
52+ $ this ->excludedPaths = array_flip ($ excludedPaths );
53+ }
5854
59- return !(in_array ($ current ->getFilename (), $ excludes , true ) || $ current ->isDir ());
55+ public function accept (): bool {
56+ return !isset ($ this ->excludedPaths [$ this ->current ()->getFilename ()]);
6057 }
6158}
6259
6360
6461class Updater {
65- private string $ baseDir ;
62+ private string $ nextcloudDir ;
6663 private array $ configValues = [];
6764 private string $ currentVersion = 'unknown ' ;
6865 private string $ buildTime ;
@@ -75,13 +72,15 @@ class Updater {
7572 * @param string $baseDir the absolute path to the /updater/ directory in the Nextcloud root
7673 * @throws \Exception
7774 */
78- public function __construct (string $ baseDir ) {
79- $ this ->baseDir = $ baseDir ;
75+ public function __construct (
76+ private string $ baseDir
77+ ) {
78+ $ this ->nextcloudDir = realpath (dirname ($ baseDir ));
8079
8180 if ($ dir = getenv ('NEXTCLOUD_CONFIG_DIR ' )) {
82- $ configFileName = rtrim ($ dir, ' / ' ) . '/config.php ' ;
81+ $ configFileName = realpath ($ dir . '/config.php ' ) ;
8382 } else {
84- $ configFileName = $ this ->baseDir . '/.. /config/config.php ' ;
83+ $ configFileName = $ this ->nextcloudDir . '/config/config.php ' ;
8584 }
8685 if (!file_exists ($ configFileName )) {
8786 throw new \Exception ('Could not find config.php. Is this file in the "updater" subfolder of Nextcloud? ' );
@@ -102,7 +101,7 @@ public function __construct(string $baseDir) {
102101 throw new \Exception ('Could not read data directory from config.php. ' );
103102 }
104103
105- $ versionFileName = $ this ->baseDir . '/.. /version.php ' ;
104+ $ versionFileName = $ this ->nextcloudDir . '/version.php ' ;
106105 if (!file_exists ($ versionFileName )) {
107106 // fallback to version in config.php
108107 $ version = $ this ->getConfigOptionString ('version ' );
@@ -133,27 +132,23 @@ public function __construct(string $baseDir) {
133132
134133 /**
135134 * Returns whether the web updater is disabled
136- *
137- * @return bool
138135 */
139- public function isDisabled () {
136+ public function isDisabled (): bool {
140137 return $ this ->disabled ;
141138 }
142139
143140 /**
144141 * Returns current version or "unknown" if this could not be determined.
145- *
146- * @return string
147142 */
148- public function getCurrentVersion () {
143+ public function getCurrentVersion (): string {
149144 return $ this ->currentVersion ;
150145 }
151146
152147 /**
153148 * Returns currently used release channel
154149 */
155150 private function getCurrentReleaseChannel (): string {
156- return ( $ this ->getConfigOptionString ('updater.release.channel ' ) ?? 'stable ' ) ;
151+ return $ this ->getConfigOptionString ('updater.release.channel ' ) ?? 'stable ' ;
157152 }
158153
159154 /**
@@ -323,16 +318,19 @@ private function getAppDirectories(): array {
323318 /**
324319 * Gets the recursive directory iterator over the Nextcloud folder
325320 *
326- * @return \RecursiveIteratorIterator<\RecursiveDirectoryIterator>
321+ * @return \RecursiveIteratorIterator<\RecursiveDirectoryIterator|RecursiveDirectoryIteratorFilter >
327322 */
328- private function getRecursiveDirectoryIterator (?string $ folder = null ): \RecursiveIteratorIterator {
323+ private function getRecursiveDirectoryIterator (?string $ folder = null , array $ excludedPaths = [] ): \RecursiveIteratorIterator {
329324 if ($ folder === null ) {
330325 $ folder = $ this ->baseDir . '/../ ' ;
331326 }
332- return new \RecursiveIteratorIterator (
333- new \RecursiveDirectoryIterator ($ folder , \RecursiveDirectoryIterator::SKIP_DOTS ),
334- \RecursiveIteratorIterator::CHILD_FIRST
335- );
327+
328+ $ iterator = new \RecursiveDirectoryIterator ($ folder , \FilesystemIterator::SKIP_DOTS );
329+ if (!empty ($ excludedPaths )) {
330+ $ iterator = new RecursiveDirectoryIteratorFilter ($ iterator , $ excludedPaths );
331+ }
332+
333+ return new \RecursiveIteratorIterator ($ iterator , \RecursiveIteratorIterator::CHILD_FIRST );
336334 }
337335
338336 /**
@@ -343,7 +341,7 @@ public function checkForExpectedFilesAndFolders(): void {
343341
344342 $ expectedElements = $ this ->getExpectedElementsList ();
345343 $ unexpectedElements = [];
346- foreach (new \DirectoryIterator ($ this ->baseDir . ' /../ ' ) as $ fileInfo ) {
344+ foreach (new \DirectoryIterator ($ this ->nextcloudDir ) as $ fileInfo ) {
347345 if (array_search ($ fileInfo ->getFilename (), $ expectedElements ) === false ) {
348346 $ unexpectedElements [] = $ fileInfo ->getFilename ();
349347 }
@@ -361,15 +359,21 @@ public function checkForExpectedFilesAndFolders(): void {
361359 public function checkWritePermissions (): void {
362360 $ this ->silentLog ('[info] checkWritePermissions() ' );
363361
364- $ notWritablePaths = array ();
365- $ dir = new \RecursiveDirectoryIterator ($ this ->baseDir . '/../ ' );
366- $ filter = new RecursiveDirectoryIteratorWithoutData ($ dir );
367- /** @var iterable<string, \SplFileInfo> */
368- $ it = new \RecursiveIteratorIterator ($ filter );
362+ $ excludedPaths = [
363+ '.rnd ' => true ,
364+ '.well-known ' => true ,
365+ 'data ' => true ,
366+ ];
367+
368+ $ it = new \DirectoryIterator ($ this ->nextcloudDir );
369369
370- foreach ($ it as $ path => $ dir ) {
371- if (!is_writable ($ path )) {
372- $ notWritablePaths [] = $ path ;
370+ $ notWritablePaths = [];
371+ foreach ($ it as $ path => $ fileInfo ) {
372+ if ($ fileInfo ->isDot () || isset ($ excludedPaths [$ fileInfo ->getFilename ()])) {
373+ continue ;
374+ }
375+ if (!$ fileInfo ->isWritable ()) {
376+ $ notWritablePaths [] = $ fileInfo ->getFilename ();
373377 }
374378 }
375379 if (count ($ notWritablePaths ) > 0 ) {
@@ -442,7 +446,7 @@ public function createBackup(): void {
442446 * @var string $path
443447 * @var \SplFileInfo $fileInfo
444448 */
445- foreach ($ this ->getRecursiveDirectoryIterator ($ currentDir ) as $ path => $ fileInfo ) {
449+ foreach ($ this ->getRecursiveDirectoryIterator ($ currentDir, $ excludedElements ) as $ path => $ fileInfo ) {
446450 $ fileName = explode ($ currentDir , $ path )[1 ];
447451 $ folderStructure = explode ('/ ' , $ fileName , -1 );
448452
@@ -971,8 +975,9 @@ public function deleteOldFiles(): void {
971975 }
972976
973977 /**
974- * Moves the specified filed except the excluded elements to the correct position
978+ * Moves the specified files except the excluded elements to the correct position
975979 *
980+ * @param string[] $excludedElements
976981 * @throws \Exception
977982 */
978983 private function moveWithExclusions (string $ dataLocation , array $ excludedElements ): void {
0 commit comments