Check out my visual testing tool https://diffy.website. It helps to save testing time during deployments and development.
There are a lot of articles on internet about functional PHP. There is very nice presentation about it http://munich2012.drupal.org/program/sessions/functional-php that was held in Munich.
I was thinking about applying techniques to every-day coding and came up with two quite useful examples.
Usually functions that generate form arrays are big. Sometimes they are very big and it is getting complicated to understand fast what elements are in the form and what are their properties.
This example is trying to address this problem.
<?php $textfield = array('#type' => 'textfield'); $required = array('#required' => TRUE); $size = function($number) { return array('#size' => $number); }; $size_maxlength = function($number) { return array('#size' => $number, '#maxlength' => $number); }; $form['first_name'] = $textfield + $size(20); $form['last_name'] = $textfield + $size(20); $form['business_name'] = $textfield + $size(20); $form['account_number'] = $textfield + $required + $size(20); $form['pin'] = $textfield + $required; $form['ssn'] = $textfield + $required + $size_maxlength(4); $form['phone_number_part1'] = $textfield + $required + $size_maxlength(3); $form['phone_number_part2'] = $textfield + $required + $size_maxlength(3); $form['phone_number_part3'] = $textfield + $required + $size_maxlength(4); ?>
Now it is pretty clear what elements are and what properties they have. If you will ask about default values or titles – default values are assigned to elements using
<?php foreach ($form as $form_key => &$element_form) { if (!isset($default_values[$form_key])) { continue; } $value_key = ($element_form['#type'] == 'value') ? '#value' : '#default_value'; $element_form[$value_key] = $default_values[$form_key]; } ?>
And all the titles are set up in theming function for this form.
In this example I like how compact are form constructors and how easy they are to read.
Second example is also related to forms.
Once I have needed to set all form sub elements to be not required. And there was another function that disables all elements.
So functions looked like:
<?php function custom_module_form_element_recursive_disable(&$element) { if (!is_array($element)) { return; } $element['#disabled'] = TRUE; foreach (element_children($element) as $key) { custom_module_form_element_recursive_disable($element[$key]); } } function custom_module_form_element_recursive_not_required(&$element) { if (!is_array($element)) { return; } if (!empty($element['#required'])) { $element['#required'] = FALSE; } foreach (element_children($element) as $key) { custom_module_form_element_recursive_disable($element[$key]); } } ?>
As you can see it is pretty simple code but there is a lot of duplicate in it.
Using functional php we can avoid duplicating:
<?php function _custom_module_recursive_form_visitor(&$element, $function) { if (!is_array($element)) { return; } $function($element); foreach (element_children($element) as $key) { _custom_module_recursive_form_visitor($element[$key], $function); } } function custom_module_form_element_recursive_disable(&$element) { $function = function(&$element) { $element['#disabled'] = TRUE; }; _custom_module_recursive_form_visitor($element, $function); } function custom_module_form_element_recursive_not_required(&$element) { $function = function(&$element) { if (!empty($element['#required'])) { $element['#required'] = FALSE; } }; _custom_module_recursive_form_visitor($element, $function); } ?>
Now we can add other functions that need to perform actions recursively on form elements.
If you have some other usages of anonymous functions in PHP please share.
Thanks for reading.
By the way I have submitted a session for DrupalCon Portland http://portland2013.drupal.org/session/clean-code where I will touch this topic as well from perspective of keeping your code clean. So welcome to comment on it.
Comments
Good perspective
Is it necessary in your first example?
Hi,
I quite like the syntax you've ended up with in your first example, but I can't see the real benefit of using anonymous functions to get there.
You could just have the
size()
andsize_maxlength()
(and why not do the same fortextfield
andrequired
?) as normal functions in a library file somewhere, e.g.:Like I say, I like the syntax you end with for defining the elements in the
$form
array, but what's the benefit to making that happen with anonymous functions?avoid namespace conflict
Error on posting comments
Notice: Undefined property: stdClass::$hostname in comment_notify_comment_insert() (line 270 of /var/www/ygerasimov.com/sites/all/modules/contrib/comment_notify/comment_notify.module).
Property formatting
Prior to starting out in Drupal about 2 years ago, I had a fair amount of jQuery experience where closures are pretty common. It's refreshing to see PHP users picking up on the versatility of anonymous functions.
Here's a snippet from a module that searches our LDAP directory. Anonymous functions give us a concise way of overriding the output of certain attributes:
(btw, the syntax highlighting doesn't seem to be working, at least on preview.)
Very nice example! Thanks!
Nice!! Really nice! Thanks