19 private const MARKER =
'%CODE%';
21 public function __construct() {
22 parent::__construct();
23 $this->addDescription(
'Renames language codes in repos.' );
26 'Comma separated list of group IDs (can use * as wildcard)',
45 'Target directory for exported files',
49 $this->requireExtension(
'Translate' );
52 public function execute() {
53 $target = rtrim( $this->getOption(
'target' ),
'/' );
54 $sourceLanguage = $this->getOption(
'source-language' );
55 $targetLanguage = $this->getOption(
'target-language' );
57 if ( !is_writable( $target ) ) {
58 $this->fatalError(
"Target directory is not writable ($target)." );
61 $groupIds = explode(
',', trim( $this->getOption(
'group' ) ) );
62 $groupIds = MessageGroups::expandWildcards( $groupIds );
63 $groups = MessageGroups::getGroupsById( $groupIds );
64 $groups = $this->filterGroups( $groups );
66 if ( $groups === [] ) {
67 $this->fatalError(
'EE1: No valid message groups identified.' );
70 foreach ( $groups as $group ) {
74 $sourcePath = $group->getTargetFilename( $sourceLanguage );
75 $targetPath = $group->getTargetFilename( $targetLanguage );
77 if ( !file_exists(
"$target/$sourcePath" ) ) {
81 $this->output(
"Renaming $sourcePath to $targetPath\n" );
82 $this->renameFile(
"$target/$sourcePath",
"$target/$targetPath" );
84 $pathPattern =
"$target/" . $group->getTargetFilename( self::MARKER );
86 $needsCleanup = $this->needsCleanup( $pathPattern, $sourceLanguage, $pathToRemove );
87 if ( $needsCleanup ===
'yes' ) {
88 $this->output(
"Removing empty directory $pathToRemove\n" );
89 rmdir( $pathToRemove );
90 } elseif ( $needsCleanup ===
'maybe' ) {
91 $this->output(
"Not removing (yet?) non-empty directory $pathToRemove\n" );
95 $this->output(
"Done\n" );
102 private function filterGroups( array $groups ) {
104 foreach ( $groups as $groupId => $group ) {
106 $this->output(
"Skipping non-file based message group $groupId.\n" );
109 $return[$groupId] = $group;
114 private function renameFile( $source, $target ) {
116 if ( !is_dir( dirname( $target ) ) ) {
117 mkdir( dirname( $target ), 0777,
true );
120 rename( $source, $target );
123 private function isDirectoryEmpty( $dir ) {
124 return array_diff( scandir( $dir ), [
'..',
'.' ] ) === [];
127 private function needsCleanup( $pathPattern, $sourceLanguage, &$pathToRemove ) {
129 $currentComponent = basename( $pathPattern );
130 if ( strpos( $currentComponent, self::MARKER ) ===
false ) {
131 $pathPattern = dirname( $pathPattern );
135 $pathToRemove = str_replace( self::MARKER, $sourceLanguage, $pathPattern );
136 if ( !is_dir( $pathToRemove ) ) {
141 return $this->isDirectoryEmpty( $pathToRemove ) ?
'yes' :
'maybe';
142 }
while ( $currentComponent !==
'' );