Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/config/view/PhabricatorSetupIssueView.php
12256 views
1
<?php
2
3
final class PhabricatorSetupIssueView extends AphrontView {
4
5
private $issue;
6
7
public function setIssue(PhabricatorSetupIssue $issue) {
8
$this->issue = $issue;
9
return $this;
10
}
11
12
public function getIssue() {
13
return $this->issue;
14
}
15
16
public function renderInFlight() {
17
$issue = $this->getIssue();
18
19
return id(new PhabricatorInFlightErrorView())
20
->setMessage($issue->getName())
21
->render();
22
}
23
24
public function render() {
25
$issue = $this->getIssue();
26
27
$description = array();
28
$description[] = phutil_tag(
29
'div',
30
array(
31
'class' => 'setup-issue-instructions',
32
),
33
phutil_escape_html_newlines($issue->getMessage()));
34
35
$configs = $issue->getPHPConfig();
36
if ($configs) {
37
$description[] = $this->renderPHPConfig($configs, $issue);
38
}
39
40
$configs = $issue->getMySQLConfig();
41
if ($configs) {
42
$description[] = $this->renderMySQLConfig($configs);
43
}
44
45
$configs = $issue->getPhabricatorConfig();
46
if ($configs) {
47
$description[] = $this->renderPhabricatorConfig($configs);
48
}
49
50
$related_configs = $issue->getRelatedPhabricatorConfig();
51
if ($related_configs) {
52
$description[] = $this->renderPhabricatorConfig($related_configs,
53
$related = true);
54
}
55
56
$commands = $issue->getCommands();
57
if ($commands) {
58
$run_these = pht('Run these %d command(s):', count($commands));
59
$description[] = phutil_tag(
60
'div',
61
array(
62
'class' => 'setup-issue-config',
63
),
64
array(
65
phutil_tag('p', array(), $run_these),
66
phutil_tag('pre', array(), phutil_implode_html("\n", $commands)),
67
));
68
}
69
70
$extensions = $issue->getPHPExtensions();
71
if ($extensions) {
72
$install_these = pht(
73
'Install these %d PHP extension(s):', count($extensions));
74
75
$install_info = pht(
76
'You can usually install a PHP extension using %s or %s. Common '.
77
'package names are %s or %s. Try commands like these:',
78
phutil_tag('tt', array(), 'apt-get'),
79
phutil_tag('tt', array(), 'yum'),
80
hsprintf('<tt>php-<em>%s</em></tt>', pht('extname')),
81
hsprintf('<tt>php5-<em>%s</em></tt>', pht('extname')));
82
83
// TODO: We should do a better job of detecting how to install extensions
84
// on the current system.
85
$install_commands = hsprintf(
86
"\$ sudo apt-get install php5-<em>extname</em> ".
87
"# Debian / Ubuntu\n".
88
"\$ sudo yum install php-<em>extname</em> ".
89
"# Red Hat / Derivatives");
90
91
$fallback_info = pht(
92
"If those commands don't work, try Google. The process of installing ".
93
"PHP extensions is not specific to this software, and any ".
94
"instructions you can find for installing them on your system should ".
95
"work. On Mac OS X, you might want to try Homebrew.");
96
97
$restart_info = pht(
98
'After installing new PHP extensions, <strong>restart everything '.
99
'for the changes to take effect</strong>. For help with restarting '.
100
'everything, see %s in the documentation.',
101
$this->renderRestartLink());
102
103
$description[] = phutil_tag(
104
'div',
105
array(
106
'class' => 'setup-issue-config',
107
),
108
array(
109
phutil_tag('p', array(), $install_these),
110
phutil_tag('pre', array(), implode("\n", $extensions)),
111
phutil_tag('p', array(), $install_info),
112
phutil_tag('pre', array(), $install_commands),
113
phutil_tag('p', array(), $fallback_info),
114
phutil_tag('p', array(), $restart_info),
115
));
116
117
}
118
119
$related_links = $issue->getLinks();
120
if ($related_links) {
121
$description[] = $this->renderRelatedLinks($related_links);
122
}
123
124
$actions = array();
125
if (!$issue->getIsFatal()) {
126
if ($issue->getIsIgnored()) {
127
$actions[] = javelin_tag(
128
'a',
129
array(
130
'href' => '/config/unignore/'.$issue->getIssueKey().'/',
131
'sigil' => 'workflow',
132
'class' => 'button button-grey',
133
),
134
pht('Unignore Setup Issue'));
135
} else {
136
$actions[] = javelin_tag(
137
'a',
138
array(
139
'href' => '/config/ignore/'.$issue->getIssueKey().'/',
140
'sigil' => 'workflow',
141
'class' => 'button button-grey',
142
),
143
pht('Ignore Setup Issue'));
144
}
145
146
$actions[] = javelin_tag(
147
'a',
148
array(
149
'href' => '/config/issue/'.$issue->getIssueKey().'/',
150
'class' => 'button button-grey',
151
),
152
pht('Reload Page'));
153
}
154
155
if ($actions) {
156
$actions = phutil_tag(
157
'div',
158
array(
159
'class' => 'setup-issue-actions',
160
),
161
$actions);
162
}
163
164
if ($issue->getIsIgnored()) {
165
$status = phutil_tag(
166
'div',
167
array(
168
'class' => 'setup-issue-status',
169
),
170
pht(
171
'This issue is currently ignored, and does not show a global '.
172
'warning.'));
173
$next = null;
174
} else {
175
$status = null;
176
$next = phutil_tag(
177
'div',
178
array(
179
'class' => 'setup-issue-next',
180
),
181
pht('To continue, resolve this problem and reload the page.'));
182
}
183
184
$name = phutil_tag(
185
'div',
186
array(
187
'class' => 'setup-issue-name',
188
),
189
$issue->getName());
190
191
$head = phutil_tag(
192
'div',
193
array(
194
'class' => 'setup-issue-head',
195
),
196
$name);
197
198
$body = phutil_tag(
199
'div',
200
array(
201
'class' => 'setup-issue-body',
202
),
203
array(
204
$status,
205
$description,
206
));
207
208
$tail = phutil_tag(
209
'div',
210
array(
211
'class' => 'setup-issue-tail',
212
),
213
$actions);
214
215
$issue = phutil_tag(
216
'div',
217
array(
218
'class' => 'setup-issue',
219
),
220
array(
221
$head,
222
$body,
223
$tail,
224
));
225
226
$debug_info = phutil_tag(
227
'div',
228
array(
229
'class' => 'setup-issue-debug',
230
),
231
pht('Host: %s', php_uname('n')));
232
233
return phutil_tag(
234
'div',
235
array(
236
'class' => 'setup-issue-shell',
237
),
238
array(
239
$issue,
240
$next,
241
$debug_info,
242
));
243
}
244
245
private function renderPhabricatorConfig(array $configs, $related = false) {
246
$issue = $this->getIssue();
247
248
$table_info = phutil_tag(
249
'p',
250
array(),
251
pht(
252
'The current configuration has these %d value(s):',
253
count($configs)));
254
255
$options = PhabricatorApplicationConfigOptions::loadAllOptions();
256
$hidden = array();
257
foreach ($options as $key => $option) {
258
if ($option->getHidden()) {
259
$hidden[$key] = true;
260
}
261
}
262
263
$table = null;
264
$dict = array();
265
foreach ($configs as $key) {
266
if (isset($hidden[$key])) {
267
$dict[$key] = null;
268
} else {
269
$dict[$key] = PhabricatorEnv::getUnrepairedEnvConfig($key);
270
}
271
}
272
273
$table = $this->renderValueTable($dict, $hidden);
274
275
if ($this->getIssue()->getIsFatal()) {
276
$update_info = phutil_tag(
277
'p',
278
array(),
279
pht(
280
'To update these %d value(s), run these command(s) from the command '.
281
'line:',
282
count($configs)));
283
284
$update = array();
285
foreach ($configs as $key) {
286
$update[] = hsprintf(
287
'<tt>$</tt> ./bin/config set %s <em>value</em>',
288
$key);
289
}
290
$update = phutil_tag('pre', array(), phutil_implode_html("\n", $update));
291
} else {
292
$update = array();
293
foreach ($configs as $config) {
294
if (idx($options, $config) && $options[$config]->getLocked()) {
295
$name = pht('View "%s"', $config);
296
} else {
297
$name = pht('Edit "%s"', $config);
298
}
299
$link = phutil_tag(
300
'a',
301
array(
302
'href' => '/config/edit/'.$config.'/?issue='.$issue->getIssueKey(),
303
),
304
$name);
305
$update[] = phutil_tag('li', array(), $link);
306
}
307
if ($update) {
308
$update = phutil_tag('ul', array(), $update);
309
if (!$related) {
310
$update_info = phutil_tag(
311
'p',
312
array(),
313
pht('You can update these %d value(s) here:', count($configs)));
314
} else {
315
$update_info = phutil_tag(
316
'p',
317
array(),
318
pht('These %d configuration value(s) are related:', count($configs)));
319
}
320
} else {
321
$update = null;
322
$update_info = null;
323
}
324
}
325
326
return phutil_tag(
327
'div',
328
array(
329
'class' => 'setup-issue-config',
330
),
331
array(
332
$table_info,
333
$table,
334
$update_info,
335
$update,
336
));
337
}
338
339
private function renderPHPConfig(array $configs, $issue) {
340
$table_info = phutil_tag(
341
'p',
342
array(),
343
pht(
344
'The current PHP configuration has these %d value(s):',
345
count($configs)));
346
347
$dict = array();
348
foreach ($configs as $key) {
349
$dict[$key] = $issue->getPHPConfigOriginalValue(
350
$key,
351
ini_get($key));
352
}
353
354
$table = $this->renderValueTable($dict);
355
356
ob_start();
357
phpinfo();
358
$phpinfo = ob_get_clean();
359
360
361
$rex = '@Loaded Configuration File\s*</td><td class="v">(.*?)</td>@i';
362
$matches = null;
363
364
$ini_loc = null;
365
if (preg_match($rex, $phpinfo, $matches)) {
366
$ini_loc = trim($matches[1]);
367
}
368
369
$rex = '@Additional \.ini files parsed\s*</td><td class="v">(.*?)</td>@i';
370
371
$more_loc = array();
372
if (preg_match($rex, $phpinfo, $matches)) {
373
$more_loc = trim($matches[1]);
374
if ($more_loc == '(none)') {
375
$more_loc = array();
376
} else {
377
$more_loc = preg_split('/\s*,\s*/', $more_loc);
378
}
379
}
380
381
$info = array();
382
if (!$ini_loc) {
383
$info[] = phutil_tag(
384
'p',
385
array(),
386
pht(
387
'To update these %d value(s), edit your PHP configuration file.',
388
count($configs)));
389
} else {
390
$info[] = phutil_tag(
391
'p',
392
array(),
393
pht(
394
'To update these %d value(s), edit your PHP configuration file, '.
395
'located here:',
396
count($configs)));
397
$info[] = phutil_tag(
398
'pre',
399
array(),
400
$ini_loc);
401
}
402
403
if ($more_loc) {
404
$info[] = phutil_tag(
405
'p',
406
array(),
407
pht(
408
'PHP also loaded these %s configuration file(s):',
409
phutil_count($more_loc)));
410
$info[] = phutil_tag(
411
'pre',
412
array(),
413
implode("\n", $more_loc));
414
}
415
416
$show_standard = false;
417
$show_opcache = false;
418
419
foreach ($configs as $key) {
420
if (preg_match('/^opcache\./', $key)) {
421
$show_opcache = true;
422
} else {
423
$show_standard = true;
424
}
425
}
426
427
if ($show_standard) {
428
$info[] = phutil_tag(
429
'p',
430
array(),
431
pht(
432
'You can find more information about PHP configuration values '.
433
'in the %s.',
434
phutil_tag(
435
'a',
436
array(
437
'href' => 'http://php.net/manual/ini.list.php',
438
'target' => '_blank',
439
),
440
pht('PHP Documentation'))));
441
}
442
443
if ($show_opcache) {
444
$info[] = phutil_tag(
445
'p',
446
array(),
447
pht(
448
'You can find more information about configuring OPcache in '.
449
'the %s.',
450
phutil_tag(
451
'a',
452
array(
453
'href' => 'http://php.net/manual/opcache.configuration.php',
454
'target' => '_blank',
455
),
456
pht('PHP OPcache Documentation'))));
457
}
458
459
$info[] = phutil_tag(
460
'p',
461
array(),
462
pht(
463
'After editing the PHP configuration, <strong>restart everything for '.
464
'the changes to take effect</strong>. For help with restarting '.
465
'everything, see %s in the documentation.',
466
$this->renderRestartLink()));
467
468
return phutil_tag(
469
'div',
470
array(
471
'class' => 'setup-issue-config',
472
),
473
array(
474
$table_info,
475
$table,
476
$info,
477
));
478
}
479
480
private function renderMySQLConfig(array $config) {
481
$values = array();
482
$issue = $this->getIssue();
483
$ref = $issue->getDatabaseRef();
484
if ($ref) {
485
foreach ($config as $key) {
486
$value = $ref->loadRawMySQLConfigValue($key);
487
if ($value === null) {
488
$value = phutil_tag(
489
'em',
490
array(),
491
pht('(Not Supported)'));
492
}
493
$values[$key] = $value;
494
}
495
}
496
497
$table = $this->renderValueTable($values);
498
499
$doc_href = PhabricatorEnv::getDoclink('User Guide: Amazon RDS');
500
$doc_link = phutil_tag(
501
'a',
502
array(
503
'href' => $doc_href,
504
'target' => '_blank',
505
),
506
pht('User Guide: Amazon RDS'));
507
508
$info = array();
509
$info[] = phutil_tag(
510
'p',
511
array(),
512
pht(
513
'If you are using Amazon RDS, some of the instructions above may '.
514
'not apply to you. See %s for discussion of Amazon RDS.',
515
$doc_link));
516
517
$table_info = phutil_tag(
518
'p',
519
array(),
520
pht(
521
'The current MySQL configuration has these %d value(s):',
522
count($config)));
523
524
return phutil_tag(
525
'div',
526
array(
527
'class' => 'setup-issue-config',
528
),
529
array(
530
$table_info,
531
$table,
532
$info,
533
));
534
}
535
536
private function renderValueTable(array $dict, array $hidden = array()) {
537
$rows = array();
538
foreach ($dict as $key => $value) {
539
if (isset($hidden[$key])) {
540
$value = phutil_tag('em', array(), 'hidden');
541
} else {
542
$value = $this->renderValueForDisplay($value);
543
}
544
545
$cols = array(
546
phutil_tag('th', array(), $key),
547
phutil_tag('td', array(), $value),
548
);
549
$rows[] = phutil_tag('tr', array(), $cols);
550
}
551
return phutil_tag('table', array(), $rows);
552
}
553
554
private function renderValueForDisplay($value) {
555
if ($value === null) {
556
return phutil_tag('em', array(), 'null');
557
} else if ($value === false) {
558
return phutil_tag('em', array(), 'false');
559
} else if ($value === true) {
560
return phutil_tag('em', array(), 'true');
561
} else if ($value === '') {
562
return phutil_tag('em', array(), 'empty string');
563
} else if ($value instanceof PhutilSafeHTML) {
564
return $value;
565
} else {
566
return PhabricatorConfigJSON::prettyPrintJSON($value);
567
}
568
}
569
570
private function renderRelatedLinks(array $links) {
571
$link_info = phutil_tag(
572
'p',
573
array(),
574
pht(
575
'%d related link(s):',
576
count($links)));
577
578
$link_list = array();
579
foreach ($links as $link) {
580
$link_tag = phutil_tag(
581
'a',
582
array(
583
'target' => '_blank',
584
'href' => $link['href'],
585
),
586
$link['name']);
587
$link_item = phutil_tag('li', array(), $link_tag);
588
$link_list[] = $link_item;
589
}
590
$link_list = phutil_tag('ul', array(), $link_list);
591
592
return phutil_tag(
593
'div',
594
array(
595
'class' => 'setup-issue-config',
596
),
597
array(
598
$link_info,
599
$link_list,
600
));
601
}
602
603
private function renderRestartLink() {
604
$doc_href = PhabricatorEnv::getDoclink('Restarting Phabricator');
605
return phutil_tag(
606
'a',
607
array(
608
'href' => $doc_href,
609
'target' => '_blank',
610
),
611
pht('Restarting Phabricator'));
612
}
613
614
}
615
616