Class Checkpoint

Making Parkwood Vale · Part 13 of 13

Part 12

Finish the library: reserve and return books, with emails and a loans page.

We complete the loans system. Users can reserve a book, see their loans and return it, and the number of copies available stays correct. In this part: 0:00 The plan for loans 0:34 The browse page, filtered by author or publisher 8:49 The book details page and its Reserve button 13:02 Reserving: adding a loan with a due date 7 days later 22:03 Reducing the number of copies available 27:32 A confirmation email with PHPMailer 34:39 The loans page, using JOIN queries 40:55 Returning a book and sending a thank you email 47:38 Outstanding and returned loans in Bootstrap tabs Software: Adobe Dreamweaver, UwAmp, HeidiSQL, PHP, MySQL, PHPMailer, Bootstrap.
Transcript
  1. Okay, in this session then we're going to look at how we set up the loaning ability
  2. within our library system. We're going to look at how people can reserve a book, how
  3. they can publicly browse through all of the books held in our library currently, and
  4. how they can return the book as well, making sure that when they loan a book out and
  5. when they return the book, it affects the number of available copies stored within
  6. our database.
  7. Okay, let's get into it.
  8. Okay, so here I am back in my student desktop and this one's going to be a little
  9. bit of a Blue Peter style session because here is what I was working
  10. on earlier.
  11. Now, I've actually recorded this on the Monday where I usually record on a
  12. Sunday because I wasn't too well over the weekend so I wanted to make sure all of
  13. that was clear out before I tried to record anything.
  14. I've just set up UwAmp, I've launched UwAmp, it's just starting, my local host has
  15. just come into life and Apache has stopped for a second, let me just stop that
  16. entirely and find out why
  17. just simply cycling, there you go, up and running, both sides are running and now
  18. local host should pick up
  19. eventually, there we go So what I did earlier in preparation for the session was I
  20. built this Browse Book system.
  21. Now if I very quickly jump onto Parkwood Vale, you'll see that the Browse Book
  22. system has a similar sort of layout.
  23. Again, it's not identical to it because there are some subtle differences, but where
  24. I clicked on Andy Weir, and I can close off Andy Weir, Dan Brown, close off Dan
  25. Brown, it is a similar system.
  26. So Andy Weir, I can clear the Andy Weir, I can go Bloomsbury Publishing, I can clear
  27. Bloomsbury, I can go Dennis Taylor, all that same sort of functionality.
  28. Now I'm going to show you the code I use within this functionality and talk you
  29. through it, but unlike in previous sections, I'm not going to code it live in front
  30. of you, just to speed up time ever so slightly.
  31. I also created this section here, where I could go in and see all the details about
  32. a book. I can go back to browse books.
  33. Let's go for one with a bit more details and you can see those details in place.
  34. I can log in. So that's my usual CPD
  35. password system. Submit it. Now if
  36. I'm browsing books and I'm clicking onto there now, I can reserve that book.
  37. If I click on reserve at the moment, it doesn't do anything.
  38. That's the part I've left ready to work on this session.
  39. So let's get Dreamweaver open and have a look at what it is I did
  40. earlier today.
  41. If I minimize this out then and I scroll down the first thing we're going to look at
  42. is the browse book page which was on my testing server let's grab that from
  43. there browse book and let's pull that
  44. down and do the same for book and I also put in a loan system so
  45. let's get loans as well and return to my local view
  46. now I'm on ad book there let's get rid of these close these previous session
  47. elements out so they don't confuse us and open up the browse book page
  48. I'm going to zoom out a little bit just so we can see everything and take you
  49. through what it's all doing so to start with at the top I create my PHP tag I
  50. include my header tag I don't need any session details at the moment because this
  51. page can be open to anybody. It would create a session within my header anyway but
  52. that's by the by. I've got my book SQL code here which says select star which
  53. just means everything from my books table.
  54. I've got my author SQL which is select a distinct author.
  55. Now what that distinct command will do is it'll make sure that when it pulls back
  56. all of the authors it only pulls back unique records
  57. so if I was to look back on here a second browse books if I go on to
  58. the JK Rowling page even though she is there twice it only
  59. brings back one element for her on this side here same goes with Bloomsbury
  60. Publishing it publishes both the Harry Potter books but only appears in my list once
  61. that is through that distinct command.
  62. I've done the same thing then for publisher, using the distinct command there and
  63. set that from books. Now, I've included two elements to check
  64. if author is in get or if publisher is in get.
  65. If author is set in our get, so that's in that URL field across the top there, what
  66. we want to do is a query where the author is what's in our get command.
  67. Same goes for our books all three of these are repeated to make sure we've got those
  68. in place saying those are a publisher there so I could say publisher and include
  69. those elements now the final part of PHP in this section is looking
  70. at our books doing our connection and bringing that query back based around the SQL
  71. statements we have there I then use the same layout the container the
  72. mb4 class background for my color a class p4 here for my
  73. spacing for my padding and then a div row in place
  74. inside my div row i've got my call md3 with the title of author where it says if
  75. author isn't null give me the ability to clear which takes me back to browse books
  76. same happens here for if
  77. publisher isn't doesn't equal null then give me the clear in the publisher section
  78. and give me
  79. I've got a while loop two or three while loops in this section actually all of them
  80. use row as the
  81. container their variable container but the first one is for author fetch associate
  82. and all it does is echo out a a href giving our author code
  83. as an encoded URL and then that goes out the name of that author same process
  84. here for publisher and we don't need this a second let me jump that aside can see
  85. here I have while row equals publisher fetch associated rows publisher itself they
  86. come in from this publisher command up there don't want to go too quick for anybody
  87. and I've got while each publisher in the fetch associated array in row
  88. looped through so if there's only one publisher it'll only do it once if there's 10
  89. it'll do it 10 times however many you've got in place it sets up an ahref that
  90. goes back to our standard page of browse books with publisher and it echoes out that
  91. URL encoded publishing it. Remember that URL encoding is important for situations
  92. where we have Bloomsbury Space Publishing,
  93. HarperCollins Space UK,
  94. J.R.R. Tolkien. Again, that would be important to make sure that when we
  95. put that in, it sets up our percentage 20% across the top here to
  96. search through our database correctly.
  97. That's all done with our URL encoded section.
  98. Now that section there, that div call MD3 is my sidebar in this section here.
  99. That's this section on the side here.
  100. And if I clear that a second, what we're looking at next then is the call MD9,
  101. which is set up for each of the books.
  102. We do include a div of 3 and a div of 9 in their own rows.
  103. One is to provide with my jacket image, set to 100% of its parent container.
  104. And the other just sets up a link to the book, our book page.
  105. And the ISBN is our element there.
  106. Now, I could include URL encode here
  107. just to be on the safe side. It shouldn't
  108. have an issue. It shouldn't be a situation where we need URL encode because there
  109. shouldn't be any spaces in our ISBNs.
  110. But depending on what your identifiers are, it may be a different situation.
  111. Now, as you go through, you've got the name being echoed out there.
  112. You've got the author, publisher, and description.
  113. And if I come over here, we have the name as our link, which if I hover over it down
  114. in the bottom corner, you can see the ISBN,
  115. the author, the publisher, and the description.
  116. Obviously, with the real books, we have a better description because we took that
  117. directly from Google during our section about APIs.
  118. Now, if I click onto Ready Player One, that takes me to my book page with the ISBN
  119. set as bar number across the top there.
  120. On my PHP side of things, then, so if I save that a second and close that and open
  121. up my book page, it's very similar in code.
  122. At the moment, it has an empty post section here.
  123. that's purely in place ready for what we're going to do tonight and then we've got
  124. our connection query here saying select all the information so again we're selecting
  125. star from books where the isbn is equal to what's in our get command here
  126. and then i've taken the same elements from my previous section
  127. and i've just removed one of my outlines so instead of having a nine by
  128. three and then a 3 by 9 I've simply got the 3 by 9 element in place.
  129. Starting off at the top then we have our div of curl 12 in there it tells
  130. us our row here with a md3 with our jacket image
  131. and just to reiterate and show you that is the same let me zoom back up
  132. same code we have in this bottom section here.
  133. Alongside that then we have the same information echoed out.
  134. The only main difference here is inside this first section
  135. here we have available copies set to the row available copies.
  136. That allows us down in this bottom section then to put in some search facilities.
  137. In these search facilities we have things such as if our session email it
  138. doesn't equal null so there's something in session then check to see if copies is
  139. greater than zero if copies is greater than zero set up our form to reserve the book
  140. if copies is less than zero so we have our else here say sorry the book is not
  141. available please check back and if our session information so that's all that if
  142. else if there if our session information isn't available it then takes us to our
  143. account page to log in and then just ends itself so there's two forms i've
  144. created ready in place to be used today i will show the last one i created as well
  145. which is based around loans now again this has an empty post in place let me just
  146. zoom that back out i will revisit this when it comes to this section and i will also
  147. explain exactly what's going on with this join here because that's a little bit more
  148. complicated
  149. But as we go through, we're just repeating the same process.
  150. We're searching for something, we're calling it loans this time rather than books,
  151. but we're doing the same thing.
  152. A row with a 3 and a 9. The image goes in the 3 with 100% width, and then the
  153. information about the book goes in the 9.
  154. Again, there's no difference realistically between this one and this one, just our
  155. query that we'll be performing.
  156. So what I'm going to do is just very quickly zoom fully out onto this one here.
  157. I know that is quite small, but the idea here is that I'm going to just pause it
  158. here, give you a couple of seconds to look at that code, see what it is I've done.
  159. You can pause the videos yourselves and you can have that on your screens to see
  160. what it is I've done in the different sections.
  161. let's repeat that process then so let's zoom this one out so you can see all of the
  162. code again there's a lot more code on this one so i don't actually think you can see
  163. all of that code so what i'm going to do is just give you a couple of seconds on
  164. this top section now obviously this is going out via youtube so if you want to you
  165. can pause it and then there's the bottom section that's
  166. where we finished so this is all the new stuff that should have been shown
  167. and then this last one here again let's zoom out so you can see
  168. all of that code nice and clearly in place
  169. brilliant so our first step then is going to be on book and it's going to be
  170. capturing this our post which we are posting here, hidden information of ISBN and
  171. email and updating our tables correctly to make sure that we record all of that
  172. information.
  173. I'm just gonna pause ever so slightly there just to make sure that I don't lose any
  174. elements of these recordings, have a quick drink and we'll get back to it in a
  175. couple seconds time.
  176. So what we need to do then at this stage is capture that information that we're
  177. posting back to ourselves in book and use it to update our database.
  178. The part of our database that we're specifically looking to update is our loans
  179. table. So let's just open up hide the SQL a second
  180. and look at what's currently in loans.
  181. My test data from earlier, as I expected it to be.
  182. Now, there is no return date because the book hasn't been returned.
  183. Return is set to zero because it hasn't been returned, but we have in place the same
  184. date and time for our loan. We'll be dealing with that in about five minutes time or
  185. so. What we can see is we have our email and our library ID storing in
  186. our information here. So we want to insert into that table.
  187. So let's go into our SQL, so dollar sign SQL as usual.
  188. And let me just zoom that back in so you can see it nice and clearly.
  189. There we go. And what I want to do is insert into,
  190. and the table is called loans.
  191. and the information I will be inserting isn't limited in any way.
  192. It is going to be email, library ID.
  193. Now let's just double check. I've got that as a capital L.
  194. Sometimes it can be very specific on these things.
  195. Library ID, let's check capital E for email.
  196. Email, library ID, let's go, comma.
  197. We want the loan date. Was it?
  198. Yep.
  199. long date, we want the return date,
  200. and that's about it. The values that we
  201. are going to be passing it are going to be important.
  202. Now I'm going to put a break there, my SQL end there, and what I'm going to do is
  203. simply put a return in here just to make it a little bit easier to deal with.
  204. Now the first thing we're going to be passing through to it is going to come from
  205. post.
  206. dollar sign underscore post and I want to take in email
  207. which has simply come from my hidden information here
  208. in type hidden email there. ISBN is also there I'm going to put that in next.
  209. So email will come first that goes into our email field.
  210. I'm going to put in comma now I'm going to put in again single quotations I'm going
  211. to break out of that PHP into dollar sign underscore post
  212. And in that post section there, then I want ISBN.
  213. Now, those two elements come from what we posted to it.
  214. The next element is going to be working on date time provided by PHP.
  215. So what I'm going to do is put that in place there.
  216. Again, break out of it. And I want to put in date time.
  217. So I simply use the now command
  218. in PHP.
  219. And that should have gone green if it was happy with what we wanted.
  220. Let's just double check.
  221. PHP current date time.
  222. And let's get stack overflow. Always a good starting point.
  223. Let's see. Date time. Time rather than now.
  224. Okay. So I'm quite happy.
  225. Time zone. There we go. Time. Yeah.
  226. that's what we're going to go with i'm going to go into here and simply put that in
  227. this time there i want it as more than just time though because if we look back at
  228. this let's see we want our date time to be set out similar to this
  229. we can specify how we want it laid out so let's go
  230. date and it is going to be this element here
  231. but before it i'm going to tell it how to lay it out
  232. is expecting it as year month day then time so i'm going to say
  233. capital y for year i want let's double check forward
  234. slashes i think it is no it's minor symbol month day
  235. and then we have hours
  236. minutes I believe if I do capital it's
  237. the there we go capitalization should make it double
  238. numbers so 0 7 for 7 o'clock or 19 for 7 p.m and go from
  239. there now I just want to check how that looks a second so I'm going to echo dollar
  240. sign sql and just see what's going on there let's go I'm currently
  241. Let's push that up, jump back into here, and click Reserve.
  242. Now, that has echoed out. Insert into loans.
  243. Now, it's echoing it into this page here, which has no formatting, so I've got to
  244. highlight it to see it. Insert into loans, email, library, loan date and return
  245. date, CPD of Mr. J. Jones, the ISBN, and then the date and time.
  246. Looking how I'd expect it to, which is perfectly fine.
  247. Next up then I want to use date time and I want to say let's say PHP
  248. current date time add seven days
  249. and what I can do
  250. is simply use the string to time function and do seven
  251. days plus so I'm going to steal that little tiny bit of code from there I'm going to
  252. put it into by here and explain what it's doing so
  253. second now this date function i have here if i bring this down onto its own line and
  254. talk you through it what that's saying is i want it to be a date formatted as year
  255. month day hour minute and then i for seconds of the current time
  256. which is brilliant the next one up i want
  257. is going to do a similar function so i'm going to steal this function again
  258. copy that into this section here but instead of having date time as my
  259. current date time i'm going to say i want it to be time
  260. plus seven days
  261. now with all of that in place if i save that and now put that up again
  262. and simply go back here refresh this page yes
  263. continue to resubmit that I now get 2023,
  264. the 7th of the 17th, which is correct.
  265. And then I get 2023, the 24th of the 7th, which is
  266. 7 days on from my current timestamp.
  267. So that allows me to put that in place.
  268. And that would fill in email, loan date, due date, and then return and return date
  269. are empty. What we need to do as well, I need to verify this one, is in our Heidi
  270. SQL section, null return date should allow null if I take this
  271. query then very quickly and just check it's working by running it through Heidi
  272. and click run due date doesn't have a default value okay
  273. let's see did I I did return date my bad it should be due date not return date
  274. due date there we go and if I run that
  275. what happens is when I refresh my table it's now inserted that second ID.
  276. Let's correct our code here then because I said there return date that should be due
  277. date and let's put that in place.
  278. Now if that was to be executed that would
  279. correctly insert that in. I do need to do a $SEN connection,
  280. query and I need to that
  281. there just simply to ensure that happens as well as
  282. ensuring that I'm recording the fact that that's been booked I want to query
  283. and this time I want to update so let's go update
  284. and I want to update the books table I want to set
  285. the available copies so if I go into books a second we have available copies
  286. here i'm going to be extremely lazy and just copy that and say set
  287. available copies equals available copies minus one
  288. so i can already use the information i don't have to go off and find what available
  289. copies are available i can just say take whatever's in available copies remove one
  290. from it and i'm going to say where now let me just capitalize that way because it
  291. should be capitalized and so should set it won't break them not being capitalized
  292. but it's good practice to have them capitalized as a uh let me double check and
  293. believe it's isbn yep isbn equals
  294. equals and i'm going to break out of this
  295. here a couple of full stops and back into it very quickly just there that should be
  296. fine one single quote and one single quote there always difficult putting single
  297. quotes in place it doesn't quite like things I say ISBN here
  298. so what that should do is it should allow me to
  299. record the fact that I've rented that book for a seven day period it should also
  300. allow me to then go through and update it to remove one from those copies.
  301. So the book I'm currently on, if I go back to my loans table, ended in 432.
  302. If I go back onto my books table, 432 has four copies.
  303. Let's just, we'll leave that as it is.
  304. And for a second, I'm going to go back.
  305. There you go. Ready player one, as is there.
  306. Four copies. Refresh that.
  307. Ready player one. Perfect.
  308. If I've done this right, it should load with nothing.
  309. Nothing's being echoed out at the moment, but it should reduce one from there, and
  310. it should add a new record into here.
  311. Just to make this a little bit easier on this side of things, I'm going to remove
  312. both of those records because they're not really needed at the moment, so we can
  313. clearly see if it has inserted that correctly.
  314. Reserve.
  315. It's printed something. That means I didn't press the put up button after I saved
  316. it.
  317. a problem. Save it. Let's put it up.
  318. Now let's try again.
  319. Reserve.
  320. Nothing's been printed. Looking a lot more positive.
  321. Let's refresh this. We have our record added.
  322. And let's go into books and refresh this
  323. it didn't deduct one let's have a look at why
  324. let's take this SQL here then cut it ever so slightly do dollar sign SQL
  325. again equals paste it so we can see what it's doing and put in dollar sign SQL here
  326. put that up and refresh this page
  327. yes continue to submit that information okay nothing's
  328. happening
  329. It helps if you actually echo out what it is you're trying to echo out and
  330. check.
  331. Post.
  332. No. Refresh. Yes. And here's my SQL.
  333. Let's copy that and run it through Heidi and see what Heidi has to say.
  334. Run.
  335. Ah. Very subtle. A little mistake I seem to have made.
  336. I have an open and close, an open and close there.
  337. And what that's caused is an error where it's taken that literally and then put our
  338. number in place. If I was to remove one of those elements and have that go green
  339. like it has done and run it, it updates no problem.
  340. if I go back into here and remove that second one there save it put
  341. it up we don't need to echo it because I'm extremely confident put that up
  342. and let's go back reserve
  343. okay in books for copies now becomes
  344. two okay let's just double check that's not going crazy let's go back one
  345. of course it would be two because they did one through hiding one through that if i
  346. go reserve in here it should now be one and if i go back a page
  347. reserve back a page we are now below zero so it's now telling us that the book
  348. cannot be reserved and to check back in which is brilliant complete functionality
  349. exactly what we wanted to do it is recording into our loans section when we reserved
  350. our book, giving us a month's due date and sending us a no return date, but it's
  351. also setting it up there to reduce that element.
  352. Now what we can do at this point here is steal a little bit of code from our
  353. password reset and I want to include or use our PHP
  354. mailer element. So let's copy that into books, top here,
  355. and I'm going to only use them and only require them if I'm reserving a
  356. book.
  357. And from the password reset, then if I scroll down, I'm actually looking at this try
  358. email section here. So let's zoom out just so we can make sure we don't miss
  359. anything. I want email or mail to equal new PHPMailer.
  360. I can take all of element here, copy it onto here and
  361. underneath this paste it. So it says mail is a new mailer.
  362. It is an SMTP going from a Gmail which is true.
  363. It's going through my Gmail account there which I set up for this demo with that one
  364. -time password. They port elements there.
  365. It's emailing from Parkwood Vale to the post email.
  366. We have used post email so that will all work correctly.
  367. the HTML Parkwood Vale library instead of password reset I'm gonna say book
  368. loan
  369. and all I'm gonna say in the body here is thank you for
  370. loaning a book from us today
  371. and send that if there's an error it's gonna tell
  372. me what the error is so So let's go book a second, let's go up with that information
  373. and I need to change that to a one just so I can actually reserve the book again.
  374. Refresh this, whoops, it doesn't like something on line four.
  375. Why what's on line four?
  376. Use okay, I believe these two because they are essential
  377. they do need to go at the very top there.
  378. save them put that up and refresh
  379. there we go now if I was to reserve this it should send me an
  380. email so let's go reserve it's gone off is it gonna send me an email
  381. let's have a look and
  382. not sure how well this is gonna come up with there but you can should be able to see
  383. in there it does show that I have
  384. from Parkwood Vale saying thank you for learning the book.
  385. It doesn't really tell us any information about the book.
  386. It's a little bit bland, but we could just put in a new query to grab
  387. that book's information. So I want, again, let's go back to where we had it.
  388. We already had it in book. I just want this section here.
  389. Copy this entirely
  390. and paste it there. So I'm going to grab that where the ISBN is set.
  391. it's not going to be in a GET because this section of here only works when it's a
  392. POST. So I'm going to say $ underscore
  393. POST and it's capitalized ISB and it does
  394. make a difference. Don't fall for that mistake.
  395. I've done it plenty of times and can't figure out why things aren't working.
  396. Now in there then we've got our different elements.
  397. I'm going to say that I want to fetch the associated array just like I have done
  398. down by here so let's grab that code no point rewriting it in this section here
  399. while we are fetching our associated array I'm going to say
  400. that dollar sign book name
  401. equals dollar sign row name let's
  402. keep it simple and then underneath here I'm going to say in this
  403. a book from us today.
  404. Let's go break line.
  405. Please come to the library
  406. to pick up and then in that place there I can do
  407. dot dollar sign book name.
  408. And Parkwood Vale, Central Parkwood Vale, yes, subject, book loan
  409. for, and then I'm going to say the same thing, dot, dollar sign,
  410. book name.
  411. Now, save that, and let's put that back up again.
  412. I do need to adjust that to two, just so I can't reserve it.
  413. And let's go back.
  414. Hit reserve yet again, and that's gone through.
  415. Give it a couple of seconds to pull through on my phone and hopefully I should get
  416. an email. Book loan 4. Oof. That's come through.
  417. I'm not sure how well you can see that, but it doesn't actually show you the name of
  418. that book name. It's gone through this section here.
  419. And it's not pulled it through.
  420. Capitalization. That's all it was.
  421. I'm glad I put that to 2
  422. I mean if you look at my reservations I'm a massive fan of Ready Player One I've
  423. reserved it about 14 times so far Come on And
  424. now This time round we do include Hopefully you can see that
  425. It says clearly Thank you for your reservation of Ready Player
  426. One Come to the library to collect it
  427. we've got that in place. Once we get to this section then all we need to do is
  428. redirect back to our previous element just like we did in our password
  429. reset we redirected back to the forgot password page this
  430. time around in books here we just need to redirect to a different page and the page
  431. I'm going to redirect to not forgotten password but that additional page that I've
  432. created it called loans up here as you can see a lot of ready player one
  433. so that's going directly to loans so after i reserve the book it takes
  434. me to my loans page that redirect should be in place
  435. and let's go refresh add it in again
  436. and browse book well it could be
  437. any book actually it doesn't
  438. So that lets go for the Martian and reserve.
  439. And it's brought me to this page.
  440. I've got all of those books there, all of those books.
  441. And the last one is the Martian.
  442. I should pick up another email in a couple of seconds time.
  443. There it is.
  444. And on the bottom there, you should be able to see that that is showing you my
  445. reservation.
  446. Okay, in the next section then, we're going to do the opposite system.
  447. Doing pretty much the same thing, just saying thank you for the return on an email
  448. and sending it so that the books go back into our library system.
  449. right so let's get back into this then we're going to go into our loans page now
  450. just to go through this with you again very briefly there's a session start at the
  451. top the empty header to make sure that we are logged in and redirect to the login
  452. page if we're not then we include our headed up PHP.
  453. We have this empty post for email at this section here.
  454. That's where we're going to be working in a second but let's run through the rest
  455. first.
  456. We then have a loans query connection that checks and returns all of
  457. the information for the books that we have loaned out
  458. using that loans table. Now we've got a special element here called a join.
  459. If I was to remove that section just there where we put that join in place
  460. and just look at that information that I get what will come
  461. back in my loans page will be very very blank if I actually remember to
  462. push that up as well and it's giving me
  463. the fact I can return these books but it can't find the pictures and it actually has
  464. no return IDs either. That's because without that join section
  465. it doesn't really do very much.
  466. Let's come down by here a second, let's go echo and I want to echo all of
  467. this just so I can check it into HeidiSQL and talk you through some of the elements
  468. that are involved there. Let's push that up, refresh the page, now the join is back
  469. in place, go to the top the page find that SQL command and copy it
  470. okay so what we're actually saying at this point is select
  471. all the information from this book here can I zoom in at all I
  472. don't think I can I'll see I can do it in post and see how that goes so I'm
  473. saying select star stack all from loans and if I actually just remove that join in a
  474. second and go there I'll show you what it looks like that selects everything from
  475. loans but that's just my loans data table that's
  476. nothing different to what I got there what the join will allow me to do is
  477. connect two books when there is a foreign foreign and
  478. public key as our key elements
  479. so So where you have a key field here, if I go into my table made up here, I have
  480. my primary key, not public. I knew there was a correct word for it.
  481. I have a primary key of ISBN. I have a foreign key of library ID.
  482. And those two there join and link to bring back that extra information.
  483. So when I run that, it's effectively saying, bring back all the information from my
  484. loans table. and bring back all the information from my books table where the
  485. ISBN is meeting here. But I don't have to tell it to do the ISBN element.
  486. It does that itself from that section there.
  487. I can control this. I can reduce it down.
  488. So I could say bring back name and run that and it would just give me the book
  489. names.
  490. I can also go a bit further with it.
  491. I could do a join there saying join that information.
  492. and I could join also here so I could say join
  493. and I want to join users on
  494. users dot email equals
  495. loans dot email and when I run that
  496. email closes ambiguous of course this is by here I'm say loans
  497. .email and if I run that now
  498. it brings back my loans table, my book table and if I
  499. carry on going across it also brings back my users table.
  500. So in this section what I could effectively say is bring back forname
  501. from my users table,
  502. surname and name
  503. and if I run that I get James Jones for forname and surname and the name of the book
  504. is Ready Player One Allot and The Martian is one off.
  505. I can include ISBN because it's a singular
  506. item. I could also
  507. email and pull that back. It'll say email is ambiguous.
  508. I want to say loans.email and that'll show me the email address
  509. used. So I can join using different elements.
  510. Joins can be particularly difficult.
  511. It takes a very long time to wrap your head around and make sure they're all working
  512. correctly, especially if you start looking at things like inner joins and outer
  513. joins. We don't need inner and outer joins here a simple join will do and we don't
  514. need a complex join like that one there we just need the simple join that i have in
  515. place which is if i come back here a join on the isbn and the library id so i can
  516. see all of the books that i've got in place i'll get rid of that for a second then
  517. and i'll zoom back in there so you can see it nice and clearly i got select star
  518. from loans join books on books.isbn i always put the
  519. joining table first equals so it's the same as loans.libraryid
  520. where my email is in my session email so i can only see my own books in place
  521. i could swap that out if i had a different user and i wanted to see their books i'd
  522. swap that to their id their email not mine anyway that all in place with
  523. our element in our bottom section here
  524. We are seeing that we have hidden information for ISBN and email.
  525. And I'm going to put in place the submit button that will take me back to this page
  526. here.
  527. Now, I'm going to cheat. I'm going to go back to books.
  528. I'm going to scroll to the top of books.
  529. And I'm going to say that I'm going to use my SQL.
  530. And actually, I can't cheat. Never mind.
  531. I'm going to say SQL, dollar sign, SQL equals
  532. update.
  533. and I want to update loans. I want to set return date.
  534. Let's capitalize set.
  535. And it was a capital R for return if I remember rightly.
  536. Set return date equals and I can steal this here.
  537. I just want my current date and time.
  538. I want to set my
  539. to that and I also want to set uh
  540. so I'm going to say comma here and I closed Heidi I shouldn't
  541. have closed Heidi I want to double check I'm pretty sure it's just the word returned
  542. but I want to make sure I'm doing this right so loans in here data it is returned
  543. set returned
  544. equals one where
  545. now this is where we're going to be putting in two where commands I'm going to say
  546. email equals
  547. and
  548. that's fine let me just check I've done all of these right because these always
  549. catch me out that would cause an error
  550. that's perfectly fine right email equals dot dollar sign underscore
  551. post and inside that post element I want it to be email
  552. and let's go full star that one of those
  553. there we go and so we can use that joining and element
  554. and you say ISBN, no, is library ID
  555. is equal to,
  556. and in there, I want to say dot dollar sign underscore
  557. post because we're talking about that post array again, and in there, simply put in
  558. ISBN.
  559. Okay.
  560. Let's have a look at that.
  561. need a full stop to that
  562. I
  563. want a second SQL so that will be connected so dollar sign will say SQL
  564. no I want to do connection sorry not SQL and I
  565. want to query and simply dollar sign SQL
  566. and actually library ID
  567. okay yeah I'll deal with that in a second there's something else one add in there
  568. but give me two seconds no no do it now um long set
  569. return date there return equals one and I'm going to say one other,
  570. no,
  571. where email is that and library is that, and I say and again
  572. returned equals zero.
  573. Now realistically, in a real world environment, you should never be able to loan the
  574. same book twice while you've still got it loaned out.
  575. So that should capture that and make sure that we don't have any issues.
  576. I have a lot of copies of Ready Player One loaned out, 10 of them.
  577. nonetheless that should stop any sort of anomalies and here then i've got
  578. connection equals query and that should send that off i'm going to say dollar sign
  579. sql equals up and then again it's going to be an update
  580. this time around it's going to update books it's going to set
  581. and we can do the complete opposite of this one let me just copy the bottom
  582. end of that
  583. So instead of saying minus one, I'm going to say set available copies equals
  584. available copies plus one, where ISBN is equal to post ISBN.
  585. That's in place. And again, I'm going to query it and I'm going to set that through.
  586. The last part is, like I've done here,
  587. just taking all of this email section all the way down to here and to my loans
  588. page. And I'm going to paste it below.
  589. And what I've got is in this section, it says select start from books where ISBN is
  590. the ISBN. Fetch the row, put it into book name and put it in place.
  591. Set up a new mail as a PHPMailer from my SMTP settings.
  592. All the way down.
  593. book lung I say book return for book name thank you
  594. for returning a book from us today please
  595. thank you for returning a book to us
  596. today and I'm just gonna say we hope
  597. you have enjoyed and then I've got book name now that should
  598. send that email now if I go push up on that one and on this section
  599. here then by refresh my loans page that should disappear by click on return
  600. I've got an error on line 20 what does line 20 say
  601. ah of course I can't include PHPMailer elements if I don't include PHP
  602. mailer. So I need the two users and loans
  603. at the top here, two users, and I need the requires, and I'm going to put the
  604. requires again, only used if they are Need it.
  605. Up that.
  606. Refresh that. Yep.
  607. And there we go. So I should now have return
  608. dates in my copy, in my book, sorry.
  609. I now have, if I refresh that, Ready Player One with copies.
  610. and in my email I have an email that does specify
  611. thank you for returning Ready Player One I hope you enjoyed it.
  612. So we have that system in place we can now return a book and reserve a book from
  613. our library system. They are all shown in one section all the books that I've got in
  614. place are shown in that one section let me just tidy that up because let's face it
  615. that looks very messy I
  616. the exampler there we go and I just have two books now
  617. my return book and my not return book
  618. I could and I have done actually if I look at Parkwood Vale
  619. I could look at splitting this section here so I have my div container here for
  620. these elements it's got all of our books It's got all of the information from my
  621. box. So in this section here, while that is in place,
  622. it's got the loan information as well, so it should know if it's been returned or
  623. not. I can simply add in a tag here and say echo returned.
  624. And now if I push that up and refresh this, we get one and a
  625. zero.
  626. very helpful so let's make that a bit nicer and say
  627. instead of echoing there I'm gonna say if returned
  628. there is equal to zero then I want to
  629. echo
  630. now let's flip it on its head let's say if it's equal to one then I want to
  631. echo
  632. returned.
  633. I can say on and then I could also include
  634. in that section by using dollar sign row and do
  635. returned date.
  636. Oh, is it returned date I used?
  637. Return date I used, not returned date.
  638. Return date there.
  639. And save that for that.
  640. And when I refresh that, it's not happy with line 90.
  641. I broke something here. No, I didn't.
  642. I forgot to close that if off.
  643. And now put that there.
  644. So it says returned on and then it's got that date in a very hideous fashion.
  645. But it's got the full date in place and that one doesn't have a date.
  646. I can tidy that date up by using the date command again.
  647. Open it up and say I want it in.
  648. Let's go a bit more British, shall we?
  649. So day, month, year.
  650. and I'm not going to put in the time because the exact time I returned it isn't
  651. massively relevant to me. Let's put that up and refresh this now
  652. and it says, it's not happy with it, we need to convert it, we need to use around
  653. this one string to time.
  654. I think.
  655. This part's gone off script, I'll be completely honest with you.
  656. worked okay so what I've done there is I've used a command called string to time is
  657. taking the string element that was stored in my database and converted it to a
  658. timestamp and then use the date formatter to put it in place I could include the
  659. hour let's capitalize it see if that works our minute
  660. in the seat and And save that, up that,
  661. and... I mean it didn't quite work out.
  662. I want to say it's a J.
  663. Let's have a look. Date, time,
  664. PHP, date.
  665. It's the date function.
  666. Format. PHP manual, let's have a look.
  667. HIS, yes that's fine.
  668. I'm sure there used to be a list of these things.
  669. Never mind.
  670. Let's just take that out and just put it as h i
  671. s
  672. or entirely remove it. Like I said, I've gone off script a bit with that one so that
  673. wasn't exactly what I was planning on doing.
  674. Now that's there, it's got the return date in place.
  675. What we can also do is bring this in a little bit.
  676. Again, this is completely off script, so do bear with me about errors.
  677. And I'm going to repeat this if returned is one.
  678. If returned is one, then I want to echo this section out.
  679. And let's just keep our bracket in nice and tidy so we can
  680. always tell where we are. So now it will only return or display my returned
  681. box. Pop that up, refresh this,
  682. it's only my returned box. I'm going to put in place by here then a heading 2,
  683. h2,
  684. and say returned box.
  685. I'm going to copy the whole of this div,
  686. paste it and change that to
  687. outstanding
  688. books and change that to zero.
  689. Now with that in place then if I put that up and refresh this, return
  690. books there, outstanding books there, we have a bit of an issue.
  691. Ah.
  692. Once you've gone through your row, it tends to delete what you've done.
  693. So what I would do is I'd actually move that query
  694. down to here,
  695. inline there, and we can actually reduce it ever so slightly.
  696. we can reduce it ever so slightly as I was saying.
  697. Finish your sentence. And that is that where email is there and
  698. returned
  699. equals zero. No, equals one.
  700. Now, realistically, we shouldn't need this if, but it's always good to keep it there
  701. just in case. And if I copy that and come down here with
  702. it and just paste it by there,
  703. swap that round so now return is equal to zero and put that up what we
  704. should have nice and clearly is our outstanding and our returned box
  705. and you can see the difference between the two of them if i click on return
  706. i now have two return books no outstanding books and a
  707. another email eventually there we go just come through so we can now
  708. return and reserve
  709. Let's go Harry Potter. I want to reserve it.
  710. It brings me to my books of reserves.
  711. I've got my returned books and my outstanding Harry Potter book that when I return
  712. it, returns that book into the library section.
  713. All working perfectly fine. slightly different to what I'd set up initially within
  714. Parkwood Vale where if I log into that one my loans section have outstanding
  715. and returned in two different tabs but all they are is using bootstrap
  716. tabs bootstrap and in here again examples
  717. docs even sorry layouts columns,
  718. content
  719. components
  720. Let's go on to the component section, let's go to the accordion and we can scroll
  721. through it.
  722. I can't actually remember which one of these I used.
  723. List groups?
  724. No, it's not that.
  725. Nav and Tabs is what I used.
  726. So you can see these here and what they allow you to do is have these little funky
  727. elements set up here. So you have a UL for Nav Tabs, LI for the titles
  728. and the LIs for where they are set out to.
  729. And it all allows you to put it in place.
  730. how you wish to design and how you wish to lay out your website.
  731. So now, with that, we have the final functionality element of our site in place.
  732. You can now reserve and return books.
  733. Thank you for watching. A much easier session than some of the previous ones.
  734. Hopefully it all makes sense. As always, any issues, just drop me a message and I'll
  735. do my best to help you out as much as I can.