Completed
Push — master ( 0e0abc...c66870 )
by
unknown
46:34 queued 16:16
created
apps/files/lib/Command/SanitizeFilenames.php 1 patch
Indentation   +138 added lines, -138 removed lines patch added patch discarded remove patch
@@ -26,143 +26,143 @@
 block discarded – undo
26 26
 
27 27
 class SanitizeFilenames extends Base {
28 28
 
29
-	private OutputInterface $output;
30
-	private string $charReplacement;
31
-	private bool $dryRun;
32
-
33
-	public function __construct(
34
-		private IUserManager $userManager,
35
-		private IRootFolder $rootFolder,
36
-		private IUserSession $session,
37
-		private IFactory $l10nFactory,
38
-		private FilenameValidator $filenameValidator,
39
-	) {
40
-		parent::__construct();
41
-	}
42
-
43
-	protected function configure(): void {
44
-		parent::configure();
45
-
46
-		$forbiddenCharacter = $this->filenameValidator->getForbiddenCharacters();
47
-		$charReplacement = array_diff([' ', '_', '-'], $forbiddenCharacter);
48
-		$charReplacement = reset($charReplacement) ?: '';
49
-
50
-		$this
51
-			->setName('files:sanitize-filenames')
52
-			->setDescription('Renames files to match naming constraints')
53
-			->addArgument(
54
-				'user_id',
55
-				InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
56
-				'will only rename files the given user(s) have access to'
57
-			)
58
-			->addOption(
59
-				'dry-run',
60
-				mode: InputOption::VALUE_NONE,
61
-				description: 'Do not actually rename any files but just check filenames.',
62
-			)
63
-			->addOption(
64
-				'char-replacement',
65
-				'c',
66
-				mode: InputOption::VALUE_REQUIRED,
67
-				description: 'Replacement for invalid character (by default space, underscore or dash is used)',
68
-				default: $charReplacement,
69
-			);
29
+    private OutputInterface $output;
30
+    private string $charReplacement;
31
+    private bool $dryRun;
32
+
33
+    public function __construct(
34
+        private IUserManager $userManager,
35
+        private IRootFolder $rootFolder,
36
+        private IUserSession $session,
37
+        private IFactory $l10nFactory,
38
+        private FilenameValidator $filenameValidator,
39
+    ) {
40
+        parent::__construct();
41
+    }
42
+
43
+    protected function configure(): void {
44
+        parent::configure();
45
+
46
+        $forbiddenCharacter = $this->filenameValidator->getForbiddenCharacters();
47
+        $charReplacement = array_diff([' ', '_', '-'], $forbiddenCharacter);
48
+        $charReplacement = reset($charReplacement) ?: '';
49
+
50
+        $this
51
+            ->setName('files:sanitize-filenames')
52
+            ->setDescription('Renames files to match naming constraints')
53
+            ->addArgument(
54
+                'user_id',
55
+                InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
56
+                'will only rename files the given user(s) have access to'
57
+            )
58
+            ->addOption(
59
+                'dry-run',
60
+                mode: InputOption::VALUE_NONE,
61
+                description: 'Do not actually rename any files but just check filenames.',
62
+            )
63
+            ->addOption(
64
+                'char-replacement',
65
+                'c',
66
+                mode: InputOption::VALUE_REQUIRED,
67
+                description: 'Replacement for invalid character (by default space, underscore or dash is used)',
68
+                default: $charReplacement,
69
+            );
70 70
 			
71
-	}
72
-
73
-	protected function execute(InputInterface $input, OutputInterface $output): int {
74
-		$this->charReplacement = $input->getOption('char-replacement');
75
-		if ($this->charReplacement === '' || mb_strlen($this->charReplacement) > 1) {
76
-			$output->writeln('<error>No character replacement given</error>');
77
-			return 1;
78
-		}
79
-
80
-		$this->dryRun = $input->getOption('dry-run');
81
-		if ($this->dryRun) {
82
-			$output->writeln('<info>Dry run is enabled, no actual renaming will be applied.</>');
83
-		}
84
-
85
-		$this->output = $output;
86
-		$users = $input->getArgument('user_id');
87
-		if (!empty($users)) {
88
-			foreach ($users as $userId) {
89
-				$user = $this->userManager->get($userId);
90
-				if ($user === null) {
91
-					$output->writeln("<error>User '$userId' does not exist - skipping</>");
92
-					continue;
93
-				}
94
-				$this->sanitizeUserFiles($user);
95
-			}
96
-		} else {
97
-			$this->userManager->callForSeenUsers($this->sanitizeUserFiles(...));
98
-		}
99
-		return self::SUCCESS;
100
-	}
101
-
102
-	private function sanitizeUserFiles(IUser $user): void {
103
-		// Set an active user so that event listeners can correctly work (e.g. files versions)
104
-		$this->session->setVolatileActiveUser($user);
105
-
106
-		$this->output->writeln('<info>Analyzing files of ' . $user->getUID() . '</>');
107
-
108
-		$folder = $this->rootFolder->getUserFolder($user->getUID());
109
-		$this->sanitizeFiles($folder);
110
-	}
111
-
112
-	private function sanitizeFiles(Folder $folder): void {
113
-		foreach ($folder->getDirectoryListing() as $node) {
114
-			$this->output->writeln('scanning: ' . $node->getPath(), OutputInterface::VERBOSITY_VERBOSE);
115
-
116
-			try {
117
-				$oldName = $node->getName();
118
-				if (!$this->filenameValidator->isFilenameValid($oldName)) {
119
-					$newName = $this->sanitizeName($oldName);
120
-					$newName = $folder->getNonExistingName($newName);
121
-					$path = rtrim(dirname($node->getPath()), '/');
122
-
123
-					if (!$this->dryRun) {
124
-						$node->move("$path/$newName");
125
-					} elseif (!$folder->isCreatable()) {
126
-						// simulate error for dry run
127
-						throw new NotPermittedException();
128
-					}
129
-					$this->output->writeln('renamed: "' . $oldName . '" to "' . $newName . '"');
130
-				}
131
-			} catch (LockedException) {
132
-				$this->output->writeln('<comment>skipping: ' . $node->getPath() . ' (file is locked)</>');
133
-			} catch (NotPermittedException) {
134
-				$this->output->writeln('<comment>skipping: ' . $node->getPath() . ' (no permissions)</>');
135
-			} catch (Exception) {
136
-				$this->output->writeln('<error>failed: ' . $node->getPath() . '</>');
137
-			}
138
-
139
-			if ($node instanceof Folder) {
140
-				$this->sanitizeFiles($node);
141
-			}
142
-		}
143
-	}
144
-
145
-	private function sanitizeName(string $name): string {
146
-		$l10n = $this->l10nFactory->get('files');
147
-
148
-		foreach ($this->filenameValidator->getForbiddenExtensions() as $extension) {
149
-			if (str_ends_with($name, $extension)) {
150
-				$name = substr($name, 0, strlen($name) - strlen($extension));
151
-			}
152
-		}
153
-
154
-		$basename = substr($name, 0, strpos($name, '.', 1) ?: null);
155
-		if (in_array($basename, $this->filenameValidator->getForbiddenBasenames())) {
156
-			$name = str_replace($basename, $l10n->t('%1$s (renamed)', [$basename]), $name);
157
-		}
158
-
159
-		if ($name === '') {
160
-			$name = $l10n->t('renamed file');
161
-		}
162
-
163
-		$forbiddenCharacter = $this->filenameValidator->getForbiddenCharacters();
164
-		$name = str_replace($forbiddenCharacter, $this->charReplacement, $name);
165
-
166
-		return $name;
167
-	}
71
+    }
72
+
73
+    protected function execute(InputInterface $input, OutputInterface $output): int {
74
+        $this->charReplacement = $input->getOption('char-replacement');
75
+        if ($this->charReplacement === '' || mb_strlen($this->charReplacement) > 1) {
76
+            $output->writeln('<error>No character replacement given</error>');
77
+            return 1;
78
+        }
79
+
80
+        $this->dryRun = $input->getOption('dry-run');
81
+        if ($this->dryRun) {
82
+            $output->writeln('<info>Dry run is enabled, no actual renaming will be applied.</>');
83
+        }
84
+
85
+        $this->output = $output;
86
+        $users = $input->getArgument('user_id');
87
+        if (!empty($users)) {
88
+            foreach ($users as $userId) {
89
+                $user = $this->userManager->get($userId);
90
+                if ($user === null) {
91
+                    $output->writeln("<error>User '$userId' does not exist - skipping</>");
92
+                    continue;
93
+                }
94
+                $this->sanitizeUserFiles($user);
95
+            }
96
+        } else {
97
+            $this->userManager->callForSeenUsers($this->sanitizeUserFiles(...));
98
+        }
99
+        return self::SUCCESS;
100
+    }
101
+
102
+    private function sanitizeUserFiles(IUser $user): void {
103
+        // Set an active user so that event listeners can correctly work (e.g. files versions)
104
+        $this->session->setVolatileActiveUser($user);
105
+
106
+        $this->output->writeln('<info>Analyzing files of ' . $user->getUID() . '</>');
107
+
108
+        $folder = $this->rootFolder->getUserFolder($user->getUID());
109
+        $this->sanitizeFiles($folder);
110
+    }
111
+
112
+    private function sanitizeFiles(Folder $folder): void {
113
+        foreach ($folder->getDirectoryListing() as $node) {
114
+            $this->output->writeln('scanning: ' . $node->getPath(), OutputInterface::VERBOSITY_VERBOSE);
115
+
116
+            try {
117
+                $oldName = $node->getName();
118
+                if (!$this->filenameValidator->isFilenameValid($oldName)) {
119
+                    $newName = $this->sanitizeName($oldName);
120
+                    $newName = $folder->getNonExistingName($newName);
121
+                    $path = rtrim(dirname($node->getPath()), '/');
122
+
123
+                    if (!$this->dryRun) {
124
+                        $node->move("$path/$newName");
125
+                    } elseif (!$folder->isCreatable()) {
126
+                        // simulate error for dry run
127
+                        throw new NotPermittedException();
128
+                    }
129
+                    $this->output->writeln('renamed: "' . $oldName . '" to "' . $newName . '"');
130
+                }
131
+            } catch (LockedException) {
132
+                $this->output->writeln('<comment>skipping: ' . $node->getPath() . ' (file is locked)</>');
133
+            } catch (NotPermittedException) {
134
+                $this->output->writeln('<comment>skipping: ' . $node->getPath() . ' (no permissions)</>');
135
+            } catch (Exception) {
136
+                $this->output->writeln('<error>failed: ' . $node->getPath() . '</>');
137
+            }
138
+
139
+            if ($node instanceof Folder) {
140
+                $this->sanitizeFiles($node);
141
+            }
142
+        }
143
+    }
144
+
145
+    private function sanitizeName(string $name): string {
146
+        $l10n = $this->l10nFactory->get('files');
147
+
148
+        foreach ($this->filenameValidator->getForbiddenExtensions() as $extension) {
149
+            if (str_ends_with($name, $extension)) {
150
+                $name = substr($name, 0, strlen($name) - strlen($extension));
151
+            }
152
+        }
153
+
154
+        $basename = substr($name, 0, strpos($name, '.', 1) ?: null);
155
+        if (in_array($basename, $this->filenameValidator->getForbiddenBasenames())) {
156
+            $name = str_replace($basename, $l10n->t('%1$s (renamed)', [$basename]), $name);
157
+        }
158
+
159
+        if ($name === '') {
160
+            $name = $l10n->t('renamed file');
161
+        }
162
+
163
+        $forbiddenCharacter = $this->filenameValidator->getForbiddenCharacters();
164
+        $name = str_replace($forbiddenCharacter, $this->charReplacement, $name);
165
+
166
+        return $name;
167
+    }
168 168
 }
Please login to merge, or discard this patch.
apps/files/lib/Command/WindowsCompatibleFilenames.php 1 patch
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -15,38 +15,38 @@
 block discarded – undo
15 15
 
16 16
 class WindowsCompatibleFilenames extends Base {
17 17
 
18
-	public function __construct(
19
-		private SettingsService $service,
20
-	) {
21
-		parent::__construct();
22
-	}
23
-
24
-	protected function configure(): void {
25
-		parent::configure();
26
-
27
-		$this
28
-			->setName('files:windows-compatible-filenames')
29
-			->setDescription('Enforce naming constraints for windows compatible filenames')
30
-			->addOption('enable', description: 'Enable windows naming constraints')
31
-			->addOption('disable', description: 'Disable windows naming constraints');
32
-	}
33
-
34
-	protected function execute(InputInterface $input, OutputInterface $output): int {
35
-		if ($input->getOption('enable')) {
36
-			if ($this->service->hasFilesWindowsSupport()) {
37
-				$output->writeln('<error>Windows compatible filenames already enforced.</error>', OutputInterface::VERBOSITY_VERBOSE);
38
-			}
39
-			$this->service->setFilesWindowsSupport(true);
40
-			$output->writeln('Windows compatible filenames enforced.');
41
-		} elseif ($input->getOption('disable')) {
42
-			if (!$this->service->hasFilesWindowsSupport()) {
43
-				$output->writeln('<error>Windows compatible filenames already disabled.</error>', OutputInterface::VERBOSITY_VERBOSE);
44
-			}
45
-			$this->service->setFilesWindowsSupport(false);
46
-			$output->writeln('Windows compatible filename constraints removed.');
47
-		} else {
48
-			$output->writeln('Windows compatible filenames are ' . ($this->service->hasFilesWindowsSupport() ? 'enforced' : 'disabled'));
49
-		}
50
-		return self::SUCCESS;
51
-	}
18
+    public function __construct(
19
+        private SettingsService $service,
20
+    ) {
21
+        parent::__construct();
22
+    }
23
+
24
+    protected function configure(): void {
25
+        parent::configure();
26
+
27
+        $this
28
+            ->setName('files:windows-compatible-filenames')
29
+            ->setDescription('Enforce naming constraints for windows compatible filenames')
30
+            ->addOption('enable', description: 'Enable windows naming constraints')
31
+            ->addOption('disable', description: 'Disable windows naming constraints');
32
+    }
33
+
34
+    protected function execute(InputInterface $input, OutputInterface $output): int {
35
+        if ($input->getOption('enable')) {
36
+            if ($this->service->hasFilesWindowsSupport()) {
37
+                $output->writeln('<error>Windows compatible filenames already enforced.</error>', OutputInterface::VERBOSITY_VERBOSE);
38
+            }
39
+            $this->service->setFilesWindowsSupport(true);
40
+            $output->writeln('Windows compatible filenames enforced.');
41
+        } elseif ($input->getOption('disable')) {
42
+            if (!$this->service->hasFilesWindowsSupport()) {
43
+                $output->writeln('<error>Windows compatible filenames already disabled.</error>', OutputInterface::VERBOSITY_VERBOSE);
44
+            }
45
+            $this->service->setFilesWindowsSupport(false);
46
+            $output->writeln('Windows compatible filename constraints removed.');
47
+        } else {
48
+            $output->writeln('Windows compatible filenames are ' . ($this->service->hasFilesWindowsSupport() ? 'enforced' : 'disabled'));
49
+        }
50
+        return self::SUCCESS;
51
+    }
52 52
 }
Please login to merge, or discard this patch.
apps/files/lib/Settings/DeclarativeAdminSettings.php 1 patch
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -16,52 +16,52 @@
 block discarded – undo
16 16
 
17 17
 class DeclarativeAdminSettings implements IDeclarativeSettingsFormWithHandlers {
18 18
 
19
-	public function __construct(
20
-		private IL10N $l,
21
-		private SettingsService $service,
22
-		private IURLGenerator $urlGenerator,
23
-	) {
24
-	}
19
+    public function __construct(
20
+        private IL10N $l,
21
+        private SettingsService $service,
22
+        private IURLGenerator $urlGenerator,
23
+    ) {
24
+    }
25 25
 
26
-	public function getValue(string $fieldId, IUser $user): mixed {
27
-		return match($fieldId) {
28
-			'windows_support' => $this->service->hasFilesWindowsSupport(),
29
-			default => throw new \InvalidArgumentException('Unexpected field id ' . $fieldId),
30
-		};
31
-	}
26
+    public function getValue(string $fieldId, IUser $user): mixed {
27
+        return match($fieldId) {
28
+            'windows_support' => $this->service->hasFilesWindowsSupport(),
29
+            default => throw new \InvalidArgumentException('Unexpected field id ' . $fieldId),
30
+        };
31
+    }
32 32
 
33
-	public function setValue(string $fieldId, mixed $value, IUser $user): void {
34
-		switch ($fieldId) {
35
-			case 'windows_support':
36
-				$this->service->setFilesWindowsSupport((bool)$value);
37
-				break;
38
-		}
39
-	}
33
+    public function setValue(string $fieldId, mixed $value, IUser $user): void {
34
+        switch ($fieldId) {
35
+            case 'windows_support':
36
+                $this->service->setFilesWindowsSupport((bool)$value);
37
+                break;
38
+        }
39
+    }
40 40
 
41
-	public function getSchema(): array {
42
-		return [
43
-			'id' => 'files-filename-support',
44
-			'priority' => 10,
45
-			'section_type' => DeclarativeSettingsTypes::SECTION_TYPE_ADMIN,
46
-			'section_id' => 'server',
47
-			'storage_type' => DeclarativeSettingsTypes::STORAGE_TYPE_EXTERNAL,
48
-			'title' => $this->l->t('Files compatibility'),
49
-			'doc_url' => $this->urlGenerator->linkToDocs('admin-windows-compatible-filenames'),
50
-			'description' => (
51
-				$this->l->t('Allow to restrict filenames to ensure files can be synced with all clients. By default all filenames valid on POSIX (e.g. Linux or macOS) are allowed.')
52
-				. "\n" . $this->l->t('After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner.')
53
-				. "\n" . $this->l->t('It is also possible to migrate files automatically after enabling this setting, please refer to the documentation about the occ command.')
54
-			),
41
+    public function getSchema(): array {
42
+        return [
43
+            'id' => 'files-filename-support',
44
+            'priority' => 10,
45
+            'section_type' => DeclarativeSettingsTypes::SECTION_TYPE_ADMIN,
46
+            'section_id' => 'server',
47
+            'storage_type' => DeclarativeSettingsTypes::STORAGE_TYPE_EXTERNAL,
48
+            'title' => $this->l->t('Files compatibility'),
49
+            'doc_url' => $this->urlGenerator->linkToDocs('admin-windows-compatible-filenames'),
50
+            'description' => (
51
+                $this->l->t('Allow to restrict filenames to ensure files can be synced with all clients. By default all filenames valid on POSIX (e.g. Linux or macOS) are allowed.')
52
+                . "\n" . $this->l->t('After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner.')
53
+                . "\n" . $this->l->t('It is also possible to migrate files automatically after enabling this setting, please refer to the documentation about the occ command.')
54
+            ),
55 55
 
56
-			'fields' => [
57
-				[
58
-					'id' => 'windows_support',
59
-					'title' => $this->l->t('Enforce Windows compatibility'),
60
-					'description' => $this->l->t('This will block filenames not valid on Windows systems, like using reserved names or special characters. But this will not enforce compatibility of case sensitivity.'),
61
-					'type' => DeclarativeSettingsTypes::CHECKBOX,
62
-					'default' => false,
63
-				],
64
-			],
65
-		];
66
-	}
56
+            'fields' => [
57
+                [
58
+                    'id' => 'windows_support',
59
+                    'title' => $this->l->t('Enforce Windows compatibility'),
60
+                    'description' => $this->l->t('This will block filenames not valid on Windows systems, like using reserved names or special characters. But this will not enforce compatibility of case sensitivity.'),
61
+                    'type' => DeclarativeSettingsTypes::CHECKBOX,
62
+                    'default' => false,
63
+                ],
64
+            ],
65
+        ];
66
+    }
67 67
 }
Please login to merge, or discard this patch.