1 | <?php |
||||
2 | |||||
3 | namespace BringYourOwnIdeas\Maintenance\Forms; |
||||
4 | |||||
5 | use BringYourOwnIdeas\Maintenance\Jobs\CheckForUpdatesJob; |
||||
6 | use SilverStripe\Core\Convert; |
||||
7 | use SilverStripe\Core\Injector\Injector; |
||||
8 | use SilverStripe\Forms\GridField\GridField; |
||||
9 | use SilverStripe\Forms\GridField\GridField_ActionProvider; |
||||
10 | use SilverStripe\Forms\GridField\GridField_FormAction; |
||||
11 | use SilverStripe\Forms\GridField\GridField_HTMLProvider; |
||||
12 | use SilverStripe\Forms\GridField\GridField_URLHandler; |
||||
13 | use SilverStripe\View\ArrayData; |
||||
14 | use SilverStripe\View\Requirements; |
||||
15 | use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor; |
||||
16 | use Symbiote\QueuedJobs\Services\QueuedJob; |
||||
17 | use Symbiote\QueuedJobs\Services\QueuedJobService; |
||||
18 | |||||
19 | /** |
||||
20 | * Adds a "Refresh" button to the bottom or top of a GridField. |
||||
21 | * |
||||
22 | * @package forms |
||||
23 | * @subpackage fields-gridfield |
||||
24 | */ |
||||
25 | class GridFieldRefreshButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler |
||||
26 | { |
||||
27 | private static $dependencies = [ |
||||
0 ignored issues
–
show
introduced
by
![]() |
|||||
28 | 'QueuedJobService' => '%$' . QueuedJobService::class, |
||||
29 | ]; |
||||
30 | |||||
31 | /** |
||||
32 | * @var array |
||||
33 | * @config |
||||
34 | */ |
||||
35 | private static $allowed_actions = ["check"]; |
||||
0 ignored issues
–
show
|
|||||
36 | |||||
37 | /** |
||||
38 | * Fragment to write the button to. |
||||
39 | * @var string |
||||
40 | */ |
||||
41 | protected $targetFragment; |
||||
42 | |||||
43 | /** |
||||
44 | * @var QueuedJobService |
||||
45 | */ |
||||
46 | protected $queuedJobService; |
||||
47 | |||||
48 | /** |
||||
49 | * @param string $targetFragment The HTML fragment to write the button into |
||||
50 | */ |
||||
51 | public function __construct($targetFragment) |
||||
52 | { |
||||
53 | $this->targetFragment = $targetFragment; |
||||
54 | } |
||||
55 | |||||
56 | /** |
||||
57 | * @param GridField $gridField |
||||
58 | * @return array |
||||
59 | */ |
||||
60 | public function getHTMLFragments($gridField) |
||||
61 | { |
||||
62 | Requirements::javascript('bringyourownideas/silverstripe-maintenance: client/dist/js/bundle.js'); |
||||
63 | |||||
64 | $button = GridField_FormAction::create( |
||||
65 | $gridField, |
||||
66 | 'refresh', |
||||
67 | _t(__CLASS__ . '.REFRESH', 'Check for updates'), |
||||
68 | 'refresh', |
||||
69 | null |
||||
70 | ); |
||||
71 | |||||
72 | $button->addExtraClass('btn btn-primary font-icon-sync'); |
||||
73 | |||||
74 | $button->setAttribute('data-check', $gridField->Link('check')); |
||||
75 | $button->setAttribute( |
||||
76 | 'data-message', |
||||
77 | _t( |
||||
78 | __CLASS__ . '.MESSAGE', |
||||
79 | 'Updating this list may take 2-3 minutes. You can continue to use the CMS while we run the update.' |
||||
80 | ) |
||||
81 | ); |
||||
82 | |||||
83 | if ($this->hasPendingJob()) { |
||||
84 | $button->setTitle(_t(__CLASS__ . '.UPDATE', 'Updating...')); |
||||
85 | $button->setDisabled(true); |
||||
86 | } |
||||
87 | |||||
88 | return [ |
||||
89 | $this->targetFragment => ArrayData::create(['Button' => $button->Field()]) |
||||
90 | ->renderWith(__CLASS__) |
||||
91 | ]; |
||||
92 | } |
||||
93 | |||||
94 | /** |
||||
95 | * Refresh is an action button. |
||||
96 | * |
||||
97 | * @param GridField $gridField |
||||
98 | * |
||||
99 | * @return array |
||||
100 | */ |
||||
101 | public function getActions($gridField) |
||||
102 | { |
||||
103 | return ['refresh']; |
||||
104 | } |
||||
105 | |||||
106 | /** |
||||
107 | * Handle the refresh action. |
||||
108 | * |
||||
109 | * @param GridField $gridField |
||||
110 | * @param string $actionName |
||||
111 | * @param array $arguments |
||||
112 | * @param array $data |
||||
113 | * |
||||
114 | * @return null |
||||
115 | */ |
||||
116 | public function handleAction(GridField $gridField, $actionName, $arguments, $data) |
||||
117 | { |
||||
118 | if ($actionName == 'refresh') { |
||||
119 | return $this->handleRefresh($gridField); |
||||
0 ignored issues
–
show
The call to
BringYourOwnIdeas\Mainte...Button::handleRefresh() has too many arguments starting with $gridField .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() Are you sure the usage of
$this->handleRefresh($gridField) targeting BringYourOwnIdeas\Mainte...Button::handleRefresh() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
120 | } |
||||
121 | } |
||||
122 | |||||
123 | /** |
||||
124 | * Refresh is accessible via the url |
||||
125 | * |
||||
126 | * @param GridField $gridField |
||||
127 | * @return array |
||||
128 | */ |
||||
129 | public function getURLHandlers($gridField) |
||||
130 | { |
||||
131 | return [ |
||||
132 | 'check' => 'handleCheck' |
||||
133 | ]; |
||||
134 | } |
||||
135 | |||||
136 | /** |
||||
137 | * @see hasPendingJob |
||||
138 | * @return string JSON encoded value for whether there is a job pending or in process to update the report |
||||
139 | */ |
||||
140 | public function handleCheck() |
||||
141 | { |
||||
142 | $isRunning = $this->hasPendingJob(); |
||||
143 | return Convert::raw2json($isRunning); |
||||
0 ignored issues
–
show
The function
SilverStripe\Core\Convert::raw2json() has been deprecated: 4.4.0:5.0.0 Use json_encode() instead
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
144 | } |
||||
145 | |||||
146 | /** |
||||
147 | * Check the queue for refresh jobs that are not 'done' |
||||
148 | * in one manner or another (e.g. stalled or cancelled) |
||||
149 | * |
||||
150 | * @return boolean |
||||
151 | */ |
||||
152 | public function hasPendingJob() |
||||
153 | { |
||||
154 | // We care about any queued job in the immediate queue, or any queue if the job is already running |
||||
155 | /** @var QueuedJobDescriptor $immediateJob */ |
||||
156 | $immediateJob = $this->getQueuedJobService() |
||||
157 | ->getJobList(QueuedJob::IMMEDIATE) |
||||
158 | ->filter([ |
||||
159 | 'Implementation' => CheckForUpdatesJob::class |
||||
160 | ]) |
||||
161 | ->exclude([ |
||||
162 | 'JobStatus' => [ |
||||
163 | QueuedJob::STATUS_COMPLETE, |
||||
164 | QueuedJob::STATUS_CANCELLED, |
||||
165 | QueuedJob::STATUS_BROKEN |
||||
166 | ] |
||||
167 | ]); |
||||
168 | |||||
169 | /** @var QueuedJobDescriptor $runningJob */ |
||||
170 | $runningJob = QueuedJobDescriptor::get() |
||||
171 | ->filter([ |
||||
172 | 'Implementation' => CheckForUpdatesJob::class, |
||||
173 | 'JobStatus' => QueuedJob::STATUS_RUN, |
||||
174 | ]); |
||||
175 | |||||
176 | return $immediateJob->exists() || $runningJob->exists(); |
||||
177 | } |
||||
178 | |||||
179 | /** |
||||
180 | * Handle the refresh, for both the action button and the URL |
||||
181 | */ |
||||
182 | public function handleRefresh() |
||||
183 | { |
||||
184 | if ($this->hasPendingJob()) { |
||||
185 | return; |
||||
186 | } |
||||
187 | |||||
188 | // Queue the job in the immediate queue |
||||
189 | $job = Injector::inst()->create(CheckForUpdatesJob::class); |
||||
190 | $jobDescriptorId = $this->getQueuedJobService()->queueJob($job, null, null, QueuedJob::IMMEDIATE); |
||||
0 ignored issues
–
show
Symbiote\QueuedJobs\Services\QueuedJob::IMMEDIATE of type string is incompatible with the type integer|null expected by parameter $queueName of Symbiote\QueuedJobs\Serv...dJobService::queueJob() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
191 | |||||
192 | // Check the job descriptor on the queue |
||||
193 | $jobDescriptor = QueuedJobDescriptor::get()->filter('ID', $jobDescriptorId)->first(); |
||||
194 | |||||
195 | // If the job is not immediate, change it to immediate and reschedule it to occur immediately |
||||
196 | if ($jobDescriptor->JobType !== QueuedJob::IMMEDIATE) { |
||||
197 | $jobDescriptor->JobType = QueuedJob::IMMEDIATE; |
||||
198 | $jobDescriptor->StartAfter = null; |
||||
199 | $jobDescriptor->write(); |
||||
200 | } |
||||
201 | } |
||||
202 | |||||
203 | /** |
||||
204 | * @return QueuedJobService |
||||
205 | */ |
||||
206 | public function getQueuedJobService() |
||||
207 | { |
||||
208 | return $this->queuedJobService; |
||||
209 | } |
||||
210 | |||||
211 | /** |
||||
212 | * @param QueuedJobService $queuedJobService |
||||
213 | * @return $this |
||||
214 | */ |
||||
215 | public function setQueuedJobService(QueuedJobService $queuedJobService) |
||||
216 | { |
||||
217 | $this->queuedJobService = $queuedJobService; |
||||
218 | return $this; |
||||
219 | } |
||||
220 | } |
||||
221 |