*
* @ingroup JobQueue
*/
-abstract class Job implements IJobSpecification {
+abstract class Job implements RunnableJob {
/** @var string */
public $command;
protected $title;
/** @var bool Expensive jobs may set this to true */
- protected $removeDuplicates;
+ protected $removeDuplicates = false;
/** @var string Text for error that occurred last */
protected $error;
/** @var int Job must not be wrapped in the usual explicit LBFactory transaction round */
const JOB_NO_EXPLICIT_TRX_ROUND = 1;
- /**
- * Run the job
- * @return bool Success
- */
- abstract public function run();
-
/**
* Create the appropriate object to handle a specific job
*
* @param string $command Job command
- * @param Title $title Associated title
- * @param array $params Job parameters
- * @throws MWException
+ * @param array|Title $params Job parameters
+ * @throws InvalidArgumentException
* @return Job
*/
- public static function factory( $command, Title $title, $params = [] ) {
+ public static function factory( $command, $params = [] ) {
global $wgJobClasses;
+ if ( $params instanceof Title ) {
+ // Backwards compatibility for old signature ($command, $title, $params)
+ $title = $params;
+ $params = func_num_args() >= 3 ? func_get_arg( 2 ) : [];
+ } else {
+ $title = ( isset( $params['namespace'] ) && isset( $params['title'] ) )
+ ? Title::makeTitle( $params['namespace'], $params['title'] )
+ : Title::makeTitle( NS_SPECIAL, '' );
+ }
+
+ $params = is_array( $params ) ? $params : []; // sanity
+
if ( isset( $wgJobClasses[$command] ) ) {
$handler = $wgJobClasses[$command];
if ( is_callable( $handler ) ) {
$job = call_user_func( $handler, $title, $params );
} elseif ( class_exists( $handler ) ) {
- $job = new $handler( $title, $params );
+ if ( is_subclass_of( $handler, GenericParameterJob::class ) ) {
+ $job = new $handler( $params );
+ } else {
+ $job = new $handler( $title, $params );
+ }
} else {
$job = null;
}
if ( $job instanceof Job ) {
$job->command = $command;
+
return $job;
} else {
- throw new InvalidArgumentException( "Cannot instantiate job '$command': bad spec!" );
+ throw new InvalidArgumentException( "Could instantiate job '$command': bad spec!" );
}
}
/**
* @param string $command
- * @param Title $title
- * @param array|bool $params Can not be === true
+ * @param array|Title|null $params
*/
- public function __construct( $command, $title, $params = false ) {
- $this->command = $command;
- $this->title = $title;
- $this->params = is_array( $params ) ? $params : []; // sanity
-
- // expensive jobs may set this to true
- $this->removeDuplicates = false;
+ public function __construct( $command, $params = null ) {
+ if ( $params instanceof Title ) {
+ // Backwards compatibility for old signature ($command, $title, $params)
+ $title = $params;
+ $params = func_num_args() >= 3 ? func_get_arg( 2 ) : [];
+ $params = is_array( $params ) ? $params : []; // sanity
+ // Set namespace/title params if both are missing and this is not a dummy title
+ if (
+ $title->getDBkey() !== '' &&
+ !isset( $params['namespace'] ) &&
+ !isset( $params['title'] )
+ ) {
+ $params['namespace'] = $title->getNamespace();
+ $params['title'] = $title->getDBKey();
+ // Note that JobQueue classes will prefer the parameters over getTitle()
+ $this->title = $title;
+ }
+ }
- if ( !isset( $this->params['requestId'] ) ) {
- $this->params['requestId'] = WebRequest::getRequestId();
+ $this->command = $command;
+ $this->params = $params + [ 'requestId' => WebRequest::getRequestId() ];
+ if ( $this->title === null ) {
+ $this->title = ( isset( $params['namespace'] ) && isset( $params['title'] ) )
+ ? Title::makeTitle( $params['namespace'], $params['title'] )
+ : Title::makeTitle( NS_SPECIAL, '' );
}
}
* @since 1.31
*/
public function hasExecutionFlag( $flag ) {
- return ( $this->executionFlags && $flag ) === $flag;
+ return ( $this->executionFlags & $flag ) === $flag;
}
/**
/**
* @return Title
*/
- public function getTitle() {
+ final public function getTitle() {
return $this->title;
}
return $this->params;
}
+ /**
+ * @param string|null $field Metadata field or null to get all the metadata
+ * @return mixed|null Value; null if missing
+ * @since 1.33
+ */
+ public function getMetadata( $field = null ) {
+ if ( $field === null ) {
+ return $this->metadata;
+ }
+
+ return $this->metadata[$field] ?? null;
+ }
+
+ /**
+ * @param string $field Key name to set the value for
+ * @param mixed $value The value to set the field for
+ * @return mixed|null The prior field value; null if missing
+ * @since 1.33
+ */
+ public function setMetadata( $field, $value ) {
+ $old = $this->getMetadata( $field );
+ if ( $value === null ) {
+ unset( $this->metadata[$field] );
+ } else {
+ $this->metadata[$field] = $value;
+ }
+
+ return $old;
+ }
+
/**
* @return int|null UNIX timestamp to delay running this job until, otherwise null
* @since 1.22
public function getDeduplicationInfo() {
$info = [
'type' => $this->getType(),
- 'namespace' => $this->getTitle()->getNamespace(),
- 'title' => $this->getTitle()->getDBkey(),
'params' => $this->getParams()
];
if ( is_array( $info['params'] ) ) {