/** * If no property contains the charater '*' in import file, automatically detects which property * names are used to identify records using the @representative classes annotation * * @param $class_name string * @param $properties_path string[] $property_path = string[integer $column_number] * @return array $identified = boolean[string $property_path][integer $position] */ private static function autoIdentify($class_name, $properties_path) { foreach ($properties_path as $property_path) { if (strpos($property_path, '*') !== false) { return []; } } $auto_identify = []; foreach ($properties_path as $property_path) { $class = new Reflection_Class($class_name); $representative = $class->getListAnnotation('representative')->values(); foreach (explode(DOT, $property_path) as $pos => $property_name) { if (in_array($property_name, $representative)) { $auto_identify[$property_path][$pos] = true; } $property = $class->getProperty($property_name); if (isset($property)) { $type = $property->getType(); if ($type->isClass()) { $class = new Reflection_Class($type->getElementTypeAsString()); $representative = $class->getListAnnotation('representative')->values(); } } } } return $auto_identify; }
/** * @param $property Reflection_Property * @param $map object[] */ public function __construct(Reflection_Property $property, $map) { $this->property = $property; $this->map = $map; $this->class_name = $this->property->getType()->getElementTypeAsString(); $class = new Reflection_Class($this->class_name); /** @var $representative Representative_Annotation */ $representative = $class->getListAnnotation('representative'); $this->properties = $representative->getProperties(); }
/** * @param $class_name string * @param $properties_path string[]|Reverse[] */ public function __construct($class_name, $properties_path = []) { $this->class_name = $class_name; if ($properties_path) { $this->properties_path = $properties_path; } else { $class = new Reflection_Class($class_name); $this->properties_path = $class->getListAnnotation('sort')->values(); } }
/** * Returns true if the element's property value changed since previous value * and if it is not empty * * @param $element object * @param $property_name string * @param $default_value mixed * @return boolean */ protected function valueChanged($element, $property_name, $default_value) { $id_property_name = 'id_' . $property_name; if (!isset($element->{$property_name}) && empty($id_property_name)) { return false; } $element_value = $element->{$property_name}; if (is_object($element_value)) { $class = new Reflection_Class(get_class($element_value)); $defaults = $class->getDefaultProperties(); foreach ($class->getListAnnotation('representative')->values() as $property_name) { if (isset($defaults[$property_name]) && $this->valueChanged($element_value, $property_name, $defaults[$property_name])) { return true; } } return false; } else { return isset($element_value) && strval($element_value) != '' && strval($element_value) != strval($default_value); } }
/** * Gets application parent classes names * Include extended parents using T_EXTENDS clause or @extends annotation * * @param $recursive boolean get all parents if true * @return string[] applications class names */ public static function getParentClasses($recursive = false) { $class_name = get_called_class(); $class = new Reflection_Class($class_name); $parent_class_name = get_parent_class($class_name); $extends_class_names = $class->getListAnnotation('extends')->values(); $parents = $parent_class_name ? array_merge([$parent_class_name], $extends_class_names) : $extends_class_names; if ($recursive) { foreach ($parents as $parent_class) { if ($parent_class) { $parents = array_merge($parents, call_user_func([$parent_class, 'getParentClasses'], true)); } } } return array_unique($parents); }
/** * @param $base_class string The base name for the class, ie 'SAF\Framework\User' * @param $feature_name string The name of the feature, ie 'dataList' * @param $suffix string Class suffix, ie 'Controller', 'View' * @param $extension string File extension, ie 'php', 'html' * @param $class_form boolean true to use 'Feature_Class' naming instead of 'featureClass' * @return string[] [$class, $method] */ public static function get($base_class, $feature_name, $suffix, $extension, $class_form = true) { // ie : $feature_class = 'featureName' transformed into 'Feature_Name' $feature_class = Names::methodToClass($feature_name); // $feature_what is $feature_class or $feature_name depending on $class_name $feature_what = $class_form ? $feature_class : $feature_name; $_suffix = $suffix ? '_' . $suffix : ''; $class_name = $base_class; $ext = DOT . $extension; $method = 'run'; $application_classes = Application::current()->getClassesTree(); // $classes : the controller class name and its parents // ['Vendor\Application\Module\Class_Name' => '\Module\Class_Name'] $classes = []; do { $classes[$class_name] = substr($class_name, strpos($class_name, BS, strpos($class_name, BS) + 1) + 1); if (@class_exists($class_name)) { $reflection_class = new Reflection_Class(Builder::className($class_name)); foreach ($reflection_class->getTraits() as $trait) { $classes[$trait->name] = explode(BS, $trait->name, 3)[2]; } foreach ($reflection_class->getListAnnotation('extends')->values() as $extends) { $classes[$extends] = explode(BS, $extends, 3)[2]; } } $class_name = @get_parent_class($class_name); } while ($class_name); // Looking for specific controller for each application $application_class = reset($application_classes); do { $namespace = Namespaces::of($application_class); // for the controller class and its parents foreach ($classes as $short_class_name) { $class_name = $namespace . BS . $short_class_name; $path = strtolower(str_replace(BS, SL, $class_name)); if (isset($GLOBALS['D'])) { echo '- try A1 ' . $path . SL . $feature_what . $_suffix . $ext . BR; } if (file_exists($path . SL . $feature_what . $_suffix . $ext)) { $class = $class_name . BS . $feature_what . $_suffix; break 2; } if (isset($GLOBALS['D'])) { echo '- try A2 ' . $path . SL . strtolower($feature_class) . SL . $feature_what . $_suffix . $ext . BR; } if (file_exists($path . SL . strtolower($feature_class) . SL . $feature_what . $_suffix . $ext)) { $class = $class_name . BS . $feature_class . BS . $feature_what . $_suffix; break 2; } if (isset($GLOBALS['D']) && $suffix) { echo '- try A3 ' . $path . SL . strtolower($feature_class) . SL . $suffix . $ext . BR; } if ($suffix && file_exists($path . SL . strtolower($feature_class) . SL . $suffix . $ext)) { $class = $class_name . BS . $feature_class . BS . $suffix; break 2; } if (isset($GLOBALS['D'])) { echo '- try A4 ' . Names::classToPath($class_name) . '_' . $feature_what . $_suffix . $ext . BR; } if (file_exists(Names::classToPath($class_name) . '_' . $feature_what . $_suffix . $ext)) { $class = $class_name . '_' . $feature_what . $_suffix; break 2; } if (isset($GLOBALS['D']) && $suffix) { echo '- try A5 ' . $path . SL . $suffix . $ext . BR; } if ($suffix && file_exists($path . SL . $suffix . $ext) && method_exists($class_name . BS . $suffix, 'run' . ucfirst($feature_name))) { $class = $class_name . BS . $suffix; $method = 'run' . ucfirst($feature_name); break 2; } } // next application is the parent one $application_class = next($application_classes); } while ($application_class); // Looking for default controller for each application if (empty($class)) { reset($application_classes); do { // looking for default controller $path = strtolower(str_replace(BS, SL, $namespace)); if (isset($GLOBALS['D']) && $suffix) { echo '- try B1 ' . $path . SL . strtolower($feature_class) . SL . $suffix . $ext . BR; } if ($suffix && file_exists($path . SL . strtolower($feature_class) . SL . $suffix . $ext)) { $class = $namespace . BS . $feature_class . BS . $suffix; break; } if (isset($GLOBALS['D'])) { echo '- try B2 ' . $path . SL . strtolower($feature_class) . SL . $feature_what . $_suffix . $ext . BR; } if (file_exists($path . SL . strtolower($feature_class) . SL . $feature_what . $_suffix . $ext)) { $class = $namespace . BS . $feature_class . BS . $feature_what . $_suffix; break; } if (isset($GLOBALS['D']) && $suffix) { echo '- try B3 ' . $path . SL . 'widget' . SL . strtolower($feature_class) . SL . $suffix . $ext . BR; } if ($suffix && file_exists($path . SL . 'widget' . SL . strtolower($feature_class) . SL . $suffix . $ext)) { $class = $namespace . BS . 'Widget' . BS . $feature_class . BS . $suffix; break; } if (isset($GLOBALS['D'])) { echo '- try B4 ' . $path . SL . 'widget' . SL . strtolower($feature_class) . SL . $feature_what . $_suffix . $ext . BR; } if (file_exists($path . SL . 'widget' . SL . strtolower($feature_class) . SL . $feature_what . $_suffix . $ext)) { $class = $namespace . BS . 'Widget' . BS . $feature_class . BS . $feature_what . $_suffix; break; } if (isset($GLOBALS['D']) && $suffix) { echo '- try B5 ' . $path . SL . 'webservice' . SL . strtolower($feature_class) . SL . $suffix . $ext . BR; } if ($suffix && file_exists($path . SL . 'webservice' . SL . strtolower($feature_class) . SL . $suffix . $ext)) { $class = $namespace . BS . 'Webservice' . BS . $feature_class . BS . $suffix; break; } if (isset($GLOBALS['D'])) { echo '- try B6 ' . $path . SL . 'webservice' . SL . strtolower($feature_class) . SL . $feature_what . $_suffix . $ext . BR; } if (file_exists($path . SL . 'webservice' . SL . strtolower($feature_class) . SL . $feature_what . $_suffix . $ext)) { $class = $namespace . BS . 'Webservice' . BS . $feature_class . BS . $feature_what . $_suffix; break; } // next application is the parent one } while (next($application_classes)); // Looking for direct feature call, without using any controller static $last_controller_class = ''; static $last_controller_method = ''; if (empty($class) && (strpos($suffix, 'View') === false || $last_controller_class !== $base_class && $last_controller_method !== $feature_name)) { if (strpos($suffix, 'Controller') !== false) { $last_controller_class = $base_class; $last_controller_method = $feature_name; } if (@method_exists($base_class, $feature_name)) { $class = $base_class; $method = $feature_name; } } // Looking for default controller for each application if (empty($class) && $suffix) { reset($application_classes); // $suffix == 'Html_View' => $sub = 'View/Html', $suffix = 'View' if (strpos($suffix, '_')) { $elements = explode('_', $suffix); $sub = join(SL, array_reverse($elements)); $suffix = end($elements); } else { $sub = $suffix; } do { if (isset($GLOBALS['D'])) { echo '- try C2 ' . $path . SL . strtolower($sub) . '/Default_' . $suffix . $ext . BR; } if (file_exists($path . SL . strtolower($sub) . '/Default_' . $suffix . $ext)) { $class = $namespace . BS . str_replace(SL, BS, $sub) . BS . 'Default_' . $suffix; break; } } while (next($application_classes)); } } $result = [isset($class) ? $class : null, $method]; if (isset($GLOBALS['D'])) { echo '- FOUND ' . join('::', $result) . BR; } return $result; }