From 1bdfefaec7e4655f0b47d4ec33f483ade14ac16b Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Tue, 3 Sep 2019 16:48:27 +0300 Subject: [PATCH 001/183] add createVisitAggregate listener --- .../app/Actions/Visits/CreateVisitAction.php | 7 +++--- .../app/Aggregates/Contracts/Aggregate.php | 9 ++++++++ .../VisitorsFlow/VisitorsFlowAggregate.php | 21 ++++++++++++++++++ .../app/Listeners/CreateVisitAggregate.php | 22 +++++++++++++++++++ .../app/Providers/EventServiceProvider.php | 2 ++ .../VisitorsFlow/FlowAggregateService.php | 18 +++++++++++++++ 6 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 backend/app/Aggregates/Contracts/Aggregate.php create mode 100644 backend/app/Aggregates/VisitorsFlow/VisitorsFlowAggregate.php create mode 100644 backend/app/Listeners/CreateVisitAggregate.php create mode 100644 backend/app/Services/VisitorsFlow/FlowAggregateService.php diff --git a/backend/app/Actions/Visits/CreateVisitAction.php b/backend/app/Actions/Visits/CreateVisitAction.php index 5c4d3968..9e714f9b 100644 --- a/backend/app/Actions/Visits/CreateVisitAction.php +++ b/backend/app/Actions/Visits/CreateVisitAction.php @@ -55,7 +55,6 @@ public function execute(CreateVisitRequest $request): void { JWTAuth::setToken(Str::after($request->token(), 'Bearer ')); $visitorId = JWTAuth::getPayload()->get('visitor_id'); - $visitor = $this->visitorRepository->getById($visitorId); $this->visitorRepository->updateLastActivity($visitor); @@ -125,7 +124,8 @@ private function getOrCreateSystem( string $browser, int $resolutionHeight, int $resolutionWidth - ): System { + ): System + { $system = $this->systemRepository->getByParameters( $operatingSystem, $device, @@ -171,7 +171,8 @@ private function getOrCreateSession( int $pageId, string $language, int $systemId - ): Session { + ): Session + { $session = $this->sessionRepository->lastActiveByVisitorId($visitorId); if ($session !== null) { diff --git a/backend/app/Aggregates/Contracts/Aggregate.php b/backend/app/Aggregates/Contracts/Aggregate.php new file mode 100644 index 00000000..8a501247 --- /dev/null +++ b/backend/app/Aggregates/Contracts/Aggregate.php @@ -0,0 +1,9 @@ +flowAggregateService = $flowAggregateService; + } + + public function handle(VisitCreated $event) + { + $this->flowAggregateService->aggregate($event->visit); + } +} diff --git a/backend/app/Providers/EventServiceProvider.php b/backend/app/Providers/EventServiceProvider.php index caef2bd5..d9f385a5 100644 --- a/backend/app/Providers/EventServiceProvider.php +++ b/backend/app/Providers/EventServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Listeners\CreateVisitAggregate; use Illuminate\Support\Facades\Event; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; @@ -20,6 +21,7 @@ class EventServiceProvider extends ServiceProvider ], 'App\Events\VisitCreated' => [ 'App\Listeners\SendVisitsNotification', + CreateVisitAggregate::class ], ]; diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php new file mode 100644 index 00000000..0b8ffdde --- /dev/null +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -0,0 +1,18 @@ + Date: Tue, 3 Sep 2019 20:39:39 +0300 Subject: [PATCH 002/183] add aggrigate objects --- .../app/Aggregates/Contracts/Aggregate.php | 9 --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 55 +++++++++++++++++++ .../VisitorsFlow/CountryAggregate.php | 30 ++++++++++ .../VisitorsFlow/DeviceAggregate.php | 15 +++++ .../VisitorsFlow/ScreenAggregate.php | 36 ++++++++++++ .../VisitorsFlow/SystemAggregate.php | 30 ++++++++++ .../VisitorsFlow/Values/PageValue.php | 16 ++++++ .../VisitorsFlow/VisitorsFlowAggregate.php | 21 ------- 8 files changed, 182 insertions(+), 30 deletions(-) delete mode 100644 backend/app/Aggregates/Contracts/Aggregate.php create mode 100644 backend/app/Aggregates/VisitorsFlow/Aggregate.php create mode 100644 backend/app/Aggregates/VisitorsFlow/CountryAggregate.php create mode 100644 backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php create mode 100644 backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php create mode 100644 backend/app/Aggregates/VisitorsFlow/SystemAggregate.php create mode 100644 backend/app/Aggregates/VisitorsFlow/Values/PageValue.php delete mode 100644 backend/app/Aggregates/VisitorsFlow/VisitorsFlowAggregate.php diff --git a/backend/app/Aggregates/Contracts/Aggregate.php b/backend/app/Aggregates/Contracts/Aggregate.php deleted file mode 100644 index 8a501247..00000000 --- a/backend/app/Aggregates/Contracts/Aggregate.php +++ /dev/null @@ -1,9 +0,0 @@ -websiteId = $websiteId; + $this->url = $url; + $this->nextPage = $nextPage; + $this->prevPage = $prevPage; + $this->views = $views; + $this->level = $level; + $this->isLastPage = $isLastPage; + } + + public function toArray(): array + { + return [ + 'websiteId' => $this->websiteId, + 'url' => $this->url, + 'nextPage' => [ + 'id' => $this->nextPage->id, + 'url' => $this->nextPage->url + ], + 'prevPage' => [ + 'id' => $this->prevPage->id, + 'url' => $this->prevPage->url + ], + 'level' => $this->level, + 'views' => $this->views, + 'isLastPage' => $this->isLastPage, + ]; + } +} diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php new file mode 100644 index 00000000..8a2b5bd7 --- /dev/null +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -0,0 +1,30 @@ +$country = $country; + } + + public function toArray(): array + { + return array_merge(parent::toArray(), ['country' => $this->country]); + } +} diff --git a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php new file mode 100644 index 00000000..258ec00e --- /dev/null +++ b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php @@ -0,0 +1,15 @@ +resolutionWidth = $resolutionWidth; + $this->resolutionHeight = $resolutionHeight; + } + + public function toArray(): array + { + return array_merge(parent::toArray(), [ + 'resolution_width' => $this->resolutionWidth, + 'resolution_height' => $this->resolutionHeight + ]); + } +} diff --git a/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php b/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php new file mode 100644 index 00000000..5162f61b --- /dev/null +++ b/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php @@ -0,0 +1,30 @@ +system = $system; + } + + public function toArray(): array + { + return array_merge(parent::toArray(), ['system' => $this->system]); + } +} diff --git a/backend/app/Aggregates/VisitorsFlow/Values/PageValue.php b/backend/app/Aggregates/VisitorsFlow/Values/PageValue.php new file mode 100644 index 00000000..d99071a9 --- /dev/null +++ b/backend/app/Aggregates/VisitorsFlow/Values/PageValue.php @@ -0,0 +1,16 @@ +id = $id; + $this->url = $url; + } +} diff --git a/backend/app/Aggregates/VisitorsFlow/VisitorsFlowAggregate.php b/backend/app/Aggregates/VisitorsFlow/VisitorsFlowAggregate.php deleted file mode 100644 index 38897f2f..00000000 --- a/backend/app/Aggregates/VisitorsFlow/VisitorsFlowAggregate.php +++ /dev/null @@ -1,21 +0,0 @@ - Date: Tue, 3 Sep 2019 23:25:54 +0300 Subject: [PATCH 003/183] add getPreviousVisit and getVisitsCount methods --- .../Contracts/VisitRepository.php | 2 ++ .../Repositories/EloquentVisitRepository.php | 8 ++++- .../VisitorsFlow/FlowAggregateService.php | 35 ++++++++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/backend/app/Repositories/Contracts/VisitRepository.php b/backend/app/Repositories/Contracts/VisitRepository.php index 67f220a8..1dbfec84 100644 --- a/backend/app/Repositories/Contracts/VisitRepository.php +++ b/backend/app/Repositories/Contracts/VisitRepository.php @@ -10,4 +10,6 @@ interface VisitRepository public function save(Visit $visit): Visit; public function getVisitsCountByHourAndDay(string $startDate, string $endDate): Collection; + + public function findBySessionId(int $sessionId): Collection; } diff --git a/backend/app/Repositories/EloquentVisitRepository.php b/backend/app/Repositories/EloquentVisitRepository.php index 5233e22a..74292b96 100644 --- a/backend/app/Repositories/EloquentVisitRepository.php +++ b/backend/app/Repositories/EloquentVisitRepository.php @@ -28,4 +28,10 @@ public function getVisitsCountByHourAndDay(string $startDate, string $endDate): ->groupBy('day', 'hour') ->get(); } -} \ No newline at end of file + + + public function findBySessionId(int $sessionId): Collection + { + return Visit::where('session_id', $sessionId)->get(); + } +} diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 0b8ffdde..31903135 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -4,15 +4,48 @@ namespace App\Services\VisitorsFlow; use App\Entities\Visit; +use App\Repositories\Contracts\PageRepository; +use App\Repositories\Contracts\VisitRepository; +use Carbon\Carbon; final class FlowAggregateService { - public function __construct() + private $pageRepository; + private $visitRepository; + + public function __construct( + PageRepository $pageRepository, + VisitRepository $visitRepository + ) { + $this->pageRepository = $pageRepository; + $this->visitRepository = $visitRepository; } public function aggregate(Visit $visit) { + $previousVisit = $this->getPreviousVisit($visit); + $isFirstInSession = $previousVisit === null; + if (!$isFirstInSession) { + $level = $this->getVisitsCount($visit); + } else { + $level = 1; + } + } + + private function getPreviousVisit(Visit $currentVisit): ?Visit + { + return $this->visitRepository->findBySessionId($currentVisit->session_id) + ->sortBy(function (Visit $visit) { + return (new Carbon($visit->visit_time))->getTimestamp(); + }) + ->last(function (Visit $visit) use ($currentVisit) { + return $currentVisit->id !== $visit->id; + }); + } + private function getVisitsCount(Visit $currentVisit): int + { + return $this->visitRepository->findBySessionId($currentVisit->session_id)->count(); } } From 820b353cd5fa2217aaff35c6918a822bf7911210 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Wed, 4 Sep 2019 13:46:26 +0300 Subject: [PATCH 004/183] add ElasticsearchCountryRepository --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 13 ++-- .../VisitorsFlow/CountryAggregate.php | 28 +++++++- backend/app/Providers/AppServiceProvider.php | 5 ++ .../Contracts/GeoPositionRepository.php | 3 + .../Contracts/CountryRepository.php | 16 +++++ .../ElasticsearchCountryRepository.php | 72 +++++++++++++++++++ .../EloquentGeoPositionRepository.php | 5 ++ .../VisitorsFlow/FlowAggregateService.php | 59 ++++++++++++++- readme.md | 2 +- 9 files changed, 192 insertions(+), 11 deletions(-) create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index eb0c29b2..fc384f2c 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -18,8 +18,8 @@ abstract class Aggregate public function __construct( int $websiteId, string $url, - PageValue $nextPage, - PageValue $prevPage, + ?PageValue $nextPage, + ?PageValue $prevPage, int $views, int $level, bool $isLastPage @@ -39,11 +39,11 @@ public function toArray(): array return [ 'websiteId' => $this->websiteId, 'url' => $this->url, - 'nextPage' => [ + 'nextPage' => $this->nextPage === null ? null : [ 'id' => $this->nextPage->id, 'url' => $this->nextPage->url ], - 'prevPage' => [ + 'prevPage' => $this->prevPage === null ? null : [ 'id' => $this->prevPage->id, 'url' => $this->prevPage->url ], @@ -52,4 +52,9 @@ public function toArray(): array 'isLastPage' => $this->isLastPage, ]; } + + public function getId(): int + { +// return $this->id; + } } diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index 8a2b5bd7..5363614b 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -10,21 +10,43 @@ class CountryAggregate extends Aggregate public $country; public function __construct( + int $id, int $websiteId, string $url, - PageValue $nextPage, - PageValue $prevPage, + ?PageValue $nextPage, + ?PageValue $prevPage, int $views, int $level, bool $isLastPage, string $country ) { parent::__construct($websiteId, $url, $nextPage, $prevPage, $views, $level, $isLastPage); - $this->$country = $country; + $this->country = $country; } public function toArray(): array { return array_merge(parent::toArray(), ['country' => $this->country]); } + + public static function fromResult(array $result): self + { + return new self( + (int)$result['id'], + (int)$result['websiteId'], + (string)$result['url'], + new PageValue( + (int)$result['nextPage']['id'], + (string)$result['nextPage']['url'] + ), + new PageValue( + (int)$result['prevPage']['id'], + (string)$result['prevPage']['url'] + ), + (int)$result['views'], + (int)$result['level'], + (bool)$result['isLastPage'], + (string)$result['country'] + ); + } } diff --git a/backend/app/Providers/AppServiceProvider.php b/backend/app/Providers/AppServiceProvider.php index 1c87cf2b..bc3d5432 100644 --- a/backend/app/Providers/AppServiceProvider.php +++ b/backend/app/Providers/AppServiceProvider.php @@ -22,6 +22,8 @@ use App\Repositories\Contracts\VisitRepository; use App\Repositories\Contracts\WebsiteRepository; use App\Repositories\Contracts\PageViews\ChartDataRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\CountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchCountryRepository; use App\Repositories\EloquentChartPageTimingRepository; use App\Repositories\EloquentChartVisitorRepository; use App\Repositories\EloquentButtonVisitorsRepository; @@ -96,7 +98,10 @@ public function register() $this->app->bind(TablePageViewsRepository::class, EloquentTablePageViewsRepository::class); $this->app->bind(ChartDataRepository::class, EloquentChartDataRepository::class); + $this->app->bind(ChartPageTimingRepository::class, EloquentChartPageTimingRepository::class); + + $this->app->bind(CountryRepository::class,ElasticsearchCountryRepository::class); } /** diff --git a/backend/app/Repositories/Contracts/GeoPositionRepository.php b/backend/app/Repositories/Contracts/GeoPositionRepository.php index 387c69eb..d4dbaed4 100644 --- a/backend/app/Repositories/Contracts/GeoPositionRepository.php +++ b/backend/app/Repositories/Contracts/GeoPositionRepository.php @@ -9,4 +9,7 @@ interface GeoPositionRepository public function getByParameters(string $country, string $city): ?GeoPosition; public function save(GeoPosition $geoPosition): GeoPosition; + + public function getById(int $id): GeoPosition; + } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php new file mode 100644 index 00000000..e3b10a6c --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php @@ -0,0 +1,16 @@ +client = $client; + } + + public function save(Aggregate $countryAggregate): Aggregate + { + + $this->client->index([ + 'index' => self::INDEX_NAME, + 'type' => '_doc', + 'body' => $countryAggregate->toArray() + ]); + dd($countryAggregate); + + return $countryAggregate; + } + + public function getById(int $id): CountryAggregate + { + $result = $this->client->get([ + 'index' => self::INDEX_NAME, + 'type' => '_doc', + 'id' => $id + ]); + return CountryAggregate::fromResult($result['_source']); + } + + public function getByParams(int $websiteId, string $url, int $level): ?CountryAggregate + { + $params = [ + 'index' => self::INDEX_NAME, + 'body' => [ + 'query' => [ + 'bool' => [ + 'must' => [ + ['match' => ['websiteId' => $websiteId]], + ['match' => ['level' => $level]], + ['match' => ['url' => $url]], + ] + ] + ] + ] + ]; + try { + $result = $this->client->search($params); + } catch (\Exception $exception) { + return null; + } + if (empty($result['hits']['hits'])) { + return null; + } + //доделать!!!!! + return CountryAggregate::fromResult($result['hits']); + } + +} diff --git a/backend/app/Repositories/EloquentGeoPositionRepository.php b/backend/app/Repositories/EloquentGeoPositionRepository.php index 74622098..de5a421a 100644 --- a/backend/app/Repositories/EloquentGeoPositionRepository.php +++ b/backend/app/Repositories/EloquentGeoPositionRepository.php @@ -22,4 +22,9 @@ public function save(GeoPosition $geoPosition): GeoPosition $geoPosition->save(); return $geoPosition; } + + public function getById(int $id): GeoPosition + { + return GeoPosition::findOrFail($id); + } } diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 31903135..8ea093f8 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -3,23 +3,36 @@ namespace App\Services\VisitorsFlow; +use App\Aggregates\VisitorsFlow\CountryAggregate; use App\Entities\Visit; +use App\Repositories\Contracts\GeoPositionRepository; use App\Repositories\Contracts\PageRepository; use App\Repositories\Contracts\VisitRepository; +use App\Repositories\Contracts\WebsiteRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\CountryRepository; use Carbon\Carbon; final class FlowAggregateService { private $pageRepository; private $visitRepository; + private $countryRepository; + private $websiteRepository; + private $geoPositionRepository; public function __construct( PageRepository $pageRepository, - VisitRepository $visitRepository + VisitRepository $visitRepository, + CountryRepository $countryRepository, + WebsiteRepository $websiteRepository, + GeoPositionRepository $geoPositionRepository ) { $this->pageRepository = $pageRepository; $this->visitRepository = $visitRepository; + $this->countryRepository = $countryRepository; + $this->websiteRepository = $websiteRepository; + $this->geoPositionRepository = $geoPositionRepository; } public function aggregate(Visit $visit) @@ -31,9 +44,21 @@ public function aggregate(Visit $visit) } else { $level = 1; } + $countryAggregate = $this->countryRepository->getByParams( + $visit->session->website_id, + $visit->page->url, + $level + ); + $countryAggregate = null; + + if (!$countryAggregate) { + $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); + $countryAggregate = $this->countryRepository->save($countryAggregate); + } } - private function getPreviousVisit(Visit $currentVisit): ?Visit + private + function getPreviousVisit(Visit $currentVisit): ?Visit { return $this->visitRepository->findBySessionId($currentVisit->session_id) ->sortBy(function (Visit $visit) { @@ -44,8 +69,36 @@ private function getPreviousVisit(Visit $currentVisit): ?Visit }); } - private function getVisitsCount(Visit $currentVisit): int + private + function getVisitsCount(Visit $currentVisit): int { return $this->visitRepository->findBySessionId($currentVisit->session_id)->count(); } + + private + function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit): CountryAggregate + { + $page = $this->pageRepository->getById($currentVisit->page_id); + $website = $this->websiteRepository->getById($page->website_id); + $geoPosition = $this->geoPositionRepository->getById($currentVisit->geo_position_id); + $nextPage = null; + $prevPage = null; + if ($level !== 1) { + //сделать + } + + $isLatPage = true; + $views = 1; + return new CountryAggregate( + $currentVisit->id, + $website->id, + $page->url, + $nextPage, + $prevPage, + $views, + $level, + $isLatPage, + $geoPosition->country + ); + } } diff --git a/readme.md b/readme.md index 5694beb7..efeeaf47 100644 --- a/readme.md +++ b/readme.md @@ -43,7 +43,7 @@ cp docker-compose.override.yml.windows docker-compose.override.yml cp .env.example .env docker-compose up -d -docker-compose exec app composer install +c docker-compose exec app php artisan key:generate docker-compose exec app php artisan jwt:secret docker-compose exec app php artisan migrate --seed From 522bd50d500f4c114a3967f9401b59c31c1b6a1a Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Wed, 4 Sep 2019 15:42:29 +0300 Subject: [PATCH 005/183] add nextPage and prevPage values to countryAggregte --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 6 +++- .../VisitorsFlow/CountryAggregate.php | 9 +++--- .../Contracts/CountryRepository.php | 4 ++- .../ElasticsearchCountryRepository.php | 29 ++++++++++++++----- .../VisitorsFlow/FlowAggregateService.php | 22 +++++++++----- 5 files changed, 49 insertions(+), 21 deletions(-) diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index fc384f2c..6009294d 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -7,6 +7,7 @@ abstract class Aggregate { + public $id; public $websiteId; public $url; public $nextPage; @@ -16,6 +17,7 @@ abstract class Aggregate public $isLastPage; public function __construct( + int $id, int $websiteId, string $url, ?PageValue $nextPage, @@ -25,6 +27,7 @@ public function __construct( bool $isLastPage ) { + $this->id = $id; $this->websiteId = $websiteId; $this->url = $url; $this->nextPage = $nextPage; @@ -37,6 +40,7 @@ public function __construct( public function toArray(): array { return [ + 'id' => $this->id, 'websiteId' => $this->websiteId, 'url' => $this->url, 'nextPage' => $this->nextPage === null ? null : [ @@ -55,6 +59,6 @@ public function toArray(): array public function getId(): int { -// return $this->id; + return $this->id; } } diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index 5363614b..6f8275d0 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -19,8 +19,9 @@ public function __construct( int $level, bool $isLastPage, string $country - ) { - parent::__construct($websiteId, $url, $nextPage, $prevPage, $views, $level, $isLastPage); + ) + { + parent::__construct($id, $websiteId, $url, $nextPage, $prevPage, $views, $level, $isLastPage); $this->country = $country; } @@ -35,11 +36,11 @@ public static function fromResult(array $result): self (int)$result['id'], (int)$result['websiteId'], (string)$result['url'], - new PageValue( + $result['nextPage'] === null ? null : new PageValue( (int)$result['nextPage']['id'], (string)$result['nextPage']['url'] ), - new PageValue( + $result['prevPage'] === null ? null : new PageValue( (int)$result['prevPage']['id'], (string)$result['prevPage']['url'] ), diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php index e3b10a6c..2c658f42 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php @@ -10,7 +10,9 @@ interface CountryRepository { public function save(Aggregate $tableAggregate): Aggregate; + public function update(Aggregate $tableAggregate): Aggregate; + public function getById(int $id): CountryAggregate; - public function getByParams(int $websiteId, string $url, int $level): ?CountryAggregate; + public function getByParams(int $websiteId, string $url, int $level); } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php index e701fd00..a8e2e4cc 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php @@ -20,28 +20,41 @@ public function __construct(ElasticsearchManager $client) public function save(Aggregate $countryAggregate): Aggregate { - $this->client->index([ 'index' => self::INDEX_NAME, + 'id' => $countryAggregate->getId(), 'type' => '_doc', 'body' => $countryAggregate->toArray() ]); - dd($countryAggregate); return $countryAggregate; } - public function getById(int $id): CountryAggregate + public function update(Aggregate $countryAggregate): Aggregate { - $result = $this->client->get([ + $this->client->index([ 'index' => self::INDEX_NAME, + 'id' => $countryAggregate->getId(), 'type' => '_doc', - 'id' => $id + 'body' => [ + 'doc' => $countryAggregate->toArray() + ] ]); - return CountryAggregate::fromResult($result['_source']); + + return $countryAggregate; + } + + public function getById(int $id): CountryAggregate + { +// $result = $this->client->get([ +// 'index' => self::INDEX_NAME, +// 'type' => '_doc', +// 'id' => $id +// ]); +// return CountryAggregate::fromResult($result['_source']); } - public function getByParams(int $websiteId, string $url, int $level): ?CountryAggregate + public function getByParams(int $websiteId, string $url, int $level) { $params = [ 'index' => self::INDEX_NAME, @@ -66,7 +79,7 @@ public function getByParams(int $websiteId, string $url, int $level): ?CountryAg return null; } //доделать!!!!! - return CountryAggregate::fromResult($result['hits']); + return CountryAggregate::fromResult($result['hits']['hits'][0]['_source']); } } diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 8ea093f8..5e8ca208 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -4,6 +4,7 @@ namespace App\Services\VisitorsFlow; use App\Aggregates\VisitorsFlow\CountryAggregate; +use App\Aggregates\VisitorsFlow\Values\PageValue; use App\Entities\Visit; use App\Repositories\Contracts\GeoPositionRepository; use App\Repositories\Contracts\PageRepository; @@ -54,11 +55,11 @@ public function aggregate(Visit $visit) if (!$countryAggregate) { $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); $countryAggregate = $this->countryRepository->save($countryAggregate); + dd($countryAggregate); } } - private - function getPreviousVisit(Visit $currentVisit): ?Visit + private function getPreviousVisit(Visit $currentVisit): ?Visit { return $this->visitRepository->findBySessionId($currentVisit->session_id) ->sortBy(function (Visit $visit) { @@ -69,14 +70,12 @@ function getPreviousVisit(Visit $currentVisit): ?Visit }); } - private - function getVisitsCount(Visit $currentVisit): int + private function getVisitsCount(Visit $currentVisit): int { return $this->visitRepository->findBySessionId($currentVisit->session_id)->count(); } - private - function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit): CountryAggregate + private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit): CountryAggregate { $page = $this->pageRepository->getById($currentVisit->page_id); $website = $this->websiteRepository->getById($page->website_id); @@ -84,7 +83,16 @@ function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $previou $nextPage = null; $prevPage = null; if ($level !== 1) { - //сделать + //get previous aggregate + $previousAggregate = $this->countryRepository->getByParams( + $previousVisit->session->website_id, + $previousVisit->page->url, + $level - 1 + ); + $previousAggregate->nextPage = new PageValue($currentVisit->id, $currentVisit->page->url); + $previousAggregate->isLastPage = false; + $this->countryRepository->update($previousAggregate); + $prevPage = new PageValue($previousVisit->id, $previousAggregate->url); } $isLatPage = true; From 4aacf47530599432a61bdc1ec916701134df431b Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Wed, 4 Sep 2019 15:54:49 +0300 Subject: [PATCH 006/183] add page title to aggreagate --- backend/app/Aggregates/VisitorsFlow/Aggregate.php | 4 ++++ backend/app/Aggregates/VisitorsFlow/CountryAggregate.php | 4 +++- backend/app/Services/VisitorsFlow/FlowAggregateService.php | 3 +-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index 6009294d..1c1c2ccc 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -10,6 +10,7 @@ abstract class Aggregate public $id; public $websiteId; public $url; + public $title; public $nextPage; public $prevPage; public $views; @@ -20,6 +21,7 @@ public function __construct( int $id, int $websiteId, string $url, + string $title, ?PageValue $nextPage, ?PageValue $prevPage, int $views, @@ -30,6 +32,7 @@ public function __construct( $this->id = $id; $this->websiteId = $websiteId; $this->url = $url; + $this->title = $title; $this->nextPage = $nextPage; $this->prevPage = $prevPage; $this->views = $views; @@ -43,6 +46,7 @@ public function toArray(): array 'id' => $this->id, 'websiteId' => $this->websiteId, 'url' => $this->url, + 'title'=>$this->title, 'nextPage' => $this->nextPage === null ? null : [ 'id' => $this->nextPage->id, 'url' => $this->nextPage->url diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index 6f8275d0..4ce010ff 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -13,6 +13,7 @@ public function __construct( int $id, int $websiteId, string $url, + string $title, ?PageValue $nextPage, ?PageValue $prevPage, int $views, @@ -21,7 +22,7 @@ public function __construct( string $country ) { - parent::__construct($id, $websiteId, $url, $nextPage, $prevPage, $views, $level, $isLastPage); + parent::__construct($id, $websiteId, $url, $title,$nextPage, $prevPage, $views, $level, $isLastPage); $this->country = $country; } @@ -36,6 +37,7 @@ public static function fromResult(array $result): self (int)$result['id'], (int)$result['websiteId'], (string)$result['url'], + (string)$result['title'], $result['nextPage'] === null ? null : new PageValue( (int)$result['nextPage']['id'], (string)$result['nextPage']['url'] diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 5e8ca208..c6ce8bb8 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -50,12 +50,10 @@ public function aggregate(Visit $visit) $visit->page->url, $level ); - $countryAggregate = null; if (!$countryAggregate) { $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); $countryAggregate = $this->countryRepository->save($countryAggregate); - dd($countryAggregate); } } @@ -101,6 +99,7 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $currentVisit->id, $website->id, $page->url, + $page->name, $nextPage, $prevPage, $views, From 48dfaefc1a1ecefbd8f8023cc3d6093bc7bebbf7 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Wed, 4 Sep 2019 19:56:11 +0300 Subject: [PATCH 007/183] fix getByParams method --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 7 ----- .../VisitorsFlow/CountryAggregate.php | 7 +---- .../Contracts/CountryRepository.php | 2 +- .../ElasticsearchCountryRepository.php | 26 ++++++------------- .../VisitorsFlow/FlowAggregateService.php | 9 ++++--- 5 files changed, 15 insertions(+), 36 deletions(-) diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index 1c1c2ccc..e17ddd0e 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -11,7 +11,6 @@ abstract class Aggregate public $websiteId; public $url; public $title; - public $nextPage; public $prevPage; public $views; public $level; @@ -22,7 +21,6 @@ public function __construct( int $websiteId, string $url, string $title, - ?PageValue $nextPage, ?PageValue $prevPage, int $views, int $level, @@ -33,7 +31,6 @@ public function __construct( $this->websiteId = $websiteId; $this->url = $url; $this->title = $title; - $this->nextPage = $nextPage; $this->prevPage = $prevPage; $this->views = $views; $this->level = $level; @@ -47,10 +44,6 @@ public function toArray(): array 'websiteId' => $this->websiteId, 'url' => $this->url, 'title'=>$this->title, - 'nextPage' => $this->nextPage === null ? null : [ - 'id' => $this->nextPage->id, - 'url' => $this->nextPage->url - ], 'prevPage' => $this->prevPage === null ? null : [ 'id' => $this->prevPage->id, 'url' => $this->prevPage->url diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index 4ce010ff..4005686e 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -14,7 +14,6 @@ public function __construct( int $websiteId, string $url, string $title, - ?PageValue $nextPage, ?PageValue $prevPage, int $views, int $level, @@ -22,7 +21,7 @@ public function __construct( string $country ) { - parent::__construct($id, $websiteId, $url, $title,$nextPage, $prevPage, $views, $level, $isLastPage); + parent::__construct($id, $websiteId, $url, $title, $prevPage, $views, $level, $isLastPage); $this->country = $country; } @@ -38,10 +37,6 @@ public static function fromResult(array $result): self (int)$result['websiteId'], (string)$result['url'], (string)$result['title'], - $result['nextPage'] === null ? null : new PageValue( - (int)$result['nextPage']['id'], - (string)$result['nextPage']['url'] - ), $result['prevPage'] === null ? null : new PageValue( (int)$result['prevPage']['id'], (string)$result['prevPage']['url'] diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php index 2c658f42..ace71092 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php @@ -14,5 +14,5 @@ public function update(Aggregate $tableAggregate): Aggregate; public function getById(int $id): CountryAggregate; - public function getByParams(int $websiteId, string $url, int $level); + public function getByParams(int $websiteId, string $url, int $level): ?CountryAggregate; } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php index a8e2e4cc..442c22a5 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php @@ -36,25 +36,13 @@ public function update(Aggregate $countryAggregate): Aggregate 'index' => self::INDEX_NAME, 'id' => $countryAggregate->getId(), 'type' => '_doc', - 'body' => [ - 'doc' => $countryAggregate->toArray() - ] + 'body' => $countryAggregate->toArray() ]); return $countryAggregate; } - public function getById(int $id): CountryAggregate - { -// $result = $this->client->get([ -// 'index' => self::INDEX_NAME, -// 'type' => '_doc', -// 'id' => $id -// ]); -// return CountryAggregate::fromResult($result['_source']); - } - - public function getByParams(int $websiteId, string $url, int $level) + public function getByParams(int $websiteId, string $url, int $level):?CountryAggregate { $params = [ 'index' => self::INDEX_NAME, @@ -63,9 +51,12 @@ public function getByParams(int $websiteId, string $url, int $level) 'bool' => [ 'must' => [ ['match' => ['websiteId' => $websiteId]], - ['match' => ['level' => $level]], - ['match' => ['url' => $url]], - ] + ], + 'filter' => [ + ['term' => ['level' => $level]], + ['match_phrase' => ['url' => $url]], + ], + ] ] ] @@ -78,7 +69,6 @@ public function getByParams(int $websiteId, string $url, int $level) if (empty($result['hits']['hits'])) { return null; } - //доделать!!!!! return CountryAggregate::fromResult($result['hits']['hits'][0]['_source']); } diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index c6ce8bb8..1123bea3 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -50,10 +50,14 @@ public function aggregate(Visit $visit) $visit->page->url, $level ); - if (!$countryAggregate) { $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); $countryAggregate = $this->countryRepository->save($countryAggregate); + dd($countryAggregate); + } else { + $countryAggregate->views++; + $countryAggregate = $this->countryRepository->update($countryAggregate); + dd($countryAggregate); } } @@ -78,7 +82,6 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $page = $this->pageRepository->getById($currentVisit->page_id); $website = $this->websiteRepository->getById($page->website_id); $geoPosition = $this->geoPositionRepository->getById($currentVisit->geo_position_id); - $nextPage = null; $prevPage = null; if ($level !== 1) { //get previous aggregate @@ -87,7 +90,6 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit->page->url, $level - 1 ); - $previousAggregate->nextPage = new PageValue($currentVisit->id, $currentVisit->page->url); $previousAggregate->isLastPage = false; $this->countryRepository->update($previousAggregate); $prevPage = new PageValue($previousVisit->id, $previousAggregate->url); @@ -100,7 +102,6 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $website->id, $page->url, $page->name, - $nextPage, $prevPage, $views, $level, From 17015d3cfa72c6078a76eceba3750922d0299167 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Wed, 4 Sep 2019 19:59:59 +0300 Subject: [PATCH 008/183] remove getById method --- .../Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php index ace71092..40fece2a 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php @@ -12,7 +12,5 @@ public function save(Aggregate $tableAggregate): Aggregate; public function update(Aggregate $tableAggregate): Aggregate; - public function getById(int $id): CountryAggregate; - public function getByParams(int $websiteId, string $url, int $level): ?CountryAggregate; } From 148ca41184be2108ec94e2139b960713577e7590 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Wed, 4 Sep 2019 22:50:58 +0300 Subject: [PATCH 009/183] add aggregates --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 9 ++-- .../VisitorsFlow/CountryAggregate.php | 16 ++++---- .../VisitorsFlow/DeviceAggregate.php | 41 +++++++++++++++++-- .../VisitorsFlow/ScreenAggregate.php | 31 +++++++++++--- .../VisitorsFlow/SystemAggregate.php | 27 ++++++++++-- backend/app/Providers/AppServiceProvider.php | 6 +-- ...y.php => VisitorFlowCountryRepository.php} | 2 +- ...ticsearchVisitorFlowCountryRepository.php} | 4 +- .../VisitorsFlow/FlowAggregateService.php | 8 ++-- readme.md | 3 +- 10 files changed, 112 insertions(+), 35 deletions(-) rename backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/{CountryRepository.php => VisitorFlowCountryRepository.php} (91%) rename backend/app/Repositories/Elasticsearch/VisitorsFlow/{ElasticsearchCountryRepository.php => ElasticsearchVisitorFlowCountryRepository.php} (91%) diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index e17ddd0e..98d32661 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -21,20 +21,21 @@ public function __construct( int $websiteId, string $url, string $title, - ?PageValue $prevPage, int $views, int $level, - bool $isLastPage + bool $isLastPage, + ?PageValue $prevPage ) { $this->id = $id; $this->websiteId = $websiteId; $this->url = $url; $this->title = $title; - $this->prevPage = $prevPage; $this->views = $views; $this->level = $level; $this->isLastPage = $isLastPage; + $this->prevPage = $prevPage; + } public function toArray(): array @@ -43,7 +44,7 @@ public function toArray(): array 'id' => $this->id, 'websiteId' => $this->websiteId, 'url' => $this->url, - 'title'=>$this->title, + 'title' => $this->title, 'prevPage' => $this->prevPage === null ? null : [ 'id' => $this->prevPage->id, 'url' => $this->prevPage->url diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index 4005686e..2d256bee 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -14,14 +14,14 @@ public function __construct( int $websiteId, string $url, string $title, - ?PageValue $prevPage, int $views, int $level, bool $isLastPage, - string $country + string $country, + ?PageValue $prevPage ) { - parent::__construct($id, $websiteId, $url, $title, $prevPage, $views, $level, $isLastPage); + parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); $this->country = $country; } @@ -37,14 +37,14 @@ public static function fromResult(array $result): self (int)$result['websiteId'], (string)$result['url'], (string)$result['title'], - $result['prevPage'] === null ? null : new PageValue( - (int)$result['prevPage']['id'], - (string)$result['prevPage']['url'] - ), (int)$result['views'], (int)$result['level'], (bool)$result['isLastPage'], - (string)$result['country'] + (string)$result['country'], + $result['prevPage'] === null ? null : new PageValue( + (int)$result['prevPage']['id'], + (string)$result['prevPage']['url'] + ) ); } } diff --git a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php index 258ec00e..17d26385 100644 --- a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php @@ -3,13 +3,48 @@ namespace App\Aggregates\VisitorsFlow; -use App\Aggregates\Contracts\Aggregate; +use App\Aggregates\VisitorsFlow\Values\PageValue; -class DeviceAggregate implements Aggregate +class DeviceAggregate extends Aggregate { + public $device; + + public function __construct( + int $id, + int $websiteId, + string $url, + string $title, + int $views, + int $level, + bool $isLastPage, + string $device, + ?PageValue $prevPage + ) + { + parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); + $this->$device = $device; + } + public function toArray(): array { - // TODO: Implement toArray() method. + return array_merge(parent::toArray(), ['device' => $this->device]); } + public static function fromResult(array $result): self + { + return new self( + (int)$result['id'], + (int)$result['websiteId'], + (string)$result['url'], + (string)$result['title'], + (int)$result['views'], + (int)$result['level'], + (bool)$result['isLastPage'], + (string)$result['device'], + $result['prevPage'] === null ? null : new PageValue( + (int)$result['prevPage']['id'], + (string)$result['prevPage']['url'] + ) + ); + } } diff --git a/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php b/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php index ad4af2ac..66f4c702 100644 --- a/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php @@ -11,17 +11,19 @@ class ScreenAggregate extends Aggregate public $resolutionHeight; public function __construct( + int $id, int $websiteId, string $url, - PageValue $nextPage, - PageValue $prevPage, + string $title, int $views, int $level, bool $isLastPage, int $resolutionWidth, - int $resolutionHeight - ) { - parent::__construct($websiteId, $url, $nextPage, $prevPage, $views, $level, $isLastPage); + int $resolutionHeight, + ?PageValue $prevPage + ) + { + parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); $this->resolutionWidth = $resolutionWidth; $this->resolutionHeight = $resolutionHeight; } @@ -33,4 +35,23 @@ public function toArray(): array 'resolution_height' => $this->resolutionHeight ]); } + + public static function fromResult(array $result): self + { + return new self( + (int)$result['id'], + (int)$result['websiteId'], + (string)$result['url'], + (string)$result['title'], + (int)$result['views'], + (int)$result['level'], + (bool)$result['isLastPage'], + (int)$result['resolution_width'], + (int)$result['resolution_height'], + $result['prevPage'] === null ? null : new PageValue( + (int)$result['prevPage']['id'], + (string)$result['prevPage']['url'] + ) + ); + } } diff --git a/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php b/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php index 5162f61b..127b6ce6 100644 --- a/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php @@ -10,16 +10,17 @@ class SystemAggregate extends Aggregate public $system; public function __construct( + int $id, int $websiteId, string $url, - PageValue $nextPage, - PageValue $prevPage, + string $title, int $views, int $level, bool $isLastPage, - string $system + string $system, + ?PageValue $prevPage ) { - parent::__construct($websiteId, $url, $nextPage, $prevPage, $views, $level, $isLastPage); + parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); $this->system = $system; } @@ -27,4 +28,22 @@ public function toArray(): array { return array_merge(parent::toArray(), ['system' => $this->system]); } + + public static function fromResult(array $result): self + { + return new self( + (int)$result['id'], + (int)$result['websiteId'], + (string)$result['url'], + (string)$result['title'], + (int)$result['views'], + (int)$result['level'], + (bool)$result['isLastPage'], + (string)$result['system'], + $result['prevPage'] === null ? null : new PageValue( + (int)$result['prevPage']['id'], + (string)$result['prevPage']['url'] + ) + ); + } } diff --git a/backend/app/Providers/AppServiceProvider.php b/backend/app/Providers/AppServiceProvider.php index bc3d5432..771f1030 100644 --- a/backend/app/Providers/AppServiceProvider.php +++ b/backend/app/Providers/AppServiceProvider.php @@ -22,8 +22,8 @@ use App\Repositories\Contracts\VisitRepository; use App\Repositories\Contracts\WebsiteRepository; use App\Repositories\Contracts\PageViews\ChartDataRepository; -use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\CountryRepository; -use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchCountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowCountryRepository; use App\Repositories\EloquentChartPageTimingRepository; use App\Repositories\EloquentChartVisitorRepository; use App\Repositories\EloquentButtonVisitorsRepository; @@ -101,7 +101,7 @@ public function register() $this->app->bind(ChartPageTimingRepository::class, EloquentChartPageTimingRepository::class); - $this->app->bind(CountryRepository::class,ElasticsearchCountryRepository::class); + $this->app->bind(VisitorFlowCountryRepository::class,ElasticsearchVisitorFlowCountryRepository::class); } /** diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php similarity index 91% rename from backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php rename to backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php index 40fece2a..a2e64a2b 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/CountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php @@ -6,7 +6,7 @@ use App\Aggregates\VisitorsFlow\Aggregate; use App\Aggregates\VisitorsFlow\CountryAggregate; -interface CountryRepository +interface VisitorFlowCountryRepository { public function save(Aggregate $tableAggregate): Aggregate; diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php similarity index 91% rename from backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php rename to backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php index 442c22a5..509b78b3 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchCountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php @@ -5,10 +5,10 @@ use App\Aggregates\VisitorsFlow\Aggregate; use App\Aggregates\VisitorsFlow\CountryAggregate; -use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\CountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use Cviebrock\LaravelElasticsearch\Manager as ElasticsearchManager; -final class ElasticsearchCountryRepository implements CountryRepository +final class ElasticsearchVisitorFlowCountryRepository implements VisitorFlowCountryRepository { const INDEX_NAME = 'country-visitors-flow'; private $client; diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 1123bea3..45cfef59 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -10,7 +10,7 @@ use App\Repositories\Contracts\PageRepository; use App\Repositories\Contracts\VisitRepository; use App\Repositories\Contracts\WebsiteRepository; -use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\CountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use Carbon\Carbon; final class FlowAggregateService @@ -24,7 +24,7 @@ final class FlowAggregateService public function __construct( PageRepository $pageRepository, VisitRepository $visitRepository, - CountryRepository $countryRepository, + VisitorFlowCountryRepository $countryRepository, WebsiteRepository $websiteRepository, GeoPositionRepository $geoPositionRepository ) @@ -102,11 +102,11 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $website->id, $page->url, $page->name, - $prevPage, $views, $level, $isLatPage, - $geoPosition->country + $geoPosition->country, + $prevPage ); } } diff --git a/readme.md b/readme.md index efeeaf47..d56f2372 100644 --- a/readme.md +++ b/readme.md @@ -43,7 +43,8 @@ cp docker-compose.override.yml.windows docker-compose.override.yml cp .env.example .env docker-compose up -d -c +docker-compose exec app composer install + docker-compose exec app php artisan key:generate docker-compose exec app php artisan jwt:secret docker-compose exec app php artisan migrate --seed From e51a79500ab9094e8f0ce000ca7ed7b19ed4d1d4 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 01:12:28 +0300 Subject: [PATCH 010/183] add visitorFlowBrowserRespoistory --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 2 + ...stemAggregate.php => BrowserAggregate.php} | 16 ++-- .../VisitorsFlow/CountryAggregate.php | 4 +- .../VisitorsFlow/DeviceAggregate.php | 4 +- .../VisitorsFlow/ScreenAggregate.php | 4 +- backend/app/Providers/AppServiceProvider.php | 6 +- .../VisitorsFlow/Contracts/Criteria.php | 9 ++ .../VisitorFlowBrowserRepository.php | 16 ++++ .../VisitorFlowCountryRepository.php | 2 +- ...sticsearchVisitorFlowBrowserRepository.php | 83 ++++++++++++++++++ ...sticsearchVisitorFlowCountryRepository.php | 41 +++++---- .../VisitorsFlow/FlowAggregateService.php | 84 +++++++++++++++---- 12 files changed, 223 insertions(+), 48 deletions(-) rename backend/app/Aggregates/VisitorsFlow/{SystemAggregate.php => BrowserAggregate.php} (74%) create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index 98d32661..26e68c3a 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -59,4 +59,6 @@ public function getId(): int { return $this->id; } + + public abstract static function fromResult(array $result): self; } diff --git a/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php b/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php similarity index 74% rename from backend/app/Aggregates/VisitorsFlow/SystemAggregate.php rename to backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php index 127b6ce6..0f20483a 100644 --- a/backend/app/Aggregates/VisitorsFlow/SystemAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php @@ -5,9 +5,9 @@ use App\Aggregates\VisitorsFlow\Values\PageValue; -class SystemAggregate extends Aggregate +class BrowserAggregate extends Aggregate { - public $system; + public $browser; public function __construct( int $id, @@ -17,21 +17,21 @@ public function __construct( int $views, int $level, bool $isLastPage, - string $system, + string $browser, ?PageValue $prevPage ) { parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); - $this->system = $system; + $this->browser = $browser; } public function toArray(): array { - return array_merge(parent::toArray(), ['system' => $this->system]); + return array_merge(parent::toArray(), ['browser' => $this->browser]); } - public static function fromResult(array $result): self + public static function fromResult(array $result): Aggregate { - return new self( + return new static( (int)$result['id'], (int)$result['websiteId'], (string)$result['url'], @@ -39,7 +39,7 @@ public static function fromResult(array $result): self (int)$result['views'], (int)$result['level'], (bool)$result['isLastPage'], - (string)$result['system'], + (string)$result['browser'], $result['prevPage'] === null ? null : new PageValue( (int)$result['prevPage']['id'], (string)$result['prevPage']['url'] diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index 2d256bee..a47a816a 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -30,9 +30,9 @@ public function toArray(): array return array_merge(parent::toArray(), ['country' => $this->country]); } - public static function fromResult(array $result): self + public static function fromResult(array $result): Aggregate { - return new self( + return new static( (int)$result['id'], (int)$result['websiteId'], (string)$result['url'], diff --git a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php index 17d26385..86f4f41a 100644 --- a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php @@ -30,9 +30,9 @@ public function toArray(): array return array_merge(parent::toArray(), ['device' => $this->device]); } - public static function fromResult(array $result): self + public static function fromResult(array $result): Aggregate { - return new self( + return new static( (int)$result['id'], (int)$result['websiteId'], (string)$result['url'], diff --git a/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php b/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php index 66f4c702..d577351a 100644 --- a/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php @@ -36,9 +36,9 @@ public function toArray(): array ]); } - public static function fromResult(array $result): self + public static function fromResult(array $result): Aggregate { - return new self( + return new static( (int)$result['id'], (int)$result['websiteId'], (string)$result['url'], diff --git a/backend/app/Providers/AppServiceProvider.php b/backend/app/Providers/AppServiceProvider.php index 771f1030..dd621359 100644 --- a/backend/app/Providers/AppServiceProvider.php +++ b/backend/app/Providers/AppServiceProvider.php @@ -22,7 +22,9 @@ use App\Repositories\Contracts\VisitRepository; use App\Repositories\Contracts\WebsiteRepository; use App\Repositories\Contracts\PageViews\ChartDataRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowCountryRepository; use App\Repositories\EloquentChartPageTimingRepository; use App\Repositories\EloquentChartVisitorRepository; @@ -101,7 +103,9 @@ public function register() $this->app->bind(ChartPageTimingRepository::class, EloquentChartPageTimingRepository::class); - $this->app->bind(VisitorFlowCountryRepository::class,ElasticsearchVisitorFlowCountryRepository::class); + $this->app->bind(VisitorFlowCountryRepository::class, ElasticsearchVisitorFlowCountryRepository::class); + + $this->app->bind(VisitorFlowBrowserRepository::class, ElasticsearchVisitorFlowBrowserRepository::class); } /** diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php new file mode 100644 index 00000000..fbaa74c1 --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php @@ -0,0 +1,9 @@ +client = $client; + } + + public function save(Aggregate $countryAggregate): Aggregate + { + $this->client->index([ + 'index' => self::INDEX_NAME, + 'id' => $countryAggregate->getId(), + 'type' => '_doc', + 'body' => $countryAggregate->toArray() + ]); + + return $countryAggregate; + } + + public function update(Aggregate $countryAggregate): Aggregate + { + $this->client->index([ + 'index' => self::INDEX_NAME, + 'id' => $countryAggregate->getId(), + 'type' => '_doc', + 'body' => $countryAggregate->toArray() + ]); + + return $countryAggregate; + } + + public function getCriteria(int $websiteId, string $url, int $level,string $browser): array + { + return [ + 'query' => [ + 'bool' => [ + 'must' => [ + ['match' => ['websiteId' => $websiteId]], + ], + 'filter' => [ + ['term' => ['level' => $level]], + ['match_phrase' => ['url' => $url]], + ['match_phrase' => ['browser' => $browser]], + + ], + ] + ] + ]; + } + + public function getByCriteria(int $websiteId, string $url, int $level,string $browser): ?BrowserAggregate + { + $params = [ + 'index' => self::INDEX_NAME, + 'body' => $this->getCriteria($websiteId, $url, $level) + ]; + try { + $result = $this->client->search($params); + } catch (\Exception $exception) { + return null; + } + if (empty($result['hits']['hits'])) { + return null; + } + return BrowserAggregate::fromResult($result['hits']['hits'][0]['_source']); + } +} diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php index 509b78b3..7bf528f0 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php @@ -5,10 +5,13 @@ use App\Aggregates\VisitorsFlow\Aggregate; use App\Aggregates\VisitorsFlow\CountryAggregate; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\Criteria; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use Cviebrock\LaravelElasticsearch\Manager as ElasticsearchManager; -final class ElasticsearchVisitorFlowCountryRepository implements VisitorFlowCountryRepository +final class ElasticsearchVisitorFlowCountryRepository implements + VisitorFlowCountryRepository, + Criteria { const INDEX_NAME = 'country-visitors-flow'; private $client; @@ -42,25 +45,30 @@ public function update(Aggregate $countryAggregate): Aggregate return $countryAggregate; } - public function getByParams(int $websiteId, string $url, int $level):?CountryAggregate + public function getCriteria(int $websiteId, string $url, int $level,string $country): array { - $params = [ - 'index' => self::INDEX_NAME, - 'body' => [ - 'query' => [ - 'bool' => [ - 'must' => [ - ['match' => ['websiteId' => $websiteId]], - ], - 'filter' => [ - ['term' => ['level' => $level]], - ['match_phrase' => ['url' => $url]], - ], - - ] + return [ + 'query' => [ + 'bool' => [ + 'must' => [ + ['match' => ['websiteId' => $websiteId]], + ], + 'filter' => [ + ['term' => ['level' => $level]], + ['match_phrase' => ['url' => $url]], + ['match_phrase' => ['country' => $country]], + ], ] ] ]; + } + + public function getByCriteria(int $websiteId, string $url, int $level,string $country): ?CountryAggregate + { + $params = [ + 'index' => self::INDEX_NAME, + 'body' => $this->getCriteria($websiteId, $url, $level, $country) + ]; try { $result = $this->client->search($params); } catch (\Exception $exception) { @@ -71,5 +79,4 @@ public function getByParams(int $websiteId, string $url, int $level):?CountryAgg } return CountryAggregate::fromResult($result['hits']['hits'][0]['_source']); } - } diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 45cfef59..6351085f 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -3,6 +3,7 @@ namespace App\Services\VisitorsFlow; +use App\Aggregates\VisitorsFlow\BrowserAggregate; use App\Aggregates\VisitorsFlow\CountryAggregate; use App\Aggregates\VisitorsFlow\Values\PageValue; use App\Entities\Visit; @@ -10,6 +11,7 @@ use App\Repositories\Contracts\PageRepository; use App\Repositories\Contracts\VisitRepository; use App\Repositories\Contracts\WebsiteRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use Carbon\Carbon; @@ -17,23 +19,26 @@ final class FlowAggregateService { private $pageRepository; private $visitRepository; - private $countryRepository; + private $visitorFlowCountryRepository; private $websiteRepository; private $geoPositionRepository; + private $visitorFlowBrowserRepository; public function __construct( PageRepository $pageRepository, VisitRepository $visitRepository, - VisitorFlowCountryRepository $countryRepository, + VisitorFlowCountryRepository $visitorFlowCountryRepository, WebsiteRepository $websiteRepository, - GeoPositionRepository $geoPositionRepository + GeoPositionRepository $geoPositionRepository, + VisitorFlowBrowserRepository $visitorFlowBrowserRepository ) { $this->pageRepository = $pageRepository; $this->visitRepository = $visitRepository; - $this->countryRepository = $countryRepository; + $this->visitorFlowCountryRepository = $visitorFlowCountryRepository; $this->websiteRepository = $websiteRepository; $this->geoPositionRepository = $geoPositionRepository; + $this->visitorFlowBrowserRepository = $visitorFlowBrowserRepository; } public function aggregate(Visit $visit) @@ -45,19 +50,36 @@ public function aggregate(Visit $visit) } else { $level = 1; } - $countryAggregate = $this->countryRepository->getByParams( + $countryAggregate = $this->visitorFlowCountryRepository->getByCriteria( $visit->session->website_id, $visit->page->url, - $level + $level, + $visit->geo_position->country + ); + $browserAggregate = $this->visitorFlowBrowserRepository->getByCriteria( + $visit->session->website_id, + $visit->page->url, + $level, + $visit->session->system->browser ); if (!$countryAggregate) { $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); - $countryAggregate = $this->countryRepository->save($countryAggregate); - dd($countryAggregate); + $countryAggregate = $this->visitorFlowCountryRepository->save($countryAggregate); +// dd($countryAggregate); } else { - $countryAggregate->views++; - $countryAggregate = $this->countryRepository->update($countryAggregate); - dd($countryAggregate); + $countryAggregate->views++; + $countryAggregate = $this->visitorFlowCountryRepository->update($countryAggregate); +// dd($countryAggregate); + } + + if (!$browserAggregate) { + $browserAggregate = $this->createBrowserAggregate($visit, $level, $previousVisit); + $browserAggregate = $this->visitorFlowBrowserRepository->save($browserAggregate); + dd($browserAggregate); + } else { + $browserAggregate->views++; + $browserAggregate = $this->visitorFlowBrowserRepository->update($browserAggregate); + dd($browserAggregate); } } @@ -84,14 +106,14 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $geoPosition = $this->geoPositionRepository->getById($currentVisit->geo_position_id); $prevPage = null; if ($level !== 1) { - //get previous aggregate - $previousAggregate = $this->countryRepository->getByParams( + $previousAggregate = $this->visitorFlowCountryRepository->getByCriteria( $previousVisit->session->website_id, $previousVisit->page->url, - $level - 1 + $level - 1, + $previousVisit->geo_position->country ); $previousAggregate->isLastPage = false; - $this->countryRepository->update($previousAggregate); + $this->visitorFlowCountryRepository->update($previousAggregate); $prevPage = new PageValue($previousVisit->id, $previousAggregate->url); } @@ -109,4 +131,36 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $prevPage ); } + + private function createBrowserAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit): BrowserAggregate + { + $page = $this->pageRepository->getById($currentVisit->page_id); + $website = $this->websiteRepository->getById($page->website_id); + $prevPage = null; + if ($level !== 1) { + $previousAggregate = $this->visitorFlowBrowserRepository->getByCriteria( + $previousVisit->session->website_id, + $previousVisit->page->url, + $level - 1, + $currentVisit->session->system->browser + ); + $previousAggregate->isLastPage = false; + $this->visitorFlowBrowserRepository->update($previousAggregate); + $prevPage = new PageValue($previousVisit->id, $previousAggregate->url); + } + + $isLatPage = true; + $views = 1; + return new BrowserAggregate( + $currentVisit->id, + $website->id, + $page->url, + $page->name, + $views, + $level, + $isLatPage, + $currentVisit->session->system->browser, + $prevPage + ); + } } From c1ef132e83ce604fa96a16e40c12803d6d401572 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 02:55:52 +0300 Subject: [PATCH 011/183] fix CountryAggregate --- .../VisitorsFlow/Contracts/Criteria.php | 2 +- .../VisitorFlowBrowserRepository.php | 2 +- .../VisitorFlowCountryRepository.php | 2 +- .../VisitorsFlow/CountryCriteria.php | 33 ++++++++++++ ...sticsearchVisitorFlowBrowserRepository.php | 39 ++++++-------- ...sticsearchVisitorFlowCountryRepository.php | 38 ++++++------- .../VisitorsFlow/FlowAggregateService.php | 54 ++++++++++--------- 7 files changed, 98 insertions(+), 72 deletions(-) create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php index fbaa74c1..cee0efc9 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php @@ -5,5 +5,5 @@ interface Criteria { - public function getCriteria(int $websiteId, string $url, int $level, string $type): array; + public static function getCriteria(int $websiteId, string $url, int $level, string $type); } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php index cabb1192..d17a45a4 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php @@ -12,5 +12,5 @@ public function save(Aggregate $browserAggregate): Aggregate; public function update(Aggregate $browserAggregate): Aggregate; - public function getByCriteria(int $websiteId, string $url, int $level, string $browser): ?BrowserAggregate; + public function getByCriteria(Criteria $criteria): ?BrowserAggregate; } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php index d9804792..79ef8cf1 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php @@ -12,5 +12,5 @@ public function save(Aggregate $tableAggregate): Aggregate; public function update(Aggregate $tableAggregate): Aggregate; - public function getByCriteria(int $websiteId, string $url, int $level, string $country): ?CountryAggregate; + public function getByCriteria(Criteria $criteria): ?CountryAggregate; } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php new file mode 100644 index 00000000..2f485a23 --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php @@ -0,0 +1,33 @@ +websiteId = $websiteId; + $this->url = $url; + $this->level = $level; + $this->country = $country; + } + + public static function getCriteria(int $websiteId, string $url, int $level, string $type) + { + return new static( + $websiteId, + $url, + $level, + $type + ); + } + +} diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php index b08a58de..ec4e89d2 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php @@ -9,9 +9,7 @@ use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use Cviebrock\LaravelElasticsearch\Manager as ElasticsearchManager; -class ElasticsearchVisitorFlowBrowserRepository implements - VisitorFlowBrowserRepository, - Criteria +class ElasticsearchVisitorFlowBrowserRepository implements VisitorFlowBrowserRepository { const INDEX_NAME = 'browser-visitors-flow'; private $client; @@ -45,30 +43,27 @@ public function update(Aggregate $countryAggregate): Aggregate return $countryAggregate; } - public function getCriteria(int $websiteId, string $url, int $level,string $browser): array - { - return [ - 'query' => [ - 'bool' => [ - 'must' => [ - ['match' => ['websiteId' => $websiteId]], - ], - 'filter' => [ - ['term' => ['level' => $level]], - ['match_phrase' => ['url' => $url]], - ['match_phrase' => ['browser' => $browser]], - ], - ] - ] - ]; - } - public function getByCriteria(int $websiteId, string $url, int $level,string $browser): ?BrowserAggregate + public function getByCriteria(Criteria $criteria): ?BrowserAggregate { $params = [ 'index' => self::INDEX_NAME, - 'body' => $this->getCriteria($websiteId, $url, $level) + 'body' => [ + 'query' => [ + 'bool' => [ + 'must' => [ + ['match' => ['websiteId' => $criteria->websiteId]], + ], + 'filter' => [ + ['term' => ['level' => $criteria->level]], + ['match_phrase' => ['url' => $criteria->url]], + ['match_phrase' => ['browser' => $criteria->browser]], + + ], + ] + ] + ] ]; try { $result = $this->client->search($params); diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php index 7bf528f0..80547f54 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php @@ -9,9 +9,7 @@ use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use Cviebrock\LaravelElasticsearch\Manager as ElasticsearchManager; -final class ElasticsearchVisitorFlowCountryRepository implements - VisitorFlowCountryRepository, - Criteria +final class ElasticsearchVisitorFlowCountryRepository implements VisitorFlowCountryRepository { const INDEX_NAME = 'country-visitors-flow'; private $client; @@ -45,29 +43,25 @@ public function update(Aggregate $countryAggregate): Aggregate return $countryAggregate; } - public function getCriteria(int $websiteId, string $url, int $level,string $country): array - { - return [ - 'query' => [ - 'bool' => [ - 'must' => [ - ['match' => ['websiteId' => $websiteId]], - ], - 'filter' => [ - ['term' => ['level' => $level]], - ['match_phrase' => ['url' => $url]], - ['match_phrase' => ['country' => $country]], - ], - ] - ] - ]; - } - public function getByCriteria(int $websiteId, string $url, int $level,string $country): ?CountryAggregate + public function getByCriteria(Criteria $criteria): ?CountryAggregate { $params = [ 'index' => self::INDEX_NAME, - 'body' => $this->getCriteria($websiteId, $url, $level, $country) + 'body' => [ + 'query' => [ + 'bool' => [ + 'must' => [ + ['match' => ['websiteId' => $criteria->websiteId]], + ], + 'filter' => [ + ['term' => ['level' => $criteria->level]], + ['match_phrase' => ['url' => $criteria->url]], + ['match_phrase' => ['country' => $criteria->country]], + ], + ] + ] + ] ]; try { $result = $this->client->search($params); diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 6351085f..bb6949a0 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -13,6 +13,7 @@ use App\Repositories\Contracts\WebsiteRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\CountryCriteria; use Carbon\Carbon; final class FlowAggregateService @@ -51,36 +52,37 @@ public function aggregate(Visit $visit) $level = 1; } $countryAggregate = $this->visitorFlowCountryRepository->getByCriteria( - $visit->session->website_id, - $visit->page->url, - $level, - $visit->geo_position->country - ); - $browserAggregate = $this->visitorFlowBrowserRepository->getByCriteria( - $visit->session->website_id, - $visit->page->url, - $level, - $visit->session->system->browser + CountryCriteria::getCriteria( + $visit->session->website_id, + $visit->page->url, + $level, + $visit->geo_position->country) ); +// $browserAggregate = $this->visitorFlowBrowserRepository->getByCriteria( +// $visit->session->website_id, +// $visit->page->url, +// $level, +// $visit->session->system->browser +// ); if (!$countryAggregate) { $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); $countryAggregate = $this->visitorFlowCountryRepository->save($countryAggregate); -// dd($countryAggregate); + dd($countryAggregate); } else { $countryAggregate->views++; $countryAggregate = $this->visitorFlowCountryRepository->update($countryAggregate); -// dd($countryAggregate); + dd($countryAggregate); } - if (!$browserAggregate) { - $browserAggregate = $this->createBrowserAggregate($visit, $level, $previousVisit); - $browserAggregate = $this->visitorFlowBrowserRepository->save($browserAggregate); - dd($browserAggregate); - } else { - $browserAggregate->views++; - $browserAggregate = $this->visitorFlowBrowserRepository->update($browserAggregate); - dd($browserAggregate); - } +// if (!$browserAggregate) { +// $browserAggregate = $this->createBrowserAggregate($visit, $level, $previousVisit); +// $browserAggregate = $this->visitorFlowBrowserRepository->save($browserAggregate); +// dd($browserAggregate); +// } else { +// $browserAggregate->views++; +// $browserAggregate = $this->visitorFlowBrowserRepository->update($browserAggregate); +// dd($browserAggregate); +// } } private function getPreviousVisit(Visit $currentVisit): ?Visit @@ -107,10 +109,12 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $prevPage = null; if ($level !== 1) { $previousAggregate = $this->visitorFlowCountryRepository->getByCriteria( - $previousVisit->session->website_id, - $previousVisit->page->url, - $level - 1, - $previousVisit->geo_position->country + CountryCriteria::getCriteria( + $previousVisit->session->website_id, + $previousVisit->page->url, + $level - 1, + $previousVisit->geo_position->country + ) ); $previousAggregate->isLastPage = false; $this->visitorFlowCountryRepository->update($previousAggregate); From 41e62bb5f7bf380179932b05f8db7bd7f497f0c3 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 03:31:32 +0300 Subject: [PATCH 012/183] create browserCriteria --- .../VisitorsFlow/BrowserCriteria.php | 32 +++++++++++++ .../VisitorsFlow/CountryCriteria.php | 1 - ...sticsearchVisitorFlowBrowserRepository.php | 18 ++++---- .../VisitorsFlow/FlowAggregateService.php | 46 ++++++++++--------- 4 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php new file mode 100644 index 00000000..a145713e --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php @@ -0,0 +1,32 @@ +websiteId = $websiteId; + $this->url = $url; + $this->level = $level; + $this->browser = $browser; + } + + public static function getCriteria(int $websiteId, string $url, int $level, string $type) + { + return new static( + $websiteId, + $url, + $level, + $type + ); + } +} diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php index 2f485a23..b08e9709 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php @@ -29,5 +29,4 @@ public static function getCriteria(int $websiteId, string $url, int $level, stri $type ); } - } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php index ec4e89d2..c70af296 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php @@ -19,32 +19,31 @@ public function __construct(ElasticsearchManager $client) $this->client = $client; } - public function save(Aggregate $countryAggregate): Aggregate + public function save(Aggregate $browserAggregate): Aggregate { $this->client->index([ 'index' => self::INDEX_NAME, - 'id' => $countryAggregate->getId(), + 'id' => $browserAggregate->getId(), 'type' => '_doc', - 'body' => $countryAggregate->toArray() + 'body' => $browserAggregate->toArray() ]); - return $countryAggregate; + return $browserAggregate; } - public function update(Aggregate $countryAggregate): Aggregate + public function update(Aggregate $browserAggregate): Aggregate { $this->client->index([ 'index' => self::INDEX_NAME, - 'id' => $countryAggregate->getId(), + 'id' => $browserAggregate->getId(), 'type' => '_doc', - 'body' => $countryAggregate->toArray() + 'body' => $browserAggregate->toArray() ]); - return $countryAggregate; + return $browserAggregate; } - public function getByCriteria(Criteria $criteria): ?BrowserAggregate { $params = [ @@ -59,7 +58,6 @@ public function getByCriteria(Criteria $criteria): ?BrowserAggregate ['term' => ['level' => $criteria->level]], ['match_phrase' => ['url' => $criteria->url]], ['match_phrase' => ['browser' => $criteria->browser]], - ], ] ] diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index bb6949a0..67d83dfc 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -11,6 +11,7 @@ use App\Repositories\Contracts\PageRepository; use App\Repositories\Contracts\VisitRepository; use App\Repositories\Contracts\WebsiteRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\BrowserCriteria; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use App\Repositories\Elasticsearch\VisitorsFlow\CountryCriteria; @@ -44,6 +45,7 @@ public function __construct( public function aggregate(Visit $visit) { + dd($visit); $previousVisit = $this->getPreviousVisit($visit); $isFirstInSession = $previousVisit === null; if (!$isFirstInSession) { @@ -58,31 +60,31 @@ public function aggregate(Visit $visit) $level, $visit->geo_position->country) ); -// $browserAggregate = $this->visitorFlowBrowserRepository->getByCriteria( -// $visit->session->website_id, -// $visit->page->url, -// $level, -// $visit->session->system->browser -// ); + $browserAggregate = $this->visitorFlowBrowserRepository->getByCriteria( + BrowserCriteria::getCriteria( + $visit->session->website_id, + $visit->page->url, + $level, + $visit->session->system->browser + ) + ); if (!$countryAggregate) { $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); $countryAggregate = $this->visitorFlowCountryRepository->save($countryAggregate); - dd($countryAggregate); } else { $countryAggregate->views++; $countryAggregate = $this->visitorFlowCountryRepository->update($countryAggregate); - dd($countryAggregate); } -// if (!$browserAggregate) { -// $browserAggregate = $this->createBrowserAggregate($visit, $level, $previousVisit); -// $browserAggregate = $this->visitorFlowBrowserRepository->save($browserAggregate); -// dd($browserAggregate); -// } else { -// $browserAggregate->views++; -// $browserAggregate = $this->visitorFlowBrowserRepository->update($browserAggregate); -// dd($browserAggregate); -// } + if (!$browserAggregate) { + $browserAggregate = $this->createBrowserAggregate($visit, $level, $previousVisit); + $browserAggregate = $this->visitorFlowBrowserRepository->save($browserAggregate); + dd($browserAggregate); + } else { + $browserAggregate->views++; + $browserAggregate = $this->visitorFlowBrowserRepository->update($browserAggregate); + dd($browserAggregate); + } } private function getPreviousVisit(Visit $currentVisit): ?Visit @@ -143,10 +145,12 @@ private function createBrowserAggregate(Visit $currentVisit, int $level, ?Visit $prevPage = null; if ($level !== 1) { $previousAggregate = $this->visitorFlowBrowserRepository->getByCriteria( - $previousVisit->session->website_id, - $previousVisit->page->url, - $level - 1, - $currentVisit->session->system->browser + BrowserCriteria::getCriteria( + $previousVisit->session->website_id, + $previousVisit->page->url, + $level - 1, + $currentVisit->session->system->browser + ) ); $previousAggregate->isLastPage = false; $this->visitorFlowBrowserRepository->update($previousAggregate); From 1b05b817742571374a44c625fa07a5990a59ae6b Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 15:27:29 +0300 Subject: [PATCH 013/183] add getPreviousVisit method --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 4 ++ .../VisitorsFlow/BrowserAggregate.php | 4 +- .../VisitorsFlow/CountryAggregate.php | 4 +- .../VisitorsFlow/DeviceAggregate.php | 4 +- .../VisitorsFlow/ScreenAggregate.php | 4 +- .../VisitorsFlow/Values/PageValue.php | 2 +- .../VisitorsFlow/BrowserCriteria.php | 11 +++-- .../VisitorsFlow/Contracts/Criteria.php | 2 +- .../VisitorsFlow/CountryCriteria.php | 9 ++-- ...sticsearchVisitorFlowBrowserRepository.php | 1 + ...sticsearchVisitorFlowCountryRepository.php | 1 + .../VisitorsFlow/FlowAggregateService.php | 42 ++++++++++++++----- 12 files changed, 65 insertions(+), 23 deletions(-) diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index 26e68c3a..e1b84d1f 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -15,6 +15,7 @@ abstract class Aggregate public $views; public $level; public $isLastPage; + public $exitCount; public function __construct( int $id, @@ -24,6 +25,7 @@ public function __construct( int $views, int $level, bool $isLastPage, + int $exitCount, ?PageValue $prevPage ) { @@ -34,6 +36,7 @@ public function __construct( $this->views = $views; $this->level = $level; $this->isLastPage = $isLastPage; + $this->exitCount = $exitCount; $this->prevPage = $prevPage; } @@ -52,6 +55,7 @@ public function toArray(): array 'level' => $this->level, 'views' => $this->views, 'isLastPage' => $this->isLastPage, + 'exitCount' => $this->exitCount ]; } diff --git a/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php b/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php index 0f20483a..067f5f1f 100644 --- a/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php @@ -17,10 +17,11 @@ public function __construct( int $views, int $level, bool $isLastPage, + int $exitCount, string $browser, ?PageValue $prevPage ) { - parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); + parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); $this->browser = $browser; } @@ -39,6 +40,7 @@ public static function fromResult(array $result): Aggregate (int)$result['views'], (int)$result['level'], (bool)$result['isLastPage'], + (int)$result['exitCount'], (string)$result['browser'], $result['prevPage'] === null ? null : new PageValue( (int)$result['prevPage']['id'], diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index a47a816a..d0af86a3 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -17,11 +17,12 @@ public function __construct( int $views, int $level, bool $isLastPage, + int $exitCount, string $country, ?PageValue $prevPage ) { - parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); + parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); $this->country = $country; } @@ -40,6 +41,7 @@ public static function fromResult(array $result): Aggregate (int)$result['views'], (int)$result['level'], (bool)$result['isLastPage'], + (int)$result['exitCount'], (string)$result['country'], $result['prevPage'] === null ? null : new PageValue( (int)$result['prevPage']['id'], diff --git a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php index 86f4f41a..67dc0dd3 100644 --- a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php @@ -17,11 +17,12 @@ public function __construct( int $views, int $level, bool $isLastPage, + int $exitCount, string $device, ?PageValue $prevPage ) { - parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); + parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); $this->$device = $device; } @@ -40,6 +41,7 @@ public static function fromResult(array $result): Aggregate (int)$result['views'], (int)$result['level'], (bool)$result['isLastPage'], + (int)$result['exitCount'], (string)$result['device'], $result['prevPage'] === null ? null : new PageValue( (int)$result['prevPage']['id'], diff --git a/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php b/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php index d577351a..e4e3ee16 100644 --- a/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php @@ -18,12 +18,13 @@ public function __construct( int $views, int $level, bool $isLastPage, + int $exitCount, int $resolutionWidth, int $resolutionHeight, ?PageValue $prevPage ) { - parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $prevPage); + parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); $this->resolutionWidth = $resolutionWidth; $this->resolutionHeight = $resolutionHeight; } @@ -46,6 +47,7 @@ public static function fromResult(array $result): Aggregate (int)$result['views'], (int)$result['level'], (bool)$result['isLastPage'], + (int)$result['exitCount'], (int)$result['resolution_width'], (int)$result['resolution_height'], $result['prevPage'] === null ? null : new PageValue( diff --git a/backend/app/Aggregates/VisitorsFlow/Values/PageValue.php b/backend/app/Aggregates/VisitorsFlow/Values/PageValue.php index d99071a9..fbeda97d 100644 --- a/backend/app/Aggregates/VisitorsFlow/Values/PageValue.php +++ b/backend/app/Aggregates/VisitorsFlow/Values/PageValue.php @@ -8,7 +8,7 @@ class PageValue public $id; public $url; - public function __construct(int $id, string $url) + public function __construct(int $id = null, string $url = 'null') { $this->id = $id; $this->url = $url; diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php index a145713e..128458ae 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php @@ -5,28 +5,31 @@ use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\Criteria; -class BrowserCriteria implements Criteria +class BrowserCriteria implements Criteria { public $websiteId; public $url; public $level; public $browser; + public $prevPageUrl; - private function __construct(int $websiteId, string $url, int $level, string $browser) + private function __construct(int $websiteId, string $url, int $level, string $browser, ?string $prevPageUrl) { $this->websiteId = $websiteId; $this->url = $url; $this->level = $level; $this->browser = $browser; + $this->prevPageUrl = $prevPageUrl; } - public static function getCriteria(int $websiteId, string $url, int $level, string $type) + public static function getCriteria(int $websiteId, string $url, int $level, string $type, ?string $prevPageUrl) { return new static( $websiteId, $url, $level, - $type + $type, + $prevPageUrl ); } } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php index cee0efc9..d8b10374 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php @@ -5,5 +5,5 @@ interface Criteria { - public static function getCriteria(int $websiteId, string $url, int $level, string $type); + public static function getCriteria(int $websiteId, string $url, int $level, string $type, ?string $prevPageUrl); } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php index b08e9709..9a9e9c48 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/CountryCriteria.php @@ -11,22 +11,25 @@ class CountryCriteria implements Criteria public $url; public $level; public $country; + public $prevPageUrl; - private function __construct(int $websiteId, string $url, int $level, string $country) + private function __construct(int $websiteId, string $url, int $level, string $country, ?string $prevPageUrl) { $this->websiteId = $websiteId; $this->url = $url; $this->level = $level; $this->country = $country; + $this->prevPageUrl = $prevPageUrl; } - public static function getCriteria(int $websiteId, string $url, int $level, string $type) + public static function getCriteria(int $websiteId, string $url, int $level, string $type, ?string $prevPageUrl) { return new static( $websiteId, $url, $level, - $type + $type, + $prevPageUrl ); } } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php index c70af296..6da34285 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowBrowserRepository.php @@ -58,6 +58,7 @@ public function getByCriteria(Criteria $criteria): ?BrowserAggregate ['term' => ['level' => $criteria->level]], ['match_phrase' => ['url' => $criteria->url]], ['match_phrase' => ['browser' => $criteria->browser]], + ['match_phrase'=>['prevPage.url'=>$criteria->prevPageUrl]] ], ] ] diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php index 80547f54..c3788b2a 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowCountryRepository.php @@ -58,6 +58,7 @@ public function getByCriteria(Criteria $criteria): ?CountryAggregate ['term' => ['level' => $criteria->level]], ['match_phrase' => ['url' => $criteria->url]], ['match_phrase' => ['country' => $criteria->country]], + ['match_phrase'=>['prevPage.url'=>$criteria->prevPageUrl]] ], ] ] diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 67d83dfc..84fd3bac 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -45,8 +45,7 @@ public function __construct( public function aggregate(Visit $visit) { - dd($visit); - $previousVisit = $this->getPreviousVisit($visit); + $previousVisit = $this->getLastVisit($visit); $isFirstInSession = $previousVisit === null; if (!$isFirstInSession) { $level = $this->getVisitsCount($visit); @@ -58,14 +57,17 @@ public function aggregate(Visit $visit) $visit->session->website_id, $visit->page->url, $level, - $visit->geo_position->country) + $visit->geo_position->country, + $isFirstInSession ? 'null' : $previousVisit->page->url + ) ); $browserAggregate = $this->visitorFlowBrowserRepository->getByCriteria( BrowserCriteria::getCriteria( $visit->session->website_id, $visit->page->url, $level, - $visit->session->system->browser + $visit->session->system->browser, + $isFirstInSession ? 'null' : $previousVisit->page->url ) ); if (!$countryAggregate) { @@ -87,7 +89,7 @@ public function aggregate(Visit $visit) } } - private function getPreviousVisit(Visit $currentVisit): ?Visit + private function getLastVisit(Visit $currentVisit): ?Visit { return $this->visitRepository->findBySessionId($currentVisit->session_id) ->sortBy(function (Visit $visit) { @@ -98,6 +100,18 @@ private function getPreviousVisit(Visit $currentVisit): ?Visit }); } + private function getPreviousVisit(Visit $currentVisit): ?Visit + { + return $this->visitRepository->findBySessionId($currentVisit->session_id) + ->filter(function (Visit $visit) use ($currentVisit) { + return (new Carbon($currentVisit->visit_time))->greaterThan(new Carbon($visit->visit_time)); + }) + ->sortBy(function (Visit $visit) { + return (new Carbon($visit->visit_time))->getTimestamp(); + }) + ->last(); + } + private function getVisitsCount(Visit $currentVisit): int { return $this->visitRepository->findBySessionId($currentVisit->session_id)->count(); @@ -108,22 +122,26 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $page = $this->pageRepository->getById($currentVisit->page_id); $website = $this->websiteRepository->getById($page->website_id); $geoPosition = $this->geoPositionRepository->getById($currentVisit->geo_position_id); - $prevPage = null; + $prevPage = new PageValue(); if ($level !== 1) { + $previousAggregate = $this->visitorFlowCountryRepository->getByCriteria( CountryCriteria::getCriteria( $previousVisit->session->website_id, $previousVisit->page->url, $level - 1, - $previousVisit->geo_position->country + $previousVisit->geo_position->country, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' ) ); $previousAggregate->isLastPage = false; + $previousAggregate->exitCount--; $this->visitorFlowCountryRepository->update($previousAggregate); $prevPage = new PageValue($previousVisit->id, $previousAggregate->url); } $isLatPage = true; + $exitCount = 1; $views = 1; return new CountryAggregate( $currentVisit->id, @@ -133,6 +151,7 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $views, $level, $isLatPage, + $exitCount, $geoPosition->country, $prevPage ); @@ -142,21 +161,23 @@ private function createBrowserAggregate(Visit $currentVisit, int $level, ?Visit { $page = $this->pageRepository->getById($currentVisit->page_id); $website = $this->websiteRepository->getById($page->website_id); - $prevPage = null; + $prevPage = new PageValue(); if ($level !== 1) { $previousAggregate = $this->visitorFlowBrowserRepository->getByCriteria( BrowserCriteria::getCriteria( $previousVisit->session->website_id, $previousVisit->page->url, $level - 1, - $currentVisit->session->system->browser + $currentVisit->session->system->browser, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' ) ); $previousAggregate->isLastPage = false; + $previousAggregate->exitCount--; $this->visitorFlowBrowserRepository->update($previousAggregate); $prevPage = new PageValue($previousVisit->id, $previousAggregate->url); } - + $exitCount = 1; $isLatPage = true; $views = 1; return new BrowserAggregate( @@ -167,6 +188,7 @@ private function createBrowserAggregate(Visit $currentVisit, int $level, ?Visit $views, $level, $isLatPage, + $exitCount, $currentVisit->session->system->browser, $prevPage ); From 4237cf5f7d063d6be93d55be75a7c98343866dd9 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 15:55:05 +0300 Subject: [PATCH 014/183] add exitCount for counting left visitors from page --- .../VisitorsFlow/FlowAggregateService.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 84fd3bac..fcca9bda 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -83,7 +83,22 @@ public function aggregate(Visit $visit) $browserAggregate = $this->visitorFlowBrowserRepository->save($browserAggregate); dd($browserAggregate); } else { + if ($level > 1) { + $previousAggregate = $this->visitorFlowBrowserRepository->getByCriteria( + BrowserCriteria::getCriteria( + $previousVisit->session->website_id, + $previousVisit->page->url, + $level - 1, + $previousVisit->session->system->browser, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' + ) + ); + $previousAggregate->isLastPage = false; + $previousAggregate->exitCount--; + $this->visitorFlowBrowserRepository->update($previousAggregate); + } $browserAggregate->views++; + $browserAggregate->exitCount++; $browserAggregate = $this->visitorFlowBrowserRepository->update($browserAggregate); dd($browserAggregate); } From d29b74d019042b40231700811b4781e25c295e52 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 16:38:09 +0300 Subject: [PATCH 015/183] implement countryAggregate and browserAggregate --- .../VisitorsFlow/FlowAggregateService.php | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index fcca9bda..f44e5e85 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -3,6 +3,7 @@ namespace App\Services\VisitorsFlow; +use App\Aggregates\VisitorsFlow\Aggregate; use App\Aggregates\VisitorsFlow\BrowserAggregate; use App\Aggregates\VisitorsFlow\CountryAggregate; use App\Aggregates\VisitorsFlow\Values\PageValue; @@ -12,6 +13,7 @@ use App\Repositories\Contracts\VisitRepository; use App\Repositories\Contracts\WebsiteRepository; use App\Repositories\Elasticsearch\VisitorsFlow\BrowserCriteria; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\Criteria; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use App\Repositories\Elasticsearch\VisitorsFlow\CountryCriteria; @@ -74,7 +76,14 @@ public function aggregate(Visit $visit) $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); $countryAggregate = $this->visitorFlowCountryRepository->save($countryAggregate); } else { + if ($level > 1) { + $previousAggregate = $this->getPreviousCountryAggregate($previousVisit, $level); + $previousAggregate->isLastPage = false; + $previousAggregate->exitCount--; + $this->visitorFlowCountryRepository->update($previousAggregate); + } $countryAggregate->views++; + $countryAggregate->exitCount++; $countryAggregate = $this->visitorFlowCountryRepository->update($countryAggregate); } @@ -84,15 +93,7 @@ public function aggregate(Visit $visit) dd($browserAggregate); } else { if ($level > 1) { - $previousAggregate = $this->visitorFlowBrowserRepository->getByCriteria( - BrowserCriteria::getCriteria( - $previousVisit->session->website_id, - $previousVisit->page->url, - $level - 1, - $previousVisit->session->system->browser, - $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' - ) - ); + $previousAggregate = $this->getPreviousBrowserAggregate($previousVisit, $level); $previousAggregate->isLastPage = false; $previousAggregate->exitCount--; $this->visitorFlowBrowserRepository->update($previousAggregate); @@ -132,6 +133,32 @@ private function getVisitsCount(Visit $currentVisit): int return $this->visitRepository->findBySessionId($currentVisit->session_id)->count(); } + private function getPreviousBrowserAggregate(Visit $previousVisit, int $level): BrowserAggregate + { + return $this->visitorFlowBrowserRepository->getByCriteria( + BrowserCriteria::getCriteria( + $previousVisit->session->website_id, + $previousVisit->page->url, + $level - 1, + $previousVisit->session->system->browser, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' + ) + ); + } + + private function getPreviousCountryAggregate(Visit $previousVisit, int $level): CountryAggregate + { + return $this->visitorFlowCountryRepository->getByCriteria( + CountryCriteria::getCriteria( + $previousVisit->session->website_id, + $previousVisit->page->url, + $level - 1, + $previousVisit->geo_position->country, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' + ) + ); + } + private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit): CountryAggregate { $page = $this->pageRepository->getById($currentVisit->page_id); @@ -139,16 +166,7 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $geoPosition = $this->geoPositionRepository->getById($currentVisit->geo_position_id); $prevPage = new PageValue(); if ($level !== 1) { - - $previousAggregate = $this->visitorFlowCountryRepository->getByCriteria( - CountryCriteria::getCriteria( - $previousVisit->session->website_id, - $previousVisit->page->url, - $level - 1, - $previousVisit->geo_position->country, - $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' - ) - ); + $previousAggregate = $this->getPreviousCountryAggregate($previousVisit, $level); $previousAggregate->isLastPage = false; $previousAggregate->exitCount--; $this->visitorFlowCountryRepository->update($previousAggregate); @@ -178,15 +196,7 @@ private function createBrowserAggregate(Visit $currentVisit, int $level, ?Visit $website = $this->websiteRepository->getById($page->website_id); $prevPage = new PageValue(); if ($level !== 1) { - $previousAggregate = $this->visitorFlowBrowserRepository->getByCriteria( - BrowserCriteria::getCriteria( - $previousVisit->session->website_id, - $previousVisit->page->url, - $level - 1, - $currentVisit->session->system->browser, - $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' - ) - ); + $previousAggregate = $this->getPreviousBrowserAggregate($previousVisit, $level); $previousAggregate->isLastPage = false; $previousAggregate->exitCount--; $this->visitorFlowBrowserRepository->update($previousAggregate); From 5cb4503d7904239eaed1bf92e94fcfd2447c6171 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 17:34:30 +0300 Subject: [PATCH 016/183] replace getPreviousAggregate method to Aggregate --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 9 +++ .../VisitorsFlow/BrowserAggregate.php | 24 +++++++- .../VisitorsFlow/CountryAggregate.php | 21 +++++++ .../VisitorFlowBrowserRepository.php | 2 +- .../VisitorFlowCountryRepository.php | 2 +- .../Contracts/VisitorFlowRepository.php | 9 +++ .../VisitorsFlow/FlowAggregateService.php | 56 ++++++++----------- 7 files changed, 88 insertions(+), 35 deletions(-) create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowRepository.php diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index e1b84d1f..3072bffb 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -4,6 +4,8 @@ namespace App\Aggregates\VisitorsFlow; use App\Aggregates\VisitorsFlow\Values\PageValue; +use App\Entities\Visit; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowRepository; abstract class Aggregate { @@ -65,4 +67,11 @@ public function getId(): int } public abstract static function fromResult(array $result): self; + + public abstract static function getPreviousAggregate( + VisitorFlowRepository $visitorFlowBrowserRepository, + Visit $visit, + string $previousVisitUrl, + int $level + ): Aggregate; } diff --git a/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php b/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php index 067f5f1f..984fe188 100644 --- a/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php @@ -4,6 +4,9 @@ namespace App\Aggregates\VisitorsFlow; use App\Aggregates\VisitorsFlow\Values\PageValue; +use App\Entities\Visit; +use App\Repositories\Elasticsearch\VisitorsFlow\BrowserCriteria; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowRepository; class BrowserAggregate extends Aggregate { @@ -20,7 +23,8 @@ public function __construct( int $exitCount, string $browser, ?PageValue $prevPage - ) { + ) + { parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); $this->browser = $browser; } @@ -48,4 +52,22 @@ public static function fromResult(array $result): Aggregate ) ); } + + public static function getPreviousAggregate( + VisitorFlowRepository $visitorFlowBrowserRepository, + Visit $visit, + string $previousVisitUrl, + int $level + ): Aggregate + { + return $visitorFlowBrowserRepository->getByCriteria( + BrowserCriteria::getCriteria( + $visit->session->website_id, + $visit->page->url, + $level - 1, + $visit->session->system->browser, + $previousVisitUrl + ) + ); + } } diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index d0af86a3..74c600f5 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -4,6 +4,9 @@ namespace App\Aggregates\VisitorsFlow; use App\Aggregates\VisitorsFlow\Values\PageValue; +use App\Entities\Visit; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\CountryCriteria; class CountryAggregate extends Aggregate { @@ -49,4 +52,22 @@ public static function fromResult(array $result): Aggregate ) ); } + + public static function getPreviousAggregate( + VisitorFlowRepository $visitorFlowCountryRepository, + Visit $visit, + string $previousVisitUrl, + int $level + ): Aggregate + { + return $visitorFlowCountryRepository->getByCriteria( + CountryCriteria::getCriteria( + $visit->session->website_id, + $visit->page->url, + $level - 1, + $visit->geo_position->country, + $previousVisitUrl + ) + ); + } } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php index d17a45a4..efc12f80 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowBrowserRepository.php @@ -6,7 +6,7 @@ use App\Aggregates\VisitorsFlow\Aggregate; use App\Aggregates\VisitorsFlow\BrowserAggregate; -interface VisitorFlowBrowserRepository +interface VisitorFlowBrowserRepository extends VisitorFlowRepository { public function save(Aggregate $browserAggregate): Aggregate; diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php index 79ef8cf1..36da6c8b 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowCountryRepository.php @@ -6,7 +6,7 @@ use App\Aggregates\VisitorsFlow\Aggregate; use App\Aggregates\VisitorsFlow\CountryAggregate; -interface VisitorFlowCountryRepository +interface VisitorFlowCountryRepository extends VisitorFlowRepository { public function save(Aggregate $tableAggregate): Aggregate; diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowRepository.php new file mode 100644 index 00000000..e6acc7e5 --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowRepository.php @@ -0,0 +1,9 @@ +visitorFlowCountryRepository->save($countryAggregate); } else { if ($level > 1) { - $previousAggregate = $this->getPreviousCountryAggregate($previousVisit, $level); + $previousAggregate = CountryAggregate::getPreviousAggregate( + $this->visitorFlowCountryRepository, + $previousVisit, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null', + $level + ); $previousAggregate->isLastPage = false; $previousAggregate->exitCount--; $this->visitorFlowCountryRepository->update($previousAggregate); @@ -93,7 +96,12 @@ public function aggregate(Visit $visit) dd($browserAggregate); } else { if ($level > 1) { - $previousAggregate = $this->getPreviousBrowserAggregate($previousVisit, $level); + $previousAggregate = BrowserAggregate::getPreviousAggregate( + $this->visitorFlowBrowserRepository, + $previousVisit, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null', + $level + ); $previousAggregate->isLastPage = false; $previousAggregate->exitCount--; $this->visitorFlowBrowserRepository->update($previousAggregate); @@ -133,32 +141,6 @@ private function getVisitsCount(Visit $currentVisit): int return $this->visitRepository->findBySessionId($currentVisit->session_id)->count(); } - private function getPreviousBrowserAggregate(Visit $previousVisit, int $level): BrowserAggregate - { - return $this->visitorFlowBrowserRepository->getByCriteria( - BrowserCriteria::getCriteria( - $previousVisit->session->website_id, - $previousVisit->page->url, - $level - 1, - $previousVisit->session->system->browser, - $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' - ) - ); - } - - private function getPreviousCountryAggregate(Visit $previousVisit, int $level): CountryAggregate - { - return $this->visitorFlowCountryRepository->getByCriteria( - CountryCriteria::getCriteria( - $previousVisit->session->website_id, - $previousVisit->page->url, - $level - 1, - $previousVisit->geo_position->country, - $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null' - ) - ); - } - private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit): CountryAggregate { $page = $this->pageRepository->getById($currentVisit->page_id); @@ -166,7 +148,12 @@ private function createCountryAggregate(Visit $currentVisit, int $level, ?Visit $geoPosition = $this->geoPositionRepository->getById($currentVisit->geo_position_id); $prevPage = new PageValue(); if ($level !== 1) { - $previousAggregate = $this->getPreviousCountryAggregate($previousVisit, $level); + $previousAggregate = CountryAggregate::getPreviousAggregate( + $this->visitorFlowCountryRepository, + $previousVisit, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null', + $level + ); $previousAggregate->isLastPage = false; $previousAggregate->exitCount--; $this->visitorFlowCountryRepository->update($previousAggregate); @@ -196,7 +183,12 @@ private function createBrowserAggregate(Visit $currentVisit, int $level, ?Visit $website = $this->websiteRepository->getById($page->website_id); $prevPage = new PageValue(); if ($level !== 1) { - $previousAggregate = $this->getPreviousBrowserAggregate($previousVisit, $level); + $previousAggregate = BrowserAggregate::getPreviousAggregate( + $this->visitorFlowBrowserRepository, + $previousVisit, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null', + $level + ); $previousAggregate->isLastPage = false; $previousAggregate->exitCount--; $this->visitorFlowBrowserRepository->update($previousAggregate); From b8726eb530047ea0eb1cfe9d53a08620647c74a8 Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 18:16:02 +0300 Subject: [PATCH 017/183] implement device aggregate --- .../VisitorsFlow/DeviceAggregate.php | 24 +++++- backend/app/Providers/AppServiceProvider.php | 4 + .../Contracts/VisitorFlowDeviceRepository.php | 16 ++++ .../VisitorsFlow/DeviceCriteria.php | 36 +++++++++ ...asticsearchVisitorFlowDeviceRepository.php | 78 +++++++++++++++++++ .../VisitorsFlow/FlowAggregateService.php | 78 ++++++++++++++++++- 6 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowDeviceRepository.php create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/DeviceCriteria.php create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowDeviceRepository.php diff --git a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php index 67dc0dd3..035367c8 100644 --- a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php @@ -4,6 +4,10 @@ namespace App\Aggregates\VisitorsFlow; use App\Aggregates\VisitorsFlow\Values\PageValue; +use App\Entities\Visit; +use App\Repositories\Elasticsearch\VisitorsFlow\BrowserCriteria; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\DeviceCriteria; class DeviceAggregate extends Aggregate { @@ -23,7 +27,7 @@ public function __construct( ) { parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); - $this->$device = $device; + $this->device = $device; } public function toArray(): array @@ -49,4 +53,22 @@ public static function fromResult(array $result): Aggregate ) ); } + + public static function getPreviousAggregate( + VisitorFlowRepository $visitorFlowDeviceRepository, + Visit $visit, + string $previousVisitUrl, + int $level + ): Aggregate + { + return $visitorFlowDeviceRepository->getByCriteria( + DeviceCriteria::getCriteria( + $visit->session->website_id, + $visit->page->url, + $level - 1, + $visit->session->system->device, + $previousVisitUrl + ) + ); + } } diff --git a/backend/app/Providers/AppServiceProvider.php b/backend/app/Providers/AppServiceProvider.php index f55987a0..150f081e 100644 --- a/backend/app/Providers/AppServiceProvider.php +++ b/backend/app/Providers/AppServiceProvider.php @@ -25,8 +25,10 @@ use App\Repositories\Contracts\PageViews\ChartDataRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowDeviceRepository; use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowCountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowDeviceRepository; use App\Repositories\EloquentChartPageTimingRepository; use App\Repositories\EloquentChartVisitorRepository; use App\Repositories\EloquentButtonVisitorsRepository; @@ -110,6 +112,8 @@ public function register() $this->app->bind(VisitorFlowCountryRepository::class, ElasticsearchVisitorFlowCountryRepository::class); $this->app->bind(VisitorFlowBrowserRepository::class, ElasticsearchVisitorFlowBrowserRepository::class); + + $this->app->bind(VisitorFlowDeviceRepository::class, ElasticsearchVisitorFlowDeviceRepository::class); } /** diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowDeviceRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowDeviceRepository.php new file mode 100644 index 00000000..6174152b --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowDeviceRepository.php @@ -0,0 +1,16 @@ +websiteId = $websiteId; + $this->url = $url; + $this->level = $level; + $this->device = $device; + $this->prevPageUrl = $prevPageUrl; + } + + public static function getCriteria(int $websiteId, string $url, int $level, string $type, ?string $prevPageUrl) + { + return new static( + $websiteId, + $url, + $level, + $type, + $prevPageUrl + ); + } +} + diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowDeviceRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowDeviceRepository.php new file mode 100644 index 00000000..3a97105e --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowDeviceRepository.php @@ -0,0 +1,78 @@ +client = $client; + } + + public function save(Aggregate $deviceAggregate): Aggregate + { + $this->client->index([ + 'index' => self::INDEX_NAME, + 'id' => $deviceAggregate->getId(), + 'type' => '_doc', + 'body' => $deviceAggregate->toArray() + ]); + + return $deviceAggregate; + } + + public function update(Aggregate $deviceAggregate): Aggregate + { + $this->client->index([ + 'index' => self::INDEX_NAME, + 'id' => $deviceAggregate->getId(), + 'type' => '_doc', + 'body' => $deviceAggregate->toArray() + ]); + + return $deviceAggregate; + } + + + public function getByCriteria(Criteria $criteria): ?DeviceAggregate + { + $params = [ + 'index' => self::INDEX_NAME, + 'body' => [ + 'query' => [ + 'bool' => [ + 'must' => [ + ['match' => ['websiteId' => $criteria->websiteId]], + ], + 'filter' => [ + ['term' => ['level' => $criteria->level]], + ['match_phrase' => ['url' => $criteria->url]], + ['match_phrase' => ['device' => $criteria->device]], + ['match_phrase'=>['prevPage.url'=>$criteria->prevPageUrl]] + ], + ] + ] + ] + ]; + try { + $result = $this->client->search($params); + } catch (\Exception $exception) { + return null; + } + if (empty($result['hits']['hits'])) { + return null; + } + return DeviceAggregate::fromResult($result['hits']['hits'][0]['_source']); + } +} diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 9361412e..977b5e9f 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -5,6 +5,7 @@ use App\Aggregates\VisitorsFlow\BrowserAggregate; use App\Aggregates\VisitorsFlow\CountryAggregate; +use App\Aggregates\VisitorsFlow\DeviceAggregate; use App\Aggregates\VisitorsFlow\Values\PageValue; use App\Entities\Visit; use App\Repositories\Contracts\GeoPositionRepository; @@ -14,7 +15,9 @@ use App\Repositories\Elasticsearch\VisitorsFlow\BrowserCriteria; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowDeviceRepository; use App\Repositories\Elasticsearch\VisitorsFlow\CountryCriteria; +use App\Repositories\Elasticsearch\VisitorsFlow\DeviceCriteria; use Carbon\Carbon; final class FlowAggregateService @@ -25,6 +28,8 @@ final class FlowAggregateService private $websiteRepository; private $geoPositionRepository; private $visitorFlowBrowserRepository; + private $visitorFlowDeviceRepository; + public function __construct( PageRepository $pageRepository, @@ -32,7 +37,8 @@ public function __construct( VisitorFlowCountryRepository $visitorFlowCountryRepository, WebsiteRepository $websiteRepository, GeoPositionRepository $geoPositionRepository, - VisitorFlowBrowserRepository $visitorFlowBrowserRepository + VisitorFlowBrowserRepository $visitorFlowBrowserRepository, + VisitorFlowDeviceRepository $visitorFlowDeviceRepository ) { $this->pageRepository = $pageRepository; @@ -41,6 +47,7 @@ public function __construct( $this->websiteRepository = $websiteRepository; $this->geoPositionRepository = $geoPositionRepository; $this->visitorFlowBrowserRepository = $visitorFlowBrowserRepository; + $this->visitorFlowDeviceRepository = $visitorFlowDeviceRepository; } public function aggregate(Visit $visit) @@ -70,6 +77,16 @@ public function aggregate(Visit $visit) $isFirstInSession ? 'null' : $previousVisit->page->url ) ); + + $deviceAggregate = $this->visitorFlowDeviceRepository->getByCriteria( + DeviceCriteria::getCriteria( + $visit->session->website_id, + $visit->page->url, + $level, + $visit->session->system->device, + $isFirstInSession ? 'null' : $previousVisit->page->url + ) + ); if (!$countryAggregate) { $countryAggregate = $this->createCountryAggregate($visit, $level, $previousVisit); $countryAggregate = $this->visitorFlowCountryRepository->save($countryAggregate); @@ -93,7 +110,7 @@ public function aggregate(Visit $visit) if (!$browserAggregate) { $browserAggregate = $this->createBrowserAggregate($visit, $level, $previousVisit); $browserAggregate = $this->visitorFlowBrowserRepository->save($browserAggregate); - dd($browserAggregate); +// dd($browserAggregate); } else { if ($level > 1) { $previousAggregate = BrowserAggregate::getPreviousAggregate( @@ -109,7 +126,28 @@ public function aggregate(Visit $visit) $browserAggregate->views++; $browserAggregate->exitCount++; $browserAggregate = $this->visitorFlowBrowserRepository->update($browserAggregate); - dd($browserAggregate); +// dd($browserAggregate); + } + if (!$deviceAggregate) { + $deviceAggregate = $this->createDeviceAggregate($visit, $level, $previousVisit); + $deviceAggregate = $this->visitorFlowDeviceRepository->save($deviceAggregate); + dd($deviceAggregate); + } else { + if ($level > 1) { + $previousAggregate = DeviceAggregate::getPreviousAggregate( + $this->visitorFlowDeviceRepository, + $previousVisit, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null', + $level + ); + $previousAggregate->isLastPage = false; + $previousAggregate->exitCount--; + $this->visitorFlowDeviceRepository->update($previousAggregate); + } + $deviceAggregate->views++; + $deviceAggregate->exitCount++; + $deviceAggregate = $this->visitorFlowDeviceRepository->update($deviceAggregate); + dd($deviceAggregate); } } @@ -210,4 +248,38 @@ private function createBrowserAggregate(Visit $currentVisit, int $level, ?Visit $prevPage ); } + + private function createDeviceAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit): DeviceAggregate + { + $page = $this->pageRepository->getById($currentVisit->page_id); + $website = $this->websiteRepository->getById($page->website_id); + $prevPage = new PageValue(); + if ($level !== 1) { + $previousAggregate = DeviceAggregate::getPreviousAggregate( + $this->visitorFlowDeviceRepository, + $previousVisit, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null', + $level + ); + $previousAggregate->isLastPage = false; + $previousAggregate->exitCount--; + $this->visitorFlowDeviceRepository->update($previousAggregate); + $prevPage = new PageValue($previousVisit->id, $previousAggregate->url); + } + $exitCount = 1; + $isLatPage = true; + $views = 1; + return new DeviceAggregate( + $currentVisit->id, + $website->id, + $page->url, + $page->name, + $views, + $level, + $isLatPage, + $exitCount, + $currentVisit->session->system->device, + $prevPage + ); + } } From 679ef46bd0804350c8a4786ddf8e2a1abe1888ad Mon Sep 17 00:00:00 2001 From: Serhii Plotnikov Date: Thu, 5 Sep 2019 22:11:58 +0300 Subject: [PATCH 018/183] implement screenAggregate --- .../app/Aggregates/VisitorsFlow/Aggregate.php | 4 +- .../VisitorsFlow/BrowserAggregate.php | 8 +- .../VisitorsFlow/CountryAggregate.php | 8 +- .../VisitorsFlow/DeviceAggregate.php | 9 +- .../VisitorsFlow/ScreenAggregate.php | 34 +++++-- backend/app/Providers/AppServiceProvider.php | 4 + .../VisitorsFlow/BrowserCriteria.php | 8 +- .../VisitorsFlow/Contracts/Criteria.php | 2 +- .../Contracts/VisitorFlowScreenRepository.php | 16 ++++ .../VisitorsFlow/CountryCriteria.php | 8 +- .../VisitorsFlow/DeviceCriteria.php | 8 +- ...asticsearchVisitorFlowScreenRepository.php | 79 ++++++++++++++++ .../VisitorsFlow/ScreenCriteria.php | 45 +++++++++ .../VisitorsFlow/FlowAggregateService.php | 93 ++++++++++++++++--- 14 files changed, 281 insertions(+), 45 deletions(-) create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowScreenRepository.php create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowScreenRepository.php create mode 100644 backend/app/Repositories/Elasticsearch/VisitorsFlow/ScreenCriteria.php diff --git a/backend/app/Aggregates/VisitorsFlow/Aggregate.php b/backend/app/Aggregates/VisitorsFlow/Aggregate.php index 3072bffb..eeb9a290 100644 --- a/backend/app/Aggregates/VisitorsFlow/Aggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/Aggregate.php @@ -28,7 +28,7 @@ public function __construct( int $level, bool $isLastPage, int $exitCount, - ?PageValue $prevPage + PageValue $prevPage ) { $this->id = $id; @@ -50,7 +50,7 @@ public function toArray(): array 'websiteId' => $this->websiteId, 'url' => $this->url, 'title' => $this->title, - 'prevPage' => $this->prevPage === null ? null : [ + 'prevPage' => [ 'id' => $this->prevPage->id, 'url' => $this->prevPage->url ], diff --git a/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php b/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php index 984fe188..9b3a917f 100644 --- a/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/BrowserAggregate.php @@ -22,7 +22,7 @@ public function __construct( bool $isLastPage, int $exitCount, string $browser, - ?PageValue $prevPage + PageValue $prevPage ) { parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); @@ -46,7 +46,7 @@ public static function fromResult(array $result): Aggregate (bool)$result['isLastPage'], (int)$result['exitCount'], (string)$result['browser'], - $result['prevPage'] === null ? null : new PageValue( + new PageValue( (int)$result['prevPage']['id'], (string)$result['prevPage']['url'] ) @@ -65,8 +65,8 @@ public static function getPreviousAggregate( $visit->session->website_id, $visit->page->url, $level - 1, - $visit->session->system->browser, - $previousVisitUrl + $previousVisitUrl, + $visit->session->system->browser ) ); } diff --git a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php index 74c600f5..5e79fd5a 100644 --- a/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/CountryAggregate.php @@ -22,7 +22,7 @@ public function __construct( bool $isLastPage, int $exitCount, string $country, - ?PageValue $prevPage + PageValue $prevPage ) { parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); @@ -46,7 +46,7 @@ public static function fromResult(array $result): Aggregate (bool)$result['isLastPage'], (int)$result['exitCount'], (string)$result['country'], - $result['prevPage'] === null ? null : new PageValue( + new PageValue( (int)$result['prevPage']['id'], (string)$result['prevPage']['url'] ) @@ -65,8 +65,8 @@ public static function getPreviousAggregate( $visit->session->website_id, $visit->page->url, $level - 1, - $visit->geo_position->country, - $previousVisitUrl + $previousVisitUrl, + $visit->geo_position->country ) ); } diff --git a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php index 035367c8..14ef6c7f 100644 --- a/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/DeviceAggregate.php @@ -5,7 +5,6 @@ use App\Aggregates\VisitorsFlow\Values\PageValue; use App\Entities\Visit; -use App\Repositories\Elasticsearch\VisitorsFlow\BrowserCriteria; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowRepository; use App\Repositories\Elasticsearch\VisitorsFlow\DeviceCriteria; @@ -23,7 +22,7 @@ public function __construct( bool $isLastPage, int $exitCount, string $device, - ?PageValue $prevPage + PageValue $prevPage ) { parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); @@ -47,7 +46,7 @@ public static function fromResult(array $result): Aggregate (bool)$result['isLastPage'], (int)$result['exitCount'], (string)$result['device'], - $result['prevPage'] === null ? null : new PageValue( + new PageValue( (int)$result['prevPage']['id'], (string)$result['prevPage']['url'] ) @@ -66,8 +65,8 @@ public static function getPreviousAggregate( $visit->session->website_id, $visit->page->url, $level - 1, - $visit->session->system->device, - $previousVisitUrl + $previousVisitUrl, + $visit->session->system->device ) ); } diff --git a/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php b/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php index e4e3ee16..8f6fc47c 100644 --- a/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php +++ b/backend/app/Aggregates/VisitorsFlow/ScreenAggregate.php @@ -4,6 +4,9 @@ namespace App\Aggregates\VisitorsFlow; use App\Aggregates\VisitorsFlow\Values\PageValue; +use App\Entities\Visit; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\ScreenCriteria; class ScreenAggregate extends Aggregate { @@ -19,9 +22,9 @@ public function __construct( int $level, bool $isLastPage, int $exitCount, - int $resolutionWidth, - int $resolutionHeight, - ?PageValue $prevPage + string $resolutionWidth, + string $resolutionHeight, + PageValue $prevPage ) { parent::__construct($id, $websiteId, $url, $title, $views, $level, $isLastPage, $exitCount, $prevPage); @@ -48,12 +51,31 @@ public static function fromResult(array $result): Aggregate (int)$result['level'], (bool)$result['isLastPage'], (int)$result['exitCount'], - (int)$result['resolution_width'], - (int)$result['resolution_height'], - $result['prevPage'] === null ? null : new PageValue( + (string)$result['resolution_width'], + (string)$result['resolution_height'], + new PageValue( (int)$result['prevPage']['id'], (string)$result['prevPage']['url'] ) ); } + + public static function getPreviousAggregate( + VisitorFlowRepository $visitorFlowScreenRepository, + Visit $visit, + string $previousVisitUrl, + int $level + ): Aggregate + { + return $visitorFlowScreenRepository->getByCriteria( + ScreenCriteria::getCriteria( + $visit->session->website_id, + $visit->page->url, + $level - 1, + $previousVisitUrl, + $visit->session->system->resolution_width, + $visit->session->system->resolution_height + ) + ); + } } diff --git a/backend/app/Providers/AppServiceProvider.php b/backend/app/Providers/AppServiceProvider.php index 150f081e..2bccda60 100644 --- a/backend/app/Providers/AppServiceProvider.php +++ b/backend/app/Providers/AppServiceProvider.php @@ -26,9 +26,11 @@ use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowDeviceRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowScreenRepository; use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowCountryRepository; use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowDeviceRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\ElasticsearchVisitorFlowScreenRepository; use App\Repositories\EloquentChartPageTimingRepository; use App\Repositories\EloquentChartVisitorRepository; use App\Repositories\EloquentButtonVisitorsRepository; @@ -114,6 +116,8 @@ public function register() $this->app->bind(VisitorFlowBrowserRepository::class, ElasticsearchVisitorFlowBrowserRepository::class); $this->app->bind(VisitorFlowDeviceRepository::class, ElasticsearchVisitorFlowDeviceRepository::class); + + $this->app->bind(VisitorFlowScreenRepository::class, ElasticsearchVisitorFlowScreenRepository::class); } /** diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php index 128458ae..f4145976 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/BrowserCriteria.php @@ -13,7 +13,7 @@ class BrowserCriteria implements Criteria public $browser; public $prevPageUrl; - private function __construct(int $websiteId, string $url, int $level, string $browser, ?string $prevPageUrl) + private function __construct(int $websiteId, string $url, int $level, ?string $prevPageUrl, string $browser) { $this->websiteId = $websiteId; $this->url = $url; @@ -22,14 +22,14 @@ private function __construct(int $websiteId, string $url, int $level, string $br $this->prevPageUrl = $prevPageUrl; } - public static function getCriteria(int $websiteId, string $url, int $level, string $type, ?string $prevPageUrl) + public static function getCriteria(int $websiteId, string $url, int $level, ?string $prevPageUrl, ...$params) { return new static( $websiteId, $url, $level, - $type, - $prevPageUrl + $prevPageUrl, + $params[0] ); } } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php index d8b10374..57c893f7 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/Criteria.php @@ -5,5 +5,5 @@ interface Criteria { - public static function getCriteria(int $websiteId, string $url, int $level, string $type, ?string $prevPageUrl); + public static function getCriteria(int $websiteId, string $url, int $level, ?string $prevPageUrl, ...$params); } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowScreenRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowScreenRepository.php new file mode 100644 index 00000000..f0ea29da --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/Contracts/VisitorFlowScreenRepository.php @@ -0,0 +1,16 @@ +websiteId = $websiteId; $this->url = $url; @@ -22,14 +22,14 @@ private function __construct(int $websiteId, string $url, int $level, string $co $this->prevPageUrl = $prevPageUrl; } - public static function getCriteria(int $websiteId, string $url, int $level, string $type, ?string $prevPageUrl) + public static function getCriteria(int $websiteId, string $url, int $level, ?string $prevPageUrl, ...$params) { return new static( $websiteId, $url, $level, - $type, - $prevPageUrl + $prevPageUrl, + $params[0] ); } } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/DeviceCriteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/DeviceCriteria.php index 5e04f9e7..667c93aa 100644 --- a/backend/app/Repositories/Elasticsearch/VisitorsFlow/DeviceCriteria.php +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/DeviceCriteria.php @@ -13,7 +13,7 @@ class DeviceCriteria implements Criteria public $device; public $prevPageUrl; - private function __construct(int $websiteId, string $url, int $level, string $device, ?string $prevPageUrl) + private function __construct(int $websiteId, string $url, int $level, ?string $prevPageUrl, string $device) { $this->websiteId = $websiteId; $this->url = $url; @@ -22,14 +22,14 @@ private function __construct(int $websiteId, string $url, int $level, string $de $this->prevPageUrl = $prevPageUrl; } - public static function getCriteria(int $websiteId, string $url, int $level, string $type, ?string $prevPageUrl) + public static function getCriteria(int $websiteId, string $url, int $level, ?string $prevPageUrl, ...$params) { return new static( $websiteId, $url, $level, - $type, - $prevPageUrl + $prevPageUrl, + $params[0] ); } } diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowScreenRepository.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowScreenRepository.php new file mode 100644 index 00000000..7d455520 --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ElasticsearchVisitorFlowScreenRepository.php @@ -0,0 +1,79 @@ +client = $client; + } + + public function save(Aggregate $screenAggregate): Aggregate + { + $this->client->index([ + 'index' => self::INDEX_NAME, + 'id' => $screenAggregate->getId(), + 'type' => '_doc', + 'body' => $screenAggregate->toArray() + ]); + + return $screenAggregate; + } + + public function update(Aggregate $screenAggregate): Aggregate + { + $this->client->index([ + 'index' => self::INDEX_NAME, + 'id' => $screenAggregate->getId(), + 'type' => '_doc', + 'body' => $screenAggregate->toArray() + ]); + + return $screenAggregate; + } + + + public function getByCriteria(Criteria $criteria): ?ScreenAggregate + { + $params = [ + 'index' => self::INDEX_NAME, + 'body' => [ + 'query' => [ + 'bool' => [ + 'must' => [ + ['match' => ['websiteId' => $criteria->websiteId]], + ], + 'filter' => [ + ['term' => ['level' => $criteria->level]], + ['match_phrase' => ['resolution_width' => $criteria->resolutionWidth]], + ['match_phrase' => ['resolution_height' => $criteria->resolutionHeight]], + ['match_phrase' => ['url' => $criteria->url]], + ['match_phrase'=>['prevPage.url'=>$criteria->prevPageUrl]] + ], + ] + ] + ] + ]; + try { + $result = $this->client->search($params); + } catch (\Exception $exception) { + return null; + } + if (empty($result['hits']['hits'])) { + return null; + } + return ScreenAggregate::fromResult($result['hits']['hits'][0]['_source']); + } +} diff --git a/backend/app/Repositories/Elasticsearch/VisitorsFlow/ScreenCriteria.php b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ScreenCriteria.php new file mode 100644 index 00000000..2aba6e30 --- /dev/null +++ b/backend/app/Repositories/Elasticsearch/VisitorsFlow/ScreenCriteria.php @@ -0,0 +1,45 @@ +websiteId = $websiteId; + $this->url = $url; + $this->level = $level; + $this->resolutionWidth = $resolutionWidth; + $this->resolutionHeight = $resolutionHeight; + $this->prevPageUrl = $prevPageUrl; + } + + public static function getCriteria(int $websiteId, string $url, int $level, ?string $prevPageUrl, ...$params) + { + return new static( + $websiteId, + $url, + $level, + $prevPageUrl, + $params[0], + $params[1] + ); + } +} diff --git a/backend/app/Services/VisitorsFlow/FlowAggregateService.php b/backend/app/Services/VisitorsFlow/FlowAggregateService.php index 977b5e9f..040fa08f 100644 --- a/backend/app/Services/VisitorsFlow/FlowAggregateService.php +++ b/backend/app/Services/VisitorsFlow/FlowAggregateService.php @@ -6,6 +6,7 @@ use App\Aggregates\VisitorsFlow\BrowserAggregate; use App\Aggregates\VisitorsFlow\CountryAggregate; use App\Aggregates\VisitorsFlow\DeviceAggregate; +use App\Aggregates\VisitorsFlow\ScreenAggregate; use App\Aggregates\VisitorsFlow\Values\PageValue; use App\Entities\Visit; use App\Repositories\Contracts\GeoPositionRepository; @@ -16,8 +17,10 @@ use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowBrowserRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowCountryRepository; use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowDeviceRepository; +use App\Repositories\Elasticsearch\VisitorsFlow\Contracts\VisitorFlowScreenRepository; use App\Repositories\Elasticsearch\VisitorsFlow\CountryCriteria; use App\Repositories\Elasticsearch\VisitorsFlow\DeviceCriteria; +use App\Repositories\Elasticsearch\VisitorsFlow\ScreenCriteria; use Carbon\Carbon; final class FlowAggregateService @@ -29,7 +32,7 @@ final class FlowAggregateService private $geoPositionRepository; private $visitorFlowBrowserRepository; private $visitorFlowDeviceRepository; - + private $visitorFlowScreenRepository; public function __construct( PageRepository $pageRepository, @@ -38,7 +41,8 @@ public function __construct( WebsiteRepository $websiteRepository, GeoPositionRepository $geoPositionRepository, VisitorFlowBrowserRepository $visitorFlowBrowserRepository, - VisitorFlowDeviceRepository $visitorFlowDeviceRepository + VisitorFlowDeviceRepository $visitorFlowDeviceRepository, + VisitorFlowScreenRepository $visitorFlowScreenRepository ) { $this->pageRepository = $pageRepository; @@ -48,6 +52,7 @@ public function __construct( $this->geoPositionRepository = $geoPositionRepository; $this->visitorFlowBrowserRepository = $visitorFlowBrowserRepository; $this->visitorFlowDeviceRepository = $visitorFlowDeviceRepository; + $this->visitorFlowScreenRepository = $visitorFlowScreenRepository; } public function aggregate(Visit $visit) @@ -64,8 +69,8 @@ public function aggregate(Visit $visit) $visit->session->website_id, $visit->page->url, $level, - $visit->geo_position->country, - $isFirstInSession ? 'null' : $previousVisit->page->url + $isFirstInSession ? 'null' : $previousVisit->page->url, + $visit->geo_position->country ) ); $browserAggregate = $this->visitorFlowBrowserRepository->getByCriteria( @@ -73,18 +78,27 @@ public function aggregate(Visit $visit) $visit->session->website_id, $visit->page->url, $level, - $visit->session->system->browser, - $isFirstInSession ? 'null' : $previousVisit->page->url + $isFirstInSession ? 'null' : $previousVisit->page->url, + $visit->session->system->browser ) ); - $deviceAggregate = $this->visitorFlowDeviceRepository->getByCriteria( DeviceCriteria::getCriteria( $visit->session->website_id, $visit->page->url, $level, - $visit->session->system->device, - $isFirstInSession ? 'null' : $previousVisit->page->url + $isFirstInSession ? 'null' : $previousVisit->page->url, + $visit->session->system->device + ) + ); + $screenAggregate = $this->visitorFlowScreenRepository->getByCriteria( + ScreenCriteria::getCriteria( + $visit->session->website_id, + $visit->page->url, + $level, + $isFirstInSession ? 'null' : $previousVisit->page->url, + $visit->session->system->resolution_width, + $visit->session->system->resolution_height ) ); if (!$countryAggregate) { @@ -131,7 +145,7 @@ public function aggregate(Visit $visit) if (!$deviceAggregate) { $deviceAggregate = $this->createDeviceAggregate($visit, $level, $previousVisit); $deviceAggregate = $this->visitorFlowDeviceRepository->save($deviceAggregate); - dd($deviceAggregate); +// dd($deviceAggregate); } else { if ($level > 1) { $previousAggregate = DeviceAggregate::getPreviousAggregate( @@ -147,7 +161,29 @@ public function aggregate(Visit $visit) $deviceAggregate->views++; $deviceAggregate->exitCount++; $deviceAggregate = $this->visitorFlowDeviceRepository->update($deviceAggregate); - dd($deviceAggregate); +// dd($deviceAggregate); + } + + if (!$screenAggregate) { + $screenAggregate = $this->createScreenAggregate($visit, $level, $previousVisit); + $screenAggregate = $this->visitorFlowScreenRepository->save($screenAggregate); + dd($screenAggregate); + } else { + if ($level > 1) { + $previousAggregate = ScreenAggregate::getPreviousAggregate( + $this->visitorFlowScreenRepository, + $previousVisit, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null', + $level + ); + $previousAggregate->isLastPage = false; + $previousAggregate->exitCount--; + $this->visitorFlowScreenRepository->update($previousAggregate); + } + $screenAggregate->views++; + $screenAggregate->exitCount++; + $screenAggregate = $this->visitorFlowScreenRepository->update($screenAggregate); + dd($screenAggregate); } } @@ -282,4 +318,39 @@ private function createDeviceAggregate(Visit $currentVisit, int $level, ?Visit $ $prevPage ); } + + private function createScreenAggregate(Visit $currentVisit, int $level, ?Visit $previousVisit): ScreenAggregate + { + $page = $this->pageRepository->getById($currentVisit->page_id); + $website = $this->websiteRepository->getById($page->website_id); + $prevPage = new PageValue(); + if ($level !== 1) { + $previousAggregate = ScreenAggregate::getPreviousAggregate( + $this->visitorFlowScreenRepository, + $previousVisit, + $level > 2 ? ($this->getPreviousVisit($previousVisit))->page->url : 'null', + $level + ); + $previousAggregate->isLastPage = false; + $previousAggregate->exitCount--; + $this->visitorFlowScreenRepository->update($previousAggregate); + $prevPage = new PageValue($previousVisit->id, $previousAggregate->url); + } + $exitCount = 1; + $isLatPage = true; + $views = 1; + return new ScreenAggregate( + $currentVisit->id, + $website->id, + $page->url, + $page->name, + $views, + $level, + $isLatPage, + $exitCount, + $currentVisit->session->system->resolution_width, + $currentVisit->session->system->resolution_height, + $prevPage + ); + } } From 5c8484448199e54966112cb2251946d1977eabe7 Mon Sep 17 00:00:00 2001 From: Yana Yakovenko Date: Thu, 5 Sep 2019 22:24:07 +0300 Subject: [PATCH 019/183] move widgets to new row --- .../dashboard/home/ActiveVisitorsCard.vue | 6 ++++-- .../dashboard/home/VisitsDensityWidget.vue | 7 +++++-- .../src/components/widgets/DevicesPieChart.vue | 5 +++-- frontend/src/pages/Dashboard.vue | 15 ++++++--------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/frontend/src/components/dashboard/home/ActiveVisitorsCard.vue b/frontend/src/components/dashboard/home/ActiveVisitorsCard.vue index def469fe..e64163f3 100644 --- a/frontend/src/components/dashboard/home/ActiveVisitorsCard.vue +++ b/frontend/src/components/dashboard/home/ActiveVisitorsCard.vue @@ -1,5 +1,5 @@