Procházet zdrojové kódy

[doc] translatable doc updates, also some misc changes

gediminasm před 14 roky
rodič
revize
06e3b849fc
5 změnil soubory, kde provedl 145 přidání a 25 odebrání
  1. 6 0
      README.markdown
  2. 31 0
      bin/clear_temp.php
  3. 48 0
      bin/purify.php
  4. 0 24
      bin/update_vendors.sh
  5. 60 1
      doc/translatable.md

+ 6 - 0
README.markdown

@@ -25,6 +25,12 @@ use these extensions from separate branch **doctrine2.0.x** or simply checkout t
 
 ### Latest updates
 
+**2011-04-16**
+
+- Translation **query walker** is a killer feature for translatable extension. It lets to
+translate any query components and filter or order by translated fields. I recommmend you
+to use it extensively since it is very performative also.
+
 **2011-04-11**
 
 - **Tree nestedset** was improved, now all in memory nodes are synchronized and do not require `$em->clear()` all the time.

+ 31 - 0
bin/clear_temp.php

@@ -0,0 +1,31 @@
+<?php
+
+$location = __DIR__ . '/../tests/temp';
+define('VENDOR_PATH', realpath(__DIR__ . '/../vendor'));
+
+set_include_path(implode(PATH_SEPARATOR, array(
+    VENDOR_PATH,
+    get_include_path(),
+)));
+
+$classLoaderFile = VENDOR_PATH . '/doctrine-common/lib/Doctrine/Common/ClassLoader.php';
+if (!file_exists($classLoaderFile)) {
+    die('cannot find vendor, git submodule init && git submodule update');
+}
+
+require_once $classLoaderFile;
+$classLoader = new Doctrine\Common\ClassLoader('Symfony');
+$classLoader->register();
+
+$finder = new Symfony\Component\Finder\Finder;
+$finder->files()
+    ->name('*')
+    ->in(__DIR__ . '/../tests/temp');
+
+foreach ($finder as $fileInfo) {
+    if (!$fileInfo->isWritable()) {
+        continue;
+    }
+    echo 'removing: ' . $fileInfo->getRealPath() . PHP_EOL;
+    @unlink($fileInfo->getRealPath());
+}

+ 48 - 0
bin/purify.php

@@ -0,0 +1,48 @@
+<?php
+
+define('VENDOR_PATH', realpath(__DIR__ . '/../vendor'));
+
+set_include_path(implode(PATH_SEPARATOR, array(
+    VENDOR_PATH,
+    get_include_path(),
+)));
+
+$classLoaderFile = VENDOR_PATH . '/doctrine-common/lib/Doctrine/Common/ClassLoader.php';
+if (!file_exists($classLoaderFile)) {
+    die('cannot find vendor, git submodule init && git submodule update');
+}
+
+require_once $classLoaderFile;
+$classLoader = new Doctrine\Common\ClassLoader('Symfony');
+$classLoader->register();
+
+$finder = new Symfony\Component\Finder\Finder;
+$finder->files()
+    ->name('*.php')
+    ->in(__DIR__ . '/../lib')
+    ->in(__DIR__ . '/../tests');
+
+foreach ($finder as $fileInfo) {
+    if (!$fileInfo->isReadable()) {
+        continue;
+    }
+    $count = 0;
+    $total = 0;
+    $needsSave = false;
+    $content = file_get_contents($fileInfo->getRealPath());
+
+    $content = str_replace("\t", '    ', $content, $count);
+    $total += $count;
+
+    $content = str_replace("\r\n", "\n", $content, $count);
+    $total += $count;
+
+    $needsSave = $total != 0;
+
+    if ($needsSave) {
+        file_put_contents($fileInfo->getRealPath(), $content);
+        echo $fileInfo->getRealPath() . PHP_EOL;
+    }
+}
+
+echo 'done';

+ 0 - 24
bin/update_vendors.sh

@@ -1,24 +0,0 @@
-#!/bin/sh
-
-cd ../
-ROOT=$(pwd)
-VENDOR="$ROOT/vendor"
-
-if [ ! -d "$VENDOR/doctrine-orm/lib" ]; then
-	cd $ROOT
-	git submodule init
-	git submodule update
-else
-    # Doctrine ORM
-    cd $VENDOR/doctrine-orm && git pull
-    
-    # Doctrine DBAL
-    cd $VENDOR/doctrine-dbal && git pull
-    
-    # Doctrine common
-    cd $VENDOR/doctrine-common && git pull
-    
-    # Doctrine MongoDB
-    cd $VENDOR/doctrine-mongodb-odm && git pull
-    cd $VENDOR/doctrine-mongodb && git pull
-fi

+ 60 - 1
doc/translatable.md

@@ -10,11 +10,19 @@ Features:
 - Automatic storage of translations in database
 - ORM and ODM support using same listener -Automatic translation of Entity or
 Document fields then loaded
+- ORM query can use **hint** to translate all records without issuing additional queries
 - Can be nested with other behaviors
 - Annotation and Yaml mapping support for extensions
 
 [blog_test]: http://gediminasm.org/test "Test extensions on this blog"
 
+Update **2011-04-16**
+- Made an ORM query **hint** to hook into any select type query, which will join the translations
+and let you **filter, order or search** by translated fields directly. It also will translate
+all selected **collections or simple components** without issuing additional queries. It also
+supports translation fallbacks
+- For performance reasons, translation fallbacks are disabled by default
+
 Update **2011-04-04**
 - Made single listener, one instance can be used for any object manager
 and any number of them
@@ -25,7 +33,7 @@ and any number of them
 - Public [Translatable repository](http://github.com/l3pp4rd/DoctrineExtensions "Translatable extension on Github") is available on github
 - Using other extensions on the same Entity fields may result in unexpected way
 - May inpact your application performace since it does an additional query for translation
-- Last update date: **2011-04-04**
+- Last update date: **2011-04-16**
 
 **Portability:**
 
@@ -42,6 +50,7 @@ Content:
 - Document [example](#document)
 - [Yaml](#yaml) mapping example
 - Basic usage [examples](#basic-examples)
+- Using ORM query [hint](#orm-query-hint)
 - Advanced usage [examples](#advanced-examples)
 
 ## Setup and autoloading {#including-extension}
@@ -328,6 +337,56 @@ Lets try to load it and it should be translated in English
     echo $article->getContent();
     // prints: "my content in en"
 
+## Using ORM query hint {#orm-query-hint}
+
+By default, behind the scenes, when you load a record - translatable hooks into **postLoad**
+event and issues additional query to translate all fields. Imagine that when you load a collection,
+when it issues a lot of queries just to translate those fields. Also if you want to hydrate
+result as an **array**, it is not possible to hook any **postLoad** event since it is not an
+entity being hydrated. These are the main reason why **TranslationWalker** was born.
+
+**TranslationWalker** uses a query **hint** to hook into any **select type query**,
+and when you execute the query, no matter which hydration method you use, it automatically
+joins the translations for all fields, so you could use ordering filtering or whatever you
+want on **translations of the fields** instead of original record fields.
+
+And in result there is only one query for all this happyness.
+
+If you use translation [fallbacks](#advanced-examples) it will be also in the same single
+query and during the hydration process it will replace the empty fields in case if they
+do not have a translation in currently used locale.
+
+Now enough talking, here is an example:
+
+    $dql = "SELECT a, c, u FROM Article a "
+         . "LEFT JOIN a.comments c "
+         . "JOIN c.author u "
+         . "WHERE a.title LIKE '%translated_title%' "
+         . "ORDER BY a.title";
+    
+    $query = $em->createQuery($dql);
+    // set the translation query hint
+    $query->setHint(
+        \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
+        'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
+    );
+    
+    $articles = $query->getResult(); // object hydration
+    $articles = $query->getArrayResult(); // array hydration
+
+Theres no need for any words anymore.. right?
+I recommend you to use it extensively since it is a way better performance, even in
+cases where you need a single object query.
+
+Notice: Even in **COUNT** select statements translations are joined to leave a
+possibility to filter by translated field, if you do not need it, just do not set
+the **hint**. Also take into account that it is not possibble to translate components
+in **JOIN WITH** statement, example `JOIN a.comments c WITH c.message LIKE '%will_not_be_translated%'`
+
+Notice: any **find** related method calls cannot hook this hint automagically, we
+will use a different approach when **persister overriding feature** will be
+available in **Doctrine** 
+
 ## Advanced examples: {#advanced-examples}
 
 ### Default locale