<commit_before><?php
/**
 * @copyright 2014 Integ S.A.
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
 * @author <NAME> <<EMAIL>>
 */

namespace GoIntegro\Bundle\HateoasBundle\JsonApi\Serializer;

// Interfaces.
use GoIntegro\Bundle\HateoasBundle\JsonApi\ResourceEntityInterface,
    Doctrine\Common\Collections\Collection as CollectionInterface;
// Datos.
use GoIntegro\Bundle\HateoasBundle\Util\Inflector;
// Recursos.
use GoIntegro\Bundle\HateoasBundle\JsonApi\DocumentResource,
    GoIntegro\Bundle\HateoasBundle\JsonApi\EntityResource;
// Excepciones.
use Exception;

class ResourceObjectSerializer implements SerializerInterface
{
    const ERROR_FIELD_IS_RELATIONSHIP = "El campo \"%s\" es en sí un recurso vinculado.",
        ERROR_UNKOWN_FIELD = "El campo \"%s\" no existe.";

    public $resource;
    public $fields = [];

    public function __construct(
        DocumentResource $resource,
        array $sparseFields = []
    )
    {
        $this->resource = $resource;
        $this->fields = $sparseFields ?: $resource->getMetadata()->fields;
    }

    public function serialize()
    {
        $metadata = $this->resource->getMetadata();
        $json = [
            'id' => $this->resource->id,
            'type' => $metadata->type
        ];

        if ($this->resource->getMetadata()->type != $metadata->subtype) {
            $json['subtype'] = $metadata->subtype;
        }

        foreach ($this->fields as $field) {
            if ($metadata->isRelationship($field)) {
                $message = sprintf(self::ERROR_FIELD_IS_RELATIONSHIP, $field);
                throw new Exception($message);
            }

            if ($this->resource->isFieldBlacklisted($field)) {
                $message = sprintf(self::ERROR_UNKOWN_FIELD, $field);
                throw new Exception($message);
            }

            try {
                $value = $this->resource->callGetter($field);
            } catch (Exception $e) {
                $message = sprintf(self::ERROR_UNKOWN_FIELD, $field);
                throw new Exception($message);
            }

            if ('object' == gettype($value)) {
                $value = $this->serializeObjectFieldValue($value);
            }

            $json[$field] = $value;
        }

        if ($metadata->hasRelationships()) {
            $json['links']
                = $this->getResourceLinks($this->resource);
        }

        return $json;
    }

    /**
     * @param object $fieldValue
     */
    private function serializeObjectFieldValue($fieldValue)
    {
        $serializer = new ObjectFieldValueSerializer($fieldValue);

        return $serializer->serialize();
    }

    private function getResourceLinks(DocumentResource $resource)
    {
        $links = [];

        foreach (
            $this->resource->getMetadata()->relationships->toOne as $relationship => $relation
        ) {
            $entity = $this->resource->callGetter($relationship);
            EntityResource::validateToOneRelation($entity, $relationship);
            $links[$relationship] = EntityResource::getStringId($entity);
        }

        foreach (
            $this->resource->getMetadata()->relationships->toMany as $relationship => $relation
        ) {
            $collection = $this->resource->callGetter($relationship);
            $collection = EntityResource::normalizeToManyRelation(
                $collection, $relationship
            );
            $callback = function(ResourceEntityInterface $entity) {
                return EntityResource::getStringId($entity);
            };
            $links[$relationship] = $collection->map($callback)->toArray();
        }

        return $links;
    }
}<commit_msg>Adding some more array normalization.<commit_after><?php
/**
 * @copyright 2014 Integ S.A.
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
 * @author <NAME> <<EMAIL>>
 */

namespace GoIntegro\Bundle\HateoasBundle\JsonApi\Serializer;

// Interfaces.
use GoIntegro\Bundle\HateoasBundle\JsonApi\ResourceEntityInterface,
    Doctrine\Common\Collections\Collection as CollectionInterface;
// Datos.
use GoIntegro\Bundle\HateoasBundle\Util\Inflector;
// Recursos.
use GoIntegro\Bundle\HateoasBundle\JsonApi\DocumentResource,
    GoIntegro\Bundle\HateoasBundle\JsonApi\EntityResource;
// Excepciones.
use Exception;

class ResourceObjectSerializer implements SerializerInterface
{
    const ERROR_FIELD_IS_RELATIONSHIP = "El campo \"%s\" es en sí un recurso vinculado.",
        ERROR_UNKOWN_FIELD = "El campo \"%s\" no existe.";

    public $resource;
    public $fields = [];

    public function __construct(
        DocumentResource $resource,
        array $sparseFields = []
    )
    {
        $this->resource = $resource;
        $this->fields = $sparseFields ?: $resource->getMetadata()->fields;
    }

    public function serialize()
    {
        $metadata = $this->resource->getMetadata();
        $json = [
            'id' => $this->resource->id,
            'type' => $metadata->type
        ];

        if ($this->resource->getMetadata()->type != $metadata->subtype) {
            $json['subtype'] = $metadata->subtype;
        }

        foreach ($this->fields as $field) {
            if ($metadata->isRelationship($field)) {
                $message = sprintf(self::ERROR_FIELD_IS_RELATIONSHIP, $field);
                throw new Exception($message);
            }

            if ($this->resource->isFieldBlacklisted($field)) {
                $message = sprintf(self::ERROR_UNKOWN_FIELD, $field);
                throw new Exception($message);
            }

            try {
                $value = $this->resource->callGetter($field);
            } catch (Exception $e) {
                $message = sprintf(self::ERROR_UNKOWN_FIELD, $field);
                throw new Exception($message);
            }

            if ('object' == gettype($value)) {
                $value = $this->serializeObjectFieldValue($value);
            }

            $json[$field] = $value;
        }

        if ($metadata->hasRelationships()) {
            $json['links']
                = $this->getResourceLinks($this->resource);
        }

        return $json;
    }

    /**
     * @param object $fieldValue
     */
    private function serializeObjectFieldValue($fieldValue)
    {
        $serializer = new ObjectFieldValueSerializer($fieldValue);

        return $serializer->serialize();
    }

    private function getResourceLinks(DocumentResource $resource)
    {
        $links = [];

        foreach (
            $this->resource->getMetadata()->relationships->toOne as $relationship => $relation
        ) {
            $entity = $this->resource->callGetter($relationship);
            EntityResource::validateToOneRelation($entity, $relationship);
            $links[$relationship] = EntityResource::getStringId($entity);
        }

        foreach (
            $this->resource->getMetadata()->relationships->toMany as $relationship => $relation
        ) {
            $collection = $this->resource->callGetter($relationship);
            $collection = EntityResource::normalizeToManyRelation(
                $collection, $relationship
            );
            $callback = function(ResourceEntityInterface $entity) {
                return EntityResource::getStringId($entity);
            };
            $links[$relationship] = $collection->map($callback)->toArray();
            $links[$relationship] = array_values($links[$relationship]);
        }

        return $links;
    }
}
{'fraction_non_alphanumeric': 0.13263548429839672, 'fraction_numerical': 0.001060023850536637, 'mean_word_length': 2.286025250326513, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 95, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2227618', 'n_tokens_mistral': 2069, 'n_tokens_neox': 1983, 'n_words': 358}