カスタム拡張機能の書き方


143

最近、無料の商用拡張機能で多くの問題が発生したため、この質問をして、拡張機能を作成するときに通常実行する手順で回答することにしました。回答を編集するか、新しい回答を追加してください。
拡張機能またはテーマをインストールするほとんどの場合、必要なすべての環境で機能させるために数時間(場合によってはそれ以上、場合によってはそれ以下)を費やす必要があります。

  • dev:通常localhost、プロジェクトはサブフォルダーにあります
  • preprod&live

これは大きくても、拡張プロバイダからの拡張機能(それは私が本当に怒る少なくともまでは無名のまま、ここに自分の名前を追加する必要があります)で起こっている
ので、品質を確保するための拡張を書くとき、私は検討すべき段階is..what主な質問技術および非技術者がコードを使用し、技術者がコードを変更するのを容易にしますか?


11
大規模な拡張プロバイダの1つがこの質問を好まなかったため、それを却下したようです。:)
マリウス

1
個人的には、ワイオマインドには絶対に問題はありませんが、彼らはコードを暗号化し、「プレミアムパートナー」のままです:((たとえば)
-sv3n

回答:


186

ここに私が通常やることがあります:

  1. 常にerror_reportingonで開発します。
  2. 常ににisDeveloperMode設定して開発しtrueます。ファイル(またはNginxまたはその他の対応するファイル)に追加SetEnv MAGE_IS_DEVELOPER_MODE 1するだけhttpd.confです
  3. 拡張機能がコア機能にリンクされている場合、宣言ファイルに依存関係を追加します <depends><Mage_Catalog /></depend>
  4. モジュールがコミュニティで使用さcommunityれる場合は、コードプールとして使用して、開発者がコードを直接変更せずに一部のクラスをオーバーライドできるようにします
  5. フロントエンドデザインファイルを入れてapp/design/frontend/base/default 、すべてのテーマで使用できるようにします。
  6. 管理者デザインファイルを配置し app/design/adminhtml/default/default、管理者テーマを変更しないでください。モジュールの1つで変更したい場合があります。
  7. レイアウトファイル名とテンプレートフォルダー名の前に会社名を付けて、簡単に分離できるようにします。 easylife_articles.xmlそしてapp/design/.../easylife_articles
  8. 静的リソース(JavaScript、CSS、および画像)をテンプレートファイルと同様のフォルダーに配置します easylife_articles/images/doh.png
  9. 拡張機能をアンインストールする方法が記載された簡単なテキストファイルを添付します。どのファイルを削除する必要があるか、どのテーブルを削除する必要があるか、どの構成設定をcore_config_dataテーブルから削除する必要があるか。
  10. モデル、ブロック、またはヘルパーにクエリを直接記述しないでください。そのためにリソースモデルを使用してください。
  11. テーブル名を直接使用してクエリを記述しないでくださいSelect * from sales_flat_order where ...。を使用し、Zend_Selectを使用してテーブル名を変換します->getTable('sales/order')
  12. ベースURLを使用して、jsファイルをテンプレートに含めます。間違ってい <script type="text/javascript" src="../js/some.js"></script>ます。 <script type="text/javascript" src="<?php echo Mage::getBaseUrl('js').'some.js'?>"></script>
  13. 必要でない限り、クラスを書き換えないでください。オブザーバーを使用し、オーバーライドするクラスのパラメーターおよびインスタンスとして受け取るヘルパーメソッドを使用できない場合。誤りMage_Catalog_Model_Productメソッドを追加するためにオーバーライドし getProductArticles()ます。そうです。ヘルパーに追加します getProductArticles(Mage_Catalog_Model_Product $product)
  14. クラスをオーバーライドする場合、それらのリストをreadme.txtファイルに入れます
  15. モジュールの管理セクションにデフォルトの管理パスを使用します。 間違った管理URL articles/adminhtml_articles/index正しい管理URL admin/articles/index
  16. 管理セクションのACLを追加します。一部の管理者へのアクセスを制限したい場合があります。
  17. 必要でない場合は、別のJavaScriptフレームワーク(jQuery、MooToolsなど)を追加しないでください。プロトタイプでコードを書いてください。
  18. HTML W3Cのテンプレートを有効にします(これは私のようなOCD開発者向けです)。
  19. 画像をmediaフォルダに入れないでください。を使用しskinます。media フォルダは通常バージョン管理されていない、これはそれが難しい異なる環境へのウェブサイトを移動することができます。
  20. フラットカタログをオンまたはオフにして拡張機能をテストします。開発時間を2倍にしないために、Chaos Monkeyを使用します。
  21. cache onとcache を使用して拡張機能をテストしますoff
  22. モジュール名とクラス名に大文字を使用しないでください。適切にテストされない場合、これは異なるOSで問題を引き起こす可能性があります。これは、「推奨」ではなく「推奨」です。
  23. コード内のイベントをディスパッチして、開発者が機能を簡単に変更できるようにします。
  24. Magentoが使用するのと同じコーディング標準に従い、コードにコメントを付けます。
  25. PHPの短いタグ(<? $this->doSomething() ?>)を使用しないでください。完全なタグを使用します(<?php $this->doSomething()?>)。また、短いエコータグはまだ使用しないでください。(<?="D'oh";?>)。使用(<?php echo "D'oh";?>
  26. 少なくとも言語について$this->__は、テキスト(app/local/en_US/Easylife_Articles.csv)を使用してロケール翻訳ファイルを使用してテキストを翻訳し、追加しますen_US。すべてのウェブサイトが英語で構築されているわけではなく、翻訳するテキストの識別に時間がかかります。
  27. 拡張機能を販売する場合は、少なくとも基本的なサポートを提供してください。または、受け取ったサポートメールに少なくとも答えてください。
  28. ライセンスの検証のために、拡張機能を介してサーバーを常に呼び出してはいけません。一度、インストール時に十分です(私はこのアプローチも好きではありませんが、常に電話をかけるよりも良いです)。(この質問に触発さ)
  29. ログをアクティブにして開発し、時々var/log/system.logファイルを見てください。ここにリストされているエラーは、開発者モードがオンの場合でも表示されません。少なくとも1つのエラーがある場合、拡張機能を実行してから数か月後に大きなログファイルが作成されます。
  30. 拡張機能がチェックアウトプロセスまたは注文に何らかの影響を与える場合は、複数発送で機能することを確認します。複数発送で機能しない場合は、影響を与えないことを確認します。
  31. デフォルトの管理通知バー(またはフィードURL)を置き換えないでください。あなたが提供しなければならないことに興味があるなら、私はあなたのニュースレターを購読します。Magentoの発言内容を見てみましょう。それは私にとってより重要です。
  32. Ioncube(または他の何か)を使用してコードファイルを暗号化する場合...まあ...私はあなたを憎み、あなたのビジネスが破産することを願っています

それはこれまでのところです。何か他のことを考えたらすぐに追加します。


私はあなたに同意します、それは間違いなく良いスタートです。確かに、すべての異なる種類の構成と問題を常にカバーできるとは限らないことも理解できます。少なくとも可能なものは減ります。私が他の拡張機能で遭遇する問題や私の人々で遭遇する問題のほとんどは、上書きとの競合によるものです。
シルヴァンレイエ

2
@ Marius、sure 1+ from me.itは、開発で直面しているほとんどのケースとシナリオをカバーしています。
リヤカット

4
@colinm まず第一に、ここにあなたのコメントがあることは名誉です。:)。違いがあることに同意し、答えを修正しますが、少なくともPHP 5.3が「新しいPHP 4」になるまで、両方とも避けるべきだと思います。まだ大規模に使用されているということです。
マリウス

4
@マリウス、あなたのポイントは非常に役立ちます。#31まで、私は真剣に各ポイントに焦点を合わせていましたが、#32では大笑いをしました。ポイント#32
MTM 14

1
If you encrypt your code files with Ioncube (or something else)...well...I just hate you and I hope your business goes bankrupt同じように感じます。更新されたバージョンを提供しない会社もありますが、そのためにお金を払わなければなりません。それは私にとって本当にイライラし、なぜ同じ製品を何度も何度も販売したいのか理解できません。私は彼らの製品をもう買わない。あなたは私が誰について話しているか知っています。
アダルシュカトリ

31

私はmodmanを使用することの大ファンであるため、拡張機能だけを開発およびソース管理でき、コアファイルとフォルダー構造は変更されません。また、異なるインストール間でのテストの実行がスムーズになります。

ああ、一つの大きなヒントは、Magento Connectにアップロードする前に、パッケージ化された拡張機能をmagentoのクリーンインストールに常にローカルにインストールしようとすることです。パッケージマネージャーで何度もファイルを見逃しています。


3
「パッケージ化された拡張機能をローカルにインストールする」ことをお勧めします。これは次のカテゴリに分類されると思います:「上から下まで、拡張機能をテストしてください」。
マリウス

私もこれに気付いたことがあります。パッケージをパッケージ化したものとは異なるクリーンインストールでテストしてください。
ジョセフリーディ

22

Andreas von StudnitzとDr. Nikolai Krambrockは、Meet Magento DE 2014でコード品質に関する優れたプレゼンテーションを行いました。彼らは一般的なコード品質とMagento固有のコード品質を区別します。つまり、次の一般的なルールがあります。

  • 構造要素の使用は、クラスやメソッドと同様に、中間クラスに配置する必要があります。構造のこれらの要素は、構造化に使用される場合にのみ意味をなします。したがって、それらは中規模である必要があります。クラスには100〜200行のコードを使用し、メソッドには3〜20行のコードを使用すると見なされます。
  • 「if」または「while」を使用しているため、コードはインデントされます。インデントが3つ以上ある場合は、修正することをお勧めします。インデントが多すぎると、コードの複雑さの証拠となるため、避ける必要があります。
  • デッドコードは避けて削除する必要があります。静的分析は、存在する場合にそれを見つけるのに役立ちます。

さらに重要なのは、Magento固有のルールです。

  • モジュールは独立して動作するはずです。他のモジュールにはほとんど依存せず、テンプレートには依存しないようにします。解決策は、テンプレートファイルおよびテンプレートの追加機能をカバーするモジュールに適応する代わりに、レイアウト更新(ベース/デフォルト)を使用することです。
  • Magentoのコアハックおよび外部モジュールのハックで更新機能を維持するには、回避する必要があります。より良い方法は、代わりにリライタまたはオブザーバを使用することです。
  • 変更については、データベースまたは管理者を直接変更するのではなく、セットアップスクリプトを使用することをお勧めします。それらのおかげで、変更は一度だけ行う必要があります。

プレゼンテーションの詳細とビデオを次に示します。http//www.code4business.de/code-quality-magento/


1
しかし、あなたが投稿したリンクの英語版があればもっといいでしょう。
マリウス

このプレゼンテーションの英語版はまもなく作成されます。私はあなたを最新の状態に保ち、英語版が公開され次第、新しいリンクを共有します。
user3743859 14

プレゼンテーションの英語版は現在オンラインです。リンクは次のとおり
quality

え?まだドイツ語です。しかし、たった2週間前にMeetMagentRoで英語でこのプレゼンテーションに出席したところです。素晴らしいもの。
マリウス

18

拡張機能を販売したり、他のユーザーと共有したりする場合は、人間が読めるコードを書くことを検討してください。

  1. メソッドを複雑にしすぎないでください
  2. メソッドにDOCブロックを追加します*
  3. 以下のような適切な変数名、使用$productIdsの代わりに$ids
  4. メソッドについても同じで、public function myOnProductSaveMethod() {...}...何も言わないがtryDisableInternetOnProductSave()、ヒントが必要だというヒントを与える
  5. 意味のある場所でタイプヒントを使用する someMethod(Varien_Data_Db_Collection $collection)
  6. 魔法の数字と文字列を避ける**
  7. モデルセット$_eventPrefixプロパティ(および$_eventObject)を使用して、オブザーバーによりアクセスしやすくする場合
  8. システム構成フィールドを追加する場合
    • デフォルト値を設定する config.xml
    • <validate>ノードをフィールドに追加しますsystem.xml
    • ACLリソースを追加する adminhtml.xml
  9. 管理バックエンドに不要な/広告の第1レベルメニューエントリを追加しないでください-トップバーにも設定セクションにも
  10. すべてのコントローラーアクションにACLリソースを追加します(マスアクションも!)
  11. クエリがDB テーブルプレフィックスで機能することを確認します
  12. 下位互換性について考えます(これは本当に意見に基づいています)
    • Mysql4クラスをサポートしていません
    • 非推奨のメソッドを使用しないでください
  13. すべてのケースで期待通りに機能することを確認してください-UnitTests(PhpUnitなど)を追加してください
  14. David Mannersに加えて...を追加composer.jsonして展開を容易にします
  15. PHP5.6はEOLなので、PHP7のコードを記述します。declare(strict_types=1);入力タイプと出力タイプを使用および定義する
  16. Magento2:のようなツールを分析静的コードを使用してコードをチェックphpstanをここで魔法のメソッドのサポート。(最新のコミットは2.3で機能しますが、2.1 / 2.2以前は-phpstan 0.8.5が必要です)

* DOCブロック:

PSR2標準またはPHPMDの PHP_CodeSnifferでMagento-1コードを確認する場合、この行を追加することをお勧めします(意味がある場合)...

  • クラスへ
    • @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
    • @phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore -継承されたプロパティ
    • @phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
    • @SuppressWarnings(PHPMD.CamelCaseClassName)
    • @SuppressWarnings(PHPMD.CamelCasePropertyName) -継承されたプロパティ
  • メソッドへ
    • @SuppressWarnings(PHPMD.CamelCaseMethodName) -継承されたメソッド
    • @SuppressWarnings(PHPMD.StaticAccess)- Mage::または他の静的呼び出しを使用する場合

** 頻繁に使用されます:

  • 管理ストアID
    • 0 > Mage_Core_Model_App::ADMIN_STORE_ID
  • 製品 status
    • 1 > Mage_Catalog_Model_Product_Status::STATUS_ENABLED
    • 2> Mage_Catalog_Model_Product_Status::STATUS_DISABLED 0予想どおりではない)
  • 製品 type
    • simple > Mage_Catalog_Model_Product_Type::TYPE_SIMPLE
    • bundle > Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
    • configurable > Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE
    • grouped > Mage_Catalog_Model_Product_Type::TYPE_GROUPED
    • virtual > Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL
  • 製品 visibity
    • 1 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE
    • 2 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
    • 3 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH
    • 4 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH

SQLの順に同じASCZend_Db_Select::SQL_ASC (例えば)

言って、「それは今までに変更されることはありません原因それはnessessaryではありませんか」?たとえばcatalog_product、Magento 1.5と1.9の間のどこかで属性のエンティティIDがからに変更された10ため4、これにより拡張機能が破損する可能性があります。

$collection->addFieldToFilter('entity_type_id', 10)

代わりにこれを使用すると、クエリが1つ追加されますが、安全になります...

$entityTypeId = Mage::getModel('eav/config')
    ->getEntityType(Mage_Catalog_Model_Product::ENTITY)
    ->getEntityTypeId();

$collection->addFieldToFilter('entity_type_id', $entityTypeId)

8

@marius、コーディング標準に関して(リストのポイント24)。

これらの標準を自動的に施行するために、EQP およびECG CS とともにPHP_CodeSnifferを使用するのが好きです。

PHP_CodeSnifferを使用するarray()[]、withのようなものを忘れる心配をする必要はありませんis_null

PHP_CodeSnifferは常にそれについて通知します。


同意した!可能なハウツー:magento.stackexchange.com/questions/178640/…– sv3n
21:37

PHPStormで両方のCSを構成する方法はないと思います(PHPStormを使用する人向け)が、コードのCSをチェックするために端末をいつでも使用できます。また、少し役立つgrumphp github.com/phpro/grumphpなどのツールもあります。
ディアズワトソン

それはあなたが助けとなるかもしれないmagento.stackexchange.com/questions/200022/...
PramodさんKharade
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.