CakePHP 3: Changing the Results Set Structure

I am new to CakePHP and have the following problem:

I have tables "Images", "Keywords" and "Keywords". Each image can have many keywords (many for many), and each keyword has a category (many to one). Retrieving a List of Images Using

$images = $this->Images->find()->contain(['Keywords',  'Keywords.KeywordCategories']);

returns the structure of the results as follows:

[
   {
      "id":1,
      "keywords":[
         {
            "keyword":"Dog",
            "keyword_category":{
               "title":"Animal"
            }
         },
         {
            "keyword":"Cat",
            "keyword_category":{
               "title":"Animal"
            }
         },
         {
            "keyword":"Black",
            "keyword_category":{
               "title":"Color"
            }
         }
      ]
   }
]

This is good, but I want the keywords to be grouped by their category of keywords in this structure:

[
   {
      "id":1,
      "keyword_categories":[
         {
            "title":"Animal",
            "keywords":[
               {
                  "keyword":"Dog"
               },
               {
                  "keyword":"Cat"
               }
            ]
         },
         {
            "title":"Color",
            "keywords":[
               {
                  "keyword":"Black"
               }
            ]
         }
      ]
   }
]

Any idea how I can achieve this using CakePHP request?

+4
source share
1 answer

, ORMs. , ... , , , , .

- ( ), foo, -

// ...
->find()
->contain(['Keywords', 'Keywords.KeywordCategories'])
->formatResults(function ($results) {
    /* @var $results \Cake\Datasource\ResultSetInterface|\Cake\Collection\CollectionInterface */
    return $results->map(
        function ($image) {
            $image['keyword_categories'] =
                collection($image['keywords'])
                    ->groupBy('keyword_category.title')
                    ->map(function ($keywords, $category) {
                        foreach ($keywords as &$keyword) {
                            unset($keyword['keyword_category']);
                        }
                        return [
                            'title' => $category,
                            'keywords' => $keywords
                        ];
                    })
                    ->toList();
            unset($image['keywords']);
            return $image;
        }
    );
});

*

.. keyword_categories , , , , title keywords, , , .

.

+4

Source: https://habr.com/ru/post/1624666/


All Articles