Podnoszenie wersji z symfony 5.3 na symfony 6.4

0

Witam wszystkich.
Przewertowałem strony w poszukiwaniu rozwiązania, ale cały czas siedzę w miejscu z problemem, pisałem nawet do autora paczki, ale nic nie ruszyło się do przodu.

Opisze problem w skrócie.
Próbuję podnieść wersję projektu z symfony 5.3 na symfony 6.4 wraz z zależnościami, na początku napotykałem błędy z innymi paczkami ale jakoś udawało się iść do przodu.

Natrafiłem na problem z paczką nelmio/api-doc-bundle, był przeskok z wersji 3 na wersję 4 dosyć istotny wymagało podmianę SWG na OA Dokumentacja

Próbuję odpalić projekt, lecz jest problem z generowaniem routingu opatrzony takim błędem.
screenshot-20240524141743.png

To jest api, więc tak wygląda adnotacja związana z routingiem
screenshot-20240524141953.png

Może ktoś miał już styczność z takim problemem i wie jak to rozwiązać, ja nie mam kompletnie pomysłu a siedzę już któryś tydzień z tym Nelmio\ApiDocBundle\Annotation\Model

1

Nie wrzucaj screenow, tylko tekst.

Edit.
Wygląda to tak, jakby gdzieś był zwracany obiekt, a nie string.

3

Półżartem odpowiem: zostań kontrybutorem i zaimplementuj __toString() w klasie, która wyrzuca błąd.

Przy okazji prośba: możesz wkleić kod? Ze screena wynika, że use dla tej klasy jest nieużywany. U mnie w tym samym IDE use używany nie jest na szaro przy poprawnie zrobionej adnotacji.

I pytanie: na screenie są twoje dane osobowe. To celowe?

0

ja kiedys nie mialem zaktualizowanej paczki od google bucket i musilem sam napisac swoja wersje, wiec dasz rade

0
ccwrc napisał(a):

Półżartem odpowiem: zostań kontrybutorem i zaimplementuj __toString() w klasie, która wyrzuca błąd.

Przy okazji prośba: możesz wkleić kod? Ze screena wynika, że use dla tej klasy jest nieużywany. U mnie w tym samym IDE use używany nie jest na szaro przy poprawnie zrobionej adnotacji.

I pytanie: na screenie są twoje dane osobowe. To celowe?

Nie to nie moje dane osobowe, przejąłem projekt po jakiejś osobie i próbuję to ogarnąć

0

Okej teraz będą wklejał kod zamiast screenów.
Analizując dokładnie kod natrafiłem na to, że został napisany własny loader dla tych adnotacji z Nelmio\ApiDocBundle\Annotation\Model

<?php

declare(strict_types=1);

namespace App\UI\Api\Router;

use App\UI\Api\Router\Annotation\ApiActionRoute;
use App\UI\Api\Router\Annotation\ApiBulkActionRoute;
use App\UI\Api\Router\Annotation\ApiCreateRoute;
use App\UI\Api\Router\Annotation\ApiDeleteItemRoute;
use App\UI\Api\Router\Annotation\ApiDownloadItemRoute;
use App\UI\Api\Router\Annotation\ApiGetItemInfoRoute;
use App\UI\Api\Router\Annotation\ApiGetItemRoute;
use App\UI\Api\Router\Annotation\ApiListRoute;
use App\UI\Api\Router\Annotation\ApiRoute;
use App\UI\Api\Router\Annotation\ApiUpdateRoute;
use Doctrine\Common\Annotations\Reader;
use Doctrine\Inflector\Inflector;
use Doctrine\Inflector\InflectorFactory;
use Symfony\Component\Routing\Loader\AttributeClassLoader;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

class ApiRouteAnnotationLoader extends AttributeClassLoader
{
    private Inflector $inflector;

    public function __construct(Reader $reader = null)
    {
        $this->inflector = InflectorFactory::create()->build();
        parent::__construct($reader);
    }

    protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot): void
    {
        if ($annot instanceof ApiRoute) {
            $this->handle($route, $annot);
            $this->addDefaults($route, ['api_route' => get_class($annot)]);
        } 
    }

    private function handle(Route $route, ApiRoute $annot): void
    {
        $name = $this->prepareName($annot->getResourceClassShortName());

        switch (true) {
            case $annot instanceof ApiListRoute:
                $this->handleAnnot($route, $annot, "/{$name}", "api_{$name}", ['GET']);
                break;
            case $annot instanceof ApiGetItemRoute:
                $this->handleAnnot($route, $annot, "/{$name}/{id}", "api_{$name}_item", ['GET']);
                break;
            case $annot instanceof ApiGetItemInfoRoute:
                $infoName = $annot->getInfoName() ?? 'info';
                $this->handleAnnot($route, $annot, "/{$name}/{id}/{$infoName}", "api_{$name}_item_{$infoName}", ['GET']);
                break;
            case $annot instanceof ApiCreateRoute:
                $this->handleAnnot($route, $annot, "/{$name}", "api_{$name}_create", ['POST']);
                break;
            case $annot instanceof ApiDeleteItemRoute:
                $this->handleAnnot($route, $annot, "/{$name}/{id}", "api_{$name}_delete", ['DELETE']);
                break;
            case $annot instanceof ApiUpdateRoute:
                $this->handleAnnot($route, $annot, "/{$name}/{id}", "api_{$name}_update", ['PUT']);
                break;
            case $annot instanceof ApiActionRoute:
                $action = $this->prepareName($annot->getActionName(), false);
                $this->handleAnnot($route, $annot, "/{$name}/{id}/actions/{$action}", "api_{$name}_item_action_{$action}", ['POST']);
                break;
            case $annot instanceof ApiBulkActionRoute:
                $action = $this->prepareName($annot->getActionName(), false);
                $this->handleAnnot($route, $annot, "/{$name}/actions/{$action}", "api_{$name}_action_{$action}", ['POST']);
                break;
            case $annot instanceof ApiDownloadItemRoute:
                $this->handleAnnot($route, $annot, "/{$name}/{id}/download", "api_{$name}_download", ['GET']);
                break;
        }
    }

    private function handleAnnot(Route $route, ApiRoute $annot, string $path, string $name, array $methods): void
    {
        if (!$route->getPath()) {
            $route->setPath($path);
        }
        if (!$route->getName()) {
            $route->setDefault('_route', $name);
        }

        if (preg_match('#{id}#', $route->getPath())) {
            $route->setRequirement('id', '^[\w\-]+$');
        }

        if (empty($route->getMethods())) {
            $route->setMethods($methods);
        }
    }

    private function addDefaults(Route $route, array $defaults = []): void
    {
        $route->setDefaults(array_merge($route->getDefaults(), $defaults));
    }

    private function prepareName(string $name, bool $pluralize = true): string
    {
        $name = preg_replace_callback('#([A-Z])([A-Z]+)([A-Z]|$)#', fn($word) => $word[1] . strtolower($word[2]) . $word[3], $name);

        if ($pluralize) {
            $words = preg_split('/(?=[A-Z])/', $name);
            $lastWord = array_pop($words);
            $words[] = $this->inflector->pluralize($lastWord);
            $name = implode('', $words);
        }

        return $this->inflector->tableize($name);
    }
}


W services.yaml jest zarejestrowany ten loader, ale symfony 6.4 tak jak by go nie czytało, dałem dd('test') w configureRoute, i nie wypluwa w konsoli, na poprzedniej wersji projektu wypluwa

Tutaj rejestracja loadera w services.yaml

    # ApiRoute route generation
    routing.loader.annotation:
        class: App\UI\Api\Router\ApiRouteAnnotationLoader

Object of class Nelmio\ApiDocBundle\Annotation\Model could not be converted !! to string, jest spowodowane tym, że AttributeClassLoader otrzymuje w $path obiekt Nelmio, a nie ścieżke do wygenerowania
Tutaj kawałek kodu gdzie to pobiera, tego raczej nie ruszamy bo jest to paczka z vendora symfonowska, i trzeba jakoś uruchomić tem niestandardowy ApiRouteAnnotationLoader

$path = $annot->getLocalizedPaths() ?: $annot->getPath();
        $prefix = $globals['localized_paths'] ?: $globals['path'];
        $paths = [];

Przeglądałem dokumentację rejestracji niestandardowego loadera, ale na marne od razu leci domyślny AttributeClassLoader.

Wiem, że w nowszych wersjach symfony zalecane jest używanie atrybutów, ale stary projekt jest oparty na adnotacjach, rector zamienił mi tylko adnotacje na atrybuty w encjach, tam gdzie jest wykorzystywana paczka Nelmio jest już problem

0
Herdion napisał(a):
ccwrc napisał(a):

Półżartem odpowiem: zostań kontrybutorem i zaimplementuj __toString() w klasie, która wyrzuca błąd.

Przy okazji prośba: możesz wkleić kod? Ze screena wynika, że use dla tej klasy jest nieużywany. U mnie w tym samym IDE use używany nie jest na szaro przy poprawnie zrobionej adnotacji.

I pytanie: na screenie są twoje dane osobowe. To celowe?

Nie to nie moje dane osobowe, przejąłem projekt po jakiejś osobie i próbuję to ogarnąć

To tym bardziej wykasuj screeny z danymi osobowymi.

Wkleiłeś kod z namespace App\UI\Api\Router, klasa ApiRouteAnnotationLoader, ale nie wkleiłeś reszty dla tej przestrzeni nazw. Tam jest jeszcze 10 klas, które w pliku są jako brakujące use.

1 użytkowników online, w tym zalogowanych: 0, gości: 1