Skip to content

Developer

As a developer you can enhance the phone input masks with custom validation types.

Below is an instruction on how to do so.

Create class

Create a class in Civi\PhoneInputMask\Type\Regex.php:

namespace Civi\PhoneInputMask\Type;

use Civi\PhoneInputMask\TypeInterface;

class Regex implements TypeInterface {

  /**
   * @var array
   */
  protected $configuration;

  /**
   * @var String
   */
  protected $title;

  /**
   * @var String
   */
  protected $name;

}

Add initialize function.

The initialize function is called to initialize the class with the right configuration.

  /**
   * Initialize the type
   *
   * @param String $name
   * @param String $title
   * @param array $configuration
   */
  public function initialize($name, $title, $configuration) {
    $this->name = $name;
    $this->title = $title;
    $this->configuration = $configuration;
  }

Add validation function.

The validatePhone function checks whether the phone number is valid.

In our example we use a regex from the configuration and check whether the phone matches this regex.

  /**
   * Returns true when the phone number is valid.
   * Returns an error message when the phone number is invalid.
   *
   * @param $phone
   *
   * @return true|false
   */
  public function validatePhone($phone) {
    $regex = $this->configuration['regex'];
    $matches = array();
    $return = preg_match($regex, $phone, $matches);
    if ($return > 0) {
      return TRUE;
    }
    return FALSE;
  }

Add configuration functoinality.

We need to add the following functions:

  • hasConfiguration returns true because we have user configuration options (the regex and an example phone number)
  • buildConfigurationForm here we add the regex and the example phone number field to the form
  • getConfigurationTemplateFileName the name of the template
  • processConfiguration here we process the submitted values and return an array holding the configuration
/**
   * Returns true when this type has additional configuration.
   *
   * @return bool
   */
  public function hasConfiguration() {
    return TRUE;
  }

  /**
   * When this type has additional configuration you can add
   * the fields on the form with this function.
   *
   * @param \CRM_Core_Form $form
   * @param array $phoneInputMask
   */
  public function buildConfigurationForm(\CRM_Core_Form $form, $phoneInputMask = []) {
    $form->add('text', 'regex', E::ts('Regex'), ['class' => 'huge'], true);
    $form->add('text', 'example', E::ts('Example Phone Number'), ['class' => 'huge'], true);
    if (isset($phoneInputMask['configuration'])) {
      $defaults = [];
      if (isset($phoneInputMask['configuration']['regex'])) {
        $defaults['regex'] = $phoneInputMask['configuration']['regex'];
      }
      if (isset($phoneInputMask['configuration']['example'])) {
        $defaults['example'] = $phoneInputMask['configuration']['example'];
      }
      $form->setDefaults($defaults);
    }
  }

  /**
   * When this type has configuration specify the template file name
   * for the configuration form.
   *
   * @return false|string
   */
  public function getConfigurationTemplateFileName() {
    return 'CRM/Phoneinputmask/Form/Type/Regex.tpl';
  }

  /**
   * Process the submitted values and create a configuration array
   *
   * @param $submittedValues
   *
   * @return array
   */
  public function processConfiguration($submittedValues) {
    $configuration = array();
    $configuration['regex'] = $submittedValues['regex'];
    $configuration['example'] = $submittedValues['example'];
    return $configuration;
  }

Add the template

In templates/CRM/Phoneinputmask/Form/Type/Regex.tpl we add the following:

{crmScope extensionKey='phoneinputmask'}
<div class="crm-section">
  <div class="label">{$form.regex.label}</div>
  <div class="content">{$form.regex.html}</div>
  <div class="clear"></div>
</div>
<div class="crm-section">
  <div class="label">{$form.example.label}</div>
  <div class="content">{$form.example.html}</div>
  <div class="clear"></div>
</div>
{/crmScope}

Add the other neccessary helper functions

The function getExamples returns an array with example phone numbers. We will return only one example phone number as we let the site administrator enter only one example.

The function getTypeTitle returns a translatable title of this validation type.

 /**
   * Return a description of the type.
   *
   * E.g. 'Use the format +31 (0) 6123 456 78
   *
   * @return String[]
   */
  public function getExamples() {
    return [$this->configuration['example']];
  }

  /**
   * @return String
   */
  public function getTypeTitle() {
    return E::ts('Regex');
  }

Add the type to the factory

In Civi\PhoneInputMask\CompilerPass we need to add our type to the factory.

public function process(ContainerBuilder $container) {
  // ...
  if ($container->hasDefinition('phone_input_mask_factory')) {
      $container->getDefinition('phone_input_mask_factory')
      ->addMethodCall('addType', ['regex', new Definition('\Civi\PhoneInputMask\Type\Regex')]);
  }
  // ...
}

If you have developed your validation type in another extension you can add the compiler pass functionality in a compiler pass in your extension.