/** * Convert given query condition value which is supposed to contain types * identifiers to integer identifiers * * This function will take care of awaited query format */ public function convertQueryCondition($value) { // First fetch the type if (null === $value) { return 0; } if (!is_array($value)) { $value = [$value]; } $hasOperator = false; // FIXME Sorry for this if (!Misc::isIndexed($value)) { // We have an operator. $operator = array_keys($value)[0]; $values = $value[$operator][0]; $hasOperator = true; } else { $values = $value; } foreach ($values as $key => $type) { if (null === $type) { $values[$key] = 0; } else { if ($typeId = $this->getTypeId($type, false)) { $values[$key] = $typeId; } else { unset($values[$key]); } } } if (empty($values)) { // It should not have been empty, this is an impossible // condition $values = [-1]; } if ($hasOperator) { return [$operator => $values]; } else { return $values; } }
/** * Notify an action happened on a resource in an arbitrary channel * * @param string|string[] $chanId * @param string $resourceType * @param string|string[] $resourceId * @param string $action * @param array $data * Arbitrary data to send along * @param int $level * Arbitrary level, see Notification::LEVEL_* constants. This value is * purely arbitrary, it is up to the business layer to do something with * it. It does not alters the notification system behavior. * @param boolean $doExcludeCurrent * If set to false the current subscribers won't be excluded from the * current notification recipient list */ public function notifyChannel($chanId, $resourceType, $resourceId, $action, $data = [], $level = null, $doExcludeCurrent = true) { if (null === $level) { $level = NotificationInterface::LEVEL_INFO; } $chanIdList = Misc::toIterable($chanId); $data = ['data' => $data]; $data['id'] = Misc::toArray($resourceId); $type = $resourceType . ':' . $action; try { $exclude = []; if ($doExcludeCurrent && $this->currentSubscribers) { foreach ($this->currentSubscribers as $name) { // Using getSubscriptionIds() will avoid an odd number of // backend queries (at least for SQL backend). I do hope // that our current subscriber does not have thousands... $exclude = array_merge($exclude, $this->backend->getSubscriber($name)->getSubscriptionsIds()); } } $this->prepareNotification($type, $data, $level); // Channels are not automatically created // TODO Find a better a way, to filter out non-existing channels $this->backend->createChannels($chanIdList, true); $this->backend->send($chanIdList, $data, $type, null, $level, $exclude); } catch (ChannelDoesNotExistException $e) { // Nothing to do, no channel means no subscription } catch (Exception $e) { // Any other exception must be shutdown when in production mode if (!$this->silentMode) { throw $e; } } }
/** * Add channel to notification destination * * @param string|string[] $chanId */ public function addArbitraryChanId($chanId) { foreach (Misc::toIterable($chanId) as $id) { $this->chanIdList[] = $id; } }
/** * Add one or more recipients to this thread * * @param string $threadId * Thread identifier * @param string|string[] $userId * User identifier or list of user identifiers */ public function addRecipientsTo($threadId, $userIdList) { $subList = []; foreach (Misc::toIterable($userIdList) as $userId) { $subList[] = $this->backend->getSubscriber($this->getUserSubscriberId($userId))->subscribe($threadId)->getId(); } $this->backend->copyQueue($threadId, $subList); }
/** * Apply the operator onto the query * * @param \SelectQueryInterface $query * @param string $statement * @param string $value */ protected final function applyOperator(\SelectQueryInterface $query, $statement, $value) { // Check if $value contains an operator (i.e. if is associative array) if (is_array($value) && !Misc::isIndexed($value)) { // First key will be the operator $keys = array_keys($value); $operator = $keys[0]; $value = $value[$operator]; switch ($operator) { case '<>': if (is_array($value)) { $query->condition($statement, $value, 'NOT IN'); } else { $query->condition($statement, $value, '<>'); } break; case 'exists': $query->exists($value); break; case 'in': $query->condition($statement, $value, 'IN'); break; default: $query->condition($statement, $value, $operator); break; } } else { if (null === $value) { $query->isNull($statement); } else { $query->condition($statement, $value); } } }