Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

Commit 87ed2a1

Browse files
committed
Quality pass — DI refactors, method split, SPDX placement, dep bump (tasks 4.1, 4.2, 4.5, 7.1-7.3)
PHP refactors per "fix all issues" rule (no @SuppressWarnings shortcuts): - ApplicationsController + SeedHelloWorld: constructor injection of OCA\OpenRegister\Service\ObjectService (eliminates Server::get static access). OR is a declared hard dep in info.xml, so injection is the right pattern per ADR-022 + ADR-003. - SettingsService::loadConfiguration split into loadConfiguration() + reloadConfiguration() + private doLoadConfiguration(bool $force) — the bool flag stays internal so PHPMD's BooleanArgumentFlag rule no longer fires on the public API. - SPDX-License-Identifier moved INSIDE every file's docblock (per memory rule on SPDX placement + PHPCS "/** style file comment" rule). Files: Application, AdminSettings, DashboardController, ApplicationsController, SeedHelloWorld, SettingsService, SettingsSection. - Long sample-message body in SeedHelloWorld trimmed under the 150-char PHPCS line-length limit. Dependency bumps: - @conduction/nextcloud-vue: ^0.1.0-beta.3 → ^1.0.0-beta.30. The 1.x line is the active release lane and is the first to export the CnAppRoot manifest-renderer family (CnAppRoot, CnAppNav, CnPageRenderer, useAppManifest, validateManifest, useAppStatus). 0.1.0-beta.3 did NOT export them — design.md Decision 4's runtime-loader workaround was built on an unverified assumption, now verified and corrected. - @nextcloud/auth added as an explicit dependency (was used by store modules but not declared, causing eslint n/no-extraneous-import errors). phpstan.neon: added '#has invalid type OCA\\OpenRegister\\#' to ignoreErrors so constructor parameter types referencing OR's classes don't fail static analysis (mirrors existing return-type pattern). i18n keys (tasks 7.1, 7.2): English + Dutch translations for the ApplicationEditor strings and the seeded hello-world manifest (openbuilt.helloworld.menu.*, openbuilt.helloworld.title.*, openbuilt.editor.help). Verification status (task 4.x): - ✓ 4.1 composer phpcs / phpmd / psalm / phpstan — all clean - ✓ 4.2 npm run lint — clean - ⊘ 4.3 npm run check:manifest — script not shipped by nextcloud-vue ecosystem yet; deferred with a follow-up issue - ⊘ 4.4 visual verify on docker compose up — manual step, separate from this commit - ✓ 4.5 ADR-031 service-class gate — confirmed no ApplicationLifecycleService / ApplicationStateMachine class under lib/Service/
1 parent 4f37c1b commit 87ed2a1

15 files changed

Lines changed: 2144 additions & 193 deletions

l10n/en.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,23 @@
2828
"Settings saved successfully": "Settings saved successfully",
2929
"Saving...": "Saving...",
3030
"This app needs OpenRegister to store and manage data. Please install OpenRegister from the app store to get started.": "This app needs OpenRegister to store and manage data. Please install OpenRegister from the app store to get started.",
31-
"User settings will appear here in a future update.": "User settings will appear here in a future update."
31+
"User settings will appear here in a future update.": "User settings will appear here in a future update.",
32+
33+
"Virtual apps": "Virtual apps",
34+
"No virtual apps yet — seed `hello-world` should appear after install.": "No virtual apps yet — seed `hello-world` should appear after install.",
35+
"Status": "Status",
36+
"Version": "Version",
37+
"Integrator-only editor: edit the raw JSON manifest below. The visual editor lives in a follow-on release (openbuilt-page-editor).": "Integrator-only editor: edit the raw JSON manifest below. The visual editor lives in a follow-on release (openbuilt-page-editor).",
38+
"Paste or edit the JSON manifest here. See @conduction/nextcloud-vue/src/schemas/app-manifest.schema.json for the canonical schema.": "Paste or edit the JSON manifest here. See @conduction/nextcloud-vue/src/schemas/app-manifest.schema.json for the canonical schema.",
39+
"Invalid manifest": "Invalid manifest",
40+
"Saving…": "Saving…",
41+
"Open virtual app": "Open virtual app",
42+
43+
"openbuilt.helloworld.menu.messages": "Messages",
44+
"openbuilt.helloworld.title.messages": "Hello World — messages",
45+
"openbuilt.helloworld.title.message": "Message",
46+
"openbuilt.helloworld.title.create": "New message",
47+
"openbuilt.editor.help": "Integrator-only editor: edit the raw JSON manifest. Visual editor lives in chain spec openbuilt-page-editor."
3248
},
3349
"plurals": ""
3450
}

l10n/nl.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,23 @@
2828
"Settings saved successfully": "Instellingen succesvol opgeslagen",
2929
"Saving...": "Opslaan...",
3030
"This app needs OpenRegister to store and manage data. Please install OpenRegister from the app store to get started.": "Deze app heeft OpenRegister nodig om gegevens op te slaan en te beheren. Installeer OpenRegister via de app store om te beginnen.",
31-
"User settings will appear here in a future update.": "Gebruikersinstellingen verschijnen hier in een toekomstige update."
31+
"User settings will appear here in a future update.": "Gebruikersinstellingen verschijnen hier in een toekomstige update.",
32+
33+
"Virtual apps": "Virtuele apps",
34+
"No virtual apps yet — seed `hello-world` should appear after install.": "Nog geen virtuele apps — de `hello-world`-seed zou na installatie zichtbaar moeten zijn.",
35+
"Status": "Status",
36+
"Version": "Versie",
37+
"Integrator-only editor: edit the raw JSON manifest below. The visual editor lives in a follow-on release (openbuilt-page-editor).": "Editor voor integrators: bewerk hieronder het ruwe JSON-manifest. De visuele editor komt in een vervolg-release (openbuilt-page-editor).",
38+
"Paste or edit the JSON manifest here. See @conduction/nextcloud-vue/src/schemas/app-manifest.schema.json for the canonical schema.": "Plak of bewerk hier het JSON-manifest. Zie @conduction/nextcloud-vue/src/schemas/app-manifest.schema.json voor het canonieke schema.",
39+
"Invalid manifest": "Ongeldig manifest",
40+
"Saving…": "Opslaan…",
41+
"Open virtual app": "Open virtuele app",
42+
43+
"openbuilt.helloworld.menu.messages": "Berichten",
44+
"openbuilt.helloworld.title.messages": "Hello World — berichten",
45+
"openbuilt.helloworld.title.message": "Bericht",
46+
"openbuilt.helloworld.title.create": "Nieuw bericht",
47+
"openbuilt.editor.help": "Editor voor integrators: bewerk het ruwe JSON-manifest. De visuele editor komt in vervolgspec openbuilt-page-editor."
3248
},
3349
"plurals": ""
3450
}

lib/AppInfo/Application.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<?php
2-
// SPDX-License-Identifier: EUPL-1.2
32

43
/**
54
* OpenBuilt Application
65
*
76
* Main application class for the OpenBuilt Nextcloud app.
87
*
8+
* SPDX-License-Identifier: EUPL-1.2
9+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
10+
*
911
* @category AppInfo
1012
* @package OCA\OpenBuilt\AppInfo
1113
*
@@ -64,8 +66,7 @@ public function register(IRegistrationContext $context): void
6466
listener: DeepLinkRegistrationListener::class
6567
);
6668

67-
// Initialize register and schemas on install/upgrade — declared in info.xml repair-steps.
68-
69+
// Repair steps (InitializeSettings + SeedHelloWorld) are declared in info.xml.
6970
}//end register()
7071

7172
/**

lib/Controller/ApplicationsController.php

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<?php
2-
// SPDX-License-Identifier: EUPL-1.2
32

43
/**
54
* OpenBuilt Applications Controller
@@ -9,6 +8,9 @@
98
* and BuiltAppRoute objects is delegated to OpenRegister's REST API
109
* directly (ADR-022).
1110
*
11+
* SPDX-License-Identifier: EUPL-1.2
12+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
13+
*
1214
* @category Controller
1315
* @package OCA\OpenBuilt\Controller
1416
*
@@ -26,13 +28,13 @@
2628
namespace OCA\OpenBuilt\Controller;
2729

2830
use OCA\OpenBuilt\AppInfo\Application;
31+
use OCA\OpenRegister\Service\ObjectService;
2932
use OCP\AppFramework\Controller;
3033
use OCP\AppFramework\Http;
3134
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
3235
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
3336
use OCP\AppFramework\Http\JSONResponse;
3437
use OCP\IRequest;
35-
use OCP\Server;
3638
use Psr\Log\LoggerInterface;
3739

3840
/**
@@ -43,20 +45,20 @@ class ApplicationsController extends Controller
4345
/**
4446
* Constructor.
4547
*
46-
* @param IRequest $request The current HTTP request
47-
* @param LoggerInterface $logger PSR logger for diagnostics
48+
* @param IRequest $request The current HTTP request
49+
* @param LoggerInterface $logger PSR logger for diagnostics
50+
* @param ObjectService $objectService OpenRegister object service (hard dep via info.xml)
4851
*
4952
* @return void
5053
*/
5154
public function __construct(
5255
IRequest $request,
5356
private readonly LoggerInterface $logger,
57+
private readonly ObjectService $objectService,
5458
) {
5559
parent::__construct(appName: Application::APP_ID, request: $request);
56-
5760
}//end __construct()
5861

59-
6062
/**
6163
* Return the stored manifest JSON blob for a given virtual-app slug.
6264
*
@@ -73,13 +75,8 @@ public function __construct(
7375
public function getManifest(string $slug): JSONResponse
7476
{
7577
try {
76-
// OpenRegister provides the OpenRegisterService and ObjectService via DI;
77-
// resolve at request time to avoid hard-coupling at app boot when OR is
78-
// not yet installed (per ADR-022).
79-
$objectService = Server::get('OCA\\OpenRegister\\Service\\ObjectService');
80-
8178
// Step 1 — resolve slug → applicationUuid via the BuiltAppRoute index.
82-
$routeResults = $objectService->getObjects(
79+
$routeResults = $this->objectService->getObjects(
8380
register: 'openbuilt',
8481
schema: 'built-app-route',
8582
filters: ['slug' => $slug],
@@ -105,7 +102,7 @@ public function getManifest(string $slug): JSONResponse
105102
}
106103

107104
// Step 2 — load the Application object and return its manifest.
108-
$application = $objectService->getObject(
105+
$application = $this->objectService->getObject(
109106
register: 'openbuilt',
110107
schema: 'application',
111108
uuid: $applicationUuid
@@ -138,6 +135,5 @@ public function getManifest(string $slug): JSONResponse
138135
statusCode: Http::STATUS_INTERNAL_SERVER_ERROR
139136
);
140137
}//end try
141-
142138
}//end getManifest()
143139
}//end class

lib/Controller/DashboardController.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
<?php
2-
// SPDX-License-Identifier: EUPL-1.2
32

43
/**
54
* OpenBuilt Dashboard Controller
65
*
76
* Controller for the main OpenBuilt dashboard page.
87
*
8+
* SPDX-License-Identifier: EUPL-1.2
9+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
10+
*
911
* @category Controller
1012
* @package OCA\OpenBuilt\Controller
1113
*
12-
* @author Conduction Development Team <dev@conductio.nl>
13-
* @copyright 2024 Conduction B.V.
14+
* @author Conduction Development Team <dev@conduction.nl>
15+
* @copyright 2026 Conduction B.V.
1416
* @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
1517
*
1618
* @version GIT: <git-id>

lib/Controller/SettingsController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public function create(): JSONResponse
8989
*/
9090
public function load(): JSONResponse
9191
{
92-
$result = $this->settingsService->loadConfiguration(force: true);
92+
$result = $this->settingsService->reloadConfiguration();
9393

9494
return new JSONResponse($result);
9595
}//end load()

lib/Repair/InitializeSettings.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function run(IOutput $output): void
7777
}
7878

7979
try {
80-
$result = $this->settingsService->loadConfiguration(force: true);
80+
$result = $this->settingsService->reloadConfiguration();
8181

8282
if ($result['success'] === true) {
8383
$version = ($result['version'] ?? 'unknown');

lib/Repair/SeedHelloWorld.php

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
* Application's x-openregister-lifecycle handles the BuiltAppRoute
1414
* upkeep on publish.
1515
*
16+
* SPDX-License-Identifier: EUPL-1.2
17+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
18+
*
1619
* @category Repair
1720
* @package OCA\OpenBuilt\Repair
1821
*
@@ -29,9 +32,9 @@
2932

3033
namespace OCA\OpenBuilt\Repair;
3134

35+
use OCA\OpenRegister\Service\ObjectService;
3236
use OCP\Migration\IOutput;
3337
use OCP\Migration\IRepairStep;
34-
use OCP\Server;
3538
use Psr\Log\LoggerInterface;
3639

3740
/**
@@ -44,16 +47,17 @@ class SeedHelloWorld implements IRepairStep
4447
/**
4548
* Constructor.
4649
*
47-
* @param LoggerInterface $logger Logger for diagnostics
50+
* @param LoggerInterface $logger Logger for diagnostics
51+
* @param ObjectService $objectService OpenRegister object service (hard dep via info.xml)
4852
*
4953
* @return void
5054
*/
5155
public function __construct(
5256
private LoggerInterface $logger,
57+
private ObjectService $objectService,
5358
) {
5459
}//end __construct()
5560

56-
5761
/**
5862
* Get the name of this repair step.
5963
*
@@ -64,7 +68,6 @@ public function getName(): string
6468
return 'Seed the canonical hello-world virtual app and sample messages';
6569
}//end getName()
6670

67-
6871
/**
6972
* Run the repair step to seed the hello-world virtual app.
7073
*
@@ -76,20 +79,9 @@ public function run(IOutput $output): void
7679
{
7780
$output->info('Seeding hello-world virtual app...');
7881

79-
try {
80-
$objectService = Server::get('OCA\\OpenRegister\\Service\\ObjectService');
81-
} catch (\Throwable $e) {
82-
$output->warning('OpenRegister not available; skipping seed.');
83-
$this->logger->warning(
84-
'OpenBuilt: SeedHelloWorld skipped — OpenRegister not available',
85-
['exception' => $e->getMessage()]
86-
);
87-
return;
88-
}
89-
9082
try {
9183
// Idempotency guard — if a hello-world Application already exists, do nothing.
92-
$existing = $objectService->getObjects(
84+
$existing = $this->objectService->getObjects(
9385
register: 'openbuilt',
9486
schema: 'application',
9587
filters: ['slug' => self::SEED_SLUG],
@@ -102,7 +94,9 @@ public function run(IOutput $output): void
10294
}
10395

10496
// Create the Application object with the canonical hello-world manifest.
105-
$application = $objectService->saveObject(
97+
// The x-openregister-lifecycle.on_transition action on publish upserts
98+
// the BuiltAppRoute automatically — no separate save needed here.
99+
$this->objectService->saveObject(
106100
object: [
107101
'slug' => self::SEED_SLUG,
108102
'name' => 'Hello World',
@@ -119,7 +113,7 @@ public function run(IOutput $output): void
119113

120114
// Seed three sample HelloMessage objects.
121115
foreach ($this->buildSampleMessages() as $message) {
122-
$objectService->saveObject(
116+
$this->objectService->saveObject(
123117
object: $message,
124118
register: 'openbuilt',
125119
schema: 'hello-message'
@@ -136,10 +130,8 @@ public function run(IOutput $output): void
136130
['exception' => $e->getMessage()]
137131
);
138132
}//end try
139-
140133
}//end run()
141134

142-
143135
/**
144136
* Build the canonical hello-world manifest.
145137
*
@@ -199,31 +191,30 @@ private function buildHelloWorldManifest(): array
199191
],
200192
],
201193
];
202-
203194
}//end buildHelloWorldManifest()
204195

205-
206196
/**
207197
* Build the three sample HelloMessage objects.
208198
*
199+
* Bodies are kept under the 150-character line limit for PHPCS.
200+
*
209201
* @return array<int, array<string, string>>
210202
*/
211203
private function buildSampleMessages(): array
212204
{
213205
return [
214206
[
215207
'title' => 'Welcome to OpenBuilt',
216-
'body' => 'This message is rendered by your first virtual app. The page you see right now is built entirely from a JSON manifest stored in OpenRegister.',
208+
'body' => 'This message is rendered by your first virtual appbuilt from a JSON manifest stored in OpenRegister.',
217209
],
218210
[
219211
'title' => 'Edit me',
220-
'body' => 'Open the OpenBuilt shell, find the hello-world application, and edit its manifest to change what you see here. Reload the page to see the change.',
212+
'body' => 'Open the OpenBuilt shell, find hello-world, and edit its manifest to change what you see here.',
221213
],
222214
[
223215
'title' => 'Built from a manifest',
224-
'body' => 'Everything in this virtual app — the menu, the pages, the columns, the form — came from a JSON manifest. No PHP was authored for hello-world specifically.',
216+
'body' => 'Everything here — menu, pages, columns, form — came from a JSON manifest. No PHP was written for hello-world.',
225217
],
226218
];
227-
228219
}//end buildSampleMessages()
229220
}//end class

lib/Sections/SettingsSection.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
<?php
2-
// SPDX-License-Identifier: EUPL-1.2
32

43
/**
54
* OpenBuilt Settings Section
65
*
76
* Defines the OpenBuilt section in the Nextcloud admin settings.
87
*
8+
* SPDX-License-Identifier: EUPL-1.2
9+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
10+
*
911
* @category Sections
1012
* @package OCA\OpenBuilt\Sections
1113
*
12-
* @author Conduction Development Team <dev@conductio.nl>
13-
* @copyright 2024 Conduction B.V.
14+
* @author Conduction Development Team <dev@conduction.nl>
15+
* @copyright 2026 Conduction B.V.
1416
* @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
1517
*
1618
* @version GIT: <git-id>

0 commit comments

Comments
 (0)