|
9 | 9 | use Cake\Core\App;
|
10 | 10 | use Cake\Core\Configure;
|
11 | 11 | use Cake\Core\Plugin;
|
12 |
| -use Cake\Filesystem\Filesystem; |
13 | 12 | use Cake\Utility\Hash;
|
14 | 13 | use Cake\Utility\Inflector;
|
15 | 14 |
|
@@ -335,294 +334,4 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar
|
335 | 334 |
|
336 | 335 | return $parser;
|
337 | 336 | }
|
338 |
| - |
339 |
| - /** |
340 |
| - * Extract tokens out of all files to be processed |
341 |
| - * |
342 |
| - * @param \Cake\Console\Arguments $args The io instance |
343 |
| - * @param \Cake\Console\ConsoleIo $io The io instance |
344 |
| - * @return void |
345 |
| - */ |
346 |
| - protected function _extractTokens(Arguments $args, ConsoleIo $io): void |
347 |
| - { |
348 |
| - /** @var \Cake\Shell\Helper\ProgressHelper $progress */ |
349 |
| - $progress = $io->helper('progress'); |
350 |
| - $progress->init(['total' => count($this->_files)]); |
351 |
| - $isVerbose = $args->getOption('verbose'); |
352 |
| - |
353 |
| - $functions = [ |
354 |
| - '__' => ['singular'], |
355 |
| - '__n' => ['singular', 'plural'], |
356 |
| - '__d' => ['domain', 'singular'], |
357 |
| - '__dn' => ['domain', 'singular', 'plural'], |
358 |
| - '__x' => ['context', 'singular'], |
359 |
| - '__xn' => ['context', 'singular', 'plural'], |
360 |
| - '__dx' => ['domain', 'context', 'singular'], |
361 |
| - '__dxn' => ['domain', 'context', 'singular', 'plural'], |
362 |
| - ]; |
363 |
| - $pattern = '/(' . implode('|', array_keys($functions)) . ')\s*\(/'; |
364 |
| - |
365 |
| - foreach ($this->_files as $file) { |
366 |
| - $this->_file = $file; |
367 |
| - if ($isVerbose) { |
368 |
| - $io->verbose(sprintf('Processing %s...', $file)); |
369 |
| - } |
370 |
| - |
371 |
| - $code = file_get_contents($file); |
372 |
| - |
373 |
| - if (preg_match($pattern, $code) === 1) { |
374 |
| - $allTokens = token_get_all($code); |
375 |
| - |
376 |
| - $this->_tokens = []; |
377 |
| - foreach ($allTokens as $token) { |
378 |
| - if (!is_array($token) || ($token[0] !== T_WHITESPACE && $token[0] !== T_INLINE_HTML)) { |
379 |
| - $this->_tokens[] = $token; |
380 |
| - } |
381 |
| - } |
382 |
| - unset($allTokens); |
383 |
| - |
384 |
| - foreach ($functions as $functionName => $map) { |
385 |
| - $this->_parse($io, $functionName, $map); |
386 |
| - } |
387 |
| - } |
388 |
| - |
389 |
| - if (!$isVerbose) { |
390 |
| - $progress->increment(1); |
391 |
| - $progress->draw(); |
392 |
| - } |
393 |
| - } |
394 |
| - } |
395 |
| - |
396 |
| - /** |
397 |
| - * Parse tokens |
398 |
| - * |
399 |
| - * @param \Cake\Console\ConsoleIo $io The io instance |
400 |
| - * @param string $functionName Function name that indicates translatable string (e.g: '__') |
401 |
| - * @param array $map Array containing what variables it will find (e.g: domain, singular, plural) |
402 |
| - * @return void |
403 |
| - */ |
404 |
| - protected function _parse(ConsoleIo $io, string $functionName, array $map): void |
405 |
| - { |
406 |
| - $count = 0; |
407 |
| - $tokenCount = count($this->_tokens); |
408 |
| - |
409 |
| - while ($tokenCount - $count > 1) { |
410 |
| - $countToken = $this->_tokens[$count]; |
411 |
| - $firstParenthesis = $this->_tokens[$count + 1]; |
412 |
| - if (!is_array($countToken)) { |
413 |
| - $count++; |
414 |
| - continue; |
415 |
| - } |
416 |
| - |
417 |
| - [$type, $string, $line] = $countToken; |
418 |
| - if (($type === T_STRING) && ($string === $functionName) && ($firstParenthesis === '(')) { |
419 |
| - $position = $count; |
420 |
| - $depth = 0; |
421 |
| - |
422 |
| - while (!$depth) { |
423 |
| - if ($this->_tokens[$position] === '(') { |
424 |
| - $depth++; |
425 |
| - } elseif ($this->_tokens[$position] === ')') { |
426 |
| - $depth--; |
427 |
| - } |
428 |
| - $position++; |
429 |
| - } |
430 |
| - |
431 |
| - $mapCount = count($map); |
432 |
| - $strings = $this->_getStrings($position, $mapCount); |
433 |
| - |
434 |
| - if ($mapCount === count($strings)) { |
435 |
| - $singular = ''; |
436 |
| - $plural = $context = null; |
437 |
| - extract(array_combine($map, $strings)); |
438 |
| - $domain = $domain ?? 'default'; |
439 |
| - $details = [ |
440 |
| - 'file' => $this->_file, |
441 |
| - 'line' => $line, |
442 |
| - ]; |
443 |
| - if ($this->_relativePaths) { |
444 |
| - $details['file'] = '.' . str_replace(ROOT, '', $details['file']); |
445 |
| - } |
446 |
| - if ($plural !== null) { |
447 |
| - $details['msgid_plural'] = $plural; |
448 |
| - } |
449 |
| - if ($context !== null) { |
450 |
| - $details['msgctxt'] = $context; |
451 |
| - } |
452 |
| - $this->_addTranslation($domain, $singular, $details); |
453 |
| - } else { |
454 |
| - $this->_markerError($io, $this->_file, $line, $functionName, $count); |
455 |
| - } |
456 |
| - } |
457 |
| - $count++; |
458 |
| - } |
459 |
| - } |
460 |
| - |
461 |
| - /** |
462 |
| - * Get the strings from the position forward |
463 |
| - * |
464 |
| - * @param int $position Actual position on tokens array |
465 |
| - * @param int $target Number of strings to extract |
466 |
| - * @return array Strings extracted |
467 |
| - */ |
468 |
| - protected function _getStrings(int &$position, int $target): array |
469 |
| - { |
470 |
| - $strings = []; |
471 |
| - $count = count($strings); |
472 |
| - while ( |
473 |
| - $count < $target |
474 |
| - && ($this->_tokens[$position] === ',' |
475 |
| - || $this->_tokens[$position][0] === T_CONSTANT_ENCAPSED_STRING |
476 |
| - || $this->_tokens[$position][0] === T_LNUMBER |
477 |
| - ) |
478 |
| - ) { |
479 |
| - $count = count($strings); |
480 |
| - if ($this->_tokens[$position][0] === T_CONSTANT_ENCAPSED_STRING && $this->_tokens[$position + 1] === '.') { |
481 |
| - $string = ''; |
482 |
| - while ( |
483 |
| - $this->_tokens[$position][0] === T_CONSTANT_ENCAPSED_STRING |
484 |
| - || $this->_tokens[$position] === '.' |
485 |
| - ) { |
486 |
| - if ($this->_tokens[$position][0] === T_CONSTANT_ENCAPSED_STRING) { |
487 |
| - $string .= $this->_formatString($this->_tokens[$position][1]); |
488 |
| - } |
489 |
| - $position++; |
490 |
| - } |
491 |
| - $strings[] = $string; |
492 |
| - } elseif ($this->_tokens[$position][0] === T_CONSTANT_ENCAPSED_STRING) { |
493 |
| - $strings[] = $this->_formatString($this->_tokens[$position][1]); |
494 |
| - } elseif ($this->_tokens[$position][0] === T_LNUMBER) { |
495 |
| - $strings[] = $this->_tokens[$position][1]; |
496 |
| - } |
497 |
| - $position++; |
498 |
| - } |
499 |
| - |
500 |
| - return $strings; |
501 |
| - } |
502 |
| - |
503 |
| - /** |
504 |
| - * Format a string to be added as a translatable string |
505 |
| - * |
506 |
| - * @param string $string String to format |
507 |
| - * @return string Formatted string |
508 |
| - */ |
509 |
| - protected function _formatString(string $string): string |
510 |
| - { |
511 |
| - $quote = substr($string, 0, 1); |
512 |
| - $string = substr($string, 1, -1); |
513 |
| - if ($quote === '"') { |
514 |
| - $string = stripcslashes($string); |
515 |
| - } else { |
516 |
| - $string = strtr($string, ["\\'" => "'", '\\\\' => '\\']); |
517 |
| - } |
518 |
| - $string = str_replace("\r\n", "\n", $string); |
519 |
| - |
520 |
| - return addcslashes($string, "\0..\37\\\""); |
521 |
| - } |
522 |
| - |
523 |
| - /** |
524 |
| - * Indicate an invalid marker on a processed file |
525 |
| - * |
526 |
| - * @param \Cake\Console\ConsoleIo $io The io instance. |
527 |
| - * @param string $file File where invalid marker resides |
528 |
| - * @param int $line Line number |
529 |
| - * @param string $marker Marker found |
530 |
| - * @param int $count Count |
531 |
| - * @return void |
532 |
| - */ |
533 |
| - protected function _markerError($io, string $file, int $line, string $marker, int $count): void |
534 |
| - { |
535 |
| - if (strpos($this->_file, CAKE_CORE_INCLUDE_PATH) === false) { |
536 |
| - $this->_countMarkerError++; |
537 |
| - } |
538 |
| - |
539 |
| - if (!$this->_markerError) { |
540 |
| - return; |
541 |
| - } |
542 |
| - |
543 |
| - $io->err(sprintf("Invalid marker content in %s:%s\n* %s(", $file, $line, $marker)); |
544 |
| - $count += 2; |
545 |
| - $tokenCount = count($this->_tokens); |
546 |
| - $parenthesis = 1; |
547 |
| - |
548 |
| - while (($tokenCount - $count > 0) && $parenthesis) { |
549 |
| - if (is_array($this->_tokens[$count])) { |
550 |
| - $io->err($this->_tokens[$count][1], 0); |
551 |
| - } else { |
552 |
| - $io->err($this->_tokens[$count], 0); |
553 |
| - if ($this->_tokens[$count] === '(') { |
554 |
| - $parenthesis++; |
555 |
| - } |
556 |
| - |
557 |
| - if ($this->_tokens[$count] === ')') { |
558 |
| - $parenthesis--; |
559 |
| - } |
560 |
| - } |
561 |
| - $count++; |
562 |
| - } |
563 |
| - $io->err("\n"); |
564 |
| - } |
565 |
| - |
566 |
| - /** |
567 |
| - * Search files that may contain translatable strings |
568 |
| - * |
569 |
| - * @return void |
570 |
| - */ |
571 |
| - protected function _searchFiles(): void |
572 |
| - { |
573 |
| - $pattern = false; |
574 |
| - if (!empty($this->_exclude)) { |
575 |
| - $exclude = []; |
576 |
| - foreach ($this->_exclude as $e) { |
577 |
| - if (DIRECTORY_SEPARATOR !== '\\' && $e[0] !== DIRECTORY_SEPARATOR) { |
578 |
| - $e = DIRECTORY_SEPARATOR . $e; |
579 |
| - } |
580 |
| - $exclude[] = preg_quote($e, '/'); |
581 |
| - } |
582 |
| - $pattern = '/' . implode('|', $exclude) . '/'; |
583 |
| - } |
584 |
| - |
585 |
| - foreach ($this->_paths as $path) { |
586 |
| - $path = realpath($path) . DIRECTORY_SEPARATOR; |
587 |
| - /** @psalm-suppress InternalClass */ |
588 |
| - $fs = new Filesystem(); |
589 |
| - /** @psalm-suppress InternalMethod */ |
590 |
| - $files = $fs->findRecursive($path, '/\.php$/'); |
591 |
| - $files = array_keys(iterator_to_array($files)); |
592 |
| - sort($files); |
593 |
| - if (!empty($pattern)) { |
594 |
| - $files = preg_grep($pattern, $files, PREG_GREP_INVERT); |
595 |
| - $files = array_values($files); |
596 |
| - } |
597 |
| - $this->_files = array_merge($this->_files, $files); |
598 |
| - } |
599 |
| - $this->_files = array_unique($this->_files); |
600 |
| - } |
601 |
| - |
602 |
| - /** |
603 |
| - * Returns whether this execution is meant to extract string only from directories in folder represented by the |
604 |
| - * APP constant, i.e. this task is extracting strings from same application. |
605 |
| - * |
606 |
| - * @return bool |
607 |
| - */ |
608 |
| - protected function _isExtractingApp(): bool |
609 |
| - { |
610 |
| - /** @psalm-suppress UndefinedConstant */ |
611 |
| - return $this->_paths === [APP]; |
612 |
| - } |
613 |
| - |
614 |
| - /** |
615 |
| - * Checks whether or not a given path is usable for writing. |
616 |
| - * |
617 |
| - * @param string $path Path to folder |
618 |
| - * @return bool true if it exists and is writable, false otherwise |
619 |
| - */ |
620 |
| - protected function _isPathUsable($path): bool |
621 |
| - { |
622 |
| - if (!is_dir($path)) { |
623 |
| - mkdir($path, 0770, true); |
624 |
| - } |
625 |
| - |
626 |
| - return is_dir($path) && is_writable($path); |
627 |
| - } |
628 | 337 | }
|
0 commit comments