Automatically Reload CSS with Zend Framework and Assetic

This article is targeted at Zend Framework programmers on OSX that use Assetic to compile their CSS/JS.  With some interpretation, it might work for you if you don't fit into the above!


Hot reloading means reloading parts of a page without reloading the page itself.  If you've worked on SPA apps in React or Angular, this is a must-have, but MVC stackers ignore you can have this cake and eat it too with the ZF3/Twig/Assetic combo on OSX.

Plus, it makes CSS work kind of fun (at most).  I'd rather be doing other stuff too.

Your workflow becomes this:

  1. You modify your SCSS
  2. Something compiles your SCSS to CSS
  3. Assetic has to be triggered (typically triggered on page load, the usual)
  4. The CSS in the page has to reload dynamically

Step 1 is you, that part is clear.  How do we get the rest working...


Your first quest on this journey to reload-button independence is to run Prepros, which dually provides file compilation and a reload proxy.

  1. Fire up Prepros
  2. Add a new Project within Prepros, and set the base folder right at your module's assets folder (so, not your public folder -- the place where your SCSS initially compiles to CSS).
  3. Under Settings:
    1. enable the file watcher
    2. enable live preview, and use custom server
    3. set your server URL to be the domain that serves your stuff
  4. Under Live reload
    1. enable live reload
    2. enable animate css changes (this is the cool part)
    3. configure live reload delay.  This one is a bit of a magic value that'll need some tuning.  It's a function of your computer's speed.  Essentially, this is the time that assetic needs to run.  If you have a reasonably fast computer, you can set this to 2000.  If you find that it stutters sometimes, you will need to increase its value.
  5. Under Composer Settings
    1.  set your compiler to Node Sass.  Zero chance that Ruby will be fast enough to please you.

If you make some SCSS changes now, you should see Prepros compile your CSS for you.  You even get the fancy OSX notifications as confirmation that it's working.  Point your browser to http://localhost:7880 (or whatever port you configured in Prepros), and you will see your site!  The problem is that the CSS isn't changing; why?!

You got it.

There's no page reload, nothing invokes the Zend MVC stack, and Assetic is therefore asleep.  Let's find another way to trigger Assetic.


Enter fswatch,, which can use the extremely efficient FSEvents on OSX to trigger filesystem events.  

Install it with homebrew by issuing: brew install fswatch

Now, go into your Project's base folder, and create a new file called 'watchcss' with these contents:

fswatch -e ".*" -i "\\.css$" -0 . | xargs -0 -n 1 -I {} ./vendor/bin/assetic build

The command is simple; exclude everything, yet include CSS, and run vendor/bin/assetic build when something changes.

Make watchcss executable, and run it ./watchcss

Now, fswatch will trigger assetic whenever Prepros compiles your CSS files.  Then, Prepros will wait 2000 ms (adjust this as required) and thereafter hot reload your CSS!

Buying Bitcoin and IOTA in Canada

Not in the typical vein of this blog, but I thought my experience might help some.  My want was very simple: buy BTC.  Of course the crypto bug sets in and you'll want to buy more than just BTC (IOTA!).


My first foray into the fund-and-buy was admittedly with  They got good reviews, and they had a nice website; great UI design!  It took a VERY long time to wade through the verification process, and I failed.  I waited approximately 15 days to be told that my credit card couldn't be used with the account type that I had (claiming it was a business card, while this wasn't entirely true). The verification process is very black and white, and any failure imposes massive time penalties (they probably don't get to consider nuances with the volume of applicants they probably receive).  The minimum withdrawal values were a pain (I never did get verified).  I found myself having to transfer BTC (which carries a fee) into just to surpass the min transfer threshold so I could get leftover BTC out.  I can't recommend this exchange. Verification is a hassle, and the fees are very real.  Great study on modern UI design though!


After this I had tried to register with Gemini.  I did get an initial onboarding response within about 2 weeks, replied with all required documentation, and still haven't heard from them (it's been quite some time!).  Might pan out one day, who knows...


Bitfinex was the next find.  I registered and headed to the verification area.  The documentation requirements were very thorough, and direct deposit was not working at the time at which I wanted in.  Before handing over the critical personal information; I thought I'd do a bit more Googling about Bitfinex...  The writing on the web has that Bitfinex has been hacked twice already.  I chose to stay away, too much negative on the web for my personal taste. 


Now the good:!  What a change in pace (and breath of fresh air!).  Their site isn't as pretty as's; much more utilitarian -- but it works.  I registered and submitted the verification documentation on the same evening; and was validated about 2 days later.  Back in, went through the Equifax verification, and was off to the races!! Exciting!  

On a 2k deposit, you end up with $1,970 usable funds (transaction fee). Plus, funding from major Canadian banks is near immediate with direct transfer!  I wish I had found these guys first!


Last bit before I wrap this up then!  If you are registered on and would like to buy IOTA (really promising idea with unique propositions); I managed to do this successfully yesterday.

  1. First, register an account at
  2. Purchase BTC on Quadriga, meaning: fund your account with CAD, then buy BTC from the Dashboard or Trade tab.
  3. Log into, and access the Funds and Withdrawals area.
  4. Locate the BTC (Important!! Screw this up and you lose your BTC) row, and click on Deposit.
  5. Copy your BTC deposit address very carefully (it has happened, that this address takes a few seconds to appear).
  6. Head back to Quadriga, and click on "Withdraw" to send your Quadriga-bought BTC over to Binance.  On the withdraw panel, specify desired BTC amount, and paste the Binance fund address into the Quadriga withdrawal form.
  7. Wait for the transaction confirmation to occur (on average, has taken me 20 minutes or so).

When the transaction verifies (be patient, the BTC transaction can take some time to verify), simply trade your BTC for IOTA in your Binance trade panel (under Exchange/Basic):

  1. Top right, select BTC and search for iota (image below)
  2. Click the IOTA/BTC row in the search results
  3. The center area will yield the section where you can transform your BTC into IOTA
  4. For a fast buy, click the Market tab; click the 100% button in the Buy IOTA panel, and then click Buy IOTA
  5. Done!
IOTA search panel in

When I buy BTC, I quickly send it to my Ledger Nano S (recommended!) to mitigate any loss if the exchanges are breached.  There's unfortunately no support for IOTA right now -- so consider your cold storage options carefully.  Drop me a comment if you've solved this bit!

Don't forget to secure your Binance and accounts with Google Authenticator!

Good luck!

Gemini, © Copyright 2017 Gemini Trust Company, LLC.
CEX.IO, © Copyright 2017 CEX.IO LTD.
Bitfinex, © Copyright 2013-2017 iFinex Inc. All rights reserved.
QuadrigaCX, © Copyright 2017 QuadrigaCX. All rights reserved.

Setting up Bamboo and PHPSPEC

Setting up PHPSPEC tests on Atlassian Bamboo can be a real pain; it's fundamentally simple, but it's so easy to kludge and the build process logs aren't that great.  This guide will help you set things up from A to Z.  

Setting up your Stages

A single stage should do.  Click on the Create Stage button, give it a name, and save.

Stages tab, in the Plan Configuration area.

Stages tab, in the Plan Configuration area.

With your Stage created, access the Tasks tab, and configure your Source Code Checkout, defining the repository it will download.  It will draw a list of repositories from any source control tool you've linked.  [If you haven't yet done this, do it before continuing]  

Next, we configure our tasks.

The Composer Build Task

  1. Click on 'Add Task'
  2. Find the 'Script' task and click 'Add'
  3. In its configuration window, give Task Description a name of 'Composer Build'
  4. Interpreter will be Shell
  5. Script Location will be Inline
  6. Your Script Body will contain:
/usr/local/bin/composer update 1>&2

Leave the remaining details blank, and click save.



If your developers are like mine, they run their spec tests in pretty mode, but we'll need the output as junit would expect.  Configure a script task as you previously did, changing the name to be something meaningful like Run PHPSpec, yet selecting an Interpreter of /bin/sh and use this Script body to sub pretty for junit:

sed -i -e 's/ pretty/ junit/g' phpspec.yml
vendor/bin/phpspec run > build/junit.xml 2>/dev/null
exit 0

The remaining fields are left blank, and you click Save.  We do things this way, because phpspec will not exit with 0 if there are errors, and this is what Bamboo considers a success.  This'll let phpspec finish, and subsequent tasks will run (such as the one where your JUNIT results are evaluated).

The JUnit Task

Lastly, you'll need to configure the test task.

  1. Click on Add Task and select the JUNIT type
  2. Give it a Task Description of Evaluate Test Results
  3. Specify custom results directories should read build/junit.xml
  4. Click Save

Storing ARtifacts

Still on the same screen, click on the Artifacts tab up top.  Then, click on the Create definition button in the left hand corner of this tab.

  1. Location should read build
  2. Copy pattern should read *.xml
  3. The Shared checkbox remains unchecked
  4. Click Save

Clover Coverage

Done with Artifacts, click on the Miscellaneous tab, and check the User Clover to collect Code Coverage for this build checkbox.  A section will expand, in which you select Clover is already integrated into this build and a clover.xml file will be produced.  Lastly, specify Clover XML Location to be build/coverage.xml.


Putting it all together

The rest of the magic is actually done in your code's phpspec.yml configuration, and in your project's composer.json

Your phpspec configuration would typically look like this

        namespace: Lemonade
        spec_prefix: Spec
        src_path: module/Lemonade/src/
        spec_path: module/Lemonade/bundle
#  .... the rest of your suites are here
# pretty
      - html
      - clover
      html: build/coverage
      clover: build/coverage.xml
     - module

Note the inclusion of the PhpSpecCodeCoverage\CodeCoverageExtension that's outputting into our build folder, that's keeping all .xml artifacts in Bamboo.  Install that extension through composer, by installing henrikbjorn/phpspec-code-coverage