vespula / slim-skeleton
A Starting point for creating Slim Framework v3 applications.
Requires
- php: >=5.5
- aura/session: ^2.0
- league/climate: ^3.2
- league/plates: ^3.1
- slim/slim: ^3.0
- vespula/auth: ^0.2
- vespula/event: ^1.0
- vespula/locale: ^1.0
- vespula/log: ^0.2
Suggests
- zendframework/zend-permissions-rbac: Role Based Access Control
README
This is a skeleton application for quickly getting started with the Slim Framework version 3. It contains
- the Slim Framework,
- a template system via League/Plates,
- a session flash tool via Slim/Flash,
- a Command Line Interface (CLI) for creating projects and controllers via League/CLImate,
- a localization library for displaying localized strings,
- a PSR-3 logger, and
- an authentication system.
Table of Contents
- Setup/Installation
- Creating a project
- Creating a controller
- Adding routes
- Logging
- Localization
- Authentication
- Alerts
- Troubleshooting
- Resources
Setup/Installation
- Get the most recent dev version
composer create-project -s dev vespula/slim-skeleton your/path
- Get the most stable without VCS
composer create-project vespula/slim-skeleton your/path
- Get the most stable with VCS
composer create-project --keep-vcs vespula\slim-skeleton your/path
- Or just clone or download the repository then run
composer install
, thencomposer run-script post-create-project-cmd
.
If you choose to delete the VCS (.git) info for the project and use your own repository, make sure you modify the .gitignore
file. The one that comes with it ignores the src folder, which you might not want to do when going on your own.
If you keep the VCS (.git) info, then you can put new projects created in the src
folder under their own version control. The src
folder is ignored by default.
Check your .htaccess file
The default setup comes with a .htaccess file that uses mod_rewrite for the URLs. It points all requests back to index.php. Additionally, there is a setting called RewriteBase which needs to be set correctly to match your setup. By default, it points to /slim (for example if you were using an alias in apache). If the project is set up at the root of your web server, comment out the RewriteBase setting. If you are using a different folder name as an alias, adjust the RewriteBase to match your folder.
Creating a Project with the CLI tool
- Change to your slim-skeleton folder and issue the following command:
$ ./script/create
- Follow the prompts to create your project by pressing "p". When creating a project, a default Index controller and associated view will be created as well.
- A default route has been created in the html/index.php file. It will point to the newly created controller class and index method.
- When completed, you should be able to browse to your folder and view the result.
- You can create more controllers via the command line tool as well. Launch the script as above and choose "c" for a controller.
I highly recommend digging through the code to see examples of how the system works.
Creating a Controller
After you have created a project, you can easily create new controllers for that project. Use the create
script to create a controller making sure to use your project as the namespace.
$ ./script/create
- Follow the prompts to create your controller by pressing "c".
Adding Routes
A route file is included when you create a project. They will be in the routes.php
file in /src/YourProject
.
You can use this file as an example to create new routes. If using controllers, just remember that a controller takes
3 arguments: An Interop\Container\ContainerInterface $container
, a Psr\Http\Message\ServerRequestInterface $request
,
and a Psr\Http\Message\ResponseInterface $response
.
More information about routing is available on Slim's website.
Logging
The skeleton app comes with a PSR-3 compliant logger that you can replace or remove if you want. Here is a simple example:
<?php
$this->log->warning('This is a warning message');
$this->log->info('This is informative');
Where the log outputs data is up to you. You define the adapter in your dependencies file. See the Vespula/Log documentation.
Localization
The skeleton app comes with a library for outputting translated strings. It does not translate for you, but will output the appropriate string depending on what locale you are using. The locale object is configured in the dependencies file.
<?php
echo $locale->gettext('TEXT_HELLO');
Information on setting up and using the locale class, please refer to its documentation.
Authentication
The skeleton app comes with a lightweight authentication library that can validate users against SQL databases using PDO or against Active Directory/LDAP. It also has a simple Text validation adapter for testing. The auth object is defined in the dependencies file. You can modify the settings there. All the documentation for setting up the authentication object and the different adapters is available on the Vespula/Auth documentation.
First you need to set up a few routes to match the login requests (one via GET and one via POST), and the logout request. In your project's routes.php
file, add the following:
<?php
// Replace "Project" with the name of your project
$app->group('/login', function () {
$this->get('', function($request, $response) {
$controller = new \Project\Controllers\Index($this, $request, $response);
return $controller->login();
});
$this->post('', function($request, $response) {
$controller = new \Project\Controllers\Index($this, $request, $response);
return $controller->doLogin();
});
});
$app->get('/logout', function ($request, $response) {
$controller = new \Project\Controllers\Index($this, $request, $response);
return $controller->logout();
});
Next, you need actions in the controller you described in the routes for login()
, doLogin()
, and logout()
.
<?php
namespace Project\Controllers;
class Index extends Controller {
// ...
public function login()
{
// you should use a csrf strategy here too. Aura Session (included) has csrf tools.
$content = $this->view->render('index/login', ['messages'=>$this->messages]);
return $this->response->write($content);
}
public function doLogin()
{
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_POST, 'password', FILTER_DEFAULT);
$password = strip_tags($password);
$credentials = [
'username'=>$username,
'password'=>$password
];
$this->auth->login($credentials);
if ($this->auth->isValid()) {
$this->setFlash('info', 'You are logged in');
// $this->log->info($username . ' logged in');
return $this->redirect('/');
} else {
$this->setFlash('error', 'bad login');
// $this->log->error($username . ' failed to log in');
return $this->redirect('/login');
}
}
public function logout()
{
$username = $this->auth->getUsername();
$this->auth->logout();
if ($this->auth->isAnon()) {
$this->setFlash('info', 'Goodbye');
// $this->log->info($username . ' logged out');
return $this->redirect('/');
} else {
$this->setFlash('error', 'Could not log you out...');
// $this->log->error($username . ' failed logging out');
return $this->redirect('/');
}
}
}
Some other checks might be worthwhile for authentication status. For example, you might want to know if the person has been idle for too long, or they have gone past the expire time for the session. You can set those check up in your base controller's constructor.
if ($this->auth->isIdle()) {
// flash message, etc
}
if ($this->auth->isExpired()) {
// flash some message
}
Any time you want to check if the user is valid, just call the $this->auth->isValid()
. Within views, you can call $auth->isValid()
.
Login Template
Your login template index/login.php
in the Views folder might look like this:
<?php $this->layout('layouts::' . $theme); ?>
<?php echo $this->alerts($messages); ?>
<?php if ($auth->isValid()) : ?>
<p>You are already logged in! How special for you!</p>
<?php else : ?>
<h2>Login</h2>
<div class="row">
<div class="col-lg-2">
<form action="" method="post">
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" name="username" id="username" placeholder="Username" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" id="password" placeholder="Password" autocomplete="off" />
</div>
<input type="submit" class="btn btn-primary" value="Login" />
</form>
</div>
</div>
<?php endif; ?>
Displaying Alerts
A simple League Plates extension is bundled with the skeleton app. Any time you want to output a themed alert in your view, you can call it like a view helper.
The Alerts extension has 4 themes that match the layouts that come with the slim skeleton. You can specify a theme at anytime by passing a theme as a second argument, but it's recommended that you do it in your container where the alerts are defined. See the dependencies file. $alerts->setTheme()
.
The alerts extension comes with the following themes: bootstrap, foundation, gcweb, and gcwu. The last two are Government of Canada templates.
<?php
echo $this->info('Some message');
echo $this->error('Some message', $mytheme);
// Echo several at once
$messages = [
'error'=>[
'Error one',
'Error two'
],
'info'=>[
'Info one',
'Info two'
]
];
echo $this->alerts($messages);
Troubleshooting
If you have any issues, the first place to check is :
- is your alias or virtual host set up correctly and pointing to the /slim-skeleton/html folder?
- if you have apache mod_rewrite on, check the .htaccess in the html folder and make sure the RewriteBase setting is correct. It may not be by default.