Top_Posts.php
74 lines
| 1 | <?php |
| 2 | |
| 3 | namespace IAWP\Public_API; |
| 4 | |
| 5 | use IAWPSCOPED\Carbon\CarbonImmutable; |
| 6 | use IAWP\Date_Range\Exact_Date_Range; |
| 7 | use IAWP\Illuminate_Builder; |
| 8 | use IAWP\Query; |
| 9 | use IAWPSCOPED\Illuminate\Database\Query\JoinClause; |
| 10 | /** @internal */ |
| 11 | class Top_Posts |
| 12 | { |
| 13 | public $options = []; |
| 14 | public function __construct(array $options = []) |
| 15 | { |
| 16 | $this->options = $this->validate_options($options); |
| 17 | } |
| 18 | public function get() : array |
| 19 | { |
| 20 | $date_range = new Exact_Date_Range($this->options['from']->toDateTime(), $this->options['to']->toDateTime()); |
| 21 | $resources_table = Query::get_table_name(Query::RESOURCES); |
| 22 | $views_table = Query::get_table_name(Query::VIEWS); |
| 23 | $sessions_table = Query::get_table_name(Query::SESSIONS); |
| 24 | $resource_statistics_query = Illuminate_Builder::new(); |
| 25 | $resource_statistics_query->selectRaw('resources.singular_id AS id')->selectRaw('resources.cached_title AS title')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->from("{$views_table} as views")->join("{$resources_table} AS resources", function (JoinClause $join) { |
| 26 | $join->on('resources.id', '=', 'views.resource_id'); |
| 27 | })->join("{$sessions_table} AS sessions", function (JoinClause $join) { |
| 28 | $join->on('sessions.session_id', '=', 'views.session_id'); |
| 29 | })->whereNotNull('resources.singular_id')->where('resources.cached_type', '=', $this->options['post_type'])->whereBetween('views.viewed_at', [$date_range->iso_start(), $date_range->iso_end()])->limit($this->options['limit'])->orderByDesc($this->options['sort_by'])->groupBy('resources.id'); |
| 30 | $results = $resource_statistics_query->get()->toArray(); |
| 31 | return $results; |
| 32 | } |
| 33 | private function validate_options(array $options) : array |
| 34 | { |
| 35 | // Post type |
| 36 | if (\array_key_exists('post_type', $options) && \post_type_exists($options['post_type'])) { |
| 37 | $post_type = $options['post_type']; |
| 38 | } else { |
| 39 | $post_type = 'post'; |
| 40 | } |
| 41 | // Limit |
| 42 | if (\array_key_exists('limit', $options) && \is_int($options['limit'])) { |
| 43 | $limit = $options['limit']; |
| 44 | } else { |
| 45 | $limit = 10; |
| 46 | } |
| 47 | // From |
| 48 | if (\array_key_exists('from', $options) && $options['from'] instanceof \DateTime) { |
| 49 | $from = CarbonImmutable::instance($options['from']); |
| 50 | } else { |
| 51 | $from = CarbonImmutable::now()->subtract('days', 30); |
| 52 | } |
| 53 | // To |
| 54 | if (\array_key_exists('to', $options) && $options['to'] instanceof \DateTime) { |
| 55 | $to = CarbonImmutable::instance($options['to']); |
| 56 | } else { |
| 57 | $to = CarbonImmutable::now(); |
| 58 | } |
| 59 | // Is date range valid? |
| 60 | if ($from->greaterThanOrEqualTo($to)) { |
| 61 | $from = CarbonImmutable::now()->subtract('days', 30); |
| 62 | $to = CarbonImmutable::now(); |
| 63 | } |
| 64 | // Sort by |
| 65 | $valid_sorting_options = ['views', 'visitors', 'sessions']; |
| 66 | if (\array_key_exists('sort_by', $options) && \in_array($options['sort_by'], $valid_sorting_options)) { |
| 67 | $sort_by = $options['sort_by']; |
| 68 | } else { |
| 69 | $sort_by = 'views'; |
| 70 | } |
| 71 | return ['post_type' => $post_type, 'limit' => $limit, 'from' => $from, 'to' => $to, 'sort_by' => $sort_by]; |
| 72 | } |
| 73 | } |
| 74 |