0

I've read this cuestion with a similar problem: Laravel 8 Jetstream profile-photos not showing

However, I'm using now Laravel 9 instead of 8.

The issue is this one:

When I run my app using: 'php artisan serve', and I access my app with the URL: http://localhost:8000/, I can load my profile photo without any problem.

However, when I try to access it using Apache server, using the URL: http://localhost/infoalq_jetstream/public/, it does nothing at all, not even loading anything in the database. In my table 'users', the field 'profile_photo_path' stays 'NULL'.

I've already have a shorcut in 'public' folder to 'storage'. In fact, when I've tried to do 'php artisan storage:link', I got: ' ERROR The [public/storage] link already exists. '. I've checked in the file explorer, and the shorcut actually exists.

I've followed the steps of this video (in spanish): https://www.youtube.com/watch?v=v-R5FLGAB58&list=PLZ2ovOgdI-kWWS9aq8mfUDkJRfYib-SvF&index=30

Here's my ".env":

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:N+QlCYsU2lDVNWiJ+KEP+QraqWsDbar7eLWwtJa+M3s=
APP_DEBUG=true
APP_URL=http://localhost/infoalq_jetstream/public/

LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=jetstream
DB_USERNAME=root
DB_PASSWORD=root

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=database
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=0a3a3bb4fcb540
MAIL_PASSWORD=7a9e2495cc9668
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="leandro@caplan.com"
MAIL_FROM_NAME="Leandro Caplan"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1

VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

I've tried to leave the field APP_URL empty, to assign it the value 'http://localhost', and after that, the value I'm showing here.

Here's my "jetstream.php":

<?php

use Laravel\Jetstream\Features;
use Laravel\Jetstream\Http\Middleware\AuthenticateSession;

return [

    /*
    |--------------------------------------------------------------------------
    | Jetstream Stack
    |--------------------------------------------------------------------------
    |
    | This configuration value informs Jetstream which "stack" you will be
    | using for your application. In general, this value is set for you
    | during installation and will not need to be changed after that.
    |
    */

    'stack' => 'livewire',

    /*
     |--------------------------------------------------------------------------
     | Jetstream Route Middleware
     |--------------------------------------------------------------------------
     |
     | Here you may specify which middleware Jetstream will assign to the routes
     | that it registers with the application. When necessary, you may modify
     | these middleware; however, this default value is usually sufficient.
     |
     */

    'middleware' => ['web'],

    'auth_session' => AuthenticateSession::class,

    /*
    |--------------------------------------------------------------------------
    | Jetstream Guard
    |--------------------------------------------------------------------------
    |
    | Here you may specify the authentication guard Jetstream will use while
    | authenticating users. This value should correspond with one of your
    | guards that is already present in your "auth" configuration file.
    |
    */

    'guard' => 'sanctum',

    /*
    |--------------------------------------------------------------------------
    | Features
    |--------------------------------------------------------------------------
    |
    | Some of Jetstream's features are optional. You may disable the features
    | by removing them from this array. You're free to only remove some of
    | these features or you can even remove all of these if you need to.
    |
    */

    'features' => [
        // Features::termsAndPrivacyPolicy(),
        Features::profilePhotos(),
        // Features::api(),
        // Features::teams(['invitations' => true]),
        Features::accountDeletion(),
    ],

    /*
    |--------------------------------------------------------------------------
    | Profile Photo Disk
    |--------------------------------------------------------------------------
    |
    | This configuration value determines the default disk that will be used
    | when storing profile photos for your application's users. Typically
    | this will be the "public" disk but you may adjust this if needed.
    |
    */

    'profile_photo_disk' => 'public',

];

Finally, here's my "filesystems.php":

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Filesystem Disk
    |--------------------------------------------------------------------------
    |
    | Here you may specify the default filesystem disk that should be used
    | by the framework. The "local" disk, as well as a variety of cloud
    | based disks are available to your application. Just store away!
    |
    */

    'default' => env('FILESYSTEM_DISK', 'local'),

    /*
    |--------------------------------------------------------------------------
    | Filesystem Disks
    |--------------------------------------------------------------------------
    |
    | Here you may configure as many filesystem "disks" as you wish, and you
    | may even configure multiple disks of the same driver. Defaults have
    | been set up for each driver as an example of the required values.
    |
    | Supported Drivers: "local", "ftp", "sftp", "s3"
    |
    */

    'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
            'throw' => false,
        ],

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
            'throw' => false,
        ],

        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
            'endpoint' => env('AWS_ENDPOINT'),
            'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
            'throw' => false,
        ],

    ],

    /*
    |--------------------------------------------------------------------------
    | Symbolic Links
    |--------------------------------------------------------------------------
    |
    | Here you may configure the symbolic links that will be created when the
    | `storage:link` Artisan command is executed. The array keys should be
    | the locations of the links and the values should be their targets.
    |
    */

    'links' => [
        public_path('storage') => storage_path('app/public'),
    ],

];

I'm using:

  • Linux Mint 21 Vanessa

  • Apache/2.4.52 (Ubuntu)

  • PHP 8.2.1

  • Laravel v9.48.0

Does anyone got an idea of what's going wrong? If there's any more information needed, please let me know.

Thanks a lot!

1 Answers1

0

I've solved this issue by tracking my code, following the routes which came with Jetstream, and looking the database current state with phpMyAdmin. Running 'php artisan route:list', also hepled a lot for doing the mentioned tracking.

First of all, I've upgraded from Jetstream 2 to Jetstream 3. That it wasn't the solution, but it was something I should have tried, and I think it also wasn't a bad idea.

Then, I saw that in the navigation menu ("\resources\views\navigation-menu.blade.php"), I had a link to a route named 'profile.show'. After running 'php artisan route:list', I've found that route defined like this:

'GET|HEAD user/profile ...................................... profile.show › Laravel\Jetstream › UserProfileController@show'

So then, in this Laracasts post I've found where could I locate the controller 'UserProfileController.php': https://laracasts.com/discuss/channels/laravel/customize-userprofile-jetstream

The answer it was like this (In Jetstream 3 with LiveWire): "\vendor\laravel\jetstream\src\Http\Controllers\Livewire\UserProfileController.php"

By following the link with VS Code, I've found the correspondent view at: "\resources\views\profile\show.blade.php"

In that file, I've found the line which shows me the component used for updating the profile information section (which includes the profile photo). '@livewire('profile.update-profile-information-form')'

So then, that component is coded into: "\resources\views\profile\update-profile-information-form.blade.php"

Until that moment, when I loaded a new photo, it displayed me instead a text with my whole name in the place, into the circle where the photo should be displayed.

When I clicked the 'Remove Photo' button, it showed me again a circle with the initial letters of my name.

After that, I've looked my content of the database via phpMyAdmin. I found that when the field 'profile_photo_path' was NULL, the page displayed a circle with my initial letters (LC), but when it had some path value in it (for example: "profile-photos/zBvkWHK4J6WLBwZVsG12Gm50KboVjyBZaCTL2H16.png"), the page displayed my whole name.

So then, I thought it was a good idea to see the HTML source returned into my navigator. I've found then, that the path at my database was related with the APP_URL I had defined in my '.env'.

For example, if that path was 'http://localhost:8000', the path of the image was: "http://localhost:8000/storage/profile-photos/wKLYv80Ykd05RyRqdYJ7WZ4TprYHSqZ0ZzBbJxzL.png"

Then, I've realized of two things. The first one, it was the reason why the app behaved different with PHP server than with Apache server, since only one of those had the correspondent URL associated in my '.env'. I could solve this easily, by configurating my '.env' according to the URL used in my Apache VirtualHost.

The second one, was that Jetstream didn't store the original path, in this case at my HDD drive, where I had the image, but made a copy of the image into some of the project folders instead.

By copying the URL which was on the HTML returned by the server into the address bar in the browser, I had a 404 error.

I've found a solution for that error in this stackOverflow post:

Laravel 5.6 storage link already exists but i am getting 404 error when trying to get a file from the public folder

In fact, when I looked into: "/storage/app/public/profile-photos", I've found the correspondent image loaded. However, when I went to "/public/storage/profile-photos", I didn't found a shortcut at all.

I've followed the steps showed in that post, by running:

'rm -rf public/storage' 'php artisan storage:link'

After that, everything worked like a charm. I think that at certain moment, I've made something that corrupted that link. However, after running those commands, it was solved.

  • @PovilasKorop You were right. It was needed to do what you suggested. However, the problem I had in the moment I published the question was related to the '.env' APP_URL issue. But later, removing and linking the folder again was also needed. – Leandro Caplan Mar 07 '23 at 20:30