perf(events): declare OrderCustomerListener's register/schema interest - #3
Merged
Merged
Conversation
OrderCustomerListener stamps `order.customer` only for petstore/order objects (its own REGISTER_SLUG / SCHEMA_SLUG), but ObjectCreatingEvent is dispatched from OpenRegister's central write path for every object on the instance — so every create constructed the listener and ran the two mapper lookups isPetstoreOrder() needs before rejecting the object. Declare petstore/order through OpenRegister's ObjectEventSubscription, guarded on class_exists so an instance whose OpenRegister predates the mechanism falls back to the global registration it replaced. The in-listener guard stays in place as defence in depth.
Contributor
Quality Report — ConductionNL/petstore @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ❌ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ✅ 100/100 | |||
| npm | ✅ | ✅ 612/612 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-07-31 12:00 UTC
Download the full PDF report from the workflow artifacts.
…-independent Declaring the filtered subscription in register() was boot-order sensitive: Nextcloud enables each app's autoloader immediately before calling that app's own register(), so OpenRegister's ObjectEventSubscription was only autoloadable to apps registering after it. The class_exists() guard then failed silently and the app fell back to an unfiltered registration that looked identical to a working narrowing. boot() runs only after every app's register() has completed, so the guard resolves regardless of this app's position. The fallback now logs a warning naming the app and listener instead of degrading silently.
Contributor
Quality Report — ConductionNL/petstore @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ❌ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ✅ 100/100 | |||
| npm | ✅ | ✅ 612/612 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-07-31 21:17 UTC
Download the full PDF report from the workflow artifacts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
OrderCustomerListenerstampsorder.customerfrom the session, and only for petstore/order objects. ButObjectCreatingEventis dispatched from OpenRegister's central write path for every object on the instance, so every create constructed the listener and ran the two mapper lookups (SchemaMapper::find()+RegisterMapper::find()) thatisPetstoreOrder()needs before rejecting the object.It now declares register
petstore/ schemaorderthrough OpenRegister'sObjectEventSubscription.Evidence for the declaration
handle()returns immediately whenisPetstoreOrder()is false — nothing else in the listener runs. Both values are compile-time constants, not config.ObjectEventSubscriptionANDs the two filters, which is exactly the listener's own&&.Slug verification (dev instance)
Both slugs resolve, but⚠️ the combination does not exist on the dev instance: the installed petstore register carries only
categoryandpet; the onlyorderschema belongs to decidesk.lib/Settings/petstore_register.jsondoes ship anorderschema ("slug": "order"), so this is a stale/partial register import on the dev instance rather than a code problem.This makes the change behaviour-neutral either way: the current
isPetstoreOrder()guard requires the same register+schema combination, so the listener body cannot run on this instance today, and it cannot after this change. On an instance with a fully imported petstore register both the guard and the declaration match the same objects.Safety
class_exists('\OCA\OpenRegister\Event\ObjectEventSubscription')— openregister#2223 is not merged, so on an instance without it this degrades to the exactregisterEventListener()call it replaced. No hard cross-app reference.ObjectCreatingEventcarriesgetObject(), so OpenRegister's proxy can identify the object and the filter is real (not fail-open), and the proxy passes the original event object through, sosetModifiedData()still reaches OR's write path.isPetstoreOrder()is left in place as defence in depth.Branch note
petstore has no
developmentbranch — this PR targetsmain, the repository default.Checks
php -l: cleanphpcs --standard=phpcs.xml lib/AppInfo/Application.php: clean, 0 errors 0 warnings, same as baselinephpstan analyse lib/AppInfo/Application.php: No errorspsalm lib/AppInfo/Application.php: 4UndefinedClasserrors before and after (autoloader artefacts of analysing a single file — petstore has no localvendor/, so a sibling app's vendor was mounted); no deltaphpmd lib/AppInfo/Application.php text phpmd.xml: no findingscomposer check:strictnot run — petstore has no installedvendor/in this working tree; the checks above were run in anextcloud:34container with a sibling app's toolchain and petstore's ownphpcs.xml/phpmd.xml/phpstan.neon/ custom sniffs.