Penultimate Supervisor Meeting

26.10.17

Report Notes:

  • More for project plan
    • As mentioned, turn bullet points into paragraphs
  • Writing level is acceptable
  • Images:
    • Treat as figures:
      • Right click > insert > caption
    • Refer back to images by their fig number
  • Evaluation
    • Go into my Laravel experience
    • Really let out my foibles and disappointments or what went wrong
  • Conclusion
    • Like an abstract
    • Conclude the abstract

Getting a NewSimland space to upload the program

Todd has allocated some space on newsimland to upload the prototype

Details for this are in a OneNote note

UPDATE:

Successfully hooked up to it with WinSCP.

The next steps are to copy the public folder to public_html, and the rest to the root folder. Then, change the .env file to reflect the database details Todd provided.

Fingers Crossed!

Poster Evening

  • Compulsory
  • Roughly Friday 11th
    • Goes to about 5 – 6.30pm

Blog Export

  • Due next Thursday, sort of, but maybe not
  • Pay close attention to export and submission instructions

Deploying the Prototype

I’m currently trying to deploy the application to the newsimland shared server, so the client can play around with the prototype, give feedback, and demonstrate the prototype to a developer who will hopefully create a commercial version of pivot.

Deploying a Laravel application to a remote server is not necessarily difficult, but it can be, apparently especially to a shared server with multiple hosts.

Having deployed a Laravel application recently for a friend’s website, I’d already encountered and overcome many of the problems that are typical of these deployments. Here are the steps I’ve performed so far:

  • Create local and GitHub back up of the Laravel app
  • Create connection to the server at my allocated space with username and password
  • Copy the local ‘public’ folder within the Laravel app into the remote ‘public_html’ folder
  • In the .env file:
    • change the app name to ‘pivot’ from ‘Laravel’
    • set the database variables (db name, username, password)
  • In the root of the remote server, create a new folder called ‘pivot’ (after the name of the Laravel application folder)
  • Copy the local contents of the Laravel folder, apart from the ‘public’ folder, into the remote ‘pivot’ folder
  • In the remote copy of ‘index.php’ within the ‘public_html’ folder, change the __DIR__ and $app path variables to also include the folder with the non-public contents:

    From this:

    require
    __DIR__.‘/../bootstrap/autoload.php’;

    To this:

    require
    __DIR__.‘/../pivot/bootstrap/autoload.php’;

 

  • To migrate the database tables, enter the shell and execute ‘php artisan migrate’, and now all the database tables are created.

NB: The contents of the local Laravel application are placed in different folders like this because only the contents of the ‘public’ / ‘public_html’ folder should be accessible to the public. If all the app was technically accessible from the browser, then malicious actors could access the database directly, or perform other such actions.

Initial Results

These were the same steps I took to upload my friends website, and I didn’t experience any further problems. With PIVOT, the website is now up and accessible, but, I believe extra problems have creeped in because of the shared deployment with the unusual access URL meaning that more steps hae to be taken.

For example, the home page loads and user’s can register and login. Some pages are accessible, but also the css and javascript are a bit weird. Upon inspection, this seems to all be my local css and js that is not loading properly, and it’s because the folders are not being pointed to properly.

This also seems to be a pretty major problem with basic routing, and in particular, routing for the Models and Controllers that handle the CRUD tasks for the health diary and results. Links seems to concatenate with the current view link, making a nonsense route. One solution to this may be with the Laravel/php route() method for calling a route, but the problem here is that only a select few routes have the name property which will allow this:

  • The home link is defined by a pre-configured HomeController. Links to home (href=”/”) are redirecting to some odd newsimland.com home page. This actually makes sense because of the shared hosting nature, but I’m not sure how to point to the correct home page of this application in particular.

The body map is also having huge problems and not loading properly. It is possible to point to the correct local css and jss with the {{asset()}} method, but I’m not sure whether this is a correct fix. It also hasn’t fixed the problem because the body map assets (graphics/sprites) are not being loaded as THEY are using a path structure that is seeminly incompatible with the shared hosting structure.

It may be possible to fix all these problems with crude hacks to all the affected values, but I believe there will be a more elegant solution which is generalisable to any shared deployment solution, and so hoefullt that is what I’ll report on in the next update to this post.

Penultimate Supervisor Meeting

Report Notes:

  • More for project plan
    • As mentioned, turn bullet points into paragraphs
  • Writing level is acceptable
  • Images:
    • Treat as figures:
      • Right click > insert > caption
    • Refer back to images by their fig number
  • Evaluation
    • Go into my Laravel experience
    • Really let out my foibles and disappointments or what went wrong
  • Conclusion
    • Like an abstract
    • Conclude the abstract above
    • Don’t provide new information

Getting a NewSimland space to upload the program

Todd has allocated some space on newsimland to upload the prototype

Details for this are in a OneNote note

UPDATE:

Successfully hooked up to it with WinSCP.

The next steps are to copy the public folder to public_html, and the rest to the root folder. Then, change the .env file to reflect the database details Todd provided.

Fingers Crossed!

Poster Evening

  • Compulsory
  • Roughly Friday 11th
    • Goes to about 5 – 6.30pm
  • Class on 2nd deals with posters, and is unfortunately compulsory, so report should really be finished by Wednesday

Blog Export

  • Due next Thursday, sort of, but maybe not
  • Pay close attention to export and submission instructions

Final Features Before Submission

Intro

This post documents the implementation of some final features which will be included in the application and thus the report before the report is submitted.

Desired Features

  • Display solutions dynamically
    • Display solutions for certain body parts only (where clause)
  • Adjust user profile features
  • Display user journey with charts
  • User picks from list of solutions
    • On click, the user is provided the form to document their progress
    • This would be a “blog post” like setup for each solution

Implementation

Display Solutions Dynamically

What I’d Like to Do

Something I want to do is change up the flow of action.

  1. Users click an area of the body map that is causing trouble
  2. Taken to screen of solutions which are generated dynamically based on body part
    1. Also ordered into the ‘lights’ categories
    2. Implementing that with the existing embedded pill functions will be fun (/s), but also possibly very rewarding and cool
  3. User clicks on a solution they’d like to try and are given a pop-up form to track how they’re going with this exercise.
    1. These would need to be stored as practically blog posts
    2. Solution would be the title with entry being the body. Other details like body part and solution category would be other details posted.
  4. Would be good to have somewhere next to each solution which lets user’s know they have tried it

What I Probably Will Do

Make it so solutions are dynamically presented.

  • Could put a checkbox next to them which can be submitted and at least give user’s that knowledge of their progress.

What I Did

STORING THE SOLUTIONS

Here is a code snippet of the ‘store()’ method in the SolutionsController which is used to enter health advice into the database, which will then be output to the solutions page.


$bodypart = $request[‘bodypart’];


$light = $request[‘light’];


$problem = $request[‘problem’];


$_solution = $request[‘solution’];

 


$solution = new
Solution;


$solution->bodypart = $bodypart;


$solution->light = $light;


$solution->problem = $problem;


$solution->solution = $_solution;

 


$solution->save();

 

DISPLAYING THE SOLUTIONS

For now because I can’t figure out how to send a parameter to the premade ‘index()’ controller method, I’m fudging the bodypart for display purposes. BUT, this does output correctly, at least


$bodypart = “lowerback”;

 


$solutions = Solution::all()->where(‘bodypart’, ‘=’, $bodypart);

 


return
view(‘v2.pages.solutions’)->with(‘solutions’, $solutions);

 

The actual code snippet inside the view is even better. So now, instead of having all these solutions hard-coded in and super-annoying if I wanna mix things up, we now have this:

@if(count($solutions) > 0)

@foreach($solutions as $solution)


<div
class=“card card-outline-danger mb-3”>


<h3
class=“card-header bg-danger text-light”>{{$solution->problem}}</h3>


<p
class=“card-body”>

{{$solution->solution}}


</p>


</div>

@endforeach

@endif

This is what is awesome about computers: they can repeat stuff really easy. So now the database records are pulled to this page and loaded dynamically:

Next Step

Next, I would perhaps like to add a bool field which will be a checkbox. Then user’s can ‘check’ when they’ve used some of the advice. The problem there is then submitting this checked state.

Route Model Binding: I don’t think this is what I’m doing here, but a forum solution provided that as the answer. IIRC, route-model binding would take care of this before hand, but this may be a bridge too far.

 

To Be Continued…

Supervisor Meeting – 19.10.17

This meeting was somewhat brief because of my unexpected mystery illness, but otherwise very productive.

I gave Todd a copy of my report, and it was good to get some feedback; some things I already suspected were confirmed (no personal pronouns, listing steps in processes), but more important was what I didn’t know.

Todd Advice

Project Plan

  • Extend the bullet points and describe them in brief sentences

Software Development

  • Code snippets
    • Provide code snippets to guide the reader through the process more viscerally
    • Code snippets can also perhaps provide a visual break in the report, making it easer to read
    • Both narrative flow and visual
  • Installation
    • Provide those snippets

Whole Report Structure

  • Try not to use bullet points as the main technique (which I definitely do for blog posts!)
  • Have more words 😛
  • Can potentially use personal pronouns for evaluation, but I’ll stick to the client/developer paradigm I’ve been using thus far.
  • Get rid of those numbering section headers – they’re completely out of whack
  • Create larger breaks in between important paragraph sections to provide clearer report flow (maybe even use page breaks at the end of major sections?)

Blog Dump

Sorry for the apparently random ordering of blog posts. I’ve been negligent with actually posting the blogs that I’ve written, and so have posted a bunch up right now, but only realised afterwards that they were out of order by days and weeks at a time.

Laravel – Creating a Social Network

This post will detail lessons learnt in a video series on making a social network using Laravel. Of course, not every aspect of a social network site would be useful for PIVOT, but some features will most likely be useful – such as maintenance of user data and posts – and some aspects of the video will probably be indirectly useful.

Setup & Introduction

  • ‘app’ folder contains most of the business logic
  • ‘config’ folder contains authentications and general configurations
  • Don’t touch anything in the ‘vendor’ folder!
  • The css and js folders are in

Some Insights I’m Borrowing

  • Creating an ‘includes’ folder within ‘views’ folder:
    • This folder contains the sections for nav bars and possibly footers that can be inserted in pages
  • Creating a ‘layouts’ folder within ‘views’ folder:
    • This folder contains a master page which forms the skeleton for every other page (except probably error page)
  • Using the blade templating tool of Laravel to succinctly post content in a more programmatic fashion
    • The blade templating tool simplifies control structures of php (for e.g. @if … @endif), output (for e.g. {{5+5}})
    • Also brings methods for creating simple views that target classified elements.
      • For e.g. by creating a @yield(‘title’) within the master page <title> tags, this section can be defined with individual views to output the page’s title

Capturing User Health Data Form

An important aspect of PIVOT is capturing the user’s impression of their health over time. Another aspect of this is that the data should be localised to an area of the body.

The client suggested a 10 point survey to be answered. Although this would possibly capture all the aspects of the user’s health state, I informed the client that such a survey taken regularly would also lead to a “form fatigue” – meaning less use of the system – unless survey was well calibrated and/or the user saw the utility of using this.

I don’t think I’ve been successful with capturing the user’s requirements and mapping them to this solution (more on this in another post), but we were able to come to some idea of how to briefly and succinctly capture the user’s health journey.

The Basic Idea of the Form

By going back and forth with the client, these are the datum that need to be captured by the user, and some of the preferred methods for capturing the data:

  1. A slider to capture the user’s pain, e.g.:

  • This was to create a slick feeling, as well as be an obvious visual indicator.
  • Should the slider default to the last given value, middle pain value, or no pain value?

     

  1. A text box to capture some journaling of the user’s state.
  2. Some questions – with radio buttons or dropdowns – for the user to answer

For a production version of this program, questions and journaling would probably be specific to each body part, but as this is a demo of only 1 part, the form will be the same regardless.

How to Implement the Form?

My first stab at the simple form looks like this:

The journaling aspect is handled by a textarea, which is identified in the form by using the HTML5 attribute ‘form’.

The slider is using a bootstrap-slider library of css/js to make it look nice with the rest of the bootstrap components.

  • NB: these features, among others, will not work with Internet Explorer 10 and below (some features of the entire design using bootstrap don’t work with ANY version of IE).
  • This would be a problem that has to be addressed for a commercial application of PIVOT, because so many offices still use IE, including older versions. This is something to consider in discussion of PIVOT going forward.

Laravel Forms

Currently, this form has an action that is not tied to a database of any kind, it is just taking the user to the lowerback advice page.

When the form is submitted a Laravel specific error is genereated :

MethodNotAllowedHttpException

 

This error is not apparent if the method is GET, but a get method is unacceptable for a work health tracking app such as this one, so I’ll need to get to the bottom of Laravel’s form methods.

Next Steps:

  • Grapple with the Laravel form system
  • Successfully post when submitting the form
  • Create a simple database structure
  • Create a Laravel database
  • Provide a tooltip of some other way to transmit the current value of the pain slider

 

Creating User Health Model & Controller

Following on from my post on creating the pain form, today I need to work on the back-end logic that will capture and utilise the pain data. Eventually this data will be presented in a format that is useful for a user, and potentially a health practitioner or manager.

The first aspect of this back-end logic is utilising Laravel’s Models, Migrations and Controllers.

The Model

Laravel ships with a user model, controller and other authorisation classes. I may use these, or integrate them into today’s problem eventually. But for now, my objective here is to create a model for capturing the data and using elsewhere in the app; data security concerns are not relevant to me right now (famous last words).

A Laravel model is a class that allows us to access and work with the database intuitively. If a model is created in the command line with a -m option, a migration file is also created, where the table can be defined in php and then created or dropped as required.

For this exercise, I’ll be creating a PainJournal model.

The Migration

The migration file contains the different aspects of the database table that will be built to satisfy the pain journal model. For now, I will add a string description field (use string in place of a varchar) and an int pain field. The can be updated and rolled back to add functionality at a later date

Creating the PainJournal model with the -m migration flag also created a migration/db.table file associated with it. The default name of the table is called pain_journals, which has auto-increment ids and timestamps, and to which I will add the fields the be captured by the pain journal form.

The Controller

The controller is where form requests will be received and acted on, so the route page will need to be updated to point towards this new controller.

  • For form controllers, we must add the Request namespace (use Illuminate\Http\Request)
  • Also, we must add the name space of the model that is being used/saved to (use App\PainJournal)
  • Laravel has a built-in hash security function (e.g. $password = bcrypt($request[‘password’])), but this does not seem like an immediate answer to the data security needed for this app, as what is posted to the database is a hash, and AFAIK, there is no way to get the original message back apart from brute force – generating random values and hashing them to get the correct hash – so this is not the function I need for protecting personal data from programmers.

There is a convenient way of creating this controller with CRUD methods already defined. php artisan make:controller [ControllerName] –resource will create a controller with methods to list all, create, update, delete, etc.

  • With all these methods defined in our controller, in the web.php file which manages routes, a single line which points the object to be CRUD’ed to the controller will handle all such requests
  • I.e.: Route::resource(‘pain_journals’, ‘PainJournalsController’);
  • If we look at the routes that are listed for this app, we can see that the above command has pointed CRUD requests to the appropriate controller

The next step is to define within the Controller methods what they should do.

Putting it All Together

The first CRUD functionality will be the simplest; displaying all the user’s pain journal entries. The controller has a predefined index() method that will perform this function.

  1. The first step is importing the PainJournal namespace of the PainJournal model to the controller
  2. Then define a variable will which hold an array of all instances of the fetched PainJournal model:
    1. $pain_journals = PainJournal::all();
  3. Then we will return a view which will display this information, and pass it the array. In this instance, I’m passing a page called ‘myhealth.blade.php’
  4. Finally, we create a view that will accept the array of entries and loop through and display them in a table:

And this is the output:

This is the template for data retrieval. Next, data creation.

Data Entry/Creation

After some unnecessary hiccups, it turns out that data entry with Laravel can be very simple and easy. There is more to the system that I need to learn over time, but the basics with this simple controller setup are working well enough for this project.

The basic steps are:

  1. Set the action of the form to the name given for the route::resource in the web.php route document
    1. Route::resource(‘pain_journals’, ‘PainJournalsController’);
  2. In the create() function of the controller, provide the view which has the form
  3. In the store() function of the controller, set variables to retrieve the posted values from form submission
  4. Create a new model object and set the values of the model object to the form values
  5. Save the model object
  6. Redirect to whatever.
    1. In this application, I want the user to be redirected to the health suggestions after they’ve made an entry.
    2. There should be entry feedback sent to this redirect, but for now this functionality will be enough

Fig. The form page with the bodymap


Fig. The successfully captured and output data.

Ethical Aside

It occurs to me that I haven’t thought through data security concerns re: database and health information; sensitive health information is right out in the open and visible to the data admin (me). There must be some standard methods as there are for protecting passwords, but I’ve not researched them yet. This will either need to be a step I take soon, or a deficiency that is catalogued and discussed further.

 

Creating a survey for journaling pain

The latest client meeting produced an idea to measure the user’s pain and progress: a survey form related to specific body parts.

The idea was to produce a form when a user clicks on a body part. I would like the form to “fade in” using jQuery/bootstrap, and then the information gathered should be posted to the database for use by the user, and/or the manager if appropriate consent is given.

Necessary Fields

  • Pain – the client has suggested a slider here, and I agree. There should also be a tooltip or help icon beside every field to help the user because some of the fields can be very subjective.
  • Diary entry – the user’s thoughts on the pain; a diary entry
  • Survey questions – don’t know what these are yet, or in what format. They may be checkboxes or radio buttons. Also unsure if there will be too much information for the user to input
  • CSRF Token – this is a Laravel specific hidden field token. This prevents cross site form attacks, which I am unclear of, but this is still a necessary field when using Laravel, and it’s nice that this safety feature which I would not have known about it protected.