Merge "maintenance: Script to rename titles for Unicode uppercasing changes"
[lhc/web/wiklou.git] / includes / jobqueue / Job.php
index 6054e35..c87dedc 100644 (file)
@@ -52,9 +52,6 @@ abstract class Job implements RunnableJob {
        /** @var int Bitfield of JOB_* class constants */
        protected $executionFlags = 0;
 
-       /** @var int Job must not be wrapped in the usual explicit LBFactory transaction round */
-       const JOB_NO_EXPLICIT_TRX_ROUND = 1;
-
        /**
         * Create the appropriate object to handle a specific job
         *
@@ -70,14 +67,19 @@ abstract class Job implements RunnableJob {
                        // Backwards compatibility for old signature ($command, $title, $params)
                        $title = $params;
                        $params = func_num_args() >= 3 ? func_get_arg( 2 ) : [];
+               } elseif ( isset( $params['namespace'] ) && isset( $params['title'] ) ) {
+                       // Handle job classes that take title as constructor parameter.
+                       // If a newer classes like GenericParameterJob uses these parameters,
+                       // then this happens in Job::__construct instead.
+                       $title = Title::makeTitle( $params['namespace'], $params['title'] );
                } else {
-                       $title = ( isset( $params['namespace'] ) && isset( $params['title'] ) )
-                               ? Title::makeTitle( $params['namespace'], $params['title'] )
-                               : Title::makeTitle( NS_SPECIAL, '' );
+                       // Default title for job classes not implementing GenericParameterJob.
+                       // This must be a valid title because it not directly passed to
+                       // our Job constructor, but rather it's subclasses which may expect
+                       // to be able to use it.
+                       $title = Title::makeTitle( NS_SPECIAL, 'Blankpage' );
                }
 
-               $params = is_array( $params ) ? $params : []; // sanity
-
                if ( isset( $wgJobClasses[$command] ) ) {
                        $handler = $wgJobClasses[$command];
 
@@ -98,7 +100,9 @@ abstract class Job implements RunnableJob {
 
                                return $job;
                        } else {
-                               throw new InvalidArgumentException( "Could instantiate job '$command': bad spec!" );
+                               throw new InvalidArgumentException(
+                                       "Could not instantiate job '$command': bad spec!"
+                               );
                        }
                }
 
@@ -114,34 +118,39 @@ abstract class Job implements RunnableJob {
                        // 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;
-                       }
+               } else {
+                       // Newer jobs may choose to not have a top-level title (e.g. GenericParameterJob)
+                       $title = null;
+               }
+
+               if ( !is_array( $params ) ) {
+                       throw new InvalidArgumentException( '$params must be an array' );
+               }
+
+               if (
+                       $title &&
+                       !isset( $params['namespace'] ) &&
+                       !isset( $params['title'] )
+               ) {
+                       // When constructing this class for submitting to the queue,
+                       // normalise the $title arg of old job classes as part of $params.
+                       $params['namespace'] = $title->getNamespace();
+                       $params['title'] = $title->getDBKey();
                }
 
                $this->command = $command;
                $this->params = $params + [ 'requestId' => WebRequest::getRequestId() ];
+
                if ( $this->title === null ) {
+                       // Set this field for access via getTitle().
                        $this->title = ( isset( $params['namespace'] ) && isset( $params['title'] ) )
                                ? Title::makeTitle( $params['namespace'], $params['title'] )
+                               // GenericParameterJob classes without namespace/title params
+                               // should not use getTitle(). Set an invalid title as placeholder.
                                : Title::makeTitle( NS_SPECIAL, '' );
                }
        }
 
-       /**
-        * @param int $flag JOB_* class constant
-        * @return bool
-        * @since 1.31
-        */
        public function hasExecutionFlag( $flag ) {
                return ( $this->executionFlags & $flag ) === $flag;
        }
@@ -217,20 +226,10 @@ abstract class Job implements RunnableJob {
                        : null;
        }
 
-       /**
-        * @return string|null Id of the request that created this job. Follows
-        *  jobs recursively, allowing to track the id of the request that started a
-        *  job when jobs insert jobs which insert other jobs.
-        * @since 1.27
-        */
        public function getRequestId() {
                return $this->params['requestId'] ?? null;
        }
 
-       /**
-        * @return int|null UNIX timestamp of when the job was runnable, or null
-        * @since 1.26
-        */
        public function getReadyTimestamp() {
                return $this->getReleaseTimestamp() ?: $this->getQueuedTimestamp();
        }
@@ -250,19 +249,10 @@ abstract class Job implements RunnableJob {
                return $this->removeDuplicates;
        }
 
-       /**
-        * @return bool Whether this job can be retried on failure by job runners
-        * @since 1.21
-        */
        public function allowRetries() {
                return true;
        }
 
-       /**
-        * @return int Number of actually "work items" handled in this job
-        * @see $wgJobBackoffThrottling
-        * @since 1.23
-        */
        public function workItemCount() {
                return 1;
        }
@@ -363,20 +353,12 @@ abstract class Job implements RunnableJob {
                $this->teardownCallbacks[] = $callback;
        }
 
-       /**
-        * Do any final cleanup after run(), deferred updates, and all DB commits happen
-        * @param bool $status Whether the job, its deferred updates, and DB commit all succeeded
-        * @since 1.27
-        */
        public function teardown( $status ) {
                foreach ( $this->teardownCallbacks as $callback ) {
                        call_user_func( $callback, $status );
                }
        }
 
-       /**
-        * @return string
-        */
        public function toString() {
                $paramString = '';
                if ( $this->params ) {