* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 */ namespace App\Http\Controllers\Staff; use App\Http\Controllers\Controller; use App\Http\Requests\StorePoll; use App\Models\Option; use App\Models\Poll; use App\Repositories\ChatRepository; /** * @see \Tests\Todo\Feature\Http\Controllers\Staff\PollControllerTest */ class PollController extends Controller { /** * @var ChatRepository */ private $chatRepository; /** * PollController Constructor. * * @param \App\Repositories\ChatRepository $chatRepository */ public function __construct(ChatRepository $chatRepository) { $this->chatRepository = $chatRepository; } /** * Display All Polls. * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function index() { $polls = Poll::latest()->paginate(25); return \view('Staff.poll.index', ['polls' => $polls]); } /** * Show A Poll. * * @param \App\Models\Poll $id * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function show($id) { $poll = Poll::where('id', '=', $id)->firstOrFail(); return \view('Staff.poll.show', ['poll' => $poll]); } /** * Poll Add Form. * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function create() { return \view('Staff.poll.create'); } /** * Store A New Poll. * * @param \App\Http\Requests\StorePoll $storePoll * * @return \Illuminate\Http\RedirectResponse */ public function store(StorePoll $storePoll) { $user = $storePoll->user(); $poll = $storePoll->user() ? $user->polls()->create($storePoll->all()) : Poll::create($storePoll->all()); $options = \collect($storePoll->input('options'))->map(fn ($value) => new Option(['name' => $value])); $poll->options()->saveMany($options); $poll_url = \href_poll($poll); $this->chatRepository->systemMessage( \sprintf('A new poll has been created [url=%s]%s[/url] vote on it now! :slight_smile:', $poll_url, $poll->title) ); return \redirect()->route('staff.polls.index') ->withSuccess('Your poll has been created.'); } /** * Poll Edit Form. * * @param \App\Models\Poll $id * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function edit($id) { $poll = Poll::findOrFail($id); return \view('Staff.poll.edit', ['poll' => $poll]); } /** * Update A New Poll. * * @param \App\Http\Requests\StorePoll $storePoll * @param $id * * @throws \Exception * * @return \Illuminate\Http\RedirectResponse */ public function update(StorePoll $storePoll, $id) { $poll = Poll::findOrFail($id); $poll->title = $storePoll->input('title'); $poll->multiple_choice = (bool) $storePoll->input('multiple_choice'); // Remove the deleted options in poll $oldOptionIds = \collect($poll->options)->map(fn ($option) => $option->id)->all(); $existingOldOptionIds = \collect($storePoll->input('option-id'))->map(fn ($id) => (int) $id)->all(); $idsOfOptionToBeRemove = \array_diff($oldOptionIds, $existingOldOptionIds); foreach ($idsOfOptionToBeRemove as $id) { $option = Option::findOrFail($id); $option->delete(); } // Update existing options $existingOldOptionContents = \collect($storePoll->input('option-content'))->map(fn ($content) => \strval($content))->all(); if (\count($existingOldOptionContents) === \count($existingOldOptionIds)) { $len = \count($existingOldOptionContents); for ($i = 0; $i < $len; $i++) { $option = Option::findOrFail($existingOldOptionIds[$i]); $option->name = $existingOldOptionContents[$i]; $option->save(); } } // Insert new options $newOptions = \collect($storePoll->input('new-option-content'))->map(fn ($content) => new Option(['name' => $content])); $poll->options()->saveMany($newOptions); // Last work from store() $poll_url = \href_poll($poll); $this->chatRepository->systemMessage( \sprintf('A poll has been updated [url=%s]%s[/url] vote on it now! :slight_smile:', $poll_url, $poll->title) ); $poll->save(); return \redirect()->route('staff.polls.index') ->withSuccess('Your poll has been edited.'); } /** * Delete A Poll. * * @param \App\Models\Poll $id * * @throws \Exception * * @return \Illuminate\Http\RedirectResponse */ public function destroy($id) { $poll = Poll::findOrFail($id); $poll->delete(); return \redirect()->route('staff.polls.index') ->withSuccess('Poll has successfully been deleted'); } }