From: Vincent Vanwaelscappel Date: Wed, 17 Aug 2022 11:59:23 +0000 (+0200) Subject: wait #5398 @0.5 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=fc7bb0ab2b10db2b50b7827e8ce0d2e8bc93c623;p=fluidbook-toolbox.git wait #5398 @0.5 --- diff --git a/app/Http/Controllers/Admin/FluidbookStatsController.php b/app/Http/Controllers/Admin/FluidbookStatsController.php index 8dad6405b..52a4f9fab 100644 --- a/app/Http/Controllers/Admin/FluidbookStatsController.php +++ b/app/Http/Controllers/Admin/FluidbookStatsController.php @@ -11,164 +11,5 @@ use Cubist\Matomo\Reporting; class FluidbookStatsController extends Controller { - - public static function getMatomoTokens() { - // Each stats server has a different instance of Matamo, so we need to provide different API tokens for each - // Normally this information would be stored in the .env but there's no good way to do that with an array, so - // it is simpler to keep it here. These are also stored in the shared Bitwarden entry for Matomo. - return [ - 'stats3.fluidbook.com' => '9df722a0bd30878ddc4d737352427502', - 'stats4.fluidbook.com' => '3ffdbe052ae625f065573df9fa9515df', - 'stats5.fluidbook.com' => '85e9cc307b6e5083249949e9472a80b8', - ]; - } - - private function _getReporting($fluidbook_id) - { - // Get the appropriate server / API token based on the Fluidbook ID - // Stats are split across different servers depending on the ID: - // ID < 21210 = stats3.fluidbook.com - // ID >= 21210 (even numbers) = stats4.fluidbook.com - // ID >= 21211 (odd numbers) = stats5.fluidbook.com - - $fluidbook_id = intval($fluidbook_id); - - if ($fluidbook_id < 21210) { - $server = 'stats3.fluidbook.com'; - } elseif ($fluidbook_id >= 21210 && $fluidbook_id % 2 === 0) { - $server = 'stats4.fluidbook.com'; - } else { - $server = 'stats5.fluidbook.com'; - } - - //dump("Server is $server"); - - $matomo_tokens = self::getMatomoTokens(); - - return new Reporting("https://{$server}/", $matomo_tokens[$server]); - } - - - private function _parseDate($date) { - // Match possible date strings: - // - YYYY - // - YYYY-MM - // - YYYY-MM-DD - // - YYYY-MM-DD,YYYY-MM-DD - // https://regex101.com/r/BLrqm0/1 - $regex = '/^(?(?2\d{3})-?(?0[1-9]|1[012])?-?(?0[1-9]|[12][0-9]|3[01])?),?(?2\d{3}-(?>0[1-9]|1[012])-(?>0[1-9]|[12][0-9]|3[01]))?/'; - - preg_match($regex, $date, $date_matches); - - return $date_matches; - } - - protected function summary($fluidbook_id, $date = null) - { - $dates = $date ? $this->_parseDate($date) : false; - - $fluidbook = FluidbookPublication::findOrFail($fluidbook_id); - - - // TODO: year(s)? view like the old version: https://workshop.fluidbook.com/stats/10003_ab3cacc39ebbf2478e0931629d114e74 - // Need to calculate all the available dates, probably based on creation date of the Fluidbook - - // TODO: month view, breakdown of individual day stats: https://workshop.fluidbook.com/stats/10003_ab3cacc39ebbf2478e0931629d114e74/2017/10 - // These would be linked from the "Year(s)" view above... - - // Matomo API - // We need to pass it a date (eg. "2022-01-01") or date range (eg. "2022-03-01,2022-05-15") - // We can then specify the granularity of stats by specifying the period: - // - range = aggregated summary of stats for the specified date range - // - year = summary of stats broken down by year(s) - // - month = summary of stats broken down by month(s) - // - day = summary of stats broken down by day(s) - - // Which mode are we in? - if (isset($dates['start_date']) && isset($dates['end_date'])) { // Custom date range - $mode = 'range'; - $date_range = "{$dates['start_date']},{$dates['end_date']}"; - $period = 'day'; // Segregate stats by day - - } elseif (isset($dates['start_year']) && isset($dates['start_month'])) { // Month view - $mode = 'month'; - $month = $dates['start_month']; - $year = $dates['start_year']; - $last_day_of_month = cal_days_in_month(CAL_GREGORIAN, $month, $year); - $date_range = "{$year}-{$month}-01,{$year}-{$month}-{$last_day_of_month}"; - $period = 'day'; // Segregate stats by day - - } elseif (isset($dates['start_year'])) { - $mode = 'year'; - $year = $dates['start_year']; - $end_date = $year == date('Y') ? date('Y-m-d') : "{$year}-12-31"; // If it's the current year, don't get future dates - $date_range = "{$year}-01-01,{$end_date}"; // Full range of specified year - $period = 'month'; // Segregate stats by month - - } else { // No valid dates specified, display the full data set - $mode = 'overview'; - $start_date = $fluidbook->created_at->isoFormat('YYYY-MM-DD'); - $date_range = $start_date . ',' . date('Y-m-d'); - $period = 'month'; // Segregate stats by month - } - - // TODO: support the ability to specify a date range from a date-picker and also maybe choose the breakdown (by year/month/day/range) - - $report = $this->_getReporting($fluidbook_id); - - echo "Getting stats for date range $date_range, segregated by $period"; - //dump(collect($report->getVisits($fluidbook_id, $date_range, $period))->sum('nb_visits')); - //dump($report->getVisits($fluidbook_id, $date_range, 'range')); - // dd($report->getVisits($fluidbook_id, $date_range, $period)); - $visits = collect($report->getVisits($fluidbook_id, $date_range, $period)); - $pageviews = collect($report->getPageViews($fluidbook_id, $date_range, $period)); - - // Get the search keywords as a range because we don't need to display them by date - $searches = collect($report->getSearchKeywords($fluidbook_id, $date_range, 'range')); - - // Format dates for display as labels on the x-axis - $labels = $visits->keys()->map(function($label, $index) use ($period) { - return match ($period) { - 'day' => Carbon::parse($label)->isoFormat('DD'), // Convert YYYY-MM-DD string from API into zero-padded day alone - 'month' => Carbon::parse($label)->isoFormat('MMM'), // Convert to abbreviated month name - default => $label, - }; - })->toArray(); - - // Format dates for display in the tooltip title - $formatted_dates = $visits->keys()->map(function($label, $index) use ($period) { - return match ($period) { - 'day' => Carbon::parse($label)->isoFormat('dddd Do MMMM YYYY'), - 'month' => Carbon::parse($label)->isoFormat('MMMM YYYY'), - default => $label, - }; - })->toArray(); - - $chart = Chartisan::build() - ->labels($labels) - ->extra(['tooltip_labels' => array_combine($labels, $formatted_dates)]) - ->dataset('Visits', $visits->pluck('nb_visits')->toArray()) - ->dataset('Page Views', $pageviews->pluck('nb_pageviews')->toArray()) - ->toJSON(); - - // header('Content-Type: application/json; charset=utf-8'); - // return $chart; - - return view('fluidbook_stats.summary', compact('fluidbook', 'visits', 'pageviews', 'searches', 'chart', 'mode', 'period', 'dates')); - - - } - - protected function API() { - - if (!can('superadmin')) { - // Only allow superadmin access because this is a dev tool and it exposes the API tokens - return response(null)->setStatusCode('403'); - } - - $matomo_tokens = json_encode(static::getMatomoTokens()); - - return view('fluidbook_stats.API', compact('matomo_tokens')); - } - + // @see App\Http\Controllers\Admin\Operations\FluidbookPublication\StatsOperation } diff --git a/app/Http/Controllers/Admin/Operations/FluidbookPublication/StatsOperation.php b/app/Http/Controllers/Admin/Operations/FluidbookPublication/StatsOperation.php new file mode 100644 index 000000000..5689a5224 --- /dev/null +++ b/app/Http/Controllers/Admin/Operations/FluidbookPublication/StatsOperation.php @@ -0,0 +1,190 @@ +withoutMiddleware([CheckIfAdmin::class]); + } + + protected function setupStatsDefaults() + { + $this->crud->addButtonFromView('line', 'stats', 'fluidbook_publication.stats', 'end'); + } + + + public static function getMatomoTokens() + { + // Each stats server has a different instance of Matamo, so we need to provide different API tokens for each + // Normally this information would be stored in the .env but there's no good way to do that with an array, so + // it is simpler to keep it here. These are also stored in the shared Bitwarden entry for Matomo. + return [ + 'stats3.fluidbook.com' => '9df722a0bd30878ddc4d737352427502', + 'stats4.fluidbook.com' => '3ffdbe052ae625f065573df9fa9515df', + 'stats5.fluidbook.com' => '85e9cc307b6e5083249949e9472a80b8', + ]; + } + + private function _getReporting($fluidbook_id) + { + // Get the appropriate server / API token based on the Fluidbook ID + // Stats are split across different servers depending on the ID: + // ID < 21210 = stats3.fluidbook.com + // ID >= 21210 (even numbers) = stats4.fluidbook.com + // ID >= 21211 (odd numbers) = stats5.fluidbook.com + + $fluidbook_id = intval($fluidbook_id); + + if ($fluidbook_id < 21210) { + $server = 'stats3.fluidbook.com'; + } elseif ($fluidbook_id >= 21210 && $fluidbook_id % 2 === 0) { + $server = 'stats4.fluidbook.com'; + } else { + $server = 'stats5.fluidbook.com'; + } + + //dump("Server is $server"); + + $matomo_tokens = self::getMatomoTokens(); + + return new Reporting("https://{$server}/", $matomo_tokens[$server]); + } + + + private function _parseDate($date) + { + // Match possible date strings: + // - YYYY + // - YYYY-MM + // - YYYY-MM-DD + // - YYYY-MM-DD,YYYY-MM-DD + // https://regex101.com/r/BLrqm0/1 + $regex = '/^(?(?2\d{3})-?(?0[1-9]|1[012])?-?(?0[1-9]|[12][0-9]|3[01])?),?(?2\d{3}-(?>0[1-9]|1[012])-(?>0[1-9]|[12][0-9]|3[01]))?/'; + + preg_match($regex, $date, $date_matches); + + return $date_matches; + } + + protected function statsSummary($fluidbook_id, $hash, $date = null) + { + $dates = $date ? $this->_parseDate($date) : false; + + $fluidbook = FluidbookPublication::where('id', $fluidbook_id)->where('hash', $hash)->first(); + if (null === $fluidbook) { + abort(404); + } + + // TODO: year(s)? view like the old version: https://workshop.fluidbook.com/stats/10003_ab3cacc39ebbf2478e0931629d114e74 + // Need to calculate all the available dates, probably based on creation date of the Fluidbook + + // TODO: month view, breakdown of individual day stats: https://workshop.fluidbook.com/stats/10003_ab3cacc39ebbf2478e0931629d114e74/2017/10 + // These would be linked from the "Year(s)" view above... + + // Matomo API + // We need to pass it a date (eg. "2022-01-01") or date range (eg. "2022-03-01,2022-05-15") + // We can then specify the granularity of stats by specifying the period: + // - range = aggregated summary of stats for the specified date range + // - year = summary of stats broken down by year(s) + // - month = summary of stats broken down by month(s) + // - day = summary of stats broken down by day(s) + + // Which mode are we in? + if (isset($dates['start_date']) && isset($dates['end_date'])) { // Custom date range + $mode = 'range'; + $date_range = "{$dates['start_date']},{$dates['end_date']}"; + $period = 'day'; // Segregate stats by day + + } elseif (isset($dates['start_year']) && isset($dates['start_month'])) { // Month view + $mode = 'month'; + $month = $dates['start_month']; + $year = $dates['start_year']; + $last_day_of_month = cal_days_in_month(CAL_GREGORIAN, $month, $year); + $date_range = "{$year}-{$month}-01,{$year}-{$month}-{$last_day_of_month}"; + $period = 'day'; // Segregate stats by day + + } elseif (isset($dates['start_year'])) { + $mode = 'year'; + $year = $dates['start_year']; + $end_date = $year == date('Y') ? date('Y-m-d') : "{$year}-12-31"; // If it's the current year, don't get future dates + $date_range = "{$year}-01-01,{$end_date}"; // Full range of specified year + $period = 'month'; // Segregate stats by month + + } else { // No valid dates specified, display the full data set + $mode = 'overview'; + $start_date = $fluidbook->created_at->isoFormat('YYYY-MM-DD'); + $date_range = $start_date . ',' . date('Y-m-d'); + $period = 'month'; // Segregate stats by month + } + + // TODO: support the ability to specify a date range from a date-picker and also maybe choose the breakdown (by year/month/day/range) + + $report = $this->_getReporting($fluidbook_id); + + echo "Getting stats for date range $date_range, segregated by $period"; + //dump(collect($report->getVisits($fluidbook_id, $date_range, $period))->sum('nb_visits')); + //dump($report->getVisits($fluidbook_id, $date_range, 'range')); + // dd($report->getVisits($fluidbook_id, $date_range, $period)); + $visits = collect($report->getVisits($fluidbook_id, $date_range, $period)); + $pageviews = collect($report->getPageViews($fluidbook_id, $date_range, $period)); + + // Get the search keywords as a range because we don't need to display them by date + $searches = collect($report->getSearchKeywords($fluidbook_id, $date_range, 'range')); + + // Format dates for display as labels on the x-axis + $labels = $visits->keys()->map(function ($label, $index) use ($period) { + return match ($period) { + 'day' => Carbon::parse($label)->isoFormat('DD'), // Convert YYYY-MM-DD string from API into zero-padded day alone + 'month' => Carbon::parse($label)->isoFormat('MMM'), // Convert to abbreviated month name + default => $label, + }; + })->toArray(); + + // Format dates for display in the tooltip title + $formatted_dates = $visits->keys()->map(function ($label, $index) use ($period) { + return match ($period) { + 'day' => Carbon::parse($label)->isoFormat('dddd Do MMMM YYYY'), + 'month' => Carbon::parse($label)->isoFormat('MMMM YYYY'), + default => $label, + }; + })->toArray(); + +// $chart = Chartisan::build() +// ->labels($labels) +// ->extra(['tooltip_labels' => array_combine($labels, $formatted_dates)]) +// ->dataset('Visits', $visits->pluck('nb_visits')->toArray()) +// ->dataset('Page Views', $pageviews->pluck('nb_pageviews')->toArray()) +// ->toJSON(); + + // header('Content-Type: application/json; charset=utf-8'); + // return $chart; + + return view('fluidbook_stats.summary', compact('fluidbook', 'visits', 'pageviews', 'searches', /*'chart',*/ 'mode', 'period', 'dates')); + + + } + + protected function statsAPI() + { + + if (!can('superadmin')) { + // Only allow superadmin access because this is a dev tool and it exposes the API tokens + return response(null)->setStatusCode('403'); + } + + $matomo_tokens = json_encode(static::getMatomoTokens()); + + return view('fluidbook_stats.API', compact('matomo_tokens')); + } + +} diff --git a/resources/views/fluidbook_stats/summary.blade.php b/resources/views/fluidbook_stats/summary.blade.php index 307b8d2ef..971778e48 100644 --- a/resources/views/fluidbook_stats/summary.blade.php +++ b/resources/views/fluidbook_stats/summary.blade.php @@ -3,89 +3,89 @@ @section('content')

{{ __('Statistiques') }}

-
-
-
+{{--
--}} +{{--
--}} +{{--
--}} @dump($fluidbook, $visits, $pageviews, $searches) @endsection -@push('after_scripts') - {{-- Charting library --}} - - {{-- Chartisan --}} - +{{--@push('after_scripts')--}} +{{-- --}}{{-- Charting library --}} +{{-- --}} +{{-- --}}{{-- Chartisan --}} +{{-- --}} - +{{-- // The function must always return the new chart configuration.--}} +{{-- })--}} +{{-- })--}} +{{-- --}} -@endpush +{{--@endpush--}} diff --git a/resources/views/vendor/backpack/crud/buttons/fluidbook_publication/stats.blade.php b/resources/views/vendor/backpack/crud/buttons/fluidbook_publication/stats.blade.php new file mode 100644 index 000000000..cc51b3af9 --- /dev/null +++ b/resources/views/vendor/backpack/crud/buttons/fluidbook_publication/stats.blade.php @@ -0,0 +1,6 @@ +@if($entry->stats) + {{__('Stats')}} + +@endif diff --git a/routes/web.php b/routes/web.php index bcb795198..018383ffe 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,6 +13,4 @@ Route::group([ Route::get('fluidbookthemepreview/{id}-burger.jpg', 'FluidbookThemePreviewController@previewBurger'); Route::get('fluidbookthemepreview/{id}-menu.jpg', 'FluidbookThemePreviewController@previewMenu'); Route::get('fluidbookthemepreview/{id}.jpg', 'FluidbookThemePreviewController@preview'); - Route::get('fluidbook-stats/API', 'FluidbookStatsController@API'); - Route::get('fluidbook-stats/{fluidbook_id}/{date?}', 'FluidbookStatsController@summary'); });