কীভাবে কোনও ইভেন্টের মধ্য দিয়ে যাওয়া স্ট্রিং আমি পরিবর্তন করতে পারি?


10

আমার পর্যবেক্ষক ফাংশনে, আমি ইভেন্টটির মতো করে একটি পরিবর্তনশীল পেয়েছি:

public function observerFunc(Varien_Event_Observer $observer)
{
    $sth = $observer->getEvent()->getSth();
}

যদি sthকোনও বস্তু হয় তবে আমি এটিতে পদ্ধতিগুলি কল করে এটি পরিবর্তন করতে পারি। sthএটি সরল স্ট্রিং হলে কীভাবে আমি পরিবর্তন করতে পারি ? আমি সাফল্য ছাড়াই নিম্নলিখিত চেষ্টা করেছি:

public function observerFunc(Varien_Event_Observer $observer)
{
    $sth = $observer->getEvent()->getSth();
    $observer->getEvent()->setSth('test');
    $observer->setSth('test');
}

আমি কেবল শিখেছি যে কিছু ইভেন্টগুলি ট্রান্সপোর্ট আইটেমটিও পাস করে যেখানে স্ট্রিংটি পরিবর্তন করা যায় (ধন্যবাদ অ্যালেক্স ), তবে ইভেন্টটি page_block_html_topmenu_gethtml_afterতা করে না। তাই আমি কি করতে পারি?

প্রশ্নে থাকা ইভেন্টটি এভাবে প্রেরণ করা হয়ে যায় এবং আমি $ এইচটিএমএল পরিবর্তন করতে চাই:

$html = $this->_getHtml($this->_menu, $childrenWrapClass);
Mage::dispatchEvent('page_block_html_topmenu_gethtml_after', array(
    'menu' => $this->_menu,
    'html' => $html
));

উত্তর:


12

আপনি পারবেন না।

পরিবহনের অবজেক্টের জন্য কাজ করার কারণটি হ'ল পিএইচপি-র বিষয়বস্তু হ'ল উপাধি / রেফারেন্স । আপনি যখন কোনও বস্তুটি সংশোধন করেন, আপনি ওয়ান ট্রু অবজেক্টটি সংশোধন করছেন।

পিএইচপি এর আদিম ধরণের (ints, স্ট্রিং, বুলিয়ানস ইত্যাদি) বস্তু নয় এবং আর্গুমেন্টের মান নিয়মে পিএইচপি পাসের অধীনে আসে । যদি কোনও ম্যাজেন্টো মডিউল বিকাশকারী আপনাকে ইভেন্ট পর্যবেক্ষকের কাছে কাঁচা স্ট্রিং দেয়

    Mage::dispatchEvent('page_block_html_topmenu_gethtml_after', array(
        'menu' => $this->_menu,
        'html' => $html
    ));

এটা তাদের বলার উপায়

আপনি এই মানটি দেখতে পারেন, তবে আমি চাই না আপনি এটি পরিবর্তন করুন।

এটি ইচ্ছাকৃত ডিজাইনের সিদ্ধান্ত হোক বা কোনও বিকাশকারী পাঠকের জন্য অনুশীলন হিসাবে জিনিসগুলি না ভেবেই ছাড়বেন।

আপনার অনাবৃত প্রশ্ন অনুসারে, আপনি যদি শীর্ষস্থানীয় মেনুটি পরিবর্তন করতে চান তবে আমি গ্রহণ করার জন্য কয়েকটি পন্থা রয়েছে। page_block_html_topmenu_gethtml_beforeইভেন্টটিতে জড়িত হওয়া এবং menuঅবজেক্টটি সংশোধন করা

    Mage::dispatchEvent('page_block_html_topmenu_gethtml_before', array(
        'menu' => $this->_menu
    ));

কাজ করা উচিত, যেহেতু _menuএকটি বস্তু

/**
 * Top menu data tree
 *
 * @var Varien_Data_Tree_Node
 */
protected $_menu;

দ্বিতীয়ত, আপনি মেনু উত্পাদনকারী ক্লাসটি আবার লিখতে পারেন

public function getHtml($outermostClass = '', $childrenWrapClass = '')
{
    $html = parent::getHtml($outermostClass, $childrenWrapClass);
    //monkey with $html here to add your menu items or custom markup
    return $html;
}

তৃতীয়, আপনি বিদ্যমান শীর্ষ মেনু ব্লকটি সরাতে লেআউট আপডেটগুলি ব্যবহার করতে এবং আপনার তৈরি কাস্টম শ্রেণীর সাহায্যে একটি নতুন ব্লক inোকাতে পারেন। আপনার কাস্টম ক্লাসটি বিদ্যমান শীর্ষ মেনু শ্রেণীর প্রসারিত করবে এবং তারপরে নতুন সংজ্ঞা দেবে getHtml। এটি আরও জটিল তবে পুনরায় লেখার সাথে সম্পর্কিত সমস্যাগুলি এড়িয়ে চলে।


5

আমি বলব এটি সেই ইভেন্টের একটি ডিজাইন বাগ।

অবজেক্টগুলি রেফারেন্সের মাধ্যমে প্রায় পাস হয়ে যায়, যাতে সেগুলি হেরফের করা যায়। স্ট্রিং সবসময় অনুলিপি করা হয়। সুতরাং এই ক্ষেত্রে স্ট্রিংটি পর্যবেক্ষকের অভ্যন্তরে হেরফের করা যায় না, এমনকি page_block_html_topmenu_gethtml_afterইভেন্টটি কেবল আমার মতো দেখায় এর উদ্দেশ্যটি আপনাকে হেরফের করার সুযোগ দেয় $html


3

এটা তোলে হয় দেখে পরিবাহিত STRING হয়ে ব্লক আউটপুট পরিবর্তন করা আর সম্ভব core_block_abstract_to_html_afterঘটনা (লিঙ্ক) । এই ইভেন্টে, রেন্ডার করা সামগ্রীটি ব্লক উদাহরণ থেকে পর্যবেক্ষকের উদাহরণে স্থানান্তরিত হয় এবং - সবচেয়ে গুরুত্বপূর্ণ - ট্রান্সপোর্টেড সামগ্রীটি ব্লক শ্রেণীর দ্বারা ফিরে আসে। মনে রাখবেন যে এখানে উদাহরণের নীচে ব্যাখ্যা করেছি এমন একটি গুরুত্বপূর্ণ ক্যাচিং বিবেচনা রয়েছে।

উদাহরণ

যেহেতু এই ইভেন্টটি প্রতিটি ব্লক রেন্ডারের জন্য বরখাস্ত করা হয় , আপনার পর্যবেক্ষককে একটি সিঙ্গলটন হিসাবে কনফিগার করতে হবে এবং পরীক্ষা করতে হবে যে ব্লকের ধরণটি একটি উদাহরণ Mage_Page_Block_Html_Topmenu

public function manipulateTopmenuOutput(Varien_Event_Observer $obs)
{
     if ($obs->getBlock() instanceof Mage_Page_Block_Html_Topmenu){
         $initialOutput = $obs->getTransport()->getHtml();
         //e.g. $modified output = $this->yourManipulationMethod($initialOutput);
         $obs->getTransport()->setHtml($modifiedOutput);
     }
}

আপনার কারসাজি যুক্তি পর্যবেক্ষণ পদ্ধতিতে প্রয়োগ করা যেতে পারে বা পর্যবেক্ষককে অন্য পদ্ধতিতে স্থাপন করা যেতে পারে।

সমস্যা

কারণ এতে আউটপুট ম্যানিপুলেশন জড়িত এবং পর্যবেক্ষককে সমস্ত ব্লক রেন্ডারগুলির জন্য ডাকা হয়, এটি কেবল তখনই ব্যবহার করা উচিত যখন প্রাথমিক উদ্বেগ কোনও ব্লক পুনর্লিখন এড়ানো হয়। এছাড়াও, এই পর্যবেক্ষকের উত্পন্ন সামগ্রীটি পোস্ট- block_htmlক্যাশে রাইটিং (ব্লকের উদাহরণের মাধ্যমে কল করে _saveCache()) ম্যানিপুলেটেড হয়, সুতরাং আপনাকে অবশ্যই block_htmlপর্যবেক্ষকটিতে প্রবেশের পুনরায় ক্যাশে করতে হবে (কিছুটা আঠালো, আপনি যেমন প্রতিচ্ছবি ব্যবহার করছেন তবে) বা ক্যাশে এন্ট্রি লেখার জন্য উভয় পদ্ধতি _saveCache()এবং _getSidPlaceholder()পদ্ধতি থেকে লজিকের নকল করা এবং অবশেষে, আপনার যদি গাছের নোডের ডেটা সম্পর্কিত কোনও কিছু চালনার দরকার হয় তবে আপনাকে গাছের নোডের একটি অনুলিপি তৈরি করতে হবে This এটি তাত্ত্বিকভাবে করা যেতে পারে দখল Mage_Catalog_Model_ObserverSingleton এবং তা থেকে গাছ দখল ... খুব চটচটে প্রকৃতপক্ষে।


1
আমি আমার আত্মার একেবারে সারাংশ দিয়ে টপমেনুকে ম্যাগান্টোর প্রয়োগকে ঘৃণা করি। ন্যাভিগেশন কাস্টমাইজেশন প্রয়োজন যে কোনও বাস্তবায়নের সময় আমি নিয়মিত তার বিরুদ্ধে মাথা ঘামি। তারা এইচটিএমএল আউটপুটটিকে আপত্তিহীন উপায়ে টুইঙ্ক করা অত্যন্ত কঠিন করে তুলেছে; ম্যাজেন্টো আপনাকে প্রতিটি পদক্ষেপে লড়াই করে।
wlvrn

ঠিক আছে, হ্যাঁ, মেনুটি অনুপযুক্তভাবে জটিল নয়, তবে আপনি কার্যকরীতাটি বেশ খানিকটা পাবেন।
বেনমার্কস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.