コアファイルをオーバーライドする

コアをハックしない

「コアをハックするな」とは、オープンソースコミュニティでよく耳にするフレーズです。

コアをハックする、とは?

一般的に、「コア」とは、CMSを構成する基本ファイル一式のことを指します。あなたがconcrete5をダウンロードした時、つまりそれがコアファイルです。

なぜコアファイルを変更してはいけないのですか?

concrete5を自由にカスタマイズしたいなら、コアファイルを変更することが最も簡単な方法ですが、その誘惑に負けてはいけません。なぜなら、

  • concrete5のアップデートができなくなります。
  • そのことで、セキュリティ脆弱性を残すことになります。
  • サイトのメンテナンスが難しくなります。
  • プログラマがあなたを嫌いになります。

もしコアを変更することでしか実現できない機能があれば、パッチを提供することを検討してください。GitHubでissueを作成し、コミュニティにあなたが何をしたいのか知らせてください。その後テストされ、あなたの開発した機能がconcrete5の一部になることもあるでしょう。

複雑なconcrete5サイトを構築したい時、コアの機能を変更したいニーズが発生することがあります。最新バージョンのconcrete5は、アップデート性とパフォーマンスを維持したまま、コアの機能を変更する方法がいくつか用意されています。

サービスプロバイダーオーバーライド

concrete5のコア機能のほとんどは「サービス」と呼ぶものとして登録されており、それらのサービスは /concrete/src/ ディレクトリ内のサブディレクトリで見つけることができます。
これらのサービスを登録するために、concrete5は「サービスプロバイダー」として知られるデザインパターンを使用します。サービスプロバイダーは、サービスの起動を管理し、我々のアプリケーションインスタンスに登録します。サービスの機能を変更したい場合は、ここがスタート地点になります。

例えば、コアのロガーをカスタマイズしたものに差し替えたい場合はどうすれば良いでしょうか。

  1. コアの app config グループを開きます。場所は /concrete/config/app.php にあります。
  2. "LoggingServiceProvider" が登録されている場所を探し、コンフィグキーを調べます。この場合は、 app.providers.core_logging になります。
  3. アプリケーションの app config グループを開きます。場所は /application/config/app.php にあります。
  4. app.providers.core_logging をカスタムクラスに変更します。

/application/config/app.php

<?php

return array(
    'providers' => array(
        'core_logging' => '\Application\Src\Custom\CustomLoggingServiceProvider'
    )
);

この設定で、コアのロギングサービスプロバイダーを独自のものに変更することができました。ただし、この CustomLoggingServiceProvider クラスはまだ存在しないので、作成する必要があります。

/application/src/Custom/CustomLoggingServiceProvider

<?php
namespace Application\Src\Custom;

class CustomLoggingServiceProvider extends \Concrete\Core\Service\Provider
{

    public function register()
    {
        $my_psr3_logger = new \Some\Custom\Logger();

        $this->app->bind('log', $my_psr3_logger);

        // Set the rest of the bindings that the core sets
        $this->app->bind('Concrete\Core\Logging\Logger', 'log');
        $this->app->bind('Psr\Log\LoggerInterface', 'log');
    }

}

これでコアのロギングサービスプロバイダーの代わりに、独自のロギングサービスプロバイダーを登録でき、カスタムロガーがコアのロガーの代わりに使われるようになります!

パスベースのオーバーライド

concrete5内の多くのファイルは、シンプルにファイルを特定のパスに設置するだけでオーバーライドできます。唯一の例外は、concrete/src/ ディレクトリ内のファイルになります。今日、サービス以外のすべては基本的にパスでオーバーライドできます。

基本的にすべてのパスオーバーライドは、次のシンプルなパターンに従います。すなわち、concrete ディレクトリ内のオーバーライドしたいファイルを探し、application ディレクトリ内に同じパスでファイルを作成します。

例:

コア: /concrete/blocks/some_block/view.php
オーバーライド: /application/blocks/some_block/view.php

コア: /concrete/js/some_js_file.js
オーバーライド: /application/js/some_js_file.js

コアブロックタイプをオーバーライド

concrete5 は多くの便利なブロックタイプを持っていますが、コアブロックの機能を微調整したい場合もあるでしょう。コアブロックをオーバーライドするには、次の方法があります。

  • 機能と表示をオーバーライドする
  • カスタムテンプレートを追加する

機能と表示をオーバーライドする

アクションを追加したり、どのようにデータが保存されるかを変更したり、データを差し替えたりといったことが、ブロックコントローラーをオーバーライドすることで可能になります。

例えば、記事ブロックですべてのテキストをキャピタライズ(先頭の小文字を大文字にすること)したい場合:

/application/blocks/content/controller.php

<?php
namespace Application\Block\Content;

class Controller extends \Concrete\Block\Content\Controller
{
    public function view()
    {
        $this->set('content', strtoupper($this->getContent()));
    }
}

オーバーライドで可能なことはこれだけではありません。/concrete/blocks/content/ ディレクトリ内の他のファイルも同様に、/application/blocks/content/ ディレクトリにファイルを作成することでオーバーライドできるのです!

カスタムテンプレートの追加

カスタムテンプレートは、ブロックに対してオプションで別の表示を選ばせることができる機能です。

例えば、HTMLブロックの内容を code タグで表示したい場合は、

/application/blocks/html/templates/code_block/view.php

<pre><code><?= h(trim($content)) ?>code>pre>

カスタムテンプレートを使えば、コントローラーを差し替えることなく、ビューファイル、Javascript、CSSを差し替えることができます。

パスベースオーバーライドの例

  • テーマ
    • コアパス: /concrete/themes/theme_handle/page_theme.php
    • パッケージパス: /concrete/packages/package_handle/themes/theme_handle/page_theme.php
    • オーバーライドパス: /application/themes/theme_handle/page_theme.php
    • オーバーライドクラス名: \Application\Theme\ThemeHandle\PageTheme
  • ブロック
    • コアパス: /concrete/blocks/block_handle/controller.php
    • パッケージパス: /concrete/packages/package_handle/blocks/block_handle/controller.php
    • オーバーライドパス: /application/blocks/block_handle/controller.php
    • オーバーライドクラス名: \Application\Block\BlockHandle\Controller
  • 属性
    • コアパス: /concrete/attributes/attribute_handle/controller.php
    • パッケージパス:/concrete/packages/package_handle/attributes/attribute_handle/controller.php
    • オーバーライドパス: /application/attributes/attribute_handle/controller.php
    • オーバーライドクラス名: \Application\Attribute\AttributeHandle\Controller
  • 属性タイプ
    • コアパス: /concrete/authentication/type_handle/controller.php
    • パッケージパス: /concrete/packages/package_handle/authentication/type_handle/controller.php
    • オーバーライドパス: /application/authentication/type_handle/controller.php
    • オーバーライドクラス名: \Application\Authentication\TypeHandle\Controller
  • コントローラー
    • コアパス: /concrete/controllers/single_page/page_name.php
    • パッケージパス: /concrete/packages/package_handle/controllers/single_page/page_name.php
    • オーバーライドパス: /application/controllers/single_page/page_name.php
    • オーバーライドクラス名: \Application\Controller\SinglePage\PageName
  • シングルページ
    • コアパス: /concrete/single_pages/account/avatar.php
    • オーバーライドパス: /application/elements/account/avatar.php
  • エレメント
    • コアパス: /concrete/elements/account/menu.php
    • オーバーライドパス: /application/elements/account/menu.php
  • コンパイル済みCSS
    • コアパス: /concrete/css/image-editor.css
    • オーバーライドパス: /application/css/image-editor.css
  • コンパイル済みJS
    • コアパス: /concrete/js/jquery.js
    • オーバーライドパス: /application/js/jquery.js

原文:Be Responsible. Never Hack the Core.Override (almost) any core file in 5.7