|
|
|
|
@ -477,40 +477,55 @@ class UserConfig implements IUserConfig {
|
|
|
|
|
$this->assertParams('', $app, $key, allowEmptyUser: true);
|
|
|
|
|
$this->matchAndApplyLexiconDefinition('', $app, $key);
|
|
|
|
|
|
|
|
|
|
$lexiconEntry = $this->getLexiconEntry($app, $key);
|
|
|
|
|
if ($lexiconEntry?->isFlagged(self::FLAG_INDEXED) === false) {
|
|
|
|
|
$this->logger->notice('UserConfig+Lexicon: using searchUsersByTypedValue on a config key not set as indexed');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$qb = $this->connection->getQueryBuilder();
|
|
|
|
|
$qb->from('preferences');
|
|
|
|
|
$qb->select('userid');
|
|
|
|
|
$qb->where($qb->expr()->eq('appid', $qb->createNamedParameter($app)));
|
|
|
|
|
$qb->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter($key)));
|
|
|
|
|
|
|
|
|
|
// search within 'indexed' OR 'configvalue' only if 'flags' is set as not indexed
|
|
|
|
|
// TODO: when implementing config lexicon remove the searches on 'configvalue' if value is set as indexed
|
|
|
|
|
$configValueColumn = ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) ? $qb->expr()->castColumn('configvalue', IQueryBuilder::PARAM_STR) : 'configvalue';
|
|
|
|
|
if (is_array($value)) {
|
|
|
|
|
$where = $qb->expr()->orX(
|
|
|
|
|
$qb->expr()->in('indexed', $qb->createNamedParameter($value, IQueryBuilder::PARAM_STR_ARRAY)),
|
|
|
|
|
$qb->expr()->andX(
|
|
|
|
|
$qb->expr()->neq($qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED), $qb->createNamedParameter(self::FLAG_INDEXED, IQueryBuilder::PARAM_INT)),
|
|
|
|
|
$qb->expr()->in($configValueColumn, $qb->createNamedParameter($value, IQueryBuilder::PARAM_STR_ARRAY))
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
if ($caseInsensitive) {
|
|
|
|
|
$where = $qb->expr()->in('indexed', $qb->createNamedParameter($value, IQueryBuilder::PARAM_STR_ARRAY));
|
|
|
|
|
// in case lexicon does not exist for this key - or is not set as indexed - we keep searching for non-index entries if 'flags' is set as not indexed
|
|
|
|
|
if ($lexiconEntry?->isFlagged(self::FLAG_INDEXED) !== true) {
|
|
|
|
|
$where = $qb->expr()->orX(
|
|
|
|
|
$qb->expr()->eq($qb->func()->lower('indexed'), $qb->createNamedParameter(strtolower($value))),
|
|
|
|
|
$where,
|
|
|
|
|
$qb->expr()->andX(
|
|
|
|
|
$qb->expr()->neq($qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED), $qb->createNamedParameter(self::FLAG_INDEXED, IQueryBuilder::PARAM_INT)),
|
|
|
|
|
$qb->expr()->eq($qb->func()->lower($configValueColumn), $qb->createNamedParameter(strtolower($value)))
|
|
|
|
|
$qb->expr()->in($configValueColumn, $qb->createNamedParameter($value, IQueryBuilder::PARAM_STR_ARRAY))
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ($caseInsensitive) {
|
|
|
|
|
$where = $qb->expr()->eq($qb->func()->lower('indexed'), $qb->createNamedParameter(strtolower($value)));
|
|
|
|
|
// in case lexicon does not exist for this key - or is not set as indexed - we keep searching for non-index entries if 'flags' is set as not indexed
|
|
|
|
|
if ($lexiconEntry?->isFlagged(self::FLAG_INDEXED) !== true) {
|
|
|
|
|
$where = $qb->expr()->orX(
|
|
|
|
|
$where,
|
|
|
|
|
$qb->expr()->andX(
|
|
|
|
|
$qb->expr()->neq($qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED), $qb->createNamedParameter(self::FLAG_INDEXED, IQueryBuilder::PARAM_INT)),
|
|
|
|
|
$qb->expr()->eq($qb->func()->lower($configValueColumn), $qb->createNamedParameter(strtolower($value)))
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$where = $qb->expr()->orX(
|
|
|
|
|
$qb->expr()->eq('indexed', $qb->createNamedParameter($value)),
|
|
|
|
|
$qb->expr()->andX(
|
|
|
|
|
$qb->expr()->neq($qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED), $qb->createNamedParameter(self::FLAG_INDEXED, IQueryBuilder::PARAM_INT)),
|
|
|
|
|
$qb->expr()->eq($configValueColumn, $qb->createNamedParameter($value))
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
$where = $qb->expr()->eq('indexed', $qb->createNamedParameter($value));
|
|
|
|
|
// in case lexicon does not exist for this key - or is not set as indexed - we keep searching for non-index entries if 'flags' is set as not indexed
|
|
|
|
|
if ($lexiconEntry?->isFlagged(self::FLAG_INDEXED) !== true) {
|
|
|
|
|
$where = $qb->expr()->orX(
|
|
|
|
|
$where,
|
|
|
|
|
$qb->expr()->andX(
|
|
|
|
|
$qb->expr()->neq($qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED), $qb->createNamedParameter(self::FLAG_INDEXED, IQueryBuilder::PARAM_INT)),
|
|
|
|
|
$qb->expr()->eq($configValueColumn, $qb->createNamedParameter($value))
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1408,13 +1423,19 @@ class UserConfig implements IUserConfig {
|
|
|
|
|
$this->assertParams('', $app, $key, allowEmptyUser: true);
|
|
|
|
|
$this->matchAndApplyLexiconDefinition('', $app, $key);
|
|
|
|
|
|
|
|
|
|
foreach (array_keys($this->getValuesByUsers($app, $key)) as $userId) {
|
|
|
|
|
try {
|
|
|
|
|
$this->updateIndexed($userId, $app, $key, $indexed);
|
|
|
|
|
} catch (UnknownKeyException) {
|
|
|
|
|
// should not happen and can be ignored
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$bitPosition = log(self::FLAG_INDEXED) / log(2); // emulate base-2 logarithm (log2)
|
|
|
|
|
$bitOperation = ($indexed) ? '`flags` | (1 << ' . $bitPosition . ')' : '`flags` & ~(1 << ' . $bitPosition . ')';
|
|
|
|
|
|
|
|
|
|
$update = $this->connection->getQueryBuilder();
|
|
|
|
|
$update->update('preferences')
|
|
|
|
|
->set('flags', $update->createFunction($bitOperation))
|
|
|
|
|
->set('indexed', ($indexed) ? 'configvalue' : $update->createNamedParameter(''))
|
|
|
|
|
->where(
|
|
|
|
|
$update->expr()->eq('appid', $update->createNamedParameter($app)),
|
|
|
|
|
$update->expr()->eq('configkey', $update->createNamedParameter($key))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$update->executeStatement();
|
|
|
|
|
|
|
|
|
|
// we clear all cache
|
|
|
|
|
$this->clearCacheAll();
|
|
|
|
|
|