#!/usr/bin/env php * Copyright (c) 2015 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ $sapi_type = php_sapi_name(); $script_file = basename(__FILE__); $path=dirname(__FILE__).'/'; $web=0; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { $web=1; } if ($web) { echo ""; echo ""; echo ""; echo ""; } echo "If you call this with argument \"unused=true\" it searches for the translation strings that exist in en_US but are never used.\n"; if ($web) print "
"; echo "IMPORTANT: that can take quite a lot of time (up to 10 minutes), you need to tune the max_execution_time on your php.ini accordingly.\n"; if ($web) print "
"; // STEP 1 - Search duplicates keys // directory containing the php and lang files $htdocs = $path."../../htdocs/"; $scripts = $path."../../scripts/"; // directory containing the english lang files $workdir = $htdocs."langs/en_US/"; $files = scandir($workdir); if (empty($files)) { echo "Can't scan workdir = ".$workdir; exit; } $dups=array(); $exludefiles = array('.','..','README'); $files = array_diff($files,$exludefiles); // To force a file: $files=array('myfile.lang'); if (isset($argv[2])) { $files = array($argv[2]); } $langstrings_3d = array(); $langstrings_full = array(); foreach ($files AS $file) { $path_file = pathinfo($file); // we're only interested in .lang files if ($path_file['extension']=='lang') { $content = file($workdir.$file); foreach ($content AS $line => $row) { // don't want comment lines if (substr($row,0,1) !== '#') { // don't want lines without the separator (why should those even be here, anyway...) if (strpos($row,'=')!==false) { $row_array = explode('=',$row); // $row_array[0] = key $langstrings_3d[$path_file['basename']][$line+1]=$row_array[0]; $langstrings_3dtrans[$path_file['basename']][$line+1]=$row_array[1]; $langstrings_full[]=$row_array[0]; $langstrings_dist[$row_array[0]]=$row; } } } } } foreach ($langstrings_3d AS $filename => $file) { foreach ($file AS $linenum => $value) { $keys = array_keys($langstrings_full, $value); if (count($keys)>1) { foreach ($keys AS $key) { $dups[$value][$filename][$linenum] = trim($langstrings_3dtrans[$filename][$linenum]); } } } } if ($web) print "

"; print "Duplicate strings in lang files in $workdir - ".count($dups)." found\n"; if ($web) print "

"; if ($web) { echo ''."\n"; echo "\n"; echo "\n"; } $sduplicateinsamefile=''; $sinmainandother=''; $sininstallandadmin=''; $sother=''; $count = 0; foreach ($dups as $string => $pages) { $count++; $s=''; // Keyword $string if ($web) $s.=""; if ($web) $s.=""; if ($web) $s.=""; if ($web) $s.=""; $s.="\n"; if ($duplicateinsamefile) $sduplicateinsamefile .= $s; else if ($inmain) $sinmainandother .= $s; else if ($inadmin) $sininstallandadmin .= $s; else $sother .= $s; } if (! $web) print "\n***** Entries duplicated in same file\n"; print $sduplicateinsamefile; if (! $web && empty($sduplicateinsamefile)) print "None\n"; if (! $web) print "\n"; if (! $web) print "***** Entries in main and another (keep only entry in main)\n"; print $sinmainandother; if (! $web && empty($sinmainandother)) print "None\n"; if (! $web) print "\n"; if (! $web) print "***** Entries in admin and another\n"; print $sininstallandadmin; if (! $web && empty($sininstallandadmin)) print "None\n"; if (! $web) print "\n"; if (! $web) print "***** Other\n"; print $sother; if (! $web && empty($sother)) print "None\n"; if (! $web) print "\n"; if ($web) { echo "\n"; echo "
#StringFile and lines
"; if ($web) $s.=$count; if ($web) $s.=""; $s.=$string; if ($web) $s.=""; if (! $web) $s.= ' : '; // Loop on each files keyword was found $duplicateinsamefile=0; $inmain=0; $inadmin=0; foreach ($pages AS $file => $lines) { if ($file == 'main.lang') { $inmain=1; $inadmin=0; } if ($file == 'admin.lang' && ! $inmain) { $inadmin=1; } $s.=$file." "; // Loop on each line keword was found into file. $listoffilesforthisentry=array(); foreach ($lines as $line => $translatedvalue) { if (! empty($listoffilesforthisentry[$file])) $duplicateinsamefile=1; $listoffilesforthisentry[$file]=1; $s.= "(".$line." - ".htmlentities($translatedvalue).") "; } if ($web) $s.="
"; } if ($web) $s.="
\n"; } // STEP 2 - Search key not used if ((! empty($_REQUEST['unused']) && $_REQUEST['unused'] == 'true') || (isset($argv[1]) && $argv[1]=='unused=true')) { print "***** Strings in en_US that are never used:\n"; $unused=array(); foreach ($langstrings_dist AS $value => $line) { $qualifiedforclean=1; // Check if we must keep this key to be into file for removal if (preg_match('/^Module\d+/', $value)) $qualifiedforclean=0; if (preg_match('/^Permission\d+/', $value)) $qualifiedforclean=0; if (preg_match('/^PermissionAdvanced\d+/', $value)) $qualifiedforclean=0; if (preg_match('/^ProfId\d+/', $value)) $qualifiedforclean=0; if (preg_match('/^Delays_/', $value)) $qualifiedforclean=0; if (preg_match('/^BarcodeDesc/', $value)) $qualifiedforclean=0; if (preg_match('/^Extrafield/', $value)) $qualifiedforclean=0; if (preg_match('/^LocalTax/', $value)) $qualifiedforclean=0; if (preg_match('/^Country/', $value)) $qualifiedforclean=0; if (preg_match('/^Civility/', $value)) $qualifiedforclean=0; if (preg_match('/^Currency/', $value)) $qualifiedforclean=0; if (preg_match('/^DemandReasonTypeSRC/', $value)) $qualifiedforclean=0; if (preg_match('/^PaperFormat/', $value)) $qualifiedforclean=0; if (preg_match('/^Duration/', $value)) $qualifiedforclean=0; if (preg_match('/^AmountLT/', $value)) $qualifiedforclean=0; if (preg_match('/^TotalLT/', $value)) $qualifiedforclean=0; if (preg_match('/^Month/', $value)) $qualifiedforclean=0; if (preg_match('/^MonthShort/', $value)) $qualifiedforclean=0; if (preg_match('/^Day\d/', $value)) $qualifiedforclean=0; if (preg_match('/^Short/', $value)) $qualifiedforclean=0; if (preg_match('/^ExportDataset_/', $value)) $qualifiedforclean=0; if (preg_match('/^ImportDataset_/', $value)) $qualifiedforclean=0; if (preg_match('/^ActionAC_/', $value)) $qualifiedforclean=0; if (preg_match('/^TypeLocaltax/', $value)) $qualifiedforclean=0; if (preg_match('/^StatusProspect/', $value)) $qualifiedforclean=0; if (preg_match('/^PL_/', $value)) $qualifiedforclean=0; if (preg_match('/^TE_/', $value)) $qualifiedforclean=0; if (preg_match('/^JuridicalStatus/', $value)) $qualifiedforclean=0; if (preg_match('/^CalcMode/', $value)) $qualifiedforclean=0; if (preg_match('/^newLT/', $value)) $qualifiedforclean=0; if (preg_match('/^LT\d/', $value)) $qualifiedforclean=0; if (preg_match('/^TypeContact_contrat_/', $value)) $qualifiedforclean=0; if (preg_match('/^ErrorPriceExpression/', $value)) $qualifiedforclean=0; if (preg_match('/^Language_/', $value)) $qualifiedforclean=0; if (preg_match('/^DescADHERENT_/', $value)) $qualifiedforclean=0; if (preg_match('/^SubmitTranslation/', $value)) $qualifiedforclean=0; // main.lang if (preg_match('/^Duration/', $value)) $qualifiedforclean=0; if (preg_match('/^FormatDate/', $value)) $qualifiedforclean=0; if (preg_match('/^DateFormat/', $value)) $qualifiedforclean=0; if (preg_match('/^.b$/', $value)) $qualifiedforclean=0; if (preg_match('/^.*Bytes$/', $value)) $qualifiedforclean=0; if (preg_match('/^(DoTest|Under|Limits|Cards|CurrentValue|DateLimit|DateAndHour|NbOfLines|NbOfObjects|NbOfReferes|TotalTTCShort|VATs)/', $value)) $qualifiedforclean=0; // orders if (preg_match('/^OrderSource/', $value)) $qualifiedforclean=0; if (preg_match('/^TypeContact_/', $value)) $qualifiedforclean=0; // other.lang if (preg_match('/^Notify_/', $value)) $qualifiedforclean=0; if (preg_match('/^PredefinedMail/', $value)) $qualifiedforclean=0; if (preg_match('/^DemoCompany/', $value)) $qualifiedforclean=0; if (preg_match('/^WeightUnit/', $value)) $qualifiedforclean=0; if (preg_match('/^LengthUnit/', $value)) $qualifiedforclean=0; if (preg_match('/^SurfaceUnit/', $value)) $qualifiedforclean=0; if (preg_match('/^VolumeUnit/', $value)) $qualifiedforclean=0; if (preg_match('/^SizeUnit/', $value)) $qualifiedforclean=0; if (preg_match('/^EMailText/', $value)) $qualifiedforclean=0; if (preg_match('/ById$/', $value)) $qualifiedforclean=0; if (preg_match('/ByLogin$/', $value)) $qualifiedforclean=0; // products if (preg_match('/GlobalVariableUpdaterType$/', $value)) $qualifiedforclean=0; if (preg_match('/GlobalVariableUpdaterHelp$/', $value)) $qualifiedforclean=0; if (preg_match('/OppStatus/', $value)) $qualifiedforclean=0; if (preg_match('/AvailabilityType/', $value)) $qualifiedforclean=0; if (preg_match('/sms/i', $value)) $qualifiedforclean=0; if (preg_match('/TF_/i', $value)) $qualifiedforclean=0; if (preg_match('/WithBankUsing/i', $value)) $qualifiedforclean=0; if (preg_match('/descWORKFLOW_/i', $value)) $qualifiedforclean=0; if (! $qualifiedforclean) { continue; } //$search = '\'trans("'.$value.'")\''; $search = '-e "\''.$value.'\'" -e \'"'.$value.'"\' -e "('.$value.')"'; $string = 'grep -R -m 1 -F --exclude=includes/* --include=*.php '.$search.' '.$htdocs.'* '.$scripts.'*'; //print $string."
\n"; exec($string,$output); if (empty($output)) { $unused[$value] = $line; echo $line; // $trad contains the \n } else { unset($output); //print 'X'.$output.'Y'; } } if (empty($unused)) print "No string not used found.\n"; else { $filetosave='/tmp/'.($argv[2]?$argv[2]:"").'notused.lang'; print "Strings in en_US that are never used are saved into file ".$filetosave.":\n"; file_put_contents($filetosave, join("",$unused)); print "To remove from original file, run command :\n"; if (($argv[2]?$argv[2]:"")) print 'cd htdocs/langs/en_US; mv '.($argv[2]?$argv[2]:"")." ".($argv[2]?$argv[2]:"").".tmp; "; print "diff ".($argv[2]?$argv[2]:"").".tmp ".$filetosave." | grep \< | cut -b 3- > ".($argv[2]?$argv[2]:""); if (($argv[2]?$argv[2]:"")) print "; rm ".($argv[2]?$argv[2]:"").".tmp;\n"; } } echo "\n"; if ($web) { echo "\n"; echo "\n"; } exit;