Lesson Weekend

Now that we have our basic methods and specs ready for our To Do list with SQL, let's update our Silex app to reflect these new changes. At this point, we have two classes Task and Category. Our previous Silex To Do app listed out all of the tasks we needed to do, so now we will just alter our app so that we can also list out all of the categories.

Let's create an index.html.twig file to be our "homepage" for our application. From this page, a user can click a link to see all of the categories or click a link to see all of our tasks.

views/index.html.twig
<html>
<head>
    <title>To Do List</title>
</head>
<body>
    <h1>Welcome to To Do List</h1>

    <p><a href="/categories">Click here</a> to see all of the categories and to add a category.</p>
    <p><a href="/tasks">Click here</a> to see all of the tasks and to add a task.</p>

</body>
</html>

Let's update our app.php file to handle these changes. Since we will be displaying categories as well as tasks in our application, we need to first include the line require_once __DIR__."/../src/Category.php"; at the top of this file.

app/app.php
<?php
    require_once __DIR__."/../vendor/autoload.php";
    require_once __DIR__."/../src/Task.php";
    require_once __DIR__."/../src/Category.php";

    $app = new Silex\Application();

    $server = 'mysql:host=localhost:8889;dbname=to_do';
    $username = 'root';
    $password = 'root';
    $DB = new PDO($server, $username, $password);



    $app->register(new Silex\Provider\TwigServiceProvider(), array(
        'twig.path' => __DIR__.'/../views'
    ));

    $app->get("/", function() use ($app) {
        return $app['twig']->render('index.html.twig');
    });

    $app->get("/tasks", function() use ($app) {
        return $app['twig']->render('tasks.html.twig', array('tasks' => Task::getAll()));
    });

    $app->get("/categories", function() use ($app) {
        return $app['twig']->render('categories.html.twig', array('categories' => Category::getAll()));
    });

    $app->post("/tasks", function() use ($app) {
        $task = new Task($_POST['description']);
        $task->save();
        return $app['twig']->render('tasks.html.twig', array('tasks' => Task::getAll()));
    });

    $app->post("/delete_tasks", function() use ($app) {
        Task::deleteAll();
        return $app['twig']->render('index.html.twig');
    });

    return $app;
?>

A couple of things to note about this code:

  • We changed the view that is rendered for the get("/"... route, so it will take our users to index.html.twig instead of tasks.html.twig.
  • We added a get("/tasks"... route so that when a user clicks on the link for tasks in our index.html.twig view, they will be routed to the correct view tasks.html.twig. We are passing in the list of all of the tasks to this view as well.
  • We added a get("/categories"... route for the same reasons as above, but we are passing in the list of all of the categories as the variable categories.
  • We have also changed the view rendered from create_task.html.twig back to tasks.html.twig. In order for the list of tasks to display again in this view, we need to remember to pass in Task::getAll() as the variable tasks.
  • We changed the post("/delete_tasks"... route to render the index.html.twig view, once someone deletes all of the tasks.

Let's create a categories.html.twig file for when a user clicks on the categories link from the index view.

views/categories.html.twig
<html>
<head>
    <title>To Do List</title>
</head>
<body>
    <h1>Categories</h1>

    {% if categories is not empty %}
        <p>Here are all your categories:</p>
        <ul>
            {% for category in categories %}
                <li>{{ category.getName }}</li>
            {% endfor %}
        </ul>
    {% endif %}

    <form action='/categories' method='post'>
        <label for='name'>Category name</label>
        <input id='name' name='name' type='text'>

        <button type='submit'>Add category</button>
    </form>
    <form action='/delete_categories' method='post'>
        <button type='submit'>Clear</button>
    </form>

    <p><a href='/'>Home</a></p>
</body>
</html>

This looks almost exactly the same as our tasks.html.twig file. Now let's update our routes in our app.php file to handle the post("/categories"... and post("/delete_categories"... routes.

app/app.php
<?php
...    
    $app->post("/categories", function() use ($app) {
        $category = new Category($_POST['name']);
        $category->save();
        return $app['twig']->render('categories.html.twig', array('categories' => Category::getAll()));
    });

    $app->post("/delete_categories", function() use ($app) {
        Category::deleteAll();
        return $app['twig']->render('index.html.twig');
    });

...
    return $app;
?>