Completed
Push — master ( c0a409...2c6d3d )
by
unknown
31:40
created
core/Command/Background/Job.php 2 patches
Indentation   +116 added lines, -116 removed lines patch added patch discarded remove patch
@@ -19,120 +19,120 @@
 block discarded – undo
19 19
 use Symfony\Component\Console\Output\OutputInterface;
20 20
 
21 21
 class Job extends Command {
22
-	public function __construct(
23
-		protected IJobList $jobList,
24
-	) {
25
-		parent::__construct();
26
-	}
27
-
28
-	protected function configure(): void {
29
-		$this
30
-			->setName('background-job:execute')
31
-			->setDescription('Execute a single background job manually')
32
-			->addArgument(
33
-				'job-id',
34
-				InputArgument::REQUIRED,
35
-				'The ID of the job in the database'
36
-			)
37
-			->addOption(
38
-				'force-execute',
39
-				null,
40
-				InputOption::VALUE_NONE,
41
-				'Force execute the background job, independent from last run and being reserved'
42
-			)
43
-		;
44
-	}
45
-
46
-	protected function execute(InputInterface $input, OutputInterface $output): int {
47
-		$jobId = (string)$input->getArgument('job-id');
48
-
49
-		$job = $this->jobList->getById($jobId);
50
-		if ($job === null) {
51
-			$output->writeln('<error>Job with ID ' . $jobId . ' could not be found in the database</error>');
52
-			return 1;
53
-		}
54
-
55
-		$this->printJobInfo($jobId, $job, $output);
56
-		$output->writeln('');
57
-
58
-		$lastRun = $job->getLastRun();
59
-		if ($input->getOption('force-execute')) {
60
-			$lastRun = 0;
61
-			$output->writeln('<comment>Forcing execution of the job</comment>');
62
-			$output->writeln('');
63
-
64
-			$this->jobList->resetBackgroundJob($job);
65
-		}
66
-
67
-		$job = $this->jobList->getById($jobId);
68
-		if ($job === null) {
69
-			$output->writeln('<error>Something went wrong when trying to retrieve Job with ID ' . $jobId . ' from database</error>');
70
-			return 1;
71
-		}
72
-		$job->start($this->jobList);
73
-		$job = $this->jobList->getById($jobId);
74
-
75
-		if (($job === null) || ($lastRun !== $job->getLastRun())) {
76
-			$output->writeln('<info>Job executed!</info>');
77
-			$output->writeln('');
78
-
79
-			if ($job instanceof TimedJob) {
80
-				$this->printJobInfo($jobId, $job, $output);
81
-			}
82
-		} else {
83
-			$output->writeln('<comment>Job was not executed because it is not due</comment>');
84
-			$output->writeln('Specify the <question>--force-execute</question> option to run it anyway');
85
-		}
86
-
87
-		return 0;
88
-	}
89
-
90
-	protected function printJobInfo(string $jobId, IJob $job, OutputInterface $output): void {
91
-		$row = $this->jobList->getDetailsById($jobId);
92
-
93
-		$lastRun = new \DateTime();
94
-		$lastRun->setTimestamp((int)$row['last_run']);
95
-		$lastChecked = new \DateTime();
96
-		$lastChecked->setTimestamp((int)$row['last_checked']);
97
-		$reservedAt = new \DateTime();
98
-		$reservedAt->setTimestamp((int)$row['reserved_at']);
99
-
100
-		$output->writeln('Job class:            ' . get_class($job));
101
-		$output->writeln('Arguments:            ' . json_encode($job->getArgument()));
102
-
103
-		$isTimedJob = $job instanceof TimedJob;
104
-		if ($isTimedJob) {
105
-			$output->writeln('Type:                 timed');
106
-		} elseif ($job instanceof QueuedJob) {
107
-			$output->writeln('Type:                 queued');
108
-		} else {
109
-			$output->writeln('Type:                 job');
110
-		}
111
-
112
-		$output->writeln('');
113
-		$output->writeln('Last checked:         ' . $lastChecked->format(\DateTimeInterface::ATOM));
114
-		if ((int)$row['reserved_at'] === 0) {
115
-			$output->writeln('Reserved at:          -');
116
-		} else {
117
-			$output->writeln('Reserved at:          <comment>' . $reservedAt->format(\DateTimeInterface::ATOM) . '</comment>');
118
-		}
119
-		$output->writeln('Last executed:        ' . $lastRun->format(\DateTimeInterface::ATOM));
120
-		$output->writeln('Last duration:        ' . $row['execution_duration']);
121
-
122
-		if ($isTimedJob) {
123
-			$reflection = new \ReflectionClass($job);
124
-			$intervalProperty = $reflection->getProperty('interval');
125
-			$intervalProperty->setAccessible(true);
126
-			$interval = $intervalProperty->getValue($job);
127
-
128
-			$nextRun = new \DateTime();
129
-			$nextRun->setTimestamp($row['last_run'] + $interval);
130
-
131
-			if ($nextRun > new \DateTime()) {
132
-				$output->writeln('Next execution:       <comment>' . $nextRun->format(\DateTimeInterface::ATOM) . '</comment>');
133
-			} else {
134
-				$output->writeln('Next execution:       <info>' . $nextRun->format(\DateTimeInterface::ATOM) . '</info>');
135
-			}
136
-		}
137
-	}
22
+    public function __construct(
23
+        protected IJobList $jobList,
24
+    ) {
25
+        parent::__construct();
26
+    }
27
+
28
+    protected function configure(): void {
29
+        $this
30
+            ->setName('background-job:execute')
31
+            ->setDescription('Execute a single background job manually')
32
+            ->addArgument(
33
+                'job-id',
34
+                InputArgument::REQUIRED,
35
+                'The ID of the job in the database'
36
+            )
37
+            ->addOption(
38
+                'force-execute',
39
+                null,
40
+                InputOption::VALUE_NONE,
41
+                'Force execute the background job, independent from last run and being reserved'
42
+            )
43
+        ;
44
+    }
45
+
46
+    protected function execute(InputInterface $input, OutputInterface $output): int {
47
+        $jobId = (string)$input->getArgument('job-id');
48
+
49
+        $job = $this->jobList->getById($jobId);
50
+        if ($job === null) {
51
+            $output->writeln('<error>Job with ID ' . $jobId . ' could not be found in the database</error>');
52
+            return 1;
53
+        }
54
+
55
+        $this->printJobInfo($jobId, $job, $output);
56
+        $output->writeln('');
57
+
58
+        $lastRun = $job->getLastRun();
59
+        if ($input->getOption('force-execute')) {
60
+            $lastRun = 0;
61
+            $output->writeln('<comment>Forcing execution of the job</comment>');
62
+            $output->writeln('');
63
+
64
+            $this->jobList->resetBackgroundJob($job);
65
+        }
66
+
67
+        $job = $this->jobList->getById($jobId);
68
+        if ($job === null) {
69
+            $output->writeln('<error>Something went wrong when trying to retrieve Job with ID ' . $jobId . ' from database</error>');
70
+            return 1;
71
+        }
72
+        $job->start($this->jobList);
73
+        $job = $this->jobList->getById($jobId);
74
+
75
+        if (($job === null) || ($lastRun !== $job->getLastRun())) {
76
+            $output->writeln('<info>Job executed!</info>');
77
+            $output->writeln('');
78
+
79
+            if ($job instanceof TimedJob) {
80
+                $this->printJobInfo($jobId, $job, $output);
81
+            }
82
+        } else {
83
+            $output->writeln('<comment>Job was not executed because it is not due</comment>');
84
+            $output->writeln('Specify the <question>--force-execute</question> option to run it anyway');
85
+        }
86
+
87
+        return 0;
88
+    }
89
+
90
+    protected function printJobInfo(string $jobId, IJob $job, OutputInterface $output): void {
91
+        $row = $this->jobList->getDetailsById($jobId);
92
+
93
+        $lastRun = new \DateTime();
94
+        $lastRun->setTimestamp((int)$row['last_run']);
95
+        $lastChecked = new \DateTime();
96
+        $lastChecked->setTimestamp((int)$row['last_checked']);
97
+        $reservedAt = new \DateTime();
98
+        $reservedAt->setTimestamp((int)$row['reserved_at']);
99
+
100
+        $output->writeln('Job class:            ' . get_class($job));
101
+        $output->writeln('Arguments:            ' . json_encode($job->getArgument()));
102
+
103
+        $isTimedJob = $job instanceof TimedJob;
104
+        if ($isTimedJob) {
105
+            $output->writeln('Type:                 timed');
106
+        } elseif ($job instanceof QueuedJob) {
107
+            $output->writeln('Type:                 queued');
108
+        } else {
109
+            $output->writeln('Type:                 job');
110
+        }
111
+
112
+        $output->writeln('');
113
+        $output->writeln('Last checked:         ' . $lastChecked->format(\DateTimeInterface::ATOM));
114
+        if ((int)$row['reserved_at'] === 0) {
115
+            $output->writeln('Reserved at:          -');
116
+        } else {
117
+            $output->writeln('Reserved at:          <comment>' . $reservedAt->format(\DateTimeInterface::ATOM) . '</comment>');
118
+        }
119
+        $output->writeln('Last executed:        ' . $lastRun->format(\DateTimeInterface::ATOM));
120
+        $output->writeln('Last duration:        ' . $row['execution_duration']);
121
+
122
+        if ($isTimedJob) {
123
+            $reflection = new \ReflectionClass($job);
124
+            $intervalProperty = $reflection->getProperty('interval');
125
+            $intervalProperty->setAccessible(true);
126
+            $interval = $intervalProperty->getValue($job);
127
+
128
+            $nextRun = new \DateTime();
129
+            $nextRun->setTimestamp($row['last_run'] + $interval);
130
+
131
+            if ($nextRun > new \DateTime()) {
132
+                $output->writeln('Next execution:       <comment>' . $nextRun->format(\DateTimeInterface::ATOM) . '</comment>');
133
+            } else {
134
+                $output->writeln('Next execution:       <info>' . $nextRun->format(\DateTimeInterface::ATOM) . '</info>');
135
+            }
136
+        }
137
+    }
138 138
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -44,11 +44,11 @@  discard block
 block discarded – undo
44 44
 	}
45 45
 
46 46
 	protected function execute(InputInterface $input, OutputInterface $output): int {
47
-		$jobId = (string)$input->getArgument('job-id');
47
+		$jobId = (string) $input->getArgument('job-id');
48 48
 
49 49
 		$job = $this->jobList->getById($jobId);
50 50
 		if ($job === null) {
51
-			$output->writeln('<error>Job with ID ' . $jobId . ' could not be found in the database</error>');
51
+			$output->writeln('<error>Job with ID '.$jobId.' could not be found in the database</error>');
52 52
 			return 1;
53 53
 		}
54 54
 
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
 
67 67
 		$job = $this->jobList->getById($jobId);
68 68
 		if ($job === null) {
69
-			$output->writeln('<error>Something went wrong when trying to retrieve Job with ID ' . $jobId . ' from database</error>');
69
+			$output->writeln('<error>Something went wrong when trying to retrieve Job with ID '.$jobId.' from database</error>');
70 70
 			return 1;
71 71
 		}
72 72
 		$job->start($this->jobList);
@@ -91,14 +91,14 @@  discard block
 block discarded – undo
91 91
 		$row = $this->jobList->getDetailsById($jobId);
92 92
 
93 93
 		$lastRun = new \DateTime();
94
-		$lastRun->setTimestamp((int)$row['last_run']);
94
+		$lastRun->setTimestamp((int) $row['last_run']);
95 95
 		$lastChecked = new \DateTime();
96
-		$lastChecked->setTimestamp((int)$row['last_checked']);
96
+		$lastChecked->setTimestamp((int) $row['last_checked']);
97 97
 		$reservedAt = new \DateTime();
98
-		$reservedAt->setTimestamp((int)$row['reserved_at']);
98
+		$reservedAt->setTimestamp((int) $row['reserved_at']);
99 99
 
100
-		$output->writeln('Job class:            ' . get_class($job));
101
-		$output->writeln('Arguments:            ' . json_encode($job->getArgument()));
100
+		$output->writeln('Job class:            '.get_class($job));
101
+		$output->writeln('Arguments:            '.json_encode($job->getArgument()));
102 102
 
103 103
 		$isTimedJob = $job instanceof TimedJob;
104 104
 		if ($isTimedJob) {
@@ -110,14 +110,14 @@  discard block
 block discarded – undo
110 110
 		}
111 111
 
112 112
 		$output->writeln('');
113
-		$output->writeln('Last checked:         ' . $lastChecked->format(\DateTimeInterface::ATOM));
114
-		if ((int)$row['reserved_at'] === 0) {
113
+		$output->writeln('Last checked:         '.$lastChecked->format(\DateTimeInterface::ATOM));
114
+		if ((int) $row['reserved_at'] === 0) {
115 115
 			$output->writeln('Reserved at:          -');
116 116
 		} else {
117
-			$output->writeln('Reserved at:          <comment>' . $reservedAt->format(\DateTimeInterface::ATOM) . '</comment>');
117
+			$output->writeln('Reserved at:          <comment>'.$reservedAt->format(\DateTimeInterface::ATOM).'</comment>');
118 118
 		}
119
-		$output->writeln('Last executed:        ' . $lastRun->format(\DateTimeInterface::ATOM));
120
-		$output->writeln('Last duration:        ' . $row['execution_duration']);
119
+		$output->writeln('Last executed:        '.$lastRun->format(\DateTimeInterface::ATOM));
120
+		$output->writeln('Last duration:        '.$row['execution_duration']);
121 121
 
122 122
 		if ($isTimedJob) {
123 123
 			$reflection = new \ReflectionClass($job);
@@ -129,9 +129,9 @@  discard block
 block discarded – undo
129 129
 			$nextRun->setTimestamp($row['last_run'] + $interval);
130 130
 
131 131
 			if ($nextRun > new \DateTime()) {
132
-				$output->writeln('Next execution:       <comment>' . $nextRun->format(\DateTimeInterface::ATOM) . '</comment>');
132
+				$output->writeln('Next execution:       <comment>'.$nextRun->format(\DateTimeInterface::ATOM).'</comment>');
133 133
 			} else {
134
-				$output->writeln('Next execution:       <info>' . $nextRun->format(\DateTimeInterface::ATOM) . '</info>');
134
+				$output->writeln('Next execution:       <info>'.$nextRun->format(\DateTimeInterface::ATOM).'</info>');
135 135
 			}
136 136
 		}
137 137
 	}
Please login to merge, or discard this patch.
core/Command/Background/JobBase.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -20,63 +20,63 @@
 block discarded – undo
20 20
 
21 21
 abstract class JobBase extends Base {
22 22
 
23
-	public function __construct(
24
-		protected IJobList $jobList,
25
-		protected LoggerInterface $logger,
26
-	) {
27
-		parent::__construct();
28
-	}
29
-
30
-	protected function printJobInfo(string $jobId, IJob $job, OutputInterface $output): void {
31
-		$row = $this->jobList->getDetailsById($jobId);
32
-
33
-		if ($row === null) {
34
-			return;
35
-		}
36
-
37
-		$lastRun = new \DateTime();
38
-		$lastRun->setTimestamp((int)$row['last_run']);
39
-		$lastChecked = new \DateTime();
40
-		$lastChecked->setTimestamp((int)$row['last_checked']);
41
-		$reservedAt = new \DateTime();
42
-		$reservedAt->setTimestamp((int)$row['reserved_at']);
43
-
44
-		$output->writeln('Job class:            ' . get_class($job));
45
-		$output->writeln('Arguments:            ' . json_encode($job->getArgument()));
46
-
47
-		$isTimedJob = $job instanceof TimedJob;
48
-		if ($isTimedJob) {
49
-			$output->writeln('Type:                 timed');
50
-		} elseif ($job instanceof QueuedJob) {
51
-			$output->writeln('Type:                 queued');
52
-		} else {
53
-			$output->writeln('Type:                 job');
54
-		}
55
-
56
-		$output->writeln('');
57
-		$output->writeln('Last checked:         ' . $lastChecked->format(\DateTimeInterface::ATOM));
58
-		if ((int)$row['reserved_at'] === 0) {
59
-			$output->writeln('Reserved at:          -');
60
-		} else {
61
-			$output->writeln('Reserved at:          <comment>' . $reservedAt->format(\DateTimeInterface::ATOM) . '</comment>');
62
-		}
63
-		$output->writeln('Last executed:        ' . $lastRun->format(\DateTimeInterface::ATOM));
64
-		$output->writeln('Last duration:        ' . $row['execution_duration']);
65
-
66
-		if ($isTimedJob) {
67
-			$reflection = new \ReflectionClass($job);
68
-			$intervalProperty = $reflection->getProperty('interval');
69
-			$intervalProperty->setAccessible(true);
70
-			$interval = $intervalProperty->getValue($job);
71
-
72
-			$nextRun = new \DateTime();
73
-			$nextRun->setTimestamp((int)$row['last_run'] + $interval);
74
-
75
-			if ($nextRun > new \DateTime()) {
76
-				$output->writeln('Next execution:       <comment>' . $nextRun->format(\DateTimeInterface::ATOM) . '</comment>');
77
-			} else {
78
-				$output->writeln('Next execution:       <info>' . $nextRun->format(\DateTimeInterface::ATOM) . '</info>');
79
-			}
80
-		}
81
-	}
23
+    public function __construct(
24
+        protected IJobList $jobList,
25
+        protected LoggerInterface $logger,
26
+    ) {
27
+        parent::__construct();
28
+    }
29
+
30
+    protected function printJobInfo(string $jobId, IJob $job, OutputInterface $output): void {
31
+        $row = $this->jobList->getDetailsById($jobId);
32
+
33
+        if ($row === null) {
34
+            return;
35
+        }
36
+
37
+        $lastRun = new \DateTime();
38
+        $lastRun->setTimestamp((int)$row['last_run']);
39
+        $lastChecked = new \DateTime();
40
+        $lastChecked->setTimestamp((int)$row['last_checked']);
41
+        $reservedAt = new \DateTime();
42
+        $reservedAt->setTimestamp((int)$row['reserved_at']);
43
+
44
+        $output->writeln('Job class:            ' . get_class($job));
45
+        $output->writeln('Arguments:            ' . json_encode($job->getArgument()));
46
+
47
+        $isTimedJob = $job instanceof TimedJob;
48
+        if ($isTimedJob) {
49
+            $output->writeln('Type:                 timed');
50
+        } elseif ($job instanceof QueuedJob) {
51
+            $output->writeln('Type:                 queued');
52
+        } else {
53
+            $output->writeln('Type:                 job');
54
+        }
55
+
56
+        $output->writeln('');
57
+        $output->writeln('Last checked:         ' . $lastChecked->format(\DateTimeInterface::ATOM));
58
+        if ((int)$row['reserved_at'] === 0) {
59
+            $output->writeln('Reserved at:          -');
60
+        } else {
61
+            $output->writeln('Reserved at:          <comment>' . $reservedAt->format(\DateTimeInterface::ATOM) . '</comment>');
62
+        }
63
+        $output->writeln('Last executed:        ' . $lastRun->format(\DateTimeInterface::ATOM));
64
+        $output->writeln('Last duration:        ' . $row['execution_duration']);
65
+
66
+        if ($isTimedJob) {
67
+            $reflection = new \ReflectionClass($job);
68
+            $intervalProperty = $reflection->getProperty('interval');
69
+            $intervalProperty->setAccessible(true);
70
+            $interval = $intervalProperty->getValue($job);
71
+
72
+            $nextRun = new \DateTime();
73
+            $nextRun->setTimestamp((int)$row['last_run'] + $interval);
74
+
75
+            if ($nextRun > new \DateTime()) {
76
+                $output->writeln('Next execution:       <comment>' . $nextRun->format(\DateTimeInterface::ATOM) . '</comment>');
77
+            } else {
78
+                $output->writeln('Next execution:       <info>' . $nextRun->format(\DateTimeInterface::ATOM) . '</info>');
79
+            }
80
+        }
81
+    }
82 82
 }
Please login to merge, or discard this patch.
core/Command/Background/Delete.php 2 patches
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -17,49 +17,49 @@
 block discarded – undo
17 17
 use Symfony\Component\Console\Question\ConfirmationQuestion;
18 18
 
19 19
 class Delete extends Base {
20
-	public function __construct(
21
-		protected IJobList $jobList,
22
-	) {
23
-		parent::__construct();
24
-	}
20
+    public function __construct(
21
+        protected IJobList $jobList,
22
+    ) {
23
+        parent::__construct();
24
+    }
25 25
 
26
-	protected function configure(): void {
27
-		$this
28
-			->setName('background-job:delete')
29
-			->setDescription('Remove a background job from database')
30
-			->addArgument(
31
-				'job-id',
32
-				InputArgument::REQUIRED,
33
-				'The ID of the job in the database'
34
-			);
35
-	}
26
+    protected function configure(): void {
27
+        $this
28
+            ->setName('background-job:delete')
29
+            ->setDescription('Remove a background job from database')
30
+            ->addArgument(
31
+                'job-id',
32
+                InputArgument::REQUIRED,
33
+                'The ID of the job in the database'
34
+            );
35
+    }
36 36
 
37
-	protected function execute(InputInterface $input, OutputInterface $output): int {
38
-		$jobId = (string)$input->getArgument('job-id');
37
+    protected function execute(InputInterface $input, OutputInterface $output): int {
38
+        $jobId = (string)$input->getArgument('job-id');
39 39
 
40
-		$job = $this->jobList->getById($jobId);
41
-		if ($job === null) {
42
-			$output->writeln('<error>Job with ID ' . $jobId . ' could not be found in the database</error>');
43
-			return 1;
44
-		}
40
+        $job = $this->jobList->getById($jobId);
41
+        if ($job === null) {
42
+            $output->writeln('<error>Job with ID ' . $jobId . ' could not be found in the database</error>');
43
+            return 1;
44
+        }
45 45
 
46
-		$output->writeln('Job class: ' . get_class($job));
47
-		$output->writeln('Arguments: ' . json_encode($job->getArgument()));
48
-		$output->writeln('');
46
+        $output->writeln('Job class: ' . get_class($job));
47
+        $output->writeln('Arguments: ' . json_encode($job->getArgument()));
48
+        $output->writeln('');
49 49
 
50
-		$question = new ConfirmationQuestion(
51
-			'<comment>Do you really want to delete this background job ? It could create some misbehaviours in Nextcloud.</comment> (y/N) ', false,
52
-			'/^(y|Y)/i'
53
-		);
50
+        $question = new ConfirmationQuestion(
51
+            '<comment>Do you really want to delete this background job ? It could create some misbehaviours in Nextcloud.</comment> (y/N) ', false,
52
+            '/^(y|Y)/i'
53
+        );
54 54
 
55
-		/** @var QuestionHelper $helper */
56
-		$helper = $this->getHelper('question');
57
-		if (!$helper->ask($input, $output, $question)) {
58
-			$output->writeln('aborted.');
59
-			return 0;
60
-		}
55
+        /** @var QuestionHelper $helper */
56
+        $helper = $this->getHelper('question');
57
+        if (!$helper->ask($input, $output, $question)) {
58
+            $output->writeln('aborted.');
59
+            return 0;
60
+        }
61 61
 
62
-		$this->jobList->remove($job, $job->getArgument());
63
-		return 0;
64
-	}
62
+        $this->jobList->remove($job, $job->getArgument());
63
+        return 0;
64
+    }
65 65
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -35,16 +35,16 @@
 block discarded – undo
35 35
 	}
36 36
 
37 37
 	protected function execute(InputInterface $input, OutputInterface $output): int {
38
-		$jobId = (string)$input->getArgument('job-id');
38
+		$jobId = (string) $input->getArgument('job-id');
39 39
 
40 40
 		$job = $this->jobList->getById($jobId);
41 41
 		if ($job === null) {
42
-			$output->writeln('<error>Job with ID ' . $jobId . ' could not be found in the database</error>');
42
+			$output->writeln('<error>Job with ID '.$jobId.' could not be found in the database</error>');
43 43
 			return 1;
44 44
 		}
45 45
 
46
-		$output->writeln('Job class: ' . get_class($job));
47
-		$output->writeln('Arguments: ' . json_encode($job->getArgument()));
46
+		$output->writeln('Job class: '.get_class($job));
47
+		$output->writeln('Arguments: '.json_encode($job->getArgument()));
48 48
 		$output->writeln('');
49 49
 
50 50
 		$question = new ConfirmationQuestion(
Please login to merge, or discard this patch.