From f6a80a75fbdf6903406021fb430e6b9d0129399b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Tue, 8 Sep 2026 08:52:54 +0200 Subject: [PATCH] 16: Strip PHP from administration Removes the "PHP API" section from the recent activity page, keeping its Configuration, Permission and security, User privacy and REST API sections; removes the ConfigResolver service-injection section from dynamic configuration while keeping the SiteAccess scope and namespace semantics the spec preserves; and drops the container parameter sample from the configuration page. Clears residue R2 (a GraphQL console reference orphaned by ticket 07) and R17 (the back office described as produced by the ibexa/admin-ui bundle, which a tenant does not install). Repoints three anchor links orphaned by the removed PHP API section at the surviving REST API section. Removes 20 administration/ entries from the invariant baseline. Co-Authored-By: Claude Opus 5 (1M context) --- .../administration/back_office/back_office.md | 2 +- .../back_office/integrated_help.md | 2 +- .../configuration/configuration.md | 6 - .../configuration/dynamic_configuration.md | 56 ----- .../recent_activity/recent_activity.md | 214 ------------------ .../activity_log_criteria.md | 2 +- .../activity_log_sort_clauses.md | 2 +- tests/python/invariants-baseline.yaml | 20 -- 8 files changed, 4 insertions(+), 300 deletions(-) diff --git a/docs/administration/back_office/back_office.md b/docs/administration/back_office/back_office.md index 9873c191ca..9ee1ca845d 100644 --- a/docs/administration/back_office/back_office.md +++ b/docs/administration/back_office/back_office.md @@ -5,7 +5,7 @@ page_type: landing_page # Back office -The back office interface is produced by the [`ibexa/admin-ui` bundle](https://github.com/ibexa/admin-ui). +The back office is the web interface where editors and administrators work with content. Additionally, it uses React-based modules that make each part of the UI extensible, and Bootstrap for styling. The interface is accessible in your browser at `http:///admin`. diff --git a/docs/administration/back_office/integrated_help.md b/docs/administration/back_office/integrated_help.md index 1394d9c6cb..53255b0632 100644 --- a/docs/administration/back_office/integrated_help.md +++ b/docs/administration/back_office/integrated_help.md @@ -10,7 +10,7 @@ With this feature installed, users can click the ![Help icon](about-info.png){.i ![Integrated help menu](5_0_integrated_help_menu.png) -Integrated help is contextual, therefore, apart from user documentation, release notes, and partner guidelines, which are available to editors and store managers, developers can access API references, the GraphQL console, or the support portal. +Integrated help is contextual, therefore, apart from user documentation, release notes, and partner guidelines, which are available to editors and store managers, developers can access API references or the support portal. ## Product tours diff --git a/docs/administration/configuration/configuration.md b/docs/administration/configuration/configuration.md index 560f2a9201..010a591c49 100644 --- a/docs/administration/configuration/configuration.md +++ b/docs/administration/configuration/configuration.md @@ -72,12 +72,6 @@ parameters: an_array: [apple, banana, pear] ``` -``` php -// Usage inside a controller -/** @var \Symfony\Component\DependencyInjection\ContainerInterface $container */ -$myParameter = $container->getParameter('myapp.parameter.name'); -``` - ## Configuration settings For specific configuration settings, see: diff --git a/docs/administration/configuration/dynamic_configuration.md b/docs/administration/configuration/dynamic_configuration.md index 76191c243c..07dd91561f 100644 --- a/docs/administration/configuration/dynamic_configuration.md +++ b/docs/administration/configuration/dynamic_configuration.md @@ -29,24 +29,6 @@ parameters: Inside a controller extending the `Ibexa\Core\MVC\Symfony\Controller\Controller` class, in `site_group` SiteAccess, you can use the parameters in the following way (the same applies for `hasParameter()`): -``` php {skip-validation} -$configResolver = $this->getConfigResolver(); - -// ibexa.site_access.config is the default namespace, so no need to specify it -// The following will resolve ibexa.site_access.config..content.default_ttl -// In the case of site_group, it will return 3600. -// Otherwise it will return the value for ibexa.site_access.config.default.content.default_ttl (60) -$locationViewSetting = $configResolver->getParameter( 'content.default_ttl' ); - -// For you own namespace, you need to specify it, here as "myapp" -$myParamSetting = $configResolver->getParameter( 'my_param', 'myapp' ); -// $myParamSetting's value will be 'value' -  -// You can also force the scope by naming it explicitly (here as "admin_group") -$myParamSettingAdmin = $configResolver->getParameter( 'my_param', 'myapp', 'admin_group' ); -// $myParamSetting's value will be 'another value' -``` - !!! tip To learn more about scopes, see [SiteAccess documentation](multisite_configuration.md#scope). @@ -56,41 +38,3 @@ Both `getParameter()` and `hasParameter()` can take three arguments: 1. `$paramName` - the name of the parameter 2. `$namespace` - your application namespace, `myapp` in the previous example. If null, the default namespace is used, which is `ibexa.site_access.config` by default. 3. `$scope` - a SiteAccess name. If null, the current SiteAccess is used. - -## Inject ConfigResolver into services - -You can use the ConfigResolver in your own services whenever needed. -To do this, inject the `ibexa.config.resolver` service: - -``` yaml -services: - App\Service: - arguments: ['@ibexa.config.resolver'] -``` - -You can also use the [autowire feature]([[= symfony_doc =]]/service_container/autowiring.html), by type hinting against `ConfigResolverInterface`. - -For more information about dependency injection, see [Service container]([[= symfony_doc =]]/service_container.html). - -!!! note - - Don't store the retrieved config value unless you know what you're doing. - SiteAccess can change during code execution, which means you might work on the wrong value. - -``` php -namespace App; - -use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; - -class Service -{ - public function __construct(private readonly ConfigResolverInterface $configResolver) - { - } - - public function someMethodThatNeedConfig(): void - { - $configValue = $this->configResolver->getParameter('my_param', 'myapp'); - } -} -``` diff --git a/docs/administration/recent_activity/recent_activity.md b/docs/administration/recent_activity/recent_activity.md index 978f573b3d..93337d7609 100644 --- a/docs/administration/recent_activity/recent_activity.md +++ b/docs/administration/recent_activity/recent_activity.md @@ -64,8 +64,6 @@ ibexa: enabled: false ``` -You can also disable activity log for a single action by using the [PHP API](#disable-logging-activities). - ## Permission and security The [`activity_log/read`](policies.md#activity-log) policy gives a role the access to the **Admin** -> **Activity list**, the dashboard's **Recent activity** block, and the user profile's **Recent activity**. @@ -89,218 +87,6 @@ This policy is required to view [activity log in user profile]([[= user_doc =]]/ For example, if a content edition feature, such as reader's comments, is available in the front office, the recent activity log records the front users' IPs. -## PHP API - -The `ActivityLogService` PHP API can be used to browse activity logs and write new entries. - -### Searching in the Activity Log groups - -You can search among the activity log entry groups with the `ActivityLogService::findGroups` method, by passing an `Ibexa\Contracts\ActivityLog\Values\ActivityLog\Query` object. -This `Query`'s constructor has four arguments: - -- `$criteria` - an array of criteria from `Ibexa\Contracts\ActivityLog\Values\ActivityLog\Criterion` combined as a logical AND. -- `$sortClauses` - an array of `Ibexa\Contracts\ActivityLog\Values\ActivityLog\SortClause`. -- `$offset` - a zero-based index integer indicating at which group to start, its default value is `0` (zero, nothing skipped). -- `$limit` - an integer as the maximum returned group count, default is 25. - -See [Activity Log Search Criteria reference](activity_log_criteria.md) and [Activity Log Search Sort Clauses reference](activity_log_sort_clauses.md) to discover query possibilities. - -In the following example, log groups that contain at least one creation of a Content item are displayed in terminal, with a maximum of 10 groups within the last hour. -It uses the default `admin` user that has a [permission](#permission-and-security) to list everyone's entries. - -``` php hl_lines="34-38" -[[= include_code('code_samples/recent_activity/src/Command/MonitorRecentContentCreationCommand.php') =]] -``` - -```console -% php bin/console app:monitor-content-creation - -web ---- - - --------------------------- --------- --------------------------- -------- ---------- ------------ - Logged at Obj. ID Object Name Action User IP - --------------------------- --------- --------------------------- -------- ---------- ------------ - 2024-01-29T15:01:57+00:00 323 “Bar” (formerly “Folder”) create jane_doe 172.20.0.5 - --------------------------- --------- --------------------------- -------- ---------- ------------ - -migration ---------- - - Migrating file: create_foo_company - --------------------------- --------- -------------------- -------------- ------- ---- - Logged at Obj. ID Object Name Action User IP - --------------------------- --------- -------------------- -------------- ------- ---- - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ create admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ publish admin - 2024-01-29T14:58:53+00:00 318 “Members“ create admin - 2024-01-29T14:58:53+00:00 318 “Members“ publish admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ create_draft admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ update admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ publish admin - 2024-01-29T14:58:53+00:00 319 “Address Book“ create admin - 2024-01-29T14:58:53+00:00 319 “Address Book“ publish admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ create_draft admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ update admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ publish admin - 2024-01-29T14:58:53+00:00 320 “HQ“ create admin - 2024-01-29T14:58:53+00:00 320 “HQ“ publish admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ create_draft admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ update admin - 2024-01-29T14:58:53+00:00 317 “Foo Company Ltd.“ publish admin - --------------------------- --------- -------------------- -------------- ------- ---- -``` - -### Add custom Activity Log entries - -!!! caution - - Keep activity logging as light as possible. - Don't make database requests or heavy computation at logging time. - Keep them for activity log list display time. - If needed, you can [disable logging for specific operations](#disable-logging-activities) using the PHP API. - -#### Create an entry - -Your custom features can write into the activity log. - -First, inject `Ibexa\Contracts\ActivityLog\ActivityLogServiceInterface` into your PHP class from where you want to log an activity (such as a custom event subscriber, event listener, service, or controller). - -In the following example, an event subscriber is subscribing to an event dispatched by a custom feature. -This event has the information needed by a log entry (see details after the example). - -``` php -[[= include_code('code_samples/recent_activity/src/EventSubscriber/MyFeatureEventSubscriber.php') =]] -``` - -`ActivityLogService::build()` function returns an `Ibexa\Contracts\ActivityLog\Values\CreateActivityLogStruct` which can then be passed to `ActivityLogService::save`. - -`ActivityLogService::build` has three arguments: - -- `$className` is a FQCN of the object actually manipulated by the feature, for example `Ibexa\Contracts\Core\Repository\Values\Content\Content::class` -- `$id` is an ID or identifier of the manipulated object, for example, the Content ID cast to string -- `$action` is an identifier of the performed object manipulation, or example, `create`, `update` or `delete` - -The returned `CreateActivityLogStruct` is always related to the currently logged-in user. - -You can still display activity log of an object which was deleted or renamed. -To store the name of the log, you need to use `CreateActivityLogStruct::setName` before saving the log entry. -This stored name can be used at the time of displaying information whether the associated object isn't available anymore, or to check if it has been renamed. - -#### Context group - -If you log several related entries at once, you can group them into a context. -Context is a set of actions done for the same purpose, for example, it could group the actions of a CRON that fetches third party data and updates content items. -The built-in contexts include: - -- `web` - groups actions made in the back office, like the update and the publishing of a new content item's version -- `migration` - groups every action from a migration file execution - -A context group counts as one item in regard to `activity_logs_limit` configuration and `ActivityLogService::findGroups`'s `$limit` argument. - -To open a context group, use `ActivityLogService::prepareContext` which has two arguments: - -- `$source` - describes, usually through a short identifier, what is triggering the set of actions. -For example, some already existing sources are `web` (incl. actions from the back office), `graphql`, `rest` and `migration` -- `$description` - an optional, more specific contextualisation. -For example, `migration` context source is associated with the migration file name in its context description. - -To close a context group, use `ActivityLogService::dismissContext`. - -In the following example, several actions are logged into one context group, even those triggered by a cascade outside the piece of code: - -- `my_feature` - - `init` - - `create` - - `publish` - - `simulate` - - `complete` - -``` php -[[= include_code('code_samples/recent_activity/src/Command/ActivityLogContextTestCommand.php', 47, 66, remove_indent=True) =]] -``` - -Context groups can't be nested. -If a new context is prepared when a context is already grouping log entries, this new context is ignored. -To start a new context, make sure to previously dismiss the existing one. - -When displayed in the back office, a context group is folded below its first entry. -The `my_feature` context from the example is folded below its first action, the `init` action. -Other actions are displayed after you click the **Show more** button. - -![The example context group displayed on the Recent Activity page](activity_log_group.png "`my_feature` context from the example") - -#### Display log entries - -To display your log entry, if your object's PHP class isn't already covered, you have to: - -- implement `ClassNameMapperInterface` to associate the class name with an identifier, -- eventually create a `PostActivityListLoadEvent` subscriber if you need to load the object for the template, -- create a template to display this class log entries. - -You can have a template that is: - -- specific to a class identifier and placed in `templates/themes//activity_log/ui/.html.twig` -- specific to an action on an identifier and placed in `templates/themes//activity_log/ui//.html.twig` - -Template existence is tested in reverse order: if there is no action that specifies the template, the identifier's default is used. -For the same identifier, you could have specific templates for few actions, and a default one for the remaining actions. - -A default template is used if no template is found for the identifier. -The built-in default template `@ibexadesign/activity_log/ui/default.html.twig` has an empty `activity_log_description_widget` block and doesn't display anything for unknown objects. -Your template can extend `@ibexadesign/activity_log/ui/default.html.twig`, and only redefine the `activity_log_description_widget` block for your objects. - -First, follow an example of a default template overriding the one from the bundle. -It can be used during development as a fallback for classes that aren't mapped yet. - -``` twig -[[= include_code('code_samples/recent_activity/templates/themes/admin/activity_log/ui/default.html.twig') =]] -``` - -Here is an example of a `ClassNameMapperInterface` associating the class `App\MyFeature\MyFeature` with the identifier `my_feature`: - -``` php -[[= include_code('code_samples/recent_activity/src/ActivityLog/ClassNameMapper/MyFeatureNameMapper.php') =]] -``` - -This mapper also provides a translation for the class name in the **Filters** menu. -This translation can be extracted with `php bin/console jms:translation:extract en --domain=ibexa_activity_log --dir=src --output-dir=translations`. - -To be taken into account, this mapper must be registered as a service: - -``` yaml -[[= include_code('code_samples/recent_activity/config/append_to_services.yaml') =]] -``` - -Here is an example of a `PostActivityListLoadEvent` subscriber which loads the related object when it's an `App\MyFeature\MyFeature`, and attaches it to the log entry: - -``` php -[[= include_code('code_samples/recent_activity/src/EventSubscriber/MyFeaturePostActivityListLoadEventSubscriber.php') =]] -``` - -The following template is made to display the object of `App\MyFeature\MyFeature` (now identified as `my_feature`) when the action is `simulate`, -so, it's named in `templates/themes/admin/activity_log/ui/my_feature/simulate.html.twig`. -Thanks to the previous subscriber, the related object is available at display time: - -``` twig -[[= include_code('code_samples/recent_activity/templates/themes/admin/activity_log/ui/my_feature/simulate.html.twig') =]] -``` - -### Disable logging activities - -You can disable logging the activities with PHP API, for example, when loading large amounts of data in cases where you don't want logging to slow down the process or the actions to be included in the log. - -Call `ActivityLogService::disable()` - before running the relevant code, then `ActivityLogService::enable()` to restore the logging process: - -``` php -[[= include_code('code_samples/recent_activity/src/recent_activity_disable.php') =]] -``` - -When disabled, any call to `ActivityLogService::save()` has no effect and no entries are written to the database. - -You can check the current state with `ActivityLogService::isEnabled()` and `ActivityLogService::isDisabled()`. - ## REST API You can browse activity logs with REST API. diff --git a/docs/search/activity_log_search_reference/activity_log_criteria.md b/docs/search/activity_log_search_reference/activity_log_criteria.md index c9f64c3188..a9f991d566 100644 --- a/docs/search/activity_log_search_reference/activity_log_criteria.md +++ b/docs/search/activity_log_search_reference/activity_log_criteria.md @@ -12,7 +12,7 @@ Those Criteria are to be used with `Ibexa\Contracts\ActivityLog\Values\ActivityL They're applied to log entry groups. For example, with the criterion `ActionCriterion`, you get log entry groups that have at least one entry with this action (and possibly other actions as well). -See [Searching in the Activity Log groups](recent_activity.md#searching-in-the-activity-log-groups) for how to use a query, and an example combining several criteria. +See [Recent activity](../../administration/recent_activity/recent_activity.md#rest-api) for how to browse the activity log over the REST API. ## Value-based criteria diff --git a/docs/search/activity_log_search_reference/activity_log_sort_clauses.md b/docs/search/activity_log_search_reference/activity_log_sort_clauses.md index 41ebc3e92b..ac1a8fdc4c 100644 --- a/docs/search/activity_log_search_reference/activity_log_sort_clauses.md +++ b/docs/search/activity_log_search_reference/activity_log_sort_clauses.md @@ -1,6 +1,6 @@ # Activity Log Search Sort Clauses reference -See [Searching in the Activity Log groups](recent_activity.md#searching-in-the-activity-log-groups) for the whole API. +See [Recent activity](../../administration/recent_activity/recent_activity.md#rest-api) for how to browse the activity log over the REST API. Sort Clauses are found in the `Ibexa\Contracts\ActivityLog\Values\ActivityLog\SortClause` namespace. diff --git a/tests/python/invariants-baseline.yaml b/tests/python/invariants-baseline.yaml index 960b561fdd..2a46ce0bc5 100644 --- a/tests/python/invariants-baseline.yaml +++ b/tests/python/invariants-baseline.yaml @@ -27,26 +27,6 @@ deleted_product_variables: [] # 314 page(s) contain a PHP code sample (fenced block or .php include macro). php_code_sample: - - administration/back_office/add_user_setting.md - - administration/back_office/back_office_elements/extending_thumbnails.md - - administration/back_office/back_office_elements/formatting_date_and_time.md - - administration/back_office/back_office_menus/add_menu_item.md - - administration/back_office/back_office_menus/back_office_menus.md - - administration/back_office/back_office_tabs/back_office_tabs.md - - administration/back_office/back_office_tabs/create_dashboard_tab.md - - administration/back_office/browser/browser.md - - administration/back_office/content_tab_switcher.md - - administration/back_office/customize_calendar.md - - administration/back_office/customize_integrated_help.md - - administration/back_office/customize_product_tour.md - - administration/back_office/customize_search_sorting.md - - administration/back_office/customize_search_suggestion.md - - administration/back_office/notifications.md - - administration/configuration/configuration.md - - administration/configuration/dynamic_configuration.md - - administration/configuration/repository_configuration.md - - administration/dashboard/php_api_dashboard_service.md - - administration/recent_activity/recent_activity.md - ai/ai_actions/configure_ai_actions.md - ai/ai_actions/extend_ai_actions.md - ai/mcp/mcp_usage.md