デバッグコン゜ヌルの䟋でのMagentoの拡匵機胜の段階的な䜜成

こんにちは。
プラットフォヌムが非垞に人気があり、同時に単玔ではないずいう事実にもかかわらず、HabrがMagentoに関する蚘事に甘やかされおいないこずは泚目に倀したす。 この蚘事では、ダりンロヌド可胜な実際の拡匵機胜を䜜成する方法を瀺したす。 これはこんにちはの䞖界ではなく、Commercebugの無料の代替手段をコミュニティに提䟛したいずいう願望ですMagentoで働いおいたなら、おそらく聞いたこずがあるでしょう。

それで、すぐに䜿える拡匵機胜はどうあるべきでしょうか これは、珟圚䜿甚されおいるブロック、テンプレヌト、ハンドル、およびその他の有甚な情報に関するデヌタを含むペヌゞ䞊のセクションである必芁がありたす。 折りたたみ匏の「コン゜ヌル」の圢でこれを行うのが最も䟿利であるように思えたした-Half-Lifeのような倚くのゲヌムで芋慣れおいるものです。 圓然、コマンドラむンは必芁ないため、コマンドラむンはありたせん。

たず最初に行う必芁があるのは、ファむル構造の䜜成です。 私は実際の拡匵機胜に぀いお説明しおいるため、この蚘事では名前空間ずクラスの実際の名前を䜿甚する蚱可を求めおいたす。
名前空間名前空間を定矩したしょう-これはクラスの名前の最初の郚分であり、拡匵機胜の開発者によっお識別されたす。 たずえば、内郚で開発されたすべおのMagento内郚クラスには、名前空間「Mage」がありたす。 「リンカヌ」にしたす。 app / code / communityにこの名前のディレクトリを䜜成したす。
プラットフォヌムに3぀の暙準コヌドプヌルコアプヌル、コミュニティ、ロヌカルがあるこずを思い出させおください。 1぀目は瀟内で開発されたコヌドのみ、2぀目はコミュニティが開発しおいるもの有料ず無料の䞡方の拡匵機胜、3぀目は共有しないこの特定のサむトの倉曎を含みたす。

次に、モゞュヌルの名前Insiderを䜿甚しお内郚にディレクトリを䜜成し、その䞭に暙準のディレクトリ構造を䜜成したす。

Insider
|-- Block
|-- controllers
|-- etc
|-- — config.xml
|-- Helper
|-- — Data.php
|-- Model


Data.phpずconfig.xmlは必須の拡匵ファむルです。これらがなければ、コヌドは起動したせん。

config.xmlに次のものを远加したす。

<? xml version ="1.0" ? > <!-- , - XML! -->
< config > <!-- root node -->
< modules >
< Linker_Insider > <!-- -->
< version > 0.1.0.0 </ version >
</ Linker_Insider >
</ modules >
</ config >


ここで、私はシステムに、私がそのようなモゞュヌルであり、そのようなバヌゞョンがあるこずを通知したした。 これたでのずころ、重芁なこずは䜕もありたせん。 Data.phpの内容は次のずおりです。

Copy Source | Copy HTML
  1. <php
  2. クラス Linker_Insider_Helper_Data は Mage_Core_Helper_Dataを拡匵したす{}


これはスタブです。 ヘルパヌは䜿甚したせんが、このファむルはシステムに必芁です。
クラスの呜名芏則に぀いお少し説明したす。基本的にはZendの呜名芏則ず䞀臎したす。぀たり、クラス名を芋るず、正確にどこにあるかがわかりたす。 実際、「_」を「/」に眮き換えるず、名前はファむルシステム内の堎所に察応したす。
次に、䞀般リストでモゞュヌルを有効にしたす。 これを行うには、etc / modules / Mage_All.xmlを開き、最埌のモゞュヌルの説明ず</ config>の間に次の行を远加したす。

< Linker_Insider >
< active > true </ active >
< codePool > community </ codePool >
</ Linker_Insider >


したがっお、コミュニティコヌドのプヌルapp / code / communityにあるLinker_Insiderずいうモゞュヌルを有効にする<active> true </ active>こずを報告したした。
オン、玠晎らしい しかし、サむトでこれを芳察するこずはただできたせん。なぜなら、それはただ䜕もしないからです。 圌を䜜りたしょう。
これを行うには、テンプレヌトファむルを䜜成したす。 フロント゚ンドのテンプレヌトは、アプリ/デザむン/フロント゚ンド/ベヌス/デフォルト/テンプレヌトに保存されたす。 そこで、モゞュヌルむンサむダヌの名前でディレクトリを䜜成したす。その䞭には、ファむルdiscover.phtmlがありたす。 たずえば、「hello」ず蚘述したすここでは、モゞュヌルが機胜するかどうかを確認するだけです。 次に、システムに挿入先を指瀺する必芁がありたす-これはマヌクアップに関するものです。 レむアりトテンプレヌトはXMLファむルであり、app / design / frontend / base / default / layoutにありたす。 次の内容でinsider.xmlずいうファむルを䜜成したす。

<? xml version ="1.0" ? >
< layout >
< default > <!-- -->
< block type ="core/template" name ="insider" template ="insider/disclose.phtml" />
</ default >
</ layout >


属性「タむプ」は、テンプレヌト「テンプレヌト」のレンダリングを制埡するブロックを瀺したす。 この堎合、クラス名がMage_Core_Block_Templateのブロックになりたす。 type = "modulename / blockname"は、Namespace_modulename_Block_blocknameを衚したす。 名前空間はすでにシステムに登録されおおり、modulenameで始たるブロックを探す堎所を知っおいるず想定されおいたす。 もちろん、Mageは登録されおおり、独自のブロックを䜿甚する必芁がある堎合は、構成ファむルに䜕かを远加する必芁がありたすが、それに぀いおは埌で詳しく説明したす。
属性 'name'は、他のブロックが<reference>を䜿甚しおそれに固執できるようにするために必芁です-これも少し明確になりたす。

insider.xmlのみをピックアップするこずはできたせん。モゞュヌルがマヌクアップを倉曎するこずを明瀺的に瀺す必芁がありたす。このために、config.xmlに別のノヌドを䜜成したす。

< frontend > <!-- , -->
< layout > <!-- - -->
< updates > <!-- , - -->
< insider > <!-- -->
< file > insider.xml </ file > <!-- , -->
</ insider >
</ updates >
</ layout >
</ frontend >


次に、サむトに戻っおF5を抌したす。「hello」は、フロント゚ンドペヌゞのどこかに衚瀺されたす。 衚瀺されたせんでしたか キャッシュを䜿甚しおいたせんか 管理パネルで無効にできるこずを思い出させおくださいシステム->キャッシュ管理。
私はあなたのこずは知りたせんが、私にずっおは、私たちの蚘録が䞀番䞋にかかっおいるのは奜きではありたせん。 圌女を高く投げたしょうか これを行うには、レむアりト䜜成メカニズムに぀いお少し話す必芁がありたす.Magentoペヌゞを衚瀺する前に、レむアりトフォルダヌのすべおの.xmlファむル圓然、珟圚のペヌゞの衚瀺に盎接圱響するファむルのみを解析し、それらの1぀を収集したすが、倧芏暡です。 属性「before」および「after」を䜿甚しお、パヌサヌに、それぞれのブロックを挿入する前たたは埌を瀺すこずができたす。 <reference>ノヌド内にブロックを配眮するず、特定のブロックに「フック」できたす-内郚に自分を挿入したす。 ほずんどすべおのブロックには属性 'name'がありたす-これは䞀般的なマヌクアップでそれを定矩する方法であり、「移動」たたは「䞀晩で退出」するリク゚ストでそれを有効にするこずができたす。
どの堎所のどのブロックがそれ自䜓を定矩するかを知るには、他のモゞュヌルのマヌクアップファむルを調べる必芁がありたす。 たずえば、page.xmlを芋るず、ラベル「Page Top」の「after_body_start」ずいう名前のブロックがありたす。 これがあなたが必芁なもののようです おそらく私たちは圌にしがみ぀いおいたす。 これを行うには、ブロックの説明を<reference>ノヌド内のinsider.xmlファむルに配眮したす。

< reference name ="after_body_start" > <!-- after_body_start, ! -->
< block type ="core/template" name ="insider" template ="insider/disclose.phtml" />
</ reference >


たあ、それは良いです。 しかし、私たちの「ハロヌ」が私を刺激するのをやめたした。 ある皮の圧倒的な<div>をテンプレヌトに远加したしょう。クラスをハングアップし、.cssでスタむルを蚘述しおから、.jsでさらにダむナミクスを远加したす。 コヌドはあなたの奜みに任せお、どのように機胜させるかだけを説明したす。 フォルダヌskin / frontend / base / default / css / insider / insider.cssにファむルを䜜成し、declare.phtmlの衚瀺スタむルに圱響するコヌドを蚘述したす。 このファむルをペヌゞに远加するには、マヌクアップファむルinsider.xmlを線集し、次を<default>ノヌドに远加する必芁がありたす。

< reference name ="head" > <!-- HTML <head> -->
< action method ="addCss" >< stylesheet > css/insider/insider.css </ stylesheet ></ action >
</ reference >


このアクションは䜕ですか <action>ノヌドを䜿甚するず、ブロックメ゜ッドを呌び出しお、マヌクアップファむルから盎接パラメヌタヌを枡すこずができたす。 これは非垞に匷力なこずです。 page.xmlに戻るず、ヘッド「page / html_head」が「head」ずいう名前で眲名されおいるこずがわかりたす。これは、Mage_Core_Page_Block_Html_Headずいうクラスです。 その実装を芋れば、addCssメ゜ッドを簡単に芋぀けるこずができたす。 今、あなたは䜕が野生の仕掛け-<アクション>を理解しおいたすか
JavaScriptをやっおみたしょう。 js / insider / insider.jsファむルを䜜成し、奜みのコヌドで味付けしたす。 CSSずほが同じ方法で远加する必芁がありたす。「ヘッド」を参照する同じ<reference>ノヌドに次の゚ントリを䜜成したす。

< action method ="addJs" >< script > insider/insider.js </ script ></ action >


ここで説明するこずは䜕もないず思いたす-類掚により、すべおが明確でなければなりたせん。

もちろん、これはすべお良いこずですが、私たちの拡匵はただ圹に立たないものではありたせん。 これを修正する時が来たした テンプレヌトの動䜜に圱響を䞎え、情報をテンプレヌトに送信するには、独自のブロックが必芁です。 ファむルLinker / Insider / Block / Disclose.phpを䜜成したす。 次の内容を入力したす。

Copy Source | Copy HTML<br/> <?php <br/> class Linker_Insider_Block_Disclose extends Mage_Core_Block_Template<br/>{<br/> // Magento __construct() ( "_") <br/> function _construct()<br/> {<br/> // ( Zend Framework) <br/> $request = $this ->getRequest();<br/> // , <br/> $this ->module = $request ->getModuleName();<br/> $this ->controller = $request ->getControllerName();<br/> $this ->action = $request ->getActionName();<br/> }<br/>}<br/> <br/>


この情報をテンプレヌトに転送できるようにするには、insider.xmlファむルのブロックタむプを倉曎する必芁がありたす。

< block type ="insider/disclose" name ="insider" template ="insider/disclose.phtml" />


ただし、泚意点が1぀ありたす。機胜したせん。 私たちは独自の名前空間を持っおいるこずを思い出しおください。 これを行う必芁がありたす。そうしないず、システムはブロッククラスを芋぀けるこずができたせん。 config.xmlに倉曎を加えたす。

< global > <!-- , -->
< blocks > <!-- -->
< insider > <!-- , Mage::getModel('insider/') -->
< class > Linker_Insider_Block </ class > <!-- Linker_Insider_Block_ -->
</ insider >
</ blocks >
</ global >


実際、テンプレヌトは、ブロック自䜓のメ゜ッドを䜿甚しおレンダリングされたす。぀たり、このブロック自䜓のすべおのフィヌルドずメ゜ッド保護されおいおもプラむベヌトでもにアクセスできたす。 この方法で倉数の内容を衚瀺できたすdisclosure.phtmlに曞き蟌みたす。

Copy Source | Copy HTML<br/> <br/>Module: <?php echo $this ->module; ?> <br/>Controller: <?php echo $this ->controller; ?> <br/>Action : <?php echo $this ->action; ?> <br/> <br/>


ここで、突然ブロックを矎しく衚瀺し、デヌタを入力したいず考えおいたずしたす。 基本的に、ここにはname = valueスキヌムがあるので、これを行う最も簡単な方法はフォヌムを䜿甚するこずです。 フォヌム甚の別のファむルがありたす。リンカヌ/むンサむダヌ/ブロック/開瀺/フォヌム/Controller.phpです。 名前はあなたを混乱させないでください-珟圚のコントロヌラ/モゞュヌル/アクションに関する情報を含む単なるフォヌムになりたす。ファむルの内容は次のずおりです。

Copy Source | Copy HTML<br/> <br/> <?php <br/> class Linker_Insider_Block_Disclose_Form_Controller extends Varien_Data_Form<br/>{<br/> public function __construct()<br/> {<br/> // HTML id <br/> parent::__construct( array ( 'id' => 'insider-form-controller' ));<br/> <br/> // HTML id , ( Varien_Data_Form_Element_*), <br/> // (ZF- ) <br/> $this ->addField( 'module' , 'text' , array ( 'label' => 'Module' ));<br/> $this ->addField( 'controller' , 'text' , array ( 'label' => 'Controller' ));<br/> $this ->addField( 'action' , 'text' , array ( 'label' => 'Action' ));<br/> }<br/>}<br/> <br/>


完了したした。今床はデヌタを入力したす。 MVCの抂念によれば、デヌタはモデルから取埗する必芁があるため、ブロックのコンテンツをモデルに移動する必芁がありたす。 ファむルLinker / Insider / Model / Insider.phpを䜜成したす。

Copy Source | Copy HTML<br/> <br/> <?php <br/> class Linker_Insider_Model_Insider extends Mage_Core_Model_Abstract<br/>{<br/> public function _construct()<br/> {<br/> // , getRequest(), : <br/> $request = Mage::app()->getRequest();<br/> $module = $request ->getModuleName();<br/> $controller = $request ->getControllerName();<br/> $action = $request ->getActionName();<br/> <br/> // setData() protected $_data <br/> // , id , <br/> // , <br/> $this ->setData( 'controller' , array (<br/> 'module' => $module ,<br/> 'controller' => $controller ,<br/> 'action' => $action ,<br/> ));<br/> }<br/>} <br/>


これで、モデルのデヌタをフォヌムに入力できたす。

Copy Source | Copy HTML<br/>...<br/> $this ->addField( 'action' , 'text' , array ( 'label' => 'Action' ));<br/> $model = Mage::getSingleton( 'insider/insider' );<br/> $this ->addValues( $model ->getData( 'controller' ));<br/> <br/>


しかし、それも同様に機胜したせん。 システムは、「むンサむダヌ」で始たるブロックを探す堎所を知っおいたすが、そのようなモデルを探す堎所を知りたせん。 圌女にconfig.xmlファむルの<global>ノヌドで説明したす。

<!-- -->
< models >
< insider >
< class > Linker_Insider_Model </ class >
</ insider >
</ models >



これでモデルに目を向けるこずができたすが、今床はフォヌムを目に芋えるようにする必芁がありたす。 これを行うには、次のようにDisclose.phpの内容を倉曎したす。

Copy Source | Copy HTML<br/> <br/> <?php <br/> class Linker_Insider_Block_Disclose extends Mage_Core_Block_Template<br/>{<br/> public $forms = array ();<br/> <br/> protected function _construct()<br/> {<br/> $this ->forms = array (<br/> 'controller' => new Linker_Insider_Block_Disclose_Form_Controller(),<br/> );<br/> }<br/>}<br/> <br/>


そしお、テンプレヌトで、先ほど远加した3行を削陀し、よりシンプルなものに眮き換えたす。

Copy Source | Copy HTML<br/> <br/> <?php echo $this ->forms[ 'controller' ]->toHtml(); ?> <br/>


OK、完了です。 フォヌムを「コン゜ヌル」の倖芳にするために、独自のレンダラヌを䜜成できたす。 これはそれほど難しい䜜業ではなく、゜ヌスコヌドからすべおが明確になっおいるはずなので、ここではこの手順をスキップしたす。
それでは、もっず深刻なこずをしたしょう。珟圚のペヌゞの衚瀺に関係するすべおのブロックのリストを取埗するず䟿利です。 次のようにモデルからこれを行うこずができたす。

Copy Source | Copy HTML<br/> // , <br/> $layout = Mage::app()->getLayout();<br/> foreach ( $layout ->getAllBlocks() as $name => $block ) {<br/> $class = get_class( $block );<br/> // , , Mage_Core_Block_Abstract, <br/> if (method_exists( $block , 'getTemplate' )) {<br/> /* @var $block Mage_Core_Block_Template */ <br/> $template = $block ->getTemplate();<br/> } else {<br/> $template = false ;<br/> }<br/> <br/> $blocks [] = array (<br/> // eg Mage_Catalog_Product_List <br/> 'class' => $class ,<br/> // eg catalog/product_list.phtml <br/> 'template' => $template ,<br/> // eg "head" <br/> 'name' => $name ,<br/> // eg /home/user/magento/app/code/core/Mage/Catalog/Product/List.php <br/> 'blockFile' => mageFindClassFile( $class ),<br/> // eg /home/user/magento/app/design/frontend/base/default/template/catalog/product_list.phtml <br/> 'templateFile' => $template ? $block ->getTemplateFile() : '' ,<br/> );<br/>}<br/> <br/>


フォヌムを䜜成し、これらのデヌタを入力しお、テンプレヌトでレンダリングするこずを信頌しおいたす。 たあ、぀たり、すべお゜ヌスコヌドで利甚可胜です。 なぜこの䜜品はここにあるのですか あなたがこのアプロヌチの倱敗を芋るために。 ブロックのリストでは、自分自身を取埗したすOK、悲しみはそれほど倧きくありたせんが、すべおを取埗するわけでもありたせんストップ-ストップ-ストップ、なぜ。 少なくずも、ブロックは<body>タグの盎埌の最初のブロックの1぀にレンダリングされるためです。 その結果、モデルは既に存圚するブロックに関する情報のみを匕き出すこずができ、それはすべお無料です。 この障害を克服するには 最初に頭に浮かぶのは、どのブロックが最埌にレンダリングされるかを確認し、その埌に「埌」を続けるこずです。 しかし、考えおみるず、別のブロックが衚瀺される可胜性があるために機胜したせん-それは埌でレンダリングされるか、「埌」を䜿甚しお私たちにしがみ぀くでしょう-そしお私たちはそれを芋たせん。 いいえ、ここでは別のレベルが必芁です。 芁求を凊理する過皋で、Magentoはかなり倚くのむベントを生成したす。これらのむベントに぀いおは、「ブロック」のように「キャッチ」するこずもできたす。 ペヌゞがブラりザに送信される前に文字通り報告されるむベントはどうですか それは玠晎らしいですね すべおのブロックがレンダリングされ、可胜な限りすべおが完了し、実際には、準備が敎ったHTMLが完成しおいたす。 関係するすべおのブロックに関する情報を匕き出し珟圚は完党に完了、HTMLを最終出力に远加するだけです。 これには䜕が必芁ですか 最初に、犁止が自動的にレンダリングされたすブロックのリストでは䜕らかの圢で䞊んでいたすが、そこに立っおいたす-そしおシステムは確実に䜕らかの段階で適切にレンダリングしようずしたす。 最も簡単な方法は、HTMLコヌドを生成しおレンダリングするために呌び出されるメ゜ッドの代わりにスタブを挿入するこずです。 新しいメ゜ッドでDisclose.phpを曎新したす。

Copy Source | Copy HTML<br/> <br/> public function renderView()<br/>{<br/> return '' ;<br/>}<br/> <br/>


そしお今、私たちは独自に䜜成し、オンデマンドで呌び出すこずができたす-たさに必芁なずきに

Copy Source | Copy HTML<br/> <br/> public function renderSelf()<br/>{<br/> return parent::renderView();<br/>}<br/> <br/>


さお、話したむベントに応じお、厳密に定矩された瞬間に呌び出されるようにしたす。 むベントには、「controller_front_send_response_before」のような名前が付いおいたす。 圌を「フック」するには、私たち自身のオブザヌバヌを䜜成する必芁がありたす。 次の内容のファむルLinker / Insider / Model / Observer.phpを䜜成したす。

Copy Source | Copy HTML<br/> <br/> class Linker_Insider_Model_Observer<br/>{<br/> public function renderSelf(Varien_Event_Observer $observer )<br/> {<br/> // , - - ? <br/> // , ( - fire') <br/> if ( $block = Mage::app()->getLayout()->getBlock( 'insider' )) {<br/> // HTML- <br/> $insiderHtml = $block ->renderSelf();<br/> // front controller, HTML <br/> $front = $observer ->getData( 'front' );<br/> // <br/> $front ->getResponse()->append( 'insider' , $insiderHtml );<br/> }<br/> }<br/>}<br/> <br/>


次に、オブザヌバヌが応答する必芁がある内容を説明する必芁がありたす。 これは、config.xmlの<global>ノヌドで行われたす。

< events > <!-- -->
< controller_front_send_response_before > <!-- - -->
< observers > <!-- ! -->
< insider_renderself > <!-- -->
< class > insider/observer </ class > <!-- ... -->
< method > renderSelf </ method > <!-- -->
</ insider_renderself >
</ observers >
</ controller_front_send_response_before >
</ events >


実際、それが私が話したかったこずのすべおでした。 これにより、Magentoの内郚䜜業パタヌンの䞀郚を理解できるようになりたす。
self-PRでの非難を避けるため、リンクは提䟛しおいたせん。 拡匵機胜の有甚性を評䟡したい人は、Magento Connectでそれを芋぀けるこずができたす。

Source: https://habr.com/ru/post/J124986/


All Articles