false ]; }; $routes['#^/finance#'] = function($path) { return ['hasBlackHeader' => $path !== '/finance']; }; $routes['#^/report$#'] = function($path, $query, $matches) { $filter = isset($query['filter']) ? $query['filter'] : null; $reports = require PROJECT_APP_PATH .'/data/reports.php'; $filters = require PROJECT_APP_PATH .'/data/report_filters.php'; if ($filter) { $reports = array_filter($reports, function($v) use ($filter) { return $v['category'] === $filter; }); foreach ($filters as $f) { if ($f['name'] === $filter) { $filter = $f; break; } } } return compact('reports', 'filter', 'filters') + [ 'hasBlackHeader' => false ]; }; $routes['#^/report/(.*)$#'] = function($path, $query, $matches) { $achievements = require PROJECT_APP_PATH .'/data/achievements.php'; $achievements = array_values(array_filter($achievements, function($v) use ($path) { return $v['url'] === $path; })); $reports = require PROJECT_APP_PATH .'/data/reports.php'; $report = null; foreach ($reports as $_report) { if ($_report['name'] === $matches[1]) { $report = $_report; break; } } return compact('report', 'achievements') + [ 'hasBlackHeader' => true ]; }; // // Functions // // Matches current request against registered routes and // returns view variables. $matchRoute = function($path, $routes) { $query = parse_url($path, PHP_URL_QUERY); parse_str($query, $query); $path = parse_url($path, PHP_URL_PATH); foreach ($routes as $regex => $handler) { if (preg_match($regex, $path, $matches)) { return $handler($path, $query, $matches); } } return false; }; $renderView = function($viewVars, $scripts, $helpers, $_path, $_lang) { $_viewFileFromURI = function($path, $lang) { // $path may contain query string $path = parse_url($path, PHP_URL_PATH); $viewBase = PROJECT_APP_PATH . '/views/pages/' . $lang; $viewName = str_replace('/', '_', trim($path, '/')); $viewFile = $viewBase . '/' . $viewName . '.php'; $viewFile = realpath($viewFile); if ($viewName === '') { return $viewBase . '/home.php'; } // Prevent directory traversal attack // see http://stackoverflow.com/a/4205278 if ($viewFile === false || strpos($viewFile, $viewBase) !== 0) { return false; } return $viewFile; }; $_viewFile = $_viewFileFromURI($_path, $_lang); if ($_viewFile === false || trim($_path, '/') === 'home') { return false; } extract($helpers, EXTR_SKIP); extract($viewVars, EXTR_SKIP); require PROJECT_APP_PATH . '/views/elements/' . $_lang . '/header.php'; require $_viewFile; require PROJECT_APP_PATH . '/views/elements/' . $_lang . '/footer.php'; }; // // Handle the request // $viewVars += compact('lang', 'isCanonical', 'path'); if (($viewVars += $matchRoute($path, $routes)) === false) { header('HTTP/1.1 404 Not Found'); exit(); } if ($renderView($viewVars, $scripts, $helpers, $path, $lang) === false) { header('HTTP/1.1 404 Not Found'); exit(); } ?>