CakeDC Blog

TIPS, INSIGHTS AND THE LATEST FROM THE EXPERTS BEHIND CAKEPHP

CakePHP Migrations plugin: easily version and deploy whole applications

This article is a quick introduction to the Migrations plugin, open sourced a few weeks ago by our company. You will see how simple it is to use the plugin and what you could do with it. I hope this article will show you the benefits of using migrations in your CakePHP applications and make you give it a try right after the reading!

Here is a one-sentence description of the plugin: the Migrations plugin allows developers to easily version and automate the creation / update process of any database schema and application data from the command line.

For information, CakeDC uses this plugin on its project since several years to make team collaboration and deployment easier. The plugin has been entirely rewritten a few months ago and fully tested (code coverage >95% as always at CakeDC) before being open sourced under the MIT license. It is now available to the community along with its documentation... and it is free!

Why is it useful?

It has been a while since companies integrated Source Code Management in their development process and CVS, SVN, Mercurial or Git are now common tools. Inspired from the open source movement it is also a good practice for single developers to version application source code.

As you might know, an application almost always depends of the database schema it is aimed to use... however it is not easy to version both the source code and database schema with a SCM. Let's take the example of a CakePHP application: until now the only way to do was to version a single file, either a sql dump or a CakePHP schema.php file generated with the cake schema shell. These two approaches are not very convenient to use on a daily basis, the first one forcing the developer to drop and recreate the whole database every time!

Moreover, a web application development is never really finished (there are always new features to add, software updates or bug fixing to do...) and deploying these change on a test or production server is always a delicate task.

Here comes the Migrations plugin! It provides a simple and easy way to version a database... and to perform many other different tasks thanks to its callback system. Here are some features:

  • keep a local database schema up-to-date: you just have to run all non applied migrations to update the local database schema to the latest version
  • make team work easier: when several developers work on the same application it is important that all of them work with the same database schema during all the development cycle. With migrations every commit is tied to the database schema at this precise instant, which makes easy switching branches and resetting a branch to a specific commit.
  • make installation and updates easier: ready to push the new version of your application live? You will only have to push the sources on the server and run all non applied migrations!
  • migrate more than database schema: the callback system allows you to do everything you want before (or after) applying (or reverting) each migration. Here are some examples: creating an initial admin account, add initial or test data to the application (lorem ipsums, categories, content...), update values from the database, send an email if debug > 0... The only limit may be your imagination ;)

Where can I find the code?

Announced a few weeks ago, a packaged version of the plugin can be downloaded from the new "Downloads" section of CakeDC.com. This page contains a link to download the 1.0 version, the plugin documentation and the Codaset project url for tickets and direct Git access to the repository.

To make people aware of the need to show their support to the Cake Software Fundation by donating a few bucks (this is unfortunately not done enough), the plugin was first available to donors only. The "Download without donation" button was added later, when the repository was made public! However, if you find this plugin useful please consider making a donation to the CSF... that is the best thing you could do for thanking us.

Click here to lend your support to: cakephp1x and make a donation at www.pledgie.com !

Even better! A sample application was also released for those who want to see how migrations could be used and integrated in an application. To play with it, Download the code or git clone the project using:

git clone git://codaset.com/cakedc/sample-migrations-application.git sample_migrations

You will only need to create a database.php configuration file and update CakePHP's core location to make the application work. Git users, run

git submodule init
git submodule update

to automatically add the migrations plugin as a submodule!

What do I need to use it in my application?

Note: the packaged plugin is for the CakePHP 1.3 version only. You can either download the 1.3-beta package of the framework, or use the 1.2 branch available in the Git repository.

Adding the plugin to an existing application is very simple. If you downloaded the archive containing the plugin code, unzip it in the "/plugins/migrations" folder of your application. Git users can add it as a submodule with the following command:

git submodule add git://codaset.com/cakedc/migrations.git plugins/migrations

To check that it is installed correctly, execute the following command from your application root (it will display the available command to use the plugin):

cake migration help

If you encounter any problem here, please read the official documentation about CakePHP's console usage.

How does it work?

This post is not aimed at providing a comprehensive tutorial on how to use the plugin, thus I will just introduce the most useful commands along with some use cases.

For a complete documentation, please read the official documentation provided on the plugin page. For a simple (but useful for understanding purpose) use case you can take a look at the sample application introduced above. Going through the commit history will allow you to understand how migrations could be used in a development process.

Create a migration

To generate a new migration, type the following command

cake migration generate

The tool will ask you to give a name to the migration and suggest to do a dump of the current database schema. If a "schema.php" file is found in the application, it will ask you if you want to generate a diff between this schema and your current database one.

Generated migration files will be added to the "/config/migrations" application directory.

Apply / Revert migrations

When you pull an application containing migrations, several commands are available to apply or revert migrations. The simplest one is:

cake migration

It will display all the found migrations along with their status (applied or not applied) and id number. Just enter a migration number to update your database to the correct version. Some convenience commands are also available. You can use:

cake migration up, down, all or reset

These commands will respectively:

  • apply the next migration
  • revert the latest applied migration
  • apply all non applied migrations (and thus update the schema to the most recent version)
  • revert all applied migrations (and empty the database)

Migrations for plugins

Adding plugins to an existing application often implies adding new tables to the database or altering existing ones. The Migrations plugin brings a quick and efficient way to automate this installation. On the one hand developers can easily add necessary migrations to their plugin (making upgrades easier), on the other hand users can apply them as easily.

The only difference compared with commands introduced above is the parameter "-plugin pluginname" that needs to be added. Here is how the user will install the database for the newly added / updated plugin "test":

cake migration run all -plugin test

I would like to highlight the fact that callbacks allow the developer to do everything they want before / after each migration. It is convenient for adding initial data, and one can even implement a callback method opening the bootstrap.php file to append plugin's configuration entries there (it is just an example ;)).

... going further

Of course, feel free to add any remark or example of migrations use in the comments.

As this post is not aimed at providing support for the plugin, I recommend you to use the official tools available:

  • If you found a bug or want to suggest enhancements: open a ticket!
  • An installation problem or a question about the plugin usage? Ask your question to the community on CakeQs!
  • You would like a custom version of this plugin, or professional related services... contact us, it is our job ;)

I hope you enjoyed this post, it is now time for you to start playing with the Migrations plugin...

Latest articles

Towards Data Integrity: Validations and Behaviors in CakePHP 3.0

  Validation
Let us consider “validation” in a little more detail to see how it has been implemented and optimized in CakePHP 3.0. In addition to what we discussed in the earlier sections, validation now incorporates two complementary conceptions or areas. These include 1) data type and format validation and 2) Application rules. 1. Data Type and Format Validation This part of the validation deals structural aspects such as data type, format validation, and basic types. Unlike in previous versions, validation is applied before ORM entities are created. This is a very useful feature that ensures everything is totally in sync and set in a way that preserves data integrity and the overall stability of the entire application. Moreover, it markedly reduces application errors and inconsistencies throughout the system. It is therefore a significant enhancement over previous versions. 2. Application Rules Application rules are the second component of validation in CakePHP 3.0 implementation. They play a key role in quality control to ensure that all application rules and workflows are operating in an orderly and systematic fashion. This is implemented through buildRules() method in tables. Here is a code example that uses buildRules() method for articles table. // In src/Model/Table/ArticlesTable.php namespace App\Model\Table; use Cake\ORM\Table; use Cake\ORM\RulesChecker; class Articles extends Table { public function buildRules(RulesChecker $rules) { $rules->add($rules->existsIn('user_id', 'Users')); $rules->add( function ($article, $options) { return ($article->published && empty($article->reviewer)); }, 'isReviewed', [ 'errorField' => 'published', 'message' => 'Articles must be reviewed before publishing.' ] ); return $rules; } }   Identifier Quoting Identifier quoting is another CakePHP feature or process that has changed in CakePHP 3.0. In the new release, quoted identifiers, which were expensive and involved a notoriously error-prone process of parsing SQL snippets has been disabled by default - thereby removing a major source of frustration for developers. The only time you may want to enable identifier quoting is when working with column names or table names with special characters or reserved words. Here is how to enable identifier quoting when configuring a connection. // In config/app.php 'Datasources' => [ 'default' => [ 'className' => 'Cake\Database\Driver\Mysql', 'username' => 'root', 'password' => 'super_secret', 'host' => 'localhost', 'database' => 'cakephp', 'quoteIdentifiers' => true ] ],
Note: Identifiers in QueryExpression objects require manual quoting or IdentifierExpression objects.   Updating Behaviors Let us now turn to behaviors. As with most features that has to do with ORM, the way behaviors are setup and configured has evolved for smooth integration with the new framework. Among other things, behaviors now attach to table instances. Here are some other significant differences in the way behaviors are handled in CakePHP as compared to earlier versions. 1. Each table that uses a behavior will have its own instance. No storing of “name space” setting in a behavior is required. 2. Method signature for mixin, callback, and base class for behaviors have all changed 3. Finder methods can now be added easily by behaviors.   The above, in a nutshell, summarizes the main changes and enhancements in the new ORM and CakePHP 3.0 in general. Like all major releases or upgrades, the new release supplants many processes and functions in previous versions while at the same time adding many brand new features. But as you go through the initial learning curve, please remember that you, the developer, have been the primary driving force behind the changes and enhancements. Your feedback and critiques over the years was the invaluable source that inspired CakePHP team to produce this groundbreaking and cutting-edge release that you are reviewing.

CakePHP ORM 3.0 Unleashes New, Flexible, and Powerful Functions

  In line with its overall goal of eliminating redundancy and increasing efficiency, the new ORM has replaced several functions in the earlier versions with newer and significantly improved functions or functionality. Among the functions affected, we will confine ourselves here to three functions, commands, or processes: 1. afterFind or virtual fields Developers of previous versions will recall how extensively they had to use afterFind callback and virtual fields to generate data properties. In the new CakePHP 3.0, this is no longer necessary and has been removed in favor of virtual properties on entities which are easier and more powerful. For example, using this method, properties can be generated on the fly to user entities with both first and last names by adding an accessor for full_name. Here is a code example. By defining accessors you can provide access to fields/properties that do not actually exist. For example if your users table has first_name and last_name you could create a method for the full name: namespace App\Model\Entity; use Cake\ORM\Entity; class User extends Entity { protected function _getFullName() { return $this->_properties['first_name'] . ' ' . $this->_properties['last_name']; } } You can access virtual fields as if they existed on the entity. The property name will be the lower case and underscored version of the method: echo $user->full_name; Do bear in mind that virtual fields cannot be used in finds. Once a code segment similar to the above has been defined, the new property can be accessed easily using $user->full_name. Moreover, you can build aggregated data sets from your results. Note also that though virtual fields no longer constitute an explicit feature of ORM, you will still be able to achieve the same result using query builder and expression objects which are more powerful and flexible. Here is a code example that will make this clear. 2. Definition of Associations Another extremely important feature introduced in CakePHP 3.0 is the use of methods to create associations. Instead of defining associations using properties like $belongsTo and $hasMany, this significant attribute uses methods that bypass the many inherent limitations of class definitions by allowing only one way of defining associations. Furthermore, the same API handles the “initialize” method and all other parts of your application code when manipulating associations. This is much more efficient and significantly improves productivity. Here is a code snippet to illustrate this. class ArticlesTable extends Table { public function initialize(array $config) { $this->belongsTo('Authors'); $this->hasMany('Comments', [ 'className' => 'Comments', 'conditions' => ['approved' => true] ]); $this->hasMany('UnapprovedComments', [ 'className' => 'Comments', 'conditions' => ['approved' => false], 'propertyName' => 'unapproved_comments' ]); } } Beside the use of methods to create associations as shown in the example above, the awkward name hasAndBelongsToMany has been renamed to belongsToMany. As if the above enhancements were not enough, CakePHP 3.0 has equipped developers with the ability to create custom association classes which will be a welcome relief as a safety valve for situations where the built-in relation types do not meet specific requirements. For more details on creating associations, please consult our section: Associations – Linking Tables together. 3. Validation Rules Validation plays a crucial role in all software development efforts but if they are to contribute to the overall productivity of the development cycle, the way they are defined and used must be straightforward and easy. When it comes to validation rules, CakePHP 3.0 team introduced an elegant solution to many problems with earlier versions through the use of Validator object to generate validation rules. With this feature, defining multiple sets of rules has become a breeze! Here is an example:   class UsersTable extends Table { public function validationPasswordConfirm(Validator $validator) { $validator ->requirePresence('password_confirm', 'create') ->notEmpty('password_confirm'); $validator->add('password', 'custom', [ 'rule' => function ($value, $context) { $confirm = Hash::get($context, 'data.password_confirm'); if (!is_null($confirm) && $value != $confirm) { return false; } return true; }, 'message' => __d('Users', 'Your password does not match your confirm password. Please try again'), 'on' => ['create', 'update'], 'allowEmpty' => false ]); return $validator; } } In Patch entity validationPasswordConfirm will be applied if is passed in ‘validate’ param.   $user = $this->Users->patchEntity($user, $this->request->data(), ['validate' => 'passwordConfirm']); What is noteworthy about the above code segment is the ability to define as many validation methods as needed. Notice how each method should be prefixed with validation and should be structured to accept a $validator argument.

How CakePHP can boost your organization's productivity while saving you money

  As the name suggests, CakePHP is a delightfully easy-to-use framework for rapid application development (RAD). It has evolved to become the most advanced and the most sought-after rapid application development in PHP. Part of this popularity stems from the framework’s ability to simultaneously fulfill the needs of the various stake holders to a project including business owners, project managers, developers, and system administrators. If you are a business owner, you will love CakePHP because it requires no purchasing costs and no licensing fees. Moreover, the entire development cycle from conception to development to deployment is so breathtakingly simple that it can be completed in a matter of weeks. This is possible because CakePHP, from its very inception, was designed to streamline and simplify the process of delivery. The precious time and effort that is often wasted in frantically wrestling with code to make it work can instead be redirected to building a feature-rich site. If you are a project manager, CakePHP is an answer to your projects. You will be relieved to find out that it resolves many issues that pestered you in the past. First, costing less than a fraction of what other commercial products charge, it will neatly fit your business plan whatever the size of your organization. Second, assembling a team of highly qualified developed will be easy due to the abundance of PHP developers. Third, it requires little training or coaching due to its intuitive simplicity and the lots of clear documentation that come with it. And finally, its functionality can be expanded and enhanced to meet the growing demands and needs of a project or an organization. Likewise, if you are a developer, you will find CakePHP markedly boosts your productivity and the quality of the final deliverable you hand over. Furthermore, it obviates the need for the often tedious and prone to error process of integrating different components. With CakePHP, you can have a fully functional unit in half a day or so because code generation tools do much of the work for you. From simple design and syntax to application scaffolding and code generation tools, CakePHP makes it easy for all developers regardless of skill levels to achieve quick results with minimum effort. Even developers with little or no previous web development experience will be able to learn it and figure out its syntax and conventions. Another important feature of CakePHP is its innovative implementation of “convention over configuration” concept that drastically reduces the overall size of code. This is a technique that bypasses endless configuration and setting by attributing special meaning to names given to tables, fields, directories, classes etc… To this end, CakePHP requires adherence to naming conventions. MVC is also another aspect of CakePHP that contributes to its flexibility and robustness. By dividing the system into three distinct self-contained layers according to function, CakePHP ensure the maintainability and manageability of your code. Last but not least, system administrators will appreciate the ease with which CakePHP can be installed on an existence system. A ready-made package, the framework is easy to decipher and configure. Plug-ins and third party libraries are also available for added functionality when and if needed. Additionally, it has a flexible directory structure, solid security infrastructure, and support for the most popular databases. All a system administrator need to do to get the ball rolling is to download the code; define databases, and set file permissions and, voila, the system is ready to go! The above is a brief synopsis of what CakePHP can do for you. Whether what you want is rapid prototyping or the creation of full-fledged website, you will find all the necessary tools within CakePHP. Please contact us if you have questions or need a more detailed explanation of its many features.

BOOK A 15 MINUTES FREE
CONSULTING WITH US:
We Bake with CakePHP