eVitabu development week, Feb 2019
In early February 2019 I took a week off work to undertake some development of eVitabu full time. Over the course of five days I fixed a number of bugs, added new features and got an API operational to integrate with their Client/Customer Relation Management (CRM) system. It wasn't always plain sailing, with some development problems along the way.
APF's office
Most of my eVitabu development has been done at home, with all the distractions that brings. For development week I was invited to work from the APF offices above a nearby farm shop. As the charity's CEO put it, "it has better coffee". The advantage of working from their office was immediate access to end-users: I could ask Geoff for his opinions on user interface changes in real time.
Environment wise, APF's office is very different to what I'm used to. Working in the public sector, with cost cuts and reducing staff numbers, there's always pressure to get something done "yesterday" and you're pulled in multiple directions all the time. Development week was quite relaxing (for the most part) and it was good to just be able to focus on one thing. Another benefit of working directly with the charity's people was the incidental comments I could pick up about eVitabu. These affected some of the changes I was going to make, so that was beneficial.
Now let's look at the week from a development perspective...
Imposter syndrome
As I mentioned in my Hacktoberfest 2018 post, I sometimes struggle with the "I'm not good enough" mentality when it comes to code. My biggest concern was that I wanted to make sure the charity felt they were getting benefits from my week with them, especially as they offered to pay me for the work. It was really encouraging that I'd managed to implement most of the CRM integration API by following the Yii2 documentation and researching the task. Framework documentation, and following code execution paths, is certainly something you have to get used to and I feel I improved at that over the week.
Don't blindly trust the doc comment
The API used to integrate with the CRM is restricted by IP and also requires user authentication. As this is a REST API, so stateless (the user logged in state is not remembered between requests), I'm using tokens and HTTP Bearer Auth to handle authentication. eVitabu's app also authenticates this way (although via Google) so it should be easy enough to implement.
I use PHPStorm as my integrated development environment (IDE) and one of its benefits is that you get told what a function should output: string
, array
, null
, type of object etc. This isn't unique to PHPStorm by any means, but is something I use extensively to save flicking backwards and forwards through code. While implementing a method called findIdentityByAccessToken()
, which does what you'd expect, I was repeatedly told my code was wrong as I had to return void
. Semantically that doesn't make any sense given the doc comment (the comment telling the IDE about the function) says this:
/**
* Finds an identity by the given token. This is how the API logs a user in.
* @param mixed $token the token to be looked for
* @param mixed $type the type of the token. The value of this parameter depends on the implementation.
* For example, [[\yii\filters\auth\HttpBearerAuth]] will set this parameter to be `yii\filters\auth\HttpBearerAuth`.
* @return void \yii\db\ActiveRecord the identity object that matches the given token.
* Null should be returned if such an identity cannot be found
* or the identity is not in an active state (disabled, deleted, etc.)
*/
How could I return a user object that matched the specified token while at the same time returning void
? To my mind those concepts are mutually exclusive (they are). I looked at the code for the eVitabu app authentication and, sure enough, I was returning a user object there. The doc comment was different too. I checked some other documentation and there was no mention of void
there either. After a while I decided to follow my instinct and just return the user object - bearer authentication worked and the doc comment was wrong.
Lesson for the day: don't always trust the doc comment.
Auto-tagging resources
When looking at the current content in eVitabu we found about 5% of the resources were tagged. Tags are really important for allowing the end user to discover content as they act like additional search terms. For example, a farming manual might include the tags aggriculture, soil and plants. Geoff had an idea about auto-tagging resources, getting eVitabu's management system (EVM) to read the uploaded PDF and then suggest tags based on the words it found.
To do that it's necessary to have keywords associated to tags. Taking the farming example above, the farming tag could have keywords of growth, mud, earth, corn etc. Once the PDF is read and the keywords found EVM would suggest possible tags. It's important they're only suggested because "earth" could also apply to the planet Earth, at which point the resource might actually be about creation and not farming.
I started work on this but it wasn't one of the priorities for the week so had to go on the back burner. Overall it's one of the higher priorities though, so will be coded soon.
Firebase issues
My most frustrating day was Thursday, when I was trying to focus on the Android app. Due to some stability issues with my Android development virtual machine I needed to move my development environment into my native laptop's OS. That's when I encountered problems using the version of eVitabu that my new environment produced. I won't go into full details here, as I've already covered this in a previous blog post. Needless to say it wasn't a great day and my keyboard certainly took a pounding...
For a full run down on this problem please see my blog post about it.
Font sizing in the eVitabu app
Following an upgrade to Android 8 (Oreo) on the tablets the font size in the eVitabu app was huge. We're not just talking a little bigger than necessary, we're talking completely wrong. After a bit of digging in the source I found they were all specified as point values rather than "device independent pixels" (dp
) which, roughly speaking, scale to take into account the size of screen and resolution you're using. There's a second scaling measurement in Android, sp
, which is best for text as it scales based on the screen size but also takes into consideration the user's font size preferences. If a user needs a larger font, perhaps due to a sight problem, sp
will respect that. There's a good explanation on this StackOverflow question.
Was the week useful?
Overall, the development week was useful and I got a lot done. It was really good to be able to concentrate on eVitabu full time (albeit briefly) and it was nice to have a better insight into how the charity operates day-to-day. I know it was a busman's holiday, but I'd happily take another week off to work on eVitabu again.
Clearly there was a lot more that happened than what I've written here. Some of those features will be the subject of a future blog post (or two).
Banner image is a screenshot of the code that caused me a problem.