123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591 |
- #!/usr/bin/env php
- <?php
- /* Copyright (c) 2015 Tommaso Basilici <t.basilici@19.coop>
- * Copyright (c) 2015 Laurent Destailleur <eldy@destailleur.fr>
- * Copyright (C) 2014-2016 Juanjo Menent <jmenent@2byte.es>
- *
- * 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 3 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 <https://www.gnu.org/licenses/>.
- */
- $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 "<html>";
- echo "<head>";
- echo "<STYLE type=\"text/css\">
- table {
- background: #f5f5f5;
- border-collapse: separate;
- box-shadow: inset 0 1px 0 #fff;
- font-size: 12px;
- line-height: 24px;
- margin: 30px auto;
- text-align: left;
- width: 800px;
- }
- th {
- background-color: #777;
- border-left: 1px solid #555;
- border-right: 1px solid #777;
- border-top: 1px solid #555;
- border-bottom: 1px solid #333;
- color: #fff;
- font-weight: bold;
- padding: 10px 15px;
- position: relative;
- text-shadow: 0 1px 0 #000;
- }
- td {
- border-right: 1px solid #fff;
- border-left: 1px solid #e8e8e8;
- border-top: 1px solid #fff;
- border-bottom: 1px solid #e8e8e8;
- padding: 10px 15px;
- position: relative;
- }
- tr {
- background-color: #f1f1f1;
- }
- tr:nth-child(odd) td {
- background-color: #f1f1f1;
- }
- </STYLE>";
- echo "<body>";
- }
- 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 "<br>";
- }
- 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 "<br>";
- }
- // 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 "<h2>";
- }
- print "Duplicate strings in lang files in $workdir - ".count($dups)." found\n";
- if ($web) {
- print "</h2>";
- }
- if ($web) {
- echo '<table border_bottom="1">'."\n";
- echo "<thead><tr><th align=\"center\">#</th><th>String</th><th>File and lines</th></thead>\n";
- echo "<tbody>\n";
- }
- $sduplicateinsamefile='';
- $sinmainandother='';
- $sininstallandadmin='';
- $sother='';
- $count = 0;
- foreach ($dups as $string => $pages) {
- $count++;
- $s='';
- // Keyword $string
- if ($web) {
- $s.="<tr>";
- }
- if ($web) {
- $s.="<td align=\"center\">";
- }
- if ($web) {
- $s.=$count;
- }
- if ($web) {
- $s.="</td>";
- }
- if ($web) {
- $s.="<td>";
- }
- $s.=$string;
- if ($web) {
- $s.="</td>";
- }
- if ($web) {
- $s.="<td>";
- }
- 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.="<br>";
- }
- }
- if ($web) {
- $s.="</td></tr>";
- }
- $s.="\n";
- if ($duplicateinsamefile) {
- $sduplicateinsamefile .= $s;
- } elseif ($inmain) {
- $sinmainandother .= $s;
- } elseif ($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 "</tbody>\n";
- echo "</table>\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[0-9]/', $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;
- }
- if (preg_match('/^ModuleCompanyCode/', $value)) {
- $qualifiedforclean=0;
- }
- if (preg_match('/InDolibarr$/', $value)) {
- $qualifiedforclean=0;
- }
- // admin.lang
- if (preg_match('/^DAV_ALLOW_PUBLIC_DIR/i', $value)) {
- $qualifiedforclean=0;
- }
- if (preg_match('/^DAV_ALLOW_ECM_DIR/i', $value)) {
- $qualifiedforclean=0;
- }
- // boxes.lang
- if (preg_match('/^BoxTitleLast/', $value)) {
- $qualifiedforclean=0;
- }
- if (preg_match('/^BoxTitleLatest/', $value)) {
- $qualifiedforclean=0;
- }
- // install.lang
- if (preg_match('/^KeepDefaultValues/', $value)) {
- $qualifiedforclean=0;
- }
- // mail.lang
- if (preg_match('/MailingModuleDesc/i', $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('/^NoteSomeFeaturesAreDisabled/', $value)) {
- $qualifiedforclean=0;
- }
- if (preg_match('/^(DoTest|Under|Limits|Cards|CurrentValue|DateLimit|DateAndHour|NbOfLines|NbOfObjects|NbOfReferes|TotalTTCShort|VATs)/', $value)) {
- $qualifiedforclean=0;
- }
- // modulebuilder
- if (preg_match('/^ModuleBuilderDesc/', $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;
- }
- // printing
- if (preg_match('/PrintingDriverDesc$/', $value)) {
- $qualifiedforclean=0;
- }
- if (preg_match('/PrintTestDesc$/', $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('/CardProduct/', $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.')" -e "('.$value.',"';
- $string = 'grep -R -m 1 -F --exclude=includes/* --include=*.php '.$search.' '.$htdocs.'* '.$scripts.'*';
- //print $string."<br>\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, implode("", $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 "</body>\n";
- echo "</html>\n";
- }
- exit;
|