/**
  * When a class is compiled, all classes that extends it must be compiled too
  *
  * @param &$sources Reflection_Source[]
  * @return Reflection_Source[] added sources list
  */
 public function moreSourcesToCompile(&$sources)
 {
     $added = [];
     // we will search all extends dependencies
     /** @var $dependency Dependency */
     $dependency_search = Search_Object::create(Dependency::class);
     $dependency_search->type = Dependency::T_EXTENDS;
     foreach ($sources as $source) {
         foreach ($source->getClasses() as $class) {
             if (!Builder::isBuilt($class->name)) {
                 // add all classes that extend source classes
                 $dependency_search->dependency_name = $class->name;
                 foreach (Dao::search($dependency_search) as $dependency) {
                     if (!isset($sources[$dependency->file_name]) && !Builder::isBuilt($dependency->class_name)) {
                         $added[$dependency->file_name] = new Reflection_Source($dependency->file_name);
                     }
                 }
             }
         }
     }
     return $added;
 }
Beispiel #2
0
 /**
  * Includes the php file that contains the given class (must contain namespace)
  *
  * @param $class_name string class name (with or without namespace)
  * @return boolean
  */
 public function autoload($class_name)
 {
     if ($i = strrpos($class_name, '\\')) {
         $namespace = strtolower(str_replace('\\', '/', substr($class_name, 0, $i)));
         $file_name = substr($class_name, $i + 1);
         // 'A\Class' stored into 'a/class/Class.php'
         if (file_exists($file1 = strtolower($namespace . '/' . $file_name) . '/' . $file_name . '.php')) {
             /** @noinspection PhpIncludeInspection */
             $result = (include_once Include_Filter::file($file1));
         } elseif (file_exists($file2 = strtolower($namespace) . '/' . $file_name . '.php')) {
             /** @noinspection PhpIncludeInspection */
             $result = (include_once Include_Filter::file($file2));
         } else {
             if (Builder::isBuilt($class_name)) {
                 $file = 'cache/compiled/' . str_replace(SL, '-', Names::classToPath($class_name));
                 if (file_exists($file)) {
                     /** @noinspection PhpIncludeInspection */
                     $result = (include_once $file);
                 }
             }
             if (!isset($result)) {
                 if (error_reporting()) {
                     trigger_error('Class not found ' . $class_name . ', should be into ' . $file1 . ' or ' . $file2, E_USER_ERROR);
                 }
                 $result = false;
             }
         }
     } else {
         /** @noinspection PhpIncludeInspection */
         $result = (include_once Include_Filter::file($class_name . '.php'));
     }
     // instantiate plugin
     if ($result && class_exists($class_name, false) && is_a($class_name, Plugin::class, true)) {
         if (Session::current()) {
             Session::current()->plugins->get($class_name);
         }
     }
 }
Beispiel #3
0
 /**
  * @param $sources Reflection_Source[]
  * @return Reflection_Source[] added sources list
  */
 public function moreSourcesToCompile(&$sources)
 {
     $added = [];
     // search into dependencies : used classes
     /** @var $search Dependency */
     $search = Search_Object::create(Dependency::class);
     $search->type = Dependency::T_USE;
     foreach ($sources as $source) {
         foreach ($source->getClasses() as $class) {
             if ($class->type === T_TRAIT) {
                 $search->dependency_name = $class->name;
                 foreach (Dao::search($search, Dependency::class) as $dependency) {
                     while ($dependency && Builder::isBuilt($dependency->class_name)) {
                         $search_built_parent = Search_Object::create(Dependency::class);
                         $search_built_parent->class_name = $dependency->class_name;
                         $search_built_parent->type = Dependency::T_EXTENDS;
                         $dependency = Dao::searchOne($search_built_parent);
                         if (!$dependency) {
                             trigger_error('Not parent class for built class ' . $search_built_parent->class_name, E_USER_ERROR);
                         }
                         $search_built_parent->class_name = $dependency->dependency_name;
                         $search_built_parent->type = Dependency::T_DECLARATION;
                         $dependency = Dao::searchOne($search_built_parent);
                         if (!$dependency) {
                             trigger_error('Not declaration dependency for class ' . $search_built_parent->class_name, E_USER_ERROR);
                         }
                     }
                     /** @var $dependency Dependency */
                     if (!isset($sources[$dependency->file_name])) {
                         $source = new Reflection_Source($dependency->file_name);
                         $sources[$dependency->file_name] = $source;
                         $added[$dependency->file_name] = $source;
                     }
                 }
             }
         }
     }
     // search into dependencies : registered methods
     foreach ($sources as $source) {
         $search->file_name = $source->file_name;
         $search->dependency_name = Registerable::class;
         $search->type = Dependency::T_IMPLEMENTS;
         if (Dao::searchOne($search, Dependency::class)) {
             unset($search->dependency_name);
             $search->type = Dependency::T_CLASS;
             foreach (Dao::search($search, Dependency::class) as $dependency) {
                 $source = Reflection_Source::of($dependency->dependency_name);
                 if (!isset($sources[$source->file_name])) {
                     $sources[$source->file_name] = $source;
                     $added[$source->file_name] = $source;
                 }
             }
         }
     }
     // classes that are already into $sources
     $already = [];
     foreach ($sources as $source) {
         foreach ($source->getClasses() as $class) {
             $already[$class->name] = true;
         }
     }
     // search into advices and add sources that have sources to compile as advice
     foreach ($this->weaver->getJoinpoints() as $class_name => $joinpoint) {
         if (!isset($already[$class_name])) {
             foreach ($joinpoint as $advices) {
                 foreach ($advices as $advice) {
                     if (is_array($advice = $advice[1])) {
                         $advice_class = $advice[0];
                         if (is_object($advice_class)) {
                             $advice_class = get_class($advice_class);
                         }
                         if (isset($already[$advice_class])) {
                             $source = Reflection_Source::of($class_name);
                             /*
                             if ($source->file_name && !$source->isInternal() && !is_file($source->file_name)) {
                             	$applicant_source = Reflection_Source::of($advice_class);
                             	if (
                             		!$source->searchFile($class_name, array_keys($applicant_source->getRequires()))
                             	) {
                             		trigger_error(
                             			'Reflection_Source file not found for class ' . $class_name, E_USER_ERROR
                             		);
                             	}
                             }
                             */
                             if ($source->getClass($class_name)) {
                                 $sources[$source->file_name] = $source;
                                 $added[$source->file_name] = $source;
                                 $already[$class_name] = true;
                             } else {
                                 trigger_error('No class ' . $class_name . ' into file ' . $source->file_name, E_USER_ERROR);
                             }
                         }
                     }
                 }
             }
         }
     }
     return $added;
 }
Beispiel #4
0
 /**
  * Gets a Reflection_Source knowing its class _name.
  * Uses sources cache, or router's getClassFilename() and fill-in cache.
  *
  * @param $class_name string
  * @return Reflection_Source
  */
 public function getClassFilename($class_name)
 {
     if (isset($this->sources_cache[$class_name])) {
         return $this->sources_cache[$class_name];
     } else {
         /** @var $router Router */
         $router = Session::current()->plugins->get(Router::class);
         if (Builder::isBuilt($class_name)) {
             $file_name = $this->getCacheDir() . SL . str_replace(SL, '-', Names::classToPath($class_name));
         } else {
             $file_name = $router->getClassFilename($class_name);
         }
         $source = new Reflection_Source($file_name, $this, $class_name);
         foreach (array_keys($source->getClasses()) as $class_name) {
             $this->sources_cache[$class_name] = $source;
             if (count($this->sources_cache) > self::MAX_OPENED_SOURCES) {
                 $source->free(self::SOURCES_FREE);
             }
         }
         return $this->sources_cache[$class_name];
     }
 }
Beispiel #5
0
 /**
  * @param $class_name string
  * @return Reflection_Source
  */
 public static function of($class_name)
 {
     $file = Names::classToPath($class_name) . '.php';
     if (Builder::isBuilt($class_name)) {
         $file = 'cache/compiled/' . str_replace(SL, '-', substr($file, 0, -4));
     }
     if (!file_exists($file)) {
         $file = strtolower(substr($file, 0, -4)) . SL . rLastParse($file, SL);
     }
     return new Reflection_Source($file);
 }
Beispiel #6
0
 /**
  * Generates a link for to an object and feature, using parameters if needed
  *
  * @param $object     object|string linked object or class name
  * @param $feature    string linked feature name
  * @param $parameters string|string[]|object|object[] optional parameters list
  * @param $arguments  string|string[] optional arguments list
  * @return string
  */
 public function link($object, $feature = null, $parameters = null, $arguments = null)
 {
     // class name : not Built, not Set
     $class_names = is_string($object) ? $object : get_class($object);
     $class_name = Names::setToClass($class_names, false);
     $set_class = $class_name != $class_names;
     while (Builder::isBuilt($class_name)) {
         $class_name = get_parent_class($class_name);
     }
     if ($set_class) {
         $class_name = Names::classToSet($class_name);
     }
     // build uri
     $link = str_replace(BS, SL, is_object($object) && Dao::getObjectIdentifier($object) ? $class_name . SL . Dao::getObjectIdentifier($object) : $class_name);
     if (isset($feature)) {
         $link .= SL . $feature;
     }
     if (isset($parameters)) {
         if (!is_array($parameters)) {
             $parameters = [$parameters];
         }
         foreach ($parameters as $key => $value) {
             if (!is_numeric($key)) {
                 $link .= SL . $key;
             }
             if (is_object($value)) {
                 $link .= SL . Names::classToUri(get_class($value)) . SL . Dao::getObjectIdentifier($value);
             } else {
                 $link .= SL . $value;
             }
         }
     }
     // build arguments
     if (!empty($arguments)) {
         if (!is_array($arguments)) {
             $link .= '?' . urlencode($arguments);
         } else {
             $link .= '?';
             $first = true;
             foreach ($arguments as $key => $value) {
                 if ($first) {
                     $first = false;
                 } else {
                     $link .= '&';
                 }
                 $link .= $key . '=' . urlencode($value);
             }
         }
     }
     return SL . $link;
 }