ম্যাগ_গ্যাটালগ_মোডেল_ রিসোর্স_প্রডাক্ট_কলেকশনে কীভাবে স্টোর আইডি সেট করবেন?


34

কাজটি তুচ্ছ। ফ্ল্যাট ক্যাটালগ সক্ষম হওয়া সহ নির্দিষ্ট স্টোর ভিউয়ের জন্য পণ্যের তালিকা পেতে আমার দরকার need সর্বাধিক সুস্পষ্ট সমাধান নিম্নলিখিত:

$collection = Mage::getResourceModel('catalog/product_collection')
    ->setStore($storeId);

প্রকৃতপক্ষে setStore()পদ্ধতিটি এখানে কোনও পার্থক্য করছে না কারণ স্টোর আইডির উপর ভিত্তি করে ফ্ল্যাট টেবিলের নামটি পাওয়া যায় সেই _initSelect()পদ্ধতির পরে তাকে বলা হয় Mage_Catalog_Model_Resource_Product_Collection। স্টোর আইডি এখনও সেট না করা হিসাবে এটি বর্তমান স্টোর আইডি লাগে।

সুতরাং স্পষ্টত কাজটি হবে মডেল পাওয়ার আগে একটি বর্তমান স্টোর আইডি সেট করা।

Mage::app()->setCurrentStore($storeId);

$collection = Mage::getResourceModel('catalog/product_collection');

এটা কাজ করবে। তবে আপনার যদি একবার সংগ্রহের প্রয়োজন হয়। যদি আপনাকে লুপে সংগ্রহ করতে হয় বা আপনার কেবল দুটি পিছনে পিছনে সংগ্রহের প্রয়োজন হয় তবে আপনি তাদের জন্য নির্দিষ্ট স্টোর সেট করতে পারবেন না।

কারণটি হ'ল Mage_Catalog_Model_Resource_Product_Flatশ্রেণীর নিজস্ব _storeIdসম্পত্তি রয়েছে এবং নির্মাতায় এটি বর্তমান স্টোর আইডিতে সেট করা আছে। এজন্য এটি প্রথমবার সেট করা হবে। তারপরে কোনও কারণে (স্বর্গ জানে আমি আশা করি একটি আছে) Mage_Eav_Model_Entity_Collection_Abstract::_initপ্রতিটি সংস্থান মডিউলে একটি সিঙ্গলটন হিসাবে আনা হয়। 2 র্থ কলের জন্য কোনও নির্মাণকারী নেই।

এগুলি এতোটাই ভুল দেখাচ্ছে যে আমি নিশ্চিত যে আমি ভুল এবং এটি অন্য কোনও ম্যাজেন্টো বাগ (বা দুটি) নয়। আশা করি কেউ এটির উপর আলোকপাত করতে পারে।


উদাহরণস্বরূপ আপনি কি getResourceModel () ব্যবহার করবেন? getModel ('ক্যাটালগ / রিসোর্স_প্রোডাক্ট_লোকশন') কেবলমাত্র কাজ করতে পারে।
ক্রেস্টফ ফুমানে

না, একেবারে একই। এটি কোনও উপায়ে রিসোর্স মডেল সিঙ্গলটন ইনস্ট্যান্ট করছে।
ব্যবহারকারী 487772

টিম, এটি একটি উত্তর হিসাবে যুক্ত করুন দয়া করে!
ফ্যাবিয়ান ব্লাচসমিড

@ ফ্যাবিয়ান ব্লাচস্মিডিট সম্পন্ন হয়েছে।
ব্যবহারকারী 487772

উত্তর:


13

এটি ম্যাজেন্টোর কোন সংস্করণ? এগুলি ম্যাজেন্টো 1.9 এর জন্য আমার ফলাফল:

ফ্ল্যাট ক্যাটালগ সক্ষম:

ফ্ল্যাট ক্যাটালগ সূচকযুক্ত:

নির্দিষ্ট স্টোর ভিউতে কিছু ডেটা সেট করা হয়েছে:

কোড ব্যবহৃত:

<?php

require_once 'app/Mage.php';

Mage::app('admin');

$collection = Mage::getResourceModel('catalog/product_collection')
    ->addAttributeToSelect('*')                                                                                                                                                                                                                                                 
    ->addFieldToFilter('entity_id', array('eq' => 231))
    ->setStore(2);

var_dump($collection->getFirstItem()->getName());

আশানুরূপ ফলাফল:

string(18) "But I Am Le French"

সম্পাদনা:

কিছুই নয়, ফ্ল্যাট ক্যাটালগ বিশেষভাবে অ্যাডমিন স্টোরের জন্য নিষিদ্ধ:

// Flat Data can be used only on frontend
if (Mage::app()->getStore()->isAdmin()) {
    return false;
}

তদন্ত ...

edit2:

দেখে মনে হচ্ছে আপনি ঠিক আছেন। _initSelectআমরা স্টোর আইডি সংশোধন করতে সক্ষম হওয়ার আগে বলা হয় যা টেবিলের নাম তৈরি করতে ব্যবহৃত হয়।

অবশ্যই (যদি আমরা পুনরায় লেখার পথে যেতে না চাই) আমরা করতে পারি:

  • getSelect(), একটি রিসেট করুন এবং () থেকে একটি নতুন সেট করুন
  • $collection->getEntity()->setStoreId(123)এবং তারপরে _initSelectআবার কল করার জন্য প্রতিবিম্ব ব্যবহার করুন
  • কেবল আমাদের নিজস্ব সংস্থান মডেল তৈরি করুন এবং ফ্ল্যাট থেকে প্রসারিত করুন, সঠিক সময়ে স্টোর Iোকানোর কিছু উপায় দিন ( __construct, বিলম্বকরণ _initSelect, ইত্যাদি)।
  • setCurrentStoreআমরা সংগ্রহ তৈরি করার সময় কল করুন ।

তবে এগুলি খুব হ্যাক লাগছে ... দুঃখিত, এটি একটি অসন্তুষ্ট উত্তর হতে পারে :-(

edit3:

সুতরাং কমপক্ষে একটি উত্তর সরবরাহ করার জন্য:

// Get collection and update store ID.
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->getEntity()->setStoreId(2);

// Reset the select.
$collection->getSelect()->reset();

// Update table name.
$reflectionMethod = new ReflectionMethod($collection, '_initSelect');
$reflectionMethod->setAccessible(true);
$reflectionMethod->invoke($collection);

// Do any other operations on the collection now.
$collection->addAttributeToSelect('*');

দয়া করে এটি ব্যবহার করবেন না ;-)


সুতরাং আপনি কি এটি একটি বাগ হিসাবে মনে করেন?
ব্যবহারকারী 487772

1
আমি কোডটি দিয়ে স্কিমেড করেছি তবে product_collectionএর কনস্ট্রাক্টর রিসোর্স মডেলটিকে আর্গুমেন্ট হিসাবে গ্রহণ করে। সুতরাং যদি আপনি একটি তৈরি করেন Product_Resource_Flat, এটির স্টোর আইডি সেট করুন, এটি ক্লোন করুন এবং একটি আলাদা স্টোর আইডি সেট করুন, তবে এটি সংগ্রহকারী কনস্ট্রাক্টরকে দিন, তা কি সম্ভব?
মেলভিন 6

1
@ টিম: দুঃখিত, কেবল আপনার মন্তব্য দেখেছি। হ্যাঁ আমি মনে করি এটি একটি বাগ।
ড্যানিয়েল স্লোফ

দুর্দান্ত উত্তরের জন্য, এটি 1.14.2.0
ব্যবহারকারীর 4531

10

সুতরাং আমি এগুলিকে ম্যাজেন্টোতে দুটি বাগ হিসাবে বিবেচনা করি।

প্রথমটি হ'ল আপনি catalog/productসংগ্রহে স্টোর আইডি সেট করতে পারবেন না । এবং দ্বিতীয়টি হ'ল আপনি সম্পূর্ণরূপে অ-সিঙ্গলটন হিসাবে সংস্থান মডেল পেতে পারবেন না।

সুতরাং বোকা workaround মডেল দু'বার ইনস্ট্যান্ট করা হয়। প্রথমবার স্টোর আইডি সেট করা যাবে এবং দ্বিতীয় ইনস্ট্যান্টেশন এটি ব্যবহার করবে:

Mage::getResourceModel('catalog/product_collection')->setStore($storeId);

$collection = Mage::getResourceModel('catalog/product_collection')

আমি জানি না কেন ম্যাগে আমার সেট স্টোর :: getModel ('ক্যাটালগ / বিভাগ') -> getProduct Colલેક્શન () -> সেটস্টোরআইডি () কাজ করেনি এবং আপনার কাজ করেছে।
যাইহোক

3

মজার বিষয় হচ্ছে, ব্যবহৃত ফ্ল্যাট টেবিলটি একবার সেট করা হয় এবং কখনই পরিবর্তন হয় না যা EAV এর জন্য কাজ করে যে টেবিলের নাম পরিবর্তন হয় না তবে ফ্ল্যাটের জন্য নয় কারণ টেবিলের নামটিতে স্টোর আইডি অন্তর্ভুক্ত রয়েছে। একটি কার্যপ্রণালী হ'ল সাহায্যকারী তৈরি করা যা কোয়েরির FROM অংশে টেবিলটি সরিয়ে দেয়। এই জাতীয় সাহায্যকারীর উদাহরণ এখানে:

class My_Module_Helper_Data extends Mage_Core_Helper_Abstract
{
    public function getProductCollectionForStore($store)
    {
        $collection = Mage::getResourceModel('catalog/product_collection');

        // Change the store on the entity
        // This doesn't change it in the (already constructed) SQL query
        $collection->setStore($store);

        if (! $collection->isEnabledFlat()) {
            return $collection;
        }

        // Change the used table to the $store we want
        $select = $collection->getSelect();
        $from = $select->getPart('from');

        // Here, getFlatTableName() will pick up the store set above
        $from[$collection::MAIN_TABLE_ALIAS]['table'] =
        $from[$collection::MAIN_TABLE_ALIAS]['tableName'] = 
            $collection->getEntity()->getFlatTableName();

        $select->setPart('from', $from);
        return $collection;
    }
}

তারপরে আপনি এটিকে সহজভাবে ব্যবহার করতে পারেন:

$collection = Mage::helper('my_module')->getProductCollectionForStore('somestore')
    ->addAttributeToSelect('name');

আমি কল্পনা করি যে এটি এসকিউএল-তে কোনও সমস্যা তৈরি করবে না যেহেতু আপনি একক ফ্ল্যাট টেবিল থেকে সমস্ত ডেটা আনছেন তবে এটি সিঙ্গলটন যেহেতু সর্বশেষ ব্যবহৃত স্টোর অন্য কোথাও ব্যবহৃত হবে।

বিকল্প সমাধান হ'ল কোনও পর্যবেক্ষক তৈরি করা catalog_product_collection_load_beforeযা এর উপরে এই জাতীয় কিছু করে:

class My_Module_Model_Observer
{
    public function setCorrectFlatStore(Varien_Event_Observer $observer)
    {
        $collection = $observer->getCollection();
        if (! $collection->isEnabledFlat()) {
            return;
        }

        $select = $collection->getSelect();
        $from = $select->getPart('from');

        // If somebody called setStore() on the collection make sure
        // to update the used flat table
        $from[$collection::MAIN_TABLE_ALIAS]['table'] =
        $from[$collection::MAIN_TABLE_ALIAS]['tableName'] =
            $collection->getEntity()->getFlatTableName();

        $select->setPart('from', $from);
    }
}

আমি সম্মত হই যে ম্যাগেন্টো ছেলেরা _beforeLoad()পদ্ধতিতে এটি ঠিক করা উচিত ।


0

সাধারণ ফিল্টার ব্যবহার করবেন না কেন?

$collection->addAttributeToFilter('store_id', $store_id);

store_id * _eav_entity টেবিলটিতে নিয়মিত কলাম হিসাবে দেওয়া হয় , আপনি এটির মাধ্যমেও ফিল্টার করতে পারেন। আমার জন্য কাজ করেছেন।


0

কোর / অ্যাপ_মুলেশন সহ আমার এই সমাধানটি সমাধান করুন:

$storeId = 3;
$emulationModel = Mage::getModel('core/app_emulation');

// Emulate shop environment to disable using flat model and get collection for specific store
$emulationModel->startEnvironmentEmulation($storeId);
$products = Mage::getModel('catalog/product')->getCollection();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.