TABLE OF CONTENTS
FILES CONFIG NOTES
Files and config list for this module, and some notes (if any).
FILES LIST
LIB/LIB-Route.php
The one that resolves “URL to PHP file”.LIB/HOOK-Routes.php
Manual overrides for “URL to PHP file”.LIB/HOOK-API-CORS.php
Manual overrides for “which domains can access the API”.
RELATED CONFIG
In CORE-Config.php
, the “important URL settings” are:
HOST_BASE
Your base URL.- If the project is deployed at the root –
http://site.com/
- Include the path and trailing slash if not –
http://site.com/myproject/
- If the project is deployed at the root –
HOST_API
This defaults toapi/
. That is, the API endpoints will be deployed athttp://site.com/api/
.API_CORS
Cross-origins permissions for API.false
No cross-origins allowed. Use this if you are not planning to develop mobile apps and open up to 3rd parties.true
All cross-origins are allowed. NOT RECOMMENDED. Huge security risk.string
Only calls from this domain are allowed.array
Only calls from this list of domains are allowed.
URL ROUTE ENGINE CONCEPTS
The “pretty URL” engine in Core Boxx covers 2 parts – Serving HTML pages and responding to API calls.
A QUICK TRACE OF WHAT HAPPENS
HTACCESS
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
To drive the pretty URL, Apache mod_rewrite
must be enabled to work properly. As for this .htaccess
file, I “borrowed” it from WordPress. In simple English:
- Route all URLs to
index.php
. - Do not rewrite HTTP auth requests.
- Do not rewrite existing files and folders.
Simply put, we will write our own PHP to resolve the URL.
P.S. If you are using IIS or NGINX, you can translate this on your own.
ROUTE ENGINE TAKEOVER
require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "CORE-Go.php";
$_CORE->load("Route");
$_CORE->Route->run();
Now that http://site.com/EVERYTHING
will point to index.php
, we can build our own “URL resolve engine”. Not going to explain line-by-line, a quick summary:
$_CORE->Route->run()
Determines if it is a request for an HTML page or an API call.$_CORE->Route->resolve()
Will handle “URL to HTML page”, then$_CORE->Route->load()
will load the file itself.$_CORE->Route->api()
Will handle API calls.
RESOLVING HTML PAGES
DEFAULT “URL TO HTML PAGE”
http://site.com/
will resolve topages/PAGE-home.php
.http://site.com/foo
will resolve topages/PAGE-foo.php
.http://site.com/foo/bar
will resolve topages/PAGE-foo-bar.php
.- If
pages/PAGE-foo.php
is not found, it will loadpages/PAGE-404.php
.
So at the bare minimum, your project needs to have:
pages/PAGE-home.php
The home page.pages/PAGE-404.php
Not found.
OVERRIDE URL RESOLVE
You can override the “URL to HTML page” in lib/HOOK-Routes.php
.
$override
A function to modify the URL path.$routes
Map URL path to file.$wild
Wildcard path routing.
The precedence order as above – Path override, exact route, wildcard route, default route. See “override examples” below for more.
RESOLVING API CALLS
DEFAULT “URL TO API HANDLER”
- API URLs have the following structure –
http://site.com/api/MODULE/ACTION
. Examples:- Access
http://site.com/api/items/get
to get all items. - Send
$_POST["name"] = "NEW"
tohttp://site.com/api/items/save
to add a new item. - Send
$_POST["id"] = 123
tohttp://site.com/api/items/del
to delete an item.
- Access
http://site.com/api/items
will resolve tolib/API-items.php
. If this script is not found, it will output an “invalid request”.
DUMMY API EXAMPLE
// AUTOMATIC RESOLVE
// API/ITEMS/GET WILL CALL $_CORE->ITEMS->GET()
// API/ITEMS/SAVE WILL CALL $_CORE->ITEMS->SAVE()
// API/ITEMS/DEL WILL CALL $_CORE->ITEMS->DEL()
$_CORE->autoAPI([
"get" => ["Items", "get"],
"save" => ["Items", "save"],
"del" => ["Items", "del"]
]);
// OR MANUALLY RESOLVE IF YOU WANT...
switch ($_CORE->Route->act) {
case "get":
$_CORE->load("Items");
$items = $_CORE->Items->get($_POST["search"]);
$_CORE->respond(1, null, null, $items);
break;
}
OVERRIDE EXAMPLES
Need to deal with pagination? Categories? Restrict access to registered users only? Here are a few common examples.
URL PATH OVERRIDE
$override = function ($path) {
// EXAMPLE - REDIRECT TO LOGIN PAGE IF NOT SIGNED IN
if (!isset($_SESSION["user"]) && $path!="login/") {
header("Location: " . HOST_BASE . "login/");
exit();
}
// EXAMPLE - TWEAK PATH BASED ON USER ROLE
if ($path=="products/" && $_SESSION["user"]["user_level"]=="A") {
$path = "admin/products/";
}
// MUST RETURN OVERIDDEN PATH
return $path;
);
$_CORE->Route->run()
will parse the current URL path into $_CORE->Route->path
. Use this override to change the parsed path, very useful for things like access control or “load a different page for certain user roles”.
EXACT PATH OVERRIDE
// EXACT PATH ROUTING
$routes = [
"/" => "myhome.php", // http://site.com/ > pages/myhome.php
"foo/" => "bar.php" // http://site.com/foo/ > pages/bar.php
];
Pretty self-explanatory, if you want to load a specific file for a particular URL.
WILDCARD PATH OVERRIDE
// WILDCARD PATH ROUTING
$wild = [
"category/" => "category.php" // http://site.com/category/* > pages/category.php
];
Use this to cover a range of URL paths. Good for things like pagination and categories. See the example below.
CATEGORY & PAGINATION
WILDCARD MAP ALL PRODUCTS
$wild = [
"products/" => "PDT-list.php"
];
For this example, we will be working with a dummy products page. This will map http://site.com/products/*
to pages/PDT-list.php
PRODUCTS HANDLER SCRIPT
// (A) EXPLODE CURRENT PATH INTO AN ARRAY FIRST
// $REQ[0] = "PRODUCTS"
// $REQ[1] = CATEGORY
// $REQ[2] = PAGE NUMBER
$req = explode("/", rtrim($_CORE->Route->path, "/"));
// (B) INVALID
if (count($req) != 3) {
$_CORE->Route->load("PAGE-404.php", 404); exit();
}
// (C) GET PRODUCTS
$_CORE->load("Products");
$products = $_CORE->Products->get($req[1], $req[2]);
// (D) DRAW HTML
foreach ($products as $p) { ... }
Parse the current URL path, and use them to load the products/pagination accordingly.
CONTROL ACCESS TO ADMIN PAGES
MAP ALL ADMIN PAGES TO A “CHECK PAGE”
$wild = [
"admin/" => "ADM-check.php"
];
Want to restrict some pages to administrators only? Start by doing a wildcard map to an “access check script”.
ADMIN PERMISSION CHECK
// (A) ADMIN ONLY
$_CORE->ucheck("A");
// (B) STRIP "ADMIN/" FROM PATH
$_CORE->Route->path = substr($_CORE->Route->path, 6);
// (C) OK - LOAD PAGE
$_CORE->Route->load($_CORE->Route->path==""
? "ADM-home.php"
: "ADM-" . str_replace("/", "-", rtrim($_CORE->Route->path, "/\\")) . ".php"
);
Do a check against the session or cookie – Whichever you are using to track user login. Then, use $_CORE->Route->load()
to load the requested page.
API-CORS CONTROL
// (A) EXAMPLE - ALLOW "FOO.COM" TO ACCESS "TEST" MODULE
if ($this->orihost=="foo.com" && $this->mod=="test") {
$access = true;
}
// (B) EXAMPLE - ALLOW "BAR.COM" TO ACCESS SOME ACTIONS IN "TEST" MODULE
$allowed = ["get", "getAll"];
if ($this->orihost=="bar.com" && $this->mod=="test" && in_array($this->act, $allowed)) {
$access = true;
}
If you want to give API access to a certain domain, but not open all modules – This is a good place to do your checks.
URL ROUTE LIBRARY REFERENCES
Don’t think this is necessary, but just for the “official documentation”.
PRETTY URL
Reads the current URL and determines if it is an API call or request for an HTML page.
Regenerates .htaccess
and CB-manifest.json
.
HTML PAGE RESOLVE
Resolve URL path to HTML page.
A “helper function” for resolve()
. You can also use this in your pages to load the given HTML page.
$file
– String, file to load.$http
– Integer, optional HTTP response code.
$_CORE->Route->load("NO-ACCESS.PHP", 403);
API RESOLVE
Reads the current URL path http://site.com/api/MODULE/ACTION
and maps it to lib/API-MODULE.php
.