Esempio n. 1
0
/**
 * Returns true if an object / class /interface / trait is a class / interface / trait
 *
 * All parent classes, interfaces and traits are scanned recursively
 *
 * @param $object     string|object
 * @param $class_name string|object
 * @return boolean
 */
function isA($object, $class_name)
{
    if (is_string($object)) {
        $object = Builder::className($object);
    } elseif (is_object($object)) {
        $object = get_class($object);
    } else {
        return false;
    }
    if (is_object($class_name)) {
        $class_name = get_class($class_name);
    }
    if (is_a($object, $class_name, true)) {
        return true;
    }
    $classes = class_parents($object) + class_uses($object);
    while ($classes) {
        $next_classes = [];
        foreach ($classes as $class) {
            if (is_a($class, $class_name, true)) {
                return true;
            }
            $next_classes += class_uses($class);
        }
        $classes = $next_classes;
    }
    return false;
}
Esempio n. 2
0
 /**
  * Returns a new instance of an object, but sets all its properties values to empty
  *
  * The empty value depends on the type of the property, simple type get an empty value of the
  * same type. Object, resource, callable properties get an empty value of null.
  *
  * @param $class_name string
  * @return object
  */
 public static function create($class_name)
 {
     $object = Builder::create($class_name);
     foreach ((new Reflection_Class($class_name))->accessProperties() as $property) {
         if (!$property->isStatic()) {
             switch ($property->getType()->asString()) {
                 case Type::INTEGER:
                 case Type::FLOAT:
                     $value = 0;
                     break;
                 case Type::STRING:
                     $value = '';
                     break;
                 case Type::BOOLEAN:
                     $value = false;
                     break;
                 case Type::_ARRAY:
                     $value = [];
                     break;
                 default:
                     $value = null;
             }
             $property->setValue($object, $value);
         }
     }
     return $object;
 }
Esempio n. 3
0
 /**
  * Gets/sets current environment's object
  *
  * @param $set_current mixed
  * @return Current
  */
 public static function current($set_current = null)
 {
     $called_class = get_called_class();
     // set current (ignore Reflection_Property : to enable use of @default Class::current)
     if ($set_current && !is_a($set_current, Reflection_Property::class)) {
         static::$current = $set_current;
         if (!is_a($called_class, Plugin::class, true)) {
             Session::current()->set($set_current, Builder::current()->sourceClassName($called_class));
         }
     } elseif (!isset(static::$current)) {
         // get current plugin from plugins manager
         if (is_a($called_class, Plugin::class, true)) {
             if ($called_class === Builder::class) {
                 static::$current = new Builder();
             } else {
                 $plugin = Session::current()->plugins->get(Builder::current()->sourceClassName($called_class));
                 if (!isset(static::$current)) {
                     static::$current = $plugin;
                 }
             }
         } else {
             static::$current = Session::current()->get($called_class);
         }
     }
     return static::$current;
 }
Esempio n. 4
0
 /**
  * @return Body
  */
 protected function buildBody()
 {
     $body = parent::buildBody();
     $row = $this->buildRow(Builder::create($this->class_name));
     $row->addClass('new');
     $body->addRow($row);
     return $body;
 }
Esempio n. 5
0
 /**
  * @param $parameters Parameters
  * @param $form       array
  * @param $class_name string
  * @return mixed[]
  */
 protected function getViewParameters(Parameters $parameters, $form, $class_name)
 {
     $parameters = $parameters->getObjects();
     $object = reset($parameters);
     if (empty($object) || !is_object($object) || !is_a($object, $class_name, true)) {
         $object = Builder::create($class_name);
         $parameters = array_merge([$class_name => $object], $parameters);
     }
     return $parameters;
 }
Esempio n. 6
0
 /**
  * Returns a new instance of an object, but sets all its properties values to null
  *
  * @param $class_name string
  * @return object
  */
 public static function create($class_name)
 {
     $object = Builder::create($class_name);
     foreach ((new Reflection_Class($class_name))->accessProperties() as $property) {
         if (!$property->isStatic()) {
             $property->setValue($object, null);
         }
     }
     return $object;
 }
Esempio n. 7
0
 /**
  * @param $elements Setting[]
  */
 public function __construct($elements = null)
 {
     $settings = [];
     if (isset($elements)) {
         foreach ($elements as $setting) {
             $settings[$setting->code] = $setting;
         }
     }
     parent::__construct(Builder::className('SAF\\Framework\\Setting'), $settings);
 }
Esempio n. 8
0
 /**
  * @before SAF\Framework\Dao\Data_Link::write($this)
  */
 public function setNumber()
 {
     if (isA($this, Has_Counter::class)) {
         /** @var $counter Counter */
         $counter = Dao::searchOne(['class_name' => get_class($this)], Counter::class);
         if (!isset($counter)) {
             $counter = Builder::create(Counter::class, [get_class($this)]);
         }
         $this->setCounter($counter->increment());
     }
 }
Esempio n. 9
0
 /**
  * Run the default json controller
  *
  * @param $parameters Parameters
  * @param $form array
  * @param $files array
  * @param $class_name string
  * @return string
  */
 public function run(Parameters $parameters, $form, $files, $class_name)
 {
     $parameters = $parameters->getObjects();
     // read all objects corresponding to class name
     if (!$parameters) {
         return json_encode(Dao::readAll(Names::setToClass($class_name, false), [Dao::sort()]));
     }
     // read object
     $first_parameter = reset($parameters);
     if (is_object($first_parameter)) {
         return json_encode($first_parameter);
     }
     // search objects for autocomplete combo pull-down list
     if (isset($parameters['term'])) {
         $element_class_name = Names::setToClass($class_name, false);
         $search = null;
         if (!empty($parameters['term'])) {
             $search = (new Search_Array_Builder())->buildMultiple(new Reflection_Class($element_class_name), $parameters['term'], '', '%');
         }
         if (isset($parameters['filters']) && $parameters['filters']) {
             if (!(is_object($search) && $search->isAnd())) {
                 $search = Dao\Func::andOp($search ? [$search] : []);
             }
             foreach ($parameters['filters'] as $filter_name => $filter_value) {
                 $search->arguments[$filter_name] = $filter_value[0] == '!' ? Dao\Func::notEqual(substr($filter_value, 1)) : $filter_value;
             }
             if (count($search->arguments) == 1) {
                 reset($search->arguments);
                 $search = [key($search->arguments) => current($search->arguments)];
             }
         }
         $objects = [];
         // first object only
         if (isset($parameters['first']) && $parameters['first']) {
             $objects = Dao::search($search, $element_class_name, [Dao::sort(), Dao::limit(1)]);
             $source_object = $objects ? reset($objects) : Builder::create($element_class_name);
             return json_encode(new Autocomplete_Entry(Dao::getObjectIdentifier($source_object), strval($source_object)));
         } else {
             $search_options = [Dao::sort()];
             if (isset($parameters['limit'])) {
                 $search_options[] = Dao::limit($parameters['limit']);
             }
             foreach (Dao::search($search, $element_class_name, $search_options) as $source_object) {
                 $objects[] = new Autocomplete_Entry(Dao::getObjectIdentifier($source_object), strval($source_object));
             }
             return json_encode($objects);
         }
     } elseif (isset($parameters['id'])) {
         $element_class_name = Names::setToClass($class_name);
         $source_object = Dao::read($parameters['id'], $element_class_name);
         return json_encode(new Autocomplete_Entry(Dao::getObjectIdentifier($source_object), strval($source_object)));
     }
     return '';
 }
Esempio n. 10
0
 /**
  * @param $serialized string
  * @return void
  */
 public function unserialize($serialized)
 {
     $this->files = [];
     foreach (unserialize($serialized) as $file_name => $temporary_file_name) {
         /** @var $file File */
         $file = Builder::create(File::class);
         $file->name = $file_name;
         $file->temporary_file_name = $temporary_file_name;
         $this->files[] = $file;
     }
 }
Esempio n. 11
0
 /**
  * Load a counter linked to the class of an object from default data link and increment it
  *
  * @param $object     object The object to use to format the counter
  * @param $identifier string The identifier of the counter ; default is get_class($object)
  * @return string The new counter value
  */
 public static function increment($object, $identifier = null)
 {
     Dao::begin();
     if (empty($identifier)) {
         $identifier = Builder::current()->sourceClassName(get_class($object));
     }
     $counter = Dao::searchOne(['identifier' => $identifier], get_called_class()) ?: new Counter($identifier);
     $next_value = $counter->next($object);
     Dao::write($counter);
     Dao::commit();
     return $next_value;
 }
Esempio n. 12
0
 /**
  * @param $temporary_file_name string
  */
 public function __construct($temporary_file_name = null)
 {
     if (isset($temporary_file_name)) {
         if (!isset($this->name)) {
             $this->name = rLastParse($temporary_file_name, SL, 1, true);
         }
         $this->temporary_file_name = $temporary_file_name;
     }
     if (!isset($this->updated_on)) {
         $this->updated_on = Builder::create(Date_Time::class);
     }
 }
Esempio n. 13
0
 /**
  * Apply class name : if constructor was called without columns, this will initialize columns list
  *
  * This applies default column names if there was no default class name, or if class name changed,
  * or if there were no column names.
  *
  * @param $class_name string
  */
 private function applyClassName($class_name)
 {
     if (isset($class_name) && $class_name != $this->class_name && (isset($this->class_name) || !isset($this->columns))) {
         $class_name = Builder::className($class_name);
         $this->class_name = $class_name;
         $columns = (new Reflection_Class($class_name))->getListAnnotation('sort')->values();
         if (!$columns) {
             $columns = (new Reflection_Class($class_name))->getListAnnotation('representative')->values();
         }
         $this->columns = $columns;
         $this->calculateReverse();
     }
 }
Esempio n. 14
0
 /**
  * @param $source Reflection_Source
  */
 public function onCompileSource(Reflection_Source $source)
 {
     Dao::begin();
     foreach ($source->getClasses() as $class) {
         /** @var $log Compiler_Log */
         $log = Builder::create(Compiler_Log::class);
         $log->class_name = $class->getName();
         $log->date_time = Date_Time::now();
         Dao::write($log);
         $this->log_flag = true;
     }
     Dao::commit();
 }
Esempio n. 15
0
 /**
  * Get the object of class $class_name from session
  *
  * @param $class_name     string
  * @param $create_default boolean Create a default object for the class name if does not exist
  * @return object|null
  */
 public function get($class_name, $create_default = false)
 {
     if (isset($this->current[$class_name])) {
         $current = $this->current[$class_name];
         if (is_array($current)) {
             $current = $current[1];
             $this->current[$class_name] = $current = is_numeric($current) ? Dao::read($current, $class_name) : unserialize($current);
         }
         return $current;
     } elseif ($create_default) {
         return $this->current[$class_name] = Builder::create($class_name);
     } else {
         return null;
     }
 }
Esempio n. 16
0
 /**
  * @param $sources Reflection_Source[] Key is the file path
  * @return Reflection_Source[] added sources list
  */
 public function moreSourcesToCompile(&$sources)
 {
     $added = [];
     foreach ($sources as $file_path => $source) {
         if (!strpos($file_path, SL)) {
             $reload = true;
             break;
         }
     }
     if (isset($reload)) {
         $old_compositions = Builder::current()->getCompositions();
         $old_levels = Session::current()->plugins->getAll(true);
         if (isset(Main::$current)) {
             Main::$current->resetSession();
         }
         $new_compositions = Builder::current()->getCompositions();
         $new_levels = Session::current()->plugins->getAll(true);
         // add classes where builder composition changed
         foreach ($old_compositions as $class_name => $old_composition) {
             if (!isset($new_compositions[$class_name]) || $old_composition != $new_compositions[$class_name] || is_array($old_composition) && (array_diff($old_composition, $new_compositions[$class_name]) || array_diff($new_compositions[$class_name], $old_composition))) {
                 $this->moreSourcesAdd($class_name, $sources, $added);
             }
         }
         foreach ($new_compositions as $class_name => $new_composition) {
             if (!isset($old_compositions[$class_name])) {
                 $this->moreSourcesAdd($class_name, $sources, $added);
             }
         }
         // add classes of globally added/removed plugins
         foreach ($old_levels as $level => $old_plugins) {
             foreach ($old_plugins as $class_name => $old_plugin) {
                 if (!isset($new_levels[$level][$class_name])) {
                     $this->moreSourcesAdd($class_name, $sources, $added);
                 }
             }
         }
         foreach ($new_levels as $level => $new_plugins) {
             foreach ($new_plugins as $class_name => $new_plugin) {
                 if (!isset($old_levels[$level][$class_name])) {
                     $this->moreSourcesAdd($class_name, $sources, $added);
                 }
             }
         }
     }
     return $added;
 }
Esempio n. 17
0
 /**
  * Returns a new instance of a search-formatted object of given class
  *
  * This creates an object with unset properties, as only set properties are used for searches.
  * Private or protected properties can't be unset : they are kept with a null value.
  *
  * @param $class_name string
  * @return object
  */
 public static function create($class_name)
 {
     $object = Builder::create($class_name);
     foreach ((new Reflection_Class(get_class($object)))->accessProperties() as $property) {
         if (!$property->isStatic()) {
             if ($property->isPublic()) {
                 $name = $property->name;
                 if (!isset($object->{$name}) || $object->{$name} !== $object) {
                     unset($object->{$name});
                 }
             } else {
                 $property->setValue($object, null);
             }
         }
     }
     return $object;
 }
Esempio n. 18
0
 /**
  * @param $form             array
  * @param $name_element     array
  * @param $tmp_name_element array
  * @return array
  */
 private function appendToFormRecurse($form, $name_element, $tmp_name_element)
 {
     foreach ($name_element as $key => $name_sub_element) {
         if (is_array($name_sub_element)) {
             if (!isset($form[$key])) {
                 $form[$key] = [];
             }
             $form[$key] = $this->appendToFormRecurse($form[$key], $name_sub_element, $tmp_name_element[$key]);
         } else {
             /** @var $file File */
             $file = Builder::create(File::class);
             $file->name = $name_sub_element;
             $file->temporary_file_name = $tmp_name_element[$key];
             $form[$key] = $file;
         }
     }
     return $form;
 }
Esempio n. 19
0
 /**
  * Encodes the email into MIME format
  *
  * Returns the MIME Multipart string
  * If the mail is plain text without attachment, the plain text is returned without any change
  *
  * @return string
  */
 public function encode()
 {
     if ($this->email->attachments || strpos($this->email->content, '<body')) {
         /** @var $mail Mail_mime */
         $mail = Builder::create(Mail_mime::class);
         $body = $this->parseImages($mail, $this->email->content);
         $error_reporting = error_reporting();
         error_reporting(E_ALL & ~E_WARNING);
         $mail->setTXTBody(convert_html_to_text($this->email->content));
         error_reporting($error_reporting);
         $mail->setHTMLBody($body);
         $this->addAttachments($mail);
         $mime_params = ['text_encoding' => '8bit', 'text_charset' => 'UTF-8', 'html_charset' => 'UTF-8', 'head_charset' => 'UTF-8'];
         $body = $mail->get($mime_params);
         $this->email->headers = $mail->headers($this->email->getHeadersAsStrings());
         return $body;
     }
     return $this->email->content;
 }
Esempio n. 20
0
 /**
  * Apply namespace and use entries to the type name (if class)
  *
  * Return the full element class name, used to modify the type (multiple stays multiple)
  *
  * @param $namespace string
  * @param $use       string[]
  * @return string
  */
 public function applyNamespace($namespace, $use = [])
 {
     /** @var $this Annotation|Types_Annotation */
     /** @var $values string[] */
     $values = is_array($this->value) ? $this->value : [$this->value];
     foreach ($values as $key => $class_name) {
         if (ctype_upper($class_name[0])) {
             if (substr($class_name, -2) == '[]') {
                 $class_name = substr($class_name, 0, -2);
                 $multiple = '[]';
             } else {
                 $multiple = '';
             }
             $values[$key] = Builder::className((new Type($class_name))->applyNamespace($namespace, $use)) . $multiple;
         } elseif ($class_name[0] === BS) {
             $values[$key] = substr($class_name, 1);
         }
     }
     $this->value = is_array($this->value) ? $values : reset($values);
 }
Esempio n. 21
0
 /**
  * @param $template_file string
  * @param $parameters    array
  * @param $feature_name string
  * @return string
  */
 protected function executeTemplate($template_file, $parameters, $feature_name)
 {
     if (isset($parameters[Template::TEMPLATE])) {
         unset($parameters[Template::TEMPLATE]);
     }
     if (isset($parameters[Template::TEMPLATE_CLASS])) {
         $template_class = $parameters[Template::TEMPLATE_CLASS];
     } elseif (isset($parameters[Template::TEMPLATE_NAMESPACE])) {
         $template_class = $parameters[Template::TEMPLATE_NAMESPACE] . BS . 'Html_Template';
         unset($parameters[Template::TEMPLATE_NAMESPACE]);
     } else {
         $template_class = Template::class;
     }
     /** @var $template Template */
     $template = Builder::create($template_class, [reset($parameters), $template_file, $feature_name]);
     $template->setParameters($parameters);
     $current = Framework\View::current();
     if ($current instanceof Engine && ($css = $current->getCss())) {
         $template->setCss($css);
     }
     return $template->parse();
 }
Esempio n. 22
0
 /**
  * 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;
 }
Esempio n. 23
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);
         }
     }
 }
Esempio n. 24
0
 /**
  * @param $properties_list Reflection_Property[] new indices will be 'property.sub_property'
  * @param $property        Reflection_Property
  * @param $object          object
  * @param $property_name   string
  * @param $display_prefix  string
  * @param $blocks          string[]
  * @return Reflection_Property[] added properties list (empty if none applies) indices are
  *         'property.sub_property'
  * @todo probably things to clean up (was patched for 'all properties as values' without controls)
  */
 private static function expandUsingPropertyInternal(&$properties_list, $property, $object, $property_name, $display_prefix = '', $blocks = [])
 {
     $expanded = [];
     /** @var $integrated Integrated_Annotation */
     $integrated = $property->getListAnnotation('integrated');
     if ($integrated->value && !$property->isStatic()) {
         if ($integrated->has('block')) {
             $blocks[$property->path ?: $property->name] = $property->path ?: $property->name;
         }
         $integrated_simple = $integrated->has('simple');
         $sub_properties_class = $property->getType()->asReflectionClass();
         $expand_properties = $sub_properties_class->getProperties([T_EXTENDS, T_USE]);
         $value = $property->getValue($object) ?: Builder::create($property->getType()->asString());
         foreach ($expand_properties as $sub_property_name => $sub_property) {
             if (!$sub_property->getListAnnotation('user')->has(User_Annotation::INVISIBLE)) {
                 $display = $display_prefix . ($display_prefix ? DOT : '') . $property->name . DOT . $sub_property_name;
                 $sub_prefix = $integrated_simple ? $display_prefix : $display;
                 if ($more_expanded = self::expandUsingPropertyInternal($properties_list, $sub_property, $value, $property_name . DOT . $sub_property_name, $sub_prefix, $blocks)) {
                     $expanded = array_merge($expanded, $more_expanded);
                 } else {
                     $sub_property = new Reflection_Property_Value($sub_property->class, $sub_property->name, $value, false, true);
                     $sub_property->final_class = $sub_properties_class->name;
                     $sub_property->display = $integrated_simple ? $integrated->has('alias') ? $sub_property->getAnnotation('alias')->value : $sub_property_name : $display;
                     /** @var $block_annotation List_Annotation */
                     $block_annotation = $sub_property->setAnnotationLocal('block');
                     foreach ($blocks as $block) {
                         $block_annotation->add($block);
                     }
                     $sub_property->path = $property_name . DOT . $sub_property_name;
                     $properties_list[$property_name . DOT . $sub_property_name] = $sub_property;
                     $expanded[$property_name . DOT . $sub_property_name] = $sub_property;
                 }
             }
         }
     }
     return $expanded;
 }
Esempio n. 25
0
 /**
  * @param $view             string
  * @param $view_method_name string
  * @param $parameters       array
  * @param $form             array
  * @param $files            array
  * @param $class_name       string
  * @param $feature_name     string
  * @return mixed
  */
 private static function executeView($view, $view_method_name, $parameters, $form, $files, $class_name, $feature_name)
 {
     $object = reset($parameters);
     $view_object = is_object($object) && isA($object, $view) ? reset($parameters) : Builder::create($view);
     return $view_object->{$view_method_name}($parameters, $form, $files, $class_name, $feature_name);
 }
Esempio n. 26
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;
 }
Esempio n. 27
0
 /**
  * Extends the list of sources to compile
  *
  * When you modify a file, all these classes may have their matching mysql structure changed :
  * - the class itself
  * - all classes that extend the class or use the trait
  *
  * @param &$sources Reflection_Source[]
  * @return Reflection_Source[] added sources list
  */
 public function moreSourcesToCompile(&$sources)
 {
     $added = [];
     // Builder is disabled during the listing as we want to get the original linked class name when
     // reading class annotation @link
     Builder::current()->enabled = false;
     /** @var $search Dependency */
     $search = Search_Object::create(Dependency::class);
     $search->file_name = Func::notLike('cache/%');
     $search->type = Func::orOp([Dependency::T_EXTENDS, Dependency::T_USE]);
     foreach ($sources as $source) {
         foreach ($source->getClasses() as $class) {
             while ($linked_class = $class->getAnnotation('link')->value) {
                 $source = Reflection_Class::of($linked_class)->source;
                 if (!isset($sources[$source->file_name])) {
                     $sources[$source->file_name] = $source;
                     $added[$source->file_name] = $source;
                 }
                 $class = $source->getClass($linked_class);
             }
             $search->dependency_name = $class->name;
             foreach (Dao::search($search, Dependency::class) as $dependency) {
                 /** @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;
                 }
             }
         }
     }
     Builder::current()->enabled = true;
     return $added;
 }
Esempio n. 28
0
 /**
  * Create a clone of the object, using a built class if needed
  *
  * @param $object            object
  * @param $class_name        string if set, the new object will use the matching built class
  *                           this class name must inherit from the object's class
  * @param $properties_values array some properties values for the cloned object
  * @param $same_identifier   boolean
  * @return object
  */
 public static function createClone($object, $class_name = null, $properties_values = [], $same_identifier = true)
 {
     $class_name = self::className($class_name);
     $source_class_name = get_class($object);
     if (!isset($class_name)) {
         $class_name = self::className($source_class_name);
     }
     if ($class_name !== $source_class_name) {
         // initialises cloned object
         $clone = self::create($class_name);
         $destination_class = new Link_Class($class_name);
         // deactivate AOP
         if (isset($clone->_)) {
             $save_aop = $clone->_;
             unset($clone->_);
         }
         // copy official properties values from the source object
         $properties = (new Reflection_Class($source_class_name))->accessProperties();
         foreach ($properties as $property) {
             if (!isset($save_aop[$property->name])) {
                 $property->setValue($clone, $property->getValue($object));
             }
         }
         // copy unofficial properties values from the source object (ie AOP properties aliases)
         // clone collection objects using the destination collection property type
         $clone_collection = [];
         foreach (get_object_vars($object) as $property_name => $value) {
             if ($property_name !== '_' && !isset($properties[$property_name])) {
                 $clone->{$property_name} = $value;
                 if (isset($properties[rtrim($property_name, '_')])) {
                     $property = $properties[rtrim($property_name, '_')];
                     if ($property->getAnnotation('link') == Link_Annotation::COLLECTION) {
                         $element_class_from = $property->getType()->getElementTypeAsString();
                         $property = $destination_class->getProperty($property->name);
                         $element_class_to = $property->getType()->getElementTypeAsString();
                         if ($element_class_to != $element_class_from) {
                             $clone_collection[substr($property_name, 0, -1)] = $element_class_to;
                         }
                     }
                 }
             }
         }
         // reactivate AOP
         if (isset($save_aop)) {
             $clone->_ = $save_aop;
         }
         foreach ($clone_collection as $property_name => $element_class_to) {
             $elements = [];
             foreach ($object->{$property_name} as $key => $element) {
                 $elements[$key] = Builder::createClone($element, $element_class_to, [], $same_identifier);
             }
             $clone->{$property_name} = $elements;
         }
         // linked class object to link class object : store source object to linked object
         $destination_class = new Link_Class($class_name);
         if ($linked_class_name = $destination_class->getLinkedClassName()) {
             if ($linked_class_name == $source_class_name) {
                 $destination_class->getLinkProperty()->setValue($clone, $object);
             }
         }
         // identify destination object = source object, or disconnect destination object
         if ($same_identifier) {
             Dao::replace($clone, $object, false);
         } else {
             Dao::disconnect($clone);
         }
     } else {
         $clone = clone $object;
     }
     // copy added properties values to the cloned object
     if ($properties_values) {
         $properties = (new Reflection_Class($class_name))->accessProperties();
         foreach ($properties_values as $property_name => $value) {
             $properties[$property_name]->setValue($clone, $value);
         }
     }
     return $clone;
 }
Esempio n. 29
0
 /**
  * @param $property_name string
  * @param $format_value  boolean
  * @return mixed
  */
 protected function parseSingleValue($property_name, $format_value = true)
 {
     $source_object = $object = reset($this->objects);
     if (!strlen($property_name)) {
         $object = $this->parseParent();
     } elseif (is_numeric($property_name) && is_string($object)) {
         $object = substr($object, $property_name, 1);
     } elseif ($property_name === '#') {
         $object = reset($this->var_names);
     } elseif (strpos($property_name, '?')) {
         $object = $this->parseConditional($property_name);
     } elseif ($property_name[0] == Q && substr($property_name, -1) == Q || $property_name[0] == DQ && substr($property_name, -1) == DQ) {
         $object = $this->parseConstant($property_name);
     } elseif (isset($this->parse_class_name)) {
         if ($property_name === 'class') {
             $object = $this->parse_class_name;
         } elseif (method_exists($this->parse_class_name, $property_name)) {
             $object = $this->parseStaticMethod($this->parse_class_name, $property_name);
         } elseif (property_exists($this->parse_class_name, $property_name)) {
             $object = $this->parseStaticProperty($this->parse_class_name, $property_name);
         } elseif (defined($this->parse_class_name . '::' . $property_name)) {
             $object = constant($this->parse_class_name . '::' . $property_name);
         } else {
             $object = isA($this->parse_class_name, $this->parseClassName($property_name));
         }
         $this->parse_class_name = null;
     } elseif ($property_name[0] >= 'A' && $property_name[0] <= 'Z') {
         if (is_array($object) && (isset($object[$property_name]) || !@class_exists($property_name))) {
             $object = $this->parseArrayElement($object, $property_name);
         } elseif (strlen($property_name) > 1 && ($property_name[1] >= 'a' && $property_name[1] <= 'z' || strpos($property_name, BS) !== false)) {
             $this->parse_class_name = $this->parseClassName($property_name);
         } else {
             $object = $this->parseConst($object, $property_name);
         }
     } elseif ($property_name[0] === AT) {
         $object = $this->parseFunc(substr($property_name, 1));
     } elseif ($i = strpos($property_name, '(')) {
         if ((is_object($object) || ctype_upper($object[0])) && method_exists($object, substr($property_name, 0, $i))) {
             $object = $this->parseMethod($object, $property_name);
         } else {
             $object = $this->callFunc(reset($this->objects), $property_name);
         }
     } elseif (is_array($object)) {
         $object = $this->parseArrayElement($object, $property_name);
     } elseif (!is_object($object) && !isset($this->parameters[$property_name])) {
         $object = $this->parseString($object, $property_name);
     } elseif ((is_object($object) || is_string($object) && !empty($object) && ctype_upper($object[0])) && method_exists($object, $property_name)) {
         if ($property_name == 'value' && $object instanceof Reflection_Property && ($builder = $object->getAnnotation('widget')->value) && is_a($builder, Property::class, true)) {
             $builder = Builder::create($builder, [$object, $this->parseMethod($object, $property_name), $this]);
             /** @var $builder Property */
             $object = $builder->buildHtml();
             $format_value = false;
         } else {
             $object = $this->parseMethod($object, $property_name);
         }
     } elseif (isset($object->{$property_name})) {
         $object = $this->parseProperty($object, $property_name);
     } elseif (isset($this->parameters[$property_name])) {
         $object = $this->parseParameter($object, $property_name);
     } else {
         $object = $this->parseProperty($object, $property_name);
     }
     if ($format_value && $source_object instanceof Reflection_Property && $property_name == 'value') {
         $object = (new Reflection_Property_View($source_object))->formatValue($object);
     }
     return $object;
 }
Esempio n. 30
0
 /**
  * Parse a variable / function / include and returns its return value
  *
  * @param $property_name string can be an unique var or path.of.vars
  * @param $format_value  boolean
  * @return string var value after reading value / executing specs (can be an object)
  */
 protected function parseSingleValue($property_name, $format_value = true)
 {
     $property = $source_object = reset($this->objects);
     if ($property instanceof Reflection_Property_Value && $property_name == 'value') {
         if (($builder = $property->getAnnotation('widget')->value) && is_a($builder, Property::class, true)) {
             $builder = Builder::create($builder, [$property, $property->value(), $this]);
             /** @var $builder Property */
             $builder->parameters[Feature::F_EDIT] = Feature::F_EDIT;
             $value = $builder->buildHtml();
             if ($builder instanceof Value_Widget) {
                 $value = (new Html_Builder_Property($property, $value))->setTemplate($this)->build();
             }
         } else {
             $value = $property->getType()->isBoolean() ? $property->value() : parent::parseSingleValue($property_name, false);
             if (($preprop = lLastParse($property->pathAsField(), '[', 1, false)) && (!isset($this->cache[self::PARSED_ID]) || !isset($this->cache[self::PARSED_ID][$this->getFormId()]) || !isset($this->cache[self::PARSED_ID][$this->getFormId()][$preprop]))) {
                 $this->cache[self::PARSED_ID][$this->getFormId()][$preprop] = true;
                 if ($property instanceof Reflection_Property_Value) {
                     $parent_object = $property->getObject();
                     $id = isset($parent_object) ? Dao::getObjectIdentifier($parent_object) : null;
                     $html_builder_type = new Html_Builder_Type('id', null, $id, $preprop);
                     $id_value = $html_builder_type->setTemplate($this)->build();
                 } else {
                     $id_value = '';
                 }
             } else {
                 $id_value = '';
             }
             if ($property->getAnnotation('output')->value == 'string') {
                 $property->setAnnotationLocal('var')->value = 'string';
                 $value = isset($value) ? strval($value) : null;
                 $id_value = '';
             }
             $value = $id_value . (new Html_Builder_Property($property, $value))->setTemplate($this)->build();
         }
     } else {
         $value = parent::parseSingleValue($property_name);
     }
     return $value;
 }