Completed
Push — master ( 16708b...81d0c7 )
by
unknown
30:54 queued 10s
created
build/rector.php 2 patches
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -21,82 +21,82 @@  discard block
 block discarded – undo
21 21
 $nextcloudDir = dirname(__DIR__);
22 22
 
23 23
 class NextcloudNamespaceSkipVoter implements ClassNameImportSkipVoterInterface {
24
-	private array $namespacePrefixes = [
25
-		'OC',
26
-		'OCA',
27
-		'OCP',
28
-	];
29
-	private array $skippedClassNames = [
30
-		'Backend',
31
-		'Connection',
32
-		'Exception',
33
-		'IManager',
34
-		'IProvider',
35
-		'Manager',
36
-		'Plugin',
37
-		'Provider',
38
-	];
39
-	public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool {
40
-		if (in_array($fullyQualifiedObjectType->getShortName(), $this->skippedClassNames)) {
41
-			// Skip common class names to avoid confusion
42
-			return true;
43
-		}
44
-		foreach ($this->namespacePrefixes as $prefix) {
45
-			if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix . '\\')) {
46
-				// Import Nextcloud namespaces
47
-				return false;
48
-			}
49
-		}
50
-		// Skip everything else
51
-		return true;
52
-	}
24
+    private array $namespacePrefixes = [
25
+        'OC',
26
+        'OCA',
27
+        'OCP',
28
+    ];
29
+    private array $skippedClassNames = [
30
+        'Backend',
31
+        'Connection',
32
+        'Exception',
33
+        'IManager',
34
+        'IProvider',
35
+        'Manager',
36
+        'Plugin',
37
+        'Provider',
38
+    ];
39
+    public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool {
40
+        if (in_array($fullyQualifiedObjectType->getShortName(), $this->skippedClassNames)) {
41
+            // Skip common class names to avoid confusion
42
+            return true;
43
+        }
44
+        foreach ($this->namespacePrefixes as $prefix) {
45
+            if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix . '\\')) {
46
+                // Import Nextcloud namespaces
47
+                return false;
48
+            }
49
+        }
50
+        // Skip everything else
51
+        return true;
52
+    }
53 53
 }
54 54
 
55 55
 $config = RectorConfig::configure()
56
-	->withPaths([
57
-		$nextcloudDir . '/apps',
58
-		$nextcloudDir . '/core',
59
-		$nextcloudDir . '/ocs',
60
-		$nextcloudDir . '/ocs-provider',
61
-		$nextcloudDir . '/console.php',
62
-		$nextcloudDir . '/cron.php',
63
-		$nextcloudDir . '/index.php',
64
-		$nextcloudDir . '/occ',
65
-		$nextcloudDir . '/public.php',
66
-		$nextcloudDir . '/remote.php',
67
-		$nextcloudDir . '/status.php',
68
-		$nextcloudDir . '/version.php',
69
-		$nextcloudDir . '/lib/private/Share20/ProviderFactory.php',
70
-		$nextcloudDir . '/tests',
71
-		// $nextcloudDir . '/config',
72
-		// $nextcloudDir . '/lib',
73
-		// $nextcloudDir . '/themes',
74
-	])
75
-	->withSkip([
76
-		$nextcloudDir . '/apps/*/3rdparty/*',
77
-		$nextcloudDir . '/apps/*/build/stubs/*',
78
-		$nextcloudDir . '/apps/*/composer/*',
79
-		$nextcloudDir . '/apps/*/config/*',
80
-		// The mock classes are excluded, as the tests explicitly test the annotations which should not be migrated to attributes
81
-		$nextcloudDir . '/tests/lib/AppFramework/Middleware/Mock/*',
82
-		$nextcloudDir . '/tests/lib/AppFramework/Middleware/Security/Mock/*',
83
-	])
84
-	// uncomment to reach your current PHP version
85
-	// ->withPhpSets()
86
-	->withImportNames(importShortClasses:false)
87
-	->withTypeCoverageLevel(0)
88
-	->withRules([
89
-		UseSpecificWillMethodRector::class,
90
-		StaticDataProviderClassMethodRector::class,
91
-		DataProviderAnnotationToAttributeRector::class,
92
-	])
93
-	->withConfiguredRule(ClassPropertyAssignToConstructorPromotionRector::class, [
94
-		'inline_public' => true,
95
-		'rename_property' => true,
96
-	])
97
-	->withSets([
98
-		NextcloudSets::NEXTCLOUD_27,
99
-	]);
56
+    ->withPaths([
57
+        $nextcloudDir . '/apps',
58
+        $nextcloudDir . '/core',
59
+        $nextcloudDir . '/ocs',
60
+        $nextcloudDir . '/ocs-provider',
61
+        $nextcloudDir . '/console.php',
62
+        $nextcloudDir . '/cron.php',
63
+        $nextcloudDir . '/index.php',
64
+        $nextcloudDir . '/occ',
65
+        $nextcloudDir . '/public.php',
66
+        $nextcloudDir . '/remote.php',
67
+        $nextcloudDir . '/status.php',
68
+        $nextcloudDir . '/version.php',
69
+        $nextcloudDir . '/lib/private/Share20/ProviderFactory.php',
70
+        $nextcloudDir . '/tests',
71
+        // $nextcloudDir . '/config',
72
+        // $nextcloudDir . '/lib',
73
+        // $nextcloudDir . '/themes',
74
+    ])
75
+    ->withSkip([
76
+        $nextcloudDir . '/apps/*/3rdparty/*',
77
+        $nextcloudDir . '/apps/*/build/stubs/*',
78
+        $nextcloudDir . '/apps/*/composer/*',
79
+        $nextcloudDir . '/apps/*/config/*',
80
+        // The mock classes are excluded, as the tests explicitly test the annotations which should not be migrated to attributes
81
+        $nextcloudDir . '/tests/lib/AppFramework/Middleware/Mock/*',
82
+        $nextcloudDir . '/tests/lib/AppFramework/Middleware/Security/Mock/*',
83
+    ])
84
+    // uncomment to reach your current PHP version
85
+    // ->withPhpSets()
86
+    ->withImportNames(importShortClasses:false)
87
+    ->withTypeCoverageLevel(0)
88
+    ->withRules([
89
+        UseSpecificWillMethodRector::class,
90
+        StaticDataProviderClassMethodRector::class,
91
+        DataProviderAnnotationToAttributeRector::class,
92
+    ])
93
+    ->withConfiguredRule(ClassPropertyAssignToConstructorPromotionRector::class, [
94
+        'inline_public' => true,
95
+        'rename_property' => true,
96
+    ])
97
+    ->withSets([
98
+        NextcloudSets::NEXTCLOUD_27,
99
+    ]);
100 100
 
101 101
 $config->registerService(NextcloudNamespaceSkipVoter::class, tag:ClassNameImportSkipVoterInterface::class);
102 102
 
@@ -108,11 +108,11 @@  discard block
 block discarded – undo
108 108
 $ignoredEntries = array_values($ignoredEntries);
109 109
 
110 110
 foreach ($ignoredEntries as $ignoredEntry) {
111
-	if (str_ends_with($ignoredEntry, '/')) {
112
-		$config->withSkip([$ignoredEntry . '*']);
113
-	} else {
114
-		$config->withSkip([$ignoredEntry . '/*']);
115
-	}
111
+    if (str_ends_with($ignoredEntry, '/')) {
112
+        $config->withSkip([$ignoredEntry . '*']);
113
+    } else {
114
+        $config->withSkip([$ignoredEntry . '/*']);
115
+    }
116 116
 }
117 117
 
118 118
 return $config;
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -42,7 +42,7 @@  discard block
 block discarded – undo
42 42
 			return true;
43 43
 		}
44 44
 		foreach ($this->namespacePrefixes as $prefix) {
45
-			if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix . '\\')) {
45
+			if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix.'\\')) {
46 46
 				// Import Nextcloud namespaces
47 47
 				return false;
48 48
 			}
@@ -54,32 +54,32 @@  discard block
 block discarded – undo
54 54
 
55 55
 $config = RectorConfig::configure()
56 56
 	->withPaths([
57
-		$nextcloudDir . '/apps',
58
-		$nextcloudDir . '/core',
59
-		$nextcloudDir . '/ocs',
60
-		$nextcloudDir . '/ocs-provider',
61
-		$nextcloudDir . '/console.php',
62
-		$nextcloudDir . '/cron.php',
63
-		$nextcloudDir . '/index.php',
64
-		$nextcloudDir . '/occ',
65
-		$nextcloudDir . '/public.php',
66
-		$nextcloudDir . '/remote.php',
67
-		$nextcloudDir . '/status.php',
68
-		$nextcloudDir . '/version.php',
69
-		$nextcloudDir . '/lib/private/Share20/ProviderFactory.php',
70
-		$nextcloudDir . '/tests',
57
+		$nextcloudDir.'/apps',
58
+		$nextcloudDir.'/core',
59
+		$nextcloudDir.'/ocs',
60
+		$nextcloudDir.'/ocs-provider',
61
+		$nextcloudDir.'/console.php',
62
+		$nextcloudDir.'/cron.php',
63
+		$nextcloudDir.'/index.php',
64
+		$nextcloudDir.'/occ',
65
+		$nextcloudDir.'/public.php',
66
+		$nextcloudDir.'/remote.php',
67
+		$nextcloudDir.'/status.php',
68
+		$nextcloudDir.'/version.php',
69
+		$nextcloudDir.'/lib/private/Share20/ProviderFactory.php',
70
+		$nextcloudDir.'/tests',
71 71
 		// $nextcloudDir . '/config',
72 72
 		// $nextcloudDir . '/lib',
73 73
 		// $nextcloudDir . '/themes',
74 74
 	])
75 75
 	->withSkip([
76
-		$nextcloudDir . '/apps/*/3rdparty/*',
77
-		$nextcloudDir . '/apps/*/build/stubs/*',
78
-		$nextcloudDir . '/apps/*/composer/*',
79
-		$nextcloudDir . '/apps/*/config/*',
76
+		$nextcloudDir.'/apps/*/3rdparty/*',
77
+		$nextcloudDir.'/apps/*/build/stubs/*',
78
+		$nextcloudDir.'/apps/*/composer/*',
79
+		$nextcloudDir.'/apps/*/config/*',
80 80
 		// The mock classes are excluded, as the tests explicitly test the annotations which should not be migrated to attributes
81
-		$nextcloudDir . '/tests/lib/AppFramework/Middleware/Mock/*',
82
-		$nextcloudDir . '/tests/lib/AppFramework/Middleware/Security/Mock/*',
81
+		$nextcloudDir.'/tests/lib/AppFramework/Middleware/Mock/*',
82
+		$nextcloudDir.'/tests/lib/AppFramework/Middleware/Security/Mock/*',
83 83
 	])
84 84
 	// uncomment to reach your current PHP version
85 85
 	// ->withPhpSets()
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
 $config->registerService(NextcloudNamespaceSkipVoter::class, tag:ClassNameImportSkipVoterInterface::class);
102 102
 
103 103
 /* Ignore all files ignored by git */
104
-$ignoredEntries = shell_exec('git status --porcelain --ignored ' . escapeshellarg($nextcloudDir));
104
+$ignoredEntries = shell_exec('git status --porcelain --ignored '.escapeshellarg($nextcloudDir));
105 105
 $ignoredEntries = explode("\n", $ignoredEntries);
106 106
 $ignoredEntries = array_filter($ignoredEntries, static fn (string $line) => str_starts_with($line, '!! '));
107 107
 $ignoredEntries = array_map(static fn (string $line) => substr($line, 3), $ignoredEntries);
@@ -109,9 +109,9 @@  discard block
 block discarded – undo
109 109
 
110 110
 foreach ($ignoredEntries as $ignoredEntry) {
111 111
 	if (str_ends_with($ignoredEntry, '/')) {
112
-		$config->withSkip([$ignoredEntry . '*']);
112
+		$config->withSkip([$ignoredEntry.'*']);
113 113
 	} else {
114
-		$config->withSkip([$ignoredEntry . '/*']);
114
+		$config->withSkip([$ignoredEntry.'/*']);
115 115
 	}
116 116
 }
117 117
 
Please login to merge, or discard this patch.
core/Command/Base.php 2 patches
Indentation   +221 added lines, -221 removed lines patch added patch discarded remove patch
@@ -19,225 +19,225 @@
 block discarded – undo
19 19
 use Symfony\Component\Console\Output\OutputInterface;
20 20
 
21 21
 class Base extends Command implements CompletionAwareInterface {
22
-	public const OUTPUT_FORMAT_PLAIN = 'plain';
23
-	public const OUTPUT_FORMAT_JSON = 'json';
24
-	public const OUTPUT_FORMAT_JSON_PRETTY = 'json_pretty';
25
-
26
-	protected string $defaultOutputFormat = self::OUTPUT_FORMAT_PLAIN;
27
-	private bool $php_pcntl_signal = false;
28
-	private bool $interrupted = false;
29
-
30
-	protected function configure() {
31
-		// Some of our commands do not extend this class; and some of those that do do not call parent::configure()
32
-		$defaultHelp = 'More extensive and thorough documentation may be found at ' . Server::get(Defaults::class)->getDocBaseUrl() . PHP_EOL;
33
-		$this
34
-			->setHelp($defaultHelp)
35
-			->addOption(
36
-				'output',
37
-				null,
38
-				InputOption::VALUE_OPTIONAL,
39
-				'Output format (plain, json or json_pretty, default is plain)',
40
-				$this->defaultOutputFormat
41
-			)
42
-		;
43
-	}
44
-
45
-	protected function writeArrayInOutputFormat(InputInterface $input, OutputInterface $output, iterable $items, string $prefix = '  - '): void {
46
-		switch ($input->getOption('output')) {
47
-			case self::OUTPUT_FORMAT_JSON:
48
-				$items = (is_array($items) ? $items : iterator_to_array($items));
49
-				$output->writeln(json_encode($items));
50
-				break;
51
-			case self::OUTPUT_FORMAT_JSON_PRETTY:
52
-				$items = (is_array($items) ? $items : iterator_to_array($items));
53
-				$output->writeln(json_encode($items, JSON_PRETTY_PRINT));
54
-				break;
55
-			default:
56
-				foreach ($items as $key => $item) {
57
-					if (is_iterable($item)) {
58
-						$output->writeln($prefix . $key . ':');
59
-						$this->writeArrayInOutputFormat($input, $output, $item, '  ' . $prefix);
60
-						continue;
61
-					}
62
-					if (!is_int($key) || get_class($this) === ListCommand::class) {
63
-						$value = $this->valueToString($item);
64
-						if (!is_null($value)) {
65
-							$output->writeln($prefix . $key . ': ' . $value);
66
-						} else {
67
-							$output->writeln($prefix . $key);
68
-						}
69
-					} else {
70
-						$output->writeln($prefix . $this->valueToString($item));
71
-					}
72
-				}
73
-				break;
74
-		}
75
-	}
76
-
77
-	protected function writeTableInOutputFormat(InputInterface $input, OutputInterface $output, array $items): void {
78
-		switch ($input->getOption('output')) {
79
-			case self::OUTPUT_FORMAT_JSON:
80
-				$output->writeln(json_encode($items));
81
-				break;
82
-			case self::OUTPUT_FORMAT_JSON_PRETTY:
83
-				$output->writeln(json_encode($items, JSON_PRETTY_PRINT));
84
-				break;
85
-			default:
86
-				$table = new Table($output);
87
-				$table->setRows($items);
88
-				if (!empty($items) && is_string(array_key_first(reset($items)))) {
89
-					$table->setHeaders(array_keys(reset($items)));
90
-				}
91
-				$table->render();
92
-				break;
93
-		}
94
-	}
95
-
96
-	protected function writeStreamingTableInOutputFormat(InputInterface $input, OutputInterface $output, \Iterator $items, int $tableGroupSize): void {
97
-		switch ($input->getOption('output')) {
98
-			case self::OUTPUT_FORMAT_JSON:
99
-			case self::OUTPUT_FORMAT_JSON_PRETTY:
100
-				$this->writeStreamingJsonArray($input, $output, $items);
101
-				break;
102
-			default:
103
-				foreach ($this->chunkIterator($items, $tableGroupSize) as $chunk) {
104
-					$this->writeTableInOutputFormat($input, $output, $chunk);
105
-				}
106
-				break;
107
-		}
108
-	}
109
-
110
-	protected function writeStreamingJsonArray(InputInterface $input, OutputInterface $output, \Iterator $items): void {
111
-		$first = true;
112
-		$outputType = $input->getOption('output');
113
-
114
-		$output->writeln('[');
115
-		foreach ($items as $item) {
116
-			if (!$first) {
117
-				$output->writeln(',');
118
-			}
119
-			if ($outputType === self::OUTPUT_FORMAT_JSON_PRETTY) {
120
-				$output->write(json_encode($item, JSON_PRETTY_PRINT));
121
-			} else {
122
-				$output->write(json_encode($item));
123
-			}
124
-			$first = false;
125
-		}
126
-		$output->writeln("\n]");
127
-	}
128
-
129
-	public function chunkIterator(\Iterator $iterator, int $count): \Iterator {
130
-		$chunk = [];
131
-
132
-		for ($i = 0; $iterator->valid(); $i++) {
133
-			$chunk[] = $iterator->current();
134
-			$iterator->next();
135
-			if (count($chunk) == $count) {
136
-				// Got a full chunk, yield and start a new one
137
-				yield $chunk;
138
-				$chunk = [];
139
-			}
140
-		}
141
-
142
-		if (count($chunk)) {
143
-			// Yield the last chunk even if incomplete
144
-			yield $chunk;
145
-		}
146
-	}
147
-
148
-
149
-	/**
150
-	 * @param mixed $item
151
-	 */
152
-	protected function writeMixedInOutputFormat(InputInterface $input, OutputInterface $output, $item) {
153
-		if (is_array($item)) {
154
-			$this->writeArrayInOutputFormat($input, $output, $item, '');
155
-			return;
156
-		}
157
-
158
-		switch ($input->getOption('output')) {
159
-			case self::OUTPUT_FORMAT_JSON:
160
-				$output->writeln(json_encode($item));
161
-				break;
162
-			case self::OUTPUT_FORMAT_JSON_PRETTY:
163
-				$output->writeln(json_encode($item, JSON_PRETTY_PRINT));
164
-				break;
165
-			default:
166
-				$output->writeln($this->valueToString($item, false));
167
-				break;
168
-		}
169
-	}
170
-
171
-	protected function valueToString($value, bool $returnNull = true): ?string {
172
-		if ($value === false) {
173
-			return 'false';
174
-		} elseif ($value === true) {
175
-			return 'true';
176
-		} elseif ($value === null) {
177
-			return $returnNull ? null : 'null';
178
-		} if ($value instanceof \UnitEnum) {
179
-			return $value->value;
180
-		} else {
181
-			return $value;
182
-		}
183
-	}
184
-
185
-	/**
186
-	 * Throw InterruptedException when interrupted by user
187
-	 *
188
-	 * @throws InterruptedException
189
-	 */
190
-	protected function abortIfInterrupted() {
191
-		if ($this->php_pcntl_signal === false) {
192
-			return;
193
-		}
194
-
195
-		pcntl_signal_dispatch();
196
-
197
-		if ($this->interrupted === true) {
198
-			throw new InterruptedException('Command interrupted by user');
199
-		}
200
-	}
201
-
202
-	/**
203
-	 * Changes the status of the command to "interrupted" if ctrl-c has been pressed
204
-	 *
205
-	 * Gives a chance to the command to properly terminate what it's doing
206
-	 */
207
-	public function cancelOperation(): void {
208
-		$this->interrupted = true;
209
-	}
210
-
211
-	public function run(InputInterface $input, OutputInterface $output): int {
212
-		// check if the php pcntl_signal functions are accessible
213
-		$this->php_pcntl_signal = function_exists('pcntl_signal');
214
-		if ($this->php_pcntl_signal) {
215
-			// Collect interrupts and notify the running command
216
-			pcntl_signal(SIGTERM, [$this, 'cancelOperation']);
217
-			pcntl_signal(SIGINT, [$this, 'cancelOperation']);
218
-		}
219
-
220
-		return parent::run($input, $output);
221
-	}
222
-
223
-	/**
224
-	 * @param string $optionName
225
-	 * @param CompletionContext $context
226
-	 * @return string[]
227
-	 */
228
-	public function completeOptionValues($optionName, CompletionContext $context) {
229
-		if ($optionName === 'output') {
230
-			return ['plain', 'json', 'json_pretty'];
231
-		}
232
-		return [];
233
-	}
234
-
235
-	/**
236
-	 * @param string $argumentName
237
-	 * @param CompletionContext $context
238
-	 * @return string[]
239
-	 */
240
-	public function completeArgumentValues($argumentName, CompletionContext $context) {
241
-		return [];
242
-	}
22
+    public const OUTPUT_FORMAT_PLAIN = 'plain';
23
+    public const OUTPUT_FORMAT_JSON = 'json';
24
+    public const OUTPUT_FORMAT_JSON_PRETTY = 'json_pretty';
25
+
26
+    protected string $defaultOutputFormat = self::OUTPUT_FORMAT_PLAIN;
27
+    private bool $php_pcntl_signal = false;
28
+    private bool $interrupted = false;
29
+
30
+    protected function configure() {
31
+        // Some of our commands do not extend this class; and some of those that do do not call parent::configure()
32
+        $defaultHelp = 'More extensive and thorough documentation may be found at ' . Server::get(Defaults::class)->getDocBaseUrl() . PHP_EOL;
33
+        $this
34
+            ->setHelp($defaultHelp)
35
+            ->addOption(
36
+                'output',
37
+                null,
38
+                InputOption::VALUE_OPTIONAL,
39
+                'Output format (plain, json or json_pretty, default is plain)',
40
+                $this->defaultOutputFormat
41
+            )
42
+        ;
43
+    }
44
+
45
+    protected function writeArrayInOutputFormat(InputInterface $input, OutputInterface $output, iterable $items, string $prefix = '  - '): void {
46
+        switch ($input->getOption('output')) {
47
+            case self::OUTPUT_FORMAT_JSON:
48
+                $items = (is_array($items) ? $items : iterator_to_array($items));
49
+                $output->writeln(json_encode($items));
50
+                break;
51
+            case self::OUTPUT_FORMAT_JSON_PRETTY:
52
+                $items = (is_array($items) ? $items : iterator_to_array($items));
53
+                $output->writeln(json_encode($items, JSON_PRETTY_PRINT));
54
+                break;
55
+            default:
56
+                foreach ($items as $key => $item) {
57
+                    if (is_iterable($item)) {
58
+                        $output->writeln($prefix . $key . ':');
59
+                        $this->writeArrayInOutputFormat($input, $output, $item, '  ' . $prefix);
60
+                        continue;
61
+                    }
62
+                    if (!is_int($key) || get_class($this) === ListCommand::class) {
63
+                        $value = $this->valueToString($item);
64
+                        if (!is_null($value)) {
65
+                            $output->writeln($prefix . $key . ': ' . $value);
66
+                        } else {
67
+                            $output->writeln($prefix . $key);
68
+                        }
69
+                    } else {
70
+                        $output->writeln($prefix . $this->valueToString($item));
71
+                    }
72
+                }
73
+                break;
74
+        }
75
+    }
76
+
77
+    protected function writeTableInOutputFormat(InputInterface $input, OutputInterface $output, array $items): void {
78
+        switch ($input->getOption('output')) {
79
+            case self::OUTPUT_FORMAT_JSON:
80
+                $output->writeln(json_encode($items));
81
+                break;
82
+            case self::OUTPUT_FORMAT_JSON_PRETTY:
83
+                $output->writeln(json_encode($items, JSON_PRETTY_PRINT));
84
+                break;
85
+            default:
86
+                $table = new Table($output);
87
+                $table->setRows($items);
88
+                if (!empty($items) && is_string(array_key_first(reset($items)))) {
89
+                    $table->setHeaders(array_keys(reset($items)));
90
+                }
91
+                $table->render();
92
+                break;
93
+        }
94
+    }
95
+
96
+    protected function writeStreamingTableInOutputFormat(InputInterface $input, OutputInterface $output, \Iterator $items, int $tableGroupSize): void {
97
+        switch ($input->getOption('output')) {
98
+            case self::OUTPUT_FORMAT_JSON:
99
+            case self::OUTPUT_FORMAT_JSON_PRETTY:
100
+                $this->writeStreamingJsonArray($input, $output, $items);
101
+                break;
102
+            default:
103
+                foreach ($this->chunkIterator($items, $tableGroupSize) as $chunk) {
104
+                    $this->writeTableInOutputFormat($input, $output, $chunk);
105
+                }
106
+                break;
107
+        }
108
+    }
109
+
110
+    protected function writeStreamingJsonArray(InputInterface $input, OutputInterface $output, \Iterator $items): void {
111
+        $first = true;
112
+        $outputType = $input->getOption('output');
113
+
114
+        $output->writeln('[');
115
+        foreach ($items as $item) {
116
+            if (!$first) {
117
+                $output->writeln(',');
118
+            }
119
+            if ($outputType === self::OUTPUT_FORMAT_JSON_PRETTY) {
120
+                $output->write(json_encode($item, JSON_PRETTY_PRINT));
121
+            } else {
122
+                $output->write(json_encode($item));
123
+            }
124
+            $first = false;
125
+        }
126
+        $output->writeln("\n]");
127
+    }
128
+
129
+    public function chunkIterator(\Iterator $iterator, int $count): \Iterator {
130
+        $chunk = [];
131
+
132
+        for ($i = 0; $iterator->valid(); $i++) {
133
+            $chunk[] = $iterator->current();
134
+            $iterator->next();
135
+            if (count($chunk) == $count) {
136
+                // Got a full chunk, yield and start a new one
137
+                yield $chunk;
138
+                $chunk = [];
139
+            }
140
+        }
141
+
142
+        if (count($chunk)) {
143
+            // Yield the last chunk even if incomplete
144
+            yield $chunk;
145
+        }
146
+    }
147
+
148
+
149
+    /**
150
+     * @param mixed $item
151
+     */
152
+    protected function writeMixedInOutputFormat(InputInterface $input, OutputInterface $output, $item) {
153
+        if (is_array($item)) {
154
+            $this->writeArrayInOutputFormat($input, $output, $item, '');
155
+            return;
156
+        }
157
+
158
+        switch ($input->getOption('output')) {
159
+            case self::OUTPUT_FORMAT_JSON:
160
+                $output->writeln(json_encode($item));
161
+                break;
162
+            case self::OUTPUT_FORMAT_JSON_PRETTY:
163
+                $output->writeln(json_encode($item, JSON_PRETTY_PRINT));
164
+                break;
165
+            default:
166
+                $output->writeln($this->valueToString($item, false));
167
+                break;
168
+        }
169
+    }
170
+
171
+    protected function valueToString($value, bool $returnNull = true): ?string {
172
+        if ($value === false) {
173
+            return 'false';
174
+        } elseif ($value === true) {
175
+            return 'true';
176
+        } elseif ($value === null) {
177
+            return $returnNull ? null : 'null';
178
+        } if ($value instanceof \UnitEnum) {
179
+            return $value->value;
180
+        } else {
181
+            return $value;
182
+        }
183
+    }
184
+
185
+    /**
186
+     * Throw InterruptedException when interrupted by user
187
+     *
188
+     * @throws InterruptedException
189
+     */
190
+    protected function abortIfInterrupted() {
191
+        if ($this->php_pcntl_signal === false) {
192
+            return;
193
+        }
194
+
195
+        pcntl_signal_dispatch();
196
+
197
+        if ($this->interrupted === true) {
198
+            throw new InterruptedException('Command interrupted by user');
199
+        }
200
+    }
201
+
202
+    /**
203
+     * Changes the status of the command to "interrupted" if ctrl-c has been pressed
204
+     *
205
+     * Gives a chance to the command to properly terminate what it's doing
206
+     */
207
+    public function cancelOperation(): void {
208
+        $this->interrupted = true;
209
+    }
210
+
211
+    public function run(InputInterface $input, OutputInterface $output): int {
212
+        // check if the php pcntl_signal functions are accessible
213
+        $this->php_pcntl_signal = function_exists('pcntl_signal');
214
+        if ($this->php_pcntl_signal) {
215
+            // Collect interrupts and notify the running command
216
+            pcntl_signal(SIGTERM, [$this, 'cancelOperation']);
217
+            pcntl_signal(SIGINT, [$this, 'cancelOperation']);
218
+        }
219
+
220
+        return parent::run($input, $output);
221
+    }
222
+
223
+    /**
224
+     * @param string $optionName
225
+     * @param CompletionContext $context
226
+     * @return string[]
227
+     */
228
+    public function completeOptionValues($optionName, CompletionContext $context) {
229
+        if ($optionName === 'output') {
230
+            return ['plain', 'json', 'json_pretty'];
231
+        }
232
+        return [];
233
+    }
234
+
235
+    /**
236
+     * @param string $argumentName
237
+     * @param CompletionContext $context
238
+     * @return string[]
239
+     */
240
+    public function completeArgumentValues($argumentName, CompletionContext $context) {
241
+        return [];
242
+    }
243 243
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@  discard block
 block discarded – undo
29 29
 
30 30
 	protected function configure() {
31 31
 		// Some of our commands do not extend this class; and some of those that do do not call parent::configure()
32
-		$defaultHelp = 'More extensive and thorough documentation may be found at ' . Server::get(Defaults::class)->getDocBaseUrl() . PHP_EOL;
32
+		$defaultHelp = 'More extensive and thorough documentation may be found at '.Server::get(Defaults::class)->getDocBaseUrl().PHP_EOL;
33 33
 		$this
34 34
 			->setHelp($defaultHelp)
35 35
 			->addOption(
@@ -55,19 +55,19 @@  discard block
 block discarded – undo
55 55
 			default:
56 56
 				foreach ($items as $key => $item) {
57 57
 					if (is_iterable($item)) {
58
-						$output->writeln($prefix . $key . ':');
59
-						$this->writeArrayInOutputFormat($input, $output, $item, '  ' . $prefix);
58
+						$output->writeln($prefix.$key.':');
59
+						$this->writeArrayInOutputFormat($input, $output, $item, '  '.$prefix);
60 60
 						continue;
61 61
 					}
62 62
 					if (!is_int($key) || get_class($this) === ListCommand::class) {
63 63
 						$value = $this->valueToString($item);
64 64
 						if (!is_null($value)) {
65
-							$output->writeln($prefix . $key . ': ' . $value);
65
+							$output->writeln($prefix.$key.': '.$value);
66 66
 						} else {
67
-							$output->writeln($prefix . $key);
67
+							$output->writeln($prefix.$key);
68 68
 						}
69 69
 					} else {
70
-						$output->writeln($prefix . $this->valueToString($item));
70
+						$output->writeln($prefix.$this->valueToString($item));
71 71
 					}
72 72
 				}
73 73
 				break;
Please login to merge, or discard this patch.
core/Controller/TwoFactorChallengeController.php 1 patch
Indentation   +204 added lines, -204 removed lines patch added patch discarded remove patch
@@ -31,232 +31,232 @@
 block discarded – undo
31 31
 
32 32
 #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
33 33
 class TwoFactorChallengeController extends Controller {
34
-	public function __construct(
35
-		string $appName,
36
-		IRequest $request,
37
-		private Manager $twoFactorManager,
38
-		private IUserSession $userSession,
39
-		private ISession $session,
40
-		private IURLGenerator $urlGenerator,
41
-		private LoggerInterface $logger,
42
-	) {
43
-		parent::__construct($appName, $request);
44
-	}
34
+    public function __construct(
35
+        string $appName,
36
+        IRequest $request,
37
+        private Manager $twoFactorManager,
38
+        private IUserSession $userSession,
39
+        private ISession $session,
40
+        private IURLGenerator $urlGenerator,
41
+        private LoggerInterface $logger,
42
+    ) {
43
+        parent::__construct($appName, $request);
44
+    }
45 45
 
46
-	/**
47
-	 * @return string
48
-	 */
49
-	protected function getLogoutUrl() {
50
-		return OC_User::getLogoutUrl($this->urlGenerator);
51
-	}
46
+    /**
47
+     * @return string
48
+     */
49
+    protected function getLogoutUrl() {
50
+        return OC_User::getLogoutUrl($this->urlGenerator);
51
+    }
52 52
 
53
-	/**
54
-	 * @param IProvider[] $providers
55
-	 */
56
-	private function splitProvidersAndBackupCodes(array $providers): array {
57
-		$regular = [];
58
-		$backup = null;
59
-		foreach ($providers as $provider) {
60
-			if ($provider->getId() === 'backup_codes') {
61
-				$backup = $provider;
62
-			} else {
63
-				$regular[] = $provider;
64
-			}
65
-		}
53
+    /**
54
+     * @param IProvider[] $providers
55
+     */
56
+    private function splitProvidersAndBackupCodes(array $providers): array {
57
+        $regular = [];
58
+        $backup = null;
59
+        foreach ($providers as $provider) {
60
+            if ($provider->getId() === 'backup_codes') {
61
+                $backup = $provider;
62
+            } else {
63
+                $regular[] = $provider;
64
+            }
65
+        }
66 66
 
67
-		return [$regular, $backup];
68
-	}
67
+        return [$regular, $backup];
68
+    }
69 69
 
70
-	/**
71
-	 * @TwoFactorSetUpDoneRequired
72
-	 *
73
-	 * @param string $redirect_url
74
-	 * @return StandaloneTemplateResponse
75
-	 */
76
-	#[NoAdminRequired]
77
-	#[NoCSRFRequired]
78
-	#[FrontpageRoute(verb: 'GET', url: '/login/selectchallenge')]
79
-	public function selectChallenge($redirect_url) {
80
-		$user = $this->userSession->getUser();
81
-		$providerSet = $this->twoFactorManager->getProviderSet($user);
82
-		$allProviders = $providerSet->getProviders();
83
-		[$providers, $backupProvider] = $this->splitProvidersAndBackupCodes($allProviders);
84
-		$setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
70
+    /**
71
+     * @TwoFactorSetUpDoneRequired
72
+     *
73
+     * @param string $redirect_url
74
+     * @return StandaloneTemplateResponse
75
+     */
76
+    #[NoAdminRequired]
77
+    #[NoCSRFRequired]
78
+    #[FrontpageRoute(verb: 'GET', url: '/login/selectchallenge')]
79
+    public function selectChallenge($redirect_url) {
80
+        $user = $this->userSession->getUser();
81
+        $providerSet = $this->twoFactorManager->getProviderSet($user);
82
+        $allProviders = $providerSet->getProviders();
83
+        [$providers, $backupProvider] = $this->splitProvidersAndBackupCodes($allProviders);
84
+        $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
85 85
 
86
-		$data = [
87
-			'providers' => $providers,
88
-			'backupProvider' => $backupProvider,
89
-			'providerMissing' => $providerSet->isProviderMissing(),
90
-			'redirect_url' => $redirect_url,
91
-			'logout_url' => $this->getLogoutUrl(),
92
-			'hasSetupProviders' => !empty($setupProviders),
93
-		];
94
-		Util::addScript('core', 'twofactor-request-token');
95
-		return new StandaloneTemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
96
-	}
86
+        $data = [
87
+            'providers' => $providers,
88
+            'backupProvider' => $backupProvider,
89
+            'providerMissing' => $providerSet->isProviderMissing(),
90
+            'redirect_url' => $redirect_url,
91
+            'logout_url' => $this->getLogoutUrl(),
92
+            'hasSetupProviders' => !empty($setupProviders),
93
+        ];
94
+        Util::addScript('core', 'twofactor-request-token');
95
+        return new StandaloneTemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
96
+    }
97 97
 
98
-	/**
99
-	 * @TwoFactorSetUpDoneRequired
100
-	 *
101
-	 * @param string $challengeProviderId
102
-	 * @param string $redirect_url
103
-	 * @return StandaloneTemplateResponse|RedirectResponse
104
-	 */
105
-	#[NoAdminRequired]
106
-	#[NoCSRFRequired]
107
-	#[UseSession]
108
-	#[FrontpageRoute(verb: 'GET', url: '/login/challenge/{challengeProviderId}')]
109
-	public function showChallenge($challengeProviderId, $redirect_url) {
110
-		$user = $this->userSession->getUser();
111
-		$providerSet = $this->twoFactorManager->getProviderSet($user);
112
-		$provider = $providerSet->getProvider($challengeProviderId);
98
+    /**
99
+     * @TwoFactorSetUpDoneRequired
100
+     *
101
+     * @param string $challengeProviderId
102
+     * @param string $redirect_url
103
+     * @return StandaloneTemplateResponse|RedirectResponse
104
+     */
105
+    #[NoAdminRequired]
106
+    #[NoCSRFRequired]
107
+    #[UseSession]
108
+    #[FrontpageRoute(verb: 'GET', url: '/login/challenge/{challengeProviderId}')]
109
+    public function showChallenge($challengeProviderId, $redirect_url) {
110
+        $user = $this->userSession->getUser();
111
+        $providerSet = $this->twoFactorManager->getProviderSet($user);
112
+        $provider = $providerSet->getProvider($challengeProviderId);
113 113
 
114
-		if (is_null($provider)) {
115
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
116
-		}
114
+        if (is_null($provider)) {
115
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
116
+        }
117 117
 
118
-		$backupProvider = $providerSet->getProvider('backup_codes');
119
-		if (!is_null($backupProvider) && $backupProvider->getId() === $provider->getId()) {
120
-			// Don't show the backup provider link if we're already showing that provider's challenge
121
-			$backupProvider = null;
122
-		}
118
+        $backupProvider = $providerSet->getProvider('backup_codes');
119
+        if (!is_null($backupProvider) && $backupProvider->getId() === $provider->getId()) {
120
+            // Don't show the backup provider link if we're already showing that provider's challenge
121
+            $backupProvider = null;
122
+        }
123 123
 
124
-		$errorMessage = '';
125
-		$error = false;
126
-		if ($this->session->exists('two_factor_auth_error')) {
127
-			$this->session->remove('two_factor_auth_error');
128
-			$error = true;
129
-			$errorMessage = $this->session->get('two_factor_auth_error_message');
130
-			$this->session->remove('two_factor_auth_error_message');
131
-		}
132
-		$tmpl = $provider->getTemplate($user);
133
-		$tmpl->assign('redirect_url', $redirect_url);
134
-		$data = [
135
-			'error' => $error,
136
-			'error_message' => $errorMessage,
137
-			'provider' => $provider,
138
-			'backupProvider' => $backupProvider,
139
-			'logout_url' => $this->getLogoutUrl(),
140
-			'redirect_url' => $redirect_url,
141
-			'template' => $tmpl->fetchPage(),
142
-		];
143
-		$response = new StandaloneTemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
144
-		if ($provider instanceof IProvidesCustomCSP) {
145
-			$response->setContentSecurityPolicy($provider->getCSP());
146
-		}
147
-		Util::addScript('core', 'twofactor-request-token');
148
-		return $response;
149
-	}
124
+        $errorMessage = '';
125
+        $error = false;
126
+        if ($this->session->exists('two_factor_auth_error')) {
127
+            $this->session->remove('two_factor_auth_error');
128
+            $error = true;
129
+            $errorMessage = $this->session->get('two_factor_auth_error_message');
130
+            $this->session->remove('two_factor_auth_error_message');
131
+        }
132
+        $tmpl = $provider->getTemplate($user);
133
+        $tmpl->assign('redirect_url', $redirect_url);
134
+        $data = [
135
+            'error' => $error,
136
+            'error_message' => $errorMessage,
137
+            'provider' => $provider,
138
+            'backupProvider' => $backupProvider,
139
+            'logout_url' => $this->getLogoutUrl(),
140
+            'redirect_url' => $redirect_url,
141
+            'template' => $tmpl->fetchPage(),
142
+        ];
143
+        $response = new StandaloneTemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
144
+        if ($provider instanceof IProvidesCustomCSP) {
145
+            $response->setContentSecurityPolicy($provider->getCSP());
146
+        }
147
+        Util::addScript('core', 'twofactor-request-token');
148
+        return $response;
149
+    }
150 150
 
151
-	/**
152
-	 * @TwoFactorSetUpDoneRequired
153
-	 *
154
-	 *
155
-	 * @param string $challengeProviderId
156
-	 * @param string $challenge
157
-	 * @param string $redirect_url
158
-	 * @return RedirectResponse
159
-	 */
160
-	#[NoAdminRequired]
161
-	#[NoCSRFRequired]
162
-	#[UseSession]
163
-	#[FrontpageRoute(verb: 'POST', url: '/login/challenge/{challengeProviderId}')]
164
-	#[UserRateLimit(limit: 5, period: 100)]
165
-	public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
166
-		$user = $this->userSession->getUser();
167
-		$provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
168
-		if (is_null($provider)) {
169
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
170
-		}
151
+    /**
152
+     * @TwoFactorSetUpDoneRequired
153
+     *
154
+     *
155
+     * @param string $challengeProviderId
156
+     * @param string $challenge
157
+     * @param string $redirect_url
158
+     * @return RedirectResponse
159
+     */
160
+    #[NoAdminRequired]
161
+    #[NoCSRFRequired]
162
+    #[UseSession]
163
+    #[FrontpageRoute(verb: 'POST', url: '/login/challenge/{challengeProviderId}')]
164
+    #[UserRateLimit(limit: 5, period: 100)]
165
+    public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
166
+        $user = $this->userSession->getUser();
167
+        $provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
168
+        if (is_null($provider)) {
169
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
170
+        }
171 171
 
172
-		try {
173
-			if ($this->twoFactorManager->verifyChallenge($challengeProviderId, $user, $challenge)) {
174
-				if (!is_null($redirect_url)) {
175
-					return new RedirectResponse($this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)));
176
-				}
177
-				return new RedirectResponse($this->urlGenerator->linkToDefaultPageUrl());
178
-			}
179
-		} catch (TwoFactorException $e) {
180
-			/*
172
+        try {
173
+            if ($this->twoFactorManager->verifyChallenge($challengeProviderId, $user, $challenge)) {
174
+                if (!is_null($redirect_url)) {
175
+                    return new RedirectResponse($this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)));
176
+                }
177
+                return new RedirectResponse($this->urlGenerator->linkToDefaultPageUrl());
178
+            }
179
+        } catch (TwoFactorException $e) {
180
+            /*
181 181
 			 * The 2FA App threw an TwoFactorException. Now we display more
182 182
 			 * information to the user. The exception text is stored in the
183 183
 			 * session to be used in showChallenge()
184 184
 			 */
185
-			$this->session->set('two_factor_auth_error_message', $e->getMessage());
186
-		}
185
+            $this->session->set('two_factor_auth_error_message', $e->getMessage());
186
+        }
187 187
 
188
-		$ip = $this->request->getRemoteAddress();
189
-		$uid = $user->getUID();
190
-		$this->logger->warning("Two-factor challenge failed: $uid (Remote IP: $ip)");
191
-		$this->session->set('two_factor_auth_error', true);
192
-		return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.showChallenge', [
193
-			'challengeProviderId' => $provider->getId(),
194
-			'redirect_url' => $redirect_url,
195
-		]));
196
-	}
188
+        $ip = $this->request->getRemoteAddress();
189
+        $uid = $user->getUID();
190
+        $this->logger->warning("Two-factor challenge failed: $uid (Remote IP: $ip)");
191
+        $this->session->set('two_factor_auth_error', true);
192
+        return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.showChallenge', [
193
+            'challengeProviderId' => $provider->getId(),
194
+            'redirect_url' => $redirect_url,
195
+        ]));
196
+    }
197 197
 
198
-	#[NoAdminRequired]
199
-	#[NoCSRFRequired]
200
-	#[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge')]
201
-	public function setupProviders(?string $redirect_url = null): StandaloneTemplateResponse {
202
-		$user = $this->userSession->getUser();
203
-		$setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
198
+    #[NoAdminRequired]
199
+    #[NoCSRFRequired]
200
+    #[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge')]
201
+    public function setupProviders(?string $redirect_url = null): StandaloneTemplateResponse {
202
+        $user = $this->userSession->getUser();
203
+        $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
204 204
 
205
-		$data = [
206
-			'providers' => $setupProviders,
207
-			'logout_url' => $this->getLogoutUrl(),
208
-			'redirect_url' => $redirect_url,
209
-		];
205
+        $data = [
206
+            'providers' => $setupProviders,
207
+            'logout_url' => $this->getLogoutUrl(),
208
+            'redirect_url' => $redirect_url,
209
+        ];
210 210
 
211
-		Util::addScript('core', 'twofactor-request-token');
212
-		return new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest');
213
-	}
211
+        Util::addScript('core', 'twofactor-request-token');
212
+        return new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest');
213
+    }
214 214
 
215
-	#[NoAdminRequired]
216
-	#[NoCSRFRequired]
217
-	#[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge/{providerId}')]
218
-	public function setupProvider(string $providerId, ?string $redirect_url = null) {
219
-		$user = $this->userSession->getUser();
220
-		$providers = $this->twoFactorManager->getLoginSetupProviders($user);
215
+    #[NoAdminRequired]
216
+    #[NoCSRFRequired]
217
+    #[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge/{providerId}')]
218
+    public function setupProvider(string $providerId, ?string $redirect_url = null) {
219
+        $user = $this->userSession->getUser();
220
+        $providers = $this->twoFactorManager->getLoginSetupProviders($user);
221 221
 
222
-		$provider = null;
223
-		foreach ($providers as $p) {
224
-			if ($p->getId() === $providerId) {
225
-				$provider = $p;
226
-				break;
227
-			}
228
-		}
222
+        $provider = null;
223
+        foreach ($providers as $p) {
224
+            if ($p->getId() === $providerId) {
225
+                $provider = $p;
226
+                break;
227
+            }
228
+        }
229 229
 
230
-		if ($provider === null) {
231
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
232
-		}
230
+        if ($provider === null) {
231
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
232
+        }
233 233
 
234
-		/** @var IActivatableAtLogin $provider */
235
-		$tmpl = $provider->getLoginSetup($user)->getBody();
236
-		$data = [
237
-			'provider' => $provider,
238
-			'logout_url' => $this->getLogoutUrl(),
239
-			'redirect_url' => $redirect_url,
240
-			'template' => $tmpl->fetchPage(),
241
-		];
242
-		$response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest');
243
-		Util::addScript('core', 'twofactor-request-token');
244
-		return $response;
245
-	}
234
+        /** @var IActivatableAtLogin $provider */
235
+        $tmpl = $provider->getLoginSetup($user)->getBody();
236
+        $data = [
237
+            'provider' => $provider,
238
+            'logout_url' => $this->getLogoutUrl(),
239
+            'redirect_url' => $redirect_url,
240
+            'template' => $tmpl->fetchPage(),
241
+        ];
242
+        $response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest');
243
+        Util::addScript('core', 'twofactor-request-token');
244
+        return $response;
245
+    }
246 246
 
247
-	/**
248
-	 * @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page
249
-	 */
250
-	#[NoAdminRequired]
251
-	#[NoCSRFRequired]
252
-	#[FrontpageRoute(verb: 'POST', url: 'login/setupchallenge/{providerId}')]
253
-	public function confirmProviderSetup(string $providerId, ?string $redirect_url = null) {
254
-		return new RedirectResponse($this->urlGenerator->linkToRoute(
255
-			'core.TwoFactorChallenge.showChallenge',
256
-			[
257
-				'challengeProviderId' => $providerId,
258
-				'redirect_url' => $redirect_url,
259
-			]
260
-		));
261
-	}
247
+    /**
248
+     * @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page
249
+     */
250
+    #[NoAdminRequired]
251
+    #[NoCSRFRequired]
252
+    #[FrontpageRoute(verb: 'POST', url: 'login/setupchallenge/{providerId}')]
253
+    public function confirmProviderSetup(string $providerId, ?string $redirect_url = null) {
254
+        return new RedirectResponse($this->urlGenerator->linkToRoute(
255
+            'core.TwoFactorChallenge.showChallenge',
256
+            [
257
+                'challengeProviderId' => $providerId,
258
+                'redirect_url' => $redirect_url,
259
+            ]
260
+        ));
261
+    }
262 262
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/AuthorizedGroupController.php 1 patch
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -15,49 +15,49 @@
 block discarded – undo
15 15
 use OCP\IRequest;
16 16
 
17 17
 class AuthorizedGroupController extends Controller {
18
-	public function __construct(
19
-		string $appName,
20
-		IRequest $request,
21
-		private AuthorizedGroupService $authorizedGroupService,
22
-	) {
23
-		parent::__construct($appName, $request);
24
-	}
18
+    public function __construct(
19
+        string $appName,
20
+        IRequest $request,
21
+        private AuthorizedGroupService $authorizedGroupService,
22
+    ) {
23
+        parent::__construct($appName, $request);
24
+    }
25 25
 
26
-	/**
27
-	 * @throws NotFoundException
28
-	 * @throws Exception
29
-	 */
30
-	public function saveSettings(array $newGroups, string $class): DataResponse {
31
-		$currentGroups = $this->authorizedGroupService->findExistingGroupsForClass($class);
26
+    /**
27
+     * @throws NotFoundException
28
+     * @throws Exception
29
+     */
30
+    public function saveSettings(array $newGroups, string $class): DataResponse {
31
+        $currentGroups = $this->authorizedGroupService->findExistingGroupsForClass($class);
32 32
 
33
-		foreach ($currentGroups as $group) {
34
-			/** @var AuthorizedGroup $group */
35
-			$removed = true;
36
-			foreach ($newGroups as $groupData) {
37
-				if ($groupData['gid'] === $group->getGroupId()) {
38
-					$removed = false;
39
-					break;
40
-				}
41
-			}
42
-			if ($removed) {
43
-				$this->authorizedGroupService->delete($group->getId());
44
-			}
45
-		}
33
+        foreach ($currentGroups as $group) {
34
+            /** @var AuthorizedGroup $group */
35
+            $removed = true;
36
+            foreach ($newGroups as $groupData) {
37
+                if ($groupData['gid'] === $group->getGroupId()) {
38
+                    $removed = false;
39
+                    break;
40
+                }
41
+            }
42
+            if ($removed) {
43
+                $this->authorizedGroupService->delete($group->getId());
44
+            }
45
+        }
46 46
 
47
-		foreach ($newGroups as $groupData) {
48
-			$added = true;
49
-			foreach ($currentGroups as $group) {
50
-				/** @var AuthorizedGroup $group */
51
-				if ($groupData['gid'] === $group->getGroupId()) {
52
-					$added = false;
53
-					break;
54
-				}
55
-			}
56
-			if ($added) {
57
-				$this->authorizedGroupService->create($groupData['gid'], $class);
58
-			}
59
-		}
47
+        foreach ($newGroups as $groupData) {
48
+            $added = true;
49
+            foreach ($currentGroups as $group) {
50
+                /** @var AuthorizedGroup $group */
51
+                if ($groupData['gid'] === $group->getGroupId()) {
52
+                    $added = false;
53
+                    break;
54
+                }
55
+            }
56
+            if ($added) {
57
+                $this->authorizedGroupService->create($groupData['gid'], $class);
58
+            }
59
+        }
60 60
 
61
-		return new DataResponse(['valid' => true]);
62
-	}
61
+        return new DataResponse(['valid' => true]);
62
+    }
63 63
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/CheckSetupController.php 1 patch
Indentation   +93 added lines, -93 removed lines patch added patch discarded remove patch
@@ -27,59 +27,59 @@  discard block
 block discarded – undo
27 27
 
28 28
 #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
29 29
 class CheckSetupController extends Controller {
30
-	/** @var Checker */
31
-	private $checker;
32
-
33
-	public function __construct(
34
-		$appName,
35
-		IRequest $request,
36
-		private IConfig $config,
37
-		private IURLGenerator $urlGenerator,
38
-		private IL10N $l10n,
39
-		Checker $checker,
40
-		private LoggerInterface $logger,
41
-		private ISetupCheckManager $setupCheckManager,
42
-	) {
43
-		parent::__construct($appName, $request);
44
-		$this->checker = $checker;
45
-	}
46
-
47
-	/**
48
-	 * @return DataResponse
49
-	 */
50
-	#[NoCSRFRequired]
51
-	#[NoAdminRequired]
52
-	public function setupCheckManager(): DataResponse {
53
-		return new DataResponse($this->setupCheckManager->runAll());
54
-	}
55
-
56
-	/**
57
-	 * @return RedirectResponse
58
-	 */
59
-	#[NoCSRFRequired]
60
-	#[AuthorizedAdminSetting(settings: Overview::class)]
61
-	public function rescanFailedIntegrityCheck(): RedirectResponse {
62
-		$this->checker->runInstanceVerification();
63
-		return new RedirectResponse(
64
-			$this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'overview'])
65
-		);
66
-	}
67
-
68
-	#[NoCSRFRequired]
69
-	#[AuthorizedAdminSetting(settings: Overview::class)]
70
-	public function getFailedIntegrityCheckFiles(): DataDisplayResponse {
71
-		if (!$this->checker->isCodeCheckEnforced()) {
72
-			return new DataDisplayResponse('Integrity checker has been disabled. Integrity cannot be verified.');
73
-		}
74
-
75
-		$completeResults = $this->checker->getResults();
76
-
77
-		if ($completeResults === null) {
78
-			return new DataDisplayResponse('Integrity checker has not been run. Integrity information not available.');
79
-		}
80
-
81
-		if (!empty($completeResults)) {
82
-			$formattedTextResponse = 'Technical information
30
+    /** @var Checker */
31
+    private $checker;
32
+
33
+    public function __construct(
34
+        $appName,
35
+        IRequest $request,
36
+        private IConfig $config,
37
+        private IURLGenerator $urlGenerator,
38
+        private IL10N $l10n,
39
+        Checker $checker,
40
+        private LoggerInterface $logger,
41
+        private ISetupCheckManager $setupCheckManager,
42
+    ) {
43
+        parent::__construct($appName, $request);
44
+        $this->checker = $checker;
45
+    }
46
+
47
+    /**
48
+     * @return DataResponse
49
+     */
50
+    #[NoCSRFRequired]
51
+    #[NoAdminRequired]
52
+    public function setupCheckManager(): DataResponse {
53
+        return new DataResponse($this->setupCheckManager->runAll());
54
+    }
55
+
56
+    /**
57
+     * @return RedirectResponse
58
+     */
59
+    #[NoCSRFRequired]
60
+    #[AuthorizedAdminSetting(settings: Overview::class)]
61
+    public function rescanFailedIntegrityCheck(): RedirectResponse {
62
+        $this->checker->runInstanceVerification();
63
+        return new RedirectResponse(
64
+            $this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'overview'])
65
+        );
66
+    }
67
+
68
+    #[NoCSRFRequired]
69
+    #[AuthorizedAdminSetting(settings: Overview::class)]
70
+    public function getFailedIntegrityCheckFiles(): DataDisplayResponse {
71
+        if (!$this->checker->isCodeCheckEnforced()) {
72
+            return new DataDisplayResponse('Integrity checker has been disabled. Integrity cannot be verified.');
73
+        }
74
+
75
+        $completeResults = $this->checker->getResults();
76
+
77
+        if ($completeResults === null) {
78
+            return new DataDisplayResponse('Integrity checker has not been run. Integrity information not available.');
79
+        }
80
+
81
+        if (!empty($completeResults)) {
82
+            $formattedTextResponse = 'Technical information
83 83
 =====================
84 84
 The following list covers which files have failed the integrity check. Please read
85 85
 the previous linked documentation to learn more about the errors and how to fix
@@ -88,47 +88,47 @@  discard block
 block discarded – undo
88 88
 Results
89 89
 =======
90 90
 ';
91
-			foreach ($completeResults as $context => $contextResult) {
92
-				$formattedTextResponse .= "- $context\n";
93
-
94
-				foreach ($contextResult as $category => $result) {
95
-					$formattedTextResponse .= "\t- $category\n";
96
-					if ($category !== 'EXCEPTION') {
97
-						foreach ($result as $key => $results) {
98
-							$formattedTextResponse .= "\t\t- $key\n";
99
-						}
100
-					} else {
101
-						foreach ($result as $key => $results) {
102
-							$formattedTextResponse .= "\t\t- $results\n";
103
-						}
104
-					}
105
-				}
106
-			}
107
-
108
-			$formattedTextResponse .= '
91
+            foreach ($completeResults as $context => $contextResult) {
92
+                $formattedTextResponse .= "- $context\n";
93
+
94
+                foreach ($contextResult as $category => $result) {
95
+                    $formattedTextResponse .= "\t- $category\n";
96
+                    if ($category !== 'EXCEPTION') {
97
+                        foreach ($result as $key => $results) {
98
+                            $formattedTextResponse .= "\t\t- $key\n";
99
+                        }
100
+                    } else {
101
+                        foreach ($result as $key => $results) {
102
+                            $formattedTextResponse .= "\t\t- $results\n";
103
+                        }
104
+                    }
105
+                }
106
+            }
107
+
108
+            $formattedTextResponse .= '
109 109
 Raw output
110 110
 ==========
111 111
 ';
112
-			$formattedTextResponse .= print_r($completeResults, true);
113
-		} else {
114
-			$formattedTextResponse = 'No errors have been found.';
115
-		}
116
-
117
-
118
-		return new DataDisplayResponse(
119
-			$formattedTextResponse,
120
-			Http::STATUS_OK,
121
-			[
122
-				'Content-Type' => 'text/plain',
123
-			]
124
-		);
125
-	}
126
-
127
-	/**
128
-	 * @return DataResponse
129
-	 */
130
-	#[AuthorizedAdminSetting(settings: Overview::class)]
131
-	public function check() {
132
-		return new DataResponse($this->setupCheckManager->runAll());
133
-	}
112
+            $formattedTextResponse .= print_r($completeResults, true);
113
+        } else {
114
+            $formattedTextResponse = 'No errors have been found.';
115
+        }
116
+
117
+
118
+        return new DataDisplayResponse(
119
+            $formattedTextResponse,
120
+            Http::STATUS_OK,
121
+            [
122
+                'Content-Type' => 'text/plain',
123
+            ]
124
+        );
125
+    }
126
+
127
+    /**
128
+     * @return DataResponse
129
+     */
130
+    #[AuthorizedAdminSetting(settings: Overview::class)]
131
+    public function check() {
132
+        return new DataResponse($this->setupCheckManager->runAll());
133
+    }
134 134
 }
Please login to merge, or discard this patch.
apps/files_trashbin/lib/BackgroundJob/ExpireTrash.php 2 patches
Indentation   +115 added lines, -115 removed lines patch added patch discarded remove patch
@@ -23,119 +23,119 @@
 block discarded – undo
23 23
 use Psr\Log\LoggerInterface;
24 24
 
25 25
 class ExpireTrash extends TimedJob {
26
-	public const TOGGLE_CONFIG_KEY_NAME = 'background_job_expire_trash';
27
-	public const OFFSET_CONFIG_KEY_NAME = 'background_job_expire_trash_offset';
28
-	private const THIRTY_MINUTES = 30 * 60;
29
-	private const USER_BATCH_SIZE = 10;
30
-
31
-	public function __construct(
32
-		private IAppConfig $appConfig,
33
-		private IUserManager $userManager,
34
-		private Expiration $expiration,
35
-		private LoggerInterface $logger,
36
-		private SetupManager $setupManager,
37
-		private ILockingProvider $lockingProvider,
38
-		ITimeFactory $time,
39
-	) {
40
-		parent::__construct($time);
41
-		$this->setInterval(self::THIRTY_MINUTES);
42
-	}
43
-
44
-	protected function run($argument) {
45
-		$backgroundJob = $this->appConfig->getValueBool(Application::APP_ID, self::TOGGLE_CONFIG_KEY_NAME, true);
46
-		if (!$backgroundJob) {
47
-			return;
48
-		}
49
-
50
-		$maxAge = $this->expiration->getMaxAgeAsTimestamp();
51
-		if (!$maxAge) {
52
-			return;
53
-		}
54
-
55
-		$startTime = time();
56
-
57
-		// Process users in batches of 10, but don't run for more than 30 minutes
58
-		while (time() < $startTime + self::THIRTY_MINUTES) {
59
-			$offset = $this->getNextOffset();
60
-			$users = $this->userManager->getSeenUsers($offset, self::USER_BATCH_SIZE);
61
-			$count = 0;
62
-
63
-			foreach ($users as $user) {
64
-				$uid = $user->getUID();
65
-				$count++;
66
-
67
-				try {
68
-					if ($this->setupFS($user)) {
69
-						$dirContent = Helper::getTrashFiles('/', $uid, 'mtime');
70
-						Trashbin::deleteExpiredFiles($dirContent, $uid);
71
-					}
72
-				} catch (\Throwable $e) {
73
-					$this->logger->error('Error while expiring trashbin for user ' . $uid, ['exception' => $e]);
74
-				} finally {
75
-					$this->setupManager->tearDown();
76
-				}
77
-			}
78
-
79
-			// If the last batch was not full it means that we reached the end of the user list.
80
-			if ($count < self::USER_BATCH_SIZE) {
81
-				$this->resetOffset();
82
-				break;
83
-			}
84
-		}
85
-	}
86
-
87
-	/**
88
-	 * Act on behalf on trash item owner
89
-	 */
90
-	protected function setupFS(IUser $user): bool {
91
-		$this->setupManager->setupForUser($user);
92
-
93
-		// Check if this user has a trashbin directory
94
-		$view = new View('/' . $user->getUID());
95
-		if (!$view->is_dir('/files_trashbin/files')) {
96
-			return false;
97
-		}
98
-
99
-		return true;
100
-	}
101
-
102
-	private function getNextOffset(): int {
103
-		return $this->runMutexOperation(function () {
104
-			$this->appConfig->clearCache();
105
-
106
-			$offset = $this->appConfig->getValueInt(Application::APP_ID, self::OFFSET_CONFIG_KEY_NAME, 0);
107
-			$this->appConfig->setValueInt(Application::APP_ID, self::OFFSET_CONFIG_KEY_NAME, $offset + self::USER_BATCH_SIZE);
108
-
109
-			return $offset;
110
-		});
111
-
112
-	}
113
-
114
-	private function resetOffset() {
115
-		$this->runMutexOperation(function (): void {
116
-			$this->appConfig->setValueInt(Application::APP_ID, self::OFFSET_CONFIG_KEY_NAME, 0);
117
-		});
118
-	}
119
-
120
-	private function runMutexOperation($operation): mixed {
121
-		$acquired = false;
122
-
123
-		while ($acquired === false) {
124
-			try {
125
-				$this->lockingProvider->acquireLock(self::OFFSET_CONFIG_KEY_NAME, ILockingProvider::LOCK_EXCLUSIVE, 'Expire trashbin background job offset');
126
-				$acquired = true;
127
-			} catch (LockedException $e) {
128
-				// wait a bit and try again
129
-				usleep(100000);
130
-			}
131
-		}
132
-
133
-		try {
134
-			$result = $operation();
135
-		} finally {
136
-			$this->lockingProvider->releaseLock(self::OFFSET_CONFIG_KEY_NAME, ILockingProvider::LOCK_EXCLUSIVE);
137
-		}
138
-
139
-		return $result;
140
-	}
26
+    public const TOGGLE_CONFIG_KEY_NAME = 'background_job_expire_trash';
27
+    public const OFFSET_CONFIG_KEY_NAME = 'background_job_expire_trash_offset';
28
+    private const THIRTY_MINUTES = 30 * 60;
29
+    private const USER_BATCH_SIZE = 10;
30
+
31
+    public function __construct(
32
+        private IAppConfig $appConfig,
33
+        private IUserManager $userManager,
34
+        private Expiration $expiration,
35
+        private LoggerInterface $logger,
36
+        private SetupManager $setupManager,
37
+        private ILockingProvider $lockingProvider,
38
+        ITimeFactory $time,
39
+    ) {
40
+        parent::__construct($time);
41
+        $this->setInterval(self::THIRTY_MINUTES);
42
+    }
43
+
44
+    protected function run($argument) {
45
+        $backgroundJob = $this->appConfig->getValueBool(Application::APP_ID, self::TOGGLE_CONFIG_KEY_NAME, true);
46
+        if (!$backgroundJob) {
47
+            return;
48
+        }
49
+
50
+        $maxAge = $this->expiration->getMaxAgeAsTimestamp();
51
+        if (!$maxAge) {
52
+            return;
53
+        }
54
+
55
+        $startTime = time();
56
+
57
+        // Process users in batches of 10, but don't run for more than 30 minutes
58
+        while (time() < $startTime + self::THIRTY_MINUTES) {
59
+            $offset = $this->getNextOffset();
60
+            $users = $this->userManager->getSeenUsers($offset, self::USER_BATCH_SIZE);
61
+            $count = 0;
62
+
63
+            foreach ($users as $user) {
64
+                $uid = $user->getUID();
65
+                $count++;
66
+
67
+                try {
68
+                    if ($this->setupFS($user)) {
69
+                        $dirContent = Helper::getTrashFiles('/', $uid, 'mtime');
70
+                        Trashbin::deleteExpiredFiles($dirContent, $uid);
71
+                    }
72
+                } catch (\Throwable $e) {
73
+                    $this->logger->error('Error while expiring trashbin for user ' . $uid, ['exception' => $e]);
74
+                } finally {
75
+                    $this->setupManager->tearDown();
76
+                }
77
+            }
78
+
79
+            // If the last batch was not full it means that we reached the end of the user list.
80
+            if ($count < self::USER_BATCH_SIZE) {
81
+                $this->resetOffset();
82
+                break;
83
+            }
84
+        }
85
+    }
86
+
87
+    /**
88
+     * Act on behalf on trash item owner
89
+     */
90
+    protected function setupFS(IUser $user): bool {
91
+        $this->setupManager->setupForUser($user);
92
+
93
+        // Check if this user has a trashbin directory
94
+        $view = new View('/' . $user->getUID());
95
+        if (!$view->is_dir('/files_trashbin/files')) {
96
+            return false;
97
+        }
98
+
99
+        return true;
100
+    }
101
+
102
+    private function getNextOffset(): int {
103
+        return $this->runMutexOperation(function () {
104
+            $this->appConfig->clearCache();
105
+
106
+            $offset = $this->appConfig->getValueInt(Application::APP_ID, self::OFFSET_CONFIG_KEY_NAME, 0);
107
+            $this->appConfig->setValueInt(Application::APP_ID, self::OFFSET_CONFIG_KEY_NAME, $offset + self::USER_BATCH_SIZE);
108
+
109
+            return $offset;
110
+        });
111
+
112
+    }
113
+
114
+    private function resetOffset() {
115
+        $this->runMutexOperation(function (): void {
116
+            $this->appConfig->setValueInt(Application::APP_ID, self::OFFSET_CONFIG_KEY_NAME, 0);
117
+        });
118
+    }
119
+
120
+    private function runMutexOperation($operation): mixed {
121
+        $acquired = false;
122
+
123
+        while ($acquired === false) {
124
+            try {
125
+                $this->lockingProvider->acquireLock(self::OFFSET_CONFIG_KEY_NAME, ILockingProvider::LOCK_EXCLUSIVE, 'Expire trashbin background job offset');
126
+                $acquired = true;
127
+            } catch (LockedException $e) {
128
+                // wait a bit and try again
129
+                usleep(100000);
130
+            }
131
+        }
132
+
133
+        try {
134
+            $result = $operation();
135
+        } finally {
136
+            $this->lockingProvider->releaseLock(self::OFFSET_CONFIG_KEY_NAME, ILockingProvider::LOCK_EXCLUSIVE);
137
+        }
138
+
139
+        return $result;
140
+    }
141 141
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
 						Trashbin::deleteExpiredFiles($dirContent, $uid);
71 71
 					}
72 72
 				} catch (\Throwable $e) {
73
-					$this->logger->error('Error while expiring trashbin for user ' . $uid, ['exception' => $e]);
73
+					$this->logger->error('Error while expiring trashbin for user '.$uid, ['exception' => $e]);
74 74
 				} finally {
75 75
 					$this->setupManager->tearDown();
76 76
 				}
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
 		$this->setupManager->setupForUser($user);
92 92
 
93 93
 		// Check if this user has a trashbin directory
94
-		$view = new View('/' . $user->getUID());
94
+		$view = new View('/'.$user->getUID());
95 95
 		if (!$view->is_dir('/files_trashbin/files')) {
96 96
 			return false;
97 97
 		}
@@ -100,7 +100,7 @@  discard block
 block discarded – undo
100 100
 	}
101 101
 
102 102
 	private function getNextOffset(): int {
103
-		return $this->runMutexOperation(function () {
103
+		return $this->runMutexOperation(function() {
104 104
 			$this->appConfig->clearCache();
105 105
 
106 106
 			$offset = $this->appConfig->getValueInt(Application::APP_ID, self::OFFSET_CONFIG_KEY_NAME, 0);
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
 	}
113 113
 
114 114
 	private function resetOffset() {
115
-		$this->runMutexOperation(function (): void {
115
+		$this->runMutexOperation(function(): void {
116 116
 			$this->appConfig->setValueInt(Application::APP_ID, self::OFFSET_CONFIG_KEY_NAME, 0);
117 117
 		});
118 118
 	}
Please login to merge, or discard this patch.
apps/files_trashbin/tests/Command/ExpireTrashTest.php 1 patch
Indentation   +121 added lines, -121 removed lines patch added patch discarded remove patch
@@ -29,126 +29,126 @@
 block discarded – undo
29 29
  * @package OCA\Files_Trashbin\Tests\Command
30 30
  */
31 31
 class ExpireTrashTest extends TestCase {
32
-	private Expiration $expiration;
33
-	private Node $userFolder;
34
-	private IConfig $config;
35
-	private IUserManager $userManager;
36
-	private IUser $user;
37
-	private ITimeFactory $timeFactory;
32
+    private Expiration $expiration;
33
+    private Node $userFolder;
34
+    private IConfig $config;
35
+    private IUserManager $userManager;
36
+    private IUser $user;
37
+    private ITimeFactory $timeFactory;
38 38
 
39
-
40
-	protected function setUp(): void {
41
-		parent::setUp();
42
-
43
-		$this->config = Server::get(IConfig::class);
44
-		$this->timeFactory = $this->createMock(ITimeFactory::class);
45
-		$this->expiration = Server::get(Expiration::class);
46
-		$this->invokePrivate($this->expiration, 'timeFactory', [$this->timeFactory]);
47
-
48
-		$userId = self::getUniqueID('user');
49
-		$this->userManager = Server::get(IUserManager::class);
50
-		$this->user = $this->userManager->createUser($userId, $userId);
51
-
52
-		$this->loginAsUser($userId);
53
-		$this->userFolder = Server::get(IRootFolder::class)->getUserFolder($userId);
54
-	}
55
-
56
-	protected function tearDown(): void {
57
-		$this->logout();
58
-
59
-		if (isset($this->user)) {
60
-			$this->user->delete();
61
-		}
62
-
63
-		$this->invokePrivate($this->expiration, 'timeFactory', [Server::get(ITimeFactory::class)]);
64
-		parent::tearDown();
65
-	}
66
-
67
-	#[\PHPUnit\Framework\Attributes\DataProvider('retentionObligationProvider')]
68
-	public function testRetentionObligation(string $obligation, string $quota, int $elapsed, int $fileSize, bool $shouldExpire): void {
69
-		$this->config->setSystemValues(['trashbin_retention_obligation' => $obligation]);
70
-		$this->expiration->setRetentionObligation($obligation);
71
-
72
-		$this->user->setQuota($quota);
73
-
74
-		$bytes = 'ABCDEFGHIKLMNOPQRSTUVWXYZ';
75
-
76
-		$file = 'foo.txt';
77
-		$this->userFolder->newFile($file, substr($bytes, 0, $fileSize));
78
-
79
-		$filemtime = $this->userFolder->get($file)->getMTime();
80
-		$this->timeFactory->expects($this->any())
81
-			->method('getTime')
82
-			->willReturn($filemtime + $elapsed);
83
-		$this->userFolder->get($file)->delete();
84
-		$this->userFolder->getStorage()
85
-			->getCache()
86
-			->put('files_trashbin', ['size' => $fileSize, 'unencrypted_size' => $fileSize]);
87
-
88
-		$userId = $this->user->getUID();
89
-		$trashFiles = Helper::getTrashFiles('/', $userId);
90
-		$this->assertEquals(1, count($trashFiles));
91
-
92
-		$outputInterface = $this->createMock(OutputInterface::class);
93
-		$inputInterface = $this->createMock(InputInterface::class);
94
-		$inputInterface->expects($this->any())
95
-			->method('getArgument')
96
-			->with('user_id')
97
-			->willReturn([$userId]);
98
-
99
-		$command = new ExpireTrash(
100
-			Server::get(LoggerInterface::class),
101
-			Server::get(IUserManager::class),
102
-			$this->expiration
103
-		);
104
-
105
-		$this->invokePrivate($command, 'execute', [$inputInterface, $outputInterface]);
106
-
107
-		$trashFiles = Helper::getTrashFiles('/', $userId);
108
-		$this->assertEquals($shouldExpire ? 0 : 1, count($trashFiles));
109
-	}
110
-
111
-	public static function retentionObligationProvider(): array {
112
-		$hour = 3600; // 60 * 60
113
-
114
-		$oneDay = 24 * $hour;
115
-		$fiveDays = 24 * 5 * $hour;
116
-		$tenDays = 24 * 10 * $hour;
117
-		$elevenDays = 24 * 11 * $hour;
118
-
119
-		return [
120
-			['disabled', '20 B', 0, 1, false],
121
-
122
-			['auto', '20 B', 0, 5, false],
123
-			['auto', '20 B', 0, 21, true],
124
-
125
-			['0, auto', '20 B', 0, 21, true],
126
-			['0, auto', '20 B', $oneDay, 5, false],
127
-			['0, auto', '20 B', $oneDay, 19, true],
128
-			['0, auto', '20 B', 0, 19, true],
129
-
130
-			['auto, 0', '20 B', $oneDay, 19, true],
131
-			['auto, 0', '20 B', $oneDay, 21, true],
132
-			['auto, 0', '20 B', 0, 5, false],
133
-			['auto, 0', '20 B', 0, 19, true],
134
-
135
-			['1, auto', '20 B', 0, 5, false],
136
-			['1, auto', '20 B', $fiveDays, 5, false],
137
-			['1, auto', '20 B', $fiveDays, 21, true],
138
-
139
-			['auto, 1', '20 B', 0, 21, true],
140
-			['auto, 1', '20 B', 0, 5, false],
141
-			['auto, 1', '20 B', $fiveDays, 5, true],
142
-			['auto, 1', '20 B', $oneDay, 5, false],
143
-
144
-			['2, 10', '20 B', $fiveDays, 5, false],
145
-			['2, 10', '20 B', $fiveDays, 20, true],
146
-			['2, 10', '20 B', $elevenDays, 5, true],
147
-
148
-			['10, 2', '20 B', $fiveDays, 5, false],
149
-			['10, 2', '20 B', $fiveDays, 21, false],
150
-			['10, 2', '20 B', $tenDays, 5, false],
151
-			['10, 2', '20 B', $elevenDays, 5, true]
152
-		];
153
-	}
39
+
40
+    protected function setUp(): void {
41
+        parent::setUp();
42
+
43
+        $this->config = Server::get(IConfig::class);
44
+        $this->timeFactory = $this->createMock(ITimeFactory::class);
45
+        $this->expiration = Server::get(Expiration::class);
46
+        $this->invokePrivate($this->expiration, 'timeFactory', [$this->timeFactory]);
47
+
48
+        $userId = self::getUniqueID('user');
49
+        $this->userManager = Server::get(IUserManager::class);
50
+        $this->user = $this->userManager->createUser($userId, $userId);
51
+
52
+        $this->loginAsUser($userId);
53
+        $this->userFolder = Server::get(IRootFolder::class)->getUserFolder($userId);
54
+    }
55
+
56
+    protected function tearDown(): void {
57
+        $this->logout();
58
+
59
+        if (isset($this->user)) {
60
+            $this->user->delete();
61
+        }
62
+
63
+        $this->invokePrivate($this->expiration, 'timeFactory', [Server::get(ITimeFactory::class)]);
64
+        parent::tearDown();
65
+    }
66
+
67
+    #[\PHPUnit\Framework\Attributes\DataProvider('retentionObligationProvider')]
68
+    public function testRetentionObligation(string $obligation, string $quota, int $elapsed, int $fileSize, bool $shouldExpire): void {
69
+        $this->config->setSystemValues(['trashbin_retention_obligation' => $obligation]);
70
+        $this->expiration->setRetentionObligation($obligation);
71
+
72
+        $this->user->setQuota($quota);
73
+
74
+        $bytes = 'ABCDEFGHIKLMNOPQRSTUVWXYZ';
75
+
76
+        $file = 'foo.txt';
77
+        $this->userFolder->newFile($file, substr($bytes, 0, $fileSize));
78
+
79
+        $filemtime = $this->userFolder->get($file)->getMTime();
80
+        $this->timeFactory->expects($this->any())
81
+            ->method('getTime')
82
+            ->willReturn($filemtime + $elapsed);
83
+        $this->userFolder->get($file)->delete();
84
+        $this->userFolder->getStorage()
85
+            ->getCache()
86
+            ->put('files_trashbin', ['size' => $fileSize, 'unencrypted_size' => $fileSize]);
87
+
88
+        $userId = $this->user->getUID();
89
+        $trashFiles = Helper::getTrashFiles('/', $userId);
90
+        $this->assertEquals(1, count($trashFiles));
91
+
92
+        $outputInterface = $this->createMock(OutputInterface::class);
93
+        $inputInterface = $this->createMock(InputInterface::class);
94
+        $inputInterface->expects($this->any())
95
+            ->method('getArgument')
96
+            ->with('user_id')
97
+            ->willReturn([$userId]);
98
+
99
+        $command = new ExpireTrash(
100
+            Server::get(LoggerInterface::class),
101
+            Server::get(IUserManager::class),
102
+            $this->expiration
103
+        );
104
+
105
+        $this->invokePrivate($command, 'execute', [$inputInterface, $outputInterface]);
106
+
107
+        $trashFiles = Helper::getTrashFiles('/', $userId);
108
+        $this->assertEquals($shouldExpire ? 0 : 1, count($trashFiles));
109
+    }
110
+
111
+    public static function retentionObligationProvider(): array {
112
+        $hour = 3600; // 60 * 60
113
+
114
+        $oneDay = 24 * $hour;
115
+        $fiveDays = 24 * 5 * $hour;
116
+        $tenDays = 24 * 10 * $hour;
117
+        $elevenDays = 24 * 11 * $hour;
118
+
119
+        return [
120
+            ['disabled', '20 B', 0, 1, false],
121
+
122
+            ['auto', '20 B', 0, 5, false],
123
+            ['auto', '20 B', 0, 21, true],
124
+
125
+            ['0, auto', '20 B', 0, 21, true],
126
+            ['0, auto', '20 B', $oneDay, 5, false],
127
+            ['0, auto', '20 B', $oneDay, 19, true],
128
+            ['0, auto', '20 B', 0, 19, true],
129
+
130
+            ['auto, 0', '20 B', $oneDay, 19, true],
131
+            ['auto, 0', '20 B', $oneDay, 21, true],
132
+            ['auto, 0', '20 B', 0, 5, false],
133
+            ['auto, 0', '20 B', 0, 19, true],
134
+
135
+            ['1, auto', '20 B', 0, 5, false],
136
+            ['1, auto', '20 B', $fiveDays, 5, false],
137
+            ['1, auto', '20 B', $fiveDays, 21, true],
138
+
139
+            ['auto, 1', '20 B', 0, 21, true],
140
+            ['auto, 1', '20 B', 0, 5, false],
141
+            ['auto, 1', '20 B', $fiveDays, 5, true],
142
+            ['auto, 1', '20 B', $oneDay, 5, false],
143
+
144
+            ['2, 10', '20 B', $fiveDays, 5, false],
145
+            ['2, 10', '20 B', $fiveDays, 20, true],
146
+            ['2, 10', '20 B', $elevenDays, 5, true],
147
+
148
+            ['10, 2', '20 B', $fiveDays, 5, false],
149
+            ['10, 2', '20 B', $fiveDays, 21, false],
150
+            ['10, 2', '20 B', $tenDays, 5, false],
151
+            ['10, 2', '20 B', $elevenDays, 5, true]
152
+        ];
153
+    }
154 154
 }
Please login to merge, or discard this patch.
apps/comments/lib/Search/Result.php 1 patch
Indentation   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -14,96 +14,96 @@
 block discarded – undo
14 14
  * @deprecated 20.0.0
15 15
  */
16 16
 class Result extends BaseResult {
17
-	/**
18
-	 * @deprecated 20.0.0
19
-	 */
20
-	public $type = 'comment';
21
-	/**
22
-	 * @deprecated 20.0.0
23
-	 */
24
-	public $comment;
25
-	/**
26
-	 * @deprecated 20.0.0
27
-	 */
28
-	public $authorId;
29
-	/**
30
-	 * @deprecated 20.0.0
31
-	 */
32
-	public $path;
33
-	/**
34
-	 * @deprecated 20.0.0
35
-	 */
36
-	public $fileName;
17
+    /**
18
+     * @deprecated 20.0.0
19
+     */
20
+    public $type = 'comment';
21
+    /**
22
+     * @deprecated 20.0.0
23
+     */
24
+    public $comment;
25
+    /**
26
+     * @deprecated 20.0.0
27
+     */
28
+    public $authorId;
29
+    /**
30
+     * @deprecated 20.0.0
31
+     */
32
+    public $path;
33
+    /**
34
+     * @deprecated 20.0.0
35
+     */
36
+    public $fileName;
37 37
 
38
-	/**
39
-	 * @throws NotFoundException
40
-	 * @deprecated 20.0.0
41
-	 */
42
-	public function __construct(
43
-		string $search,
44
-		IComment $comment,
45
-		/**
46
-		 * @deprecated 20.0.0
47
-		 */
48
-		public string $authorName,
49
-		string $path,
50
-		/**
51
-		 * @deprecated 20.0.0
52
-		 */
53
-		public int $fileId,
54
-	) {
55
-		parent::__construct(
56
-			$comment->getId(),
57
-			$comment->getMessage()
58
-			/* @todo , [link to file] */
59
-		);
38
+    /**
39
+     * @throws NotFoundException
40
+     * @deprecated 20.0.0
41
+     */
42
+    public function __construct(
43
+        string $search,
44
+        IComment $comment,
45
+        /**
46
+         * @deprecated 20.0.0
47
+         */
48
+        public string $authorName,
49
+        string $path,
50
+        /**
51
+         * @deprecated 20.0.0
52
+         */
53
+        public int $fileId,
54
+    ) {
55
+        parent::__construct(
56
+            $comment->getId(),
57
+            $comment->getMessage()
58
+            /* @todo , [link to file] */
59
+        );
60 60
 
61
-		$this->comment = $this->getRelevantMessagePart($comment->getMessage(), $search);
62
-		$this->authorId = $comment->getActorId();
63
-		$this->fileName = basename($path);
64
-		$this->path = $this->getVisiblePath($path);
65
-	}
61
+        $this->comment = $this->getRelevantMessagePart($comment->getMessage(), $search);
62
+        $this->authorId = $comment->getActorId();
63
+        $this->fileName = basename($path);
64
+        $this->path = $this->getVisiblePath($path);
65
+    }
66 66
 
67
-	/**
68
-	 * @throws NotFoundException
69
-	 */
70
-	protected function getVisiblePath(string $path): string {
71
-		$segments = explode('/', trim($path, '/'), 3);
67
+    /**
68
+     * @throws NotFoundException
69
+     */
70
+    protected function getVisiblePath(string $path): string {
71
+        $segments = explode('/', trim($path, '/'), 3);
72 72
 
73
-		if (!isset($segments[2])) {
74
-			throw new NotFoundException('Path not inside visible section');
75
-		}
73
+        if (!isset($segments[2])) {
74
+            throw new NotFoundException('Path not inside visible section');
75
+        }
76 76
 
77
-		return $segments[2];
78
-	}
77
+        return $segments[2];
78
+    }
79 79
 
80
-	/**
81
-	 * @throws NotFoundException
82
-	 */
83
-	protected function getRelevantMessagePart(string $message, string $search): string {
84
-		$start = mb_stripos($message, $search);
85
-		if ($start === false) {
86
-			throw new NotFoundException('Comment section not found');
87
-		}
80
+    /**
81
+     * @throws NotFoundException
82
+     */
83
+    protected function getRelevantMessagePart(string $message, string $search): string {
84
+        $start = mb_stripos($message, $search);
85
+        if ($start === false) {
86
+            throw new NotFoundException('Comment section not found');
87
+        }
88 88
 
89
-		$end = $start + mb_strlen($search);
89
+        $end = $start + mb_strlen($search);
90 90
 
91
-		if ($start <= 25) {
92
-			$start = 0;
93
-			$prefix = '';
94
-		} else {
95
-			$start -= 25;
96
-			$prefix = '…';
97
-		}
91
+        if ($start <= 25) {
92
+            $start = 0;
93
+            $prefix = '';
94
+        } else {
95
+            $start -= 25;
96
+            $prefix = '…';
97
+        }
98 98
 
99
-		if ((mb_strlen($message) - $end) <= 25) {
100
-			$end = mb_strlen($message);
101
-			$suffix = '';
102
-		} else {
103
-			$end += 25;
104
-			$suffix = '…';
105
-		}
99
+        if ((mb_strlen($message) - $end) <= 25) {
100
+            $end = mb_strlen($message);
101
+            $suffix = '';
102
+        } else {
103
+            $end += 25;
104
+            $suffix = '…';
105
+        }
106 106
 
107
-		return $prefix . mb_substr($message, $start, $end - $start) . $suffix;
108
-	}
107
+        return $prefix . mb_substr($message, $start, $end - $start) . $suffix;
108
+    }
109 109
 }
Please login to merge, or discard this patch.
apps/federation/lib/Controller/SettingsController.php 1 patch
Indentation   +90 added lines, -90 removed lines patch added patch discarded remove patch
@@ -21,105 +21,105 @@
 block discarded – undo
21 21
 use Psr\Log\LoggerInterface;
22 22
 
23 23
 class SettingsController extends OCSController {
24
-	public function __construct(
25
-		string $appName,
26
-		IRequest $request,
27
-		private IL10N $l,
28
-		private TrustedServers $trustedServers,
29
-		private LoggerInterface $logger,
30
-	) {
31
-		parent::__construct($appName, $request);
32
-	}
24
+    public function __construct(
25
+        string $appName,
26
+        IRequest $request,
27
+        private IL10N $l,
28
+        private TrustedServers $trustedServers,
29
+        private LoggerInterface $logger,
30
+    ) {
31
+        parent::__construct($appName, $request);
32
+    }
33 33
 
34 34
 
35
-	/**
36
-	 * Add server to the list of trusted Nextcloud servers
37
-	 *
38
-	 * @param string $url The URL of the server to add
39
-	 * @return DataResponse<Http::STATUS_OK, array{id: int, message: string, url: string}, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_CONFLICT, array{message: string}, array{}>
40
-	 *
41
-	 * 200: Server added successfully
42
-	 * 404: Server not found at the given URL
43
-	 * 409: Server is already in the list of trusted servers
44
-	 */
45
-	#[AuthorizedAdminSetting(settings: Admin::class)]
46
-	#[ApiRoute(verb: 'POST', url: '/trusted-servers')]
47
-	public function addServer(string $url): DataResponse {
48
-		$this->checkServer(trim($url));
35
+    /**
36
+     * Add server to the list of trusted Nextcloud servers
37
+     *
38
+     * @param string $url The URL of the server to add
39
+     * @return DataResponse<Http::STATUS_OK, array{id: int, message: string, url: string}, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_CONFLICT, array{message: string}, array{}>
40
+     *
41
+     * 200: Server added successfully
42
+     * 404: Server not found at the given URL
43
+     * 409: Server is already in the list of trusted servers
44
+     */
45
+    #[AuthorizedAdminSetting(settings: Admin::class)]
46
+    #[ApiRoute(verb: 'POST', url: '/trusted-servers')]
47
+    public function addServer(string $url): DataResponse {
48
+        $this->checkServer(trim($url));
49 49
 
50
-		// Add the server to the list of trusted servers, all is well
51
-		$id = $this->trustedServers->addServer(trim($url));
52
-		return new DataResponse([
53
-			'url' => $url,
54
-			'id' => $id,
55
-			'message' => $this->l->t('Added to the list of trusted servers')
56
-		]);
57
-	}
50
+        // Add the server to the list of trusted servers, all is well
51
+        $id = $this->trustedServers->addServer(trim($url));
52
+        return new DataResponse([
53
+            'url' => $url,
54
+            'id' => $id,
55
+            'message' => $this->l->t('Added to the list of trusted servers')
56
+        ]);
57
+    }
58 58
 
59
-	/**
60
-	 * Add server to the list of trusted Nextcloud servers
61
-	 *
62
-	 * @param int $id The ID of the trusted server to remove
63
-	 * @return DataResponse<Http::STATUS_OK, array{id: int}, array{}>|DataResponse<Http::STATUS_NOT_FOUND, array{message: string}, array{}>
64
-	 *
65
-	 * 200: Server removed successfully
66
-	 * 404: Server not found at the given ID
67
-	 */
68
-	#[AuthorizedAdminSetting(settings: Admin::class)]
69
-	#[ApiRoute(verb: 'DELETE', url: '/trusted-servers/{id}', requirements: ['id' => '\d+'])]
70
-	public function removeServer(int $id): DataResponse {
71
-		try {
72
-			$this->trustedServers->getServer($id);
73
-		} catch (\Exception $e) {
74
-			throw new OCSNotFoundException($this->l->t('No server found with ID: %s', [$id]));
75
-		}
59
+    /**
60
+     * Add server to the list of trusted Nextcloud servers
61
+     *
62
+     * @param int $id The ID of the trusted server to remove
63
+     * @return DataResponse<Http::STATUS_OK, array{id: int}, array{}>|DataResponse<Http::STATUS_NOT_FOUND, array{message: string}, array{}>
64
+     *
65
+     * 200: Server removed successfully
66
+     * 404: Server not found at the given ID
67
+     */
68
+    #[AuthorizedAdminSetting(settings: Admin::class)]
69
+    #[ApiRoute(verb: 'DELETE', url: '/trusted-servers/{id}', requirements: ['id' => '\d+'])]
70
+    public function removeServer(int $id): DataResponse {
71
+        try {
72
+            $this->trustedServers->getServer($id);
73
+        } catch (\Exception $e) {
74
+            throw new OCSNotFoundException($this->l->t('No server found with ID: %s', [$id]));
75
+        }
76 76
 
77
-		try {
78
-			$this->trustedServers->removeServer($id);
79
-			return new DataResponse(['id' => $id]);
80
-		} catch (\Exception $e) {
81
-			$this->logger->error($e->getMessage(), ['e' => $e]);
82
-			throw new OCSException($this->l->t('Could not remove server'), Http::STATUS_INTERNAL_SERVER_ERROR);
83
-		}
84
-	}
77
+        try {
78
+            $this->trustedServers->removeServer($id);
79
+            return new DataResponse(['id' => $id]);
80
+        } catch (\Exception $e) {
81
+            $this->logger->error($e->getMessage(), ['e' => $e]);
82
+            throw new OCSException($this->l->t('Could not remove server'), Http::STATUS_INTERNAL_SERVER_ERROR);
83
+        }
84
+    }
85 85
 
86
-	/**
87
-	 * List all trusted servers
88
-	 *
89
-	 * @return DataResponse<Http::STATUS_OK, list<array{id: int, status: int, url: string}>, array{}>
90
-	 *
91
-	 * 200: List of trusted servers
92
-	 */
93
-	#[AuthorizedAdminSetting(settings: Admin::class)]
94
-	#[ApiRoute(verb: 'GET', url: '/trusted-servers')]
95
-	public function getServers(): DataResponse {
96
-		$servers = $this->trustedServers->getServers();
86
+    /**
87
+     * List all trusted servers
88
+     *
89
+     * @return DataResponse<Http::STATUS_OK, list<array{id: int, status: int, url: string}>, array{}>
90
+     *
91
+     * 200: List of trusted servers
92
+     */
93
+    #[AuthorizedAdminSetting(settings: Admin::class)]
94
+    #[ApiRoute(verb: 'GET', url: '/trusted-servers')]
95
+    public function getServers(): DataResponse {
96
+        $servers = $this->trustedServers->getServers();
97 97
 
98
-		// obfuscate the shared secret
99
-		$servers = array_map(function ($server) {
100
-			return [
101
-				'url' => $server['url'],
102
-				'id' => $server['id'],
103
-				'status' => $server['status'],
104
-			];
105
-		}, $servers);
98
+        // obfuscate the shared secret
99
+        $servers = array_map(function ($server) {
100
+            return [
101
+                'url' => $server['url'],
102
+                'id' => $server['id'],
103
+                'status' => $server['status'],
104
+            ];
105
+        }, $servers);
106 106
 
107
-		// return the list of trusted servers
108
-		return new DataResponse($servers);
109
-	}
107
+        // return the list of trusted servers
108
+        return new DataResponse($servers);
109
+    }
110 110
 
111 111
 
112
-	/**
113
-	 * Check if the server should be added to the list of trusted servers or not.
114
-	 */
115
-	#[AuthorizedAdminSetting(settings: Admin::class)]
116
-	protected function checkServer(string $url): void {
117
-		if ($this->trustedServers->isTrustedServer($url) === true) {
118
-			throw new OCSException($this->l->t('Server is already in the list of trusted servers.'), Http::STATUS_CONFLICT);
119
-		}
112
+    /**
113
+     * Check if the server should be added to the list of trusted servers or not.
114
+     */
115
+    #[AuthorizedAdminSetting(settings: Admin::class)]
116
+    protected function checkServer(string $url): void {
117
+        if ($this->trustedServers->isTrustedServer($url) === true) {
118
+            throw new OCSException($this->l->t('Server is already in the list of trusted servers.'), Http::STATUS_CONFLICT);
119
+        }
120 120
 
121
-		if ($this->trustedServers->isNextcloudServer($url) === false) {
122
-			throw new OCSNotFoundException($this->l->t('No server to federate with found'));
123
-		}
124
-	}
121
+        if ($this->trustedServers->isNextcloudServer($url) === false) {
122
+            throw new OCSNotFoundException($this->l->t('No server to federate with found'));
123
+        }
124
+    }
125 125
 }
Please login to merge, or discard this patch.