Ubiquity  2.0.3
php rapid development framework
ModelViewer.php
Go to the documentation of this file.
1 <?php
2 
4 
13 use Ajax\JsUtils;
22 
23 class ModelViewer {
24 
28  private $jquery;
29 
33  protected $controller;
34 
36  $this->jquery = $controller->jquery;
37  $this->controller=$controller;
38  }
47  public function getForm($identifier, $instance) {
48  $type = ($instance->_new) ? "new" : "edit";
49  $messageInfos = [ "new" => [ "icon" => HtmlIconGroups::corner ( "table", "plus", "big" ),"message" => "New object creation" ],"edit" => [ "icon" => HtmlIconGroups::corner ( "table", "edit", "big" ),"message" => "Editing an existing object" ] ];
50  $message = $messageInfos [$type];
51  $form = $this->jquery->semantic ()->dataForm ( $identifier, $instance );
52  $className = \get_class ( $instance );
53  $fields = $this->controller->_getAdminData ()->getFormFieldNames ( $className );
54  $form->setFields ( $fields );
55  $form->insertField ( 0, "_message" );
56  $form->fieldAsMessage ( "_message", [ "icon" => $message ["icon"] ] );
57  $instance->_message = $className;
58  $fieldTypes = OrmUtils::getFieldTypes ( $className );
59  $this->setFormFieldsComponent($form, $fieldTypes);
60  $this->relationMembersInForm ( $form, $instance, $className );
61  $form->setCaptions ( $this->getFormCaptions ( $form->getInstanceViewer ()->getVisibleProperties (), $className, $instance ) );
62  $form->setCaption ( "_message", $message ["message"] );
63  $form->setSubmitParams ( $this->controller->_getBaseRoute () . "/update", "#frm-add-update" );
64  return $form;
65  }
66 
72  public function setFormFieldsComponent(DataForm $form,$fieldTypes){
73  foreach ( $fieldTypes as $property => $type ) {
74  switch ($type) {
75  case "tinyint(1)" :
76  $form->fieldAsCheckbox ( $property );
77  break;
78  case "int" :
79  case "integer" :
80  $form->fieldAsInput ( $property, [ "inputType" => "number" ] );
81  break;
82  case "date" :
83  $form->fieldAsInput ( $property, [ "inputType" => "date" ] );
84  break;
85  case "datetime" :
86  $form->fieldAsInput ( $property, [ "inputType" => "datetime-local" ] );
87  break;
88  }
89  }
90  }
91 
92  public function getModelDataElement($instance,$model,$modal){
93  $adminRoute = $this->controller->_getBaseRoute ();
94  $semantic = $this->jquery->semantic ();
95  $fields = $this->controller->_getAdminData ()->getElementFieldNames( $model );
96 
97  $dataElement = $semantic->dataElement( "de", $instance );
98  $pk=OrmUtils::getFirstKeyValue($instance);
99  $dataElement->getInstanceViewer()->setIdentifierFunction(function() use($pk){return $pk;});
100  $dataElement->setFields($fields);
101  $dataElement->setCaptions($this->getElementCaptions($fields, $model, $instance));
102 
103  $fkInstances=CRUDHelper::getFKIntances($instance, $model);
104  foreach ( $fkInstances as $member=>$fkInstanceArray ) {
105  if(array_search($member, $fields)!==false){
106  $dataElement->setValueFunction($member, function() use($fkInstanceArray,$member){
107  return $this->getFkMemberElement($member,$fkInstanceArray["objectFK"],$fkInstanceArray["fkClass"],$fkInstanceArray["fkTable"]);
108  });
109  }
110  }
111  return $dataElement;
112  }
113 
123  public function getModelDataTable($instances, $model,$page=1) {
124  $adminRoute = $this->controller->_getBaseRoute ();
125  $semantic = $this->jquery->semantic ();
126 
127  $modal = ($this->isModal ( $instances, $model ) ? "modal" : "no");
128  $dataTable = $this->getDataTableInstance( $instances,$model,$page );
129  $attributes = $this->controller->_getAdminData()->getFieldNames ( $model );
130 
131  $dataTable->setCaptions ( $this->getCaptions ( $attributes, $model ) );
132  $dataTable->setButtons($this->getDataTableRowButtons());
133  $dataTable->setFields ( $attributes );
134 
135  $dataTable->setIdentifierFunction ( CRUDHelper::getIdentifierFunction ( $model ) );
136  if($this->showDetailsOnDataTableClick()){
137  $dataTable->getOnRow ( "click", $adminRoute . "/showDetail", "#table-details", [ "attr" => "data-ajax" ] );
138  $dataTable->setActiveRowSelector ( "error" );
139  }
140  $dataTable->setUrls ( [ "refresh"=>$adminRoute . "/refresh_","delete" => $adminRoute . "/delete","edit" => $adminRoute . "/edit/" . $modal ,"display"=> $adminRoute."/display/".$modal] );
141  $dataTable->setTargetSelector ( [ "delete" => "#table-messages","edit" => "#frm-add-update" ,"display"=>"#table-details" ] );
142  $dataTable->addClass ( "small very compact" );
143  $lbl=new HtmlLabel("search-query","<span id='search-query-content'></span>");
144  $icon=$lbl->addIcon("delete",false);
145  $lbl->wrap("<span>","</span>");
146  $lbl->setProperty("style", "display: none;");
147  $icon->getOnClick($adminRoute."/refreshTable","#lv",["jqueryDone"=>"replaceWith","hasLoader"=>"internal"]);
148 
149  $dataTable->addItemInToolbar($lbl);
150  $dataTable->addSearchInToolbar();
151  $dataTable->setToolbarPosition(PositionInTable::FOOTER);
152  $dataTable->getToolbar()->setSecondary();
153  $this->addAllButtons($dataTable, $attributes);
154  return $dataTable;
155  }
156 
157  public function recordsPerPage($model,$totalCount=0){
158  if($totalCount>6)
159  return 6;
160  return ;
161  }
162 
163  protected function getDataTableInstance($instances,$model,$page=1):DataTable{
164  $totalCount=DAO::count($model,$this->controller->_getInstancesFilter($model));
165  $semantic = $this->jquery->semantic ();
166  $recordsPerPage=$this->recordsPerPage($model,$totalCount);
167  if(is_numeric($recordsPerPage)){
168  $dataTable = $semantic->jsonDataTable( "lv", $model, $instances );
169  $dataTable->paginate($page,$totalCount,$recordsPerPage,5);
170  $dataTable->onActiveRowChange('$("#table-details").html("");');
171  $dataTable->onSearchTerminate('$("#search-query-content").html(data);$("#search-query").show();$("#table-details").html("");');
172  }else{
173  $dataTable = $semantic->dataTable( "lv", $model, $instances );
174  }
175  return $dataTable;
176  }
177 
182  protected function getDataTableRowButtons(){
183  return ["edit","delete"];
184  }
185 
186  public function addAllButtons(DataTable $dataTable,$attributes){
187  $dataTable->onPreCompile ( function () use ($attributes, &$dataTable) {
188  $dataTable->getHtmlComponent ()->colRight ( \count ( $attributes ) );
189  } );
190  $dataTable->addAllButtons( false, [ "ajaxTransition" => "random" ], function ($bt) {
191  $bt->addClass ( "circular" );
192  }, function ($bt) {
193  $bt->addClass ( "circular" );
194  }, function ($bt) {
195  $bt->addClass ( "circular" );
196  });
197  $dataTable->setDisplayBehavior(["jsCallback"=>'$("#dataTable").hide();',"ajaxTransition"=>"random"]);
198  }
199 
200  public function confirmButtons(HtmlButton $confirmBtn,HtmlButton $cancelBtn){
201 
202  }
203 
204 
212  public function isModal($objects, $model) {
213  return \count ( $objects ) > 5;
214  }
215 
222  public function getCaptions($captions, $className) {
223  return array_map ( "ucfirst", $captions );
224  }
225 
232  public function getFormCaptions($captions, $className, $instance) {
233  return array_map ( "ucfirst", $captions );
234  }
235 
242  public function getElementCaptions($captions, $className, $instance) {
243  return array_map ( "ucfirst", $captions );
244  }
245 
253  public function getFkHeaderElementDetails($member, $className, $object) {
254  return new HtmlHeader( "", 4, $member, "content" );
255  }
256 
264  public function getFkHeaderListDetails($member, $className, $list) {
265  return new HtmlHeader( "", 4, $member . " (" . \count ( $list ) . ")", "content" );
266  }
267 
275  public function getFkElementDetails($member, $className, $object) {
276  return $this->jquery->semantic ()->htmlLabel ( "element-" . $className . "." . $member, $object . "" );
277  }
278 
286  public function getFkListDetails($member, $className, $list) {
287  $element = $this->jquery->semantic ()->htmlList ( "list-" . $className . "." . $member );
288  $element->setMaxVisible(15);
289 
290  return $element->addClass ( "animated divided celled" );
291  }
292 
301  public function getFkMemberElementDetails($memberFK,$objectFK,$fkClass,$fkTable){
302  $header=new HtmlHeader("", 4, $memberFK, "content");
303  if (is_array($objectFK) || $objectFK instanceof \Traversable) {
304  $header=$this->getFkHeaderListDetails($memberFK, $fkClass, $objectFK);
305  $element=$this->getFkListDetails($memberFK, $fkClass, $objectFK);
306  foreach ( $objectFK as $oItem ) {
307  if (method_exists($oItem, "__toString")) {
308  $id=(CRUDHelper::getIdentifierFunction($fkClass))(0, $oItem);
309  $item=$element->addItem($oItem . "");
310  $item->setProperty("data-ajax", $fkTable . "." . $id);
311  $item->addClass("showTable");
312  $this->displayFkElementListDetails($item, $memberFK, $fkClass, $oItem);
313  }
314  }
315  } else {
316  if (method_exists($objectFK, "__toString")) {
317  $header=$this->getFkHeaderElementDetails($memberFK, $fkClass, $objectFK);
318  $id=(CRUDHelper::getIdentifierFunction($fkClass))(0, $objectFK);
319  $element=$this->getFkElementDetails($memberFK, $fkClass, $objectFK);
320  $element->setProperty("data-ajax", $fkTable . "." . $id)->addClass("showTable");
321  }
322  }
323  if(isset($element)){
324  return [$header,$element];
325  }
326  return null;
327  }
328 
336  public function displayFkElementListDetails($element, $member, $className, $object) {
337  }
338 
347  public function getFkMemberElement($memberFK,$objectFK,$fkClass,$fkTable){
348  $element="";
349  if (is_array($objectFK) || $objectFK instanceof \Traversable) {
350  $element=$this->getFkList($memberFK,$objectFK);
351  foreach ( $objectFK as $oItem ) {
352  if (method_exists($oItem, "__toString")) {
353  $id=(CRUDHelper::getIdentifierFunction($fkClass))(0, $oItem);
354  $item=$element->addItem($oItem . "");
355  $item->setProperty("data-ajax", $fkTable . "." . $id);
356  $item->addClass("showTable");
357  $this->displayFkElementList($item, $memberFK, $fkClass, $oItem);
358  }
359  }
360  } else {
361  if (method_exists($objectFK, "__toString")) {
362  $id=(CRUDHelper::getIdentifierFunction($fkClass))(0, $objectFK);
363  $element=$this->getFkElement($memberFK, $fkClass, $objectFK);
364  $element->setProperty("data-ajax", $fkTable . "." . $id)->addClass("showTable");
365  }
366  }
367  return $element;
368  }
369 
377  public function getFkList($member, $list) {
378  $element = $this->jquery->semantic ()->htmlList ( "list-". $member );
379  $element->setMaxVisible(10);
380  return $element->addClass ( "animated" );
381  }
382 
390  public function displayFkElementList($element, $member, $className, $object) {
391  }
392 
400  public function getFkElement($member, $className, $object) {
401  return $this->jquery->semantic ()->htmlLabel ( "element-" . $className . "." . $member, $object . "" );
402  }
403 
408  public function showDetailsOnDataTableClick(){
409  return true;
410  }
411 
412  protected function relationMembersInForm($form, $instance, $className) {
413  $relations = OrmUtils::getFieldsInRelations ( $className );
414  foreach ( $relations as $member ) {
415  if ($this->controller->_getAdminData ()->getUpdateManyToOneInForm () && OrmUtils::getAnnotationInfoMember ( $className, "#manyToOne", $member ) !== false) {
416  $this->manyToOneFormField ( $form, $member, $className, $instance );
417  } elseif ($this->controller->_getAdminData ()->getUpdateOneToManyInForm () && ($annot = OrmUtils::getAnnotationInfoMember ( $className, "#oneToMany", $member )) !== false) {
418  $this->oneToManyFormField ( $form, $member, $instance, $annot );
419  } elseif ($this->controller->_getAdminData ()->getUpdateManyToManyInForm () && ($annot = OrmUtils::getAnnotationInfoMember ( $className, "#manyToMany", $member )) !== false) {
420  $this->manyToManyFormField ( $form, $member, $instance, $annot );
421  }
422  }
423  }
424 
425  protected function manyToOneFormField(DataForm $form, $member, $className, $instance) {
426  $joinColumn = OrmUtils::getAnnotationInfoMember ( $className, "#joinColumn", $member );
427  if ($joinColumn) {
428  $fkObject = Reflexion::getMemberValue ( $instance, $member );
429  $fkClass = $joinColumn ["className"];
430  if ($fkObject === null) {
431  $fkObject = new $fkClass ();
432  }
433  $fkId = OrmUtils::getFirstKey ( $fkClass );
434  $fkIdGetter = "get" . \ucfirst ( $fkId );
435  if (\method_exists ( $fkObject, "__toString" ) && \method_exists ( $fkObject, $fkIdGetter )) {
436  $fkField = $joinColumn ["name"];
437  $fkValue = OrmUtils::getFirstKeyValue ( $fkObject );
438  if (! Reflexion::setMemberValue ( $instance, $fkField, $fkValue )) {
439  $instance->{$fkField} = OrmUtils::getFirstKeyValue ( $fkObject );
440  $form->addField ( $fkField );
441  }
442  $form->fieldAsDropDown ( $fkField, JArray::modelArray ( DAO::getAll ( $fkClass ), $fkIdGetter, "__toString" ) );
443  $form->setCaption ( $fkField, \ucfirst ( $member ) );
444  }
445  }
446  }
447 
448  protected function oneToManyFormField(DataForm $form, $member, $instance, $annot) {
449  $newField = $member . "Ids";
450  $fkClass = $annot ["className"];
451  $fkId = OrmUtils::getFirstKey ( $fkClass );
452  $fkIdGetter = "get" . \ucfirst ( $fkId );
453  $fkInstances = DAO::getOneToMany ( $instance, $member );
454  $form->addField ( $newField );
455  $ids = \array_map ( function ($elm) use ($fkIdGetter) {
456  return $elm->{$fkIdGetter} ();
457  }, $fkInstances );
458  $instance->{$newField} = \implode ( ",", $ids );
459  $form->fieldAsDropDown ( $newField, JArray::modelArray ( DAO::getAll ( $fkClass ), $fkIdGetter, "__toString" ), true );
460  $form->setCaption ( $newField, \ucfirst ( $member ) );
461  }
462 
463  protected function manyToManyFormField(DataForm $form, $member, $instance, $annot) {
464  $newField = $member . "Ids";
465  $fkClass = $annot ["targetEntity"];
466  $fkId = OrmUtils::getFirstKey ( $fkClass );
467  $fkIdGetter = "get" . \ucfirst ( $fkId );
468  $fkInstances = DAO::getManyToMany ( $instance, $member );
469  $form->addField ( $newField );
470  $ids = \array_map ( function ($elm) use ($fkIdGetter) {
471  return $elm->{$fkIdGetter} ();
472  }, $fkInstances );
473  $instance->{$newField} = \implode ( ",", $ids );
474  $form->fieldAsDropDown ( $newField, JArray::modelArray ( $this->controller->_getAdminData ()->getManyToManyDatas ( $fkClass, $instance, $member ), $fkIdGetter, "__toString" ), true, [ "jsCallback" => function ($elm) {
475  $elm->getField ()->asSearch ();
476  } ] );
477  $form->setCaption ( $newField, \ucfirst ( $member ) );
478  }
479 
480 }
481 
getFkElementDetails($member, $className, $object)
Returns a component for displaying a single foreign object (manyToOne relation), (from DataTable) ...
static getFieldsInRelations($class)
Definition: OrmUtils.php:223
getFkMemberElement($memberFK, $objectFK, $fkClass, $fkTable)
Returns a component for displaying a foreign object (from DataElement)
manyToManyFormField(DataForm $form, $member, $instance, $annot)
getFormCaptions($captions, $className, $instance)
Returns the captions for form fields.
getDataTableRowButtons()
Returns an array of buttons ["display","edit","delete"] to display for each row in dataTable...
getElementCaptions($captions, $className, $instance)
Returns the captions for DataElement fields.
static getAnnotationInfoMember($class, $keyAnnotation, $member)
Definition: OrmUtils.php:201
static setMemberValue($instance, $member, $value)
Definition: Reflexion.php:40
relationMembersInForm($form, $instance, $className)
addAllButtons(DataTable $dataTable, $attributes)
getFkListDetails($member, $className, $list)
Returns a list component for displaying a collection of foreign objects (*ToMany relations), (from DataTable)
getFkHeaderListDetails($member, $className, $list)
Returns the header for a list of foreign objects (issue from oneToMany or ManyToMany), (from DataTable)
static getFirstKey($class)
Definition: OrmUtils.php:122
static getFirstKeyValue($instance)
Definition: OrmUtils.php:127
showDetailsOnDataTableClick()
To override to make sure that the detail of a clicked object is displayed or not. ...
static getManyToMany($instance, $member, $array=null, $useCache=NULL)
Assigns / loads the child records in the $member member of $instance.
Definition: DAO.php:127
static getAll($className, $condition='', $loadManyToOne=true, $loadOneToMany=false, $useCache=NULL)
Returns an array of $className objects from the database.
Definition: DAO.php:193
getForm($identifier, $instance)
Returns the form for adding or modifying an object.
Definition: ModelViewer.php:47
getFkHeaderElementDetails($member, $className, $object)
Returns the header for a single foreign object (element is an instance, issue from ManyToOne)...
manyToOneFormField(DataForm $form, $member, $className, $instance)
getFkMemberElementDetails($memberFK, $objectFK, $fkClass, $fkTable)
Returns a component for displaying a foreign object (from DataTable)
getCaptions($captions, $className)
Returns the captions for list fields in showTable action.
static count($className, $condition='')
Returns the number of objects of $className from the database respecting the condition possibly passe...
Definition: DAO.php:347
static getMemberValue($instance, $member)
Definition: Reflexion.php:34
getModelDataTable($instances, $model, $page=1)
Returns the dataTable responsible for displaying instances of the model.
static getFieldTypes($className)
Definition: OrmUtils.php:86
displayFkElementList($element, $member, $className, $object)
To modify for displaying an element in a list component of foreign objects, (from DataElement) ...
getDataTableInstance($instances, $model, $page=1)
static getFKIntances($instance, $model)
Definition: CRUDHelper.php:137
static getOneToMany($instance, $member, $useCache=NULL, $annot=null)
Assign / load the child records in the $member member of $instance.
Definition: DAO.php:71
getFkElement($member, $className, $object)
Returns a component for displaying a single foreign object (manyToOne relation), (from DataElement) ...
confirmButtons(HtmlButton $confirmBtn, HtmlButton $cancelBtn)
getModelDataElement($instance, $model, $modal)
Definition: ModelViewer.php:92
__construct(HasModelViewerInterface $controller)
Definition: ModelViewer.php:35
oneToManyFormField(DataForm $form, $member, $instance, $annot)
displayFkElementListDetails($element, $member, $className, $object)
To modify for displaying an element in a list component of foreign objects (from DataTable) ...
setFormFieldsComponent(DataForm $form, $fieldTypes)
Sets the components for each field.
Definition: ModelViewer.php:72
isModal($objects, $model)
Condition to determine if the edit or add form is modal for $model objects.
getFkList($member, $list)
Returns a list component for displaying a collection of foreign objects (*ToMany relations), (from DataElement)