Passed
Push — master ( 5c9089...a37889 )
by Georgi
05:25
created

CommonDataSettings::getUpdateModal()   B

Complexity

Conditions 8
Paths 1

Size

Total Lines 36
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 16
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 36
rs 8.4444
1
<?php
2
3
namespace Epesi\Base\CommonData;
4
5
use Epesi\Core\System\Integration\Modules\ModuleView;
6
use Illuminate\Support\Facades\Auth;
7
use Epesi\Core\Layout\Seeds\ActionBar;
8
use Epesi\Base\CommonData\Database\Models\CommonData;
9
use Epesi\Core\System\Seeds\Form;
10
use atk4\ui\jsExpression;
11
use atk4\ui\jQuery;
12
use atk4\ui\TableColumn\Actions;
13
use atk4\ui\jsModal;
14
15
class CommonDataSettings extends ModuleView
16
{
17
	protected $label = 'Common Data';
18
	
19
	protected $form;
20
	protected $parentId;
21
22
	protected $buttons = [];
23
	
24
	public static function access()
25
	{
26
		return Auth::user()->can('modify system settings');
27
	}
28
	
29
	public function body()
30
	{
31
		ActionBar::addButton('back')->link(url('view/system'));
32
		
33
		$this->parentId = $this->stickyGet('parentId')?: null;
34
		
35
		$this->displayBreadCrumb();
36
		
37
		$this->displayGrid();
38
	}
39
	
40
	public function displayBreadCrumb()
41
	{
42
		$breadcrumb = $this->add('BreadCrumb');
43
		
44
		$breadcrumb->addCrumb(__('Common Data Root'), '?parentId=0');
1 ignored issue
show
Bug introduced by
The method addCrumb() does not exist on atk4\ui\View. It seems like you code against a sub-type of atk4\ui\View such as atk4\ui\BreadCrumb. ( Ignorable by Annotation )

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

44
		$breadcrumb->/** @scrutinizer ignore-call */ 
45
               addCrumb(__('Common Data Root'), '?parentId=0');
Loading history...
45
	
46
		foreach (CommonData::ancestorsAndSelf($this->parentId) as $node) {
47
			$label = $node->key;
48
			$link = '?parentId=' . $node->id;
49
			
50
			$breadcrumb->addCrumb($label, $link);
51
		}
52
		
53
		$breadcrumb->popTitle();
1 ignored issue
show
Bug introduced by
The method popTitle() does not exist on atk4\ui\View. It seems like you code against a sub-type of atk4\ui\View such as atk4\ui\BreadCrumb. ( Ignorable by Annotation )

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

53
		$breadcrumb->/** @scrutinizer ignore-call */ 
54
               popTitle();
Loading history...
54
		
55
		return $this;
56
	}
57
	
58
	public function displayGrid()
59
	{		
60
		$this->grid = $this->add([
0 ignored issues
show
Bug Best Practice introduced by
The property grid does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
61
				'CRUD',
62
				'itemCreate' => ActionBar::addButton('add'),
63
				'formCreate' => $this->getNodeForm(),
64
				'formUpdate' => $this->getNodeForm(),
65
				'fieldsCreate' => ['key', 'value'],
66
				'fieldsUpdate' => ['key', 'value'],
67
				'notifyDefault' => ['jsNotify', 'content' => __('Data is saved!'), 'color' => 'green'],
68
				'canUpdate' => false, //use custom update routine
69
				'canDelete' => false, //use custom delete routine
70
				'paginator' => false,
71
				'menu' => false,
72
		]);
73
		
74
		$this->grid->table->addClass('selectable')->addStyle('cursor', 'pointer');
75
76
		$this->grid->setModel($model = $this->getModel());
77
		
78
		if ($model->action('count')->getOne() ) {
79
			$this->grid->on('click', 'td', new jsExpression(
80
					'document.location=\'?parentId=\'+[]',
81
					[(new jQuery())->closest('tr')->data('id')]
1 ignored issue
show
Unused Code introduced by
The call to atk4\ui\jQuery::closest() has too many arguments starting with 'tr'. ( Ignorable by Annotation )

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

81
					[(new jQuery())->/** @scrutinizer ignore-call */ closest('tr')->data('id')]

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
82
			));
83
		}
84
		
85
		$this->grid->addDragHandler()->onReorder(function ($order) {
1 ignored issue
show
Bug introduced by
The method addDragHandler() does not exist on atk4\ui\View. It seems like you code against a sub-type of atk4\ui\View such as atk4\ui\Grid. ( Ignorable by Annotation )

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

85
		$this->grid->/** @scrutinizer ignore-call */ 
86
               addDragHandler()->onReorder(function ($order) {
Loading history...
86
			$result = true;
87
			foreach ($this->nodes()->get() as $node) {
88
				$node->position = array_search($node->id, $order);
89
				
90
				$result &= $node->save();
91
			}
92
			
93
			$notifier = $result? $this->notify(__('Items reordered!')): $this->notifyError(__('Error saving order!'));
94
			
95
			return $this->grid->jsSave($notifier);
96
		});
97
		
98
		$this->addContolButton('update', $this->getUpdateModal(), 'edit');
99
			
100
		$this->addContolButton('delete', function ($jschain, $id) {
101
			CommonData::find($id)->delete();
102
				
103
			return $jschain->closest('tr')->transition('fade left');
104
		}, 'red trash');
105
			
106
		$this->grid->addColumn('actions', ['Multiformat', function($row, $column) {		
0 ignored issues
show
Unused Code introduced by
The parameter $column 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

106
		$this->grid->addColumn('actions', ['Multiformat', function($row, /** @scrutinizer ignore-unused */ $column) {		

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...
107
			return [['Template', $this->getControlButtonsHtml($row)]];
108
		}, 'caption' => ' ']);
109
		
110
		return $this;
111
	}
112
	
113
	public function getControlButtonsHtml($row)
114
	{
115
		if ($row['readonly']) return '';
116
		
117
		$ret = '';
118
		foreach ($this->buttons as $button) {
119
			$ret .= $button->getHtml();
120
		}
121
		
122
		return $ret;;
123
	}
124
	
125
	public function getUpdateModal()
126
	{
127
		$grid = $this->grid;
128
		
129
		$grid->pageUpdate = $grid->add($grid->pageUpdate ?: $grid->pageDefault, ['short_name'=>'edit']);
130
		
131
		$modal = new jsModal(__('Edit'), $grid->pageUpdate, [$grid->name => $grid->jsRow()->data('id'), $grid->name.'_sort' => $grid->getSortBy()]);
132
		
133
		$grid->pageUpdate->set(function () {
134
			$grid = $this->grid;
135
			
136
			$grid->model->load($grid->app->stickyGet($grid->name));
137
			
138
			// Maybe developer has already created form
139
			if (!is_object($grid->formUpdate) || !$grid->formUpdate->_initialized) {
140
				$grid->formUpdate = $grid->pageUpdate->add($grid->formUpdate ?: $grid->formDefault);
141
			}
142
			
143
			$grid->formUpdate->setModel($grid->model, $grid->fieldsUpdate ?: $grid->fieldsDefault);
144
			
145
			if ($sortBy = $grid->getSortBy()) {
146
				$grid->formUpdate->stickyGet($grid->name.'_sort', $sortBy);
147
			}
148
			
149
			// set save handler with reload trigger
150
			// adds default submit hook if it is not already set for this form
151
			if (!$grid->formUpdate->hookHasCallbacks('submit')) {
152
				$grid->formUpdate->onSubmit(function ($form) {
153
					$form->model->save();
154
					
155
					return $this->grid->jsSaveUpdate();
156
				});
157
			}
158
		});
159
		
160
		return $modal;
161
	}
162
	
163
	public function addContolButton($name, $callback, $icon = null)
164
	{
165
		$class = "button_$name";
166
		
167
		$this->grid->on('click', ".$class", $callback, [$this->grid->table->jsRow()->data('id')]);
168
		
169
		$this->buttons[$name] = new \atk4\ui\Button($icon? compact('icon'): $name);
170
		
171
		$this->buttons[$name]->app = $this->app;
172
		
173
		$this->buttons[$name]->addClass("compact $class");
174
	}
175
	
176
	public function nodes()
177
	{
178
		return CommonData::where('parent_id', $this->parentId);
179
	}
180
	
181
	public function getModel()
182
	{
183
		$rows = [];
184
		foreach ($this->nodes()->orderBy('position')->get() as $node) {
185
			$rows[] = [
186
					'id' => $node->id,
187
					'position' => $node->position,
188
					'key' => $node->key,
189
					'value' => $node->value,
190
					'readonly' => $node->readonly
191
			];
192
		}
193
		
194
		$rowsEmpty = [];
195
		
196
		$model = new \atk4\data\Model($rows? new \atk4\data\Persistence_Static($rows): new \atk4\data\Persistence_Array($rowsEmpty));
197
		
198
		$captions = [
199
				'position' => __('Position'),
200
				'key' => __('Key'),
201
				'value' => __('Value'),
202
				'readonly' => __('Read Only')
203
		];
204
		
205
		foreach ($captions as $key => $caption) {
206
			$field = $rows? $model->hasField($key): $model->addField($key);
207
			
208
			if ($key === 'readonly') {
209
				$field->setDefaults(['ui' => ['visible' => false]]);
210
				
211
				continue;
212
			}
213
			
214
			$field->setDefaults(compact('caption'));
215
		}
216
		
217
		return $model;
218
	}
219
	
220
	public function getNodeForm()
221
	{
222
		if (! $this->form) {
223
			$this->form = new Form(['buttonSave' => ['Button', __('Save'), 'primary']]);
224
			
225
			$this->form->addHook('submit', function($form) {
226
				$values = $form->getValues();
227
				
228
				if ($id = $values['id']?? null) {
229
					CommonData::find($id)->update($values);
230
					
231
					return $this->grid->jsSaveUpdate();
232
				}
233
				
234
				CommonData::create(array_merge($values, [
235
						'position' => $this->nodes()->max('position') + 1
236
				]), $this->parentId? CommonData::find($this->parentId): null);
237
				
238
				return $this->grid->jsSaveCreate();
239
			});
240
		}
241
		
242
		return $this->form;
243
	}
244
}
245