Skip to content

Commit

Permalink
Merge branch 'multiple-values'
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Stříbrný committed May 11, 2016
2 parents 9a7bb78 + effeb97 commit f9b96d4
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 49 deletions.
21 changes: 20 additions & 1 deletion src/Components/AjaxSelect/Entities/AbstractEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,26 @@ public function parseOptions(array $options) {

/**
* @internal
* @param mixed|array $value
* @param array $values
* @return bool[] $value => $isValid
*/
public function areValidValues($values) {
$result = [ ];

if (!is_array($values)) {
$values = [ $values ];
}

foreach ($values as $value) {
$result[$value] = $this->isValidValue($value);
}

return $result;
}

/**
* @internal
* @param mixed $value
* @return bool
*/
public abstract function isValidValue($value);
Expand Down
44 changes: 23 additions & 21 deletions src/Components/AjaxSelect/Traits/AjaxServiceControlTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,35 @@ public function setAjaxEntity(AjaxSelect\Entities\AbstractEntity $ajaxEntity) {
$this->ajaxEntity = $ajaxEntity;
}

protected function handleInvalidValue($value, $e) {
if (!$this->getAjaxEntity()->isValidValue($value)) {
switch ($this->getAjaxEntity()->getConfig()[AjaxSelect\DI\AjaxSelectExtension::CONFIG_INVALID_VALUE_MODE]) {
case AjaxSelect\DI\AjaxSelectExtension::INVALID_VALUE_MODE_EMPTY:
$this->value = NULL;
return $this;

case AjaxSelect\DI\AjaxSelectExtension::INVALID_VALUE_MODE_EXCEPTION:
default:
throw $e;
protected abstract function handleInvalidValues($values);

/**
* Processes value that could not be assigned.
* @param mixed|array $values
* @return mixed|array Value to assign.
*/
protected function processValues($values) {
$validValues = [ ];
$invalidValues = [ ];

foreach ($this->getAjaxEntity()->areValidValues($values) as $value => $isValid) {
if ($isValid) {
$validValues[] = $value;
} else {
$invalidValues[] = $value;
}
}

$items = $value;

// ensure $items is array
if (!is_array($items)) {
$items = [ $items ];
if (count($invalidValues) > 0) {
$validValues = array_merge($validValues, $this->handleInvalidValues($invalidValues) ?: [ ]);
}

// list of ids combine to identity array i.e. key = value
$items = array_combine($items, $items);
// combine list of ids to identity array i.e. key = value
$items = array_combine($validValues, $validValues);

// set items and value
$this->setItems($items);
$this->value = $value;
// add to list of valid values
$this->setItems($this->getItems() + $items);

return $this;
return $validValues;
}
}
57 changes: 38 additions & 19 deletions src/Components/AjaxSelect/Traits/InvalidSetValueTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,49 @@ public function setInvalidValueMode($mode) {

protected abstract function getHttpData($type, $htmlTail = NULL);
protected abstract function isDisabled();
protected abstract function handleInvalidValue($value, $exception);

/**
* Processes value that could not be assigned.
* @param mixed|array $value
* @return mixed|array Value to assign.
*/
protected abstract function processValues($value);

protected function handleInvalidValues($values) {
switch ($this->getInvalidValueMode()) {
case AjaxSelect\DI\AjaxSelectExtension::INVALID_VALUE_MODE_EXCEPTION:
throw new \Nette\InvalidArgumentException;

case AjaxSelect\DI\AjaxSelectExtension::INVALID_VALUE_MODE_EMPTY:
return $this instanceof AjaxSelect\Interfaces\IMultiSelectControl
? [ ] : NULL;
break;
}

return $this;
}

public function setValue($value) {
try {
// try assign value
// try to assign value
return parent::setValue($value);
} catch (\Nette\InvalidArgumentException $e) {
try {
// try create and assign value
return $this->handleInvalidValue($value, $e);
} catch (\Nette\InvalidArgumentException $e) {
// value is invalid and there is no way of assigning it

switch ($this->invalidValueMode) {
case AjaxSelect\DI\AjaxSelectExtension::INVALID_VALUE_MODE_EMPTY:
$this->value = NULL;
return $this;

case AjaxSelect\DI\AjaxSelectExtension::INVALID_VALUE_MODE_EXCEPTION:
default:
throw $e;
}
}
} catch (\Nette\InvalidArgumentException $e) {}

// make sure $value is an array
if (!is_array($value)) {
$value = [ $value ];
}

// try create and assign value
$value = $this->processValues($value);

// revert array to single value if needed
if (!$this instanceof AjaxSelect\Interfaces\IMultiSelectControl) {
$value = reset($value);
}

// try to assign value
return parent::setValue($value);
}

}
23 changes: 15 additions & 8 deletions src/Components/AjaxSelect/Traits/ItemFactoryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace ADT\Components\AjaxSelect\Traits;

use ADT\Components\AjaxSelect;

trait ItemFactoryTrait {

/** @var callable|NULL */
Expand All @@ -23,24 +25,29 @@ public function setItemFactory($itemFactory) {
return $this;
}

protected abstract function getItems();
protected abstract function setItems($items);
protected abstract function handleInvalidValues($value);

protected function handleInvalidValue($value, $e) {
/**
* TODO: cannot handle multiple values
* @param $values
* @return mixed
*/
protected function processValues($values) {
if ($this->itemFactory === NULL) {
throw $e;
return $this->handleInvalidValues($values);
}

$item = call_user_func($this->itemFactory, $value);
$item = call_user_func($this->itemFactory, $values);

if (empty($item)) {
throw $e;
return $this->handleInvalidValues($values);
}

// add value to list of valid items
$items = $this->getItems();
$items[$value] = $item;
$items[$values] = $item;
$this->setItems($items);

return parent::setValue($value);
return $values;
}
}

0 comments on commit f9b96d4

Please sign in to comment.