/**
* Get the Query database connection (read-only)
- * @return DatabaseBase
+ * @return Database
*/
protected function getDB() {
if ( is_null( $this->mDb ) ) {
* @param string $name Name to assign to the database connection
* @param int $db One of the DB_* constants
* @param array $groups Query groups
- * @return DatabaseBase
+ * @return Database
*/
public function selectNamedDB( $name, $db, $groups ) {
$this->mDb = $this->getQuery()->getNamedDB( $name, $db, $groups );
* 'options' => ...,
* 'join_conds' => ...
* ]
+ * @param array|null &$hookData If set, the ApiQueryBaseBeforeQuery and
+ * ApiQueryBaseAfterQuery hooks will be called, and the
+ * ApiQueryBaseProcessRow hook will be expected.
* @return ResultWrapper
*/
- protected function select( $method, $extraQuery = [] ) {
+ protected function select( $method, $extraQuery = [], array &$hookData = null ) {
$tables = array_merge(
$this->tables,
isset( $extraQuery['join_conds'] ) ? (array)$extraQuery['join_conds'] : []
);
+ if ( $hookData !== null ) {
+ Hooks::run( 'ApiQueryBaseBeforeQuery',
+ [ $this, &$tables, &$fields, &$where, &$options, &$join_conds, &$hookData ]
+ );
+ }
+
$res = $this->getDB()->select( $tables, $fields, $where, $method, $options, $join_conds );
+ if ( $hookData !== null ) {
+ Hooks::run( 'ApiQueryBaseAfterQuery', [ $this, $res, &$hookData ] );
+ }
+
return $res;
}
+ /**
+ * Call the ApiQueryBaseProcessRow hook
+ *
+ * Generally, a module that passed $hookData to self::select() will call
+ * this just before calling ApiResult::addValue(), and treat a false return
+ * here in the same way it treats a false return from addValue().
+ *
+ * @since 1.28
+ * @param object $row Database row
+ * @param array &$data Data to be added to the result
+ * @param array &$hookData Hook data from ApiQueryBase::select()
+ * @return bool Return false if row processing should end with continuation
+ */
+ protected function processRow( $row, array &$data, array &$hookData ) {
+ return Hooks::run( 'ApiQueryBaseProcessRow', [ $this, $row, &$data, &$hookData ] );
+ }
+
/**
* @param string $query
* @param string $protocol
$likeQuery = LinkFilter::makeLikeArray( $query, $protocol );
if ( !$likeQuery ) {
- $this->dieUsage( 'Invalid query', 'bad_query' );
+ $this->dieWithError( 'apierror-badquery' );
}
$likeQuery = LinkFilter::keepOneWildcard( $likeQuery );
$t = Title::makeTitleSafe( $namespace, $titlePart . 'x' );
if ( !$t || $t->hasFragment() ) {
// Invalid title (e.g. bad chars) or contained a '#'.
- $this->dieUsageMsg( [ 'invalidtitle', $titlePart ] );
+ $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $titlePart ) ] );
}
if ( $namespace != $t->getNamespace() || $t->isExternal() ) {
// This can happen in two cases. First, if you call titlePartToKey with a title part
// difficult to handle such a case. Such cases cannot exist and are therefore treated
// as invalid user input. The second case is when somebody specifies a title interwiki
// prefix.
- $this->dieUsageMsg( [ 'invalidtitle', $titlePart ] );
+ $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $titlePart ) ] );
}
return substr( $t->getDBkey(), 0, -1 );
$t = Title::newFromText( $titlePart . 'x', $defaultNamespace );
if ( !$t || $t->hasFragment() || $t->isExternal() ) {
// Invalid title (e.g. bad chars) or contained a '#'.
- $this->dieUsageMsg( [ 'invalidtitle', $titlePart ] );
+ $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $titlePart ) ] );
}
return [ $t->getNamespace(), substr( $t->getDBkey(), 0, -1 ) ];
* @return bool
*/
public function validateSha1Hash( $hash ) {
- return preg_match( '/^[a-f0-9]{40}$/', $hash );
+ return (bool)preg_match( '/^[a-f0-9]{40}$/', $hash );
}
/**
* @return bool
*/
public function validateSha1Base36Hash( $hash ) {
- return preg_match( '/^[a-z0-9]{31}$/', $hash );
+ return (bool)preg_match( '/^[a-z0-9]{31}$/', $hash );
}
/**