Login, Session and MVC

Getting Started

For this assignment, you're going to update the post/comment pages to use the MVC design pattern and add user login (using the User class from assignment 8). The starting repo is empty since you'll want to start with your A7/A8 pages and models.

Repo invite: https://classroom.github.com/a/12d5x7pf

Model-View-Controller (MVC)

The MVC design pattern organizes code by separating it:

  • The Models contain all the working logic for the domain. This is usually centered around classes for each of the database tables (the ORM models). Additional logic like hashing and login verification are also put into the models, as we did in assignment 8.
  • The Views generate HTML. They should be limited to only looping and conditionals to decide what to put on the page, nothing that constitutes actual decision making or domain work. Conversely, the Models and Controllers shouldn't be outputting any HTML.
  • The Controllers handle routing. In our current model, each Controller is in a separate PHP file. Each Controller handles one route, one way that the user can request from the server. The job of the Controller is to figure out who the user is, enforce security, use the Models to do any necessary work, and then show the user a View.

For example, the single PHP page from assignment 7 to show the list of posts should be re-factored into a Controller and a View. The filenames below are an arbitrary convention, but you need to be consistent.

ShowPosts.php (controller)

<?php
// import models, database connection config
require_once 'vendor/autoload.php';
require_once 'generated-conf/config.php';

// get all posts from database using the model
$posts = PostQuery::create()->orderByPostDate()->find();

// show the view
require('views/view_posts.php');
?>
  

views/view_posts.php (view, not complete from A7, but the general idea)

<html>

<head>

<title>PHP Comment Board</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
<link rel="stylesheet" href="style.css"/>

</head>

<body>

<div class="container">

<div class="page-header">
  <h1>My Fake Blog</h1>
</div>

<div class="row col-md-8 col-md-offset-2">

<table class="table table-striped">

<?php foreach($posts as $post) { ?>

<tr>
  <td>February 26, 2018, 10:21pm</td>
  <td><strong><?=$post->getUserId()?></strong></td>
  <td><a href="post.php?postId=<?=$post->getId()?>"><?=$post->getContent()?></a></td>
</tr>

<?php } ?>

</table>

</div>

<script src="http://code.jquery.com/jquery.min.js">

</body>

</html>
  

To complete this assignment, you'll need to create the following Controllers.

  • ShowPosts: handle GET request to display all the posts. If the user is logged in, there should be a session with a user id in it (see the Login controller). If that is true, get the User model from the database so that the view can show the username.
  • ShowPost: handle GET request to display a specific post. If the user is logged in, there should be a session with a user id in it (see the Login controller). If that is true, get the User model from the database so that the view can show the username.
  • ShowLogin: handle GET request to display the login page
  • Login: handle POST request to login, which can succeed or fail. On success, start a new session for that user and store the user id, then show the list of posts (you'll need to query the database to get $posts ready just like in the ShowPosts controller. On failure, show the login form again with an error message.
  • PostComment: handle POST request to add a comment. You'll need to get the user id from the session and the POST will need to send the post id that is being commented on (along with the comment text).

And Views:

  • view/view_posts: display the posts, assumes that the array of posts is already there to use. If the user is logged in, there should be a User object available to use so that you can add a "Hello, name" message to the page. Otherwise, provide a link to ShowLogin.
  • view/view_post: display a single post, assumes that the single post is already there to use. Keep the "Hello, name" message or login link.
  • view/view_login: display the login form (username and password). Add an error message ("bad username or password") that can be shown on a bad login attempt by setting a variable in the Controller.

Turning In

Commit the controllers and views that you created, as well as your modified User.php model (which won't have changed from assignment 8).