Apparently it’s not working for me…

This comes across my radar every once-in-awhile.  Here’s yet another recent article from the Independant which talks about caffeine and cognitive health.

I first came across this research all the way back in 2008 from this Slashdot post. According to a BBC article, regular doses of caffeine may actually help prevent dementia, as shown in experiments on rabbits.

And this is all well and good, but what I want to know is what is science doing to protect us from what are apparently marauding bands of demented super rabbits?

I think I need more coffee.

 

A few simple questions to better vet offshore development vendors

A friend of mine recently ran into a fairly common problem: Trouble with an offshore vendor.  Bad offshore development can be a black hole for both time and money.

He pinged me for advice on how to evaluate if they could really do the job.  Here are some questions I recommended that he pose to them:

  • Can I receive background history of the developers working on the project? Will I be able to discuss issues with them directly?
  • What bug/issue tracking system do you use? Can I get access to this?
  • What automated testing system do you use? Will I be able to see the results of each build?

And of course, ask for a list of references.  Now, if you’re like me you will probably receive this list, verify that the companies / names are real via Google, LinkedIn, etc. and leave it at that.  Don’t.  Call at least two of the references and speak with them in detail.  Ask them about the above questions.

And if you can swing it, travel out to the meet the company personally.  Turn it into a vacation.  Better a vacation than black hole purgatory.

 

Format a CSV string in Twig

If you’ve ever had to format a string of values in most languages then you’re certainly familiar with the ugly logical hoops you have to jump through just to get the formatting to look good.

Here’s a nice way to do it in Twig:

So given a dirty array of phone numbers:

['123-4567', '', '321-7654']

the above snippet will strip empty values, chomp extraneous whitespace, and output:

Phones: 123-4567, 321-7654

Validating multiple files in Symfony 2.5

Symfony 2.5 implemented handy multiple file upload support, e.g. input fields that look like this:

<input id="form_resumes" multiple="multiple" name="form[documents][]" required="required" type="file" />

Unfortunately there seem to be some problems in the Validator component. For example, it’s difficult to require at least one file. Likewise the All constraint doesn’t play nicely with validation groups. Here are a few workarounds.

To require at least one file but not more than three, use the Count constraint in combination with All and NotNull:

This works around a bug where 'min'=>1 is ignored.

If you’re using validation groups, you may notice that the All constraint is not being applied. Here’s how to fix it:

Note line 11: 'groups' => 'Test',

Technically we shouldn’t have to specify validation groups for the All constraint; in fact there seems to be no way to do this in YAML. Hacking it in as an option to All on the PHP side however seems to be working for me. YMMV. And as far as I can tell this last one is fixed in 2.6.

End User Help Documentation: Tricks of the Trade

Some internal rumination that I thought would make a nice blog post.  Stuff we’ve learned after a dozen years of dealing with startup software documentation.

Because most software is a moving target, the vast majority of end user documentation is out-of-date soon after it is created.  Out-of-date documentation is worse than no documentation because it adds to, rather than detracts from, confusion.  This problem becomes exponentially worse when maintaining documentation across multiple languages.  It can become a nightmare when resources are limited.

To help prevent the documentation from turning into a problem, consider the following heuristics:

  • Only create a piece of documentation when there is a real need.  Never create documentation for features that are intuitive.  When in doubt, leave it out.
  • A picture is worth a thousand words.  Use screenshots and a minimal amount of text.
  • Avoid full-screen screenshots.  “Narrow” screenshots are easier to understand and much easier to maintain as the software evolves.  That said, leave enough surrounding space so that the user can recognize context.  (A screenshot of, for example, a single widget is like trying to ask someone to make an identification from a picture of an eyeball..)
  • When possible, describe a feature in general terms rather than specific steps.  This approach will have more “staying power”, meaning that the documentation is less likely to change even if there are small changes to the software.
  • Create a style guide to help keep the documentation consistent.  Especially important when multiple people are working on the documentation.
  • If resources are limited, only translate “proven” documentation or documentation that is demand.  Services like Freshdesk have “Was this answer helpful?” features.  I recommend only translating documentation that gets at least one up vote, or issues for which we get at least two support requests.

And of course:

  • Whenever possible refactor for usability rather than write even a line of documentation!

If you’re working on documentation and have come across this post, I feel for ya..  Keeping the scope as small as possible will bear you in good stead.

 

Postmaster Abuse

Here’s an interesting feature of Google Apps that got me into trouble recently:

https://support.google.com/a/answer/33389

The “abuse” and “postmaster” accounts are monitored by Google and always active. Even if explicitly configured in your Google Apps interface, emails to these accounts will be accepted into a Google black hole rather than bounce.

To make sure you get copies of emails going to these, be sure to create “abuse” and “postmaster” groups, otherwise you *will* miss an important email or two. Note that these need to be created as actual group addresses.. the abuse and postmaster accounts cannot be added to other addresses as an alias.

Git branch from a specific commit

Yet more git syntax I keep forgetting. To branch and create a new line of development from a specific commit, do the following:

git branch newbranchname a9c146a09505837ec03b

Add the -b switch to immediately checkout after branching.

Since the commit will likley be behind, use --force when pushing to tell git to ignore future commits from the original branch and start a new fork.

Know your CSRF timeouts

Web development frameworks such as Symfony these days bake-in a number of security features, CSRF protection being a fairly common one. I recently made the mistake of not scrutinizing Symfony’s CSRF protection defaults, which led to occasional confusing CSRF errors after a web app had been deployed.

CSRF protection embeds a code into both the generated form and some client-side storage mechanism (cookies, though I suppose this could work with an HTML5 client-side database or whatnot). On submit, if the value embedded into the form and the cookie value match, then we know the form is submitted by the user who originally requested it.

In Symfony, the CSRF cookie lifetime can be configured, defaulting to null, which falls back to session.cookie_lifetime value from php.ini. I had originally set this to be one hour, probably based on configuration examples from a year or so back..

Anyway, app users lately have been leaving forms open for more than an hour. This is a good thing: It means they are treating our web app more like a client side app, which indeed it is meant to replace. Took some sleuthing, however, to figure out why I was seeing the occasional CSRF error when everything else seemed hunky dory. I’ve now set this to

which will retain the cookie for the length of the browser session.
Lesson learned. Know your timeouts. And for that matter, plan some time to review old assumptions.