public function copyAlterableProperties($object, AbstractEntity $entity, $scope = ScopeInterface::SCOPE_SCALR)
{
/* @var $entity GlobalVariable */
$rules = $this->getRules();
if (!isset($rules[static::RULE_TYPE_ALTERABLE])) {
//Nothing to copy
throw new Exception(sprintf("ApiEntityAdapter::RULE_TYPE_ALTERABLE offset of rules has not been defined for the %s class.", get_class($this)));
}
$notAlterable = array_diff(array_keys(get_object_vars($object)), $rules[static::RULE_TYPE_ALTERABLE]);
if (!empty($notAlterable)) {
if (count($notAlterable) > 1) {
$message = "You are trying to set properties %s that either are not alterable or do not exist";
} else {
$message = "You are trying to set the property %s which either is not alterable or does not exist";
}
throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, sprintf($message, implode(', ', $notAlterable)));
}
$allowOnlyValue = $this->scopesPriority[$entity->getScope()] < $this->scopesPriority[$scope];
if ($entity->final && $allowOnlyValue) {
throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, "You can't change final variable locked on {$entity->getScope()} level");
}
foreach ($rules[static::RULE_TYPE_ALTERABLE] as $key) {
if (!property_exists($object, $key)) {
continue;
}
//As the name of the property that goes into response may be different from the
//real property name in the Entity object it should be mapped at first
if (!empty($rules[static::RULE_TYPE_TO_DATA])) {
//if toData rule is null it means all properties are allowed
if (($property = array_search($key, $rules[static::RULE_TYPE_TO_DATA])) !== false) {
if (is_string($property)) {
//In this case the real name of the property is the key of the array
if ($property[0] === '_' && method_exists($this, $property)) {
//It is callable
continue;
}
} else {
$property = $key;
}
if ($allowOnlyValue && $property != 'value' && isset($object->{$key}) && $object->{$key} != $entity->{$property}) {
throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, sprintf("This variable was declared in the %s Scope, you can only modify its 'value' field in the Farm Role Scope", ucfirst($entity->getScope())));
}
}
}
}
}