CakePHP CsvMigrations: prototype in 3 2 .. Done!

Every programmer is tired of coding yet another login form. Yet another CRUD view module. So today I’ll show you an example where our laziness can get you building prototype systems without a single line of extra code.

One of the tasks, that we had to face when developing Qobrix CRM, was fast prototyping of the system. The result of ultimate laziness and DRY concept resulted in cakephp-csv-migrations plugin that we try to use pretty much everywhere, while delivering the system.

Your application is not unique

Whatever you request for your Prototype is mostly based on same functionality:

  • CRUD views
  • Basic CRUD actions
  • Event/Trigger system that allows you mutating the data

If we dive deeper into these points, whatever you work with is form based – your input fields are the minimum atomic unit of interaction: strings, longtexts, datetime. Looks familiar? Exactly, database data types.

In certain cases, you store dates in strings, names in varchars, or even longtext. At this moment we come to the point of having a binding mechanism of your application logic with your storage engine. For simplicity reasons – I’d base this example on RDBMS like MariaDB, MySQL, etc.

Changing those binding might be difficult for the user. As the supplier of the system, you don’t know who’s going to deal with the system: some companies don’t have IT departments, but need to modify things rapidly. The same applies to developers level of expertise for the system. We wanted to make it as simple as possible.

Preparing the App

Note: If you already have a CakePHP application running, just composer require qobo/cakephp-csv-migrations, and you can skip this part.

Theory is boring without examples, so I’ll try to show you a basic thing on how to expand the system with extra modules. For simplicity reasons, I’ll base it on project-template-cakephp template that we frequently use. It already has some dependencies, as well as cakephp-csv-migrations plugin as part of cakephp-utils.

composer create-project qobo/project-template-cakephp baking_app
cd baking_app
./bin/build app:install DB_NAME="baking_app",CHOWN_USER=$USER,CHGRP_GROUP=$USER,PROJECT_NAME="My Baking App"

That’s enough to check that your app is up and running. For basic creadentials and stuff, you can check .env file that was generated by the Robo build scripts.

Baking Recipes Module

Here comes the baking part. We’re going to make a simple recipes module to store our favourite recipes.

./bin/cake bake csv_module Recipes
./bin/cake bake csv_migration Recipes

First command will create dummy MVC instances for CakePHP: Model/Entity, Controller and ApiController files, based on which the second script will verify that you can bake a migration script (based on Phinx migrations).

If you’ll look into migration file created in config/Migrations/<timestamp>_Receipts<timestamp>.php, you see something like that:

use CsvMigrations\CsvMigration;

class Recipes20180126154309 extends CsvMigration
        public function change()
        $table = $this->table('recipes');
        $table = $this->csv($table);

        if (!$this->hasTable('recipes')) {
        } else {

        $joinedTables = $this->joins('recipes');
        if (!empty($joinedTables)) {
            foreach ($joinedTables as $joinedTable) {

Where are the fields? That’s the point where all the magic happens.

CsvMigrations plugin provides you with vast number of input types that can bind to basic data types of your database. They’re stored in config/Modules/Recipes/db/migration.csv file. We’ll expand it a bit:


I’ve added name, type and recipe fields that can be handled by varchar and longtext data types in the database. Let’s cook it:

./bin/cake migrations migrate

And we are done! You noticed list(<list_name>) type used within migration.csv. This FieldHandler type is used for defined option lists for rendering Select boxes in you form. The lists are stored in config/Modules/Common/lists/meal_types.csv:

Where are my views?

If you start up the application, and navigate to http://localhost:8000/recipes/add you’ll see something like that:

add recipes form

Now we need to add fields to CRUD form. CsvMigrations can help you with that. All your form fields are located in config/Modules/Recipes/views:

Details,name, meal_type

The example above is for add/edit.csv files being modified. Reloading the add page:

add form complete
Complete add form

Now you’re ready to work with basic CRUD. All the common CRUD logic is already located in cakephp-csv-migrations plugin that will handle API requests for the index page for DataTables grid loading. If you want to change its behavior, you can always override action methods in `RecipesController`.


WordPress Gutenberg: it’s not about Text Editor

I wasn’t paying much attention after the announcement of Gutenberg projects from WordPress guys back in 2010’s.

I never had any dramatic impacts by CKEditor embedded in the WordPress admin panel. I still think it’s one of the best examples of UI/UX text editors on the Web. The whole development process caught my attention due to React licensing issue that got the Internet buzzing about for couple of months, until Facebook changed it.

And then I checked this video on the future of WYSIWYG editor and Gutenberg’s impact on the WordPress ecosystem.

This is huge! The whole ecosystem will change its standards of writing plugins/themes. The concept of expanding viewports going beyond the classical monitor resolution, including wearables and other portable devices. Block architecture. Enough with spoilers – just watch the video.

Fairwell 2017. New Year – new challenges

The end of this crazy year is almost around the corner, and I guess it’s the time to summarise it.


We finally got some time to travel abroad. Scotland was the destination. Nadia and I think on planning one more trip there; this time checking the West Coast of the country. Edinburgh, is definitely the city to consider moving, in case I’ll ever get tired of Cyprus.


2017 passed by the aegis of “Hold my beer!” Number of really challenging projects that were successfully launched in 2017. Couple of zombie-projects that had to be resurrected from the nearly dead condition so they could survive Black Friday and Christmas sales. And they did!

Surprisingly found myself coding lots of JavaScript at work and free time. Never thought of becoming a frontend developer, and still not planning to, but JS appears on my way more frequently then I expected (huh!).

Free Time

Is there any, duh?.. 2017 was full of different pivoting moments. Health wise, 3-month gym challenge proved that I can’t stand without it for long. It seems that this hobby is here to stay.

Hiking. I’d like to keep it on weekly basis, but apparently monthly period is more realistic (plus Cyprus is running out of hiking routes quiet fast with such pace!).

Back to normality. Apart of reading tech books, finally found some place for non-technical literature. Definite challenge of 2018 would be to finalise Hugo Awards list, which makes another 8-10 books remaining from 2017.

2018 Resolutions

Everyone likes lists. Lists are easier to memorise. It might help me remember, what I was planning for 2018. At least for a week.

  • Travel more!
  • More sports (Gym is fun, but with goal setting, is more challenging)
  • Figure out what kind of monster is(are): Python, Swift.
  • Pump my JavaScript/PHP madskillz.
  • Read more. A lot more.
  • Survive after quitting cigarettes.

Well, this looks like a list that I can accomplish, or at least try to 🙂


Happy New Year y’all! Now lots of food, festive mood, and wishes health, happiness, and whatever crazy comes in mind…

Over & out.

Puppeteer: NodeJS browser automation

Puppeteer is a Node library which provides a high-level API to control headless Chrome over the DevTools Protocol. It can also be configured to use full (non-headless) Chrome.

Demo is woth thousand words. API Documentation covers all the aspects of browser emulation/handling I could think of..

Whether it will be a replacement of NightwatchJS or a sub-component in the current end-to-end stack – fun times of trials & errors will tell.

NoSQL: MongoDB vs DynamoDB for Big Data storage

Minor quote on basic comparison of MongoDB vs DynamoDB from Amazon:

Engines DynamoDB MongoDB
Data Model
  • Key-value with JSON support
  • Up to 400 kb record size
  • Limited data type support
  • JSON-like document
  • Up to 16 mb record size
Querying Key-value queries Query & analyze data in multiple ways — by single keys, ranges, faceted search, graph traversals, and geospatial queries through to complex aggregations

In both cases they perfectly suite for big data storage. Both offer cloud-based (AWS, and Mongo Atlas) and local storage solutions.

Positive feedback on DynamoDB and its pricing policy  (pricing calculator):

Amazon lets you buy operations per second capability rather than CPU hours or storage space. This removes a whole lot of complexity for developers who would otherwise need to tune the database configuration, monitor performance levels, ramp up hardware resources when needed. This provides users a fast and reliable storage space for their needs with costs that scale in direct proportion to the demand.

For now, DynamoDB looks more favorable. The fact that it’s an AWS-only engine doesn’t set any limits. The overall stack of AWS tools that exists in their infrastructure looks promising.

HubSpot: Gatekeepers and Gardeners

HubSpot tech blog published great article on job balancing and tech leads paradox of gatekeepers gardeners.

You might be a gatekeeper if:

  • your team regularly waits for you to review their PRs
  • your team waits to do the next thing assigned to them instead of taking initiative to find projects for themselves
  • you hesitate to go on vacation because you’re concerned your team will struggle in your absence

On the opposite.

A gardener might:

  • forego reviewing work, or let other members of the team take on the responsibility
  • let the team handle their own task management, trusting they understand the needs of the customer, business, and team
  • encourage members to build relationships on and off the team
  • let the team experience failure, trusting in their accountability to fix their problems and learn from their mistakes
  • have their team take on grungy work along with the “fun” work, because they understand the value of it

Great overview of these two roles people occasionally take once becoming managers/tech leads.

Amazon AWS: Giant dilemma in IT

Microsoft, Google, Apple. Now Amazon. Whenever IT company becomes a leader in its niche, people start grumbling about its “evil” intents or monopolizing the market. Well, it’s natural for a market (i.e. capitalist) model. Monopoly kills competition, but to become a monopolist you have to really work hard to reach it.

Same happened with Amazon recently.

Amazon is a retailer, price sensitivity is in their DNA. In the past, when new companies like Digital Ocean have gotten large enough to show up on their radar they’ve reacted with deep price cuts.


Adding this all up, Amazon is terrifying to compete with.



Main Software Engineering cornerstone: Quality

Recently Paul M. Jones published great article on the Software Engineering major conflict between Business and Software worlds: Product quality that perfectly matches Robert L.Glass book I’ve been recently reading on “Facts and Fallacies of Software Engineering“. If you still didn’t read it – strongly recommended!

Just few excerpts on the article:

They [engineers] have a reputation to maintain. Low quality for their kind of work is bad for reputation among their peers. (Note that their peers are not necessarily their employers.)

They understand they may be working on the same project later; higher quality means easier work later, although at the expense of (harder? more?) work now.

And on the other side (dark side?..):

The reputation of the payer is not dependent on how the work is done, only that the work is done, and in a way that can be presented to customers. Note that the customers are mostly not the programmer’s peers.