Skip to content

Commit

Permalink
Refactor favorite and user list tag unlinking. (#3807)
Browse files Browse the repository at this point in the history
  • Loading branch information
demiankatz committed Jun 17, 2024
1 parent d5c5c30 commit cce247f
Show file tree
Hide file tree
Showing 14 changed files with 287 additions and 75 deletions.
6 changes: 3 additions & 3 deletions module/VuFind/src/VuFind/Db/Service/ResourceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function __construct(protected Resource $resourceTable)
*/
public function beginTransaction(): void
{
$this->resourceTable->getAdapter()->getDriver()->getConnection()->beginTransaction();
$this->resourceTable->beginTransaction();
}

/**
Expand All @@ -78,7 +78,7 @@ public function beginTransaction(): void
*/
public function commitTransaction(): void
{
$this->resourceTable->getAdapter()->getDriver()->getConnection()->commit();
$this->resourceTable->commitTransaction();
}

/**
Expand All @@ -89,7 +89,7 @@ public function commitTransaction(): void
*/
public function rollBackTransaction(): void
{
$this->resourceTable->getAdapter()->getDriver()->getConnection()->rollback();
$this->resourceTable->rollbackTransaction();
}

/**
Expand Down
103 changes: 100 additions & 3 deletions module/VuFind/src/VuFind/Db/Service/ResourceTagsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,44 @@
*/
class ResourceTagsService extends AbstractDbService implements
ResourceTagsServiceInterface,
Feature\TransactionInterface,
\VuFind\Db\Table\DbTableAwareInterface
{
use \VuFind\Db\Table\DbTableAwareTrait;

/**
* Begin a database transaction.
*
* @return void
* @throws Exception
*/
public function beginTransaction(): void
{
$this->getDbTable('ResourceTags')->beginTransaction();
}

/**
* Commit a database transaction.
*
* @return void
* @throws Exception
*/
public function commitTransaction(): void
{
$this->getDbTable('ResourceTags')->commitTransaction();
}

/**
* Roll back a database transaction.
*
* @return void
* @throws Exception
*/
public function rollBackTransaction(): void
{
$this->getDbTable('ResourceTags')->rollbackTransaction();
}

/**
* Get Resource Tags Paginator
*
Expand Down Expand Up @@ -178,7 +212,19 @@ public function destroyResourceTagsLinksForUser(
): void {
$userId = $userOrId instanceof UserEntityInterface ? $userOrId->getId() : $userOrId;
$listId = $listOrId instanceof UserListEntityInterface ? $listOrId->getId() : $listOrId;
$this->getDbTable('ResourceTags')->destroyResourceLinks($resourceId, $userId, $listId, $tagId);
$callback = function ($select) use ($resourceId, $userId, $listId, $tagId) {
$select->where->equalTo('user_id', $userId);
if (null !== $resourceId) {
$select->where->in('resource_id', (array)$resourceId);
}
if (null !== $listId) {
$select->where->equalTo('list_id', $listId);
}
if (null !== $tagId) {
$select->where->in('tag_id', (array)$tagId);
}
};
$this->getDbTable('ResourceTags')->delete($callback);
}

/**
Expand All @@ -197,7 +243,17 @@ public function destroyNonListResourceTagsLinksForUser(
int|array|null $tagId = null
): void {
$userId = $userOrId instanceof UserEntityInterface ? $userOrId->getId() : $userOrId;
$this->getDbTable('ResourceTags')->destroyResourceLinks($resourceId, $userId, 'none', $tagId);
$callback = function ($select) use ($resourceId, $userId, $tagId) {
$select->where->equalTo('user_id', $userId);
if (null !== $resourceId) {
$select->where->in('resource_id', (array)$resourceId);
}
$select->where->isNull('list_id');
if (null !== $tagId) {
$select->where->in('tag_id', (array)$tagId);
}
};
$this->getDbTable('ResourceTags')->delete($callback);
}

/**
Expand All @@ -217,7 +273,48 @@ public function destroyAllListResourceTagsLinksForUser(
int|array|null $tagId = null
): void {
$userId = $userOrId instanceof UserEntityInterface ? $userOrId->getId() : $userOrId;
$this->getDbTable('ResourceTags')->destroyResourceLinks($resourceId, $userId, true, $tagId);
$callback = function ($select) use ($resourceId, $userId, $tagId) {
$select->where->equalTo('user_id', $userId);
if (null !== $resourceId) {
$select->where->in('resource_id', (array)$resourceId);
}
$select->where->isNotNull('list_id');
if (null !== $tagId) {
$select->where->in('tag_id', (array)$tagId);
}
};
$this->getDbTable('ResourceTags')->delete($callback);
}

/**
* Unlink rows for the specified user list. This removes tags ON THE LIST ITSELF, not tags on
* resources within the list.
*
* @param UserListEntityInterface|int $listOrId ID or entity representing list
* @param UserEntityInterface|int $userOrId ID or entity representing user
* @param int|int[]|null $tagId ID or array of IDs of tag(s) to unlink (null for ALL matching tags)
*
* @return void
*/
public function destroyUserListLinks(
UserListEntityInterface|int $listOrId,
UserEntityInterface|int $userOrId,
int|array|null $tagId = null
): void {
$listId = $listOrId instanceof UserListEntityInterface ? $listOrId->getId() : $listOrId;
$userId = $userOrId instanceof UserEntityInterface ? $userOrId->getId() : $userOrId;
$callback = function ($select) use ($userId, $listId, $tagId) {
$select->where->equalTo('user_id', $userId);
// retrieve tags assigned to a user list and filter out user resource tags
// (resource_id is NULL for list tags).
$select->where->isNull('resource_id');
$select->where->equalTo('list_id', $listId);

if (null !== $tagId) {
$select->where->in('tag_id', (array)$tagId);
}
};
$this->getDbTable('ResourceTags')->delete($callback);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,22 @@ public function destroyAllListResourceTagsLinksForUser(
int|array|null $tagId = null
): void;

/**
* Unlink rows for the specified user list. This removes tags ON THE LIST ITSELF, not tags on
* resources within the list.
*
* @param UserListEntityInterface|int $listOrId ID or entity representing list
* @param UserEntityInterface|int $userOrId ID or entity representing user
* @param int|int[]|null $tagId ID or array of IDs of tag(s) to unlink (null for ALL matching tags)
*
* @return void
*/
public function destroyUserListLinks(
UserListEntityInterface|int $listOrId,
UserEntityInterface|int $userOrId,
int|array|null $tagId = null
): void;

/**
* Gets unique tagged resources from the database.
*
Expand Down
6 changes: 3 additions & 3 deletions module/VuFind/src/VuFind/Db/Service/ShortlinksService.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class ShortlinksService extends AbstractDbService implements
*/
public function beginTransaction(): void
{
$this->getDbTable('shortlinks')->getAdapter()->getDriver()->getConnection()->beginTransaction();
$this->getDbTable('shortlinks')->beginTransaction();
}

/**
Expand All @@ -71,7 +71,7 @@ public function beginTransaction(): void
*/
public function commitTransaction(): void
{
$this->getDbTable('shortlinks')->getAdapter()->getDriver()->getConnection()->commit();
$this->getDbTable('shortlinks')->commitTransaction();
}

/**
Expand All @@ -82,7 +82,7 @@ public function commitTransaction(): void
*/
public function rollBackTransaction(): void
{
$this->getDbTable('shortlinks')->getAdapter()->getDriver()->getConnection()->rollback();
$this->getDbTable('shortlinks')->rollbackTransaction();
}

/**
Expand Down
33 changes: 33 additions & 0 deletions module/VuFind/src/VuFind/Db/Service/UserResourceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,39 @@ public function createOrUpdateLink(
return $result;
}

/**
* Unlink rows for the specified resource.
*
* @param int|int[]|null $resourceId ID (or array of IDs) of resource(s) to unlink (null for ALL
* matching resources)
* @param UserEntityInterface|int $userOrId ID or entity representing user removing links
* @param UserListEntityInterface|int $listOrId ID or entity representing list to unlink (null for ALL
* matching lists)
*
* @return void
*/
public function unlinkFavorites(
int|array|null $resourceId,
UserEntityInterface|int $userOrId,
UserListEntityInterface|int|null $listOrId = null
): void {
// Build the where clause to figure out which rows to remove:
$listId = is_int($listOrId) ? $listOrId : $listOrId?->getId();
$userId = is_int($userOrId) ? $userOrId : $userOrId->getId();
$callback = function ($select) use ($resourceId, $userId, $listId) {
$select->where->equalTo('user_id', $userId);
if (null !== $resourceId) {
$select->where->in('resource_id', (array)$resourceId);
}
if (null !== $listId) {
$select->where->equalTo('list_id', $listId);
}
};

// Delete the rows:
$this->getDbTable('UserResource')->delete($callback);
}

/**
* Create a UserResource entity object.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ public function createOrUpdateLink(
string $notes = ''
): UserResourceEntityInterface;

/**
* Unlink rows for the specified resource.
*
* @param int|int[]|null $resourceId ID (or array of IDs) of resource(s) to unlink (null for ALL
* matching resources)
* @param UserEntityInterface|int $userOrId ID or entity representing user removing links
* @param UserListEntityInterface|int $listOrId ID or entity representing list to unlink (null for ALL
* matching lists)
*
* @return void
*/
public function unlinkFavorites(
int|array|null $resourceId,
UserEntityInterface|int $userOrId,
UserListEntityInterface|int|null $listOrId = null
): void;

/**
* Create a UserResource entity object.
*
Expand Down
34 changes: 34 additions & 0 deletions module/VuFind/src/VuFind/Db/Table/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

namespace VuFind\Db\Table;

use Exception;
use Laminas\Db\Adapter\Adapter;
use Laminas\Db\TableGateway\AbstractTableGateway;
use Laminas\Db\TableGateway\Feature;
Expand Down Expand Up @@ -154,4 +155,37 @@ public function getDbTable($table)
{
return $this->tableManager->get($table);
}

/**
* Begin a database transaction.
*
* @return void
* @throws Exception
*/
public function beginTransaction(): void
{
$this->getAdapter()->getDriver()->getConnection()->beginTransaction();
}

/**
* Commit a database transaction.
*
* @return void
* @throws Exception
*/
public function commitTransaction(): void
{
$this->getAdapter()->getDriver()->getConnection()->commit();
}

/**
* Roll back a database transaction.
*
* @return void
* @throws Exception
*/
public function rollBackTransaction(): void
{
$this->getAdapter()->getDriver()->getConnection()->rollback();
}
}
10 changes: 10 additions & 0 deletions module/VuFind/src/VuFind/Db/Table/ResourceTags.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ public function createLink(
* @param array $ids IDs to check.
*
* @return array Associative array with two keys: present and missing
*
* @deprecated
*/
public function checkForTags($ids)
{
Expand Down Expand Up @@ -322,6 +324,10 @@ public function getStatistics($extended = false, $caseSensitiveTags = null)
* for ALL matching tags)
*
* @return void
*
* @deprecated Use ResourceTagsServiceInterface::destroyResourceTagsLinksForUser() or
* ResourceTagsServiceInterface::destroyNonListResourceTagsLinksForUser() or
* ResourceTagsServiceInterface::destroyAllListResourceTagsLinksForUser()
*/
public function destroyResourceLinks($resource, $user, $list = null, $tag = null)
{
Expand Down Expand Up @@ -363,6 +369,8 @@ public function destroyResourceLinks($resource, $user, $list = null, $tag = null
* for ALL matching tags)
*
* @return void
*
* @deprecated Use ResourceTagsServiceInterface::destroyUserListLinks()
*/
public function destroyListLinks($list, $user, $tag = null)
{
Expand Down Expand Up @@ -391,6 +399,8 @@ public function destroyListLinks($list, $user, $tag = null)
* @param Object $callback Callback function for selecting deleted rows.
*
* @return void
*
* @deprecated
*/
protected function processDestroyLinks($callback)
{
Expand Down
9 changes: 3 additions & 6 deletions module/VuFind/src/VuFind/Db/Table/UserResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@
use VuFind\Db\Service\ResourceTagsServiceInterface;
use VuFind\Db\Service\UserResourceServiceInterface;

use function is_array;

/**
* Table Definition for user_resource
*
Expand Down Expand Up @@ -158,6 +156,8 @@ public function createOrUpdateLink(
* any tags associated with the $resource_id independently of lists)
*
* @return void
*
* @deprecated
*/
public function destroyLinks($resource_id, $user_id, $list_id = null)
{
Expand All @@ -175,10 +175,7 @@ public function destroyLinks($resource_id, $user_id, $list_id = null)
$callback = function ($select) use ($resource_id, $user_id, $list_id) {
$select->where->equalTo('user_id', $user_id);
if (null !== $resource_id) {
if (!is_array($resource_id)) {
$resource_id = [$resource_id];
}
$select->where->in('resource_id', $resource_id);
$select->where->in('resource_id', (array)$resource_id);
}
// null or true values of $list_id have different meanings in the
// context of the destroyResourceTagsLinksForUser() call above, since
Expand Down
Loading

0 comments on commit cce247f

Please sign in to comment.