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