Skip to content

Commit

Permalink
Add/remove options
Browse files Browse the repository at this point in the history
  • Loading branch information
akiyamaSM committed May 13, 2020
1 parent 79ef65d commit a8ea695
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 158 deletions.
5 changes: 4 additions & 1 deletion src/Http/Controllers/PollManagerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ public function edit(Poll $poll)
'value' => $option->name,
];
})->toArray();
return view('larapoll::dashboard.edit', compact('poll', 'options'));

$canChangeOptions = $poll->votes()->count() === 0;

return view('larapoll::dashboard.edit', compact('poll', 'options', 'canChangeOptions'));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Option extends Model
{
use Votable;

protected $fillable = ['name'];
protected $guarded = [];

protected $table = 'larapoll_options';
/**
Expand Down
10 changes: 10 additions & 0 deletions src/Poll.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,14 @@ public function canGuestVote()
{
return $this->canVisitorsVote === 1;
}

/**
* Check if the user can change options
*
* @return bool
*/
public function canChangeOptions()
{
return $this->votes()->count() === 0;
}
}
13 changes: 13 additions & 0 deletions src/helpers/PollHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Inani\Larapoll\Exceptions\OptionsInvalidNumberProvidedException;
use Inani\Larapoll\Exceptions\OptionsNotProvidedException;
use Inani\Larapoll\Exceptions\RemoveVotedOptionException;
use Inani\Larapoll\Option;
use Inani\Larapoll\Poll;
use InvalidArgumentException;

Expand Down Expand Up @@ -55,6 +56,18 @@ public static function createFromRequest($request)
*/
public static function modify(Poll $poll, $data)
{
if($poll->canChangeOptions()){
$poll->options()->delete();

collect($data['options'])->each(function ($option) use($poll){
Option::create([
'name' => $option,
'poll_id' => $poll->id,
'votes' => 0
]);
});
}

if (isset($data['count_check'])) {
if ($data['count_check'] < $poll->options()->count()) {
$poll->canSelect($data['count_check']);
Expand Down
307 changes: 154 additions & 153 deletions src/traits/PollCreator.php
Original file line number Diff line number Diff line change
@@ -1,153 +1,154 @@
<?php
namespace Inani\Larapoll\Traits;

use Illuminate\Support\Facades\DB;
use Inani\Larapoll\Exceptions\CheckedOptionsException;
use Inani\Larapoll\Exceptions\OptionsInvalidNumberProvidedException;
use Inani\Larapoll\Exceptions\OptionsNotProvidedException;
use Inani\Larapoll\Option;
use Inani\Larapoll\Exceptions\DuplicatedOptionsException;

trait PollCreator
{
protected $options_add = [];
protected $maxSelection = 1;

/**
* Add an option to the array if not exists
*
* @param $option
* @return bool
* @throws DuplicatedOptionsException
*/
private function pushOption($option)
{
if (!in_array($option, $this->options_add)) {
$this->options_add[] = $option;
return true;
}
throw new DuplicatedOptionsException();
}

/**
* Add new Options
*
* @param $options
* @return $this
* @throws \InvalidArgumentException
*/
public function addOptions($options)
{
if (is_array($options)) {
foreach ($options as $option) {
if (is_string($option)) {
$this->pushOption($option);
} else {
throw new \InvalidArgumentException("Array arguments must be composed of Strings values");
}
}
return $this;
}

if (is_string($options)) {
$this->pushOption($options);
return $this;
}

throw new \InvalidArgumentException("Invalid Argument provided");
}

/**
* Select max options to be voted by a user
*
* @param int $number
* @return $this
*/
public function maxSelection($number = 1)
{
if ($number <= 1) {
$number = 1;
}
$this->maxSelection = $number;

return $this;
}

/**
* It starts at
*
* @param null $at
* @return $this
*/
public function startsAt($at = null)
{
$this->starts_at = !is_null($at) ? $at : now();

return $this;
}

/**
* It ends at
*
* @param null $at
* @return $this
*/
public function endsAt($at = null)
{
$this->ends_at = !is_null($at) ? $at : now()->addDays(7);

return $this;
}

/**
* Generate the poll
*
* @return bool
* @throws CheckedOptionsException
* @throws OptionsInvalidNumberProvidedException
* @throws OptionsNotProvidedException
*/
public function generate()
{
$totalOptions = count($this->options_add);

// No option add yet
if ($totalOptions == 0)
throw new OptionsNotProvidedException();

// There must be 2 options at least
if ($totalOptions == 1)
throw new OptionsInvalidNumberProvidedException();

// At least one options should not be selected
if ($totalOptions <= $this->maxSelection)
throw new CheckedOptionsException();

// Create Poll && assign options to it
DB::transaction(function () {
$this->maxCheck = $this->maxSelection;
$this->save();
$this->options()
->saveMany($this->instantiateOptions());
});

return true;
}

/**
* Instantiate the options
*
* @return array
*/
private function instantiateOptions()
{
$options = [];
foreach ($this->options_add as $option) {
$options[] = new Option([
'name' => $option
]);
}

return $options;
}
}
<?php
namespace Inani\Larapoll\Traits;

use Illuminate\Support\Facades\DB;
use Inani\Larapoll\Exceptions\CheckedOptionsException;
use Inani\Larapoll\Exceptions\OptionsInvalidNumberProvidedException;
use Inani\Larapoll\Exceptions\OptionsNotProvidedException;
use Inani\Larapoll\Option;
use Inani\Larapoll\Exceptions\DuplicatedOptionsException;

trait PollCreator
{
protected $options_add = [];
protected $maxSelection = 1;

/**
* Add an option to the array if not exists
*
* @param $option
* @return bool
* @throws DuplicatedOptionsException
*/
private function pushOption($option)
{
if (!in_array($option, $this->options_add)) {
$this->options_add[] = $option;
return true;
}
throw new DuplicatedOptionsException();
}

/**
* Add new Options
*
* @param $options
* @return $this
* @throws \InvalidArgumentException
* @throws DuplicatedOptionsException
*/
public function addOptions($options)
{
if (is_array($options)) {
foreach ($options as $option) {
if (is_string($option)) {
$this->pushOption($option);
} else {
throw new \InvalidArgumentException("Array arguments must be composed of Strings values");
}
}
return $this;
}

if (is_string($options)) {
$this->pushOption($options);
return $this;
}

throw new \InvalidArgumentException("Invalid Argument provided");
}

/**
* Select max options to be voted by a user
*
* @param int $number
* @return $this
*/
public function maxSelection($number = 1)
{
if ($number <= 1) {
$number = 1;
}
$this->maxSelection = $number;

return $this;
}

/**
* It starts at
*
* @param null $at
* @return $this
*/
public function startsAt($at = null)
{
$this->starts_at = !is_null($at) ? $at : now();

return $this;
}

/**
* It ends at
*
* @param null $at
* @return $this
*/
public function endsAt($at = null)
{
$this->ends_at = !is_null($at) ? $at : now()->addDays(7);

return $this;
}

/**
* Generate the poll
*
* @return bool
* @throws CheckedOptionsException
* @throws OptionsInvalidNumberProvidedException
* @throws OptionsNotProvidedException
*/
public function generate()
{
$totalOptions = count($this->options_add);

// No option add yet
if ($totalOptions == 0)
throw new OptionsNotProvidedException();

// There must be 2 options at least
if ($totalOptions == 1)
throw new OptionsInvalidNumberProvidedException();

// At least one options should not be selected
if ($totalOptions <= $this->maxSelection)
throw new CheckedOptionsException();

// Create Poll && assign options to it
DB::transaction(function () {
$this->maxCheck = $this->maxSelection;
$this->save();
$this->options()
->saveMany($this->instantiateOptions());
});

return true;
}

/**
* Instantiate the options
*
* @return array
*/
private function instantiateOptions()
{
$options = [];
foreach ($this->options_add as $option) {
$options[] = new Option([
'name' => $option
]);
}

return $options;
}
}
7 changes: 4 additions & 3 deletions src/views/dashboard/edit.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@
Options
</label>
<div v-for="(option, index) in options" class="w-full flex items-center border-b border-b-2 border-teal-500 py-2">
<input v-model="option.value" :placeholder="option.placeholder" class="appearance-none bg-transparent border-none block w-full text-gray-700 mr-3 py-1 px-2 leading-tight focus:outline-none" type="text" />
<button @click.prevent="remove(index)" class="flex-shrink-0 border-transparent border-4 text-teal-500 hover:text-teal-800 text-sm py-1 px-2 rounded" type="button">
<input :disabled="canChangeOptions" v-model="option.value" :placeholder="option.placeholder" class="appearance-none bg-transparent border-none block w-full text-gray-700 mr-3 py-1 px-2 leading-tight focus:outline-none" type="text" />
<button v-if="canChangeOptions" @click.prevent="remove(index)" class="flex-shrink-0 border-transparent border-4 text-teal-500 hover:text-teal-800 text-sm py-1 px-2 rounded" type="button">
Remove
</button>
</div>
<div class="w-full flex items-center border-b border-b-2 border-teal-500 py-2">
<div v-if="canChangeOptions" class="w-full flex items-center border-b border-b-2 border-teal-500 py-2">
<input @keyup.enter="addNewOption" v-model="newOption" class="appearance-none bg-transparent border-none block w-full text-gray-700 mr-3 py-1 px-2 leading-tight focus:outline-none" type="text" placeholder="Luka Modric" aria-label="Full name">
<button @click.prevent="addNewOption" class="flex-shrink-0 bg-teal-500 hover:bg-teal-700 border-teal-500 hover:border-teal-700 text-sm border-4 text-white py-1 px-2 rounded" type="button">
Add
Expand Down Expand Up @@ -134,6 +134,7 @@
return {
id: "{{ $poll->id }}",
newOption: '',
canChangeOptions: "{{ $canChangeOptions }}",
question: "{{ $poll->question }}",
options: {!! json_encode($options) !!},
error_message: '',
Expand Down

0 comments on commit a8ea695

Please sign in to comment.