Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkp/pkp-lib#10506 Refactor UserGroup to use Eloquent #10519

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Hafsa-Naeem
Copy link
Contributor

No description provided.

Copy link
Collaborator

@Vitaliy-1 Vitaliy-1 left a comment

Choose a reason for hiding this comment

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

Thanks! I've left a couple of comments but overall it looks good!

* Retrieve a keyed Collection (key = user_group_id, value = count) with the amount of active users for each UserGroup.
*
* @param int|null $contextId
* @return Collection
*/
public function getUserCountByContextId(?int $contextId = null): Collection
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we move this to the Model as a scope?

*
* @param array $params
* @return UserGroup
*/
public function newDataObject(array $params = []): UserGroup
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think that we need this method

self::forgetEditorialHistoryCache($userGroup->context_id);
}

$userGroup->delete();

Hook::call('UserGroup::delete', [$userGroup]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can rely on the Model's events here. But this needs to be added to the list of the removed hooks, the same as for Announcements

@@ -110,6 +111,10 @@ public function insertGetId(array $values, $sequence = null)
$settingValues->each(function (mixed $settingValue, string $settingName) use ($id, &$rows) {
$settingName = Str::camel($settingName);
if ($this->isMultilingual($settingName)) {
// if non-localized data passed, set the locale to default one
if (is_string($settingValue)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure if it makes the code better. @jonasraoni, do you have an opinion whether we should allow to set multilingual value by the default locale?

* @param int $id
* @param int|null $contextId
* @return UserGroup|null
*/
public function get(int $id, ?int $contextId = null): ?UserGroup
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would move some of the logic from Repository to the Model. In particular, methods that are associated with basic operations with the entity, like this one

*/
public function getContextId(): ?int
public function setAttribute($key, $value)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think we need to override setAttribute() here in order to allow to set multilingual values as usual strings. It's better to think about general solution

*/
public function setDefault($isDefault)
public function stageAssignments(): HasMany
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you also add the relationship to the StageAssignment? And the same for the UserUserGroup

return collect($item)->unique();
});
return $userIdsByUserGroupId->toArray();
$users = UserUserGroup::query()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it work without query() method applied?

$cacheKeyPrefix = 'PKP\userGroup\Repository::getMastheadUserIdsByRoleIds';
$cacheKeys = [
"{$cacheKeyPrefix}EditorialMasthead{$contextId}" . self::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME,
"{$cacheKeyPrefix}EditorialHistory{$contextId}" . self::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this method also clear cache for the Editorial History?

@@ -34,6 +34,7 @@
use PKP\userGroup\relationships\UserUserGroup;
use PKP\validation\ValidatorFactory;
use PKP\xml\PKPXMLParser;
use Illuminate\Database\Query\Builder;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Several use statements aren't used anymore.

Copy link
Collaborator

@Vitaliy-1 Vitaliy-1 left a comment

Choose a reason for hiding this comment

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

Thanks, that's a huge piece of work!
I left comments, in general they are all small. I recommend to use scopes as per pattern in other refactored Models

->getMany();
$submitterUserGroups = UserGroup::where('contextId', $context->getId())
->where('roleId', Role::ROLE_ID_MANAGER)
->orWhere('roleId', Role::ROLE_ID_AUTHOR)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We have several where clauses here, do we need to group this orWhere as per eloquent documentation?
Or we could use whereIn


$userGroupIdPropName = 'userGroupId';

if (isset($params[$userGroupIdPropName])) {
$submitAsUserGroup = $submitterUserGroups
->first(function (UserGroup $userGroup) use ($params, $userGroupIdPropName) {
return $userGroup->getId() === $params[$userGroupIdPropName];
return $userGroup->usergroupid === $params[$userGroupIdPropName];
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe here and in other places it could be replaced with $userGroup->id

@@ -624,14 +621,14 @@ public function add(Request $illuminateRequest): JsonResponse
})
->first();
} else {
$submitAsUserGroup = Repo::userGroup()->getFirstSubmitAsAuthorUserGroup($context->getId());
$submitAsUserGroup = UserGroup::where('contextId', $context->getId())->where('roleId', Role::ROLE_ID_AUTHOR)->first();
Copy link
Collaborator

Choose a reason for hiding this comment

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

According to the getFirstSubmit... method's body, it uses also permitSelfRegistration filter. I see you already have a scope for it to apply here

->filterByContextIds([$submission->getData('contextId')])
->getMany();
$contextId = $submission->getData('contextId');
$userGroups = UserGroup::where('context_id', $contextId)->get();
Copy link
Collaborator

Choose a reason for hiding this comment

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

UserGroup::where('contextId', $contextId)->get()

->getCollector()
->filterByContextIds([$submission->getData('contextId')])
->getMany();
$contextId = $submission->getData('contextId');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here and in other places, it could be just one line:

$userGroups = UserGroup::where('contextId', $submission->getData('contextId'))->get()


// Determine masthead status
$masthead = match ($mastheadStatus) {
UserUserGroupMastheadStatus::STATUS_ON => 1,
Copy link
Collaborator

Choose a reason for hiding this comment

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

masthead should be true/false

'permit_metadata_edit' => $permitMetadataEdit,
'is_default' => true,
'show_title' => true,
'masthead' => $masthead,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you double check if we are settings boolean true/false values and not a string?


// insert the group into the DB
$userGroupId = $this->add($userGroup);
$userGroupId = $userGroup->user_group_id;
Copy link
Collaborator

Choose a reason for hiding this comment

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

camel case

$userGroup->setMasthead($masthead ?? false);
// Create a new UserGroup instance and set attributes
$userGroup = new UserGroup([
'role_id' => $roleId,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here and in other places, can we use camel case when creating a model with attributes?

$abbrevKey = $userGroup->settings['abbrevLocaleKey'] ?? null;

if ($nameKey) {
$userGroup->settings['name'] = __($nameKey, [], $locale);
Copy link
Collaborator

Choose a reason for hiding this comment

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

It should be possible to interact with and set settings attributes normally

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants