File: D:/HostingSpaces/slenders/slenders.nl/app/Komma/Shop/Discounts/Conditions/DiscountableCondition.php
<?php
namespace App\Komma\Shop\Discounts\Conditions;
use App\Komma\Shop\Discounts\DiscountableInterface;
use App\Komma\Shop\Discounts\DiscountableTypes;
/**
* Helps applying a discount to a specific discountable
*
* @package App\Komma\Shop\Discounts
*/
class DiscountableCondition extends AbstractDiscountCondition
{
/** @var int[] $discountableIds */
private $discountableIds;
/**
* AbsoluteDiscountCondition constructor.
* @param DiscountableInterface|string $discountable
* @param array|null $discountableIds
*/
public function __construct($discountable, array $discountableIds = null)
{
$conditionSettings = DiscountableTypes::toDiscountableTypeConstantValue($discountable); //Validation of this is done further in the flow
$conditionSettings = (!$discountableIds) ? $conditionSettings : $conditionSettings.','.implode(',', $discountableIds);
parent::__construct($conditionSettings);
}
/**
* Whether or not the discount that this condition belongs to can be applied according to this rule
*
* @param DiscountableInterface $discountable
* @return bool
*/
public function canBeApplied(DiscountableInterface $discountable): bool
{
//An absolute value discount can be applied on a shopping cart or shopping cart item
if(!is_a($discountable, $this->discountable)) return false;
if(is_array($this->discountableIds) && ! in_array($discountable->id, $this->discountableIds)) return false;
return true;
}
/**
* Dissect a value that comes from a discount into something that the DiscountCondition understands
*
* @param string $discountValue
* @return bool
*/
protected function dissectDiscountValue(string $discountValue): bool
{
$discountValueParts = $this->returnDissectedValueIfValid($discountValue);
$this->assignDiscountableIfValid($discountValueParts[0]);
if(count($discountValueParts) > 1) $this->assignDiscountableIdsIfValid(array_shift($discountValueParts));
return false;
}
/**
* Create a new instance from the settings from a discount model
*
* @param string $discountConditionSettings
* @return AbstractDiscountCondition
*/
public static function newInstanceFromDiscountSettings(string $discountConditionSettings): AbstractDiscountCondition
{
$settings = DiscountableCondition::returnDissectedValueIfValid($discountConditionSettings);
$settingsItemCount = count($settings);
$settings[0] = DiscountableTypes::typeConstantToDiscountableInterface($settings[0]);
if($settingsItemCount == 1) return new self($settings[0]);
else return new self($settings[0], $settings[1]);
}
/**
* Checks if the value delimited string is correctly defined and returns the separate values
*
* @param $discountValue
* @return array
*/
private static function returnDissectedValueIfValid($discountValue):array
{
$discountValueParts = explode(',', $discountValue);
if(!count($discountValueParts) >= 1) throw new \InvalidArgumentException('The value for an absolute discount must be specified like this: <DiscountableTypes::constant>[,DiscountableId]. Got: '.$discountValue);
return $discountValueParts;
}
/**
* Checks if the Discountable id is set and if if it is numeric and assigns it internally. If not throws an exception
*
* @param int[] $ints
*/
private function assignDiscountableIdsIfValid(array $ints)
{
foreach($ints as $int) if(!is_null($int) && !is_numeric($int)) throw new \InvalidArgumentException('The discountable id must be numeric (or null) but was of type: '.gettype($int));
$this->discountableIds = $ints;
}
}