CMS Tutorial - Creating the Database

Now that we have CakePHP installed, let’s set up the database for our CMS application. If you haven’t already done so, createan empty database for use in this tutorial, with a name of your choice, e.g.cake_cms. You can execute the following SQL to create the necessarytables:

  1. USE cake_cms;
  2.  
  3. CREATE TABLE users (
  4. id INT AUTO_INCREMENT PRIMARY KEY,
  5. email VARCHAR(255) NOT NULL,
  6. password VARCHAR(255) NOT NULL,
  7. created DATETIME,
  8. modified DATETIME
  9. );
  10.  
  11. CREATE TABLE articles (
  12. id INT AUTO_INCREMENT PRIMARY KEY,
  13. user_id INT NOT NULL,
  14. title VARCHAR(255) NOT NULL,
  15. slug VARCHAR(191) NOT NULL,
  16. body TEXT,
  17. published BOOLEAN DEFAULT FALSE,
  18. created DATETIME,
  19. modified DATETIME,
  20. UNIQUE KEY (slug),
  21. FOREIGN KEY user_key (user_id) REFERENCES users(id)
  22. ) CHARSET=utf8mb4;
  23.  
  24. CREATE TABLE tags (
  25. id INT AUTO_INCREMENT PRIMARY KEY,
  26. title VARCHAR(191),
  27. created DATETIME,
  28. modified DATETIME,
  29. UNIQUE KEY (title)
  30. ) CHARSET=utf8mb4;
  31.  
  32. CREATE TABLE articles_tags (
  33. article_id INT NOT NULL,
  34. tag_id INT NOT NULL,
  35. PRIMARY KEY (article_id, tag_id),
  36. FOREIGN KEY tag_key(tag_id) REFERENCES tags(id),
  37. FOREIGN KEY article_key(article_id) REFERENCES articles(id)
  38. );
  39.  
  40. INSERT INTO users (email, password, created, modified)
  41. VALUES
  42. ('cakephp@example.com', 'secret', NOW(), NOW());
  43.  
  44. INSERT INTO articles (user_id, title, slug, body, published, created, modified)
  45. VALUES
  46. (1, 'First Post', 'first-post', 'This is the first post.', 1, now(), now());

You may have noticed that the articles_tags table used a composite primarykey. CakePHP supports composite primary keys almost everywhere allowing you tohave simpler schemas that don’t require additional id columns.

The table and column names we used were not arbitrary. By using CakePHP’snaming conventions, we can leverage CakePHP moreeffectively and avoid needing to configure the framework. While CakePHP isflexible enough to accommodate almost any database schema, adhering to theconventions will save you time as you can leverage the convention based defaultsCakePHP provides.

Database Configuration

Next, let’s tell CakePHP where our database is and how to connect to it. Replacethe values in the Datasources.default array in your config/app.php filewith those that apply to your setup. A sample completed configuration arraymight look something like the following:

  1. <?php
  2. return [
  3. // More configuration above.
  4. 'Datasources' => [
  5. 'default' => [
  6. 'className' => 'Cake\Database\Connection',
  7. 'driver' => 'Cake\Database\Driver\Mysql',
  8. 'persistent' => false,
  9. 'host' => 'localhost',
  10. 'username' => 'cakephp',
  11. 'password' => 'AngelF00dC4k3~',
  12. 'database' => 'cake_cms',
  13. 'encoding' => 'utf8mb4',
  14. 'timezone' => 'UTC',
  15. 'cacheMetadata' => true,
  16. ],
  17. ],
  18. // More configuration below.
  19. ];

Once you’ve saved your config/app.php file, you should see that ‘CakePHP isable to connect to the database’ section have a green chef hat.

Note

A copy of CakePHP’s default configuration file is found inconfig/app.default.php.

Creating our First Model

Models are the heart of a CakePHP applications. They enable us to read andmodify our data. They allow us to build relations between our data, validatedata, and apply application rules. Models build the foundations necessary tobuild our controller actions and templates.

CakePHP’s models are composed of Table and Entity objects. Tableobjects provide access to the collection of entities stored in a specific table.They are stored in src/Model/Table. The file we’ll be creating will be savedto src/Model/Table/ArticlesTable.php. The completed file should look likethis:

  1. <?php
  2. // src/Model/Table/ArticlesTable.php
  3. namespace App\Model\Table;
  4.  
  5. use Cake\ORM\Table;
  6.  
  7. class ArticlesTable extends Table
  8. {
  9. public function initialize(array $config): void
  10. {
  11. $this->addBehavior('Timestamp');
  12. }
  13. }

We’ve attached the Timestamp behavior which willautomatically populate the created and modified columns of our table.By naming our Table object ArticlesTable, CakePHP can use naming conventionsto know that our model uses the articles table. CakePHP also usesconventions to know that the id column is our table’s primary key.

Note

CakePHP will dynamically create a model object for you if itcannot find a corresponding file in src/Model/Table. This also meansthat if you accidentally name your file wrong (i.e. articlestable.php orArticleTable.php), CakePHP will not recognize any of your settings and willuse the generated model instead.

We’ll also create an Entity class for our Articles. Entities represent a singlerecord in the database, and provide row level behavior for our data. Our entitywill be saved to src/Model/Entity/Article.php. The completed file shouldlook like this:

  1. <?php
  2. // src/Model/Entity/Article.php
  3. namespace App\Model\Entity;
  4.  
  5. use Cake\ORM\Entity;
  6.  
  7. class Article extends Entity
  8. {
  9. protected $_accessible = [
  10. '*' => true,
  11. 'id' => false,
  12. 'slug' => false,
  13. ];
  14. }

Our entity is quite slim right now, and we’ve only setup the _accessibleproperty which controls how properties can be modified byMass Assignment.

We can’t do much with our models right now, so next we’ll create our firstController and Template to allow us to interactwith our model.