Added custom user avatars
This commit is contained in:
		
							parent
							
								
									db3acabc66
								
							
						
					
					
						commit
						8f7c642f32
					
				| 
						 | 
					@ -33,6 +33,9 @@ GOOGLE_APP_SECRET=false
 | 
				
			||||||
# URL used for social login redirects, NO TRAILING SLASH
 | 
					# URL used for social login redirects, NO TRAILING SLASH
 | 
				
			||||||
APP_URL=http://bookstack.dev
 | 
					APP_URL=http://bookstack.dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# External services
 | 
				
			||||||
 | 
					USE_GRAVATAR=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Mail settings
 | 
					# Mail settings
 | 
				
			||||||
MAIL_DRIVER=smtp
 | 
					MAIL_DRIVER=smtp
 | 
				
			||||||
MAIL_HOST=localhost
 | 
					MAIL_HOST=localhost
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ class ImageController extends Controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get all gallery images, Paginated
 | 
					     * Get all images for a specific type, Paginated
 | 
				
			||||||
     * @param int $page
 | 
					     * @param int $page
 | 
				
			||||||
     * @return \Illuminate\Http\JsonResponse
 | 
					     * @return \Illuminate\Http\JsonResponse
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
| 
						 | 
					@ -43,6 +43,17 @@ class ImageController extends Controller
 | 
				
			||||||
        return response()->json($imgData);
 | 
					        return response()->json($imgData);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get all images for a user.
 | 
				
			||||||
 | 
					     * @param int $page
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\JsonResponse
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getAllForUserType($page = 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $imgData = $this->imageRepo->getPaginatedByType('user', $page, 24, $this->currentUser->id);
 | 
				
			||||||
 | 
					        return response()->json($imgData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Handles image uploads for use on pages.
 | 
					     * Handles image uploads for use on pages.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ class UserController extends Controller
 | 
				
			||||||
        $this->checkPermission('user-create');
 | 
					        $this->checkPermission('user-create');
 | 
				
			||||||
        $this->validate($request, [
 | 
					        $this->validate($request, [
 | 
				
			||||||
            'name'             => 'required',
 | 
					            'name'             => 'required',
 | 
				
			||||||
            'email'            => 'required|email',
 | 
					            'email'            => 'required|email|unique:users,email',
 | 
				
			||||||
            'password'         => 'required|min:5',
 | 
					            'password'         => 'required|min:5',
 | 
				
			||||||
            'password-confirm' => 'required|same:password',
 | 
					            'password-confirm' => 'required|same:password',
 | 
				
			||||||
            'role'             => 'required|exists:roles,id'
 | 
					            'role'             => 'required|exists:roles,id'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,6 +57,9 @@ Route::group(['middleware' => 'auth'], function () {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Image routes
 | 
					    // Image routes
 | 
				
			||||||
    Route::group(['prefix' => 'images'], function() {
 | 
					    Route::group(['prefix' => 'images'], function() {
 | 
				
			||||||
 | 
					        // Get for user images
 | 
				
			||||||
 | 
					        Route::get('/user/all', 'ImageController@getAllForUserType');
 | 
				
			||||||
 | 
					        Route::get('/user/all/{page}', 'ImageController@getAllForUserType');
 | 
				
			||||||
        // Standard get, update and deletion for all types
 | 
					        // Standard get, update and deletion for all types
 | 
				
			||||||
        Route::get('/thumb/{id}/{width}/{height}/{crop}', 'ImageController@getThumbnail');
 | 
					        Route::get('/thumb/{id}/{width}/{height}/{crop}', 'ImageController@getThumbnail');
 | 
				
			||||||
        Route::put('/update/{imageId}', 'ImageController@update');
 | 
					        Route::put('/update/{imageId}', 'ImageController@update');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,10 @@
 | 
				
			||||||
namespace BookStack;
 | 
					namespace BookStack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
use Images;
 | 
					use Images;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Image
 | 
					class Image extends Model
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use Ownable;
 | 
					    use Ownable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,9 +17,10 @@ class Image
 | 
				
			||||||
     * @param  int       $width
 | 
					     * @param  int       $width
 | 
				
			||||||
     * @param  int       $height
 | 
					     * @param  int       $height
 | 
				
			||||||
     * @param bool|false $hardCrop
 | 
					     * @param bool|false $hardCrop
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function getThumb($width, $height, $hardCrop = false)
 | 
					    public function getThumb($width, $height, $hardCrop = false)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Images::getThumbnail($this, $width, $height, $hardCrop);
 | 
					        return Images::getThumbnail($this, $width, $height, $hardCrop);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,12 +40,18 @@ class ImageRepo
 | 
				
			||||||
     * @param string $type
 | 
					     * @param string $type
 | 
				
			||||||
     * @param int    $page
 | 
					     * @param int    $page
 | 
				
			||||||
     * @param int    $pageSize
 | 
					     * @param int    $pageSize
 | 
				
			||||||
 | 
					     * @param bool|int   $userFilter
 | 
				
			||||||
     * @return array
 | 
					     * @return array
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function getPaginatedByType($type, $page = 0, $pageSize = 24)
 | 
					    public function getPaginatedByType($type, $page = 0, $pageSize = 24, $userFilter = false)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $images = $this->image->where('type', '=', strtolower($type))
 | 
					        $images = $this->image->where('type', '=', strtolower($type));
 | 
				
			||||||
            ->orderBy('created_at', 'desc')->skip($pageSize * $page)->take($pageSize + 1)->get();
 | 
					
 | 
				
			||||||
 | 
					        if ($userFilter !== false) {
 | 
				
			||||||
 | 
					            $images = $images->where('created_by', '=', $userFilter);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $images = $images->orderBy('created_at', 'desc')->skip($pageSize * $page)->take($pageSize + 1)->get();
 | 
				
			||||||
        $hasMore = count($images) > $pageSize;
 | 
					        $hasMore = count($images) > $pageSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $returnImages = $images->take(24);
 | 
					        $returnImages = $images->take(24);
 | 
				
			||||||
| 
						 | 
					@ -67,7 +73,7 @@ class ImageRepo
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function saveNew(UploadedFile $uploadFile, $type)
 | 
					    public function saveNew(UploadedFile $uploadFile, $type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $image = $this->imageService->saveNew($this->image, $uploadFile, $type);
 | 
					        $image = $this->imageService->saveNewFromUpload($uploadFile, $type);
 | 
				
			||||||
        $this->loadThumbs($image);
 | 
					        $this->loadThumbs($image);
 | 
				
			||||||
        return $image;
 | 
					        return $image;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
<?php namespace BookStack\Services;
 | 
					<?php namespace BookStack\Services;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Image;
 | 
					use BookStack\Image;
 | 
				
			||||||
 | 
					use BookStack\User;
 | 
				
			||||||
use Intervention\Image\ImageManager;
 | 
					use Intervention\Image\ImageManager;
 | 
				
			||||||
use Illuminate\Contracts\Filesystem\Factory as FileSystem;
 | 
					use Illuminate\Contracts\Filesystem\Factory as FileSystem;
 | 
				
			||||||
use Illuminate\Contracts\Filesystem\Filesystem as FileSystemInstance;
 | 
					use Illuminate\Contracts\Filesystem\Filesystem as FileSystemInstance;
 | 
				
			||||||
| 
						 | 
					@ -34,11 +35,48 @@ class ImageService
 | 
				
			||||||
        $this->cache = $cache;
 | 
					        $this->cache = $cache;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function saveNew(Image $image, UploadedFile $uploadedFile, $type)
 | 
					    /**
 | 
				
			||||||
 | 
					     * Saves a new image from an upload.
 | 
				
			||||||
 | 
					     * @param UploadedFile $uploadedFile
 | 
				
			||||||
 | 
					     * @param  string      $type
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function saveNewFromUpload(UploadedFile $uploadedFile, $type)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $imageName = $uploadedFile->getClientOriginalName();
 | 
				
			||||||
 | 
					        $imageData = file_get_contents($uploadedFile->getRealPath());
 | 
				
			||||||
 | 
					        return $this->saveNew($imageName, $imageData, $type);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets an image from url and saves it to the database.
 | 
				
			||||||
 | 
					     * @param             $url
 | 
				
			||||||
 | 
					     * @param string      $type
 | 
				
			||||||
 | 
					     * @param bool|string $imageName
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     * @throws \Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function saveNewFromUrl($url, $type, $imageName = false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $imageName = $imageName ? $imageName : basename($url);
 | 
				
			||||||
 | 
					        $imageData = file_get_contents($url);
 | 
				
			||||||
 | 
					        if($imageData === false) throw new \Exception('Cannot get image from ' . $url);
 | 
				
			||||||
 | 
					        return $this->saveNew($imageName, $imageData, $type);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Saves a new image
 | 
				
			||||||
 | 
					     * @param string $imageName
 | 
				
			||||||
 | 
					     * @param string $imageData
 | 
				
			||||||
 | 
					     * @param string $type
 | 
				
			||||||
 | 
					     * @return Image
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function saveNew($imageName, $imageData, $type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $storage = $this->getStorage();
 | 
					        $storage = $this->getStorage();
 | 
				
			||||||
        $secureUploads = Setting::get('app-secure-images');
 | 
					        $secureUploads = Setting::get('app-secure-images');
 | 
				
			||||||
        $imageName = str_replace(' ', '-', $uploadedFile->getClientOriginalName());
 | 
					        $imageName = str_replace(' ', '-', $imageName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($secureUploads) $imageName = str_random(16) . '-' . $imageName;
 | 
					        if ($secureUploads) $imageName = str_random(16) . '-' . $imageName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,10 +86,10 @@ class ImageService
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $fullPath = $imagePath . $imageName;
 | 
					        $fullPath = $imagePath . $imageName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $storage->put($fullPath, file_get_contents($uploadedFile->getRealPath()));
 | 
					        $storage->put($fullPath, $imageData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $userId = auth()->user()->id;
 | 
					        $userId = auth()->user()->id;
 | 
				
			||||||
        $image = $image->forceCreate([
 | 
					        $image = Image::forceCreate([
 | 
				
			||||||
            'name'       => $imageName,
 | 
					            'name'       => $imageName,
 | 
				
			||||||
            'path'       => $fullPath,
 | 
					            'path'       => $fullPath,
 | 
				
			||||||
            'url'        => $this->getPublicUrl($fullPath),
 | 
					            'url'        => $this->getPublicUrl($fullPath),
 | 
				
			||||||
| 
						 | 
					@ -137,6 +175,26 @@ class ImageService
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Save a gravatar image and set a the profile image for a user.
 | 
				
			||||||
 | 
					     * @param User $user
 | 
				
			||||||
 | 
					     * @param int  $size
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function saveUserGravatar(User $user, $size = 500)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!env('USE_GRAVATAR', false)) return false;
 | 
				
			||||||
 | 
					        $emailHash = md5(strtolower(trim($user->email)));
 | 
				
			||||||
 | 
					        $url = 'http://www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon';
 | 
				
			||||||
 | 
					        $imageName = str_replace(' ', '-', $user->name . '-gravatar.png');
 | 
				
			||||||
 | 
					        $image = $this->saveNewFromUrl($url, 'user', $imageName);
 | 
				
			||||||
 | 
					        $image->created_by = $user->id;
 | 
				
			||||||
 | 
					        $image->save();
 | 
				
			||||||
 | 
					        $user->avatar()->associate($image);
 | 
				
			||||||
 | 
					        $user->save();
 | 
				
			||||||
 | 
					        return $image;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get the storage that will be used for storing images.
 | 
					     * Get the storage that will be used for storing images.
 | 
				
			||||||
     * @return FileSystemInstance
 | 
					     * @return FileSystemInstance
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								app/User.php
								
								
								
								
							
							
						
						
									
										15
									
								
								app/User.php
								
								
								
								
							| 
						 | 
					@ -24,7 +24,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @var array
 | 
					     * @var array
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected $fillable = ['name', 'email', 'password'];
 | 
					    protected $fillable = ['name', 'email', 'password', 'image_id'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The attributes excluded from the model's JSON form.
 | 
					     * The attributes excluded from the model's JSON form.
 | 
				
			||||||
| 
						 | 
					@ -145,8 +145,17 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function getAvatar($size = 50)
 | 
					    public function getAvatar($size = 50)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $emailHash = md5(strtolower(trim($this->email)));
 | 
					        if ($this->image_id === 0 || $this->image_id === null) return '/user_avatar.png';
 | 
				
			||||||
        return '//www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon';
 | 
					        return $this->avatar->getThumb($size, $size, true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the avatar for the user.
 | 
				
			||||||
 | 
					     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function avatar()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->belongsTo('BookStack\Image', 'image_id');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Database\Schema\Blueprint;
 | 
				
			||||||
 | 
					use Illuminate\Database\Migrations\Migration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AddUserAvatars extends Migration
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Run the migrations.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function up()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::table('users', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->integer('image_id')->default(0);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reverse the migrations.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function down()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::table('users', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->dropColumn('image_id');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 7.2 KiB  | 
| 
						 | 
					@ -80,15 +80,6 @@
 | 
				
			||||||
            imageType: {
 | 
					            imageType: {
 | 
				
			||||||
                type: String,
 | 
					                type: String,
 | 
				
			||||||
                required: true
 | 
					                required: true
 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            resizeWidth: {
 | 
					 | 
				
			||||||
                type: String
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            resizeHeight: {
 | 
					 | 
				
			||||||
                type: String
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            resizeCrop: {
 | 
					 | 
				
			||||||
                type: Boolean
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,21 +128,7 @@
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            returnCallback: function (image) {
 | 
					            returnCallback: function (image) {
 | 
				
			||||||
                var _this = this;
 | 
					                this.callback(image);
 | 
				
			||||||
                var isResized = _this.resizeWidth && _this.resizeHeight;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (!isResized) {
 | 
					 | 
				
			||||||
                    _this.callback(image);
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                var cropped = _this.resizeCrop ? 'true' : 'false';
 | 
					 | 
				
			||||||
                var requestString = '/images/thumb/' + image.id + '/' + _this.resizeWidth + '/' + _this.resizeHeight + '/' + cropped;
 | 
					 | 
				
			||||||
                _this.$http.get(requestString, function(data) {
 | 
					 | 
				
			||||||
                    image.thumbs.custom = data.url;
 | 
					 | 
				
			||||||
                    _this.callback(image);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            imageClick: function (image) {
 | 
					            imageClick: function (image) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,31 +7,89 @@
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <button class="button" type="button" @click="showImageManager">Select Image</button>
 | 
					        <button class="button" type="button" @click="showImageManager">Select Image</button>
 | 
				
			||||||
        <br>
 | 
					        <br>
 | 
				
			||||||
        <button class="text-button" @click="reset" type="button">Reset</button> <span class="sep">|</span> <button class="text-button neg" v-on:click="remove" type="button">Remove</button>
 | 
					        <button class="text-button" @click="reset" type="button">Reset</button> <span v-show="showRemove" class="sep">|</span> <button v-show="showRemove" class="text-button neg" @click="remove" type="button">Remove</button>
 | 
				
			||||||
        <input type="hidden" :name="name" :id="name" v-model="image">
 | 
					        <input type="hidden" :name="name" :id="name" v-model="value">
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
    module.exports = {
 | 
					    module.exports = {
 | 
				
			||||||
        props: ['currentImage', 'name', 'imageClass', 'defaultImage'],
 | 
					        props: {
 | 
				
			||||||
        data: function() {
 | 
					            currentImage: {
 | 
				
			||||||
            return {
 | 
					                required: true,
 | 
				
			||||||
                image: this.currentImage
 | 
					                type: String
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            currentId: {
 | 
				
			||||||
 | 
					                required: false,
 | 
				
			||||||
 | 
					                default: 'false',
 | 
				
			||||||
 | 
					                type: String
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            name: {
 | 
				
			||||||
 | 
					                required: true,
 | 
				
			||||||
 | 
					                type: String
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            defaultImage: {
 | 
				
			||||||
 | 
					                required: true,
 | 
				
			||||||
 | 
					                type: String
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            imageClass: {
 | 
				
			||||||
 | 
					                required: true,
 | 
				
			||||||
 | 
					                type: String
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            resizeWidth: {
 | 
				
			||||||
 | 
					                type: String
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            resizeHeight: {
 | 
				
			||||||
 | 
					                type: String
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            resizeCrop: {
 | 
				
			||||||
 | 
					                type: Boolean
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            showRemove: {
 | 
				
			||||||
 | 
					                type: Boolean,
 | 
				
			||||||
 | 
					                default: 'true'
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        data: function() {
 | 
				
			||||||
 | 
					            return {
 | 
				
			||||||
 | 
					                image: this.currentImage,
 | 
				
			||||||
 | 
					                value: false
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        compiled: function() {
 | 
				
			||||||
 | 
					            this.value = this.currentId === 'false' ? this.currentImage : this.currentId;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        methods: {
 | 
					        methods: {
 | 
				
			||||||
 | 
					            setCurrentValue: function(imageModel, imageUrl) {
 | 
				
			||||||
 | 
					                this.image = imageUrl;
 | 
				
			||||||
 | 
					                this.value = this.currentId === 'false' ?  imageUrl : imageModel.id;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            showImageManager: function(e) {
 | 
					            showImageManager: function(e) {
 | 
				
			||||||
                var _this = this;
 | 
					                var _this = this;
 | 
				
			||||||
                ImageManager.show(function(image) {
 | 
					                ImageManager.show(function(image) {
 | 
				
			||||||
                    _this.image = image.thumbs.custom || image.url;
 | 
					                    _this.updateImageFromModel(image);
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            reset: function() {
 | 
					            reset: function() {
 | 
				
			||||||
                this.image = '';
 | 
					                this.setCurrentValue({id: 0}, this.defaultImage);
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            remove: function() {
 | 
					            remove: function() {
 | 
				
			||||||
                this.image = 'none';
 | 
					                this.image = 'none';
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            updateImageFromModel: function(model) {
 | 
				
			||||||
 | 
					                var _this = this;
 | 
				
			||||||
 | 
					                var isResized = _this.resizeWidth && _this.resizeHeight;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!isResized) {
 | 
				
			||||||
 | 
					                    _this.setCurrentValue(model, model.url);
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var cropped = _this.resizeCrop ? 'true' : 'false';
 | 
				
			||||||
 | 
					                var requestString = '/images/thumb/' + model.id + '/' + _this.resizeWidth + '/' + _this.resizeHeight + '/' + cropped;
 | 
				
			||||||
 | 
					                _this.$http.get(requestString, function(data) {
 | 
				
			||||||
 | 
					                    _this.setCurrentValue(model, data.url);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,10 @@ body.dragging, body.dragging * {
 | 
				
			||||||
    width: 40px;
 | 
					    width: 40px;
 | 
				
			||||||
    height: 40px;
 | 
					    height: 40px;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  &.large {
 | 
				
			||||||
 | 
					    width: 80px;
 | 
				
			||||||
 | 
					    height: 80px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// System wide notifications
 | 
					// System wide notifications
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@
 | 
				
			||||||
                <div class="form-group" id="logo-control">
 | 
					                <div class="form-group" id="logo-control">
 | 
				
			||||||
                    <label for="setting-app-logo">Application Logo</label>
 | 
					                    <label for="setting-app-logo">Application Logo</label>
 | 
				
			||||||
                    <p class="small">This image should be 43px in height. <br>Large images will be scaled down.</p>
 | 
					                    <p class="small">This image should be 43px in height. <br>Large images will be scaled down.</p>
 | 
				
			||||||
                    <image-picker current-image="{{ Setting::get('app-logo', '') }}" default-image="/logo.png" name="setting-app-logo" image-class="logo-image"></image-picker>
 | 
					                    <image-picker resize-height="43" resize-width="200" current-image="{{ Setting::get('app-logo', '') }}" default-image="/logo.png" name="setting-app-logo" image-class="logo-image"></image-picker>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
| 
						 | 
					@ -86,6 +86,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<image-manager image-type="system" resize-height="43" resize-width="200"></image-manager>
 | 
					<image-manager image-type="system"></image-manager>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@stop
 | 
					@stop
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,26 +19,25 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="container small">
 | 
					    <div class="container small">
 | 
				
			||||||
 | 
					        <form action="/users/{{$user->id}}" method="post">
 | 
				
			||||||
        <div class="row">
 | 
					        <div class="row">
 | 
				
			||||||
            <div class="col-md-6">
 | 
					            <div class="col-md-6">
 | 
				
			||||||
                <h1>Edit {{ $user->id === $currentUser->id ? 'Profile' : 'User' }}</h1>
 | 
					                <h1>Edit {{ $user->id === $currentUser->id ? 'Profile' : 'User' }}</h1>
 | 
				
			||||||
                <form action="/users/{{$user->id}}" method="post">
 | 
					 | 
				
			||||||
                {!! csrf_field() !!}
 | 
					                {!! csrf_field() !!}
 | 
				
			||||||
                <input type="hidden" name="_method" value="put">
 | 
					                <input type="hidden" name="_method" value="put">
 | 
				
			||||||
                @include('users/form', ['model' => $user])
 | 
					                @include('users/form', ['model' => $user])
 | 
				
			||||||
                </form>
 | 
					
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div class="col-md-6">
 | 
					            <div class="col-md-6">
 | 
				
			||||||
                <h1> </h1>
 | 
					                <h1> </h1>
 | 
				
			||||||
                <div class="shaded padded margin-top">
 | 
					                <div class="form-group" id="logo-control">
 | 
				
			||||||
                    <p>
 | 
					                    <label for="user-avatar">User Avatar</label>
 | 
				
			||||||
                        <img class="avatar" src="{{ $user->getAvatar(80) }}" alt="{{ $user->name }}">
 | 
					                    <p class="small">This image should be approx 256px square.</p>
 | 
				
			||||||
                    </p>
 | 
					                    <image-picker resize-height="512" resize-width="512" current-image="{{ $user->getAvatar(80) }}" current-id="{{ $user->image_id }}" default-image="/user_avatar.png" name="image_id" show-remove="false" image-class="avatar large"></image-picker>
 | 
				
			||||||
                    <p class="text-muted">You can change your profile picture at <a href="http://en.gravatar.com/">Gravatar</a>.</p>
 | 
					 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <hr class="margin-top large">
 | 
					        <hr class="margin-top large">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,5 +79,5 @@
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p class="margin-top large"><br></p>
 | 
					    <p class="margin-top large"><br></p>
 | 
				
			||||||
 | 
					    <image-manager image-type="user"></image-manager>
 | 
				
			||||||
@stop
 | 
					@stop
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,3 +37,4 @@
 | 
				
			||||||
    <a href="/users" class="button muted">Cancel</a>
 | 
					    <a href="/users" class="button muted">Cancel</a>
 | 
				
			||||||
    <button class="button pos" type="submit">Save</button>
 | 
					    <button class="button pos" type="submit">Save</button>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue