Regent Street Cinema

Web-App Design and Development

Develop a web-app for the Regent Street Cinema.

Visit Website Git

PHP 46.4%
HTML 42.8%
CSS 9.2%
JavaScript 1.6%

Databases & Languages

PHP

PHP

HTML5

HTML5

JavaScript

JavaScript

MySQL

MySQL

Frameworks

CodeIgniter

CodeIgniter

Bootstrap

Bootstrap

jQuery

jQuery

jQuery Mobile

jQuery Mobile

Services

Stripe

Stripe

Collaboration

GitHub

GitHub


Technologies

jQuery, HTML & CSS

We used jQuery mobile to create the user interface to make our responsive web-app accessible on iOS devices. Throughout our web-app we used the jQuery mobile button, form, grid, navbar, table, and toolbar widgets and custom icons. For the book tickets page we used the jQuery selectmenu widgetFor the contact us page we used the jQuery mobile list view widget. For the account page we used the jQuery mobile flipswitch widget. For the game we used the jQuery mobile radio buttons widget.

We used jQuery core JavaScript to create functionality such as selecting and deselecting a seat on the seat map page. All of our own custom JavaScript is Ced at ~resources/js/rsc.js, except for the game JavaScript which is located inline at ~application/views/heritage/game.php, we also include the jQuery core, jQuery mobile and Stripe Checkout JavaScript libraries.

Our custom JavaScript is enclosed in the jQuery mobile page create event so after a user loads a page our JavaScript is re-loaded to apply to the updated Document Object Model (DOM). The ‘Account - Newsletter’ and ‘Account - Favourites’ sections toggles the newsletter or favourites subscription on the account page, they use the jQuery change event so after a user toggles the switch it checks the state of the toggle (‘on’ or ‘off’) and then uses AJAX to call the relevant newsletter or favourite, subscribe or unsubscribe API. The ‘Films and Events - Favourites’ sections toggles the film or event favourite, it uses the jQuery each utility to loop through all the favourite buttons and then uses the jQuery click event so after a user clicks the button it checks the state of the button (‘add’ or ‘remove’) and then uses AJAX to call the relevant add or remove API. The ‘Film or Event - Trailers’ section plays a trailer and shows the controls, this has no affect for iOS devices. The ‘Film or Event - Book’ section books tickets by calculating the price, then uses the Stripe Checkout payment gateway to complete the transaction, and then uses AJAX to call the relevant pay API and shows the ticket, the Stripe token ID, and then changes the page to the ticket. The ‘Name a Seat - Seat Map’ section selects or deselects a seat, and zooms in or out the seat map, it hides the request seat button, then calculates if there’s enough width to automatically zoom the seat map and hide the zoom button, it also uses the jQuery each utility to loop through all the seats and then uses the jQuery click event so after a user clicks the seat it checks the state of the seat (available or disabled), if the seat is disabled it flashes the seat to indicate it is unavailable, otherwise it checks the state of the seat (selected or unselected), if the seat is selected it unselects it and hides the request seat button, otherwise if the seat is unselected it uses the jQuery each utility to loop through all the seats and unselects them then selects the selected seat, it also uses the jQuery click event so after a user clicks the zoom button it checks the state of the button (‘in’ or ‘out’), if zoom in then it uses the jQuery each utility to loop through all the seats and increases them and changes the button to zoom out, otherwise if zoom out then it uses the jQuery each utility to loop through all the seats and decreases them and changes the button to zoom in, and it also uses the jQuery click event so after a user clicks the request seat button it gets the seat row and number and changes the page to the request seat page.

For out game JavaScript; the first section hides the questions, continue button and score, it uses the jQuery each utility to loop through all the questions and hides them. The second section sets the question numbers and answers, and total and remaining questions. The third section sets the score. The fourth section creates a random number function, a minimum and maximum number are required. The fifth section creates a calculate score function which resets the score, gets the form, loops the questions, and checks if the answers are correct, if the user gets an answer correct it increases the score by 1 and called the relevant game set API to set a cookie which unlocks content throughout the heritage section. The sixth section creates a next question function which hides the questions and continue button, checks if there are any remaining questions, if there are any remaining questions it shows the next question and removes the question from the remaining question, otherwise it calculates and shows the score. The seventh section uses the jQuery click event so after a user clicks the play button it hides the play button, shows the continue button and goes to the next question. The eighth section uses the jQuery click event so after the continue button it goes to the next question.

We used HTML to mark-up our pages, because we also used jQuery mobile we used data attributes on elements to extend jQuery mobile. Using standard HTML means if jQuery or CSS is unable to load, the page’s content and structure remain intact.

We used CSS to create the styling to appear the same as our prototypes. All of our own custom CSS is located at ~resources/css/themes/rsc-custom.css, we also include our custom jQuery mobile theme, and the jQuery mobile theme.

For our custom CSS; the ‘Page’ section removes the text shadow. The ‘Header’ section changes the buttons in the header to be purple against dark grey. The ‘Header Icons’ section sets the back, account, and favourite icons. The ‘Navbar’ section changes the buttons in the nabber to be purple against dark grey, similar to the header. The ‘Navbar Icons’ section sets the home, films and events, heritage, name a seat, and information icons. The ‘Account’ section uses media queries; on an iconne it enters the user’s full name and email address, and on an iPad it splits the view vertically with the user’s profile image on the left-half and the user’s details on the right-half. The ‘Films and Events’ section sets the poster size (150px x 200px), sets the film or event title to show an ellipsis if it’s too long, it also uses media queries; on an iPhone it splits the the films and events horizontally and hides the description and buttons, and on an iPad it splits the films and events vertically and shows the description and buttons. The ‘Film or Event’ section positions the promo at the top-half and positions the content at the bottom-half, it also uses media queries; on an iPhone it shows the iPhone promo (and hides the iPad promo), on an iPhone in landscape it hides the promo, and on an iPad it shows the iPad promo (and hides the iPhone promo). The ‘Book’ section sets the quantities size to full-width. The ‘Ticket’ section sets the promo size to full-screen and blurs and lightens it, sets the poster size (150px x 200px), sets the barcode size (full-width x 75px), all the elements are positioned appropriately, it also uses media queries; on an iPhone it shows the iPhone promo (and hides the iPad promo) and hides the poster, and on an iPad it shows the iPad promo (and hides the iPhone promo). The ‘Heritage’ section sets the background image and positions the timeline, artefacts, and game buttons at the bottom, it also used media queries; on an iPhone it hides the content, and on an iPad it shows the content and positions the background image to the left-half. The ‘Timeline’ section sets the timeline’s “line” and events, it also uses media queries; on an iPhone it hides the description, and on an iPad it shows the description. The ‘Artefacts’ section sets the artefacts in the middle. The ‘Seat Map’ sections changes the table’s display to appear like a seat map. The ‘Seat Map Icons’ sections sets the zoom in and out icons. The ‘Info’ section positions the video to the top-half, and sets the content to the bottom-half. The ‘Map’ section positions the map full-screen. The ‘Home’ section sets the background image, and positions the content at the bottom with a semi-transparent background. The ‘Sign Up / In / Out’ section uses media queries; on an iPhone it shows the relevant form, and on an iPad it splits the forms vertically, showing the sign in form on the left and the sign up form on the right. The ‘Name a Seat’ section uses media queries; on an iPhone it sets the background image and positions the content at the bottom-half.

CodeIgniter

“CodeIgniter is a powerful PHP framework with a very small footprint, built for developers who need a simple and elegant toolkit to create full-featured web applications” (CodeIgniter, 2014).

The .htaccess file routes everything (except the favicon.ico, and robots.txt files, and the images, resources, docs, and media folders) through the index.php file. The index.php file initialises the CodeIgniter system, the routing system then inspects the URL and its segments to determine the application controller to route it to (for example; the URL ‘/filmsevents’ routes to the Filmsevents controller located at ~application/controllers/filmsevents.php). The security system filters any user submitted data before loading the application controller, the application controller then loads any relevant drivers (for example; the database driver), models (for example; the ‘Auth_model’ model), libraries (for example; the form validation library), and helpers (for example; the form helper), the view system then sends the final view is sent to the user (for example; the URL ‘/heritage/timeline’ routes to the Heritage controller located at ~appllication/controllers/heritage.php, then loads the ~application/views/mobile/templates/header.php, ~application/views/heritage/timeline.php, and ~application/views/templates/footer.php views). Since we have not implemented any caching, we can skip this system. (CodeIgniter, 2014).

We have several application controller for our navigation sections, account and authentication sections, admin section, and API, all located at ~application/controllers. The ‘Welcome’, ‘Filmsevents’, ‘Heritage’, ‘Nameseat’, and ‘Info’ controllers are for our navigation sections, the ‘Welcome’ controller loads our home page, the ‘Filmsevents’ controller loads our films and events, favourites, film or event, book tickets, and ticket pages, the ‘Heritage’ controller loads our heritage, timeline, artefacts, and game pages, the ‘Nameseat’ controller loads our name a seat, seat map, and request seat pages, and the ‘Info’ controller loads our information, map, and contact us pages. The ‘Account’, and ‘Auth’ controller are for our account section and handles the sign up, in, and out processes, the ‘Account’ controller loads our account, upload profile image, and booked films and events pages, and the ‘Auth’ controller loads our sign in, out, and up pages. The admin section contains three controllers that load the admin dashboard, the films and events allows admins to add, edit, and delete films and events, times, and trailers, and the newsletter allows a admins to send newsletter and favourite emails to users. The ‘Api’ controllers handles our API.

We have two helpers for our web-app located at ~application/helpers. The domain helper uses the base URL to get the domain of the current web-app. The UUID helper creates a universally unique ID.

We have two models for out web-app located at ~application/models. The ‘Auth_model’ model has several functions; verify a user using a user’s email and password, verify a user’s session or redirects the user to sign in, creates user and inserts the user into the ‘users’ table in the database, encrypts a password using a password and salt, and sets, gets or redirects the previous URL. The ‘Data_model’ model has several function that abstracts the database including creating, reading, updating and deleting (CRUD) database records, and searching the database.

We have several views for our pages, split into mobile, email, and web. The mobile folder contains several folders to keep the views organises, the templates folder contains the ‘header’ view which is used for every page before the content, and the ‘footer’ view which is used for every page after the content, the ‘welcome_message’ view is used for the home page, the ‘filmsevents’ view is used for the films and events, favourites, and booked films and events pages, the filmsevents folder contains the ‘filmevent’, ‘book’, and ‘ticket’ views for the film or event, book tickets, and ticket pages, the heritage folder contains the ‘heritage’, ‘timeline’, ‘artefacts’, and ‘game' views for the heritage, timeline, artefacts, and game pages, the nameseat folder contains the ‘nameseat’, ‘seatmap’, and ‘requestseat’ views for the name seat, seat map, and request seat pages, the info folder contains the ‘info’, ‘map’, and ‘contact’ views for the information, map, and contact us pages, the account folder contains the ‘account’, and ‘userimg’ views for the account, and upload profile image pages, the auth folder contains the ‘signin’, and ‘signup’ views for the sign in and out pages. The email folder contains several folders again, similar to the mobile folder, including a templates folder, the ‘default’ view is used for the content of emails. The web folder contains several folders again, similar to both the mobile and email folders, these views are used for the admin pages.

It is important to use encryption for the authentication, ideally our web-app would be using an SSL certificate to allow HTTPS connections. We do encrypt all passwords using 2 layers of security; the SHA-2 512-bit hash and a randomly generated salt, every users salt is randomly generated.

The media folder located at ~media contains all the uploaded media such as films and events posters, promos, trailers, and trailer placeholders.

The resources folder located at ~resources contains all the JavaScript, CSS, and static images.

We’ve configured CodeIgniter not to set a base URL so that it can be easily moved to a different URL without requiring a configuration change, we’ve also configured it to use the shorthand ‘rsc’ (Regent Street Cinema’) as a cookie prefix to prevent possible clashes, and to use the ‘sessions’ table in the database to store and verify users session data.

MySQL Database

We used database schema to store non-static data into tables, this allows data (for example; films and events) to be added, edited, and deleted easily whilst keeping the existing page code.

Our database model includes ten tables with relationships between specific tables. The ‘filmsevents’ table contains all the films and events including their title, description, and poster and promo media locations. The ‘filmevent_types’ table contains the film and event types to distinguish between a film or an event. The ‘film_trailers’ table contains all the films or events’ trailers and trailer placeholders media locations. The ‘filmevent_times’ table contains all the films or events’ dates and times, a film or event can have multiple film or event times. The ‘users’ table contains all the users including their full name, email subscriptions, profile image location,and password. The ‘emails’ table contains all the users’ email addresses, a user can have multiple email addresses. The ‘booked_filmsevents’ table contains all the booked tickets and Stripe token IDs, a film or event time and a user can have multiple booked tickets. The ‘favorite_rels’ table contains the users’ favourite films and events. The ‘sessions’ table contains users session data. The ‘email_verification’ table has not been implemented, but contains the users’ email verification codes.

Stripe Checkout API

We used the Stripe Checkout payment gateway to complete the transactions of booking tickets, which requires the use of the Stripe Checkout API, we check if the transaction was successful and then store the successful transactions’s Stripe token ID. This would allow us to get data for the transaction, such as the transaction type (card or bank account), and card or bank account data.

API

We created a basic Application Programming Interface (API) to be used with our custom JavaScript. Our custom API is location at ~application/controllers/api.php.

The ‘Favourites API’ has 4 resources; ‘add’, ‘remove’, ‘subscribe’, and ‘unsubscribe’. The ‘add’ resource adds a film or event to the user’s favourites, a film or event ID is required, it then inserts the user’s ID and film or event ID into the ‘favorite_rels’ table in the database. The ‘remove’ resource removes a film or event from the user’s favourites, a film or event ID is required, it then removes the user’s ID and film or event ID from the ‘favorite_rels’ table in the database. The ‘subscribe’ resource subscribes a user to the favourites emails, it sets the favourites column to 1 and inserts it into the ‘users’ table in the database. The ‘unsubscribe’ resource unsubscribes a user to the favourites emails, it sets the favourites column to 0 and inserts it into the ‘users’ table in the database.

The ‘Films and events API’ has 2 resources; ‘filmeventtimeshtml’, and ‘pay’. The ‘filmeventtimeshtml’ resource returns film or event times HTML, a film or event ID and date are required, it then gets the relevant film or event times from the ‘filmevent_times’ table in the database, the HTML is for the book tickets page. The ‘pay’ resource pays for a booking of a film or event, a Stripe token ID, film or event ID, date and time, and quantities are required, it then inserts the film or event time ID, user ID, quantities, price, and Stripe token ID into the ‘booked_filmsevents’ table in the database, and emails the user a receipt email and a ticket email.

The ‘Game API’ has 1 resource; ‘set’. The ‘set’ resource sets a cookie for the game which unlocks content throughout the heritage section, a question ID is required.

The ‘Newsletter API’ has 2 resources: ‘subscribe’, and ‘unsubscribe’. The ‘subscribe’ resource subscribes a user to the newsletter emails, it sets the newsletter column to 1 and inserts it into the ‘users’ table in the database. The ‘unsubscribe’ resource unsubscribes a user from the newsletter emails, it sets the newsletter column to 0 and inserts it into the ‘users’ table in the database.

All the APIs return JSON data with success as true if successful or a 404 status error, except the ‘pay’ resource which returns JSON data with success as true, and the booked film or event ID if successful or a 404 status error, and except the HTML resource which returns HTML or a 404 status error.

User Experience

Admin

The admin section is available to administrators users only. It allows administrators to add, edit, and delete films and events, times, and trailers, and send users newsletter and favourite emails.

Accessibility

Our web-app is natively accessible, allowing users with disabilities to use the iOS devices native Accessibility features to enhance their experience.

Native Integration

Passbook integration would allow users to view their booked films and events tickets using Passbook, utilising the iOS’ native Passbook feature; the user is able to add their booked films and events tickets directly to Passbook. Unfortunately adding Passbook integration requires an iOS Developer Program membership, so we were unable to utilise this feature.

Calendar integration would allow users to view their booked films and events dates and times using Calendar, utilising the iOS’ Calendar app; the user is able to add their booked films and events directly to the Calendar app. Unfortunately we did not have time to include Calendar integration, but feel it is a feature we would have liked to include to bridge the gap between web-app and native app.