/** * Analyzes the given comparison expression and alters it according. * * @param \Cake\Database\Expression\Comparison $expression Comparison expression * @param string $bundle Consider attributes only for a specific bundle * @param \Cake\ORM\Query $query The query instance this expression comes from * @return \Cake\Database\Expression\Comparison Scoped expression (or not) */ protected function _inspectComparisonExpression(Comparison $expression, $bundle, Query $query) { $field = $expression->getField(); $column = is_string($field) ? $this->_toolbox->columnName($field) : ''; if (empty($column) || in_array($column, (array) $this->_table->schema()->columns()) || !in_array($column, $this->_toolbox->getAttributeNames()) || !$this->_toolbox->isSearchable($column)) { // nothing to alter return $expression; } $attr = $this->_toolbox->attributes($bundle)[$column]; $value = $expression->getValue(); $type = $this->_toolbox->getType($column); $conjunction = $expression->getOperator(); $conditions = ['EavValues.eav_attribute_id' => $attr['id'], "EavValues.value_{$type} {$conjunction}" => $value]; // subquery scope $subQuery = TableRegistry::get('Eav.EavValues')->find()->select('EavValues.entity_id')->where($conditions); // some variables $pk = $this->_tablePrimaryKey(); $driverClass = $this->_driverClass($query); switch ($driverClass) { case 'sqlite': $concat = implode(' || ', $pk); $field = "({$concat} || '')"; break; case 'mysql': case 'postgres': case 'sqlserver': default: $concat = implode(', ', $pk); $field = "CONCAT({$concat}, '')"; break; } // compile query, faster than raw subquery in most cases $ids = $subQuery->all()->extract('entity_id')->toArray(); $ids = empty($ids) ? ['-1'] : $ids; $expression->setField($field); $expression->setValue($ids); $expression->setOperator('IN'); $class = new \ReflectionClass($expression); $property = $class->getProperty('_type'); $property->setAccessible(true); $property->setValue($expression, 'string'); $property = $class->getProperty('_isMultiple'); $property->setAccessible(true); $property->setValue($expression, true); return $expression; }
/** * Método a ser usado como callable no beforeFind. * @param Comparison $comparison O objeto de comparação da query * @return void */ public function traverseClause($comparison) { if (isset($comparison)) { if ($this->_table->schema()->columnType($comparison->getField()) === "float") { if (is_string($comparison->getValue()) && !preg_match('/^[0-9]+(\\.[0-9]+)?$/', $comparison->getValue())) { $comparison->setValue(str_replace(',', '.', str_replace('.', '', $comparison->getValue()))); } } } }