Author: dr
Date: Mon Feb  4 20:56:17 2008
New Revision: 7285

Log:
- Implemented issue #10912: Add translation entries.
- Added support for the new location element in Linguist version 1.1 files.

Modified:
    trunk/Translation/ChangeLog
    trunk/Translation/src/backends/ts_backend.php
    trunk/Translation/src/structs/translation_data.php
    trunk/Translation/tests/files/translations/nl-nl.xml
    trunk/Translation/tests/translation_backend_ts_test.php
    trunk/Translation/tests/translation_manager_test.php

Modified: trunk/Translation/ChangeLog
==============================================================================
--- trunk/Translation/ChangeLog [iso-8859-1] (original)
+++ trunk/Translation/ChangeLog [iso-8859-1] Mon Feb  4 20:56:17 2008
@@ -5,6 +5,8 @@
   the original language, to the translated one without substituting
   parameters. This is to have translation support for the Template
   component.
+- Implemented issue #10912: Add translation entries.
+- Added support for the new location element in Linguist version 1.1 files.
 
 
 1.1.6 - Wednesday 05 December 2007

Modified: trunk/Translation/src/backends/ts_backend.php
==============================================================================
--- trunk/Translation/src/backends/ts_backend.php [iso-8859-1] (original)
+++ trunk/Translation/src/backends/ts_backend.php [iso-8859-1] Mon Feb  4 
20:56:17 2008
@@ -73,7 +73,7 @@
  * @version //autogentag//
  * @mainclass
  */
-class ezcTranslationTsBackend implements ezcTranslationBackend, 
ezcTranslationContextRead
+class ezcTranslationTsBackend implements ezcTranslationBackend, 
ezcTranslationContextRead, ezcTranslationContextWrite
 {
     /**
      * The last read context, as read by next() method.
@@ -104,6 +104,20 @@
     private $xmlParser = null;
 
     /**
+     * Contains the DOM tree for modifications while writing a new translation 
file
+     *
+     * @var DomDocument
+     */
+    private $dom;
+
+    /**
+     * Contains the locale used for writing a new translation file
+     *
+     * @var string
+     */
+    private $writeLocale = null;
+
+    /**
      * Container to hold the properties
      *
      * @var array(string=>mixed)
@@ -190,7 +204,7 @@
     }
 
     /**
-     * Creates an SimpleXML parser object for the locale $locale..
+     * Creates an SimpleXML parser object for the locale $locale.
      *
      * You can set the class of the returned object through the $returnClass
      * parameter. That class should extend the SimpleXMLElement class.
@@ -220,6 +234,39 @@
     }
 
     /**
+     * Creates a DOM parser object for the locale $locale.
+     *
+     * This function checks if the <i>location</i> setting is made, if the file
+     * with the filename as returned by buildTranslationFileName() exists and
+     * creates a DOM parser object for this file. If the setting
+     * is not made, it throws an exception. IF the file does not exist, a new
+     * DomDocument is created.
+     *
+     * @param string $locale
+     * @return object The created parser.
+     */
+    public function openTranslationFileForWriting( $locale )
+    {
+        $filename = $this->buildTranslationFileName( $locale );
+        if ( !file_exists( $filename ) )
+        {
+            $dom = new DOMDocument( '1.0', 'UTF-8' );
+            $dom->formatOutput = true;
+            $root = $dom->createElement( 'TS' );
+            $dom->appendChild( $root );
+        }
+        else
+        {
+            $dom = new DOMDocument( '1.0', 'UTF-8' );
+            $dom->formatOutput = true;
+            $dom->load( $filename );
+            $root = $dom->getElementsByTagName( 'TS' )->item( 0 );
+        }
+
+        return $dom;
+    }
+
+    /**
      * Returns the data from the XML element $message as an
      * ezcTranslationData object.
      *
@@ -246,7 +293,15 @@
         $translation = strlen( $translation ) ? $translation : false;
         $comment = strlen( $comment ) ? $comment : false;
 
-        return new ezcTranslationData( $source, $translation, $comment, 
$status );
+        $location = $message->location;
+        $file = $line = false;
+        if ( $location )
+        {
+            $file = trim( (string) $location['filename'] );
+            $line = trim( (string) $location['line'] );
+        }
+
+        return new ezcTranslationData( $source, $translation, $comment, 
$status, $file, $line );
     }
 
 
@@ -328,6 +383,127 @@
     }
 
     /**
+     * Stores a context.
+     *
+     * This method stores the context that it received to the backend specified
+     * storage place.
+     *
+     * @throws ezcTranslationWriterNotInitializedException when the writer is
+     *         not initialized with initWriter().
+     * @param string $context The context's name
+     * @param array(ezcTranslationData)  $data The context's translation map
+     * @return void
+     */
+    public function storeContext( $context, array $data )
+    {
+        if ( is_null( $this->dom ) )
+        {
+            throw new ezcTranslationWriterNotInitializedException();
+        }
+        foreach ( $data as $key => $cachedElement )
+        {
+            if ( $cachedElement->status == ezcTranslationData::OBSOLETE )
+            {
+                unset( $data[$key] );
+            }
+        }
+
+        $dom = $this->dom;
+        $root = $dom->getElementsByTagName( 'TS' )->item( 0 );
+
+        // find the context element
+        $xpath = new DOMXPath( $dom );
+        $result = $xpath->query( '//context/name[text()="' . htmlspecialchars( 
$context ) . '"]' );
+
+        // If the context does not exist, we create a node for it; otherwise 
we just use it.
+        if ( !$result->length )
+        {
+            $contextNode = $dom->createElement( 'context' );
+            $nameNode = $dom->createElement( 'name', htmlspecialchars( 
$context ) );
+            $contextNode->appendChild( $nameNode );
+            $root->appendChild( $contextNode );
+        }
+        else
+        {
+            $contextNode = $result->item( 0 )->parentNode;
+        }
+
+        // for every entry, we add a new message
+        foreach ( $data as $info )
+        {
+            // check if the string is already there, if so, remove it first
+            $xpath = new DOMXPath( $dom );
+            $result = $xpath->query( '//message/source[text()="' . 
htmlspecialchars( $info->original ) . '"]', $contextNode );
+            if ( $result->length )
+            {
+                $node = $result->item( 0 )->parentNode;
+                $contextNode->removeChild( $node );
+            }
+
+            // create the new element
+            $message = $dom->createElement( 'message' );
+            $source = $dom->createElement( 'source', htmlspecialchars( 
$info->original ) ); 
+            $message->appendChild( $source );
+
+            $translation = $dom->createElement( 'translation', 
htmlspecialchars( $info->translation ) );
+            switch ( $info->status )
+            {
+                case ezcTranslationData::UNFINISHED:
+                    $translation->setAttribute( 'type', 'unfinished' );
+                    break;
+                case ezcTranslationData::OBSOLETE:
+                    $translation->setAttribute( 'type', 'obsolete' );
+                    break;
+            }
+            $message->appendChild( $translation );
+
+            if ( $info->comment )
+            {
+                $comment = $dom->createElement( 'comment', htmlspecialchars( 
$info->comment ) );
+                $message->appendChild( $comment );
+            }
+
+            if ( $info->filename && $info->line )
+            {
+                $location = $dom->createElement( 'location' );
+                $location->setAttribute( 'filename', $info->filename );
+                $location->setAttribute( 'line', $info->line );
+                $message->appendChild( $location );
+            }
+
+            $contextNode->appendChild( $message );
+        }
+    }
+
+    /**
+     * Initializes the writer to write to locale $locale.
+     *
+     * Opens the translation file.
+     *
+     * @throws ezcTranslationNotConfiguredException if the option <i>format</i>
+     *         is not set before this method is called.
+     *
+     * @param string $locale
+     * @return void
+     */
+    public function initWriter( $locale )
+    {
+        $this->dom = $this->openTranslationFileForWriting( $locale );
+        $this->writeLocale = $locale;
+    }
+
+    /**
+     * Deinitializes the writer
+     *
+     * @return void
+     */
+    public function deinitWriter()
+    {
+        $filename = $this->buildTranslationFileName( $this->writeLocale );
+        $this->dom->save( $filename );
+    }
+
+    /**
      * Advanced to the next context.
      *
      * This method parses a little bit more of the XML file to be able to

Modified: trunk/Translation/src/structs/translation_data.php
==============================================================================
--- trunk/Translation/src/structs/translation_data.php [iso-8859-1] (original)
+++ trunk/Translation/src/structs/translation_data.php [iso-8859-1] Mon Feb  4 
20:56:17 2008
@@ -62,19 +62,46 @@
     public $status;
 
     /**
+     * The filename the string was found in
+     *
+     * @var string
+     */
+    public $filename;
+
+    /**
+     * The line where the string is
+     *
+     * @var integer
+     */
+    public $line;
+
+    /**
+     * The column where the string is
+     *
+     * @var integer
+     */
+    public $column;
+
+    /**
      * Constructs an ezcTranslationData object.
      *
      * @param string $original
      * @param string $translation
      * @param string $comment
      * @param int $status
+     * @param string $filename
+     * @param int $line
+     * @param int $column
      */
-    function __construct( $original, $translation, $comment, $status )
+    function __construct( $original, $translation, $comment, $status, 
$filename = null, $line = null, $column = null )
     {
         $this->original = $original;
         $this->translation = $translation;
         $this->comment = $comment;
         $this->status = $status;
+        $this->filename = $filename;
+        $this->line = $line;
+        $this->column = $column;
     }
 
     /**
@@ -93,7 +120,7 @@
      */
     static public function __set_state( array $array )
     {
-        return new ezcTranslationData( $array['original'], 
$array['translation'], $array['comment'], $array['status'] );
+        return new ezcTranslationData( $array['original'], 
$array['translation'], $array['comment'], $array['status'], $array['filename'], 
$array['line'], $array['column'] );
     }
 }
 ?>

Modified: trunk/Translation/tests/files/translations/nl-nl.xml
==============================================================================
--- trunk/Translation/tests/files/translations/nl-nl.xml [iso-8859-1] (original)
+++ trunk/Translation/tests/files/translations/nl-nl.xml [iso-8859-1] Mon Feb  
4 20:56:17 2008
@@ -4,6 +4,7 @@
     <message>
         <source>Node ID: %node_id Visibility: %visibility</source>
         <translation>Knoop ID: %node_id Zichtbaar: %visibility</translation>
+        <location filename="test.ezt" line="85"/>
     </message>
 </context>
 <context>

Modified: trunk/Translation/tests/translation_backend_ts_test.php
==============================================================================
--- trunk/Translation/tests/translation_backend_ts_test.php [iso-8859-1] 
(original)
+++ trunk/Translation/tests/translation_backend_ts_test.php [iso-8859-1] Mon 
Feb  4 20:56:17 2008
@@ -188,7 +188,7 @@
         $backend->setOptions( array ( 'format' => '[LOCALE].xml' ) );
         $context = $backend->getContext( 'nl-nl', 
'contentstructuremenu/show_content_structure' );
 
-        $expected = array( new ezcTranslationData( 'Node ID: %node_id 
Visibility: %visibility', 'Knoop ID: %node_id Zichtbaar: %visibility', false, 
ezcTranslationData::TRANSLATED ) );
+        $expected = array( new ezcTranslationData( 'Node ID: %node_id 
Visibility: %visibility', 'Knoop ID: %node_id Zichtbaar: %visibility', false, 
ezcTranslationData::TRANSLATED, 'test.ezt', 85 ) );
         self::assertEquals( $expected, $context );
     }
 
@@ -382,6 +382,133 @@
         }
     }
 
+    public function testAddTranslation1()
+    {
+        $currentDir = dirname( __FILE__ );
+        $backend = new ezcTranslationTsBackend( 
"{$currentDir}/files/translations" );
+        $backend->setOptions( array ( 'format' => '[LOCALE].xml' ) );
+        $context = $backend->getContext( 'nb-no', 
'contentstructuremenu/show_content_structure' );
+        $context[] = new ezcTranslationData( 'Test string to be added', 'Test 
string die wordt toegevoegd', 'comment', ezcTranslationData::TRANSLATED, 
'test.ezt', 5 );
+
+        $backend->setOptions( array ( 'format' => '[LOCALE].test.xml' ) );
+        $backend->initWriter( 'nb-no' );
+        $backend->storeContext( 'contentstructuremenu/show_content_structure', 
$context );
+        $backend->deinitWriter();
+
+        $context = $backend->getContext( 'nb-no', 
'contentstructuremenu/show_content_structure' );
+        unlink( "{$currentDir}/files/translations/nb-no.test.xml" );
+
+        $expected = array(
+            new ezcTranslationData( 'Node ID: %node_id Visibility: 
%visibility', 'Node-ID: %node_id Synlig/skjult: %visibility', false, 
ezcTranslationData::TRANSLATED ),
+            new ezcTranslationData( 'Test string to be added', 'Test string 
die wordt toegevoegd', 'comment', ezcTranslationData::TRANSLATED, 'test.ezt', 5 
),
+        );
+        self::assertEquals( $expected, $context );
+    }
+
+    public function testAddTranslation2()
+    {
+        $currentDir = dirname( __FILE__ );
+
+        // cp for test
+        copy( "{$currentDir}/files/translations/nb-no.xml", 
"{$currentDir}/files/translations/nb-no.test.xml" );
+
+        $backend = new ezcTranslationTsBackend( 
"{$currentDir}/files/translations" );
+        $context = array();
+        $context[] = new ezcTranslationData( 'Test string to be added', 'Test 
string die wordt toegevoegd', 'comment', ezcTranslationData::TRANSLATED, 
'test.ezt', 5 );
+
+        $backend->setOptions( array ( 'format' => '[LOCALE].test.xml' ) );
+        $backend->initWriter( 'nb-no' );
+        $backend->storeContext( 'contentstructuremenu/show_content_structure', 
$context );
+        $backend->deinitWriter();
+
+        $context = $backend->getContext( 'nb-no', 
'contentstructuremenu/show_content_structure' );
+        unlink( "{$currentDir}/files/translations/nb-no.test.xml" );
+
+        $expected = array(
+            new ezcTranslationData( 'Node ID: %node_id Visibility: 
%visibility', 'Node-ID: %node_id Synlig/skjult: %visibility', false, 
ezcTranslationData::TRANSLATED ),
+            new ezcTranslationData( 'Test string to be added', 'Test string 
die wordt toegevoegd', 'comment', ezcTranslationData::TRANSLATED, 'test.ezt', 5 
),
+        );
+        self::assertEquals( $expected, $context );
+    }
+
+    public function testAddTranslation3()
+    {
+        $currentDir = dirname( __FILE__ );
+
+        // cp for test
+        copy( "{$currentDir}/files/translations/nb-no.xml", 
"{$currentDir}/files/translations/nb-no.test.xml" );
+
+        $backend = new ezcTranslationTsBackend( 
"{$currentDir}/files/translations" );
+        $context = array();
+        $context[] = new ezcTranslationData( 'Test string to be added', 'Test 
string die wordt toegevoegd', 'comment', ezcTranslationData::TRANSLATED, 
'test.ezt', 5 );
+
+        $backend->setOptions( array ( 'format' => '[LOCALE].test.xml' ) );
+        $backend->initWriter( 'nb-no' );
+        $backend->storeContext( 'number_two', $context );
+        $backend->deinitWriter();
+
+        $context = $backend->getContext( 'nb-no', 
'contentstructuremenu/show_content_structure' );
+        $expected = array(
+            new ezcTranslationData( 'Node ID: %node_id Visibility: 
%visibility', 'Node-ID: %node_id Synlig/skjult: %visibility', false, 
ezcTranslationData::TRANSLATED ),
+        );
+
+        $context = $backend->getContext( 'nb-no', 'number_two' );
+        $expected = array(
+            new ezcTranslationData( 'Test string to be added', 'Test string 
die wordt toegevoegd', 'comment', ezcTranslationData::TRANSLATED, 'test.ezt', 5 
),
+        );
+        unlink( "{$currentDir}/files/translations/nb-no.test.xml" );
+
+        self::assertEquals( $expected, $context );
+    }
+
+    public function testChangeTranslation1()
+    {
+        $currentDir = dirname( __FILE__ );
+        $backend = new ezcTranslationTsBackend( 
"{$currentDir}/files/translations" );
+        $backend->setOptions( array ( 'format' => '[LOCALE].xml' ) );
+        $context = $backend->getContext( 'nb-no', 
'contentstructuremenu/show_content_structure' );
+        $context[] = new ezcTranslationData( 'Node ID: %node_id Visibility: 
%visibility', 'Test string die wordt toegevoegd', 'comment', 
ezcTranslationData::TRANSLATED, 'test.ezt', 5 );
+
+        $backend->setOptions( array ( 'format' => '[LOCALE].test.xml' ) );
+        $backend->initWriter( 'nb-no' );
+        $backend->storeContext( 'contentstructuremenu/show_content_structure', 
$context );
+        $backend->deinitWriter();
+
+        $context = $backend->getContext( 'nb-no', 
'contentstructuremenu/show_content_structure' );
+
+        unlink( "{$currentDir}/files/translations/nb-no.test.xml" );
+
+        $expected = array(
+            new ezcTranslationData( 'Node ID: %node_id Visibility: 
%visibility', 'Test string die wordt toegevoegd', 'comment', 
ezcTranslationData::TRANSLATED, 'test.ezt', 5 ),
+        );
+        self::assertEquals( $expected, $context );
+    }
+
+    public function testChangeAndAddTranslation1()
+    {
+        $currentDir = dirname( __FILE__ );
+        $backend = new ezcTranslationTsBackend( 
"{$currentDir}/files/translations" );
+        $backend->setOptions( array ( 'format' => '[LOCALE].xml' ) );
+        $context = $backend->getContext( 'nb-no', 
'contentstructuremenu/show_content_structure' );
+        $context[] = new ezcTranslationData( 'Node ID: %node_id Visibility: 
%visibility', 'Test string die wordt toegevoegd', 'comment', 
ezcTranslationData::TRANSLATED, 'test.ezt', 5 );
+        $context[] = new ezcTranslationData( 'Test string to be added', 'Test 
string die wordt toegevoegd', 'comment', ezcTranslationData::TRANSLATED, 
'test.ezt', 6 );
+
+        $backend->setOptions( array ( 'format' => '[LOCALE].test.xml' ) );
+        $backend->initWriter( 'nb-no' );
+        $backend->storeContext( 'contentstructuremenu/show_content_structure', 
$context );
+        $backend->deinitWriter();
+
+        $context = $backend->getContext( 'nb-no', 
'contentstructuremenu/show_content_structure' );
+
+        unlink( "{$currentDir}/files/translations/nb-no.test.xml" );
+
+        $expected = array(
+            new ezcTranslationData( 'Node ID: %node_id Visibility: 
%visibility', 'Test string die wordt toegevoegd', 'comment', 
ezcTranslationData::TRANSLATED, 'test.ezt', 5 ),
+            new ezcTranslationData( 'Test string to be added', 'Test string 
die wordt toegevoegd', 'comment', ezcTranslationData::TRANSLATED, 'test.ezt', 6 
),
+        );
+        self::assertEquals( $expected, $context );
+    }
+
     public static function suite()
     {
          return new PHPUnit_Framework_TestSuite( "ezcTranslationTsBackendTest" 
);

Modified: trunk/Translation/tests/translation_manager_test.php
==============================================================================
--- trunk/Translation/tests/translation_manager_test.php [iso-8859-1] (original)
+++ trunk/Translation/tests/translation_manager_test.php [iso-8859-1] Mon Feb  
4 20:56:17 2008
@@ -23,7 +23,7 @@
         $trm = new ezcTranslationManager( $backend );
         $context = $trm->getContext( 'nl-nl', 
'contentstructuremenu/show_content_structure' );
 
-        $expected = new ezcTranslation( array( new ezcTranslationData( 'Node 
ID: %node_id Visibility: %visibility', 'Knoop ID: %node_id Zichtbaar: 
%visibility', false, ezcTranslationData::TRANSLATED ) ) );
+        $expected = new ezcTranslation( array( new ezcTranslationData( 'Node 
ID: %node_id Visibility: %visibility', 'Knoop ID: %node_id Zichtbaar: 
%visibility', false, ezcTranslationData::TRANSLATED, 'test.ezt', 85 ) ) );
         self::assertEquals( $expected, $context );
     }
 
@@ -34,7 +34,7 @@
         $backend->setOptions( array ( 'format' => '[LOCALE].xml' ) );
 
         $trm = new ezcTranslationManager( $backend );
-        $expected = new ezcTranslation( array( new ezcTranslationData( 'Node 
ID: %node_id Visibility: %visibility', 'Knoop ID: %node_id Zichtbaar: 
%visibility', false, ezcTranslationData::TRANSLATED ) ) );
+        $expected = new ezcTranslation( array( new ezcTranslationData( 'Node 
ID: %node_id Visibility: %visibility', 'Knoop ID: %node_id Zichtbaar: 
%visibility', false, ezcTranslationData::TRANSLATED, 'test.ezt', 85 ) ) );
 
         $context1 = $trm->getContext( 'nl-nl', 
'contentstructuremenu/show_content_structure' );
         self::assertEquals( $expected, $context1 );


-- 
svn-components mailing list
svn-components@lists.ez.no
http://lists.ez.no/mailman/listinfo/svn-components

Reply via email to