registerErrorHandler(); $this->saveSERVER(); $this->defineServer( true, $filePath, $shortScriptName, $queryString ); $app = new App($rootFolder,new TestBaseUrl()); $thrown = false; $foundTh = null; try { $output = $app->runPico(); } catch (TestBaseUrlException $th) { $thrown = true; $foundTh = $th; } catch (Throwable $th){ } $sn = $_SERVER['SCRIPT_NAME']; $cwd = getcwd(); $this->revertSERVER(); $this->assertTrue($thrown,"TestBaseUrlException not found"); $this->assertEquals($waitedBaseUrl,$foundTh->getBaseUrl(),"Not same baseUrl ($sn)"); $this->assertEquals("$cwd/vendor/picocms/plugins/",$foundTh->getPluginDir(),"Not same pluginDir"); $this->assertEquals("$cwd/vendor/picocms/themes/",$foundTh->getThemeDir(),"Not same themeDir"); $this->assertEquals("$cwd/",$foundTh->getRootDir(),"Not same rootDir"); $currentPage = $foundTh->getcurrentPage(); $this->assertIsArray($currentPage,"Current Page should be an array"); $this->assertArrayHasKey('id',$currentPage,"Current Page should be an array with key 'id'"); $this->assertEquals($waitedPageId,$currentPage['id'],"Not waited page's id"); $this->assertArrayHasKey('url',$currentPage,"Current Page should be an array with key 'url'"); $this->assertEquals($waitedPageUrl,$currentPage['url'],"Not waited page's url"); $twigVariables = $foundTh->getTwigVariables(); $this->assertIsArray($twigVariables,"Twigvariables should be an array"); $this->assertArrayHasKey('themes_url',$twigVariables,"Twigvariables should be an array with key 'themes_url'"); $this->assertEquals($waitedThemesUrl,$twigVariables['themes_url'],"Not waited themes_url"); $this->assertArrayHasKey('plugins_url',$twigVariables,"Twigvariables should be an array with key 'plugins_url'"); $this->assertEquals($waitedPluginsUrl,$twigVariables['plugins_url'],"Not waited plugins_url"); } public function apiRewriteProvider() { $data = []; $this->prepareAPage($data,'','content','index'); $this->prepareAPage($data,'','content','sub/index'); $this->prepareAPage($data,'','content','theme'); $this->prepareAPage($data,'','sites/default','index'); $this->prepareAPage($data,'','sites/default','sub/index'); $this->prepareAPage($data,'','sites/default','theme'); $this->prepareAPage($data,'/sea','content','index'); $this->prepareAPage($data,'/sea','content','sub/index'); $this->prepareAPage($data,'/sea','content','theme'); $this->prepareAPage($data,'/sea','sites/default','index'); $this->prepareAPage($data,'/sea','sites/default','sub/index'); $this->prepareAPage($data,'/sea','sites/default','theme'); return $data; } protected function prepareAPage( array &$data, string $baseScriptName, string $rootFolder, string $waitedPageId ) { $baseUrl = 'http://localhost'.$baseScriptName.'/'; // tests $isIndex = ($waitedPageId == 'index'); $isSubIndex = (substr($waitedPageId,-strlen('/index')) == '/index'); // intermediate variables $pageIdInUrl = $isIndex ? '' : ($isSubIndex ? substr($waitedPageId,0,-strlen('/index')) : $waitedPageId) ; $waitedPageEndUrl = $pageIdInUrl; foreach([false,true] as $viaQueryString){ $queryString = $viaQueryString ? $pageIdInUrl : ''; $queryStringWithQuestion = ($viaQueryString && !empty($pageIdInUrl)) ? "?$pageIdInUrl" : ''; $formattedQueryString = str_replace('/','%2F',$pageIdInUrl); foreach (['','index.php'] as $endShortScriptName) { // $filePath from getcwd if ($rootFolder == 'content' && $viaQueryString){ // test also from base $filePath = 'index.php'; $shortScriptName = "$baseScriptName/$endShortScriptName"; $name = $rootFolder.$shortScriptName.$queryStringWithQuestion.'*'; $waitedBaseUrl = "$baseUrl/content/"; $this->prepareData($baseUrl,$data,$name,$rootFolder,$filePath,$shortScriptName,$queryString,$waitedBaseUrl,$waitedPageId,$waitedPageEndUrl); } foreach([false,true] as $viaScriptName){ $folderInScriptName = ($viaScriptName && !empty($pageIdInUrl)) ? "$pageIdInUrl/" : ''; $folderInScriptFileName = ($viaScriptName && !empty($pageIdInUrl)) ? "/$pageIdInUrl" :'' ; foreach ([false,true] as $withRewrite) { if ($viaQueryString || $endShortScriptName){ $filePath = "$rootFolder$folderInScriptFileName/index.php"; $shortScriptName = $withRewrite ? "$baseScriptName/$folderInScriptName$endShortScriptName" : "$baseScriptName/$rootFolder/$folderInScriptName$endShortScriptName"; $waitedBaseUrl = $withRewrite ? $baseUrl : "$baseUrl$rootFolder/"; $name = $rootFolder.$shortScriptName.$queryStringWithQuestion.($withRewrite ? ' R': ''); $this->prepareData($baseUrl,$data,$name,$rootFolder,$filePath,$shortScriptName,$queryString,$waitedBaseUrl,$waitedPageId,$waitedPageEndUrl); } } } } } } protected function prepareData( string $baseUrl, array &$data, string $name, string $rootFolder, string $filePath, string $shortScriptName, string $queryString, string $waitedBaseUrl, string $waitedPageId, string $waitedPageEndUrl ) { $waitedPageUrl = $waitedBaseUrl.$waitedPageEndUrl; $waitedThemesUrl = $baseUrl.'vendor/picocms/themes'; $waitedPluginsUrl = $baseUrl.'vendor/picocms/plugins'; $data[$name] = compact([ 'rootFolder', 'filePath', 'shortScriptName', 'queryString', 'waitedBaseUrl', 'waitedPageId', 'waitedPageUrl', 'waitedThemesUrl', 'waitedPluginsUrl' ]); } /** * define $_SERVER because fastcgi not run in CLI * @param bool $reset reset previous $_SERVER * @param string $filePath realpath of current script file * @param string $shortScriptName uri path of current script file * @param string $queryString wanted query string * @param string $method * @param string $pathInfo */ public function defineServer( bool $reset, string $filePath, string $shortScriptName, string $queryString, string $method = 'GET', string $pathInfo = '' ) { if (is_file($filePath)){ if (!is_array($_SERVER) || $reset){ $new = []; if (is_array($_SERVER)){ foreach(['SERVER_SOFTWARE','SERVER_PROTOCOL','GATEWAY_INTERFACE'] as $key){ if (array_key_exists($key,$_SERVER)){ $new[$key] = $_SERVER[$key]; } } } $_SERVER = $new; } $_SERVER['QUERY_STRING'] = $queryString; $_SERVER['REQUEST_METHOD'] = in_array($method,['GET','POST','PUT','DELETE','HEAD']) ? $method : 'GET'; // $_SERVER['CONTENT_TYPE'] = 'not defined'; // $_SERVER['CONTENT_LENGTH'] = 'not defined'; $documentRoot = dirname(realpath($filePath)); $fileName = basename(realpath($filePath)); $documentRootShort = (substr($documentRoot,-strlen(DIRECTORY_SEPARATOR)) != DIRECTORY_SEPARATOR) ? $documentRoot : substr($documentRoot,0,-strlen(DIRECTORY_SEPARATOR)); $documentRootFull = $documentRootShort.DIRECTORY_SEPARATOR; $scriptName = (basename($shortScriptName) == $fileName) ? $shortScriptName : $shortScriptName.((empty($shortScriptName) || substr($shortScriptName,-1) == '/') ? '' : '/').$fileName; $hashPos = strpos($queryString,'#'); $queryStringWithoutHash = (empty($queryString) || ($hashPos === 0)) ? '' : ( ($hashPos === false) ? "?$queryString" : '?'.sustr($queryString,0,$hashPos+1) ); $_SERVER['SCRIPT_FILENAME'] = $documentRootFull.$fileName; $_SERVER['SCRIPT_NAME'] = $scriptName; $_SERVER['PHP_SELF'] = $scriptName.$pathInfo; $_SERVER['PATH_INFO'] = $pathInfo; $_SERVER['ORIG_PATH_INFO'] = $pathInfo; $_SERVER['PATH_TRANSLATED'] = $documentRootShort.$pathInfo; if (substr($shortScriptName,-1) == '/'){ if (!empty($pathInfo) && substr($pathInfo,0,1) == '/'){ $_SERVER['DOCUMENT_URI'] = $shortScriptName.substr($pathInfo,1); } else { $_SERVER['DOCUMENT_URI'] = $shortScriptName.$pathInfo; } } else if (empty($pathInfo) || substr($pathInfo,0,1) == '/'){ $_SERVER['DOCUMENT_URI'] = $shortScriptName.$pathInfo; } else { $_SERVER['DOCUMENT_URI'] = $shortScriptName.'/'.$pathInfo; } $_SERVER['REQUEST_URI'] = $_SERVER['DOCUMENT_URI'].$queryStringWithoutHash; $_SERVER['DOCUMENT_ROOT'] = $documentRootShort; $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // forced $_SERVER['REMOTE_PORT'] = '80'; // forced $_SERVER['SERVER_ADDR'] = '127.0.0.1'; // forced $_SERVER['SERVER_PORT'] = '80'; // forced $_SERVER['SERVER_NAME'] = 'localhost'; // forced $_SERVER['HTTPS'] = null; // forced $_SERVER['REQUEST_TIME'] = time(); } } /** * save previous $_SERVER in $GLOBALS if existing */ public function saveSERVER() { if (!isset($GLOBALS['savedSERVER'])){ $GLOBALS['savedSERVER'] = [ 'saved' => false, 'value' => null ]; } if (!$GLOBALS['savedSERVER']['saved']){ if (!isset($_SERVER)){ $GLOBALS['savedSERVER']['value'] = null; $GLOBALS['savedSERVER']['saved'] = true; } else { $GLOBALS['savedSERVER']['value'] = $_SERVER; $GLOBALS['savedSERVER']['saved'] = true; } } } /** * revert previous $_SERVER in $GLOBALS if existing */ public function revertSERVER() { if (isset($GLOBALS['savedSERVER']['saved']) && $GLOBALS['savedSERVER']['saved']){ if (is_null($GLOBALS['savedSERVER']['value'])){ unset($_SERVER); } else { $_SERVER = $GLOBALS['savedSERVER']['value']; } $GLOBALS['savedSERVER']['saved'] = false; $GLOBALS['savedSERVER']['value'] = null; } } }