+
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
8bd2a39
IBX-9060: Added $query parameter for filtering notifications count an…
tbialcz Apr 3, 2025
b1370e9
Merge branch '4.6' into ibx_9060-notification-filtering
tbialcz Apr 10, 2025
49c4ec0
IBX-9060: Fixed code style
tbialcz Apr 10, 2025
b5a96d8
IBX-9060: Implemented notification query logic: added NotificationQue…
tbialcz May 8, 2025
dc978aa
Merge branch '4.6' into ibx_9060-notification-filtering
tbialcz May 8, 2025
8f0c65b
Merge branch '4.6' into ibx_9060-notification-filtering
tbialcz May 20, 2025
852c013
IBX-9060: Refactored notification loading logic by splitting `loadNot…
tbialcz Jun 10, 2025
626debe
IBX-9060: Refactored notification filtering with criterion handlers, …
tbialcz Jun 10, 2025
70061b3
IBX-9060: Replaced `Criterion` abstract class with `CriterionInterfac…
tbialcz Jun 10, 2025
f722a69
IBX-9060: Replaced `Criterion` abstract class with `CriterionInterfac…
tbialcz Jun 10, 2025
9a12a9d
Merge remote-tracking branch 'origin/ibx_9060-notification-filtering'…
tbialcz Jun 11, 2025
dac3c1d
IBX-9060: Optimized notification count caching logic by avoiding unne…
tbialcz Jun 20, 2025
2b79cf5
IBX-9060: Refactored `NotificationQuery` namespace, improved encapsul…
tbialcz Jun 20, 2025
00c0c64
IBX-9060: Fixed issues after code review
tbialcz Jun 23, 2025
8b26279
IBX-9060: Added `ibexa/polyfill-php82` dependency and utilized `itera…
tbialcz Jun 23, 2025
3b687a0
IBX-9060: Simplified resource path in legacy notification service con…
tbialcz Jun 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
"friendsofphp/proxy-manager-lts": "^1.0",
"psr/event-dispatcher": "^1.0",
"symfony/templating": "^5.3.0",
"composer/package-versions-deprecated": "^1.11"
"composer/package-versions-deprecated": "^1.11",
"ibexa/polyfill-php82": "^1.0"
},
"require-dev": {
"behat/behat": "^3.6.1",
Expand Down
152 changes: 7 additions & 145 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -22735,15 +22735,9 @@ parameters:
path: src/lib/Persistence/Legacy/Notification/Gateway.php

-
message: '#^Method Ibexa\\Core\\Persistence\\Legacy\\Notification\\Gateway\:\:loadUserNotifications\(\) return type has no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
message: '#^Method Ibexa\\Core\\Persistence\\Legacy\\Notification\\Gateway\\DoctrineDatabase\:\:__construct\(\) has parameter \$criterionHandlers with generic interface Ibexa\\Contracts\\Core\\Repository\\Values\\Notification\\CriterionHandlerInterface but does not specify its types\: T$#'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tbialcz I'm coming a bit late to the party, but the issues in new code need to be resolved instead of being added to the baseline.

identifier: missingType.generics
count: 1
path: src/lib/Persistence/Legacy/Notification/Gateway.php

-
message: '#^Cannot call method fetchAll\(\) on Doctrine\\DBAL\\ForwardCompatibility\\Result\|int\|string\.$#'
identifier: method.nonObject
count: 2
path: src/lib/Persistence/Legacy/Notification/Gateway/DoctrineDatabase.php

-
Expand All @@ -22759,14 +22753,14 @@ parameters:
path: src/lib/Persistence/Legacy/Notification/Gateway/DoctrineDatabase.php

-
message: '#^Method Ibexa\\Core\\Persistence\\Legacy\\Notification\\Gateway\\DoctrineDatabase\:\:loadUserNotifications\(\) return type has no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
message: '#^Property Ibexa\\Contracts\\Core\\Persistence\\Notification\\Notification\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: src/lib/Persistence/Legacy/Notification/Gateway/DoctrineDatabase.php

-
message: '#^Property Ibexa\\Contracts\\Core\\Persistence\\Notification\\Notification\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
message: '#^Property Ibexa\\Core\\Persistence\\Legacy\\Notification\\Gateway\\DoctrineDatabase\:\:\$criterionHandlers with generic interface Ibexa\\Contracts\\Core\\Repository\\Values\\Notification\\CriterionHandlerInterface does not specify its types\: T$#'
identifier: missingType.generics
count: 1
path: src/lib/Persistence/Legacy/Notification/Gateway/DoctrineDatabase.php

Expand All @@ -22788,12 +22782,6 @@ parameters:
count: 1
path: src/lib/Persistence/Legacy/Notification/Gateway/ExceptionConversion.php

-
message: '#^Method Ibexa\\Core\\Persistence\\Legacy\\Notification\\Gateway\\ExceptionConversion\:\:loadUserNotifications\(\) return type has no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: src/lib/Persistence/Legacy/Notification/Gateway/ExceptionConversion.php

-
message: '#^Method Ibexa\\Core\\Persistence\\Legacy\\Notification\\Mapper\:\:extractNotificationFromRow\(\) has parameter \$row with no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
Expand Down Expand Up @@ -42486,72 +42474,6 @@ parameters:
count: 2
path: tests/integration/Core/Repository/NonRedundantFieldSetTest.php

-
message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Notification\\\\Notification'' and Ibexa\\Contracts\\Core\\Repository\\Values\\Notification\\Notification will always evaluate to true\.$#'
identifier: method.alreadyNarrowedType
count: 2
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Notification\\\\NotificationList'' and Ibexa\\Contracts\\Core\\Repository\\Values\\Notification\\NotificationList will always evaluate to true\.$#'
identifier: method.alreadyNarrowedType
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testCreateNotification\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testCreateNotificationThrowsInvalidArgumentExceptionOnMissingOwner\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testCreateNotificationThrowsInvalidArgumentExceptionOnMissingType\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testDeleteNotification\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testGetNotification\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testGetNotificationCount\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testGetPendingNotificationCount\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testLoadNotifications\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\NotificationServiceTest\:\:testMarkNotificationAsRead\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/integration/Core/Repository/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\ObjectStateServiceAuthorizationTest\:\:testCreateObjectStateGroupThrowsUnauthorizedException\(\) has no return type specified\.$#'
identifier: missingType.return
Expand Down Expand Up @@ -50364,48 +50286,6 @@ parameters:
count: 1
path: tests/lib/Event/LocationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Event\\NotificationServiceTest\:\:testCreateNotificationEvents\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Event/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Event\\NotificationServiceTest\:\:testCreateNotificationStopPropagationInBeforeEvents\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Event/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Event\\NotificationServiceTest\:\:testDeleteNotificationEvents\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Event/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Event\\NotificationServiceTest\:\:testDeleteNotificationStopPropagationInBeforeEvents\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Event/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Event\\NotificationServiceTest\:\:testMarkNotificationAsReadEvents\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Event/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Event\\NotificationServiceTest\:\:testMarkNotificationAsReadStopPropagationInBeforeEvents\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Event/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Event\\NotificationServiceTest\:\:testReturnCreateNotificationResultInBeforeEvents\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Event/NotificationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Event\\ObjectStateServiceTest\:\:testCreateObjectStateEvents\(\) has no return type specified\.$#'
identifier: missingType.return
Expand Down Expand Up @@ -67236,12 +67116,6 @@ parameters:
count: 1
path: tests/lib/Persistence/Legacy/Notification/Gateway/DoctrineDatabaseTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Persistence\\Legacy\\Notification\\Gateway\\DoctrineDatabaseTest\:\:testLoadUserNotifications\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Persistence/Legacy/Notification/Gateway/DoctrineDatabaseTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Persistence\\Legacy\\Notification\\Gateway\\DoctrineDatabaseTest\:\:testUpdateNotification\(\) has no return type specified\.$#'
identifier: missingType.return
Expand Down Expand Up @@ -67278,12 +67152,6 @@ parameters:
count: 1
path: tests/lib/Persistence/Legacy/Notification/HandlerTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Persistence\\Legacy\\Notification\\HandlerTest\:\:testLoadUserNotifications\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Persistence/Legacy/Notification/HandlerTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Persistence\\Legacy\\Notification\\HandlerTest\:\:testUpdateNotification\(\) has no return type specified\.$#'
identifier: missingType.return
Expand Down Expand Up @@ -69144,20 +69012,14 @@ parameters:
count: 1
path: tests/lib/Repository/Decorator/NotificationServiceDecoratorTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Repository\\Decorator\\NotificationServiceDecoratorTest\:\:testLoadNotificationsDecorator\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Repository/Decorator/NotificationServiceDecoratorTest.php

-
message: '#^Method Ibexa\\Tests\\Core\\Repository\\Decorator\\NotificationServiceDecoratorTest\:\:testMarkNotificationAsReadDecorator\(\) has no return type specified\.$#'
identifier: missingType.return
count: 1
path: tests/lib/Repository/Decorator/NotificationServiceDecoratorTest.php

-
message: '#^Parameter \#1 \$innerService of class Ibexa\\Contracts\\Core\\Repository\\Decorator\\NotificationServiceDecorator@anonymous/tests/lib/Repository/Decorator/NotificationServiceDecoratorTest\.php\:22 constructor expects Ibexa\\Contracts\\Core\\Repository\\NotificationService, PHPUnit\\Framework\\MockObject\\MockObject given\.$#'
message: '#^Parameter \#1 \$innerService of class Ibexa\\Contracts\\Core\\Repository\\Decorator\\NotificationServiceDecorator@anonymous/tests/lib/Repository/Decorator/NotificationServiceDecoratorTest\.php\:24 constructor expects Ibexa\\Contracts\\Core\\Repository\\NotificationService, PHPUnit\\Framework\\MockObject\\MockObject given\.$#'
identifier: argument.type
count: 1
path: tests/lib/Repository/Decorator/NotificationServiceDecoratorTest.php
Expand Down
13 changes: 5 additions & 8 deletions src/contracts/Persistence/Notification/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace Ibexa\Contracts\Core\Persistence\Notification;

use Ibexa\Contracts\Core\Repository\Values\Notification\Notification as APINotification;
use Ibexa\Contracts\Core\Repository\Values\Notification\Query\NotificationQuery;

interface Handler
{
Expand Down Expand Up @@ -51,20 +52,16 @@ public function countPendingNotifications(int $ownerId): int;
public function getNotificationById(int $notificationId): Notification;

/**
* @param int $userId
* @param int $offset
* @param int $limit
*
* @return \Ibexa\Contracts\Core\Persistence\Notification\Notification[]
*/
public function loadUserNotifications(int $userId, int $offset, int $limit): array;

/**
* @param int $currentUserId
*
* @return int
* @return \Ibexa\Contracts\Core\Persistence\Notification\Notification[]
*/
public function countNotifications(int $currentUserId): int;
public function findUserNotifications(int $userId, ?NotificationQuery $query = null): array;

public function countNotifications(int $currentUserId, ?NotificationQuery $query = null): int;

/**
* @param \Ibexa\Contracts\Core\Repository\Values\Notification\Notification $notification
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Ibexa\Contracts\Core\Repository\Values\Notification\CreateStruct;
use Ibexa\Contracts\Core\Repository\Values\Notification\Notification;
use Ibexa\Contracts\Core\Repository\Values\Notification\NotificationList;
use Ibexa\Contracts\Core\Repository\Values\Notification\Query\NotificationQuery;

abstract class NotificationServiceDecorator implements NotificationService
{
Expand All @@ -30,6 +31,11 @@ public function loadNotifications(
return $this->innerService->loadNotifications($offset, $limit);
}

public function findNotifications(?NotificationQuery $query = null): NotificationList
{
return $this->innerService->findNotifications($query);
}

public function getNotification(int $notificationId): Notification
{
return $this->innerService->getNotification($notificationId);
Expand All @@ -50,9 +56,9 @@ public function getPendingNotificationCount(): int
return $this->innerService->getPendingNotificationCount();
}

public function getNotificationCount(): int
public function getNotificationCount(?NotificationQuery $query = null): int
{
return $this->innerService->getNotificationCount();
return $this->innerService->getNotificationCount($query);
}

public function createNotification(CreateStruct $createStruct): Notification
Expand Down
18 changes: 4 additions & 14 deletions src/contracts/Repository/NotificationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,18 @@
use Ibexa\Contracts\Core\Repository\Values\Notification\CreateStruct;
use Ibexa\Contracts\Core\Repository\Values\Notification\Notification;
use Ibexa\Contracts\Core\Repository\Values\Notification\NotificationList;
use Ibexa\Contracts\Core\Repository\Values\Notification\Query\NotificationQuery;

/**
* Service to manager user notifications. It works in the context of a current User (obtained from
* the PermissionResolver).
*/
interface NotificationService
{
/**
* Get currently logged user notifications.
*
* @param int $offset the start offset for paging
* @param int $limit the number of notifications returned
*
* @return \Ibexa\Contracts\Core\Repository\Values\Notification\NotificationList
*/
public function loadNotifications(int $offset, int $limit): NotificationList;

public function findNotifications(?NotificationQuery $query = null): NotificationList;

/**
* Load single notification (by ID).
*
Expand Down Expand Up @@ -64,12 +59,7 @@ public function markNotificationAsUnread(Notification $notification): void;
*/
public function getPendingNotificationCount(): int;

/**
* Get count of total users notifications.
*
* @return int
*/
public function getNotificationCount(): int;
public function getNotificationCount(?NotificationQuery $query = null): int;

/**
* Creates a new notification.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Contracts\Core\Repository\Values\Notification;

use Doctrine\DBAL\Query\QueryBuilder;
use Ibexa\Contracts\Core\Repository\Values\Notification\Query\CriterionInterface;

/**
* @template T of \Ibexa\Contracts\Core\Repository\Values\Notification\Query\CriterionInterface
*/
interface CriterionHandlerInterface
{
public function supports(CriterionInterface $criterion): bool;

/**
* @param \Doctrine\DBAL\Query\QueryBuilder $qb
* @param T $criterion
*/
public function apply(QueryBuilder $qb, CriterionInterface $criterion): void;
}
Loading
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载