fsi-open / files

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Trouble setting up the project for Symfony

pawloaka opened this issue · comments

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
        }
    }
}

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.

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.

@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"?

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.

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"
    }
...

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)?

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! :)

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 :)

Resolved by #56