Your IP : 18.224.66.85
<?php
/**
* Created by PhpStorm.
* User: Alexey
* Date: 09.01.2015
* Time: 17:39
*/
namespace Bitrix\Sale;
use Bitrix\Main;
use Bitrix\Sale\Internals\Input,
Bitrix\Sale\Internals\OrderPropsGroupTable,
Bitrix\Main\ArgumentOutOfRangeException,
Bitrix\Main\Entity,
Bitrix\Main\Localization\Loc;
Loc::loadMessages(__FILE__);
class PropertyValueCollection
extends Internals\EntityCollection
{
/** @var Order */
protected $order;
private $attributes = array(
'IS_EMAIL' => null,
'IS_PAYER' => null,
'IS_LOCATION' => null,
'IS_LOCATION4TAX' => null,
'IS_PROFILE_NAME' => null,
'IS_ZIP' => null,
'IS_PHONE' => null,
'IS_ADDRESS' => null,
);
private $propertyGroupMap = array();
private $propertyGroups = array();
private static $eventClassName = null;
/**
* @return Order
*/
protected function getEntityParent()
{
return $this->getOrder();
}
public function createItem(array $prop)
{
$property = PropertyValue::create($this, $prop);
$this->addItem($property);
return $property;
}
public function addItem(Internals\CollectableEntity $property)
{
/** @var PropertyValue $property */
$property = parent::addItem($property);
$order = $this->getOrder();
return $order->onPropertyValueCollectionModify(EventActions::ADD, $property);
}
/**
* @internal
*
* @param $index
* @return bool
*/
public function deleteItem($index)
{
$oldItem = parent::deleteItem($index);
/** @var Order $order */
$order = $this->getOrder();
return $order->onPropertyValueCollectionModify(EventActions::DELETE, $oldItem);
}
/**
* @param Internals\CollectableEntity $item
* @param null $name
* @param null $oldValue
* @param null $value
*
* @return bool
*/
public function onItemModify(Internals\CollectableEntity $item, $name = null, $oldValue = null, $value = null)
{
$this->setAttributes($item);
/** @var Order $order */
$order = $this->getOrder();
return $order->onPropertyValueCollectionModify(EventActions::UPDATE, $item, $name, $oldValue, $value);
}
public function onOrderModify($name, $oldValue, $value)
{
return new Result();
}
public function getOrder()
{
return $this->order;
}
/**
* @param OrderBase $order
*/
public function setOrder(OrderBase $order)
{
$this->order = $order;
}
/**
* @return PropertyValueCollection
*/
protected static function createPropertyValueCollectionObject()
{
$registry = Registry::getInstance(Registry::REGISTRY_TYPE_ORDER);
$propertyValueCollectionClassName = $registry->getPropertyValueCollectionClassName();
return new $propertyValueCollectionClassName();
}
public static function load(OrderBase $order)
{
/** @var PropertyValueCollection $propertyCollection */
$propertyCollection = static::createPropertyValueCollectionObject();
$propertyCollection->setOrder($order);
static $groups = array();
$personTypeId = $order->getPersonTypeId();
if (empty($groups[$personTypeId]))
{
$groupRes = OrderPropsGroupTable::getList(array(
'select' => array('ID', 'NAME', 'PERSON_TYPE_ID'),
'filter' => array('PERSON_TYPE_ID' => $order->getPersonTypeId()),
'order' => array('SORT' => 'ASC'),
));
while ($row = $groupRes->fetch())
{
$groups[$personTypeId][$row['ID']] = $row;
}
}
$props = PropertyValue::loadForOrder($order);
/** @var PropertyValue $prop */
foreach ($props as $prop)
{
$prop->setCollection($propertyCollection);
$propertyCollection->addItem($prop);
$propertyCollection->setAttributes($prop);
$propertyCollection->propertyGroupMap[$prop->getGroupId() > 0 && isset($groups[$personTypeId][$prop->getGroupId()])? $prop->getGroupId() : 0][] = $prop;
}
return $propertyCollection;
}
/**
* @return Entity\Result
* @throws Main\ArgumentException
* @throws Main\ObjectNotFoundException
* @throws \Exception
*/
public function save()
{
$result = new Entity\Result();
/** @var Order $order */
if (!$order = $this->getOrder())
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$itemsFromDb = array();
if ($order->getId() > 0)
{
$itemsFromDbList = Internals\OrderPropsValueTable::getList(
array(
"filter" => array("ORDER_ID" => $this->getOrder()->getId()),
"select" => array("ID", "NAME", "CODE", "VALUE")
)
);
while ($itemsFromDbItem = $itemsFromDbList->fetch())
$itemsFromDb[$itemsFromDbItem["ID"]] = $itemsFromDbItem;
}
$isChanged = false;
/** @var PropertyValue $property */
foreach ($this->collection as $property)
{
$isNew = (bool)($property->getId() <= 0);
if (!$isChanged && $property->isChanged())
{
$isChanged = true;
}
if ($order->getId() > 0 && $isChanged)
{
$logFields = array(
"NAME" => $property->getField("NAME"),
"VALUE" => $property->getField("VALUE"),
"CODE" => $property->getField("CODE"),
);
if (!$isNew)
{
$fields = $property->getFields();
$originalValues = $fields->getOriginalValues();
if (array_key_exists("NAME", $originalValues))
$logFields['OLD_NAME'] = $originalValues["NAME"];
if (array_key_exists("VALUE", $originalValues))
$logFields['OLD_VALUE'] = $originalValues["VALUE"];
if (array_key_exists("CODE", $originalValues))
$logFields['OLD_CODE'] = $originalValues["CODE"];
}
}
$r = $property->save();
if ($r->isSuccess())
{
if ($order->getId() > 0)
{
if ($isChanged)
{
OrderHistory::addLog('PROPERTY', $order->getId(), $isNew ? 'PROPERTY_ADD' : 'PROPERTY_UPDATE', $property->getId(), $property,
$logFields, OrderHistory::SALE_ORDER_HISTORY_LOG_LEVEL_1);
}
}
}
else
{
$result->addErrors($r->getErrors());
}
if (isset($itemsFromDb[$property->getId()]))
unset($itemsFromDb[$property->getId()]);
}
if ($result->isSuccess() && $order->getId() > 0 && $isChanged)
{
OrderHistory::addAction(
'PROPERTY',
$order->getId(),
"PROPERTY_SAVED",
null,
null,
array(),
OrderHistory::SALE_ORDER_HISTORY_ACTION_LOG_LEVEL_1
);
}
if (self::$eventClassName === null)
{
$registry = Registry::getInstance(Registry::REGISTRY_TYPE_ORDER);
$propertyClassName = $registry->get(Registry::ENTITY_PROPERTY_VALUE);
self::$eventClassName = $propertyClassName::getEntityEventName();
}
foreach ($itemsFromDb as $k => $v)
{
/** @var Main\Event $event */
$event = new Main\Event('sale', "OnBefore".self::$eventClassName."Deleted", array(
'VALUES' => $v,
));
$event->send();
Internals\OrderPropsValueTable::delete($k);
/** @var Main\Event $event */
$event = new Main\Event('sale', "On".self::$eventClassName."Deleted", array(
'VALUES' => $v,
));
$event->send();
if ($order->getId() > 0)
{
OrderHistory::addAction('PROPERTY', $order->getId(), 'PROPERTY_REMOVE', $k, null, array(
"NAME" => $v['NAME'],
"CODE" => $v['CODE'],
"VALUE" => $v['VALUE'],
));
}
}
if ($order->getId() > 0)
{
OrderHistory::collectEntityFields('PROPERTY', $order->getId());
}
return $result;
}
static function initJs()
{
Input\Manager::initJs();
\CJSCore::RegisterExt('SaleOrderProperties', array(
'js' => '/bitrix/js/sale/orderproperties.js',
'lang' => '/bitrix/modules/sale/lang/'.LANGUAGE_ID.'/lib/propertyvaluecollection.php',
'rel' => array('input'),
));
\CJSCore::Init(array('SaleOrderProperties'));
}
protected function __construct()
{
}
private function setAttributes(PropertyValue $propValue)
{
$prop = $propValue->getProperty();
foreach ($this->attributes as $k => &$v)
{
if ($prop[$k] == 'Y')
$v = $propValue;
}
}
/**
* @param $name
* @return PropertyValue
* @throws ArgumentOutOfRangeException
*/
public function getAttribute($name)
{
if (!array_key_exists($name, $this->attributes))
throw new ArgumentOutOfRangeException("name");
if ($this->attributes[$name] !== null)
return $this->attributes[$name];
return null;
}
function getUserEmail()
{
return $this->getAttribute('IS_EMAIL');
}
function getPayerName()
{
return $this->getAttribute('IS_PAYER');
}
function getDeliveryLocation()
{
return $this->getAttribute('IS_LOCATION');
}
function getTaxLocation()
{
return $this->getAttribute('IS_LOCATION4TAX');
}
function getProfileName()
{
return $this->getAttribute('IS_PROFILE_NAME');
}
function getDeliveryLocationZip()
{
return $this->getAttribute('IS_ZIP');
}
function getPhone()
{
return $this->getAttribute('IS_PHONE');
}
function getAddress()
{
return $this->getAttribute('IS_ADDRESS');
}
function setValuesFromPost($post, $files)
{
$post = Input\File::getPostWithFiles($post, $files);
$result = new Result();
/** @var PropertyValue $property */
foreach ($this->collection as $property)
{
$r = $property->setValueFromPost($post);
if (!$r->isSuccess())
$result->addErrors($r->getErrors());
}
return $result;
}
/**
* @param $fields
* @param $files
* @param $skipUtils
*
* @return Result
*/
public function checkErrors($fields, $files, $skipUtils = false)
{
$fields = Input\File::getPostWithFiles($fields, $files);
$result = new Result();
/** @var PropertyValue $property */
foreach ($this->collection as $property)
{
if ($skipUtils && $property->isUtil())
continue;
$propertyData = $property->getProperty();
$key = isset($propertyData["ID"]) ? $propertyData["ID"] : "n".$property->getId();
$value = isset($fields['PROPERTIES'][$key]) ? $fields['PROPERTIES'][$key] : null;
if (!isset($fields['PROPERTIES'][$key]))
{
$value = $property->getValue();
}
$r = $property->checkValue($key, $value);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
}
return $result;
}
/**
* @param array $rules
* @param array $fields
*
* @return Result
*/
public function checkRequired(array $rules, array $fields)
{
$result = new Result();
/** @var PropertyValue $property */
foreach ($this->collection as $property)
{
$propertyData = $property->getProperty();
$key = isset($propertyData["ID"]) ? $propertyData["ID"] : "n".$property->getId();
if (!in_array($key, $rules))
{
continue;
}
$value = isset($fields['PROPERTIES'][$key]) ? $fields['PROPERTIES'][$key] : null;
if (!isset($fields['PROPERTIES'][$key]))
{
$value = $property->getValue();
}
$r = $property->checkRequiredValue($key, $value);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
}
return $result;
}
public function getGroups()
{
if (empty($this->propertyGroups) && !empty($this->propertyGroupMap))
{
$result = OrderPropsGroupTable::getList(array(
'select' => array('ID', 'NAME', 'PERSON_TYPE_ID', 'SORT'),
'filter' => array('=ID' => array_keys($this->propertyGroupMap)),
'order' => array('SORT' => 'ASC'),
));
while ($row = $result->fetch())
$this->propertyGroups[] = $row;
if ($unknown = $this->propertyGroupMap[0])
$this->propertyGroups[] = array('NAME' => Loc::getMessage('SOP_UNKNOWN_GROUP'), 'ID' => 0);
}
return $this->propertyGroups;
}
public function getGroupProperties($groupId)
{
return $this->propertyGroupMap[$groupId];
}
function getArray()
{
$groups = $this->getGroups();
$properties = array();
/** @var PropertyValue $property */
foreach ($this->collection as $k => $property)
{
$p = $property->getProperty();
if (!isset($p["ID"]))
$p["ID"] = "n".$property->getId();
$value = $property->getValue();
$value = $property->getValueId() ? $value : ($value ? $value : $p['DEFAULT_VALUE']);
$value = array_values(Input\Manager::asMultiple($p, $value));
$p['VALUE'] = $value;
$properties []= $p;
}
return array('groups' => $groups, 'properties' => $properties);
}
/**
* @param $orderPropertyId
* @return PropertyValue
*/
public function getItemByOrderPropertyId($orderPropertyId)
{
/** @var PropertyValue $property */
foreach ($this->collection as $k => $property)
{
if($property->getField('ORDER_PROPS_ID') == $orderPropertyId)
return $property;
}
}
/**
* @internal
* @param \SplObjectStorage $cloneEntity
*
* @return PropertyValueCollection
*/
public function createClone(\SplObjectStorage $cloneEntity)
{
if ($this->isClone() && $cloneEntity->contains($this))
{
return $cloneEntity[$this];
}
$propertyValueCollectionClone = clone $this;
$propertyValueCollectionClone->isClone = true;
if ($this->order)
{
if ($cloneEntity->contains($this->order))
{
$propertyValueCollectionClone->order = $cloneEntity[$this->order];
}
}
if (!$cloneEntity->contains($this))
{
$cloneEntity[$this] = $propertyValueCollectionClone;
}
/**
* @var int key
* @var PropertyValue $propertyValue
*/
foreach ($propertyValueCollectionClone->collection as $key => $propertyValue)
{
if (!$cloneEntity->contains($propertyValue))
{
$cloneEntity[$propertyValue] = $propertyValue->createClone($cloneEntity);
}
$propertyValueCollectionClone->collection[$key] = $cloneEntity[$propertyValue];
}
return $propertyValueCollectionClone;
}
/**
* @return Result
* @throws Main\ObjectNotFoundException
*/
public function verify()
{
$result = new Result();
/** @var Order $order */
if (!$order = $this->getOrder())
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
EntityMarker::deleteByFilter(
array(
"ORDER_ID" => $order->getId(),
"ENTITY_TYPE" => EntityMarker::ENTITY_TYPE_PROPERTY_VALUE
)
);
/** @var PropertyValue $propertyValue */
foreach ($this->collection as $propertyValue)
{
$r = $propertyValue->checkValue($propertyValue->getPropertyId(),$propertyValue->getValue());
if (!$r->isSuccess() && (int)$propertyValue->getId() > 0)
{
$result->addWarnings($r->getWarnings());
EntityMarker::addMarker($order, $propertyValue, $r);
$order->setField('MARKED', 'Y');
}
}
return $result;
}
}