dinandmentink / nova-markdown

Adds a markdown editor component to laravel nova.
MIT License
36 stars 4 forks source link

Target class [] does not exist thrown when trying to drag\drop the uploads #27

Closed sitefinitysteve closed 2 years ago

sitefinitysteve commented 2 years ago

I get this 500 when I drag\drop an image to upload into the editor

"message": "Target class [] does not exist.",
"exception": "Illuminate\\Contracts\\Container\\BindingResolutionException",

I can see the nova-markdown/uploads in the route list and afaik this is the only issue, it looks and works great

I do have spatie media setup as well for the site

Full Response

{
    "message": "Target class [] does not exist.",
    "exception": "Illuminate\\Contracts\\Container\\BindingResolutionException",
    "file": "/app/vendor/laravel/framework/src/Illuminate/Container/Container.php",
    "line": 877,
    "trace": [
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Container/Container.php",
            "line": 756,
            "function": "build",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php",
            "line": 855,
            "function": "resolve",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Container/Container.php",
            "line": 692,
            "function": "resolve",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php",
            "line": 840,
            "function": "make",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 169,
            "function": "make",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 726,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 703,
            "function": "runRouteWithinStack",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 667,
            "function": "runRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 656,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 167,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Illuminate\\Foundation\\Http\\{closure}",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/nova/src/Http/Middleware/ServeNova.php",
            "line": 23,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Laravel\\Nova\\Http\\Middleware\\ServeNova",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
            "line": 31,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
            "line": 40,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
            "line": 86,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php",
            "line": 49,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Http\\Middleware\\HandleCors",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php",
            "line": 39,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Http\\Middleware\\TrustProxies",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 142,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 111,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/app/public/index.php",
            "line": 52,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        }
    ]
}{
    "message": "Target class [] does not exist.",
    "exception": "Illuminate\\Contracts\\Container\\BindingResolutionException",
    "file": "/app/vendor/laravel/framework/src/Illuminate/Container/Container.php",
    "line": 877,
    "trace": [
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Container/Container.php",
            "line": 756,
            "function": "build",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php",
            "line": 855,
            "function": "resolve",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Container/Container.php",
            "line": 692,
            "function": "resolve",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php",
            "line": 840,
            "function": "make",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 206,
            "function": "make",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 180,
            "function": "terminateMiddleware",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/app/public/index.php",
            "line": 55,
            "function": "terminate",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        }
    ]
}

Here's the XHR payload after drop, all seems to be there...

_token: XXXXX
resourceName: blog-posts
resourceId: 1
image: (binary)
sitefinitysteve commented 2 years ago

If I edit your vendor routes.php and add in

           Route::get("upload-test", function() {
                return "cool";
            });

I get the exact same error

dinandmentink commented 2 years ago

I'll have a look next week but this may not be from nova-markdown.

What version of nova-markdown and laravel are you using? What's your config?

sitefinitysteve commented 2 years ago

Appreciate it, I've been trying to modify the vendor folder directly but I haven't figured it out yet... thats why I tried the simple GET route. It defiantly registers, that code for sure triggers, but I can't hit those routes without that error, and so the store method on the controller also doesn't get hit.

Googling, the "Target class does not exist" seems to show up in v8?

https://litvinjuan.medium.com/how-to-fix-target-class-does-not-exist-in-laravel-8-f9e28b79f8b4

    "require": {
        "php": "^8.0.2",
        "dinandmentink/nova-markdown": "^4.1",
        "ebess/advanced-nova-media-library": "^4.0",
        "guzzlehttp/guzzle": "^7.2",
        "inertiajs/inertia-laravel": "^0.5.2",
        "laravel/framework": "^9.11",
        "laravel/jetstream": "^2.8",
        "laravel/nova": "~4.0",
        "laravel/sanctum": "^2.14.1",
        "laravel/tinker": "^2.7",
        "mailchimp/marketing": "^3.0",
        "sendgrid/sendgrid": "^8.0",
        "spatie/laravel-medialibrary": "^10.0.0",
        "spatie/laravel-sitemap": "^6.2",
        "tightenco/ziggy": "^1.0"
    },
    "require-dev": {
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^6.1",
        "phpunit/phpunit": "^9.5.10",
        "spatie/laravel-ignition": "^1.0"
    },

Nothing crazy on the config, basically stock, no overrides in ENV

<?php

/**
 * Configuration for nova-markdown
 */

return [

    /**
     * Enable or disable uploads entirely
     */

    'uploads' => env("NOVA_MARKDOWN_UPLOADS", true),

    /**
     * Enable uploads by default.
     * Note, this has no effect up uploads are disabled entirely.
     */

    'uploads-default-enabled' => env("NOVA_MARKDOWN_UPLOADS_DEFAULT_ENABLED", true),

    /**
     * The path prefix that will be used by nova-markdown routes
     */

    'route-prefix' => env("NOVA_MARKDOWN_ROUTE_PREFIX", 'nova-markdown'),

    /**
     * The disk on which to store uploaded images, choose a disk as
     * configured in config/filesystems.php.
     */

    'disk' => env('MEDIA_DISK', 'public'),

    /**
     * The visibility option when storing uploaded images.
     *
     * Files may either be declared "public" or "private". When a file is declared
     * "public", you are indicating that the file should generally be accessible
     * to others.
     */

    'file-visibility' => env("NOVA_MARKDOWN_FILE_VISIBILITY", 'public'),

    /**
     * The directory where to place uploaded images within the disk.
     *
     * Can be a string with the directoryname. Alternatively, it's possible
     * to configure a function, which takes the uploading $user as argument and
     * returns the directory. This can be used to group uploads in a folder
     * by user.
     *
     * Example:
     * function($user) { return "uploads/" . \Str::slug($user->name); }
     */

    'directory' => env("NOVA_MARKDOWN_DIRECTORY", "uploads"),

    /**
     * The maximum size for uploaded images in kilobytes
     */

    'max-size' => env("NOVA_MARKDOWN_MAX_SIZE", 8 * 1024),

    /**
     * The maximum width for uploaded images in pixels.
     * Uploaded images will be scaled down to this width.
     * Use null to disable image scaling.
     */

    'max-width' => env("NOVA_MARKDOWN_MAX_WIDTH", 1920),

    /**
     * Uploaded images will be converted to this quality.
     * Integer between 0 and 100. Use null to disable quality adjustments.
     */

    'quality' => env("NOVA_MARKDOWN_QUALITY", 85),

    /**
     * Define the middleware stack to be used by nova-markdown routes.
     * A sensible default has been set.
     */

    'middleware' => config("nova.middleware"),

    /**
     * Uploaded images will be stored by default using a slug version of its
     * original filename. You can set this to true to use a random filename.
     */

    'random_filename' => env("NOVA_MARKDOWN_RANDOM_FILENAME", false),

];
sitefinitysteve commented 2 years ago

Ok I think I have it

This is returning null config("nova-markdown.middleware")

https://github.com/dinandmentink/nova-markdown/blob/main/src/routes.php#L7

If I comment out the line, the upload seems to work fine

if I

dd(config("nova-markdown.quality"));

I get "75" which is what I set in the nova-markdown config, it's different than the default so I know it's reading the config

But this guy...

dd(config("nova-markdown.middleware"));

Returns null

The line in the config is

    'middleware' => config("nova.middleware"),

...and if I dd(config("nova.middleware")) somewhere else directly I get the proper nova stack I would be expecting.

^ array:4 [▼
  0 => "web"
  1 => "Laravel\Nova\Http\Middleware\HandleInertiaRequests"
  2 => "Laravel\Nova\Http\Middleware\DispatchServingNovaEvent"
  3 => "Laravel\Nova\Http\Middleware\BootTools"
]

Is there a step I'm just missing somewhere maybe?

dinandmentink commented 2 years ago

Ah. This helps!

I can't deep dive now, but could it be you are caching your configuration? If you are caching your configuration then there should be no config items using dynamic things (like config() or function() {}).

sitefinitysteve commented 2 years ago

Here's the dump on just config()

image

I'm not INTENTIONALLY caching anything outside of what's stock on a Laravel\Jetstream\Nova project. I don't think it's cached, I can change the quality in your config and it's reflected in the dd instantly.

You can see the nova markdown config is weirdly null in there too

    'middleware' => config("nova.middleware"),
sitefinitysteve commented 2 years ago

I do have a hack I'm not proud of, but it's getting it working lol

    /**
     * Define the middleware stack to be used by nova-markdown routes.
     * A sensible default has been set.
     */

    'middleware' => [
        0 => "web",
        1 => "Laravel\Nova\Http\Middleware\HandleInertiaRequests",
        2 => "Laravel\Nova\Http\Middleware\DispatchServingNovaEvent",
        3 => "Laravel\Nova\Http\Middleware\BootTools"
      ],

Hardcoded it based on what the config() said was in for novas middleware, this is so error prone going forward, but it gets me forward eh!

sitefinitysteve commented 2 years ago

Nooope, php artisan config:clear, bloody hell

dinandmentink commented 2 years ago

Good to see you figured it out!

Some notes.

  1. I'll make a note of laravel caching of the config in the readme.
  2. If you do want/need to cache the config you could, I believe, simply leave these config items out. Internally they'll default anyway. There may be other packages however that also don't play well with config caching (spatie/media-library if I recall correctly for example).