diff --git a/.gitignore b/.gitignore index f5b7047..fd66817 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,7 @@ Homestead.yaml npm-debug.log yarn-error.log .idea +/public/css/ +/public/fonts/ +/public/js/ +/public/images/ diff --git a/README.md b/README.md index a61fad1..0cc88c1 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,5 @@ éditer le fichier `.env` `php artisan migrate` + +`php artisan db:seed --class=TagsTableSeeder` diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php new file mode 100644 index 0000000..e279091 --- /dev/null +++ b/app/Http/Controllers/DashboardController.php @@ -0,0 +1,175 @@ +middleware('auth'); + } + + /** + * Show the application dashboard. + * + * @return \Illuminate\Contracts\Support\Renderable + * @throws \Exception + */ + public function index() + { + setlocale(LC_TIME, 'fr_FR.utf8'); + $today = new DateTime(); + $user_id = Auth::user()->getAuthIdentifier(); + $user = \App\User::find($user_id); + $all_counts = Post::where('user_id', $user_id)->count(); + $year_counts = Post::where('user_id', $user_id)->whereYear('date_post', $today->format('Y'))->count(); + $month_counts = Post::where('user_id', $user_id) + ->whereYear('date_post', $today->format('Y')) + ->whereMonth('date_post', $today->format('m'))->count(); + $image_counts = Post::where('user_id', Auth::user()->getAuthIdentifier()) + ->where('image', '!=', 'null') + ->count(); + $posts = Post::where('user_id', $user_id)->orderBy('date_post', 'DESC')->limit(9)->get(); + $today_post = Post::whereDate('date_post', '=', $today->format('Y-m-d')) + ->where('user_id', $user_id) + ->count(); + + $already = false; + if ($today_post > 0) { + $already = true; + } + + return view('home', [ + 'already' => $already, + 'must_encrypt' => $user->encrypt_messages, + 'all_counts' => $all_counts, + 'year_counts' => $year_counts, + 'month_counts' => $month_counts, + 'image_counts' => $image_counts, + 'today' => $today, + 'posts' => $posts, + ]); + } + + /** + * Edit today's entry + */ + public function edit(TagDetectorService $tag_detector) + { + /** @var Post $today_post */ + $today_post = Post::whereDate('date_post', '=', (new DateTime())->format('Y-m-d')) + ->where('user_id', Auth::user()->getAuthIdentifier()) + ->firstOrFail(); + + $data = request()->validate([ + 'message' => 'required' + ]); + + $today_post->deleteTags(); + + $tags = $tag_detector->detectFrom($data['message']); + + $today_post->content = $data['message']; + $today_post->save(); + $all_tags = Tag::all(); + $all_tags_names = []; + foreach ($all_tags as $tag) { + $all_tags_names[$tag->id] = $tag->name; + } + + foreach ($tags as $tag) { + if (in_array($tag, $all_tags_names)) { + PostsTag::create([ + 'post_id' => $today_post->id, + 'tag_id' => array_search($tag, $all_tags_names), + ]); + } + } + + return Redirect::to('home')->withSuccess('Great! Form successfully submit with validation.'); + } + + /** + * @return \Illuminate\Http\RedirectResponse + * @throws \Exception + */ + public function delete() + { + try { + $today_post = Post::whereDate('date_post', '=', (new DateTime())->format('Y-m-d')) + ->where('user_id', Auth::user()->getAuthIdentifier()) + ->firstOrFail(); + /** @var Post $today_post */ + $today_post->deleteTags(); + $today_post->delete(); + return Redirect::to('home')->withSuccess('Great! Your today\'s post is now deleted. You can make a new one!'); + } catch (\ErrorException $e) { + return Redirect::to('home')->withErrors('Oh no! We could\'t find your today\'s post.'); + } + } + + /** + * @param TagDetectorService $tag_detector + * @return mixed + * @throws \Exception + */ + public function store(TagDetectorService $tag_detector, ImageService $image_service) + { + $user_id = Auth::user()->getAuthIdentifier(); + + $validated_data = request()->validate([ + 'message' => 'required', + 'file' => 'file|mimes:jpeg,png,jpg,gif,svg', + ]); + + $data = [ + 'user_id' => $user_id, + 'date_post' => new DateTime(), + 'content' => $validated_data['message'], + ]; + + if (!empty($validated_data['file'])) { + /** @var UploadedFile $uploaded_document */ + $uploaded_document = $validated_data['file']; + $file_name = $uploaded_document->getClientOriginalName(); + $uploaded_document->storeAs(Auth::user()->getFolder(), $file_name); + $image_service->makeThumbnail($uploaded_document->getRealPath(), ['width' => 300]); + $data['image'] = $file_name; + } + + $tags = $tag_detector->detectFrom($data['content']); + + $check = Post::create($data); + $all_tags = Tag::all(); + $all_tags_names = []; + foreach ($all_tags as $tag) { + $all_tags_names[$tag->id] = $tag->name; + } + + foreach ($tags as $tag) { + if (in_array($tag, $all_tags_names)) { + PostsTag::create([ + 'post_id' => $check->id, + 'tag_id' => array_search($tag, $all_tags_names), + ]); + } + } + + return Redirect::to('home')->withSuccess('Great! Form successfully submit with validation.'); + } +} diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php deleted file mode 100644 index 31d9488..0000000 --- a/app/Http/Controllers/HomeController.php +++ /dev/null @@ -1,99 +0,0 @@ -middleware('auth'); - } - - /** - * Show the application dashboard. - * - * @return \Illuminate\Contracts\Support\Renderable - */ - public function index() - { - setlocale(LC_TIME, 'fr_FR.utf8'); - $today = new DateTime(); - $user_id = Auth::user()->getAuthIdentifier(); - $user = \App\User::find($user_id); - $all_counts = Post::where('user_id', $user_id)->count(); - $year_counts = Post::where('user_id', $user_id)->whereYear('date_post', $today->format('Y'))->count(); - $month_counts = Post::where('user_id', $user_id) - ->whereYear('date_post', $today->format('Y')) - ->whereMonth('date_post', $today->format('m'))->count(); - $image_counts = 0; // TODO #4 - $posts = Post::where('user_id', $user_id)->orderBy('date_post', 'DESC')->limit(9)->get(); - $today_post = Post::whereDate('date_post', '=', $today->format('Y-m-d')) - ->where('user_id', $user_id) - ->count(); - - $already = false; - if ($today_post > 0) { - $already = true; - } - - return view('home', [ - 'already' => $already, - 'must_encrypt' => $user->encrypt_messages, - 'all_counts' => $all_counts, - 'year_counts' => $year_counts, - 'month_counts' => $month_counts, - 'image_counts' => $image_counts, - 'today' => $today, - 'posts' => $posts, - ]); - } - - public function store(TagDetectorService $tag_detector) - { - $today = new DateTime(); - - $data = request()->validate([ - 'message' => 'required' - ]); - - $data = [ - 'user_id' => Auth::user()->getAuthIdentifier(), - 'date_post' => new DateTime(), // Take back the date from the form ? - 'content' => $data['message'], - ]; - - $tags = $tag_detector->detectFrom($data['content']); - - $check = Post::create($data); - $all_tags = Tag::all(); - $all_tags_names = []; - foreach ($all_tags as $tag) { - $all_tags_names[$tag->id] = $tag->name; - } - - foreach ($tags as $tag) { - if (in_array($tag, $all_tags_names)) { - PostsTag::create([ - 'post_id' => $check->id, - 'tag_id' => array_search($tag, $all_tags_names), - ]); - } - } - - return Redirect::to('home')->withSuccess('Great! Form successfully submit with validation.'); - } -} diff --git a/app/Http/Controllers/ImageController.php b/app/Http/Controllers/ImageController.php new file mode 100644 index 0000000..1d97c85 --- /dev/null +++ b/app/Http/Controllers/ImageController.php @@ -0,0 +1,60 @@ +getAuthIdentifier() !== (int)$post->user_id) { + throw new UnauthorizedHttpException('Cette image ne vous appartient pas.'); + } + + $original = sprintf('%s/%s/%s', storage_path('app'), Auth::user()->getFolder(), $image); + if ('o:full' === $options) { + $img = $image_service->makeThumbnail($original); + } else { + $img = $image_service->makeThumbnail($original, ['width' => 300]); + } + + return $img->response(File::extension($original)); + } + + /** + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function gallery() + { + $posts_with_image = Post::where('user_id', Auth::user()->getAuthIdentifier()) + ->where('image', '!=', 'null') + ->orderBy('created_at', 'desc') + ->paginate(30); + + return view('gallery.my', [ + 'posts' => $posts_with_image, + ]); + } +} diff --git a/app/Http/Controllers/WelcomeController.php b/app/Http/Controllers/WelcomeController.php index f7cba65..a1fa40d 100644 --- a/app/Http/Controllers/WelcomeController.php +++ b/app/Http/Controllers/WelcomeController.php @@ -3,13 +3,22 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; class WelcomeController extends Controller { + /** + * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View + * @throws \Exception + */ public function index() { - return view('welcome', [ - 'today' => new \DateTime(), - ]); + if (Auth::guest()) { + return view('welcome', [ + 'today' => new \DateTime(), + ]); + } + + return redirect(route('dashboard')); } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 0d7d8c1..e4a0e03 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -2,7 +2,28 @@ namespace App\Http; +use App\Http\Middleware\Authenticate; +use App\Http\Middleware\CheckForMaintenanceMode; +use App\Http\Middleware\EncryptCookies; +use App\Http\Middleware\GenerateMenus; +use App\Http\Middleware\RedirectIfAuthenticated; +use App\Http\Middleware\TrimStrings; +use App\Http\Middleware\TrustProxies; +use App\Http\Middleware\VerifyCsrfToken; +use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth; +use Illuminate\Auth\Middleware\Authorize; +use Illuminate\Auth\Middleware\EnsureEmailIsVerified; +use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse; use Illuminate\Foundation\Http\Kernel as HttpKernel; +use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull; +use Illuminate\Foundation\Http\Middleware\ValidatePostSize; +use Illuminate\Http\Middleware\SetCacheHeaders; +use Illuminate\Routing\Middleware\SubstituteBindings; +use Illuminate\Routing\Middleware\ThrottleRequests; +use Illuminate\Routing\Middleware\ValidateSignature; +use Illuminate\Session\Middleware\AuthenticateSession; +use Illuminate\Session\Middleware\StartSession; +use Illuminate\View\Middleware\ShareErrorsFromSession; class Kernel extends HttpKernel { @@ -14,11 +35,11 @@ class Kernel extends HttpKernel * @var array */ protected $middleware = [ - \App\Http\Middleware\TrustProxies::class, - \App\Http\Middleware\CheckForMaintenanceMode::class, - \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, - \App\Http\Middleware\TrimStrings::class, - \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, + TrustProxies::class, + CheckForMaintenanceMode::class, + ValidatePostSize::class, + TrimStrings::class, + ConvertEmptyStringsToNull::class, ]; /** @@ -28,13 +49,14 @@ class Kernel extends HttpKernel */ protected $middlewareGroups = [ 'web' => [ - \App\Http\Middleware\EncryptCookies::class, - \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, - \Illuminate\Session\Middleware\StartSession::class, + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, - \Illuminate\View\Middleware\ShareErrorsFromSession::class, - \App\Http\Middleware\VerifyCsrfToken::class, - \Illuminate\Routing\Middleware\SubstituteBindings::class, + ShareErrorsFromSession::class, + VerifyCsrfToken::class, + SubstituteBindings::class, + GenerateMenus::class, ], 'api' => [ @@ -51,15 +73,15 @@ class Kernel extends HttpKernel * @var array */ protected $routeMiddleware = [ - 'auth' => \App\Http\Middleware\Authenticate::class, - 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, - 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, - 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, - 'can' => \Illuminate\Auth\Middleware\Authorize::class, - 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, - 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, - 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, - 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'auth' => Authenticate::class, + 'auth.basic' => AuthenticateWithBasicAuth::class, + 'bindings' => SubstituteBindings::class, + 'cache.headers' => SetCacheHeaders::class, + 'can' => Authorize::class, + 'guest' => RedirectIfAuthenticated::class, + 'signed' => ValidateSignature::class, + 'throttle' => ThrottleRequests::class, + 'verified' => EnsureEmailIsVerified::class, ]; /** @@ -70,12 +92,12 @@ class Kernel extends HttpKernel * @var array */ protected $middlewarePriority = [ - \Illuminate\Session\Middleware\StartSession::class, - \Illuminate\View\Middleware\ShareErrorsFromSession::class, - \App\Http\Middleware\Authenticate::class, - \Illuminate\Routing\Middleware\ThrottleRequests::class, - \Illuminate\Session\Middleware\AuthenticateSession::class, - \Illuminate\Routing\Middleware\SubstituteBindings::class, - \Illuminate\Auth\Middleware\Authorize::class, + StartSession::class, + ShareErrorsFromSession::class, + Authenticate::class, + ThrottleRequests::class, + AuthenticateSession::class, + SubstituteBindings::class, + Authorize::class, ]; } diff --git a/app/Http/Middleware/GenerateMenus.php b/app/Http/Middleware/GenerateMenus.php new file mode 100644 index 0000000..56178e3 --- /dev/null +++ b/app/Http/Middleware/GenerateMenus.php @@ -0,0 +1,40 @@ +make('menu', function (Builder $menu) { + $accueil = $menu->add('Accueil', ['route' => 'dashboard', 'class' => 'nav-item'])->nickname('home'); + $accueil->link->attr(['class' => 'nav-link']); + $accueil->prepend(' '); + $accueil->checkActivationStatus(); + + $stats = $menu->add('Mes statistiques', ['route' => 'stats', 'class' => 'nav-item'])->nickname('stats'); + $stats->link->attr(['class' => 'nav-link']); + $stats->prepend(' '); + $stats->checkActivationStatus(); + + $gallery = $menu->add('Ma gallerie', ['route' => 'gallery', 'class' => 'nav-item'])->nickname('gallery'); + $gallery->link->attr(['class' => 'nav-link']); + $gallery->prepend(' '); + $gallery->checkActivationStatus(); + }); + + return $next($request); + } +} diff --git a/app/Post.php b/app/Post.php index 5f112ca..3657a13 100644 --- a/app/Post.php +++ b/app/Post.php @@ -14,16 +14,16 @@ class Post extends Model protected $fillable = [ 'content', 'image', 'date_post', 'user_id' ]; - + /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ - + ]; - + /** * The attributes that should be cast to native types. * @@ -32,4 +32,15 @@ class Post extends Model protected $casts = [ 'date_post' => 'datetime', ]; + + /** + * Delete this posts tags + */ + public function deleteTags() + { + $tags_to_delete = PostsTag::where('post_id', $this->id)->get(); + foreach ($tags_to_delete as $tag_to_delete) { + $tag_to_delete->delete(); + } + } } diff --git a/app/Providers/ImageServiceProvider.php b/app/Providers/ImageServiceProvider.php new file mode 100644 index 0000000..2034dff --- /dev/null +++ b/app/Providers/ImageServiceProvider.php @@ -0,0 +1,29 @@ +app->bind(ImageService::class); + } + + /** + * Bootstrap services. + * + * @return void + */ + public function boot() + { + // + } +} diff --git a/app/Services/ImageService.php b/app/Services/ImageService.php new file mode 100644 index 0000000..2e95f20 --- /dev/null +++ b/app/Services/ImageService.php @@ -0,0 +1,56 @@ +basePath()); + $file_name = basename($image); + + $width = null; + if (array_key_exists('width', $options)) { + $width = $options['width']; + $file_name = sprintf('w%u-%s', $width, $file_name); + } + + $height = null; + if (array_key_exists('$height', $options)) { + $height = $options['$height']; + $file_name = sprintf('h%u-%s', $height, $file_name); + } + + $full_path = sprintf('%s/%s', $folder, $file_name); + if (!array_key_exists('force', $options) && is_readable($full_path)) { + return Image::make($full_path); + } + + //http://image.intervention.io/getting_started/ + $img->resize($width, $height, static function (Constraint $constraint) { + $constraint->aspectRatio(); + })->save(sprintf('%s/%s', $folder, $file_name)); + + return $img; + } +} diff --git a/app/User.php b/app/User.php index e79dab7..b7c1510 100644 --- a/app/User.php +++ b/app/User.php @@ -36,4 +36,10 @@ class User extends Authenticatable protected $casts = [ 'email_verified_at' => 'datetime', ]; + + public function getFolder() + { + $arrayHash = str_split(strtolower(md5($this->id))); + return sprintf('%s/%s', $arrayHash[0], $arrayHash[1]); + } } diff --git a/composer.json b/composer.json index 0d3f00d..4de1904 100644 --- a/composer.json +++ b/composer.json @@ -10,8 +10,10 @@ "require": { "php": "^7.2", "fideloper/proxy": "^4.0", + "intervention/image": "^2.5", "laravel/framework": "^6.0", - "laravel/tinker": "^1.0" + "laravel/tinker": "^1.0", + "lavary/laravel-menu": "^1.7" }, "require-dev": { "facade/ignition": "^1.4", diff --git a/composer.lock b/composer.lock index d8da420..a25d7a0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3f43a645b4cb3d85ae04049046b0845a", + "content-hash": "a8999b4d9f518e7a9608ff59c6ba40e9", "packages": [ { "name": "dnoegel/php-xdg-base-dir", @@ -380,6 +380,147 @@ ], "time": "2019-09-03T16:45:42+00:00" }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "intervention/image", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "abbf18d5ab8367f96b3205ca3c89fb2fa598c69e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/abbf18d5ab8367f96b3205ca3c89fb2fa598c69e", + "reference": "abbf18d5ab8367f96b3205ca3c89fb2fa598c69e", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.2", + "phpunit/phpunit": "^4.8 || ^5.7" + }, + "suggest": { + "ext-gd": "to use GD library based image processing.", + "ext-imagick": "to use Imagick based image processing.", + "intervention/imagecache": "Caching extension for the Intervention Image library" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + }, + "laravel": { + "providers": [ + "Intervention\\Image\\ImageServiceProvider" + ], + "aliases": { + "Image": "Intervention\\Image\\Facades\\Image" + } + } + }, + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src/Intervention/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@olivervogel.com", + "homepage": "http://olivervogel.com/" + } + ], + "description": "Image handling and manipulation library with support for Laravel integration", + "homepage": "http://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "laravel", + "thumbnail", + "watermark" + ], + "time": "2019-11-02T09:15:47+00:00" + }, { "name": "jakub-onderka/php-console-color", "version": "v0.2", @@ -676,6 +817,58 @@ ], "time": "2019-08-07T15:10:45+00:00" }, + { + "name": "lavary/laravel-menu", + "version": "v1.7.7", + "source": { + "type": "git", + "url": "https://github.com/lavary/laravel-menu.git", + "reference": "5592778b3193ae561614ecb107467469b694ab11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lavary/laravel-menu/zipball/5592778b3193ae561614ecb107467469b694ab11", + "reference": "5592778b3193ae561614ecb107467469b694ab11", + "shasum": "" + }, + "require": { + "illuminate/support": ">=5.0", + "illuminate/view": ">=5.0", + "php": ">=5.4.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Lavary\\Menu\\ServiceProvider" + ], + "aliases": { + "Menu": "Lavary\\Menu\\Facade" + } + } + }, + "autoload": { + "psr-0": { + "Lavary\\Menu\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lavary", + "email": "mrl.8081@gmail.com" + } + ], + "description": "A quick way to create menus in Laravel 5", + "homepage": "https://github.com/lavary/laravel-menu", + "keywords": [ + "laravel" + ], + "time": "2019-09-06T16:28:16+00:00" + }, { "name": "league/flysystem", "version": "1.0.55", @@ -1164,6 +1357,56 @@ ], "time": "2017-02-14T16:28:37+00:00" }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, { "name": "psr/log", "version": "1.1.0", @@ -1333,6 +1576,46 @@ ], "time": "2018-10-13T15:16:03+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, { "name": "ramsey/uuid", "version": "3.8.0", diff --git a/config/app.php b/config/app.php index 7e4d3a8..1b675c2 100644 --- a/config/app.php +++ b/config/app.php @@ -13,7 +13,7 @@ return [ | */ - 'name' => env('APP_NAME', 'Laravel'), + 'name' => env('APP_NAME', 'Journal Intime'), /* |-------------------------------------------------------------------------- @@ -67,7 +67,7 @@ return [ | */ - 'timezone' => 'UTC', + 'timezone' => 'Europe/Paris', /* |-------------------------------------------------------------------------- @@ -176,7 +176,8 @@ return [ App\Providers\RouteServiceProvider::class, \App\Providers\TagDetectorProvider::class, - + \App\Providers\ImageServiceProvider::class, + Intervention\Image\ImageServiceProvider::class, ], /* @@ -209,6 +210,7 @@ return [ 'File' => Illuminate\Support\Facades\File::class, 'Gate' => Illuminate\Support\Facades\Gate::class, 'Hash' => Illuminate\Support\Facades\Hash::class, + 'Image' => Intervention\Image\Facades\Image::class, 'Lang' => Illuminate\Support\Facades\Lang::class, 'Log' => Illuminate\Support\Facades\Log::class, 'Mail' => Illuminate\Support\Facades\Mail::class, diff --git a/config/image.php b/config/image.php new file mode 100644 index 0000000..2b1d2c3 --- /dev/null +++ b/config/image.php @@ -0,0 +1,20 @@ + 'gd' + +]; diff --git a/config/laravel-menu/settings.php b/config/laravel-menu/settings.php new file mode 100644 index 0000000..2eb25b0 --- /dev/null +++ b/config/laravel-menu/settings.php @@ -0,0 +1,13 @@ + [ + 'auto_activate' => true, + 'activate_parents' => true, + 'active_class' => 'active', + 'restful' => false, + 'cascade_data' => true, + 'rest_base' => '', // string|array + 'active_element' => 'link', // item|link + ], +]; diff --git a/config/laravel-menu/views.php b/config/laravel-menu/views.php new file mode 100644 index 0000000..e136d88 --- /dev/null +++ b/config/laravel-menu/views.php @@ -0,0 +1,5 @@ + 'laravel-menu::bootstrap-navbar-items', +]; diff --git a/resources/js/app.js b/resources/js/app.js index 0ed8fc4..f9650c1 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -29,8 +29,8 @@ window.Vue = require('vue'); import Vue from 'vue'; import Autocomplete from './components/Autocomplete.vue'; -import { Endcrypt } from 'endcrypt'; -import { Vue2Storage } from 'vue2-storage' +import {Endcrypt} from 'endcrypt'; +import {Vue2Storage} from 'vue2-storage'; const e = new Endcrypt(); @@ -49,6 +49,14 @@ Vue.component( 'messageform', { name: 'MessageForm', props: { + 'imageLabel': { + type: String, + default: "Choisir une image" + }, + 'uploadClass': { + type: String, + default: "fe fe-upload" + }, 'mustencrypt': { type: Boolean, default: true @@ -64,11 +72,24 @@ Vue.component( if (this.mustencrypt) { // https://www.npmjs.com/package/endcrypt let plain = document.querySelector("[name=message]").value; - let encryptedMessage = JSON.stringify(e.encryptWithKey(plain, this.$storage.get('passphrase'))); - document.querySelector("[name=message]").value = encryptedMessage; + document.querySelector("[name=message]").value = JSON.stringify(e.encryptWithKey(plain, this.$storage.get('passphrase'))); } document.getElementById('messageForm').submit(); return false; + }, + fileNameChanged: function(inputName, inputFiles) { + let file = inputFiles[0]; + let imageName = file["name"]; + if (imageName !== "") { + imageName = imageName.split('\\').pop(); + } + if (imageName !== "") { + this.uploadClass = "fe fe-check"; + this.imageLabel = imageName; + } else { + this.uploadClass = "fe fe-upload"; + this.imageLabel = "Choisir une image"; + } } }, beforeMount: function() { @@ -86,7 +107,6 @@ Vue.component( cardBody.innerHTML = e.decryptWithKey(cardBodyDecrypted, $this.$storage.get('passphrase')); } catch (e) { console.log('can\'t decode '+ cardBody.innerHTML); - console.log(e); } card.addEventListener('click', function(evt) { let $card = this.parentElement.parentElement.parentElement; @@ -103,6 +123,8 @@ Vue.component( } ); -new Vue({ - el: '#store' -}); +if (document.getElementById("store")) { + new Vue({ + el: '#store' + }); +} diff --git a/resources/js/components/Autocomplete.vue b/resources/js/components/Autocomplete.vue index b89c65e..076dd3d 100644 --- a/resources/js/components/Autocomplete.vue +++ b/resources/js/components/Autocomplete.vue @@ -51,6 +51,13 @@ } } }); + let collapse = document.getElementById("collapse"); + let already = collapse && document.getElementById("collapse").classList.contains("collapse"); + if (already) { + let post = document.querySelector(".already").innerText; + document.querySelector("textarea").innerHTML = post; + this.inputValue = post; + } }, computed: { listToSearch() { diff --git a/resources/sass/_general.scss b/resources/sass/_general.scss index e84e0cc..1b8d812 100644 --- a/resources/sass/_general.scss +++ b/resources/sass/_general.scss @@ -1,3 +1,47 @@ h1, h2, h3, h4 { font-family: $font-family-base; } + +.card-options .btn-link { + color: #9aa0ac; + text-decoration: none; + min-width: 0; + padding: 0; + margin-left: 5px; + &:hover { + color: #6e7687; + } +} + +.btn-tertiary { + color: #555; + padding: 0; + line-height: 40px; + width: 300px; + margin: auto; + display: block; + border: 2px solid #555; + &:hover, + &:focus { + color: lighten(#555, 20%); + border-color: lighten(#555, 20%); + } +} + +/* input file style */ + +.input-file { + width: 0.1px; + height: 0.1px; + opacity: 0; + overflow: hidden; + position: absolute; + z-index: -1; + + .js-labelFile { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: 0 10px; + cursor: pointer; + } +} diff --git a/resources/sass/app.scss b/resources/sass/app.scss index dc1c79c..5c1925f 100644 --- a/resources/sass/app.scss +++ b/resources/sass/app.scss @@ -11,7 +11,7 @@ } // Bootstrap -//@import '~bootstrap/scss/bootstrap'; +@import '~bootstrap/scss/bootstrap'; @import '~tabler-ui/src/assets/scss/bundle.scss'; // Variables diff --git a/resources/views/components/app.blade.php b/resources/views/components/app.blade.php index 44e54d9..a5ecd1c 100644 --- a/resources/views/components/app.blade.php +++ b/resources/views/components/app.blade.php @@ -1,12 +1,19 @@ -
+ {{ $crsf }}
+
+
+ +
diff --git a/resources/views/gallery/my.blade.php b/resources/views/gallery/my.blade.php new file mode 100644 index 0000000..5f0fca1 --- /dev/null +++ b/resources/views/gallery/my.blade.php @@ -0,0 +1,33 @@ +@extends('layouts.connected') + +@section('content') +
+ +
+ @foreach($posts as $post) +
+
+
+
+

{{ ucfirst(\Carbon\Carbon::instance($post->date_post)->diffForHumans()) }}

+
+ +
+
+
+

+ + + +

+
+
+
+ @endforeach +
+
+@endsection diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index 8779d97..ad74dac 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -13,6 +13,16 @@ {{ session('status') }}
@endif + @if (session('success')) + + @endif + @if (session('errors')) + + @endif
@@ -80,23 +90,19 @@ @endcomponent
@else -
-
-
-
-

{{ strftime('%B %G', $today->format('U')) }}

-
-
-
- @component('components/app', [ - 'route' => url('store'), - 'crsf' => csrf_field(), - 'mustencrypt' => $must_encrypt, - 'possible' => !$already, - ]) - @endcomponent -
-
+
+
+

{{ strftime('%B %G', $today->format('U')) }}

+
+
+
+ @component('components/app', [ + 'route' => url('store'), + 'crsf' => csrf_field(), + 'mustencrypt' => $must_encrypt, + 'possible' => !$already, + ]) + @endcomponent
@@ -110,11 +116,18 @@

{{ ucfirst(\Carbon\Carbon::instance($post->date_post)->diffForHumans()) }}

- + @if($today->format('Y-m-d') === \Carbon\Carbon::instance($post->date_post)->format('Y-m-d')) + + + @csrf + + + @endif
-
- {!! $tag_detector->linkTagFrom($post->content) !!} +
+ @if($post->image != '')

@endif +

{!! $tag_detector->linkTagFrom($post->content) !!}

diff --git a/resources/views/vendor/laravel-menu/bootstrap-navbar-items.blade.php b/resources/views/vendor/laravel-menu/bootstrap-navbar-items.blade.php new file mode 100644 index 0000000..47909dd --- /dev/null +++ b/resources/views/vendor/laravel-menu/bootstrap-navbar-items.blade.php @@ -0,0 +1,20 @@ +@foreach($items as $item) +
  • hasChildren()) class="nav-item dropdown" @endif @lm_endattrs> + @if($item->link) link) @if($item->hasChildren()) class="nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" @else class="nav-link" @endif @lm_endattrs href="{!! $item->url() !!}"> + {!! $item->title !!} + @if($item->hasChildren()) @endif + + @else + {!! $item->title !!} + @endif + @if($item->hasChildren()) + + @endif +
  • + @if($item->divider) + divider) !!}> + @endif +@endforeach diff --git a/routes/web.php b/routes/web.php index 3f6eb2a..17626f2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,6 +14,10 @@ Auth::routes(); Route::get('/', 'WelcomeController@index')->name('home'); -Route::get('/home', 'HomeController@index')->name('dashboard'); -Route::post('store', 'HomeController@store')->name('store'); +Route::get('/home', 'DashboardController@index')->name('dashboard'); +Route::post('store', 'DashboardController@store')->name('store'); +Route::post('delete', 'DashboardController@delete')->name('delete'); +Route::post('edit', 'DashboardController@edit')->name('edit'); Route::post('stats', 'StatsController@tag')->name('stats'); // TODO make a group for stats +Route::get('/display/{post_id}/{options}/{image_name}', 'ImageController@display')->name('display_image'); +Route::get('/gallery', 'ImageController@gallery')->name('gallery');