\chapter{Problems}
\section{WMOTU Games}
Our company, WMOTU (Web Masters Of The Universe), has decided to enter the online computer game sales business. Plan and develop the the web site using most of the material covered in sections \ref{HTML5} and \ref{CSS3}.

\section{WMOTU League}
We have been asked to develop a football league information app.

\subsection{WMOTU League Service}
Develop a script that displays the rank and number of points for a given football club. For instance, \href{\ft WMOTULeagueService/index.php?club=Leverkusen}{\texttt{index.php?club=Leverkusen}} displays the current rank and number of Leverkusen. For now store the club data in an array.

\subsection{WMOTU League}
Develop an app that displays the football results saved in the file \href{\ft WMOTULeague/league.csv}{\texttt{league.csv}}. The result should look like this \href{\ft WMOTULeague/WMOTULeague.png}{screenshot}. Use the PHP functions \href{http://php.net/manual/en/function.file.php}{\texttt{file}} and \href{http://php.net/manual/en/function.explode.php}{\texttt{explode}}.

\section{WMOTU Sorter}
Develop an app (\url{\ft WMOTUSorter}) that offers the user a drop down list to choose from the files \href{\ft WMOTUSorter/testdata1.csv}{\texttt{testdata1.csv}}, \href{\ft WMOTUSorter/testdata2.csv}{\texttt{testdata2.csv}} and \href{\ft WMOTUSorter/testdata3.csv}{\texttt{testdata3.csv}} containing a number of records. After form submission the app displays the records in a table in alphabetical order based on the last name. Use the \href{http://php.net/manual/en/function.usort.php}{\texttt{usort}} and \href{http://php.net/manual/en/function.array-splice.php}{\texttt{array\_splice}} functions.

\section{WMOTU Sub}
Develop the sink the ship game (\url{\ft WMOTUSub}). The sea has a size of 20 by 20. There are 10 ships with sizes from 2 to 5.

\section{WMOTU Mailer}
WMOTU has been asked to develop a web mailing app.
 
\subsection{WMOTU Mailer v1}
Develop a web app (\url{\ft WMOTUMailerv1}) to send an email. Sender, recipient, subject and message are provided by the user. The email gets only submitted if all fields are filled in (no data validation).

\subsection{WMOTU Mailer v1++}
For aspiring WMOTUs: What is the problem with WMOTUMailer v1? Come up with a solution  (\url{\ft WMOTUMailerv1++})!

\subsection{WMOTU Mailer v2}
Enhance WMOTUMailer by storing all emails sent in a MySQL database and displaying the current number of emails sent.

\subsection{WMOTU Mailer v3}
Further enhance WMOTUMailer by adding sign up and login functionality. Only registered users can send email. The registration includes the user's email address, which is filled in as the sender by default. The user name is displayed.

\subsection{WMOTU Mailer v4}
A user can get a listing of all their emails, sorted by date (the newest one at the top). He/she can read and delete each one. Our client also wants a good looking and user-friendly interface.

\subsection{WMOTU Mailer v5}
A user can upload an avatar that is displayed next to the user name. Before the email gets sent, an in-depth data validation is performed.

\pagebreak 
\section{WMOTU Quack}
Impressed by our performance on the mailer problem, our customer has tasked us with the development of a full fledged social network.

\subsection{Security}
Create a \texttt{protected} folder that is secured as explained in \ref{Security}.

\subsection{DB}
Create a SQL script named \texttt{createDB.sql} that creates the table named \texttt{WMOTUQuack\_users} to store the following fields:
\begin{enumerate}
\item \verb|id|: primary key, positive, automatically incremented
\item \verb|first_name|: maximum 40 characters.
\item \verb|last_name|: maximum 40 characters.
\item \verb|email_address|: maximum 255 characters.
\item \verb|user_name|: maximum 32 characters.
\item \verb|password|: maximum 40 characters.
\item \verb|activated|: indicates whether a user is activated, i.e. has clicked on the validation link.
\item \verb|description|: long text.
\item \verb|last_time_seen|: the current time stamp (see \url{http://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html}). The data type to be used is \verb|TIMESTAMP|, the default value is \verb|CURRENT_TIMESTAMP|.
\end{enumerate}
If the table already exists it is first deleted and then created. The DB engine is set to \texttt{INNODB}. The user name needs to be unique. Only the description can be empty.

Add an instruction to insert test data into the table.
Execute the script (remember that this is very easy to do with PhpStorm (cf. \ref{PHPSTORMDBScript})) and verify that the database has been created correctly. Where do you save your script? Why?

\subsection{\texttt{db\_credentials.php}}
Create the \texttt{db\_credentials.php} file (cf. \ref{db_credentials}). In this file we call the static \texttt{set\_credentials} method in the \texttt{Database} class, which we'll create in the next subsection (cf. \ref{db_credentials}).

\subsection{\texttt{database.php}}
Create class \texttt{Database} in the file \texttt{database.php}. For efficiency reasons \textbf{all properties and methods of this class are static}, which means that we do not need to create an object of this class. Study \ref{PHPObjects} and \ref{WMOTUDB}.

\subsubsection{Constants}
Define the constants \verb|$DB_HOST|, \verb|$DB_USER|, \verb|$DB_PASSWORD|, \verb|$DB_NAME|, \verb|$DB_USER_TABLE| and \verb|$DB_LOGGEDIN_USER_TABLE|. These constants are all private to the class.
Assign the correct values to \verb|$DB_USER_TABLE| and \verb|$DB_LOGGEDIN_USER_TABLE|. The other constants will get their values from the method \verb|set_credentials| that we'll create in the next step. 

\subsubsection{\texttt{set\_credentials}}
Create the method \texttt{set\_credentials}, which sets the values of the \verb|$DB_HOST|, \verb|$DB_USER|, \verb|$DB_PASSWORD| and \verb|$DB_NAME| constants (cf. \ref{WMOTUDB}).

\subsubsection{\texttt{connect}}
Create the method \texttt{connect}, which creates a connection to the DB and returns the connection handle. We set the character set of the connection to \texttt{utf8}.
 
\subsubsection{\texttt{get\_user\_id}}
Create the method \texttt{get\_user\_id}, which returns the user id for a given user name, or \texttt{FALSE} if such a user does not exist.

\subsubsection{\texttt{get\_user\_name}}
Create the method \texttt{get\_user\_name}, which returns the user name for a given user id, or \texttt{FALSE} if such an id does not exist.

\subsubsection{\texttt{get\_user\_data}}
Create the method \texttt{get\_user\_data}, which returns the user name and description for a given user id as an associative array, or \texttt{FALSE} if such an id does not exist.

\subsubsection{\texttt{get\_users}}
Create the method \texttt{get\_users}, which returns an associate array containing all data for all users or \texttt{FALSE} if no users exist.

\subsubsection{\texttt{get\_description}}
Create the method \texttt{get\_description}, which returns the description for a given user id, or \texttt{FALSE} if such an id does not exist.

\subsubsection{\texttt{update\_description}}
Create the method \texttt{update\_description}, which updates the description for a given user id. The method returns \texttt{FALSE} if something went wrong, for instance if such an id does not exist, otherwise \verb|TRUE|.

\subsubsection{\texttt{is\_logged\_in}}
Create the method \texttt{is\_logged\_in}, which returns \texttt{TRUE} if the user with a given user id has a time stamp that is not older than 2 seconds. Use the \verb|UNIX_TIMESTAMP| function (cf. \url{http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_unix-timestamp}) to convert \verb|last_time_seen| and then compare it to the current time in PHP using the \verb|time| function (cf. \url{http://www.php.net/manual/en/function.time.php}). If the time stamp is older than 2 seconds, the method returns \texttt{FALSE}. In the main script, we'll install a timer that updates the user's time stamp every 2 seconds. This will allow us to monitor in near real time who is logged in and who is not.

\subsubsection{\texttt{update\_login\_timestamp}}
Create the method \texttt{update\_login\_timestamp}, which sets \verb|last_time_seen| to the current time for the user with a given id. Use the MySQL function \verb|NOW| (cf. \url{http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_now}). The method returns \verb|TRUE| if the update succeeded, otherwise \verb|FALSE|.

\subsubsection{\texttt{register\_login}}
Create the method \texttt{register\_login}, which first checks whether a user with a given id is already logged in, in which case \texttt{FALSE} is returned. Otherwise, the method updates the user's time stamp and returns the result of this update.

\subsubsection{\texttt{login}}
Create the method \texttt{login}, which registers the login and returns the user id if a user with a given name and password exists in the user table and is activated, otherwise FALSE.

\subsubsection{\texttt{activate\_user}}
Create the method \texttt{activate\_user}, which activates the user with a given id and returns the result of the operation.

\subsubsection{\texttt{create\_user}}
Create the method \texttt{create\_user}, which creates a user with the given first name, last name, email, user name and password. Leading and trailing spaces are removed from all parameters except the password. The password is stored in encrypted form using the \texttt{SHA1} function of MySQL (cf. \url{http://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_sha1}). The method returns the user id or \texttt{FALSE}.

\subsubsection{\texttt{delete\_user}}
Create the method \texttt{delete\_user}, which deletes the user with the given id. The method returns TRUE if the operation succeeded, otherwise \texttt{FALSE}.

%\subsubsection{title}



\subsection{\texttt{index.php}}
Develop the login and sign up page. You can use the HTML and CSS from the original. The following features need to be implemented:
\begin{enumerate}
\item Session IDs may only be passed via cookies, not appended to URLs.
\item The path for the cookie is set to the current directory in order to prevent it from being available to scripts in other directories.
\item In this particular case, we do NOT use SSL, as the SSL certificate on Foxi is currently not accessible from PHP, which prevents the WebSocket server from being able to use SSL.
\item If no session is currently started, we start one.
\item After 30 seconds we'll generate a new session ID to prevent a session fixation attack (cf. PHP Cookbook p. 338).
\item If a user is already logged in, we let him through to \texttt{main.php}.
\item Else, if the user has submitted his login details, we need to check them. If the check fails, we go to \texttt{index.php}. If a user with these credentials exists, we set the session data and go to the main page.
\item Else, if the user has submitted the sign up form, we need to make sure that a password has been entered. We also have to check the CAPTCHA and the user name. If the user name already exists, we create an alert informing the user and stop the script. Otherwise, we validate the email address (cf. \ref{EmailValidation}). If the email address is invalid, we go to \texttt{index.php}. Otherwise, we create the new user and send a validation email. The subject is \verb|Validation email|, the sender is \verb|do_not_reply@ltam.lu| and the body contains the text \texttt{To validate this email address click the following link: http://wsers.foxi.lu/Tutorial/WMOTUQuack/index.php?s=} followed by the email address followed by \verb|&m=| followed by the hash value (using \texttt{md5}) followed by \verb|&i=| followed by the user id multiplied by 5. The hash value is the string \verb|T2IF2| followed by the user's email address. This whole string is then encrypted using the \verb|md5| function of PHP. After sending the email, we display an alert with the text \texttt{A validation email has been sent. Please check your inbox.} and stop the script.
\item Else, if a user has clicked on the link in the validation email that was sent during sign up, we check whether the email address corresponds to the hash value. If that's the case, we activate the user. We retrieve the user name. If it exists, we create a directory \texttt{protected/users/} followed by the user name. Then we set the directory permissions so that the owner and group have full rights and others have none. We then go to \texttt{index.php}.
\item Else, we generate the CAPTCHA. We use the font \texttt{Jumpman} (cf. \url{http://www.dafont.com/jumpman.font}). The CAPTCHA generation is based on pages 613-614 of "Head First PHP \& MySQL". It has however been adapted in order to display a simple calculation that the user has to perform to prove his or her humanness. For this purpose, we generate two random numbers \verb|$num1| and \verb|$num2|, each between 0 and 9. We then create an array \verb|$ops| with the following operators: \verb|+|, \verb|-| and \verb|*| stored as characters. Now we choose a random number \verb|$op| between 0 and 2. The pass phrase will then be \verb|$num1 . $ops[$op] . $num2|. The result of the calculation needs to be stored in the session, which can be done like this:

\begin{scriptsize}
\begin{minted}[tabsize=2, linenos=true, startinline=true]{php}
$_SESSION['pass_phrase'] = eval("return intval($pass_phrase);");
\end{minted}
\end{scriptsize}
The approach chosen in the book, to send the image via a header, did not work for me, so I used the \texttt{imagepng} function to save the image on disk from where the HTML document retrieves it in the \texttt{img} tag.
\end{enumerate}

\subsection{\texttt{main.php}}
You can use the HTML, CSS and JavaScript from the original.
The following features need to be implemented:
\begin{enumerate}
\item The bouncer needs to be included to prevent unauthorized usage of our app. 
\item We need our DB class.
\item Behind the \verb|Logout| text we display the user name of the logged in user.
\item We need to store the user id of the currently logged in user in a JavaScript variable named \verb|userId| and the user name in a variable named \verb|userName|. These two variables are used by \verb|websocket.js|.
\item In the profile section we display the description of the user. Be careful not to display inexisting spaces!
\end{enumerate}

\subsection{\texttt{logout.php}}
The script performs the following steps:
\begin{enumerate}
\item If no session is started we start one.
\item We delete the session array.
\item If a session ID exists we expire the session cookie.
\item We destroy the session.
\item we send the browser to the login page.
\end{enumerate}

\subsection{\texttt{updatedescription.php}}
The script is executed when the user clicks the \verb|Update description| link and performs the following steps:
\begin{enumerate}
\item We include the bouncer.
\item We need the DB class.
\item We update the description with the user id stored in the session and the description submitted by the \verb|updateDescription| function in the \verb|main| object in \verb|main.js|. 
\end{enumerate}

\subsection{\texttt{deleteprofile.php}}
The script is executed when the user clicks the \verb|Delete profile| link and performs the following steps:
\begin{enumerate}
\item We include the bouncer.
\item We need the DB class.
\item We delete the user from the DB.
\item We delete the user directory with all sub directories using the following code:
%{\scriptsize\inputminted[tabsize=2, linenos=true]{php}{includes/deleteprofile.php}}
\begin{scriptsize}
\begin{minted}[tabsize=2, linenos=true, startinline=true]{php}
$dir_path = "./protected/users/{$_SESSION['user_name']}";
#http://stackoverflow.com/questions/1407338/a-recursive-remove-directory-function-for-php
try {
	foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir_path,
		FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
		$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
	}
	rmdir($dir_path);
} catch (Exception $e) {
}
\end{minted}
\end{scriptsize}
\item We send the browser to the logout script.
\end{enumerate}

\subsection{\texttt{deleteprofileimage.php}}
The script is executed when the user clicks the \verb|Delete image| link and performs the following steps:
\begin{enumerate}
\item We include the bouncer.
\item We delete the file using the following code:
%{\scriptsize\inputminted[tabsize=2, linenos=true]{php}{includes/deleteprofileimage.php}}
\begin{scriptsize}
\begin{minted}[tabsize=2, linenos=true, startinline=true]{php}
$file_path = '';
	$dir_path = "./protected/users/{$_SESSION['user_name']}";
	try { # Run through all files in the directory. This primitive approach is good for now.
		foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir_path,
			FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
			if ($path->isFile()) $file_path = $path->getPathname();
		}
	} catch (Exception $e) {
	}
	if ($file_path !== '') unlink($file_path);
\end{minted}
\end{scriptsize}
\end{enumerate}

\subsection{\texttt{getprofileimage.php}}
The script is executed when the user clicks the \verb|Delete image| link and when the \verb|Members| button is activated. It performs the following steps:
\begin{enumerate}
\item We include the bouncer.
\item We declare a variable \verb|$file_path| and initialize it with an empty string.
\item If the user name has been transmitted via \verb|GET| we set \verb|$dir_path| to \verb|./protected/users/{$_GET['user_name']}|, else we set \verb|$dir_path| to \verb|./protected/users/{$_SESSION['user_name']}|.
\item We run through all the files in \verb|$dir_path| and save the path of the last one in \verb|$file_path|.
\item We tell the browser that we will now be sending a png image.
\item If the file path is not empty we read the file.
\end{enumerate}

\subsection{\texttt{getmember.php}}
The script is executed when the \verb|Profile| button is activated. It performs the following steps:
\begin{enumerate}
\item We include the bouncer.
\item We need the DB class.
\item We declare the variable \verb|$output| and initialize it with an empty string.
\item If the user id has been submitted via \verb|POST|, we get the user data. If this data exists, we
\begin{enumerate}
\item build a string with a paragraph containing the user name,
\item followed by an image with the profile image,
\sloppy\item followed by
\begin{scriptsize}
\begin{minted}[tabsize=2, startinline=true]{html}
draggable=false onmousedown="event.preventDefault(); alt="",
\end{minted}
\end{scriptsize}
\item followed by a new line,
\item followed by a new paragraph with as preformatted content the user's description.
\end{enumerate}
\item We send the string to the browser.
\end{enumerate}
