HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/ASmits/kemi.nl/app/KommaApp/Shop/Discounts/Conditions/DiscountableCondition.php
<?php


namespace App\KommaApp\Shop\Discounts\Conditions;

use App\KommaApp\Shop\Discounts\DiscountableInterface;
use App\KommaApp\Shop\Discounts\DiscountableTypes;


/**
 * Helps applying a discount to a specific discountable
 *
 * @package App\KommaApp\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(count($this->discountableIds) > 0 && !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;
    }
}