Archive for the developer Category

How to validate Eloquent Models with dynamic patterns and multipe database connections

Loving Laravel and Eloquent Models

Well after some years sticking with Zend Framework, we at me’kono completely fell for Laravel as our main PHP Web development framework, which has a beautiful and easy to read MVC design pattern. One of the most frequently used Classes / Feature of Laravel is the Eloquent Class which – basically speaking – represents an entry in your database and adds methods and relations to it. One very important method is the save()  function obviously, which gathers all the data of the current object instance and tries to save it to the database.

Validation before saving

Since we didn’t want this method to simply run against the database and maybe return an error, the decision was made to have a validation before even starting the storage process. To make things more readable, the validation patterns are stored in a static array in the notation defined by the Laravel Validation Class:

To have these validation rules being applied each time the object gets stored to the database, simply override the save()  method with something like this:

And the isValid()  method we use comes here:

As you can see the method gets all attributes of the object, dynamically creates a Validator from the class’s validation rules and applies them. If validation fails the errors get stored in the object’s errors property. Hence you can better hunt down why storing the data ran into trouble.

Some special DB fields

Ok, this is pretty easy and straight forward, but occasionally you might run into the following problem:
Let’s pick up the common requirement that there should be no duplicate email address in your Users table, i.e. email should be unique. So you can change the validation rule to the following:

If you try this, it works fine if your user’s data is inserted once and then only read from the database, meaning you cannot update it. The eloquent update()  method also uses the save()  method. But since your email is already in the database, the logic just implemented prevents you from storing to the database.

But the guys from Laravel are clever and have taken care of this. You may specify an additional parameter for an ID, which should be ignored or is fine the have the same email (from the docs):

Make it dynamic

Almost there!

Just some additional thoughts: This way all your isValid()  methods have to be custom made for each model. And – you have to distinguish between save operations and update operations. So we came up with the idea of dynamic validation rules. The strings defining the validation are parsed before creation of the Validator and some variables of the object are filled in upon request (changes to above highlighted):

The syntax is dead simple: %[name of object property]$[printf output format]

The array_walk function  iterates over the validation rules and nvsprintf  applies the object properties to the validation strings.

Multiple DB connections and upgrading to Laravel 5.2

When we starting with Laravel, the framework stood at version 4, then we quickly moved to 5.1 – which is the first Long Term Support (LTS) Version of the framework and our project grew bigger and bigger. Now in some parts the framework is using two database connections – even in it model validation. So to search in the correct database for unique values, you have to define, which connection to use. In Laravel 5.1 this may look like this:

We created the Eloquent object over a specific database connection ( User::on('my-other-db')->find($user_public_id); ) and before updating it to the database, the Validator has to be assigned the same database connection.

Now in Laravel 5.2 the validateUnique() method of the Validator Class changed reading the database connection from the defining string. So the database connection has to be set in the validation rules. Since we already had implemented dynamic validation rules this was easy to achieve:

And a slight change to our isValid() method:

 

Aloha Editor: How to create toggling Toolbar Buttons?

As we are preparing our new admin section at me’kono, i was looking for a new up-to-date WYSIWYG Editor to use and finally thought to go with the aloha editor Version 2. To my disappointment the documentation at the time of writing is quite… ah, well… not the best – and simple questions popped up quite fast. So in this first post we’d like to share our findings and how to create toggling formatting buttons for your toolbar in the Aloha editor.

Let’s start where Leap 3 in the very short docs leaves you.

So you got your buttons defined like this:

and your jQuery event handler looks like this:

Now these event handler can set the selection to bold, italic, underline, etc. but don’t reset the style if you click once again. If you have a look at the predefined array of commands, there are no is no help either:

But the unformat object uses a method removeFormatting and after having a look at that, you can figure out how tags are applied on a basic level.

This can be applied to our click handler so we use the Editing.wrap  method too:

Short explanation:

  • aloha.ui.commands  are objects consisting of at least an action property – a function, which gets called. We create this on the fly on lines 5-9.
  • To calculate the tag to wrap around the selection we use the node property of the command in uppercase.
  • To get the clicked command we substract ‚action-‚ from the buttons class property

Well, this should now do the same as before. So what’s the deal here? It’s simple – just change the last parameter of the wrap method call to false and you and up with a toggling formatting button. We do this by checking if the clicked formatting button has the active property – which you should have if you have gotten to Leap 5: Update Button States in the tutorial and simply set an extra active attribute . So our final code looks like this:

So, we hope this helps you create a toolbar for your Aloha Editor with toggling format buttons.

 

Permalink Aside

So you could not resist getting yourself that free upgrade to OS X 10.9 Mavericks and now your local development environment went south? Or you are thinking of upgrading, but first want to know what problems you will have to face? So here is a short list of problems i ran into, what their causes are and how to fix them:

What’s not working (for me)

After upgrading these things were not working anymore:

  • no virtual hosts
  • no php
  • no mysql
  • no mcrypt
  • Zend generating timeouts in various modules

Detecting the first two was quite obvious, but why Zend framework resulted in timeouts was somewhat of a mystery in the first place. Mysql server worked nicely, as i checked that with Sequel Pro – contecting worked fine, all the data was there. So here are the reasons why stuff did not work on my machine:

Reasons for not working

  • no virtual hosts because the upgrade moved my vhost-file to a backup file and did not replicate the already created ones
  • no php because similar happened to the httpd.conf file where by default php module is commented out
  • no mysql (via php) because the default connection sockets are not set in the php.ini, where the previous version also got backup-ed
  • no mcyrpt because it is not completed in the new version coming with OS X 10.9 Mavericks, which is PHP 5.4.17 (at the moment)
  • the Zend timeout occurred because of the missing mysql socket of php

How to fix these problems

So, know that we know the reasons for the errors here are the links and ways to get your development mac up and running again:

  • Go to /private/etc/apache2/extra and check your httpd-vhosts.conf file or another where you have stored your virtual hosts. Usually it simply requires copying the old version indicated by ~orig at the end and renaming it the desired .conf file.
  • Check your httpd.conf (/private/etc/apache2) and enable php5 by uncommenting the line starting with LoadModule php5_module.
  • Reenabling Mysql: there are various websites on the net explaining how to enable mysql on php5 on a mac – so follow that or simply compare your /private/etc/php.ini.default (currently used) with your original from before the upgrade (/private/etc/php.ini-5.2-previous~orig, or similar). Especially watch out for instructions like „mysqli.default_socket = “ where the new version is empty.
  • Ok, installing mcrypt is a longer process. I followed the instructions from Neil Gee and it just worked – many thanks!
  • After your mysql socket is working properly Zend should also be humming again…

Hope this helps everybody who is keen to do the step to Mavericks – it really paid of for me. Just one simple fact to undermine my excitement: 10 GB extra space on my hard drive!!

get the least / greatest from multiple columns in mysql 5.x

Looking for the lowest or biggest value in multiple columns in a mysql table? There are two handy function in mysql, namely LEAST and GREATEST, which return the lowest / biggest value from the given list of parameters. Therefore, if you like to get the absolute minimum or maximum in the whole table over multiple rows, you could combine these two functions with MIN or MAX and use the following SQL statement:

SELECT MIN(LEAST(column1, column2, column3, column...)) FROM table1

But LEAST and GREATEST have some limitations concerning their handling of NULL values:

  • GREATEST returns NULL if any of the values is NULL
  • LEAST returns NULL if all values are NULL

The problem in my case was, that some columns in my table were not required and had to stay NULL and my statement – especially for retrieving the absolute maximum – failed to deviler the proper values. Searching for a solution was quite tedious, so I thought to share it, since it turns out to be pretty simple – just turn it around:

SELECT LEAST(MIN(column1), MIN(column2), MIN(column3), ...)) FROM table1