public function testParameter_fail() { try { Assert::parameter(false, 'test', 'testing'); } catch (ParameterAssertionException $ex) { $this->assertEquals('test', $ex->getParameterName()); } }
/** * Constructs a TitleValue. * * @note TitleValue expects a valid DB key; typically, a TitleValue is constructed either * from a database entry, or by a TitleParser. We could apply "some" normalization here, * such as substituting spaces by underscores, but that would encourage the use of * un-normalized text when constructing TitleValues. For constructing a TitleValue from * user input or external sources, use a TitleParser. * * @param int $namespace The namespace ID. This is not validated. * @param string $dbkey The page title in valid DBkey form. No normalization is applied. * @param string $fragment The fragment title. Use '' to represent the whole page. * No validation or normalization is applied. * * @throws InvalidArgumentException */ public function __construct($namespace, $dbkey, $fragment = '') { Assert::parameterType('integer', $namespace, '$namespace'); Assert::parameterType('string', $dbkey, '$dbkey'); Assert::parameterType('string', $fragment, '$fragment'); // Sanity check, no full validation or normalization applied here! Assert::parameter(!preg_match('/^_|[ \\r\\n\\t]|_$/', $dbkey), '$dbkey', 'invalid DB key'); Assert::parameter($dbkey !== '', '$dbkey', 'should not be empty'); $this->namespace = $namespace; $this->dbkey = $dbkey; $this->fragment = $fragment; }
/** * Adds data type definitions. The new definitions are merged with the existing definitions. * If a data type in $dataTypeDefinitions was already defined, the old definition is not * replaced but the definitions are merged. * * @param array[] $dataTypeDefinitions An associative array mapping property data type ids * (with the prefix "PT:") and value types (with the prefix "VT:") to data type definitions. * Each data type definitions are associative arrays, refer to the class level documentation * for details. */ public function registerDataTypes(array $dataTypeDefinitions) { Assert::parameterElementType('array', $dataTypeDefinitions, '$dataTypeDefinitions'); foreach ($dataTypeDefinitions as $id => $def) { Assert::parameter(strpos($id, ':'), "\$dataTypeDefinitions[{$id}]", 'Key must start with a prefix like "PT:" or "VT:".'); if (isset($this->dataTypeDefinitions[$id])) { $this->dataTypeDefinitions[$id] = array_merge($this->dataTypeDefinitions[$id], $dataTypeDefinitions[$id]); } else { $this->dataTypeDefinitions[$id] = $dataTypeDefinitions[$id]; } } }
/** * @param Title $title * @param array $params */ public function __construct(Title $title, array $params) { parent::__construct('wikibase-addUsagesForPage', $title, $params); Assert::parameter(isset($params['pageId']) && is_int($params['pageId']) && $params['pageId'] > 0, '$params["pageId"]', 'must be a positive integer'); Assert::parameter(isset($params['usages']) && is_array($params['usages']) && !empty($params['usages']), '$params["usages"]', 'must be a non-empty array'); Assert::parameter(isset($params['touched']) && is_string($params['touched']) && $params['touched'] !== '', '$params["touched"]', 'must be a timestamp string'); Assert::parameterElementType('array', $params['usages'], '$params["usages"]'); $this->pageId = $params['pageId']; $this->usages = $params['usages']; $this->touched = $params['touched']; $wikibaseClient = WikibaseClient::getDefaultInstance(); $usageUpdater = $wikibaseClient->getStore()->getUsageUpdater(); $idParser = $wikibaseClient->getEntityIdParser(); $this->overrideServices($usageUpdater, $idParser); }
/** * @param int $maxKeys Maximum number of entries allowed (min 1). * @throws Exception When $maxCacheKeys is not an int or not above zero. */ public function __construct($maxKeys) { Assert::parameterType('integer', $maxKeys, '$maxKeys'); Assert::parameter($maxKeys > 0, '$maxKeys', 'must be above zero'); $this->maxCacheKeys = $maxKeys; }
/** * Get a statistically unique 128-bit unsigned integer ID string. * The bits of the UID are prefixed with the time (down to the millisecond). * * These IDs are suitable as globally unique IDs, without any enforced uniqueness. * New rows almost always have higher UIDs, which makes B-TREE updates on INSERT fast. * They can also be stored as "DECIMAL(39) UNSIGNED" or BINARY(16) in MySQL. * * UID generation is serialized on each server (as the node ID is for the whole machine). * * @param int $base Specifies a base other than 10 * @return string Number * @throws MWException */ public static function newTimestampedUID128($base = 10) { Assert::parameterType('integer', $base, '$base'); Assert::parameter($base <= 36, '$base', 'must be <= 36'); Assert::parameter($base >= 2, '$base', 'must be >= 2'); $gen = self::singleton(); $time = $gen->getTimestampAndDelay('lockFile128', 16384, 1048576); return wfBaseConvert($gen->getTimestampedID128($time), 2, $base); }
/** * Get a statistically unique 128-bit unsigned integer ID string. * The bits of the UID are prefixed with the time (down to the millisecond). * * These IDs are suitable as globally unique IDs, without any enforced uniqueness. * New rows almost always have higher UIDs, which makes B-TREE updates on INSERT fast. * They can also be stored as "DECIMAL(39) UNSIGNED" or BINARY(16) in MySQL. * * UID generation is serialized on each server (as the node ID is for the whole machine). * * @param int $base Specifies a base other than 10 * @return string Number * @throws RuntimeException */ public static function newTimestampedUID128($base = 10) { Assert::parameterType('integer', $base, '$base'); Assert::parameter($base <= 36, '$base', 'must be <= 36'); Assert::parameter($base >= 2, '$base', 'must be >= 2'); $gen = self::singleton(); $info = $gen->getTimeAndDelay('lockFile128', 16384, 1048576, 1048576); $info['offsetCounter'] = $info['offsetCounter'] % 1048576; return Wikimedia\base_convert($gen->getTimestampedID128($info), 2, $base); }
/** * Resize the maximum number of cache entries, removing older entries as needed * * @param int $maxKeys * @return void * @throws UnexpectedValueException */ public function resize($maxKeys) { Assert::parameterType('integer', $maxKeys, '$maxKeys'); Assert::parameter($maxKeys > 0, '$maxKeys', 'must be above zero'); $this->maxCacheKeys = $maxKeys; while (count($this->cache) > $this->maxCacheKeys) { reset($this->cache); $evictKey = key($this->cache); unset($this->cache[$evictKey]); unset($this->cacheTimes[$evictKey]); } }
private function switchMode($mode) { Assert::parameter(substr($mode, -4) === 'Mode', '$mode', 'should end in Mode'); $oldMode = $this->parseMode; $this->parseMode = $mode; return $oldMode; }
/** * @param int $limit Hard upper limit of 5000 */ public function setLimit($limit) { Assert::parameterType('integer', $limit, '$limit'); Assert::parameter($limit > 0, '$limit', 'Must be positive'); if ($limit > self::HARD_LIMIT) { $limit = self::HARD_LIMIT; } $this->limit = $limit; }
/** * @param mixed $value */ private function checkValueIsNotList($value) { Assert::parameter(!(is_array($value) && isset($value[0])), '$value', '$value must not be a list'); }
/** * @param array $params Additional parameters include: * - maxKeys : only allow this many keys (using oldest-first eviction) */ function __construct($params = array()) { parent::__construct($params); $this->maxCacheKeys = isset($params['maxKeys']) ? $params['maxKeys'] : INF; Assert::parameter($this->maxCacheKeys > 0, 'maxKeys', 'must be above zero'); }
/** * @param User $user * @param array $options Allowed keys: * 'forWrite' => bool defaults to false * 'sort' => string optional sorting by namespace ID and title * one of the self::SORT_* constants * * @return WatchedItem[] */ public function getWatchedItemsForUser(User $user, array $options = []) { $options += ['forWrite' => false]; $dbOptions = []; if (array_key_exists('sort', $options)) { Assert::parameter(in_array($options['sort'], [self::SORT_ASC, self::SORT_DESC]), '$options[\'sort\']', 'must be SORT_ASC or SORT_DESC'); $dbOptions['ORDER BY'] = ["wl_namespace {$options['sort']}", "wl_title {$options['sort']}"]; } $db = $this->getConnectionRef($options['forWrite'] ? DB_MASTER : DB_REPLICA); $res = $db->select('watchlist', ['wl_namespace', 'wl_title', 'wl_notificationtimestamp'], ['wl_user' => $user->getId()], __METHOD__, $dbOptions); $watchedItems = []; foreach ($res as $row) { // todo these could all be cached at some point? $watchedItems[] = new WatchedItem($user, new TitleValue((int) $row->wl_namespace, $row->wl_title), $row->wl_notificationtimestamp); } return $watchedItems; }
/** * For simple listing of user's watchlist items, see WatchedItemStore::getWatchedItemsForUser * * @param User $user * @param array $options Allowed keys: * 'sort' => string optional sorting by namespace ID and title * one of the self::SORT_* constants * 'namespaceIds' => int[] optional namespace IDs to filter by (defaults to all namespaces) * 'limit' => int maximum number of items to return * 'filter' => string optional filter, one of the self::FILTER_* contants * 'from' => LinkTarget requires 'sort' key, only return items starting from * those related to the link target * 'until' => LinkTarget requires 'sort' key, only return items until * those related to the link target * 'startFrom' => LinkTarget requires 'sort' key, only return items starting from * those related to the link target, allows to skip some link targets * specified using the form option * @return WatchedItem[] */ public function getWatchedItemsForUser(User $user, array $options = []) { if ($user->isAnon()) { // TODO: should this just return an empty array or rather complain loud at this point // as e.g. ApiBase::getWatchlistUser does? return []; } $options += ['namespaceIds' => []]; Assert::parameter(!isset($options['sort']) || in_array($options['sort'], [self::SORT_ASC, self::SORT_DESC]), '$options[\'sort\']', 'must be SORT_ASC or SORT_DESC'); Assert::parameter(!isset($options['filter']) || in_array($options['filter'], [self::FILTER_CHANGED, self::FILTER_NOT_CHANGED]), '$options[\'filter\']', 'must be FILTER_CHANGED or FILTER_NOT_CHANGED'); Assert::parameter(!isset($options['from']) && !isset($options['until']) && !isset($options['startFrom']) || isset($options['sort']), '$options[\'sort\']', 'must be provided if any of "from", "until", "startFrom" options is provided'); $db = $this->getConnection(); $conds = $this->getWatchedItemsForUserQueryConds($db, $user, $options); $dbOptions = $this->getWatchedItemsForUserQueryDbOptions($options); $res = $db->select('watchlist', ['wl_namespace', 'wl_title', 'wl_notificationtimestamp'], $conds, __METHOD__, $dbOptions); $watchedItems = []; foreach ($res as $row) { // todo these could all be cached at some point? $watchedItems[] = new WatchedItem($user, new TitleValue((int) $row->wl_namespace, $row->wl_title), $row->wl_notificationtimestamp); } return $watchedItems; }