fsi-open / files

0 stars 2 forks source link

Trouble setting up the project for Symfony #39

Closed pawloaka closed 2 years ago

pawloaka commented 3 years ago

After going to the url of this controller:

<?php

declare(strict_types=1);

namespace App\Controller;

use FSi\Component\Files\Upload\FileFactory;
...

class StartController extends AbstractController
{
    private FileFactory $fileFactory;

    public function __construct(FileFactory $fileFactory)
    {
        $this->fileFactory = $fileFactory;
    }
    public function __invoke(ServerRequestInterface $request): Response
    {
        return $this->json([]);
    }

I am getting the following error:

The service "FSi\Component\Files\Integration\Symfony\Form\Transformer\PsrFileToWebFileTransformer" has a dependency on a non-existent service "FSi\Component\Files\Upload\FileFactory".

I am using Symfony 4.4 In the ./config directory I didn't change anything. So should I add some config for your bundle? May you help me to resolve the issue?

My composer.json looks like:

{
    "type": "project",
    "license": "proprietary",
    "require": {
        "php": "^7.4",
        "doctrine/orm": "^2.8",
        "friendsofsymfony/ckeditor-bundle": "^2.3",
        "fsi/files": "1.0.*",
        "nyholm/psr7": "^1.1",
        "sensio/framework-extra-bundle": "^5.1",
        "symfony/asset": "4.4.*",
        "symfony/console": "4.4.*",
        "symfony/doctrine-bridge": "^4.1",
        "symfony/dotenv": "4.4.*",
        "symfony/expression-language": "4.4.*",
        "symfony/flex": "^1.3.1",
        "symfony/form": "4.4.*",
        "symfony/framework-bundle": "4.4.*",
        "symfony/serializer": "4.4.*",
        "symfony/translation": "4.4.*",
        "symfony/twig-bundle": "^4.4",
        "symfony/validator": "4.4.*",
        "symfony/yaml": "4.4.*",
        "twig/extensions": "^1.5",
        "twig/extra-bundle": "^2.12|^3.0",
        "doctrine/annotations": "^1.0",
        "doctrine/doctrine-bundle": "^2.3",
        "doctrine/doctrine-fixtures-bundle": "^3.0",
        "doctrine/doctrine-migrations-bundle": "^3.1",
        "symfony/lock": "^4.1",
        "symfony/messenger": "^4.1",
        "symfony/monolog-bundle": "^3.1",
        "symfony/psr-http-message-bridge": "^1.0",
        "symfony/security-bundle": "4.4.*"
    },
    "require-dev": {
        "symfony/browser-kit": "^4.4",
        "symfony/css-selector": "^4.4",
        "symfony/debug-bundle": "^4.4",
        "symfony/maker-bundle": "^1.0",
        "symfony/phpunit-bridge": "^5.2",
        "symfony/web-profiler-bundle": "^4.4"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "ckeditor:install --clear=drop": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    },
    "extra": {
        "symfony": {
            "allow-contrib": false
        }
    }
}
szymach commented 3 years ago

Hello, make sure this line

...
FSi\Component\Files\Integration\Symfony\FilesBundle::class => ['all' => true],
...

is present in your config/bundles.php. If you added the package through composer require fsi/files it should have been added automatically.

szymach commented 3 years ago

Also, you will need to add additional configuration for the bundle and for any entity that you wish file be persisted for. For now we don't have a documentation, but you can refer to the test project configuration to get an idea how to do it (you need both oneup_flysystem and fsi_files sections. You can of course put it in a YAML file.

pawloaka commented 3 years ago

@szymach Thanks for your response, so I have added following configuration: config/packages/oneup_flysystem.yaml:

oneup_flysystem:
    adapters:
        local_adapter:
            local:
                directory: '%kernel.project_dir%/public/files'
    filesystems:
        public:
            adapter: local_adapter
            mount: 'public'

config/packages/fsi_files.yaml:

fsi_files:
    url_adapters:
        public: 'fsi_files.url_adapter.public'
    entities:
        App\Entity\User:
            filesystem: 'public'
            prefix: user
            fields: ['file']

And in config/services.yaml:

...
FSi\Component\Files\UrlAdapter\BaseUrlAdapter:
    arguments:
      $uriFactory: '@Psr\Http\Message\UriFactoryInterface'
      $baseUrl: '/files/'

  FSi\Tests\App\Http\UriFactory: ~

  fsi_files.url_adapter.public:
    class: FSi\Component\Files\UrlAdapter\BaseUrlAdapter
    arguments:
      $uriFactory: '@FSi\Tests\App\Http\UriFactory'
      $baseUrl: '/files/'
...

After going to the URL of StartController I get the following error:

Attempted to load class "UriFactory" from namespace "FSi\Tests\App\Http".
Did you forget a "use" statement for "Http\Message\UriFactory"?
szymach commented 3 years ago

FSi\Tests\App\Http\UriFactory is just a test class for our project, don't use it since it is not even loaded in the production class map. You need a class implementing Psr\Http\Message\UriInterface\UriFactory, like the one from nyholm/psr7. Just replace the typehint with @Psr\Http\Message\UriFactoryInterface and make sure you have services for nyholm configured like so:

# config/packages/nyholm_psr7.yaml
services:
    # Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories)
    Psr\Http\Message\RequestFactoryInterface: '@nyholm.psr7.psr17_factory'
    Psr\Http\Message\ResponseFactoryInterface: '@nyholm.psr7.psr17_factory'
    Psr\Http\Message\ServerRequestFactoryInterface: '@nyholm.psr7.psr17_factory'
    Psr\Http\Message\StreamFactoryInterface: '@nyholm.psr7.psr17_factory'
    Psr\Http\Message\UploadedFileFactoryInterface: '@nyholm.psr7.psr17_factory'
    Psr\Http\Message\UriFactoryInterface: '@nyholm.psr7.psr17_factory'

    # Register nyholm/psr7 services for autowiring with HTTPlug factories
    Http\Message\MessageFactory: '@nyholm.psr7.httplug_factory'
    Http\Message\RequestFactory: '@nyholm.psr7.httplug_factory'
    Http\Message\ResponseFactory: '@nyholm.psr7.httplug_factory'
    Http\Message\StreamFactory: '@nyholm.psr7.httplug_factory'
    Http\Message\UriFactory: '@nyholm.psr7.httplug_factory'

    Nyholm\Psr7\Factory\Psr17Factory: ~
    nyholm.psr7.psr17_factory:
        class: Nyholm\Psr7\Factory\Psr17Factory

    nyholm.psr7.httplug_factory:
        class: Nyholm\Psr7\Factory\HttplugFactory

You will also need guzzlehttp/psr7 to handle file streams. Unfortunately the PSR-7 packages are tricky and each has something missing, so we had to use both.

pawloaka commented 3 years ago

The file config/packages/nyholm_psr7.yaml in my project is the same as yours. I have changed config/services.yaml to:

  FSi\Component\Files\UrlAdapter\BaseUrlAdapter:
    arguments:
      $uriFactory: '@Psr\Http\Message\UriFactoryInterface'
      $baseUrl: '/files/'

  fsi_files.url_adapter.public:
    class: FSi\Component\Files\UrlAdapter\BaseUrlAdapter
    arguments:
      $uriFactory: '@Psr\Http\Message\UriFactoryInterface'
      $baseUrl: '/files/'

And now I am getting the following error:

The service "FSi\Component\Files\FileUrlResolver" has a dependency on a non-existent service "@nyholm.psr7.psr17_factory".

And here you have my updated composer.json file:

...
    "require": {
        "php": "^7.4",
        "doctrine/orm": "^2.8",
        "friendsofsymfony/ckeditor-bundle": "^2.3",
        "fsi/files": "1.0.*",
        "nyholm/psr7": "^1.1",
        "sensio/framework-extra-bundle": "^5.1",
        "symfony/asset": "4.4.*",
        "symfony/console": "4.4.*",
        "symfony/doctrine-bridge": "^4.1",
        "symfony/dotenv": "4.4.*",
        "symfony/expression-language": "4.4.*",
        "symfony/flex": "^1.3.1",
        "symfony/form": "4.4.*",
        "symfony/framework-bundle": "4.4.*",
        "symfony/serializer": "4.4.*",
        "symfony/translation": "4.4.*",
        "symfony/twig-bundle": "^4.4",
        "symfony/validator": "4.4.*",
        "symfony/yaml": "4.4.*",
        "twig/extensions": "^1.5",
        "twig/extra-bundle": "^2.12|^3.0",
        "doctrine/annotations": "^1.0",
        "doctrine/doctrine-bundle": "^2.3",
        "doctrine/doctrine-fixtures-bundle": "^3.0",
        "doctrine/doctrine-migrations-bundle": "^3.1",
        "symfony/lock": "^4.1",
        "symfony/messenger": "^4.1",
        "symfony/monolog-bundle": "^3.1",
        "symfony/psr-http-message-bridge": "^1.0",
        "symfony/security-bundle": "4.4.*",
        "guzzlehttp/psr7": "^1.5",
        "oneup/flysystem-bundle": "^3.0"
    }
...
szymach commented 3 years ago

Firstly, please try changing "fsi/files": "1.0.*" to "fsi/files": "^1.1". Secondly, you do not need two separate service definitions for the adapters,

  fsi_files.url_adapter.public:
    class: FSi\Component\Files\UrlAdapter\BaseUrlAdapter
    arguments:
      $uriFactory: '@Psr\Http\Message\UriFactoryInterface'
      $baseUrl: '/files/'

will suffice.

As for that error message, it is rather weird considering this class should never have a dependency on that service. Can you post your whole services.yaml and also make sure that the service nyholm.psr7.psr17_factory actually is registered in the container (bin/console debug:container nyholm.psr7.psr17_factory)?

pawloaka commented 3 years ago

nyholm.psr7.psr17_factory was not registered in the container, I have reinstalled the whole project and now it works fine. Thanks for the help! :)

szymach commented 3 years ago

I am glad it worked :) Still, I will be leaving this issue open for the time being, until we will create an actual documentation for the project. That way perhaps people will not open new ones until we do :)

szymach commented 2 years ago

Resolved by #56