Example #1
0
 /**
  *	Init
  *	This method must return self
  *	@return self
  */
 public function init()
 {
     parent::init();
     $reflector = new \ReflectionClass($this);
     $this->_applicationNamespace = $reflector->getNamespaceName();
     //Define BASE Asset paths
     $assetConfig = $this->config()->get("assets");
     $assetPath = $assetConfig->get("assets", "assets");
     if (!defined("BASE_ASSETS")) {
         define("BASE_ASSETS", Router::buildPath(SITE_URL, $assetPath));
     }
     if (!defined("BASE_IMAGES")) {
         define("BASE_IMAGES", Router::buildPath(SITE_URL, $assetPath, $assetConfig->get("images", "images")));
     }
     if (!defined("BASE_STYLES")) {
         define("BASE_STYLES", Router::buildPath(SITE_URL, $assetPath, $assetConfig->get("css", "css")));
     }
     if (!defined("BASE_SCRIPTS")) {
         define("BASE_SCRIPTS", Router::buildPath(SITE_URL, $assetPath, $assetConfig->get("js", "js")));
     }
     if (!defined("BASE_TEMPLATES")) {
         define("BASE_TEMPLATES", Filesystem::buildPath(PROJECT_PATH, $assetConfig->get("templates", "Templates")));
     }
     return $this;
 }
 /**
  *	Request
  *	@param requestMethod
  *	@param requestEndpoint
  *	@param requestBody
  *	@return VOID
  */
 public function request($requestMethod, $requestEndpoint, $requestBody = NULL, $requestHeaders = [])
 {
     if (!$requestMethod || !$requestEndpoint) {
         throw new \InvalidArgumentException("Missing Arguments");
     }
     $this->addHeaders($requestHeaders);
     if (Router::isDev()) {
         ob_start();
         \pre_r($requestMethod, $requestEndpoint, $requestBody, $this->getAllHeaders());
         $apiLog = ob_get_contents();
         ob_end_clean();
         error_log($apiLog);
     }
     $c = curl_init();
     curl_setopt($c, CURLOPT_URL, $requestEndpoint);
     curl_setopt($c, CURLOPT_TIMEOUT, 30);
     curl_setopt($c, CURLOPT_USERAGENT, 'touchbase-php-library/2.0');
     curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($c, CURLINFO_HEADER_OUT, true);
     curl_setopt($c, CURLOPT_HTTPHEADER, $this->getAllHeaders());
     curl_setopt($c, CURLOPT_CUSTOMREQUEST, strtoupper($requestMethod));
     curl_setopt($c, CURLOPT_POSTFIELDS, $requestBody);
     curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
     $this->_lastResponse = curl_exec($c);
     $this->_lastResponseStatus = curl_getinfo($c, CURLINFO_HTTP_CODE);
     $this->_lastResponseContentType = curl_getinfo($c, CURLINFO_CONTENT_TYPE);
     $curlError = curl_error($c);
     if ($curlError) {
         throw new \RuntimeException(is_string($curlError) ? $curlError : "Something Terrible Happened!");
     }
     return $this->_lastResponse;
 }
Example #3
0
 /**
  *	_configure
  *	@param \Touchbase\Core\Config\Store
  *	@return Touchbase\Core\Config\Store
  */
 private function _configure(ConfigStore $config)
 {
     $ns = $src = "";
     try {
         //Load Main Configuration File
         $configurationData = IniConfigProvider::create()->parseIniFile(File::create([BASE_PATH, 'config.ini']));
         $config->addConfig($configurationData->getConfiguration());
         $ns = $config->get("project")->get("namespace", "Project");
         $src = $config->get("project")->get("source", "src");
         //Load Extra Configuration Files
         $loadExtraConfig = function ($files, $configFilePath = BASE_PATH) use(&$loadExtraConfig, &$config) {
             if (!empty($files)) {
                 foreach ($files as $condition => $file) {
                     $extraConfigFile = File::create([$configFilePath, $file]);
                     //Not a domain, path or environment - load always
                     if (is_numeric($condition)) {
                         if ($extraConfigFile->exists()) {
                             $configurationData = IniConfigProvider::create()->parseIniFile($extraConfigFile);
                             $config->addConfig($extraConfig = $configurationData->getConfiguration());
                             $loadExtraConfig($extraConfig->get("config")->get("files", ""), File::buildPath($configFilePath, dirname($file)));
                         }
                         //We want to match a certain condition
                     } else {
                         if ((!Router::isCLI() && strpos(@$_SERVER['HTTP_X_FORWARDED_HOST'] ?: $_SERVER['HTTP_HOST'], $condition) !== false || !Router::isCLI() && strpos($_SERVER["REQUEST_URI"], $condition) === 0 || !Router::isCLI() && strpos($_SERVER["SERVER_NAME"], $condition) === 0 || strtoupper(substr(php_uname('s'), 0, 3)) === 'WIN' && $condition == "windows" || defined("TOUCHBASE_ENV") && TOUCHBASE_ENV == $condition) && $extraConfigFile->exists()) {
                             $configurationData = IniConfigProvider::create()->parseIniFile($extraConfigFile);
                             $config->addConfig($extraConfig = $configurationData->getConfiguration());
                             $loadExtraConfig($extraConfig->get("config")->get("files", ""), File::buildPath($configFilePath, dirname($file)));
                         }
                     }
                 }
             }
         };
         $loadExtraConfig($config->get("config")->get("files", ""));
         StaticStore::shared()->set(ConfigStore::CONFIG_KEY, $config);
     } catch (\Exception $e) {
     }
     if (!defined('PROJECT_PATH')) {
         $psr0 = realpath(File::buildPath(BASE_PATH, $src, $ns));
         $psr4 = realpath(File::buildPath(BASE_PATH, $src));
         define('PROJECT_PATH', $psr0 ?: $psr4);
     }
     return $config;
 }
Example #4
0
 /**
  *	Strip Url Parameters
  *	@oaram string $urk
  *	@param array $excludedParams
  *	@return string
  */
 public static function stripUrlParameters($url, $excludedParams = [])
 {
     $parsedUrl = @parse_url($url);
     if (!empty($parsedUrl)) {
         if (!empty($parsedUrl['host'])) {
             $parsedUrl['host'] = mb_strtolower($parsedUrl['host'], 'UTF-8');
         }
         if (!empty($parsedUrl['fragment'])) {
             $fragment =& $parsedUrl['fragment'];
             if (substr($fragment, -1) == '#') {
                 $fragment = substr($fragment, 0, strlen($fragment) - 1);
             }
         }
         if (!empty($parsedUrl['query'])) {
             if (count($excludedParams)) {
                 parse_str($parsedUrl['query'], $params);
                 $parsedUrl['query'] = http_build_query(array_diff_key($params, array_flip($excludedParams)));
             } else {
                 unset($parsedUrl['query']);
             }
         }
     }
     return Router::buildUrl($parsedUrl);
 }
Example #5
0
 /**
  *	Path For Asset Url
  *	@param string assetUrl
  *	@return string
  */
 public static function pathForAssetUrl($assetUrl, $assetType = null)
 {
     if (Router::isSiteUrl($assetUrl)) {
         list($assetMapFragment, $assetUrl) = array_pad(explode("/", Router::relativeUrl($assetUrl), 2), 2, null);
         $file = File::create([BASE_PATH, static::pathForAssetMap($assetMapFragment), $assetUrl]);
         if ($file->exists()) {
             return $file->path;
         }
         // //Is it a folder?
         // $folder = Folder::create([BASE_PATH, static::pathForAssetMap($assetMapFragment), $assetUrl]);
         // if($folder->exists()){
         // 	return $folder->path;
         // }
         return null;
     }
     return $assetUrl;
 }
Example #6
0
 /**
  *	Redirect
  *	Redirect the response
  *	@param string $destinationUrl
  *	@param int $statusCode
  *	@return \Touchbase\Control\HTTPResponse
  */
 public function redirect($destinationUrl, $statusCode = 302)
 {
     if (is_numeric($destinationUrl) && $destinationUrl < 0) {
         $routeHistory = Router::routeHistory();
         $destinationUrl = $routeHistory[count($routeHistory) - abs($destinationUrl)];
     }
     if (Router::isRelativeURL($destinationUrl)) {
         $destinationUrl = Router::buildPath(SITE_URL, $destinationUrl);
     }
     $statusCode = in_array($statusCode, $this->redirectCodes) ? $statusCode : 302;
     $this->setStatusCode($statusCode);
     $this->addHeader('Location', $destinationUrl);
     return $this;
 }
Example #7
0
 /**
  *	Handler
  *	This method handles the displaying of the error message
  *	@param int $errorType
  *	@param string $errorMessage
  *	@param string $errorFile
  *	@param int $errorLine
  *	@param array $errorContext
  *	@return VOID
  */
 private function handler($errorType, $errorMessage, $errorFile = null, $errorLine = 0, $errorContext = array())
 {
     if (in_array($errorType, array(E_CORE_WARNING, E_CORE_ERROR))) {
         return;
     }
     //Lets add the real line and file number to errors that have been thrown via `trigger_error`
     if (in_array($errorType, self::$userErrors)) {
         $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4 + (self::$callerBacktraceBump ? self::$callerBacktraceBump-- : 0));
         $caller = end($backtrace);
         $errorFile = $caller['file'];
         $errorLine = $caller['line'];
     }
     error_log(sprintf($cliError = "PHP %s: %s in %s on line %d", $this->errorText[$errorType], $errorMessage, $errorFile, $errorLine));
     print sprintf(Router::isCLI() ? $cliError : "<pre><strong>%s:</strong> %s in <strong>%s</strong> on line <strong>%d</strong></pre>", $this->errorText[$errorType], $errorMessage, $errorFile, $errorLine);
     //Kill the application if required.
     if (in_array($errorType, self::$terminalErrors)) {
         exit;
     }
 }
Example #8
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;
 }
Example #9
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();
         }
     }
 }