Ejemplo n.º 1
0
 public static function defineClass($className, $extends = '')
 {
     //        $namespace = 'Eddmash\PowerOrm\Migration\Model';
     $namespace = '';
     $use = '';
     $extendedClass = '';
     if (empty($extends) || Model::isModelBase($extends)) {
         $extends = Model::getFullClassName();
     } else {
         $extendedClass = sprintf('%s%s', ClassHelper::getFormatNamespace($namespace, true), $extends);
         $use = sprintf('use %s;', $extendedClass);
         $extends = trim(substr($extends, strripos($extends, '\\')), '\\');
     }
     if (!StringHelper::isEmpty($extendedClass) && !ClassHelper::classExists($extendedClass, $namespace)) {
         self::$deferedClasses[$extends][] = ['class' => $className, 'extends' => $extends];
         return false;
     }
     $extends = ClassHelper::getNameFromNs($extends, $namespace);
     $class = sprintf(self::getTemplate(), $namespace, $use, $className, $extends);
     $className = sprintf('%s%s', ClassHelper::getFormatNamespace($namespace, true), $className);
     if (ArrayHelper::hasKey(self::$deferedClasses, $className)) {
         foreach (self::$deferedClasses[$className] as $deferedClass) {
             self::defineClass($deferedClass['class'], $deferedClass['extends']);
         }
     }
     if (!ClassHelper::classExists($className, $namespace)) {
         eval($class);
     }
     return $className;
 }
Ejemplo n.º 2
0
 public function getConstructorArgs()
 {
     $constructorArgs = parent::getConstructorArgs();
     if (isset($constructorArgs['meta']) && empty($constructorArgs['meta'])) {
         unset($constructorArgs['meta']);
     }
     if (isset($constructorArgs['extends'])) {
         if (StringHelper::isEmpty($constructorArgs['extends']) || Model::isModelBase($constructorArgs['extends'])) {
             unset($constructorArgs['extends']);
         } else {
             $constructorArgs['extends'] = ClassHelper::getNameFromNs($constructorArgs['extends'], BaseOrm::getModelsNamespace());
         }
     }
     return $constructorArgs;
 }
Ejemplo n.º 3
0
 public function registerModel(Model $model)
 {
     $name = ClassHelper::getNameFromNs($model->meta->modelName, BaseOrm::getModelsNamespace());
     if (!ArrayHelper::hasKey($this->allModels, $name)) {
         $this->allModels[$name] = $model;
     }
     $this->resolvePendingOps($model);
 }
Ejemplo n.º 4
0
 public static function getMigrationsNamespace()
 {
     $namespace = ClassHelper::getFormatNamespace(self::getInstance()->appNamespace, true);
     return ClassHelper::getFormatNamespace(sprintf('%s%s', $namespace, 'Migrations'), true, false);
 }
Ejemplo n.º 5
0
 /**
  * {@inheritdoc}
  */
 public function getConstructorArgs()
 {
     $kwargs = parent::getConstructorArgs();
     if (ArrayHelper::hasKey($kwargs, 'onDelete')) {
         $kwargs['onDelete'] = $this->relation->onDelete;
     }
     if (is_string($this->relation->toModel)) {
         $kwargs['to'] = $this->relation->toModel;
     } else {
         $name = $this->relation->toModel->getFullClassName();
         $kwargs['to'] = ClassHelper::getNameFromNs($name, BaseOrm::getModelsNamespace());
     }
     if ($this->relation->parentLink) {
         $kwargs['parentLink'] = $this->relation->parentLink;
     }
     return $kwargs;
 }
Ejemplo n.º 6
0
 /**
  * Gets information about a model and all its parent.
  *
  * Some fact to check for :
  *  - proxy model should have at least one concrete model.
  *  - proxy model should not extend an abstract class that contains fields.
  *
  * returns the concrete model in the hierarchy and the fields in each of the models in the hierarchy.
  *
  * @param string    $method     the method to invoke
  * @param null      $args       the arguments to pass to the method
  * @param bool|true $fromOldest do we traverse from BaseObject to the child model
  *
  * @return array
  *
  * @throws TypeError
  * @throws FieldError
  *
  * @since 1.1.0
  *
  * @author Eddilbert Macharia (http://eddmash.com) <*****@*****.**>
  */
 private function getHierarchyMeta($method = 'unboundFields', $args = null, $fromOldest = true)
 {
     $modelNamespace = BaseOrm::getModelsNamespace();
     $isProxy = $this->meta->proxy;
     // start from oldest parent e.g BaseObject to the last child model
     $parents = $this->getParents([\PModel::getFullClassName(), self::getFullClassName()]);
     $parents = array_merge([$this->getFullClassName() => new \ReflectionObject($this)], $parents);
     if ($fromOldest) {
         $parents = array_reverse($parents);
     }
     $modelFields = [];
     $concreteParent = null;
     $immediateParent = null;
     $previousAbstractParent = null;
     /** @var $reflectionParent \ReflectionClass */
     /* @var $concreteParent \ReflectionClass */
     foreach ($parents as $index => $reflectionParent) {
         $parentName = $reflectionParent->getName();
         $isOnCurrentModel = $this->getFullClassName() === $parentName;
         if (!$reflectionParent->hasMethod($method) || $reflectionParent->getMethod($method)->isAbstract()) {
             continue;
         }
         // concrete is a class that can be instantiated.
         // check for at least one concrete parent nearest to the last child model.
         // since we are going downwards we keep updating the concrete variable.
         if (!($isOnCurrentModel && $isProxy) && $reflectionParent->isInstantiable()) {
             $concreteParent = $reflectionParent;
         }
         // ************ get the fields *******************
         // we need to call the parent version of the method for each class to get its fields
         // this is how we bypass the overriding functionality of php, otherwise if we don't do this the $method will
         // always provide the fields defined in the last child class.
         $parentMethodCall = sprintf('%1$s::%2$s', $parentName, $method);
         if ($args != null) {
             if (is_array($args)) {
                 $fields = call_user_func_array([$this, $parentMethodCall], $args);
             } else {
                 $fields = call_user_func([$this, $parentMethodCall], $args);
             }
         } else {
             $fields = call_user_func([$this, $parentMethodCall]);
         }
         // =========================== Some Validations ========================
         /*
          * confirm fields with same name don't exist on the parents and current model.
          * i choose to through an exception of overriding for consistence sake. that is on the $method no overriding
          * takes place.
          *
          */
         if ($immediateParent != null && $immediateParent != $previousAbstractParent) {
             $fieldKeys = array_keys($fields);
             $parentKeys = isset($modelFields[$immediateParent]) ? array_keys($modelFields[$immediateParent]) : [];
             $commonFields = array_intersect($parentKeys, $fieldKeys);
             if (!empty($commonFields)) {
                 throw new FieldError(sprintf('Local field [ %s ] in class "%s" clashes with field of similar name from base class "%s" ', implode(', ', $commonFields), $parentName, $immediateParent));
             }
         }
         // if the parent is an abstract model and the current model is a proxy model
         // the parent should not have any fields. abstract models cant have fields
         // incases where the child is a proxy model
         if ($isOnCurrentModel && $isProxy && $immediateParent === $previousAbstractParent) {
             $parentFields = $modelFields[$previousAbstractParent];
             if (!empty($parentFields)) {
                 throw new TypeError(sprintf('Abstract base class containing model fields not ' . "permitted for proxy model '%s'.", $parentName));
             }
         }
         // ****************** Import fields from Abstract ***************
         // get fields of immediate parent fields if it was an abstract model add them to child model.
         if (!$isProxy && $previousAbstractParent != null) {
             $parentFields = isset($modelFields[$previousAbstractParent]) ? $modelFields[$previousAbstractParent] : [];
             $fields = array_merge($parentFields, $fields);
         }
         if ($reflectionParent->isAbstract()) {
             $previousAbstractParent = $parentName;
         } else {
             $previousAbstractParent = null;
         }
         if (!$isOnCurrentModel) {
             $immediateParent = $parentName == $previousAbstractParent ? '' : $parentName;
         }
         $modelFields[ClassHelper::getNameFromNs($parentName, $modelNamespace)] = $fields;
     }
     if ($isProxy && $concreteParent == null) {
         throw new TypeError(sprintf("Proxy model '%s' has no non-abstract" . ' model base class.', $this->getShortClassName()));
     }
     return [$concreteParent == null ?: ClassHelper::getNameFromNs($concreteParent->getName(), $modelNamespace), $immediateParent, $modelFields];
 }
Ejemplo n.º 7
0
 /**
  * @param $name
  *
  * @return BaseCommand
  *
  * @since 1.1.0
  *
  * @author Eddilbert Macharia (http://eddmash.com) <*****@*****.**>
  */
 public function fetchCommand($name)
 {
     $name = ucfirst($name);
     $file = null;
     $packageName = null;
     foreach ($this->path as $package => $path) {
         $file_handler = new FileHandler($path);
         $file = $file_handler->getFile($name);
         if ($file !== false) {
             $packageName = $package;
             break;
         }
     }
     if (false === $file) {
         $this->error(sprintf('Unknown command: ` %1$s`. Does the file exists `%2$s/%1$s.php` ?' . PHP_EOL, $name, $this->path));
         $message = $this->ansiFormat(sprintf('php %s.php help', $this->managerName), Console::FG_YELLOW);
         $this->normal(sprintf('Type %s for usage.' . PHP_EOL, $message));
         return false;
     }
     // commands are in the commands namespace
     /** @var $className BaseCommand */
     $className = ClassHelper::getFormatNamespace($packageName) . 'Console\\Command\\' . $name;
     return new $className();
 }
Ejemplo n.º 8
0
 public function getName($name)
 {
     return ClassHelper::getNameFromNs($name, BaseOrm::getModelsNamespace());
 }
Ejemplo n.º 9
0
 /**
  * @dataProvider nameFromNamespaceProvider
  *
  * @since 1.1.0
  *
  * @author Eddilbert Macharia (http://eddmash.com) <*****@*****.**>
  */
 public function testGettingNameFromNamespace($originalValue, $expectedValue)
 {
     $this->assertEquals($expectedValue, ClassHelper::getNameFromNs($originalValue, '\\app\\model'));
 }
Ejemplo n.º 10
0
 /**
  * @return array
  *
  * @throws ClassNotFoundException
  *
  * @since 1.1.0
  *
  * @author Eddilbert Macharia (http://eddmash.com) <*****@*****.**>
  */
 public function getMigrationsClasses()
 {
     $migrationFiles = $this->getMigrationsFiles();
     $classes = [];
     $namespace = BaseOrm::getMigrationsNamespace();
     foreach ($migrationFiles as $migrationFile) {
         $className = ClassHelper::getClassNameFromFile($migrationFile, BaseOrm::getMigrationsPath());
         $foundClass = ClassHelper::classExists($className, $namespace);
         if (!$className) {
             throw new ClassNotFoundException(sprintf('The class [ %2$s\\%1$s or \\%1$s ] could not be located', $className, $namespace));
         }
         $classes[] = $foundClass;
     }
     return $classes;
 }
Ejemplo n.º 11
0
 /**
  * Defines a new model class.
  *
  * we create a new namespace and define new classes because, we might be dealing with a model that has been dropped
  * Meaning if we try to load the model using the normal way, we will get and error of model does not exist.
  *
  * @param string $className
  * @param string $extends
  *
  * @return Model
  *
  * @since 1.1.0
  *
  * @author Eddilbert Macharia (http://eddmash.com) <*****@*****.**>
  */
 private static function createInstance($className, $extends = '')
 {
     if (!ClassHelper::classExists($className, BaseOrm::getModelsNamespace())) {
         MigrationModel::defineClass($className, $extends);
     }
     return new $className();
 }