Подтвердить что ты не робот

Как хранить количество продукта в массиве

У меня есть массив данных, который суммирует все элементы в корзине для всех продуктов как одно число.

Я пытался выяснить способ подсчета массива данных() всех разных итогов всех разных элементов в корзине и представить их в разделенном запяте. Надеюсь, это имеет смысл.

if ($order->getId()) {
    $items = $order->getAllVisibleItems();
    $itemIds = array();
    $itemNames = array();
    $itemPrices = array();
    $itemMargins = array();
    $itemTypes = array();
    $itemGenders = array();
    $itemSports = array();
    $itemCategoryIds = array();
    $itemCategoryNames = array();
    /** @var Mage_Sales_Model_Quote_Item $item */
    foreach ($items as $item) {

        // Get the parent item - it is NOT included in the quote due to
        // customizations made by the OrganicInternet module for simple
        // product pricing. So I had to come up with another way to get it.
        $options = $item->getProductOptions();
        $parent = $item->getProduct();
        if (array_key_exists('info_buyRequest', $options)) {
            if (array_key_exists('cpid', $options['info_buyRequest'])) {
                $parentId = $options['info_buyRequest']['cpid'];
                $parent = Mage::getModel('catalog/product')->getCollection()
                    ->addAttributeToSelect('name')
                    ->addAttributeToSelect('season')
                    ->addAttributeToSelect('gender')
                    ->addAttributeToSelect('sport')
                    ->addAttributeToFilter('entity_id', $parentId)
                    ->getFirstItem();
            }
        }

        $itemIds[] = $item->getSku();
        $itemNames[] = $parent->getName();
        $itemPrices[] = $item->getBasePrice() ?: 0;
        $itemMargins[] = $this->_calculateMargin($parent, null, $item);
        $itemTypes[] = $parent->getAttributeText('season');
        $itemGenders[] = $parent->getAttributeText('gender');
        $itemSports[] = $parent->getAttributeText('sport') ?: 'Other';
        $categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
        $itemCategoryIds[] = $categories['id'];
        $itemCategoryNames[] = $categories['name'];
    }

    // # Products

    $data['u1'] = count($items);

Вышеупомянутое вернет:

dataLayer = [{ "visitorLoginState": "Logged out", "visitorType": "NOT LOGGED IN", "visitorLifetimeValue": 0, "visitorExistingCustomer": "Нет", "u1": 2, "u2": [ "889623392590", "889623135517" ]

Он отображает в общей сложности 2 продукта для переменной U1 и два sku для переменной u2 в массиве данных.

Если у меня есть несколько продуктов для первого sku, я хочу, чтобы он разделял количества. т.е... "u1":1,1,3

Можно ли использовать array_sum или некоторый тип многомерного массива для удовлетворения моих потребностей?

4b9b3361

Ответ 1

Если у меня есть несколько продуктов для первого sku, я хочу, чтобы он разделился количества. т.е... "u1": 1,1,3

Мне не совсем ясно, что отношение между sku и продуктом и какие переменные в вашем массиве относятся к ним. Я делаю следующие предположения: 1) A product эквивалентен одному элементу $items 2) A sku является уникальным значением $itemIds[]

Я использую ключ массива как простой способ отслеживать каждый уникальный sku и значение, чтобы отслеживать количество продуктов для sku.

if ($order->getId()) {
    $items = $order->getAllVisibleItems();
    $itemIds = array();
    $itemNames = array();
    $itemPrices = array();
    $itemMargins = array();
    $itemTypes = array();
    $itemGenders = array();
    $itemSports = array();
    $itemCategoryIds = array();
    $itemCategoryNames = array();

    // My addition (UPDATE: fixed to the correct variable name)
    $uniqueItemIds = array();

    /** @var Mage_Sales_Model_Quote_Item $item */
    foreach ($items as $item) {

        // Get the parent item - it is NOT included in the quote due to
        // customizations made by the OrganicInternet module for simple
        // product pricing. So I had to come up with another way to get it.
        $options = $item->getProductOptions();
        $parent = $item->getProduct();
        if (array_key_exists('info_buyRequest', $options)) {
            if (array_key_exists('cpid', $options['info_buyRequest'])) {
                $parentId = $options['info_buyRequest']['cpid'];
                $parent = Mage::getModel('catalog/product')->getCollection()
                    ->addAttributeToSelect('name')
                    ->addAttributeToSelect('season')
                    ->addAttributeToSelect('gender')
                    ->addAttributeToSelect('sport')
                    ->addAttributeToFilter('entity_id', $parentId)
                    ->getFirstItem();
            }
        }
        // *******************************
        // My addition / changes
        $sku = $item->getSku();
        $itemIds[] = $sku;        // I don't use this but keep $itemIds for compatibility            

        // use the array key to track counts for each sku
        if (!isset($uniqueItemIds[$sku])){
            $uniqueItemIds[$sku] = 1;   // UPDATE: fixed to start at 1 not 0
        } else {
            $uniqueItemIds[$sku]++;
        }
        // *******************************
        $itemNames[] = $parent->getName();
        $itemPrices[] = $item->getBasePrice() ?: 0;
        $itemMargins[] = $this->_calculateMargin($parent, null, $item);
        $itemTypes[] = $parent->getAttributeText('season');
        $itemGenders[] = $parent->getAttributeText('gender');
        $itemSports[] = $parent->getAttributeText('sport') ?: 'Other';
        $categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
        $itemCategoryIds[] = $categories['id'];
        $itemCategoryNames[] = $categories['name'];
    }

    // show # Products
    // "u1":1,1,3 NOTE: this should be a string => "u1":"1,1,3"
    $data['u1'] = "";
    foreach ($uniqueItemIds as $key => $val)
        // show unique skus in u2
        $data['u2'][] = $key;
        // show counts for each sku in u1
        if (strlen($data['u1'] == 0)){
            $data['u1'] = (string)$value;
        } else {
           $data['u1'] .= ("," . $value);
        }            
    }

Ответ 2

Как насчет чего-то вроде...

if ($order->getId()) {
    .....
    .....
    .....
    /** @var Mage_Sales_Model_Quote_Item $item */
    $sku_based_array = array();

    foreach ($items as $item) {
        ......
        ......
        ......
        $categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
        $itemCategoryIds[] = $categories['id'];
        $itemCategoryNames[] = $categories['name'];

        if (isset($sku_based_array[$item->getSku()])) {
            $sku_based_array[$item->getSku()] = $sku_based_array[$item->getSku()]++;
        } else {
            $sku_based_array[$item->getSku()] = 1;
        }
    }

    // # Products

    $data['u1'] = array_values($sku_based_array);

Ответ 3

Часть проблемы с вашими данными здесь заключается в том, что все в $item скрыто за аксессуаром. Вместо создания множества массивов я предлагаю либо создать новый объект для размещения информации, либо просто изменить $item напрямую.

Взаимодействие с объектом напрямую связано с тем, что вы случайно используете имя переменной, которое существует в области protected или private, хотя, вероятно, лучше всего использовать свои собственные, например.

if ($order->getId()) {
    $items = $order->getAllVisibleItems();

    // only need one array, no need for all data points to have their own
    $myItems = [];

    /** @var Mage_Sales_Model_Quote_Item $item */
    foreach ($items as $item) {
        // basic shell
        $myItem = [];

        // get $options and $parent
        // ...

        // build your own data object
        $myItem['sku'] = $item->getSku();
        $myItem['name'] = $parent->getName();
        $myItem['price'] = $item->getBasePrice() ?: 0;
        $myItem['margin'] = $this->_calculateMargin($parent, null, $item);
        $myItem['type'] = $parent->getAttributeText('season');
        $myItem['gender'] = $parent->getAttributeText('gender');
        $myItem['sport'] = $parent->getAttributeText('sport') ?: 'Other';
        $categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
        $myItem['categoryId'] = $categories['id'];
        $myItem['categoryName'] = $categories['name'];

        $myItems[] = $myItem;
    }

    // At this point, $myItems is manipulable by all the array_* functions

    // number of items e.g. 3
    $data['u1'] = count($myItems);
    // array of skus e.g. ["889623392590","889623392590","889623135517"]
    // note: can use objects for $myItem if on PHP 7 
    //       if you like -> notation better (in the loop)
    $skus = array_column($myItems, 'sku');
    // array of skus with counts e.g. ["889623392590" => 2, "889623135517" => 1]
    $skus_with_counts = array_count_values($skus);
    // just the counts (assuming indexes on other arrays must match) e.g. [2, 1]
    // note: might be useful if you want to keep the counts as an array in dataLayer
    $sku_counts = array_values($skus_with_counts);
    // if you want this as a comma-separated list for u1, e.g. "2,1"
    // note: will also work if you implode $skus_with_counts
    $data['u1'] = implode(',', $sku_counts);
    // get a list of unique SKUs (both will work), e.g. ["889623392590","889623135517"]
    $data['u2'] = array_unique($skus);
    $data['u2'] = array_keys($skus_with_counts);
}

Большинство из этих функций PHP будут работать и с вашими другими типами данных, если вы хотите делать подсчет и кластеризацию, и, как вы указываете, вы можете также выполнять операции над ними, если хотите.

Ссылки на манипуляции с массивами PHP: array_column, array_count_values, array_values, implode, array_unique, array_keys.

В качестве боковой панели Mage_Sales_Model_Quote_Item имеет доступный getParentItemId() и getQtyOptions, который возвращает как количество, так и модель продукта.

Ответ 4

Посмотрев на код, похоже, он будет возвращать только один продукт, поскольку переменная $parent перезаписывается, чтобы получить первый элемент. Я добавил новую переменную с именем $itemProductCounts, это будет возвращено в выходной массив $data как itemProductCounts Я подозреваю, что это всегда будет равно одному.

<?php
if ($order->getId()) {
    $items              = $order->getAllVisibleItems();
    $itemIds            = array();
    $itemNames          = array();
    $itemPrices         = array();
    $itemMargins        = array();
    $itemTypes          = array();
    $itemGenders        = array();
    $itemSports         = array();
    $itemCategoryIds    = array();
    $itemCategoryNames  = array();
    $itemProductCounts  = array();
    /** @var Mage_Sales_Model_Quote_Item $item */
    foreach ($items as $item) {

        // Get the parent item - it is NOT included in the quote due to
        // customizations made by the OrganicInternet module for simple
        // product pricing. So I had to come up with another way to get it.
        $options    = $item->getProductOptions();
        $parent     = $item->getProduct();
        if (array_key_exists('info_buyRequest', $options)) {
            if (array_key_exists('cpid', $options['info_buyRequest'])) {
                $parentId = $options['info_buyRequest']['cpid'];
                $parent = Mage::getModel('catalog/product')->getCollection()
                    ->addAttributeToSelect('name')
                    ->addAttributeToSelect('season')
                    ->addAttributeToSelect('gender')
                    ->addAttributeToSelect('sport')
                    ->addAttributeToFilter('entity_id', $parentId)
                    ->getFirstItem();
            }
        }

        $itemIds[]                          = $item->getSku();
        $itemNames[]                        = $parent->getName();
        $itemPrices[]                       = $item->getBasePrice() ?: 0;
        $itemMargins[]                      = $this->_calculateMargin($parent, null, $item);
        $itemTypes[]                        = $parent->getAttributeText('season');
        $itemGenders[]                      = $parent->getAttributeText('gender');
        $itemSports[]                       = $parent->getAttributeText('sport') ?: 'Other';
        $categories                         = $this->_getAllCategoryIdsAndNames($item->getProduct());
        $itemCategoryIds[]                  = $categories['id'];
        $itemCategoryNames[]                = $categories['name'];
        $itemProductCounts[$item->getSku()] = count($parent);
    }

    // # Products

    $data['u1'] = count($items);
    $data['itemProductCounts'] = $itemProductCounts;

С учетом сказанного выше приведенный выше код должен приблизить вас к тому, что вам нужно, вы должны заменить строку $itemProductCounts[$item->getSku()] = count($parent); на правильный массив с количеством продуктов для этого SKU.

Ответ 5

Я думаю, вы смешиваете вещи.

В простой системе вы должны:

  • Заказ имеет массив OrderedItems

  • Каждый OrderedItem хранит ProductObject и OrderedQuantity

  • И ProductObject содержит все данные о продуктах.

Итак, в вашем примере вместо подсчета SKU вы должны иметь поле $item- > quantity, и вы должны работать с ним при добавлении/удалении/изменении содержимого заказа.