From 36f1dfefd0d1c69c8f2cb70d1d985a481c039e69 Mon Sep 17 00:00:00 2001 From: apsky Date: Thu, 1 Oct 2020 17:42:51 +0300 Subject: [PATCH 01/18] start create News --- app/Http/Controllers/NewsController.php | 45 +++ app/News.php | 15 + composer.lock | 305 +++++++++++------- database/factories/NewsFactory.php | 19 ++ .../2020_10_01_153124_create_news_table.php | 33 ++ database/seeds/DatabaseSeeder.php | 1 + database/seeds/NewsTableSeeder.php | 19 ++ resources/views/layouts/base/header.blade.php | 4 + resources/views/news/index.blade.php | 47 +++ routes/web.php | 2 + 10 files changed, 376 insertions(+), 114 deletions(-) create mode 100644 app/Http/Controllers/NewsController.php create mode 100644 app/News.php create mode 100644 database/factories/NewsFactory.php create mode 100644 database/migrations/2020_10_01_153124_create_news_table.php create mode 100644 database/seeds/NewsTableSeeder.php create mode 100644 resources/views/news/index.blade.php diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php new file mode 100644 index 0000000..4634f4a --- /dev/null +++ b/app/Http/Controllers/NewsController.php @@ -0,0 +1,45 @@ +=5.5.0" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.0" + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", "extra": { @@ -727,20 +727,20 @@ "keywords": [ "promise" ], - "time": "2016-12-20T10:07:11+00:00" + "time": "2020-09-30T07:37:28+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.6.1", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", "shasum": "" }, "require": { @@ -753,15 +753,15 @@ }, "require-dev": { "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" }, "suggest": { - "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -798,20 +798,20 @@ "uri", "url" ], - "time": "2019-07-01T23:21:34+00:00" + "time": "2020-09-30T07:37:11+00:00" }, { "name": "laravel/framework", - "version": "v8.4.0", + "version": "v8.7.1", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "1c57ab5e375d0a897c22b29e8352453be514131e" + "reference": "3fb29e904a152b3e1fe49581f66ba5e02fe991f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/1c57ab5e375d0a897c22b29e8352453be514131e", - "reference": "1c57ab5e375d0a897c22b29e8352453be514131e", + "url": "https://api.github.com/repos/laravel/framework/zipball/3fb29e904a152b3e1fe49581f66ba5e02fe991f2", + "reference": "3fb29e904a152b3e1fe49581f66ba5e02fe991f2", "shasum": "" }, "require": { @@ -961,7 +961,7 @@ "framework", "laravel" ], - "time": "2020-09-16T16:13:13+00:00" + "time": "2020-09-29T15:39:07+00:00" }, { "name": "laravel/helpers", @@ -1018,16 +1018,16 @@ }, { "name": "laravel/telescope", - "version": "v4.0.0", + "version": "v4.0.1", "source": { "type": "git", "url": "https://github.com/laravel/telescope.git", - "reference": "ff4594284ad73e895070265a26e1c0538b984191" + "reference": "4bd0a8b01b889c7704cd0a1d04a849c8da993f43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/telescope/zipball/ff4594284ad73e895070265a26e1c0538b984191", - "reference": "ff4594284ad73e895070265a26e1c0538b984191", + "url": "https://api.github.com/repos/laravel/telescope/zipball/4bd0a8b01b889c7704cd0a1d04a849c8da993f43", + "reference": "4bd0a8b01b889c7704cd0a1d04a849c8da993f43", "shasum": "" }, "require": { @@ -1073,7 +1073,7 @@ "laravel", "monitoring" ], - "time": "2020-09-08T14:55:22+00:00" + "time": "2020-09-22T16:49:01+00:00" }, { "name": "laravel/tinker", @@ -1382,16 +1382,16 @@ }, { "name": "league/mime-type-detection", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "fda190b62b962d96a069fcc414d781db66d65b69" + "reference": "ea2fbfc988bade315acd5967e6d02274086d0f28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/fda190b62b962d96a069fcc414d781db66d65b69", - "reference": "fda190b62b962d96a069fcc414d781db66d65b69", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ea2fbfc988bade315acd5967e6d02274086d0f28", + "reference": "ea2fbfc988bade315acd5967e6d02274086d0f28", "shasum": "" }, "require": { @@ -1429,7 +1429,7 @@ "type": "tidelift" } ], - "time": "2020-08-09T10:34:01+00:00" + "time": "2020-09-21T18:10:53+00:00" }, { "name": "monolog/monolog", @@ -1524,16 +1524,16 @@ }, { "name": "nesbot/carbon", - "version": "2.40.0", + "version": "2.40.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "6c7646154181013ecd55e80c201b9fd873c6ee5d" + "reference": "d9a76d8b7eb0f97cf3a82529393245212f40ba3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/6c7646154181013ecd55e80c201b9fd873c6ee5d", - "reference": "6c7646154181013ecd55e80c201b9fd873c6ee5d", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d9a76d8b7eb0f97cf3a82529393245212f40ba3b", + "reference": "d9a76d8b7eb0f97cf3a82529393245212f40ba3b", "shasum": "" }, "require": { @@ -1609,20 +1609,20 @@ "type": "tidelift" } ], - "time": "2020-09-11T19:00:58+00:00" + "time": "2020-09-23T08:17:37+00:00" }, { "name": "nikic/php-parser", - "version": "v4.9.1", + "version": "v4.10.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28" + "reference": "658f1be311a230e0907f5dfe0213742aff0596de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/88e519766fc58bd46b8265561fb79b54e2e00b28", - "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", + "reference": "658f1be311a230e0907f5dfe0213742aff0596de", "shasum": "" }, "require": { @@ -1661,7 +1661,7 @@ "parser", "php" ], - "time": "2020-08-30T16:15:20+00:00" + "time": "2020-09-26T10:30:38+00:00" }, { "name": "opis/closure", @@ -2406,16 +2406,16 @@ }, { "name": "symfony/console", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "186f395b256065ba9b890c0a4e48a91d598fa2cf" + "reference": "04c3a31fe8ea94b42c9e2d1acc93d19782133b00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/186f395b256065ba9b890c0a4e48a91d598fa2cf", - "reference": "186f395b256065ba9b890c0a4e48a91d598fa2cf", + "url": "https://api.github.com/repos/symfony/console/zipball/04c3a31fe8ea94b42c9e2d1acc93d19782133b00", + "reference": "04c3a31fe8ea94b42c9e2d1acc93d19782133b00", "shasum": "" }, "require": { @@ -2495,11 +2495,11 @@ "type": "tidelift" } ], - "time": "2020-09-02T07:07:40+00:00" + "time": "2020-09-18T14:27:32+00:00" }, { "name": "symfony/css-selector", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -2630,16 +2630,16 @@ }, { "name": "symfony/error-handler", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "525636d4b84e06c6ca72d96b6856b5b169416e6a" + "reference": "d2f1d4996d5499f1261164d10080e4120001f041" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/525636d4b84e06c6ca72d96b6856b5b169416e6a", - "reference": "525636d4b84e06c6ca72d96b6856b5b169416e6a", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/d2f1d4996d5499f1261164d10080e4120001f041", + "reference": "d2f1d4996d5499f1261164d10080e4120001f041", "shasum": "" }, "require": { @@ -2697,20 +2697,20 @@ "type": "tidelift" } ], - "time": "2020-08-17T10:01:29+00:00" + "time": "2020-09-27T03:44:28+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "94871fc0a69c3c5da57764187724cdce0755899c" + "reference": "d5de97d6af175a9e8131c546db054ca32842dd0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/94871fc0a69c3c5da57764187724cdce0755899c", - "reference": "94871fc0a69c3c5da57764187724cdce0755899c", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d5de97d6af175a9e8131c546db054ca32842dd0f", + "reference": "d5de97d6af175a9e8131c546db054ca32842dd0f", "shasum": "" }, "require": { @@ -2730,6 +2730,7 @@ "psr/log": "~1.0", "symfony/config": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0", + "symfony/error-handler": "^4.4|^5.0", "symfony/expression-language": "^4.4|^5.0", "symfony/http-foundation": "^4.4|^5.0", "symfony/service-contracts": "^1.1|^2", @@ -2783,7 +2784,7 @@ "type": "tidelift" } ], - "time": "2020-08-13T14:19:42+00:00" + "time": "2020-09-18T14:27:32+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -2863,16 +2864,16 @@ }, { "name": "symfony/finder", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "2b765f0cf6612b3636e738c0689b29aa63088d5d" + "reference": "2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/2b765f0cf6612b3636e738c0689b29aa63088d5d", - "reference": "2b765f0cf6612b3636e738c0689b29aa63088d5d", + "url": "https://api.github.com/repos/symfony/finder/zipball/2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8", + "reference": "2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8", "shasum": "" }, "require": { @@ -2922,20 +2923,95 @@ "type": "tidelift" } ], - "time": "2020-08-17T10:01:29+00:00" + "time": "2020-09-02T16:23:27+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3", + "reference": "3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "41a4647f12870e9d41d9a7d72ff0614a27208558" + "reference": "6cca6b2e4b69fc5bace160d14cf1ee5f71483db4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/41a4647f12870e9d41d9a7d72ff0614a27208558", - "reference": "41a4647f12870e9d41d9a7d72ff0614a27208558", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6cca6b2e4b69fc5bace160d14cf1ee5f71483db4", + "reference": "6cca6b2e4b69fc5bace160d14cf1ee5f71483db4", "shasum": "" }, "require": { @@ -2997,20 +3073,20 @@ "type": "tidelift" } ], - "time": "2020-08-17T07:48:54+00:00" + "time": "2020-09-13T05:01:27+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "3e32676e6cb5d2081c91a56783471ff8a7f7110b" + "reference": "17227644c3c66dcf32bdfeceff4364d090cd6756" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3e32676e6cb5d2081c91a56783471ff8a7f7110b", - "reference": "3e32676e6cb5d2081c91a56783471ff8a7f7110b", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/17227644c3c66dcf32bdfeceff4364d090cd6756", + "reference": "17227644c3c66dcf32bdfeceff4364d090cd6756", "shasum": "" }, "require": { @@ -3019,6 +3095,7 @@ "symfony/deprecation-contracts": "^2.1", "symfony/error-handler": "^4.4|^5.0", "symfony/event-dispatcher": "^5.0", + "symfony/http-client-contracts": "^1.1|^2", "symfony/http-foundation": "^4.4|^5.0", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", @@ -3110,20 +3187,20 @@ "type": "tidelift" } ], - "time": "2020-09-02T08:15:18+00:00" + "time": "2020-09-27T04:33:19+00:00" }, { "name": "symfony/mime", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "89a2c9b4cb7b5aa516cf55f5194c384f444c81dc" + "reference": "4404d6545125863561721514ad9388db2661eec5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/89a2c9b4cb7b5aa516cf55f5194c384f444c81dc", - "reference": "89a2c9b4cb7b5aa516cf55f5194c384f444c81dc", + "url": "https://api.github.com/repos/symfony/mime/zipball/4404d6545125863561721514ad9388db2661eec5", + "reference": "4404d6545125863561721514ad9388db2661eec5", "shasum": "" }, "require": { @@ -3187,7 +3264,7 @@ "type": "tidelift" } ], - "time": "2020-08-17T10:01:29+00:00" + "time": "2020-09-02T16:23:27+00:00" }, { "name": "symfony/polyfill-ctype", @@ -3971,16 +4048,16 @@ }, { "name": "symfony/process", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "1864216226af21eb76d9477f691e7cbf198e0402" + "reference": "d3a2e64866169586502f0cd9cab69135ad12cee9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/1864216226af21eb76d9477f691e7cbf198e0402", - "reference": "1864216226af21eb76d9477f691e7cbf198e0402", + "url": "https://api.github.com/repos/symfony/process/zipball/d3a2e64866169586502f0cd9cab69135ad12cee9", + "reference": "d3a2e64866169586502f0cd9cab69135ad12cee9", "shasum": "" }, "require": { @@ -4031,20 +4108,20 @@ "type": "tidelift" } ], - "time": "2020-07-23T08:36:24+00:00" + "time": "2020-09-02T16:23:27+00:00" }, { "name": "symfony/routing", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "47b0218344cb6af25c93ca8ee1137fafbee5005d" + "reference": "d36e06eb02a55522a8eed070c1cbc3dc3c389876" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/47b0218344cb6af25c93ca8ee1137fafbee5005d", - "reference": "47b0218344cb6af25c93ca8ee1137fafbee5005d", + "url": "https://api.github.com/repos/symfony/routing/zipball/d36e06eb02a55522a8eed070c1cbc3dc3c389876", + "reference": "d36e06eb02a55522a8eed070c1cbc3dc3c389876", "shasum": "" }, "require": { @@ -4123,7 +4200,7 @@ "type": "tidelift" } ], - "time": "2020-08-10T08:03:57+00:00" + "time": "2020-09-02T16:23:27+00:00" }, { "name": "symfony/service-contracts", @@ -4203,16 +4280,16 @@ }, { "name": "symfony/string", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "0de4cc1e18bb596226c06a82e2e7e9bc6001a63a" + "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/0de4cc1e18bb596226c06a82e2e7e9bc6001a63a", - "reference": "0de4cc1e18bb596226c06a82e2e7e9bc6001a63a", + "url": "https://api.github.com/repos/symfony/string/zipball/4a9afe9d07bac506f75bcee8ed3ce76da5a9343e", + "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e", "shasum": "" }, "require": { @@ -4284,20 +4361,20 @@ "type": "tidelift" } ], - "time": "2020-08-17T07:48:54+00:00" + "time": "2020-09-15T12:23:47+00:00" }, { "name": "symfony/translation", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "917b02cdc5f33e0309b8e9d33ee1480b20687413" + "reference": "e3cdd5119b1b5bf0698c351b8ee20fb5a4ea248b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/917b02cdc5f33e0309b8e9d33ee1480b20687413", - "reference": "917b02cdc5f33e0309b8e9d33ee1480b20687413", + "url": "https://api.github.com/repos/symfony/translation/zipball/e3cdd5119b1b5bf0698c351b8ee20fb5a4ea248b", + "reference": "e3cdd5119b1b5bf0698c351b8ee20fb5a4ea248b", "shasum": "" }, "require": { @@ -4376,7 +4453,7 @@ "type": "tidelift" } ], - "time": "2020-08-17T10:01:29+00:00" + "time": "2020-09-27T03:44:28+00:00" }, { "name": "symfony/translation-contracts", @@ -4455,16 +4532,16 @@ }, { "name": "symfony/var-dumper", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "b43a3905262bcf97b2510f0621f859ca4f5287be" + "reference": "c976c115a0d788808f7e71834c8eb0844f678d02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b43a3905262bcf97b2510f0621f859ca4f5287be", - "reference": "b43a3905262bcf97b2510f0621f859ca4f5287be", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c976c115a0d788808f7e71834c8eb0844f678d02", + "reference": "c976c115a0d788808f7e71834c8eb0844f678d02", "shasum": "" }, "require": { @@ -4541,7 +4618,7 @@ "type": "tidelift" } ], - "time": "2020-08-17T07:42:30+00:00" + "time": "2020-09-18T14:27:32+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -5606,28 +5683,28 @@ }, { "name": "phpspec/prophecy", - "version": "1.11.1", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2", - "phpdocumentor/reflection-docblock": "^5.0", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^8.0 || ^9.0 <9.3" }, "type": "library", "extra": { @@ -5665,7 +5742,7 @@ "spy", "stub" ], - "time": "2020-07-08T12:44:21+00:00" + "time": "2020-09-29T09:10:42+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/database/factories/NewsFactory.php b/database/factories/NewsFactory.php new file mode 100644 index 0000000..473713c --- /dev/null +++ b/database/factories/NewsFactory.php @@ -0,0 +1,19 @@ + $this->faker->words(2, true), + 'text' => $this->faker->text, + ]; + } +} diff --git a/database/migrations/2020_10_01_153124_create_news_table.php b/database/migrations/2020_10_01_153124_create_news_table.php new file mode 100644 index 0000000..05e301e --- /dev/null +++ b/database/migrations/2020_10_01_153124_create_news_table.php @@ -0,0 +1,33 @@ +id(); + $table->string('name'); + $table->text('text'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('news'); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 0b25e0f..c4fb86e 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -16,5 +16,6 @@ class DatabaseSeeder extends Seeder public function run() { $this->call(\Database\Seeders\UsersTableSeeder::class); + $this->call(\Database\Seeders\NewsTableSeeder::class); } } diff --git a/database/seeds/NewsTableSeeder.php b/database/seeds/NewsTableSeeder.php new file mode 100644 index 0000000..6cd5d8f --- /dev/null +++ b/database/seeds/NewsTableSeeder.php @@ -0,0 +1,19 @@ +count(4)->create(); + } +} diff --git a/resources/views/layouts/base/header.blade.php b/resources/views/layouts/base/header.blade.php index 8dca032..f117cfe 100644 --- a/resources/views/layouts/base/header.blade.php +++ b/resources/views/layouts/base/header.blade.php @@ -16,6 +16,10 @@ {{ __('Contact Us') }} @else + + diff --git a/resources/views/news/index.blade.php b/resources/views/news/index.blade.php new file mode 100644 index 0000000..bea3f86 --- /dev/null +++ b/resources/views/news/index.blade.php @@ -0,0 +1,47 @@ +@extends('layouts.app') + +@section('header') + @include('layouts.base.header') +@endsection + +@section('content') +
+
+
+

News

+ +
+ @forelse($news as $new) +
+
+ new #{{ $new->id }} + +

{{ $new->name }}

+ +
{{ $new->created_at->toFormattedDateString() }}
+ +

{{ str_limit($new->text, $limit = 100, $end = '...') }}

+
+ +{{--
--}} +{{-- Edit--}} + +{{--
--}} +{{-- @csrf--}} +{{-- @method('DELETE')--}} +{{-- --}} +{{--
--}} +{{--
--}} +
+ @empty +

No available news yet

+ @endforelse +
+
+
+
+@endsection + +@section('footer') + @include('layouts.base.footer') +@endsection diff --git a/routes/web.php b/routes/web.php index a96340d..8b7b747 100644 --- a/routes/web.php +++ b/routes/web.php @@ -8,6 +8,8 @@ Route::get('/posts', 'PostsController@userPosts')->name('user.posts'); Route::resource('posts', PostsController::class)->except(['index']); +Route::get('/news', 'NewsController@index')->name('news.index'); + Route::get('/about', 'StaticPagesController@aboutIndex')->name('about'); Route::get('/contacts', 'StaticPagesController@contactsIndex')->name('contacts'); From 4b74b066c6ad66b03274762f560e57ff7f72b0dc Mon Sep 17 00:00:00 2001 From: apsky Date: Fri, 2 Oct 2020 16:42:03 +0300 Subject: [PATCH 02/18] create news routes and pages --- .../Controllers/AdministrationController.php | 7 ++- app/Http/Controllers/NewsController.php | 19 +++++--- app/View/Components/NewForm.php | 20 +++++++++ .../2020_10_01_153124_create_news_table.php | 7 +-- resources/views/components/new-form.blade.php | 43 +++++++++++++++++++ .../views/components/post-form.blade.php | 2 +- .../layouts/admin/admin-header.blade.php | 12 +++++- resources/views/news/create.blade.php | 28 ++++++++++++ resources/views/news/edit.blade.php | 28 ++++++++++++ resources/views/news/index.blade.php | 18 ++++---- resources/views/news/show.blade.php | 39 +++++++++++++++++ resources/views/posts/index.blade.php | 2 +- routes/web.php | 25 ++++++----- 13 files changed, 213 insertions(+), 37 deletions(-) create mode 100644 app/View/Components/NewForm.php create mode 100644 resources/views/components/new-form.blade.php create mode 100644 resources/views/news/create.blade.php create mode 100644 resources/views/news/edit.blade.php create mode 100644 resources/views/news/show.blade.php diff --git a/app/Http/Controllers/AdministrationController.php b/app/Http/Controllers/AdministrationController.php index c796560..b6f52b5 100644 --- a/app/Http/Controllers/AdministrationController.php +++ b/app/Http/Controllers/AdministrationController.php @@ -2,8 +2,8 @@ namespace App\Http\Controllers; +use App\News; use App\Post; -use Illuminate\Http\Request; class AdministrationController extends Controller { @@ -20,4 +20,9 @@ public function posts() { $posts = Post::with('tags')->latest()->get(); return view('/admin.posts', compact('posts')); } + + public function news() { + $news = News::all(); + return view('/news.index', compact('news')); + } } diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index 4634f4a..ec8a100 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -15,7 +15,7 @@ public function index() public function create() { -// return view('news.create'); + return view('news.create'); } public function store(Request $request) @@ -23,19 +23,26 @@ public function store(Request $request) // } - public function show(News $news) + public function show(News $new) { - // + return view('news.show', compact('new')); } - public function edit(News $news) + public function edit(News $new) { - // + return view('news.edit', compact('new')); } public function update(Request $request, News $news) { - // + $values = $request->validate([ + 'name' => 'required|unique:news|max:100', + 'text' => 'required', + ]); + + $news->update($values); + + return back(); } public function destroy(News $news) diff --git a/app/View/Components/NewForm.php b/app/View/Components/NewForm.php new file mode 100644 index 0000000..27e6336 --- /dev/null +++ b/app/View/Components/NewForm.php @@ -0,0 +1,20 @@ +new = $new; + } + + public function render() + { + return view('components.new-form', ['new' => $this->new]); + } +} diff --git a/database/migrations/2020_10_01_153124_create_news_table.php b/database/migrations/2020_10_01_153124_create_news_table.php index 05e301e..7c16841 100644 --- a/database/migrations/2020_10_01_153124_create_news_table.php +++ b/database/migrations/2020_10_01_153124_create_news_table.php @@ -15,17 +15,12 @@ public function up() { Schema::create('news', function (Blueprint $table) { $table->id(); - $table->string('name'); + $table->string('name', 100); $table->text('text'); $table->timestamps(); }); } - /** - * Reverse the migrations. - * - * @return void - */ public function down() { Schema::dropIfExists('news'); diff --git a/resources/views/components/new-form.blade.php b/resources/views/components/new-form.blade.php new file mode 100644 index 0000000..ce2f6a8 --- /dev/null +++ b/resources/views/components/new-form.blade.php @@ -0,0 +1,43 @@ +
+
+ + + +
+ New Name is required. +
+ + @error('name') +
+ {{ $message }} +
+ @enderror +
+ +
+ + + +
+ New Text is required. +
+ + @error('text') +
+ {{ $message }} +
+ @enderror +
+
diff --git a/resources/views/components/post-form.blade.php b/resources/views/components/post-form.blade.php index 88592c0..9e0f978 100644 --- a/resources/views/components/post-form.blade.php +++ b/resources/views/components/post-form.blade.php @@ -73,7 +73,7 @@ class="form-control @error('text') is-invalid @enderror" required="">{{ old('text', $post->text) }}
- Post Description is required. + Post Text is required.
@error('text') diff --git a/resources/views/layouts/admin/admin-header.blade.php b/resources/views/layouts/admin/admin-header.blade.php index 2d84ef7..6747968 100644 --- a/resources/views/layouts/admin/admin-header.blade.php +++ b/resources/views/layouts/admin/admin-header.blade.php @@ -21,11 +21,19 @@ + + + + diff --git a/resources/views/news/create.blade.php b/resources/views/news/create.blade.php new file mode 100644 index 0000000..034e5d8 --- /dev/null +++ b/resources/views/news/create.blade.php @@ -0,0 +1,28 @@ +@extends('layouts.app') + +@section('header') + @include('layouts.admin.admin-header') +@endsection + +@section('content') +
+
+
+

Creating New

+ +
+ @csrf + + + + +
+
+
+
+@endsection + + +@section('footer') + @include('layouts.admin.admin-footer') +@endsection diff --git a/resources/views/news/edit.blade.php b/resources/views/news/edit.blade.php new file mode 100644 index 0000000..ba93000 --- /dev/null +++ b/resources/views/news/edit.blade.php @@ -0,0 +1,28 @@ +@extends('layouts.app') + +@section('header') + @include('layouts.admin.admin-header') +@endsection + +@section('content') +
+
+
+

Edit new #{{ $new->id }}

+ +
+ @csrf + @method('patch') + + + + +
+
+
+
+@endsection + +@section('footer') + @include('layouts.admin.admin-footer') +@endsection diff --git a/resources/views/news/index.blade.php b/resources/views/news/index.blade.php index bea3f86..2af3b05 100644 --- a/resources/views/news/index.blade.php +++ b/resources/views/news/index.blade.php @@ -20,18 +20,16 @@
{{ $new->created_at->toFormattedDateString() }}
-

{{ str_limit($new->text, $limit = 100, $end = '...') }}

- +

{{ str_limit($new->text, $limit = 200, $end = '...') }}

-{{--
--}} -{{-- Edit--}} +
+ Read -{{--
--}} -{{-- @csrf--}} -{{-- @method('DELETE')--}} -{{-- --}} -{{--
--}} -{{--
--}} + @if(auth()->user()->hasRole('admin')) + Edit + @endif +
+ @empty

No available news yet

diff --git a/resources/views/news/show.blade.php b/resources/views/news/show.blade.php new file mode 100644 index 0000000..cfe96bb --- /dev/null +++ b/resources/views/news/show.blade.php @@ -0,0 +1,39 @@ +@extends('layouts.app') + +@section('header') + @include('layouts.base.header') +@endsection + +@section('content') +
+
+

New #{{ $new->id }}

+ +
+
+
+

Name : {{ $new->name }}

+ +
Created at : + {{ $new->created_at->toFormattedDateString() }} +
+
+
+ +
+

Text

+ +

{{ $new->text }}

+
+ + @if(auth()->user()->hasRole('admin')) + Edit new + @endif +
+
+
+@endsection + +@section('footer') + @include('layouts.base.footer') +@endsection diff --git a/resources/views/posts/index.blade.php b/resources/views/posts/index.blade.php index 2d9cb38..da15730 100644 --- a/resources/views/posts/index.blade.php +++ b/resources/views/posts/index.blade.php @@ -44,7 +44,7 @@
- Edit + Edit
@csrf diff --git a/routes/web.php b/routes/web.php index 8b7b747..6babcf0 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,21 +3,26 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Route; -Route::get('/tags/{tag}', 'TagsController@index')->name('tags.show'); -Route::get('/', 'PostsController@index')->name('home'); -Route::get('/posts', 'PostsController@userPosts')->name('user.posts'); +Route::get('/tags/{tag}', [App\Http\Controllers\TagsController::class,'index'])->name('tags.show'); +Route::get('/', [App\Http\Controllers\PostsController::class,'index'])->name('home'); +Route::get('/posts', [App\Http\Controllers\PostsController::class,'userPosts'])->name('user.posts'); + Route::resource('posts', PostsController::class)->except(['index']); +Route::resource('news', NewsController::class)->except(['create', 'edit']); + +Route::get('/admin/news/create', [App\Http\Controllers\NewsController::class,'create'])->name('news.create'); -Route::get('/news', 'NewsController@index')->name('news.index'); +Route::get('/admin/news/{new}/edit', [App\Http\Controllers\NewsController::class,'edit'])->name('news.edit');; -Route::get('/about', 'StaticPagesController@aboutIndex')->name('about'); +Route::get('/about', [App\Http\Controllers\StaticPagesController::class,'aboutIndex'])->name('about'); -Route::get('/contacts', 'StaticPagesController@contactsIndex')->name('contacts'); +Route::get('/contacts', [App\Http\Controllers\StaticPagesController::class,'contactsIndex'])->name('contacts'); -Route::get('/admin', 'AdministrationController@index')->name('admin'); -Route::get('/admin/posts', 'AdministrationController@posts')->name('admin.posts'); +Route::get('/admin', [App\Http\Controllers\AdministrationController::class,'index'])->name('admin'); +Route::get('/admin/posts', [App\Http\Controllers\AdministrationController::class,'posts'])->name('admin.posts'); +Route::get('/admin/news', [App\Http\Controllers\AdministrationController::class,'news'])->name('admin.news'); -Route::get('/admin/feedbacks', 'FeedbacksController@index')->name('feedback');; -Route::post('/admin/feedbacks', 'FeedbacksController@store'); +Route::get('/admin/feedbacks', [App\Http\Controllers\FeedbacksController::class,'index'])->name('feedback');; +Route::post('/admin/feedbacks', [App\Http\Controllers\FeedbacksController::class,'store']); Auth::routes(); From e1ec37890b46ad4b51216b57d45639f6cfb618a1 Mon Sep 17 00:00:00 2001 From: apsky Date: Mon, 5 Oct 2020 17:45:08 +0300 Subject: [PATCH 03/18] edit news controller --- .../Controllers/AdministrationController.php | 2 +- app/Http/Controllers/NewsController.php | 36 +++++++++---- app/News.php | 2 - resources/views/admin/news.blade.php | 52 +++++++++++++++++++ .../layouts/admin/admin-header.blade.php | 2 + resources/views/news/index.blade.php | 9 +++- resources/views/news/show.blade.php | 10 ++-- 7 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 resources/views/admin/news.blade.php diff --git a/app/Http/Controllers/AdministrationController.php b/app/Http/Controllers/AdministrationController.php index b6f52b5..f6ac2d8 100644 --- a/app/Http/Controllers/AdministrationController.php +++ b/app/Http/Controllers/AdministrationController.php @@ -23,6 +23,6 @@ public function posts() { public function news() { $news = News::all(); - return view('/news.index', compact('news')); + return view('/admin.news', compact('news')); } } diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index ec8a100..f20792c 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -4,9 +4,18 @@ use App\News; use Illuminate\Http\Request; +use Illuminate\Validation\Rule; class NewsController extends Controller { + public function validateRequest($request, $new) + { + return $request->validate([ + 'name' => ['required', 'max:100', Rule::unique('news')->ignore($new->id)], + 'text' => 'required' + ]); + } + public function index() { $news = News::all(); @@ -20,33 +29,40 @@ public function create() public function store(Request $request) { - // + $values = $this->validateRequest($request, new News()); + + $new = News::create($values); + flash('New created successfully'); + + return back(); } - public function show(News $new) + public function show(News $news) { - return view('news.show', compact('new')); + return view('news.show', compact('news')); } - public function edit(News $new) + public function edit(News $news) { - return view('news.edit', compact('new')); + return view('news.edit', compact('news')); } public function update(Request $request, News $news) { - $values = $request->validate([ - 'name' => 'required|unique:news|max:100', - 'text' => 'required', - ]); + $values = $this->validateRequest($request, $news); $news->update($values); + flash( 'New updated successfully'); return back(); } public function destroy(News $news) { - // + $news->delete(); + + flash( 'New deleted successfully'); + + return back(0); } } diff --git a/app/News.php b/app/News.php index 1e647a1..9675dd4 100644 --- a/app/News.php +++ b/app/News.php @@ -10,6 +10,4 @@ class News extends Model use HasFactory; protected $guarded = []; - - } diff --git a/resources/views/admin/news.blade.php b/resources/views/admin/news.blade.php new file mode 100644 index 0000000..0891d34 --- /dev/null +++ b/resources/views/admin/news.blade.php @@ -0,0 +1,52 @@ +@extends('layouts.app') + +@section('header') + @include('layouts.admin.admin-header') +@endsection + +@section('content') +
+
+
+

News

+ +
+ @forelse($news as $new) +
+
+ new #{{ $new->id }} + +

{{ $new->name }}

+ +
{{ $new->created_at->toFormattedDateString() }}
+ +

{{ str_limit($new->text, $limit = 200, $end = '...') }}

+ +
+ Read + + Edit + + + @csrf + @method('DELETE') + + + + +{{-- Delete--}} +
+
+
+ @empty +

No available news yet

+ @endforelse +
+
+
+
+@endsection + +@section('footer') + @include('layouts.admin.admin-footer') +@endsection diff --git a/resources/views/layouts/admin/admin-header.blade.php b/resources/views/layouts/admin/admin-header.blade.php index 6747968..d1dd36f 100644 --- a/resources/views/layouts/admin/admin-header.blade.php +++ b/resources/views/layouts/admin/admin-header.blade.php @@ -71,4 +71,6 @@
+ + @include('layouts.notifications.flash_messages') diff --git a/resources/views/news/index.blade.php b/resources/views/news/index.blade.php index 2af3b05..41e932a 100644 --- a/resources/views/news/index.blade.php +++ b/resources/views/news/index.blade.php @@ -26,7 +26,14 @@ Read @if(auth()->user()->hasRole('admin')) - Edit + Edit + +
+ @csrf + @method('DELETE') + + +
@endif diff --git a/resources/views/news/show.blade.php b/resources/views/news/show.blade.php index cfe96bb..011383d 100644 --- a/resources/views/news/show.blade.php +++ b/resources/views/news/show.blade.php @@ -7,15 +7,15 @@ @section('content')
-

New #{{ $new->id }}

+

New #{{ $news->id }}

-

Name : {{ $new->name }}

+

Name : {{ $news->name }}

Created at : - {{ $new->created_at->toFormattedDateString() }} + {{ $news->created_at->toFormattedDateString() }}
@@ -23,11 +23,11 @@

Text

-

{{ $new->text }}

+

{{ $news->text }}

@if(auth()->user()->hasRole('admin')) - Edit new + Edit new @endif
From 0f154eb5a0496efb349def1903130d68991831aa Mon Sep 17 00:00:00 2001 From: apsky Date: Tue, 6 Oct 2020 17:44:41 +0300 Subject: [PATCH 04/18] create pivot table tags with news --- .../Controllers/AdministrationController.php | 2 +- app/Http/Controllers/NewsController.php | 22 +++++++++--------- app/NewTag.php | 10 ++++++++ app/News.php | 5 ++++ app/Tag.php | 5 ++++ ...2020_10_06_152240_create_new_tag_table.php | 23 +++++++++++++++++++ database/seeds/DatabaseSeeder.php | 2 +- database/seeds/NewsTableSeeder.php | 2 +- database/seeds/UsersTableSeeder.php | 7 ++++++ resources/views/admin/news.blade.php | 20 ++++++++++------ resources/views/news/index.blade.php | 20 ++++++++++++---- resources/views/news/show.blade.php | 10 ++++---- routes/web.php | 16 +++++++------ 13 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 app/NewTag.php create mode 100644 database/migrations/2020_10_06_152240_create_new_tag_table.php diff --git a/app/Http/Controllers/AdministrationController.php b/app/Http/Controllers/AdministrationController.php index f6ac2d8..941169f 100644 --- a/app/Http/Controllers/AdministrationController.php +++ b/app/Http/Controllers/AdministrationController.php @@ -22,7 +22,7 @@ public function posts() { } public function news() { - $news = News::all(); + $news = News::latest()->get(); return view('/admin.news', compact('news')); } } diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index f20792c..61af20b 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -18,7 +18,7 @@ public function validateRequest($request, $new) public function index() { - $news = News::all(); + $news = News::with('tags')->latest()->get(); return view('news.index', compact('news')); } @@ -37,32 +37,32 @@ public function store(Request $request) return back(); } - public function show(News $news) + public function show(News $new) { - return view('news.show', compact('news')); + return view('news.show', compact('new')); } - public function edit(News $news) + public function edit(News $new) { - return view('news.edit', compact('news')); + return view('news.edit', compact('new')); } - public function update(Request $request, News $news) + public function update(Request $request, News $new) { - $values = $this->validateRequest($request, $news); + $values = $this->validateRequest($request, $new); - $news->update($values); + $new->update($values); flash( 'New updated successfully'); return back(); } - public function destroy(News $news) + public function destroy(News $new) { - $news->delete(); + $new->delete(); flash( 'New deleted successfully'); - return back(0); + return back(); } } diff --git a/app/NewTag.php b/app/NewTag.php new file mode 100644 index 0000000..b0cba3d --- /dev/null +++ b/app/NewTag.php @@ -0,0 +1,10 @@ +belongsToMany(Tag::class, 'new_tag', 'new_id', 'tag_id'); + } } diff --git a/app/Tag.php b/app/Tag.php index 8df7266..4d5d2cb 100644 --- a/app/Tag.php +++ b/app/Tag.php @@ -18,6 +18,11 @@ public function posts() return $this->belongsToMany(Post::class); } + public function news() + { + return $this->belongsToMany(News::class, 'new_tag', 'tag_id', 'new_id'); + } + public function getRouteKeyName() { return 'name'; diff --git a/database/migrations/2020_10_06_152240_create_new_tag_table.php b/database/migrations/2020_10_06_152240_create_new_tag_table.php new file mode 100644 index 0000000..ce24968 --- /dev/null +++ b/database/migrations/2020_10_06_152240_create_new_tag_table.php @@ -0,0 +1,23 @@ +foreignId('new_id')->constrained('news')->onDelete('Cascade'); + $table->foreignId('tag_id')->constrained('tags')->onDelete('Cascade'); + + $table->primary(['new_id', 'tag_id']); + }); + } + + public function down() + { + Schema::dropIfExists('new_tag'); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index c4fb86e..ced1eb1 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -15,7 +15,7 @@ class DatabaseSeeder extends Seeder */ public function run() { - $this->call(\Database\Seeders\UsersTableSeeder::class); $this->call(\Database\Seeders\NewsTableSeeder::class); + $this->call(\Database\Seeders\UsersTableSeeder::class); } } diff --git a/database/seeds/NewsTableSeeder.php b/database/seeds/NewsTableSeeder.php index 6cd5d8f..b5788cd 100644 --- a/database/seeds/NewsTableSeeder.php +++ b/database/seeds/NewsTableSeeder.php @@ -14,6 +14,6 @@ class NewsTableSeeder extends Seeder */ public function run() { - News::factory()->count(4)->create(); + News::factory()->count(4)->hasTags(2)->create(); } } diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index 2f4ab8a..6e72fa5 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -2,6 +2,7 @@ namespace Database\Seeders; +use App\News; use App\Permission; use App\Post; use App\Role; @@ -43,5 +44,11 @@ public function run() }); }) ; + + $news = News::all(); + + foreach ($news as $new) { + $new->tags()->attach($tags->random(random_int(0,1))); + } } } diff --git a/resources/views/admin/news.blade.php b/resources/views/admin/news.blade.php index 0891d34..32458dc 100644 --- a/resources/views/admin/news.blade.php +++ b/resources/views/admin/news.blade.php @@ -7,13 +7,13 @@ @section('content')
-
-

News

+
+

News

-
+
@forelse($news as $new)
-
+
new #{{ $new->id }}

{{ $new->name }}

@@ -22,7 +22,15 @@

{{ str_limit($new->text, $limit = 200, $end = '...') }}

-
+ @if($new->tags->isNotEmpty()) + + @endif + +
Read Edit @@ -33,8 +41,6 @@ - -{{-- Delete--}}
diff --git a/resources/views/news/index.blade.php b/resources/views/news/index.blade.php index 41e932a..4d71717 100644 --- a/resources/views/news/index.blade.php +++ b/resources/views/news/index.blade.php @@ -7,13 +7,13 @@ @section('content')
-
-

News

+
+

News

-
+
@forelse($news as $new) -
-
+
+
new #{{ $new->id }}

{{ $new->name }}

@@ -22,6 +22,14 @@

{{ str_limit($new->text, $limit = 200, $end = '...') }}

+ @if($new->tags->isNotEmpty()) + + @endif +
Read @@ -42,6 +50,8 @@

No available news yet

@endforelse
+ + @include('layouts.aside-tags')
diff --git a/resources/views/news/show.blade.php b/resources/views/news/show.blade.php index 011383d..ce45e9d 100644 --- a/resources/views/news/show.blade.php +++ b/resources/views/news/show.blade.php @@ -7,15 +7,15 @@ @section('content')
-

New #{{ $news->id }}

+

New #{{ $new->id }}

-

Name : {{ $news->name }}

+

Name : {{ $new->name }}

Created at : - {{ $news->created_at->toFormattedDateString() }} + {{ $new->created_at->toFormattedDateString() }}
@@ -23,11 +23,11 @@

Text

-

{{ $news->text }}

+

{{ $new->text }}

@if(auth()->user()->hasRole('admin')) - Edit new + Edit @endif
diff --git a/routes/web.php b/routes/web.php index 6babcf0..5b2331c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,20 +3,19 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Route; +Route::get('/test', function () { + +}); + Route::get('/tags/{tag}', [App\Http\Controllers\TagsController::class,'index'])->name('tags.show'); Route::get('/', [App\Http\Controllers\PostsController::class,'index'])->name('home'); Route::get('/posts', [App\Http\Controllers\PostsController::class,'userPosts'])->name('user.posts'); Route::resource('posts', PostsController::class)->except(['index']); -Route::resource('news', NewsController::class)->except(['create', 'edit']); +Route::resource('news', NewsController::class)->except(['create', 'edit'])->parameters(['news' => 'new']); Route::get('/admin/news/create', [App\Http\Controllers\NewsController::class,'create'])->name('news.create'); - -Route::get('/admin/news/{new}/edit', [App\Http\Controllers\NewsController::class,'edit'])->name('news.edit');; - -Route::get('/about', [App\Http\Controllers\StaticPagesController::class,'aboutIndex'])->name('about'); - -Route::get('/contacts', [App\Http\Controllers\StaticPagesController::class,'contactsIndex'])->name('contacts'); +Route::get('/admin/news/{new}/edit', [App\Http\Controllers\NewsController::class,'edit'])->name('news.edit'); Route::get('/admin', [App\Http\Controllers\AdministrationController::class,'index'])->name('admin'); Route::get('/admin/posts', [App\Http\Controllers\AdministrationController::class,'posts'])->name('admin.posts'); @@ -25,4 +24,7 @@ Route::get('/admin/feedbacks', [App\Http\Controllers\FeedbacksController::class,'index'])->name('feedback');; Route::post('/admin/feedbacks', [App\Http\Controllers\FeedbacksController::class,'store']); +Route::get('/about', [App\Http\Controllers\StaticPagesController::class,'aboutIndex'])->name('about'); +Route::get('/contacts', [App\Http\Controllers\StaticPagesController::class,'contactsIndex'])->name('contacts'); + Auth::routes(); From ae1362c58d7ecaf84f7e11886ec8e8176caeb24a Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Tue, 6 Oct 2020 23:47:52 +0300 Subject: [PATCH 05/18] change templates --- app/Http/Controllers/TagsController.php | 3 +- app/Providers/AppServiceProvider.php | 12 +++- resources/views/admin/news.blade.php | 47 +------------- resources/views/admin/posts.blade.php | 50 +-------------- resources/views/layouts/aside-tags.blade.php | 2 +- .../views/layouts/news/news-section.blade.php | 50 +++++++++++++++ .../layouts/posts/posts-section.blade.php | 57 +++++++++++++++++ resources/views/layouts/tags/index.blade.php | 61 +++++++++++++++++++ .../layouts/{posts => tags}/tags.blade.php | 0 resources/views/news/index.blade.php | 51 +--------------- resources/views/posts/index.blade.php | 58 +----------------- 11 files changed, 185 insertions(+), 206 deletions(-) create mode 100644 resources/views/layouts/news/news-section.blade.php create mode 100644 resources/views/layouts/posts/posts-section.blade.php create mode 100644 resources/views/layouts/tags/index.blade.php rename resources/views/layouts/{posts => tags}/tags.blade.php (100%) diff --git a/app/Http/Controllers/TagsController.php b/app/Http/Controllers/TagsController.php index 76820d0..a05f310 100644 --- a/app/Http/Controllers/TagsController.php +++ b/app/Http/Controllers/TagsController.php @@ -10,6 +10,7 @@ class TagsController extends Controller public function index(Tag $tag) { $posts = $tag->posts()->with('tags')->get(); - return view('index', compact('posts')); + $news = $tag->news()->with('tags')->get(); + return view('index', compact('posts', 'news')); } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 3210700..1ace8fb 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,8 @@ namespace App\Providers; +use App\NewTag; +use App\PostTag; use App\Tag; use Illuminate\Support\ServiceProvider; @@ -15,7 +17,13 @@ class AppServiceProvider extends ServiceProvider public function register() { view()->composer('layouts.aside-tags', function ($view) { - $view->with('tagsCloud', Tag::all()); + $postsTags = PostTag::all()->unique('tag_id')->keyBy('tag_id'); + $newsTags = NewTag::all()->unique('tag_id')->keyBy('tag_id'); + $keys = $postsTags->mergeRecursive($newsTags)->keyBy('tag_id')->keys()->sort(); + + $postsAndNewsTags = Tag::all()->whereIn('id', $keys); + + $view->with('tagsCloud', $postsAndNewsTags); }); } @@ -26,6 +34,6 @@ public function register() */ public function boot() { - // + } } diff --git a/resources/views/admin/news.blade.php b/resources/views/admin/news.blade.php index 32458dc..84a0675 100644 --- a/resources/views/admin/news.blade.php +++ b/resources/views/admin/news.blade.php @@ -5,52 +5,7 @@ @endsection @section('content') -
-
-
-

News

- -
- @forelse($news as $new) -
-
- new #{{ $new->id }} - -

{{ $new->name }}

- -
{{ $new->created_at->toFormattedDateString() }}
- -

{{ str_limit($new->text, $limit = 200, $end = '...') }}

- - @if($new->tags->isNotEmpty()) - - @endif - -
- Read - - Edit - -
- @csrf - @method('DELETE') - - -
-
-
-
- @empty -

No available news yet

- @endforelse -
-
-
-
+ @include('layouts.news.news-section') @endsection @section('footer') diff --git a/resources/views/admin/posts.blade.php b/resources/views/admin/posts.blade.php index 0b1ca96..992f240 100644 --- a/resources/views/admin/posts.blade.php +++ b/resources/views/admin/posts.blade.php @@ -5,55 +5,7 @@ @endsection @section('content') -
-
-
-

Posts

- - @if ($posts->count()) -
- @foreach($posts as $post) -
-
-
- Post #{{ $post->id }} - -

{{ $post->name }}

- -
{{ $post->created_at->toFormattedDateString() }}
- -

{{ str_limit($post->text, $limit = 100, $end = '...') }}

- - Continue reading -
- -
- - Placeholder - - Thumbnail - -
- -
- Edit - -
- @csrf - @method('DELETE') - -
-
-
-
- @endforeach -
- @else -

No available posts yet

- @endif -
-
-
+ @include('layouts.posts.posts-section') @endsection @section('footer') diff --git a/resources/views/layouts/aside-tags.blade.php b/resources/views/layouts/aside-tags.blade.php index 1908564..c3a93f8 100644 --- a/resources/views/layouts/aside-tags.blade.php +++ b/resources/views/layouts/aside-tags.blade.php @@ -2,7 +2,7 @@ @if($tagsCloud->isNotEmpty())

Available Tags

- @include('layouts.posts.tags', ['tags' => $tagsCloud]) + @include('layouts.tags.tags', ['tags' => $tagsCloud]) @else

No available tags

@endif diff --git a/resources/views/layouts/news/news-section.blade.php b/resources/views/layouts/news/news-section.blade.php new file mode 100644 index 0000000..4916704 --- /dev/null +++ b/resources/views/layouts/news/news-section.blade.php @@ -0,0 +1,50 @@ +
+
+
+

News

+ +
+ @forelse($news as $new) +
+
+ new #{{ $new->id }} + +

{{ $new->name }}

+ +
{{ $new->created_at->toFormattedDateString() }}
+ +

{{ str_limit($new->text, $limit = 200, $end = '...') }}

+ + @if($new->tags->isNotEmpty()) + + @endif + +
+ Read + + @if(auth()->user()->hasRole('admin')) + Edit + +
+ @csrf + @method('DELETE') + + +
+ @endif +
+
+
+ @empty +

No available news yet

+ @endforelse +
+ + @include('layouts.aside-tags') +
+
+
diff --git a/resources/views/layouts/posts/posts-section.blade.php b/resources/views/layouts/posts/posts-section.blade.php new file mode 100644 index 0000000..f4c9c00 --- /dev/null +++ b/resources/views/layouts/posts/posts-section.blade.php @@ -0,0 +1,57 @@ +
+
+
+

Posts

+ + @if ($posts->count()) +
+ @foreach($posts as $post) +
+
+
+ Post #{{ $post->id }} + +

{{ $post->name }}

+ +
{{ $post->created_at->toFormattedDateString() }}
+ +

{{ str_limit($post->text, $limit = 100, $end = '...') }}

+ + @if($post->tags->isNotEmpty()) + + @endif + + Continue reading +
+ +
+ + Placeholder + + Thumbnail + +
+ +
+ Edit + +
+ @csrf + @method('DELETE') + +
+
+
+
+ @endforeach +
+ @else +

No available posts yet

+ @endif +
+
+
diff --git a/resources/views/layouts/tags/index.blade.php b/resources/views/layouts/tags/index.blade.php new file mode 100644 index 0000000..eda5f07 --- /dev/null +++ b/resources/views/layouts/tags/index.blade.php @@ -0,0 +1,61 @@ +@extends('layouts.app') + +@section('header') + @include('layouts.base.header') +@endsection + +@section('content') +
+
+
+
+

Latest posts

+ + @if ($posts->count()) +
+ @foreach($posts as $post) +
+
+
+ Post #{{ $post->id }} + +

{{ $post->name }}

+ +
{{ $post->created_at->toFormattedDateString() }}
+ +

{{ str_limit($post->text, $limit = 100, $end = '...') }}

+ + @if($post->tags->isNotEmpty()) + + @endif + + Continue reading +
+ +
+ + Placeholder + + Thumbnail + +
+
+
+ @endforeach +
+ @else +

No available posts yet

+ @endif +
+
+
+
+@endsection + +@section('footer') + @include('layouts.base.footer') +@endsection diff --git a/resources/views/layouts/posts/tags.blade.php b/resources/views/layouts/tags/tags.blade.php similarity index 100% rename from resources/views/layouts/posts/tags.blade.php rename to resources/views/layouts/tags/tags.blade.php diff --git a/resources/views/news/index.blade.php b/resources/views/news/index.blade.php index 4d71717..2d050a3 100644 --- a/resources/views/news/index.blade.php +++ b/resources/views/news/index.blade.php @@ -5,56 +5,7 @@ @endsection @section('content') -
-
-
-

News

- -
- @forelse($news as $new) -
-
- new #{{ $new->id }} - -

{{ $new->name }}

- -
{{ $new->created_at->toFormattedDateString() }}
- -

{{ str_limit($new->text, $limit = 200, $end = '...') }}

- - @if($new->tags->isNotEmpty()) - - @endif - -
- Read - - @if(auth()->user()->hasRole('admin')) - Edit - -
- @csrf - @method('DELETE') - - -
- @endif -
-
-
- @empty -

No available news yet

- @endforelse -
- - @include('layouts.aside-tags') -
-
-
+ @include('layouts.news.news-section') @endsection @section('footer') diff --git a/resources/views/posts/index.blade.php b/resources/views/posts/index.blade.php index da15730..11b8bd0 100644 --- a/resources/views/posts/index.blade.php +++ b/resources/views/posts/index.blade.php @@ -5,63 +5,7 @@ @endsection @section('content') -
-
-
-

Posts

- - @if ($posts->count()) -
- @foreach($posts as $post) -
-
-
- Post #{{ $post->id }} - -

{{ $post->name }}

- -
{{ $post->created_at->toFormattedDateString() }}
- -

{{ str_limit($post->text, $limit = 100, $end = '...') }}

- - @if($post->tags->isNotEmpty()) - - @endif - - Continue reading -
- -
- - Placeholder - - Thumbnail - -
- -
- Edit - -
- @csrf - @method('DELETE') - -
-
-
-
- @endforeach -
- @else -

No available posts yet

- @endif -
-
-
+ @include('layouts.posts.posts-section') @endsection @section('footer') From 74c6e878e39437098ad10d7652127c9a337c05e7 Mon Sep 17 00:00:00 2001 From: apsky Date: Wed, 7 Oct 2020 17:45:57 +0300 Subject: [PATCH 06/18] edit frontend --- app/Http/Controllers/NewsController.php | 21 ++++ app/Http/Controllers/PostsController.php | 32 +------ app/helpers.php | 39 ++++++++ resources/views/admin/news.blade.php | 9 +- resources/views/admin/posts.blade.php | 9 +- resources/views/components/new-form.blade.php | 11 +++ resources/views/index.blade.php | 53 ++--------- resources/views/layouts/base/header.blade.php | 2 +- .../views/layouts/news/news-section.blade.php | 71 +++++++------- .../layouts/posts/posts-section.blade.php | 95 +++++++++---------- resources/views/news/index.blade.php | 9 +- resources/views/posts/index.blade.php | 9 +- routes/web.php | 19 ++-- 13 files changed, 202 insertions(+), 177 deletions(-) diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index 61af20b..ebf71d7 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -3,11 +3,18 @@ namespace App\Http\Controllers; use App\News; +use App\NewTag; +use App\Tag; use Illuminate\Http\Request; use Illuminate\Validation\Rule; class NewsController extends Controller { + public function __construct() + { + $this->middleware('role:admin')->except(['index', 'show']); + } + public function validateRequest($request, $new) { return $request->validate([ @@ -32,6 +39,15 @@ public function store(Request $request) $values = $this->validateRequest($request, new News()); $new = News::create($values); + + if (!is_null($request['tags'])) { + $requestTags = explode(', ', $request['tags']); + foreach ($requestTags as $tag) { + $tag = Tag::firstOrCreate(['name' => $tag]); + $new->tags()->attach($tag); + } + } + flash('New created successfully'); return back(); @@ -52,6 +68,11 @@ public function update(Request $request, News $new) $values = $this->validateRequest($request, $new); $new->update($values); + + $newTags = $new->tags->keyBy('name'); + + updateTags($new, $request, NewTag::class); + flash( 'New updated successfully'); return back(); diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index 2d183d2..3de6280 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -29,12 +29,6 @@ public function validateRequest($request, $post) } public function index() - { - $posts = Post::with('tags')->where('published', 1)->latest()->get(); - return view('/index', compact('posts')); - } - - public function userPosts() { $posts = auth()->user()->posts()->with('tags')->latest()->get(); return view('/posts.index', compact('posts')); @@ -96,31 +90,7 @@ public function update(Request $request, Post $post) $post->update($values); - $postTags = $post->tags->keyBy('name'); - - if (!is_null($request['tags'])) { - $requestTags = collect(explode(', ', $request['tags']))->keyBy(function ($item) { return $item; }); - } else { - $requestTags = collect([]); - } - - $deleteTags = $postTags->diffKeys($requestTags); - $addTags = $requestTags->diffKeys($postTags); - - if ($addTags->isNotEmpty()) { - foreach ($addTags as $tag) { - $tag = Tag::firstOrCreate(['name' => $tag]); - $post->tags()->attach($tag); - }; - } - - if ($deleteTags->isNotEmpty()) { - foreach ($deleteTags as $tag) { - $post->tags()->detach($tag); - $isLastTag = PostTag::where('tag_id', $tag->id)->first(); - if (!$isLastTag) $tag->delete(); - }; - } + updateTags($post, $request, PostTag::class); sendMailNotifyToAdmin(new PostEdited($post)); flash( 'Post edited successfully'); diff --git a/app/helpers.php b/app/helpers.php index b7f9ca0..2efe6cc 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,5 +1,7 @@ send($text, $title); } } + +if (! function_exists('updateTags')) { + /** + * @param $model + * @param $request + * @param $pivotTable + */ + + function updateTags($model, $request, $pivotTable) { + $modelTags = $model->tags->keyBy('name'); + + if (!is_null($request['tags'])) { + $requestTags = collect(explode(', ', $request['tags']))->keyBy(function ($item) { return $item; }); + } else { + $requestTags = collect([]); + } + + $deleteTags = $modelTags->diffKeys($requestTags); + $addTags = $requestTags->diffKeys($modelTags); + + if ($addTags->isNotEmpty()) { + foreach ($addTags as $tag) { + $tag = Tag::firstOrCreate(['name' => $tag]); + $model->tags()->attach($tag); + }; + } + + if ($deleteTags->isNotEmpty()) { + foreach ($deleteTags as $tag) { + $model->tags()->detach($tag); + $isLastTag = $pivotTable::where('tag_id', $tag->id)->first(); + if (!$isLastTag) $tag->delete(); + }; + } + } +} + diff --git a/resources/views/admin/news.blade.php b/resources/views/admin/news.blade.php index 84a0675..41aaa19 100644 --- a/resources/views/admin/news.blade.php +++ b/resources/views/admin/news.blade.php @@ -5,7 +5,14 @@ @endsection @section('content') - @include('layouts.news.news-section') +
+
+
+ @include('layouts.news.news-section') + @include('layouts.aside-tags') +
+
+
@endsection @section('footer') diff --git a/resources/views/admin/posts.blade.php b/resources/views/admin/posts.blade.php index 992f240..e1c3bfd 100644 --- a/resources/views/admin/posts.blade.php +++ b/resources/views/admin/posts.blade.php @@ -5,7 +5,14 @@ @endsection @section('content') - @include('layouts.posts.posts-section') +
+
+
+ @include('layouts.posts.posts-section') + @include('layouts.aside-tags') +
+
+
@endsection @section('footer') diff --git a/resources/views/components/new-form.blade.php b/resources/views/components/new-form.blade.php index ce2f6a8..7312548 100644 --- a/resources/views/components/new-form.blade.php +++ b/resources/views/components/new-form.blade.php @@ -40,4 +40,15 @@ class="form-control @error('text') is-invalid @enderror"
@enderror
+ +
+ + +
diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index 5e72341..13c32c1 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -7,51 +7,14 @@ @section('content')
-
-

Latest posts

- - @if ($posts->count()) -
- @foreach($posts as $post) -
-
-
- Post #{{ $post->id }} - -

{{ $post->name }}

- -
{{ $post->created_at->toFormattedDateString() }}
- -

{{ str_limit($post->text, $limit = 100, $end = '...') }}

- - @if($post->tags->isNotEmpty()) - - @endif - - Continue reading -
- -
- - Placeholder - - Thumbnail - -
-
-
- @endforeach -
- - @include('layouts.aside-tags') - @else -

No available posts yet

- @endif -
+
+
+ @include('layouts.posts.posts-section') + @include('layouts.news.news-section') +
+ + @include('layouts.aside-tags') +
@endsection diff --git a/resources/views/layouts/base/header.blade.php b/resources/views/layouts/base/header.blade.php index f117cfe..3fe1f1c 100644 --- a/resources/views/layouts/base/header.blade.php +++ b/resources/views/layouts/base/header.blade.php @@ -21,7 +21,7 @@
+ diff --git a/resources/views/layouts/posts/posts-section.blade.php b/resources/views/layouts/posts/posts-section.blade.php index f4c9c00..e8addcf 100644 --- a/resources/views/layouts/posts/posts-section.blade.php +++ b/resources/views/layouts/posts/posts-section.blade.php @@ -1,57 +1,48 @@ -
-
-
-

Posts

- - @if ($posts->count()) -
- @foreach($posts as $post) -
-
-
- Post #{{ $post->id }} - -

{{ $post->name }}

- -
{{ $post->created_at->toFormattedDateString() }}
- -

{{ str_limit($post->text, $limit = 100, $end = '...') }}

- - @if($post->tags->isNotEmpty()) - - @endif - - Continue reading -
- -
- - Placeholder - - Thumbnail - +
+

Latest posts

+ + @if ($posts->count()) +
+ @foreach($posts as $post) +
+
+
+ Post #{{ $post->id }} + +

{{ $post->name }}

+ +
{{ $post->created_at->toFormattedDateString() }}
+ +

{{ str_limit($post->text, $limit = 100, $end = '...') }}

+ + @if($post->tags->isNotEmpty()) + + @endif - -
- @csrf - @method('DELETE') - -
-
-
+
+ + Placeholder + + Thumbnail +
- @endforeach +
- @else -

No available posts yet

- @endif -
-
-
+ @endforeach +
+ @else +

No available posts yet

+ @endif + diff --git a/resources/views/news/index.blade.php b/resources/views/news/index.blade.php index 2d050a3..b200c8f 100644 --- a/resources/views/news/index.blade.php +++ b/resources/views/news/index.blade.php @@ -5,7 +5,14 @@ @endsection @section('content') - @include('layouts.news.news-section') +
+
+
+ @include('layouts.news.news-section') + @include('layouts.aside-tags') +
+
+
@endsection @section('footer') diff --git a/resources/views/posts/index.blade.php b/resources/views/posts/index.blade.php index 11b8bd0..da78050 100644 --- a/resources/views/posts/index.blade.php +++ b/resources/views/posts/index.blade.php @@ -5,7 +5,14 @@ @endsection @section('content') - @include('layouts.posts.posts-section') +
+
+
+ @include('layouts.posts.posts-section') + @include('layouts.aside-tags') +
+
+
@endsection @section('footer') diff --git a/routes/web.php b/routes/web.php index 5b2331c..327f638 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,7 @@ where('published', 1)->latest()->take(3)->get(); + $news = News::with('tags')->latest()->take(3)->get(); + + return view('/index', compact('posts', 'news')); +})->name('home'); + Route::get('/tags/{tag}', [App\Http\Controllers\TagsController::class,'index'])->name('tags.show'); -Route::get('/', [App\Http\Controllers\PostsController::class,'index'])->name('home'); -Route::get('/posts', [App\Http\Controllers\PostsController::class,'userPosts'])->name('user.posts'); -Route::resource('posts', PostsController::class)->except(['index']); +Route::resource('posts', PostsController::class); Route::resource('news', NewsController::class)->except(['create', 'edit'])->parameters(['news' => 'new']); -Route::get('/admin/news/create', [App\Http\Controllers\NewsController::class,'create'])->name('news.create'); -Route::get('/admin/news/{new}/edit', [App\Http\Controllers\NewsController::class,'edit'])->name('news.edit'); - Route::get('/admin', [App\Http\Controllers\AdministrationController::class,'index'])->name('admin'); Route::get('/admin/posts', [App\Http\Controllers\AdministrationController::class,'posts'])->name('admin.posts'); + Route::get('/admin/news', [App\Http\Controllers\AdministrationController::class,'news'])->name('admin.news'); +Route::get('/admin/news/create', [App\Http\Controllers\NewsController::class,'create'])->name('news.create'); +Route::get('/admin/news/{new}/edit', [App\Http\Controllers\NewsController::class,'edit'])->name('news.edit'); Route::get('/admin/feedbacks', [App\Http\Controllers\FeedbacksController::class,'index'])->name('feedback');; Route::post('/admin/feedbacks', [App\Http\Controllers\FeedbacksController::class,'store']); From eed4eaa229d2bc1173eacc5f075e75ed6d2917f5 Mon Sep 17 00:00:00 2001 From: apsky Date: Thu, 8 Oct 2020 17:40:43 +0300 Subject: [PATCH 07/18] create Tags and Comments morphed tables to Post and News models --- app/Comment.php | 20 ++++ app/Http/Controllers/CommentsController.php | 24 ++++ app/Http/Controllers/NewsController.php | 6 +- app/Http/Controllers/PostsController.php | 8 +- app/Http/Controllers/TagsController.php | 2 +- app/News.php | 8 +- app/Post.php | 8 +- app/Providers/AppServiceProvider.php | 20 ++-- app/Tag.php | 6 +- app/Taggable.php | 10 ++ database/factories/CommentFactory.php | 18 +++ database/factories/NewsFactory.php | 2 +- ...020_09_07_185537_create_post_tag_table.php | 16 +-- ...2020_10_06_152240_create_new_tag_table.php | 14 +-- ...20_10_08_120022_create_taggables_table.php | 32 ++++++ ...020_10_08_143357_create_comments_table.php | 33 ++++++ database/seeds/NewsTableSeeder.php | 2 +- database/seeds/UsersTableSeeder.php | 2 +- resources/views/admin/news.blade.php | 7 +- resources/views/admin/posts.blade.php | 7 +- resources/views/index.blade.php | 17 ++- .../views/layouts/news/news-items.blade.php | 29 +++++ .../views/layouts/news/news-section.blade.php | 45 -------- .../views/layouts/posts/posts-items.blade.php | 40 +++++++ .../layouts/posts/posts-section.blade.php | 48 -------- resources/views/layouts/tags/index.blade.php | 103 +++++++++++++----- resources/views/news/index.blade.php | 7 +- resources/views/news/show.blade.php | 74 +++++++++++-- resources/views/posts/index.blade.php | 7 +- resources/views/posts/show.blade.php | 11 +- routes/web.php | 1 + 31 files changed, 457 insertions(+), 170 deletions(-) create mode 100644 app/Comment.php create mode 100644 app/Http/Controllers/CommentsController.php create mode 100644 app/Taggable.php create mode 100644 database/factories/CommentFactory.php create mode 100644 database/migrations/2020_10_08_120022_create_taggables_table.php create mode 100644 database/migrations/2020_10_08_143357_create_comments_table.php create mode 100644 resources/views/layouts/news/news-items.blade.php delete mode 100644 resources/views/layouts/news/news-section.blade.php create mode 100644 resources/views/layouts/posts/posts-items.blade.php delete mode 100644 resources/views/layouts/posts/posts-section.blade.php diff --git a/app/Comment.php b/app/Comment.php new file mode 100644 index 0000000..f17422d --- /dev/null +++ b/app/Comment.php @@ -0,0 +1,20 @@ +morphTo(); + } +} diff --git a/app/Http/Controllers/CommentsController.php b/app/Http/Controllers/CommentsController.php new file mode 100644 index 0000000..fb7ea13 --- /dev/null +++ b/app/Http/Controllers/CommentsController.php @@ -0,0 +1,24 @@ +validate([ + 'text' => 'required' + ]); + + $values['commentable_id'] = $new->id; + $values['commentable_type'] = News::class; + + $comment = Comment::create($values); + + return back(); + } +} diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index ebf71d7..a7fe3b4 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -12,6 +12,7 @@ class NewsController extends Controller { public function __construct() { + $this->middleware('auth'); $this->middleware('role:admin')->except(['index', 'show']); } @@ -25,7 +26,8 @@ public function validateRequest($request, $new) public function index() { - $news = News::with('tags')->latest()->get(); + $news = News::with(['tags', 'comments'])->latest()->get(); + return view('news.index', compact('news')); } @@ -84,6 +86,6 @@ public function destroy(News $new) flash( 'New deleted successfully'); - return back(); + return redirect('/admin/news'); } } diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index 3de6280..624d96f 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -30,7 +30,7 @@ public function validateRequest($request, $post) public function index() { - $posts = auth()->user()->posts()->with('tags')->latest()->get(); + $posts = auth()->user()->posts()->with(['tags', 'comments'])->latest()->get(); return view('/posts.index', compact('posts')); } @@ -109,6 +109,10 @@ public function destroy(Post $post) flash( 'Post deleted successfully'); pushNotification('Post deleted successfully', 'New Notification'); - return back(); + if (auth()->user()->hasRole('admin')) { + return redirect('/admin/posts'); + } else { + return back(); + } } } diff --git a/app/Http/Controllers/TagsController.php b/app/Http/Controllers/TagsController.php index a05f310..c9f9cf4 100644 --- a/app/Http/Controllers/TagsController.php +++ b/app/Http/Controllers/TagsController.php @@ -11,6 +11,6 @@ public function index(Tag $tag) { $posts = $tag->posts()->with('tags')->get(); $news = $tag->news()->with('tags')->get(); - return view('index', compact('posts', 'news')); + return view('layouts.tags.index', compact('posts', 'news')); } } diff --git a/app/News.php b/app/News.php index 4d543d9..91b9eae 100644 --- a/app/News.php +++ b/app/News.php @@ -13,6 +13,12 @@ class News extends Model public function tags() { - return $this->belongsToMany(Tag::class, 'new_tag', 'new_id', 'tag_id'); +// return $this->belongsToMany(Tag::class, 'new_tag', 'new_id', 'tag_id'); + return $this->morphToMany(Tag::class, 'taggable'); + } + + public function comments() + { + return $this->morphMany(Comment::class, 'commentable'); } } diff --git a/app/Post.php b/app/Post.php index 90c29ac..606725c 100644 --- a/app/Post.php +++ b/app/Post.php @@ -20,11 +20,17 @@ class Post extends Model public function tags() { - return $this->belongsToMany(Tag::class); +// return $this->belongsToMany(Tag::class); + return $this->morphToMany(Tag::class, 'taggable'); } public function owner() { return $this->belongsTo(User::class); } + + public function comments() + { + return $this->morphMany(Comment::class, 'commentable'); + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 1ace8fb..fded2c3 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,9 +2,10 @@ namespace App\Providers; -use App\NewTag; -use App\PostTag; +use App\News; +use App\Post; use App\Tag; +use App\Taggable; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -17,13 +18,18 @@ class AppServiceProvider extends ServiceProvider public function register() { view()->composer('layouts.aside-tags', function ($view) { - $postsTags = PostTag::all()->unique('tag_id')->keyBy('tag_id'); - $newsTags = NewTag::all()->unique('tag_id')->keyBy('tag_id'); - $keys = $postsTags->mergeRecursive($newsTags)->keyBy('tag_id')->keys()->sort(); + $postsAndNewsUniqueTagsID = Taggable::where('taggable_type', News::class) + ->orWhere('taggable_type', Post::class) + ->get() + ->unique('tag_id') + ->keyBy('tag_id') + ->keys() + ->sort() + ; - $postsAndNewsTags = Tag::all()->whereIn('id', $keys); + $tags = Tag::all()->whereIn('id', $postsAndNewsUniqueTagsID); - $view->with('tagsCloud', $postsAndNewsTags); + $view->with('tagsCloud', $tags); }); } diff --git a/app/Tag.php b/app/Tag.php index 4d5d2cb..1fa0d0d 100644 --- a/app/Tag.php +++ b/app/Tag.php @@ -15,12 +15,14 @@ class Tag extends Model public function posts() { - return $this->belongsToMany(Post::class); +// return $this->belongsToMany(Post::class); + return $this->morphedByMany(Post::class, 'taggable'); } public function news() { - return $this->belongsToMany(News::class, 'new_tag', 'tag_id', 'new_id'); +// return $this->belongsToMany(News::class, 'new_tag', 'tag_id', 'new_id'); + return $this->morphedByMany(News::class, 'taggable'); } public function getRouteKeyName() diff --git a/app/Taggable.php b/app/Taggable.php new file mode 100644 index 0000000..b23248f --- /dev/null +++ b/app/Taggable.php @@ -0,0 +1,10 @@ + $this->faker->text(250), + ]; + } +} diff --git a/database/factories/NewsFactory.php b/database/factories/NewsFactory.php index 473713c..fe94af1 100644 --- a/database/factories/NewsFactory.php +++ b/database/factories/NewsFactory.php @@ -13,7 +13,7 @@ public function definition() { return [ 'name' => $this->faker->words(2, true), - 'text' => $this->faker->text, + 'text' => $this->faker->realText($maxNbChars = 1000, $indexSize = 2), ]; } } diff --git a/database/migrations/2020_09_07_185537_create_post_tag_table.php b/database/migrations/2020_09_07_185537_create_post_tag_table.php index ca1f0ea..fb99b4f 100644 --- a/database/migrations/2020_09_07_185537_create_post_tag_table.php +++ b/database/migrations/2020_09_07_185537_create_post_tag_table.php @@ -13,13 +13,13 @@ class CreatePostTagTable extends Migration */ public function up() { - Schema::create('post_tag', function (Blueprint $table) { - $table->unsignedBigInteger('post_id'); - $table->unsignedBigInteger('tag_id'); - $table->primary(['post_id', 'tag_id']); - $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); - $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade'); - }); +// Schema::create('post_tag', function (Blueprint $table) { +// $table->unsignedBigInteger('post_id'); +// $table->unsignedBigInteger('tag_id'); +// $table->primary(['post_id', 'tag_id']); +// $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); +// $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade'); +// }); } /** @@ -29,6 +29,6 @@ public function up() */ public function down() { - Schema::dropIfExists('post_tag'); +// Schema::dropIfExists('post_tag'); } } diff --git a/database/migrations/2020_10_06_152240_create_new_tag_table.php b/database/migrations/2020_10_06_152240_create_new_tag_table.php index ce24968..af6c2cb 100644 --- a/database/migrations/2020_10_06_152240_create_new_tag_table.php +++ b/database/migrations/2020_10_06_152240_create_new_tag_table.php @@ -8,16 +8,16 @@ class CreateNewTagTable extends Migration { public function up() { - Schema::create('new_tag', function (Blueprint $table) { - $table->foreignId('new_id')->constrained('news')->onDelete('Cascade'); - $table->foreignId('tag_id')->constrained('tags')->onDelete('Cascade'); - - $table->primary(['new_id', 'tag_id']); - }); +// Schema::create('new_tag', function (Blueprint $table) { +// $table->foreignId('new_id')->constrained('news')->onDelete('Cascade'); +// $table->foreignId('tag_id')->constrained('tags')->onDelete('Cascade'); +// +// $table->primary(['new_id', 'tag_id']); +// }); } public function down() { - Schema::dropIfExists('new_tag'); +// Schema::dropIfExists('new_tag'); } } diff --git a/database/migrations/2020_10_08_120022_create_taggables_table.php b/database/migrations/2020_10_08_120022_create_taggables_table.php new file mode 100644 index 0000000..4417a39 --- /dev/null +++ b/database/migrations/2020_10_08_120022_create_taggables_table.php @@ -0,0 +1,32 @@ +foreignId('tag_id')->constrained('tags')->onDelete('Cascade'); + $table->morphs('taggable'); + $table->primary(['tag_id', 'taggable_id', 'taggable_type']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('taggables'); + } +} diff --git a/database/migrations/2020_10_08_143357_create_comments_table.php b/database/migrations/2020_10_08_143357_create_comments_table.php new file mode 100644 index 0000000..458b333 --- /dev/null +++ b/database/migrations/2020_10_08_143357_create_comments_table.php @@ -0,0 +1,33 @@ +id(); + $table->morphs('commentable'); + $table->text('text'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('comments'); + } +} diff --git a/database/seeds/NewsTableSeeder.php b/database/seeds/NewsTableSeeder.php index b5788cd..815d8df 100644 --- a/database/seeds/NewsTableSeeder.php +++ b/database/seeds/NewsTableSeeder.php @@ -14,6 +14,6 @@ class NewsTableSeeder extends Seeder */ public function run() { - News::factory()->count(4)->hasTags(2)->create(); + News::factory()->count(4)->hasTags(2)->hasComments(random_int(1,3))->create(); } } diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index 6e72fa5..97e3e4b 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -32,7 +32,7 @@ public function run() }); User::factory() - ->has(Post::factory() + ->has(Post::factory()->hasComments(random_int(0, 2)) ->count(9)) ->count(2) ->create() diff --git a/resources/views/admin/news.blade.php b/resources/views/admin/news.blade.php index 41aaa19..87624bc 100644 --- a/resources/views/admin/news.blade.php +++ b/resources/views/admin/news.blade.php @@ -8,7 +8,12 @@
- @include('layouts.news.news-section') +
+

News

+ + @include('layouts.news.news-items') +
+ @include('layouts.aside-tags')
diff --git a/resources/views/admin/posts.blade.php b/resources/views/admin/posts.blade.php index e1c3bfd..8c9ba64 100644 --- a/resources/views/admin/posts.blade.php +++ b/resources/views/admin/posts.blade.php @@ -8,7 +8,12 @@
- @include('layouts.posts.posts-section') +
+

Posts

+ + @include('layouts.posts.posts-items') +
+ @include('layouts.aside-tags')
diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index 13c32c1..ae6065c 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -8,9 +8,20 @@
-
- @include('layouts.posts.posts-section') - @include('layouts.news.news-section') +
+
+
+

Latest posts

+ + @include('layouts.posts.posts-items') +
+ +
+

Latest News

+ + @include('layouts.news.news-items') +
+
@include('layouts.aside-tags') diff --git a/resources/views/layouts/news/news-items.blade.php b/resources/views/layouts/news/news-items.blade.php new file mode 100644 index 0000000..a82e36c --- /dev/null +++ b/resources/views/layouts/news/news-items.blade.php @@ -0,0 +1,29 @@ +@forelse($news as $new) +
+
+
+ new #{{ $new->id }} + +

{{ $new->name }}

+ +
{{ $new->created_at->toFormattedDateString() }}
+ +

{{ str_limit($new->text, $limit = 100, $end = '...') }}

+ + @if($new->tags->isNotEmpty()) + + @endif + + Continue reading +
+
+
+@empty +

No available news yet

+@endforelse + + diff --git a/resources/views/layouts/news/news-section.blade.php b/resources/views/layouts/news/news-section.blade.php deleted file mode 100644 index daff285..0000000 --- a/resources/views/layouts/news/news-section.blade.php +++ /dev/null @@ -1,45 +0,0 @@ -
-

News

- -
- @forelse($news as $new) -
-
- new #{{ $new->id }} - -

{{ $new->name }}

- -
{{ $new->created_at->toFormattedDateString() }}
- -

{{ str_limit($new->text, $limit = 200, $end = '...') }}

- - @if($new->tags->isNotEmpty()) - - @endif - -
- Read - - @if(auth()->user()->hasRole('admin')) - Edit - -
- @csrf - @method('DELETE') - - -
- @endif -
-
-
- @empty -

No available news yet

- @endforelse -
-
- diff --git a/resources/views/layouts/posts/posts-items.blade.php b/resources/views/layouts/posts/posts-items.blade.php new file mode 100644 index 0000000..504c5e5 --- /dev/null +++ b/resources/views/layouts/posts/posts-items.blade.php @@ -0,0 +1,40 @@ +@if ($posts->count()) +
+ @foreach($posts as $post) +
+
+
+ Post #{{ $post->id }} + +

{{ $post->name }}

+ +
{{ $post->created_at->toFormattedDateString() }}
+ +

{{ str_limit($post->text, $limit = 100, $end = '...') }}

+ + @if($post->tags->isNotEmpty()) + + @endif + + Continue reading +
+ +
+ + Placeholder + + Thumbnail + +
+
+
+ @endforeach +
+@else +

No available posts yet

+@endif + diff --git a/resources/views/layouts/posts/posts-section.blade.php b/resources/views/layouts/posts/posts-section.blade.php deleted file mode 100644 index e8addcf..0000000 --- a/resources/views/layouts/posts/posts-section.blade.php +++ /dev/null @@ -1,48 +0,0 @@ -
-

Latest posts

- - @if ($posts->count()) -
- @foreach($posts as $post) -
-
-
- Post #{{ $post->id }} - -

{{ $post->name }}

- -
{{ $post->created_at->toFormattedDateString() }}
- -

{{ str_limit($post->text, $limit = 100, $end = '...') }}

- - @if($post->tags->isNotEmpty()) - - @endif - - Continue reading -
- -
- - Placeholder - - Thumbnail - -
-
-
- @endforeach -
- @else -

No available posts yet

- @endif -
diff --git a/resources/views/layouts/tags/index.blade.php b/resources/views/layouts/tags/index.blade.php index eda5f07..2c7ca02 100644 --- a/resources/views/layouts/tags/index.blade.php +++ b/resources/views/layouts/tags/index.blade.php @@ -7,50 +7,97 @@ @section('content')
-
-
-

Latest posts

+
+
+

Find results

@if ($posts->count()) -
- @foreach($posts as $post) -
-
-
- Post #{{ $post->id }} +
+

Posts

-

{{ $post->name }}

+
+ @foreach($posts as $post) +
+
+
+ Post #{{ $post->id }} -
{{ $post->created_at->toFormattedDateString() }}
+

{{ $post->name }}

-

{{ str_limit($post->text, $limit = 100, $end = '...') }}

+
{{ $post->created_at->toFormattedDateString() }}
- @if($post->tags->isNotEmpty()) - - @endif +

{{ str_limit($post->text, $limit = 100, $end = '...') }}

+ + @if($post->tags->isNotEmpty()) + + @endif + + Continue reading +
- Continue reading +
+ + Placeholder + + Thumbnail + +
+
+ @endforeach +
+
+ @endif + + @if ($news->count()) +
+

News

+ + @foreach($news as $new) +
+
+ new #{{ $new->id }} + +

{{ $new->name }}

-
- - Placeholder - - Thumbnail - +
{{ $new->created_at->toFormattedDateString() }}
+ +

{{ str_limit($new->text, $limit = 100, $end = '...') }}

+ + @if($new->tags->isNotEmpty()) + + @endif + +
+ Read + + @if(auth()->user() && auth()->user()->hasRole('admin')) + Edit + +
+ @csrf + @method('DELETE') + + +
+ @endif
@endforeach
- @else -

No available posts yet

@endif
+ + @include('layouts.aside-tags')
diff --git a/resources/views/news/index.blade.php b/resources/views/news/index.blade.php index b200c8f..e5a2834 100644 --- a/resources/views/news/index.blade.php +++ b/resources/views/news/index.blade.php @@ -8,7 +8,12 @@
- @include('layouts.news.news-section') +
+

News

+ + @include('layouts.news.news-items') +
+ @include('layouts.aside-tags')
diff --git a/resources/views/news/show.blade.php b/resources/views/news/show.blade.php index ce45e9d..74be4e8 100644 --- a/resources/views/news/show.blade.php +++ b/resources/views/news/show.blade.php @@ -6,11 +6,11 @@ @section('content')
-
+

New #{{ $new->id }}

-
-
+
+

Name : {{ $new->name }}

@@ -23,12 +23,72 @@

Text

-

{{ $new->text }}

+

{{ $new->text }}

- @if(auth()->user()->hasRole('admin')) - Edit - @endif +
+

Comments

+ +
+ @forelse($new->comments as $comment) +
+
Comment from #{{ $comment->id }}
+
{{ $comment->text }}
+
{{ $comment->created_at }}
+ + @if(auth()->user() && auth()->user()->hasRole('admin')) + // + @endif +
+ @empty +

+ No comments yet +

+ @endforelse +
+
+ +
+ @csrf + +
Add comment
+ +
+
+ + + +
+ Comment Text is required. +
+ + @error('text') +
+ {{ $message }} +
+ @enderror +
+
+ + +
+
+ +
+ Edit + +
+ @csrf + @method('DELETE') + + +
diff --git a/resources/views/posts/index.blade.php b/resources/views/posts/index.blade.php index da78050..b554f02 100644 --- a/resources/views/posts/index.blade.php +++ b/resources/views/posts/index.blade.php @@ -8,7 +8,12 @@
- @include('layouts.posts.posts-section') +
+

Posts

+ + @include('layouts.posts.posts-items') +
+ @include('layouts.aside-tags')
diff --git a/resources/views/posts/show.blade.php b/resources/views/posts/show.blade.php index a4e8129..bdaed25 100644 --- a/resources/views/posts/show.blade.php +++ b/resources/views/posts/show.blade.php @@ -40,7 +40,16 @@

{{ $post->text }}

- Edit post +
+ Edit + +
+ @csrf + @method('DELETE') + + +
+
diff --git a/routes/web.php b/routes/web.php index 327f638..98b9fea 100644 --- a/routes/web.php +++ b/routes/web.php @@ -20,6 +20,7 @@ Route::resource('posts', PostsController::class); Route::resource('news', NewsController::class)->except(['create', 'edit'])->parameters(['news' => 'new']); +Route::post('/news/{new}/comments', [App\Http\Controllers\CommentsController::class,'store'])->name('comments.store'); Route::get('/admin', [App\Http\Controllers\AdministrationController::class,'index'])->name('admin'); Route::get('/admin/posts', [App\Http\Controllers\AdministrationController::class,'posts'])->name('admin.posts'); From cc1db91faee65d60e0d73fd87e9c955eae183a52 Mon Sep 17 00:00:00 2001 From: apsky Date: Fri, 9 Oct 2020 16:33:07 +0300 Subject: [PATCH 08/18] edit comments and create history for changes to post model --- app/Events/PostUpdated.php | 20 +++++ app/History.php | 15 ++++ app/Http/Controllers/CommentsController.php | 33 ++++++-- app/Http/Controllers/NewsController.php | 2 +- app/Http/Controllers/PostsController.php | 2 +- app/Listeners/AddHistoryOnUpdatePost.php | 39 ++++++++++ app/Post.php | 13 +++- app/Providers/EventServiceProvider.php | 6 +- app/helpers.php | 5 +- ...20_10_09_123904_create_histories_table.php | 35 +++++++++ .../views/layouts/comments/comments.blade.php | 1 + .../views/layouts/news/news-items.blade.php | 2 +- resources/views/news/show.blade.php | 65 ++++++++-------- resources/views/posts/show.blade.php | 76 +++++++++++++++++++ routes/web.php | 6 +- 15 files changed, 272 insertions(+), 48 deletions(-) create mode 100644 app/Events/PostUpdated.php create mode 100644 app/History.php create mode 100644 app/Listeners/AddHistoryOnUpdatePost.php create mode 100644 database/migrations/2020_10_09_123904_create_histories_table.php create mode 100644 resources/views/layouts/comments/comments.blade.php diff --git a/app/Events/PostUpdated.php b/app/Events/PostUpdated.php new file mode 100644 index 0000000..d01693f --- /dev/null +++ b/app/Events/PostUpdated.php @@ -0,0 +1,20 @@ +post = $post; + } +} diff --git a/app/History.php b/app/History.php new file mode 100644 index 0000000..c85d6e3 --- /dev/null +++ b/app/History.php @@ -0,0 +1,15 @@ +validate([ - 'text' => 'required' + 'text' => 'required' ]); - $values['commentable_id'] = $new->id; - $values['commentable_type'] = News::class; + $values['commentable_id'] = $model; + $values['commentable_type'] = $modelClassName; + + return $values; + } + + public function newsCommentStore(Request $request, $new) + { + $values = $this->getValuesForStore($request, $new, News::class); $comment = Comment::create($values); return back(); } + + public function postsCommentStore(Request $request, $post) + { + $values = $this->getValuesForStore($request, $post, Post::class); + + $comment = Comment::create($values); + + return back(); + } + + public function destroy(Comment $comment) + { + $comment->delete(); + + return back(); + } } diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index a7fe3b4..d67d5b3 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -73,7 +73,7 @@ public function update(Request $request, News $new) $newTags = $new->tags->keyBy('name'); - updateTags($new, $request, NewTag::class); + updateTags($new, $request); flash( 'New updated successfully'); diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index 624d96f..25b99f4 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -90,7 +90,7 @@ public function update(Request $request, Post $post) $post->update($values); - updateTags($post, $request, PostTag::class); + updateTags($post, $request); sendMailNotifyToAdmin(new PostEdited($post)); flash( 'Post edited successfully'); diff --git a/app/Listeners/AddHistoryOnUpdatePost.php b/app/Listeners/AddHistoryOnUpdatePost.php new file mode 100644 index 0000000..9e409f7 --- /dev/null +++ b/app/Listeners/AddHistoryOnUpdatePost.php @@ -0,0 +1,39 @@ +post->getDirty(); + unset($dirtyValues['updated_at']); + $freshValues = $event->post->fresh()->toArray(); + + if ($dirtyValues['published'] === true && $freshValues['published'] === 1) { + unset($dirtyValues['published']); + } + + foreach ($dirtyValues as $key => $field) { + $result = 'Изменено поле ' . $key . ' Было ' . $freshValues[$key] . ' Стало ' . $field . PHP_EOL; + } + + $values = [ + 'user_email' => auth()->user()->email, + 'text' => $result + ]; + + $event->post->history()->create($values); + } +} diff --git a/app/Post.php b/app/Post.php index 606725c..2341625 100644 --- a/app/Post.php +++ b/app/Post.php @@ -2,7 +2,7 @@ namespace App; -use App\Events\PostCreated; +use App\Events\PostUpdated; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -14,9 +14,9 @@ class Post extends Model protected $guarded = []; -// protected $dispatchesEvents = [ -// 'created' => PostCreated::class, -// ]; + protected $dispatchesEvents = [ + 'updated' => PostUpdated::class, + ]; public function tags() { @@ -33,4 +33,9 @@ public function comments() { return $this->morphMany(Comment::class, 'commentable'); } + + public function history() + { + return $this->hasMany(History::class); + } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index a598943..feec67d 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -3,6 +3,8 @@ 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; @@ -20,8 +22,8 @@ class EventServiceProvider extends ServiceProvider Registered::class => [ SendEmailVerificationNotification::class, ], - PostCreated::class => [ - SendPostCreateNotification::class, + PostUpdated::class => [ + AddHistoryOnUpdatePost::class, ], ]; diff --git a/app/helpers.php b/app/helpers.php index 2efe6cc..ebc43f5 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,6 +1,7 @@ tags->keyBy('name'); if (!is_null($request['tags'])) { @@ -75,7 +76,7 @@ function updateTags($model, $request, $pivotTable) { if ($deleteTags->isNotEmpty()) { foreach ($deleteTags as $tag) { $model->tags()->detach($tag); - $isLastTag = $pivotTable::where('tag_id', $tag->id)->first(); + $isLastTag = Taggable::where('tag_id', $tag->id)->first(); if (!$isLastTag) $tag->delete(); }; } diff --git a/database/migrations/2020_10_09_123904_create_histories_table.php b/database/migrations/2020_10_09_123904_create_histories_table.php new file mode 100644 index 0000000..37eda8a --- /dev/null +++ b/database/migrations/2020_10_09_123904_create_histories_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('user_email'); + $table->text('text'); + $table->timestamps(); + $table->foreignId('post_id')->constrained('posts')->onDelete('cascade'); + $table->foreign('user_email')->references('email')->on('users')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('histories'); + } +} diff --git a/resources/views/layouts/comments/comments.blade.php b/resources/views/layouts/comments/comments.blade.php new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/resources/views/layouts/comments/comments.blade.php @@ -0,0 +1 @@ + diff --git a/resources/views/layouts/news/news-items.blade.php b/resources/views/layouts/news/news-items.blade.php index a82e36c..87575d9 100644 --- a/resources/views/layouts/news/news-items.blade.php +++ b/resources/views/layouts/news/news-items.blade.php @@ -8,7 +8,7 @@
{{ $new->created_at->toFormattedDateString() }}
-

{{ str_limit($new->text, $limit = 100, $end = '...') }}

+

{{ str_limit($new->text, $limit = 200, $end = '...') }}

@if($new->tags->isNotEmpty()) -
-
- @csrf - -
Add comment
- -
-
- - - -
- Comment Text is required. + + @csrf + +
Add comment
+ +
+
+ + + +
+ Comment Text is required. +
+ + @error('text') +
+ {{ $message }} +
+ @enderror
- - @error('text') -
- {{ $message }} -
- @enderror
-
- - + + +
diff --git a/resources/views/posts/show.blade.php b/resources/views/posts/show.blade.php index bdaed25..7f585f6 100644 --- a/resources/views/posts/show.blade.php +++ b/resources/views/posts/show.blade.php @@ -40,6 +40,82 @@

{{ $post->text }}

+
+

Comments

+ +
+ @forelse($post->comments as $comment) +
+
Comment from #{{ $comment->id }}
+
{{ $comment->text }}
+
{{ $comment->created_at }}
+ + @if(auth()->user() && auth()->user()->hasRole('admin')) +
+ @csrf + @method('DELETE') + + +
+ @endif +
+ @empty +

+ No comments yet +

+ @endforelse +
+ +
+ @csrf + +
Add comment
+ +
+
+ + + +
+ Comment Text is required. +
+ + @error('text') +
+ {{ $message }} +
+ @enderror +
+
+ + +
+
+ +
+

History of changes

+ +
+ @forelse($post->history as $history) +
+
{{ $history->user_email }}
+
{{ $history->text }}
+
{{ $history->created_at->diffForHumans() }}
+
+ @empty +

+ No post changes yet +

+ @endforelse +
+
+
Edit diff --git a/routes/web.php b/routes/web.php index 98b9fea..ca9803f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -10,7 +10,7 @@ }); Route::get('/', function () { - $posts = Post::with('tags')->where('published', 1)->latest()->take(3)->get(); + $posts = Post::with('tags')->where('published', 1)->latest()->take(4)->get(); $news = News::with('tags')->latest()->take(3)->get(); return view('/index', compact('posts', 'news')); @@ -20,7 +20,9 @@ Route::resource('posts', PostsController::class); Route::resource('news', NewsController::class)->except(['create', 'edit'])->parameters(['news' => 'new']); -Route::post('/news/{new}/comments', [App\Http\Controllers\CommentsController::class,'store'])->name('comments.store'); +Route::post('/news/{new}/comments/', [App\Http\Controllers\CommentsController::class,'newsCommentStore'])->name('comments.news.store'); +Route::post('/post/{post}/comments/', [App\Http\Controllers\CommentsController::class,'postsCommentStore'])->name('comments.posts.store'); +Route::delete('/comments/{comment}', [App\Http\Controllers\CommentsController::class,'destroy'])->name('comments.destroy'); Route::get('/admin', [App\Http\Controllers\AdministrationController::class,'index'])->name('admin'); Route::get('/admin/posts', [App\Http\Controllers\AdministrationController::class,'posts'])->name('admin.posts'); From 438fd2931166f7425a829014c31309ee8b13ac8c Mon Sep 17 00:00:00 2001 From: apsky Date: Mon, 12 Oct 2020 17:37:51 +0300 Subject: [PATCH 09/18] start make statistics page --- app/Http/Controllers/CommentsController.php | 5 ++ .../Controllers/StaticPagesController.php | 7 +++ app/Listeners/AddHistoryOnUpdatePost.php | 8 +-- app/helpers.php | 55 +++++++++++++++++++ resources/views/static/statistics.blade.php | 55 +++++++++++++++++++ routes/web.php | 23 ++++++++ 6 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 resources/views/static/statistics.blade.php diff --git a/app/Http/Controllers/CommentsController.php b/app/Http/Controllers/CommentsController.php index ef755dc..d431bc9 100644 --- a/app/Http/Controllers/CommentsController.php +++ b/app/Http/Controllers/CommentsController.php @@ -25,6 +25,7 @@ public function newsCommentStore(Request $request, $new) $values = $this->getValuesForStore($request, $new, News::class); $comment = Comment::create($values); + flash('Comment create successfully'); return back(); } @@ -35,6 +36,8 @@ public function postsCommentStore(Request $request, $post) $comment = Comment::create($values); + flash('Comment create successfully'); + return back(); } @@ -42,6 +45,8 @@ public function destroy(Comment $comment) { $comment->delete(); + flash('Comment delete successfully'); + return back(); } } diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index fe0af1e..6d537b8 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Post; use Illuminate\Http\Request; class StaticPagesController extends Controller @@ -13,4 +14,10 @@ public function contactsIndex() { public function aboutIndex() { return view('static.about'); } + + public function statisticsIndex() { + + + return view('static.statistics', ['statistics' => $statistics]); + } } diff --git a/app/Listeners/AddHistoryOnUpdatePost.php b/app/Listeners/AddHistoryOnUpdatePost.php index 9e409f7..17d477a 100644 --- a/app/Listeners/AddHistoryOnUpdatePost.php +++ b/app/Listeners/AddHistoryOnUpdatePost.php @@ -3,8 +3,6 @@ namespace App\Listeners; use App\Events\PostUpdated; -use Illuminate\Contracts\Queue\ShouldQueue; -use Illuminate\Queue\InteractsWithQueue; class AddHistoryOnUpdatePost { @@ -17,16 +15,16 @@ public function handle(PostUpdated $event) { $result = ''; - $dirtyValues = $event->post->getDirty(); + $dirtyValues = $event->post->getChanges(); + $freshValues = $event->post->getOriginal(); unset($dirtyValues['updated_at']); - $freshValues = $event->post->fresh()->toArray(); if ($dirtyValues['published'] === true && $freshValues['published'] === 1) { unset($dirtyValues['published']); } foreach ($dirtyValues as $key => $field) { - $result = 'Изменено поле ' . $key . ' Было ' . $freshValues[$key] . ' Стало ' . $field . PHP_EOL; + $result .= 'Изменено поле: "' . $key . '". Было: "' . $freshValues[$key] . '". Стало: "' . $field . '"' . PHP_EOL; } $values = [ diff --git a/app/helpers.php b/app/helpers.php index ebc43f5..8e2e2ce 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -83,3 +83,58 @@ function updateTags($model, $request) { } } + +if (! function_exists('getUserWithMaxPosts')) { + + function getUserWithMaxPosts() { + $usersWithPostsCount = \App\User::withCount('posts')->get(); + + $maxPosts = 0; + $usersWithMaxPosts = []; + + foreach ($usersWithPostsCount as $user) { + if ($user->posts_count > $maxPosts) { + $usersWithMaxPosts = []; + + $maxPosts = $user->posts_count; + array_push($usersWithMaxPosts, $user); + } elseif ($user->posts_count = $maxPosts) { + array_push($usersWithMaxPosts, $user); + } + } + + if (!empty($usersWithMaxPosts)) { + return $usersWithMaxPosts; + } + } +} + +if (! function_exists('getTheLongestPosts')) { + + function getTheLongestPosts() { + $maxLength = 0; + $postsWithMaxTextLength = []; + + foreach (\App\Post::all() as $post) { + $len = mb_strlen($post->text); + + if ($len > $maxLength) { + $postsWithMaxTextLength = []; + + $maxLength = mb_strlen($post->text); + array_push($postsWithMaxTextLength, $post); + } elseif ($len = $maxLength) { + array_push($postsWithMaxTextLength, $post); + } + } + + if (!empty($postsWithMaxTextLength)) { + return $postsWithMaxTextLength; + } + } +} + + + + + diff --git a/resources/views/static/statistics.blade.php b/resources/views/static/statistics.blade.php new file mode 100644 index 0000000..58885e8 --- /dev/null +++ b/resources/views/static/statistics.blade.php @@ -0,0 +1,55 @@ +@extends('layouts.app') + +@section('header') + @include('layouts.base.header') +@endsection + +@section('content') +
+
+
+

Some interestings on apsky-laravel

+ +
+
    +
  • + Общее количество статей +
  • + +
  • + Общее количество новостей +
  • + +
  • + ФИО автора, у которого больше всего статей на сайте +
  • + +
  • + Самая длинная статья - название, ссылка на статью и длина статьи в символах +
  • + +
  • + Самая короткая статья - название, ссылка на статью и длина статьи в символах +
  • + +
  • + Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи +
  • + +
  • + Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз +
  • + +
  • + Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. +
  • +
+
+
+
+
+@endsection + +@section('footer') + @include('layouts.base.footer') +@endsection diff --git a/routes/web.php b/routes/web.php index ca9803f..7178ece 100644 --- a/routes/web.php +++ b/routes/web.php @@ -6,7 +6,29 @@ use Illuminate\Support\Facades\Route; Route::get('/test', function () { + $statistics = []; + //Общее количество статей + $postsCount = Post::all()->count(); + //Общее количество новостей + $newsCount = News::all()->count(); + //ФИО автора, у которого больше всего статей на сайте + $userWithMostPosts = getUserWithMaxPosts(); + + //Самая длинная статья - название, ссылка на статью и длина статьи в символах + $theLongestPost = getTheLongestPosts(); + + dd($theLongestPost); + + //Самая короткая статья - название, ссылка на статью и длина статьи в символах + $theShortestPost = Post::where('text', Post::min('text'))->get(); + + dd($theShortestPost); + //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи + //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз + //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. + + dd($theLongestPost); }); Route::get('/', function () { @@ -36,5 +58,6 @@ Route::get('/about', [App\Http\Controllers\StaticPagesController::class,'aboutIndex'])->name('about'); Route::get('/contacts', [App\Http\Controllers\StaticPagesController::class,'contactsIndex'])->name('contacts'); +Route::get('/statistics', [App\Http\Controllers\StaticPagesController::class,'statisticsIndex'])->name('statistics'); Auth::routes(); From 7fc9e646cd151de35199b87d660fa56b0b44b5cb Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Mon, 12 Oct 2020 22:51:26 +0300 Subject: [PATCH 10/18] edit statistic page --- .../Controllers/StaticPagesController.php | 35 ++++- app/helpers.php | 130 +++++++++++++++++- database/seeds/UsersTableSeeder.php | 4 +- resources/views/layouts/base/header.blade.php | 4 + resources/views/posts/show.blade.php | 2 +- resources/views/static/statistics.blade.php | 25 ++-- routes/web.php | 22 --- 7 files changed, 184 insertions(+), 38 deletions(-) diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index 6d537b8..827f8d3 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -2,8 +2,8 @@ namespace App\Http\Controllers; +use App\News; use App\Post; -use Illuminate\Http\Request; class StaticPagesController extends Controller { @@ -16,7 +16,40 @@ public function aboutIndex() { } public function statisticsIndex() { + //Общее количество статей + $postsCount = Post::all()->count(); + //Общее количество новостей + $newsCount = News::all()->count(); + + //ФИО автора, у которого больше всего статей на сайте + $userWithMostPosts = getUserWithMaxPosts(); + + //Самая длинная статья - название, ссылка на статью и длина статьи в символах + $theLongestPost = getTheLongestPosts(); + + //Самая короткая статья - название, ссылка на статью и длина статьи в символах + $theShortestPost = getTheShortestPosts(); + + //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи + $avgPostsHaveActiveUsers = getAveragePosts(); + + //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз + $mostChangingPost = getMostChangingPosts(); + + //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. + $mostCommentPosts = getMostCommentPosts(); + + $statistics = [ + 'posts_count' => $postsCount, + 'news_count' => $newsCount, + 'user_with_most_posts' => $userWithMostPosts, + 'the_longest_posts' => $theLongestPost, + 'the_shortest_posts' => $theShortestPost, + 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, + 'most_changing_posts' => $mostChangingPost, + 'most_comment_posts' => $mostCommentPosts + ]; return view('static.statistics', ['statistics' => $statistics]); } diff --git a/app/helpers.php b/app/helpers.php index 8e2e2ce..73acaa5 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,7 +1,9 @@ first(); + $admin = User::where('email', env('ADMIN_EMAIL_FOR_NOTIFICATIONS'))->first(); if ($admin) { $admin->notify($mailView); @@ -85,9 +87,12 @@ function updateTags($model, $request) { if (! function_exists('getUserWithMaxPosts')) { + /** + * @return array + */ function getUserWithMaxPosts() { - $usersWithPostsCount = \App\User::withCount('posts')->get(); + $usersWithPostsCount = User::withCount('posts')->get(); $maxPosts = 0; $usersWithMaxPosts = []; @@ -110,12 +115,15 @@ function getUserWithMaxPosts() { } if (! function_exists('getTheLongestPosts')) { + /** + * @return array + */ function getTheLongestPosts() { $maxLength = 0; $postsWithMaxTextLength = []; - foreach (\App\Post::all() as $post) { + foreach (Post::all() as $post) { $len = mb_strlen($post->text); if ($len > $maxLength) { @@ -123,7 +131,7 @@ function getTheLongestPosts() { $maxLength = mb_strlen($post->text); array_push($postsWithMaxTextLength, $post); - } elseif ($len = $maxLength) { + } elseif ($len === $maxLength) { array_push($postsWithMaxTextLength, $post); } } @@ -134,6 +142,120 @@ function getTheLongestPosts() { } } +if (! function_exists('getTheShortestPosts')) { + /** + * @return array + */ + + function getTheShortestPosts() { + $isFirst = true; + $postsWithMinTextLength = []; + + foreach (Post::all() as $post) { + if ($isFirst) { + $maxLength = mb_strlen($post->text); + $isFirst = false; + } + + $len = mb_strlen($post->text); + + if ($len < $maxLength) { + $postsWithMinTextLength = []; + + $maxLength = $len; + array_push($postsWithMinTextLength, $post); + } elseif ($len === $maxLength) { + array_push($postsWithMinTextLength, $post); + } + } + + if (!empty($postsWithMinTextLength)) { + return $postsWithMinTextLength; + } + } +} + +if (! function_exists('getAveragePosts')) { + /** + * @return int + */ + + function getAveragePosts() { + $activeUsers = []; + $activeUsersPostsCount = 0; + + $users = User::withCount('posts')->get(); + + foreach ($users as $user) { + if ($user->posts_count >= 1) { + array_push($activeUsers, $user); + $activeUsersPostsCount += $user->posts_count; + } + } + + if (!empty($activeUsers)) { + $result = intval(round($activeUsersPostsCount / count($activeUsers), 0)); + + return $result; + } + } +} + +if (! function_exists('getMostChangingPosts')) { + /** + * @return array + */ + + function getMostChangingPosts() { + $mostChangingPosts = []; + $postsWithChanges = Post::has('history', '>=', 1)->withCount('history')->get(); + + $changeCount = 0; + + foreach ($postsWithChanges as $post) { + if ($post->history_count > $changeCount) { + $mostChangingPosts = []; + $changeCount = $post->history_count; + + array_push($mostChangingPosts, $post); + } elseif ($post->history_count === $changeCount) { + array_push($mostChangingPosts, $post); + } + } + + if (!empty($mostChangingPosts)) { + return $mostChangingPosts; + } + } +} + +if (! function_exists('getMostCommentPosts')) { + /** + * @return array + */ + + function getMostCommentPosts() { + $mostCommentPosts = []; + $postsWithComments = Post::has('comments', '>=', 1)->withCount('comments')->get(); + + $commentsCount = 0; + + foreach ($postsWithComments as $post) { + if ($post->comments_count > $commentsCount) { + $mostCommentPosts = []; + $commentsCount = $post->comments_count; + + array_push($mostCommentPosts, $post); + } elseif ($post->comments_count === $commentsCount) { + array_push($mostCommentPosts, $post); + } + } + + if (!empty($mostCommentPosts)) { + return $mostCommentPosts; + } + } +} diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index 97e3e4b..f650412 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -32,9 +32,9 @@ public function run() }); User::factory() - ->has(Post::factory()->hasComments(random_int(0, 2)) + ->has(Post::factory()->hasComments(random_int(0, 3)) ->count(9)) - ->count(2) + ->count(3) ->create() ->each(function (User $user) use ($registeredRole, $registeredPermissions, $tags) { $user->roles()->attach($registeredRole); diff --git a/resources/views/layouts/base/header.blade.php b/resources/views/layouts/base/header.blade.php index 3fe1f1c..fe458ec 100644 --- a/resources/views/layouts/base/header.blade.php +++ b/resources/views/layouts/base/header.blade.php @@ -24,6 +24,10 @@ {{ __('My posts') }} + + diff --git a/resources/views/posts/show.blade.php b/resources/views/posts/show.blade.php index 7f585f6..87dbc05 100644 --- a/resources/views/posts/show.blade.php +++ b/resources/views/posts/show.blade.php @@ -116,7 +116,7 @@ class="form-control @error('text') is-invalid @enderror"
-
+
Edit
diff --git a/resources/views/static/statistics.blade.php b/resources/views/static/statistics.blade.php index 58885e8..0b95c4a 100644 --- a/resources/views/static/statistics.blade.php +++ b/resources/views/static/statistics.blade.php @@ -8,20 +8,29 @@
-

Some interestings on apsky-laravel

+

Interesting Facts

    -
  • - Общее количество статей -
  • + @if(!is_null($statistics['posts_count'])) +
  • + Общее количество статей на сайте : + {{ $statistics['posts_count'] }} +
  • + @endif -
  • - Общее количество новостей -
  • + @if(!is_null($statistics['news_count'])) +
  • + Общее количество новостей : + {{ $statistics['news_count'] }} +
  • + @endif
  • - ФИО автора, у которого больше всего статей на сайте + ФИО автора, у которого больше всего статей на сайте : +{{-- @foreach()--}} + +{{-- @endforeach--}}
  • diff --git a/routes/web.php b/routes/web.php index 7178ece..1e08df9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -6,29 +6,7 @@ use Illuminate\Support\Facades\Route; Route::get('/test', function () { - $statistics = []; - //Общее количество статей - $postsCount = Post::all()->count(); - //Общее количество новостей - $newsCount = News::all()->count(); - //ФИО автора, у которого больше всего статей на сайте - $userWithMostPosts = getUserWithMaxPosts(); - - //Самая длинная статья - название, ссылка на статью и длина статьи в символах - $theLongestPost = getTheLongestPosts(); - - dd($theLongestPost); - - //Самая короткая статья - название, ссылка на статью и длина статьи в символах - $theShortestPost = Post::where('text', Post::min('text'))->get(); - - dd($theShortestPost); - //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи - //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз - //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. - - dd($theLongestPost); }); Route::get('/', function () { From 25d217e531fb03a7c4c74ffc23f671afe7076f4c Mon Sep 17 00:00:00 2001 From: apsky Date: Tue, 13 Oct 2020 10:54:33 +0300 Subject: [PATCH 11/18] finishing make statistics --- .../Controllers/StaticPagesController.php | 8 +- resources/views/static/statistics.blade.php | 97 +++++++++++++++---- 2 files changed, 80 insertions(+), 25 deletions(-) diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index 827f8d3..0506d49 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -23,7 +23,7 @@ public function statisticsIndex() { $newsCount = News::all()->count(); //ФИО автора, у которого больше всего статей на сайте - $userWithMostPosts = getUserWithMaxPosts(); + $usersWithMostPosts = getUserWithMaxPosts(); //Самая длинная статья - название, ссылка на статью и длина статьи в символах $theLongestPost = getTheLongestPosts(); @@ -35,7 +35,7 @@ public function statisticsIndex() { $avgPostsHaveActiveUsers = getAveragePosts(); //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз - $mostChangingPost = getMostChangingPosts(); + $mostChangingPosts = getMostChangingPosts(); //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. $mostCommentPosts = getMostCommentPosts(); @@ -43,11 +43,11 @@ public function statisticsIndex() { $statistics = [ 'posts_count' => $postsCount, 'news_count' => $newsCount, - 'user_with_most_posts' => $userWithMostPosts, + 'users_with_most_posts' => $usersWithMostPosts, 'the_longest_posts' => $theLongestPost, 'the_shortest_posts' => $theShortestPost, 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, - 'most_changing_posts' => $mostChangingPost, + 'most_changing_posts' => $mostChangingPosts, 'most_comment_posts' => $mostCommentPosts ]; diff --git a/resources/views/static/statistics.blade.php b/resources/views/static/statistics.blade.php index 0b95c4a..f545ad1 100644 --- a/resources/views/static/statistics.blade.php +++ b/resources/views/static/statistics.blade.php @@ -21,37 +21,92 @@ @if(!is_null($statistics['news_count']))
  • - Общее количество новостей : + Общее количество новостей на сайте : {{ $statistics['news_count'] }}
  • @endif -
  • - ФИО автора, у которого больше всего статей на сайте : -{{-- @foreach()--}} + @if(!is_null($statistics['users_with_most_posts'])) +
  • + Авторы с наибольшим количеством статей на сайте : + @foreach($statistics['users_with_most_posts'] as $key => $user) +
    + {{ $key + 1 }}. {{ $user->name }} -{{-- @endforeach--}} -
  • + {{ $user->email }} - -
  • - Самая длинная статья - название, ссылка на статью и длина статьи в символах -
  • + {{ $user->posts_count }} +
+ @endforeach + + @endif -
  • - Самая короткая статья - название, ссылка на статью и длина статьи в символах -
  • + @if(!is_null($statistics['the_longest_posts'])) +
  • + Самая длинная статья на сайте. + @foreach($statistics['the_longest_posts'] as $key => $post) +
    + {{ $key + 1 }}. + Название статьи: + {{ $post->name }} - + {{ mb_strlen($post->text) }} + +
    + @endforeach +
  • + @endif -
  • - Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи -
  • + @if(!is_null($statistics['the_shortest_posts'])) +
  • + Самая короткая статья на сайте. + @foreach($statistics['the_shortest_posts'] as $key => $post) +
    + {{ $key + 1 }}. + Название статьи: + {{ $post->name }} - + {{ mb_strlen($post->text) }} + +
    + @endforeach +
  • + @endif -
  • - Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз -
  • + @if(!is_null($statistics['avg_posts_have_active_users'])) +
  • + Среднее количество статей у "активных" пользователей - + {{ $statistics['avg_posts_have_active_users'] }} +
  • + @endif -
  • - Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. -
  • + @if(!is_null($statistics['most_changing_posts'])) +
  • + Самая часто изменяемая статья на сайте. + @foreach($statistics['most_changing_posts'] as $key => $post) +
    + {{ $key + 1 }}. + Название статьи: + {{ $post->name }} - + {{ $post->history_count }} + +
    + @endforeach +
  • + @endif + + @if(!is_null($statistics['most_comment_posts'])) +
  • + Самая обсуждаемая статья на сайте. + @foreach($statistics['most_comment_posts'] as $key => $post) +
    + {{ $key + 1 }}. + Название статьи: + {{ $post->name }} - + {{ $post->comments_count }} + +
    + @endforeach +
  • + @endif
    From 174b404e5a8713d606b2ca43f96ed61b58bd4e4c Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Tue, 13 Oct 2020 21:53:22 +0300 Subject: [PATCH 12/18] git commit -m 'add TagsCreatorService for update method on Post and News models. Edit tags method on AppServiceProvider for tagsCloud' --- app/Http/Controllers/CommentsController.php | 22 ++++------ app/Http/Controllers/NewsController.php | 6 ++- app/Http/Controllers/PostsController.php | 6 ++- app/Providers/AppServiceProvider.php | 12 +----- app/Services/TagsCreatorService.php | 47 +++++++++++++++++++++ 5 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 app/Services/TagsCreatorService.php diff --git a/app/Http/Controllers/CommentsController.php b/app/Http/Controllers/CommentsController.php index d431bc9..809630c 100644 --- a/app/Http/Controllers/CommentsController.php +++ b/app/Http/Controllers/CommentsController.php @@ -9,32 +9,26 @@ class CommentsController extends Controller { - public function getValuesForStore($request, $model, $modelClassName) { + public function newsCommentStore(Request $request, News $new) + { $values = $request->validate([ 'text' => 'required' ]); - $values['commentable_id'] = $model; - $values['commentable_type'] = $modelClassName; - - return $values; - } - - public function newsCommentStore(Request $request, $new) - { - $values = $this->getValuesForStore($request, $new, News::class); + $new->comments()->create($values); - $comment = Comment::create($values); flash('Comment create successfully'); return back(); } - public function postsCommentStore(Request $request, $post) + public function postsCommentStore(Request $request, Post $post) { - $values = $this->getValuesForStore($request, $post, Post::class); + $values = $request->validate([ + 'text' => 'required' + ]); - $comment = Comment::create($values); + $post->comments()->create($values); flash('Comment create successfully'); diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index d67d5b3..e87ced5 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -4,6 +4,7 @@ use App\News; use App\NewTag; +use App\Services\TagsCreatorService; use App\Tag; use Illuminate\Http\Request; use Illuminate\Validation\Rule; @@ -71,9 +72,10 @@ public function update(Request $request, News $new) $new->update($values); - $newTags = $new->tags->keyBy('name'); + $updater = new TagsCreatorService($new, $request); + $updater->updateTags(); - updateTags($new, $request); +// updateTags($new, $request); flash( 'New updated successfully'); diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index 25b99f4..dce5829 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -7,6 +7,7 @@ use App\Notifications\PostEdited; use App\Post; use App\PostTag; +use App\Services\TagsCreatorService; use App\Tag; use Illuminate\Http\Request; use Illuminate\Validation\Rule; @@ -90,7 +91,10 @@ public function update(Request $request, Post $post) $post->update($values); - updateTags($post, $request); + $updater = new TagsCreatorService($post, $request); + $updater->updateTags(); + +// updateTags($post, $request); sendMailNotifyToAdmin(new PostEdited($post)); flash( 'Post edited successfully'); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index fded2c3..bf26353 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -4,6 +4,7 @@ use App\News; use App\Post; +use App\Services\TagsCreatorService; use App\Tag; use App\Taggable; use Illuminate\Support\ServiceProvider; @@ -18,16 +19,7 @@ class AppServiceProvider extends ServiceProvider public function register() { view()->composer('layouts.aside-tags', function ($view) { - $postsAndNewsUniqueTagsID = Taggable::where('taggable_type', News::class) - ->orWhere('taggable_type', Post::class) - ->get() - ->unique('tag_id') - ->keyBy('tag_id') - ->keys() - ->sort() - ; - - $tags = Tag::all()->whereIn('id', $postsAndNewsUniqueTagsID); + $tags = Tag::whereHas('posts')->orWhereHas('news')->get(); $view->with('tagsCloud', $tags); }); diff --git a/app/Services/TagsCreatorService.php b/app/Services/TagsCreatorService.php new file mode 100644 index 0000000..e819bba --- /dev/null +++ b/app/Services/TagsCreatorService.php @@ -0,0 +1,47 @@ +model = $model; + $this->request = $request; + } + + public function updateTags() { + $modelTags = $this->model->tags->keyBy('name'); + + if (!is_null($this->request['tags'])) { + $requestTags = collect(explode(', ', $this->request['tags']))->keyBy(function ($item) { return $item; }); + } else { + $requestTags = collect([]); + } + + $deleteTags = $modelTags->diffKeys($requestTags); + $addTags = $requestTags->diffKeys($modelTags); + + if ($addTags->isNotEmpty()) { + foreach ($addTags as $tag) { + $tag = Tag::firstOrCreate(['name' => $tag]); + $this->model->tags()->attach($tag); + }; + } + + if ($deleteTags->isNotEmpty()) { + foreach ($deleteTags as $tag) { + $this->model->tags()->detach($tag); + $isLastTag = Taggable::where('tag_id', $tag->id)->first(); + if (!$isLastTag) $tag->delete(); + }; + } + } +} From 0d04f75c2c110c78ded5482dfa6191439b4003f8 Mon Sep 17 00:00:00 2001 From: apsky Date: Wed, 14 Oct 2020 17:45:38 +0300 Subject: [PATCH 13/18] start edit statistics service --- .../Controllers/StaticPagesController.php | 42 ++++++------- app/Services/GetStatisticService.php | 59 +++++++++++++++++++ routes/web.php | 7 +++ 3 files changed, 87 insertions(+), 21 deletions(-) create mode 100644 app/Services/GetStatisticService.php diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index 0506d49..211c234 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -17,40 +17,40 @@ public function aboutIndex() { public function statisticsIndex() { //Общее количество статей - $postsCount = Post::all()->count(); +// $postsCount = Post::all()->count(); //Общее количество новостей - $newsCount = News::all()->count(); +// $newsCount = News::all()->count(); //ФИО автора, у которого больше всего статей на сайте - $usersWithMostPosts = getUserWithMaxPosts(); +// $usersWithMostPosts = getUserWithMaxPosts(); //Самая длинная статья - название, ссылка на статью и длина статьи в символах - $theLongestPost = getTheLongestPosts(); +// $theLongestPost = getTheLongestPosts(); //Самая короткая статья - название, ссылка на статью и длина статьи в символах - $theShortestPost = getTheShortestPosts(); +// $theShortestPost = getTheShortestPosts(); //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи - $avgPostsHaveActiveUsers = getAveragePosts(); +// $avgPostsHaveActiveUsers = getAveragePosts(); //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз - $mostChangingPosts = getMostChangingPosts(); +// $mostChangingPosts = getMostChangingPosts(); //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. - $mostCommentPosts = getMostCommentPosts(); - - $statistics = [ - 'posts_count' => $postsCount, - 'news_count' => $newsCount, - 'users_with_most_posts' => $usersWithMostPosts, - 'the_longest_posts' => $theLongestPost, - 'the_shortest_posts' => $theShortestPost, - 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, - 'most_changing_posts' => $mostChangingPosts, - 'most_comment_posts' => $mostCommentPosts - ]; - - return view('static.statistics', ['statistics' => $statistics]); +// $mostCommentPosts = getMostCommentPosts(); + +// $statistics = [ +// 'posts_count' => $postsCount, +// 'news_count' => $newsCount, +// 'users_with_most_posts' => $usersWithMostPosts, +// 'the_longest_posts' => $theLongestPost, +// 'the_shortest_posts' => $theShortestPost, +// 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, +// 'most_changing_posts' => $mostChangingPosts, +// 'most_comment_posts' => $mostCommentPosts +// ]; + +// return view('static.statistics', ['statistics' => $statistics]); } } diff --git a/app/Services/GetStatisticService.php b/app/Services/GetStatisticService.php new file mode 100644 index 0000000..5893fb6 --- /dev/null +++ b/app/Services/GetStatisticService.php @@ -0,0 +1,59 @@ +count(); + } + + /** + * Общее количество новостей + * @return int + */ + static public function getNewsCount() + { + return News::all()->count(); + } + + + /** + * Пользователь с наибольшим количеством постов + * @return User + */ + static public function getUserWithMaxPosts() + { + $maxPosts = DB::table('posts') + ->select(DB::raw('count(*) as post_count, owner_id')) + ->groupBy('owner_id') + ->orderBy('post_count', 'desc') + ->take(1) + ->get(); + + $usersWithMaxPostsCount = \App\User::find($maxPosts[0]->owner_id); + + return $usersWithMaxPostsCount; + } + + static public function getTheLongestPosts() + { + + + return; + } + + + +} diff --git a/routes/web.php b/routes/web.php index 1e08df9..581eb47 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,10 +3,17 @@ use App\News; use App\Post; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Route; Route::get('/test', function () { + $posts = DB::table('posts') + ->select(DB::raw('MIN(text) as max_text')) + ->get(); + $posts2 = Post::min('text'); + + dd($posts, $posts2); }); Route::get('/', function () { From acb35581510110b0456a445cd265149f100868a6 Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Wed, 14 Oct 2020 23:01:15 +0300 Subject: [PATCH 14/18] create GetStatisticService --- .../Controllers/StaticPagesController.php | 45 ++-- app/Providers/AppServiceProvider.php | 4 - app/Services/GetStatisticService.php | 74 ++++-- app/helpers.php | 212 ------------------ routes/web.php | 7 - 5 files changed, 83 insertions(+), 259 deletions(-) diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index 211c234..7538b78 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -2,8 +2,7 @@ namespace App\Http\Controllers; -use App\News; -use App\Post; +use App\Services\GetStatisticService; class StaticPagesController extends Controller { @@ -17,40 +16,40 @@ public function aboutIndex() { public function statisticsIndex() { //Общее количество статей -// $postsCount = Post::all()->count(); + $postsCount = GetStatisticService::getPostsCount(); //Общее количество новостей -// $newsCount = News::all()->count(); + $newsCount = GetStatisticService::getNewsCount(); //ФИО автора, у которого больше всего статей на сайте -// $usersWithMostPosts = getUserWithMaxPosts(); + $usersWithMostPosts = GetStatisticService::getUserWithMaxPosts(); //Самая длинная статья - название, ссылка на статью и длина статьи в символах -// $theLongestPost = getTheLongestPosts(); + $theLongestPost = GetStatisticService::getTheLongestPosts(); //Самая короткая статья - название, ссылка на статью и длина статьи в символах -// $theShortestPost = getTheShortestPosts(); + $theShortestPost = GetStatisticService::getTheShortestPosts(); //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи -// $avgPostsHaveActiveUsers = getAveragePosts(); + $avgPostsHaveActiveUsers = GetStatisticService::getAveragePosts(); //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз -// $mostChangingPosts = getMostChangingPosts(); + $mostChangingPosts = GetStatisticService::getMostChangingPosts(); //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. -// $mostCommentPosts = getMostCommentPosts(); - -// $statistics = [ -// 'posts_count' => $postsCount, -// 'news_count' => $newsCount, -// 'users_with_most_posts' => $usersWithMostPosts, -// 'the_longest_posts' => $theLongestPost, -// 'the_shortest_posts' => $theShortestPost, -// 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, -// 'most_changing_posts' => $mostChangingPosts, -// 'most_comment_posts' => $mostCommentPosts -// ]; - -// return view('static.statistics', ['statistics' => $statistics]); + $mostCommentPosts = GetStatisticService::getMostCommentPosts(); + + $statistics = [ + 'posts_count' => $postsCount, + 'news_count' => $newsCount, + 'users_with_most_posts' => $usersWithMostPosts, + 'the_longest_posts' => $theLongestPost, + 'the_shortest_posts' => $theShortestPost, + 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, + 'most_changing_posts' => $mostChangingPosts, + 'most_comment_posts' => $mostCommentPosts + ]; + + return view('static.statistics', ['statistics' => $statistics]); } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index bf26353..a429766 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,11 +2,7 @@ namespace App\Providers; -use App\News; -use App\Post; -use App\Services\TagsCreatorService; use App\Tag; -use App\Taggable; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider diff --git a/app/Services/GetStatisticService.php b/app/Services/GetStatisticService.php index 5893fb6..d6ac6f8 100644 --- a/app/Services/GetStatisticService.php +++ b/app/Services/GetStatisticService.php @@ -5,7 +5,7 @@ use App\News; use App\Post; use App\User; -use Illuminate\Support\Facades\App; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Facades\DB; class GetStatisticService @@ -30,30 +30,78 @@ static public function getNewsCount() /** - * Пользователь с наибольшим количеством постов - * @return User + * @return Collection */ + static public function getUserWithMaxPosts() { - $maxPosts = DB::table('posts') - ->select(DB::raw('count(*) as post_count, owner_id')) - ->groupBy('owner_id') - ->orderBy('post_count', 'desc') - ->take(1) - ->get(); - - $usersWithMaxPostsCount = \App\User::find($maxPosts[0]->owner_id); + $users = User::has('posts')->withCount('posts')->get(); + $usersWithMostPostsCount = $users->where('posts_count', $users->max('posts_count')); - return $usersWithMaxPostsCount; + return $usersWithMostPostsCount; } + + /** + * @return Collection + */ + static public function getTheLongestPosts() { + $theLongestPosts = Post::where(DB::raw('Length(text)'), function($query){ + $query->select(DB::raw('MAX(Length(text))')) + ->from(DB::table('posts')); + })->get(); + + return $theLongestPosts; + } + + /** + * @return Collection + */ + + static public function getTheShortestPosts() + { + $theShortestPosts = Post::where(DB::raw('Length(text)'), function($query){ + $query->select(DB::raw('MIN(Length(text))')) + ->from(DB::table('posts')); + })->get(); + + return $theShortestPosts; + } + + /** + * @return int + */ + + static public function getAveragePosts() + { + $posts = User::has('posts', '>', 1)->withCount('posts')->get(); + $averagePosts = intval(round($posts->avg('posts_count'))); + return $averagePosts; + } - return; + /** + * @return Collection + */ + static public function getMostChangingPosts() + { + $posts = Post::has('history', '>=', 1)->withCount('history')->get(); + $maxChangingPosts = $posts->where('history_count', $posts->max('history_count')); + + return $maxChangingPosts; } + /** + * @return Collection + */ + static public function getMostCommentPosts() + { + $posts = Post::has('comments', '>=', 1)->withCount('comments')->get(); + $mostCommentPosts = $posts->where('comments_count', $posts->max('comments_count')); + return $mostCommentPosts; + } } diff --git a/app/helpers.php b/app/helpers.php index 73acaa5..bdac04a 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,8 +1,5 @@ tags->keyBy('name'); - - if (!is_null($request['tags'])) { - $requestTags = collect(explode(', ', $request['tags']))->keyBy(function ($item) { return $item; }); - } else { - $requestTags = collect([]); - } - - $deleteTags = $modelTags->diffKeys($requestTags); - $addTags = $requestTags->diffKeys($modelTags); - - if ($addTags->isNotEmpty()) { - foreach ($addTags as $tag) { - $tag = Tag::firstOrCreate(['name' => $tag]); - $model->tags()->attach($tag); - }; - } - - if ($deleteTags->isNotEmpty()) { - foreach ($deleteTags as $tag) { - $model->tags()->detach($tag); - $isLastTag = Taggable::where('tag_id', $tag->id)->first(); - if (!$isLastTag) $tag->delete(); - }; - } - } -} - - -if (! function_exists('getUserWithMaxPosts')) { - /** - * @return array - */ - - function getUserWithMaxPosts() { - $usersWithPostsCount = User::withCount('posts')->get(); - - $maxPosts = 0; - $usersWithMaxPosts = []; - - foreach ($usersWithPostsCount as $user) { - if ($user->posts_count > $maxPosts) { - $usersWithMaxPosts = []; - - $maxPosts = $user->posts_count; - array_push($usersWithMaxPosts, $user); - } elseif ($user->posts_count = $maxPosts) { - array_push($usersWithMaxPosts, $user); - } - } - - if (!empty($usersWithMaxPosts)) { - return $usersWithMaxPosts; - } - } -} - -if (! function_exists('getTheLongestPosts')) { - /** - * @return array - */ - - function getTheLongestPosts() { - $maxLength = 0; - $postsWithMaxTextLength = []; - - foreach (Post::all() as $post) { - $len = mb_strlen($post->text); - - if ($len > $maxLength) { - $postsWithMaxTextLength = []; - - $maxLength = mb_strlen($post->text); - array_push($postsWithMaxTextLength, $post); - } elseif ($len === $maxLength) { - array_push($postsWithMaxTextLength, $post); - } - } - - if (!empty($postsWithMaxTextLength)) { - return $postsWithMaxTextLength; - } - } -} - -if (! function_exists('getTheShortestPosts')) { - /** - * @return array - */ - - function getTheShortestPosts() { - $isFirst = true; - $postsWithMinTextLength = []; - - foreach (Post::all() as $post) { - if ($isFirst) { - $maxLength = mb_strlen($post->text); - $isFirst = false; - } - - $len = mb_strlen($post->text); - - if ($len < $maxLength) { - $postsWithMinTextLength = []; - - $maxLength = $len; - array_push($postsWithMinTextLength, $post); - } elseif ($len === $maxLength) { - array_push($postsWithMinTextLength, $post); - } - } - - if (!empty($postsWithMinTextLength)) { - return $postsWithMinTextLength; - } - } -} - -if (! function_exists('getAveragePosts')) { - /** - * @return int - */ - - function getAveragePosts() { - $activeUsers = []; - $activeUsersPostsCount = 0; - - $users = User::withCount('posts')->get(); - - foreach ($users as $user) { - if ($user->posts_count >= 1) { - array_push($activeUsers, $user); - $activeUsersPostsCount += $user->posts_count; - } - } - - if (!empty($activeUsers)) { - $result = intval(round($activeUsersPostsCount / count($activeUsers), 0)); - - return $result; - } - } -} - -if (! function_exists('getMostChangingPosts')) { - /** - * @return array - */ - - function getMostChangingPosts() { - $mostChangingPosts = []; - $postsWithChanges = Post::has('history', '>=', 1)->withCount('history')->get(); - - $changeCount = 0; - - foreach ($postsWithChanges as $post) { - if ($post->history_count > $changeCount) { - $mostChangingPosts = []; - $changeCount = $post->history_count; - - array_push($mostChangingPosts, $post); - } elseif ($post->history_count === $changeCount) { - array_push($mostChangingPosts, $post); - } - } - - if (!empty($mostChangingPosts)) { - return $mostChangingPosts; - } - } -} - -if (! function_exists('getMostCommentPosts')) { - /** - * @return array - */ - - function getMostCommentPosts() { - $mostCommentPosts = []; - $postsWithComments = Post::has('comments', '>=', 1)->withCount('comments')->get(); - - $commentsCount = 0; - - foreach ($postsWithComments as $post) { - if ($post->comments_count > $commentsCount) { - $mostCommentPosts = []; - $commentsCount = $post->comments_count; - - array_push($mostCommentPosts, $post); - } elseif ($post->comments_count === $commentsCount) { - array_push($mostCommentPosts, $post); - } - } - - if (!empty($mostCommentPosts)) { - return $mostCommentPosts; - } - } -} - - diff --git a/routes/web.php b/routes/web.php index 581eb47..1e08df9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,17 +3,10 @@ use App\News; use App\Post; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Route; Route::get('/test', function () { - $posts = DB::table('posts') - ->select(DB::raw('MIN(text) as max_text')) - ->get(); - $posts2 = Post::min('text'); - - dd($posts, $posts2); }); Route::get('/', function () { From 7b0bb7cc0d2dc21d918a3fea9f748a0c910c9a12 Mon Sep 17 00:00:00 2001 From: apsky Date: Thu, 15 Oct 2020 17:43:44 +0300 Subject: [PATCH 15/18] start correction getStaticService --- app/Services/GetStatisticService.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/Services/GetStatisticService.php b/app/Services/GetStatisticService.php index d6ac6f8..46e3ee6 100644 --- a/app/Services/GetStatisticService.php +++ b/app/Services/GetStatisticService.php @@ -16,7 +16,7 @@ class GetStatisticService */ static public function getPostsCount() { - return Post::all()->count(); + return Post::count(); } /** @@ -25,7 +25,7 @@ static public function getPostsCount() */ static public function getNewsCount() { - return News::all()->count(); + return News::count(); } @@ -35,8 +35,17 @@ static public function getNewsCount() static public function getUserWithMaxPosts() { - $users = User::has('posts')->withCount('posts')->get(); - $usersWithMostPostsCount = $users->where('posts_count', $users->max('posts_count')); +// $users = User::has('posts')->withCount('posts')->get(); +// $usersWithMostPostsCount = $users->where('posts_count', $users->max('posts_count')); + + $users = DB::table('users') + ->join('posts', 'users.id', '=', 'owner_id') + ->select('users.name', DB::raw('Count(*) as posts_count')) + ->groupBy('users.name') + ->orderByDesc('posts_count') + ->first(); + + $usersWithMostPostsCount = User::find('name', $users->name); return $usersWithMostPostsCount; } From 7580fa33d72ebf3cdf179dbfc8961f8ea9e96fab Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Thu, 15 Oct 2020 21:46:17 +0300 Subject: [PATCH 16/18] correct StatisticService and its methods --- .../Controllers/StaticPagesController.php | 20 +-- app/Services/GetStatisticService.php | 116 -------------- app/Services/StatisticService.php | 143 ++++++++++++++++++ routes/web.php | 2 +- 4 files changed, 155 insertions(+), 126 deletions(-) delete mode 100644 app/Services/GetStatisticService.php create mode 100644 app/Services/StatisticService.php diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index 7538b78..0b668e8 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers; -use App\Services\GetStatisticService; +use App\Services\StatisticService; class StaticPagesController extends Controller { @@ -16,28 +16,30 @@ public function aboutIndex() { public function statisticsIndex() { //Общее количество статей - $postsCount = GetStatisticService::getPostsCount(); + $statisticService = new StatisticService(); + + $postsCount = $statisticService->getPostsCount(); //Общее количество новостей - $newsCount = GetStatisticService::getNewsCount(); + $newsCount = $statisticService->getNewsCount(); //ФИО автора, у которого больше всего статей на сайте - $usersWithMostPosts = GetStatisticService::getUserWithMaxPosts(); + $usersWithMostPosts = $statisticService->getUserWithMaxPosts(); //Самая длинная статья - название, ссылка на статью и длина статьи в символах - $theLongestPost = GetStatisticService::getTheLongestPosts(); + $theLongestPost = $statisticService->getTheLongestPosts(); //Самая короткая статья - название, ссылка на статью и длина статьи в символах - $theShortestPost = GetStatisticService::getTheShortestPosts(); + $theShortestPost = $statisticService->getTheShortestPosts(); //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи - $avgPostsHaveActiveUsers = GetStatisticService::getAveragePosts(); + $avgPostsHaveActiveUsers = $statisticService->getAveragePosts(); //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз - $mostChangingPosts = GetStatisticService::getMostChangingPosts(); + $mostChangingPosts = $statisticService->getMostChangingPosts(); //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. - $mostCommentPosts = GetStatisticService::getMostCommentPosts(); + $mostCommentPosts = $statisticService->getMostCommentPosts(); $statistics = [ 'posts_count' => $postsCount, diff --git a/app/Services/GetStatisticService.php b/app/Services/GetStatisticService.php deleted file mode 100644 index 46e3ee6..0000000 --- a/app/Services/GetStatisticService.php +++ /dev/null @@ -1,116 +0,0 @@ -withCount('posts')->get(); -// $usersWithMostPostsCount = $users->where('posts_count', $users->max('posts_count')); - - $users = DB::table('users') - ->join('posts', 'users.id', '=', 'owner_id') - ->select('users.name', DB::raw('Count(*) as posts_count')) - ->groupBy('users.name') - ->orderByDesc('posts_count') - ->first(); - - $usersWithMostPostsCount = User::find('name', $users->name); - - return $usersWithMostPostsCount; - } - - - /** - * @return Collection - */ - - static public function getTheLongestPosts() - { - $theLongestPosts = Post::where(DB::raw('Length(text)'), function($query){ - $query->select(DB::raw('MAX(Length(text))')) - ->from(DB::table('posts')); - })->get(); - - return $theLongestPosts; - } - - /** - * @return Collection - */ - - static public function getTheShortestPosts() - { - $theShortestPosts = Post::where(DB::raw('Length(text)'), function($query){ - $query->select(DB::raw('MIN(Length(text))')) - ->from(DB::table('posts')); - })->get(); - - return $theShortestPosts; - } - - /** - * @return int - */ - - static public function getAveragePosts() - { - $posts = User::has('posts', '>', 1)->withCount('posts')->get(); - $averagePosts = intval(round($posts->avg('posts_count'))); - - return $averagePosts; - } - - /** - * @return Collection - */ - static public function getMostChangingPosts() - { - $posts = Post::has('history', '>=', 1)->withCount('history')->get(); - $maxChangingPosts = $posts->where('history_count', $posts->max('history_count')); - - return $maxChangingPosts; - } - - /** - * @return Collection - */ - - static public function getMostCommentPosts() - { - $posts = Post::has('comments', '>=', 1)->withCount('comments')->get(); - $mostCommentPosts = $posts->where('comments_count', $posts->max('comments_count')); - - return $mostCommentPosts; - } -} diff --git a/app/Services/StatisticService.php b/app/Services/StatisticService.php new file mode 100644 index 0000000..432fbea --- /dev/null +++ b/app/Services/StatisticService.php @@ -0,0 +1,143 @@ +withCount('posts')->get(); +// $usersWithMostPostsCount = $users->where('posts_count', $users->max('posts_count')); + + $users = DB::table('users') + ->join('posts', 'users.id', '=', 'owner_id') + ->select('users.name', DB::raw('Count(*) as posts_count')) + ->groupBy('users.name') + ->orderByDesc('posts_count') + ->first(); + + $usersWithMostPostsCount = User::where('name', $users->name)->withCount('posts')->get(); + + return $usersWithMostPostsCount; + } + + + /** + * @return Collection + */ + + public function getTheLongestPosts() + { + $theLongestPosts = Post::where(DB::raw('Length(text)'), function($query){ + $query->select(DB::raw('MAX(Length(text))')) + ->from(DB::table('posts')); + })->get(); + + return $theLongestPosts; + } + + /** + * @return Collection + */ + + public function getTheShortestPosts() + { + $theShortestPosts = Post::where(DB::raw('Length(text)'), function($query){ + $query->select(DB::raw('MIN(Length(text))')) + ->from(DB::table('posts')); + })->get(); + + return $theShortestPosts; + } + + /** + * @return int + */ + + public function getAveragePosts() + { +// $posts = User::has('posts', '>', 1)->withCount('posts')->get(); +// $averagePosts = intval(round($posts->avg('posts_count'))); + + $averagePosts = DB::select('select AVG(u.posts_count) as avg_posts_count from (select users.*, (select Count(*) from posts where users.id = posts.owner_id) as posts_count from users) as u')[0]; + + $averagePosts = intval(round($averagePosts->avg_posts_count)); + + return $averagePosts; + } + + /** + * @return Collection + */ + public function getMostChangingPosts() + { +// $posts = Post::has('history', '>=', 1)->withCount('history')->get(); +// $maxChangingPosts = $posts->where('history_count', $posts->max('history_count')); + + $maxHistoryCount = DB::table('posts') + ->join('histories as h', 'posts.id', '=', 'h.post_id') + ->select('posts.name', DB::raw('Count(*) as history_count')) + ->groupBy('posts.name') + ->orderByDesc('history_count') + ->first() + ; + + $maxChangingPosts = Post::where('name', $maxHistoryCount->name)->withCount('history')->get(); + + return $maxChangingPosts; + } + + /** + * @return Collection + */ + + public function getMostCommentPosts() + { +// $posts = Post::has('comments', '>=', 1)->withCount('comments')->get(); +// $mostCommentPosts = $posts->where('comments_count', $posts->max('comments_count')); + + $maxComment = DB::table('posts') + ->join('comments as c', function ($join) { + $join->on('posts.id', '=', 'c.commentable_id') + ->where('c.commentable_type', '=', 'App\Post'); + }) + ->select('posts.name', DB::raw('Count(*) as comments_count')) + ->groupBy('posts.name') + ->orderByDesc('comments_count') + ->first() + ; + + $mostCommentPosts = Post::where('name', $maxComment->name)->withCount('comments')->get(); + + return $mostCommentPosts; + } +} diff --git a/routes/web.php b/routes/web.php index 1e08df9..5faabe4 100644 --- a/routes/web.php +++ b/routes/web.php @@ -7,7 +7,7 @@ Route::get('/test', function () { -}); + }); Route::get('/', function () { $posts = Post::with('tags')->where('published', 1)->latest()->take(4)->get(); From b57c5aad77ed3c39eaba78a5ca09f00fcb43fc97 Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Fri, 16 Oct 2020 19:17:33 +0300 Subject: [PATCH 17/18] some changes with statistics selects --- .../Controllers/StaticPagesController.php | 10 +++--- app/Services/StatisticService.php | 34 +++++++++---------- resources/views/static/statistics.blade.php | 30 +++++++--------- routes/web.php | 2 +- 4 files changed, 36 insertions(+), 40 deletions(-) diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index 0b668e8..eca1edd 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -27,19 +27,19 @@ public function statisticsIndex() { $usersWithMostPosts = $statisticService->getUserWithMaxPosts(); //Самая длинная статья - название, ссылка на статью и длина статьи в символах - $theLongestPost = $statisticService->getTheLongestPosts(); + $theLongestPost = $statisticService->getTheLongestPost(); //Самая короткая статья - название, ссылка на статью и длина статьи в символах - $theShortestPost = $statisticService->getTheShortestPosts(); + $theShortestPost = $statisticService->getTheShortestPost(); //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи $avgPostsHaveActiveUsers = $statisticService->getAveragePosts(); //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз - $mostChangingPosts = $statisticService->getMostChangingPosts(); + $mostChangingPosts = $statisticService->getMostChangingPost(); //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. - $mostCommentPosts = $statisticService->getMostCommentPosts(); + $mostCommentPosts = $statisticService->getMostCommentPost(); $statistics = [ 'posts_count' => $postsCount, @@ -52,6 +52,8 @@ public function statisticsIndex() { 'most_comment_posts' => $mostCommentPosts ]; +// dd($theShortestPost); + return view('static.statistics', ['statistics' => $statistics]); } } diff --git a/app/Services/StatisticService.php b/app/Services/StatisticService.php index 432fbea..84de3d9 100644 --- a/app/Services/StatisticService.php +++ b/app/Services/StatisticService.php @@ -35,7 +35,7 @@ public function getNewsCount() public function getUserWithMaxPosts() { -// $users = User::has('posts')->withCount('posts')->get(); + $users = User::has('posts')->withCount('posts')->get(); // $usersWithMostPostsCount = $users->where('posts_count', $users->max('posts_count')); $users = DB::table('users') @@ -45,9 +45,9 @@ public function getUserWithMaxPosts() ->orderByDesc('posts_count') ->first(); - $usersWithMostPostsCount = User::where('name', $users->name)->withCount('posts')->get(); + $userWithMostPostsCount = User::where('name', $users->name)->withCount('posts')->get(); - return $usersWithMostPostsCount; + return $userWithMostPostsCount; } @@ -55,28 +55,28 @@ public function getUserWithMaxPosts() * @return Collection */ - public function getTheLongestPosts() + public function getTheLongestPost() { - $theLongestPosts = Post::where(DB::raw('Length(text)'), function($query){ + $theLongestPost = Post::where(DB::raw('Length(text)'), function($query){ $query->select(DB::raw('MAX(Length(text))')) ->from(DB::table('posts')); - })->get(); + })->first(); - return $theLongestPosts; + return $theLongestPost; } /** * @return Collection */ - public function getTheShortestPosts() + public function getTheShortestPost() { - $theShortestPosts = Post::where(DB::raw('Length(text)'), function($query){ + $theShortestPost = Post::where(DB::raw('Length(text)'), function($query){ $query->select(DB::raw('MIN(Length(text))')) ->from(DB::table('posts')); - })->get(); + })->first(); - return $theShortestPosts; + return $theShortestPost; } /** @@ -98,7 +98,7 @@ public function getAveragePosts() /** * @return Collection */ - public function getMostChangingPosts() + public function getMostChangingPost() { // $posts = Post::has('history', '>=', 1)->withCount('history')->get(); // $maxChangingPosts = $posts->where('history_count', $posts->max('history_count')); @@ -111,16 +111,16 @@ public function getMostChangingPosts() ->first() ; - $maxChangingPosts = Post::where('name', $maxHistoryCount->name)->withCount('history')->get(); + $maxChangingPost = Post::where('name', $maxHistoryCount->name)->withCount('history')->get(); - return $maxChangingPosts; + return $maxChangingPost; } /** * @return Collection */ - public function getMostCommentPosts() + public function getMostCommentPost() { // $posts = Post::has('comments', '>=', 1)->withCount('comments')->get(); // $mostCommentPosts = $posts->where('comments_count', $posts->max('comments_count')); @@ -136,8 +136,8 @@ public function getMostCommentPosts() ->first() ; - $mostCommentPosts = Post::where('name', $maxComment->name)->withCount('comments')->get(); + $mostCommentPost = Post::where('name', $maxComment->name)->withCount('comments')->get(); - return $mostCommentPosts; + return $mostCommentPost; } } diff --git a/resources/views/static/statistics.blade.php b/resources/views/static/statistics.blade.php index f545ad1..b64cccc 100644 --- a/resources/views/static/statistics.blade.php +++ b/resources/views/static/statistics.blade.php @@ -44,30 +44,24 @@ @if(!is_null($statistics['the_longest_posts']))
  • Самая длинная статья на сайте. - @foreach($statistics['the_longest_posts'] as $key => $post) -
    - {{ $key + 1 }}. - Название статьи: - {{ $post->name }} - - {{ mb_strlen($post->text) }} - -
    - @endforeach +
    + Название статьи: + {{ $statistics['the_longest_posts']->name }} - + {{ mb_strlen($statistics['the_longest_posts']->text) }} + +
  • @endif @if(!is_null($statistics['the_shortest_posts']))
  • Самая короткая статья на сайте. - @foreach($statistics['the_shortest_posts'] as $key => $post) -
    - {{ $key + 1 }}. - Название статьи: - {{ $post->name }} - - {{ mb_strlen($post->text) }} - -
    - @endforeach +
    + Название статьи: + {{ $statistics['the_shortest_posts']->name }} - + {{ mb_strlen($statistics['the_shortest_posts']->text) }} + +
  • @endif diff --git a/routes/web.php b/routes/web.php index 5faabe4..1e08df9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -7,7 +7,7 @@ Route::get('/test', function () { - }); +}); Route::get('/', function () { $posts = Post::with('tags')->where('published', 1)->latest()->take(4)->get(); From 74b4fb6161673aebbd65d37c88ce37e31b358338 Mon Sep 17 00:00:00 2001 From: apsky Date: Mon, 19 Oct 2020 16:44:20 +0300 Subject: [PATCH 18/18] correct statistic service with PR on git, add historyFactory seeding --- .../Controllers/StaticPagesController.php | 37 +++++---- app/Providers/AppServiceProvider.php | 3 + app/Services/StatisticService.php | 81 +++++++++---------- database/factories/HistoryFactory.php | 33 ++++++++ database/factories/PostFactory.php | 1 - database/seeds/DatabaseSeeder.php | 4 - database/seeds/UsersTableSeeder.php | 4 +- resources/views/static/statistics.blade.php | 60 ++++++-------- 8 files changed, 119 insertions(+), 104 deletions(-) create mode 100644 database/factories/HistoryFactory.php diff --git a/app/Http/Controllers/StaticPagesController.php b/app/Http/Controllers/StaticPagesController.php index eca1edd..50ff25e 100644 --- a/app/Http/Controllers/StaticPagesController.php +++ b/app/Http/Controllers/StaticPagesController.php @@ -6,6 +6,13 @@ class StaticPagesController extends Controller { + protected $statisticService; + + public function __construct(StatisticService $statisticService) + { + $this->statisticService = $statisticService; + } + public function contactsIndex() { return view('static.contacts'); } @@ -16,44 +23,40 @@ public function aboutIndex() { public function statisticsIndex() { //Общее количество статей - $statisticService = new StatisticService(); - - $postsCount = $statisticService->getPostsCount(); + $postsCount = $this->statisticService->getPostsCount(); //Общее количество новостей - $newsCount = $statisticService->getNewsCount(); + $newsCount = $this->statisticService->getNewsCount(); //ФИО автора, у которого больше всего статей на сайте - $usersWithMostPosts = $statisticService->getUserWithMaxPosts(); + $userWithMostPosts = $this->statisticService->getUserWithMaxPosts(); //Самая длинная статья - название, ссылка на статью и длина статьи в символах - $theLongestPost = $statisticService->getTheLongestPost(); + $theLongestPost = $this->statisticService->getTheLongestPost(); //Самая короткая статья - название, ссылка на статью и длина статьи в символах - $theShortestPost = $statisticService->getTheShortestPost(); + $theShortestPost = $this->statisticService->getTheShortestPost(); //Средние количество статей у “активных” пользователей, при этом активным пользователь считается, если у него есть более 1-й статьи - $avgPostsHaveActiveUsers = $statisticService->getAveragePosts(); + $avgPostsHaveActiveUsers = $this->statisticService->getAveragePosts(); //Самая непостоянная - название, ссылка на статью, которую меняли больше всего раз - $mostChangingPosts = $statisticService->getMostChangingPost(); + $mostChangingPost = $this->statisticService->getMostChangingPost(); //Самая обсуждаемая статья - название, ссылка на статью, у которой больше всего комментариев. - $mostCommentPosts = $statisticService->getMostCommentPost(); + $mostCommentPost = $this->statisticService->getMostCommentPost(); $statistics = [ 'posts_count' => $postsCount, 'news_count' => $newsCount, - 'users_with_most_posts' => $usersWithMostPosts, - 'the_longest_posts' => $theLongestPost, - 'the_shortest_posts' => $theShortestPost, + 'user_with_most_posts' => $userWithMostPosts, + 'the_longest_post' => $theLongestPost, + 'the_shortest_post' => $theShortestPost, 'avg_posts_have_active_users' => $avgPostsHaveActiveUsers, - 'most_changing_posts' => $mostChangingPosts, - 'most_comment_posts' => $mostCommentPosts + 'most_changing_post' => $mostChangingPost, + 'most_comment_post' => $mostCommentPost ]; -// dd($theShortestPost); - return view('static.statistics', ['statistics' => $statistics]); } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index a429766..158eefe 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Services\StatisticService; use App\Tag; use Illuminate\Support\ServiceProvider; @@ -19,6 +20,8 @@ public function register() $view->with('tagsCloud', $tags); }); + + $this->app->make(StatisticService::class); } /** diff --git a/app/Services/StatisticService.php b/app/Services/StatisticService.php index 84de3d9..d682e67 100644 --- a/app/Services/StatisticService.php +++ b/app/Services/StatisticService.php @@ -30,29 +30,26 @@ public function getNewsCount() /** - * @return Collection + * @return User */ public function getUserWithMaxPosts() { - $users = User::has('posts')->withCount('posts')->get(); -// $usersWithMostPostsCount = $users->where('posts_count', $users->max('posts_count')); - - $users = DB::table('users') - ->join('posts', 'users.id', '=', 'owner_id') - ->select('users.name', DB::raw('Count(*) as posts_count')) - ->groupBy('users.name') - ->orderByDesc('posts_count') - ->first(); + $userWithMostPostsCount = User::has('posts')->withCount('posts')->orderBy('posts_count', 'desc')->first(); - $userWithMostPostsCount = User::where('name', $users->name)->withCount('posts')->get(); +// $users = DB::table('users') +// ->join('posts', 'users.id', '=', 'owner_id') +// ->select('users.name', DB::raw('Count(*) as posts_count')) +// ->groupBy('users.name') +// ->orderByDesc('posts_count') +// ->first(); return $userWithMostPostsCount; } /** - * @return Collection + * @return Post */ public function getTheLongestPost() @@ -66,7 +63,7 @@ public function getTheLongestPost() } /** - * @return Collection + * @return Post */ public function getTheShortestPost() @@ -85,33 +82,30 @@ public function getTheShortestPost() public function getAveragePosts() { -// $posts = User::has('posts', '>', 1)->withCount('posts')->get(); -// $averagePosts = intval(round($posts->avg('posts_count'))); + $posts = User::has('posts', '>', 1)->withCount('posts')->get(); + $averagePosts = intval(round($posts->avg('posts_count'))); - $averagePosts = DB::select('select AVG(u.posts_count) as avg_posts_count from (select users.*, (select Count(*) from posts where users.id = posts.owner_id) as posts_count from users) as u')[0]; - - $averagePosts = intval(round($averagePosts->avg_posts_count)); +// $averagePosts = DB::select('select AVG(u.posts_count) as avg_posts_count from (select users.*, (select Count(*) from posts where users.id = posts.owner_id) as posts_count from users) as u')[0]; +// $averagePosts = intval(round($averagePosts->avg_posts_count)); return $averagePosts; } /** - * @return Collection + * @return Post */ + public function getMostChangingPost() { -// $posts = Post::has('history', '>=', 1)->withCount('history')->get(); -// $maxChangingPosts = $posts->where('history_count', $posts->max('history_count')); - - $maxHistoryCount = DB::table('posts') - ->join('histories as h', 'posts.id', '=', 'h.post_id') - ->select('posts.name', DB::raw('Count(*) as history_count')) - ->groupBy('posts.name') - ->orderByDesc('history_count') - ->first() - ; + $maxChangingPost = Post::has('history', '>=', 1)->withCount('history')->orderBy('history_count', 'desc')->first(); - $maxChangingPost = Post::where('name', $maxHistoryCount->name)->withCount('history')->get(); +// $maxHistoryCount = DB::table('posts') +// ->join('histories as h', 'posts.id', '=', 'h.post_id') +// ->select('posts.name', DB::raw('Count(*) as history_count')) +// ->groupBy('posts.name') +// ->orderByDesc('history_count') +// ->first() +// ; return $maxChangingPost; } @@ -122,21 +116,18 @@ public function getMostChangingPost() public function getMostCommentPost() { -// $posts = Post::has('comments', '>=', 1)->withCount('comments')->get(); -// $mostCommentPosts = $posts->where('comments_count', $posts->max('comments_count')); - - $maxComment = DB::table('posts') - ->join('comments as c', function ($join) { - $join->on('posts.id', '=', 'c.commentable_id') - ->where('c.commentable_type', '=', 'App\Post'); - }) - ->select('posts.name', DB::raw('Count(*) as comments_count')) - ->groupBy('posts.name') - ->orderByDesc('comments_count') - ->first() - ; - - $mostCommentPost = Post::where('name', $maxComment->name)->withCount('comments')->get(); + $mostCommentPost = Post::has('comments', '>=', 1)->withCount('comments')->orderBy('comments_count', 'desc')->first(); + +// $maxComment = DB::table('posts') +// ->join('comments as c', function ($join) { +// $join->on('posts.id', '=', 'c.commentable_id') +// ->where('c.commentable_type', '=', 'App\Post'); +// }) +// ->select('posts.name', DB::raw('Count(*) as comments_count')) +// ->groupBy('posts.name') +// ->orderByDesc('comments_count') +// ->first() +// ; return $mostCommentPost; } diff --git a/database/factories/HistoryFactory.php b/database/factories/HistoryFactory.php new file mode 100644 index 0000000..4e15bba --- /dev/null +++ b/database/factories/HistoryFactory.php @@ -0,0 +1,33 @@ +random()->email; + + return [ + 'post_id' => 1, + 'text' => $this->faker->sentence(), + 'user_email' => $randomUserEmail, + ]; + } +} diff --git a/database/factories/PostFactory.php b/database/factories/PostFactory.php index 07b639f..3c0d340 100644 --- a/database/factories/PostFactory.php +++ b/database/factories/PostFactory.php @@ -5,7 +5,6 @@ use App\Post; use App\User; use Illuminate\Database\Eloquent\Factories\Factory; -use Illuminate\Support\Str; class PostFactory extends Factory { diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index ced1eb1..4d60f7d 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -1,10 +1,6 @@ has(Post::factory()->hasComments(random_int(0, 3)) - ->count(9)) + ->has(Post::factory()->hasHistory(random_int(0,3))->hasComments(random_int(0,3))->count(9)) ->count(3) ->create() ->each(function (User $user) use ($registeredRole, $registeredPermissions, $tags) { diff --git a/resources/views/static/statistics.blade.php b/resources/views/static/statistics.blade.php index b64cccc..50a6d8e 100644 --- a/resources/views/static/statistics.blade.php +++ b/resources/views/static/statistics.blade.php @@ -26,40 +26,38 @@ @endif - @if(!is_null($statistics['users_with_most_posts'])) + @if(!is_null($statistics['user_with_most_posts']))
  • - Авторы с наибольшим количеством статей на сайте : - @foreach($statistics['users_with_most_posts'] as $key => $user) -
    - {{ $key + 1 }}. {{ $user->name }} + Автор с наибольшим количеством статей на сайте : +
    + {{ $statistics['user_with_most_posts']->name }} - {{ $user->email }} - + {{ $statistics['user_with_most_posts']->email }} - - {{ $user->posts_count }} -
    - @endforeach + {{ $statistics['user_with_most_posts']->posts_count }} +
  • @endif - @if(!is_null($statistics['the_longest_posts'])) + @if(!is_null($statistics['the_longest_post']))
  • Самая длинная статья на сайте.
    Название статьи: - {{ $statistics['the_longest_posts']->name }} - - {{ mb_strlen($statistics['the_longest_posts']->text) }} + {{ $statistics['the_longest_post']->name }} - + {{ mb_strlen($statistics['the_longest_post']->text) }}
  • @endif - @if(!is_null($statistics['the_shortest_posts'])) + @if(!is_null($statistics['the_shortest_post']))
  • Самая короткая статья на сайте.
    Название статьи: - {{ $statistics['the_shortest_posts']->name }} - - {{ mb_strlen($statistics['the_shortest_posts']->text) }} + {{ $statistics['the_shortest_post']->name }} - + {{ mb_strlen($statistics['the_shortest_post']->text) }}
  • @@ -72,33 +70,27 @@ @endif - @if(!is_null($statistics['most_changing_posts'])) + @if(!is_null($statistics['most_changing_post']))
  • Самая часто изменяемая статья на сайте. - @foreach($statistics['most_changing_posts'] as $key => $post) -
    - {{ $key + 1 }}. - Название статьи: - {{ $post->name }} - - {{ $post->history_count }} - -
    - @endforeach +
    + Название статьи: + {{ $statistics['most_changing_post']->name }} - + {{ $statistics['most_changing_post']->history_count }} + +
  • @endif - @if(!is_null($statistics['most_comment_posts'])) + @if(!is_null($statistics['most_comment_post']))
  • Самая обсуждаемая статья на сайте. - @foreach($statistics['most_comment_posts'] as $key => $post) -
    - {{ $key + 1 }}. - Название статьи: - {{ $post->name }} - - {{ $post->comments_count }} +
    + Название статьи: + {{ $statistics['most_comment_post']->name }} - + {{ $statistics['most_comment_post']->comments_count }} -
    - @endforeach +
  • @endif