Alex Trofimov 12 лет назад
Родитель
Сommit
1a30899c99
1 измененных файлов с 246 добавлено и 0 удалено
  1. 246 0
      scripts/check_unused_lang.php

+ 246 - 0
scripts/check_unused_lang.php

@@ -0,0 +1,246 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DolphinInstall Dolphin Install
+ * @{
+ */
+
+$aPathInfo = pathinfo(__FILE__);
+require_once ($aPathInfo['dirname'] . '/../inc/header.inc.php');
+require_once(BX_DIRECTORY_PATH_INC . 'design.inc.php');
+
+bx_import('BxDolXmlParser');
+
+/**
+ * Command line interface for checking for unused language strings
+ */
+class BxDolCheckUnusedLangsCmd
+{
+    protected $_bQuiet = false;
+    protected $_sInputFile = '';
+    protected $_sOutputFoundFile = '';
+    protected $_sOutputUnusedFile = '';
+    protected $_bSortOutput = false;
+    protected $_sModule = false;
+    protected $_iLimit = 0;
+    protected $_aOptionsSystem;
+    protected $_aOptionsModule;
+
+    public function __construct() 
+    {
+        $this->_aOptionsSystem = array (
+            'dirs' => array (
+                '' => array ('*.php'),
+                'install/' => array('*.php', '*.sql'),
+                'studio/' => array('*.php', '*.html'),
+                'inc/' => array ('*.php'),
+                'modules/' => array('*.php', '*.html', '*.sql'),
+                'template/' => array('*.php', '*.html'),
+            ),
+        );
+
+        $this->_aOptionsModule = array (
+            'dirs' => array (
+                "modules/{module_dir}/" => array ('*.php'),
+                "modules/{module_dir}/install/sql/" => array('*.sql'),
+                "modules/{module_dir}/classes/" => array('*.php'),
+                "modules/{module_dir}/templates/" => array('*.php', '*.html'),
+                "modules/{module_dir}/inc/" => array ('*.php'),
+                "modules/{module_dir}/integrations/" => array ('*.php'),
+            ),
+        );
+    }
+
+    public function main()
+    {
+        $a = getopt('hqsm:l:i:f:u:');
+
+        if (isset($a['h']))
+            $this->finish(0, $this->getHelp());
+
+        if (isset($a['q']))
+            $this->_bQuiet = true;
+
+        if (isset($a['s']))
+            $this->_bSortOutput = true;
+
+        if (isset($a['m']))
+            $this->_sModule = $a['m'];
+
+        if (isset($a['l']))
+            $this->_iLimit = (int)$a['l'];
+
+        if (isset($a['i']))
+            $this->_sInputFile = $a['i'];
+
+        if (!$this->_sInputFile || !file_exists($this->_sInputFile))
+            $this->finish(2, 'Input file not exist - ' . $this->_sInputFile);
+
+        if (isset($a['f']))
+            $this->_sOutputFoundFile = $a['f'];
+
+        if (isset($a['u']))
+            $this->_sOutputUnusedFile = $a['u'];
+
+        $aOptions = $this->_sModule ? $this->prepareModuleConfig($this->_aOptionsModule) : $this->_aOptionsSystem;
+
+        $iTimeStart = microtime ();
+
+        $this->output('Processing ' . ($this->_iLimit > 0 ? "first {$this->_iLimit} strings of " : '') . $this->_sInputFile . ' ' . ($this->_sModule ? 'module(' . $this->_sModule .')' : 'system') . ' language file...');
+        $this->output('');
+
+        $oXmlParser = BxDolXmlParser::getInstance();
+        $sXmlContent = file_get_contents($this->_sInputFile);
+        $LANG = $oXmlParser->getValues($sXmlContent, 'string');
+        $LANG_FOUND = array();
+        $LANG_LOST = array();
+        $iCount = 1;
+
+        foreach ($LANG as $sKey => $sString) {
+            if ($this->findLangKey($sKey, $aOptions))
+                $LANG_FOUND[$sKey] = $sString;
+            else
+                $LANG_LOST[$sKey] = $sString;
+            if (++$iCount > $this->_iLimit && $this->_iLimit > 0)
+                break;
+        }
+
+        if (!$this->_bQuiet) {
+            $this->output('Found language strings: ');
+            $this->output('--------------');
+            empty($LANG_FOUND) ? $this->output('Empty') : $this->output($this->xmlExport($LANG_FOUND), false);
+            $this->output('--------------');
+            $this->output('');
+        }
+
+        if ($this->_bSortOutput)
+            ksort($LANG_FOUND);
+        if ($this->_sOutputFoundFile && !empty($LANG_FOUND))
+            file_put_contents($this->_sOutputFoundFile, $this->xmlExport($LANG_FOUND));
+
+        if (!$this->_bQuiet) {
+            $this->output('Unused language strings: ');
+            $this->output('--------------');
+            empty($LANG_LOST) ? $this->output('Empty') : $this->output($this->xmlExport($LANG_LOST), false);
+            $this->output('--------------');
+            $this->output('');
+        }
+
+        if ($this->_bSortOutput)
+            ksort($LANG_LOST);
+        if ($this->_sOutputUnusedFile && !empty($LANG_LOST))
+            file_put_contents($this->_sOutputUnusedFile, $this->xmlExport($LANG_LOST));
+
+        $i1 = explode(' ', microtime ());
+        $i2 = explode(' ', $iTimeStart);
+        $iSec = round(($i1[0]+$i1[1]) - ($i2[0]+$i2[1]), 3);
+        $this->output("Time ($iCount): " . $iSec . ' sec');
+        if ($this->_iLimit > 0) {
+            $iTotalSec = round(count($LANG) / $iCount * (($i1[0]+$i1[1]) - ($i2[0]+$i2[1])), 3);
+            $this->output("Estimated Total Time (" . count($LANG) . "): " . $iTotalSec . ' sec (' . round($iTotalSec / 60.0, 3) . ' min)');
+        }
+
+        $this->finish(empty($LANG_LOST) ? 0 : 1);
+    }
+
+    protected function getHelp()
+    {
+        $n = 20;
+        $s = "Usage: php check_unused_lang.php [options]\n";
+
+        $s .= str_pad("\t -h", $n) . "Print this help\n";
+        $s .= str_pad("\t -q", $n) . "Quiet\n";
+        $s .= str_pad("\t -s", $n) . "Sort output\n";
+        $s .= str_pad("\t -m <vendor/module>", $n) . "Process as module lang file, vendor and module folder names must be specified\n";
+        $s .= str_pad("\t -l <number>", $n) . "Limit number of processing strings (usefull for estimating output time)\n";
+        $s .= str_pad("\t -i <input_file>", $n) . "Input XML language file\n";
+        $s .= str_pad("\t -f <output_file>", $n) . "Output XML file for found strings\n";
+        $s .= str_pad("\t -u <output_file>", $n) . "Output XML file for unused strings\n";
+        $s .= "\n";
+
+        $s .= "Return codes:\n";
+        $s .= str_pad("\t 0", 5) . "Success - no unused language strings\n";
+        $s .= str_pad("\t 1", 5) . "Unused language strings were found\n";
+        $s .= str_pad("\t 2", 5) . "Error occured\n";
+
+        return $s;
+    }
+
+    protected function findLangKey($sKey, $aOptions)
+    {
+        $aAlwaysTrue = array (
+            '/^_mma_/',
+            '/^_ps_group_/',
+            '/^_adm_txt_modules_/',
+            '/^_adm_ipbl_Type/',
+            '/^_week_/',
+
+            /* wall */
+            '/^_bx_timeline_alert_module_/',
+            '/^_bx_timeline_alert_action_/',
+
+            /* sites */
+            '/^_bx_sites_txt_status_/',
+        );
+        foreach ($aAlwaysTrue as $sReg)
+            if (preg_match($sReg, $sKey))
+                return true;
+
+        foreach ($aOptions['dirs'] as $sDir => $aExt) {
+            $sDepth = $sDir ? '' : ' -depth 1 ';
+            $sDir = BX_DIRECTORY_PATH_ROOT . $sDir;
+            if (!file_exists($sDir))
+                continue;
+            foreach ($aExt as $sExt) {
+                $sResults = `find $sDir $sDepth -name "$sExt" -exec grep "\<$sKey\>" {} \;`;
+                if ($sResults)
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    protected function xmlExport($a, $sRoot = 'resources', $bCData = true) 
+    {
+        $s = "<" . $sRoot . ">\n";
+        foreach ($a as $sKey => $sString) {
+            if ($bCData)
+                $sString = '<![CDATA[' . $sString . ']]>';
+            $s .= "\t".'<string name="' . $sKey . '">' . $sString . "</string>\n";
+        }
+        $s .= "</" . $sRoot . ">\n";
+        return $s;
+    }
+
+    protected function prepareModuleConfig ($a) {
+        if (!$this->_sModule)
+            return $a;
+        $aRet = array();
+        $aRet['dirs'] = array();
+        foreach ($a['dirs'] as $sDir => $aPatterns) {
+            $sDir = str_replace('{module_dir}', $this->_sModule, $sDir);
+            $aRet['dirs'][$sDir] = $aPatterns;
+        }
+        return $aRet;
+    }
+    
+    protected function finish ($iCode, $sMsg = null, $bAddLn = true)
+    {
+        if (!$this->_bQuiet && null !== $sMsg)
+            echo $sMsg . ($bAddLn ? "\n" : '');
+        exit($iCode);
+    }
+
+    protected function output ($sMsg, $bAddLn = true)
+    {
+        if (!$this->_bQuiet)
+            echo $sMsg . ($bAddLn ? "\n" : '');
+    }
+}
+
+$o = new BxDolCheckUnusedLangsCmd();
+$o->main();
+
+/** @} */