Author: xavier
Date: 2010-09-23 19:14:50 +0200 (Thu, 23 Sep 2010)
New Revision: 30974

Added:
   plugins/sfDoctrineActAsTaggablePlugin/trunk/test/
   plugins/sfDoctrineActAsTaggablePlugin/trunk/test/unit/
   
plugins/sfDoctrineActAsTaggablePlugin/trunk/test/unit/sfDoctrineActAsTaggableTest.php
Log:
sfDoctrineActAsTaggablePlugin: added tests! (indeed, ported the tests from 
sfPropelActAsTaggableBehaviourPlugin)

Added: 
plugins/sfDoctrineActAsTaggablePlugin/trunk/test/unit/sfDoctrineActAsTaggableTest.php
===================================================================
--- 
plugins/sfDoctrineActAsTaggablePlugin/trunk/test/unit/sfDoctrineActAsTaggableTest.php
                               (rev 0)
+++ 
plugins/sfDoctrineActAsTaggablePlugin/trunk/test/unit/sfDoctrineActAsTaggableTest.php
       2010-09-23 17:14:50 UTC (rev 30974)
@@ -0,0 +1,536 @@
+<?php
+// test variables definition
+define('TEST_CLASS', 'Logger');
+define('TEST_CLASS_2', 'Alert');
+define('TEST_NON_TAGGABLE_CLASS', 'Event');
+
+// initializes testing framework
+$sf_root_dir = realpath(dirname(__FILE__).'/../../../../');
+$apps_dir = glob($sf_root_dir.'/apps/*', GLOB_ONLYDIR);
+$app = substr($apps_dir[0],
+              strrpos($apps_dir[0], DIRECTORY_SEPARATOR) + 1,
+              strlen($apps_dir[0]));
+if (!$app)
+{
+  throw new Exception('No app has been detected in this project');
+}
+
+// initialize database manager
+require_once($sf_root_dir.'/test/bootstrap/unit.php');
+
+if (SYMFONY_VERSION >= 1.1)
+{
+  $configuration = ProjectConfiguration::getApplicationConfiguration($app, 
'test', true);
+  $databaseManager = new sfDatabaseManager($configuration);
+}
+else
+{
+  // initialize database manager
+  require_once($sf_root_dir.'/test/bootstrap/functional.php');
+  require_once($sf_symfony_lib_dir.'/vendor/lime/lime.php');
+
+  $databaseManager = new sfDatabaseManager();
+  $databaseManager->initialize();
+  $con = Propel::getConnection();
+}
+
+if (!defined('TEST_CLASS') || !class_exists(TEST_CLASS)
+    || !defined('TEST_CLASS_2') || !class_exists(TEST_CLASS_2))
+{
+  // Don't run tests
+  return;
+}
+
+// clean the database
+Doctrine_Query::create()->delete()->from('Tag')->execute();
+Doctrine_Query::create()->delete()->from('Tagging')->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS)->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS_2)->execute();
+
+// create a new test browser
+// $browser = new sfTestBrowser();
+// $browser->initialize();
+
+// start tests
+$t = new lime_test(66, new lime_output_color());
+
+
+// these tests check for the tags attachement consistency
+$t->diag('tagging consistency');
+
+$object = _create_object();
+$t->ok($object->getTags() == array(), 'a new object has no tag.');
+
+$object->addTag('toto');
+$object_tags = $object->getTags();
+$t->ok((count($object_tags) == 1) && ($object_tags['toto'] == 'toto'), 'a 
non-saved object can get tagged.');
+
+$object->addTag('toto');
+$object_tags = $object->getTags();
+$t->ok(count($object_tags) == 1, 'a tag is only applied once to non-saved 
objects.');
+$object->save();
+
+$object->addTag('toto');
+$object_tags = $object->getTags();
+$t->ok(count($object_tags) == 1, 'a tag is also only applied once to saved 
objects.');
+$object->save();
+
+$object->addTag('tutu');
+$object_tags = $object->getTags();
+$t->ok($object->hasTag('tutu'), 'a saved object can get tagged.');
+$object->save();
+
+// get the key of this object
+$id1 = $object->getPrimaryKey();
+
+$object->removeTag('tutu');
+$t->ok(!$object->hasTag('tutu'), 'a previously saved tag can be removed.');
+
+$object->addTag('tata');
+$object->removeTag('tata');
+$t->ok(!$object->hasTag('tata'), 'a non-saved tag can also be removed.');
+
+$object->addTag('tu\'tu');
+$t->ok($object->hasTag('tu\'tu'), 'a tag can contain a quote.');
+
+$object2 = _create_object();
+$object_tags = $object2->getTags();
+$t->ok(count($object_tags) == 0, 'a new object has no tag, even if other 
tagged objects exist.');
+$object2->save();
+
+$object2->addTag('titi');
+$t->ok($object2->hasTag('titi'), 'a new object can get tagged, even if other 
tagged objects exist.');
+$t->ok(!$object->hasTag('titi'), 'tags applied to new objects do not affect 
old ones.');
+$object2->save();
+$id2 = $object2->getPrimaryKey();
+
+$object = _create_object();
+$object->addTag('tutu');
+$object->addTag('titi');
+$object->save();
+$object->addTag('tata');
+$object->removeAllTags();
+$t->ok(!$object->hasTag(), 'tags can all be removed at once.');
+
+$object = _create_object();
+$object->addTag('toto,international,tata');
+$object->save();
+$id = $object->getPrimaryKey();
+$object = Doctrine::getTable(TEST_CLASS)->findOneById($id);
+$object->removeTag('tata');
+$object->addTag('tata');
+$object->save();
+$object = Doctrine::getTable(TEST_CLASS)->findOneById($id);
+$object_tags = $object->getTags();
+$t->ok(count($object_tags) == 3, 'when removing one previously saved tag, then 
restoring it, and then saving it again, this tag is not duplicated.');
+
+$object = _create_object();
+$object->addTag('toto,tutu,tata');
+$object->save();
+$object->removeAllTags();
+$object->addTag('toto,tutu,tata');
+$object->save();
+$id = $object->getPrimaryKey();
+$object = Doctrine::getTable(TEST_CLASS)->findOneById($id);
+$object_tags = $object->getTags();
+$t->ok(count($object_tags) == 3, 'when removing all previously saved tags, 
then restoring it, and then saving it again, tags are not duplicated.');
+
+$object = _create_object();
+$object->addTag('toto,tutu,tata');
+$object->save();
+$previous_count = count($object->getTags());
+$object->removeAllTags();
+$object->save();
+$id = $object->getPrimaryKey();
+$object = Doctrine::getTable(TEST_CLASS)->findOneById($id);
+$t->ok(($previous_count == 3) && !$object->hasTag(), 'previously in-database 
tags can be deleted.');
+
+$object = _create_object();
+$object->addTag('toto, tutu, test');
+$object->save();
+$id = $object->getPrimaryKey();
+$object = Doctrine::getTable(TEST_CLASS)->findOneById($id);
+
+$object2 = _create_object();
+$object2->addTag('clever age, symfony, test');
+$object2->save();
+$object2->removeTag('test');
+$object2->save();
+
+$object_tags = $object->getTags();
+$object2_tags = $object2->getTags();
+$t->ok((count($object2_tags) == 2) && (count($object_tags) == 3), 'removing 
one tag as no effect on the other tags of the object, neither on the other 
objects.');
+
+$object2_tags = $object2->getTags(array('serialized' => true));
+$t->ok($object2_tags == 'clever age, symfony', 'tags can be retrieved in a 
serialized form.');
+
+$object->removeAllTags();
+$object->setTags('');
+$object->save();
+$id = $object->getPrimaryKey();
+$object = Doctrine::getTable(TEST_CLASS)->findOneById($id);
+$t->ok(count($object->getTags()) == 0, 'when the tags are set twice, or all 
removed twice, before the object is saved, then all the prvious tags are still 
removed.');
+
+unset($object, $object2, $object2_copy);
+
+
+// these tests check the various methods for applying tags to an object
+$t->diag('various methods for applying tags');
+$object = _create_object();
+$object->addTag('toto');
+$object_tags = $object->getTags();
+$t->ok((count($object_tags) == 1) && ($object_tags['toto'] == 'toto'), 'one 
tag can be added alone.');
+
+$object->addTag('titi,tutu');
+$object_tags = $object->getTags();
+$t->ok((count($object_tags) == 3) && $object->hasTag('tutu') && 
$object->hasTag('titi'), 'tags can be added with a comma-separated string.');
+$t->ok($object->hasTag('titi, tutu'), 'comma-separated strings are divided 
into several tags.');
+
+$object = _create_object();
+$object->addTag('titi
+tutu');
+$object_tags = $object->getTags();
+$t->ok((count($object_tags) == 2) && $object->hasTag('titi') && 
$object->hasTag('tutu'), 'tags can be added using line breaks as separators.');
+$t->ok($object->hasTag('titi
+tutu'), 'line-breaks-separated strings are divided into several tags.');
+
+$object = _create_object();
+$object->addTag('titi
+
+tutu');
+$object_tags = $object->getTags();
+$t->ok((count($object_tags) == 2) && $object->hasTag('titi') && 
$object->hasTag('tutu'), 'when adding tags using line breaks as separators, 
remove blank lines.');
+
+$object = _create_object();
+$object->addTag(array('titi', 'tutu'));
+$object_tags = $object->getTags();
+$t->ok((count($object_tags) == 2) && $object->hasTag('tutu') && 
$object->hasTag('titi'), 'tags can be added with an array.');
+
+$object->setTags('wallace, gromit');
+$object_tags = $object->getTags();
+$t->ok((count($object_tags) == 2) && $object->hasTag('wallace') && 
$object->hasTag('gromit'), 'tags can be set directly using setTags().');
+
+unset($object);
+
+
+// these tests check for the tagging removal on object deletion
+
+// clean the database
+Doctrine_Query::create()->delete()->from('Tag')->execute();
+Doctrine_Query::create()->delete()->from('Tagging')->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS)->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS_2)->execute();
+
+$t->diag('taggings removal on objects deletion');
+$object1 = _create_object();
+$object1->addTag('tag2,tag3,tag1,tag4,tag5,tag6');
+$object1->save();
+
+$object2 = _create_object();
+$object2->addTag('tag4,tag7,tag8');
+$object2->save();
+
+$object2->delete();
+
+$tags = Doctrine::getTable('Tag')->getAllTagNameWithCount();
+$t->ok(isset($tags['tag4']) && !isset($tags['tag7']), 'the taggings associated 
to one object are deleted when this object is deleted.');
+
+
+// these tests check for TagPeer methods (tag clouds generation)
+
+// clean the database
+Doctrine_Query::create()->delete()->from('Tag')->execute();
+Doctrine_Query::create()->delete()->from('Tagging')->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS)->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS_2)->execute();
+
+$t->diag('tag clouds');
+$object1 = _create_object();
+$object1->addTag('tag2,tag3,tag1,tag4,tag5,tag6');
+$object1->save();
+
+$object2 = _create_object();
+$object2->addTag('tag1,tag3,tag4,tag7');
+$object2->save();
+
+$object3 = _create_object();
+$object3->addTag('tag2,tag3,tag7,tag8');
+$object3->save();
+
+$object4 = _create_object();
+$object4->addTag('tag3');
+$object4->save();
+
+$object5 = _create_object();
+$object5->addTag('tag1,tag3,tag7');
+$object5->save();
+
+// getAllTagName() test
+$result = Doctrine::getTable('Tag')->getAllTagName();
+$t->ok($result == array('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6', 
'tag7', 'tag8'), 'all tags can be retrieved with getAllTagName().');
+
+// getAllTagNameWithCount() test
+$tags = Doctrine::getTable('Tag')->getAllTagNameWithCount();
+$t->ok($tags == array('tag1' => 3, 'tag2' => 2, 'tag3' => 5, 'tag4' => 2, 
'tag5' => 1, 'tag6' => 1, 'tag7' => 3, 'tag8' => 1), 'all tags can be retrieved 
with getAllTagName().');
+
+// getPopulars() test
+$q = Doctrine_Query::create()->limit(3);
+$tags = Doctrine::getTable('Tag')->getPopulars($q);
+$t->ok(array_keys($tags) == array('tag1', 'tag3', 'tag7'), 'most popular tags 
can be retrieved with getPopulars().');
+$t->ok($tags['tag3'] >= $tags['tag1'], 'getPopulars() preserves tag 
importance.');
+
+// getRelatedTags() test
+$tags = Doctrine::getTable('Tag')->getRelatedTags('tag8');
+$t->ok(array_keys($tags) == array('tag2', 'tag3', 'tag7'), 'related tags can 
be retrieved with getRelatedTags().');
+
+$tags = Doctrine::getTable('Tag')->getRelatedTags('tag2', array('limit' => 1));
+$t->ok(array_keys($tags) == array('tag3'), 'when a limit is set, only most 
popular related tags are returned by getRelatedTags().');
+
+// getRelatedTags() test
+$tags = Doctrine::getTable('Tag')->getRelatedTags('tag7');
+$t->ok(array_keys($tags) == array('tag1', 'tag2', 'tag3', 'tag4', 'tag8'), 
'getRelatedTags() aggregates tags from different objects.');
+
+// getRelatedTags() test
+$tags = Doctrine::getTable('Tag')->getRelatedTags(array('tag2', 'tag7'));
+$t->ok(array_keys($tags) == array('tag3', 'tag8'), 'getRelatedTags() can 
retrieve tags related to an array of tags.');
+
+// getRelatedTags() test
+$tags = Doctrine::getTable('Tag')->getRelatedTags('tag2,tag7');
+$t->ok(array_keys($tags) == array('tag3', 'tag8'), 'getRelatedTags() also 
accepts a coma-separated string.');
+
+// getObjectTaggedWith() tests
+$object_2_1 = _create_object_2();
+$object_2_1->addTag('tag1,tag3,tag7');
+$object_2_1->save();
+
+$object_2_2 = _create_object_2();
+$object_2_2->addTag('tag2,tag7');
+$object_2_2->save();
+
+$tagged_with_tag4 = Doctrine::getTable('Tag')->getObjectTaggedWith('tag4');
+$t->ok(count($tagged_with_tag4) == 2, 'getObjectTaggedWith() returns objects 
tagged with one specific tag.');
+
+$tagged_with_tag7 = Doctrine::getTable('Tag')->getObjectTaggedWith('tag7');
+$t->ok(count($tagged_with_tag7) == 5, 'getObjectTaggedWith() can return 
several object types.');
+
+$tagged_with_tag17 = 
Doctrine::getTable('Tag')->getObjectTaggedWith(array('tag1', 'tag7'));
+$t->ok(count($tagged_with_tag17) == 3, 'getObjectTaggedWith() returns objects 
tagged with several specific tags.');
+
+$tagged_with_tag127 = Doctrine::getTable('Tag')->getObjectTaggedWith('tag1, 
tag2, tag7',
+                                             array('nb_common_tags' => 2));
+$t->ok(count($tagged_with_tag127) == 6, 'the "nb_common_tags" option of 
getObjectTaggedWith() returns objects tagged with a certain number of tags 
within a set of specific tags.');
+
+
+// these tests check the preloadTags() method
+Taggable::preloadTags($tagged_with_tag17);
+$nb_tags = 0;
+
+foreach ($tagged_with_tag17 as $tmp_object)
+{
+  $nb_tags += count($tmp_object->getTags());
+}
+
+$t->ok($nb_tags === 10, 'preloadTags() preloads the tags of the objects.');
+
+
+// these tests check the isTaggable() method
+$t->diag('detecting if a model is taggable or not');
+
+$t->ok(TaggableToolkit::isTaggable(TEST_CLASS) === true, 'it is possible to 
tell if a model is taggable from its name.');
+
+$object = _create_object();
+$t->ok(TaggableToolkit::isTaggable($object) === true, 'it is possible to tell 
if a model is taggable from one of its instances.');
+$t->ok(TaggableToolkit::isTaggable(TEST_NON_TAGGABLE_CLASS) === false, 
TEST_NON_TAGGABLE_CLASS.' is not taggable, and that is fine.');
+
+// clean the database
+Doctrine_Query::create()->delete()->from('Tag')->execute();
+Doctrine_Query::create()->delete()->from('Tagging')->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS)->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS_2)->execute();
+
+
+// these tests check for the application of triple tags
+$t->diag('applying triple tagging');
+
+$t->ok(TaggableToolkit::extractTriple('ns:key=value') === 
array('ns:key=value', 'ns', 'key', 'value'), 'triple extracted successfully.');
+$t->ok(TaggableToolkit::extractTriple('ns:key') === array('ns:key', null, 
null, null), 'ns:key is not a triple.');
+$t->ok(TaggableToolkit::extractTriple('ns') === array('ns', null, null, null), 
'ns is not a triple.');
+
+$object = _create_object();
+$object->addTag('tutu');
+$object->save();
+
+$object = _create_object();
+$object->addTag('ns:key=value');
+$object->addTag('ns:key=tutu');
+$object->addTag('ns:key=titi');
+$object->addTag('ns:key=toto');
+$object->save();
+
+$object_tags = $object->getTags();
+$t->ok($object->hasTag('ns:key=value'), 'object has triple tag');
+
+$tag = Doctrine::getTable('Tag')->findOrCreateByTagname('ns:key=value');
+$t->ok($tag->getIsTriple(), 'a triple tag created from a string is identified 
as a triple.');
+
+$tag = Doctrine::getTable('Tag')->findOrCreateByTagname('tutu');
+$t->ok(!$tag->getIsTriple(), 'a non tripled tag created from a string is not 
identified as a triple.');
+
+
+// these tests check the retrieval of the tags of one object, based on
+// triple-tags constraints
+$t->diag('retrieving triple tags, and extracting only parts of it');
+
+$object = _create_object();
+$object->addTag('geo:lat=50.7');
+$object->addTag('geo:long=6.1');
+$object->addTag('de:city=Aachen');
+$object->addTag('fr:city=Aix la Chapelle');
+$object->addTag('en:city=Aix Chapel');
+$object->save();
+
+// get all the tags
+$tags = $object->getTags();
+$t->ok(count($tags) == 5, 'The addTags() method permits to create triple tags, 
that can be retrieved using getTags().');
+
+$id = $object->getPrimaryKey();
+$object = Doctrine::getTable(TEST_CLASS)->findOneById($id);
+$tags = $object->getTags();
+$t->ok(count($tags) == 5, 'The addTags() method permits to create triple tags, 
that can be retrieved using getTags(), even when saved.');
+
+// get all the informations in the "geo" namespace
+$tags = $object->getTags(array('is_triple' => true,
+                               'namespace' => 'geo',
+                               'return'    => 'value'));
+$t->ok(count($tags) == 2, 'The getTags() method permits to select triple tags 
in one specific namespace.');
+
+// get all the values of the triple tags for which the key is "city", whatever
+// the namespace
+$tags = $object->getTags(array('is_triple' => true,
+                               'key'       => 'city',
+                               'return'    => 'value'));
+$t->ok(count($tags) == 3, 'The getTags() method permits to select triple tags 
for one specific key.');
+
+$object2 = _create_object();
+$object2->addTag('geo:lat=48.8');
+$object2->addTag('geo:long=2.4');
+$object2->addTag('de:city=Paris');
+$object2->addTag('fr:city=Paris');
+$object2->addTag('en:city=Paris');
+$object2->save();
+
+// get all the values of the triple tags for which the key is "city", whatever
+// the namespace
+$tags = $object2->getTags(array('is_triple' => true,
+                                'key'       => 'city',
+                                'return'    => 'value'));
+$t->ok(count($tags) == 1, 'When selecting only the values of triple tags of 
one object, there is no duplicate.');
+
+$ns = $object2->getTags(array('is_triple' => true,
+                              'return'    => 'namespace'));
+$t->ok(count($ns) == 4, 'The method getTags() permit to select only the names 
of the namespaces of the tags attached to one object.');
+
+
+// these tests check for TagPeer triple tags specific methods (tag clouds 
generation)
+sfConfig::set('app_sfDoctrineActAsTaggablePlugin_triple_distinct', false);
+$t->diag('querying triple tagging');
+
+$result = Doctrine::getTable('Tag')->getAllTagName(null, array('triple' => 
true));
+$t->ok(in_array('ns:key=value', $result), 'triple tags are returned when 
searching for triples only.');
+$t->ok(!in_array('tutu', $result), 'ordinary tags are not returned when 
searching for triples only.');
+
+$result = Doctrine::getTable('Tag')->getAllTagName(null, array('triple' => 
false));
+$t->ok(in_array('tutu', $result), 'normal tags are returned when searching for 
ordinary ones only.');
+$t->ok(!in_array('ns:key=value', $result), 'triple tags are not returned when 
searching for normal ones.');
+
+
+// these tests the search of specific triple tags parts
+$t->diag('searching for specific parts of triple');
+
+$result = Doctrine::getTable('Tag')->getAllTagName(null, array('triple' => 
true, 'namespace' => 'ns'));
+$t->ok($result === array('ns:key=value', 'ns:key=tutu', 'ns:key=titi', 
'ns:key=toto'), 'it is possible to search for triple tags by namespace.');
+
+$result = Doctrine::getTable('Tag')->getAllTagName(null, array('triple' => 
true, 'key' => 'key'));
+$t->ok($result === array('ns:key=value', 'ns:key=tutu', 'ns:key=titi', 
'ns:key=toto'), 'it is possible to search for triple tags by key.');
+
+$result = Doctrine::getTable('Tag')->getAllTagName(null, array('triple' => 
true, 'value' => 'tutu'));
+$t->ok($result === array('ns:key=tutu'), 'it is possible to search for triple 
tags by value.');
+
+$objects_triple = Doctrine::getTable('Tag')->getObjectTaggedWith(array(), 
array('namespace' => 'ns', 'model' => TEST_CLASS));
+$t->ok(count($objects_triple) == 1, 'it is possible to retrieve objects tagged 
with certain triple tags.');
+
+
+// clean the database
+Doctrine_Query::create()->delete()->from('Tag')->execute();
+Doctrine_Query::create()->delete()->from('Tagging')->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS)->execute();
+Doctrine_Query::create()->delete()->from(TEST_CLASS_2)->execute();
+
+
+// these tests check for the behavior of the triple tags when the plugin is set
+// up so that namespace:key is a unique key
+sfConfig::set('app_sfDoctrineActAsTaggablePlugin_triple_distinct', true);
+$t->diag('querying triple tagging');
+
+$object = _create_object();
+$object->addTag('tutu');
+$object->save();
+
+$object = _create_object();
+$object->addTag('ns:key=value');
+$object->addTag('ns:key=tutu');
+$object->addTag('ns:key=titi');
+$object->addTag('ns:second_key=toto');
+$object->save();
+
+$tags_triple = Doctrine::getTable('Tag')->getAllTagName(null, array('triple' 
=> true, 'namespace' => 'ns'));
+$t->ok(count($tags_triple) == 2, 'it is possible to set up the plugin so that 
namespace:key is a unique key.');
+
+$object2 = _create_object();
+$object2->addTag('ns:key=value');
+$object2->addTag('ns:second_key=toto');
+$object2->save();
+
+$tags_triple = Doctrine::getTable('Tag')->getAllTagName(null, array('triple' 
=> true, 'namespace' => 'ns'));
+$t->ok(count($tags_triple) == 3, 'it is possible to apply triple tags to 
various objects when the plugin is set up so that namespace:key is a unique 
key.');
+
+
+
+// test object creation
+function _create_object()
+{
+  $classname = TEST_CLASS;
+
+  if (!class_exists($classname))
+  {
+    throw new Exception(sprintf('Unknow class "%s"', $classname));
+  }
+
+  return new $classname();
+}
+
+// second type of test object creation
+function _create_object_2()
+{
+  $classname = TEST_CLASS_2;
+
+  if (!class_exists($classname))
+  {
+    throw new Exception(sprintf('Unknow class "%s"', $classname));
+  }
+
+  return new $classname();
+}
+
+// second type of test object creation
+function _create_object_not_taggable()
+{
+  $classname = TEST_NON_TAGGABLE_CLASS;
+
+  if (!class_exists($classname))
+  {
+    throw new Exception(sprintf('Unknow class "%s"', $classname));
+  }
+
+  return new $classname();
+}

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/symfony-svn?hl=en.

Reply via email to