-
Notifications
You must be signed in to change notification settings - Fork 645
/
Copy pathMissingComponentTrait.php
140 lines (128 loc) · 4.96 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
<?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. <[email protected]>
* @since 3.0.0
*/
trait MissingComponentTrait
{
/**
* @var class-string<ComponentInterface> The expected component class name.
*/
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 class-string<ComponentInterface> $type The component class that should be used as the fallback
* @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'
));
}
}