Kuotes Admin section structure and DB in CakePHP

Except the login page, I don’t think any other resource should be made public.

Hence, the only public page is “Login”! (duh!).

Purpose of the admin panel is to allow a user (an Admin user, that is) to be able to manage (add/update/remove/archive/disable) Kuotes (for the Kuotes App).

Considering the above set of functionality, and the fact that basic searching, sorting, pagination etc would be required as well, following is the (high level) list of features/sections/pages that is expected to be developed (this week?, today?):

  1. Dashboard (high level stats for admin)
    1. Total number of kuotes
    2. Active/Inactive (disabled + archived)
    3. Without photo?
    4. User generated (not yet?)
  2. List of kuotes
    1. List view : Author, Kuote, Date added, status, owner (Admin / User)
    2. Search (Author name, Kuote text, Date added, status)
    3. Pagination (Previous, 1-n, Next)
    4. Sorting (Author, Date, Status)
    5. Edit
    6. Delete
    7. View
  3. Manage Authors
    1. Name
    2. Photo (optional)
  4. Add new Kuote
    1. Select Author name (select dropdown, and if not found then input field)
    2. Add Kuote
    3. Add Photo (optional)
    4. Custom date-added (optional)
    5. Status (optional, defaults to Active)
    6. Owner (optional, defaults to Admin)
  5. Edit Kuote
    1. All of the Add new Kuote features/options
  6. Delete Kuote
    1. Soft delete (change status to Delete in DB, and set a deleted_at timestamp)
    2. All queries in the application to exclude all kuotes with deleted_at status (need to see how best to manage this, or at each request method)
  7. Logout (!!)


Future features to be added:

  1. Allow users to login and perform actions (akin to the Admin ones above) for their own kuotes (added from App or from Web)
  2. Generate a Pull Request of sort to Admin to include their Kuote as Public kuote (generated personally or referring an existing Kuote)
  3. Photo view in Admin and User sections to allow setting a default photo against a Kuote (allowing app-users to be able to customise it, but still have a default one)


That’s it about the features and now moving towards the DB structure.


  1. Users
    1. ID (Numeric?)
    2. Name
    3. Email
    4. Password
    5. Role (defaults to Owner/Admin for Kuotes)
    6. Email verified at
    7. Status (or Active perhaps?)
    8. Created
  2. User Logins
    1. ID
    2. User ID
    3. Login status (logged in successfully or not)
    4. Consecutive attempts (before logging in successfully)
    5. IP address (In either case)
    6. Browser/Meta info (Log all server info available with request)
    7. Created
  3.  Authors
    1. ID
    2. Name
    3. Photo
    4. Created
    5. Status
  4. Kuotes
    1. ID
    2. Author ID
    3. Kuote
    4. Date Added
    5. Status
    6. Deleted At (defaults to null)
    7. Owner (Defaults to null/0, for Admin/Kuotes)
    8. Photo
    9. Created

Looks like these 4 tables should be fine/enough. If required then more info would be added.

This will be deployed to GCP at (probably): kuotes-admin.konnector.dev or kuotes.konnector.dev or even kuotes.konnector.dev/admin


CakePHP 1 | Install, configure, DB migrations

We won’t be walking or jogging, let’s run. Let’s call this run pastry  😉

  1. Create a folder in your server’s web root (/var/www/html in Ubuntu/Apache)
    mkdir pastry and then go inside this folder cd pastry.
  2. Run composer create-project --prefer-dist cakephp/app ./
    This will download latest version of CakePHP from the template/skeleton repo app at github.com/cakephp/app in the current folder (the ./ part tells composer to install in this folder, rather than creating another folder inside this).
    Once cakephp/app package and all the dependent packages are installed, there will be a prompt to set folder permissions (for logs/cache etc). Press Enter on the prompt, or n if you want to set the permissions later or with a different access level.
    After the permissions are set, Security.Salt value will be updated in config/app.php automatically (this will be referred in the next step).
  3. Go to config folder : cd config
  4. Copy .env.default to .env : cp .env.default .env
    Note : Environment variables would be used rather than changing the code files, to keep code consistency across different deployment environments.
  5. Open bootstrap.php and un-comment following lines:
    if (!env('APP_NAME') && file_exists(CONFIG . '.env')) {

    $dotenv = new \josegonzalez\Dotenv\Loader([CONFIG .'.env']);

    As of writing this post, the above code is near line number 55.
    Un-commenting the above lines enable loading environment variables from .env file

  6. Go back to the main folder : cd ..
  7. Run code . : This will open VS code with current folder opened by default.
    From this point onward folder/file path will be mentioned, but not exact commands. Either you know them already (and these commands seem very trivial and stupid to include in the first place) or you would use VS code (or whatever other editor/IDE you prefer) and there would be different commands/actions to perform those actions.
  8. Open config/app.php, copy (or cut) the long string against SECURITY_SALT key, and paste it in .env file against the variable SECURITY_SALT.
    What we are doing here is keeping the code clean from any variables and using .env file for any environment changes.
    I cut the string (not copy) so that it looks like this:
  9. Open .env file and update APP_NAME and set it to any relevant name. I have set it to pastry.
    Un-comment the line with variable DATABASE_URL  and update the value in following format:
    The first pastry is DB username, and you might have something else (may be root, you shouldn’t use root for all projects, but that’s a different concern).
    The second pastry is the password.
    I have also kept the database name as pastry, which is set as APP_NAME, but if you have set it up differently, then instead of the variable ${APP_NAME}, use the DB name that you have set.
  10. Open Apache URL in browser for this folder.
    I have URL like localhost/pastry and you should be able to see all checks marked as green, as per following screenshot:
    CakePHP default home page
  11. Go to terminal (in the pastry folder) and run following command:
    bin/cake bake migration CreateUsers first_name:string? last_name:string? email:string:unique:EMAIL_INDEX password:string created modified active:boolean email_verified:boolean email_verified_at remember_me_token:string?

    Break down of above command:
    bin/cake – Cake shell (like artisan in Laravel)
    bake – Parameter to create files based on other parameters
    migration – Creates DB migration
    CreateUsers – The migration is set to Create table by name Users

    Rest of the part are columns with some specifications, in following format:
    The question mark following the fieldType will make the column nullable.
    The command will create Migration file that will be used in the next step to create DB table with specifications mentioned in this file.
    While this command is used to create the migration file, the file can be created manually as well. Additionally, I recommend opening the file (located inside config/Migrations folder) and review it to get a better understanding of the migration file, and also to fine tune if needed.

  12. Execute migrations by running following command:
    bin/cake migrations migrate
    This will create the DB table as per the specifications in the migration file.
    If there are multiple migrations created in the above step, then all will be executed with this command.
    Running this command again will NOT run previously executed migrations again.
    The log of migrations are stored in phinxlog DB table (created when this command is executed first time).


Bake command will be used in next post(CakePHP 2) to auto generate Controller, Model and View files.



CakePHP 0

This post is a first one to cover CakePHP commands for setting up a project.

I am not sure how to document this in the right/best way, so I am `starting` – the first right thing to do – and will see how this takes shape.

GitHub repo or gists would be linked wherever applicable.

Consider this CakePHPFristPost (frist = first; for those who don’t know, you don’t know).

#CakePHP_0 (the prerequisites)

1. You should have a DB setup (this is not going to be a beginner level series) and hostname, db name and db credentials should be handy. Default values used in examples/samples would be hostname=localhost, db=cakephp, username=jd, password=jd

2. Composer should be installed (globally) : Google for installation instructions

3. Ubuntu : At the time of writing this (Nov, 2019) 19.10 is out, I am using 19.04 and last LTS version available is 18.04 and either of these can be opted for development. Anything older than 18.04 would also work, any dependencies or issues comprising because of compatibility of OS would be your cake to digest.
If you do not have Ubuntu setup, then please use a VM to set it up (VMware player, virtualbox, workstation are some popular VM tools), or use Docker (this will feel more advanced if you are already NOT familiar with VM and/or Ubuntu, but this will make things much simpler for ongoing development).

4. CakePHP 4.x is not yet out of development pipeline, hence 3.x latest version would be used (3.8 at the time of writing this). Although 4.x would work as well, I have not explored it yet (on that note, I haven’t explored 3.x either – this is a learning moment for me that I am trying to document so any problem that you face might be worthy sharing considering I might also be struggling with the same one).

5. Git : Use any git provider – GitHub, BitBucket, Gitlab, GCP source repo or anything else for that matter – this would be otherwise optional, but I heavily use git (GitHub + Gitlab + GCP source repos) so a lot of my planning/managing code involves switching branches for different reasons (even for testing something small, or even a full fledged project on a branch) so if you are seeing this and would potentially would follow through other posts/series, then be ready to work in a git-enabled setup. If you don’t know git or are not comfortable with (g)it then, seriously – are you living under the rock?
Stop here, Google/GitHub/Medium/Documentation/Tutorial – whatever floats your boat – and then continue. You will thank yourselves.

6. Apache is the web server that I would be using. There is Nginx and probably other servers that can be used, but I feel more comfortable to use this for local development, and since most of the common hosting solutions have Apache as the default version so less configuration changes to debug.

7. Visual Studio Code, VS Code, is the editor (it gives major IDEs a run for their money) that I would be using for development (setup, screenshots, videos etc).
A good editor, configured right, is a tool that is often under valued, and this will be addressed in some posts.


Before you would have read and setup above, next post would be up to start CakePHP installation (start, not finish).

Have a system ready with following and let’s roll

  1. Ubuntu – OS
  2. Apache – Web server
  3. MySQL – DB
  4. PHP 7.3 (Duh!!)
  5. Composer – Dependency manager
  6. Git – Version control

CakePHP 0 concludes

On a second thought, if you are here reading about CakePHP, you should have almost everything setup already, never mind.


CakePHP – The beginning of taking the ownership of setting things right

With great power comes great responsibility – Uncle Ben aka Taylor Otwell 😉


– Laravel, comparison to CakePHP, and ownership model
– The realization (of difference in ownership)
– Impact, blockers and opportunities for me
Laravel, comparison to CakePHP, and ownership model
Taylor Otwell, the creator of Laravel, was perceived by me as an arrogant individual when I first starting to learn what Laravel is and who Taylor is.

I have been brought up during the era of CakePHP, WordPress, Magento, CI, Yii, Zend (and some other frameworks) and these frameworks are great frameworks.

They get shit done, and wow, in such awesome ways possible (genuine awesomeness and with a pinch of sarcasm as well).

None of these frameworks is owned by an individual (unless I am really ignorant about this fact), and when I go see Laravel’s homepage it says “Trademark of Taylor Otwell” and I am like “whoa… that’s arrogance”.
He is not the only one who has contributed to the development and success of Laravel, there are numerous other people (working directly on the framework, creating libraries, conducting training, sessions, conferences etc) and yet Laravel is “owned” by Taylor Otwell.
I had this discussion with quite a few people, specifically with @svikramjeet about possible reasons for this “attitude”. I was convinced that Laravel should be a an organization, under which Taylor work and operates, and yet there was no lack of people moving to Laravel (a very young framework) leaving all other mature frameworks with their well-known features and a lot of blogs and articles and training materials floating around the web.

Not until recently, a few months back, when it has been over a year since this thing have been bugging me, that I had a realization that made me change me thought process.

The realization (of difference in ownership)

Something went wrong in a version of Laravel 5.8.4 and some of the dependencies were behaving abruptly (due to removal of PutEnvAdapter).
Following links contain more info:

Taylor was on vacation, and he mentioned this in one of the thread linked above, and he promptly got the issue fixed and released the next version the next day.
This is a clear example of move fast, break things and till that day I was not able to realize this phrase. I understood, but now I realized what it meant – the worry of things going wrong should not stop you from experimentation, be courageous enough to own the process and confident enough to get things back on track if something goes south.

If this was CakePHP, then such an issue would not have happened in the first place.
And the fix might not have been so quick either.

There are very good processes in place that would prevent preventable issues to crop up, and that means there would be a lot more checks/considerations when talking about a release, which means a slower delivery schedule, a more controlled release process, which eventually means fewer contributions by newer generation of developers – these young folks are smart(er), work fast(er), expect feedback fast(er) because they are impatient, owing to the technical environment these young minds have been exposed to.

While the instant gratification process is definitely wrong, but since it is out there (yet) and there are developers who are suffering from this issue, and are good/awesome developers, they agree and align more with individuals rather than organizations or processes​. They are OK with broken things (the Zuckerberg-inspired people) as long as those are fixed soon as well.

The “So what?” attitude really helps here – yes, some code was wrong, it was fixed in less than a day, “So what?”.

Additionally, people want someone to look up to – I, for one, cannot look up to “CakePHP” as a framework or as an organization, rather I would look up to “Mark Story” or “Taylor Otwell” – the people who get things done, who inspire, instil a notion of “get-shit-done”, and are there to answer us when we reach out to them on Twitter.

Even if CakePHP Twitter handle responds, it is not guaranteed to respond every time, but when Taylor or Mark will reply, then a whole lot of “looking-up-to-them” people will reply.

I don’t know if I am rightly addressing the cause (or even if it is a right cause), and I haven’t proof-read the above content.

I am writing, and once I am done, I will hit “Publish”, I am impatient, I don’t care if some typo or a incorrect sentiment goes out, I will reply in the comments if someone asks me something, and I will acknowledge and own if something is wrong. I had no intention to hurt any individual or organization, so I know (and I am confident) that my words would not come out as hurting, but if someone would be looking for “getting hurt”, the person will find something that fits the “use case” – and yes, I won’t care.
I used to think that I belong to an older generation, but I think there are some traits that I am following.


So what’s next?

I am going to set some things right in the world of CakePHP, not necessarily because things are going wrong, but because I believe I would want to see someone respond when I there is a need to respond, someone who can understand the context, be ready rewrite everything that is out there because someone might really be talking about something small that requires an overhaul of the things.

In last few months I have felt the need for someone to act like CakePHP’s T. Otwell, M. Said, J. way, and although I found people who were close, I wanted more, and unless I find someone else, I am going to own this – this is a strong sentiment and it took me 20 minutes to write this single line because of the responsibility and ownership this needs (and I will grow where I lack).

Good luck, and god speed…