Created
January 11, 2023 13:05
-
-
Save radynsade/91a4cd84705cfcfb99ac7de8722cfbe0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Core\Models; | |
use Core\Services\Storage; | |
use Phalcon\Cache\Adapter\AdapterInterface as CacheAdapterInterface; | |
use Phalcon\Db\Adapter\AdapterInterface as DbAdapterInterface; | |
use Phalcon\Mvc\Model; | |
use ReflectionClass; | |
use ReflectionProperty; | |
use Utils\Text\Strings; | |
abstract class BaseModel extends Model { | |
/** | |
* @var string[] | |
*/ | |
protected array $modelProperties; | |
/** | |
* @var integer|null | |
*/ | |
protected ?int $id = null; | |
/** | |
* @return integer|null | |
*/ | |
public function getId(): int|null { | |
return $this->id; | |
} | |
/** | |
* @param integer|null $id | |
* @return static | |
*/ | |
public function setId($id): static { | |
$this->id = $id; | |
return $this; | |
} | |
/** | |
* @return string[] | |
*/ | |
public function getModelProperties() { | |
if (!isset($this->modelProperties)) { | |
$this->modelProperties = $this->scanProperties(); | |
} | |
return $this->modelProperties; | |
} | |
/** | |
* @return boolean | |
*/ | |
public function isSaved(): bool { | |
return !empty($this->id); | |
} | |
/** | |
* @return boolean | |
*/ | |
public function isNew(): bool { | |
return !$this->isSaved(); | |
} | |
/** | |
* @return void | |
*/ | |
public function initialize(): void { | |
$this->useDynamicUpdate(true); | |
$class = new \ReflectionClass($this); | |
$className = $class->getShortName(); | |
$namespaceName = $class->getNamespaceName(); | |
$moduleName = explode("\\", $namespaceName)[1]; | |
$tableName = Strings::camelCaseToSnakeCase($className); | |
$this->setSchema(strtolower($moduleName)); | |
$this->setSource($tableName); | |
$this->addBehavior(new ErrorLogBehavior([ | |
'notSaved' => [], | |
'notDeleted' => [] | |
])); | |
} | |
/** | |
* @return array | |
*/ | |
public function columnMap(): array { | |
return $this->buildColumnMap(); | |
} | |
/** | |
* @return string[] | |
*/ | |
protected function scanProperties(): array { | |
$properties = []; | |
$class = new ReflectionClass($this); | |
$reflectProperties = $class->getProperties(); | |
foreach ($reflectProperties as $reflectProperty) { | |
$name = $reflectProperty->getName(); | |
if ( | |
$reflectProperty->isStatic() | |
|| $this->isFrameworkProperty($name) | |
|| $name === 'modelProperties' | |
|| !$this->isAccessableProperty($class, $reflectProperty) | |
) { | |
continue; | |
} | |
$properties[] = $name; | |
} | |
return $properties; | |
} | |
/** | |
* @return Storage | |
*/ | |
protected function getStorage(): Storage { | |
return $this->container->get('storage'); | |
} | |
/** | |
* @return CacheAdapterInterface | |
*/ | |
protected function getCache(): CacheAdapterInterface { | |
return $this->container->get('cache'); | |
} | |
/** | |
* @return DbAdapterInterface | |
*/ | |
protected function getDatabase(): DbAdapterInterface { | |
return $this->container->get('db'); | |
} | |
/** | |
* @param string $propertyName | |
* @return boolean | |
*/ | |
private function isFrameworkProperty(string $propertyName): bool { | |
return in_array($propertyName, [ | |
'dirtyState', | |
'dirtyRelated', | |
'errorMessages', | |
'modelsManager', | |
'modelsMetaData', | |
'related', | |
'operationMade', | |
'oldSnapshot', | |
'skipped', | |
'snapshot', | |
'transaction', | |
'uniqueKey', | |
'uniqueParams', | |
'uniqueTypes', | |
'container', | |
'belongsTo' | |
]); | |
} | |
/** | |
* @param ReflectionProperty $property | |
* @return boolean | |
*/ | |
private function isAccessableProperty( | |
ReflectionClass $class, | |
ReflectionProperty $property | |
): bool { | |
if ($property->isPublic()) { | |
return true; | |
} | |
$name = $property->getName(); | |
$getterName = Strings::getterName($name); | |
return $class->hasMethod($getterName) | |
&& $class->getMethod($getterName)->isPublic(); | |
} | |
/** | |
* @return array | |
*/ | |
private function buildColumnMap(): array { | |
$properties = $this->getModelProperties(); | |
$map = []; | |
foreach ($properties as $property) { | |
$map[Strings::camelCaseToSnakeCase($property)] = $property; | |
} | |
return $map; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment