You are here

function _coder_translation_callback in Coder 6.2

Define the rule callbacks for style.

1 string reference to '_coder_translation_callback'
coder_i18n_reviews in includes/coder_i18n.inc
Implementation of hook_reviews().

File

includes/coder_i18n.inc, line 101
This include file implements coder functionality to check for Internationalization issues.

Code

function _coder_translation_callback(&$coder_args, $review, $rule, $lines, &$results) {
  $severity_name = _coder_severity_name($coder_args, $review, $rule);
  $ignores = $coder_args['#ignore_lines'][$review['#review_name']];

  // Parse the translation file into msgid/msgstr pairs.
  $translations = array();
  foreach ($coder_args['#all_lines'] as $lineno => $line) {
    if (preg_match('/^(msgid|msgstr) "(.*)"$/', $line, $matches)) {
      if ($matches[1] == 'msgid') {
        $msgid = $matches[2];
      }
      elseif (!empty($msgid)) {
        $translations[$lineno] = array(
          'msgid' => $msgid,
          'msgstr' => $matches[2],
        );
        unset($msgid);
      }
    }
  }

  // Check each translation.
  foreach ($translations as $lineno => $translation) {
    $msgid = $translation['msgid'];
    $msgstr = $translation['msgstr'];

    // Check the translation first capitable letter.
    if (ctype_upper($msgid[0]) != ctype_upper($msgstr[0])) {
      $rule = array(
        '#warning' => "The first letter in the translation text should have the same capitalization as it's original text.",
      );
      _coder_error($results, $rule, $severity_name, $lineno, $msgstr, $ignores);
    }

    // Check the translation trailing periods.
    if (drupal_substr($msgid, -1, 1) == '.' && !drupal_substr($msgstr, -1, 1) != '.') {
      $rule = array(
        '#warning' => 'The translation text should end in a period when the same original text also ends in a period.',
      );
      _coder_error($results, $rule, $severity_name, $lineno, $msgstr, $ignores);
    }

    // Check punctuation characters.
    if (preg_match_all('/[\\.,:;?!]/', $msgid, $matches)) {
      foreach ($matches[0] as $html) {
        if (stripos($msgstr, $html) === FALSE) {
          $rule = array(
            '#warning' => 'Punctuation characters (.,:;?!) from the original text should exist in the translation.',
          );
          _coder_error($results, $rule, $severity_name, $lineno, $msgstr, $ignores);
        }
      }
    }
    if (preg_match_all('/[\\.,:;?!]/', $msgstr, $matches)) {
      foreach ($matches[0] as $html) {
        if (stripos($msgid, $html) === FALSE) {
          $rule = array(
            '#warning' => 'Punctuations characters (.,:;?!) in the translation should also exist in the original text.',
          );
          _coder_error($results, $rule, $severity_name, $lineno, $msgstr, $ignores);
        }
      }
    }

    // Check HTML tags.
    if (preg_match_all('/<[^>]*>/', $msgid, $matches)) {
      foreach ($matches[0] as $html) {
        if (stripos($msgstr, $html) === FALSE) {
          $rule = array(
            '#warning' => 'HTML from the original text should also exist in the translation.',
          );
          _coder_error($results, $rule, $severity_name, $lineno, $msgstr, $ignores);
        }
      }
    }

    // Check placeholders.
    if (preg_match_all('/[\\!\\@\\%]\\w+/', $msgid, $matches)) {
      foreach ($matches[0] as $placeholder) {
        if (stripos($msgstr, $placeholder) === FALSE) {
          $rule = array(
            '#warning' => 'If placeholders like !name, @name or %name exist in the original text, they must also exist in the translation.',
          );
          _coder_error($results, $rule, $severity_name, $lineno, $msgstr, $ignores);
        }
      }
    }

    // @TODO: Check translations for opening/closing tags if they contain HTML.
    // @TODO: Quotation checks.
    // @TODO: Parenthesis (()[]{}) checks.
  }
}