/** * Installs the ORM-related functionality on a model. * * @param Mismatch\Model\Metadata $m */ public static function usingORM($m) { // Auto-detect attributes. $m->extend('attrs', function ($attrs, $m) { $m['orm:attr_populator']->populate($attrs); return $attrs; }); // The table that we want to connect the model to. $m['orm:table'] = function ($m) { return ORM\Inflector::tableize($m->getClass()); }; // The default foreign key of the model, by name. $m['orm:fk'] = function ($m) { return ORM\Inflector::columnize($m->getClass()) . '_id'; }; // The connection the model will use to talk to the database. $m['orm:connection'] = $m->factory(function ($m) { return $m['orm:connection_class']::create($m['orm:credentials']); }); // The class to use for this model's connection. $m['orm:connection_class'] = 'Mismatch\\ORM\\Connection'; // The query builder used for finding and modifying data $m['orm:query'] = $m->factory(function ($m) { $query = new $m['orm:query_class']($m['orm:connection'], $m['orm:table'], $m['pk']); $query->fetchAs([$m['orm:mapper'], 'hydrate']); return $query; }); // The class to use for query building. $m['orm:query_class'] = 'Mismatch\\ORM\\Query'; // The mapper to user for mapping between the DB and PHP. $m['orm:mapper'] = function ($m) { return new $m['orm:mapper_class']($m, $m['attrs']); }; // The class to use for mapping between the db and php. $m['orm:mapper_class'] = 'Mismatch\\ORM\\Mapper'; // The attribute inspector used for determining types. $m['orm:attr_populator'] = function ($m) { return new $m['orm:attr_populator_class']($m['orm:connection'], $m['orm:table']); }; $m['orm:attr_populator_class'] = 'Mismatch\\ORM\\Attr\\Populator'; }
/** * @param string $name * @param array $opts * @return array */ private function parseType($name, array $opts) { $pattern = "/^(?<type>[\\w\\\\-]+)(\\[(?<each>[\\w\\\\]+)\\])?(?<null>\\?)?\$/"; if (false === preg_match($pattern, $opts['type'], $matches)) { throw new InvalidTypeException($this->metadata->getClass(), $name, $opts['type']); } // Resolve the type with the already declared types. $opts['type'] = $this->resolveType($matches['type']); // Parse strings like "Foo" or "Foo?". A question mark at // the end of a string indicates the type is nullable. if (!empty($matches['null'])) { $opts['nullable'] = true; } // Parse strings like "Foo[Bar]" to be nested types. // We'll allow the parent type to figure out how to deal // with that nested type. if (!empty($matches['each'])) { $opts['each'] = $matches['each']; } return $opts; }
/** * Hook for when this trait is used on a class. * * @param Metadata $m */ public static function usingModel($m) { $m['attrs'] = function ($m) { return new Attrs($m); }; $m['pk'] = function ($m) { foreach ($m['attrs'] as $attr) { if ($attr instanceof Primary) { return $attr; } } throw new MissingPkException($m->getClass()); }; }
/** * Hook for creating a new model. * * @param Dataset $dataset * @return object */ protected function hydrateModel($dataset) { $class = $this->metadata->getClass(); return new $class($dataset); }