{"id":355,"date":"2014-04-28T22:28:39","date_gmt":"2014-04-28T22:28:39","guid":{"rendered":"http:\/\/blog.soton.ac.uk\/orion\/?p=355"},"modified":"2014-05-01T15:30:09","modified_gmt":"2014-05-01T15:30:09","slug":"libraries","status":"publish","type":"post","link":"https:\/\/blog.soton.ac.uk\/orion\/implementation\/libraries\/","title":{"rendered":"Design Patterns, Libraries and APIs"},"content":{"rendered":"<p>During our development of the <a href=\"http:\/\/blog.soton.ac.uk\/orion\/implementation\/screenshots-from-the-implemented-application\/\">LeapIn.it prototype<\/a>, we have used a number of design patterns, libraries and API&#8217;s. This post will give an overview of the most crucial of these.<\/p>\n<figure id=\"attachment_718\" class=\"wp-caption aligncenter\" style=\"width: 1019px\"><a href=\"http:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/Libraries-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-718\" alt=\"Libraries (blue), APIs (red) and design patterns (green) used within the LeapIn.it prototype, and where they are used.\" src=\"http:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/Libraries-2.png\" width=\"1019\" height=\"286\" srcset=\"https:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/Libraries-2.png 1019w, https:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/Libraries-2-300x84.png 300w\" sizes=\"auto, (max-width: 1019px) 100vw, 1019px\" \/><\/a><figcaption class=\"wp-caption-text\">Libraries (blue), APIs (red) and design patterns (green) used within the LeapIn.it prototype, and where they are used.<\/figcaption><\/figure>\n<h3>Server<\/h3>\n<p>The server is responsible for creating a REST interface for database access. As mentioned in our <a href=\"http:\/\/blog.soton.ac.uk\/orion\/design\/architecture-overview\/\">post on architecture<\/a>, we have chosen to use RedBeanPHP to communicate with the database, and Slim.php as a REST endpoint. We have also used tokens for security, PHPImageWorkshop for thumbnail generation and AlchemyAPI for sentiment analysis.<\/p>\n<p><b>Database access through RedBean<\/b><\/p>\n<p><a href=\"http:\/\/redbeanphp.com\/\">RedBean<\/a> is an Object-Relational Mapping (ORM), meaning that records in the database are available as objects. For example, the following PHP code may be used to change a person that exists in the database:<\/p>\n<pre lang=\"php\">\/\/ Load the person with ID 209 from the database\r\n$person = R::load('person', 209);\r\n\/\/ Get their name\r\n$name = $person->name;\r\n\/\/ Change their name\r\n$person->name = 'Joel';\r\n\/\/ Update the database\r\nR::store($person);<\/pre>\n<p>Using RedBean results in simple and more maintainable code when accessing the database. It also provides security over direct SQL queries, as it prevents SQL injection.<\/p>\n<p><b>REST interface through Slim.php<\/b><\/p>\n<p><a href=\"http:\/\/www.slimframework.com\/\">Slim<\/a> provides a simple way to create a REST endpoint on the server, which we use to allow clients to interact with the database.<\/p>\n<p>As an example, the following code allows a user to create a user. First, the client will sent a POST request to &#8216;\/api\/person&#8217; with\u00a0the username and password in the request body. All interactions with the database are done through RedBean (denoted by R). Using Slim.php, we listen for that response. In addition, we use middleware to ensure that all interactions are in JavaScript Object Notation (JSON) &#8211; this is done by adding the variable $requestJSON in the first line. The body of the function first checks if the username is already in use, and if not, creates a &#8220;person&#8221; with a username and a password (which is stored as a SHA1 hash for security). An avatar is then created by copying a random template (there are about 50 avatar templates in the database by default). The person is then stored in the database and exported as REST to the HTTP response.<\/p>\n<pre lang=\"php\" line=\"287\" src=\"https:\/\/github.com\/FlamingTempura\/leapinit\/blob\/master\/server\/index.php\"> \r\n$app->post('\/person\/', $requestJSON, function () use (&$app, &$params) {\r\n\tif (R::findOne('person', ' username = ? ', array($params->username))) {\r\n\t\t$app->render(401, [\r\n\t\t\t'msg' => 'Username already in use.'\r\n\t\t]);\r\n\t} else {\r\n\t\t$person = R::dispense('person');\r\n\t\t$person->username = $params->username;\r\n\t\t$person->password = sha1($params->password);\r\n\r\n\t\t$avatar = R::dup(R::findOne('avatar', ' ORDER BY RAND() LIMIT 1 '));\r\n\t\t$avatar->bgcolor = randomColor();\r\n\t\t$person->avatar = $avatar;\r\n\t\t$person->joined = time();\r\n\r\n\t\tR::store($person);\r\n\r\n\t\t$app->render(201, [\r\n\t\t\t'response' => exportPerson($person)\r\n\t\t]);\r\n\t}\r\n});<\/pre>\n<p><b>Security through tokens<\/b><\/p>\n<p>Because the server and client will reside in different domains, it is not possible to use cookies for authentication. Instead, we have used tokens, which are unique random strings assigned to authenticated users, which they must provide whenever they make a request to the server. This is based on a model provided in <a href=\"http:\/\/security.stackexchange.com\/questions\/19676\/token-based-authentication-securing-the-token\">this Stack Exchange discussion<\/a>.<\/p>\n<p>The token is sent as part of the URL. For example, to request a room, the token would be placed on then end: <code>http:\/\/leapin.it\/api\/room\/4?token=[user's token]<\/code><\/p>\n<p>This is not actually safe over HTTP, as the token may be observed by third parties who see the URL. If a person were to steal a token, they would be able to authenticate themselves as the user by appending the token to the end of URL&#8217;s. This is known as <a href=\"http:\/\/en.wikipedia.org\/wiki\/Session_hijacking\">session hijacking<\/a>. To prevent this, encryption will need to be used, ideally through SSL.<\/p>\n<p>Checking for tokens is done as middleware within Slim.php. The middleware is a function which validates that a token exists and identifies the user it belongs to:<\/p>\n<pre lang=\"php\">$validateToken = function () use ($app) {\r\n\t$tokenKey = $app->request()->params('token');\r\n\terror_log('checking token ' . $tokenKey);\r\n\t$token = R::findOne('token', ' `key` = ? ', array($tokenKey));\r\n\terror_log('ok');\r\n\tif ($token !== null) {\r\n\t\terror_log('found token with user', $token->person_id);\r\n\t\t$user = R::load('person', $token->person_id);\r\n\t}\r\n\tif (isset($user) && $user->id !== 0) {\r\n\t\t$app->user = $user;\r\n\t} else {\r\n\t\terror_log('no user');\r\n\t\t$app->render(401, [\r\n\t\t\t'msg' => 'Unauthorized.'\r\n\t\t]);\r\n\t}\r\n};<\/pre>\n<p>This can then be used when defining a request response, as shown below when fetching a user:<\/p>\n<pre lang=\"php\" line=\"248\" src=\"https:\/\/github.com\/FlamingTempura\/leapinit\/blob\/master\/server\/index.php\"> \r\n$app->get('\/person\/:id\/', $requestJSON, $validateToken, function ($id) use (&$app, &$params) {\r\n    $person = R::load('person', intval($id));\r\n    $app->render(200, ['result' => exportPerson($person)]);\r\n});<\/pre>\n<p><b>Thumbnails using PHPImageWorkshop<\/b><\/p>\n<p>When viewing posts on the cleint, hexagon thumbnails are displayed to form a honeycomb. These thumbnails are generated using <a href=\"http:\/\/phpimageworkshop.com\/\">PHPImageWorkshop<\/a>. As an example, the following code loads a picture, crops it to the largest square possible, and then resizes it to 100&#215;100 pixels. Finally, it save the file.<\/p>\n<pre lang=\"php\">$layer = ImageWorkshop::initFromPath($file);\r\n$layer->cropMaximumInPixel(0, 0, 'MM');\r\n$layer->resizeInPixel(100, 100)\r\nimagepng($layer->getResult(), 'thumb.png');<\/pre>\n<p><b>Sentiment analysis through AlchemyAPI<\/b><\/p>\n<p>To form the honeycomb, all posts needed to be converted to thumbnails, including text. Simply displaying text in a small hexagon would not be effective &#8211; it would be too small and cramped to read. Instead, we wanted to display a preview of what the text may contain. We therefore form a preview comprising of the following:<\/p>\n<ul>\n<li><i>the key word<\/i>: what is the subject of the text? We discover this using keyword extraction.<\/li>\n<li><i>the mood<\/i>: how positive or negative is the text? We discover this using sentiment analysis.<\/li>\n<\/ul>\n<p>For both keyword extraction and sentiment analysis, we use <a href=\"http:\/\/www.alchemyapi.com\/\">AlchemyAPI<\/a>, which has been trained with vast amounts of data, such that it is ready to analyse data with diverse contexts. The sentiment is returned as a value between -1 and 1, which we use to adjust the hue of the hexagon, such that a negative mood is red, and a positive mood is green.<\/p>\n<table>\n<tbody>\n<tr>\n<td><a href=\"http:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-1796636341535d5bd1495f56.43275819.png-100-cell.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-683\" alt=\"Analysis of &quot;Tango is awesome!&quot;\" src=\"http:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-1796636341535d5bd1495f56.43275819.png-100-cell.png\" width=\"100\" height=\"100\" srcset=\"https:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-1796636341535d5bd1495f56.43275819.png-100-cell.png 100w, https:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-1796636341535d5bd1495f56.43275819.png-100-cell-80x80.png 80w\" sizes=\"auto, (max-width: 100px) 100vw, 100px\" \/><\/a>Analysis of &#8220;Tango is awesome!&#8221;. Sentiment is 0.9 &#8211; extremely positive &#8211; so the background is green. The keyword is &#8220;Tango&#8221;.<\/td>\n<td><a href=\"http:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-320563092535d5c7d064177.22638142.png-100-cell.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-684\" alt=\"Analysis of &quot;I hate orange!&quot;\" src=\"http:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-320563092535d5c7d064177.22638142.png-100-cell.png\" width=\"100\" height=\"100\" srcset=\"https:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-320563092535d5c7d064177.22638142.png-100-cell.png 100w, https:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-320563092535d5c7d064177.22638142.png-100-cell-80x80.png 80w\" sizes=\"auto, (max-width: 100px) 100vw, 100px\" \/><\/a>Analysis of &#8220;I hate orange!&#8221;. Sentiment is -0.8 &#8211; very negative &#8211; so the background is red. The keyword is &#8220;orange&#8221;.<\/td>\n<td><a href=\"http:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-19386199945360f4a4d9bed3.48614102.png-100-cell.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-685\" alt=\"Analysis of &quot;i have a tv!&quot;\" src=\"http:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-19386199945360f4a4d9bed3.48614102.png-100-cell.png\" width=\"100\" height=\"100\" srcset=\"https:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-19386199945360f4a4d9bed3.48614102.png-100-cell.png 100w, https:\/\/blog.soton.ac.uk\/orion\/files\/2014\/04\/r-19386199945360f4a4d9bed3.48614102.png-100-cell-80x80.png 80w\" sizes=\"auto, (max-width: 100px) 100vw, 100px\" \/><\/a>Analysis of &#8220;i have a tv&#8221;. Sentiment is 0.2 &#8211; fairly neutral &#8211; so the background is off-green. The keyword is &#8220;tv&#8221;.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Client<\/h3>\n<p>The client is the application which people will use to access LeapIn.it. We use HTML, CSS and JavaScript, and use Apache Cordova to package this as native Android and iPhone apps. Backbone is used to interface with the REST endpoint and Angular is used to generate DOM content.<\/p>\n<p><strong>Apache Cordova to create mobile apps<\/strong><\/p>\n<p><a href=\"https:\/\/cordova.apache.org\/\">Cordova<\/a> provides a wrapper for HTML, CSS and JavaScript, such that it may be packaged as a mobile app. It also exposes a hardware-level API which can be used within JavaScript.<\/p>\n<p>The process of converting a web application to a Cordova application is minimal &#8211; it simply needs an app name and icon.<\/p>\n<p>We use Apache Cordova to utilise the camera as a barcode scanner. The following code is responsible for that:<\/p>\n<pre lang=\"javascript\" line=\"13\" src=\"https:\/\/github.com\/FlamingTempura\/leapinit\/blob\/master\/app\/www\/js\/screens\/scan.js\">cordova.plugins.barcodeScanner.scan(function (result) {\r\n\tscan(result.text); \/\/ find a room for this code\r\n});<\/pre>\n<p><b>Backbone used as a REST client<\/b><\/p>\n<p>To interface with the REST endpoint on the server, <a href=\"http:\/\/backbonejs.org\/\">Backbone.js<\/a> is used. This provides an object mapper for models, allowing us to modify database records much like we would with RedBean on the server. As an example, the following will get and change a room title:<\/p>\n<pre lang=\"javascript\">\/\/ Define the Rooms collection\r\nvar Rooms = Backbone.Collection.extend({\r\n\turl: 'http:\/\/leapin.it\/api\/rooms'\r\n});\r\n\/\/ Instantiate the collection\r\nvar rooms = new Rooms();\r\n\/\/ Fetch all rooms\r\nrooms.fetch().then(function () {\r\n\t\/\/ Get room with ID 10\r\n\tvar myroom = people.get(10);\r\n\t\/\/ Get the title\r\n\tvar title = myroom.get('title');\r\n\t\/\/ Change the title\r\n\tmyroom.save({ title: 'myroom' }).then(function () {\r\n\t\tconsole.log('SAVED!');\r\n\t});\r\n});<\/pre>\n<p><b>Angular used to generate DOM<\/b><\/p>\n<p><a href=\"https:\/\/angularjs.org\/\">Angular<\/a> provides HTML markup to generate the DOM automatically when data has loaded. For example, the following will generate a list of rooms:<\/p>\n<pre lang=\"html\">\r\n<ul class=\"rooms\">\r\n\t<li><a href=\"{{ room.url }}\">{{ room.title }}<\/a><\/li>\r\n<\/ul>\r\n<\/pre>\n<p><b>Other libraries used on the client<\/b><\/p>\n<ul>\n<li><a href=\"http:\/\/jquery.com\/\"><b>jQuery<\/b><\/a> is used for DOM selection.<\/li>\n<li><a href=\"http:\/\/fontawesome.io\/\"><b>Font Awesome<\/b><\/a> is a collection of icons which are used throughout the prototype.<\/li>\n<li><a href=\"http:\/\/underscorejs.org\/\"><b>Underscore<\/b><\/a> provides a number of features for functional iteration through arrays.<\/li>\n<li><a href=\"http:\/\/lesscss.org\/\"><b>Less<\/b><\/a> is used to produce hierarchical CSS<\/li>\n<li><a href=\"http:\/\/lesshat.madebysource.com\/\"><b>Lesshat<\/b><\/a> provides a number of templates for use within LESS.<\/li>\n<li><a href=\"http:\/\/momentjs.com\/\"><b>moment.js<\/b><\/a> converts unix timestamps into meaningful strings (for example, &#8220;one week ago&#8221;).<\/li>\n<li><a href=\"https:\/\/github.com\/blueimp\/jQuery-File-Upload\"><b>jQuery-file-upload<\/b><\/a> provides a convenient file upload utility which we use for creating posts.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h4>Conclusion<\/h4>\n<p>The use of existing design patterns, libraries and API&#8217;s has greatly reduced the complexity of development, allowing us to develop three prototypes in a short period of time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>During our development of the LeapIn.it prototype, we have used a number of design patterns, libraries and API&#8217;s. This post will give an overview of the most crucial of these. Server The server is responsible for creating a REST interface for database access. As mentioned in our post on architecture, we have chosen to use RedBeanPHP to communicate with the&#8230;<span class=\"path-read-more\"><a class=\"more-link\" href=\"https:\/\/blog.soton.ac.uk\/orion\/implementation\/libraries\/\" title=\"Design Patterns, Libraries and APIs\">  Read more &rarr; <\/a><\/span><\/p>\n","protected":false},"author":81318,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[177],"tags":[11849,25,723292],"class_list":["post-355","post","type-post","status-publish","format-standard","hentry","category-implementation","tag-architecture","tag-development","tag-leapin-it"],"_links":{"self":[{"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/posts\/355","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/users\/81318"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/comments?post=355"}],"version-history":[{"count":15,"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/posts\/355\/revisions"}],"predecessor-version":[{"id":721,"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/posts\/355\/revisions\/721"}],"wp:attachment":[{"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/media?parent=355"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/categories?post=355"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.soton.ac.uk\/orion\/wp-json\/wp\/v2\/tags?post=355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}