<?php
/******************************************************************************
 *  SiteBar 3 - The Bookmark Server for Personal and Team Use.                *
 *  Copyright (C) 2004  Ondrej Brablc <http://brablc.com/mailto?o>            *
 *                                                                            *
 *  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, write to the Free Software               *
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
 ******************************************************************************/

define ( "TRANSLATORS", "Translators");
define ( "DEFAULT_LANGUAGE", "en_US");

if (@!include_once('./inc/config.inc.php'))
{
    exit;
}

require_once('./inc/errorhandler.inc.php');
require_once('./inc/page.inc.php');
require_once('./inc/usermanager.inc.php');

class Translator extends ErrorHandler
{
    var $parts = array
    (
        'text' => array
        (
            'label'=>'Texts',
            'file'=>'text.inc.php',
            'inline'=>true,
            'show_default'=>false,
        ),
        'para' => array
        (
            'label'=>'Paragraphs',
            'file'=>'para.inc.php',
            'inline'=>false,
            'show_default'=>true,
        ),
        'topic' => array
        (
            'label'=>'Help Topics',
            'file'=>'topic.inc.php',
            'inline'=>true,
            'show_default'=>true,
        ),
        'help' => array
        (
            'label'=>'Help Content',
            'file'=>'help.inc.php',
            'inline'=>false,
            'show_default'=>true,
        ),
    );

    var $fmt = './locale/%s/%s';
    var $langs = array();
    var $gid = null;

    function Translator()
    {
        foreach ($this->parts as $part => $param)
        {
            include(sprintf($this->fmt,DEFAULT_LANGUAGE,$param['file']));
            eval('$this->parts[$part][DEFAULT_LANGUAGE] = $'.$part.';');
        }

        if ($dir = @opendir("./locale"))
        {
            while (($lang = readdir($dir)) !== false)
            {
                $filename = sprintf($this->fmt,$lang,"info.inc.php");
                if (!@file_exists($filename))
                {
                    continue;
                }
                $stat = stat('./locale/'.$lang);
                if ($stat[2] != 040777)
                {
                    continue;
                }
                $this->langs[] = $lang;
            }

            closedir($dir);
            sort($this->langs);
        }
    }

    function run()
    {
        if (isset($_REQUEST['edit']))
        {
            $this->check(false);
            $this->edit($_REQUEST['lang'], $_REQUEST['edit'], @$_REQUEST['cmd'], isset($_REQUEST['save']));
            exit;
        }
        else if (isset($_REQUEST['create']))
        {
            $this->check(true);
            $this->create();
            exit;
        }
        else if (isset($_REQUEST['download']))
        {
            require('./lib/zip.lib.php');
            $zipfile = new zipfile();

            foreach ($this->langs as $lang)
            {
                if ($_REQUEST['download'] && $lang!=$_REQUEST['download'])
                {
                    continue;
                }

                $this->addFile($zipfile, $lang, "info.inc.php");

                foreach ($this->parts as $part => $params)
                {
                    $this->addFile($zipfile, $lang, $params['file']);
                }
            }

            $name = sprintf( "locale%s.zip", ($_REQUEST['download']?"_".$_REQUEST['download']:''));

            //force download dialog
            header("Content-type: application/x-zip\n");
            header("Content-disposition: attachment; filename=\"$name\"\n");
            header("Content-transfer-encoding: binary\n");
            header("Content-length: " . strlen($zipfile->file()) . "\n");

            echo $zipfile->file();
            exit;
        }
        else
        {
            $this->statistics();
        }
    }

    function addFile(&$zipfile, $lang, $file)
    {
        $file = sprintf($this->fmt, $lang, $file);
        $handle = fopen ($file, "rb");
        $contents = fread ($handle, filesize ($file));
        fclose ($handle);
        $zipfile->addFile($contents, $file);
    }

    function check($needAdmin=false)
    {
        $um = UserManager::staticInstance();

        // We must be logged in pass this point
        if (!$um->isLogged())
        {
            header("Location: command.php?command=Log%20In&forward=translator.php");
            exit;
        }

        if ($needAdmin)
        {
            if (!$um->isAdmin())
            {
                Page::head("Translator Error", "locale");
                echo 'You must be admin to create new dir!';
                Page::foot();
                exit;
            }
            else
            {
                return true;
            }
        }

        $groups = $um->getGroups();
        $trGid = null;
        foreach ($groups as $gid => $rec)
        {
            if ($rec["name"] == TRANSLATORS)
            {
                $trGid = $gid;
                break;
            }
        }

        if (!$trGid)
        {
            Page::head("Translator Error", "locale");
            echo 'This installation does not have group "' . TRANSLATORS . '"!';
            Page::foot();
            exit;
        }

        $myGroups = $um->getUserGroups();
        $member = false;
        foreach ($myGroups as $gid => $rec)
        {
            if ($rec["name"] == TRANSLATORS)
            {
                $member = true;
                break;
            }
        }

        if (!$member)
        {
            Page::head("Translator Error", "locale");
            echo 'You must be member of "' . TRANSLATORS . '" group to edit localizations! ';
            echo 'Ask <a href="command.php?command=Contact%20Moderator&amp;gid=' . $trGid . '">moderator</a> for membership.';
            Page::foot();
            exit;
        }
    }

    function statistics()
    {
        Page::head("Translator", "locale");
?>
<h2>Translations</h2>

<h4>Information for users</h4>
<ul>
    <li>It is possible to download separate localizations or the whole
        <a href='translator.php?download'>localization package</a> as ZIP files.
</ul>

<h4>Information for translators</h4>
<ul>
    <li>Although the languages can be edited on any SiteBar instance, the only authorized
        server to edit translation to be incorporated in the official release is
        <a href="http://brablc.com/sitebar/translator.php">brablc.com</a>.
    <li>In order to edit translations, you must have an account in this SiteBar installation
        and be member of group "<?php echo TRANSLATORS?>".
    <li>You can <a href='command.php?command=Sign%20Up'>create an account</a> yourself and ask
        moderator of the group to give you membership.
    <li>If there is some language missing then you have to
        <a href='command.php?command=Contact%20Admin'>contact admin</a> of this installation
        and ask him to <a href='translator.php?create'>create a directory</a> for your language, you will then be listed as the primary
        language translator.
    <li><strong>This is real online translation.</strong> Open <a href="sitebar.php">Sitebar</a>,
        change your language in the <a href='command.php?command=User%20Settings'>User Settings</a>
        and check the result.
    <li>Paragraphs that need update are marked with green color and &lt;@&gt; sign at the beginning.
        Remove this sign after update.
</ul>

<h4>Differences<h4>
<ul>
    <li><a href="http://cvs.sourceforge.net/viewcvs.py/sitebar/sitebar3/locale/en_US/help.inc.php?r1=text&amp;tr1=1.5&amp;r2=1.7%3AHEAD&amp;tr2=&amp;diff_format=h">Help change from 3.2 to 3.2.5</a> - Validate Links
</ul>

<table class='stat'>
<tr>
    <th>Dir</th>
    <th>Language</th>
    <th>Author</th>
<?php
        foreach ($this->parts as $part => $param)
        {
?>
    <th colspan="2"><?php echo $this->parts[$part]['label']?></th>
<?php
        }

?>
    <th>&nbsp;</th>
</tr>
<?php
        foreach ($this->langs as $lang)
        {
            include(sprintf($this->fmt,$lang,"info.inc.php"));

            $author = $info['author'];

            if ($info['url'])
            {
                $url = $info['url'];
                if (strstr($url,"mailto:"))
                {
                    $url =  str_replace("@", " ~at~ ", $url);
                    $url =  str_replace(".", " ~dot~ ", $url);
                }
                $author = "<a href='".$url."'>".$info['author']."</a>";

                if (isset($info["co-authors"]))
                {
                    $author .= '<br>' . $info["co-authors"];
                }
            }
?>
<tr>
    <td class='fixed'><?php echo $lang?>&nbsp;</td>
    <td><?php echo $info['language']?></td>
    <td><?php echo $author?></td>
<?php
            foreach ($this->parts as $part => $param)
            {
                eval('$'.$part.'=array();');
                include(sprintf($this->fmt,$lang,$param['file']));
                eval('$data = $'.$part.';');
                $this->parts[$part][$lang] = $data;

                $ok = 0;
                $total = 0;
                $missing = 0;
                $update = 0;

                foreach ($this->parts[$part][DEFAULT_LANGUAGE] as $label => $value)
                {
                    $total++;

                    $missingTest = false;
                    $updateTest  = false;

                    if (!isset($data[$label]) || ($data[$label]=='' && $lang!=DEFAULT_LANGUAGE))
                    {
                        $missingTest = true;
                        $missing++;
                    }

                    if (isset($data[$label]) && substr($data[$label],0,3)=='<@>')
                    {
                        $updateTest = true;
                        $update++;
                    }

                    if (!$missingTest && !$updateTest)
                    {
                        $ok++;
                    }
                }

                $ratio = sprintf( "%2.2f", $ok/$total*100);
?>
    <td class='stat'><?php echo $ratio?>%</td>
    <td class='statCmd'><?php

                if ($lang!=DEFAULT_LANGUAGE)
                {
                ?>[<a href='translator.php?lang=<?php echo $lang?>&amp;edit=<?php echo $part?>'>EDIT</a>]<?php
if ($missing) : ?><br>[<a href='translator.php?lang=<?php echo $lang?>&amp;cmd=add&amp;edit=<?php echo $part?>'>ADD</a>]<?php endif;
if ($update) :  ?><br>[<a href='translator.php?lang=<?php echo $lang?>&amp;cmd=upd&amp;edit=<?php echo $part?>'>UPD</a>]<?php endif;
                }
            }
?>
    <td class='stat'>[<a href='translator.php?download=<?php echo $lang?>'>Download</a>]</td>
</tr>
<?php
        }

?>
</table>
<?php
        Page::foot();
    }

    function encodeValue($value, $show=false)
    {
        if ($show)
        {
            $value = str_replace("&amp;#39;","'", htmlspecialchars($value));
        }
        return $value;
    }

    function decodeValue(&$param, $value)
    {
        if ($param['inline'])
        {
            return str_replace("'", "&#39;", stripslashes($value));
        }
        else
        {
            return str_replace("&#39;", "'", stripslashes($value));
        }
    }

    function edit($lang, $part, $cmd, $save)
    {
        Page::head("Edit Translation", "locale");
?>
<h2>Edit Translation</h2>
[<a href="translator.php">Back to Translation List</a>]
<p>
<?php
        $param = $this->parts[$part];
        $file = sprintf($this->fmt,$lang,$param['file']);

        include($file);
        eval('$data = $'.$part.';');
        eval('$'.$part.'=array();');
        include(sprintf($this->fmt,DEFAULT_LANGUAGE,$param['file']));
        eval('$default = $'.$part.';');

        if ($save)
        {
            $values = array();
            $md5 = array();

            foreach ( $_REQUEST['label'] as $i => $label)
            {
                $label = $this->decodeValue($param, $label);
                $values[$label] = $this->decodeValue($param, $_REQUEST['value'][$i]);
                $md5[$label] = $_REQUEST['md5'][$i];
            }

            $ok = 0;
            $total = 0;

            if (!($fh = fopen($file,"wb")))
            {
                echo "Cannot write results to file: $file" .
                exit;
            }

            fwrite( $fh, "<?php\n\n");

            if ($param['inline'])
            {
                fwrite( $fh, "\$$part = array\n(\n");
            }
            else
            {
                fwrite( $fh, "\$$part = array();\n\n");
            }

            foreach ($default as $label => $value)
            {
                $changed = isset($md5[$label]) && (md5(@$values[$label]) != @$md5[$label]);

                if (isset($data[$label]) && $cmd=='add')
                {
                    $value = $data[$label];
                }
                else if (isset($values[$label]) && ($changed || isset($data[$label])))
                {
                    $value = $changed?html_entity_decode($values[$label]):$data[$label];
                }
                else if (!$param['inline'] && $cmd=='upd' && !$changed && isset($data[$label]))
                {
                    $value = $data[$label];
                }
                else
                {
                    $value = '';
                }

                if (strlen($value))
                {
                    if ($param['inline'])
                    {
                        fwrite( $fh, sprintf("'%s' => '%s',\n", $label, $value));
                    }
                    else
                    {
                        $value = str_replace("\r\n","\n", $value);
                        fwrite( $fh, "\$".$part."['".$label."'] = <<<_P\n");
                        fwrite( $fh, $value);
                        fwrite( $fh, "\n_P;\n\n");
                    }
                }
            }

            if ($param['inline'])
            {
                fwrite( $fh, ");\n\n");
            }

            fwrite( $fh, "?>\n");
            fclose( $fh);

            echo "<h4>Data saved to $file.</h4>\n";

            // Reread to display
            eval('$'.$part.'=array();');
            include($file);
            eval('$data = $'.$part.';');
        }

?>
<form method="POST">
<table class='edit'>
<?php
        $i  = 0;

        foreach ($default as $label => $value)
        {
            $safeValue = isset($data[$label])?$data[$label]:'';

            $title  = $param['show_default']?$value:$label;
            $dCount = count(explode("\n", $title));
            $lCount = count(explode("\n", $safeValue));
            $rows   = max($lCount,$dCount);

            if ($cmd=='add' && strlen($safeValue))
            {
                continue;
            }

            if ($cmd=='upd' && substr($safeValue,0,3)!='<@>')
            {
                continue;
            }

            if (!$param['show_default'] && strlen($value))
            {
?>
<tr>
    <td class='comment'><?php echo $this->encodeValue($value,true)?></td>
</tr>
<?php
            }
            else if ($param['show_default'])
            {
?>
<tr>
    <td class='comment'><?php echo $label ?></td>
</tr>
<?php
            }
?>
<tr>
    <td class='label'><?php echo $this->encodeValue($title,true)?></td>
</tr>
<tr>
    <td class='<?php echo strlen($safeValue)?(substr($safeValue,0,3)=='<@>'?'update':'value'):'missing'?>'>
        <input type='hidden' name='label[<?php echo $i?>]' value='<?php echo $this->encodeValue($label)?>'>
        <input type='hidden' name='md5[<?php echo $i?>]' value='<?php echo md5($safeValue)?>'>
<?php
            if ($param['inline'])
            {
?>
        <input name='value[<?php echo $i?>]' value='<?php echo $this->encodeValue($safeValue)?>'>
<?php
            }
            else
            {
?>
        <textarea name='value[<?php echo $i?>]' rows='<?php echo $rows?>'><?php echo htmlspecialchars($safeValue)?></textarea>
<?php
            }
?>
    </td>
</tr>
<?php
            $i++;
        }
?>
</table>
<?php if ($i): ?>
<input type='hidden' name='count' value='<?php echo $i?>'>
<input type='submit' name='save' value='Submit'>
<input type='reset'>
<?php endif;?>
</form>
<?php
        Page::foot();
    }

    function create()
    {
        Page::head("Edit Translation", "locale");
?>
<h2>Create Translation</h2>
[<a href="translator.php">Back to Translation List</a>]
<p>
<?php
        if (isset($_REQUEST['save']))
        {
            $ok = true;

            foreach (array('dir','language','author','url') as $name)
            {
                if (!isset($_REQUEST[$name]) || !strlen($_REQUEST[$name]))
                {
                    $ok = false;
                    echo "Field $name must be filled!<br>";
                }
            }

            if ($ok)
            {
                $lang = $_REQUEST['dir'];
                if (!mkdir('./locale/' . $lang))
                {
                    die("Cannot create directory!");
                }
                chmod('./locale/' . $lang, 0777);
                foreach ($this->parts as $part => $param)
                {
                    $file = sprintf($this->fmt, $lang, $param['file']);
                    if (!$fh = fopen($file, "w"))
                    {
                        die("Cannot create file $file!");
                    }
                    fwrite($fh, "<?php \$$part = array(); ?>");
                    fclose($fh);
                    chmod($file, 0666);
                }

                $file = sprintf($this->fmt, $lang, "info.inc.php");
                if (!$fh = fopen($file, "w"))
                {
                    die("Cannot create file $file!");
                }
                $text = <<<_INFO
<?php

\$info = array
(
    'language' => '${_REQUEST['language']}',
    'author' => '${_REQUEST['author']}',
    'url' => '${_REQUEST['url']}',
);

?>
_INFO;
                fwrite($fh, $text);
                fclose($fh);
                chmod($file, 0666);

                echo 'Directory created!';
            }
        }
        else
        {
?>
<form method="POST">
<table>
<tr>
    <th>Directory</th>
    <td><input name='dir'></td>
</tr>
<tr>
    <th>Language</th>
    <td><input name='language'></td>
</tr>
<tr>
    <th>Author</th>
    <td><input name='author'></td>
</tr>
<tr>
    <th>URL</th>
    <td><input name='url'></td>
</tr>
</table>
<input type='submit' name='save' value='Submit'>
<input type='reset'>
</form>
<?php
        }
        Page::foot();
    }
}

$tr = new Translator();
$tr->run();
?>
