authorizeForUser($this->getUser(), 'statistics.public-access'); $stats = DB::table('photos') ->whereIn('photos.album_id', DbHelper::getAlbumIDsForCurrentUser()) ->join('albums', 'albums.id', '=', 'photos.album_id') ->groupBy('albums.name') ->select('albums.name', DB::raw('count(photos.id) as photo_count')) ->orderBy('photo_count', 'desc') ->limit(10) ->get(); $labels = []; $data = []; foreach ($stats as $stat) { $labels[] = $stat->name; $data[] = $stat->photo_count; } return response()->json([ 'labels' => $labels, 'backgrounds' => $this->rotateColoursForData($data), 'data' => $data ]); } public function albumSizeByPhotoSizeChart(Request $request) { $this->authorizeForUser($this->getUser(), 'statistics.public-access'); $stats = DB::table('photos') ->whereIn('photos.album_id', DbHelper::getAlbumIDsForCurrentUser()) ->join('albums', 'albums.id', '=', 'photos.album_id') ->groupBy('albums.name') ->select('albums.name', DB::raw('sum(photos.file_size) as photo_size')) ->orderBy('photo_size', 'desc') ->limit(10) ->get(); $labels = []; $data = []; foreach ($stats as $stat) { $labels[] = $stat->name; $data[] = ceil($stat->photo_size / 1024 / 1024); } return response()->json([ 'labels' => $labels, 'backgrounds' => $this->rotateColoursForData($data), 'data' => $data ]); } public function camerasChart(Request $request) { $this->authorizeForUser($this->getUser(), 'statistics.public-access'); $stats = DB::table('photos') ->where([ ['camera_make', '!=', ''], ['camera_model', '!=', ''] ]) ->whereIn('album_id', DbHelper::getAlbumIDsForCurrentUser()) ->groupBy('camera_make', 'camera_model') ->select('camera_make', 'camera_model', DB::raw('count(*) as photo_count')) ->orderBy('photo_count', 'desc') ->get(); $labels = []; $data = []; foreach ($stats as $stat) { // Remove the model from the make if it starts with it // E.g. CANON - CANON EOS 1200D becomes just CANON EOS 1200D if (substr($stat->camera_model, 0, strlen($stat->camera_make)) == $stat->camera_make) { $stat->camera_make = trim(substr($stat->camera_make, strlen($stat->camera_make))); } $labels[] = sprintf('%s %s', $stat->camera_make, $stat->camera_model); $data[] = $stat->photo_count; } return response()->json([ 'labels' => $labels, 'backgrounds' => $this->rotateColoursForData($data), 'data' => $data ]); } public function fileSizeChart(Request $request) { $this->authorizeForUser($this->getUser(), 'statistics.public-access'); $labels = [ trans('gallery.statistics.file_sizes_legend.small'), trans('gallery.statistics.file_sizes_legend.medium'), trans('gallery.statistics.file_sizes_legend.large'), trans('gallery.statistics.file_sizes_legend.huge') ]; $data = [0, 0, 0, 0]; $stats = DB::table('photos')->whereIn('album_id', DbHelper::getAlbumIDsForCurrentUser()); $stats->chunk(100, function($photos) use (&$data) { foreach ($photos as $photo) { if ($photo->file_size < (1 * 1024 * 1024)) { $data[0]++; } else if ($photo->file_size < (3 * 1024 * 1024)) { $data[1]++; } else if ($photo->file_size < (5 * 1024 * 1024)) { $data[2]++; } else if ($photo->file_size >= (5 * 1024 * 1024)) { $data[3]++; } } }); return response()->json([ 'labels' => $labels, 'backgrounds' => $this->rotateColoursForData($data), 'data' => $data ]); } public function index(Request $request) { $this->authorizeForUser($this->getUser(), 'statistics.public-access'); // Numbers for at-a-glance $albumIDs = DbHelper::getAlbumIDsForCurrentUser(); $albumCount = count($albumIDs); $labelCount = Label::all()->count(); $photoCount = Photo::whereIn('album_id', $albumIDs)->count(); return Theme::render('gallery.statistics', [ 'album_count' => $albumCount, 'label_count' => $labelCount, 'photo_count' => $photoCount ]); } public function photosCombined(Request $request) { $this->authorizeForUser($this->getUser(), 'statistics.public-access'); $labels = []; $data = [ ['label' => trans('gallery.statistics.photos_combined.taken'), 'values' => []], ['label' => trans('gallery.statistics.photos_combined.uploaded'), 'values' => []] ]; foreach ($this->lastXMonthsDates(18) as $date) { $fromDate = sprintf('%04d-%02d-01 00:00:00', $date[0], $date[1]); $toDate = sprintf('%04d-%02d-%02d 23:59:59', $date[0], $date[1], cal_days_in_month(CAL_GREGORIAN, $date[1], $date[0])); $photoCountTaken = Photo::whereBetween('taken_at', array($fromDate, $toDate))->count(); $photoCountUploaded = Photo::whereBetween('created_at', array($fromDate, $toDate))->count(); $labels[] = date('M Y', strtotime($fromDate)); $data[0]['values'][] = $photoCountTaken; $data[1]['values'][] = $photoCountUploaded; } return response()->json([ 'labels' => array_reverse($labels), 'data' => array_reverse($data) ]); } public function photosTaken12Months(Request $request) { $this->authorizeForUser($this->getUser(), 'statistics.public-access'); $labels = []; $data = []; foreach ($this->lastXMonthsDates() as $date) { $fromDate = sprintf('%04d-%02d-01 00:00:00', $date[0], $date[1]); $toDate = sprintf('%04d-%02d-%02d 23:59:59', $date[0], $date[1], cal_days_in_month(CAL_GREGORIAN, $date[1], $date[0])); $photoCount = Photo::whereBetween('taken_at', array($fromDate, $toDate))->count(); $labels[] = date('M Y', strtotime($fromDate)); $data[] = $photoCount; } return response()->json([ 'labels' => array_reverse($labels), 'data' => array_reverse($data) ]); } public function photosUploaded12Months(Request $request) { $this->authorizeForUser($this->getUser(), 'statistics.public-access'); $labels = []; $data = []; foreach ($this->lastXMonthsDates() as $date) { $fromDate = sprintf('%04d-%02d-01 00:00:00', $date[0], $date[1]); $toDate = sprintf('%04d-%02d-%02d 23:59:59', $date[0], $date[1], cal_days_in_month(CAL_GREGORIAN, $date[1], $date[0])); $photoCount = Photo::whereBetween('created_at', array($fromDate, $toDate))->count(); $labels[] = date('M Y', strtotime($fromDate)); $data[] = $photoCount; } return response()->json([ 'labels' => array_reverse($labels), 'data' => array_reverse($data) ]); } private function lastXMonthsDates($x = 12) { $year = intval(date('Y')); $month = intval(date('m')); $datesNeeded = []; while (count($datesNeeded) < $x) { $datesNeeded[] = [$year, $month]; $month--; if ($month == 0) { $month = 12; $year--; } } return $datesNeeded; } private function rotateColoursForData(array $data = []) { $colours = [ '#d54d36', '#59c669', '#aa5ccf', '#85b83a', '#5f6cd9', '#bbb248', '#ca49a1', '#479341', '#d94b70', '#52b395', '#7b589e', '#da8f32', '#6e8bd0', '#8a722c', '#46aed7', '#aa5839', '#d48cca', '#64803f', '#a5506d', '#e19774' ]; $result = []; $lastIndex = 0; for ($i = 0; $i < count($data); $i++) { $result[] = $colours[$lastIndex]; $lastIndex++; if ($lastIndex >= count($colours)) { $lastIndex = 0; } } return $result; } }