Ubiquity  2.0.3
php rapid development framework
UbiquityMyAdminViewer.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use Ajax\JsUtils;
39 
50  private $jquery;
51 
56  private $controller;
57 
59  $this->jquery = $controller->jquery;
60  $this->controller = $controller;
61  }
62 
63  public function getMainMenuElements() {
64  return [ "models" => [ "Models","sticky note","Used to perform CRUD operations on data." ],"routes" => [ "Routes","car","Displays defined routes with annotations" ],"controllers" => [ "Controllers","heartbeat","Displays controllers and actions" ],
65  "cache" => [ "Cache","lightning","Annotations, models, router and controller cache" ],"rest" => [ "Rest","server","Restfull web service" ],"config" => [ "Config","settings","Configuration variables" ],"git" => [ "Git","github","Git versioning" ],
66  "seo" => [ "Seo","google","Search Engine Optimization" ],"logs" => [ "Logs","bug","Log files" ] ];
67  }
68 
69  public function getRoutesDataTable($routes, $dtName = "dtRoutes") {
70  $errors = [ ];
71  $messages = "";
72  foreach ( $routes as $route ) {
73  $errors = \array_merge ( $errors, $route->getMessages () );
74  }
75  if (\sizeof ( $errors ) > 0) {
76  $messages = $this->controller->showSimpleMessage ( $errors, "error","Error", "warning" );
77  }
78  $dt = $this->jquery->semantic ()->dataTable ( $dtName, "Ubiquity\controllers\admin\popo\Route", $routes );
79  $dt->setIdentifierFunction ( function ($i, $instance) {
80  return $instance->getId ();
81  } );
82  $dt->setFields ( [ "path","methods","controller","action","cache","expired","name" ] );
83  $dt->setCaptions ( [ "Path","Methods","Controller","Action & parameters","Cache","Expired","Name","" ] );
84  $dt->fieldAsLabel ( "path", "car" );
85  $this->_dtCache ( $dt );
86  $this->_dtMethods ( $dt );
87  $this->_dtAction ( $dt );
88  $this->_dtExpired ( $dt );
89  $dt->onRowClick ( '$("#filter-routes").val($(this).find(".ui.label").text());' );
90  $dt->onPreCompile ( function ($dTable) {
91  $dTable->setColAlignment ( 7, TextAlignment::RIGHT );
92  $dTable->setColAlignment ( 5, TextAlignment::CENTER );
93  } );
94  $this->addGetPostButtons ( $dt );
95  $dt->setActiveRowSelector ( "warning" );
96  $dt->wrap ( $messages );
97  $dt->setEdition ()->addClass ( "compact" );
98  return $dt;
99  }
100 
101  public function getControllersDataTable($controllers) {
102  $filteredCtrls=USession::init("filtered-controllers", UArray::remove(ControllerAction::$controllers,"controllers\Admin"));
103  $controllers=array_filter($controllers,function($item) use ($filteredCtrls){
104  return array_search($item->getController(), $filteredCtrls)!==false;
105  });
106  $dt = $this->jquery->semantic ()->dataTable ( "dtControllers", "Ubiquity\controllers\admin\popo\ControllerAction", $controllers );
107  $dt->setFields ( [ "controller","action","dValues" ] );
108  $dt->setIdentifierFunction ( function ($i, $instance) {
109  return \urlencode ( $instance->getController () );
110  } );
111  $dt->setCaptions ( [ "Controller","Action [routes]","Default values","" ] );
112  $this->addGetPostButtons ( $dt );
113  $dt->setValueFunction ( "controller", function ($v, $instance, $index) {
114  $bts = new HtmlButtonGroups ( "bt-" . \urlencode ( $v ), [ $v ] );
115  $bts->addClass ( "basic" );
116  $bt = $bts->getItem ( 0 );
117  $bt->addClass ( "_clickFirst" )->setIdentifier ( "bt-0-" . $v );
118  $bt->addIcon ( "heartbeat", true, true );
119  $bt->setToggle ();
120  $dd = $bts->addDropdown ( [ "Add new action in <b>{$v}</b>..." ] );
121  $dd->setIcon ( "plus" );
122  $item = $dd->getItem ( 0 );
123  $item->addClass ( "_add-new-action" )->setProperty ( "data-controller", $instance->getController () );
124  $bt->onClick ( "$(\"tr[data-ajax='" . \urlencode ( $instance->getController () ) . "'] td:not([rowspan])\").toggle(!$(this).hasClass('active'));" );
125  return $bts;
126  } );
127  $dt->setValueFunction ( "action", function ($v, $instance, $index) {
128  $action = $v;
129  $controller = ClassUtils::getClassSimpleName ( $instance->getController () );
130  $r = new \ReflectionMethod ( $instance->getController (), $action );
131  $lines = file ( $r->getFileName () );
132  $params = $instance->getParameters ();
133  \array_walk ( $params, function (&$item) {
134  $item = $item->name;
135  } );
136  $params = " (" . \implode ( " , ", $params ) . ")";
137  $v = new HtmlSemDoubleElement ( "", "span", "", "<b>" . $v . "</b>" );
138  $v->setProperty ( "style", "color: #3B83C0;" );
139  $v->addIcon ( "lightning" );
140  $v .= new HtmlSemDoubleElement ( "", "span", "", $params );
141  $annots = $instance->getAnnots ();
142  foreach ( $annots as $path => $annotDetail ) {
143  $lbl = new HtmlLabel ( "", $path, "car" );
144  $lbl->setProperty ( "data-ajax", \htmlspecialchars ( ($path) ) );
145  $lbl->addClass ( "_route" );
146  $v .= "&nbsp;" . $lbl;
147  }
148  $v = \array_merge ( [ $v,"<span class='_views-container'>" ], $this->getActionViews ( $instance->getController (), $controller, $action, $r, $lines ) );
149  $v [] = "</span>";
150  return $v;
151  } );
152  $dt->onPreCompile ( function ($dt) {
153  $dt->setColAlignment ( 3, TextAlignment::RIGHT );
154  $dt->getHtmlComponent ()->mergeIdentiqualValues ( 0 );
155  } );
156  $dt->setEdition ( true );
157  $dt->addClass ( "compact" );
158  return $dt;
159  }
160 
161  public function getFilterControllers($controllers){
162  $selecteds=USession::init("filtered-controllers", UArray::remove($controllers,"controllers\Admin"));
163  $list = $this->jquery->semantic ()->htmlList ( "lst-filter" );
164  $list->addCheckedList ( array_combine($controllers,$controllers), "<i class='heartbeat icon'></i>&nbsp;Controllers", $selecteds, false, "filtered-controllers[]" );
165  return $list;
166  }
167 
168  public function getActionViews($controllerFullname, $controller, $action, \ReflectionMethod $r, $lines) {
169  $result = [ ];
170  $loadedViews = UIntrospection::getLoadedViews ( $r, $lines );
171  foreach ( $loadedViews as $view ) {
172  if (\file_exists ( ROOT . DS . "views" . DS . $view )) {
173  $lbl = new HtmlLabel ( "lbl-view-" . $controller . $action . $view, $view, "browser", "span" );
174  $lbl->addClass ( "violet" );
175  $lbl->addPopupHtml ( "<i class='icon info circle green'></i>&nbsp;<b>" . $view . "</b> is ok." );
176  } else {
177  $lbl = new HtmlLabel ( "lbl-view-" . $controller . $action . $view, $view, "warning", "span" );
178  $lbl->addClass ( "orange" );
179  $lbl->addPopupHtml ( "<i class='icon warning circle'></i>&nbsp;<b>" . $view . "</b> file is missing." );
180  }
181  $result [] = $lbl;
182  }
183  $viewname = $controller . "/" . $action . ".html";
184  if (! \file_exists ( ROOT . DS . "views" . DS . $viewname )) {
185  $bt = new HtmlButton ( "", "Create view " . $viewname );
186  $bt->setProperty ( "data-action", $action );
187  $bt->setProperty ( "data-controller", $controller );
188  $bt->setProperty ( "data-controllerFullname", $controllerFullname );
189  $bt->addClass ( "_create-view visibleover basic violet mini" )->setProperty ( "style", "visibility: hidden;" )->addIcon ( "plus" );
190  $result [] = $bt;
191  } elseif (\array_search ( $viewname, $loadedViews ) === false) {
192  $lbl = new HtmlLabel ( "lbl-view-" . $controller . $action . $viewname, $viewname, "browser", "span" );
193  $lbl->addPopupHtml ( "<i class='icon warning circle'></i>&nbsp;<b>" . $viewname . "</b> exists but is never loaded in action <b>" . $action . "</b>." );
194  $result [] = $lbl;
195  }
196  return $result;
197  }
198 
199  protected function addGetPostButtons(DataTable $dt) {
200  $dt->addFieldButtons ( [ "GET","POST" ], true, function (HtmlButtonGroups $bts, $instance, $index) {
201  $path = $instance->getPath ();
202  $path = \str_replace ( "(.*?)", "", $path );
203  $path = \str_replace ( "(index/)?", "", $path );
204  $bts->setIdentifier ( "bts-" . $instance->getId () . "-" . $index );
205  $bts->getItem ( 0 )->addClass ( "_get" )->setProperty ( "data-url", $path );
206  $bts->getItem ( 1 )->addClass ( "_post" )->setProperty ( "data-url", $path );
207  $item = $bts->addDropdown ( [ "Post with parameters..." ] )->getItem ( 0 );
208  $item->addClass ( "_postWithParams" )->setProperty ( "data-url", $path );
209  } );
210  }
211 
212  public function getCacheDataTable($cacheFiles) {
213  $dt = $this->jquery->semantic ()->dataTable ( "dtCacheFiles", "Ubiquity\controllers\admin\popo\CacheFile", $cacheFiles );
214  $dt->setFields ( [ "type","name","timestamp","size" ] );
215  $dt->setCaptions ( [ "Type","Name","Timestamp","Size","" ] );
216  $dt->setValueFunction ( "type", function ($v, $instance, $index) {
217  $item = $this->jquery->semantic ()->htmlDropdown ( "dd-type-" . $v, $v );
218  $item->addItems ( [ "Delete all","(Re-)Init cache" ] );
219  $item->setPropertyValues ( "data-ajax", $v );
220  $item->getItem ( 0 )->addClass ( "_delete-all" );
221  if ($instance->getFile () === "")
222  $item->getItem ( 0 )->setDisabled ();
223  $item->getItem ( 1 )->addClass ( "_init" );
224  if ($instance->getType () !== "Models" && $instance->getType () !== "Controllers")
225  $item->getItem ( 1 )->setDisabled ();
226  $item->asButton ()->addIcon ( "folder", true, true );
227  return $item;
228  } );
229  $dt->addDeleteButton ( true, [ ], function ($o, $instance) {
230  if ($instance->getFile () == "")
231  $o->setDisabled ();
232  $type = $instance->getType ();
233  $o->setProperty ( "data-type", $type );
234  $type = \strtolower ( $type );
235  if ($type == 'models' || $type == 'controllers') {
236  $o->setProperty ( "data-key", $instance->getName () );
237  } else {
238  $o->setProperty ( "data-key", $instance->getFile () );
239  }
240  } );
241  $dt->setIdentifierFunction ( "getFile" );
242  $dt->setValueFunction ( "timestamp", function ($v) {
243  if ($v !== "")
244  return date ( DATE_RFC2822, $v );
245  } );
246  $dt->setValueFunction ( "size", function ($v) {
247  if ($v !== "")
248  return self::formatBytes ( $v );
249  } );
250  $dt->setValueFunction ( "name", function ($name, $instance, $i) {
251  if (JString::isNotNull ( $name )) {
252  $link = new HtmlLink ( "lnl-" . $i );
253  $link->setContent ( $name );
254  $link->addIcon ( "edit" );
255  $link->addClass ( "_lnk" );
256  $link->setProperty ( "data-type", $instance->getType () );
257  $link->setProperty ( "data-ajax", $instance->getFile () );
258  $link->setProperty ( "data-key", $instance->getName () );
259  return $link;
260  }
261  } );
262  $dt->onPreCompile ( function ($dt) {
263  $dt->getHtmlComponent ()->mergeIdentiqualValues ( 0 );
264  } );
265  $this->jquery->postOnClick ( "._lnk", $this->controller->_getAdminFiles ()->getAdminBaseRoute () . "/_showFileContent", "{key:$(this).attr('data-key'),type:$(this).attr('data-type'),filename:$(this).attr('data-ajax')}", "#modal", [ "hasLoader" => false ] );
266  $this->jquery->postFormOnClick ( "._delete", $this->controller->_getAdminFiles ()->getAdminBaseRoute () . "/deleteCacheFile", "frmCache", "#dtCacheFiles tbody", [ "jqueryDone" => "replaceWith","params" => "{type:$(this).attr('data-type'),toDelete:$(this).attr('data-key')}" ] );
267  $this->jquery->postFormOnClick ( "._delete-all", $this->controller->_getAdminFiles ()->getAdminBaseRoute () . "/deleteAllCacheFiles", "frmCache", "#dtCacheFiles tbody", [ "jqueryDone" => "replaceWith","params" => "{type:$(this).attr('data-ajax')}" ] );
268  $this->jquery->postFormOnClick ( "._init", $this->controller->_getAdminFiles ()->getAdminBaseRoute () . "/initCacheType", "frmCache", "#dtCacheFiles tbody", [ "jqueryDone" => "replaceWith","params" => "{type:$(this).attr('data-ajax')}" ] );
269  return $dt;
270  }
271 
272  public function getModelsStructureDataTable($datas) {
273  $de = $this->jquery->semantic ()->dataElement ( "dtStructure", $datas );
274  $fields = \array_keys ( $datas );
275  $de->setFields ( $fields );
276  $de->setCaptions ( $fields );
277  foreach ( $fields as $key ) {
278  $de->setValueFunction ( $key, function ($value) {
279  if ($value instanceof \stdClass) {
280  $value = ( array ) $value;
281  }
282  return \print_r ( $value, true );
283  } );
284  }
285  return $de;
286  }
287 
288  public function getRestRoutesTab($datas) {
289  $tabs = $this->jquery->semantic ()->htmlTab ( "tabsRest" );
290 
291  foreach ( $datas as $controller => $restAttributes ) {
292  $doc = "";
293  $list = new HtmlList ( "attributes", [ [ "heartbeat","Controller",$controller ],[ "car","Route",$restAttributes ["restAttributes"] ["route"] ] ] );
294  $list->setHorizontal ();
295  if (\class_exists ( $controller )) {
297  $desc = $parser->getDescriptionAsHtml ();
298  if (isset ( $desc )) {
299  $doc = new HtmlMessage ( "msg-doc-controller-" . $controller, $desc );
300  $doc->setIcon ( "help blue circle" )->setDismissable ()->addClass ( "transition hidden" );
301  }
302  }
303  $routes = Route::init ( $restAttributes ["routes"] );
304  $errors = [ ];
305  foreach ( $routes as $route ) {
306  $errors = \array_merge ( $errors, $route->getMessages () );
307  }
308  $resource = $restAttributes ["restAttributes"] ["resource"];
309  $tab = $tabs->addTab ( $resource, [ $doc,$list,$this->_getRestRoutesDataTable ( $routes, "dtRest", $resource, $restAttributes ["restAttributes"] ["authorizations"] ) ] );
310  if (\sizeof ( $errors ) > 0) {
311  $tab->menuTab->addLabel ( "error" )->setColor ( "red" )->addIcon ( "warning sign" );
312  $tab->addContent ( $this->controller->showSimpleMessage ( \array_values ( $errors ), "error",null, "warning" ), true );
313  }
314  if ($doc !== "") {
315  $tab->menuTab->addIcon ( "help circle blue" )->onClick ( "$('#" . $doc->getIdentifier () . "').transition('horizontal flip');" );
316  }
317  }
318  return $tabs;
319  }
320 
321  protected function _getRestRoutesDataTable($routes, $dtName, $resource, $authorizations) {
322  $dt = $this->jquery->semantic ()->dataTable ( $dtName, "Ubiquity\controllers\admin\popo\Route", $routes );
323  $dt->setIdentifierFunction ( function ($i, $instance) {
324  return $instance->getPath ();
325  } );
326  $dt->setFields ( [ "path","methods","action","cache","expired" ] );
327  $dt->setCaptions ( [ "Path","Methods","Action & Parameters","Cache","Exp?","" ] );
328  $dt->fieldAsLabel ( "path", "car" );
329  $this->_dtCache ( $dt );
330  $this->_dtMethods ( $dt );
331  $dt->setValueFunction ( "action", function ($v, $instance) use ($authorizations) {
332  $auth = "";
333  if (\array_search ( $v, $authorizations ) !== false) {
334  $auth = new HtmlIcon ( "lock-" . $instance->getController () . $v, "lock alternate" );
335  $auth->addPopup ( "Authorization", "This route require a valid access token" );
336  }
337  $result = [
338  "<span style=\"color: #3B83C0;\">" . $v . "</span>" . $instance->getCompiledParams () . "<i class='ui icon help circle blue hidden transition _showMsgHelp' id='" . JString::cleanIdentifier ( "help-" . $instance->getAction () . $instance->getController () ) . "' data-show='" . JString::cleanIdentifier ( "msg-help-" . $instance->getAction () . $instance->getController () ) . "'></i>",
339  $auth ];
340  return $result;
341  } );
342  $this->_dtExpired ( $dt );
343  $dt->addFieldButton ( "Test", true, function ($bt, $instance) use ($resource) {
344  $bt->addClass ( "toggle _toTest basic circular" )->setProperty ( "data-resource", ClassUtils::cleanClassname ( $resource ) );
345  $bt->setProperty ( "data-action", $instance->getAction () )->setProperty ( "data-controller", \urlencode ( $instance->getController () ) );
346  } );
347  $dt->onPreCompile ( function ($dTable) {
348  $dTable->setColAlignment ( 5, TextAlignment::RIGHT );
349  $dTable->setColAlignment ( 4, TextAlignment::CENTER );
350  } );
351  $dt->setEdition ()->addClass ( "compact" );
352  return $dt;
353  }
354 
355  protected function _dtMethods(DataTable $dt) {
356  $dt->setValueFunction ( "methods", function ($v) {
357  $result = "";
358  if (UString::isNotNull ( $v )) {
359  if (! \is_array ( $v )) {
360  $v = [ $v ];
361  }
362  $result = new HtmlLabelGroups ( "lbls-method", $v, [ "color" => "grey" ] );
363  }
364  return $result;
365  } );
366  }
367 
368  protected function _dtCache(DataTable $dt) {
369  $dt->setValueFunction ( "cache", function ($v, $instance) {
370  $ck = new HtmlFormCheckbox ( "ck-" . $instance->getPath (), $instance->getDuration () . "" );
371  $ck->setChecked ( UString::isBooleanTrue ( $v ) );
372  $ck->setDisabled ();
373  return $ck;
374  } );
375  }
376 
377  protected function _dtExpired(DataTable $dt) {
378  $dt->setValueFunction ( "expired", function ($v, $instance, $index) {
379  $icon = null;
380  $expired = null;
381  if ($instance->getCache ()) {
382  if (\sizeof ( $instance->getParameters () ) === 0 || $instance->getParameters () === null)
383  $expired = CacheManager::isExpired ( $instance->getPath (), $instance->getDuration () );
384  if ($expired === false) {
385  $icon = "hourglass full";
386  } elseif ($expired === true) {
387  $icon = "hourglass empty orange";
388  } else {
389  $icon = "help";
390  }
391  }
392  return new HtmlIcon ( "", $icon );
393  } );
394  }
395 
396  protected function _dtAction(DataTable $dt) {
397  $dt->setValueFunction ( "action", function ($v, $instance) {
398  $result = "<span style=\"font-weight: bold;color: #3B83C0;\">" . $v . "</span>";
399  $result .= $instance->getCompiledParams ();
400  if (! \method_exists ( $instance->getController (), $v )) {
401  $errorLbl = new HtmlIcon ( "error-" . $v, "warning sign red" );
402  $errorLbl->addPopup ( "", "Missing method!" );
403  return [ $result,$errorLbl ];
404  }
405  return $result;
406  } );
407  }
408 
409  public function getConfigDataElement($config) {
410  $de = $this->jquery->semantic ()->dataElement ( "deConfig", $config );
411  $fields = \array_keys ( $config );
412  $de->setFields ( $fields );
413  $de->setCaptions ( $fields );
414  $de->setValueFunction ( "database", function ($v, $instance, $index) {
415  $dbDe = new DataElement ( "", $v );
416  $dbDe->setFields ( [ "type","dbName","serverName","port","user","password","options","cache" ] );
417  $dbDe->setCaptions ( [ "Type","dbName","serverName","port","user","password","options","cache" ] );
418  return $dbDe;
419  } );
420  $de->setValueFunction("cache", function ($v, $instance, $index) {
421  $dbDe = new DataElement ( "", $v );
422  $dbDe->setFields ( [ "directory","system","params" ] );
423  $dbDe->setCaptions ( [ "directory","system","params" ] );
424  return $dbDe;
425  });
426  $de->setValueFunction ( "templateEngineOptions", function ($v, $instance, $index) {
427  $teoDe = new DataElement ( "", $v );
428  $teoDe->setFields ( [ "cache" ] );
429  $teoDe->setCaptions ( [ "cache" ] );
430  $teoDe->fieldAsCheckbox ( "cache", [ "class" => "ui checkbox slider" ] );
431  return $teoDe;
432  } );
433  $de->setValueFunction ( "mvcNS", function ($v, $instance, $index) {
434  $mvcDe = new DataElement ( "", $v );
435  $mvcDe->setFields ( [ "models","controllers","rest" ] );
436  $mvcDe->setCaptions ( [ "Models","Controllers","Rest" ] );
437  return $mvcDe;
438  } );
439  $de->setValueFunction ( "di", function ($v, $instance, $index) use ($config) {
440  $diDe = new DataElement ( "", $v );
441  $keys = \array_keys ( $config ["di"] );
442  $diDe->setFields ( $keys );
443  foreach ( $keys as $key ) {
444  $diDe->setValueFunction ( $key, function ($value) use ($config, $key) {
445  $r = $config ['di'] [$key];
446  if (\is_callable ( $r ))
447  return \nl2br ( \htmlentities ( UIntrospection::closure_dump ( $r ) ) );
448  return $value;
449  } );
450  }
451  return $diDe;
452  } );
453  $de->setValueFunction ( "isRest", function ($v) use ($config) {
454  $r = $config ["isRest"];
455  if (\is_callable ( $r ))
456  return \nl2br ( \htmlentities ( UIntrospection::closure_dump ( $r ) ) );
457  return $v;
458  } );
459  $de->fieldAsCheckbox ( "test", [ "class" => "ui checkbox slider" ] );
460  $de->fieldAsCheckbox ( "debug", [ "class" => "ui checkbox slider" ] );
461  return $de;
462  }
463 
464  private function getCaptionToggleButton($id,$caption,$active=""){
465  $bt=(new HtmlButton($id,$caption))->setToggle($active)->setTagName("a");
466  $bt->addIcon("caret square down",false,true);
467  return $bt;
468  }
469 
470  private function labeledInput($input,$value){
471  $lbl="[empty]";
472  if(UString::isNotNull($value))
473  $lbl=$value;
474  $input->getField()->labeled($lbl);
475  return $input;
476  }
477 
478  private function _cleanStdClassValue($value){
479  if($value instanceof \stdClass){
480  $value=(array) $value;
481  }
482  if(is_array($value)){
483  $value=UArray::asPhpArray($value,"array");
484  }
485  $value=str_replace('"', "'", $value);
486  return $value;
487  }
488 
489  public function getConfigDataForm($config) {
490  $de = $this->jquery->semantic ()->dataElement ( "frmDeConfig", $config );
491  $keys=array_keys($config);
492 
493  $de->setDefaultValueFunction(function($name,$value){
494  if(is_array($value))
495  $value=UArray::asPhpArray($value,"array");
496  $input= new HtmlFormInput($name,null,"text",$value);
497  return $this->labeledInput($input, $value);
498  });
499  $fields = \array_keys ( $config );
500  $de->setFields ( $fields );
501  $de->setCaptions ( $fields );
502  $de->setCaptionCallback(function(&$captions,$instance) use($keys){
503  $dbBt=$this->getCaptionToggleButton("database-bt", "Database...");
504  $dbBt->on("toggled",'if(!event.active) {
505  var text=$("[name=database-type]").val()+"://"+$("[name=database-user]").val()+":"+$("[name=database-password]").val()+"@"+$("[name=database-serverName]").val()+":"+$("[name=database-port]").val()+"/"+$("[name=database-dbName]").val();
506  event.caption.html(text);
507  }');
508  $captions[array_search("database", $keys)]=$dbBt;
509  $captions[array_search("cache", $keys)]=$this->getCaptionToggleButton("cache-bt", "Cache...");
510  $captions[array_search("mvcNS", $keys)]=$this->getCaptionToggleButton("ns-bt", "MVC namespaces...");
511  $captions[array_search("di", $keys)]=$this->getCaptionToggleButton("di-bt", "Dependency injection","active");
512  $captions[array_search("isRest", $keys)]=$this->getCaptionToggleButton("isrest-bt", "Rest","active");
513 
514  });
515  $de->setValueFunction ( "database", function ($v, $instance, $index) {
517  $dbDe = new DataElement ( "de-database", $v );
518  $dbDe->setDefaultValueFunction(function($name,$value){
519  $value=$this->_cleanStdClassValue($value);
520  $input= new HtmlFormInput("database-".$name,null,"text",$value);
521  return $this->labeledInput($input, $value);
522  });
523  $dbDe->setFields ( [ "type","dbName","serverName","port","user","password","options","cache" ] );
524  $dbDe->setCaptions ( [ "Type","dbName","serverName","port","user","password","options","cache" ] );
525  $dbDe->fieldAsInput("password",["inputType"=>"password","name"=>"database-password"]);
526  $dbDe->fieldAsInput("port",["name"=>"database-port","inputType"=>"number","jsCallback"=>function($elm){$elm->getDataField()->setProperty("min",0);$elm->getDataField()->setProperty("max",3306);}]);
527  $dbDe->fieldAsDropDown("type",array_combine($drivers, $drivers),false,["name"=>"database-type"]);
528  $dbDe->fieldAsInput("cache",["name"=>"database-cache","jsCallback"=>function($elm,$object){
529  $ck=$elm->labeledCheckbox();
530  $ck->on("click",'$("[name=database-cache]").prop("disabled",$(this).checkbox("is unchecked"));');
531  if($object->cache!==false){
532  $ck->setChecked(true);
533  }
534  }]);
535  $dbDe->setValueFunction("dbName", function($value){
536  $input= new HtmlFormInput("database-dbName",null,"text",$value);
537  $bt=$input->addAction("Test");
538  $bt->addClass("black");
539  $bt->postFormOnClick($this->controller->_getAdminFiles()->getAdminBaseRoute() ."/_checkDbStatus","frm-frmDeConfig","#db-status",["jqueryDone"=>"replaceWith","hasLoader"=>"internal"]);
540  return $this->labeledInput($input, '<i id="db-status" class="ui question icon"></i>&nbsp;'.$value);
541  });
542  $dbDe->setEdition();
543  $dbDe->setStyle("display: none;");
544  $caption="<div class='toggle-caption'>".$v->type."://".$v->user.":".$v->password."@".$v->serverName.":".$v->port."/".$v->dbName."</div>";
545  return [$dbDe,$caption];
546  } );
547  $de->setValueFunction("cache", function ($v, $instance, $index) {
548  $dbDe = new DataElement ( "de-cache", $v );
549  $dbDe->setDefaultValueFunction(function($name,$value){
550  $value=$this->_cleanStdClassValue($value);
551  $input= new HtmlFormInput("cache-".$name,null,"text",$value);
552  return $this->labeledInput($input, $value);
553  });
554  $dbDe->setFields ( [ "directory","system","params" ] );
555  $dbDe->setCaptions ( [ "directory","system","params" ] );
556  $dbDe->setStyle("display: none;");
557  return $dbDe;
558  });
559  $de->setValueFunction ( "templateEngineOptions", function ($v, $instance, $index) {
560  $teoDe = new DataElement ( "de-template-engine", $v );
561  $teoDe->setFields ( [ "cache" ] );
562  $teoDe->setCaptions ( [ "cache" ] );
563  $teoDe->fieldAsCheckbox ( "cache", [ "class" => "ui checkbox slider","name"=>"templateEngineOptions-cache" ] );
564  return $teoDe;
565  } );
566  $de->setValueFunction ( "mvcNS", function ($v, $instance, $index) {
567  $mvcDe = new DataElement ( "deMvcNS", $v );
568  $mvcDe->setDefaultValueFunction(function($name,$value){return new HtmlFormInput("mvcNS-".$name,null,"text",$value);});
569  $mvcDe->setFields ( [ "models","controllers","rest" ] );
570  $mvcDe->setCaptions ( [ "Models","Controllers","Rest" ] );
571  $mvcDe->setStyle("display: none;");
572 
573  return $mvcDe;
574  } );
575  $de->setValueFunction ( "di", function ($v, $instance, $index) use ($config) {
576  $diDe = new DataElement ( "di", $v );
577  $diDe->setDefaultValueFunction(function($name,$value){return new HtmlFormInput("di-".$name,null,"text",$value);});
578  $keys = \array_keys ( $config ["di"] );
579  $diDe->setFields ( $keys );
580  foreach ( $keys as $key ) {
581  $diDe->setValueFunction ( $key, function ($value) use ($config, $key) {
582  $input=new HtmlFormTextarea("di-".$key);
583  $df=$input->getDataField();
584  $df->setProperty("rows","5");
585  $df->setProperty("data-editor","true");
586  $r = $config ['di'] [$key];
587  if (\is_callable ( $r )){
588  $value= \htmlentities ( UIntrospection::closure_dump ( $r ) );
589  }
590  $input->setValue($value);
591  return $input;
592  } );
593  }
594  $diDe->onPreCompile ( function () use (&$diDe) {
595  $diDe->getHtmlComponent ()->setColWidth(0, 1);
596  } );
597  return $diDe;
598  } );
599  $de->setValueFunction ( "isRest", function ($v) use ($config) {
600  $r = $config ["isRest"];
601  $input=new HtmlFormTextarea("isRest");
602  $df=$input->getDataField();
603  $df->setProperty("rows","3");
604  $df->setProperty("data-editor","true");
605  if (\is_callable ( $r )){
606  $value= \htmlentities ( UIntrospection::closure_dump ( $r ) );
607  }
608  $input->setValue($value);
609  return $input;
610  } );
611  $de->fieldAsCheckbox ( "test", [ "class" => "ui checkbox slider" ] );
612  $de->fieldAsCheckbox ( "debug", [ "class" => "ui checkbox slider" ] );
613  $js='
614  $(function() {
615  $("textarea[data-editor]").each(function() {
616  var textarea = $(this);
617  var mode = textarea.data("editor");
618  var editDiv = $("<div>", {
619  position: "absolute",
620  width: "100%",
621  height: textarea.height(),
622  "class": textarea.attr("class")
623  }).insertBefore(textarea);
624  textarea.css("display", "none");
625  var editor = ace.edit(editDiv[0]);
626  editDiv.css("border-radius","4px");
627  editor.$blockScrolling = Infinity ;
628  editor.renderer.setShowGutter(textarea.data("gutter"));
629  editor.getSession().setValue(textarea.val());
630  editor.getSession().setMode({path:"ace/mode/php", inline:true});
631  editor.setTheme("ace/theme/solarized_dark");
632  $("#frm-frmDeConfig").on("ajaxSubmit",function() {
633  textarea.val(editor.getSession().getValue());
634  });
635  });
636  });
637  ';
638  $this->jquery->exec($js,true);
639  $form=$de->getForm();
640  $form->setValidationParams(["inline"=>true,"on"=>"blur"]);
641 
642  $de->addSubmitInToolbar("save-config-btn","Save configuration", "basic inverted",$this->controller->_getAdminFiles()->getAdminBaseRoute()."/submitConfig/all","#action-response");
643  $de->addButtonInToolbar("Cancel edition")->onClick('$("#config-div").show();$("#action-response").html("");');
644  $de->getToolbar()->setSecondary()->wrap('<div class="ui inverted top attached segment">','</div>');
645  $de->setAttached();
646 
647  $form->addExtraFieldRules("siteUrl", ["empty","url"]);
648  $form->addExtraFieldRule("siteUrl", "regExp","siteUrl must ends with /","/^.*?\/$/");
649  $form->addExtraFieldRule("database-dbName", "empty");
650  $form->addExtraFieldRule("database-options", "regExp","Expression must be an array","/^array\(.*?\)$/");
651  $form->addExtraFieldRule("database-options", "checkArray","Expression is not a valid php array");
652  $form->addExtraFieldRule("database-cache", "checkClass[Ubiquity\\cache\\database\\DbCache]","Class {value} does not exists or is not a subclass of {ruleValue}");
653  $form->setOptional("database-cache");
654 
655  $form->addExtraFieldRule("cache-directory", "checkDirectory[app]","{value} directory does not exists");
656  $form->addExtraFieldRule("templateEngine", "checkClass[Ubiquity\\views\\engine\\TemplateEngine]","Class {value} does not exists or is not a subclass of {ruleValue}");
657  $form->addExtraFieldRule("cache-system", "checkClass[Ubiquity\\cache\\system\\AbstractDataCache]","Class {value} does not exists or is not a subclass of {ruleValue}");
658  $form->addExtraFieldRule("cache-params", "checkArray","Expression is not a valid php array");
659 
660  $form->addExtraFieldRule("mvcNS-models", "checkDirectory[app]","{value} directory does not exists");
661  $form->addExtraFieldRule("mvcNS-controllers", "checkDirectory[app]","{value} directory does not exists");
662  $controllersNS=Startup::getNS();
663  $form->addExtraFieldRule("mvcNS-rest", "checkDirectory[app/".$controllersNS."]", Startup::getNS()."{value} directory does not exists");
664 
665 
666  $this->jquery->exec(Rule::ajax($this->jquery, "checkArray", $this->controller->_getAdminFiles()->getAdminBaseRoute() . "/_checkArray", "{_value:value}", "result=data.result;", "post"), true);
667  $this->jquery->exec(Rule::ajax($this->jquery, "checkDirectory", $this->controller->_getAdminFiles()->getAdminBaseRoute() . "/_checkDirectory", "{_value:value,_ruleValue:ruleValue}", "result=data.result;", "post"), true);
668  $this->jquery->exec(Rule::ajax($this->jquery, "checkClass", $this->controller->_getAdminFiles()->getAdminBaseRoute() . "/_checkClass", "{_value:value,_ruleValue:ruleValue}", "result=data.result;", "post"), true);
669 
670  return $de->asForm();
671  }
672 
673  private static function formatBytes($size, $precision = 2) {
674  $base = log ( $size, 1024 );
675  $suffixes = array ('o','Ko','Mo','Go','To' );
676  return round ( pow ( 1024, $base - floor ( $base ) ), $precision ) . ' ' . $suffixes [floor ( $base )];
677  }
678 
679  public function getMainIndexItems($identifier, $array): HtmlItems {
680  $items = $this->jquery->semantic ()->htmlItems ( $identifier );
681 
682  $items->fromDatabaseObjects ( $array, function ($e) {
683  $item = new HtmlItem ( "" );
684  $item->addIcon ( $e [1] . " bordered circular" )->setSize ( "big" );
685  $item->addItemHeaderContent ( $e [0], [ ], $e [2] );
686  $item->setProperty ( "data-ajax", $e [0] );
687  return $item;
688  } );
689  $items->getOnClick ( $this->controller->_getAdminFiles ()->getAdminBaseRoute (), "#main-content", [ "attr" => "data-ajax","historize"=>true ] );
690  return $items->addClass ( "divided relaxed link" );
691  }
692 
693  public function getGitFilesDataTable($files) {
694  $list = $this->jquery->semantic ()->htmlList ( "dtGitFiles" );
695  $elements = array_map ( function ($element) {
696  return "<i class='" . GitFileStatus::getIcon ( $element->getStatus () ) . " icon'></i>&nbsp;" . $element->getName ();
697  }, $files );
698  $list->addCheckedList ( $elements, "<i class='file icon'></i>&nbsp;Files", array_keys ( $elements ), false, "files-to-commit[]" );
699  $this->jquery->getOnClick ( "#dtGitFiles label[data-value]", $this->controller->_getAdminFiles ()->getAdminBaseRoute () . "/changesInfiles", "#changesInFiles-div", [ "attr" => "data-value","preventDefault" => false,"stopPropagation" => true ] );
700  return $list;
701  }
702 
703  public function getGitCommitsDataTable($commits) {
704  $notPushed = false;
705  $dt = $this->jquery->semantic ()->dataTable ( "dtCommits", "Ubiquity\utils\git\GitCommit", $commits );
706  foreach ( $commits as $commit ) {
707  if (! $commit->getPushed ()) {
708  $notPushed = true;
709  break;
710  }
711  }
712  $dt->setColor ( "green" );
713  $dt->setIdentifierFunction ( "getLHash" );
714  $dt->setFields ( [ "cHash","author","cDate","summary" ] );
715  $dt->setCaptions ( [ "Hash","Author","Date","Summary" ] );
716  $dt->setActiveRowSelector ();
717  $dt->onRowClick ( $this->jquery->getDeferred ( $this->controller->_getAdminFiles ()->getAdminBaseRoute () . "/changesInCommit", "#changesInCommit-div", [ "attr" => "data-ajax" ] ) );
718  $dt->setValueFunction ( 0, function ($value, $instance) {
719  if ($instance->getPushed ()) {
720  return "<i class='ui green check square icon'></i>" . $value;
721  }
722  return "<i class='ui external square alternate icon'></i>" . $value;
723  } );
724  $dt->onNewRow ( function ($row, $object) {
725  if ($object->getPushed ())
726  $row->addClass ( "positive" );
727  } );
728  $this->jquery->exec ( '$("#htmlbuttongroups-push-pull-bts-0").prop("disabled",' . ($notPushed ? "false" : "true") . ');', true );
729  return $dt;
730  }
731 
732  public function gitFrmSettings(RepositoryGit $gitRepo) {
733  $frm = $this->jquery->semantic ()->dataForm ( "frmGitSettings", $gitRepo );
734  $frm->setFields ( [ "name\n","name","remoteUrl","user","password" ] );
735  $frm->setCaptions ( [ "&nbsp;Git repository settings","Repository name","Remote URL","User name","password" ] );
736  $frm->fieldAsMessage ( 0, [ "icon" => HtmlIconGroups::corner ( "git", "settings" ) ] );
737  $frm->setSubmitParams ( $this->controller->_getAdminFiles ()->getAdminBaseRoute () . "/updateGitParams", "#main-content" );
738  $frm->fieldAsInput ( 1 );
739  $frm->fieldAsInput ( 3, [ "rules" => [ "empty" ] ] );
740  $frm->fieldAsInput ( 4, [ "inputType" => "password" ] );
741  $frm->addDividerBefore ( "user", "gitHub" );
742  return $frm;
743  }
744 }
static getAvailableDrivers()
Definition: Database.php:235
static init($key, $value)
Initialize the key in Session if key does not exists.
Definition: USession.php:340
static remove($array, $search)
Definition: UArray.php:82
_getRestRoutesDataTable($routes, $dtName, $resource, $authorizations)
__construct(UbiquityMyAdminBaseController $controller)
static getNS($part="controllers")
Definition: Startup.php:45
static cleanClassname($classname)
Definition: ClassUtils.php:26
static getLoadedViews(\ReflectionMethod $r, $lines)
getActionViews($controllerFullname, $controller, $action, \ReflectionMethod $r, $lines)
static getClassSimpleName($classnameWithNamespace)
Definition: ClassUtils.php:135
static asPhpArray($array, $prefix="", $depth=1, $format=false)
Definition: UArray.php:53