Skip to content
This repository was archived by the owner on Jan 2, 2022. It is now read-only.

Commit 5c70130

Browse files
author
Designcise
committed
Initial commit
0 parents  commit 5c70130

21 files changed

Lines changed: 498 additions & 0 deletions

LICENSE.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright (c) 2017-2018 Daniyal Hamid (https://designcise.com).
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# BitFrame Basic Website Example
2+
3+
This example project demonstrates very basic functionality of the BitFrame PHP Microframework to create a simple website.
4+
5+
### Install
6+
7+
#### Prerequisites
8+
9+
* PHP 7.1.0+
10+
* Webserver with URL Rewriting (such as Apache or nginx)
11+
12+
#### Install Via Composer
13+
14+
Simply navigate to the `basic_website` project directory in terminal/command line (to the folder where `composer.json` resides) and run the following command:
15+
16+
```
17+
composer install
18+
```
19+
20+
##### Composer Dependencies
21+
22+
* "[designcise/bitframe](https://github.com/designcise/bitframe/)": "^1.0.0",
23+
* "[designcise/bitframe-whoops](https://github.com/designcise/bitframe-whoops)": "^1.0.0",
24+
* "[designcise/bitframe-diactoros](https://github.com/designcise/bitframe-diactoros)": "^1.0.0",
25+
* "[designcise/bitframe-fastroute](https://github.com/designcise/bitframe-fastroute)": "^1.0.0",
26+
* "[designcise/bitframe-leagueplates](https://github.com/designcise/bitframe-leagueplates)": "^1.0.0"
27+
28+
### Running The Code
29+
30+
Once you've installed the required dependency files, point your browser to the `basic_website` project's url (for example: http://localhost/basic_website/public_html/).
31+
32+
### Important
33+
34+
This is meant to be an example project, so prior to using it in production, make sure the following:
35+
36+
1. You've taken measures to secure your web project however you see fit;
37+
1. You've made necessary changes in env.php file (such as setting `ENV` to `'live'` and `DEBUG_MODE` to `false`);
38+
1. You've edited and customized all template files (if you're using templates);
39+
1. You've added/removed the routes (app/routes/..), dependencies (app/config/dependencies.php) and middlewares (app/config/middleware.php) you'll be using.
40+
41+
### License
42+
43+
Please see [License File](LICENSE.md) for licensing information.
44+
45+
### Useful Links
46+
47+
- [BitFrame PHP Microframework Official](https://www.bitframephp.com)
48+
- [BitFrame PHP Microframework Official Docs](https://www.bitframephp.com/doc)
49+
- [BitFrame PHP Microframework Example Projects](https://www.bitframephp.com/doc/getting-started/example-projects)

app/config/dependencies.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php // Application dependencies configuration
2+
3+
use \BitFrame\Renderer\PlatesRenderer;
4+
use \BitFrame\Renderer\TemplateInterface;
5+
6+
/**
7+
* Self-calling anonymous function to create local scope and
8+
* keep the global namespace clean.
9+
*/
10+
$app['tpl'] = call_user_func(function() use ($app) {
11+
// global template data
12+
$data = [
13+
'page_title_prefix' => '',
14+
'page_title' => '',
15+
'page_title_suffix' => ' - BitFrame PHP Microframework',
16+
'css' => [],
17+
'js' => []
18+
];
19+
20+
$plates = new PlatesRenderer(TPL_DIR, TPL_EXT, $data);
21+
22+
$req = $app->getRequest();
23+
24+
/**
25+
* Register namespaced folders.
26+
*/
27+
$plates->addPath(TPL_DIR . 'inc', 'component');
28+
29+
30+
/**
31+
* Register template params.
32+
*/
33+
$plates->addDefaultParam(TemplateInterface::TEMPLATE_ALL, [
34+
'endpoints' => $req->getEndPoints(),
35+
'querystr' => $req->getQueryParams(),
36+
'uri' => $req->getUri(),
37+
'curr_path' => trim($req->getUri()->getPath(), '/')
38+
]);
39+
40+
41+
/**
42+
* Register template functions.
43+
*/
44+
$engine = $plates->getEngine();
45+
46+
$engine->registerFunction('hasEndpoint', function ($endpoint, $base_path = '') use ($req) {
47+
return ($req->hasEndpoint($endpoint, $base_path, false));
48+
});
49+
50+
$engine->registerFunction('isEndpoint', function ($endpoint, $base_path = '') use ($req) {
51+
return ($req->isEndpoint($endpoint, $base_path));
52+
});
53+
54+
return $plates;
55+
});

app/config/middleware.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php // Application middlewares
2+
3+
use \BitFrame\ErrorHandler\WhoopsErrorHandler;
4+
use \BitFrame\Message\DiactorosResponseEmitter;
5+
use \BitFrame\Router\FastRouteRouter;
6+
7+
// run error handler to register it immediately
8+
$app->run(new WhoopsErrorHandler(
9+
//(ENV === 'dev' && DEBUG_MODE) ?
10+
// auto determine error handler in production environment
11+
//'auto' :
12+
// custom error handler in live environment
13+
function($exception, $inspector, $error_handler) use ($app) {
14+
$req = $app->getRequest();
15+
16+
// is an ajax request?
17+
if ($req->isXhr()) {
18+
header('Content-Type: application/json');
19+
20+
// error format compatible with json:api
21+
// @see http://jsonapi.org
22+
$response = [
23+
'errors' => [
24+
[
25+
'type' => $inspector->getExceptionName(),
26+
'message' => $exception->getMessage()
27+
]
28+
]
29+
];
30+
31+
// add additional error data in debug mode
32+
if (DEBUG_MODE) {
33+
$response['errors'][0]['file'] = $exception->getFile();
34+
$response['errors'][0]['line'] = $exception->getLine();
35+
}
36+
37+
// send error to client
38+
$json = json_encode($response);
39+
// output as json or jsonp?
40+
echo (
41+
($req->getMethod() === 'GET' &&
42+
! empty($callback = $req->getQueryParam('callback', ''))
43+
) ? "{$callback}($json)" : $json
44+
);
45+
} else {
46+
$data = [
47+
'page_title' => 'There was an error!',
48+
'is_error' => true,
49+
'css' => ['error.css'],
50+
51+
'err_line' => $exception->getLine(),
52+
'err_type' => $inspector->getExceptionName(),
53+
'err_msg' => $exception->getMessage(),
54+
'err_file' => $exception->getFile(),
55+
'err_trace' => $exception->getTrace(),
56+
'err_inspector' => $inspector
57+
];
58+
59+
// error tpl
60+
echo $app['tpl']->render('error', $data);
61+
}
62+
63+
return \Whoops\Handler\Handler::QUIT;
64+
},
65+
true
66+
));
67+
68+
// add middlewares
69+
$emitter = new DiactorosResponseEmitter();
70+
$router = new FastRouteRouter();
71+
72+
$app->addMiddleware([
73+
$emitter,
74+
$router
75+
]);

app/config/routes.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php // Proxy incoming routes to their corresponding handler files
2+
3+
/**
4+
* Self-calling anonymous function to create local scope and
5+
* keep the global namespace clean.
6+
*/
7+
call_user_func(function() use ($app) {
8+
$req = $app->getOriginalRequest();
9+
10+
// is the site under maintenance?
11+
if (MAINTENANCE_MODE) {
12+
$app->get('/' . $req->getUri()->getPath(), function ($request, $response, $next) use ($app) {
13+
$data = [
14+
'page_title' => 'Under Maintenance'
15+
];
16+
17+
$response->getBody()->write($app['tpl']->render('maintenance', $data));
18+
19+
return $response;
20+
});
21+
}
22+
else {
23+
$req_path = $req->getEndpoint(1);
24+
25+
// file name for requested route
26+
// if empty string, show default "HOME_PAGE"
27+
$route_file = pathinfo(($req_path ?: HOME_PAGE), PATHINFO_FILENAME) . '.php';
28+
29+
// full file path + file name for requested route
30+
$route_file_path = ROUTES_DIR . $route_file;
31+
32+
// register routes
33+
if (file_exists($route_file_path)) {
34+
require $route_file_path;
35+
}
36+
}
37+
});

app/routes/about.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
$app->get("/about", function ($request, $response, $next) use ($app) {
4+
$data = [
5+
'page_title' => 'About',
6+
'css' => ['about.css'],
7+
'js' => ['about.js']
8+
];
9+
10+
$response->getBody()->write($app['tpl']->render('about', $data));
11+
12+
return $response;
13+
});

app/routes/home.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
function controller_home($request, $response) {
4+
global $app;
5+
6+
$data = [
7+
'page_title' => 'Home'
8+
];
9+
10+
$response->getBody()->write($app['tpl']->render('home', $data));
11+
12+
return $response;
13+
}
14+
15+
// home page
16+
$app->get('/', 'controller_home');
17+
$app->get('/home', 'controller_home');

app/tpl/_layout.tpl

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
<title><?= "{$page_title_prefix}{$page_title}{$page_title_suffix}"; ?></title>
6+
7+
<base href="<?= BASE_URL; ?>" />
8+
9+
<link rel="stylesheet" type="text/css" href="static/css/style.css" />
10+
<?php foreach ($css as $file): ?>
11+
<link rel="stylesheet" type="text/css" href="static/css/<?= $file; ?>" />
12+
<?php endforeach; ?>
13+
14+
<?php foreach ($js as $file): ?>
15+
<script type="text/javascript" src="static/js/<?= $file; ?>"></script>
16+
<?php endforeach; ?>
17+
</head>
18+
19+
<body<?= (MAINTENANCE_MODE) ? ' class="maintenance"' : ''; ?>>
20+
<!-- LAYOUT -->
21+
<div id="layout">
22+
23+
<?php if (! MAINTENANCE_MODE): ?>
24+
<!-- HEADER -->
25+
<header>
26+
<?= $this->insert('component::main-nav'); ?>
27+
</header>
28+
<!-- / HEADER -->
29+
<?php endif; ?>
30+
31+
<!-- BODY -->
32+
<section id="body" class="gridWrapper">
33+
<?php if (! $is_error && ! MAINTENANCE_MODE): ?>
34+
<h2>From Parent Template</h2>
35+
36+
<p>
37+
This is a barebones example of how a website could be made with BitFrame. This text is imported from the main layout template (which is synonymous across all templates to give them the same look and feel).
38+
</p>
39+
<?php endif; ?>
40+
41+
<?= $this->section('content'); ?>
42+
43+
</section>
44+
<!-- / BODY -->
45+
46+
</div>
47+
<!-- / LAYOUT -->
48+
</body>
49+
</html>

app/tpl/about.tpl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php $this->layout('_layout', $this->data); ?>
2+
3+
<h3>From About Template</h3>
4+
5+
<p>
6+
This text comes from the <em>about.tpl</em> template file.
7+
</p>

app/tpl/error.tpl

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php $this->layout('_layout', $this->data); ?>
2+
3+
<h1>Error</h1>
4+
5+
<p class="errorMsg">
6+
<?= $err_msg; ?>
7+
</p>
8+
<?php if (! DEBUG_MODE): ?>
9+
<p>
10+
Set <code>DEBUG_MODE</code> (in env.php) to <code>true</code> to see error details.
11+
</p>
12+
<?php endif;
13+
14+
if (DEBUG_MODE && ! MAINTENANCE_MODE):
15+
16+
$frames = $err_inspector->getFrames();
17+
$total_frames = count($frames);
18+
?>
19+
<!-- ERROR DETAILS -->
20+
<div class="errorDetails">
21+
<h4><?= $err_type; ?>:</h4>
22+
23+
<p class="errorMsg">
24+
<?= $err_file; ?> (on line: <?= $err_line; ?>)
25+
</p>
26+
27+
<h4>Backtrace:</h4>
28+
29+
<ol class="backtrace">
30+
<?php foreach ($frames as $i => $frame):
31+
echo sprintf(
32+
"<li>[%d]: %s%s%s in %s: %d</li>",
33+
($total_frames - $i),
34+
($frame->getClass() ?: ''),
35+
($frame->getClass() && $frame->getFunction() ? '::' : ''),
36+
($frame->getFunction() ? $frame->getFunction() . '()' : ''),
37+
($frame->getFile() ?: '<#unknown>'),
38+
$frame->getLine()
39+
);
40+
endforeach; ?>
41+
</ol>
42+
43+
<h4>Error trace:</h4>
44+
45+
<div class="errorTrace">
46+
<pre>
47+
<?= print_r($err_trace, true); ?>
48+
</pre>
49+
</div>
50+
<?php endif; ?>
51+
52+
</div>
53+
<!-- / ERROR DETAILS -->

0 commit comments

Comments
 (0)