Posted under » CakePHP on 17 July 2019
CakePHP provides a basic organizational structure that covers class names, filenames, database table names, and other conventions. While the conventions take some time to learn, by following the conventions CakePHP provides you can avoid needless configuration and make a uniform application structure that makes working with various projects simple.
Model Layer
In the case of a social network, the Model layer would take care of tasks such as saving the user data, saving friends’ associations, storing and retrieving user photos, finding suggestions for new friends, etc. The model objects can be thought of as “Friend”, “User”, “Comment”, or “Photo”. If we wanted to load some data from our users table we
could do:
use Cake\ORM\TableRegistry; // Prior to 3.6.0 $users = TableRegistry::get('Users'); $users = TableRegistry::getTableLocator()->get('Users'); $query = $users->find(); foreach ($query as $row) { echo $row->username; }
By using conventions, CakePHP will use standard classes for table and entity classes that have not yet been defined. If we wanted to make a new user and save it (with validation) we would do something like:
use Cake\ORM\TableRegistry; // Prior to 3.6.0 $users = TableRegistry::get('Users'); $users = TableRegistry::getTableLocator()->get('Users'); $user = $users->newEntity(['email' => 'mark@example.com']); $users->save($user);
Table names corresponding to CakePHP models are plural and underscored. For example users, article_categories, and user_favorite_pages respectively.
Field/Column names with two or more words are underscored: first_name.
Foreign keys in hasMany, belongsTo/hasOne relationships are recognized by default as the (singular) name of the related table followed by _id. So if Users hasMany Articles, the articles table will refer to the users table via a user_id foreign key.
For a table like article_categories whose name contains multiple words, the foreign key would be article_category_id.
Join tables, used in BelongsToMany relationships between models, should be named after the model tables they will join or the bake command won’t work, arranged in alphabetical order (articles_tags rather than tags_articles). If you need to add additional columns on the junction table you should create a separate entity/table class for that table.
In addition to using an auto-incrementing integer as primary keys, you can also use UUID columns. CakePHP will create UUID values automatically using (Cake\Utility\Text::uuid()) whenever you save new records using the Table::save() method.
Model Conventions. Table class names are plural, PascalCased and end in Table. UsersTable, ArticleCategoriesTable, and UserFavoritePagesTable are all examples of table class names matching the users, article_categories and user_favorite_pages tables respectively.
Entity class names are singular PascalCased and have no suffix. User, ArticleCategory, and UserFavoritePage are all examples of entity names matching the users, article_categories and user_favorite_pages tables respectively.
View Layer
The View layer renders a presentation of modeled data. Being separate from the Model objects,
it is responsible for using the information it has available to produce any presentational interface your application might need. For example,
the view could use model data to render an HTML view template containing it, or a XML formatted result for others to consume:
// In a view template file, we'll render an 'element' for each user.
<¿php foreach ($users as $user): ?> <li class="user"> <?= $this->element('user_info', ['user' => $user]) ?> </li> <¿php endforeach; ?>
The View layer provides a number of extension points like View Templates, Elements and View Cells to let you re-use your presentation logic. The View layer is not only limited to HTML or text representation of the data. It can be used to deliver common data formats like JSON, XML, etc.
View template files are named after the controller functions they display, in an underscored form.
The viewAll() function of the ArticlesController class will look for a view template in src/Template/Articles/view_all.ctp.
View template files are named after the controller functions they display, in an underscored form. The viewAll() function of the ArticlesController class will look for a view template in src/Template/Articles/view_all.ctp.
The basic pattern is src/Template/Controller/underscored_function_name.ctp.
The Controller Layer
The Controller layer handles requests from users. It is responsible for rendering a response with the aid of both the Model and the View layers.
A controller can be seen as a manager that ensures that all resources needed for completing a task are delegated to the correct workers. It waits for petitions from clients, checks their validity according to authentication or authorization rules, delegates data fetching or processing to the model, selects the type of presentational data that the clients are accepting, and finally delegates the rendering process to the View layer. An example of a user registration controller would be:
public function add() { $user = $this->Users->newEntity(); if ($this->request->is('post')) { $user = $this->Users->patchEntity($user, $this->request->getData()); if ($this->Users->save($user, ['validate' => 'registration'])) { $this->Flash->success(__('You are now registered.')); } else { $this->Flash->error(__('There were some problems.')); } } $this->set('user', $user); }
CakePHP’s conventions will take care of selecting the right view and rendering it with the view data we prepared with set().
Controller class names are plural, PascalCased, and end in Controller. UsersController and ArticleCategoriesController are both examples of conventional controller names.
Public methods on Controllers are often exposed as ‘actions’ accessible through a web browser. For example the /users/view maps to the view() method of the UsersController out of the box. Protected or private methods cannot be accessed with routing.
Here’s a final example that ties the conventions together:
Using these conventions, CakePHP knows that a request to http://example.com/articles maps to a call on the index() function of the ArticlesController, w here the Articles model is automatically available (and automatically tied to the ‘articles’ table in the database), and renders to a file.
None of these relationships have been configured by any means other than by creating classes and files that you’d need to create anyway.
Note: By default CakePHP uses English inflections. If you have database tables/columns that use another language, you will need to add inflection rules (from singular to plural and vice-versa). You can use Cake\Utility\Inflector to define your custom inflection rules. See the documentation about Inflector for more information.