symfony / symfony/maker-bundle

YamlSourceManipulator: insert new element into indexed array

Open
#618 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug
Dominant language
PHP
Stars
3.4k
Forks
427
Avg merge
2d 22h
Merged PRs (30d)
20

Description

I have a original Yaml file as seen below. I want to add a new element App\Entity\Page\NewsPage but keep an alphabetical order in the elements.

page_types:
    - App\Entity\Page\ContentPage
    - App\Entity\Page\ErrorPage
    - App\Entity\Page\HomePage
    - App\Entity\Page\OverviewPage

I am able to load and manipulate the Yaml file through the YamlSourceManipulator through the code below. If I'm adding the new element at the end of the array, then this goes just fine.

<?php
$manipulator = new YamlSourceManipulator(file_get_contents('page_types.yaml'));
$data = $manipulator->getData();
$data['page_types'] = 'App\\Entity\\Page\\NewsPage';
$manipulator->setData($data);

Now I have tried two methods to get this in alphabetical order.
The first is by determining the position where to insert and use array slice:

// $pos = position determination magic here 🦄...
$data['page_types'] = array_merge(array_slice($data['page_types'], 0, $pos), ['App\\Entity\\Page\\NewsPage'], array_slice($data['page_types'], $pos));

Then, at $manipulator->setData($data);, I get:

In YamlSourceManipulator.php line 641:

  [Symfony\Bundle\MakerBundle\Util\YamlManipulationFailedException]
  Content was updated, but updated content does not match expected data. Original source: "page_types:
      - App\Entity\Page\ContentPage
      - App\Entity\Page\ErrorPage
      - App\Entity\Page\HomePage
      - App\Entity\Page\OverviewPage
  ", updated source: "page_types:
      - App\Entity\Page\ContentPage
      - App\Entity\Page\ErrorPage
      - App\Entity\Page\HomePage App\Entity\Page\NewsPage
  ", updated data: array (
    'page_types' =>
    array (
      0 => 'App\\Entity\\Page\\ContentPage',
      1 => 'App\\Entity\\Page\\ErrorPage',
      2 => 'App\\Entity\\Page\\HomePage',
      3 => 'App\\Entity\\Page\\NewsPage',
    ),
  )

So apparently there's a mismatch and looking at the "updated data" it shows NewsPage in the new position, but OverviewPage got cut off.

Edit: With the above method, an element is inserted into the array and the indices are still in incrementing order.

The second method I tried, was doing a natsort(). So I kept the $data['page_types'] = 'App\\Entity\\Page\\NewsPage'; and then I did natsort($data['page_types']);.
Then it just hangs endlessly (PHP process at 100% CPU and 63Mb memory) until I terminate it manually.

Edit: I also tried sort() instead of natsort(). With both the sort() and natsort() method, compared with the original, an element is inserted into the array. However the original indices are maintained. In this case 0, 1, 2, 4, 3. With 4 being the new element NewsPage.

Does anyone have an idea how to fix this? Or work around this? Or maybe it just isn't possible to insert an element at a position other than at the end?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in YamlSourceManipulator.php around line 641 and reproduce the issue with the page_types.yaml example and the array insertion, sort(), and natsort() cases. Trace why updated data and source lose or misorder entries; done means NewsPage is inserted alphabetically, OverviewPage is preserved, and sorting does not hang.

Written by the indexing model from the issue text.

Assessment

Tech stack
php, symfony
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.