Development

Changeset 29166

You must first sign up to be able to contribute.

Changeset 29166

Show
Ignore:
Timestamp:
04/15/10 23:52:48 (3 years ago)
Author:
sergiovier
Message:

Added support to associative arrays. Added some unit test to sfDataSourceArray and fixed some documentation.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/sfDataSourcePlugin/trunk/README

    r28744 r29166  
    33 
    44This plugin allows to read various data sources in a unified way. These data sources can be filtered and sorted in a generic way,  
    5 so they can for example be be rendered in a customizable grid. 
     5so they can for example be rendered in a customizable grid. 
    66 
    7 Currently arrays, Propel (1.5 supported, but also 1.3 although unsupported) and Doctrine tables can be used as data sources, 
     7Currently arrays (simple and associative), Propel (1.5 supported, but also 1.3 although unsupported) and Doctrine tables can be used as data sources, 
    88You are however free to add more implementations, for example to process csv or xml data. Provided is also an imap implementation, 
    99but this is also unsupported. 
     
    6464-------- 
    6565 
    66 TODO: explain 
     66The use of Doctrine is similar that with with Propel. If you like ObjectPaths, you can optionally install the  
     67plugin [sfAlyssaDoctrineObjectPath](http://www.symfony-project.org/plugins/sfAlyssaDoctrineObjectPathPlugin) that  
     68brings the same feature that sfPropelObjectPathBehaviorPlugin. 
    6769 
    68 Note: Doctrine currently doesn't have an objectPath behavior, so the handling of relations is limited  
     70 
    6971 
    7072Array 
     
    9496TODO: show more difficult schema's and relations 
    9597 
    96 The real bennefit of the sfDataSource will show up when used with the sfGrid(Plugin).  
     98The real benefit of the sfDataSource will show up when used with the sfGrid(Plugin).  
    9799RequireColumn is called automatically when you select columns for your grid, which in its turn will automatically join 
    98100related tables. Sorting on foreign fields or filtering on any table is now easy, because the model is aware of the relations.  
  • plugins/sfDataSourcePlugin/trunk/lib/sfDataSourceArray.class.php

    r29155 r29166  
    107107    $this->originalData = $data; 
    108108    $this->data = $this->originalData; 
    109      
     109 
    110110  } 
    111111 
     
    125125    } 
    126126 
    127     return $this->data[$this->key()+$this->getOffset()]; 
     127    // we do this to support associative arrays 
     128    $keys = array_keys($this->data); 
     129 
     130    return $this->data[$keys[$this->key()+$this->getOffset()]]; 
    128131  } 
    129132 
     
    172175  /** 
    173176   * requireColumn checks if the source contains the desired column. 
    174    * If the source is an empty array, any column will be accepted, since  
     177   * If the source is an empty array, any column will be accepted, since 
    175178   * the DataSource doesn't have any model-data to base its decision on 
    176    *  
     179   * 
    177180   * @see sfDataSourceInterface::requireColumn() 
    178181   */ 
     
    195198    usort($this->data, array($this, 'sortCallback')); 
    196199  } 
    197    
     200 
    198201  /** 
    199202   * Callback method used by usort(). Compares two arrays by the current 
     
    217220    } 
    218221  } 
    219    
     222 
    220223  /** 
    221224   * @see sfDataSourceInterface 
     
    224227  { 
    225228    // TODO: because of this, you should first Filter before you sort! 
    226     // TODO: possibly add sortState (asc,desc, none (per field)), and sort after filtering  
     229    // TODO: possibly add sortState (asc,desc, none (per field)), and sort after filtering 
    227230    $this->data = array(); 
    228      
     231 
    229232    $this->requireColumn($columnName); 
    230233 
     
    241244  //TODO: implement filtering on an array 
    242245  protected function filterCallback($row) 
    243   {   
     246  { 
    244247    throw new Exception('This method has not been finished yet'); 
    245248  } 
    246      
     249 
    247250} 
  • plugins/sfDataSourcePlugin/trunk/test/unit/datasource/sfDataSourceArrayTest.php

    r29155 r29166  
    1111require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); 
    1212 
    13 $t = new lime_test(37, new lime_output_color()); 
     13$t = new lime_test(57, new lime_output_color()); 
    1414 
    1515$data = array( 
     
    2929{ 
    3030  new sfDataSourceArray(array( 
    31     array('id' => 1, 'name' => 'Fabien'),  
     31    array('id' => 1, 'name' => 'Fabien'), 
    3232    array('id' => 2, 'surname' => 'Stefan'), 
    3333    array('id' => 3, 'name' => 'Jonathan'), 
     
    4242{ 
    4343  new sfDataSourceArray(array( 
    44     'id' => 1, 'name' => 'Fabien',  
     44    'id' => 1, 'name' => 'Fabien', 
    4545    'id' => 2, 'surname' => 'Stefan', 
    4646    'id' => 3, 'name' => 'Jonathan', 
     
    5555{ 
    5656  new sfDataSourceArray(array( 
    57     array('id' => 1, 'name' => 'Fabien'),  
     57    array('id' => 1, 'name' => 'Fabien'), 
    5858    'id' => 2, 'surname' => 'Stefan', 
    5959    'id' => 3, 'name' => 'Jonathan', 
     
    273273} 
    274274 
     275 
     276// associative arrays 
     277$t->diag('support for associative arrays'); 
     278 
     279$associative_data = array( 
     280  'first'  => array('id' => 1, 'name' => 'Fabien'), 
     281  'second' => array('id' => 2, 'name' => 'Francois'), 
     282  'third'  => array('id' => 3, 'name' => 'Jonathan'), 
     283); 
     284$s = new sfDataSourceArray($associative_data); 
     285try 
     286{ 
     287  $s->requireColumn('name'); 
     288  $t->pass('sfDataSourceArray accepts existing column (name) of an array'); 
     289} 
     290catch (Exception $e) 
     291{ 
     292  $t->fail('sfDataSourceArray accepts existing column (name) of an array'); 
     293} 
     294try 
     295{ 
     296  $s->requireColumn('anyColumn'); 
     297  $t->fail('sfDataSourceArray does not accept columns that are not in the array'); 
     298} 
     299catch (LogicException $e) 
     300{ 
     301  $t->pass('sfDataSourceArray does not accept columns that are not in the array'); 
     302} 
     303 
     304$t->is(array_keys(iterator_to_array($s, true)), range(0, 2), 'sfDataSourceArray implements the SeekableIterator interface'); 
     305$t->is(count(iterator_to_array($s)), 3, 'sfDataSourceArray implements the SeekableIterator interface'); 
     306 
     307$s->seek(1); 
     308$t->is($s['id'], 2, 'sfDataSourceArray implements the SeekableIterator interface'); 
     309$t->is($s['name'], 'Francois', 'sfDataSourceArray implements the SeekableIterator interface'); 
     310 
     311try 
     312{ 
     313  $s->seek(30); 
     314  $t->fail('->seek() throws an "OutOfBoundsException" when the given index is too large'); 
     315} 
     316catch (OutOfBoundsException $e) 
     317{ 
     318  $t->pass('->seek() throws an "OutOfBoundsException" when the given index is too large'); 
     319} 
     320 
     321try 
     322{ 
     323  $s->seek(-1); 
     324  $t->fail('->seek() throws an "OutOfBoundsException" when the given index is too small'); 
     325} 
     326catch (OutOfBoundsException $e) 
     327{ 
     328  $t->pass('->seek() throws an "OutOfBoundsException" when the given index is too small'); 
     329} 
     330$t->is(count($s), 3, 'sfDataSourceArray implements the Countable interface'); 
     331 
     332 
     333$s = new sfDataSourceArray($associative_data); 
     334$s->setLimit(3); 
     335$values = array(); 
     336foreach ($s as $row) 
     337{ 
     338  $values[] = $row['id']; 
     339} 
     340$t->is($values, range(1,3), '->setLimit() limits the records returned by the iterator'); 
     341 
     342 
     343$s = new sfDataSourceArray($associative_data); 
     344 
     345$t->is($s['id'], 1, 'sfDataSourceArray implements the ArrayAccess interface'); 
     346$t->is($s['name'], 'Fabien', 'sfDataSourceArray implements the ArrayAccess interface'); 
     347$t->ok(isset($s['id']), 'sfDataSourceArray implements the ArrayAccess interface'); 
     348$t->ok(!isset($s['foobar']), 'sfDataSourceArray implements the ArrayAccess interface'); 
     349$s->next(); 
     350$t->is($s['id'], 2, 'sfDataSourceArray implements the ArrayAccess interface'); 
     351$t->is($s['name'], 'Francois', 'sfDataSourceArray implements the ArrayAccess interface'); 
     352 
     353try 
     354{ 
     355  $s['name'] = 'Foobar'; 
     356  $t->fail('sfDataSourceArray throws a "LogicException" when fields are set using ArrayAccess'); 
     357} 
     358catch (LogicException $e) 
     359{ 
     360  $t->pass('sfDataSourceArray throws a "LogicException" when fields are set using ArrayAccess'); 
     361} 
     362try 
     363{ 
     364  unset($s['name']); 
     365  $t->fail('sfDataSourceArray throws a "LogicException" when fields are unset using ArrayAccess'); 
     366} 
     367catch (LogicException $e) 
     368{ 
     369  $t->pass('sfDataSourceArray throws a "LogicException" when fields are unset using ArrayAccess'); 
     370} 
     371 
     372foreach ($s as $k => $v); 
     373 
     374try 
     375{ 
     376  $s['name']; 
     377  $t->fail('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); 
     378} 
     379catch (OutOfBoundsException $e) 
     380{ 
     381  $t->pass('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); 
     382} 
     383try 
     384{ 
     385  isset($s['name']); 
     386  $t->fail('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); 
     387} 
     388catch (OutOfBoundsException $e) 
     389{ 
     390  $t->pass('sfDataSourceArray throws an "OutOfBoundsException" when fields are accessed after iterating'); 
     391}