todo.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. /**
  3. * Todo generator for Laravel-lang project.
  4. *
  5. * @author arcanedev-maroc
  6. */
  7. class TodoGenerator
  8. {
  9. /**
  10. * Base path.
  11. *
  12. * @var string
  13. */
  14. protected $basePath;
  15. /**
  16. * Excluded directories.
  17. *
  18. * @var array
  19. */
  20. protected $excluded = [];
  21. /**
  22. * Path of output file.
  23. *
  24. * @var array
  25. */
  26. protected $output = [];
  27. /**
  28. * Construct.
  29. *
  30. * @param string $basePath base path
  31. * @param array $excluded excluded directories
  32. */
  33. public function __construct($basePath, $excluded = [])
  34. {
  35. $this->basePath = realpath($basePath);
  36. $this->excluded = $excluded;
  37. $this->load();
  38. }
  39. /**
  40. * Returns object.
  41. *
  42. * @param string $basePath base path
  43. * @param array $excluded excluded directories
  44. *
  45. * @return TodoGenerator
  46. */
  47. public static function make($basePath, $excluded = [])
  48. {
  49. return new self($basePath, $excluded);
  50. }
  51. /**
  52. * Save todo list.
  53. *
  54. * @param string $path path
  55. */
  56. public function save($path)
  57. {
  58. file_put_contents($path, $this->getOutput());
  59. }
  60. /**
  61. * Compare translations and generate file.
  62. */
  63. private function load()
  64. {
  65. // Get English version
  66. $english = $this->getTranslations(__DIR__, 'en');
  67. $languages = $this->getLanguages();
  68. $this->compareTranslations($english, $languages);
  69. }
  70. /**
  71. * Returns array of translations by language.
  72. *
  73. * @param string $directory directory
  74. * @param string $language language code
  75. *
  76. * @return array
  77. */
  78. private function getTranslations($directory, $language)
  79. {
  80. $contentJson = '';
  81. $directoryJson = ($language == 'en') ? '/en/' : '/../json/';
  82. $fileJson = $directory.$directoryJson.$language.'.json';
  83. if (file_exists($fileJson)) {
  84. $contentJson = json_decode(file_get_contents($fileJson), true);
  85. }
  86. return [
  87. 'json' => $contentJson,
  88. 'auth' => include($directory.'/'.$language.'/auth.php'),
  89. 'pagination' => include($directory.'/'.$language.'/pagination.php'),
  90. 'passwords' => include($directory.'/'.$language.'/passwords.php'),
  91. 'validation' => include($directory.'/'.$language.'/validation.php'),
  92. ];
  93. }
  94. /**
  95. * Returns list of languages.
  96. *
  97. * @return array
  98. */
  99. private function getLanguages()
  100. {
  101. $directories = glob($this->basePath.'/*', GLOB_ONLYDIR);
  102. $languages = array_map(function ($dir) {
  103. $name = basename($dir);
  104. return in_array($name, $this->excluded, true) ? null : $name;
  105. }, $directories);
  106. return array_filter($languages);
  107. }
  108. /**
  109. * Compare translations.
  110. *
  111. * @param array $default language by default
  112. * @param array $languages others languages
  113. */
  114. private function compareTranslations(array $default, array $languages)
  115. {
  116. // Return diff language by language
  117. foreach ($languages as $language) {
  118. $this->addOutput($language);
  119. $current = $this->getTranslations($this->basePath, $language);
  120. foreach ($default as $key => $values) {
  121. $valuesKeys = array_keys($values);
  122. foreach ($valuesKeys as $key2) {
  123. if (in_array($key2, ['custom', 'attributes'], true)) {
  124. continue;
  125. }
  126. if (!isset($current[$key][$key2])) {
  127. $this->addOutput($language, " * {$key} : {$key2} : not present");
  128. } elseif ($current[$key][$key2] === $default[$key][$key2]) {
  129. $this->addOutput($language, " * {$key} : {$key2}");
  130. }
  131. }
  132. }
  133. }
  134. }
  135. /**
  136. * Adding elements to the resulting array.
  137. *
  138. * @param string $key
  139. * @param string|null $value
  140. */
  141. private function addOutput(string $key, string $value = null)
  142. {
  143. if (!array_key_exists($key, $this->output)) {
  144. $this->output[$key] = [];
  145. }
  146. $this->output[$key][] = $value;
  147. }
  148. /**
  149. * Forming the page content for output.
  150. *
  151. * @return string
  152. */
  153. private function getOutput()
  154. {
  155. $output = "# Todo list\n\n";
  156. // Make menu
  157. $columns = 12;
  158. $captions = implode('|', array_fill(0, $columns, ' '));
  159. $subcaptions = implode('|', array_fill(0, $columns, ':---:'));
  160. $output .= "|$captions|\n";
  161. $output .= "|$subcaptions|\n";
  162. $menu = [];
  163. foreach (array_keys($this->output) as $language) {
  164. $menu[] = "[$language](#$language)";
  165. }
  166. $rows = array_chunk($menu, $columns);
  167. array_map(function ($row) use (&$output) {
  168. $row = implode(' | ', $row);
  169. $output .= $row."\n";
  170. }, $rows);
  171. $output .= "\n\n";
  172. // Make items
  173. foreach ($this->output as $language => $values) {
  174. $output .= "#### {$language}:\n";
  175. $output .= implode(PHP_EOL, $values);
  176. $output .= "\n\n[ [to top](#todo-list) ]\n\n";
  177. }
  178. return $output;
  179. }
  180. }
  181. TodoGenerator::make(__DIR__.'/../src')->save(__DIR__.'/../todo.md');