Author: sergiovier Date: 2010-04-15 23:52:48 +0200 (Thu, 15 Apr 2010) New Revision: 29166
Modified: plugins/sfDataSourcePlugin/trunk/README plugins/sfDataSourcePlugin/trunk/lib/sfDataSourceArray.class.php plugins/sfDataSourcePlugin/trunk/test/unit/datasource/sfDataSourceArrayTest.php Log: Added support to associative arrays. Added some unit test to sfDataSourceArray and fixed some documentation. Modified: plugins/sfDataSourcePlugin/trunk/README =================================================================== --- plugins/sfDataSourcePlugin/trunk/README 2010-04-15 18:15:46 UTC (rev 29165) +++ plugins/sfDataSourcePlugin/trunk/README 2010-04-15 21:52:48 UTC (rev 29166) @@ -2,9 +2,9 @@ ============ This plugin allows to read various data sources in a unified way. These data sources can be filtered and sorted in a generic way, -so they can for example be be rendered in a customizable grid. +so they can for example be rendered in a customizable grid. -Currently arrays, Propel (1.5 supported, but also 1.3 although unsupported) and Doctrine tables can be used as data sources, +Currently arrays (simple and associative), Propel (1.5 supported, but also 1.3 although unsupported) and Doctrine tables can be used as data sources, You are however free to add more implementations, for example to process csv or xml data. Provided is also an imap implementation, but this is also unsupported. @@ -63,10 +63,12 @@ Doctrine -------- -TODO: explain +The use of Doctrine is similar that with with Propel. If you like ObjectPaths, you can optionally install the +plugin [sfAlyssaDoctrineObjectPath](http://www.symfony-project.org/plugins/sfAlyssaDoctrineObjectPathPlugin) that +brings the same feature that sfPropelObjectPathBehaviorPlugin. -Note: Doctrine currently doesn't have an objectPath behavior, so the handling of relations is limited + Array ----- @@ -93,7 +95,7 @@ TODO: show more difficult schema's and relations -The real bennefit of the sfDataSource will show up when used with the sfGrid(Plugin). +The real benefit of the sfDataSource will show up when used with the sfGrid(Plugin). RequireColumn is called automatically when you select columns for your grid, which in its turn will automatically join related tables. Sorting on foreign fields or filtering on any table is now easy, because the model is aware of the relations. Modified: plugins/sfDataSourcePlugin/trunk/lib/sfDataSourceArray.class.php =================================================================== --- plugins/sfDataSourcePlugin/trunk/lib/sfDataSourceArray.class.php 2010-04-15 18:15:46 UTC (rev 29165) +++ plugins/sfDataSourcePlugin/trunk/lib/sfDataSourceArray.class.php 2010-04-15 21:52:48 UTC (rev 29166) @@ -106,7 +106,7 @@ $this->originalData = $data; $this->data = $this->originalData; - + } /** @@ -124,7 +124,10 @@ throw new OutOfBoundsException(sprintf('The result with index %s does not exist', $this->key())); } - return $this->data[$this->key()+$this->getOffset()]; + // we do this to support associative arrays + $keys = array_keys($this->data); + + return $this->data[$keys[$this->key()+$this->getOffset()]]; } /** @@ -171,9 +174,9 @@ /** * requireColumn checks if the source contains the desired column. - * If the source is an empty array, any column will be accepted, since + * If the source is an empty array, any column will be accepted, since * the DataSource doesn't have any model-data to base its decision on - * + * * @see sfDataSourceInterface::requireColumn() */ public function requireColumn($column) @@ -194,7 +197,7 @@ usort($this->data, array($this, 'sortCallback')); } - + /** * Callback method used by usort(). Compares two arrays by the current * sort column in the given sort order. @@ -216,16 +219,16 @@ return strcmp($b[$this->sortColumn], $a[$this->sortColumn]); } } - + /** * @see sfDataSourceInterface */ public function addFilter($column, $value, $comparison = sfDataSource::EQUAL) { // TODO: because of this, you should first Filter before you sort! - // TODO: possibly add sortState (asc,desc, none (per field)), and sort after filtering + // TODO: possibly add sortState (asc,desc, none (per field)), and sort after filtering $this->data = array(); - + $this->requireColumn($columnName); if (!isset($column['value'])) @@ -240,8 +243,8 @@ //TODO: implement filtering on an array protected function filterCallback($row) - { + { throw new Exception('This method has not been finished yet'); } - + } \ No newline at end of file Modified: plugins/sfDataSourcePlugin/trunk/test/unit/datasource/sfDataSourceArrayTest.php =================================================================== --- plugins/sfDataSourcePlugin/trunk/test/unit/datasource/sfDataSourceArrayTest.php 2010-04-15 18:15:46 UTC (rev 29165) +++ plugins/sfDataSourcePlugin/trunk/test/unit/datasource/sfDataSourceArrayTest.php 2010-04-15 21:52:48 UTC (rev 29166) @@ -10,7 +10,7 @@ require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); -$t = new lime_test(37, new lime_output_color()); +$t = new lime_test(57, new lime_output_color()); $data = array( array('id' => 1, 'name' => 'Fabien'), @@ -28,7 +28,7 @@ try { new sfDataSourceArray(array( - array('id' => 1, 'name' => 'Fabien'), + array('id' => 1, 'name' => 'Fabien'), array('id' => 2, 'surname' => 'Stefan'), array('id' => 3, 'name' => 'Jonathan'), )); @@ -41,7 +41,7 @@ try { new sfDataSourceArray(array( - 'id' => 1, 'name' => 'Fabien', + 'id' => 1, 'name' => 'Fabien', 'id' => 2, 'surname' => 'Stefan', 'id' => 3, 'name' => 'Jonathan', )); @@ -54,7 +54,7 @@ try { new sfDataSourceArray(array( - array('id' => 1, 'name' => 'Fabien'), + array('id' => 1, 'name' => 'Fabien'), 'id' => 2, 'surname' => 'Stefan', 'id' => 3, 'name' => 'Jonathan', )); @@ -272,3 +272,120 @@ $t->pass('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); } + +// associative arrays +$t->diag('support for associative arrays'); + +$associative_data = array( + 'first' => array('id' => 1, 'name' => 'Fabien'), + 'second' => array('id' => 2, 'name' => 'Francois'), + 'third' => array('id' => 3, 'name' => 'Jonathan'), +); +$s = new sfDataSourceArray($associative_data); +try +{ + $s->requireColumn('name'); + $t->pass('sfDataSourceArray accepts existing column (name) of an array'); +} +catch (Exception $e) +{ + $t->fail('sfDataSourceArray accepts existing column (name) of an array'); +} +try +{ + $s->requireColumn('anyColumn'); + $t->fail('sfDataSourceArray does not accept columns that are not in the array'); +} +catch (LogicException $e) +{ + $t->pass('sfDataSourceArray does not accept columns that are not in the array'); +} + +$t->is(array_keys(iterator_to_array($s, true)), range(0, 2), 'sfDataSourceArray implements the SeekableIterator interface'); +$t->is(count(iterator_to_array($s)), 3, 'sfDataSourceArray implements the SeekableIterator interface'); + +$s->seek(1); +$t->is($s['id'], 2, 'sfDataSourceArray implements the SeekableIterator interface'); +$t->is($s['name'], 'Francois', 'sfDataSourceArray implements the SeekableIterator interface'); + +try +{ + $s->seek(30); + $t->fail('->seek() throws an "OutOfBoundsException" when the given index is too large'); +} +catch (OutOfBoundsException $e) +{ + $t->pass('->seek() throws an "OutOfBoundsException" when the given index is too large'); +} + +try +{ + $s->seek(-1); + $t->fail('->seek() throws an "OutOfBoundsException" when the given index is too small'); +} +catch (OutOfBoundsException $e) +{ + $t->pass('->seek() throws an "OutOfBoundsException" when the given index is too small'); +} +$t->is(count($s), 3, 'sfDataSourceArray implements the Countable interface'); + + +$s = new sfDataSourceArray($associative_data); +$s->setLimit(3); +$values = array(); +foreach ($s as $row) +{ + $values[] = $row['id']; +} +$t->is($values, range(1,3), '->setLimit() limits the records returned by the iterator'); + + +$s = new sfDataSourceArray($associative_data); + +$t->is($s['id'], 1, 'sfDataSourceArray implements the ArrayAccess interface'); +$t->is($s['name'], 'Fabien', 'sfDataSourceArray implements the ArrayAccess interface'); +$t->ok(isset($s['id']), 'sfDataSourceArray implements the ArrayAccess interface'); +$t->ok(!isset($s['foobar']), 'sfDataSourceArray implements the ArrayAccess interface'); +$s->next(); +$t->is($s['id'], 2, 'sfDataSourceArray implements the ArrayAccess interface'); +$t->is($s['name'], 'Francois', 'sfDataSourceArray implements the ArrayAccess interface'); + +try +{ + $s['name'] = 'Foobar'; + $t->fail('sfDataSourceArray throws a "LogicException" when fields are set using ArrayAccess'); +} +catch (LogicException $e) +{ + $t->pass('sfDataSourceArray throws a "LogicException" when fields are set using ArrayAccess'); +} +try +{ + unset($s['name']); + $t->fail('sfDataSourceArray throws a "LogicException" when fields are unset using ArrayAccess'); +} +catch (LogicException $e) +{ + $t->pass('sfDataSourceArray throws a "LogicException" when fields are unset using ArrayAccess'); +} + +foreach ($s as $k => $v); + +try +{ + $s['name']; + $t->fail('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); +} +catch (OutOfBoundsException $e) +{ + $t->pass('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); +} +try +{ + isset($s['name']); + $t->fail('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); +} +catch (OutOfBoundsException $e) +{ + $t->pass('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); +} -- 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.
