Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to the new language file parser (since Joomla 4.4.1/5.0.1) #245

Merged
merged 1 commit into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,12 @@ COM_JEDCHECKER_LANG_KEY_NOT_UPPERCASE="The key name is not uppercase"
COM_JEDCHECKER_LANG_KEY_DUPLICATED="The key name was declared previously on line %d"
COM_JEDCHECKER_LANG_TRANSLATION_ERROR="Invalid translation string"
COM_JEDCHECKER_LANG_INVALID_UTF8="Invalid UTF8 string"
COM_JEDCHECKER_LANG_TRANSLATION_QUOTES="All translation strings should be enclosed in double quotation marks."
COM_JEDCHECKER_LANG_TRANSLATION_MISSED_LEFT_QUOTE="You have missed the left quote."
COM_JEDCHECKER_LANG_TRANSLATION_MISSED_RIGHT_QUOTE="You have missed the right quote"
COM_JEDCHECKER_LANG_TRANSLATION_EMPTY="Empty translation string"
COM_JEDCHECKER_LANG_QQDEPRECATED="Usage of %s is deprecated since Joomla! 3.9. Use escaped double quotes (%s) instead"
COM_JEDCHECKER_LANG_UNESCAPED_QUOTE="Unescaped double quotation mark found"
COM_JEDCHECKER_LANG_VARIABLE_REF="A variable reference found in the translation string."
COM_JEDCHECKER_LANG_INCORRECT_ARGNUM="Probably you use incorrect placeholder format (e.g. '%1s' instead of '%1$s'), see <a href='https://www.php.net/manual/en/function.sprintf.php'>printf's argnum format specification</a> for details"
COM_JEDCHECKER_LANG_SPACES_AROUND="Spaces around the translation string are detected"
COM_JEDCHECKER_LANG_UNKNOWN_KEY_IN_CODE="Unknown language key '%s' found in the code."
COM_JEDCHECKER_LANG_JOOMLA501_BC="The behavior of the language file parser has changed in Joomla 4.4.1/5.0.1. In this update, unlike previous Joomla versions, dollar and backslash characters no longer need to be escaped. If you intend to support older Joomla versions, it is advisable to avoid using dollar and backslash in language strings."
COM_JEDCHECKER_LEVEL_ERROR="ERROR"
COM_JEDCHECKER_LEVEL_WARNING="WARNING"
COM_JEDCHECKER_LEVEL_COMPATIBILITY="COMPATIBILITY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,32 +238,18 @@ protected function find($file, $tag)
// Validate value
$value = ltrim($value);

// Parse multiline values
while (!preg_match('/^((?>\'[^\']*\'|"(?>[^"\\\\]+|\\\\.)*"|[^\'";]+)*)(;.*)?$/', $value, $matches))
{
if ($lineno + 1 >= $nLines)
{
break;
}

$lineno++;
$chunk = "\n" . trim($lines[$lineno]);
$line .= $chunk;
$value .= $chunk;
}

// The value doesn't match INI format
if (!isset($matches[0]))
if (!preg_match('/^"((?>[^"\\\\]+|\\\\.)*)"\s*(;[^"]*)?$/', $value, $matches))
{
// The value doesn't match INI format
$this->report->addWarning($file, Text::_('COM_JEDCHECKER_LANG_TRANSLATION_ERROR'), $startLineno, $line);
continue;
}

// Get value w/o comment
$value = trim($matches[1]);
$value = $matches[1];

// Check for empty value
if ($value === '""')
if ($value === '')
{
$this->report->addNotice($file, Text::_('COM_JEDCHECKER_LANG_TRANSLATION_EMPTY'), $startLineno, $line);
continue;
Expand All @@ -277,49 +263,10 @@ protected function find($file, $tag)
$this->report->addWarning($file, Text::_('COM_JEDCHECKER_LANG_INVALID_UTF8'), $startLineno, $line);
}

// Check for unquoted values
if (strlen($value) < 2 || ($value[0] !== '"' && substr($value, -1) !== '"'))
{
$this->report->addWarning($file, Text::_('COM_JEDCHECKER_LANG_TRANSLATION_QUOTES'), $startLineno, $line);
continue;
}

if ($value[0] !== '"')
{
$msg = Text::_('COM_JEDCHECKER_LANG_TRANSLATION_QUOTES') . ' ' . Text::_('COM_JEDCHECKER_LANG_TRANSLATION_MISSED_LEFT_QUOTE');
$this->report->addWarning($file, $msg, $startLineno, $line);
continue;
}

if (substr($value, -1) !== '"')
{
$msg = Text::_('COM_JEDCHECKER_LANG_TRANSLATION_QUOTES') . ' ' . Text::_('COM_JEDCHECKER_LANG_TRANSLATION_MISSED_RIGHT_QUOTE');
$this->report->addWarning($file, $msg, $startLineno, $line);
continue;
}

// Remove quotes around
$value = substr($value, 1, -1);

// Check for legacy "_QQ_" code (deprecated since Joomla! 3.9 in favour of escaped double quote \"; removed in Joomla! 4)
if (strpos($value, '"_QQ_"') !== false)
{
$this->report->addCompat($file, Text::sprintf('COM_JEDCHECKER_LANG_QQDEPRECATED', '<code>"_QQ_"</code>', '<code>\\"</code>'), $startLineno, $line);
}

// Convert "_QQ_" to escaped quotes for further analysis
$value = str_replace('"_QQ_"', '\"', $value);

// Check for unescaped quote
if (preg_match('/[^\\\\]"/', $value))
{
$this->report->addWarning($file, Text::_('COM_JEDCHECKER_LANG_UNESCAPED_QUOTE'), $startLineno, $line);
}

// Check for value interpolation (see https://www.php.net/manual/en/function.parse-ini-file.php for details)
if (strpos($value, '${') !== false)
// Process backwards compatibility break introduced in Joomla 5.0.1
if (preg_match('/\\\\[\\\\\\$]/', $value))
{
$this->report->addWarning($file, Text::_('COM_JEDCHECKER_LANG_VARIABLE_REF'), $startLineno, $line);
$this->report->addWarning($file, Text::_('COM_JEDCHECKER_LANG_JOOMLA501_BC'), $startLineno, $line);
}

// The code below detects incorrect format of numbered placeholders (e.g. "%1s" instead of "%1$s")
Expand Down