mirror of
https://github.com/chenasraf/cospend-nc.git
synced 2026-05-17 17:38:10 +00:00
start improving db member management
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Julien Veyssier <julien-nc@posteo.net
|
||||
* @author Julien Veyssier <julien-nc@posteo.net>
|
||||
* @copyright Julien Veyssier 2019
|
||||
*/
|
||||
|
||||
|
||||
86
lib/Db/Member.php
Normal file
86
lib/Db/Member.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Nextcloud - cospend
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Julien Veyssier <julien-nc@posteo.net>
|
||||
* @copyright Julien Veyssier 2024
|
||||
*/
|
||||
|
||||
namespace OCA\Cospend\Db;
|
||||
|
||||
use OCA\Cospend\Utils;
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\IAvatarManager;
|
||||
|
||||
/**
|
||||
* @method int getId()
|
||||
* @method void setId(int $id)
|
||||
* @method string getProjectid()
|
||||
* @method void setProjectid(string $projectid)
|
||||
* @method string getName()
|
||||
* @method void setName(string $name)
|
||||
* @method float getWeight()
|
||||
* @method void setWeight(float $weight)
|
||||
* @method int getActivated()
|
||||
* @method void setActivated(int $activated)
|
||||
* @method int getLastchanged()
|
||||
* @method void setLastchanged(int $lastchanged)
|
||||
* @method string getColor()
|
||||
* @method void setColor(string $color)
|
||||
* @method string|null getUserid()
|
||||
* @method void setUserid(string|null $userid)
|
||||
*/
|
||||
class Member extends Entity implements \JsonSerializable {
|
||||
|
||||
protected $projectid;
|
||||
protected $name;
|
||||
protected $weight;
|
||||
protected $activated;
|
||||
protected $lastchanged;
|
||||
protected $color;
|
||||
protected $userid;
|
||||
|
||||
private $avatarManager;
|
||||
|
||||
public function __construct() {
|
||||
$this->addType('id', 'integer');
|
||||
$this->addType('projectid', 'string');
|
||||
$this->addType('name', 'string');
|
||||
$this->addType('weight', 'float');
|
||||
$this->addType('activated', 'integer');
|
||||
$this->addType('lastchanged', 'integer');
|
||||
$this->addType('color', 'string');
|
||||
$this->addType('userid', 'string');
|
||||
$this->avatarManager = \OC::$server->get(IAvatarManager::class);
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize() {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'weight' => $this->weight,
|
||||
'activated' => $this->activated === 1,
|
||||
'lastchanged' => $this->lastchanged,
|
||||
'userid' => $this->userid,
|
||||
'color' => $this->getColorArray(),
|
||||
];
|
||||
}
|
||||
|
||||
private function getColorArray(): array {
|
||||
if ($this->color === null) {
|
||||
$av = $this->avatarManager->getGuestAvatar($this->name);
|
||||
$avBgColor = $av->avatarBackgroundColor($this->name);
|
||||
return [
|
||||
'r' => $avBgColor->red(),
|
||||
'g' => $avBgColor->green(),
|
||||
'b' => $avBgColor->blue(),
|
||||
];
|
||||
}
|
||||
return Utils::hexToRgb($this->color);
|
||||
}
|
||||
}
|
||||
139
lib/Db/MemberMapper.php
Normal file
139
lib/Db/MemberMapper.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Nextcloud - cospend
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Julien Veyssier <julien-nc@posteo.net>
|
||||
* @copyright Julien Veyssier 2024
|
||||
*/
|
||||
|
||||
namespace OCA\Cospend\Db;
|
||||
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\AppFramework\Db\QBMapper;
|
||||
use OCP\DB\Exception;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
/**
|
||||
* @extends QBMapper<Member>
|
||||
*/
|
||||
class MemberMapper extends QBMapper {
|
||||
public const TABLE_NAME = 'cospend_members';
|
||||
|
||||
public function __construct(
|
||||
IDBConnection $db,
|
||||
) {
|
||||
parent::__construct($db, self::TABLE_NAME, Member::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $projectId
|
||||
* @param string $name
|
||||
* @return Member|null
|
||||
*/
|
||||
public function getMemberByName(string $projectId, string $name): ?Member {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from(self::TABLE_NAME)
|
||||
->where(
|
||||
$qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->eq('name', $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR))
|
||||
);
|
||||
|
||||
try {
|
||||
return $this->findEntity($qb);
|
||||
} catch (DoesNotExistException | MultipleObjectsReturnedException | Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $projectId
|
||||
* @param string $userId
|
||||
* @return Member|null
|
||||
*/
|
||||
public function getMemberByUserid(string $projectId, string $userId): ?Member {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from(self::TABLE_NAME)
|
||||
->where(
|
||||
$qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->eq('userid', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
|
||||
);
|
||||
|
||||
try {
|
||||
return $this->findEntity($qb);
|
||||
} catch (DoesNotExistException | MultipleObjectsReturnedException | Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $projectId
|
||||
* @param int $memberId
|
||||
* @return Member|null
|
||||
*/
|
||||
public function getMemberById(string $projectId, int $memberId): ?Member {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from(self::TABLE_NAME)
|
||||
->where(
|
||||
$qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->eq('id', $qb->createNamedParameter($memberId, IQueryBuilder::PARAM_INT))
|
||||
);
|
||||
|
||||
try {
|
||||
return $this->findEntity($qb);
|
||||
} catch (DoesNotExistException | MultipleObjectsReturnedException | Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $projectId
|
||||
* @param string|null $order
|
||||
* @param int|null $lastchanged
|
||||
* @return array
|
||||
*/
|
||||
public function getMembers(string $projectId, ?string $order = null, ?int $lastchanged = null): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$sqlOrder = 'name';
|
||||
if ($order !== null) {
|
||||
if ($order === 'lowername') {
|
||||
$sqlOrder = $qb->func()->lower('name');
|
||||
} else {
|
||||
$sqlOrder = $order;
|
||||
}
|
||||
}
|
||||
|
||||
$qb->select('*')
|
||||
->from(self::TABLE_NAME)
|
||||
->where(
|
||||
$qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
|
||||
);
|
||||
if ($lastchanged !== null) {
|
||||
$qb->andWhere(
|
||||
$qb->expr()->gt('lastchanged', $qb->createNamedParameter($lastchanged, IQueryBuilder::PARAM_INT))
|
||||
);
|
||||
}
|
||||
$qb->orderBy($sqlOrder, 'ASC');
|
||||
|
||||
try {
|
||||
return $this->findEntities($qb);
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Julien Veyssier <julien-nc@posteo.net
|
||||
* @author Julien Veyssier <julien-nc@posteo.net>
|
||||
* @copyright Julien Veyssier 2019
|
||||
*/
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ use OCA\Cospend\Activity\ActivityManager;
|
||||
use OCA\Cospend\AppInfo\Application;
|
||||
use OCA\Cospend\Db\BillMapper;
|
||||
|
||||
use OCA\Cospend\Db\Member;
|
||||
use OCA\Cospend\Db\MemberMapper;
|
||||
use OCA\Cospend\Db\ProjectMapper;
|
||||
use OCA\Cospend\Utils;
|
||||
use OCP\App\IAppManager;
|
||||
@@ -55,19 +57,20 @@ class ProjectService {
|
||||
private array $hardCodedCategoryNames;
|
||||
|
||||
public function __construct(
|
||||
private IL10N $l10n,
|
||||
private IConfig $config,
|
||||
private ProjectMapper $projectMapper,
|
||||
private BillMapper $billMapper,
|
||||
private IL10N $l10n,
|
||||
private IConfig $config,
|
||||
private ProjectMapper $projectMapper,
|
||||
private BillMapper $billMapper,
|
||||
private MemberMapper $memberMapper,
|
||||
private ActivityManager $activityManager,
|
||||
private IAvatarManager $avatarManager,
|
||||
private IUserManager $userManager,
|
||||
private IAppManager $appManager,
|
||||
private IGroupManager $groupManager,
|
||||
private IDateTimeZone $dateTimeZone,
|
||||
private IRootFolder $root,
|
||||
private IAvatarManager $avatarManager,
|
||||
private IUserManager $userManager,
|
||||
private IAppManager $appManager,
|
||||
private IGroupManager $groupManager,
|
||||
private IDateTimeZone $dateTimeZone,
|
||||
private IRootFolder $root,
|
||||
private INotificationManager $notificationManager,
|
||||
private IDBConnection $db
|
||||
private IDBConnection $db,
|
||||
) {
|
||||
$this->defaultCategories = [
|
||||
[
|
||||
@@ -1141,53 +1144,8 @@ class ProjectService {
|
||||
* @return array|null
|
||||
*/
|
||||
public function getMemberById(string $projectId, int $memberId): ?array {
|
||||
$member = null;
|
||||
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('id', 'userid', 'name', 'weight', 'color', 'activated', 'lastchanged')
|
||||
->from('cospend_members')
|
||||
->where(
|
||||
$qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->eq('id', $qb->createNamedParameter($memberId, IQueryBuilder::PARAM_INT))
|
||||
);
|
||||
$req = $qb->executeQuery();
|
||||
|
||||
while ($row = $req->fetch()) {
|
||||
$dbMemberId = (int) $row['id'];
|
||||
$dbWeight = (float) $row['weight'];
|
||||
$dbUserid = $row['userid'];
|
||||
$dbName = $row['name'];
|
||||
$dbActivated = (int) $row['activated'];
|
||||
$dbLastchanged = (int) $row['lastchanged'];
|
||||
$dbColor = $row['color'];
|
||||
if ($dbColor === null) {
|
||||
$av = $this->avatarManager->getGuestAvatar($dbName);
|
||||
$dbColor = $av->avatarBackgroundColor($dbName);
|
||||
$dbColor = [
|
||||
'r' => $dbColor->red(),
|
||||
'g' => $dbColor->green(),
|
||||
'b' => $dbColor->blue(),
|
||||
];
|
||||
} else {
|
||||
$dbColor = Utils::hexToRgb($dbColor);
|
||||
}
|
||||
|
||||
$member = [
|
||||
'activated' => $dbActivated === 1,
|
||||
'userid' => $dbUserid,
|
||||
'name' => $dbName,
|
||||
'id' => $dbMemberId,
|
||||
'weight' => $dbWeight,
|
||||
'color' => $dbColor,
|
||||
'lastchanged' => $dbLastchanged,
|
||||
];
|
||||
break;
|
||||
}
|
||||
$req->closeCursor();
|
||||
$qb->resetQueryParts();
|
||||
return $member;
|
||||
$member = $this->memberMapper->getMemberById($projectId, $memberId);
|
||||
return $member?->jsonSerialize();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1720,64 +1678,10 @@ class ProjectService {
|
||||
* @return array
|
||||
*/
|
||||
public function getMembers(string $projectId, ?string $order = null, ?int $lastchanged = null): array {
|
||||
$members = [];
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$sqlOrder = 'name';
|
||||
if ($order !== null) {
|
||||
if ($order === 'lowername') {
|
||||
$sqlOrder = $qb->func()->lower('name');
|
||||
} else {
|
||||
$sqlOrder = $order;
|
||||
}
|
||||
}
|
||||
|
||||
$qb->select('id', 'userid', 'name', 'weight', 'color', 'activated', 'lastchanged')
|
||||
->from('cospend_members')
|
||||
->where(
|
||||
$qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
|
||||
);
|
||||
if ($lastchanged !== null) {
|
||||
$qb->andWhere(
|
||||
$qb->expr()->gt('lastchanged', $qb->createNamedParameter($lastchanged, IQueryBuilder::PARAM_INT))
|
||||
);
|
||||
}
|
||||
$qb->orderBy($sqlOrder, 'ASC');
|
||||
$req = $qb->executeQuery();
|
||||
|
||||
while ($row = $req->fetch()) {
|
||||
$dbMemberId = (int) $row['id'];
|
||||
$dbWeight = (float) $row['weight'];
|
||||
$dbUserid = $row['userid'];
|
||||
$dbName = $row['name'];
|
||||
$dbActivated = (int) $row['activated'];
|
||||
$dbLastchanged = (int) $row['lastchanged'];
|
||||
$dbColor = $row['color'];
|
||||
if ($dbColor === null) {
|
||||
$av = $this->avatarManager->getGuestAvatar($dbName);
|
||||
$avatarBgColor = $av->avatarBackgroundColor($dbName);
|
||||
$dbColor = [
|
||||
'r' => $avatarBgColor->red(),
|
||||
'g' => $avatarBgColor->green(),
|
||||
'b' => $avatarBgColor->blue(),
|
||||
];
|
||||
} else {
|
||||
$dbColor = Utils::hexToRgb($dbColor);
|
||||
}
|
||||
|
||||
$members[] = [
|
||||
'activated' => $dbActivated === 1,
|
||||
'userid' => $dbUserid,
|
||||
'name' => $dbName,
|
||||
'id' => $dbMemberId,
|
||||
'weight' => $dbWeight,
|
||||
'color' => $dbColor,
|
||||
'lastchanged' => $dbLastchanged,
|
||||
];
|
||||
}
|
||||
$req->closeCursor();
|
||||
$qb->resetQueryParts();
|
||||
return $members;
|
||||
$members = $this->memberMapper->getMembers($projectId, $order, $lastchanged);
|
||||
return array_map(static function (Member $dbMember) {
|
||||
return $dbMember->jsonSerialize();
|
||||
}, $members);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2551,51 +2455,8 @@ class ProjectService {
|
||||
* @return array|null
|
||||
*/
|
||||
public function getMemberByName(string $projectId, string $name): ?array {
|
||||
$member = null;
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('id', 'userid', 'name', 'weight', 'color', 'activated', 'lastchanged')
|
||||
->from('cospend_members')
|
||||
->where(
|
||||
$qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->eq('name', $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR))
|
||||
);
|
||||
$req = $qb->executeQuery();
|
||||
|
||||
while ($row = $req->fetch()) {
|
||||
$dbMemberId = (int) $row['id'];
|
||||
$dbWeight = (float) $row['weight'];
|
||||
$dbUserid = $row['userid'];
|
||||
$dbName = $row['name'];
|
||||
$dbActivated = (int) $row['activated'];
|
||||
$dbLastchanged = (int) $row['lastchanged'];
|
||||
$dbColor = $row['color'];
|
||||
if ($dbColor === null) {
|
||||
$av = $this->avatarManager->getGuestAvatar($dbName);
|
||||
$dbColor = $av->avatarBackgroundColor($dbName);
|
||||
$dbColor = [
|
||||
'r' => $dbColor->red(),
|
||||
'g' => $dbColor->green(),
|
||||
'b' => $dbColor->blue(),
|
||||
];
|
||||
} else {
|
||||
$dbColor = Utils::hexToRgb($dbColor);
|
||||
}
|
||||
$member = [
|
||||
'activated' => $dbActivated === 1,
|
||||
'userid' => $dbUserid,
|
||||
'name' => $dbName,
|
||||
'id' => $dbMemberId,
|
||||
'weight' => $dbWeight,
|
||||
'color' => $dbColor,
|
||||
'lastchanged' => $dbLastchanged,
|
||||
];
|
||||
break;
|
||||
}
|
||||
$req->closeCursor();
|
||||
$qb->resetQueryParts();
|
||||
return $member;
|
||||
$member = $this->memberMapper->getMemberByName($projectId, $name);
|
||||
return $member?->jsonSerialize();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2606,53 +2467,11 @@ class ProjectService {
|
||||
* @return array|null
|
||||
*/
|
||||
public function getMemberByUserid(string $projectId, ?string $userId): ?array {
|
||||
$member = null;
|
||||
if ($userId !== null) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('id', 'userid', 'name', 'weight', 'color', 'activated', 'lastchanged')
|
||||
->from('cospend_members')
|
||||
->where(
|
||||
$qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->eq('userid', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
|
||||
);
|
||||
$req = $qb->executeQuery();
|
||||
|
||||
while ($row = $req->fetch()) {
|
||||
$dbMemberId = (int) $row['id'];
|
||||
$dbWeight = (float) $row['weight'];
|
||||
$dbUserid = $row['userid'];
|
||||
$dbName = $row['name'];
|
||||
$dbActivated = (int) $row['activated'];
|
||||
$dbLastchanged = (int) $row['lastchanged'];
|
||||
$dbColor = $row['color'];
|
||||
if ($dbColor === null) {
|
||||
$av = $this->avatarManager->getGuestAvatar($dbName);
|
||||
$dbColor = $av->avatarBackgroundColor($dbName);
|
||||
$dbColor = [
|
||||
'r' => $dbColor->red(),
|
||||
'g' => $dbColor->green(),
|
||||
'b' => $dbColor->blue(),
|
||||
];
|
||||
} else {
|
||||
$dbColor = Utils::hexToRgb($dbColor);
|
||||
}
|
||||
$member = [
|
||||
'activated' => $dbActivated === 1,
|
||||
'userid' => $dbUserid,
|
||||
'name' => $dbName,
|
||||
'id' => $dbMemberId,
|
||||
'weight' => $dbWeight,
|
||||
'color' => $dbColor,
|
||||
'lastchanged' => $dbLastchanged,
|
||||
];
|
||||
break;
|
||||
}
|
||||
$req->closeCursor();
|
||||
$qb->resetQueryParts();
|
||||
if ($userId === null) {
|
||||
return null;
|
||||
}
|
||||
return $member;
|
||||
$member = $this->memberMapper->getMemberByUserid($projectId, $userId);
|
||||
return $member?->jsonSerialize();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace OCA\Cospend\Controller;
|
||||
use OCA\Cospend\Activity\ActivityManager;
|
||||
use OCA\Cospend\AppInfo\Application;
|
||||
use OCA\Cospend\Db\BillMapper;
|
||||
use OCA\Cospend\Db\MemberMapper;
|
||||
use OCA\Cospend\Db\ProjectMapper;
|
||||
use OCA\Cospend\Service\ProjectService;
|
||||
use OCA\Cospend\Service\UserService;
|
||||
@@ -44,6 +45,7 @@ class ApiControllerTest extends TestCase {
|
||||
private BillMapper $billMapper;
|
||||
private ProjectMapper $projectMapper;
|
||||
private ProjectService $projectService;
|
||||
private MemberMapper $memberMapper;
|
||||
|
||||
public static function setUpBeforeClass(): void {
|
||||
$app = new Application();
|
||||
@@ -88,6 +90,7 @@ class ApiControllerTest extends TestCase {
|
||||
// $sc = $c->get(ContainerInterface::class);
|
||||
$l10n = $c->get(IL10N::class);
|
||||
$this->billMapper = new BillMapper($sc->getDatabaseConnection());
|
||||
$this->memberMapper = new MemberMapper($sc->getDatabaseConnection());
|
||||
$this->projectMapper = new ProjectMapper($sc->getDatabaseConnection(), $l10n);
|
||||
|
||||
$activityManager = new ActivityManager(
|
||||
@@ -123,6 +126,7 @@ class ApiControllerTest extends TestCase {
|
||||
$sc->getConfig(),
|
||||
$this->projectMapper,
|
||||
$this->billMapper,
|
||||
$this->memberMapper,
|
||||
$activityManager,
|
||||
$sc->getAvatarManager(),
|
||||
$c->get(IUserManager::class),
|
||||
|
||||
Reference in New Issue
Block a user