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

Do not try to refresh attributes #6750

Merged
merged 1 commit into from
Feb 21, 2025
Merged

Conversation

lyrixx
Copy link
Contributor

@lyrixx lyrixx commented Feb 21, 2025

with the following code and test, it crashed

<?php

namespace App;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\HttpOperation;
use ApiPlatform\OpenApi\Model\Operation;
use PhpParser\Node;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor;
use PhpParser\Node\Attribute;
use PhpParser\Node\Expr\New_;
use Rector\PhpParser\Node\Value\ValueResolver;
use Rector\Rector\AbstractRector;

final class ApipMigrateOpenApiRector extends AbstractRector
{
    public function __construct(
        private readonly ValueResolver $valueResolver,
    ) {
    }

    public function getNodeTypes(): array
    {
        return [New_::class, Attribute::class];
    }

    public function refactor(Node $node)
    {
        if ($node instanceof New_ && is_a($this->getName($node->class), HttpOperation::class, true)) {
            return $this->convert($node);
        }

        if ($node instanceof Attribute && ApiProperty::class === $this->getName($node->name)) {
            return $this->convert($node);
        }

        return null;
    }

    private function convert(Node $node): ?Node
    {
        $scope = $node->getAttribute('scope');
        $update = false;

        foreach ($node->args as $arg) {
            if ('openapiContext' !== $this->getName($arg)) {
                continue;
            }


            $arg->name->name = 'openapi';

            $argValue = $arg->value;


            if (!$argValue instanceof Node\Expr\Array_) {
                // It should be an array! If it's not, we can't do anything.
                continue;
            }
            $update = true;

            $openApiArgs = [];

            foreach ($argValue->items as $item) {
                $openApiArgs[] = $i = new Node\Arg(
                    $item->value,
                    name: new Node\Identifier($this->valueResolver->getValue($item->key)),
                );
                $i->setAttribute('multiline', true);
                // Should we copy the current scope ? 
                // $i->setAttribute('scope', $scope);
            }

            $arg->value = new New_(
                new Node\Name\FullyQualified(Operation::class),
                $openApiArgs,
                [
                    'scope' => $scope,
                ]
            );

            return $node;
        }
 
        return null;
    }
}
<?php

namespace AppBundle\Api\Dto\AuditLog;

use ApiPlatform\Metadata\ApiProperty;
use AppBundle\Entity\Organization as OrganizationEntity;
use Symfony\Component\Serializer\Attribute\Groups;

#[Groups('auditLog/read')]
class Organization
{
    public function __construct(
        public ?OrganizationEntity $organization,
        public string $organizationName,
        public bool $loginPasswordAllowed,
        public bool $twoFactorRequired,
        #[ApiProperty(openapiContext: [
            'type' => 'object',
            'properties' => [
                'allowed' => ['type' => 'boolean'],
                'providers' => ['type' => 'object', 'additionalProperties' => ['type' => 'boolean']],
            ],
        ])]
        public ?array $oAuthRestriction = null,
    ) {
    }
}
-----
<?php

namespace AppBundle\Api\Dto\AuditLog;

use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Metadata\ApiProperty;
use AppBundle\Entity\Organization as OrganizationEntity;
use Symfony\Component\Serializer\Attribute\Groups;

#[Groups('auditLog/read')]
class Organization
{
    public function __construct(
        public ?OrganizationEntity $organization,
        public string $organizationName,
        public bool $loginPasswordAllowed,
        public bool $twoFactorRequired,
        #[ApiProperty(openapi: new Operation(
            type: 'object',
            properties: [
                'allowed' => ['type' => 'boolean'],
                'providers' => ['type' => 'object', 'additionalProperties' => ['type' => 'boolean']],
            ],
        ))]
        public ?array $oAuthRestriction = null,
    ) {
    }
}

@samsonasik
Copy link
Member

Thank you, it is better to use the statement that the attribute belong instead of direct Attribute so you always got correct refresh scope, but this change is ok for me :)

@samsonasik samsonasik merged commit a8eabc6 into rectorphp:main Feb 21, 2025
44 checks passed
@lyrixx lyrixx deleted the refresh-attribute branch February 21, 2025 17:26
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