1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Epesi\Core\System; |
4
|
|
|
|
5
|
|
|
use Epesi\Core\System\Modules\ModuleView; |
6
|
|
|
use Illuminate\Support\Facades\Auth; |
7
|
|
|
use Epesi\Core\System\Modules\ModuleManager; |
8
|
|
|
use Epesi\Core\Layout\View\ActionBar; |
9
|
|
|
use Epesi\Core\System\View\Form; |
10
|
|
|
|
11
|
|
|
class ModuleAdministration extends ModuleView |
12
|
|
|
{ |
13
|
|
|
protected $label = 'Module Administration'; |
14
|
|
|
|
15
|
|
|
protected $accordion; |
16
|
|
|
|
17
|
|
|
public static function access() |
18
|
|
|
{ |
19
|
|
|
return Auth::user()->can('modify system settings'); |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
public function body() |
23
|
|
|
{ |
24
|
|
|
$this->addControlButtons(); |
25
|
|
|
|
26
|
|
|
$this->addAccordion($this, $this->topLevelModules()); |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
public function topLevelModules() |
30
|
|
|
{ |
31
|
|
|
$modules = collect(ModuleManager::getAll()); |
32
|
|
|
|
33
|
|
|
return $modules->filter(function ($subModuleClass) use ($modules) { |
34
|
|
|
return ! $modules->map(function($moduleClass){ |
35
|
|
|
return $moduleClass::namespace(); |
36
|
|
|
})->contains($subModuleClass::parentNamespace()); |
37
|
|
|
})->sort(); |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
public function addAccordion($container, $modules) |
41
|
|
|
{ |
42
|
|
|
$accordion = \atk4\ui\Accordion::addTo($container, ['type' => ['styled', 'fluid'], 'settings' => ['animateChildren' => false]])->setStyle(['max-width' => '800px', 'margin-left' => 'auto', 'margin-right' => 'auto']); |
43
|
|
|
|
44
|
|
|
if ($container == $this) { |
45
|
|
|
$this->accordion = $accordion; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
foreach ($modules as $moduleClass) { |
49
|
|
|
$section = $accordion->addSection($moduleClass::label()); |
50
|
|
|
|
51
|
|
|
\atk4\ui\Message::addTo($section, ['ui' => 'tiny message'])->template->appendHTML('Content', $this->formatModuleInfo($moduleClass)); |
|
|
|
|
52
|
|
|
|
53
|
|
|
if (ModuleManager::isInstalled($moduleClass)) { |
54
|
|
|
$label = [\atk4\ui\Label::class, __('Installed'), 'green']; |
55
|
|
|
|
56
|
|
|
$this->addUninstallButton($section, $moduleClass); |
57
|
|
|
|
58
|
|
|
// $this->addReinstallButton($section, $moduleClass); |
59
|
|
|
} |
60
|
|
|
else { |
61
|
|
|
$label = [\atk4\ui\Label::class, __('Available'), 'yellow']; |
62
|
|
|
|
63
|
|
|
$this->addInstallButton($section, $moduleClass); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
$section->add($label, 'title')->setStyle('float', 'right'); |
|
|
|
|
67
|
|
|
|
68
|
|
|
$submodules = collect(ModuleManager::getAll())->filter(function ($subModuleClass) use ($moduleClass) { |
69
|
|
|
return $subModuleClass::isSubModuleOf($moduleClass); |
70
|
|
|
}); |
71
|
|
|
|
72
|
|
|
if ($submodules->isEmpty()) continue; |
73
|
|
|
|
74
|
|
|
$this->addAccordion($section, $submodules); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
return $accordion; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
public function formatModuleInfo($moduleClass) |
81
|
|
|
{ |
82
|
|
|
$moduleInfo = (array) ($moduleClass::info()?: __(' No details provided by author')); |
83
|
|
|
|
84
|
|
|
$ret = []; |
85
|
|
|
foreach ($moduleInfo as $label => $text) { |
86
|
|
|
$ret[] = (is_string($label)? "<strong>$label</strong>: ": '') . $text; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
return implode('<br>', $ret); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
public function addInstallButton($container, $moduleClass) |
93
|
|
|
{ |
94
|
|
|
$button = \atk4\ui\Button::addTo($container, [__('Install'), 'class' => ['green']]); |
95
|
|
|
|
96
|
|
|
$callback = $installCallback = \atk4\ui\JsCallback::addTo($this)->set(function() use ($moduleClass, $container) { |
|
|
|
|
97
|
|
|
ob_start(); |
98
|
|
|
ModuleManager::install($moduleClass); |
99
|
|
|
|
100
|
|
|
$message = ob_get_clean(); |
101
|
|
|
|
102
|
|
|
return [ |
103
|
|
|
$this->notifySuccess($message), |
104
|
|
|
new \atk4\ui\JsReload($this->accordion), |
105
|
|
|
]; |
106
|
|
|
}); |
107
|
|
|
|
108
|
|
|
$dependencies = ModuleManager::listDependencies($moduleClass); |
109
|
|
|
$recommended = ModuleManager::listRecommended($moduleClass); |
110
|
|
|
|
111
|
|
|
if ($dependencies || $recommended) { |
|
|
|
|
112
|
|
|
$modal = \atk4\ui\Modal::addTo($this, ['title' => __(':module Module Installation', ['module' => $moduleClass::label()])])->set(function($view) use ($installCallback, $moduleClass, $dependencies, $recommended) { |
113
|
|
|
if ($dependencies) { |
|
|
|
|
114
|
|
|
$message = \atk4\ui\Message::addTo($view, [__('Module has following dependencies which will be installed')]); |
115
|
|
|
|
116
|
|
|
foreach ($dependencies as $parentModule) { |
117
|
|
|
$message->text->addParagraph($parentModule::label()); |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
if ($recommended) { |
|
|
|
|
122
|
|
|
$message = \atk4\ui\Message::addTo($view, [__('Select to install recommended modules for best experience')]); |
|
|
|
|
123
|
|
|
|
124
|
|
|
$form = Form::addTo($view); |
125
|
|
|
foreach ($recommended as $childModule) { |
126
|
|
|
if (! ModuleManager::isAvailable($childModule)) continue; |
127
|
|
|
|
128
|
|
|
$form->addControl($childModule::alias(), [\atk4\ui\Form\Control\Checkbox::class, 'caption' => $childModule::label()]); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
$form->onSubmit(function ($form) use ($moduleClass) { |
132
|
|
|
ob_start(); |
133
|
|
|
ModuleManager::install($moduleClass, array_keys($form->getValues(), true)); |
|
|
|
|
134
|
|
|
|
135
|
|
|
return ob_get_clean(); |
136
|
|
|
}); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
\atk4\ui\Button::addTo($view, [__('Install'), 'primary'])->on('click', [ |
|
|
|
|
140
|
|
|
isset($form)? $form->submit(): $installCallback |
141
|
|
|
]); |
142
|
|
|
}); |
143
|
|
|
|
144
|
|
|
$callback = $modal->show(); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$button->on('click', $callback); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
public function addUninstallButton($container, $moduleClass) |
151
|
|
|
{ |
152
|
|
|
$button = \atk4\ui\Button::addTo($container, [__('Uninstall'), 'class' => ['red']]); |
153
|
|
|
|
154
|
|
|
$callback = $uninstallCallback = \atk4\ui\JsCallback::addTo($button, ['confirm' => __('Are you sure you want to uninstall :module', ['module' => $moduleClass::label()])])->set(function() use ($moduleClass) { |
155
|
|
|
ob_start(); |
156
|
|
|
ModuleManager::uninstall($moduleClass); |
157
|
|
|
|
158
|
|
|
$message = ob_get_clean(); |
159
|
|
|
|
160
|
|
|
return [ |
161
|
|
|
$this->notifySuccess($message), |
162
|
|
|
new \atk4\ui\JsReload($this->accordion), |
163
|
|
|
]; |
164
|
|
|
}); |
165
|
|
|
|
166
|
|
|
if ($dependents = ModuleManager::listDependents()[$moduleClass]?? []) { |
167
|
|
|
$modal = \atk4\ui\Modal::addTo($this, ['title' => __(':module Module Installation', ['module' => $moduleClass::label()])])->set(function($view) use ($moduleClass, $dependents, $uninstallCallback) { |
|
|
|
|
168
|
|
|
$message = \atk4\ui\Message::addTo($view, [__('Module is required by following modules')]); |
169
|
|
|
|
170
|
|
|
foreach ($dependents as $childModule) { |
171
|
|
|
$message->text->addParagraph($childModule::label()); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
\atk4\ui\Button::addTo($view, [__('Install'), 'primary'])->on('click', $uninstallCallback); |
|
|
|
|
175
|
|
|
}); |
176
|
|
|
|
177
|
|
|
$callback = $modal->show(); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
$button->on('click', $callback); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
public function addReinstallButton($container, $moduleClass) |
|
|
|
|
184
|
|
|
{ |
185
|
|
|
\atk4\ui\Button::addTo($container, [__('Re-install')]); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
public function addControlButtons() |
189
|
|
|
{ |
190
|
|
|
ActionBar::addItemButton('back')->link(url('view/system')); |
191
|
|
|
|
192
|
|
|
$this->addClearCacheButton(); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
public function addClearCacheButton() |
196
|
|
|
{ |
197
|
|
|
ActionBar::addItemButton([__('Clear Cache'), 'icon' => 'refresh', 'hint' => __('Clears module cache and re-discovers all available modules')])->callback(function($callback) { |
|
|
|
|
198
|
|
|
ModuleManager::clearCache(); |
199
|
|
|
|
200
|
|
|
return [ |
201
|
|
|
new \atk4\ui\JsReload($this->accordion), |
202
|
|
|
$this->notifySuccess(__('Cache cleared!')) |
203
|
|
|
]; |
204
|
|
|
}); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
} |
208
|
|
|
|
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.