/**
* Extract AbstractEntity data to array using specified list of attributes.
* If no attributes are specified, only simple and Many2One attributes will be extracted.
* If you need to get One2Many and Many2Many attributes, you need to explicitly specify a list of attributes.
*
* @param array $attributes Ex: 'title,author.name,comments.id,comments.text'
*
* @return array
*/
public function extractData($attributes = [])
{
if ($this->isEmpty($attributes)) {
$attributes = $this->getDefaultAttributes();
}
$data = [];
$attributes = $this->buildEntityFields($attributes);
foreach ($attributes as $attr => $subAttributes) {
$parts = explode(':', $attr);
$attrName = $parts[0];
$params = array_slice($parts, 1);
try {
$entityAttribute = $this->entity->getAttribute($attrName);
} catch (EntityException $e) {
continue;
}
$entityAttributeValue = $entityAttribute->getValue($params);
$isOne2Many = $this->isInstanceOf($entityAttribute, AttributeType::ONE2MANY);
$isMany2Many = $this->isInstanceOf($entityAttribute, AttributeType::MANY2MANY);
$isMany2One = $this->isInstanceOf($entityAttribute, AttributeType::MANY2ONE);
$isArray = $this->isInstanceOf($entityAttribute, AttributeType::ARR);
$isObject = $this->isInstanceOf($entityAttribute, AttributeType::OBJECT);
$isDynamic = $this->isInstanceOf($entityAttribute, AttributeType::DYNAMIC);
if ($isMany2One) {
if ($this->isNull($entityAttributeValue)) {
$data[$attrName] = null;
continue;
}
if ($entityAttribute->hasToArrayCallback()) {
$data[$attrName] = $entityAttribute->toArray($params);
continue;
}
if (self::$currentLevel < $this->nestedLevel) {
self::$currentLevel++;
$data[$attrName] = $entityAttributeValue->toArray($subAttributes, $this->nestedLevel);
self::$currentLevel--;
}
} elseif ($isOne2Many || $isMany2Many) {
$data[$attrName] = [];
foreach ($entityAttributeValue as $item) {
if (self::$currentLevel < $this->nestedLevel) {
self::$currentLevel++;
$data[$attrName][] = $item->toArray($subAttributes, $this->nestedLevel);
self::$currentLevel--;
}
}
} elseif ($isObject) {
$value = $entityAttribute->toArray($params);
if ($subAttributes) {
$keys = $this->buildNestedKeys($subAttributes);
$value = $this->arr();
foreach ($keys as $key) {
$value->keyNested($key, $entityAttribute->getValue()->keyNested($key));
}
$value = $value->val();
}
$data[$attrName] = $value;
} elseif ($isArray) {
$value = $entityAttribute->toArray();
if ($subAttributes) {
$subValues = [];
foreach ($value as $array) {
$subValues[] = $this->getSubAttributesFromArray($subAttributes, $array);
}
$value = $subValues;
$value['__webiny_array__'] = true;
}
$data[$attrName] = $value;
} elseif ($isDynamic) {
$data[$attrName] = $entityAttribute->toArray($subAttributes, $params);
} else {
$data[$attrName] = $entityAttribute->toArray($params);
}
}
// Populate alias value
$copy = $data;
$data = $this->arr($data);
// If aliases were used, recreate the entire array to remove junk keys of aliased attributes
if (count($this->aliases)) {
$cleanData = $this->arr();
foreach ($this->dottedFields as $key) {
if (array_key_exists($key, $this->aliases)) {
$cleanData->keyNested($this->aliases[$key], $data->keyNested($key), true);
continue;
}
$cleanData->keyNested($key, $data->keyNested($key), true);
}
$data = $cleanData;
}
// Copy ArrayAttribute value from backup
foreach ($copy as $key => $value) {
if (is_array($value) && array_key_exists('__webiny_array__', $value)) {
unset($value['__webiny_array__']);
$data[$key] = $value;
}
}
return $data->val();
}