<?php
/*! \brief
* This is pseudo tool to make WGF environment change to pseudo testing environment
* \author William Su
*/
// avoid excuted from web[http://].
if(isset($_SERVER['REQUEST_METHOD'])){
echo "<html><body>Permission denied.</body></html>\n";
exit();
}
require_once(dirname(__FILE__).'/../../../inc/class/init.php');
$strFolderPath = WF::getWidgetPoolFactory()->getWPHome();
$arrPathWpFiles = WF::getIOFactory()->getFile()->getArrPathByFolderPath($strFolderPath);
// Step 1 : get all en_US.xml in /path/to/wp1
$arrPathWpFilesEnUS = array();
echo ">>Valid L10n resource files list:\r\n";
$index = 1;
foreach($arrPathWpFiles as $strPathWpFiles){
if(false !== stripos($strPathWpFiles, 'en_US.') //Support en_US.xml/en_US.js
&& false === strpos($strPathWpFiles, ' - Copy')){ //Skip - Copy folder
$arrPathWpFilesEnUS[] = $strPathWpFiles;
echo $index.")".$strPathWpFiles."\r\n";
$index++;
}
}
/**
* This method help to mkdir recursively
*/
function toolPseudo_mkdirRecursive($strPathFolder){
echo "\r\n START recursive mkdir::[".$strPathFolder."]";
if(false === is_dir($strPathFolder)){
$strPathFolder = dirname($strPathFolder);
}
$arrPathFolderNeedToCreate = array();
while(!file_exists($strPathFolder)){
$arrPathFolderNeedToCreate[] = $strPathFolder;
$strPathFolder = dirname($strPathFolder);
}
if(is_array($arrPathFolderNeedToCreate) && $arrPathFolderNeedToCreate){
$arrPathFolderNeedToCreate = array_reverse($arrPathFolderNeedToCreate);
foreach($arrPathFolderNeedToCreate as $strPathFolderNeedToCreate){
WF::getIOFactory()->getFile()->mkdir($strPathFolderNeedToCreate);
}
}
echo "\r\n SUCCESS recursive mkdir::[".$strPathFolder."]\r\n";
}
/**
* This method help to get the final pseudo base on en_US string length
*/
function toolPseudo_getPseudo($str, $isJSON = false){
// handler the CDATA string
$strCDATAPrefix = '';
$strCDATASuffix = '';
if(false !== strpos($str, '<![CDATA[')){
$strCDATAPrefix = '<![CDATA[';
$strCDATASuffix = ']]>';
$str = substr($str, 9, -3);
}
$str = (true === $isJSON) ? addslashes($str) : $str;
$intStrLength = strlen($str);
$floatAdditionalSpaceNeededRatio = null; //default
// Generate the add space ratio array
/*
Below is the mapping table which provide by L10N team
Original length(char) :: Additonal Sapce needed
up to 10 :: 100%~200%
11 to 20 :: 80% to 100%
21 to 30 :: 60% to 80%
31 to 50 :: 40% to 60%
51 to 70 :: 31% to 40%
over 70 :: 30%
*/
$arrAdditionalSpaceNeededRatio = array();
for($i=1; $i<=10; $i++){
$index = $i;
$arrAdditionalSpaceNeededRatio[$index] = 2 - ($i * 0.1); //2.0, 1.9, 1.8 ~ 1.0
}
for($i=1; $i<=10; $i++){
$index = $i+10;
$arrAdditionalSpaceNeededRatio[$index] = 1 - ($i * 0.02); //1.0, 0.98, 0.96 ~ 0.8
}
for($i=1; $i<=10; $i++){
$index = $i+20;
$arrAdditionalSpaceNeededRatio[$index] = 0.8 - ($i * 0.02); //0.8, 0.78, 0.76 ~ 0.6
}
for($i=1; $i<=20; $i++){
$index = $i+30;
$arrAdditionalSpaceNeededRatio[$index] = 0.6 - ($i * 0.01); //0.6, 0.59, 0.58 ~ 0.4
}
for($i=1; $i<=20; $i++){
$index = $i+50;
$arrAdditionalSpaceNeededRatio[$index] = 0.4 - ($i * 0.01); //0.4, 0.39, 0.38 ~ 0.31
}
if($intStrLength > 70){
$arrAdditionalSpaceNeededRatio[$intStrLength] = 0.3;
}
// $floatAdditionalSpaceNeededRatio is the actual ratio need to add
$floatAdditionalSpaceNeededRatio = isset($arrAdditionalSpaceNeededRatio[$intStrLength]) ? $arrAdditionalSpaceNeededRatio[$intStrLength] : null;
// $arrPseudo is the array of Frank language pseudo char
$indexPseudo = 0;
$arrPseudo = array('é','è','à');
// $intStrLengthAfterPseudo is the L10N string length after add the pseudo string
$intStrLengthAfterPseudo = $intStrLength + ($intStrLength * $floatAdditionalSpaceNeededRatio);
$intStrLengthTmp = $intStrLength;
$strPseudoFinal = $str;
$strPrefixFinal = '';
$strSuffixFinal = '';
while($intStrLengthTmp < $intStrLengthAfterPseudo){
// use the $charPseudo alternation
$charPseudo = $arrPseudo[($indexPseudo%3)];
$strPrefixFinal .= $charPseudo;
$strSuffixFinal .= $charPseudo;
$intStrLengthTmp += 2; //$strPrefix+$strSuffix = 2
$indexPseudo++;
}
// use symbols '!' to make sure the start and the end position of string
// use symbols ["] & ['] to solve javascript functional error. EX : some javascript variable may use double quote or single quote to declare
$strPseudoFinal = $strCDATAPrefix.'!'.$strPrefixFinal.$strPseudoFinal.$strSuffixFinal.'!'.$strCDATASuffix;
return $strPseudoFinal;
}
//var_dump($arrPathWpFilesEnUS);
//exit();
//$arrPathWpFilesEnUS = array('/Users/WilliamSu/Documents/htdocs/william_su_tw-williamsu_mbpr/Core/TMLS/Dev/TMLS-1.5/TMLS-Server/src/Server/Web/UI/widget/repository/widgetPool/../../repository/widgetPool/wp1/widgetBase/modTMLS/app/l10n/en_US.js');
if(!$arrPathWpFilesEnUS){
echo("The L10N en_US.xml files is empty! Pseudo string prepare proccess abort!\r\n");
exit();
}
echo("Pseudo string prepare proccess >>>>>>>>>>> START\r\n");
// Do the backup before execute the pseudo code replacement
// You can use this backup do the rollback later
$strDateCurrent = date('YmdHis');
$strPathBackup = WF::getDocumentRoot().'/repository/backup/pseudo_'.$strDateCurrent;
//toolPseudo_mkdirRecursive($strPathBackup);
function putAppEnUSJsToAppAppJs($strContentAppJS, $searchKeyWord, $sourceAppJS){
// 2. Get content of app/l10n/en_US.js
$sourceEnUSJS = dirname(__FILE__).'/../../../'.WF::getWidgetPoolFactory()->getWPWebrootNoSlash().'/widgetBase/modTMLS/app/l10n/en_US.js';
$strContentEnUSJS = file_get_contents($sourceEnUSJS);
$strContentEnUSJSTrim = preg_replace('/\s\s+/', ' ', trim($strContentEnUSJS));
//echo '$sourceEnUSJS::'.$sourceEnUSJS."\r\n";
//echo '$strContentEnUSJSTrim::'.$strContentEnUSJSTrim."\r\n";
echo "SUCCESS get pseudo content from app/l10n/en_US.js and remove space.\r\n";
$intPosStart = strpos($strContentAppJS,$searchKeyWord);
$intPosEnd = strpos($strContentAppJS, '"}', $intPosStart);
//echo '$strContentAppJS::'.$strContentAppJS."\r\n";
//echo '$intPosStart::'.$intPosStart."\r\n";
//echo '$intPosEnd::'.$intPosEnd."\r\n";
$strContentAppJSFinal = substr_replace($strContentAppJS, $strContentEnUSJSTrim, $intPosStart, ($intPosEnd-$intPosStart)+2);
if (WF::getIOFactory()->getFile()->writeDataSafe($sourceAppJS, 'w+', $strContentAppJSFinal)) {
echo("Success put app/l10n/en_US.js to app/app.js\r\n");
}else{
echo("Failed to put app/l10n/en_US.js to app/app.js\r\n");
}
}
/**
* @param string $string
* @return param string $new_str
*/
function removeWihteLineAndChangeNOrRToNR($string){
//1. Chnage \n or \r to \r\n
$new_str = str_replace(array("\n", "\r"), "\r\n", $string );
//2. Chnage \n\n in js
$new_str = str_replace(array("\\n\\n"), "[nnn]", $new_str );
//3. Change end of string \r\n
$new_str = str_replace(array(">\r\n"), "[rnrn]", $new_str );
//4. Remove wihite line
$new_str = str_replace(array("\r\n"), "", $new_str );
//5. Recover end of string \r\n
$new_str = str_replace(array("[rnrn]"), ">\r\n", $new_str );
//6. Recover \n\n in Js.
$new_str = str_replace(array("[nnn]"), "\\n\\n", $new_str );
return $new_str;
}
/**
* @param $strPathWpFilesEnUS
* @param $strPathBackup
* @param $matchesEnUs
* @throws WFIOFileException
*/
function processXMLPseudo($strPathWpFilesEnUS, $strPathBackup)
{
$strPathWpFilesEnUSDirname = dirname($strPathWpFilesEnUS);
// Get content from en_US.xml
$strXmlEnUs = file_get_contents($strPathWpFilesEnUS);
$strXmlEnUs = removeWihteLineAndChangeNOrRToNR($strXmlEnUs);
/**
* The following is the example result of $matchesEnUs
* matched: <string id="title"><![CDATA[Sample_Test]]></string>
* part 1: <string id="title">
* part 2: string
* part 3: <![CDATA[Sample_Test]]>
* part 4: </string>
*
* matched: <string id="title">Sample_Test2</string>
* part 1: <string id="title">
* part 2: string
* part 3: Sample_Test2
* part 4: </string>
*/
$stringPseudo = 'éèà';
if (false === strpos($strXmlEnUs, $stringPseudo)) {
echo "\r\n >>> START processXMLPseudo[".$strPathWpFilesEnUS."] \r\n";
preg_match_all("/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/", $strXmlEnUs, $matchesEnUs, PREG_SET_ORDER);
// Step : backup original en_US.xml to /path/to/backup/en_US.xml
$sourceEnUs = $strPathWpFilesEnUS;
list($tmp, $strPathRelativeWpFilesEnUS) = explode(WF::getWidgetPoolFactory()->getWPWebrootNoSlash(), $strPathWpFilesEnUS);
$dest = $strPathBackup . '/' . WF::getWidgetPoolFactory()->getWPWebrootNoSlash() . $strPathRelativeWpFilesEnUS;
$strPathBackupFile = $dest;
toolPseudo_mkdirRecursive($strPathBackupFile);
if (WF::getIOFactory()->getFile()->copyRecurse($sourceEnUs, $dest)) {
echo("Backup source success: [" . $strPathRelativeWpFilesEnUS . "]\r\n");
}
$strXmlFinal = '<?xml version="1.0" encoding="utf-8"?>
<translations language="English">' . "\r\n";
foreach ($matchesEnUs as $assocMatchesEnUs) {
$strPseudoFinal = toolPseudo_getPseudo($assocMatchesEnUs[3]);
$strXmlFinal .= ' ' . $assocMatchesEnUs[1] . $strPseudoFinal . $assocMatchesEnUs[4] . "\r\n";
}
$strXmlFinal .= '</translations>';
//var_dump($strXmlFinal);
/*$pattern = '/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/';
$replacement = "$1{$strPrefix}$3{$strSuffix}$4";
$strXml = preg_replace($pattern, $replacement, $strXml);*/
if (WF::getIOFactory()->getFile()->writeDataSafe($sourceEnUs, 'w+', $strXmlFinal)) {
echo("Pseudo string prepare success : [" . $strPathRelativeWpFilesEnUS . "]\r\n");
}
echo "\r\n >>> SUCCESS processXMLPseudo[".$strPathWpFilesEnUS."] \r\n";
}else{
echo "\r\n >>> SKIP processXMLPseudo[".$strPathWpFilesEnUS."]. Reason: File already pseudo. \r\n";
}
}
/**
* @param $strPathWpFilesEnUS
* @param $strPathBackup
* @throws WFIOFileException
*/
function processJSONPseudo($strPathWpFilesEnUS, $strPathBackup)
{
$strPathWpFilesEnUSDirname = dirname($strPathWpFilesEnUS);
// Get content from en_US.js
$strJSONEnUs = file_get_contents($strPathWpFilesEnUS);
$strJSONEnUs = removeWihteLineAndChangeNOrRToNR($strJSONEnUs);
/**
* The following is the example result of $matchesEnUs
* matched: <string id="title"><![CDATA[Sample_Test]]></string>
* part 1: <string id="title">
* part 2: string
* part 3: <![CDATA[Sample_Test]]>
* part 4: </string>
*
* matched: <string id="title">Sample_Test2</string>
* part 1: <string id="title">
* part 2: string
* part 3: Sample_Test2
* part 4: </string>
*/
////preg_match_all("/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/", $strJSONEnUs, $matchesEnUs, PREG_SET_ORDER);
$stringPseudo = 'éèà';
if (false === strpos($strJSONEnUs, $stringPseudo)) {
echo "\r\n >>> START processJSONPseudo[".$strPathWpFilesEnUS."] \r\n";
// Step : backup original en_US.xml to /path/to/backup/en_US.xml
$sourceEnUs = $strPathWpFilesEnUS;
list($tmp, $strPathRelativeWpFilesEnUS) = explode(WF::getWidgetPoolFactory()->getWPWebrootNoSlash(), $strPathWpFilesEnUS);
$dest = $strPathBackup . '/' . WF::getWidgetPoolFactory()->getWPWebrootNoSlash() . $strPathRelativeWpFilesEnUS;
$strPathBackupFile = $dest;
toolPseudo_mkdirRecursive($strPathBackupFile);
if (WF::getIOFactory()->getFile()->copyRecurse($sourceEnUs, $dest)) {
echo("Backup source success: [" . $strPathRelativeWpFilesEnUS . "]\r\n");
}
$strJSONFinal = '{' . "\r\n";
$assocJSONEnUS = json_decode($strJSONEnUs, true);
$arrJSONFinal = array();
if(!empty($assocJSONEnUS)){
foreach($assocJSONEnUS as $key => $value){
$strPseudoFinal = toolPseudo_getPseudo($value, true);
$arrJSONFinal[] = '"'.$key.'": "'.$strPseudoFinal.'"';
}
$strJSONFinal .= implode(",\r\n", $arrJSONFinal);
}
$strJSONFinal .= '}';
//var_dump($strJSONFinal);exit();
/*$pattern = '/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/';
$replacement = "$1{$strPrefix}$3{$strSuffix}$4";
$strXml = preg_replace($pattern, $replacement, $strXml);*/
if (WF::getIOFactory()->getFile()->writeDataSafe($sourceEnUs, 'w+', $strJSONFinal)) {
echo("Pseudo string prepare success : [" . $strPathRelativeWpFilesEnUS . "]\r\n");
}
echo "\r\n >>> SUCCESS processJSONPseudo[".$strPathWpFilesEnUS."] \r\n";
}else{
echo "\r\n >>> SKIP processJSONPseudo[".$strPathWpFilesEnUS."]. Reason: File already pseudo. \r\n";
}
}
foreach($arrPathWpFilesEnUS as $strPathWpFilesEnUS) {
$ext = pathinfo($strPathWpFilesEnUS, PATHINFO_EXTENSION);
switch($ext){
case 'xml':
//processXMLPseudo($strPathWpFilesEnUS, $strPathBackup,$matchesEnUs);
processXMLPseudo($strPathWpFilesEnUS, $strPathBackup);
break;
case 'js':
case 'json':
processJSONPseudo($strPathWpFilesEnUS, $strPathBackup);
break;
}
}
// app/l10n/en_US.js has already been compressed into app/app.js
// Do the following items to do the pseudo file
// 1. Backup app/app.js
// 2. Get content of app/l10n/en_US.js
// 3. Put en_US.js content into app/app.js
// 1. Backup app/app.js
echo ">>> START put app/l10n/en_US.js to app/app.js\r\n";
$stringPseudo = 'éèà';
$sourceAppJS = dirname(__FILE__).'/../../../'.WF::getWidgetPoolFactory()->getWPWebrootNoSlash().'/widgetBase/modTMLS/app/app.js';
list($tmp, $strPathRelativeWpFilesAppJS) = explode(WF::getWidgetPoolFactory()->getWPWebrootNoSlash(), $sourceAppJS);
//echo '$sourceAppJS::'.$sourceAppJS."\r\n";
//echo '$strPathRelativeWpFilesAppJS::'.$strPathRelativeWpFilesAppJS."\r\n";
$destAppJS = $strPathBackup . '/' . WF::getWidgetPoolFactory()->getWPWebrootNoSlash() . $strPathRelativeWpFilesAppJS;
$destAppOriginalJS = str_replace('app.js','app-original.js', $sourceAppJS);
//echo '$destAppJS::'.$destAppJS."\r\n";
//echo '$destAppOriginalJS::'.$destAppOriginalJS."\r\n";
$contentAppJS = file_get_contents($sourceAppJS);
if (false === strpos($contentAppJS, $stringPseudo)) {
WF::getIOFactory()->getFile()->copyRecurse($sourceAppJS, $destAppOriginalJS);
}
toolPseudo_mkdirRecursive($destAppJS);
WF::getIOFactory()->getFile()->copyRecurse($destAppOriginalJS, $destAppJS);
// 3. Put en_US.js content into app/app.js
$strContentAppJS = file_get_contents($sourceAppJS);
if(false !== strpos($strContentAppJS,'{_Comment_Common')){
$searchKeyWord = '{_Comment_Common';
putAppEnUSJsToAppAppJs($strContentAppJS, $searchKeyWord, $sourceAppJS);
}elseif(false !== strpos($strContentAppJS,'{ "_Comment_Common')){
$searchKeyWord = '{ "_Comment_Common';
putAppEnUSJsToAppAppJs($strContentAppJS, $searchKeyWord, $sourceAppJS);
}else{
echo("Skip put app/l10n/en_US.js to app/app.js. Reson:Failed to find _Comment_Common in app/app.js\r\n");
exit();
}
echo("Pseudo string prepare proccess >>>>>>>>>>> END\r\n");