Ejemplo n.º 1
0
 /**
  *	Constuct Layout
  *	@return string
  */
 protected function constructLayout()
 {
     //HTML5 DocType
     $layout = "<!DOCTYPE html>\n";
     //HTML
     $currentUrlClass = "url-" . str_replace("/", "-", trim($this->controller->request()->url(), "/") ?: "index");
     $html = $this->_htmlTag->addClass($this->createBrowserClassString())->addClass($currentUrlClass);
     //HEAD
     $head = HTML::head($this->constructHead());
     //BODY
     $body = $this->_bodyTag->content($this->constructBody());
     //COMBINE
     $layout .= $html->content($head . "\n" . $body)->render();
     return $layout;
 }
Ejemplo n.º 2
0
 /**
  *	Asset Include Snipit
  *	This will find an asset and import it with the correct html tag
  *	@param string $assetType
  *	@param string $file
  *	@param array $options
  *	@return string - The html snipit
  */
 private function assetIncludeSnipit($assetType, $file, $options)
 {
     foreach ($this->assetSearchPaths($assetType) as $path) {
         if (Router::pathForAssetUrl($filePath = Router::buildPath($path, $file), $assetType)) {
             switch ($assetType) {
                 case self::CSS:
                     return HTML::link()->attr($options)->attr(["rel" => "stylesheet", "type" => "text/css", "href" => $filePath]);
                     break;
                 case self::JS:
                     return HTML::script()->attr($options)->attr(["type" => "text/javascript", "src" => $filePath]);
                     break;
                 case self::IMG:
                     return HTML::img()->attr($options)->attr(["src" => $filePath]);
                     break;
             }
         }
     }
     return NULL;
 }
Ejemplo n.º 3
0
 /**
  *	Validate Html
  *	This method scans the outgoing HTML for any forms, if found it will save the form to the session in order to validate.
  *	If any errors previously existed in the session, this method will apply `bootstrap` style css error classes.
  *	@pararm string &$htmlDocument - The outgoing HTML string
  *	@return VOID
  */
 private function validateHtml(&$htmlDocument)
 {
     if (!empty($htmlDocument)) {
         $dom = new DOMDocument();
         $dom->loadHtml($htmlDocument, LIBXML_NOWARNING | LIBXML_NOERROR | LIBXML_NOENT | LIBXML_HTML_NOIMPLIED);
         //Automatically apply an active class to links that relate to the current URL
         foreach ($dom->getElementsByTagName('a') as $link) {
             if (Router::isSiteUrl($href = Router::relativeURL($link->getAttribute("href")))) {
                 $currentClasses = explode(" ", $link->getAttribute("class"));
                 if (strcasecmp($href, $this->controller->request()->url()) == 0) {
                     $currentClasses[] = 'active';
                 }
                 if (strpos($this->controller->request()->url(), $href) === 0) {
                     $currentClasses[] = 'child-active';
                 }
                 $link->setAttribute('class', implode(" ", $currentClasses));
             }
         }
         //Save the outgoing form elements for future validation.
         foreach ($dom->getElementsByTagName('form') as $form) {
             $savedom = new \DOMDocument();
             if ($formAction = $form->getAttribute("action") && !Router::isSiteUrl($formAction)) {
                 continue;
             }
             //Add CSRF
             $rand = function_exists('random_bytes') ? random_bytes(32) : null;
             $rand = !$rand && function_exists('mcrypt_create_iv') ? mcrypt_create_iv(32, MCRYPT_DEV_URANDOM) : $rand;
             $rand = $rand ? $rand : openssl_random_pseudo_bytes(32);
             $csrfToken = bin2hex($rand);
             $formName = $form->getAttribute("name");
             $formNameToken = $formName . "_" . $csrfToken;
             $csrf = $dom->createDocumentFragment();
             $csrf->appendXML(HTML::input()->attr("type", "hidden")->attr("name", "tb_form_token")->attr("value", $formNameToken)->attr("readonly", true));
             $form->insertBefore($csrf, $form->firstChild);
             //TODO: Should we assume the form will allways have content
             foreach (["input", "textarea", "select"] as $tag) {
                 foreach ($form->getElementsByTagName($tag) as $input) {
                     $savedom->appendChild($savedom->importNode($input->cloneNode()));
                     //Populate form with previous data
                     if (($newValue = SessionStore::get("touchbase.key.session.post")->get($input->getAttribute("name"), false)) !== false) {
                         if (is_scalar($newValue) && $input->getAttribute("type") !== "hidden" && !$input->hasAttribute("readonly")) {
                             $input->setAttribute('value', $newValue);
                         }
                     }
                     //Populate errors
                     if ($errorMessage = $this->controller->errors($formName)->get($input->getAttribute("name"), false)) {
                         $currentClasses = explode(" ", $input->parentNode->getAttribute("class"));
                         foreach (["has-feedback", "has-error"] as $class) {
                             if (!in_array($class, $currentClasses)) {
                                 $currentClasses[] = $class;
                             }
                         }
                         $input->parentNode->setAttribute('class', implode(" ", $currentClasses));
                         $input->setAttribute("data-error", $errorMessage);
                     }
                 }
             }
             SessionStore::recycle($formName, $formNameToken, base64_encode(gzdeflate($savedom->saveHTML(), 9)));
         }
         //Move body scripts to bottom
         $bodies = $dom->getElementsByTagName('body');
         $body = $bodies->item(0);
         if ($body) {
             foreach ($body->getElementsByTagName('script') as $script) {
                 if ($script->parentNode->nodeName === "body") {
                     break;
                 }
                 $body->appendChild($dom->importNode($script));
             }
         }
         //Look for the special attribute that moves nodes.
         //This is useful for moving modals from the template files to the bottom output.
         $xpath = new \DOMXPath($dom);
         $appendToBodyRef = NULL;
         foreach ($xpath->query("//*[@tb-append]") as $element) {
             $appendTo = $xpath->query($element->getAttribute("tb-append"))->item(0);
             $element->removeAttribute("tb-append");
             if ($appendTo) {
                 if ($appendTo->nodeName === "body") {
                     //Special case to append above the included javascript files.
                     if (!$appendToBodyRef) {
                         $appendToBodyRef = $xpath->query('/html/body/comment()[. = " END CONTENT "][1]')->item(0);
                     }
                     $body->insertBefore($dom->importNode($element), $appendToBodyRef);
                 } else {
                     $appendTo->appendChild($dom->importNode($element));
                 }
             }
         }
         //Save the HTML with the updates.
         if ($this->controller->request()->isAjax() || !$this->controller->request()->isMainRequest()) {
             //This will remove the doctype that's automatically appended.
             $htmlDocument = $dom->saveHTML($dom->documentElement);
         } else {
             $htmlDocument = $dom->saveHTML();
         }
     }
 }