@param       $object
@param array $dataObject
@param array $mapping

@return mixed
977255
protected function doMerge($object, array $dataObject, array $mapping = [])
    {
        if (count($mapping)) {
            foreach ($mapping as $field => $params) {
                if (is_string($params)) {
                    // Tries to decode if params is a string, so we can have a mapping information stringified in JSON
                    $params = json_decode($params, true);
                }
                if (!is_array($params)) {
                    // Allows anything to be transformed into an array
                    // If we used json_decode, "null" will be returned and then it'll become an empty array
                    // Although $params should be either "1", "true" or an array, even empty
                    $params = [];
                }
                if (array_key_exists($field, $dataObject)) {
                    $this->mergeField($field, $object, $dataObject[$field], $params);
                } else {
                    throw new \InvalidArgumentException(
                        sprintf(
                            'If you want to specify "%s" as an mergeable field, then you must have to set it in your data object.',
                            $field
                        )
                    );
                }
            }
        } else {
            foreach ($dataObject as $field => $value) {
                $this->mergeField($field, $object, $value);
            }
        }

        return $object;
    }
594332
private function unserializeObject($object, &$data, string $className = null) : array
    {
        $reflectionClass = new \ReflectionClass($className ? $className : $object);
        unset($data['@type']);

        // parent class
        $parent = $reflectionClass->getParentClass();
        if ($parent) {
            $this->unserializeObject($object, $data, $parent->getName());
        }

        foreach ($reflectionClass->getProperties() as $property) {
            $name = $property->getName();

            if (array_key_exists($name, $data)) {
                $currentValue = $data[$name];

                if (isset($data[$name]['@ref'])) {
                    $currentValue = $this->references[$data[$name]['@ref']];
                } elseif (isset($data[$name]['@type'])) {
                    $reflection = new \ReflectionClass($data[$name]['@type']);

                    $parent = $reflection;
                    $internal = false;

                    while ($parent !== false) {
                        $internal = $parent->isInternal() ? true : $internal;
                        $parent = $parent->getParentClass();
                    }

                    if ($internal) {
                        $currentData = $data[$name];
                        $currentType = $data[$name]['@type'];
                        unset($currentData['@type']);

                        $serialize = preg_replace(
                            '`^a:`',
                            'O:' . strlen($currentType) . ':"' . $currentType . '":',
                            serialize($currentData)
                        );
                        $currentValue = unserialize($serialize);
                    } else {
                        $currentValue = $reflection->newInstanceWithoutConstructor();
                        $this->unserializeObject($currentValue, $data[$name]);
                    }
                } elseif (is_array($currentValue)) {
                    $currentValue = [];
                    foreach ($data[$name] as $key => $value) {
                        if (isset($value['@type'])) {
                            $reflection = new \ReflectionClass($value['@type']);
                            $currentValue[$key] = $reflection->newInstanceWithoutConstructor();
                            $this->unserializeObject($currentValue[$key], $value);
                        } else {
                            $currentValue[$key] = $value;
                        }
                    }
                }

                $property->setAccessible(true);
                $property->setValue($object, $currentValue);

                unset($data[$name]);
            }
        }

        return $data;
    }
879337
protected function normalizeAsArray($objects) : array
    {
        $key = $this->relation;

        if (!is_array($objects) && !$objects instanceof Collection) {
            throw new MappingException("column '$key' should be of type array or collection");
        }

        if ($objects instanceof Collection) {
            $objects = $objects->all();
        }

        $normalizedObjects = [];

        foreach ($objects as $object) {
            $wrapper = $this->factory->make($object);
            $normalizedObjects[] = $wrapper->getEntityAttributes();
        }

        if ($this->asJson) {
            $normalizedObjects = json_encode($normalizedObjects);
        }

        return [$key => $normalizedObjects];
    }
280994
public function validateData(\Magento\Framework\DataObject $dataObject)
    {
        $result = [];
        $fromDate = $toDate = null;

        if ($dataObject->hasFromDate() && $dataObject->hasToDate()) {
            $fromDate = $dataObject->getFromDate();
            $toDate = $dataObject->getToDate();
        }

        if ($fromDate && $toDate) {
            $fromDate = $this->dateFilter->filter($fromDate);
            $toDate = $this->dateFilter->filter($toDate);

            if ($fromDate > $toDate) {
                $result[] = __('End Date must follow Start Date.');
            }
        }

        return !empty($result) ? $result : true;
    }
554411
public function hydrate(array $data, $object)
    {
        if (!is_object($object)) {
            throw new RuntimeException(
                sprintf('%s expects the provided $object to be a PHP object', __METHOD__)
            );
        }

        return (function (array $data) {
            foreach ($data as $property => $value) {
                if (!property_exists($this, $property)) {
                    throw new RuntimeException(
                        sprintf(
                            'Property "%s" does not exist in "%s" class.',
                            $property,
                            get_class($this)
                        )
                    );
                }

                $this->{$property} = $value;
            }

            return $this;
        })->call($object, $data);
    }
861308
public static function create($mapping): Mapping
    {
        if (\is_array($mapping)) {
            $mappingObject = new self();
            $mappingObject->setProperties($mapping);

            return $mappingObject;
        }

        if ($mapping instanceof self) {
            return $mapping;
        }

        throw new InvalidException('Invalid object type');
    }
1107303
public function isRelation(DataObject $object, $name)
    {
        return (
            $this->isHasOneRelation($object, $name) ||
            $this->isHasManyRelation($object, $name) ||
            $this->isManyManyRelation($object, $name)
        );
    }
781974
protected function populate(AbstractResponse $object, array $data)
    {
        $reflect = new ReflectionClass($object);

        $properties = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);

        foreach ($properties as $property) {
            if (array_key_exists($property->name, $data)) {
                $object->{$property->name} = $this->getValueByAnnotatedType($property, $data[$property->name]);
            }
        }

        return $object;
    }
111122
private static function doDump(&$data, $object)
    {
        if (is_object($object) && static::$objectStorage->contains($object)) {
            $data = null;

            return;
        }

        if (is_object($object)) {
            static::$objectStorage->attach($object);
        }

        if (is_array($object) || $object instanceof \Traversable) {
            foreach ($object as $key => $value) {
                static::doDump($data[$key], $value);
            }
        } elseif (is_object($object)) {
            $ref = new \ReflectionObject($object);

            $properties = $ref->getProperties();

            foreach ($properties as $property) {
                $property->setAccessible(true);

                $value = $property->getValue($object);

                static::doDump($data[$property->getName()], $value);
            }
        } else {
            $data = $object;
        }
    }
398388
public function mutateClass(DataObject $object, $identifier, $data)
    {
        $class = $this->getClass();
        
        if ($object->ClassName != $class) {
            
            // Show Notice Message:
            
            $this->noticeMessage(
                sprintf(
                    'Mutating %s (%s to %s)',
                    $identifier,
                    get_class($object),
                    $class
                )
            );
            
            // Mutate Object:
            
            $object = $object->newClassInstance($class);
            
            // Write Object to Database:
            
            $object->write();
            $object->flushCache();
            
        }
        
        return $object;
    }
470005
private static function mapCollection($resource, $object)
    {
        if ($object == false || is_string($object)) {
            return $object;
        }

        $baseResource = __NAMESPACE__ . '\\' . $resource;
        self::$resource = (class_exists($baseResource)) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource;

        return array_map(array('self', 'mapCollectionObject'), $object);
    }
158051
public function hydrate( array $data, $object )
    {
        if ( $object instanceof MapperAwareInterface )
        {
            $object->setMapper( $this );
        }

        if ( $object instanceof Structure )
        {
            if ( ! empty( $data['cssFile'] ) && is_file( $data['cssFile'] ) )
            {
                $object->parseFile( $data['cssFile'] );
            }
            else if ( ! empty( $data['css'] ) )
            {
                $object->parseString( $data['css'] );
            }
        }
        else
        {
            if ( ! empty( $data['cssFile'] ) && is_file( $data['cssFile'] ) )
            {
                $object->css = file_get_contents( $data['cssFile'] );
            }
            else if ( ! empty( $data['css'] ) )
            {
                $object->css = (string) $data['css'];
            }
        }

        if ( array_key_exists( 'rootId', $data ) )
        {
            $object->rootId = $data['rootId'];
        }

        return $object;
    }
263305
public static function PrepareUserObject($data_sent, $object) {
        foreach ($data_sent as $key => $value) {
            $method = "set" . ucfirst($key);
            $object->$method(!array_key_exists($key, $data_sent) ? null : $value);
        }
        return $object;
    }
241538
public function addObject(DataObject $object)
    {
        if (!$this->isInDB()) {
            throw new BadMethodCallException("ChangeSet must be saved before adding items");
        }

        if (!$object->isInDB()) {
            throw new BadMethodCallException("Items must be saved before adding to a changeset");
        }

        $references = [
            'ObjectID' => $object->ID,
            'ObjectClass' => $object->baseClass(),
        ];

        // Get existing item in case already added
        $item = $this->Changes()->filter($references)->first();

        if (!$item) {
            $item = new ChangeSetItem($references);
            $this->Changes()->add($item);
        }

        $item->ReferencedBy()->removeAll();

        $item->Added = ChangeSetItem::EXPLICITLY;
        $item->write();

        $this->sync();
    }
756056
public function getFieldsByDatatype($objectName, $datatype)
    {
        $datatypeFieldConfigurations = array();

        $fieldConfigurations = $this->getFields($objectName);
        foreach ($fieldConfigurations as $fieldConfiguration) {
            if ($fieldConfiguration['datatype'] == $datatype) {
                $datatypeFieldConfigurations[] = $fieldConfiguration;
            }
        }

        return $datatypeFieldConfigurations;
    }
154613
private function getCachedDataByObject($object)
    {
        return $this->getCachedDataByReference(
            $this->mm->getMetadataForObject($object)->getReferenceForObject($object)
        );
    }
554565
protected function formatDataObject(DataObject $dataObject)
    {
        // api access control
        if (!RESTfulAPI::api_access_control($dataObject, 'GET')) {
            return null;
        }

        if (method_exists($dataObject, 'onBeforeSerialize')) {
            $dataObject->onBeforeSerialize();
        }
        $dataObject->extend('onBeforeSerialize');

        // setup
        $formattedDataObjectMap = array();

        // get DataObject config
        $class = get_class($dataObject);
        $db = Config::inst()->get($class, 'db');
        $has_one = Config::inst()->get($class, 'has_one');
        $has_many = Config::inst()->get($class, 'has_many');
        $many_many = Config::inst()->get($class, 'many_many');
        $belongs_many_many = Config::inst()->get($class, 'belongs_many_many');

        // Get a possibly defined list of "api_fields" for this DataObject. If defined, they will be the only fields
        // for this DataObject that will be returned, including related models.
        $apiFields = (array) Config::inst()->get($class, 'api_fields');

        //$many_many_extraFields = $dataObject->many_many_extraFields();
        $many_many_extraFields = $dataObject->stat('many_many_extraFields');

        // setup ID (not included in $db!!)
        $serializedColumnName = $this->serializeColumnName('ID');
        $formattedDataObjectMap[$serializedColumnName] = $dataObject->getField('ID');

        // iterate over simple DB fields
        if (!$db) {
            $db = array();
        }

        foreach ($db as $columnName => $fieldClassName) {
            // Check whether this field has been specified as allowed via api_fields
            if (!empty($apiFields) && !in_array($columnName, $apiFields)) {
                continue;
            }

            $serializedColumnName = $this->serializeColumnName($columnName);
            $formattedDataObjectMap[$serializedColumnName] = $dataObject->getField($columnName);
        }

        // iterate over has_one relations
        if (!$has_one) {
            $has_one = array();
        }
        foreach ($has_one as $columnName => $fieldClassName) {
            // Skip if api_fields is set for the parent, and this column is not in it
            if (!empty($apiFields) && !in_array($columnName, $apiFields)) {
                continue;
            }

            $serializedColumnName = $this->serializeColumnName($columnName);

            // convert foreign ID to integer
            $relationID = intVal($dataObject->{$columnName . 'ID'});
            // skip empty relations
            if ($relationID === 0) {
                continue;
            }

            // check if this should be embedded
            if ($this->isEmbeddable($dataObject->ClassName, $columnName)) {
                // get the relation's record ready to embed
                $embedData = $this->getEmbedData($dataObject, $columnName);
                // embed the data if any
                if ($embedData !== null) {
                    $formattedDataObjectMap[$serializedColumnName] = $embedData;
                }
            } else {
                // save foreign ID
                $formattedDataObjectMap[$serializedColumnName] = $relationID;
            }
        }

        // combine defined '_many' relations into 1 array
        $many_relations = array();
        if (is_array($has_many)) {
            $many_relations = array_merge($many_relations, $has_many);
        }
        if (is_array($many_many)) {
            $many_relations = array_merge($many_relations, $many_many);
        }
        if (is_array($belongs_many_many)) {
            $many_relations = array_merge($many_relations, $belongs_many_many);
        }

        // iterate '_many' relations
        foreach ($many_relations as $relationName => $relationClassname) {
            // Skip if api_fields is set for the parent, and this column is not in it
            if (!empty($apiFields) && !in_array($relationName, $apiFields)) {
                continue;
            }

            //get the DataList for this realtion's name
            $dataList = $dataObject->{$relationName}();

            //if there actually are objects in the relation
            if ($dataList->count()) {
                // check if this relation should be embedded
                if ($this->isEmbeddable($dataObject->ClassName, $relationName)) {
                    // get the relation's record(s) ready to embed
                    $embedData = $this->getEmbedData($dataObject, $relationName);
                    // embed the data if any
                    if ($embedData !== null) {
                        $serializedColumnName = $this->serializeColumnName($relationName);
                        $formattedDataObjectMap[$serializedColumnName] = $embedData;
                    }
                } else {
                    // set column value to ID list
                    $idList = $dataList->map('ID', 'ID')->keys();

                    $serializedColumnName = $this->serializeColumnName($relationName);
                    $formattedDataObjectMap[$serializedColumnName] = $idList;
                }
            }
        }

        if ($many_many_extraFields) {
            $extraFieldsData = array();

            // loop through extra fields config
            foreach ($many_many_extraFields as $relation => $fields) {
                $manyManyDataObjects = $dataObject->$relation();
                $relationData = array();

                // get the extra data for each object in the relation
                foreach ($manyManyDataObjects as $manyManyDataObject) {
                    $data = $manyManyDataObjects->getExtraData($relation, $manyManyDataObject->ID);

                    // format data
                    foreach ($data as $key => $value) {
                        // clear empty data
                        if (!$value) {
                            unset($data[$key]);
                            continue;
                        }

                        $newKey = $this->serializeColumnName($key);
                        if ($newKey != $key) {
                            unset($data[$key]);
                            $data[$newKey] = $value;
                        }
                    }

                    // store if there is any real data
                    if ($data) {
                        $relationData[$manyManyDataObject->ID] = $data;
                    }
                }

                // add individual DO extra data to the relation's extra data
                if ($relationData) {
                    $key = $this->serializeColumnName($relation);
                    $extraFieldsData[$key] = $relationData;
                }
            }

            // save the extrafields data
            if ($extraFieldsData) {
                $key = $this->serializeColumnName('ManyManyExtraFields');
                $formattedDataObjectMap[$key] = $extraFieldsData;
            }
        }

        if (method_exists($dataObject, 'onAfterSerialize')) {
            $dataObject->onAfterSerialize($formattedDataObjectMap);
        }
        $dataObject->extend('onAfterSerialize', $formattedDataObjectMap);

        return $formattedDataObjectMap;
    }