Completed
Push — master ( 4b1131...dbc6d3 )
by Jean-Christophe
01:37
created

CRUDController::newModel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 11
Ratio 100 %

Importance

Changes 0
Metric Value
dl 11
loc 11
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Ubiquity\controllers\crud;
4
5
use Ubiquity\orm\DAO;
6
use Ubiquity\controllers\ControllerBase;
7
use Ubiquity\controllers\admin\interfaces\HasModelViewerInterface;
8
use Ubiquity\controllers\admin\viewers\ModelViewer;
9
use Ubiquity\controllers\semantic\MessagesTrait;
10
use Ubiquity\utils\http\URequest;
11
use Ubiquity\utils\http\UResponse;
12
use Ubiquity\controllers\rest\ResponseFormatter;
13
use Ajax\semantic\widgets\datatable\Pagination;
14
use Ubiquity\orm\OrmUtils;
15
use Ubiquity\utils\base\UString;
16
use Ajax\semantic\html\collections\HtmlMessage;
17
use Ajax\common\html\HtmlContentOnly;
18
19
abstract class CRUDController extends ControllerBase implements HasModelViewerInterface{
20
	use MessagesTrait;
21
	protected $model;
22
	protected $modelViewer;
23
	protected $events;
24
	protected $crudFiles;
25
	protected $adminDatas;
26
	protected $activePage;
27
	
28
	/**
29
	 * Default page : list all objects
30
	 * Uses modelViewer.isModal, modelViewer.getModelDataTable
31
	 * Uses CRUDFiles.getViewIndex template (default : @framework/crud/index.html)
32
	 * Triggers the events onDisplayElements,beforeLoadView
33
	 */
34
	public function index() {
35
		$objects=$this->getInstances($totalCount);
36
		$modal=($this->_getModelViewer()->isModal($objects,$this->model))?"modal":"no";
37
		$dt=$this->_getModelViewer()->getModelDataTable($objects, $this->model,$totalCount);
38
		$this->jquery->getOnClick ( "#btAddNew", $this->_getBaseRoute() . "/newModel/" . $modal, "#frm-add-update",["hasLoader"=>"internal"] );
39
		$this->_getEvents()->onDisplayElements($dt,$objects,false);
40
		$this->crudLoadView($this->_getFiles()->getViewIndex(), [ "classname" => $this->model ,"messages"=>$this->jquery->semantic()->matchHtmlComponents(function($compo){return $compo instanceof HtmlMessage;})]);		
1 ignored issue
show
Bug introduced by
The class Ajax\semantic\html\collections\HtmlMessage does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
41
	}
42
	
43
	protected function getInstances(&$totalCount,$page=1,$id=null){
44
		$this->activePage=$page;
45
		$model=$this->model;
46
		$condition=$this->_getAdminData()->_getInstancesFilter($model);
47
		$totalCount=DAO::count($model,$condition);
48
		$recordsPerPage=$this->_getModelViewer()->recordsPerPage($model,$totalCount);
49
		if(is_numeric($recordsPerPage)){
50
			if(isset($id)){
51
				$rownum=DAO::getRownum($model, $id);
52
				$this->activePage=Pagination::getPageOfRow($rownum,$recordsPerPage);
53
			}
54
			return DAO::paginate($model,$this->activePage,$recordsPerPage,$condition);
55
		}
56
		return DAO::getAll($model,$condition);
57
	}
58
	
59
	protected function search($model,$search){
60
		$fields=$this->_getAdminData()->getSearchFieldNames($model);
61
		$condition=$this->_getAdminData()->_getInstancesFilter($model);
62
		return CRUDHelper::search($model, $search, $fields,$condition);
63
	}
64
	
65
	public function updateMember($member,$callback=false){
66
		$instance=@$_SESSION["instance"];
67
		$updated=CRUDHelper::update($instance, $_POST);
68
		if($updated){
69
			if($callback===false){
70
				$dt=$this->_getModelViewer()->getModelDataTable([$instance], $this->model, 1);
71
				$dt->compile();
72
				echo new HtmlContentOnly($dt->getFieldValue($member));
73
			}else{
74
				if(method_exists($this, $callback)){
75
					$this->$callback($member,$instance);
76
				}else{
77
					throw new \Exception("The method `".$callback."` does not exists in ".get_class());
78
				}
79
			}
80
		}else{
81
			UResponse::setResponseCode(404);
82
		}
83
	}
84
	
85
	protected function updateMemberDataElement($member,$instance){
86
		$dt=$this->_getModelViewer()->getModelDataElement($instance, $this->model, false);
87
		$dt->compile();
88
		echo new HtmlContentOnly($dt->getFieldValue($member));
89
	}
90
	
91
	/**
92
	 * Refreshes the area corresponding to the DataTable
93
	 */
94
	public function refresh_(){
95
		$model=$this->model;
96
		if(isset($_POST["s"])){
97
			$instances=$this->search($model, $_POST["s"]);
98
		}else{
99
			$page=URequest::post("p",1);
100
			$instances=$this->getInstances($totalCount,$page);
101
		}
102
		if(!isset($totalCount)){
103
			$totalCount=DAO::count($model,$this->_getAdminData()->_getInstancesFilter($model));
104
		}
105
		$recordsPerPage=$this->_getModelViewer()->recordsPerPage($model,$totalCount);
106
		$grpByFields=$this->_getModelViewer()->getGroupByFields();
107
		if(isset($recordsPerPage)){
108
			if(!is_array($grpByFields)){
109
				UResponse::asJSON();
110
				$responseFormatter=new ResponseFormatter();
111
				print_r($responseFormatter->getJSONDatas($instances));
112
			}else{
113
				$this->_renderDataTableForRefresh($instances, $model,$totalCount);
114
			}
115
		}else{
116
			$this->jquery->execAtLast('$("#search-query-content").html("'.$_POST["s"].'");$("#search-query").show();$("#table-details").html("");');
117
			$this->_renderDataTableForRefresh($instances, $model,$totalCount);
118
		}
119
	}
120
	
121
	private function _renderDataTableForRefresh($instances,$model,$totalCount){
122
		$this->formModal=($this->_getModelViewer()->isModal($instances,$model))? "modal" : "no";
123
		$compo= $this->_getModelViewer()->getModelDataTable($instances, $model,$totalCount)->refresh(["tbody"]);
124
		$this->_getEvents()->onDisplayElements($compo,$instances,true);
125
		$compo->setLibraryId("_compo_");
126
		$this->jquery->renderView("@framework/main/component.html");
127
	}
128
	
129
	/**
130
	 * Edits an instance
131
	 * @param string $modal Accept "no" or "modal" for a modal dialog
132
	 * @param string $ids the primary value(s)
133
	 */
134 View Code Duplication
	public function edit($modal="no", $ids="") {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
135
		if(URequest::isAjax()){
136
			$instance=$this->getModelInstance($ids);
137
			$instance->_new=false;
138
			$this->_edit($instance, $modal);
139
		}else{
140
			$this->jquery->execAtLast("$('._edit[data-ajax={$ids}]').trigger('click');");
141
			$this->index();
142
		}
143
	}
144
	/**
145
	 * Adds a new instance and edits it
146
	 * @param string $modal Accept "no" or "modal" for a modal dialog
147
	 */
148 View Code Duplication
	public function newModel($modal="no") {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
149
		if(URequest::isAjax()){
150
			$model=$this->model;
151
			$instance=new $model();
152
			$instance->_new=true;
153
			$this->_edit($instance, $modal);
154
		}else{
155
			$this->jquery->execAtLast("$('.ui.button._new').trigger('click');");
156
			$this->index();
157
		}
158
	}
159
	
160
	public function editMember($member){
161
		$ids=URequest::post("id");
162
		$td=URequest::post("td");
163
		$part=URequest::post("part");
164
		$instance=$this->getModelInstance($ids);
165
		$_SESSION["instance"]=$instance;
166
		$instance->_new=false;
167
		$form=$this->_getModelViewer()->getMemberForm("frm-member-".$member, $instance, $member,$td,$part);
168
		$form->setLibraryId("_compo_");
169
		$this->jquery->renderView("@framework/main/component.html");
170
	}
171
	
172
	/**
173
	 * Displays an instance
174
	 * @param string $modal
175
	 * @param string $ids
176
	 */
177
	public function display($modal="no",$ids=""){
178
		if(URequest::isAjax()){
179
			$instance=$this->getModelInstance($ids);
180
			$key=OrmUtils::getFirstKeyValue($instance);
181
			$this->jquery->execOn("click","._close",'$("#table-details").html("");$("#dataTable").show();');
182
			$this->jquery->getOnClick("._edit", $this->_getBaseRoute()."/edit/".$modal."/".$key,"#frm-add-update");
183
			$this->jquery->getOnClick("._delete", $this->_getBaseRoute()."/delete/".$key,"#table-messages");
184
			
185
			$this->_getModelViewer()->getModelDataElement($instance, $this->model,$modal);
186
			$this->jquery->renderView($this->_getFiles()->getViewDisplay(), [ "classname" => $this->model,"instance"=>$instance,"pk"=>$key ]);
187
		}else{
188
			$this->jquery->execAtLast("$('._display[data-ajax={$ids}]').trigger('click');");
189
			$this->index();
190
		}
191
	}
192
	
193
	protected function _edit($instance, $modal="no") {
194
		$_SESSION["instance"]=$instance;
195
		$modal=($modal == "modal");
196
		$form=$this->_getModelViewer()->getForm("frmEdit", $instance);
197
		$this->jquery->click("#action-modal-frmEdit-0", "$('#frmEdit').form('submit');", false);
198
		if (!$modal) {
199
			$this->jquery->click("#bt-cancel", "$('#form-container').transition('drop');");
200
			$this->jquery->compile($this->view);
201
			$this->loadView($this->_getFiles()->getViewForm(), [ "modal" => $modal,"instance"=>$instance,"isNew"=>$instance->_new ]);
202
		} else {
203
			$this->jquery->exec("$('#modal-frmEdit').modal('show');", true);
204
			$form=$form->asModal(\get_class($instance));
205
			$form->setActions([ "Okay","Cancel" ]);
206
			$btOkay=$form->getAction(0);
207
			$btOkay->addClass("green")->setValue("Validate modifications");
208
			$form->onHidden("$('#modal-frmEdit').remove();");
209
			echo $form->compile($this->jquery, $this->view);
210
			echo $this->jquery->compile($this->view);
211
		}
212
	}
213
	
214
	protected function _showModel($id=null) {
215
		$model=$this->model;
216
		$datas=$this->getInstances($totalCount,1,$id);
217
		$this->formModal=($this->_getModelViewer()->isModal($datas,$model))? "modal" : "no";
218
		return $this->_getModelViewer()->getModelDataTable($datas, $model,$totalCount,$this->activePage);
219
	}
220
	
221
	/**
222
	 * Deletes an instance
223
	 * @param mixed $ids
224
	 */
225
	public function delete($ids) {
226
		if(URequest::isAjax()){
227
			$instance=$this->getModelInstance($ids);
228 View Code Duplication
			if (method_exists($instance, "__toString"))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
229
				$instanceString=$instance . "";
230
			else
231
				$instanceString=get_class($instance);
232
			if (sizeof($_POST) > 0) {
233
				try{
234
					if (DAO::remove($instance)) {
0 ignored issues
show
Bug introduced by
It seems like $instance defined by $this->getModelInstance($ids) on line 227 can also be of type null; however, Ubiquity\orm\traits\DAOUpdatesTrait::remove() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
235
						$message=new CRUDMessage("Deletion of `<b>" . $instanceString . "</b>`","Deletion","info","info circle",4000);
236
						$message=$this->_getEvents()->onSuccessDeleteMessage($message,$instance);
0 ignored issues
show
Bug introduced by
It seems like $instance defined by $this->getModelInstance($ids) on line 227 can also be of type null; however, Ubiquity\controllers\cru...nSuccessDeleteMessage() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
237
						$this->jquery->exec("$('._element[data-ajax={$ids}]').remove();", true);
238
					} else {
239
						$message=new CRUDMessage("Can not delete `" . $instanceString . "`","Deletion","warning","warning circle");
240
						$message=$this->_getEvents()->onErrorDeleteMessage($message,$instance);
0 ignored issues
show
Bug introduced by
It seems like $instance defined by $this->getModelInstance($ids) on line 227 can also be of type null; however, Ubiquity\controllers\cru...:onErrorDeleteMessage() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
241
					}
242
				}catch (\Exception $e){
243
					$message=new CRUDMessage("Exception : can not delete `" . $instanceString . "`","Exception", "warning", "warning");
244
					$message=$this->_getEvents()->onErrorDeleteMessage($message,$instance);
0 ignored issues
show
Bug introduced by
It seems like $instance defined by $this->getModelInstance($ids) on line 227 can also be of type null; however, Ubiquity\controllers\cru...:onErrorDeleteMessage() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
245
				}
246
				$message=$this->_showSimpleMessage($message);
247
			} else {
248
				$message=new CRUDMessage("Do you confirm the deletion of `<b>" . $instanceString . "</b>`?", "Remove confirmation","error","question circle");
249
				$message=$this->_getEvents()->onConfDeleteMessage($message,$instance);
0 ignored issues
show
Bug introduced by
It seems like $instance defined by $this->getModelInstance($ids) on line 227 can also be of type null; however, Ubiquity\controllers\cru...::onConfDeleteMessage() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
250
				$message=$this->_showConfMessage($message, $this->_getBaseRoute() . "/delete/{$ids}", "#table-messages", $ids);
251
			}
252
			echo $message;
253
			echo $this->jquery->compile($this->view);
254
		}else{
255
			$this->jquery->execAtLast("$('._delete[data-ajax={$ids}]').trigger('click');");
256
			$this->index();
257
		}
258
	}
259
	
260
	/**
261
	 * Helper to delete multiple objects
262
	 * @param mixed $data
263
	 * @param string $action
264
	 * @param string $target the css selector for refreshing
265
	 * @param callable|string $condition the callback for generating the SQL where (for deletion) with the parameter data, or a simple string
266
	 */
267
	protected function _deleteMultiple($data,$action,$target,$condition){
268
		if(URequest::isPost()){
269
			if(is_callable($condition)){
270
				$condition=$condition($data);
271
			}
272
			$rep=DAO::deleteAll($this->model, $condition);
273
			if($rep){
274
				$message=new CRUDMessage("Deleting {count} objects","Deletion","info","info circle",4000);
275
				$message=$this->_getEvents()->onSuccessDeleteMultipleMessage($message,$rep);
276
				$message->parseContent(["count"=>$rep]);
277
			}
278
			$this->_showSimpleMessage($message,"delete-all");
0 ignored issues
show
Bug introduced by
The variable $message does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
279
			$this->index();
280
		}else{
281
			$message=new CRUDMessage("Do you confirm the deletion of this objects?", "Remove confirmation","error");
282
			$this->_getEvents()->onConfDeleteMultipleMessage($message,$data);
283
			$message=$this->_showConfMessage($message, $this->_getBaseRoute() . "/{$action}/{$data}",$target, $data,["jqueryDone"=>"replaceWith"]);
284
			echo $message;
285
			echo $this->jquery->compile($this->view);
286
		}
287
	}
288
	
289
290
	
291
	public function refreshTable($id=null) {
292
		$compo= $this->_showModel($id);
293
		$this->jquery->execAtLast('$("#table-details").html("");');
294
		$compo->setLibraryId("_compo_");
295
		$this->jquery->renderView("@framework/main/component.html");	
296
	}
297
	
298
	/**
299
	 * Updates an instance from the data posted in a form
300
	 * @return object The updated instance
301
	 */
302
	public function update() {
303
		$message=new CRUDMessage("Modifications were successfully saved", "Updating");
304
		$instance=@$_SESSION["instance"];
305
		$isNew=$instance->_new;
306
		try{
307
			$updated=CRUDHelper::update($instance, $_POST);
308
			if($updated){
309
				$message->setType("success")->setIcon("check circle outline");
310
				$message=$this->_getEvents()->onSuccessUpdateMessage($message,$instance);
311
				$this->refreshInstance($instance,$isNew);
312
			} else {
313
				$message->setMessage("An error has occurred. Can not save changes.")->setType("error")->setIcon("warning circle");
0 ignored issues
show
Bug introduced by
The method setType cannot be called on $message->setMessage('An...Can not save changes.') (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
314
				$message=$this->_getEvents()->onErrorUpdateMessage($message,$instance);
315
			}
316
		}catch(\Exception $e){
317 View Code Duplication
			if (method_exists($instance, "__toString"))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
318
				$instanceString=$instance . "";
319
			else
320
				$instanceString=get_class($instance);
321
			$message=new CRUDMessage("Exception : can not update `" . $instanceString . "`","Exception", "warning", "warning");
322
			$message=$this->_getEvents()->onErrorUpdateMessage($message,$instance);
323
		}
324
		echo $this->_showSimpleMessage($message,"updateMsg");
325
		echo $this->jquery->compile($this->view);
326
		return $instance;
327
	}
328
	
329
	protected function refreshInstance($instance,$isNew){
330
		if($this->_getAdminData()->refreshPartialInstance() && !$isNew){
331
			$this->jquery->setJsonToElement(OrmUtils::objectAsJSON($instance));
332
		}else{
333
			$pk=OrmUtils::getFirstKeyValue($instance);
334
			$this->jquery->get($this->_getBaseRoute() . "/refreshTable/".$pk, "#lv", [ "jqueryDone" => "replaceWith" ]);
335
		}
336
	}
337
	
338
	/**
339
	 * Shows associated members with foreign keys
340
	 * @param mixed $ids
341
	 */
342
	public function showDetail($ids) {
343
		if(URequest::isAjax()){
344
			$instance=$this->getModelInstance($ids);
345
			$viewer=$this->_getModelViewer();
346
			$hasElements=false;
347
			$model=$this->model;
348
			$fkInstances=CRUDHelper::getFKIntances($instance, $model);
349
			$semantic=$this->jquery->semantic();
350
			$grid=$semantic->htmlGrid("detail");
351
			if (sizeof($fkInstances) > 0) {
352
				$wide=intval(16 / sizeof($fkInstances));
353
				if ($wide < 4)
354
					$wide=4;
355
					foreach ( $fkInstances as $member=>$fkInstanceArray ) {
356
						$element=$viewer->getFkMemberElementDetails($member,$fkInstanceArray["objectFK"],$fkInstanceArray["fkClass"],$fkInstanceArray["fkTable"]);
357
						if (isset($element)) {
358
							$grid->addCol($wide)->setContent($element);
359
							$hasElements=true;
360
						}
361
					}
362
					if ($hasElements){
363
						echo $grid;
364
						$url=$this->_getFiles()->getDetailClickURL($this->model);
365
						if(UString::isNotNull($url)){
366
							$this->detailClick($url);
367
						}
368
					}
369
					echo $this->jquery->compile($this->view);
370
			}
371
		}else{
372
			$this->jquery->execAtLast("$('tr[data-ajax={$ids}]').trigger('click');");
373
			$this->index();
374
		}
375
376
	}
377
	
378
	public function detailClick($url) {
379
		$this->jquery->postOnClick(".showTable", $this->_getBaseRoute() . "/".$url,"{}", "#divTable", [ "attr" => "data-ajax","ajaxTransition" => "random" ]);
380
	}
381
	
382
	private function getModelInstance($ids) {
383
		$ids=\explode("_", $ids);
384
		$instance=DAO::getOne($this->model, $ids);
385
		if(isset($instance)){
386
			return $instance;
387
		}
388
		$message=new CRUDMessage("This object does not exist!","Get object","warning","warning circle");
389
		$message=$this->_getEvents()->onNotFoundMessage($message,$ids);
390
		echo $this->_showSimpleMessage($message);
391
		echo $this->jquery->compile($this->view);
392
		exit(1);
393
	}
394
	
395
	/**
396
	 * To override for defining a new adminData
397
	 * @return CRUDDatas
398
	 */
399
	protected function getAdminData ():CRUDDatas{
400
		return new CRUDDatas();
401
	}
402
	
403
	public function _getAdminData ():CRUDDatas{
404
		return $this->getSingleton($this->modelViewer,"getAdminData");
405
	}
406
	
407
	/**
408
	 * To override for defining a new ModelViewer
409
	 * @return ModelViewer
410
	 */
411
	protected function getModelViewer ():ModelViewer{
412
		return new ModelViewer($this);
413
	}
414
	
415
	private function _getModelViewer():ModelViewer{
416
		return $this->getSingleton($this->modelViewer,"getModelViewer");
417
	}
418
	
419
	/**
420
	 * To override for changing view files
421
	 * @return CRUDFiles
422
	 */
423
	protected function getFiles ():CRUDFiles{
424
		return new CRUDFiles();
425
	}
426
	
427
	/**
428
	 * @return CRUDFiles
429
	 */
430
	public function _getFiles(){
431
		return $this->getSingleton($this->crudFiles,"getFiles");
432
	}
433
	
434
	/**
435
	 * To override for changing events
436
	 * @return CRUDEvents
437
	 */
438
	protected function getEvents ():CRUDEvents{
439
		return new CRUDEvents($this);
440
	}
441
	
442
	private function _getEvents():CRUDEvents{
443
		return $this->getSingleton($this->events,"getEvents");
444
	}
445
	
446
	private function getSingleton($value, $method) {
447
		if (! isset ( $value )) {
448
			$value = $this->$method ();
449
		}
450
		return $value;
451
	}
452
	
453
	private function crudLoadView($viewName,$vars=[]){
454
		$this->_getEvents()->beforeLoadView($viewName,$vars);
455
		if(!URequest::isAjax()){
456
			$files=$this->_getFiles();
457
			$mainTemplate=$files->getBaseTemplate();
458
			if(isset($mainTemplate)){
459
				$vars["_viewname"]=$viewName;
460
				$vars["_base"]=$mainTemplate;
461
				$this->jquery->renderView($files->getViewBaseTemplate(),$vars);
462
			}else{
463
				$vars["hasScript"]=true;
464
				$this->jquery->renderView($viewName,$vars);
465
			}
466
		}else{
467
			$vars["hasScript"]=true;
468
			$this->jquery->renderView($viewName,$vars);
469
		}
470
	}
471
472
}
473