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

Use static instead of self when calling static functions to allow easier customisation in subclasses #96

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

miguelwicht
Copy link

This PR replaces the usage of "self" with "static" when calling the static functions in the ResourceController. This makes it possible to inherit from the ResourceController and overwrite e.g. validateScim() without having to duplicate all methods that reference a static method as well. Without those changes the validateScim() method of the subclass would never be called.

Short example:

<?php
class A {
    public static function who() {
        echo "A";
    }
    public static function test() {
        self::who();
    }
}

class B extends A {
    public static function who() {
        echo "B";
    }
}

B::test(); // will return A
?>

More infos can be found here: https://www.php.net/oop5.late-static-bindings

As far as I can see the methods don't even need to be static but changing that would be a breaking change.

Why do I need these changes? https://scimvalidator.microsoft.com requires a specific status code and scimType when creating a user fails due to the user already existing.

So what I trying to do is:

  • Create a subclass of ResourceController
  • Overwrite validateScim() (see below)
  • Change the controller used in the routes
protected static function validateScim(ResourceType $resourceType, $flattened, ?Model $resourceObject)
    {
        $validations = $resourceType->getValidations();

        foreach ($validations as $key => $value) {
            if (is_string($value)) {
                $validations[$key] = $resourceObject ? preg_replace('/,\[OBJECT_ID\]/', ',' . $resourceObject->id, $value) : str_replace(',[OBJECT_ID]', '', $value);
            }
        }

        $validator = Validator::make($flattened, $validations);

        if ($validator->fails()) {
            $e = $validator->errors();

            if ($e->has('urn:ietf:params:scim:schemas:core:2.0:User:userName')) {
                $userNameError = $e->get('urn:ietf:params:scim:schemas:core:2.0:User:userName');

                if (in_array('The urn:ietf:params:scim:schemas:core:2.0: user:user name has already been taken.', $userNameError)) {
                    $exception = new SCIMException('Invalid data!', 409);
                    $exception->setScimType('uniqueness')->setErrors($e);
                    throw $exception;
                }
            }

            throw (new SCIMException('Invalid data!'))->setCode(400)->setScimType('invalidSyntax')->setErrors($e);
        }

        return $validator->validate();
    }

Not sure if there is an easier way to achieve this. But without the changes from the PR I would have to duplicate at least createObject() and createFromSCIM() as well which means I have to update / check them every time this plugin is updated.

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.

1 participant