لا يعمل ترقيم الصفحات على الشبكة عند استخدام جملة المجموعة في المجموعة

magento.stackexchange https://magento.stackexchange.com//questions/50285

سؤال

أنا أعمل على شبكة المنتج ولكن ترقيم الصفحات أو عدد المنتجات لا يعمل (لأنه يعرض عددًا خاطئًا).نظرًا لأن وظيفة block _preparecollection الخاصة بي هي كما هو موضح أدناه. لقد قمت بإضافة رمز مرشح الفئة في المجموعة لذا لا بد لي من استخدام جملة المجموعة لمنع حدوث خطأ لنفس المعرف الموجود بالفعل.

    protected function _prepareCollection()
    {
        $store = $this->_getStore();
        $collection = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToSelect('sku')
            ->addAttributeToSelect('name')
            ->addAttributeToSelect('attribute_set_id')
            ->addAttributeToSelect('type_id')
            ->joinField('category_id',
                'catalog/category_product',
                'category_id',
                'product_id=entity_id',
                null,
                'left');
$collection->addAttributeToFilter('category_id', array('in' => array(4,10)))
            ->distinct(true);
            $collection->getSelect()->group('e.entity_id');


        if (Mage::helper('catalog')->isModuleEnabled('Mage_CatalogInventory')) {
            $collection->joinField('qty',
                'cataloginventory/stock_item',
                'qty',
                'product_id=entity_id',
                '{{table}}.stock_id=1',
                'left');
        }
        $collection->joinField('position',
                'catalog/category_product',
                'position',
                'product_id=entity_id',
                null,
                'left');
        $collection->joinField('websites',
            'catalog/product_website',
            'website_id',
            'product_id=entity_id',
            null,
            'left');
        if ($store->getId()) {
            //$collection->setStoreId($store->getId());
            $adminStore = Mage_Core_Model_App::ADMIN_STORE_ID;
            $collection->addStoreFilter($store);
            $collection->joinAttribute(
                'name',
                'catalog_product/name',
                'entity_id',
                null,
                'inner',
                $adminStore
            );

            $collection->joinAttribute(
                'custom_name',
                'catalog_product/name',
                'entity_id',
                null,
                'inner',
                $store->getId()
            );
            $collection->joinAttribute(
                'status',
                'catalog_product/status',
                'entity_id',
                null,
                'inner',
                $store->getId()
            );
            $collection->joinAttribute(
                'visibility',
                'catalog_product/visibility',
                'entity_id',
                null,
                'inner',
                $store->getId()
            );
            $collection->joinAttribute(
                'price',
                'catalog_product/price',
                'entity_id',
                null,
                'left',
                $store->getId()
            );
        }
        else {
            $collection->addAttributeToSelect('price');
            $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
            $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
        }

        $this->setCollection($collection);

        parent::_prepareCollection();
        $this->getCollection()->addWebsiteNamesToResult();
        return $this;
    }

كان لدي جوجل وحصلت على إجابة وأضفتها إلى lib/varian/data/collection/db.php

    public function getSelectCountSql()
{
     $this->_renderFilters();

        $countSelect = clone $this->getSelect();
        $countSelect->reset(Zend_Db_Select::ORDER);
        $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
        $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
        $countSelect->reset(Zend_Db_Select::COLUMNS);

        if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
            $countSelect->reset(Zend_Db_Select::GROUP);
            $countSelect->distinct(true);
            $group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
            $countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
        } else {
            $countSelect->columns('COUNT(*)');
        }
        return $countSelect;
}

enter image description hereولكن لا حظ الرجاء المساعدة في حل هذه المشكلة

هل كانت مفيدة؟

المحلول

المجموعات والتحميل البطيء في Magento

يرجع سبب عدم عمل ترقيم الصفحات إلى كيفية حساب المجموعات وكيفية عمل التحميل البطيء مع المجموعات.

المجموعات في Magento تنفذ الفصل Countable.بسبب التحميل البطيء للمجموعات في Magento، كلما كانت الطريقة count() يتم استدعاء البيانات يجب أن يتم تحميلها.كحل بديل لهذه المشكلة، تطبق المجموعات طريقة تسمى getSize().سوف يقوم باستنساخ عبارة SQL الخاصة بك، ثم لفها في ملف COUNT() وإرجاع النتيجة.سمح هذا للمجموعة بالحصول على العدد الإجمالي دون تحميل جميع البيانات.يسمح هذا بإضافة أشياء مثل المرشحات في اللحظة الأخيرة.

هذا هو ما Varien_Data_Collection_Db::getSize() وهو شريك getSelectCountSql() يشبه:

/**
     * Get collection size
     *
     * @return int
     */
    public function getSize()
    {
        if (is_null($this->_totalRecords)) {
            $sql = $this->getSelectCountSql();
            $this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);
        }
        return intval($this->_totalRecords);
    }

    /**
     * Get SQL for get record count
     *
     * @return Varien_Db_Select
     */
    public function getSelectCountSql()
    {
        $this->_renderFilters();

        $countSelect = clone $this->getSelect();
        $countSelect->reset(Zend_Db_Select::ORDER);
        $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
        $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
        $countSelect->reset(Zend_Db_Select::COLUMNS);

        $countSelect->columns('COUNT(*)');

        return $countSelect;
    }

في الأساس، فهو يسقط الحدود والأعمدة والترتيب وما إلى ذلك ويترك المرشحات خلفه.ثم يضيف MySQL COUNT() إلى الأعمدة.

المشكلة

عادةً، في أحد الجداول، يؤدي ذلك إلى إرجاع صف واحد يحتوي على العدد الإجمالي.هذا هو السبب getSize() يفعل أ fetchOne() ضد الاستعلامومع ذلك، عند القيام بأشياء مثل الانضمام إلى الجدول، والمجموعة الفرعية، وما شابه ذلك، لن تقوم بإرجاع صف واحد، بل سترجع عدة صفوف.ولهذا السبب تحتاج إلى تغيير getSize() الطريقة في مجموعتك.

الحل

هذا ما يجب أن تبدو عليه طريقتك الآن:

public function getSize() {

        if ( is_null( $this->_totalRecords ) ) {
            $sql = $this->getSelectCountSql();
            // fetch all rows since it's a joined table and run a count against it.
            $this->_totalRecords = count( $this->getConnection()->fetchall( $sql, $this->_bindParams ) );
        }

        return intval( $this->_totalRecords );
    }

بدل من fetchOne(), ، ركضنا أ fetchAll() ملفوفة في count() وظيفة PHP.الآن سوف تعود المجاميع الخاصة بك بشكل مناسب.

نصائح أخرى

حل عظيم.ربما لدى شخص ما نفس المشكلة التي واجهناها، لذلك سأقوم بنشر حل آخر ممكن.في حالتنا كانت لدينا مجموعة، والتي تضمنت أحيانًا مجموعة حسب العبارة وأحيانًا لم تكن كذلك، اعتمادًا على الشبكة التي تم تحميل المجموعة فيها.باستخدام الحل أعلاه، وجدنا مشكلتين:

  1. إذا كانت المجموعة فارغة، يتم تقييم الحجم بـ 1، على الرغم من أنه يجب أن يكون صفرًا.
  2. في الحالات التي يتم فيها استدعاء أسلوب getSize بدون عبارة "مجموعة حسب" في المجموعة، يتم تقييم الحجم بـ 1 بغض النظر عن عدد العناصر الموجودة في المجموعة.

بعد تصحيح الأخطاء لفترة من الوقت اكتشفنا أنه في الحالة 1 الجزء

$this->getConnection()->fetchall( $sql, $this->_bindParams ) 

تقوم بإرجاع مصفوفة تحتوي على إدخال واحد بقيمة 0.ولهذا السبب تقوم دالة العد بإرجاع الرقم 1 على الرغم من عدم العثور على أي إدخالات.

في الحالة 2، يقوم نفس الجزء بإرجاع مصفوفة ذات إدخال واحد، تكون قيمته هي الحجم الحقيقي للمجموعة.تقوم دالة العد مرة أخرى بإرجاع 1 وليس القيمة.

أثناء البحث عن بديل، اكتشفنا أن مجموعة المنتجات تستخدم إعادة كتابة للوظيفة getSelectCountSql().لقد قمنا بتعديل هذا وتغييره قليلاً، والذي انتهى بهذا الحل:

public function getSelectCountSql()
{
    $countSelect = parent::getSelectCountSql();
    $countSelect->reset(Zend_Db_Select::COLUMNS);
    $countSelect->reset(Zend_Db_Select::GROUP);
    $countSelect->columns('COUNT(DISTINCT item_id)');

    return $countSelect;
}

إنه يحل المشكلتين اللتين ذكرتهما بالفعل، وبقدر ما أستطيع رؤيته، فإنه يعمل أيضًا مع الحالات الأخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى magento.stackexchange
scroll top