thephpleague / plates

Native PHP template system
https://platesphp.com
MIT License
1.47k stars 180 forks source link

addData with recursive array merging #95

Closed odan closed 8 years ago

odan commented 9 years ago

Hello

I want to call addData to append data to an existing array. But if I call addData with the same key again the previous values are lost.

For example:

$engine = new \League\Plates\Engine();

// Default items
$engine->addData(['assets' => [
        'item1',
        'item2'
]]);

// Extra items
$engine->addData(['assets' => [
        'item3',
        'item4'
]]);
var_dump($engine->getData());

Output:

array (size=1)
  'assets' => 
    array (size=2)
      0 => string 'item3' (length=5)
      1 => string 'item4' (length=5)

My expected output:

array (size=1)
  'assets' => 
    array (size=4)
      0 => string 'item1' (length=5)
      1 => string 'item2' (length=5)
      2 => string 'item3' (length=5)
      3 => string 'item4' (length=5))

For a test I replaced 'array_merge' with 'array_merge_recursive' in the class League\Plates\Template\Data and it works.

Are there better solutions or should I add a pull request?

ezimuel commented 8 years ago

@odan Actually the overwrite of the shared data is a desired behavior. You can read it from the documentation web site: http://platesphp.com/templates/data/#preassigned-and-shared-data

reinink commented 8 years ago

@ezimuel That's true, but I actually think he's asking for something slightly different. He's asking that the addData method (used for assigning shared data) automatically merge arrays contained WITHIN those template values. And I think think trying to do that is smart with, especially considering it would remove the ability to overwrite a template value entirely.

Here's what I recommend instead, if you need this sort of functionality:

// Default default assets
$engine->addData(['assets' => [
    'item1',
    'item2',
]]);

// Get existing assets
$existing_assets = $this->getData()['assets'];

// Add new assets
$engine->addData(['assets' => array_merge($existing_assets, [
    'item3',
    'item4',
])]);

Again, for clarity, Plates will automatically merge template values when you call the addData() method more than once, however it will not merge arrays contained WITHIN those values.

I hope that helps!