modules/XC/WheelTireFitment/src/Model/VehicleAttributeValue.php line 24

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright (c) 2011-present Qualiteam software Ltd. All rights reserved.
  4.  * See https://www.x-cart.com/license-agreement.html for license details.
  5.  */
  6. namespace XC\WheelTireFitment\Model;
  7. use Doctrine\ORM\Mapping as ORM;
  8. use Includes\Utils\Converter as UtilsConverter;
  9. use Includes\Utils\ArrayManager;
  10. use XC\WheelTireFitment\Core\WheelTireProductAttributeFields;
  11. /**
  12.  * @ORM\Entity
  13.  * @ORM\Table (name="vehicle_attribute_values",
  14.  *     uniqueConstraints={
  15.  *         @ORM\UniqueConstraint (name="ih", columns={"id", "hash"})
  16.  *     }
  17.  * )
  18.  * @ORM\HasLifecycleCallbacks
  19.  */
  20. class VehicleAttributeValue extends AVehicleAttribute
  21. {
  22.     public const FITMENT_TYPE_ORIGINAL  'OR';
  23.     public const FITMENT_TYPE_OPTIONAL  'OP';
  24.     public const FITMENT_TYPE_PLUS_SIZE 'LS';
  25.     public const WHEEL_SIZE_PATTERN_STRING '{rimDiameter}&#8243;x{rimWidth}&#8243;';
  26.     public const TIRE_SIZE_PATTERN_STRING  '{sectionWidth}/{aspectRatio}R{rimDiameter}';
  27.     public const SCHEMA_FRONT_NAME 'front';
  28.     public const SCHEMA_REAR_NAME  'rear';
  29.     public const SCHEMA_WHEEL_NAME 'wheel';
  30.     public const SCHEMA_TIRE_NAME  'tire';
  31.     /**
  32.      * @var int
  33.      *
  34.      * @ORM\Id
  35.      * @ORM\GeneratedValue (strategy="AUTO")
  36.      * @ORM\Column (type="integer", options={ "unsigned": true })
  37.      */
  38.     protected $id;
  39.     /**
  40.      * @var integer
  41.      *
  42.      * @ORM\Column (type="integer")
  43.      */
  44.     protected $aspectRatio;
  45.     /**
  46.      * @var integer
  47.      *
  48.      * @ORM\Column (type="integer")
  49.      */
  50.     protected $aspectRatioRear;
  51.     /**
  52.      * @var integer
  53.      *
  54.      * @ORM\Column (type="integer")
  55.      */
  56.     protected $rimDiameter;
  57.     /**
  58.      * @var integer
  59.      *
  60.      * @ORM\Column (type="integer")
  61.      */
  62.     protected $rimDiameterRear;
  63.     /**
  64.      * @var float
  65.      *
  66.      * @ORM\Column (type="decimal", precision=3, scale=1)
  67.      */
  68.     protected $rimWidth;
  69.     /**
  70.      * @var float
  71.      *
  72.      * @ORM\Column (type="decimal", precision=3, scale=1)
  73.      */
  74.     protected $rimWidthRear;
  75.     /**
  76.      * @var integer
  77.      *
  78.      * @ORM\Column (type="integer")
  79.      */
  80.     protected $sectionWidth;
  81.     /**
  82.      * @var integer
  83.      *
  84.      * @ORM\Column (type="integer")
  85.      */
  86.     protected $sectionWidthRear;
  87.     /**
  88.      * Fitment type (Original, Optional, Plus size)
  89.      *
  90.      * @var string
  91.      *
  92.      * @ORM\Column (type="string", options={"fixed": true, "default": "OR"}, length=2)
  93.      */
  94.     protected $type self::FITMENT_TYPE_ORIGINAL;
  95.     /**
  96.      * Attributes hash
  97.      *
  98.      * @var string
  99.      *
  100.      * @ORM\Column (type="string", nullable=true)
  101.      */
  102.     protected $hash;
  103.     /**
  104.      * @var VehicleAttributeGroup
  105.      *
  106.      * @ORM\ManyToOne (targetEntity="XC\WheelTireFitment\Model\VehicleAttributeGroup", inversedBy="attributes")
  107.      * @ORM\JoinColumn (name="vehicleAttributeGroup", referencedColumnName="id", onDelete="CASCADE")
  108.      */
  109.     protected $vehicleAttributeGroup;
  110.     public function getId(): ?int
  111.     {
  112.         return $this->id;
  113.     }
  114.     public function getAspectRatio(): int
  115.     {
  116.         return $this->aspectRatio;
  117.     }
  118.     public function setAspectRatio($aspectRatio): void
  119.     {
  120.         $this->aspectRatio = (int) $aspectRatio;
  121.     }
  122.     public function getAspectRatioRear(): int
  123.     {
  124.         return $this->aspectRatioRear;
  125.     }
  126.     public function setAspectRatioRear($aspectRatioRear): void
  127.     {
  128.         $this->aspectRatioRear = (int) $aspectRatioRear;
  129.     }
  130.     public function getRimDiameter(): int
  131.     {
  132.         return $this->rimDiameter;
  133.     }
  134.     public function setRimDiameter($rimDiameter): void
  135.     {
  136.         $this->rimDiameter = (int) $rimDiameter;
  137.     }
  138.     public function getRimDiameterRear(): int
  139.     {
  140.         return $this->rimDiameterRear;
  141.     }
  142.     public function setRimDiameterRear($rimDiameterRear): void
  143.     {
  144.         $this->rimDiameterRear = (int) $rimDiameterRear;
  145.     }
  146.     public function getRimWidth(): float
  147.     {
  148.         return $this->rimWidth;
  149.     }
  150.     public function setRimWidth($rimWidth): void
  151.     {
  152.         $this->rimWidth = (float) $rimWidth;
  153.     }
  154.     public function getRimWidthRear(): float
  155.     {
  156.         return $this->rimWidthRear;
  157.     }
  158.     public function setRimWidthRear($rimWidthRear): void
  159.     {
  160.         $this->rimWidthRear = (float) $rimWidthRear;
  161.     }
  162.     public function getSectionWidth(): int
  163.     {
  164.         return $this->sectionWidth;
  165.     }
  166.     public function setSectionWidth($sectionWidth): void
  167.     {
  168.         $this->sectionWidth = (int) $sectionWidth;
  169.     }
  170.     public function getSectionWidthRear(): int
  171.     {
  172.         return $this->sectionWidthRear;
  173.     }
  174.     public function setSectionWidthRear($sectionWidthRear): void
  175.     {
  176.         $this->sectionWidthRear = (int) $sectionWidthRear;
  177.     }
  178.     public function getType(): string
  179.     {
  180.         return $this->type;
  181.     }
  182.     public function setType(string $type): void
  183.     {
  184.         $this->type $type;
  185.     }
  186.     public function getVehicleAttributeGroup(): VehicleAttributeGroup
  187.     {
  188.         return $this->vehicleAttributeGroup;
  189.     }
  190.     public function setVehicleAttributeGroup(VehicleAttributeGroup $vehicleAttributeGroup)
  191.     {
  192.         $this->vehicleAttributeGroup $vehicleAttributeGroup;
  193.     }
  194.     public function getHash(): string
  195.     {
  196.         return $this->hash;
  197.     }
  198.     public function setHash(string $hash): void
  199.     {
  200.         $this->hash $hash;
  201.     }
  202.     public static function getHashFields(): array
  203.     {
  204.         return [
  205.             'AspectRatio',
  206.             'AspectRatioRear',
  207.             'RimDiameter',
  208.             'RimDiameterRear',
  209.             'RimWidth',
  210.             'RimWidthRear',
  211.             'SectionWidth',
  212.             'SectionWidthRear',
  213.             'Type',
  214.         ];
  215.     }
  216.     public static function getHashDataBy(array $data): array
  217.     {
  218.         $result = [];
  219.         foreach (static::getHashFields() as $fieldName) {
  220.             if (!empty($data[$fieldName])) {
  221.                 $result[$fieldName] = $data[$fieldName];
  222.             }
  223.         }
  224.         return $result;
  225.     }
  226.     public function getHashData(): array
  227.     {
  228.         $result = [];
  229.         foreach (static::getHashFields() as $fieldName) {
  230.             $method 'get' UtilsConverter::convertToUpperCamelCase($fieldName);
  231.             if (method_exists($this$method)) {
  232.                 $result[$fieldName] = $this->$method();
  233.             }
  234.         }
  235.         return $result;
  236.     }
  237.     public static function calcHash(array $data): string
  238.     {
  239.         return ArrayManager::md5($data);
  240.     }
  241.     /**
  242.      * @ORM\PrePersist
  243.      * @ORM\PreUpdate
  244.      */
  245.     public function processBeforeUpdate(): void
  246.     {
  247.         $data $this->getHashData();
  248.         $this->setHash(static::calcHash($data));
  249.     }
  250.     public function getWheelReadableSize(bool $isFront true): string
  251.     {
  252.         $methodSuffix $isFront '' 'Rear';
  253.         return str_replace(
  254.             ['{rimDiameter}''{rimWidth}'],
  255.             [
  256.                 $this->{'getRimDiameter' $methodSuffix}(),
  257.                 $this->{'getRimWidth' $methodSuffix}(),
  258.             ],
  259.             static::WHEEL_SIZE_PATTERN_STRING
  260.         );
  261.     }
  262.     public function getTireReadableSize(bool $isFront true): string
  263.     {
  264.         $methodSuffix $isFront '' 'Rear';
  265.         return str_replace(
  266.             ['{sectionWidth}''{aspectRatio}''{rimDiameter}'],
  267.             [
  268.                 $this->{'getSectionWidth' $methodSuffix}(),
  269.                 $this->{'getAspectRatio' $methodSuffix}(),
  270.                 $this->{'getRimDiameter' $methodSuffix}(),
  271.             ],
  272.             static::TIRE_SIZE_PATTERN_STRING
  273.         );
  274.     }
  275.     public function getVehicleFrontAttributeValueSchema()
  276.     {
  277.         return [
  278.             static::SCHEMA_FRONT_NAME =>
  279.                 [
  280.                     static::SCHEMA_WHEEL_NAME => $this->getWheelReadableSize(),
  281.                     static::SCHEMA_TIRE_NAME  => $this->getTireReadableSize(),
  282.                 ],
  283.         ];
  284.     }
  285.     public function getVehicleRearAttributeValueSchema()
  286.     {
  287.         return [
  288.             static::SCHEMA_REAR_NAME =>
  289.                 [
  290.                     static::SCHEMA_WHEEL_NAME => $this->getWheelReadableSize(false),
  291.                     static::SCHEMA_TIRE_NAME  => $this->getTireReadableSize(false),
  292.                 ],
  293.         ];
  294.     }
  295.     public static function getVisibleFitmentTypes(): array
  296.     {
  297.         return [
  298.             static::FITMENT_TYPE_ORIGINAL,
  299.             static::FITMENT_TYPE_OPTIONAL,
  300.             static::FITMENT_TYPE_PLUS_SIZE
  301.         ];
  302.     }
  303.     public static function getFitmentTypeLabels(): array
  304.     {
  305.         return [
  306.             static::FITMENT_TYPE_ORIGINAL  => static::t('[wts] Fitment type Original'),
  307.             static::FITMENT_TYPE_OPTIONAL  => static::t('[wts] Fitment type Optional'),
  308.             static::FITMENT_TYPE_PLUS_SIZE => static::t('[wts] Fitment type Plus Sizes'),
  309.         ];
  310.     }
  311.     public static function getFitmentTypeLabel(string $type): string
  312.     {
  313.         $result '';
  314.         $labels VehicleAttributeValue::getFitmentTypeLabels();
  315.         if (
  316.             $type
  317.             && $labels
  318.             && isset($labels[$type])
  319.         ) {
  320.             $result $labels[$type];
  321.         }
  322.         return $result;
  323.     }
  324.     public static function getMapProductVehicleAttributes(): array
  325.     {
  326.         return [
  327.             WheelTireProductAttributeFields::WHEEL_RIM_SIZE_DIAMETER => 'rimDiameter',
  328.             WheelTireProductAttributeFields::WHEEL_RIM_SIZE_WIDTH    => 'rimWidth',
  329.             WheelTireProductAttributeFields::TIRE_SIZE_SECTION_WIDTH => 'sectionWidth',
  330.             WheelTireProductAttributeFields::TIRE_SIZE_ASPECT_RATIO  => 'aspectRatio',
  331.             WheelTireProductAttributeFields::TIRE_SIZE_RIM_DIAMETER  => 'rimDiameter',
  332.         ];
  333.     }
  334.     public function getProductAttributeFilterValues(array $filterFields = [], string $suffix ''): array
  335.     {
  336.         $resultFront parent::getProductAttributeFilterValues($filterFields);
  337.         $resultRear  parent::getProductAttributeFilterValues($filterFields'Rear');
  338.         $fields = static::getMapProductVehicleAttributes();
  339.         foreach ($fields as $productAttributeName => $modelFieldName) {
  340.             if (
  341.                 isset($resultFront[$productAttributeName])
  342.                 && $resultFront[$productAttributeName] != $resultRear[$productAttributeName]
  343.             ) {
  344.                 $resultFront[$productAttributeName] = [
  345.                     $resultFront[$productAttributeName],
  346.                     $resultRear[$productAttributeName],
  347.                 ];
  348.             }
  349.         }
  350.         return $resultFront;
  351.     }
  352.     public function isMatchingAnyFitment(array $values): array
  353.     {
  354.         $wheelRes $this->isMatchingAsWheelFitment($values);
  355.         $tireRes $this->isMatchingAsTireFitment($values);
  356.         return [
  357.             $wheelRes[0] + $tireRes[0],
  358.             $wheelRes[1] || $tireRes[1]
  359.         ];
  360.     }
  361.     public function isMatchingAsWheelFitment(array $values): array
  362.     {
  363.         $wheelValues array_merge(
  364.             $this->getProductAttributeFilterValues(
  365.                 WheelTireProductAttributeFields::getWheelSizeFields()
  366.             ),
  367.             $this->getProductAttributeFilterValues(
  368.                 WheelTireProductAttributeFields::getWheelSizeFields(),
  369.                 'Rear'
  370.             )
  371.         );
  372.         return $this->isMatchingVehicleValuesWithFilterValues(
  373.             $wheelValues,
  374.             $values
  375.         );
  376.     }
  377.     public function isMatchingAsTireFitment(array $values): array
  378.     {
  379.         $tireValues $this->getProductAttributeFilterValues(
  380.             WheelTireProductAttributeFields::getTireSizeFields()
  381.         );
  382.         return $this->isMatchingVehicleValuesWithFilterValues(
  383.             $tireValues,
  384.             $values
  385.         );
  386.     }
  387.     protected function isMatchingVehicleValuesWithFilterValues(array $vehicleValues, array $filterValues): array
  388.     {
  389.         $score 0;
  390.         $attrsMatching = [];
  391.         foreach ($vehicleValues as $name => $vehicleValue) {
  392.             $vehicleValue self::prepareValue($vehicleValue);
  393.             $filterValue  self::prepareValue($filterValues[$name] ?? null);
  394.             $intersect array_intersect($filterValue$vehicleValue);
  395.             $score += count($intersect);
  396.             $attrsMatching[$name] = count($intersect) === count($vehicleValue) && count($intersect) === count($filterValue);
  397.         }
  398.         return [
  399.             $score,
  400.             count(array_filter($attrsMatching)) === count($vehicleValues)
  401.         ];
  402.     }
  403.     protected static function prepareValue($value): array
  404.     {
  405.         if (!is_array($value)) {
  406.             $value = [$value];
  407.         }
  408.         return $value;
  409.     }
  410. }