public function testBuildMultiple()
 {
     $this->assume(__METHOD__ . '.simple', (new Tools\Search_Array_Builder())->buildMultiple(['pro1', 'pro2'], 'test'), Func::orOp(['pro1' => 'test', 'pro2' => 'test']));
     $this->assume(__METHOD__ . '.and', (new Tools\Search_Array_Builder())->buildMultiple(['pro1', 'pro2'], 'test what'), Func::andOp([Func::orOp(['pro1' => 'test', 'pro2' => 'test']), Func::orOp(['pro1' => '%what', 'pro2' => '%what'])]));
     $this->assume(__METHOD__ . '.or', (new Tools\Search_Array_Builder())->buildMultiple(['pro1', 'pro2'], 'test,what'), Func::orOp(['pro1' => ['test', 'what'], 'pro2' => ['test', 'what']]));
     $this->assume(__METHOD__ . '.mix', (new Tools\Search_Array_Builder())->buildMultiple(['pro1', 'pro2'], 'test,what else'), Func::orOp(['pro1' => ['test', Func::andOp(['what', '%else'])], 'pro2' => ['test', Func::andOp(['what', '%else'])]]));
 }
Пример #2
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;
 }
Пример #3
0
 /**
  * @param $property_names_or_class string[]|Reflection_Class
  * @param $search_phrase string
  * @param $prepend string
  * @param $append string
  * @return Logical|array
  */
 public function buildMultiple($property_names_or_class, $search_phrase, $prepend = '', $append = '')
 {
     $property_names = $property_names_or_class instanceof Reflection_Class ? $this->classRepresentativeProperties($property_names_or_class) : $property_names_or_class;
     // search phrase contains OR
     if (strpos($search_phrase, $this->or) !== false) {
         $or = [];
         foreach ($property_names as $property_name) {
             $or[$property_name] = $this->build('', $search_phrase, $prepend, $append);
         }
         $result = Func::orOp($or);
     } elseif (strpos($search_phrase, $this->and) !== false) {
         $and = [];
         foreach (explode($this->and, $search_phrase) as $search) {
             $and[] = $this->buildMultiple($property_names, $search, $prepend, $append);
             $prepend = '%';
         }
         $result = Func::andOp($and);
     } else {
         $or = [];
         foreach ($property_names as $property_name) {
             $or[$property_name] = $prepend . $search_phrase . $append;
         }
         $result = count($or) > 1 ? Func::orOp($or) : $or;
     }
     return $result;
 }
 /**
  * @param $object object
  * @return string[] combo filters
  */
 protected function getFilters($object)
 {
     $filters = ['id' => Func::notEqual(Dao::getObjectIdentifier($object))];
     foreach ((new Reflection_Class(get_class($object)))->getProperties([T_EXTENDS, T_USE]) as $property) {
         if ($property->getAnnotation('replace_filter')->value) {
             $filters[$property->name] = Dao::getObjectIdentifier($object, $property->name);
         }
     }
     return $filters;
 }
Пример #5
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 '';
 }
Пример #6
0
 /**
  * @param $object Framework\Logger
  */
 public function onLoggerStop(Framework\Logger $object)
 {
     if ($this->log_flag) {
         Dao::begin();
         foreach (Dao::search(['log' => Func::isNull()], Compiler_Log::class) as $logger) {
             /** @var $logger Compiler_Log */
             $logger->log = $object->log_entry;
             Dao::write($logger, [Dao::only(['log'])]);
         }
         $this->log_flag = false;
         Dao::commit();
     }
 }
Пример #7
0
 /**
  * Returns the Dao function as SQL
  *
  * @param $builder       Builder\Where the sql query builder
  * @param $property_path string the property path
  * @param $prefix        string
  * @return string
  */
 public function toSql(Builder\Where $builder, $property_path, $prefix = '')
 {
     $joins = $builder->getJoins();
     // sub-query
     $class_name = $joins->getStartingClassName();
     $properties = $this->properties + [$property_path => Func::max()];
     $sub_builder = new Builder\Select($class_name, $properties, null, $builder->getSqlLink(), [Dao::groupBy($this->properties)]);
     // join
     $join = new Subquery($sub_builder);
     $joins->addJoin($join);
     // where
     $where = '';
     foreach (array_merge($this->properties, [$property_path]) as $property) {
         $where .= ' AND ' . $join->foreign_alias . DOT . BQ . rLastParse($property, DOT, 1, true) . BQ . ' = ' . $builder->buildColumn($property, $prefix);
     }
     $join->where = substr($where, 5);
     return null;
 }
Пример #8
0
 /**
  * @param $last_time integer compile only files modified since this time
  */
 public function compile($last_time = 0)
 {
     set_time_limit(900);
     clearstatcache();
     $cache_dir = $this->getCacheDir();
     // create data set for dependencies, check for dependencies for deleted files
     Dao::createStorage(Dependency::class);
     Dao::begin();
     if (isset($_GET['Z'])) {
         $link = Dao::current();
         if ($link instanceof Link) {
             $link->query('TRUNCATE TABLE `dependencies`');
         }
     }
     foreach (Dao::select(Dependency::class, ['file_name' => Func::distinct()]) as $file_dependency) {
         /** @var $file_dependency List_Row */
         $file_name = $file_dependency->getValue('file_name');
         if (!file_exists($file_name)) {
             foreach (Dao::search(['file_name' => $file_name], Dependency::class) as $dependency) {
                 /** @var $dependency Dependency */
                 Dao::delete($dependency);
                 foreach (Dao::search(['dependency_name' => $dependency->class_name], Dependency::class) as $sub_dependency) {
                     /** @var $sub_dependency Dependency */
                     Dao::delete($sub_dependency);
                 }
             }
         }
     }
     Dao::commit();
     $this->sources = array_merge($this->more_sources, $this->getFilesToCompile($last_time));
     $first_group = true;
     foreach ($this->compilers as $compilers) {
         /** @var $compilers ICompiler[] */
         $saved_sources = $this->sources;
         while ($this->sources) {
             // get source and update dependencies
             foreach ($this->sources as $source) {
                 /** @var Reflection_Source $source inspector bug */
                 /** @noinspection PhpParamsInspection inspector bug (a Dependency is an object) */
                 (new Set())->replace($source->getDependencies(true), Dependency::class, ['file_name' => $source->file_name]);
             }
             do {
                 $added = [];
                 // ask each compiler for adding of compiled files, until they have nothing to add
                 foreach ($compilers as $compiler) {
                     if ($compiler instanceof Needs_Main) {
                         $compiler->setMainController($this->main_controller);
                     }
                     $added = array_merge($added, $compiler->moreSourcesToCompile($this->sources));
                 }
                 foreach ($added as $source) {
                     /** @var Reflection_Source $source inspector bug */
                     /** @noinspection PhpParamsInspection inspector bug (a Dependency is an object) */
                     (new Set())->replace($source->getDependencies(true), Dependency::class, ['file_name' => $source->file_name]);
                     $this->sources[$source->file_name] = $source;
                 }
                 if (count($compilers) == 1) {
                     $added = [];
                 }
             } while ($added);
             $saved_sources = array_merge($saved_sources, $this->sources);
             // fill in sources cache
             $sources_count = count($this->sources);
             foreach ($this->sources as $source) {
                 foreach (array_keys($source->getClasses()) as $class_name) {
                     $this->sources_cache[$class_name] = $source;
                 }
                 if ($sources_count > self::MAX_OPENED_SOURCES) {
                     $source->free(self::SOURCES_FREE);
                 }
             }
             // compile sources
             foreach ($this->sources as $source) {
                 $this->compileSource($source, $compilers, $cache_dir, $first_group, $sources_count);
             }
             $this->sources = $this->more_sources;
             $this->more_sources = [];
             foreach ($this->sources as $source) {
                 if (!isset($saved_sources[$source->file_name])) {
                     $saved_sources[$source->file_name] = $source;
                 }
             }
         }
         $this->sources = $saved_sources;
         $first_group = false;
     }
     $this->sources = null;
 }
Пример #9
0
 public function testLeftMatch()
 {
     $builder = new Select(Order::class, null, ['number' => Func::leftMatch('N01181355010')]);
     $this->assume(__METHOD__, $builder->buildQuery(), 'SELECT t0.*' . LF . 'FROM `orders` t0' . LF . 'WHERE t0.`number` = LEFT("N01181355010", LENGTH(t0.`number`))');
 }