/** * @inheritdoc */ public function persist(EntityInterface $entity, $persistType = self::TYPE_CREATE_UPDATE, $disableChecks = false) { if ($disableChecks && $persistType == self::TYPE_CREATE_UPDATE) { throw new \Exception('Can\'t have persistence of CREATE/UPDATE type with checks disabled.'); } $newCheck = 0; $primaryKeyValues = []; $uniqueKeyValues = []; $primaryKey = $entity->getPrimaryKey(); $uniqueKeys = $entity->getUniqueKeys(); // Get primary key values foreach ($primaryKey as $key) { $method = 'get' . ucfirst($key); $check = array($entity, $method); if (is_callable($check)) { $primaryKeyValues[$key] = $entity->{$method}(); $newCheck += (int) empty($primaryKeyValues[$key]); } else { throw new \Exception('Faulty entity passed. Missing method getter'); } } // Now get unique values foreach ($uniqueKeys as $key) { $method = 'get' . ucfirst($key); $check = array($entity, $method); if (is_callable($check)) { $uniqueKeyValues[$key] = $entity->{$method}(); } else { throw new \Exception('Faulty entity passed. Missing method getter'); } } // If checks are off.. just try to persist trusting the caller. if ($disableChecks) { if ($persistType == self::TYPE_CREATE_ONLY) { return $this->createNew($entity); } else { if ($persistType == self::TYPE_UPDATE_ONLY) { return $this->updateExisting($primaryKeyValues, $entity); } } return false; } // Let's check for duplicates: if ($persistType == self::TYPE_CREATE_ONLY) { $query = $this->pdo->from($entity->getTableName()); foreach ($uniqueKeyValues as $idx => $pkv) { if (is_null($pkv)) { $query = $query->where($idx . ' IS NULL'); } else { $query = $query->where($idx . '= ?', $pkv); } } if (count($duplicate = $query->fetchAll()) > 0) { throw new \Exception('Duplicate found for: ' . implode(', ', array_values($uniqueKeyValues))); } } // Ok, no duplicates so far... let's check for the primary keys // This means that the primary key wasn't specified and theoretically should be auto incremental if ($newCheck == count($primaryKey)) { if ($persistType == self::TYPE_UPDATE_ONLY) { throw new \Exception('Update only type specified. Create requested.'); } return $this->createNew($entity); } elseif (count($primaryKey) > 0) { // rimary key was passed in the entity and we should check if it exists already in the DB. $query = $this->pdo->from($entity->getTableName()); foreach ($primaryKeyValues as $idx => $pkv) { if (is_null($pkv)) { $query = $query->where($idx . ' IS NULL'); } else { $query = $query->where($idx . '= ?', $pkv); } } if (count($query->fetchAll()) > 0) { if ($persistType == self::TYPE_CREATE_ONLY) { throw new \Exception('Create only type specified. Update requested.'); } return $this->updateExisting($primaryKeyValues, $entity); } else { if ($persistType == self::TYPE_UPDATE_ONLY) { throw new \Exception('Update only type specified. Create requested.'); } return $this->createNew($entity); } } }