ModuleAdministration::addInstallButton()   B
last analyzed

Complexity

Conditions 9
Paths 2

Size

Total Lines 56
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 9
eloc 30
nc 2
nop 2
dl 0
loc 56
rs 8.0555
c 3
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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));
0 ignored issues
show
Deprecated Code introduced by
The function atk4\ui\HtmlTemplate::appendHtml() has been deprecated: use "dangerouslyAppendHtml" method instead - will be removed in v2.5 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

51
			/** @scrutinizer ignore-deprecated */ \atk4\ui\Message::addTo($section, ['ui' => 'tiny message'])->template->appendHTML('Content', $this->formatModuleInfo($moduleClass));

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.

Loading history...
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');
0 ignored issues
show
Bug introduced by
$label of type array<integer,array|string> is incompatible with the type atk4\ui\View expected by parameter $object of atk4\ui\View::add(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

66
			$section->add(/** @scrutinizer ignore-type */ $label, 'title')->setStyle('float', 'right');
Loading history...
Bug introduced by
The method setStyle() does not exist on atk4\ui\AbstractView. It seems like you code against a sub-type of atk4\ui\AbstractView such as atk4\ui\View. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
			$section->add($label, 'title')->/** @scrutinizer ignore-call */ setStyle('float', 'right');
Loading history...
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) {
0 ignored issues
show
Unused Code introduced by
The import $container is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $dependencies of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $recommended of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $dependencies of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $recommended of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
122
					$message = \atk4\ui\Message::addTo($view, [__('Select to install recommended modules for best experience')]);
0 ignored issues
show
Unused Code introduced by
The assignment to $message is dead and can be removed.
Loading history...
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));
0 ignored issues
show
Bug introduced by
array_keys($form->getValues(), true) of type array is incompatible with the type boolean expected by parameter $installRecommended of Epesi\Core\System\Modules\ModuleManager::install(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

133
						ModuleManager::install($moduleClass, /** @scrutinizer ignore-type */ array_keys($form->getValues(), true));
Loading history...
134
						
135
						return ob_get_clean();
136
					});
137
				}
138
				
139
				\atk4\ui\Button::addTo($view, [__('Install'), 'primary'])->on('click', [
0 ignored issues
show
Bug introduced by
array(IssetNode ? $form-...t() : $installCallback) of type array<integer,atk4\ui\JsCallback|mixed> is incompatible with the type string expected by parameter $selector of atk4\ui\View::on(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

139
				\atk4\ui\Button::addTo($view, [__('Install'), 'primary'])->on('click', /** @scrutinizer ignore-type */ [
Loading history...
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) {
0 ignored issues
show
Unused Code introduced by
The import $moduleClass is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
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);
0 ignored issues
show
Bug introduced by
$uninstallCallback of type atk4\ui\JsCallback is incompatible with the type string expected by parameter $selector of atk4\ui\View::on(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

174
				\atk4\ui\Button::addTo($view, [__('Install'), 'primary'])->on('click', /** @scrutinizer ignore-type */ $uninstallCallback);
Loading history...
175
			});
176
			
177
			$callback = $modal->show();
178
		}
179
			
180
		$button->on('click', $callback);
181
	}
182
	
183
	public function addReinstallButton($container, $moduleClass)
0 ignored issues
show
Unused Code introduced by
The parameter $moduleClass is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

183
	public function addReinstallButton($container, /** @scrutinizer ignore-unused */ $moduleClass)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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) {
0 ignored issues
show
Bug introduced by
The method callback() does not exist on atk4\ui\Item. It seems like you code against a sub-type of atk4\ui\Item such as Epesi\Core\Layout\View\ActionBarItem. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

197
	    ActionBar::addItemButton([__('Clear Cache'), 'icon' => 'refresh', 'hint' => __('Clears module cache and re-discovers all available modules')])->/** @scrutinizer ignore-call */ callback(function($callback) {
Loading history...
Unused Code introduced by
The parameter $callback is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

197
	    ActionBar::addItemButton([__('Clear Cache'), 'icon' => 'refresh', 'hint' => __('Clears module cache and re-discovers all available modules')])->callback(function(/** @scrutinizer ignore-unused */ $callback) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
198
			ModuleManager::clearCache();
199
			
200
			return [
201
					new \atk4\ui\JsReload($this->accordion),
202
			        $this->notifySuccess(__('Cache cleared!'))
203
			];
204
		});
205
	}
206
	
207
}
208