Syncs many to many relationships

@param $attributes Model attributes
@return object Model instance
12644
private function sync($id, $attributes)
    {
        // Return if the ID is invalid, or attributes is not an array
        if (!isset($id) || !isset($attributes) || empty($attributes)) {
            return $this;
        }

        // Return if there are no relationships of that type
        if (!isset($this->relationships['belongsToMany']) || empty($this->relationships['belongsToMany'])) {
            return $this;
        }

        // Sync each relationship
        foreach ($this->relationships['belongsToMany'] as $join) {

            // The sync option has to be true, the related attribute an array
            if (isset($join['sync']) && $join['sync'] && isset($attributes[$join['alias']]) && is_array($attributes[$join['alias']])) {

                // Delete old values
                $delete = $this->db()->table($join['pivot'])->where($join['localKey'], $id, '=')->delete();

                // Insert new values
                foreach ($attributes[$join['alias']] as $value) {
                    $this->db()->table($join['pivot'])->insert([$join['localKey'] => $id, $join['foreignKey'] => $value]);
                }
            }
        }

        // Return model instance
        return $this;
    }
231079
public function withAttributes(array $attributes): self
    {
        $result = clone $this;
        $result->attributes = new ParameterCollection($attributes);

        return $result;
    }
449297
public function setAttributes(array $attributes = [])
    {
        $this->attributes = array_merge($this->attributes, $attributes);
        isset($attributes['id']) ? $this->id         = $attributes['id'] : null;
        return $this;
    }
1009243
public function create(array $attributes)
	{
		$group = $this->createModel();
		$group->fill($attributes);
		$group->save();
		return $group;
	}
653230
public function add(array $attributes = array())
    {
        if (!$this->contains($attributes)) {
            $this->model->getModel()->newInstance($attributes)->save();
            $this->cache->forget($this->cacheKey);
        }
        return $this;
    }
491708
public static function init(array $attributes) {
        $obj = new Attributes;
        foreach ($attributes as $attribute) {
            $obj->{$attribute->key} = $attribute;
        }
        return $obj;
    }
581801
protected function prepareAttributes($attributes)
    {
        foreach($this->getAttributeConfig() as $attr => $config){

            // If the attribute is not defined in model or $attributes array
            // set the default value.
            if(!isset($this->attributes[$attr]) && !isset($attributes[$attr])){

                $attributes[$attr] = $config['default'];

            }

        }

        foreach($attributes as $key => $value){

            if(isset($this->config['attributes'][$key])){

                $attributes[$key] = $this->$key()->before_save($value);

            } elseif(isset($this->config['relationships'][$key])){

                unset($attributes[$key]);

                $relationship = $this->config['relationships'][$key];

                $this->translateShorthand($value);

                switch($relationship['type']){

                    case Relationship::HAS_PIVOT:

                        if($value instanceof Collection) $value = $value->all();

                        if($value instanceof EntityContract) $value = [$value];

                        $this->$key()->saveMany($value);

                        break;

                    case Relationship::HAS_MANY:

                        $this->$key()->saveMany((array)$value);

                        break;

                    case Relationship::BELONGS_TO:

                        $this->$key()->associate($value);

                        break;

                    case Relationship::HAS_ONE:

                        $this->$key()->save($value);

                        break;

                    default:

                        throw new \Exception(sprintf(
                            "Unknown relationship type \"%s\" on entity \"%s\"",
                            $relationship['type'],
                            $relationship['entity']
                        ));

                        break;
                }

            }

        }

        return $attributes;
    }
549564
public function contact(array $attributes = [])
    {
        $model = $this->schema->contactModel();

        return (new $model($attributes, $this->query))
            ->setAttribute($this->schema->objectClass(), [
                $this->schema->top(),
                $this->schema->person(),
                $this->schema->organizationalPerson(),
                $this->schema->contact(),
            ]);
    }
534545
public function replicate(array $attributes = [])
    {
        $groupPrefix = isset($attributes['groupPrefix']) ? $attributes['groupPrefix'] : '';

        return new static($this->parent, $this->namer, $this->groupName($groupPrefix));
    }
65982
public function setAttributes(array $attributes = [])
    {
        $this->attributes = array_merge($this->attributes, $attributes);

        $this->validateAttributes();

        $this->decoupleOptionsFromAttributes();

        return $this;
    }
1012764
public function attributes($attributes) {
        
        if(false === is_array($attributes)) {
            return trigger_error(sprintf('Argument 1 passed to %s() must be of the type array, "%s" given', __METHOD__, gettype($attributes)), E_USER_ERROR);
        }

        $this -> attributes = array_merge($this -> attributes, $attributes);

        return $this;
    }
1006936
public function addAttributes(array $attributes): self
    {
        $this->attributes = array_unique(array_merge($this->attributes, $attributes));

        return $this;
    }
335307
private function updateHasMany($id, $attributes)
    {
        // Return if the ID is invalid, or attributes is not an array
        if (!isset($id) || !isset($attributes) || empty($attributes)) {
            return $this;
        }

        // Return if there are no relationships of that type
        if (!isset($this->relationships['hasMany']) || empty($this->relationships['hasMany'])) {
            return $this;
        }

        // Sync each relationship
        foreach ($this->relationships['hasMany'] as $join) {

            // The sync option has to be set, the related attribute an array
            if (isset($join['sync']) && is_array($join['sync']) && isset($attributes[$join['alias']]) && is_array($attributes[$join['alias']])) {

                // Get related elements
                $related = $attributes[$join['alias']];

                // Write trough the model
                if (isset($join['model'])) {

                    // Get or instance the related model
                    if (isset($this->models) && isset($this->models[$join['model']])) {
                        $instance = $this->models[$join['model']];
                    } else {
                        $instance = new $join['model'];
                    }

                    // Delete elements if the overwrite option was set
                    if (in_array('overwrite', $join['sync'])) {
                        $results = $instance->where($join['foreignKey'], $id, '=', $instance->getTable())->limit($join['limit'])->get();
                        if ($results) {
                            foreach ($results as $result) {
                                $instance->destroy($result[$instance->getPrimaryKey()]);
                            }
                        }
                    }

                    // Iterate related elements
                    foreach ($related as $value) {

                        // Add the foreign key
                        $value[$join['foreignKey']] = $id;

                        // Insert elements whitout ID
                        if (in_array('insert', $join['sync']) && !isset($value['id'])) {
                            $instance->create($value);
                        }

                        // Update elements width ID
                        if (in_array('update', $join['sync']) && isset($value['id'])) {

                            // Check if the existing element belongs to this record
                            $current = $instance->find($value['id']);
                            if ($current && isset($current[$join['foreignKey']]) && $current[$join['foreignKey']] == $id) {
                                $instance->update($value['id'], $value);
                            }
                        }
                    }
                }

                // Write trough database
                if (!isset($join['model'])) {

                    // Delete elements if the overwrite option was set
                    if (in_array('overwrite', $join['sync'])) {
                        $results = $this->db()->table($join['table'])->where($join['foreignKey'], $id)->limit(100)->get();
                        if ($results) {
                            $ids = array_diff(array_column($results, 'id'), array_column($related, 'id'));
                            $this->db()->table($join['table'])->whereIn('id', $ids)->delete();
                        }
                    }

                    // Iterate related elements
                    foreach ($related as $value) {

                        // Leave only writable fields
                        $fields = array_intersect_key($value, array_flip($join['columns']));

                        // Add the foreign key
                        $fields[$join['foreignKey']] = $id;

                        // Insert elements whitout ID
                        if (in_array('insert', $join['sync']) && !isset($value['id'])) {
                            $this->db()->table($join['table'])->insert($fields);
                        }

                        // Update elements width ID
                        if (in_array('update', $join['sync']) && isset($value['id'])) {

                            // Check if the existing element belongs to this record
                            $current = $this->db()->table($join['table'])->where('id', $value['id'])->limit(1)->getOne();
                            if ($current && isset($current[$join['foreignKey']]) && $current[$join['foreignKey']] == $id) {
                                $this->db()->table($join['table'])->where('id', $value['id'])->update($fields);
                            }
                        }
                    }
                }
            }
        }

        // Return model instance
        return $this;
    }
189228
public function make(array $attributes = [])
    {
        $instance = $this->related->newInstance($attributes);
        $instance->setAttribute($this->getForeignKeyName(), $this->getParentKey());
        return $instance;
    }
195186
public function create(array $attributes)
    {
        $instance = $this->related->newInstance($attributes);

        $this->setForeignAttributesForCreate($instance);

        $instance->save();

        return $instance;
    }
385079
public function make(array $attributes = [])
    {
        $model = $this->model->newInstance($attributes);
        $this->publish('made', $model);

        return $model;
    }
1259588
public function addAttributes(array $attributes)
    {
        foreach ($attributes as $attribute => $value) {
            $this->addAttribute($attribute, $value);
        }

        return $this;
    }