Added Eloquent and Phinx for handling database connections and migrations; added a Ticket model and a simple ticket/create form to create new tickets
This commit is contained in:
parent
41aca6215e
commit
830a950bf4
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,9 @@
|
||||
# Composer dependencies
|
||||
vendor/
|
||||
|
||||
# Local data
|
||||
data/
|
||||
|
||||
# NPM dependencies (building CSS and JS)
|
||||
node_modules/
|
||||
|
||||
|
@ -4,15 +4,22 @@ $primary-color-highlight: darken($primary-color, 10%)
|
||||
$box-shadow-1: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)
|
||||
$box-shadow-2: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)
|
||||
|
||||
$nav-height: 60px
|
||||
|
||||
body
|
||||
padding-top: $nav-height
|
||||
background: lightgrey
|
||||
|
||||
.container
|
||||
max-width: 1100px
|
||||
padding: 20px 30px
|
||||
|
||||
#main-nav
|
||||
position: fixed
|
||||
top: 0
|
||||
left: 0
|
||||
width: 100%
|
||||
height: 60px
|
||||
height: $nav-height
|
||||
background: #212121
|
||||
color: #eee
|
||||
font-size: 2.75rem
|
||||
@ -36,3 +43,7 @@ body
|
||||
|
||||
&:hover
|
||||
color: $primary-color-highlight
|
||||
|
||||
#main-wrapper
|
||||
margin-top: 25px
|
||||
background: white
|
||||
|
@ -20,6 +20,8 @@
|
||||
"slim/psr7": "^1.6",
|
||||
"php-di/php-di": "^6.4",
|
||||
"slim/twig-view": "^3.3",
|
||||
"hassankhan/config": "^3.0"
|
||||
"hassankhan/config": "^3.0",
|
||||
"illuminate/database": "^9.40",
|
||||
"robmorgan/phinx": "^0.13.1"
|
||||
}
|
||||
}
|
||||
|
1847
composer.lock
generated
1847
composer.lock
generated
File diff suppressed because it is too large
Load Diff
0
data/.gitkeep
Normal file
0
data/.gitkeep
Normal file
30
db/migrations/20221120233343_add_tickets_table.php
Normal file
30
db/migrations/20221120233343_add_tickets_table.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class AddTicketsTable extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('tickets');
|
||||
$table->addColumn('title', 'string', ['null' => false])
|
||||
->addColumn('body', 'text', ['null' => false])
|
||||
->addColumn('severity', 'string', ['default' => 'low'])
|
||||
->addColumn('due_at', 'datetime')
|
||||
->addTimestamps()
|
||||
->addIndex(['title', 'body', 'due_at', 'severity'])
|
||||
->create();
|
||||
}
|
||||
}
|
37
phinx.php
Normal file
37
phinx.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
return
|
||||
[
|
||||
'paths' => [
|
||||
'migrations' => '%%PHINX_CONFIG_DIR%%/db/migrations',
|
||||
'seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds'
|
||||
],
|
||||
'environments' => [
|
||||
'default_migration_table' => 'phinxlog',
|
||||
'default_environment' => 'development',
|
||||
'production' => [
|
||||
'adapter' => 'mysql',
|
||||
'host' => 'localhost',
|
||||
'name' => 'production_db',
|
||||
'user' => 'root',
|
||||
'pass' => '',
|
||||
'port' => '3306',
|
||||
'charset' => 'utf8',
|
||||
],
|
||||
'development' => [
|
||||
'adapter' => 'sqlite',
|
||||
'name' => './data/goliath',
|
||||
'suffix' => '.db'
|
||||
],
|
||||
'testing' => [
|
||||
'adapter' => 'mysql',
|
||||
'host' => 'localhost',
|
||||
'name' => 'testing_db',
|
||||
'user' => 'root',
|
||||
'pass' => '',
|
||||
'port' => '3306',
|
||||
'charset' => 'utf8',
|
||||
]
|
||||
],
|
||||
'version_order' => 'creation'
|
||||
];
|
@ -5,12 +5,18 @@ namespace BitGoblin\Goliath\Controllers;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Slim\Views\Twig;
|
||||
use BitGoblin\Goliath\Models\Ticket;
|
||||
|
||||
class HomeController extends Controller {
|
||||
|
||||
public function getIndex(Request $request, Response $response): Response {
|
||||
// find tickets from the database
|
||||
$tickets = Ticket::all();
|
||||
|
||||
$view = Twig::fromRequest($request);
|
||||
return $view->render($response, 'index.twig');
|
||||
return $view->render($response, 'index.twig', [
|
||||
'tickets' => $tickets,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
34
src/Controllers/TicketController.php
Normal file
34
src/Controllers/TicketController.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace BitGoblin\Goliath\Controllers;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Slim\Views\Twig;
|
||||
use BitGoblin\Goliath\Models\Ticket;
|
||||
|
||||
class TicketController extends Controller {
|
||||
|
||||
public function getCreate(Request $request, Response $response): Response {
|
||||
$view = Twig::fromRequest($request);
|
||||
return $view->render($response, 'ticket/create.twig');
|
||||
}
|
||||
|
||||
public function postCreate(Request $request, Response $response): Response {
|
||||
$params = (array)$request->getParsedBody();
|
||||
|
||||
$ticket = new Ticket;
|
||||
$ticket->title = $params['ticket_title'];
|
||||
$ticket->body = $params['ticket_body'];
|
||||
$ticket->severity = $params['ticket_severity'];
|
||||
$ticket->due_at = $params['ticket_due'];
|
||||
|
||||
$ticket->save();
|
||||
|
||||
// redirect the user back to the home page
|
||||
return $response
|
||||
->withHeader('Location', '/')
|
||||
->withStatus(302);
|
||||
}
|
||||
|
||||
}
|
16
src/Models/Ticket.php
Normal file
16
src/Models/Ticket.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace BitGoblin\Goliath\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Ticket extends Model {
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'body',
|
||||
'severity',
|
||||
'due_at',
|
||||
];
|
||||
|
||||
}
|
@ -18,10 +18,16 @@ $container->set('config', function () use ($config) {
|
||||
return $config;
|
||||
});
|
||||
|
||||
// Load database configuration
|
||||
require_once __DIR__ . '/database.php';
|
||||
|
||||
// Set container to create App with on AppFactory
|
||||
AppFactory::setContainer($container);
|
||||
$app = AppFactory::create();
|
||||
|
||||
// Allow body parsing for POST parameters
|
||||
$app->addBodyParsingMiddleware();
|
||||
|
||||
// Add Error Handling Middleware
|
||||
$app->addErrorMiddleware(true, false, false);
|
||||
|
||||
|
10
src/database.php
Normal file
10
src/database.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
$capsule = new \Illuminate\Database\Capsule\Manager;
|
||||
$capsule->addConnection($config->get('database'));
|
||||
$capsule->setAsGlobal();
|
||||
$capsule->bootEloquent();
|
||||
|
||||
$container->set('db', function () use ($capsule) {
|
||||
return $capsule;
|
||||
});
|
@ -6,3 +6,7 @@ use Slim\Views\Twig;
|
||||
|
||||
// index GET route - this page should welcome the user and direct them to the available actions
|
||||
$app->get('/', '\\BitGoblin\\Goliath\\Controllers\\HomeController:getIndex')->setName('index');
|
||||
|
||||
// /ticket/create GET route - allows a user to fill out a form to create a ticket
|
||||
$app->get('/ticket/create', '\\BitGoblin\\Goliath\\Controllers\\TicketController:getCreate')->setName('ticket.create');
|
||||
$app->post('/ticket/create', '\\BitGoblin\\Goliath\\Controllers\\TicketController:postCreate');
|
||||
|
@ -3,5 +3,30 @@
|
||||
{% block title %}Home{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>This is a test.</p>
|
||||
<div class="row">
|
||||
<div class="columns twelve">
|
||||
<h1>Welcome to Goliath!</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
{% if tickets|length > 0 %}
|
||||
<table class="columns twelve">
|
||||
<thead>
|
||||
<th>Title</th>
|
||||
<th>Severity</th>
|
||||
<th>Due date</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for ticket in tickets %}
|
||||
<td>{{ ticket.title }}</td>
|
||||
<td>{{ ticket.severity }}</td>
|
||||
<td>{{ ticket.due_at }}</td>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>There a no tickets in the database at this time.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -15,13 +15,15 @@
|
||||
<div class="nav-left">
|
||||
<ul class="nav-menu">
|
||||
<li>Goliath</li>
|
||||
<li class="nav-link"><a href="/">Home</a></li>
|
||||
<li class="nav-link"><a href="/tickets">Tickets</a></li>
|
||||
<li class="nav-link"><a href="{{ url_for('index') }}">Home</a></li>
|
||||
<li class="nav-link"><a href="{{ url_for('ticket.create') }}">Create</a></li>
|
||||
<li class="nav-link"><a href="/search">Search</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="main-wrapper" class="container">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
41
views/ticket/create.twig
Normal file
41
views/ticket/create.twig
Normal file
@ -0,0 +1,41 @@
|
||||
{% extends 'layout.twig' %}
|
||||
|
||||
{% block title %}Create new ticket{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="columns twelve">
|
||||
<h1>Create new ticket</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="columns twelve">
|
||||
<form action="/ticket/create" method="POST" class="u-full-width">
|
||||
<div class="row">
|
||||
<div class="six columns">
|
||||
<label for="ticket_title">Title</label>
|
||||
<input id="ticket_title" class="u-full-width" type="text" placeholder="My new ticket" name="ticket_title">
|
||||
</div>
|
||||
<div class="columns three">
|
||||
<label for="ticket_due">Due at</label>
|
||||
<input id="ticket_due" class="u-full-width" type="datetime-local" name="ticket_due">
|
||||
</div>
|
||||
<div class="three columns">
|
||||
<label for="ticket_severity">Severity level</label>
|
||||
<select id="ticket_severity" class="u-full-width" name="ticket_severity">
|
||||
<option value="low">Low</option>
|
||||
<option value="medium">Medium</option>
|
||||
<option value="high">High</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="ticket_body">Ticket body</label>
|
||||
<textarea id="ticket_body" class="u-full-width" placeholder="Explain what this ticket is about..." name="ticket_body"></textarea>
|
||||
|
||||
<input class="button-primary" type="submit" value="Submit">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user