/** * @param string $serialized */ public final function unserialize($serialized) { $props = unserialize($serialized); $reflect = new \ReflectionClass($this); /** @var $prop \ReflectionProperty */ foreach ($reflect->getProperties() as $prop) { $key = $prop->getName(); $this->{$key} = $props[$key] ?? null; } $this->schemaTable = Schema::getTable($this->schemaTable); call_user_func_array([$this, "callBack"], Schema::getCallbackArgs()); }
/** * Using OOP magic to create magical findBy* methods * Arguments: * First = (mixed) Value to search in database with * Second = (int) Number of rows to return * Third = (bool) Throw exception on no rows found or return false? * * @param $name * @param $arguments * @throws SchemaException * @return object|bool|array */ public static final function __callStatic($name, $arguments) { // Check if necessary constants are defined if (!defined("static::SCHEMA_TABLE")) { throw SchemaException::tableInitConstant("SCHEMA_TABLE"); } elseif (!defined("static::SCHEMA_MODEL")) { throw SchemaException::tableInitConstant("SCHEMA_MODEL"); } $tableNameConstant = constant("static::SCHEMA_TABLE"); $modelNameConstant = constant("static::SCHEMA_MODEL"); // Check if calling findBy* method if (substr($name, 0, 6) === "findBy") { $findBy = substr($name, 6); $findValue[] = $arguments[0] ?? null; $findLimit = 1; if (array_key_exists(1, $arguments)) { // Check if fetch limit is explicitly provided if (is_int($arguments[1])) { // Fetch limit is provided and is an Integer $findLimit = $arguments[1]; } else { // Fetch limit must be an Integer throw SchemaException::badArgType(__METHOD__, 2, "integer", gettype($arguments[1])); } } // Throw exception is row not found? $throwException = true; if (isset($arguments[2]) && $arguments[2] === false) { $throwException = false; } // Convert PascalCase/camelCase to snake_case $findBy = Comely::snakeCase($findBy); // SELECT query $findQuery = sprintf('SELECT * FROM `%1$s` WHERE `%2$s`=? LIMIT %3$s', $tableNameConstant, $findBy, $findLimit); // Run Query $tableName = get_called_class(); $db = Schema::getTable($tableName)->getDb(); $rows = $db->query($findQuery, $findValue, Database::QUERY_FETCH); // Row(s) were found? if (empty($rows)) { // No rows were found if ($throwException) { throw new SchemaException($name, "No rows were returned from database", 1201); } else { // Return FALSE return false; } } // Check if SCHEMA_MODEL constant is set $modelClass = $modelNameConstant; $callbackArgs = Schema::getCallbackArgs(); if (!is_null($modelClass)) { if ($findLimit === 1) { // Return single model instance $model = new $modelClass($tableName, $rows[0]); // Arguments injection if (method_exists($model, "callBack")) { $model->callBack(...$callbackArgs); } return $model; } else { $models = []; // Iterate through rows foreach ($rows as $row) { $model = new $modelClass($tableName, $row); // Arguments injection if (method_exists($model, "callBack")) { $model->callBack(...$callbackArgs); } $models[] = $model; } // return indexed Array containing Model's instances return $models; } } else { // Model is not set, return fetched Array return $findLimit === 1 ? $rows[0] : $rows; } } // Throw undefined method exception throw SchemaException::undefinedMethod($name); }