public function save($identifier, array $propertyValues, $shardingKey = null)
    {
        if (false == is_array($identifier)) {
            $identifier = array();
        }

        //Check timestampable
        if (array_key_exists('timestampable', $this->configuration)) {
            if (!isset($propertyValues['createdAt'])) {
                $propertyValues['createdAt'] = new \DateTime();
            }
            $propertyValues['updatedAt'] = new \DateTime();
        }

        //First, create datas to save for each sources
        $datasBySource = array();
        foreach ($propertyValues as $propertyName => $value) {
            //Get sources for the current property
            $sources = $this->getSourcesFromPropertyName($propertyName);

            //Get field name of this property
            $field = $this->getFieldNameFromProperty($propertyName);

            //Foreach sources, if it can handle the field, save to it (should only appear once)
            $isFirstSource = true;
            foreach ($sources as $sourceName) {
                $source = $this->sourceManager->getSource($sourceName);
                if ($source->canHandle($field) && (false === is_null($value) || false === $source->isIdentifier($field) || false === $isFirstSource)) {
                    $datasBySource[$sourceName][$field] = $value;
                }
                $isFirstSource = false;
            }
        }

        //Now, map identifiers to fields
        $mappedIdentifiers = array();
        foreach ($identifier as $propertyName => $value) {
            //Get sources for the current identifier
            $sources = $this->getSourcesFromPropertyName($propertyName);

            //Get field name of this identifier
            $field = $this->getFieldNameFromProperty($propertyName);

            //Foreach sources, if it can handle the field, save to it (should only appear once)
            foreach ($sources as $sourceName) {
                $source = $this->sourceManager->getSource($sourceName);
                if ($source->canHandle($field)) {
                    $mappedIdentifiers[$sourceName][$field] = $value;
                }
            }
        }

        //order $datasBySource by reverse order of default sources
        $orderedDatasBySource = array();
        $sourceNames = $this->configuration['sources'];
        foreach ($sourceNames as $sourceName) {
            if (isset($datasBySource[$sourceName])) {
                $orderedDatasBySource[$sourceName] = $datasBySource[$sourceName];
            }
        }

        //loop on datas to save them to each sources
        $createdFieldValues = array();
        $mappedNewFields = array();
        foreach ($orderedDatasBySource as $sourceName => $datas) {
            $source = $this->sourceManager->getSource($sourceName);

            $newIdentifiers = array();
            foreach ($createdFieldValues as $field => $value) {
                if ($source->canHandle($field)) {
                    $newIdentifiers[$field] = $value;
                }
            }
            $justCreatedFieldValues = $source->save(array_merge($datas, $newIdentifiers), isset($mappedIdentifiers[$sourceName]) ? $mappedIdentifiers[$sourceName] : array(), $shardingKey);
            $createdFieldValues = array_merge($createdFieldValues, $justCreatedFieldValues);
            $mappedNewFields = array_merge($this->mapFieldsToProperties($justCreatedFieldValues, $sourceName), $mappedNewFields);
        }

        return $mappedNewFields;
    }
public function save($identifier, array $propertyValues, $shardingKey = null)
    {
        if (false == is_array($identifier)) {
            $identifier = array();
        }

        //Check timestampable
        if (array_key_exists('timestampable', $this->configuration)) {
            if (!isset($propertyValues['createdAt'])) {
                $propertyValues['createdAt'] = new \DateTime();
            }
            $propertyValues['updatedAt'] = new \DateTime();
        }

        //First, create datas to save for each sources
        $datasBySource = array();
        foreach ($propertyValues as $propertyName => $value) {
            //Get sources for the current property
            $sources = $this->getSourcesFromPropertyName($propertyName);

            //Get field name of this property
            $field = $this->getFieldNameFromProperty($propertyName);

            //Foreach sources, if it can handle the field, save to it (should only appear once)
            $isFirstSource = true;
            foreach ($sources as $sourceName) {
                $source = $this->sourceManager->getSource($sourceName);
                if ($source->canHandle($field) && (false === is_null($value) || false === $source->isIdentifier($field) || false === $isFirstSource)) {
                    $datasBySource[$sourceName][$field] = $value;
                }
                $isFirstSource = false;
            }
        }

        //Now, map identifiers to fields
        $mappedIdentifiers = array();
        foreach ($identifier as $propertyName => $value) {
            //Get sources for the current identifier
            $sources = $this->getSourcesFromPropertyName($propertyName);

            //Get field name of this identifier
            $field = $this->getFieldNameFromProperty($propertyName);

            //Foreach sources, if it can handle the field, save to it (should only appear once)
            foreach ($sources as $sourceName) {
                $source = $this->sourceManager->getSource($sourceName);
                if ($source->canHandle($field)) {
                    $mappedIdentifiers[$sourceName][$field] = $value;
                }
            }
        }

        //order $datasBySource by reverse order of default sources
        $orderedDatasBySource = array();
        $sourceNames = $this->configuration['sources'];
        foreach ($sourceNames as $sourceName) {
            if (isset($datasBySource[$sourceName])) {
                $orderedDatasBySource[$sourceName] = $datasBySource[$sourceName];
            }
        }

        //loop on datas to save them to each sources
        $createdFieldValues = array();
        $mappedNewFields = array();
        foreach ($orderedDatasBySource as $sourceName => $datas) {
            $source = $this->sourceManager->getSource($sourceName);

            $newIdentifiers = array();
            foreach ($createdFieldValues as $field => $value) {
                if ($source->canHandle($field)) {
                    $newIdentifiers[$field] = $value;
                }
            }
            $justCreatedFieldValues = $source->save(array_merge($datas, $newIdentifiers), isset($mappedIdentifiers[$sourceName]) ? $mappedIdentifiers[$sourceName] : array(), $shardingKey);
            $createdFieldValues = array_merge($createdFieldValues, $justCreatedFieldValues);
            $mappedNewFields = array_merge($this->mapFieldsToProperties($justCreatedFieldValues, $sourceName), $mappedNewFields);
        }

        return $mappedNewFields;
    }
@param mixed $identifier
@param array $propertyValues
@param null  $shardingKey

@return array
@throws \Exception