Skip to content

Commit cc48ec4

Browse files
authored
Merge pull request #58541 from nextcloud/carl/frankenphp
feat: frankenphp
2 parents d3b8521 + 3750945 commit cc48ec4

18 files changed

Lines changed: 1666 additions & 1416 deletions

File tree

Caddyfile

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# THIS IS AN EXPERIMENTAL FEATURE
5+
# DO NOT USE THIS IN PRODUCTION, YOU HAVE BEEN WARNED.
6+
7+
localhost {
8+
php_server {
9+
worker {
10+
file index.php
11+
watch
12+
}
13+
}
14+
15+
log {
16+
level ERROR
17+
output stderr
18+
}
19+
20+
encode gzip
21+
22+
redir /.well-known/carddav /remote.php/dav 301
23+
redir /.well-known/caldav /remote.php/dav 301
24+
25+
# Rule: Maps most RFC 8615 compliant well-known URIs to our main frontend controller (/index.php) by default
26+
@wellKnown {
27+
path "/.well-known/"
28+
not {
29+
path /.well-known/acme-challenge
30+
path /.well-known/pki-validation
31+
}
32+
}
33+
rewrite @wellKnown /index.php
34+
35+
rewrite /ocm-provider/ /index.php
36+
37+
@forbidden {
38+
path /.htaccess
39+
path /data/*
40+
path /config/*
41+
path /db_structure
42+
path /.xml
43+
path /README
44+
path /3rdparty/*
45+
path /lib/*
46+
path /templates/*
47+
path /occ
48+
path /build
49+
path /tests
50+
path /console.php
51+
path /autotest
52+
path /issue
53+
path /indi
54+
path /db_
55+
path /console
56+
}
57+
respond @forbidden 404
58+
}

apps/testing/appinfo/info.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
<types>
1717
<authentication/>
1818
</types>
19+
20+
<commands>
21+
<command>OCA\Testing\Command\StaticHunt</command>
22+
</commands>
23+
1924
<category>monitoring</category>
2025
<bugs>https://github.com/nextcloud/server/issues</bugs>
2126
<dependencies>

apps/testing/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
1010
'OCA\\Testing\\AlternativeHomeUserBackend' => $baseDir . '/../lib/AlternativeHomeUserBackend.php',
1111
'OCA\\Testing\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
12+
'OCA\\Testing\\Command\\StaticHunt' => $baseDir . '/../lib/Command/StaticHunt.php',
1213
'OCA\\Testing\\Controller\\ConfigController' => $baseDir . '/../lib/Controller/ConfigController.php',
1314
'OCA\\Testing\\Controller\\LockingController' => $baseDir . '/../lib/Controller/LockingController.php',
1415
'OCA\\Testing\\Controller\\RateLimitTestController' => $baseDir . '/../lib/Controller/RateLimitTestController.php',

apps/testing/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ComposerStaticInitTesting
2424
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
2525
'OCA\\Testing\\AlternativeHomeUserBackend' => __DIR__ . '/..' . '/../lib/AlternativeHomeUserBackend.php',
2626
'OCA\\Testing\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
27+
'OCA\\Testing\\Command\\StaticHunt' => __DIR__ . '/..' . '/../lib/Command/StaticHunt.php',
2728
'OCA\\Testing\\Controller\\ConfigController' => __DIR__ . '/..' . '/../lib/Controller/ConfigController.php',
2829
'OCA\\Testing\\Controller\\LockingController' => __DIR__ . '/..' . '/../lib/Controller/LockingController.php',
2930
'OCA\\Testing\\Controller\\RateLimitTestController' => __DIR__ . '/..' . '/../lib/Controller/RateLimitTestController.php',
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\Testing\Command;
11+
12+
use OCP\App\IAppManager;
13+
use Symfony\Component\Console\Command\Command;
14+
use Symfony\Component\Console\Input\InputInterface;
15+
use Symfony\Component\Console\Output\OutputInterface;
16+
17+
class StaticHunt extends Command {
18+
private const SKIP_REGEX = [
19+
'@/templates/.+.php$@',
20+
'@/ajax/.+.php$@',
21+
'@/register_command.php$@',
22+
];
23+
24+
public function __construct(
25+
private IAppManager $appManager,
26+
) {
27+
parent::__construct();
28+
}
29+
30+
#[\Override]
31+
protected function configure(): void {
32+
$this
33+
->setName('testing:static-hunt')
34+
->setDescription('Hunt for static properties in classes');
35+
}
36+
37+
#[\Override]
38+
protected function execute(InputInterface $input, OutputInterface $output): int {
39+
$folders = [
40+
'' => __DIR__ . '/../../../../lib/private/legacy',
41+
'\\OC' => __DIR__ . '/../../../../lib/private',
42+
'\\OC\\Core' => __DIR__ . '/../../../../core',
43+
];
44+
$apps = $this->appManager->getAllAppsInAppsFolders();
45+
foreach ($apps as $app) {
46+
$info = $this->appManager->getAppInfo($app);
47+
if (!isset($info['namespace'])) {
48+
continue;
49+
}
50+
$folders['\\OCA\\' . $info['namespace']] = $this->appManager->getAppPath($app) . '/lib';
51+
}
52+
$stats = [
53+
'classes' => 0,
54+
'properties' => 0,
55+
];
56+
foreach ($folders as $namespace => $folder) {
57+
$this->scanFolder($folder, $namespace, $output, $stats);
58+
}
59+
60+
$output->writeln('<info>Found ' . $stats['properties'] . ' static properties spread among ' . $stats['classes'] . ' classes</info>');
61+
62+
return 0;
63+
}
64+
65+
private function scanFolder(string $folder, string $namespace, OutputInterface $output, array &$stats): void {
66+
$folder = realpath($folder);
67+
$output->writeln('Folder ' . $folder, OutputInterface::VERBOSITY_VERBOSE);
68+
foreach ($this->recursiveGlob($folder) as $filename) {
69+
try {
70+
$filename = realpath($filename);
71+
if (($namespace === '\\OC') && str_contains($filename, 'lib/private/legacy')) {
72+
// Skip legacy in OC as it’s scanned with an empty namespace separately
73+
continue;
74+
}
75+
foreach (self::SKIP_REGEX as $skipRegex) {
76+
if (preg_match($skipRegex, $filename)) {
77+
continue 2;
78+
}
79+
}
80+
$classname = $namespace . substr(str_replace('/', '\\', substr($filename, strlen($folder))), 0, -4);
81+
$output->writeln('Class ' . $classname, OutputInterface::VERBOSITY_VERBOSE);
82+
if (!class_exists($classname)) {
83+
continue;
84+
}
85+
$rClass = new \ReflectionClass($classname);
86+
$staticProperties = $rClass->getStaticProperties();
87+
if (empty($staticProperties)) {
88+
continue;
89+
}
90+
$stats['classes']++;
91+
$output->writeln('<info># ' . str_replace(\OC::$SERVERROOT, '', $filename) . " $classname</info>");
92+
foreach ($staticProperties as $property => $value) {
93+
$propertyObject = $rClass->getProperty($property);
94+
$stats['properties']++;
95+
$output->write("$propertyObject");
96+
}
97+
$output->writeln('');
98+
} catch (\Throwable $t) {
99+
$output->writeln("$t");
100+
}
101+
}
102+
}
103+
104+
private function recursiveGlob(string $path, int $depth = 1): \Generator {
105+
$pattern = $path . str_repeat('/*', $depth);
106+
yield from glob($pattern . '.php');
107+
if (!empty(glob($pattern, GLOB_ONLYDIR))) {
108+
yield from $this->recursiveGlob($path, $depth + 1);
109+
}
110+
}
111+
}

build/files-checker.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
'vite.config.ts',
9393
'vitest.config.ts',
9494
'window.d.ts',
95+
'Caddyfile',
9596
];
9697
$actualFiles = [];
9798

build/psalm-baseline.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3268,11 +3268,6 @@
32683268
<code><![CDATA[provideInitialState]]></code>
32693269
</DeprecatedMethod>
32703270
</file>
3271-
<file src="lib/base.php">
3272-
<InvalidArgument>
3273-
<code><![CDATA[$restrictions]]></code>
3274-
</InvalidArgument>
3275-
</file>
32763271
<file src="lib/private/Accounts/AccountManager.php">
32773272
<FalsableReturnStatement>
32783273
<code><![CDATA[json_encode($preparedData)]]></code>

0 commit comments

Comments
 (0)