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-LIB][main] #10630 Add support for add existing user to a context #10631

Merged
merged 5 commits into from
Dec 24, 2024

Conversation

defstat
Copy link
Contributor

@defstat defstat commented Nov 24, 2024

No description provided.

Copy link
Collaborator

@ewhanson ewhanson left a comment

Choose a reason for hiding this comment

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

Looks good, @defstat. Just a few comments/questions. Thanks!

try {
return $this->selectedHandler->cancel();
} catch (\Exception $e) {
return response()->json([], Response::HTTP_INTERNAL_SERVER_ERROR);
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be helpful if the error text could be included as is done below (e.g. ['error' => $e->getMessage]).

Copy link
Contributor Author

@defstat defstat Dec 16, 2024

Choose a reason for hiding this comment

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

Changed to

        try {
            return $this->selectedHandler->cancel();
        } catch (\Exception $e) {
            return response()->json([
                'error' => $e->getMessage()
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }

$result = $this->invitation->updateStatus(InvitationStatus::CANCELLED);

if (!$result) {
return response()->json([], Response::HTTP_CONFLICT);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could a more descriptive error also be included? It seems like the previous iteration included some text about why it couldn't be canceled. I think in context, a 409 response might not be descriptive enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree. I have changed that to

        if (!$result) {
            return response()->json([
                'error' => __('invitation.api.error.operationFailed')
            ], Response::HTTP_UNPROCESSABLE_ENTITY);
        }

where

msgid "invitation.api.error.operationFailed"
msgstr "This invitation operation failed"

$mailable = $this->invitation->getMailable();

if (!isset($mailable)) {
return response()->json([], Response::HTTP_NOT_FOUND);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here. Could a additional description of what was not found, e.g. invitation.api.error.invitationTypeNotHasMailable be returned as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure! Changed to

        if (!isset($mailable)) {
            return response()->json([
                'error' => __('invitation.api.error.invitationTypeNotHasMailable')
            ], Response::HTTP_NOT_FOUND);
        }

@@ -35,6 +35,7 @@
use PKP\invitation\invitations\userRoleAssignment\rules\UserMustExistRule;
use PKP\mail\mailables\UserRoleAssignmentInvitationNotify;
use PKP\security\Validation;
use PKP\user\User;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This import isn't used anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use PKP\invitation\invitations\userRoleAssignment\payload\UserRoleAssignmentInvitePayload;
use PKP\user\User;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This User import isn't used.

Copy link
Contributor Author

@defstat defstat Dec 16, 2024

Choose a reason for hiding this comment

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

Isn't it used at

 protected function transformUser(?User $user): ?array

and

protected function createNewUserFromPayload(UserRoleAssignmentInvitePayload $payload): User

?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry about that. You're right. I think that comment was meant for classes/invitation/invitations/userRoleAssignment/resources/UserRoleAssignmentInviteManagerDataResource.php instead.

Copy link
Collaborator

Choose a reason for hiding this comment

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

getInvitation() below has a typehint of UserRoleAssignmentInvite but it's not clear that $this->invitation will be of that specific type rather than the broader Invitation type in the parent class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a valid comment, and I had also considered this when the code was developed.

My goal was to maintain $invitation at the parent level to allow shared functionality, while also specifying the correct type in the child class.

To achieve this, I added:

public function getInvitation(): UserRoleAssignmentInvite
{
    return $this->invitation;
}

at the child class level to ensure type specificity.

Additionally, since Invitation is an abstract class, it cannot be instantiated directly, which ensures that $invitation will always be an instance of a concrete subclass.

However, I understand that this design might not make the intended behavior obvious. Do you have any suggestions for making the returned types clearer?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm... that's a good question. I haven't tried it, but if you redefined $invitation at the top of the file with the more specific concrete class, that would probably solve the problem I had, but I'm not sure if that will cause different problems. What do you think?

Copy link
Contributor Author

@defstat defstat Dec 18, 2024

Choose a reason for hiding this comment

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

Thanks, @ewhanson! Adding $invitation in the child class is possible, but I feel it doesn’t entirely address your initial comment. It might still leave some ambiguity about the type consistency across the parent and child classes.

What are your thoughts on using generics through PHPDoc annotations? While PHP doesn't natively support generics, these annotations can improve clarity and help with IDE comments and general code analysis. However, I understand that this won’t enforce the type at runtime, so it might not fully address the overall concern.

My intent with this design was to guide developers to use the getInvitation() function rather than accessing $this->invitation directly. This ensures type safety and keeps the interaction consistent.

I’m open to other ideas or suggestions - I find this topic quite interesting!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks, @defstat! I agree this is a tricky one! I think the idea of using generics in a PHPDoc comment may be the best way to go and keep the actual type hint the underlying Invitation type is probably the best way to go. I also agree trying to get developers to use the getInvitation() is a good call!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ewhanson I have pushed the change - Would you like to take a look?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@defstat, I'm not super familiar with doing this in PHP, but it looks good to me. If it causes issues in the future we can always update it. Thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

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

If preRedirectActions() at the bottom doesn't return anything, both it and the method in the abstract class should probably be typehinted as returning void.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed

Copy link
Collaborator

Choose a reason for hiding this comment

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

Both the Repo and JsonResource imports are no longer used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

@defstat
Copy link
Contributor Author

defstat commented Dec 16, 2024

@ewhanson thanks for the review. I have added the changes for the review comments that I have no follow-up questions. Also I rebased the branch on current main branch.

@ewhanson
Copy link
Collaborator

Thanks @defstat, I can have another look.

@ewhanson
Copy link
Collaborator

Thanks @defstat, I left two responses to your questions, but other than that, it looks good to me. 👍

@defstat defstat merged commit 4788455 into pkp:main Dec 24, 2024
1 check passed
@@ -124,7 +126,7 @@ public function getGroupRoutes(): void
]),
])->group(function () {

Route::get('', $this->getMany(...))
Route::get('{type}', $this->getMany(...))
Copy link
Member

Choose a reason for hiding this comment

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

@defstat this change is causing all tests break with latest pull of pkp-lib main branch . With the add of route param type, which probably has not been considered in some other places(from where AJAX request are made) cause the following exception

[29-Dec-2024 08:20:56 UTC] Symfony\Component\HttpKernel\Exception\NotFoundHttpException: The route publicknowledge/api/v1/invitations could not be found. in /Users/abir/Sites/code/ojs-main/lib/pkp/lib/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php:44
Stack trace:
#0 /Users/abir/Sites/code/ojs-main/lib/pkp/lib/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php(163): Illuminate\Routing\AbstractRouteCollection->handleMatchedRoute(Object(Illuminate\Http\Request), NULL)
#1 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/core/PKPBaseController.php(104): Illuminate\Routing\RouteCollection->match(Object(Illuminate\Http\Request))
#2 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/middleware/traits/HasRequiredMiddleware.php(53): PKP\core\PKPBaseController::getRequestedRoute(Object(Illuminate\Http\Request))
#3 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/middleware/DecodeApiTokenWithValidation.php(64): PKP\middleware\DecodeApiTokenWithValidation->hasRequiredMiddleware(Object(Illuminate\Http\Request))
#4 /Users/abir/Sites/code/ojs-main/lib/pkp/lib/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): PKP\middleware\DecodeApiTokenWithValidation->handle(Object(Illuminate\Http\Request), Object(Closure))
#5 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/middleware/SetupContextBasedOnRequestUrl.php(63): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#6 /Users/abir/Sites/code/ojs-main/lib/pkp/lib/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): PKP\middleware\SetupContextBasedOnRequestUrl->handle(Object(Illuminate\Http\Request), Object(Closure))
#7 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/middleware/AllowCrossOrigin.php(34): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#8 /Users/abir/Sites/code/ojs-main/lib/pkp/lib/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): PKP\middleware\AllowCrossOrigin->handle(Object(Illuminate\Http\Request), Object(Closure))
#9 /Users/abir/Sites/code/ojs-main/lib/pkp/lib/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#10 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/handler/APIHandler.php(102): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#11 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/core/APIRouter.php(116): PKP\handler\APIHandler->runRoutes()
#12 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/core/Dispatcher.php(158): PKP\core\APIRouter->route(Object(APP\core\Request))
#13 /Users/abir/Sites/code/ojs-main/lib/pkp/classes/core/PKPApplication.php(395): PKP\core\Dispatcher->dispatch(Object(APP\core\Request))
#14 /Users/abir/Sites/code/ojs-main/index.php(30): PKP\core\PKPApplication->execute()
#15 /Users/abir/.composer/vendor/laravel/valet/server.php(110): require('/Users/abir/Sit...')
#16 {main}

As the route has changed with the addition of a new route param, route is not found by router .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@touhidurabir, sorry about that - I have made the change required and waiting for the tests to finish.

Copy link
Contributor Author

@defstat defstat Dec 30, 2024

Choose a reason for hiding this comment

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

@touhidurabir I don't see the error mentioned by you after the PR: pkp/ui-library#472 but those tests are still failing with other errors I think (see pkp/ojs#4573). Is there another problem that you know?

Copy link
Member

Choose a reason for hiding this comment

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

@defstat in the error log of failed tests , I can see the following exception

[Mon Dec 30 12:03:05 2024] Symfony\Component\HttpKernel\Exception\NotFoundHttpException: The route publicknowledge/api/v1/invitations/userRoleAssignment could not be found. in /home/runner/ojs/lib/pkp/lib/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php:44

but I can tests with latest pkp-lib main checkout, this works for me .

However the current pkp-lib submodule reference to main app is not the latest main but few commits behind where the route in InvitationController set as

Route::get('', $this->getMany(...))
                ->name('invitation.getMany');

I think thats causing the issue . I think you need include the latest pkp-lib submodule update also in your PR .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @touhidurabir! again it seems that the tests are failing down the PHPUnit part of the tests this time.

Copy link
Member

Choose a reason for hiding this comment

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

Tests are failing because of this

Test Errored (functional\ArticleBodyTest::testCreate)
array_reduce(): Argument #1 ($array) must be of type array, null given
After Test Method Called (functional\ArticleBodyTest::tearDown)

it's a issue with jatsTemplate plugin's unit test and I have added a fix in the PR of #10292 at https://github.com/pkp/jatsTemplate/pull/54/files#diff-c87e6397a6dd5c2bf754d5b10da491be897899cf411d80e1dbcefedb20bd9960R114

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK @touhidurabir, thanks. Everything is merged for the first error.

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.

3 participants