Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.
 All Data Structures Functions Variables Pages
MessageUtil.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
42  {
43  const GOOD_YII_T = '/\bYii::|Zurmo::t\s*\(\s*[\'"](.*?(?<!\\\\))[\'"]\s*,\s*[\'"](.*?(?<!\\\\))[\'"]\s*[,\)]/s'; // Not Coding Standard
44 
45  const GOOD_YII_T_WITH_LINEBREAK = '/\bYii|Zurmo::t\([\'"](.*?)[\'"], *[\'"](.*?)[\'"]\s[.]/'; // Not Coding Standard
46 
47  const ALL_YII_TS = '/\bYii|Zurmo::t\\([\'"][a-zA-Z]+[\'"], [\'"].*/'; // Not Coding Standard
48 
55  public static function getMessages($language, $moduleName = null, $category = null)
56  {
57  assert('is_string($language)');
58  assert('strlen($language) == 2 || strlen($language) == 5');
59  if ($moduleName === null)
60  {
61  $directories = self::getMessageDirectoriesForAllModules();
62  }
63  elseif ($moduleName != 'framework')
64  {
65  $directories = self::getMessageDirectoriesForNamedModuleAndDependencies($moduleName);
66  }
67  else
68  {
69  $directories = array();
70  }
71  array_unshift($directories, 'core');
72  $messages = array();
73  foreach ($directories as $directory)
74  {
75  $messagesDirectoryName = COMMON_ROOT . "/protected/$directory/messages/$language";
76  if (is_dir($messagesDirectoryName))
77  {
78  $fileNames = scandir($messagesDirectoryName);
79  foreach ($fileNames as $fileName)
80  {
81  if (pathinfo($fileName, PATHINFO_EXTENSION) == 'php')
82  {
83  if ($category === null || pathinfo($fileName, PATHINFO_FILENAME) == $category)
84  {
85  $fileName = "$messagesDirectoryName/$fileName";
86  if (file_exists($fileName))
87  {
88  $messages = array_merge($messages, require($fileName));
89  }
90  }
91  }
92  }
93  }
94  }
95  return $messages;
96  }
97 
98  public static function getLanguagesMessages($basePath, $moduleName, $language)
99  {
100  $messagesDirectoryName = "$basePath/protected/modules/$moduleName/messages/$language";
101  $messageFileName = "$messagesDirectoryName/Default.php";
102  if (file_exists($messageFileName))
103  {
104  return require($messageFileName);
105  }
106  else
107  {
108  return array();
109  }
110  }
111 
112  public static function checkLanguagesMessageFilesContainAllTheSameValidMessages($messagesDirectoryName, $moduleName)
113  {
114  assert('is_string($messagesDirectoryName)');
115  assert('is_dir ($messagesDirectoryName)');
116  $problems = array();
117  $languages = static::getLanguages($messagesDirectoryName);
118  if (count($languages) > 0)
119  {
120  $languagesToMessageFiles = array();
121  foreach ($languages as $language)
122  {
123  $languagesToMessageFiles[$language] = array();
124  $languageMessagesDirectoryName = "$messagesDirectoryName/$language";
125  $languagesToMessageFiles[$language]['messageDirectory'] = $languageMessagesDirectoryName;
126  $entries = scandir($languageMessagesDirectoryName);
127  foreach ($entries as $entry)
128  {
129  $fullEntryName = "$languageMessagesDirectoryName/$entry";
130  if (is_file($fullEntryName) &&
131  pathinfo($entry, PATHINFO_EXTENSION) == 'php')
132  {
133  $languagesToMessageFiles[$language][] = $entry;
134  }
135  }
136  }
137  for ($i = 0; $i < count($languages); $i++)
138  {
139  $problems = array_merge($problems,
140  static::checkLanguagesMessageFilesFormat($languagesToMessageFiles[$languages[$i]],
141  $messagesDirectoryName));
142  }
143  // Compares the first language to the others.
144  for ($i = 1; $i < count($languages); $i++)
145  {
146  $problems = array_merge($problems,
147  static::diffLanguagesMessageFiles($languagesToMessageFiles[$languages[0]],
148  $languagesToMessageFiles[$languages[$i]],
149  $messagesDirectoryName,
150  $moduleName));
151  }
152  }
153  else
154  {
155  $problems[] = 'No languages were found in the following directory:' . $messagesDirectoryName . "\n";
156  }
157  return $problems;
158  }
159 
160  public static function checkFirstLanguagesMessageFilesMessagesReallyExistInSource($messagesDirectoryName, $moduleName)
161  {
162  assert('is_string($messagesDirectoryName)');
163  assert('is_dir ($messagesDirectoryName)');
164  $problems = array();
165  $fileNamesToCategoriesToMessages = static::findFileNameToCategoryToMessage($messagesDirectoryName . '/..');
166  $categoriesToMessagesToFileNames = static::convertFileNameToCategoryToMessageToCategoryToMessageToFileName($fileNamesToCategoriesToMessages);
167  unset($categoriesToMessagesToFileNames['yii']);
168  $languages = static::getLanguages($messagesDirectoryName);
169  if (count($languages) > 0)
170  {
171  $firstLanguage = $languages[0];
172  foreach ($categoriesToMessagesToFileNames as $category => $messagesToFileNames)
173  {
174  $messageFileName = "$messagesDirectoryName/$firstLanguage/$category.php";
175  if (is_file($messageFileName))
176  {
177  $messagesInMessageFile = require($messageFileName);
178  if (!is_array($messagesInMessageFile))
179  {
180  $problems[] = "$messageFileName is not a valid message file.\n";
181  continue;
182  }
183  $messagesInMessageFile = array_keys($messagesInMessageFile);
184  }
185  else
186  {
187  continue;
188  }
189  $messagesInSourceFiles = array_keys($messagesToFileNames);
190  $messagesNotInSourceFiles = array_diff($messagesInMessageFile, $messagesInSourceFiles);
191  foreach ($messagesNotInSourceFiles as $message)
192  {
193  if (strpos($message, 'ModulePluralLabel') === false &&
194  strpos($message, 'ModuleSingularLabel') === false &&
195  strpos($message, 'ModulePluralLowerCaseLabel') === false &&
196  strpos($message, 'ModuleSingularLowerCaseLabel') === false )
197  {
198  //There is no current way to resolve this type of issue. It is possible a label has been pushed
199  //back into framework for example, even though there is no mention of the label in framework. This
200  //is so it is not duplicated in various modules. This is turned off for now from the message checker.
201  //$problems[] = "(This might be ok) '$message' in $firstLanguage/$category.php not in any source file in $moduleName.";
202  }
203  }
204  }
205  }
206  else
207  {
208  $problems[] = 'No languages were found in the following directory:' . $messagesDirectoryName . "\n";
209  }
210  return $problems;
211  }
212 
213  public static function checkFirstLanguagesMessageFilesContainAllExistingMessages($messagesDirectoryName, $moduleName, $basePath)
214  {
215  assert('is_string($messagesDirectoryName)');
216  assert('is_dir ($messagesDirectoryName)');
217  $problems = array();
218  $fileNamesToCategoriesToMessages = static::findFileNameToCategoryToMessage($messagesDirectoryName . '/..');
219  $categoriesToMessagesToFileNames = static::convertFileNameToCategoryToMessageToCategoryToMessageToFileName($fileNamesToCategoriesToMessages);
220  unset($categoriesToMessagesToFileNames['yii']);
221  $languages = static::getLanguages($messagesDirectoryName);
222  if (count($languages) > 0)
223  {
224  $firstLanguage = $languages[0];
225  foreach ($categoriesToMessagesToFileNames as $category => $messagesToFileNames)
226  {
227  $existingMessages = array_keys(MessageUtil::getMessages($firstLanguage, $moduleName, $category));
228  $duplicateCount = count($existingMessages) != count(array_unique($existingMessages));
229  if ($duplicateCount != 0)
230  {
231  $problems[] = "$moduleName and its dependencies contain $duplicateCount duplicate entries.";
232  }
233  $yiiMessageFileName = "$messagesDirectoryName/$firstLanguage/$category.php";
234  $yiiMessages = require("$basePath/../../yii/framework/messages/$firstLanguage/yii.php");
235  foreach ($messagesToFileNames as $message => $fileNames)
236  {
237  $fileNames = join(', ', $fileNames);
238  if (!in_array($message, $existingMessages) &&
239  !in_array($message, $yiiMessages))
240  {
241  $problems[] = "'$message' in $fileNames not in $firstLanguage/$category.php in $moduleName or its dependencies.";
242  }
243  elseif (in_array($message, $existingMessages) &&
244  in_array($message, $yiiMessages))
245  {
246  $problems[] = "'$message' in $fileNames in $firstLanguage/$category.php in $moduleName or its dependencies is a duplicate of definition already in Yii.";
247  }
248  }
249  }
250  }
251  else
252  {
253  $problems[] = 'No languages were found in the following directory:' . $messagesDirectoryName . "\n";
254  }
255  return $problems;
256  }
257 
258  public static function checkForYiiTCallsThatAreNotHowThisScriptExpectsThemToBe($messagesDirectoryName, $moduleName)
259  {
260  assert('is_string($messagesDirectoryName)');
261  assert('is_dir ($messagesDirectoryName)');
262  $problems = array();
263  $fileNamesToUnexpectedlyFormattedYiiTs = static::findFileNameToUnexpectedlyFormattedYiiT($messagesDirectoryName . '/..');
264  foreach ($fileNamesToUnexpectedlyFormattedYiiTs as $fileName => $unexpectedlyFormattedYiiTs)
265  {
266  foreach ($unexpectedlyFormattedYiiTs as $code)
267  {
268  $problems[] = "$code in $fileName in $moduleName.";
269  }
270  }
271  return $problems;
272  }
273 
274  public static function findFileNameToCategoryToMessage($path, $forcedCategory = '', $forTesting = false)
275  {
276  assert('is_string($path)');
277  assert('is_dir ($path)');
278  $fileNamesToCategoriesToMessages = array();
279  $f = opendir($path);
280  assert('$f !== false');
281  while ($entry = readdir($f))
282  {
283  if (!in_array($entry, array('.', '..', 'messages')))
284  {
285  $fullEntryName = "$path/$entry";
286  if (is_dir($fullEntryName))
287  {
288  $fileNamesToCategoriesToMessages = array_merge($fileNamesToCategoriesToMessages,
289  static::findFileNameToCategoryToMessage($fullEntryName));
290  }
291  elseif (is_file($fullEntryName) &&
292  pathinfo($entry, PATHINFO_EXTENSION) == 'php')
293  {
294  //Avoid any models in the framework/models folder and test models
295  if ( strpos($path, '/core') === false &&
296  strpos($path, '/tests') === false &&
297  strpos($path, '/models') !== false &&
298  strpos($fullEntryName, '.php') !== false)
299  {
300  $modelClassName = basename(substr($fullEntryName, 0, -4));
301  $modelReflectionClass = new ReflectionClass($modelClassName);
302  if ($modelReflectionClass->isSubclassOf('RedBeanModel') &&
303  $modelReflectionClass->isSubclassOf('OwnedModel') &&
304  !$modelReflectionClass->isAbstract())
305  {
306  $modelAttributes = $modelClassName::getAttributeNames();
307  foreach ($modelAttributes as $attributeName)
308  {
309  //Find attributes that are a CustomField relation. This means there is drop down values
310  //that will need to be translated.
311  if ($modelClassName::isRelation($attributeName) &&
312  ($modelClassName::getRelationModelClassName($attributeName) == 'OwnedCustomField' ||
313  $modelClassName::getRelationModelClassName($attributeName) == 'CustomField' ||
314  $modelClassName::getRelationModelClassName($attributeName) == 'MultipleValuesCustomField' ||
315  $modelClassName::getRelationModelClassName($attributeName) == 'OwnedMultipleValuesCustomField'))
316  {
317  $customFieldData = CustomFieldDataModelUtil::
318  getDataByModelClassNameAndAttributeName($modelClassName, $attributeName);
319  $customFieldDataNames = unserialize($customFieldData->serializedData);
320  foreach ($customFieldDataNames as $dataName)
321  {
322  $fileNamesToCategoriesToMessages[$fullEntryName]['Default'][] = $dataName;
323  }
324  }
325  }
326  }
327  }
328  //Check for any menu labels, rights, policies, or audit event names in the modules.
329  if ( strpos($fullEntryName, 'Module.php') !== false)
330  {
331  $moduleClassName = basename(substr($fullEntryName, 0, -4));
332  $moduleReflectionClass = new ReflectionClass($moduleClassName);
333  if ($moduleReflectionClass->isSubclassOf('SecurableModule') &&
334  !$moduleReflectionClass->isAbstract())
335  {
336  $labelsData = static::getSecurableModuleRightsPoliciesAndAuditEventLabels($moduleClassName);
337  if (!empty($labelsData))
338  {
339  if (isset($fileNamesToCategoriesToMessages[$fullEntryName]['Default']))
340  {
341  $fileNamesToCategoriesToMessages[$fullEntryName]['Default'] =
342  array_merge($fileNamesToCategoriesToMessages[$fullEntryName]['Default'], $labelsData);
343  }
344  else
345  {
346  $fileNamesToCategoriesToMessages[$fullEntryName]['Default'] = $labelsData;
347  }
348  }
349  }
350  //attempt to detect any 'state' adapters and look for state labels.
351  $stateAdapterClassName = $moduleClassName::getStateMetadataAdapterClassName();
352  if ($stateAdapterClassName != null && $stateAdapterClassName)
353  {
354  $stateModelClassName = $stateAdapterClassName::getStateModelClassName();
355  $states = $stateModelClassName::getAll();
356  foreach ($states as $state)
357  {
358  $fileNamesToCategoriesToMessages[$fullEntryName]['Default'][] = $state->name;
359  }
360  }
361  //check for menu labels
362  if (!$moduleReflectionClass->isAbstract())
363  {
364  if (isset($fileNamesToCategoriesToMessages[$fullEntryName]['Default']))
365  {
366  $fileNamesToCategoriesToMessages[$fullEntryName]['Default'] =
367  array_merge($fileNamesToCategoriesToMessages[$fullEntryName]['Default'],
368  static::getModuleMenuLabelNamesByModuleName($moduleClassName));
369  }
370  else
371  {
372  $fileNamesToCategoriesToMessages[$fullEntryName]['Default'] =
373  static::getModuleMenuLabelNamesByModuleName($moduleClassName);
374  }
375  }
376  }
377  //Check for any panel titles that need translation
378  if ( strpos($fullEntryName, 'View.php') !== false)
379  {
380  $viewClassName = basename(substr($fullEntryName, 0, -4));
381  $moduleReflectionClass = new ReflectionClass($viewClassName);
382  if ($moduleReflectionClass->isSubclassOf('MetadataView') &&
383  !$moduleReflectionClass->isAbstract())
384  {
385  $metadata = $viewClassName::getDefaultMetadata();
386  if (isset($metadata['global']) && isset($metadata['global']['panels']))
387  {
388  foreach ($metadata['global']['panels'] as $panel)
389  {
390  if (isset($panel['title']))
391  {
392  $fileNamesToCategoriesToMessages[$fullEntryName]['Default'][] = $panel['title'];
393  }
394  }
395  }
396  }
397  }
398  //Avoid picking up any models or anything in the test folders
399  if ( $forTesting || strpos($path, '/tests') === false)
400  {
401  $content = file_get_contents($fullEntryName);
402  $content = str_replace('\\\'', '\'', $content);
403  if (preg_match_all(self::GOOD_YII_T, $content, $matches))
404  {
405  foreach ($matches[1] as $index => $category)
406  {
407  if (preg_match_all('/^\w*$/', $category) != 1)
408  {
409  echo 'This is not a valid category: ' . $category . "\n";
410  }
411  else
412  {
413  if ($forcedCategory
414  AND is_string($forcedCategory)
415  AND strlen($forcedCategory))
416  {
417  $category = $forcedCategory;
418  }
419  if (!isset($fileNamesToCategoriesToMessages[$fullEntryName][$category]))
420  {
421  $fileNamesToCategoriesToMessages[$fullEntryName][$category] = array();
422  }
423  //Remove extra lines caused by ' . ' which is used for line breaks in php. Minimum 3 spaces
424  //will avoid catching 2 spaces between words which can be legitimate.
425  $massagedString = preg_replace('/[\p{Z}\s]{3,}/u', ' ', $matches[2][$index]); // Not Coding Standard
426  $massagedString = str_replace("' . '", '', $massagedString);
427  $fileNamesToCategoriesToMessages[$fullEntryName][$category][] = $massagedString;
428  if ($matches[2][$index] != $massagedString && strpos($matches[2][$index], "' .") === false && strpos($matches[2][$index], ".") > 0)
429  {
430  echo 'The following message should be using proper line breaks: ' . $matches[2][$index] . "\n";
431  }
432  }
433  }
434  }
435  }
436  }
437  }
438  }
439  return $fileNamesToCategoriesToMessages;
440  }
441 
442  public static function getSecurableModuleRightsPoliciesAndAuditEventLabels($moduleClassName)
443  {
444  assert('is_string($moduleClassName)');
445  return $moduleClassName::getAuditEventNames();
446  }
447 
448  public static function getModuleMenuLabelNamesByModuleName($moduleClassName)
449  {
450  $labels = array();
451  $metadata = $moduleClassName::getMetadata();
452  if (isset($metadata['global']['adminTabMenuItems']))
453  {
454  foreach ($metadata['global']['adminTabMenuItems'] as $menuItem)
455  {
456  if (isset($menuItem['items']))
457  {
458  foreach ($menuItem['items'] as $subMenuItem)
459  {
460  if (!in_array($subMenuItem['label'], $labels))
461  {
462  $labels[] = $subMenuItem['label'];
463  }
464  }
465  }
466  if (!in_array($menuItem['label'], $labels))
467  {
468  $labels[] = $menuItem['label'];
469  }
470  }
471  }
472  if (isset($metadata['global']['tabMenuItems']))
473  {
474  foreach ($metadata['global']['tabMenuItems'] as $menuItem)
475  {
476  if (isset($menuItem['items']))
477  {
478  foreach ($menuItem['items'] as $subMenuItem)
479  {
480  if (!in_array($subMenuItem['label'], $labels))
481  {
482  $labels[] = $subMenuItem['label'];
483  }
484  }
485  }
486  if (!in_array($menuItem['label'], $labels))
487  {
488  $labels[] = $menuItem['label'];
489  }
490  }
491  }
492  if (isset($metadata['global']['shortcutsCreateMenuItems']))
493  {
494  foreach ($metadata['global']['shortcutsCreateMenuItems'] as $menuItem)
495  {
496  if (isset($menuItem['items']))
497  {
498  foreach ($menuItem['items'] as $subMenuItem)
499  {
500  if (!in_array($subMenuItem['label'], $labels))
501  {
502  $labels[] = $subMenuItem['label'];
503  }
504  }
505  }
506  if (!in_array($menuItem['label'], $labels))
507  {
508  $labels[] = $menuItem['label'];
509  }
510  }
511  }
512  if (isset($metadata['global']['headerMenuItems']))
513  {
514  foreach ($metadata['global']['headerMenuItems'] as $menuItem)
515  {
516  if (!in_array($menuItem['label'], $labels))
517  {
518  $labels[] = $menuItem['label'];
519  }
520  }
521  }
522  if (isset($metadata['global']['userHeaderMenuItems']))
523  {
524  foreach ($metadata['global']['userHeaderMenuItems'] as $menuItem)
525  {
526  if (!in_array($menuItem['label'], $labels))
527  {
528  $labels[] = $menuItem['label'];
529  }
530  }
531  }
532  if (isset($metadata['global']['configureMenuItems']))
533  {
534  foreach ($metadata['global']['configureMenuItems'] as $menuItem)
535  {
536  if (!in_array($menuItem['titleLabel'], $labels))
537  {
538  $labels[] = $menuItem['titleLabel'];
539  }
540  if (!in_array($menuItem['descriptionLabel'], $labels))
541  {
542  $labels[] = $menuItem['descriptionLabel'];
543  }
544  }
545  }
546  return $labels;
547  }
548 
549  public static function findFileNameToUnexpectedlyFormattedYiiT($path)
550  {
551  assert('is_string($path)');
552  assert('is_dir ($path)');
553  $fileNamesToUnexpectedlyFormattedYiiTs = array();
554  $f = opendir($path);
555  assert('$f !== false');
556  while ($entry = readdir($f))
557  {
558  if (!in_array($entry, array('.', '..', 'messages')))
559  {
560  $fullEntryName = "$path/$entry";
561  if (is_dir($fullEntryName))
562  {
563  $fileNamesToUnexpectedlyFormattedYiiTs = array_merge($fileNamesToUnexpectedlyFormattedYiiTs,
564  static::findFileNameToUnexpectedlyFormattedYiiT($fullEntryName));
565  }
566  elseif (is_file($fullEntryName) &&
567  pathinfo($entry, PATHINFO_EXTENSION) == 'php')
568  {
569  $content = file_get_contents($fullEntryName);
570  if (preg_match_all(self::ALL_YII_TS, $content, $matches))
571  {
572  foreach ($matches[0] as $code)
573  {
574  $code = str_replace('\\\'', '\'', $code);
575  if (!preg_match(self::GOOD_YII_T, $code))
576  {
577  if (!preg_match(self::GOOD_YII_T_WITH_LINEBREAK, $code))
578  {
579  if (!isset($fileNamesToUnexpectedlyFormattedYiiTs[$entry]))
580  {
581  $fileNamesToUnexpectedlyFormattedYiiTs[$entry] = array();
582  }
583  $fileNamesToUnexpectedlyFormattedYiiTs[$entry][] = $code;
584  }
585  }
586  }
587  }
588  }
589  }
590  }
591  return $fileNamesToUnexpectedlyFormattedYiiTs;
592  }
593 
594  public static function convertFileNameToCategoryToMessageToCategoryToMessageToFileName(array $fileNamesToCategoriesToMessages)
595  {
596  $categoriesToMessagesToFileNames = array();
597  foreach ($fileNamesToCategoriesToMessages as $fileName => $filesCategoriesToMessages)
598  {
599  foreach ($filesCategoriesToMessages as $category => $messages)
600  {
601  foreach ($messages as $message)
602  {
603  if (!in_array ($category, $categoriesToMessagesToFileNames) ||
604  !array_key_exists($message, $categoriesToMessagesToFileNames[$category]))
605  {
606  if (!isset($categoriesToMessagesToFileNames[$category][$message]))
607  {
608  $categoriesToMessagesToFileNames[$category][$message] = array();
609  }
610  $categoriesToMessagesToFileNames[$category][$message][] = $fileName;
611  }
612  }
613  }
614  }
615  foreach ($categoriesToMessagesToFileNames as $category => $unused)
616  {
617  uksort($categoriesToMessagesToFileNames[$category], 'MessageUtil::lowercaseCompare');
618  }
619  return $categoriesToMessagesToFileNames;
620  }
621 
622  public static function convertFileNameToCategoryToMessageToMessageAndCategories(array $fileNamesToCategoriesToMessages)
623  {
624  $messageAndCategories = array();
625  foreach ($fileNamesToCategoriesToMessages as $fileName => $filesCategoriesToMessages)
626  {
627  foreach ($filesCategoriesToMessages as $category => $messages)
628  {
629  foreach ($messages as $message)
630  {
631  $message = strtolower($message);
632  if (isset($messageAndCategories[$message]))
633  {
634  if (!in_array($category, $messageAndCategories[$message]))
635  {
636  $messageAndCategories[$message][] = $category;
637  }
638  }
639  else
640  {
641  $messageAndCategories[$message] = array($category);
642  }
643  }
644  }
645  }
646  foreach ($messageAndCategories as $message => $unused)
647  {
648  uksort($messageAndCategories[$message], 'MessageUtil::lowercaseCompare');
649  }
650  return $messageAndCategories;
651  }
652 
653  public static function checkLanguagesMessageFilesFormat(array $fileNames, $messagesDirectoryName)
654  {
655  assert('is_string($messagesDirectoryName)');
656  assert('is_dir ($messagesDirectoryName)');
657  $problems = array();
658  $directoryName = $fileNames['messageDirectory'];
659  unset($fileNames['messageDirectory']);
660  foreach ($fileNames as $fileName)
661  {
662  $fullFileName = "$directoryName/$fileName";
663  $shortFileName = substr($fullFileName, strlen($messagesDirectoryName) + 1);
664  $messages = require($fullFileName);
665  if (!is_array($messages))
666  {
667  $problems = $shortFileName . ' is not a valid message file.' . PHP_EOL;
668  continue;
669  }
670  $messages = array_keys($messages);
671  $messagesSorted = $messages;
672  usort($messagesSorted, 'MessageUtil::lowercaseCompare');
673  if ($messages !== $messagesSorted)
674  {
675  $problems[] = 'Messages not in alphabetical order in ' . $messagesDirectoryName . ': ' .
676  static::compareArrays($messages, $messagesSorted);
677  }
678  }
679  return $problems;
680  }
681 
682  public static function diffLanguagesMessageFiles(array $fileNames1, array $fileNames2, $messagesDirectoryName, $moduleName)
683  {
684  assert('is_string($messagesDirectoryName)');
685  assert('is_dir ($messagesDirectoryName)');
686  $problems = array();
687  $directoryName1 = $fileNames1['messageDirectory'];
688  $directoryName2 = $fileNames2['messageDirectory'];
689  $shortDirectoryName1 = substr($directoryName1, strlen($messagesDirectoryName) + 1);
690  $shortDirectoryName2 = substr($directoryName2, strlen($messagesDirectoryName) + 1);
691  unset($fileNames1['messageDirectory']);
692  unset($fileNames2['messageDirectory']);
693  $commonFileNames = array_intersect($fileNames1, $fileNames2);
694  $only1FileNames = array_diff ($fileNames1, $fileNames2);
695  $only2FileNames = array_diff ($fileNames2, $fileNames1);
696 
697  foreach ($commonFileNames as $fileName)
698  {
699  $fullFileName1 = "$directoryName1/$fileName";
700  $fullFileName2 = "$directoryName2/$fileName";
701  $shortFileName1 = substr($fullFileName1, strlen($messagesDirectoryName) + 1);
702  $shortFileName2 = substr($fullFileName2, strlen($messagesDirectoryName) + 1);
703  $messages1 = require($fullFileName1);
704  if (is_array($messages1))
705  {
706  $messages1 = array_keys($messages1);
707  $messages2 = require($fullFileName2);
708  if (is_array($messages2))
709  {
710  $messages2 = array_keys($messages2);
711  if ($messages1 != $messages2)
712  {
713  $problems[] = "$shortFileName1 and $shortFileName2 do not contain the same messages in '$moduleName': " .
714  static::compareArrays($messages1, $messages2);
715  }
716  }
717  }
718  }
719  foreach ($only2FileNames as $fileName)
720  {
721  $problems[] = "$fileName found in $shortDirectoryName1.";
722  }
723  foreach ($only1FileNames as $fileName)
724  {
725  $problems[] = "$fileName not in $shortDirectoryName2.";
726  }
727  return $problems;
728  }
729 
730  public static function getLanguages($messagesDirectoryName)
731  {
732  assert('is_string($messagesDirectoryName)');
733  assert('is_dir ($messagesDirectoryName)');
734  $entries = scandir($messagesDirectoryName);
735  $languages = array();
736  foreach ($entries as $entry)
737  {
738  $fullEntryName = "$messagesDirectoryName/$entry";
739  if (is_dir($fullEntryName) &&
740  strlen($entry) == 2 &&
741  $entry != '..')
742  {
743  $languages[] = $entry;
744  }
745  }
746  return $languages;
747  }
748 
749  public static function lowercaseCompare($a, $b)
750  {
751  assert('is_string($a)');
752  assert('is_string($b)');
753  $al = strtolower($a);
754  $bl = strtolower($b);
755  if ($al == $bl)
756  {
757  return 0;
758  }
759  elseif ($al > $bl)
760  {
761  return 1;
762  }
763  else
764  {
765  return -1;
766  }
767  }
768 
769  public static function compareArrays(array $array1, array $array2)
770  {
771  assert('is_array($array1)');
772  assert('is_array($array2)');
773 
774  $difference = array_diff($array1, $array2);
775 
776  if (isset($difference) && sizeof($difference))
777  {
778  foreach ($difference as $i => $val)
779  {
780  $msg[] = "'" . $array1[$i] . (isset($array2[$i]) ? "' & '" . $array2[$i] . "'" : '');
781  }
782  return 'Near entries ' . implode(', ', $msg);
783  }
784  return 'OK';
785  }
786 
787  private static function getMessageDirectoriesForNamedModuleAndDependencies($moduleName)
788  {
789  $module = Yii::app()->findModule($moduleName);
790  assert('$module instanceof Module');
791  return self::getMessageDirectoriesForModuleAndDependencies($module);
792  }
793 
794  private static function getMessageDirectoriesForModuleAndDependencies(Module $module)
795  {
796  $dependencies = Module::getDependenciesForModule($module);
797  $directories = array();
798  foreach ($dependencies as $dependency)
799  {
800  $directories[] = "modules/$dependency";
801  }
802  return $directories;
803  }
804 
809  private static function getMessageDirectoriesForAllModules()
810  {
811  $modules = Module::getModuleObjects();
812  foreach ($modules as $module)
813  {
814  if (get_class($module->getParentModule()) == 'MessageUtil')
815  {
816  $directories[] = 'modules/' . $module->getDirectoryName();
817  }
818  }
819  return $directories;
820  }
821  }
822 ?>
static getMessages($language, $moduleName=null, $category=null)
Definition: MessageUtil.php:55
static getModuleObjects()
Definition: Module.php:51
static getDataByModelClassNameAndAttributeName($modelClassName, $attributeName)
static getDependenciesForModule(Module $module, $dependencies=array())
Definition: Module.php:84
Generated on Fri Jul 10 2020 07:10:28
Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.