TranslateYaml.php

Go to the documentation of this file.
00001 <?php
00016 class TranslateYaml {
00021     public static function parseGroupFile( $filename ) {
00022         $data = file_get_contents( $filename );
00023         $documents = preg_split( "/^---$/m", $data, -1, PREG_SPLIT_NO_EMPTY );
00024         $groups = array();
00025         $template = false;
00026         foreach ( $documents as $document ) {
00027             $document = self::loadString( $document );
00028 
00029             if ( isset( $document['TEMPLATE'] ) ) {
00030                 $template = $document['TEMPLATE'];
00031             } else {
00032                 if ( !isset( $document['BASIC']['id'] ) ) {
00033                     $error = "No path ./BASIC/id (group id not defined) ";
00034                     $error .= "in YAML document located in $filename";
00035                     trigger_error( $error );
00036                     continue;
00037                 }
00038                 $groups[$document['BASIC']['id']] = $document;
00039             }
00040         }
00041 
00042         foreach ( $groups as $i => $group ) {
00043             $groups[$i] = self::mergeTemplate( $template, $group );
00044         }
00045 
00046         return $groups;
00047     }
00048 
00055     public static function mergeTemplate( $base, $specific ) {
00056         foreach ( $specific as $key => $value ) {
00057             if ( is_array( $value ) && isset( $base[$key] ) && is_array( $base[$key] ) ) {
00058                 $base[$key] = self::mergeTemplate( $base[$key], $value );
00059             } else {
00060                 $base[$key] = $value;
00061             }
00062         }
00063 
00064         return $base;
00065     }
00066 
00072     public static function loadString( $text ) {
00073         global $wgTranslateYamlLibrary;
00074 
00075         switch ( $wgTranslateYamlLibrary ) {
00076             case 'spyc':
00077                 require_once __DIR__ . '/../libs/spyc/spyc.php';
00078                 $yaml = spyc_load( $text );
00079 
00080                 return self::fixSpycSpaces( $yaml );
00081             case 'syck':
00082                 $yaml = self::syckLoad( $text );
00083 
00084                 return self::fixSyckBooleans( $yaml );
00085             case 'syck-pecl':
00086                 $text = preg_replace( '~^(\s*)no(\s*:\s*[a-zA-Z-_]+\s*)$~m', '\1"no"\2', $text );
00087 
00088                 return syck_load( $text );
00089             default:
00090                 throw new MWException( "Unknown Yaml library" );
00091         }
00092     }
00093 
00098     public static function fixSyckBooleans( &$yaml ) {
00099         foreach ( $yaml as &$value ) {
00100             if ( is_array( $value ) ) {
00101                 self::fixSyckBooleans( $value );
00102             } elseif ( $value === 'yes' ) {
00103                 $value = true;
00104             }
00105         }
00106 
00107         return $yaml;
00108     }
00109 
00114     public static function fixSpycSpaces( &$yaml ) {
00115         foreach ( $yaml as $key => &$value ) {
00116             if ( is_array( $value ) ) {
00117                 self::fixSpycSpaces( $value );
00118             } elseif ( is_string( $value ) && $key === 'header' ) {
00119                 $value = preg_replace( '~^\*~m', ' *', $value ) . "\n";
00120             }
00121         }
00122 
00123         return $yaml;
00124     }
00125 
00126     public static function load( $file ) {
00127         $text = file_get_contents( $file );
00128 
00129         return self::loadString( $text );
00130     }
00131 
00132     public static function dump( $text ) {
00133         global $wgTranslateYamlLibrary;
00134 
00135         switch ( $wgTranslateYamlLibrary ) {
00136             case 'spyc':
00137                 require_once __DIR__ . '/../libs/spyc/spyc.php';
00138 
00139                 return Spyc::YAMLDump( $text );
00140             case 'syck-pecl':
00141                 // Just horrible output
00142                 // return syck_dump( $text );
00143             case 'syck':
00144                 return self::syckDump( $text );
00145             default:
00146                 throw new MWException( "Unknown Yaml library" );
00147         }
00148     }
00149 
00150     protected static function syckLoad( $data ) {
00151         # Make temporary file
00152         $td = wfTempDir();
00153         $tf = tempnam( $td, 'yaml-load-' );
00154 
00155         # Write to file
00156         file_put_contents( $tf, $data );
00157 
00158         $cmd = "perl -MYAML::Syck=LoadFile -MPHP::Serialization=serialize -wle '" .
00159             'my $tf = q[' . $tf . '];' .
00160             'my $yaml = LoadFile($tf);' .
00161             'open my $fh, ">", "$tf.serialized" or die qq[Can not open "$tf.serialized"];' .
00162             'print $fh serialize($yaml);' .
00163             'close($fh);' .
00164             "' 2>&1";
00165 
00166         $out = wfShellExec( $cmd, $ret );
00167 
00168         if ( $ret != 0 ) {
00169             throw new MWException( "The command '$cmd' died in execution with exit code '$ret': $out" );
00170         }
00171 
00172         $serialized = file_get_contents( "$tf.serialized" );
00173         $php_data = unserialize( $serialized );
00174 
00175         unlink( $tf );
00176         unlink( "$tf.serialized" );
00177 
00178         return $php_data;
00179     }
00180 
00181     protected static function syckDump( $data ) {
00182         # Make temporary file
00183         $td = wfTempDir();
00184         $tf = tempnam( $td, 'yaml-load-' );
00185 
00186         # Write to file
00187         $sdata = serialize( $data );
00188         file_put_contents( $tf, $sdata );
00189 
00190         $cmd = "perl -MYAML::Syck=DumpFile -MPHP::Serialization=unserialize -MFile::Slurp=slurp -we '" .
00191             '$YAML::Syck::Headless = 1;' .
00192             '$YAML::Syck::SortKeys = 1;' .
00193             'my $tf = q[' . $tf . '];' .
00194             'my $serialized = slurp($tf);' .
00195             'my $unserialized = unserialize($serialized);' .
00196             'my $unserialized_utf8 = deutf8($unserialized);' .
00197             'DumpFile(qq[$tf.yaml], $unserialized_utf8);' .
00198             'sub deutf8 {' .
00199                 'if(ref($_[0]) eq "HASH") {' .
00200                     'return { map { deutf8($_) } %{$_[0]} };' .
00201                 '} elsif(ref($_[0]) eq "ARRAY") {' .
00202                     'return [ map { deutf8($_) } @{$_[0]} ];' .
00203                 '} else {' .
00204                     'my $s = $_[0];' .
00205                     'utf8::decode($s);' .
00206                     'return $s;' .
00207                 '}' .
00208             '}' .
00209             "' 2>&1";
00210         $out = wfShellExec( $cmd, $ret );
00211         if ( $ret != 0 ) {
00212             throw new MWException( "The command '$cmd' died in execution with exit code '$ret': $out" );
00213         }
00214 
00215         $yaml = file_get_contents( "$tf.yaml" );
00216 
00217         unlink( $tf );
00218         unlink( "$tf.yaml" );
00219 
00220         return $yaml;
00221     }
00222 }
Generated on Tue Oct 29 00:00:26 2013 for MediaWiki Translate Extension by  doxygen 1.6.3