Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
225 lines (161 sloc) 9.14 KB

Read It Later

A Read It Later is an application for managing a reading list of articles from the Internets™. In short, you can save links into an application that you will read, well, later. Yet, most of the existing services added features on top of it, such as:

  • Offline mode: content is fetched and stored so that you don't need an Internet connection to read your saved links;
  • Comments/notes: say if you want to summarize the content of the link;
  • Support for embedded videos;
  • Categories: to sort all your links;
  • Sharing (Twitter, Email, etc.).

There are many existing services, including: Instapaper, which turns web content – articles, stories, posts, videos, and even long emails – into a great reading experience, Pocket, formerly known as Read It Later, and Wallabag, the Open Source alternative.

In order to build a Minimum Viable Product (MVP), a Read It Later application has to:

  • save links a single user wants to read later;
  • fetch the content of a link (content has to be stored) so that user can read it directly in your application;
  • mark a link as archived (or read) when a user has read it;
  • provide the ability to sort links into categories.

Ideally, fetching the content of a link SHOULD be done with a worker. A worker is a special application that runs periodically (e.g., every X minutes), and loops over a set of tasks to perform. For instance, it can retrieve (from the database) all links that have no content yet, and for each: (i) fetch the content, and (ii) store it in the database. The Symfony Console Component may help you.

Also, today's applications SHOULD be "API-oriented", that is built around an API (HTTP/RESTful). Here, it would be nice to save links by sending a request with cURL or httpie for instance.

There are many other features that can be added to this application but here are two interesting options:

  • support multiple users (with account management);
  • save a link using a bookmarklet.

Advice: give an existing application a try in case you never used any Read It Later application.

What You Have To Do Now

Write a Read It Later application.

You can use whatever tool you want as far as you can explain your choices. You MUST write the application in PHP. For instance, you can use Slim, or Silex as framework.

Rely on Composer and Packagist to install packages, and manage your project's dependencies. You can ask for advice regarding the libraries you would like to use.

Your code SHOULD be versioned. I don't mind if you loose your work before the deadline ;-)

You MUST use the Coding Standards as described in PSR-1 and PSR-2. The PHP Coding Standards Fixer could help you.

The Model

Important: you MUST focus on the Model layer, and you MUST write this layer yourself. No existing ORM allowed here. You MUST implement database design patterns seen in class, but choose them carefully according to what you need to do.

You can use a simple file as persistence storage, in YAML or JSON for instance.

If you want to use PDO, choose SQLite as database engine if you are running your code on etud, otherwise feel free to use another database engine such as PostgreSQL or MySQL.

Then again, be sure to be able to explain your choices.


Software testing is a requirement for all developers. Your job is not to write code, it is all about providing solutions for given problems. The right solution is always the one that works.

The question is: how do you ensure that your solution works? You cannot rely on the well-known it works on my machine™. This is just silly. What you need to do is to provide a set of automated tests.

Tests are more than just assertions on some properties of your application, it is also the best documentation you can provide to your customers/users because tests are always up to date.

So, your application MUST be tested. Write unit tests, but also functional tests. Behat can help you with your functional tests. It takes sort of user stories as input ;-)

Don't expect to have more than 10/20 if you don't provide tests!

Presentation Layer

While it is not the goal of this project, things that look nice are always better than ugly things, even if those things don't work. In other words, don't neglect the presentation/design.

### Various Hints

Content Negotiation

Content Negotiation is part of the HTTP protocol, used to serve a resource in the best format for a client. You can read RFC 2616: HTTP/1.1 and RFC 2295: content negotiation if you want more information.

Content negotiation means that a single resource can be presented in different ways, depending on the client preferences. To achieve this goal, HTTP headers (Accept, Accept-*) are used by a client to tell the server about its preferences.

Your application SHOULD be able to serve resources in:

  • HTML using a template;
  • JSON encoded data.

Negotiation can help you get the best format from headers by handling content negotiation. The Accept header could be found in $_SERVER['HTTP_ACCEPT']. It is possible to use Negotiation with both Silex and Slim.

Your implementation SHOULD accept parameters encoded in:

  • application/x-www-form-urlencoded - used when you submit a HTML form;
  • application/json.

When a request has a body, it should provide a Content-Type. This content type header is available in either $_SERVER['HTTP_CONTENT_TYPE'] or $_SERVER['CONTENT_TYPE'].


HTML rendering is achieved through your template engine. Rendering your data in other formats is called serialization. Serialization is the process of converting a data structure or object state into a format that can be stored.

The serialization is handled by a Serializer. This serializer can be as simple as the json_encode() function or you can use the Serializer Component.


Bookmarkets can be defined as mini applications masquerading as tiny snippets of JavaScript awesomeness that reside in your browser and provide additional functionalities, with just a click.

Read It Later applications usually provide bookmarklets so that users just have to click on them to save a page (i.e. a link) without having to open the application, copy and paste the link, submit it.

Here is a simple snippet that can be put in a a HTML element:

javascript:location.href='' + encodeURIComponent(location.href)

Such a bookmarklet redirects the user to page with the URL has parameter (query string). The /save URI is something you have to implement. Store the URL as you would usually do, but then, redirect the user to the previous page (i.e. the URL given in the query string).

Want to know more about bookmarklets? See:


Le projet est à rendre au plus tard le 25 mars 2016 à 20h00 CET. Vous ne pouvez pas être plus de deux étudiant(e)s sur un projet.

Les formats acceptés sont :

  • une archive (tar, tgz ou zip) ;
  • ou un dépôt distant (git, svn, etc.).

Le projet doit être accompagné d'instructions de mise en route. Ainsi que d'un bilan rapide de ce qui a été fait/pas fait. Le format pour ce fichier doit être textuel, donc txt ou markdown. Je ne peux pas ouvrir les fichiers Word ou Open Office.

Ce bilan n'est pas un compte rendu formel, vous pouvez simplement énumérer ce qui a été fait et ce qui n'a pas été fait, en faisant des phrases courtes, en français. Il devrait tenir sur une page, et c'est un fichier obligatoire.

Aucun retard ou problème technique ne sera toléré, c'est pourquoi il est fortement conseillé de mettre également à disposition un lien de téléchargement direct sur un service en ligne (Dropbox, Ubuntu One, Google Drive, etc.).

Si votre archive est corrompue, vous serez défaillant, faites en sorte d'envoyer quelque chose de correct. Nous vérifierons ce point à chaque réception d'un projet. Si votre archive est corrompue, nous vous l'indiquerons et vous aurez avant 20h00 pour renvoyer une archive valide.

Vous devez nommer l'archive comme suit : projet_<nom 1>_<nom 2>.zip. Le mail doit comporter la mention [ZZ3F2 PHP] dans le sujet du mail.