Ubiquity  2.0.2
php rapid development framework
SeoTrait.php
Go to the documentation of this file.
1 <?php
2 
4 
17 
24 class SeoTrait{
25 
26  abstract public function _getAdminData();
27 
28  abstract public function _getAdminViewer();
29 
30  abstract public function _getAdminFiles();
31 
32  abstract public function loadView($viewName, $pData=NULL, $asString=false);
33 
34  abstract public function seo();
35 
36  abstract protected function _seo();
37 
38  abstract protected function showConfMessage($content, $type, $url, $responseElement, $data, $attributes=NULL);
39 
40  abstract protected function showSimpleMessage($content, $type, $icon="info", $timeout=NULL, $staticName=null);
41 
42  abstract protected function _createController($controllerName,$variables=[],$ctrlTemplate='controller.tpl',$hasView=false,$jsCallback="");
43 
44  public function displaySiteMap(...$params) {
45  $controllerClass=\implode("\\", $params);
46  if(\class_exists($controllerClass)){
47  $controllerSeo=new $controllerClass();
48  USession::set("seo-sitemap", $controllerSeo);
49  $array=$controllerSeo->_getArrayUrls();
50  $parser=new UrlParser();
51  $parser->parseArray($array, true);
52  $parser->parse();
53  $urls=$parser->getUrls();
54  $dt=$this->jquery->semantic()->dataTable("dtSiteMap", 'Ubiquity\seo\Url', $urls);
55  $dt->setFields([ 'location','lastModified','changeFrequency','priority']);
56  $dt->setCaptions([ 'Location','Last Modified','Change Frequency','Priority']);
57  $dt->fieldAsInput("location");
58  $dt->setValueFunction("lastModified", function ($v, $o, $i) {
59  $d=date('Y-m-d\TH:i', $v);
60  $input=new HtmlInput("date-" . $i, 'datetime-local', $d);
61  $input->setName("lastModified[]");
62  return $input;
63  });
65  $dt->fieldAsDropDown('changeFrequency', \array_combine($freq, $freq));
66  $dt->setValueFunction("priority", function ($v, $o, $i) {
67  $input=new HtmlInput("priority-" . $i, 'number', $v);
68  $f=$input->getDataField();
69  $f->setProperty('name', 'priority[]');
70  $f->setProperty('max', '1')->setProperty('min', '0')->setProperty('step', '0.1');
71  return $input;
72  });
73  $dt->onNewRow(function ($row, $instance) {
74  if ($instance->getExisting()) {
75  $row->addClass('positive');
76  } else {
77  $row->setProperty('style', 'display: none;')->addClass('toToggle');
78  }
79  });
80  $dt->setHasCheckboxes(true);
81  $dt->setCheckedCallback(function ($object) {
82  return $object->getExisting();
83  });
84  $dt->asForm();
85  $dt->setSubmitParams($this->_getAdminFiles()->getAdminBaseRoute() . "/saveUrls", "#seo-details", [ 'attr' => '' ]);
86  $this->jquery->execOn("click", "#saveUrls", '$("#frm-dtSiteMap").form("submit");');
87  $this->jquery->exec('$("#displayAllRoutes").checkbox();',true);
88  $this->jquery->execOn('change', 'input[name="selection[]"]', '$(this).parents("tr").toggleClass("_checked",$(this).prop("checked"));');
89  $this->jquery->click('#displayAllRoutes', '$(".toToggle:not(._checked)").toggle();');
90  $this->jquery->execAtLast($this->jquery->execOn('change', '#frm-dtSiteMap input', '$("#saveUrls").show();',["immediatly"=>false]));
91  $this->jquery->compile($this->view);
92 
93  $this->loadView($this->_getAdminFiles()->getViewSeoDetails(), [ "controllerClass" => $controllerClass,"urlsFile" => $controllerSeo->_getUrlsFilename() ]);
94  }else{
95  echo $this->showSimpleMessage("The controller <b>`{$controllerClass}`</b> does not exists!", "warning","warning circle");
96  echo $this->jquery->compile($this->view);
97  }
98  }
99 
100  public function generateRobots() {
101  $frameworkDir=Startup::getFrameworkDir();
102  $config=Startup::getConfig();
103  $siteUrl=$config["siteUrl"];
104  $content=[ ];
105  if (URequest::isPost()) {
106  $template=UFileSystem::load($frameworkDir . "/admin/templates/robots.tpl");
107  $seoCtrls=URequest::post('selection', [ ]);
108  foreach ( $seoCtrls as $ctrl ) {
109  if(\class_exists($ctrl)){
110  $controllerSeo=new ControllerSeo($ctrl);
111  $content[]=\str_replace("%url%", URequest::cleanUrl($siteUrl . $controllerSeo->getPath()), $template);
112  }
113  }
114  if (\sizeof($content) > 0) {
115  $appDir=Startup::getApplicationDir();
116  $content=\implode("\n", $content);
117  UFileSystem::save($appDir . DS . 'robots.txt', $content);
118  $msg=$this->showSimpleMessage("The file <b>robots.txt</b> has been generated in " . $appDir, "success", "info circle");
119  $this->jquery->get($this->_getAdminFiles()->getAdminBaseRoute() ."/seoRefresh","#seoCtrls",['hasLoader'=>false,'jqueryDone'=>'replaceWith']);
120  } else {
121  $msg=$this->showSimpleMessage("Can not generate <b>robots.txt</b> if no SEO controller is selected.", "warning", "warning circle");
122  }
123  echo $msg;
124  echo $this->jquery->compile($this->view);
125  }
126  }
127 
128  public function seoRefresh(){
129  echo $this->_seo();
130  echo $this->jquery->compile($this->view);
131  }
132 
133  public function _newSeoController() {
134  $modal=$this->jquery->semantic()->htmlModal("modalNewSeo", "Creating a new Seo controller");
135  $modal->setInverted();
136  $frm=$this->jquery->semantic()->htmlForm("frmNewSeo");
137  $fc=$frm->addField('controllerName')->addRule([ "checkController","Controller {value} already exists!" ]);
138  $fc->labeled(Startup::getNS());
139  $fields=$frm->addFields([ "urlsFile","sitemapTemplate" ], "Urls file & sitemap twig template");
140  $fields->setFieldsPropertyValues("value", [ "urls","Seo/sitemap.xml.html" ]);
141  $fields->getItem(0)->addRules([ "empty" ]);
142 
143  $frm->addCheckbox("ck-add-route", "Add route...");
144 
145  $frm->addContent("<div id='div-new-route' style='display: none;'>");
146  $frm->addDivider();
147  $frm->addInput("path", "", "text", "")->addRule([ "checkRoute","Route {value} already exists!" ]);
148  $frm->addContent("</div>");
149 
150  $frm->setValidationParams([ "on" => "blur","inline" => true ]);
151  $frm->setSubmitParams($this->_getAdminFiles()->getAdminBaseRoute() . "/createSeoController", "#messages",["hasLoader"=>false]);
152  $modal->setContent($frm);
153  $modal->addAction("Validate");
154  $this->jquery->click("#action-modalNewSeo-0", "$('#frmNewSeo').form('submit');", false, false);
155  $modal->addAction("Close");
156  $this->jquery->change('#controllerName', 'if($("#ck-add-route").is(":checked")){$("#path").val($(this).val());}');
157  $this->jquery->exec("$('.dimmer.modals.page').html('');$('#modalNewSeo').modal('show');", true);
158  $this->jquery->jsonOn("change", "#ck-add-route", $this->_getAdminFiles()->getAdminBaseRoute() . "/_addRouteWithNewAction", "post", [ "context" => "$('#frmNewSeo')","params" => "$('#frmNewSeo').serialize()","jsCondition" => "$('#ck-add-route').is(':checked')" ]);
159  $this->jquery->exec(Rule::ajax($this->jquery, "checkRoute", $this->_getAdminFiles()->getAdminBaseRoute() . "/_checkRoute", "{}", "result=data.result;", "postForm", [ "form" => "frmNewSeo" ]), true);
160  $this->jquery->exec(Rule::ajax($this->jquery, "checkController", $this->_getAdminFiles()->getAdminBaseRoute() . "/_checkController", "{}", "result=data.result;", "postForm", [ "form" => "frmNewSeo" ]), true);
161  $this->jquery->change("#ck-add-route", '$("#div-new-route").toggle($(this).is(":checked"));if($(this).is(":checked")){$("#path").val($("#controllerName").val());}');
162  echo $modal;
163  echo $this->jquery->compile($this->view);
164  }
165 
166  public function createSeoController($force=null) {
167  if (URequest::isPost()) {
168  $variables=[ ];
169  $path=URequest::post("path");
170  $variables["%path%"]=$path;
171  if (isset($path)) {
172  $variables["%route%"]='@route("' . $path . '")';
173  }
174  $variables["%urlsFile%"]=URequest::post("urlsFile", "urls");
175  $variables["%sitemapTemplate%"]=URequest::post("sitemapTemplate", "Seo/sitemap.xml.html");
176 
177  echo $this->_createController($_POST["controllerName"], $variables, 'seoController.tpl',false,
178  $this->jquery->getDeferred($this->_getAdminFiles()->getAdminBaseRoute() ."/seoRefresh","#seoCtrls",['hasLoader'=>false,'jqueryDone'=>'replaceWith','jsCallback'=>'$("#seo-details").html("");']));
179  }
180  $this->jquery->get($this->_getAdminFiles()->getAdminBaseRoute() ."/seoRefresh","#seoCtrls",['hasLoader'=>false,'jqueryDone'=>'replaceWith','jsCallback'=>'$("#seo-details").html("");']);
181  echo $this->jquery->compile($this->view);
182  }
183 
184  public function _checkController() {
185  if (URequest::isPost()) {
186  $result=[ ];
187  $controllers=CacheManager::getControllers();
188  $ctrlNS=Startup::getNS();
189  header('Content-type: application/json');
190  $controller=$ctrlNS . $_POST["controllerName"];
191  $routes=CacheManager::getRoutes();
192  $result["result"]=(\array_search($controller, $controllers) === false);
193  echo json_encode($result);
194  }
195  }
196 
197  public function saveUrls() {
198  $result=[ ];
199  $selections=URequest::post("selection", [ ]);
200  $locations=URequest::post("location", [ ]);
201  $lastModified=URequest::post("lastModified", [ ]);
202  $changeFrequency=URequest::post("changeFrequency", [ ]);
203  $priority=URequest::post("priority", [ ]);
204  foreach ( $selections as $index ) {
205  $result[]=[ "location" => $locations[$index - 1],"lastModified" => \strtotime($lastModified[$index - 1]),"changeFrequency" => $changeFrequency[$index - 1],"priority" => $priority[$index - 1] ];
206  }
207  $seoController=USession::get("seo-sitemap");
208  if (isset($seoController) && $seoController instanceof SeoController) {
209  try{
210  $seoController->_save($result);
211  $r=new \ReflectionClass($seoController);
212  $this->displaySiteMap($r->getNamespaceName(), $r->getShortName());
213  $filename=$seoController->_getUrlsFilename();
214  $message=$this->showSimpleMessage(UString::pluralize(\sizeof($selections), '<b>`'.$filename.'`</b> saved with no url.','<b>`'.$filename.'`</b> saved with {count} url.','<b>`'.$filename.'`</b> saved with {count} urls.'), "success", "info circle");
215  }catch(\Ubiquity\exceptions\CacheException $e){
216  $message=$this->showSimpleMessage("Unable to write urls file `" . $filename . "`", "warning", "warning");
217  }
218  $this->jquery->html("#messages",$message,true);
219  echo $this->jquery->compile($this->view);
220  }
221  }
222 
223  public function deleteSeoController(...$params){
224  $controllerName=\implode("\\", $params);
225  if (sizeof($_POST) > 0) {
226  $controllerName=\urldecode($_POST["data"]);
227  if ($this->_deleteController($controllerName)) {
228  $message=$this->showSimpleMessage("Deletion of SEO controller `<b>" . $controllerName . "</b>`", "info", "info", 4000);
229  $this->jquery->get($this->_getAdminFiles()->getAdminBaseRoute() ."/seoRefresh","#seoCtrls",['hasLoader'=>false,'jqueryDone'=>'replaceWith','jsCallback'=>'$("#seo-details").html("");']);
230  } else {
231  $message=$this->showSimpleMessage("Can not delete SEO controller `" . $controllerName . "`", "warning", "warning");
232  }
233  } else {
234  $message=$this->showConfMessage("Do you confirm the deletion of SEO controller `<b>" . $controllerName . "</b>`?", "error", $this->_getAdminFiles()->getAdminBaseRoute() . "/deleteSeoController/{$params[0]}/{$params[1]}", "#messages", \urlencode($controllerName));
235  }
236  echo $message;
237  echo $this->jquery->compile($this->view);
238  }
239 
240  protected function _deleteController($controllerName){
241  $controllerName=\urldecode($controllerName);
242  if(\class_exists($controllerName)){
243  $rClass=new \ReflectionClass($controllerName);
244  return UFileSystem::deleteFile($rClass->getFileName());
245  }
246  return false;
247  }
248 
249  public function seeSeoUrl(...$params){
250  $controllerName=\implode("\\", $params);
251  $ctrl=new $controllerName();
252  \ob_start();
253  $ctrl->index();
254  $content=\ob_get_clean();
256  $modal=$this->jquery->semantic()->htmlModal("seeSeo", "sitemap file for {$ctrl->getPath()} url");
257  $modal->setInverted();
258  $modal->setContent("<pre><code>".\htmlentities($content)."</pre></code>");
259  $modal->addAction("Close");
260  $this->jquery->exec("$('.dimmer.modals.page').html('');$('#seeSeo').modal('show');", true);
261  echo $modal;
262  echo $this->jquery->compile($this->view);
263  }
264 }
static isPost()
Returns true if the request is sent by the POST method.
Definition: URequest.php:109
_createController($controllerName, $variables=[], $ctrlTemplate='controller.tpl', $hasView=false, $jsCallback="")
static asHtml($encoding='utf-8')
Sets the response content-type to text/html.
Definition: UResponse.php:70
showConfMessage($content, $type, $url, $responseElement, $data, $attributes=NULL)
loadView($viewName, $pData=NULL, $asString=false)
static pluralize($count, $zero, $one, $other)
Pluralize an expression.
Definition: UString.php:55
static post($key, $default=NULL)
Returns the value of the $key variable passed by the post method or $default if the $key variable doe...
Definition: URequest.php:146
static getNS($part="controllers")
Definition: Startup.php:43
showSimpleMessage($content, $type, $icon="info", $timeout=NULL, $staticName=null)
static set($key, $value)
Adds or sets a value to the Session at position $key.
Definition: USession.php:150
static get($key, $default=NULL)
Returns the value stored at the key position in session.
Definition: USession.php:138
static deleteFile($filename)
Definition: UFileSystem.php:28
static save($filename, $content, $flags=LOCK_EX)