This is a demo that I tasked myself with. I knew that writing code was a good way to understand how things fit together, in libraries. This was the first code I wrote with Symfony2 in 2013. As I haven't disclosed how long things took, this is a simple demo, showing use of the simple features on my current framework. I will never ask to be paid for code with this number of rewrites, or was this expensive. I didn't publish this demo until after all the others, as the others represent code that is more valuable.
I took the original spec from a website, but am ignoring everything relating to giving it back to them. Further reading on Symfony will be published symfony2-overview.
We would like you to build a demo web application that could be used alongside a live-streamed election broadcast, to provide an unscientific straw-poll of the voting habits of the viewers.
The demo should allow users to specify their parliamentary (Westminster) constituency and enter answers to the questions “Are you going to vote?” and “Who are you going to vote for?”. It should display the results of these questions nationally and for each constituency.
You may use any freely available programming language and modules. We will want to run and connect to your code on our own machines so if there are any unusual pre-requisites please document them.
You must not spend more than four hours on the task. We cannot, of course, tell if you decide to cheat, but if you do so you should be aware that [employer]’s strong ethos of integrity is not going to make it an ideal place for you to work.
We know four hours is not a long time, so please consider what you can realistically do in the time, and when you submit your work for review, please give us an idea of what you would do next if you had more time. We expect you to send us something that works, even if you have just put in stub code or dummy data.
As this is a learning practice code, there is large amounts of work that I wouldn't check-in or accept in code review. I have used:
- twig & localised twig
- services.yml for DI objects
- JS, jQuery
- Doctrine2 and Entities
- a stateless validation filter, there is no enum validator in the Symfony docs.
- .htaccess/ mod_rewrite
- Assetic asset management
- Forms, Form creation, and form validation for the POST
...which is standard. If you look at the later demos, they are written out much faster and easier.
This was a training build, it would be substantially faster for me to have written this inside my CMS iceline.
In theory this couple of pages could be configured to run without JS (this is why there are lots of little forms). However I don't have JSON to selectbox for PHP available, and this would break the action sequences. Edit: obviously I can make this in a twig, but I had assembled the JS already. To fix, I would have the no-JS version post to a second set of URLs, which wrapped the current ones, and did the form creation on the server-side.
Please note there is only one POST, as each data point is small. If anything blows up, you may loose the last 30s work, which doesn't seem an issue. This should be viewable fine over a mobile (can't test until the code is on a public network), as most of the input in select boxes. The text in the select boxes may fall off smaller screens, not sure what should happen in this situation...
This hasn't been setup for data security, but is anonymous. In other applications, one matches the IP to ensure session coherency, and for legal requirements, identify people. Under the stated goals, I can't do this here.
I am naming the JS files to be run as modules '*.js', and the files to be included once as data '*.json'. My PHP code also reads the json files. A higher performance impl may put this in the DB; but the gain won't be that much, as basically its a disk read. The file names match their contents. I named the PO, as previously I used real PO; I could have imported “maxakawizard/po-parser” from packagist, but on this scale don't need it.
It would obviously benefit if I put the JS in a tidy module. The JSON transmission is sensitive to format types, please ensure all requests are 'json' not 'jsonp'. The same host policy requires you to set the 'http://' in the front, rather than have it default to that.
This demo is made by its data. I attempted a version over a year ago but due to crampt time, couldn't assemble the raw data, so it failed.
To coordinate my sources, I have dumped everything into a DB, which is gross over kill (but the simplest means to match the county names up).
After spending over a day trying to tidy up the data into smaller units, I give up. The demo is smaller than its initial UX spec until I can get an actual list of constituencies with their county. As a *tech demo*, this doesn't represent failure.
- some wiki link
- List of MPs
- This was where my time went.
- This would take quite a few hours to extract, and so I didn't.
- many thanks David Boothroyd, of http://www.election.demon.co.uk/
This was to get each thing to work, with minimal side effects. I intensionally just made the libraries working, so I was concentrating on each thing separately. Unfortunately moving host broke the change log, as far my local GIT goes.
- (build 0) Assemble raw data in a useful fashion ~ this non code activity took about ten days after work.
- (build 1) Assemble bundle, create controllers, some views, the JS, add writing via PDO
- (build 2) Refactor code, as the Controllers are horrible. Stripping the JSON building reduces about 50% of the length, by making one general function.
- (build 3) Pull some of the Po out, as its “not a controller thing”, reduce Controller again.
- (build 4) I think that it should be using Doctrine, rebuild against this (create Entity/*)
- (build 5) Move code to new host, change version of PHP, Symfony, phpunit and have to rebuild DB. Also redo namespace to be more relevant to current situation (icelineLtd).
- (build 6) Remove all the JSON logic from the Controller as its “not a controller thing”.
- (build 7) Remove some of the doctrine code from the Controller as its “not a controller thing”, to a Service
- (build 8) As I have something that is okay OO, add all the docs and tests. Also delete a lot of unused code.
- (build 9) Revisit the JS. I could make this OO, but there doesn't seem return on investment.
As I was exploring, I didn't TDD. I can't talk with the domain experts to DDD. I kept adjusting the outcome, so didn't think BDD was useful. This represents how not to write code.
- Get constituency to county data.
- Work out why the date objects are being cached when rendering the previous votes dataset.
- Run on mobile. Adjust select box width as necessary. Currently I can't run on Mobile till its public.
- Add CSS as necessary
- Make the no-JS modality function. Put the JS into an object. I haven't due to coupling with the HTML.
- The Receipt class isn't testable in its current form. Fix this. The form dependency could be mocked.