PageRenderTime 32ms CodeModel.GetById 36ms RepoModel.GetById 31ms app.codeStats 0ms

/Assessment_Three/Coursework_3_LaTeX/Chapters/Chapter05.tex

https://github.com/bergmannf/hw_spas10
LaTeX | 205 lines | 144 code | 56 blank | 5 comment | 0 complexity | f4a16f3d15deb15d024bb20c5c11c19a MD5 | raw file
  1. %************************************************
  2. \chapter{Developer Guide}\label{ch:developer_guide} % $\mathbb{ZNR}$
  3. %************************************************
  4. This chapter will guide the reader through the different requirements and their implementation in the application.
  5. Having finished with the requirements a section highlighting certain special cases that were encountered during the development will be described.
  6. \section{Implementation of the requirements}
  7. \label{sec:implementation_requirements}
  8. \subsection{Homepage-Requirements}
  9. \label{subsec:homepage_requirements}
  10. The requirements under the \texttt{HO}-label were fulfilled in the following manner:
  11. \subsubsection{Provide a login}
  12. The graphical representation of the login is provided in the \texttt{login\_form.inc.php} file, whereas the login-logic (the checking of the username and password) is provided via the \texttt{login.inc.php} file.
  13. This way the developer can reuse the login form by including the \texttt{login\_form.inc.php}-file and the page the form will redirect to in it's form field must implement the \texttt{login.inc.php} as well.
  14. In the current representation of the web page this page is the index page:
  15. \begin{lstlisting}[caption=Redirecting the login\_form.inc.php to the index page]
  16. <form action="index.php" method="post" accept-charset="utf-8">
  17. \end{lstlisting}
  18. \subsection{Restrict access to logged-in users}
  19. This feature is provided in the \texttt{config.inc.php}-file by declaring the function \texttt{redirect\_invalid\_users()}:
  20. \begin{lstlisting}[caption=Redirecting invalid users]
  21. function redirect_invalid_user($check = 'user', $destination = 'index.php', $protocol = 'http://') {
  22. if (!isset($_SESSION[$check])) {
  23. $url = $protocol . BASE_URL . $destination . '?invalid=true';
  24. header("Location:$url");
  25. exit();
  26. }
  27. }
  28. \end{lstlisting}
  29. %$
  30. This function checks if a user is already saved in the Session and will only allow user's where this is the case to proceed. The session-variable is set in the function that checks the login.
  31. \subsection{Provide a link to the search request}
  32. This requirements is fulfilled by providing a header via the \texttt{header.php} file that provides links to the major pages.
  33. \subsection{Show user details after logging in}
  34. This requirements is fulfilled by a call to the header function with the \texttt{customer\_details.php} file as destination, after a successful login.
  35. \section{Search requirements}
  36. The search requirements were fulfilled in the following manner:
  37. \subsection{Search functionality}
  38. The search functionality is provided via two files: the form to enter the possible values is declared in the \texttt{products.php} file, whereas the real search function is declared in the \texttt{database.inc.php} file.
  39. The search function is declared in the database file, as it relies heavily on SQL to perform the search.
  40. Therefore an appropriate string is concatenated that represents the desired search:
  41. \begin{lstlisting}[caption=The search function]
  42. function search_items($search, $category=null) {
  43. global $dbc;
  44. $items = array();
  45. $query;
  46. if (isset($category)) {
  47. $query = "SELECT i.I_ID, i.I_TITLE, i.I_A_ID, i.I_PUBLISHER, i.I_SUBJECT, i.I_COST, i.I_STOCK FROM items i, authors a WHERE I_A_ID = A_ID AND ";
  48. switch ($category) {
  49. case 'Title':
  50. $query.= "i.I_TITLE like '%$search%'";
  51. break;
  52. case 'Author':
  53. $query.= "a.A_FNAME like '%$search%' OR a.A_LNAME like '%$search%'";
  54. break;
  55. case 'Publisher':
  56. $query.= "i.I_PUBLISHER like '%$search%'";
  57. break;
  58. case 'Topic':
  59. $query.= "i.I_SUBJECT like '%$search%'";
  60. break;
  61. default:
  62. $query = "SELECT DISTINCT i.I_ID, i.I_TITLE, i.I_A_ID, i.I_PUBLISHER, i.I_SUBJECT, i.I_COST, i.I_STOCK FROM items i, authors a WHERE I_A_ID = A_ID AND ";
  63. $query .= "i.I_TITLE like '%$search%' OR i.I_PUBLISHER like '%$search%' OR i.I_SUBJECT like '%$search%' OR a.A_FNAME like '%$search%' OR a.A_LNAME like '%$search%'";
  64. }
  65. } else {
  66. $query = "SELECT DISTINCT i.I_ID, i.I_TITLE, i.I_A_ID, i.I_PUBLISHER, i.I_SUBJECT, i.I_COST, i.I_STOCK FROM items i, authors a WHERE I_A_ID = A_ID AND I_A_ID = A_ID AND ";
  67. $query .= "i.I_TITLE like '%$search%' OR i.I_PUBLISHER like '%$search%' OR i.I_SUBJECT like '%$search%' OR a.A_FNAME like '%$search%' OR a.A_LNAME like '%$search%'";
  68. }
  69. $result = mysqli_query($dbc, $query);
  70. while ($row = $result->fetch_row()) {
  71. $itemId = $row[0];
  72. $quantity = 0;
  73. $title = $row[1];
  74. $authorId = $row[2];
  75. $publisher = $row[3];
  76. $subject = $row[4];
  77. $cost = $row[5];
  78. $stock = $row[6];
  79. $item = new Item($itemId, $quantity, $title, $authorId, $publisher, $subject, $cost, $stock);
  80. array_push($items, $item);
  81. }
  82. return $items;
  83. }
  84. \end{lstlisting}
  85. This search either just compares one attribute (or two in the case of the author) depending on the category, or it tries to find the provided string in all fields.
  86. \subsection{Links}
  87. The links are provided via the header from the \texttt{header.php} file.
  88. \section{Product requirements}
  89. \label{sec:product_requirements}
  90. \subsection{Display product details}
  91. The product details are displayed via the \texttt{product\_details.php} file that queries the database via the \texttt{database.inc.php} file and the \texttt{id} that was provided from the search form via \texttt{GET}-request.
  92. After that the website is created.
  93. \subsection{Provide links}
  94. The links are provided via the header from the \texttt{header.php} file.
  95. \section{Shopping cart requirements}
  96. The shopping cart requirements were implemented slightly different than requested:
  97. \subsection{Updating of already present items}
  98. This functionality is provided by the \texttt{shopping\_cart.php} file.
  99. It declares a form in every line of the table that will allow the user to either delete an item or edit it's quantity:
  100. \begin{lstlisting}[caption=Shopping cart form for editing an existing item.]
  101. <form action="" method="post" accept-charset="utf-8">
  102. <input type="text" <?php echo 'name="quantity" id="quantity" value="' . $value->quantity . '"'; ?>/>
  103. <button type="submit" <?php echo 'name="delete" id="delete" value="' . $value->itemId . '"'; ?>><img src="images/shopping-basket--minus.png"/> Delete</button>
  104. <button type="submit" <?php echo 'name="edit" id="edit" value="' . $value->itemId . '"'; ?>><img src="images/shopping-basket--pencil.png"/> Edit</button>
  105. </form>
  106. \end{lstlisting}
  107. % $
  108. As can be seen the form will call the same page again.
  109. The page will then determine if it was called via a \texttt{POST}-request and, if this is the case, perform the specified action depending on the button that was pressed.
  110. As can be seen from the form, the affected item will be determined via the button's value.
  111. \subsection{Adding items}
  112. While implementing the shopping cart the approach to allow a user to add items from the shopping cart page seemed counter-intuitive.
  113. Well known sites like \url{http://www.amazon.co.uk} only allow the addition of item's from the search.
  114. As this seemed a reasonable approach it was copied - why would a user go to the shopping cart to add new items?
  115. \subsection{Provide links}
  116. The links are provided via the header from the \texttt{header.php} file.
  117. \section{Details of the implementation}
  118. \label{sec:details_implementation}
  119. \subsection{Modularity}
  120. While implementing the bookstore a \texttt{modular} approach was taken to minimise the repetition of code.
  121. Therefore many files are includes: for example the header, footer and sidebar of every web page are implemented in one php file that is included in the page (\texttt{footer.php, sidebar.php, header.php}).
  122. Moreover a central file included by every page was created that holds all information that needs to be accessible to all pages (e.g. access to the database). This file is called \texttt{config.inc.php} and can be seen in the appendix.
  123. In this file a variable is defined (\$live) that decides whether whole error-messages are printed or just a short error-notice. Upon releasing the bookstore this variable should be set to \texttt{true}.
  124. \subsection{Form functions}
  125. Apart from this the \texttt{form\_functions.inc.php} file provides a convenience function to create form elements of the type \texttt{text} or \texttt{password}. This way standard form elements can be created easily and with reliable error-handling. Only a reference to an array where errors can be stored in needs to be provided.
  126. \begin{lstlisting}
  127. function create_form_input($name, $type, $errors) {
  128. $value = null;
  129. if (isset($_POST[$name])) {
  130. $value = $_POST[$name];
  131. if ($value && get_magic_quotes_gpc()) {
  132. $value = stripslashes($value);
  133. }
  134. }
  135. if ($type == 'text' || $type == 'password') {
  136. echo '<input type="' . $type . '"name="' . $name . '"id="' . $name . '"';
  137. }
  138. if ($value) {
  139. echo 'value="' . htmlspecialchars($value) . '"';
  140. }
  141. if (array_key_exists($name, $errors)) {
  142. echo '/><span class="error">'. $errors[$name] . '</span>';
  143. } else {
  144. echo '/>';
  145. }
  146. }
  147. \end{lstlisting}
  148. %$
  149. Moreover nearly every form is handled on the same page it is declared on (except the displaying of product details): this approach allows the function that creates the form elements to reuse values in the POST variable, if they are present. This way the form remembers the old input, but will still display the error-messages.