/** * Return a list of SQL where conditions (flattened as a list of strings) * * @return array */ public function getWhere() { Deprecation::notice('4.0', 'SQLQuery::getWhere is non-parameterised for backwards compatibility. ' . 'Use ->toAppropriateExpression()->getWhere() instead'); $conditions = parent::getWhere(); // This is where any benefits of parameterised queries die return $this->getParameterInjector()->injectConditions($conditions); }
/** * Remove a filter from the query * * @param string|array $fieldExpression The predicate of the condition to remove * (ignoring parameters). The expression will be considered a match if it's * contained within any other predicate. * @return DataQuery Self reference */ public function removeFilterOn($fieldExpression) { $matched = false; // If given a parameterised condition extract only the condition if (is_array($fieldExpression)) { reset($fieldExpression); $fieldExpression = key($fieldExpression); } $where = $this->query->getWhere(); // Iterate through each condition foreach ($where as $i => $condition) { // Rewrite condition groups as plain conditions before comparison if ($condition instanceof SQLConditionGroup) { $predicate = $condition->conditionSQL($parameters); $condition = array($predicate => $parameters); } // As each condition is a single length array, do a single // iteration to extract the predicate and parameters foreach ($condition as $predicate => $parameters) { // @see SQLSelect::addWhere for why this is required here if (strpos($predicate, $fieldExpression) !== false) { unset($where[$i]); $matched = true; } // Enforce single-item condition predicate => parameters structure break; } } // set the entire where clause back, but clear the original one first if ($matched) { $this->query->setWhere($where); } else { throw new InvalidArgumentException("Couldn't find {$fieldExpression} in the query filter."); } return $this; }
public function conditionSQL(&$parameters) { $parameters = array(); // Ignore empty conditions $where = $this->whereQuery->getWhere(); if (empty($where)) { return null; } // Allow database to manage joining of conditions $sql = DB::get_conn()->getQueryBuilder()->buildWhereFragment($this->whereQuery, $parameters); return preg_replace('/^\\s*WHERE\\s*/i', '', $sql); }
/** * Changes any SELECT query thats not filtering on an ID * to limit by the current language defined in {@link get_current_locale()}. * It falls back to "Locale='' OR Lang IS NULL" and assumes that * this implies querying for the default language. * * Use {@link disable_locale_filter()} to temporarily disable this "auto-filtering". */ public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null) { // If the record is saved (and not a singleton), and has a locale, // limit the current call to its locale. This fixes a lot of problems // with other extensions like Versioned if ($this->owner->ID && !empty($this->owner->Locale)) { $locale = $this->owner->Locale; } else { $locale = Translatable::get_current_locale(); } $baseTable = ClassInfo::baseDataClass($this->owner->class); if ($locale && self::locale_filter_enabled() && $dataQuery->getQueryParam(self::QUERY_LOCALE_FILTER_ENABLED) && !$query->filtersOnID() && array_search($baseTable, array_keys($query->getFrom())) !== false) { // Or we're already filtering by Lang (either from an earlier augmentSQL() // call or through custom SQL filters) $filtersOnLocale = array_filter($query->getWhere(), function ($predicates) { foreach ($predicates as $predicate => $params) { if (preg_match('/("|\'|`)Locale("|\'|`)/', $predicate)) { return true; } } }); if (!$filtersOnLocale) { $qry = sprintf('"%s"."Locale" = \'%s\'', $baseTable, Convert::raw2sql($locale)); $query->addWhere($qry); } } }