Ok, we have installed environment, everything works fine so we can start creating our app!
As you may remember I want to write simple application extending Evernote by simplify displaying reminders and do some daily action on some specific notes.
I’ll start with displaying the notes. By now I don’t need connection with Evernote itself, so I’ll create some dummy notes in PHP.
The model
Let’s start with the model for note. Model is the special type of PHP class which describes all data for the note. I need for sure: `id`, `title`, `description`, `remind at` date and maybe `created at` date. It is enough for now if the application will require some more information I’ll add it to the model.
The model will looks like this:
<?php namespace AppBundle\Entity; class Note { /** * @var int */ private $id; /** * @var string */ private $title; /** * @var string */ private $content; /** * @var \DateTime */ private $remindAt; /** * @var \DateTime */ private $createdAt; /** * @return int */ public function getId() : int { return $this->id; } /** * @param int $id * * @return $this */ public function setId($id) : Note { $this->id = $id; return $this; } /** * @return string */ public function getTitle() : string { return $this->title; } /** * @param string $title * * @return $this */ public function setTitle($title) : Note { $this->title = $title; return $this; } // ... and so on ;-) }
Note: The whole `Note` model is available here
In a few words this class contains all mentioned before fields and two types of methods for each one:
– `setter` – a method for setting the value of specific field (e.g. `setId` sets id of the note)
– `getter` – a method for getting the value of specific field (e.g. `getId` gets id of the note)
That’s all. To use this model I’ll create a new object of `Note` class, set its values and then pass it to the view.
Note: The note model is placed in `Entity` directory. It’s a standard directory where Doctrine models are stored. I won’t use Doctrine right now, so trust me and make it so 😉
The controller
I have a class for storing notes, but I need something to really use it. This “something” is a controller. A controller is a special (yeah, every class is special ?) type of class that receives a request from the browser, does something, e.g. gets notes data, and return the response.
For now, I need a controller that create some notes and return them to the view so I could display a list.
Controllers are usually placed in `Controller` directory and have names ending with `Controller`.
Every controller has actions, that is methods that really do the work. Every action has to end with `Action`. So, I need a controller, let’s say `NoteController` and an action, let’s say `listAction`.
<?php namespace AppBundle\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Response; /** * Class NoteController * @package AppBundle\Controller */ class NoteController extends Controller { /** * @Route("/list", name="note_list") * * @return Response */ public function listAction() : Response { } }
Note: I’ll extend `Controller` class for each controller – it contains helpers and the most often used methods. It’s standard Symfony class, so you’ll see it very often in Symfony apps 🙂
I have the `NoteController` scheme, so let’s focus on the notes. As I said before I’ll use some dummy note’s data, so I create a private method for generating them.
/** * @return Note[] */ private function getNotes() : array { $note1 = new Note(); $note1 ->setId(1) ->setTitle("first note") ->setContent("first note content") ->setRemindAt(new \DateTime("+1 hour")) ->setCreatedAt(new \DateTime()); $note2 = new Note(); $note2 ->setId(2) ->setTitle("second note") ->setContent("second note content") ->setRemindAt(new \DateTime("+1 day")) ->setCreatedAt(new \DateTime()); $note3 = new Note(); $note3 ->setId(3) ->setTitle("third note") ->setContent("third note content") ->setRemindAt(new \DateTime("+2 days 12:00:00")) ->setCreatedAt(new \DateTime()); return [$note1, $note2, $note3]; }
Now, let’s get those notes in `listAction` and pass them to the view.
/** * @Route("/list", name="note_list") * * @return Response */ public function listAction() : Response { $notes = $this->getNotes(); return $this->render(':note:list.html.twig', ["notes" => $notes]); }
Note: every action has to have the route – a special definition with route id and path for access in the browser. In this action, the route id is `note_list` (I like convention `controller_action`) and the path is simply `/list` (so it can be accessed by going to http://evernote.local:8686/app_dev.php/list URL).
The view
To display the list I need some view. As you can see I’ve used `:note:list.html.twig` file in the action. It is a special notation for finding the proper view. `:note` means that the view should be placed in `app/Resources/views/note` directory, and `list.html.twig` is the view itself. Symfony uses template engine called Twig, so the file should end with the `.twig` extension. `html` in the name tells that the view is in HTML format – it can be set to `json`, `XML`, `txt` and so on.
The view will be very simple. It will use the notes received from the controller and display them in very simple way.
{% extends 'base.html.twig' %} {% block body %} {% for note in notes %} <p>{{ note.id }}: {{ note.title }}</p> <p>created at: {{ note.createdAt | date("Y-m-d H:i:s") }}, remind at: {{ note.remindAt | date("Y-m-d H:i:s") }}</p> <p>{{ note.content }}</p> {% endfor %} {% endblock %}
If you know some other template engine it should looks familiar to you. If not, let me explain it a little.
The first line, `{% extends ‘base.html.twig’ %}` tells Twig, that this view is using the base.html.twig template, placed in `app/Resources/views` directory, as a base one. `base.html.twig` template contains all basic markdowns, including `<html>`, `<head>`, `<body>`, styles and so on.
Because it extends another template it must use blocks from the parent. Block is a special construction which you can put in any place, e.g. `<title>` section, or in our example – `<body>` section.
The main block for the body is `{% block body %}` and I’m using it to display the notes.
Because notes are stored in an array they should be displayed using a loop. The most basic loop in Twig is `{% for not in notes %}` – it gets elements of the `notes` array one by one and stores each note data in `note` variable. I can then access every field of the note using `.`, for example for getting the title I use `{{ note.title }}`.
Note: There are two markups used in Twig – `{% %}` and `{{ }}`. The first one is used for doing things, like specify blocks, create loops and if statements. The second one is used for displaying data, like `echo` but in a simpler way.
It’s alive!
Now, go to http://evernote.local:8686/app_dev.php/list URL in your browser. You should see something like this:
Summary
Huh, that was a long post, but it contains the basics of our application, so it has to be long.
We have now the model for storing notes, a controller for creating them and passing to the view, and view for displaying them as a list. It’s very good base for next steps.
You can find all the code on GitHub – I’m creating new branch for every post, so you can always check out how it looks in each stadium.
In the next post, I’ll describe Evernote SDK and show you how to get real notes from the Evernote 🙂
Stay tuned!
Don’t forget to check out other PHPhyts!
- PHPyths Buster: A great string performance test! (updated)
- PHPyths Buster: Single quotes are faster than double quotes
- PHPyths Buster: Annotations
- PHPyths Buster: End of the project
- PHPyths Buster: Displaying reminders
- PHPyths Buster: Evernote SDK [update]
- PHPyths Buster: Basic application
- PHPyths Buster: Hello World!
- PHPyths Buster: Project environment
- PHPyths Buster: The Project
Leave a Reply