diff --git a/.env.example b/.env.example index a4b04fd..0053a9e 100644 --- a/.env.example +++ b/.env.example @@ -13,15 +13,16 @@ DB_DATABASE=laravel DB_USERNAME=root DB_PASSWORD= -BROADCAST_DRIVER=log -CACHE_DRIVER=file -QUEUE_CONNECTION=sync +BROADCAST_DRIVER=redis +CACHE_DRIVER=redis +QUEUE_CONNECTION=redis SESSION_DRIVER=file SESSION_LIFETIME=120 REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 +REDIS_PREFIX=apsky_laravel_database_ MAIL_MAILER=smtp MAIL_HOST=smtp.mailtrap.io diff --git a/app/Comment.php b/app/Comment.php index f17422d..fe928a1 100644 --- a/app/Comment.php +++ b/app/Comment.php @@ -2,16 +2,18 @@ namespace App; +use App\Traits\CacheModelActions; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Comment extends Model { use HasFactory; + use CacheModelActions; protected $table = 'comments'; - protected $guarded = ['']; + public static $cacheTags = 'comments'; public function commentable() { diff --git a/app/Events/PostCreated.php b/app/Events/Posts/PostCreated.php similarity index 78% rename from app/Events/PostCreated.php rename to app/Events/Posts/PostCreated.php index e1f6f1f..d3ec0d3 100644 --- a/app/Events/PostCreated.php +++ b/app/Events/Posts/PostCreated.php @@ -12,11 +12,6 @@ class PostCreated public Post $post; - /** - * Create a new event instance. - * - * @param Post $post - */ public function __construct(Post $post) { $this->post = $post; diff --git a/app/Events/PostUpdated.php b/app/Events/Posts/PostUpdated.php similarity index 100% rename from app/Events/PostUpdated.php rename to app/Events/Posts/PostUpdated.php diff --git a/app/Events/PostUpdatedAdminChat.php b/app/Events/Posts/PostUpdatedAdminChat.php similarity index 100% rename from app/Events/PostUpdatedAdminChat.php rename to app/Events/Posts/PostUpdatedAdminChat.php diff --git a/app/Http/Controllers/AdministrationController.php b/app/Http/Controllers/AdministrationController.php index 1df4d39..57d3fa6 100644 --- a/app/Http/Controllers/AdministrationController.php +++ b/app/Http/Controllers/AdministrationController.php @@ -5,6 +5,7 @@ use App\News; use App\Post; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; class AdministrationController extends Controller { @@ -18,12 +19,18 @@ public function index() { } public function posts() { - $posts = Post::with('tags')->latest()->get(); + $posts = Cache::tags(['posts', 'tags', 'comments'])->remember('posts', 3600, function () { + return Post::with(['tags', 'comments'])->latest()->get(); + }); + return view('/admin.posts', compact('posts')); } public function news() { - $news = News::latest()->get(); + $news = Cache::tags(['news', 'tags', 'comments'])->remember('news', 3600, function () { + return News::with(['tags', 'comments'])->latest()->get(); + }); + return view('/admin.news', compact('news')); } diff --git a/app/Http/Controllers/FeedbacksController.php b/app/Http/Controllers/FeedbacksController.php index 2482d35..a368bc0 100644 --- a/app/Http/Controllers/FeedbacksController.php +++ b/app/Http/Controllers/FeedbacksController.php @@ -3,13 +3,14 @@ namespace App\Http\Controllers; use App\Feedback; +use Illuminate\Filesystem\Cache; use Illuminate\Http\Request; class FeedbacksController extends Controller { public function __construct() { - $this->middleware('role:admin'); + $this->middleware('role:admin')->except('store'); } public function index() @@ -28,6 +29,12 @@ public function store(Request $request) Feedback::create($request->all()); - return redirect('/admin/feedbacks'); + flash('Feedback successfully send (:', 'success'); + + if (auth()->user() && auth()->user()->hasRole('admin')) { + return redirect('/admin/feedbacks'); + } else { + return back(); + } } } diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index e87ced5..bd98e20 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -3,10 +3,10 @@ namespace App\Http\Controllers; use App\News; -use App\NewTag; use App\Services\TagsCreatorService; use App\Tag; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; use Illuminate\Validation\Rule; class NewsController extends Controller @@ -27,7 +27,9 @@ public function validateRequest($request, $new) public function index() { - $news = News::with(['tags', 'comments'])->latest()->get(); + $news = Cache::tags(['news', 'tags', 'comments'])->remember('news', 3600, function () { + return News::with(['tags', 'comments'])->latest()->get(); + }); return view('news.index', compact('news')); } @@ -75,8 +77,6 @@ public function update(Request $request, News $new) $updater = new TagsCreatorService($new, $request); $updater->updateTags(); -// updateTags($new, $request); - flash( 'New updated successfully'); return back(); diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index dce5829..6e5ad8d 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -6,10 +6,10 @@ use App\Notifications\PostDeleted; use App\Notifications\PostEdited; use App\Post; -use App\PostTag; use App\Services\TagsCreatorService; use App\Tag; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; use Illuminate\Validation\Rule; class PostsController extends Controller @@ -31,7 +31,10 @@ public function validateRequest($request, $post) public function index() { - $posts = auth()->user()->posts()->with(['tags', 'comments'])->latest()->get(); + $posts = Cache::tags(['posts', 'tags', 'comments', 'user_posts'])->remember('user_posts|' . auth()->id(), 3600, function () { + return auth()->user()->posts()->with(['tags', 'comments'])->latest()->get(); + }); + return view('/posts.index', compact('posts')); } diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index 50ff25e..b11a598 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Services\StatisticService; +use Illuminate\Support\Facades\Cache; class StaticPagesController extends Controller { @@ -22,40 +23,42 @@ public function aboutIndex() { } public function statisticsIndex() { - //Общее количество статей - $postsCount = $this->statisticService->getPostsCount(); - - //Общее количество новостей - $newsCount = $this->statisticService->getNewsCount(); - - //ФИО автора, у которого больше всего статей на сайте - $userWithMostPosts = $this->statisticService->getUserWithMaxPosts(); - - //Самая длинная статья - название, ссылка на статью и длина статьи в символах - $theLongestPost = $this->statisticService->getTheLongestPost(); - - //Самая короткая статья - название, ссылка на статью и длина статьи в символах - $theShortestPost = $this->statisticService->getTheShortestPost(); - - //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи - $avgPostsHaveActiveUsers = $this->statisticService->getAveragePosts(); - - //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз - $mostChangingPost = $this->statisticService->getMostChangingPost(); - - //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. - $mostCommentPost = $this->statisticService->getMostCommentPost(); - - $statistics = [ - 'posts_count' => $postsCount, - 'news_count' => $newsCount, - 'user_with_most_posts' => $userWithMostPosts, - 'the_longest_post' => $theLongestPost, - 'the_shortest_post' => $theShortestPost, - 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, - 'most_changing_post' => $mostChangingPost, - 'most_comment_post' => $mostCommentPost - ]; + $statistics = Cache::tags(['news', 'posts', 'tags', 'statistics'])->remember('statistics_data', 3600, function () { + //Общее количество статей + $postsCount = $this->statisticService->getPostsCount(); + + //Общее количество новостей + $newsCount = $this->statisticService->getNewsCount(); + + //ФИО автора, у которого больше всего статей на сайте + $userWithMostPosts = $this->statisticService->getUserWithMaxPosts(); + + //Самая длинная статья - название, ссылка на статью и длина статьи в символах + $theLongestPost = $this->statisticService->getTheLongestPost(); + + //Самая короткая статья - название, ссылка на статью и длина статьи в символах + $theShortestPost = $this->statisticService->getTheShortestPost(); + + //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи + $avgPostsHaveActiveUsers = $this->statisticService->getAveragePosts(); + + //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз + $mostChangingPost = $this->statisticService->getMostChangingPost(); + + //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. + $mostCommentPost = $this->statisticService->getMostCommentPost(); + + return [ + 'posts_count' => $postsCount, + 'news_count' => $newsCount, + 'user_with_most_posts' => $userWithMostPosts, + 'the_longest_post' => $theLongestPost, + 'the_shortest_post' => $theShortestPost, + 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, + 'most_changing_post' => $mostChangingPost, + 'most_comment_post' => $mostCommentPost + ]; + }); return view('static.statistics', ['statistics' => $statistics]); } diff --git a/app/Http/Controllers/TagsController.php b/app/Http/Controllers/TagsController.php index c9f9cf4..33c6b70 100644 --- a/app/Http/Controllers/TagsController.php +++ b/app/Http/Controllers/TagsController.php @@ -4,13 +4,20 @@ use App\Tag; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; class TagsController extends Controller { public function index(Tag $tag) { - $posts = $tag->posts()->with('tags')->get(); - $news = $tag->news()->with('tags')->get(); + $posts = Cache::tags(['posts', 'posts_by_tag'])->remember('posts_by_tag', 3600, function () use ($tag) { + return $tag->posts()->with('tags')->get(); + }); + + $news = Cache::tags(['news', 'news_by_tag'])->remember('news_by_tag', 3600, function () use ($tag) { + return $tag->news()->with('tags')->get(); + }); + return view('layouts.tags.index', compact('posts', 'news')); } } diff --git a/app/Listeners/AddHistoryOnUpdatePost.php b/app/Listeners/AddHistoryOnUpdatePost.php index 2516d74..f581755 100644 --- a/app/Listeners/AddHistoryOnUpdatePost.php +++ b/app/Listeners/AddHistoryOnUpdatePost.php @@ -33,8 +33,10 @@ public function handle(PostUpdated $event) 'text' => $result ]; - $event->post->history()->create($values); + if (!empty($result)) { + $event->post->history()->create($values); - event(new PostUpdatedAdminChat($event->post, $result)); + event(new PostUpdatedAdminChat($event->post, $result)); + } } } diff --git a/app/News.php b/app/News.php index 91b9eae..e82ac17 100644 --- a/app/News.php +++ b/app/News.php @@ -2,14 +2,17 @@ namespace App; +use App\Traits\CacheModelActions; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class News extends Model { use HasFactory; + use CacheModelActions; protected $guarded = []; + public static $cacheTags = 'news'; public function tags() { diff --git a/app/Post.php b/app/Post.php index 2341625..16767f3 100644 --- a/app/Post.php +++ b/app/Post.php @@ -3,18 +3,23 @@ namespace App; use App\Events\PostUpdated; +use App\Mail\PostCreated; +use App\Traits\CacheModelActions; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Post extends Model { use HasFactory; + use CacheModelActions; protected $table = 'posts'; - protected $guarded = []; + public static $cacheTags = 'posts'; + protected $dispatchesEvents = [ + 'created' => PostCreated::class, 'updated' => PostUpdated::class, ]; diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 158eefe..ccbb0e1 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -4,6 +4,7 @@ use App\Services\StatisticService; use App\Tag; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -12,11 +13,14 @@ class AppServiceProvider extends ServiceProvider * Register any application services. * * @return void + * @throws \Illuminate\Contracts\Container\BindingResolutionException */ public function register() { view()->composer('layouts.aside-tags', function ($view) { - $tags = Tag::whereHas('posts')->orWhereHas('news')->get(); + $tags = Cache::tags(['posts', 'news', 'tags'])->remember('tags', 3600, function () { + return Tag::whereHas('posts')->orWhereHas('news')->get(); + }); $view->with('tagsCloud', $tags); }); diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index feec67d..beef509 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,14 +2,11 @@ namespace App\Providers; -use App\Events\PostCreated; use App\Events\PostUpdated; use App\Listeners\AddHistoryOnUpdatePost; -use App\Listeners\SendPostCreateNotification; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; -use Illuminate\Support\Facades\Event; class EventServiceProvider extends ServiceProvider { @@ -35,7 +32,5 @@ class EventServiceProvider extends ServiceProvider public function boot() { parent::boot(); - - // } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 3a816d8..acf1bdf 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -2,7 +2,10 @@ namespace App\Providers; +use App\News; +use App\Post; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Route; class RouteServiceProvider extends ServiceProvider @@ -30,9 +33,23 @@ class RouteServiceProvider extends ServiceProvider */ public function boot() { - // - parent::boot(); + + Route::bind('post', function ($value) { + $post = Cache::tags(['posts', 'tags', 'comments'])->remember('post|' . $value, 3600 , function () use ($value) { + return Post::where('id', $value)->firstOrFail(); + }); + + return $post; + }); + + Route::bind('new', function ($value) { + $new = Cache::tags(['news', 'tags', 'comments'])->remember('new|' . $value, 3600 , function () use ($value) { + return News::where('id', $value)->firstOrFail(); + }); + + return $new; + }); } /** diff --git a/app/Tag.php b/app/Tag.php index 1fa0d0d..f65aeae 100644 --- a/app/Tag.php +++ b/app/Tag.php @@ -2,14 +2,17 @@ namespace App; +use App\Traits\CacheModelActions; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Tag extends Model { use HasFactory; + use CacheModelActions; protected $table = 'tags'; + public static $cacheTags = 'tags'; protected $guarded = []; diff --git a/app/Traits/CacheModelActions.php b/app/Traits/CacheModelActions.php new file mode 100644 index 0000000..d4668de --- /dev/null +++ b/app/Traits/CacheModelActions.php @@ -0,0 +1,26 @@ +flush(); + }); + + static::updated(function() + { + Cache::tags(static::$cacheTags)->flush(); + }); + + static::deleted(function() + { + Cache::tags(static::$cacheTags)->flush(); + }); + } +} diff --git a/public/css/app.css b/public/css/app.css index c0776bd..9860964 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -10928,3 +10928,32 @@ a.text-dark:focus { text-decoration: underline; } +.notify-msg { + -webkit-animation: my-animation 10s; + animation: my-animation 10s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +@-webkit-keyframes my-animation { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + z-index: -2; + } +} + +@keyframes my-animation { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + z-index: -2; + } +} + diff --git a/resources/sass/app.scss b/resources/sass/app.scss index 2a25372..2c9cc91 100644 --- a/resources/sass/app.scss +++ b/resources/sass/app.scss @@ -8,3 +8,4 @@ @import '~bootstrap/scss/bootstrap'; @import "admin-chat"; +@import "flash-msg"; diff --git a/resources/sass/test.scss b/resources/sass/flash-msg.scss similarity index 100% rename from resources/sass/test.scss rename to resources/sass/flash-msg.scss diff --git a/routes/web.php b/routes/web.php index 3b8a818..cab3da9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,15 +3,17 @@ use App\News; use App\Post; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Route; -Route::get('/test', function () { - -}); - Route::get('/', function () { - $posts = Post::with('tags')->where('published', 1)->latest()->take(4)->get(); - $news = News::with('tags')->latest()->take(3)->get(); + $posts = Cache::tags(['posts', 'tags', 'comments', 'latest_publish_posts'])->remember('latest_publish_posts', 3600, function () { + return Post::with('tags')->where('published', 1)->latest()->take(4)->get(); + }); + + $news = Cache::tags(['news', 'tags', 'comments', 'latest_news'])->remember('latest_news', 3600, function () { + return News::with('tags')->latest()->take(3)->get(); + }); return view('/index', compact('posts', 'news')); })->name('home');