blue-twilight/app/Http/Controllers/Gallery/UserController.php

255 lines
8.1 KiB
PHP

<?php
namespace App\Http\Controllers\Gallery;
use App\Album;
use App\Facade\Theme;
use App\Facade\UserConfig;
use App\Helpers\DbHelper;
use App\Http\Controllers\Controller;
use App\Http\Requests\SaveUserSettingsRequest;
use App\Mail\UserChangeEmailRequired;
use App\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Symfony\Component\HttpFoundation\Request;
class UserController extends Controller
{
public function saveSettings(SaveUserSettingsRequest $request)
{
$data = $request->only(['name', 'email', 'profile_alias', 'enable_profile_page']);
$user = $this->getUser();
if (UserConfig::get('require_email_verification'))
{
// Can't update the e-mail directly until the new e-mail address has been verified.
// TODO - send e-mail and handle response, flag e-mail as being "change in-progress"
// Send activation e-mail
// Temporarily change the e-mail address so we can send the activation message
$oldEmailAddress = $user->getEmailForPasswordReset();
$user->email = $data['email'];
Mail::to($this->getUser())->send(new UserChangeEmailRequired($this->getUser()));
$request->session()->flash('info', trans('auth.change_email_required_message'));
// Flag the user as a change e-mail in progress
$user->new_email_address = $user->email;
$user->is_email_change_in_progress = true;
$user->email = $oldEmailAddress;
$user->save();
unset($data['email']);
}
// Don't allow e-mail address to be changed if a change is in progress
if ($user->is_email_change_in_progress)
{
unset($data['email']);
}
$user->fill($data);
$user->enable_profile_page = (isset($data['enable_profile_page']) && strtolower($data['enable_profile_page']) == 'on');
$user->save();
$request->session()->flash('success', trans('gallery.user_settings.settings_saved'));
return redirect(route('userSettings'));
}
public function settings(Request $request)
{
return Theme::render('gallery.user_settings', [
'info' => $request->session()->get('info'),
'success' => $request->session()->get('success'),
'user' => $this->getUser()
]);
}
public function show(Request $request, $idOrAlias)
{
// If a user has a profile alias set, their profile page cannot be accessed by the ID
$user = User::where(DB::raw('COALESCE(profile_alias, id)'), strtolower($idOrAlias))->first();
if (is_null($user))
{
App::abort(404);
return null;
}
$this->authorizeForUser($this->getUser(), 'view', $user);
$albums = $this->getAlbumsForUser($user);
$albumIDs = $this->getAlbumIDsForUser($user);
$cameras = $this->getCamerasUsedInAlbums($albumIDs);
$activity = $this->getActivityDatesInAlbums($albumIDs);
$daysInMonth = $this->getDaysInMonths();
return Theme::render('gallery.user_profile', [
'activity_taken' => $this->constructActivityGrid($activity['taken']),
'activity_uploaded' => $this->constructActivityGrid($activity['uploaded']),
'albums' => $albums,
'cameras' => $cameras,
'month_days' => $daysInMonth,
'user' => $user
]);
}
private function constructActivityGrid(Collection $collection)
{
$results = [];
$lastYearFrom = new \DateTime();
$lastYearFrom->sub(new \DateInterval('P1Y'));
$lastYearFrom->add(new \DateInterval('P1D'));
$today = new \DateTime();
$current = clone $lastYearFrom;
while ($current < $today)
{
$year = intval($current->format('Y'));
$month = intval($current->format('m'));
$date = intval($current->format('d'));
if (!isset($results[$year]))
{
$results[$year] = [];
}
if (!isset($results[$year][$month]))
{
$results[$year][$month] = [];
}
if (!isset($results[$year][$month][$date]))
{
$results[$year][$month][$date] = 0;
}
$current->add(new \DateInterval('P1D'));
}
// Now update the totals from the collection
foreach ($collection as $photoInfo)
{
$date = \DateTime::createFromFormat('Y-m-d', $photoInfo->the_date);
$year = intval($date->format('Y'));
$month = intval($date->format('m'));
$date = intval($date->format('d'));
$results[$year][$month][$date] = $photoInfo->photos_count;
}
// Replace the month names
foreach ($results as $year => &$months)
{
foreach ($months as $month => $dates)
{
$monthDate = \DateTime::createFromFormat('m', $month);
$months[$monthDate->format('M')] = $dates;
unset($months[$month]);
}
}
return $results;
}
private function getActivityDatesInAlbums(array $albumIDs)
{
$createdAt = DB::table('photos')
->whereIn('album_id', $albumIDs)
->whereRaw(DB::raw('DATE(created_at) > DATE(DATE_SUB(NOW(), INTERVAL 1 year))'))
->select([
DB::raw('DATE(created_at) AS the_date'),
DB::raw('COUNT(photos.id) AS photos_count')
])
->groupBy(DB::raw('DATE(created_at)'))
->orderBy(DB::raw('DATE(created_at)'))
->get();
$takenAt = DB::table('photos')
->whereIn('album_id', $albumIDs)
->whereRaw(DB::raw('DATE(taken_at) > DATE(DATE_SUB(NOW(), INTERVAL 1 year))'))
->select([
DB::raw('DATE(taken_at) AS the_date'),
DB::raw('COUNT(photos.id) AS photos_count')
])
->groupBy(DB::raw('DATE(taken_at)'))
->orderBy(DB::raw('DATE(taken_at)'))
->get();
return ['uploaded' => $createdAt, 'taken' => $takenAt];
}
private function getAlbumsForUser(User $user)
{
return DbHelper::getAlbumsForCurrentUser_NonPaged()
->where('user_id', $user->id)
->paginate(UserConfig::get('items_per_page'));
}
private function getAlbumIDsForUser(User $user)
{
$results = [];
$albums = DbHelper::getAlbumsForCurrentUser_NonPaged()
->where('user_id', $user->id)
->select('albums.id')
->get();
foreach ($albums as $album)
{
$results[] = intval($album->id);
}
return $results;
}
private function getCamerasUsedInAlbums(array $albumIDs)
{
return DB::table('photos')
->whereIn('album_id', $albumIDs)
->where([
['camera_make', '!=', ''],
['camera_model', '!=', '']
])
->groupBy('camera_make', 'camera_model', 'camera_software')
->select('camera_make', 'camera_model', 'camera_software', DB::raw('count(*) as photo_count'))
->orderBy('photo_count', 'desc')
->orderBy('camera_make')
->orderBy('camera_model')
->orderBy('camera_software')
->get();
}
private function getDaysInMonths()
{
$results = [];
$lastYearFrom = new \DateTime();
$lastYearFrom->sub(new \DateInterval('P1Y'));
$lastYearFrom->sub(new \DateInterval(sprintf('P%dD', $lastYearFrom->format('d') - 1)));
$today = new \DateTime();
$current = clone $lastYearFrom;
while ($current < $today)
{
$year = intval($current->format('Y'));
$month = intval($current->format('m'));
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$results[$year][$current->format('M')] = $daysInMonth;
$current->add(new \DateInterval('P1M'));
}
return $results;
}
}