/** * Returns the part of the string left to the last occurrence of the separator * * @param $str string * @param $sep string * @param $cnt int * @param $complete_if_not bool * @return string */ function lLastParse($str, $sep, $cnt = 1, $complete_if_not = true) { if ($cnt > 1) { $str = lLastParse($str, $sep, $cnt - 1); } $i = strrpos($str, $sep); if ($i === false) { return $complete_if_not ? $str : ''; } else { return substr($str, 0, $i); } }
/** * @param $property Reflection_Property * @param $value mixed * @param $preprop string */ public function __construct(Reflection_Property $property = null, $value = null, $preprop = null) { if (isset($property)) { $name = $property->pathAsField(); if (strpos($name, '[')) { $preprop2 = lLastParse($name, '['); $preprop = $preprop ? $preprop . '[' . lParse($preprop2, '[') . '[' . rParse($preprop2, '[') : $preprop2; $name = lParse(rLastParse($name, '['), ']'); } parent::__construct($name, $property->getType(), $value, $preprop); $this->null = $property->getAnnotation('null')->value; $this->property = $property; $this->readonly = $property->getListAnnotation('user')->has(User_Annotation::READONLY); } else { parent::__construct(null, null, $value, $preprop); } }
/** * 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; }
/** * Gets temporary file name, or write content into a temporary file name and get this name if not * set or file does not exist * * @return string */ private function getTemporaryFileName() { if (isset($this->content) && (empty($this->temporary_file_name) || !file_exists($this->temporary_file_name))) { if (empty($this->temporary_file_name)) { $this->temporary_file_name = Application::current()->getTemporaryFilesPath() . SL . uniqid() . '_' . $this->name; } if (strpos($this->temporary_file_name, SL) !== false) { Files::mkdir(lLastParse($this->temporary_file_name, SL)); } file_put_contents($this->temporary_file_name, $this->content); } return $this->temporary_file_name; }
include_once __DIR__ . '/saf/framework/functions/string_functions.php'; if ($argc < 3) { die('Arguments attendus : nickname helloworld' . LF); } $nickname = str_replace('.', '_', $argv[1]); $project_name = str_replace('.', '_', $argv[2]); $database = strtolower($nickname . '_' . $project_name); $username = substr($database, 0, 16); $project_password = uniqid(); $project_dir = __DIR__ . SL . strtolower($nickname . SL . $project_name); $application_file = $project_dir . SL . 'Application.php'; $config_file = __DIR__ . SL . strtolower($project_name) . '.php'; $namespace = ucfirst($nickname) . BS . ucfirst($project_name); $config_name = str_replace(BS, SL, $namespace); $helloworld_template = $project_dir . SL . 'Application_home.html'; $alias_script = lLastParse(__DIR__, SL) . SL . strtolower($project_name) . '.php'; $application_dir = rLastParse(__DIR__, SL); $local_file = __DIR__ . SL . 'loc.php'; $password_file = __DIR__ . SL . 'pwd.php'; $cache_dir = __DIR__ . SL . 'cache'; $tmp_dir = __DIR__ . SL . 'tmp'; $update_file = __DIR__ . SL . 'update'; $vendor_dir = __DIR__ . SL . 'vendor'; echo 'Initialization of your project ' . $namespace . '...' . LF; echo '- Create directory ' . $project_dir . LF; // /$nickname/$project/ if (!is_dir($project_dir)) { mkdir($project_dir, 0755, true); } echo '- Create application class file ' . $application_file . LF; // /$nickname/$project/Application.php
/** * Gets annotation name (the displayable root of the annotation class name, when set) * * @return string */ public function getAnnotationName() { return Names::classToDisplay(lLastParse(Namespaces::shortClassName(get_class($this)), '_Annotation')); }
/** * @param $filter integer[] what to you want to get */ private function get($filter) { $filter = array_flip($filter); $f_classes = isset($filter[self::CLASSES]); $f_dependencies = isset($filter[self::DEPENDENCIES]); $f_instantiates = isset($filter[self::INSTANTIATES]); $f_namespaces = isset($filter[self::NAMESPACES]); $f_requires = isset($filter[self::REQUIRES]); $f_uses = isset($filter[self::USES]); if ($f_classes) { $this->classes = []; } if ($f_dependencies) { $this->dependencies = []; } if ($f_instantiates) { $this->instantiates = []; } if ($f_namespaces) { $this->namespaces = []; } if ($f_requires) { $this->requires = []; } if ($f_uses) { $this->use = []; } // the current namespace $this->namespace = ''; if ($this->internal) { return; } // a blank class to have a valid scan beginning, but has no any other use $class = new Reflection_Class($this, ''); // how deep is the current class $class_depth = -1; // how deep we are in { $depth = 0; // where did the last } come $last_stop = null; // level for the T_USE clause : T_NAMESPACE, T_CLASS or T_FUNCTION (T_NULL if outside any level) $use_what = null; // what namespaces or class names does the current namespace use (key = val) $use = []; // scan tokens $this->getTokens(); $tokens_count = count($this->tokens); for ($this->token_key = 0; $this->token_key < $tokens_count; $this->token_key++) { $token = $this->tokens[$this->token_key]; $token_id = $token[0]; if (isset($class_end) && is_array($token)) { $class->stop = $token[2] - 1; unset($class_end); } // stop if ($token_id === '{') { $depth++; $token = $this->tokens[++$this->token_key]; } if ($token_id === '}') { $depth--; if ($depth === $class_depth) { $class_end = true; } while ($this->token_key + 1 < $tokens_count && !is_array($token)) { $token = $this->tokens[++$this->token_key]; } } // namespace if ($token_id === T_NAMESPACE) { $use_what = T_NAMESPACE; $this->namespace = $this->scanClassName($this->token_key); $use = []; if ($f_namespaces) { $this->namespaces[$this->namespace] = $token[2]; } } // require_once if (in_array($token_id, [T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE, T_REQUIRE_ONCE])) { $eval = str_replace(['__DIR__', '__FILE__'], [Q . lLastParse($this->file_name, SL) . Q, Q . $this->file_name . Q], $this->scanRequireFilePath()); if (strpos($eval, '$') !== false) { $require_name = $eval; } elseif (strpos($eval, '::') === false && strpos($eval, '->') === false) { /** @var $require_name string */ eval('$require_name = ' . $eval . ';'); if (!isset($require_name)) { trigger_error('Bad $require_name ' . $eval . ' into ' . $this->file_name . ' line ' . $token[2], E_USER_ERROR); } $guard = 10; while (strpos($require_name, '/../') && $guard--) { $require_name = preg_replace('%\\w+/../%', '', $require_name); } if (!$guard) { trigger_error('Guard woke up on ' . $require_name . ' into ' . $this->file_name . ' line ' . $token[2], E_USER_NOTICE); } } else { unset($require_name); } if (isset($require_name)) { if ($class->name) { $class->requires[$require_name] = $token[2]; } else { $this->requires[$require_name] = $token[2]; } } } elseif ($token_id === T_USE) { // namespace use if ($use_what == T_NAMESPACE) { foreach ($this->scanClassNames($this->token_key) as $used => $line) { $use[$used] = $used; if ($f_uses) { $this->use[$used] = $line; } } } elseif ($use_what === T_CLASS) { if ($f_dependencies) { foreach ($this->scanTraitNames($this->token_key) as $trait_name => $line) { $trait_name = $this->fullClassName($trait_name); $dependency = new Dependency(); $dependency->class_name = $class->name; $dependency->dependency_name = $trait_name; $dependency->file_name = $this->file_name; $dependency->line = $line; $dependency->type = Dependency::T_USE; $this->dependencies[] = $dependency; } } } elseif ($use_what == T_FUNCTION) { // ... } } elseif (in_array($token_id, [T_CLASS, T_INTERFACE, T_TRAIT])) { $use_what = T_CLASS; $class_name = $this->fullClassName($this->scanClassName(), false); $class = new Reflection_Class($this, $class_name); $class->line = $token[2]; $class->type = $token_id; $class_depth = $depth; if ($f_classes) { $this->classes[$class_name] = $class; } $dependency = new Dependency(); $dependency->class_name = $class->name; $dependency->declaration = self::$token_id_to_dependency_declaration[$token_id]; $dependency->dependency_name = $class->name; $dependency->file_name = $this->file_name; $dependency->line = $token[2]; $dependency->type = Dependency::T_DECLARATION; $this->dependencies[] = $dependency; } elseif ($token_id === T_FUNCTION) { $use_what = T_FUNCTION; } elseif (in_array($token_id, [T_EXTENDS, T_IMPLEMENTS])) { if ($f_dependencies) { foreach ($this->scanClassNames() as $class_name => $line) { $class_name = $this->fullClassName($class_name); $dependency = new Dependency(); $dependency->class_name = $class->name; $dependency->dependency_name = $class_name; $dependency->file_name = $this->file_name; $dependency->line = $line; $dependency->type = $this->nameOf($token_id); $this->dependencies[] = $dependency; } } } elseif ($token_id === T_DOC_COMMENT) { if ($f_instantiates) { $doc_comment = $token[1]; // 0 : everything until var name, 1 : type, 2 : Class_Name / $param, 3 : Class_Name preg_match_all('%\\*\\s+@(param|return|var)\\s+([\\w\\$\\[\\]\\|\\\\]+)(?:\\s+([\\w\\$\\[\\]\\|\\\\]+))?%', $doc_comment, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); foreach ($matches as $match) { list($class_name, $pos) = $match[2]; if ($class_name[0] === '$') { list($class_name, $pos) = isset($match[3]) ? $match[3] : 'null'; } foreach (explode('|', $class_name) as $class_name) { if (ctype_upper($class_name[0])) { $class_name = str_replace(['[', ']'], '', $class_name); $line = $token[2] + substr_count(substr($doc_comment, 0, $pos), LF); $type = $match[1][0]; $class_name = $this->fullClassName($class_name); $dependency = new Dependency(); $dependency->class_name = $class->name; $dependency->dependency_name = $class_name; $dependency->file_name = $this->file_name; $dependency->line = $line; $dependency->type = $type; $this->instantiates[] = $dependency; } } } } } elseif ($token_id === T_DOUBLE_COLON) { if ($f_instantiates) { $token = $this->tokens[$this->token_key - 1]; if ($token[1][0] !== '$' && !in_array($token[1], ['self', 'static', '__CLASS__'])) { $tk = $this->token_key - 1; $class_name = ''; do { $class_name = $this->tokens[$tk][1] . $class_name; $tk--; } while (in_array($this->tokens[$tk][0], [T_NS_SEPARATOR, T_STRING])); $type = $this->tokens[++$this->token_key]; $type = is_array($type) && $type[1] === 'class' ? Dependency::T_CLASS : Dependency::T_STATIC; $class_name = $this->fullClassName($class_name); $dependency = new Dependency(); $dependency->class_name = $class->name; $dependency->dependency_name = $class_name; $dependency->file_name = $this->file_name; $dependency->line = $token[2]; $dependency->type = $type; $this->instantiates[] = $dependency; } } else { $this->token_key++; } } elseif ($token_id === T_NEW) { if ($f_instantiates) { $class_name = $this->scanClassName(); // $class_name is empty when 'new $class_name' (dynamic class name) : then ignore if ($class_name) { $class_name = $this->fullClassName($class_name); $dependency = new Dependency(); $dependency->class_name = $class->name; $dependency->dependency_name = $class_name; $dependency->file_name = $this->file_name; $dependency->line = $token[2]; $dependency->type = Dependency::T_NEW; $this->instantiates[] = $dependency; } } } } }
/** * @param $parameters Parameters * @param $form array * @param $files array * @param $class_name string * @return mixed * @todo factorize */ public function run(Parameters $parameters, $form, $files, $class_name) { // convert form files to worksheets and session files if ($files) { /** @var $import Import */ $import = $parameters->getMainObject(Import::class); $import->class_name = $class_name; $form = (new Post_Files())->appendToForm($form, $files); foreach ($form as $file) { if ($file instanceof File) { if (!isset($session_files)) { /** @var $session_files Files */ $session_files = Builder::create(Files::class); } $excel = Spreadsheet_File::fileToArray($file->temporary_file_name, $errors); $worksheet_number = 0; foreach ($excel as $temporary_file_name => $worksheet) { if (filesize($temporary_file_name) > 1) { $import_worksheet = Builder::create(Import_Worksheet::class, [$worksheet_number++, Import_Settings_Builder::buildArray($worksheet, $class_name), $csv_file = Builder::create(File::class, [$temporary_file_name])]); $import_worksheet->errors = $errors; $session_files->files[] = $csv_file; $import->worksheets[] = $import_worksheet; } } // only one file once break; } } if (isset($session_files)) { Session::current()->set($session_files); } } else { /** @var $files File[] */ $files = Session::current()->get(Files::class)->files; $parameters->unshift($import = Import_Builder_Form::build($form, $files)); $import->class_name = $class_name; } // prepare parameters $parameters = $parameters->getObjects(); $general_buttons = $this->getGeneralButtons($class_name); if (isset($parameters['constant_remove']) && strtoupper($parameters['constant_remove'][0]) === $parameters['constant_remove'][0]) { $parameters['constant_remove'] = rParse($parameters['constant_remove'], DOT); } foreach ($import->worksheets as $worksheet) { // apply controller parameters if (isset($parameters['constant_add']) && isset($worksheet->settings->classes[$parameters['constant_add']])) { $worksheet->settings->classes[$parameters['constant_add']]->addConstant(); } if (isset($parameters['constant_remove']) && isset($worksheet->settings->classes[lLastParse($parameters['constant_remove'], DOT, 1, false)])) { $worksheet->settings->classes[lLastParse($parameters['constant_remove'], DOT, 1, false)]->removeConstant(rLastParse($parameters['constant_remove'], DOT, 1, true)); } Custom_Settings_Controller::applyParametersToCustomSettings($worksheet->settings, array_merge($form, $parameters)); } // recover empty Import_Settings (after loading empty one) /** @var $files File[] */ $files = Session::current()->get(Files::class)->files; foreach ($import->worksheets as $worksheet_number => $worksheet) { if (empty($worksheet->settings->classes)) { $file = $files[$worksheet_number]; $array = $file->getCsvContent(); $import->worksheets[$worksheet_number] = new Import_Worksheet($worksheet_number, Import_Settings_Builder::buildArray($array, $class_name), $file); } } // get general buttons and customized import settings foreach ($import->worksheets as $worksheet_number => $worksheet) { $customized_import_settings = $worksheet->settings->getCustomSettings(); $worksheet_general_buttons = $general_buttons; if (!isset($customized_import_settings[$worksheet->settings->name])) { unset($worksheet_general_buttons['delete']); } $parameters['custom'][$worksheet_number] = new StdClass(); $parameters['custom'][$worksheet_number]->customized_lists = $customized_import_settings; $parameters['custom'][$worksheet_number]->general_buttons = $worksheet_general_buttons; $parameters['custom'][$worksheet_number]->settings = $worksheet->settings; $parameters['custom'][$worksheet_number]->aliases_property = Import_Array::getPropertiesAlias($worksheet->settings->getClassName()); $parameters['custom'][$worksheet_number]->properties_alias = array_flip($parameters['custom'][$worksheet_number]->aliases_property); } // view $parameters[Template::TEMPLATE] = 'importPreview'; return View::run($parameters, $form, $files, $class_name, Feature::F_IMPORT); }