Esempio n. 1
0
 /**
  * Build the object instance following current factory settings
  *
  * Errors are thrown by default but can be "gracefully" skipped using the flag `GRACEFULLY_FAILURE`.
  * In all cases, error messages are loaded in final parameter `$logs` passed by reference.
  *
  * @param string $name
  * @param array $parameters
  * @param int $flag One of the class constants flags
  * @param array $logs Passed by reference
  * @return object
  * @throws \RuntimeException if the class is not found
  * @throws \RuntimeException if the class doesn't implement or extend some required dependencies
  * @throws \RuntimeException if the class method for construction is not callable
  */
 public function build($name, array $parameters = null, $flag = self::ERROR_ON_FAILURE, array &$logs = array())
 {
     $this->flag($flag);
     $object = null;
     $builder_class_name = $this->findBuilder($name, $flag, $logs);
     if (!empty($builder_class_name)) {
         $reflection_obj = new ReflectionClass($builder_class_name);
         $is_static = $reflection_obj->hasMethod($this->call_method) && $reflection_obj->getMethod($this->call_method)->isStatic();
         if (!$is_static || $this->call_method === '__construct') {
             if ($reflection_obj->hasMethod('__construct') && $reflection_obj->getConstructor()->isPublic()) {
                 if ($this->call_method === '__construct') {
                     $organized_parameters = CodeHelper::organizeArguments('__construct', $parameters, $builder_class_name);
                     $_caller = call_user_func_array(array($reflection_obj, 'newInstance'), $organized_parameters);
                 } else {
                     $_caller = call_user_func(array($reflection_obj, 'newInstance'));
                 }
             } else {
                 try {
                     if ($this->call_method === '__construct') {
                         $_caller = new $builder_class_name($parameters);
                     } else {
                         $_caller = new $builder_class_name();
                     }
                 } catch (\Exception $e) {
                     $logs[] = $this->_getErrorMessage('Constructor method for class "%s" is not callable!', $builder_class_name);
                     if ($flag & self::ERROR_ON_FAILURE) {
                         throw new \RuntimeException(end($logs));
                     }
                 }
             }
         }
         if (isset($_caller) && $this->call_method === '__construct') {
             $object = $_caller;
         } else {
             if ($reflection_obj->hasMethod($this->call_method) && $reflection_obj->getMethod($this->call_method)->isPublic()) {
                 if ($reflection_obj->getMethod($this->call_method)->isStatic()) {
                     $organized_parameters = CodeHelper::organizeArguments($this->call_method, $parameters, $builder_class_name);
                     $object = call_user_func_array(array($builder_class_name, $this->call_method), $organized_parameters);
                 } elseif (isset($_caller)) {
                     $organized_parameters = CodeHelper::organizeArguments($this->call_method, $parameters, $_caller);
                     $object = call_user_func_array(array($_caller, $this->call_method), $organized_parameters);
                 } else {
                     $logs[] = $this->_getErrorMessage('Error while trying to create "%s->%s" by factory builder!', $builder_class_name, $this->call_method);
                     if ($flag & self::ERROR_ON_FAILURE) {
                         throw new \RuntimeException(end($logs));
                     }
                 }
             } else {
                 $logs[] = $this->_getErrorMessage('Method "%s" for factory building of class "%s" is not callable!', $this->call_method, $builder_class_name);
                 if ($flag & self::ERROR_ON_FAILURE) {
                     throw new \RuntimeException(end($logs));
                 }
             }
         }
     } else {
         $logs[] = $this->_getErrorMessage('No matching class found for factory build "%s"!', $name);
         if ($flag & self::ERROR_ON_FAILURE) {
             throw new \RuntimeException(end($logs));
         }
     }
     return $object;
 }