Writes the actual fields

@param string[] $fields
@param ApiInterface $entity

@return bool
969185
private function writeFields($fields, ApiInterface $entity, bool $writeChildren): bool {
        $isChanged = false;
        foreach($fields as $name => $value) {
            if($this->getAcl()->canWriteField($entity, $name)) {
                try {
                    if(array_key_exists($name, $entity->getChildrenUpdaters())) {
                        if($writeChildren) {
                            $entity->getChildrenUpdaters()[$name]->setData($entity, $value);
                            $isChanged = true;
                        }
                    } else {
                        $entity->writeAttribute($name, $value);
                    }
                } catch(\InvalidArgumentException $e) {
                    throw new CatchableException($e->getMessage());
                }
            }
        }
        return $isChanged;
    }
177492
protected function _validation(EntityInterface $entity)
    {
        $validator = new Validator();
        $hasErrors = false;

        foreach ($this->_attributesForEntity($entity) as $attr) {
            $field = $this->_prepareMockField($entity, $attr);
            $result = $field->validate($validator);

            if ($result === false) {
                $this->attachEntityFields($entity);

                return false;
            }

            $errors = $validator->errors($entity->toArray(), $entity->isNew());
            $entity->errors($errors);

            if (!empty($errors)) {
                $hasErrors = true;
                if ($entity->has('_fields')) {
                    $entityErrors = $entity->errors();
                    foreach ($entity->get('_fields') as $field) {
                        $postData = $entity->get($field->name);
                        if (!empty($entityErrors[$field->name])) {
                            $field->set('value', $postData);
                            $field->metadata->set('errors', (array)$entityErrors[$field->name]);
                        }
                    }
                }
            }
        }

        return !$hasErrors;
    }
674219
public function decode(EntityInterface $entity) {
		$idField = $this->_primaryKey;
		$hashid = $entity->get($idField);
		if (!$hashid) {
			return false;
		}

		$field = $this->_config['field'];
		if (!$field) {
			return false;
		}

		$id = $this->decodeHashid($hashid);

		$entity->set($field, $id);
		$entity->setDirty($field, false);

		return true;
	}
1351678
protected function canDecryptField(EntityInterface $entity, string $field): bool
    {
        if (!$this->getTable()->hasField($field)) {
            return false;
        }
        $decryptAll = $this->getConfig('decryptAll');
        if ($decryptAll === true) {
            return true;
        }

        $fields = $this->getFields();
        if (!isset($fields[$field])) {
            return false;
        }

        $decrypt = $fields[$field]['decrypt'];
        if (is_callable($decrypt)) {
            $decrypt = $decrypt($entity, $field);
        }

        return $decrypt;
    }
1312742
protected function updateField(Entity $entity, $field) {
		if ($entity->dirty($field)) {
			return;
		}

		$entity->set($field, $this->getUserId());
	}
882915
private function addField(array $properties, FieldInterface $field)
    {
        $fieldName = $field->getName();
        $fieldRoot = &$properties;

        // Read property config from the field.
        $property = $field->getMappingPropertyConfig();

        $fieldPathArray   = explode('.', $fieldName);
        $currentPathArray = [];
        $fieldPathSize    = count($fieldPathArray);

        for ($i = 0; $i < $fieldPathSize - 1; $i++) {
            $currentPathArray[] = $fieldPathArray[$i];
            $currentPath        = implode('.', $currentPathArray);

            if ($field->isNested() && $field->getNestedPath() == $currentPath && !isset($fieldRoot[$fieldPathArray[$i]])) {
                $fieldRoot[$fieldPathArray[$i]] = ['type' => FieldInterface::FIELD_TYPE_NESTED, 'properties' => []];
            } elseif (!isset($fieldRoot[$fieldPathArray[$i]])) {
                $fieldRoot[$fieldPathArray[$i]] = ['type' => FieldInterface::FIELD_TYPE_OBJECT, 'properties' => []];
            }

            $fieldRoot = &$fieldRoot[$fieldPathArray[$i]]['properties'];
        }

        /*
         * Retrieving location where the property has to be copied to.
         * Ex : searchable fields are copied to default "search" field.
         */
        $copyToProperties = $this->getFieldCopyToProperties($field);

        if (!empty($copyToProperties)) {
            // For normal fields, copy_to is append at the property root.
            $copyToRoot = &$property;
            $copyToRoot['copy_to'] = $copyToProperties;
        }

        $fieldRoot[end($fieldPathArray)] = $property;

        return $properties;
    }
397983
public function insert(EntityInterface $entity)
	{
		$sql = <<<EOT
INSERT INTO `$this->tableName` (`Name`, `Description`, `Created`) 
VALUES ( :name , :description , :created )
EOT;

		$stmt = $this->pdo->prepare($sql);
		$stmt->bindParam(':name', $entity->getName(), \PDO::PARAM_STR);
		$stmt->bindParam(':description', $entity->getDescription(), \PDO::PARAM_STR);
		$stmt->bindParam(':created', $entity->getCreatedRfc3339(), \PDO::PARAM_STR);
		$res = $stmt->execute();

		if ($res === false || $stmt->rowCount() !== 1) {
			return false;
		}

		$entity->setProjectId($this->pdo->lastInsertId());

		return $entity;
	}
551032
public function writePopulate(WriterInterface $writer)
    {
        $writer
            ->write('/**')
            ->write(' * Populate entity with the given data.')
            ->write(' * The set* method will be used to set the data.')
            ->write(' *')
            ->write(' * @param array $data')
            ->write(' * @return boolean')
            ->write(' */')
            ->write('public function populate(array $data = array())')
            ->write('{')
            ->indent()
                ->write('foreach ($data as $field => $value) {')
                ->indent()
                    ->write('$setter = sprintf(\'set%s\', ucfirst(')
                    ->indent()
                        ->write('str_replace(\' \', \'\', ucwords(str_replace(\'_\', \' \', $field)))')
                    ->outdent()
                    ->write('));')
                    ->write('if (method_exists($this, $setter)) {')
                    ->indent()
                        ->write('$this->{$setter}($value);')
                    ->outdent()
                    ->write('}')
                ->outdent()
                ->write('}')
                ->write('')
                ->write('return true;')
            ->outdent()
            ->write('}')
            ->write('')
        ;

        return $this;
    }
95061
public function updateEavCache(EntityInterface $entity)
    {
        if (!$this->config('cacheMap')) {
            return false;
        }

        $attrsById = [];
        foreach ($this->_toolbox->attributes() as $attr) {
            $attrsById[$attr['id']] = $attr;
        }

        if (empty($attrsById)) {
            return true; // nothing to cache
        }

        $query = TableRegistry::get('Eav.EavValues')
            ->find('all')
            ->where([
                'EavValues.eav_attribute_id IN' => array_keys($attrsById),
                'EavValues.entity_id' => $this->_toolbox->getEntityId($entity),
            ])
            ->toArray();

        $values = [];
        foreach ($query as $v) {
            $type = $attrsById[$v->get('eav_attribute_id')]->get('type');
            $name = $attrsById[$v->get('eav_attribute_id')]->get('name');
            $values[$name] = $this->_toolbox->marshal($v->get("value_{$type}"), $type);
        }

        $toUpdate = [];
        foreach ((array)$this->config('cacheMap') as $column => $fields) {
            $cache = [];
            if (in_array('*', $fields)) {
                $cache = $values;
            } else {
                foreach ($fields as $field) {
                    if (isset($values[$field])) {
                        $cache[$field] = $values[$field];
                    }
                }
            }

            $toUpdate[$column] = (string)serialize(new CachedColumn($cache));
        }

        if (!empty($toUpdate)) {
            $conditions = []; // scope to entity's PK (composed PK supported)
            $keys = $this->_table->primaryKey();
            $keys = !is_array($keys) ? [$keys] : $keys;
            foreach ($keys as $key) {
                // TO-DO: check key exists in entity's visible properties list.
                // Throw an error otherwise as PK MUST be correctly calculated.
                $conditions[$key] = $entity->get($key);
            }

            if (empty($conditions)) {
                return false;
            }

            return (bool)$this->_table->updateAll($toUpdate, $conditions);
        }

        return true;
    }
632851
public function delete(EntityInterface $entity)
    {
        $this->entity = $entity;
        $primaryKey = $this->getDescriptor()->getPrimaryKey()->getName();
        $table = $this->getDescriptor()->getTableName();
        $sql = Sql::createSql($this->getAdapter());

        $this->triggerBeforeDelete($entity);

        $this->setUpdateCriteria(
            $sql->delete($table),
            $primaryKey,
            $table
        )->execute();

        $this->triggerAfterDelete($entity);
        $this->removeEntity($entity);
        return $this;
    }
594296
public function afterSave(Event $event, EntityInterface $entity) {
		if ($this->_checkEvent($event) && $entity->isNew()) {
			$fileField = $this->getConfig('fileField');

			$hash = StorageUtils::getFileHash($entity->get($fileField)['tmp_name']);
			$path = $this->pathBuilder()->fullPath($entity);

			$entity->set('hash', $hash);
			$entity->set('path', $path);

			if (!$this->_storeFile($event)) {
				return;
			}

			$event->result = true;
			$event->stopPropagation();
		}
	}
561088
public function update(EntityInterface $entity)
	{
		$sql = <<<EOT
UPDATE `$this->tableName` 
SET 
	`ProjectId` = :projectId , 
	`Name` = :name , 
	`Description` = :description , 
	`Tags` = :tags , 
	`Started` = :started , 
	`Stopped` = :stopped 
WHERE `ActivityId` = :id 
EOT;

		$stmt = $this->pdo->prepare($sql);
		$stmt->bindParam(':id', $entity->getActivityId(), \PDO::PARAM_INT);
		$stmt->bindParam(':projectId', $entity->getProjectId(), \PDO::PARAM_INT);
		$stmt->bindParam(':name', $entity->getName(), \PDO::PARAM_STR);
		$stmt->bindParam(':description', $entity->getDescription(), \PDO::PARAM_STR);
		$stmt->bindParam(':tags', $entity->getTags(), \PDO::PARAM_STR);
		$stmt->bindParam(':started', $entity->getStartedRfc3339(), \PDO::PARAM_STR);
		$stmt->bindParam(':stopped', $entity->getStoppedRfc3339(), \PDO::PARAM_STR);
		$res = $stmt->execute();

		if ($res === false || $stmt->rowCount() !== 1) {
			return false;
		}

		return $entity;
	}
1257424
private function generateEntityAction(ModelInterface $entity) {
        session_write_close();
        $show = new Show($entity);
        $showCriteria = new ShowCriteria($this->request);
        return $show->generate($showCriteria->getField());
    }
699764
protected function save($entities)
    {
        if (!is_array($entities)) {
            $entities = [$entities];
        }

        foreach ($entities as $entity) {
            $entityClass = get_class($entity);
            $entityManager = $this
                ->get('base.object_manager_provider')
                ->getObjectManagerByEntityNamespace($entityClass);
            $entityManager->persist($entity);
            $entityManager->flush($entity);
        }
    }
546413
public function saveEntity($entity, $flush = true)
    {
        $this->preSaveEntity($entity);

        $this->getEntityManager()->persist($entity);

        if ($flush) {
            $this->getEntityManager()->flush($entity);
        }

        // Get updated fields, and include changes so that we have everything.
        $fields  = $entity->getUpdatedFields();
        $changes = [];
        if (method_exists($entity, 'getChanges')) {
            $changes = $entity->getChanges();

            // remove the fields that are part of changes as they were already saved via a setter
            $fields = array_diff_key($fields, $changes);
        }

        // Get Extended Fields to separate from standard Update statement.
        $extendedFields = [];
        $fieldList      = $this->getCustomFieldList('lead');
        foreach ($fields as $alias => $value) {
            if (in_array($fieldList[0][$alias]['object'], ['extendedField', 'extendedFieldSecure'])) {
                // Depends on object added by alteration in organizeFieldsByGroup.
                $extendedFields[$alias]['object'] = $fieldList[0][$alias]['object'];
                $extendedFields[$alias]['id']     = $fieldList[0][$alias]['id'];
                $extendedFields[$alias]['type']   = $fieldList[0][$alias]['type'];
                $extendedFields[$alias]['alias']  = $alias;
                $extendedFields[$alias]['value']  = $value;
                unset($fields[$alias]);
            }
        }

        $this->prepareDbalFieldsForSave($fields);

        // Save standard/core fields (same as core).
        if (!empty($fields)) {
            $table = $this->getEntityManager()->getClassMetadata($this->getClassName())->getTableName();
            $this->getEntityManager()->getConnection()->update($table, $fields, ['id' => $entity->getId()]);
        }

        // Now to update extended fields if there were any to be updated.
        if (!empty($extendedFields)) {
            $insertUpdates = $deletions = [];
            $leadId        = $entity->getId();
            /** @var \Doctrine\DBAL\Connection $connection */
            $connection = $this->getEntityManager()->getConnection();
            foreach ($extendedFields as $extendedField) {
                if (
                    !isset($changes['fields'])
                    || !isset($changes['fields'][$extendedField['alias']])
                ) {
                    // No change to this extended field detected.
                    continue;
                }
                $schema  = $this->leadFieldModel->getSchemaDefinition($extendedField['alias'], $extendedField['type']);
                $columns = [
                    'value' => $extendedField['value'],
                ];
                // Corrects boolean field values, nothing more at this point.
                $this->prepareDbalFieldsForSave($columns);
                $secure    = 'extendedFieldSecure' === $extendedField['object'] ? '_secure' : '';
                $tableName = MAUTIC_TABLE_PREFIX.'lead_fields_leads_'.$schema['type'].$secure.'_xref';

                if (
                    null !== $changes['fields'][$extendedField['alias']][0]
                    && null === $changes['fields'][$extendedField['alias']][1]
                ) {
                    // Removed an existing value.
                    $connection->delete(
                        $tableName,
                        [
                            'lead_id'       => $leadId,
                            'lead_field_id' => $extendedField['id'],
                        ]
                    );
                } else {
                    // Mark for insert/update.
                    if (!isset($insertUpdates[$tableName])) {
                        $insertUpdates[$tableName] = [];
                    }
                    if (!isset($insertUpdates[$tableName][$extendedField['id']])) {
                        $insertUpdates[$tableName][$extendedField['id']] = $columns['value'];
                    }
                }
            }
            // Handle inserts/updates in bulk by table.
            if ($insertUpdates) {
                foreach ($insertUpdates as $tableName => $leadField) {
                    $rows = $params = [];
                    foreach ($leadField as $leadFieldId => $value) {
                        $key          = $tableName.$leadFieldId;
                        $rows[]       = $leadId.', '.$leadFieldId.', :'.$key;
                        $params[$key] = $value;
                    }
                    $sql  = 'INSERT INTO '.$tableName.' (`lead_id`, `lead_field_id`, `value`) '.
                        'VALUES ('.implode('),(', $rows).') '.
                        'ON DUPLICATE KEY UPDATE `value`=VALUES(`value`);';
                    $stmt = $connection->prepare($sql);
                    $stmt->execute($params);
                }
            }
        }

        $this->postSaveEntity($entity);
    }
786263
public function setFieldValue($entity, $field, $value)
    {
        $this->reflFields[$field]->setValue($entity, $value);
    }
1277001
protected function _save(EntityInterface $entity)
    {
        $entity = $this->_table()->patchEntity(
            $entity,
            ['verified' => true],
            $this->saveOptions()
        );
        $subject = $this->_subject(['entity' => $entity]);

        $this->_trigger('beforeSave', $subject);

        $success = call_user_func(
            [$this->_table(), $this->saveMethod()],
            $entity,
            $this->saveOptions()
        );

        $this->_trigger('afterSave', $subject);

        return $success;
    }