-
Notifications
You must be signed in to change notification settings - Fork 611
/
MissingComponentTrait.php
142 lines (130 loc) · 5.02 KB
/
MissingComponentTrait.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/
namespace craft\base;
use Craft;
use craft\errors\InvalidPluginException;
use craft\helpers\Component as ComponentHelper;
use yii\base\Arrayable;
/**
* MissingComponentTrait implements the common methods and properties for classes implementing [[MissingComponentInterface]].
*
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
* @since 3.0.0
*/
trait MissingComponentTrait
{
/**
* @var string The expected component class name.
* @phpstan-var class-string<ComponentInterface>
*/
public string $expectedType;
/**
* @var string|null The exception message that explains why the component class was invalid
*/
public ?string $errorMessage = null;
/**
* @var array|null The custom settings associated with the component, if it is savable
*/
public ?array $settings = null;
/**
* Creates a new component of a given type based on this one’s properties.
*
* @param string $type The component class that should be used as the fallback
* @phpstan-param class-string<ComponentInterface> $type
* @return ComponentInterface
*/
public function createFallback(string $type): ComponentInterface
{
/** @var Arrayable $this */
$config = $this->toArray();
unset($config['expectedType'], $config['errorMessage'], $config['settings']);
$config['type'] = $type;
return ComponentHelper::createComponent($config);
}
/**
* Displays an error message (and possibly a plugin install button) in place of the normal component UI.
*
* @return string
* @since 3.0.6
*/
public function getPlaceholderHtml(): string
{
$error = $this->errorMessage ?? "Unable to find component class '$this->expectedType'.";
$showPlugin = false;
$isComposerInstalled = false;
$isInstalled = false;
$name = null;
$handle = null;
$iconUrl = null;
$iconSvg = null;
if (
Craft::$app->getUser()->getIsAdmin() &&
Craft::$app->getConfig()->getGeneral()->allowAdminChanges
) {
$pluginsService = Craft::$app->getPlugins();
// Special cases for removed 1st party components
switch ($this->expectedType) {
case 'craft\redactor\Field':
$showPlugin = true;
$isInstalled = false;
$name = 'Redactor';
$handle = 'redactor';
$iconUrl = 'https://s3-us-west-2.amazonaws.com/plugin-icons.craftcms/redactor.svg';
$error = "Support for $name fields has been moved to a plugin.";
break;
case 'craft\awss3\Volume':
$showPlugin = true;
$isInstalled = false;
$name = 'Amazon S3';
$handle = 'aws-s3';
$iconUrl = 'https://s3-us-west-2.amazonaws.com/plugin-icons.craftcms/aws-s3.svg';
$error = "Support for $name volumes has been moved to a plugin.";
break;
case 'craft\googlecloud\Volume':
$showPlugin = true;
$isInstalled = false;
$name = 'Google Cloud Storage';
$handle = 'google-cloud';
$iconUrl = 'https://s3-us-west-2.amazonaws.com/plugin-icons.craftcms/google-cloud.svg';
$error = "Support for $name volumes has been moved to a plugin.";
break;
case 'craft\rackspace\Volume':
$showPlugin = true;
$isInstalled = false;
$name = 'Rackspace Cloud Files';
$handle = 'rackspace';
$iconUrl = 'https://s3-us-west-2.amazonaws.com/plugin-icons.craftcms/rackspace.svg';
$error = "Support for $name volumes has been moved to a plugin.";
break;
default:
if ($handle = $pluginsService->getPluginHandleByClass($this->expectedType)) {
$showPlugin = true;
}
}
if ($showPlugin) {
try {
$info = Craft::$app->getPlugins()->getPluginInfo($handle);
$isComposerInstalled = true;
$isInstalled = $info['isInstalled'];
$name = $info['name'];
$iconSvg = $pluginsService->getPluginIconSvg($handle);
} catch (InvalidPluginException) {
}
}
}
return Craft::$app->getView()->renderTemplate('_special/missing-component.twig', compact(
'error',
'showPlugin',
'isComposerInstalled',
'isInstalled',
'name',
'handle',
'iconUrl',
'iconSvg'
));
}
}