PHP Like a Pro: Part 6 (A New Project)

Having created a really simple Pastebin, how about we embark on something more ambitious. An actual web app with all the usual trappings: user accounts, session management, email notifications and etc. On the other hand, I shouldn’t try to build anything too ambitious because the purpose of this series is an educational one – which means I need to be able to break it down into manageable chunks and post digestible code snippets here for your enjoyment.

Oh, and I should probably introduce some new tools and concepts. If we designed this new thing using the same exact set of tools it wouldn’t be educational, no? It would be just… Work, I guess. Cause that’s what you usually do – you find a set of tools and packages you are comfortable with and you use them often. It saves time, effort and research when you have tight deadlines. But we want to learn and grow here, so let’s use something new.

The Toolkit

For this project I want to use a PHP micro-framework called Silex. Why this one? Because I think it is fairly brilliant and elegant. Here is the idea behind it: instead of providing a traditional full stack (and the kitchen sink) framework Silex is modular. At it’s very slimmest, it gives you a very neat front controller and page routing mechanism. Observe:

$app = new Silex\Application(); 
 
$app->get('/hello/{name}', function($name) use($app) { 
    return 'Hello '.$app->escape($name); 
}); 
 
$app->run();

Is that sexy or what? It is worth using just for that. But the framework has a lot more to offer. You want templating? Sixex seamlessly integrates with Twig. Remember that Twig factory class I created for the pastebin? There is a built-in equivalent in Silex. It also has a session handling module, form generation, form validation, email handling module, database abstraction layer and etc. All of these are more or less independent projects – many of which were built for the much fatter and complex Symphony framework. Silex binds them all together and ensures they work correctly.

So for this project I figured I would use the following Silex service providers:

  1. Twig
  2. Session
  3. SwiftMailer
  4. Doctrine

I actually really wanted to use Doctrine ORM, but Silex only has the integration with Doctrine DBAL. Granted, it shouldn’t be a major issue to use the ORM – it is just not officially supported, and there is little documentation for it so we would have to figure out how to fit it into place ourselves. Not sure if I want to do that, or buckle up and just go with DBAL and write a bit more SQL by hand.

Here is the reason I really like Silex: it uses Composer to manage all these dependencies. So all I need to do to get a Silex bundle with just the packages listed above and their own dependencies is to create a properly formatted composer.json file.

Here is another great thing about this framework – it is on the bleeding edge of the PHP world. It won’t actually run on anything less than PHP 5.4 because it makes extensive use of PHP Traits and improved closure syntax. It is elegant, modern, modular, sleek and very cool. I feel it is designed the way PHP apps ought to be designed.

If you happen to be running an Ubuntu 10.4 Vagrant box, like I told you to then this is what you will have to do to upgrade it to PHP 5.4:

sudo aptitude install python-software-properties
sudo add-apt-repository ppa:ondrej/php5
sudo apt-get update
sudo apt-get install php5

For some strange reason the latest version of PHP has not been back-ported to the official Lucid Lynx repositories, so we have to use a PPA.

I want to potentially showcase a build tool that would automate the testing and prepare my project for deployment. I guess I could use Ant, but since we are trying to be all about PHP perhaps Phing would be a better choice.

There is probably also a good chance we might need some JavaScript for this project. If we do, an there is enough complexity there I’m considering using jQuery framework and perhaps RequireJS for dependency management.

How does RequireJS work? Well, it makes managing and loading JavaScript much easier. All you do is insert a single line in your template like this:

<script data-main="scripts/main" src="scripts/require-jquery.js"></script>

Then you create main.js in the directory scripts/ and do something like this:

require(["jquery", "jquery.plugin1", "other"], function($) {
    //this will load in order 
    // - srcirpts/jquery.js
    // - scripts/jquery.plugin.js
    // - scripts/other.js
});

Granted, this is supposed to be mostly a PHP series, but these days it is actually hard to do any web development without some JavaScript in the mix. So we might as well use a little bit of it. And since we will be using it, we also ought to have some way of testing it.

I’m thinking about using either QUnit or Buster.js framework. I haven’t used either one of them so it will be a learning experience for me too.

So, having decided on the tools and environment, what kind of simple, yet non-trivial kind of app could we make?

Problem Statement

There are a lot of bug tracking apps and services out there which range from really simple embedded apps (like GitHub and Google Code bug trackers), no frills standalone fully hosted services (Like Lighthouse) to full featured, modular and extensible self hosted apps (like Trac). The choice is much slimmer when it comes to IT issue tracking. Most ticketing systems out there take the kitchen sink approach to IT and like to flaunt their long feature lists. Personally, I like simplicity so many years ago I wrote my own and called it The Issue Tracking System. My boss liked the idea, but didn’t like the acronym so he told me to drop the “The” and re-brand it with company name.

But that was long ago, and I wouldn’t show you the code that runs TITS out of fear of dying out of embarrassment. But ever since I realized how bad that app was, I wanted to re-write it from scratch, simplify it even further removing the business specific features and making it generic and release it upon the world. I want it to be as simple and easy to use as the issue tracker in Google Code.

Specifications

Pastebins are kinda intuitive – if you used one, you kinda know how it works on the basic level and everything else on top are just bells and whistles. Issue tracking systems can be very complex, or very simple depending on needs. I want to keep it simple.

So let’s think about our main data entities. I can think of three:

  • Users – we obviously need accounts for end-users, and specialists/li>
  • Issues – users open up issues, or issues are opened by technicians based on calls/emails from the users
  • Updates- if the issue is not resolved right away technicians follow-up on them by posting updates that track their progress

IT tickets tend to be a little bit different than software bugs. A bug usually affects everyone, so bug trackers are typically open to the public and searchable by anyone. A typical IT issue is something along the lines of “Judy from accounting minimized her Outlook (again) and help desk had to remote in and maximize it for her, and then help her send an email because she forgot how (again).” To save Judy some embarrassment, I’m thinking our tracking system should have access controls – users only being able to see issues they are affected by.

Let’s talk about each of these elements.

User

A user is identified by an email address and a password. I envision two types: regular users who can open new issues and post updates, specialists who can edit, prioritize and close issues. Specialist may also have an optional “title” that describes their function (ie. software support, hardware support, manager, etc).

Issue

Lets keep it as simple as possible. Here is the information I want to keep about every issue:

  • Who is having this issue?
  • When was it opened? (automatic time-stamp when record is created)
  • Who is assigned to fix it? A specialist should be able to assign it to himself (default option) or delegate it to a colleague.
  • Is it open or closed? Closed status should be either “resolved” or “rejected“. Specialists ought to be able to reopen closed issues.
  • What is the priority? (low, medium, high – defaults to medium)
  • Are there other people who need to be aware of this issue (eg. a manager, ceo, supervisor, another affected user, etc)? This could be a comma separated list of emails, set by specialist.
  • Single sentence summary.
  • Detailed description and steps to reproduce.

Additional info can be attached to each issue using tag system like the one in Github issue tracker though it does not need to be that fancy. The tags can be used to implement category system (hardware, software, email, malware, etc..). It gives the system flexibility.

Update

Updates ought to be just simple text comments with a date, and name of the user who posted it. In addition, when a specialist modifies an issue (by adding a tag, or closing it) an update should be posted with that user’s credentials and automatically generated text saying for example “so and so changed status to resolved”.

Use Cases

Or maybe user stories if you want to be more agile or something. I honestly don’t care what you call these things, but I basically want to lay down basic interactions people will have with this app. I envision about 8 separate scenarios (excluding stuff like logging in and logging out) that will help us envision the interface and life cycle of an issue.

The primary actors are User and Specialist. Users can only see issues they have opened or on which they were CC’d. Specialists can see all the issues. By default when logged in everyone sees a list of open issues they are involved in. Users can click over to see closed issues. Specialists can also see new/unassigned issues.

Note this is probably boring and mostly for my benefit so I’m going to make it small so you can just skip over it if you don’t feel like reading it:

Case #1: New Issue Submitted by User

  1. A new user logs in and sees there are no visible issues posted.
  2. User clicks a link/button to create a new issue.
  3. User fills out a form consisting of the summary and detail fields and nothing else.

Case #2: User updates an issue

  1. User logs in and sees a list of existing issues opened him her.
  2. User clicks on an issue to see detailed information and updates.
  3. User scrolls down and posts and update by filling out the update box.
  4. If issue was assigned to a specialist, he gets an email notification.

Case #3: Specialist updates an issue

  1. Specialist logs in and sees a list of issues he is assigned to.
  2. Specialist clicks on an issue to see detail.
  3. Specialist scrolls down and posts and update by filling out the update box.
  4. If the issue was unassigned it automatically becomes assigned to the specialist.
  5. User gets email notification.

Case #4: Specialist changes issue priority

  1. Specialist logs in and sees a list of issues he is assigned to.
  2. Specialist clicks on an issue to see detail.
  3. Specialist changes the priority.
  4. An auto-update is posted.
  5. User gets email notification.

Case #5: Specialist closes an issue

  1. Specialist logs in and sees a list of issues he is assigned to.
  2. Specialist clicks on an issue to see detail.
  3. Specialist sets the status to resolved or rejected.
  4. Closing date is recorded.
  5. An auto-update is posted.
  6. User gets email notification.

Case #6: Specialist claims or assigns an issue

  1. Specialist logs in and sees a list of issues he is assigned to.
  2. Specialist clicks over to see a list of unassigned issues.
  3. Specialist clicks on an issue to see detail.
  4. Specialist assigns the issue to another specialist.
  5. An auto-update is posted.
  6. Both the User and the other specialist gets email notifications.

Case #7: Specialist reopens an issue

  1. Specialist logs in and sees a list of issues he is assigned to.
  2. Specialist clicks over to see a list of closed issues.
  3. Specialist clicks on an issue to see detail.
  4. Specialist changes the status to open.
  5. Closing date is removed.
  6. An auto-update is posted.
  7. User gets an email notification.

Case #8: Help Desk Call

  1. Specialist logs in and sees a list of issues he is assigned to.
  2. Specialist clicks to create a new issue based on phone call or email from User.
  3. Specialist fills out summary, detail, email of the User, chooses priority and assigned specialist (defaults to himself).
  4. Optionally Specialist checks a box “resolved”.
  5. If the box was checked closing date is recorded.
  6. User gets email notification.

Case #9: From Email

  1. User or specialist clicks on direct URI from email notification.
  2. If not logged in, prompted to do so.
  3. Taken directly to specific issue page.

We can use these use-cases as templates to create acceptance tests with Codeception.

We have a lot of auto updates for all kinds of scenarios. It would be good to be able to visually distinguish these from actual updates posted by humans. Perhaps a field in the Update table can let us do that.

User Interface Mockups

Often it is a good idea to create UI Mockups for your page before you even start working. Simple wireframe will help you nail down the rough outline for the layout – especially if you will be working with a team of designers. I used the neat online tool called Frame Box to create these.

An end user creating an issue ought to see something like this:

User View

User View of New Issue page

A specialist will have all the options available on the sidebar like this:

Specialist View

Specialist View of New Issue Page

Here is roughly how a static (ie. non editable) detailed view of the issue would like. Specialists would see a slightly different version where they would have some controls to change the status, priority or close the issue.

Issue Detail Page

Issue Detail Page

I’m actually thinking about placing these controls right above the “update” text box – this way the process of closing an issue or changing priority would be identical to that of posting an update.

Onward

Sorry for the wall of text here, but I figured we need to jot down some specifications and make a few design decisions up-front so that we can be clear as to what we want to create and how we will be going about it. Next time, we’ll actually write some code.

This entry was posted in programming and tagged , . Bookmark the permalink.



3 Responses to PHP Like a Pro: Part 6 (A New Project)

  1. I never heard of Frame Box until now. It looks useful and I think I even have a use-case for it at work really soon. Thanks!

    A user is identified by an email address and a password.

    Does this mean two accounts can have the same e-mail address, so long as they have different passwords? :-) Presumably you mean an account is identified by an e-mail address and authenticated by both an e-mail address and password.

    Also, your Buster.js link is broken.

    Reply  |  Quote
  2. Luke Maciak UNITED STATES Mozilla Firefox Windows Terminalist says:

    @ Chris Wellons:

    Thanks. Yeah, that’s what I meant. Or rather, that emails are unique enough to be used as primary keys if I wanted too. :P

    Reply  |  Quote
  3. Pingback: Super Lazy Provisioning with Vagrant | Terminally Incoherent UNITED STATES WordPress

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>