Browse Source

Update web routes

Daniel Supernault 7 years ago
parent
commit
f4f7909a06

+ 84 - 1
app/Http/Controllers/AvatarController.php

@@ -3,8 +3,91 @@
 namespace App\Http\Controllers;
 namespace App\Http\Controllers;
 
 
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
+use Auth, Log, Storage;
+use App\Avatar;
+use App\Jobs\AvatarPipeline\AvatarOptimize;
 
 
 class AvatarController extends Controller
 class AvatarController extends Controller
 {
 {
-    //
+    public function __construct()
+    {
+        return $this->middleware('auth');
+    }
+
+    public function store(Request $request)
+    {
+        $this->validate($request, [
+          'avatar' => 'required|mimes:jpeg,png|max:1000'
+        ]);
+        try {
+          $user = Auth::user();
+          $file = $request->file('avatar');
+          $path = $this->getPath($user, $file);
+          $dir = $path['root'];
+          $name = $path['name'];
+          $public = $path['storage'];
+          $currentAvatar = storage_path('app/'.$user->profile->avatar->media_path);
+          $loc = $request->file('avatar')->storeAs($public, $name);
+
+          $avatar = Avatar::whereProfileId($user->profile->id)->firstOrFail();
+          $opath = $avatar->media_path;
+          $avatar->media_path = "$public/$name";
+          $avatar->thumb_path = null;
+          $avatar->change_count = ++$avatar->change_count;
+          $avatar->last_processed_at = null;
+          $avatar->save();
+
+          AvatarOptimize::dispatch($user->profile, $currentAvatar);
+        } catch (Exception $e) {
+        }
+        return redirect()->back()->with('status', 'Avatar updated successfully. It may take a few minutes to update across the site.');
+    }
+
+    public function getPath($user, $file)
+    {
+        $basePath = storage_path('app/public/avatars');
+        $this->checkDir($basePath);
+
+        $id = $user->profile->id;
+        $path = $this->buildPath($id);
+        $dir = storage_path('app/'.$path);
+        $this->checkDir($dir);
+        $name = 'avatar.' . $file->guessExtension();
+        $res = ['root' => 'storage/app/' . $path, 'name' => $name, 'storage' => $path];
+
+        return $res;
+    }
+
+    public function checkDir($path)
+    {
+        if(!is_dir($path)) {
+            mkdir($path);
+        }
+    }
+
+    public function buildPath($id)
+    {
+        $padded = str_pad($id, 12, 0, STR_PAD_LEFT);
+        $parts = str_split($padded, 3);
+        foreach($parts as $k => $part) {
+          if($k == 0) {
+              $prefix = storage_path('app/public/avatars/'.$parts[0]);
+              $this->checkDir($prefix);
+          }
+          if($k == 1) {
+              $prefix = storage_path('app/public/avatars/'.$parts[0].'/'.$parts[1]);
+              $this->checkDir($prefix);
+          }
+          if($k == 2) {
+              $prefix = storage_path('app/public/avatars/'.$parts[0].'/'.$parts[1].'/'.$parts[2]);
+              $this->checkDir($prefix);
+          }
+          if($k == 3) {
+              $avatarpath = 'public/avatars/'.$parts[0].'/'.$parts[1].'/'.$parts[2].'/'.$parts[3];
+              $prefix = storage_path('app/'.$avatarpath);
+              $this->checkDir($prefix);
+          }
+        }
+        return $avatarpath;
+    }
 }
 }

+ 70 - 0
app/Jobs/AvatarPipeline/AvatarOptimize.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Jobs\AvatarPipeline;
+
+use \Carbon\Carbon;
+use Image as Intervention;
+use App\{Avatar, Profile};
+use Illuminate\Bus\Queueable;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+
+class AvatarOptimize implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    protected $profile;
+    protected $current;
+
+    /**
+     * Create a new job instance.
+     *
+     * @return void
+     */
+    public function __construct(Profile $profile, $current)
+    {
+        $this->profile = $profile;
+        $this->current = $current;
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $avatar = $this->profile->avatar;
+        $file = storage_path("app/$avatar->media_path");
+
+        try {
+            $img = Intervention::make($file)->orientate();
+            $img->fit(200, 200, function ($constraint) {
+                $constraint->upsize();
+            });
+            $quality = config('pixelfed.image_quality');
+            $img->save($file, $quality);
+
+            $avatar = Avatar::whereProfileId($this->profile->id)->firstOrFail();
+            $avatar->thumb_path = $avatar->media_path;
+            $avatar->change_count = ++$avatar->change_count;
+            $avatar->last_processed_at = Carbon::now();
+            $avatar->save();
+            $this->deleteOldAvatar($avatar->media_path, $this->current);
+        } catch (Exception $e) {
+            
+        }
+    }
+
+    protected function deleteOldAvatar($new, $current)
+    {
+        if(storage_path('app/' . $new) == $current) {
+            return;
+        }
+        if(is_file($current)) {
+            @unlink($current);
+        }
+    }
+}

+ 35 - 2
resources/views/settings/avatar.blade.php

@@ -6,8 +6,41 @@
     <h3 class="font-weight-bold">Avatar Settings</h3>
     <h3 class="font-weight-bold">Avatar Settings</h3>
   </div>
   </div>
   <hr>
   <hr>
-  <div class="alert alert-danger">
-    Coming Soon
+  <div class="row mt-3">
+    
+    <div class="col-12 col-md-4">
+      <p class="font-weight-bold text-center">Current Avatar</p>
+      <img src="{{Auth::user()->profile->avatarUrl()}}" class="img-thumbnail rounded-circle">
+    </div>
+    <div class="col-12 col-md-7 offset-md-1">
+      <div class="card">
+        <div class="card-header font-weight-bold bg-white">Update Avatar</div>
+        <div class="card-body">
+        <form method="post" enctype="multipart/form-data">
+          @csrf
+          <div class="form-group">
+            <div class="custom-file">
+              <input type="file" class="custom-file-input" id="fileInput" name="avatar" accept="image/*">
+              <label class="custom-file-label" for="fileInput">Upload New Avatar</label>
+            </div>
+            <small class="form-text text-muted">
+              Max Size: 1 MB. Supported formats: jpeg, png.
+            </small>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="col-12 mt-5 pt-5">
+      <hr>
+      <div class="form-group row">
+        <div class="col-12 text-right">
+          {{-- <a class="btn btn-secondary font-weight-bold py-1" href="#">Restore Default Avatar</a> --}}
+          <button type="submit" class="btn btn-primary font-weight-bold py-1">Submit</button>
+        </div>
+      </div>
+    </div>
+    </form>
+
   </div>
   </div>
 
 
 @endsection
 @endsection

+ 1 - 0
routes/web.php

@@ -85,6 +85,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware('validemail')->group(fu
     Route::get('home', 'SettingsController@home')->name('settings');
     Route::get('home', 'SettingsController@home')->name('settings');
     Route::post('home', 'SettingsController@homeUpdate');
     Route::post('home', 'SettingsController@homeUpdate');
     Route::get('avatar', 'SettingsController@avatar')->name('settings.avatar');
     Route::get('avatar', 'SettingsController@avatar')->name('settings.avatar');
+    Route::post('avatar', 'AvatarController@store');
     Route::get('password', 'SettingsController@password')->name('settings.password');
     Route::get('password', 'SettingsController@password')->name('settings.password');
     Route::post('password', 'SettingsController@passwordUpdate');
     Route::post('password', 'SettingsController@passwordUpdate');
     Route::get('email', 'SettingsController@email')->name('settings.email');
     Route::get('email', 'SettingsController@email')->name('settings.email');