Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 29.07.2017 13:57:09

Не знаю как правильно сделать

Здравствуйте.
Не могу реализовать генерацию вариантов товаров.
Структура таблиц:

products
 - id
 - name
 - price
 - ...

product_attribute
 - id
 - product_id
 - price
 - ...

product_attribute_variation
 - attribute_id // Ид атрибута к примеру Size :: S / M / XL
 - product_attribute_id // Ид аттрибута товара (таблица выше)

В идеале должно получиться вроде такого:
Products: id — 1, name — First product, price — 300
Product_attributes: id — 23, product_id — 1, price — 400
Product_attribute_variation: attribute_id -5, product_attribute_id — 23

Когда отправляю выделенные атрибуты к примеру Size — S(id: 3), Size — XS(id: 4), Color — Red (id: 1)

array:4 [
  0 => "3"
  1 => "4"
  2 => "1"
]

Получается должно создаться 2 атрибута товара потому что выбрано 2 разных размера и 1 цвет.
Как мне определять сколько создавать атрибутов товаров исходя из этого массива.
P.S. Понимаю что сдесь мало что понятно, по этому привожу живой пример чего я хочу добиться
http://bo.demo.prestashop.com/demo/index.php/product/form/7?_token=u0o1Ziy7kYWcbDKH7GAa8V0PkhmkoC2vhtzzpadeBV0#tab-step3
Спасибо!

Не в сети

#2 29.07.2017 19:54:30

TrueKanonir
Откуда: Ташкент
Сообщений: 221

Re: Не знаю как правильно сделать

Насколько я понял, задача звучит примерно так: имеется x атрибутов (size, color, height …), у этих x атрибутов есть y значения (S, M, XS, Red, Blue…), на сервер отправляются только идентификаторы значений?
В итоге должно получиться примерно так:

#1 Мужская футболка 300 руб
 - #5 400 руб
 --- Размер: XL, Цвет: белый
 - #6 400 руб
 --- Размер: L, Цвет: белый
 - #7 400 руб
 --- Размер: S, Цвет: белый
...

Если я вас правильно понял, то можно попробовать запрос типо

PHP
$values AttributeValues::whereIn('id'$request->values_id)->get();

А потом сгруппировать их по attribute_id (по id атрибута к которому относятся значения), или сразу в запросе группировать. Потом уже в цикле должно получиться

Изменено TrueKanonir (29.07.2017 19:55:31)

Не в сети

#3 30.07.2017 12:43:25

Re: Не знаю как правильно сделать

Спасибо за ответ!
попробовал я вашим способом сделать. В итоге получился массив вида

PHP
array:[
  
"1" => array:[
    
=> "3"
  
]
  
"6" => array:[
    
=> "4"
  
]
  
"12" => array:[
    
=> "3",
    
=> "5"
  
]
]

Индекс у первого массива, это группа, а вложенные массивы это значение. Но этот варриант не подходит

Изменено Testuser123 (30.07.2017 12:43:51)

Не в сети

#4 30.07.2017 18:50:36

TrueKanonir
Откуда: Ташкент
Сообщений: 221

Re: Не знаю как правильно сделать

  1. Но этот варриант не подходит

Больше в голову ничего не приходит) может другие что подскажут

Не в сети

#5 05.08.2017 10:35:05

Re: Не знаю как правильно сделать

Решил. Спасибо SO и вам TrueKanonir тоже.

PHP
    /**
     * Создаем варианты товара
     *
     * @param $id
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|string
     */
    
public function productAttributesGenerator($idRequest $request)
    {
        
$product Product::find($id);

        
$ids $this->generateCombinations($request->product_attributes);

        try
        {
            
$variations = [];

            foreach (
$ids as $id)
            {
                
$attribute ProductAttribute::create([
                    
'product_id' => $product->id,
                    
'reference' => $product->reference,
                    
'quantity' => 0,
                    
'price' => $product->price,
                    
'weight' => $product->weight $product->weight 0
                
]);

                
$attribute->combinations()->attach($id);

                
$variations[] = $attribute;
            }

            return 
view('variations', ['variations' => $variations])->render();
        }
        catch (\
Throwable $t)
        {
            return 
response()->json($t->getMessage());
        }
        catch (\
Exception $e)
        {
            return 
response()->json($e->getMessage());
        }
    }

    
/**
     * Генерируем комбинации для вариантов товара. Пример: Size - l, Color - Red
     *
     * @param array $ids
     * @return \Illuminate\Support\Collection
     */
    
public function generateCombinations(array $ids)
    {
        
$attributes AttributeValue::whereIn('id'$ids)->get()->groupBy('attribute_id')->toArray();

        
$matrix = [];
        foreach(
$attributes as $i => $b){
            foreach(
$b as $c)
            {

                
$d $this->make($attributes,$i);

                
array_walk($d, function(&$x)use($c,&$matrix){
                    
$matrix[] = [$c['id'], $x['id']];
                });
            }

            if(!
count($matrix))
                foreach (
$b as $c)
                    
$matrix[] = $c['id'];
        }

        return 
collect($matrix);
    }

    
/**
     * генерирует комбинации
     *
     * @param $attributes
     * @param $index
     * @return array
     */
    
public function make($attributes$index){
        
$arr = [];
        foreach(
$attributes as $i => $attribute){
            if(
$i $index$arr array_merge($arr$attribute);
        }

        return 
$arr;
    }

Возможно код немного говнокод, но для начало пойдет)

Изменено Testuser123 (05.08.2017 10:47:17)

Не в сети

#6 06.08.2017 00:25:23

Re: Не знаю как правильно сделать

PHP
        catch (\Throwable $t)
        {
            return 
response()->json($t->getMessage());
        }
        catch (\
Exception $e)
        {
            return 
response()->json($e->getMessage());

Exception включает Throwable, поэтому отдельный блок для Exception не нужен.

Не в сети

#7 06.08.2017 13:50:07

Re: Не знаю как правильно сделать

  1. Exception включает Throwable, поэтому отдельный блок для Exception не нужен.

Я это делаю для совместимости с php 5.5 . Когда то давно читал на хабре статью что, сначала надо ставить Throwable, а потом Exception, что бы php 5.5 не ругался на Throwable. По этому так делаю.

Не в сети

#8 06.08.2017 21:34:20

Re: Не знаю как правильно сделать

Я это делаю для совместимости с php 5.5

Тогда все верно, если действительно нужно поддерживать 5.х и 7.х.

Не в сети

Подвал раздела