# はじめに

本ドキュメントは、CS-Cartの構造を理解し、カスタマイズの方法であるアドオンの構造などについて解説しています。

CS-Cartはモジュラアーキテクチャ(組み合わせ型アーキテクチャ)の概念に従っています。 基本的な機能を司っているコア部分と、それを拡張する多数のアドオンがあります。

{% hint style="danger" %}
重要

コア関数やコントローラー、テンプレート、およびスキーマーは直接編集しないことを強くお勧めします。デフォルトの動作を拡張するにはアドオンを使用してください。
{% endhint %}

### MVCについて

#### [MVC: MODEL](https://ja.wikipedia.org/wiki/Model_View_Controller)

すべてのデータはデータベースに直接保存されています。 CS-Cartで使用されるデータベースエンジンはMySQLであるためプログラムのコンポーネントはプレースホルダを用いてMySQLからSQLクエリを通してデータを取得します。

CS-Cartの組み込み関数でデータベースに接続する例

```php
<?php
$data = array (
    'payment_id' => 5
);
 
$order_id = 3;
 
db_query('UPDATE ?:orders SET ?u WHERE order_id = ?i', $data, $order_id);// Some code
```

#### MVC: VIEW

CS-Cartはデータを表示する際、[Smarty](http://www.smarty.net/docs/ja/)テンプレートエンジンとJavascriptを使用しています。

Javascriptコードが埋め込まれたSmartyテンプレートの例:

{% code title="" %}

```smarty
{** block-description:my_twitter_addon **}
 
<script src="http://widgets.twimg.com/j/2/widget.js"></script>
<script>
new TWTR.Widget({ldelim}
    version: 2,
    type: 'profile',
    rpp: {$addons.my_twitter_addon.number_of_tweets},
    interval: 6000,
    width: 'auto',
    height: 300,
    theme: {ldelim}
        shell: {ldelim}
            background: '#FFFFFF',
            color: '#373737'
        {rdelim},
        tweets: {ldelim}
            background: '#D9EFF3',
            color: '#373737',
            links: '#005865'
        {rdelim}
    {rdelim},
    features: {ldelim}
        scrollbar: true,
        loop: true,
        live: true,
        hashtags: true,
        timestamp: true,
        avatars: true,
        behavior: 'default'
    {rdelim}
{rdelim}).render().setUser('{$addons.my_twitter_addon.username}').start();
</script>
```

{% endcode %}

#### MVC: CONTROLLER

コントローラーはPHPで書かれています。コアコントローラーは\`controllers\`ディレクトリにあります。\
アドオンは独自のコントローラーをそれぞれのディレクトリ内で定義することができます。-


# CS-Cart開発者向け注意事項

CS-Cartをカスタマイズする場合は下記のルールに従って進めてください。CS-Cartスタンダード版とCS-Cartマーケットプレイス版の使用やアップグレードが容易になります。

## コアファイルの変更は行わないでください

CS-Cartスタンダード版とCS-Cartマーケットプレイス版はソースコードが暗号化されていないオープンソースソフトウェアです。ですので、CS-Cartをダウンロードしてアーカイブを開くと、全てのファイルは暗号化されていません。デフォルトでCS-Cartスタンダード版またはCS-Cartマーケットプレイス版に含まれるすべてのファイルは、コアファイルと呼ばれます。ファイルを変更することで、システムをニーズに合わせて変更できますが、この方法は使わないでください。\
代わりに、CS-Cartは様々なカスタマイズ方法を提供しています。（例：アドオン）

{% hint style="success" %}
例外

コアファイルの変更については、いくつかの例外があります。たとえば、CS-Cartスタンダード版またはCS-cartマーケットプレイス版をインストールした直後は、セキュリティ上の理由からadmin.phpの名前を変更することをお勧めします。
{% endhint %}

## コアファイルを変更すべきでない理由

{% hint style="info" %}
アドバイス

コアファイルを変更すると、アドオンの互換性に問題が生じる可能性があります。他にも、アップグレード時に変更箇所が失われてバグを引き起こすなどの可能性もあります。変更箇所を元に戻すには、膨大なプロセスが必要となります。
{% endhint %}

変更したコアファイルをCS-Cartスタンダード版またはCS-Cartマーケットプレイス版の新しいバージョンにアップグレードする場合は、次の２点に注意してください。

* コアファイルは上書きされ、変更（カスタマイズ箇所）は失われます。
* いくつかのファイルはご自身が変更したものに変更されます。バグが発生する可能性がありますが、コアファイルの変更を元に戻すことで直せます。

アップグレードしなくても問題が発生する可能性があります。例として、コアファイルを変更してサードパーティのアドオンが適切に動作しない（デフォルトのCS-Cartスタンダード版では動作する）場合を仮定してみます。

通常、まず初めに他のアドオンを無効にして、それらが原因でないことを確認します。ただし、コアファイルを直接変更していた場合は、念のためにそれも元に戻してください。特にデフォルトコードの一部が削除または置換された場合、大変手間がかかります。

## コアファイルが変更されているかを確認するには

CS-Cartスタンダード版とCS-Cartマーケットプレイス版の4.4.1以降ではコアファイルの変更の有無を監視し、通知するFile Changes Detectorを導入しました。管理画面を開くと、コアファイルが変更されたかどうかを確認できます。

* 管理画面→ファイルの変更を検出。
* 変更されたコアファイルのスキャンをクリックします。

画像

下記は、管理画面にログインする度にコアファイルの変更の有無を自動的にチェックできるようにする設定の手順です。

* 基本設定→全般をクリック
* \[ コアファイルの変更を監視する]がオンになっていることを確認
* 右上の【保存】ボタンをクリック

これで、コアファイルがデフォルトと異なる場合には、管理画面を開くと次の通知が表示されるようになります。

{% hint style="warning" %}
注意

一部のコアファイルが変更されています。この変更は \[CS-Cart] のアップグレードの際に削除される可能性があります。
{% endhint %}

## CS-Cartのコアファイルを直接変更しないカスタマイズ方法

CS-Cartスタンダード版とCS-Cartマーケットプレイス版では、コアファイルを変更せずにカスタマイズする方法を提供しています。

* Hookを利用して、独自のアドオンを作成する。
* デフォルトのテーマを直接変更する代わりに、テーマを複製し、その複製を編集する。

## アドオンとHookを使用する

機能を追加または変更する必要がある場合は、別のアドオンとして作成します。独自のアドオンを作成する場合、Hookを使用して、コアファイルのコードを間接的に追加または変更できます。このアプローチの利点は次のとおりです。

* アドオンのすべてのファイルは、アドオン名のフォルダに個別に保存されます。個別ファイルのみを変更しているため、自身が行った変更を簡単に把握できます。
* アドオンを無効または有効にするだけで、変更を元に戻したり追加したりできます。これは、別のアドオンまたはアップグレードと変更が競合する可能性があると疑われる場合に役立ちます。

## 複製したテーマを編集してください

ストアのデザインを変更する場合でも、デフォルトの「レスポンシブテーマ」は変更せずに、代わりに、別のテーマを作成してください。最も簡単な方法は、現在のアクティブなテーマを複製することです。これは管理画面で直接行うことができます。

* \[ デザイン]→\[テーマ]に移動します。
* 右上隅の歯車ボタンをクリックします。
* 複製したテーマを選択します。

画像

CS-Cart 4.4.1以降、複製したテーマには`manifest.json`ファイル、ロゴ、およびデフォルトスタイルのみが含まれています。残りのデータはmanifest.jsonの中の parent\_theme：で指定されたテーマから自動的に反映されます。

* CSS、メディア、およびテンプレートのフォルダーは実行時、複製したテーマと親テーマに統合されます。
* 複製したテーマにないファイルは、親テーマから取得されます。
* 複製したテーマの専用ファイルは考慮されます。
* 両方のテーマにファイルが存在する場合、複製したテーマのファイルが優先されます。
* テーマのレイアウトとスタイルのフォルダーは併合されません。複製したテーマにレイアウトまたはスタイルがある場合は、それらが使用されます。それ以外の場合、レイアウトとスタイルは親テーマから継承されます。

変更を行う際は、対応するファイルを親テーマから複製したテーマにコピーし、そのファイルを編集してください。

画像


# CS-Cartの構成

CS-Cartの構成

## 開発用設定ファイル

CS-Cartでは、`config.local.php`を変更せずに開発用に個別の設定を行うことのできる開発用の設定ファイルを作成できます。このファイルは`local_conf.php`と呼ばれます。

{% hint style="success" %}
TIPS

`local_conf.php`で指定された設定は`config.local.php`よりも優先されます。
{% endhint %}

## 開発用の設定ファイルについては、以下の手順で行ってください。

* CS-Cartをインストールしたルートディレクトリに`local_conf.php`を作成します。
* `local_conf.php`を開き、次のコードを追加します。

```php
<?php

//ライブストアで作業する必要がある場合は、以下の設定を特定のIPのみに適用して、ショップのお客様が影響を受けないようにすることができます。127.0.0.1の代わりにIPアドレスを指定してください。
if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') {

    // 管理パネルおよびストアフロントのデバッグモードをオンにする
    // define('DEBUG_MODE', true);

    // 開発モードを使用してエラーを表示する
    define('DEVELOPMENT', true);

    // SMARTYおよびPHPエラーを表示
    error_reporting(E_ALL);
    ini_set('display_errors', 'on');
    ini_set('display_startup_errors', true);

    //  PHPブロックキャッシュを無効にする
    $config['tweaks']['disable_block_cache'] = true;

}

// config.local.phpを変更せずに構成を変更できます。

/*
$config['db_host'] = '%DB_HOST%';
$config['db_name'] = '%DB_NAME%';
$config['db_user'] = '%DB_USER%';
$config['db_password'] = '%DB_PASSWORD%';

$config['http_host'] = '%HTTP_HOST%';
$config['http_path'] = '%HOST_DIR%';

$config['https_host'] = '%HTTPS_HOST%';
$config['https_path'] = '%HOST_DIR%';
*/

// キャッシュとストレージのバックエンドも設定することができます

/*
// Cache backend
// 利用可能なキャッシュバックエンド: file, sqlite, database, redis, xcache, apc
// sqliteキャッシュを使用するには、「sqlite3」PHPモジュールをインストールする必要があります
// xcacheキャッシュを使用するには、「xcache」PHPモジュールをインストールしてください
// apcキャッシュを使用するには、「apc」PHPモジュールをインストールしてください
$config['cache_backend'] = 'file';
$config['cache_redis_server'] = 'localhost';
$config['cache_redis_global_ttl'] = 0; // キャッシュサイズがRedisサーバーのメモリサイズに達した場合、設定してください

// セッションのストレージバックエンド。利用可能なバックエンド： database, redis
$config['session_backend'] = 'database';
$config['session_redis_server'] = 'localhost';
$config['cache_apc_global_ttl'] = 0;
$config['cache_xcache_global_ttl'] = 0;
*/
```

## 設定の詳細

### IPアドレスの制限

`local_conf.php`で指定した設定を特定のIPアドレスのみに制限できます。ライブストアで作業する場合にこの設定をしておくと、エラーメッセージとデバッガが表示されるため便利です。IPアドレスの制限は、以下を参考にしてください。

```php
<?php
if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1'){

}
```

{% hint style="info" %}
HINT

ライブストア（公開されているストア）で作業している場合は、127.0.0.1をあなたの環境のIPアドレスに置き換えてください。ストアがまだ一般公開されていない場合は、この条件を使用しなくても問題ありません。
{% endhint %}

### デバッグモード

CS-Cartには、以下の値を確認できる組み込みデバッガーがあります。

* サーバーとPHPの設定
* 現在のページで実行されたSQLクエリーのリスト
* ページの構築に使用されているテンプレート
* リクエストパラメーター
* ページが表示される際に使用された時間とメモリーの量

デバッガーにアクセスするには、CS-Cartの管理パネルに移動し、URLに`debug`パラメーターを追加します。 <http://example.com/admin.php?debug>

Bug（虫）のアイコンは、ページの右上に表示されます。デバッガーはサイドバーをクリックして開閉することができます。または、`Ctrl + Alt + D`を押すことでも開閉が可能です。

{% hint style="info" %}
TIPS

`debug`パラメーターを使用すると、現在のブラウザーセッションのショップフロント（カスタマーエリア）でデバッガーが使用可能になります。
{% endhint %}

＜画像＞

ストアフロントと管理パネルの両方でデバッガーを常時有効にするには、`local_conf.php`の下記の箇所をコメントアウトします。

```php
<?php
define('DEBUG_MODE', true);
```

{% hint style="warning" %}
注意

一般のお客様がデバッグデータにアクセス可能になるため、ライブストアでは絶対に`define('DEBUG_MODE', true);`は使用しないでください。
{% endhint %}

### 開発モード

PHPコード、Smartyテンプレート、またはSQLクエリーにエラーがある場合、通常はSmartyおよびPHPのエラーが発生した場合は空白のページになります。

間違ったSQLクエリーが原因のデータベースエラーの場合は、次のメッセージが表示されます：\
`申し訳ございません。当ショップはメンテナンスのため一時クローズ中です。 再開まで今しばらくお待ちください。`

＜画像＞

実際のエラーメッセージを表示するには、`開発モード`を使用します。\
`local_conf.php`で下記の設定を使用することで有効化できます：

```php
<?php
define('DEVELOPMENT', true);
```

何か問題が発生した場合、エラーの原因となったファイルへのパスを含むエラーメッセージが表示されます。

＜画像＞

`開発モード`には、アドオン開発者にとって便利な機能がもう一つあります。

CS-Cartは、インストールされたアドオンの`CSS`および`TPL`ファイルを\_design/themes\_ディレクトリに保存します。通常、アドオンがアンインストールされると、CS-Cartはこれらのファイルを削除します。

また、アドオンが再度インストールされると、これらのファイルは`var/themes_repository`から取得されます。

よって開発中に\_design/themes\_ディレクトリでアドオンの`.css`ファイルと`.tpl`ファイルを変更し、管理パネルでそのアドオンをアンインストールすると、変更が失われてしまいます。

しかし、`開発モード`を有効にした場合は、アドオンをアンインストールしても、\_design/themes\_ディレクトリ内のアドオンのファイルは削除されません。

{% hint style="warning" %}
注意

もし`var/themes_repository`に`.css`や`.tpl`ファイルを含んだ状態でアドオンをインストールした場合は`design/themes`内のファイルは`var/themes_repository`の内容で上書されます。
{% endhint %}

### SmartyおよびPHPエラーの画面表示

エラーメッセージを表示するには、PHPやWebサーバーの設定を再定義する必要がある場合もあります。そのため次のコードを`local_conf.php`に追加します。

```php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'on');
ini_set('display_startup_errors', true);
```

### PHPブロックキャッシングを無効にする

CS-Cartのキャッシュはページの読み込み時間を短縮します。ただし、開発中のプロジェクトでは変更箇所を都度確認する必要があります。その際は、次のコードを`local_conf.php`に追加して、PHPブロックキャッシュを無効にしてください。

```php
<?php
$config['tweaks']['disable_block_cache'] = true;
```

### データベースとホストの設定

データベースの接続情報とストアのHTTPホストを再定義できます。\
これは既存のストアのローカルコピーで作業し、`config.local.php`を変更したくない場合に便利です。\
この機能を利用するには`local_conf.php`でこれらの設定をコメントアウトしてください。

```php
<?php
$config['db_host'] = '%DB_HOST%';
$config['db_name'] = '%DB_NAME%';
$config['db_user'] = '%DB_USER%';
$config['db_password'] = '%DB_PASSWORD%';

$config['http_host'] = '%HTTP_HOST%';
$config['http_path'] = '%HOST_DIR%';

$config['https_host'] = '%HTTPS_HOST%';
$config['https_path'] = '%HOST_DIR%';
```

## キャッシュおよびセッションバックエンド

`local_conf.php`を使用して、ストレージバックエンドなどを再定義できます。\
次のコードから以下の部分をコメントアウトし、設定をしてください。

```php
<?php
$config['cache_backend'] = 'file';
$config['cache_redis_server'] = 'localhost';
$config['cache_redis_global_ttl'] = 0; // キャッシュサイズがRedisサーバーのメモリサイズに達した場合、設定してください
```

{% hint style="info" %}
HINT

キャッシュは、file, sqlite, database, redis, xcache、およびapcが利用可能です。 Sqlite、apc、およびxcacheを使用するには、対応するPHPモジュールをサーバーにインストールする必要があります。
{% endhint %}

セッションのストレージバックエンドを変更することもできます。次のコードの部分をコメントアウトし、目的の設定行ってください。

```php
<?php
$config['session_backend'] = 'database';
$config['session_redis_server'] = 'localhost';
$config['cache_apc_global_ttl'] = 0;
$config['cache_xcache_global_ttl'] = 0;
```

{% hint style="info" %}
HINT

セッションのストレージバックエンドは、databaseとredisが利用可能です。
{% endhint %}


# デバッグ方法

デバッグ方法デバッグ方法デバッグ方法


# Hooks

Hooks

## 一般情報

1. フックは、開発者が機能を拡張するために使用します。そのため、可能な限り多くのパラメーターをフックに含めることを推奨します。
2. フックの名前には、関数の名前を含める必要があります。
3. プレフィックスは禁止されています。  サフィックス（接尾辞）のみが許可されます。
4. 多数のフックを含む複雑な関数がある場合、次の例を使用してフックに名前を付けることができます。

### PHP関数:

```php
<?php
function get_cart_product_data(){

}
```

### Hook:

```php
<?php
fn_set_hook （'get_cart_product_data_post_options' 、 $ product [ 'product_id' ]、 $ _pdata 、 $ product ）;
```

5. フックのパラメーターをリストするときは、常に関数が受け入れるパラメーターを最初に配置してください。SQLフックは唯一の例外は変数`params`です。必要なものはすべて変数に含まれています。
6. クラスのフックには、名前に呼び出し元クラスの名前が含まれている必要があります。
7. クラスのフックは、常に最初のパラメーターとしてクラスインスタンスを渡す必要があります。

```php
<?php

class Patterns
{
    public function save($style_id, $style, $uploaded_data)
    {
        ...

        /**
         * アップロードされたパターンファイルを保存する前に実行され、アップロードされたファイルとその場所を変更できます。
         *
         * @param \Tygh\Themes\Patterns $this          Patterns instance
         * @param string                $style_id      Style name
         * @param array                 $style         Style data
         * @param array                 $uploaded_data Uploaded files
         * @param string                $path          Path where patterns will be saved
         * @param string                $rel_path      Relative patterns path
         */
        fn_set_hook('patterns_save', $this, $style_id, $style, $uploaded_data, $path, $rel_path);

        ...
```

## フックを追加する方法と場所

各関数には少なくとも2つのフックが含まれている必要があると想定しています。

1. 関数の先頭にある`get_product_name_pre`ようなプレ・フック。関数が受け入るすべてのパラメーターは、このフックに渡される必要があります。
2. 関数の終わりにある`get_product_name_post`のようなポスト・フック。パラメーターを次の順序でリストします。「関数によって受け入れられたすべてのパラメーター」、次に「関数によって返されたパラメーター」、次に「他の補助的パラメーター」。 また、他の追加のフックがあるかもしれません：
3. `get_product_name`のようなSQLフック。すべてのSQL変数はこのフックに渡されます。パラメーターは、`$fields`、`$condition`、`$sorting`、`$limit`などすべて記述することをお勧めします。不要な場合は、空のままにしておくことができます。例：

```php
<?php

fn_set_hook('get_product_name', $product_id, $lang_code, $as_array, $field_list, $join, $condition);
```

もう一つの例。例として、商品データの選択の関数を使用します。

```php
<?php

fn_set_hook('get_products_before_select', $params, $join, $condition, $u_condition, $inventory_join_cond, $sortings, $total, $items_per_page, $lang_code, $having);
```

一部のフックはこれらの標準に準拠していません。この場合、次のようなコメントが追加されています。

```php
<?php

/ ** 
*非推奨：このフックはバージョン4.xまたは3.3.xで削除されます。
* 代わりにget_product_price_preを使用してください。
* /
```

次に、準拠するフックも追加します。この場合は、`get_product_price_pre`となります。

{% hint style="info" %}
HINT

関数に新しいパラメーターを追加するとき、古いフックを廃止して新しいフックを追加することはありません。代わりに、既存のフックの最後にこのパラメーターを追加します。この場合、パラメーターの正しい順序は無視できます。
{% endhint %}

## フックの標準形式

### PHPのフックと関数

コメントの形式は、PHPDocumentorに準拠します。この形式は、どこでもすべての関数に適用されます。

Doxygenは、これらのドキュメントを生成するために使用されます（[マニュアル](http://www.doxygen.jp/)）。

コメントの書き方：主なルールと推奨事項：

1. コメントは大文字で始まります。コメントの最後にピリオドはありません。
2. 関数の目的を説明する動詞は、三人称単数形で使用されます。たとえば、Gets user dataなどです。
3. 変数の名前と値、ファイルパス、ファイル名、その他の固有名詞を斜体で強調表示します（HTMLタグで使用）。例：Function *foo*(in *foo/bar/functions*) accepts parameter *$bar*
4. 以下の説明では、`class::function`関数は次のように定義されています。クラスのない関数は`::function`として定義されます。例：

```php
<?php

/** ...
*      - period - If defined, get pages by time period. ::fn_create_periods</li>
* ...
*/
```

5. 変数を記述して、この関数で変数が使用される理由を明確にします。

例：

```php
<?php

/**
 * Processes cart data after calculating all prices and other data (taxes, shippings etc)
 *
 * @param array  $cart               Cart data
 * @param array  $cart_products      Cart products
 * @param array  $auth               Auth data
 * @param string $calculate_shipping // 1-letter flag
 *      A - calculate all available methods
 *      E - calculate selected methods only (from cart[shipping])
 *      S - skip calculation
 * @param bool $calculate_taxes       Flag determines if taxes should be calculated
 * @param bool $apply_cart_promotions Flag determines if promotions should be applied to the cart
 */
fn_set_hook('calculate_cart', $cart, $cart_products, $auth, $calculate_shipping, $calculate_taxes, $apply_cart_promotions);
?>

<?php

/**
 * Change SQL parameters for product data select
 *
 * @param int $product_id Product ID
 * @param string $field_list List of fields for retrieving
 * @param string $join String with the complete JOIN information (JOIN type, tables and fields) for an SQL-query
 * @param mixed $auth Array with authorization data
 * @param string $lang_code Two-letter language code (e.g. 'en', 'ru', etc.)
 * @param string $condition Condition for selecting product data
 */
fn_set_hook('get_product_data', $product_id, $field_list, $join, $auth, $lang_code, $condition);
?>
```

{% hint style="info" %}
HINT

コメントは、フックの直前に配置する必要があります。
{% endhint %}

### TPL（テンプレート）フック

Smarty テンプレートの場合

```smarty
{** Dynamic menu item (on the navigation) *}
{hook name="index:dynamic_menu_item"}
...
{/hook}

{** Hooks for CSS styles *}
{hook name="index:styles"}{/hook}
```

{% hint style="info" %}
HINT

コメントの開始タグは、常に2つのアスタリスクと終了タグ（1つのアスタリスク）を使用する必要があります。このように、フックのコメントは通常のコメントと区別されます。
{% endhint %}

### JS（Javascript）フック

例：

```javascript
/**
 * Hook の説明
 */
var hook_data = {
    'append_obj_content': append_obj_content, // int Id of bla bla
    'var_prefix': prefix, // string Prefix of var
    'object_html': unescape(append_obj.html()), // string Object
    'var_id': id, // int ID of var
    'item_id': js_items[id] // int Item ID
};

$.ceEvent('trigger', 'ce.picker_add_js_item', [hook_data]);
```

最初に、イベントの説明を含むコメント、2番目はパラメーターを持つオブジェクトの変数、3番目にイベントの呼び出しを行います。

渡されたパラメーターへのコメントでは、最初の単語は変数のタイプであり、残りは説明です。


# コントローラー

CS-Cartのコントローラーは、２つの主要な実行可能なPHPファイル（`admin.php`または`index.php`）最初に呼び出し、プログラム機能を実装したPHPファイルをさらに連続して実行します。

## 1. index.phpまたはadmin.php-> 2. init.php-> 3. \[controller\_name] .php

CS-Cartでは、3番目のファイルはコントローラーと呼ばれます。\
プログラムでのデータ処理はこのファイルで行われます。—データベースなどから必要なデータを抽出し、表示用データを作成します。

コントローラーへのパスとその名称は、メインの実行ファイル（index.php等）へ渡された`dispatch`パラメーター（URLのパラメーター）の値に基づいて自動的にプログラムで定義されます。

dispatch パラメーターは以下のようなフォーマットになります

`[controller_name].[mode_name]`\
（コントローラー名.モード名）

* `[controller_name]`はコントローラーの名前です。
* `[mode_name]`ではコントローラーに定義されたモードが動作します。
* 呼び出されるファイル名は`[controller_name].php`となります。

管理パネル(`admin.php`)用のコントローラーは全て`app/controllers/backend`ディレクトリにあります。\
ショップフロント(`index.php`) 用のコントローラーは、`app/controllers/frontend`ディレクトリにあります。\
コントローラーがディレクトリにない場合は、CS-Cartは`app/controllers/common`から起動を試みます。\
「common」は同じコントローラーがショップフロントと管理者パネルの両方にサービスを提供する際に使用されます。提供される機能は両エリアで同じとなります。

コントローラーの接続は`/core/fn.control.php`の`fn_dispatch()`関数により実行され、任意のパラメーターを受け入れず、下記のアクションを実行します:

* `dispatch`パラメーターの整合性のチェック
* コントローラーにおける現在のユーザーのアクセス許可をチェック
* 必要に応じて安全なプロトコル（HTTPS）に置き換える
* 正しい順序で連続接続するために`precontrollers` と `postcontrollers`(アドオンまたはコアから)の実行順のリストを準備
* 表示するためのテンプレートを自動的に定義

`例`

\_<http://cscart\\_dir/admin.php?dispatch=products.manage_\\>
この場合、実行ファイルはadmin.phpとなり、dispatch パラメーターは、products.manageとなっています。

呼び出されるコントローラーは`/controllers/backend/products.php`です。\
modeパラメーターである`manage` は実行しなければならないアクションとしてコントローラーファイル内に記述されています。\
この例では、productsコントローラーのmanageモードによって、データベースから商品リストを抽出し、管理者エリアに商品のリストを表示します。

> ❗️ 注意
>
> コントローラーの名称はユニークなものにしなければなりません。あるコントローラーがアドオンで定義され、その名前がすでに標準（コア）のコントローラーの名前と同じである場合、呼び出し時にエラーが発生します。

## コントローラーの構造

各コントローラーは下記のロジカルブロックを含んでいます：

* `POST`リクエストの処理
* `GET`リクエストの処理
* コントローラ内でのみ使用されるローカル機能の定義

`dispatch`パラメーターの`[mode_name]`の部分は`GET`リクエスト処理の動作モードを設定するために使用されます。

## POSTリクエスト

`POST`リクエストは常に`GET`リクエストより先に処理されます。\
`fn_dispatch()`関数にコントローラーから返ってくるブロックの最後に文字列が存在しなければなりません。

```php
<?php
return array(CONTROLLER_STATUS_OK, "$index_script?dispatch=controller_name$suffix");
```

`CONTROLLER_STATUS_OK`というパラメーターは、コントローラーの処理結果の成功ステータスを持つ定数が含まれます。2番目のパラメーターは、POSTリクエストの処理後、置き換え用のURIを含む文字列です。

`例`

```php
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    if ($mode == 'add') {
        // ここに商品が追加された際の処理（コード）を入力します
    }

    return array(CONTROLLER_STATUS_OK, "$index_script?dispatch=products$suffix");
}
```

## GETリクエスト

`GET`リクエストの処理は常に`POST`リクエストの後ろに記述します。

`例1`

```php
if ($mode == 'manage') {
     // ここに"http：//cscart_dir/admin.php？dispatch = products.manage"が実行された際の処理を書く
}
```

ここではパラメーター`mode` (`dispatch=controller.mode` )の値をチェックされ、パラメーターが`manage`と等しい場合に条件付きオペレーター（if文）内のコードが実行されます。\
このコードはGET リクエストで実行されます。

`GET`モードの処理が終了すると、コントローラーは通常、以下の終了処理を実行します：

* テンプレーターへコントローラーを移動する
* `GET`メソッドによるリダイレクション
* 追加アクション: `exit;` 無しでのコントローラーの実行とプログラムの完了

この場合では、コントローラーの処理は自動的に`fn_dispatch()`関数に移されます。\
それがはっきりと定義されてない場合は、以下の`例２`と`例３`を行う必要があります。\
テンプレーターにデータを渡すには、以下のように記述します：

```php
<?php
$view->assign('template_var_name', $php_var_name);
```

ここでの`template_var_name`は、テンプレートで`$php_var_name`という変数の名前で利用できます。

`例2`

```php
<?php
if ($mode == 'manage') {
    $product_name = 'Product 1';
    $product_description = 'Product description';
    $view->assign('tpl_product_name', $product_name);
    $view->assign('tpl_product_description', $product_description);

}
```

このコードがコントローラで実行された2つの変数（`tpl_product_name`、`tpl_product_description`）がtemplaterに渡され、テンプレートでは`$tpl_product_name`、`$tpl_product_description`という変数で利用できるようになります。

## Functions

コントローラーファイル内に書かれた関数は、一般的な関数（function）の規則に従って定義します。特定のコントローラーファイルに書かれた関数を別のコントローラーで呼び出す必要がある場合は、アドオンの`func.php`に記述する必要があります。

## 利用可能なデータ

コントローラでデータを操作するには、次の標準配列を使用する必要があります。

* `$_REQUEST` - `GET`と`POST`リクエストが含まれます。この配列のすべての変数は特別な方法で処理されます。HTMLタグは削除されます。PHPによって自動的に追加されるスラッシュ（対応する設定が有効になっている場合）は削除されます。
* `$_SESSION` -セッションデータを格納する標準のPHP配列。
* `Registry` - プログラムの任意の場所からアクセスする必要があるデータ保持用の特別な静的クラスリポジトリ。

たとえば、起動時に読み取られるプログラムの構成パラメータは、`Registry class`に格納されます。このクラスの特徴は、このクラスに格納されているデータをキャッシュできることです。これにより、たとえば、この`Registry class`のキャッシュに情報を保存することにより、ほとんど更新されない情報をデータベースに繰り返し要求することを回避できます。

## Templaterへのデータの転送

コントローラーが実行され、制御がに戻された後、コントローラーは`fn_dispatch()`関数、プログラムの制御と、処理および表示が必要なテンプレートへのパスをテンプレート作成プログラムに転送します。

{% hint style="info" %}
TIPS

コントローラでは、templator を制御するか、スクリプトの実行を終了を行うか、別のアドレスにリダイレクトする必要があります。
{% endhint %}

デフォルトでは、このコントローラーのテンプレートのパスは次のように自動的に定義されます。

管理パネル：`/backend/templates/views/[controller_name]/[mode_name].tpl`\
ショップフロント：`/ themes / [テーマ名] /templates/views/ [controller_name] / [mode_name] .tpl`

`例`\
*http\://cscart\_dir/admin.php?dispatch=products.manage*

表示されるテンプレートのパス：`/backend/templates/views/products/manage.tpl`

## コンソールでコントローラーを実行する

* バックエンドコントローラー：

```
•	php /path/to/cart/admin.php --dispatch=controller.mode
```

* フロントエンドコントローラー：

```
•	php /path/to/cart/index.php --dispatch=controller.mode
```

* 共通（common）コントローラー：上記のコマンドのいずれか（共通コントローラーはadmin.phpおよびindex.php）で動作します。

{% hint style="info" %}
TIPS

/path/to/cartを、お使いのサーバー上のCS-Cartをインストールしたパスに置き換えます。`admin.php`の名前も異なる可能性があります（セキュリティ対策としてadmin.phpの名前を変更することをお勧めします）。
{% endhint %}

コントローラーのパラメーターは次のようになります。

```
php admin.php --dispatch=controller.mode --param1=value --param2=value --param3[]=value1 --param3[]=value2 --param4[param5]=value
```

これらのパラメーターは、通常のリクエストパラメーターとしてコントローラーに渡され、`$_REQUEST`配列で使用できます。コントローラーのモードがPOST要求を処理する場合は、パラメーターを指定した後、スクリプトに`--p引数`を設定します。

コンソールでコントローラーのモードを実施すると、そのモードで処理されたものが実行されます。コマンドの実行後にコマンドラインに何も表示されない場合は、次のような場合が考えられます：

* コントローラは、`fn_set_progress`、`fn_echo`、`fn_set_notification`の場合は値を返しません。
* コマンドに間違ったモードが指定されていた
* モードに指定されたパラメーターが正しくない（もしくはパラメーターが指定されていない）
* コントローラーは一部のスクリプトでは実行できません。たとえば、バックエンドコントローラーは`index.php`を使用して実行することはできません。


# Pre\&Post コントローラー

Pre-controllers（プレ・コントローラー）とPost-controllers（ポスト・コントローラー）は 標準のコントローラーが実行された前後に呼び出される（アドオンファイルの構造内での名前や場所に応じて）特別なPHPファイルです。

例:

* 「添付ファイルアドオン」の\_/controllers/backendや/controllers/frontend\_ディレクトリで次のようなファイルをみつけることができます: `products.post.php`

```
/app/addons/attachments/controllers/backend/products.post.php
```

これらのディレクトリ内にあるファイルはアドオン専用のコントローラーか標準コントローラー用のpre-/post-controllers どちらかです。

* pre- または post-controller ファイルの名前は以下のような構造(命名規則)となります。:

```http
[controller名].[pre/post].php
```

“products”はCS-Cartのコアコントローラー(標準コントローラー)なので、pre- または post-controllerを宣言することができます。ファイル名最後の「.post」 は、標準の“products”コントローラーが動作した後に実行されることを示しています。

```php
<?php
...
if ($mode == 'update') {
    // Assign attachments files for products
    $attachments = fn_get_attachments('product', $_REQUEST['product_id'], 'M', DESCR_SL);

    Registry::set('navigation.tabs.attachments', array (
        'title' => __('attachments'),
        'js' => true
    ));

    Registry::get('view')->assign('attachments', $attachments);
}
```

標準コントローラーの実行前に動作させたい場合は、.postを.preに置き換えて下さい。

* products.**post**.php ・・・ productsコントローラーの後に実行される
* products.**pre**.php ・・・ productsコントローラーの前に実行される


# データベース

データベースデータベースデータベースデータベース


# データベースの構造と命名規則

## テーブル名

* 各エンティティーの基本情報を格納するテーブルは、そのエンティティーにちなんだ`複数形`の名前が付けられます。たとえば、`products`テーブルにはショップの商品に関する主要な情報が格納されます。
* エンティティまたはその関連するエンティティの追加データを格納するテーブルには、`entity_suffix`のような名前が付けられます。接尾辞は`複数形`です。たとえば商品価格（product prices）を格納するテーブルは`product_prices`となります。
* 下記の例は、より複雑なテーブルの依存関係を示しています。
* `products` - 商品に関する基本情報
* `product_features` - 商品の追加情報
* `product_feature_variants` - 商品の追加情報のバリエーション情報
* `product_feature_variant_descriptions` - 商品の追加情報のバリエーションの各言語ごとの説明

{% hint style="info" %}
TIPS

依存関係が深くなるにつれて、テーブル名の最後の接尾辞のみが複数形となります。
{% endhint %}

## テーブルのプレフィックス（接頭辞）

インストール際にすべてのテーブルに使用されるプレフィックスを指定できます。\
デフォルトのプレフィックスは`cscart_`です。

データベースに接続する関数には、SQLクエリーにおいてテーブルプレフィックスを置き換える`?:`プレースホルダーがあります。したがって、SQLクエリでテーブル名を指定する場合は、テーブルの名前の前に`?:`プレースホルダーを追加する必要があります。

```php
<?php
$ products  =  db_get_array （
    'SELECT * FROM？：products LEFT JOIN？：product_popularity USING（product_id）' 
）;
```

## 主要（プライマリー）キーの命名規則

主要キーと外部キーに関するフィールドの名前には、エンティティの名前が`プレフィックスとして含まれます。`たとえばproductsテーブル内のプライマリーキーを持つフィールドは`product_id`となります。CS-Cartをカスタマイズするときは、この規則に従ってコードの整合性を維持することをお勧めします。

## 多言語に関するエンティティ

データベースに保存されたエンティティには、各言語で異なるコンテンツを持つフィールドが含まれる場合があります。たとえば、商品には言語ごとに名前と説明があるような場合などです。下記は、CS-Cartでの多言語の保存方法です。

* 言語用の別のテーブルが作成されます。このテーブルは、`entity_descriptions`（たとえば、`product_descriptions`）となります。
* このテーブルには、多言語サポートを必要とするエンティティの主要キーを参照するカラムが必要です。この場合は`product_id`です。
* テーブルには、追加される言語のコードを格納するカラムも必要です。このカラムは通常`lang_code`とし、`CHAR（2）`型とします。
* さらに多言語サポートのフィールドがテーブルに追加されています。この例では、`product`（商品名）および`full_description`（商品の詳細な説明）などです。

このテーブルを操作するロジックは、PHPコードによって処理されます。\
例として`product_descriptions`テーブルを使用して、ロジックを説明します。

* 新しい商品に関するデータを`product_descriptions`テーブルに保存するときは、`DESCR_SL`定数（商品を編集するために選択した言語）の値も`lang_code`フィールドに保存します。
* ショップフロントに表示するデータを抽出するとき、`lang_code`フィールドの値が`CART_LANGUAGE`定数（ショップフロントでユーザーが選択した言語）の値と等しいという条件で、テーブルを多言語データと結合します。
* 具体的なSQLクエリの例です。

```sql
SELECT products.*, product_descriptions.* FROM products
INNER JOIN product_descriptions
    ON product_descriptions.product_id = products.product_id
    AND product_descriptions.lang_code = 'ja'
```

## MySQLストレージエンジン

CS-Cartのすべてのテーブルは`MyISAM`を使用します。\
ただし、必要に応じてテーブルのタイプを`InnoDB`に変更できます。（CS-CartはInnoDBでも適切に機能します。）

InnoDBにはMyISAMよりも多くの利点があります。

* FOREIGN KEY制約(外部キー制約を設定する)
* 最新のMySQLバージョンでのインデックスの使用が可能
* トランザクション機能をサポート

{% hint style="info" %}
TIPS

InnoDBの構成上、MyISAMよりも、データまたはテーブルのスキーマを変更するクエリーの処理に時間がかかる場合があります。
{% endhint %}

InnoDBに移行すると、テーブルに追加したFOREIGN KEY制約が、CS-Cartのデータの変更と削除の順序を誤って処理する場合があります。

CS-CartはPHPコードを使用して、リンクしたエンティティーを更新・削除します。\
たとえば、カテゴリを削除すると、CS-Cartはすべての子商品とサブカテゴリーを削除します。その場合、MySQLは同様に処理しようとするため、`ON UPDATE CASCADE` ・ `ON DELETE CASCADE` のようなFOREIGN KEY制約のカスケードに問題がある可能性があります。

{% hint style="warning" %}
注意

カスケードの更新とデータの削除をPHPコードで実行することを強くお勧めします。
{% endhint %}

## データベース内のロジックについて注意事項

データベースにおいてロジックを使用しないでください。すべてのサーバーがトリガー、ストアドプロシージャなどを作成するMySQL権限を備えているわけではありません。\
さらに、データベースに追加されたロジックは、PHPコードを介して実行されたロジックと重複または競合する場合があります。


# データベース・プレイスホルダー

## ?u

データを更新するための構造持つ配列を格納します:

```php
<?php
$data = array (
    'payment_id' => 5
    );
$order_id = 3;
 
db_query('UPDATE ?:orders SET ?u WHERE order_id = ?i', $data, $order_id);
```

上記PHPコードは以下のSQLとなります。

```mysql
UPDATE cscart_orders SET payment_id = '5' WHERE order_id = 3;
```

## ?e

データを挿入するための構造持つ配列を格納します:

```php
<?php
$data = array (
    'payment_id' => 5,
    'order_id' => 3
);
 
db_query('INSERT INTO ?:orders ?e', $data);
```

上記PHPコードは以下のSQLとなります。

```mysql
INSERT INTO cscart_orders (payment_id, order_id) VALUES ('5', '3');
```

## ?i

文字列や数値を受け取り、整数に変換します

```php
<?php
$order_id = 4;
db_query('SELECT * FROM ?:orders WHERE order_id = ?i', $order_id);
```

上記PHPコードは以下のSQLとなります。

```mysql
SELECT * FROM cscart_orders WHERE order_id = 4;
```

## ?s

文字列や数値を（スラッシュを追加して）文字列に変換します

```php
<?php
$order_id = 'adasd';
db_query('SELECT * FROM ?:orders WHERE order_id = ?s', $order_id);
```

上記PHPコードは以下のSQLとなります。

```mysql
SELECT * FROM cscart_orders WHERE order_id = 'foo';
```

## ?l

受け取ったデータをLIKEオペレーターに置換するために文字列に変換します(ダブルバックスラッシュに変換されスラッシュが追加されます)

```php
<?php
$piece = '%black\white%';
db_query('SELECT * FROM ?:product_descriptions WHERE product LIKE ?l', $piece);
```

上記PHPコードは以下のSQLとなります。

```mysql
SELECT * FROM cscart_product_descriptions WHERE product LIKE '%black\\\\white%';
```

## ?d

データをデシマル（分数）に変換する

```php
<?php
$order_id = '123.345345';
db_query('SELECT * FROM ?:orders WHERE order_id = ?d', $order_id);
```

上記PHPコードは以下のSQLとなります。

```mysql
SELECT * FROM cscart_orders WHERE order_id = '123.35';
```

## ?a

prepares data to be used in the structure IN () as a set of strings, receives a string, number, array:\
文字列や数値、配列をIN ()で使えるデータに変換します

```php
<?php
$order_id = '123';
db_query('SELECT * FROM ?:orders WHERE order_id IN (?a)', $order_id);
```

上記PHPコードは以下のSQLとなります。

```mysql
SELECT * FROM cscart_orders WHERE order_id IN ('123');
```

## ?n

文字列や数値、配列を`IN()`で使えるデータに変換します

```php
<?php
$order_id = '123.45';
db_query('SELECT * FROM ?:orders WHERE order_id IN (?n)', $order_id);
```

## ?p

準備された値の挿入:

```php
<?php
$order_id = 'order_id = 4';
db_query('SELECT * FROM ?:orders WHERE ?p', $order_id);
```

上記PHPコードは以下のSQLとなります。

```mysql
SELECT * FROM cscart_orders WHERE order_id = 4;
```

## ?w

WHERE句で使えるデータを格納します

```php
<?php
$data = array (
    'payment_id' => 5,
    'order_id' => 3
);
 
db_query('SELECT * FROM ?:orders WHERE ?w', $data);
```

上記PHPコードは以下のSQLとなります。

```mysql
SELECT * cscart_orders WHERE payment_id = '5' AND order_id = '3';
```

**Operators**\
`?w` プレースホルダーは次のオペレーターをサポートしています: `=`, `!=`, `>`, `<`, `<=`, `>=`, `<>`, `LIKE`, `NOT LIKE`, `IN`, `NOT IN`, `NULL`

配列の例

```php
<?php
$data = array (
    field => value,
    array(field, operator, value)
);
```

* `field` テーブルのフィールド名
* `value` 値の条件
* `operator` 条件のオペレーター

## ?f

変数の値が有効なフィールド名かチェックします

```php
<?php
$data = 'payment@id';
 
db_query('SELECT * FROM ?:orders WHERE ?f = 5', $data);
```

上記PHPコードは以下のSQLとなります。

```mysql
SELECT * FROM cscart_orders WHERE  = 5;
```

## ?m

マルチインサートに対応する配列を格納します。

```php
<?php
$data = array(
    array(
        'payment_id' => 5,
        'order_id' => 3
    ),
    array(
        'payment_id' => 5,
        'order_id' => 4
    ),
);
 
db_query('INSERT INTO ?:orders ?m', $data);
```

上記PHPコードは以下のSQLとなります。

```mysql
INSERT INTO cscart_orders (payment_id, order_id) VALUES ('5', '3'),('5', '4');
```


# 他のデータベースへの接続

場合によっては複製やバックアップ、その他の目的のため外部のデータを取得するために追加のデータベース接続が必要になります。CS-Cartには標準とは別のデータベースホストへの接続を確立する便利なディベロッパーメソッドがあり、コアで厳密に定義されています。

## db\_initiate :

**外部ホスト** のデータベースへの接続を確立するためにはこのメソッドを使います。

```php
<?php
db_initiate($host, $user, $password, $name, $params = array());
```

### パラメーター

* `$host` – DBホスト
* `$user` – DBユーザー
* `$password` – DBパスワード
* `$name` – DB名
* `$params` - 追加の接続パラメーターの配列
  * `dbc_name` - ターゲットのデータベースを決めるためのローカル名
  * `table_prefix` – ターゲットのデータベース名の前に付ける。 プレイスホルダー`?:`によって置き換えられます。

## db\_connect\_to :

```php
<?php
db_connect_to($params, $name);
```

*パラメーター*

* `$name` – DB名
* `$params` - 追加の接続パラメーターの配列
  * `dbc_name` - ターゲットのDBを決めるためのローカル名
  * `[table_prefix]` – ターゲットのDB名の前に付ける。 プレイスホルダー`?:`によって置き換えられます。`db_initiate`メソッドで`$params`に使用されるデフォルト値`table_prefix`

これらの関数を呼び出した後、リクエストは新しいデータベースに対して処理されます。

例:

```php
<?php
$params = array(
	'dbc_name' => 'backup',
	'table_prefix' => 'cscart'
);
db_initiate('localhost', 'db_user', 'db_password', 'cscart_backup', $params);
db_connect_to($params, 'cscart_backup');
 
$data = db_get_array("SELECT * FROM ?:products");
```

この例では、`$data`には、ローカルホスト上のデータベース`cscart_backup`内の `cscart_products`テーブルからのデータを含んでいます。


# ショップフロント

ショップフロントショップフロント


# ブロック

ブロックとその動作は、`app/schemas/block_manager`ディレクトリにあるスキーマによって制御されます。

* `blocks.php`—ブロックのタイプを説明するメインスキーマ
* `blocks.functions.php` —メインスキーマで使用される関数
* `block_cache_properties.php` —キャッシュをサポートするすべてのブロックにグローバルに適用されるキャッシュパラメーター
* `dispatch_descriptions.php` —ディスパッチと言語に対応する変数のリスト。このファイルはDispatch、場所を追加/編集するときにフィールドのリストを作成する際にのみ必要です
* `templates.php` —ブロックで使用できるSmartyテンプレートで使用可能なパラメーターの説明
* `fillings.php`—ブロックの内容と詳細
* `dynamic_objects.php` —ダイナミックオブジェクト


# blockメインスキーマ—

メインスキーマは、レイアウトエディタで使用可能なブロックについて記述するフォーマットです。

```php
<?php
$schema = array(
    // ブロックタイプのユニークな識別子 => 配列
    'unique_block_type' => array(
        'settings' => array(),
        'templates' => array(),
        'cache' => array(),
        ...
    ),
);
```

## ブロックのパラメーター

### settings (array)

ブロックの設定の配列（settings）は、ブロックの編集で指定することができる設定を含みます。\
`（デザイン→レイアウト→ブロックオプション）`

設定は`key` – `value`のペアのリストです。`key`は設定の識別子として機能し、`value`は設定の種類とその動作を記述する配列です。keyには、ブロック編集ページで設定の名前を定義するために対応する言語変数が必要です。

ブロックの設定（settings）は次のようになります。

```php
'settings' => array(
    'ip_address' => array(
     'type' => 'text',
            'default_value' => '127.0.0.1',
    ),
    ...
),
```

## 利用可能なパラメーター

* `type` （string） - 次の設定タイプのいずれか：
  * `checkbox`—チェックボックス
  * `input`—入力フィールド
  * `selectbox`— selectフィールド
  * `input_long`— `input-text-long`クラスを持つ入力フィールド
  * `multiple_checkboxes`—複数選択可能なチェックボックス
  * `text`—WYSIWYGエディタ付きのテキスト入力フィールド
  * `simple_text`— textarea
  * `picker`—ピッカー
  * `template`—指定したテンプレートが表示されます
  * `enum`—オブジェクトの羅列（コンテンツセクションでのみ使用）
* `required`— (bool) 正の場合、必須項目となります。
* `option_name`— (string) 設定の言語変数の名前。名前が指定されていない場合は、代わりに設定の識別子（ID）が使用されます。
* `default_value`— (mixed) 設定のデフォルト値
* `values`— (array) `selectbox`や`multiple_checkboxes`などの設定に使用するオプションのリスト\
  `key - value`の形式の配列。`key`はデータベースに保存されているオプションの名前です。`value`はオプションの名前を格納した言語変数名。`no_lang`がtrueの場合、オプションの実際の名前となります。
* `no_lang`— (bool) trueの場合、オプションの値のリストが管理パネルにそのまま表示されます。falseの場合、その値は言語変数として扱われます。
* `values_settings`— (array) trueの場合、オプションの値のリストが管理パネルにそのまま表示されます。falseの場合、その値は言語変数として扱われます。
* `values_settings`— (array)このパラメーターは、親リストの特定のオプションが選択された場合に表示されるオプションおよびその他の設定のリストを指定します。これはselectboxタイプでのみ機能します。

## values\_settingsの使用例

```php
'settings' => array(
    'foo' => array(
        'type' => 'selectbox',
        'values' => array (
            'products' => 'products',
        ),
        'values_settings' => array(
            'products' => array(
                'settings' => array(
                    'rss_sort_by' => array(
                        'type' => 'selectbox',
                        'values' => array(
                            'A' => 'rss_created',
                            'U' => 'rss_updated'
                        ),
                    ),
                    'rss_display_sku' => array (
                        'type' => 'checkbox',
                    ),
                )
            )
        )
    )
);
```

* `picker`— (string) ピッカーのテンプレートへのパス。pickerタイプでのみで使用します。
* `picker_params`— (array) ピッカーの設定。pickerタイプでのみで使用します。
* `remove_indent`— (bool) trueの場合、管理パネルの右側にインデントが設定されません。
* `template`— (string) テンプレートへのパス。templateタイプでのみ使用します。

### templates (array)

templates配列は、テンプレートのリストが含まれています。

```php
'テンプレートへのパス' => array (
    'settings' => '設定のリスト',
    'fillings' => 'テンプレートで使用可能な内容の配列。他の内容はリストから自動的に除外されます。 ',
    'params' => 'パラメーターの配列',
    'bulk_modifier' => '出力前のブロックのすべての構成部分に適用される関数名'
),
```

スキーマが生成される`template`とブロックスキーマのパラメーターに含まれるすべての情報が`templates.php`で指定されたパラメーターに追加されます。テンプレートへのパスがキーとして機能します。

ブロックスキーマの`template`パラメーターには、次のものが含まれます。

`A.`すべてのパラメーターを含むテンプレートへのパスのリスト-この方法では、templates.phpファイルからの情報は必要ありません。

`B.`テンプレートへのパスのリスト—対応するキーのすべてのパラメーターは、templates.phpファイルで指定されます。

`C.`テンプレートを含むディレクトリへのパス—対応するキーのすべてのパラメーターは、templates.phpファイルで指定されます。

`D.`テンプレートのリストを返す関数の名前—対応するキーのすべてのパラメーターは、templates.phpファイルで指定されるか、関数によって返されます。

### wrappers (array)

`wrappers`の配列は、wrappersのリストまたはwrappersのフォルダへのパスを含むことができます。wrappersには追加のパラメーターはありません。

### content (array)

ブロックには、テンプレートに渡される変数をいくつでも含めることができます。\
例として次のようなブロックがあります。

```php
'test_block' => array (
    'content' => array(
        'some_value' => array(
            'type' => 'text',
        )
    )
)
```

管理パネルのブロック設定には、テキスト入力フィールドが含まれます。カスタマーエリアでは、このブロックのテンプレートに`{$some_value}`変数があり、管理パネルで指定できます。

配列`content`には、任意の設定（上記を参照）、enumeration、または関数を指定できます。

設定はシンプルに機能します。ユーザーは管理パネルでそれらを指定し、テンプレートに渡されます。

例えば、製品やカテゴリのリストなどの異なるフィリングを持つ構成部分のリストを定義する列挙型（enum）設定タイプの使用。

以下の列挙型パラメーターのリストを参照してください。

```php
'変数名' => array (
     'type' => 'enum',
     'object' => 'スキーマ内の動的オブジェクトの名前'
     'items_function' => 'アイテム生成する関数'
     'fillings' => array ( // Filling タイプ.
         'manually' => array ( // 手動 filling. ピッカーパラメータでは必要です.
             'picker' => 'pickers/companies/picker.tpl',
             'picker_params' => array (
                 'multiple' => true,
             ),
         ),
         'some_other_filling' => array (
             'params' => array (

             ),
         ),
     ),
 ),
```

`params`セクションを作成して、非manual fillingのパラメーターを保存できます。これらのパラメーターは、アイテムを生成する関数に渡されます。テンプレートまたはブロックに対して行うように、fillingの設定を指定することもできます。

関数を`content`の構成部分として使用する場合、関数によって返される結果はこの変数の値になります。

```php
'変数名' => array (
     'type' => 'function',
     'function' => array('fn_get_languages'[, 'param1'][, 'param2'][..]),
 ),
```

### cache (bool/array)

`cache` （bool / array）はブロックの一般的なキャッシュ設定を含みます。パラメーターが`false`に設定されている、もしくは指定されていない場合は、現在のパラメーターの`cache_overrides_by_dispatch`セクションにエントリがない場合、ブロックはキャッシュされません。

cacheで利用可能な値

* `false` （string） - ブロックはキャッシュされません。
* `true` （string） - ブロックは、`block_cache_properties`スキームの設定に従ってキャッシュされます。
* `array` （array） - ブロックのキャッシュ設定を含む配列。この配列で指定されたパラメーターは、`block_cache_properties`スキームからグローバルブロックキャッシュ設定に追加されます。

cacheで利用可能な値

`cache`配列のこれらのパラメーターは、ブロックのキャッシュ方法を指定します。特に指定のない限り、パラメーターは不要です。

* `update_handlers` （配列） - ブロックのキャッシュを無効にするデータベーステーブルのリスト（プレフィックスなし）。データベースを操作するための機能や方法など、CS-Cartツールを使用して、エントリの追加、編集、削除、テーブルの構造の変更を意味します。

たとえば、ユーザーのリストを表示するブロックには、`update_handlers`としてテーブル`users`と`user_profiles`テーブルが必要です。

キャッシュにエントリキーを生成するとき、このブロックに対して異なる変数とパラメーターのシリアル化された値を使用できます。以下に説明する配列内の必須パラメーターをリストします。

* `request_handlers` （array） - HTTPリクエストパラメーター（`$_REQUEST`配列内のキー）の名前のリスト

たとえば、`category_id`および`sort_by`パラメータを指定すると`...|category_id=10|sort_by=price;`が追加されます。これにより、これらのパラメータの値の組み合わせごとにキャッシュ内の異なるエントリを使用できます。

* `session_handlers` （array） - ユーザーのセッション内の変数の名前のリスト（配列内のキー`$_SESSION`）

たとえば、`items_per_page`でパラメータを指定すると、すべての値に対して個別のエントリがキャッシュに存在します`$_SESSION['items_per_page']`。

* `cookie_handlers` （array） - ユーザーのCookieのパラメーター名のリスト（配列によって返されるキー）。`fn_get_session data()`
* `auth_handlers` （array） - 配列内のキーのリスト `$_SESSION['auth']`

`request_handlers`、`session_handlers`、`cookie_handlers`、および`auth_handlers`の値を入力するには、特別なフォームを使用します。

* ネストされた要素にアクセスするには、ドットシンタックスを使用します。\
  例）`$_SESSION['auth']['user_id']`にアクセスする場合は`'session_handlers' => array('auth.user_id')`となります。
* すべての値を`\`\*で選択します。配列内のすべての値を選択します。キャッシュキーが生成されると、シリアル化された配列全体が使用されます。\
  `'session_handlers' => array('*')`
* `比較演算子`

```php
'auth_handlers' => array(
    'user_id' => array('gt', 0),
),
```

上記の例は、$\_SESSION\['auth']\['user\_id']を選択してキャッシュキーに追加しますが、値が0より大きい場合のみ適用されます。

`利用可能な比較演算子`：

* `gt` - より大きい（＞）
* `eq` - 等しい（＝）
* `neq` - 等しくない（≠）
* `lte` - 以下（＜＝）
* `lt` - 未満（＜）
* `gte` - 以上（＞＝）
* `cont` - 文字列を含む
* `ncont` - 文字列を含まない
* `in` - 配列内に存在する
* `nin` - 配列内に存在しない

cacheキーには、呼び出された関数とメソッドの結果も含めることができます。

* `callable_handlers` （array） - パラメーター名と対応する関数のリスト。呼び出された関数の結果は、これらのパラメーターの値として使用されます。

```php
'callable_handlers' => array(
    'currency' => array('fn_get_secondary_currency'),
),
```

上記のエントリ`|currency=RUB`はキャッシュキーに追加されます。\
これは呼び出される関数を記述する方法です。\
`array(Callable[, Args])`

* `Callable`は、関数の名前を含む文字列、または呼び出すことができる式です。\
  `call_user_func()`
* `Args`は、関数に渡される引数をリストする配列です。引数で始まる文字列の場合`$`、グローバル変数（変数の名前として扱われます`$_REQUEST`）または空の変数の一つ`$block_schema`と`$block_data`。
* `$block_schema` —ブロックのスキーマが含まれています
* `$block_data` —データベースのブロックに関する情報が含まれています

例：

```php
'callable_handlers' => array(
    'layout' => array('fn_get_products_layout', array('$_REQUEST')),
    'settings' => array('fn_foo_addon_cache_key_handlers', array('$block_data')),
    ),
```

上記のコードは、呼び出されたすべての関数の結果をキャッシュ内のエントリキーに追加します。

* `disable_cache_when` （array）—このブロックのキャッシュを無効にするルールを指定します。`request_handlers`、`session_handlers`、`cookie_handlers`、`auth_handlers`と`callable_handlers`をキャッシュ設定]セクションのように同じ形式で、これらのパラメータは異なる動作します。

```php
'request_handlers' => array('sort_by', 'items_per_page'),
    'auth_handlers' => array(
        'user_id' => array('gt', 0)
    ),
    'disable_cache_when' => array(
        'request_handlers' => array('sort_by', 'items_per_page'),
        'auth_handlers' => array(
            'user_id' => array('gt', 0)
        ),
    ),
),
```

`cache`と`disable_cache_when`セクションのパラメーターの動作についての違いは次のとおりです。

o cache: the values of $\_REQUEST\['sort\_by'] and $\_REQUEST\['items\_per\_page'] will be serialized and added to the cache key of the block. The value $auth\['user\_id'] will be serialized and added to the key only if the value is greater than 0

* `cache`：`$_REQUEST['sort_by']`および`$_REQUEST['items_per_page']`の値はシリアル化され、ブロックのキャッシュキーに追加されます。`$auth['user_id']`がシリアル化され、値が0より大きい場合にのみキーに追加されます。
* `cache.disable_cache_when`：`$_REQUEST`配列に`sort_by`があり`items_per_page`場合、ブロックはキャッシュしません。また`$auth`配列の`user_id`の値が0より場合、ブロックもキャッシュしません。`callable_handlers`のパラメータもで動作が異なります。

`cache.disable_cache_when`セクション：trueの場合、ブロックはしません。キャッシュ、および他の方法でラウンド。

* `regenerate_cache_when` （array） —このブロックのキャッシュ無効化のルールを記述します。 cache.disable\_cache\_whenと同じように機能します。
* `cache_overrides_by_dispatch` （配列） -個別のディスパッチごとにブロックキャッシュのパラメーターを記述します。`array('dispatch' => cache_params, ...)`

cache\_paramsの配列が指定されたディスパッチのパラメータをキャッシュします。\
配列にcurrentのエントリがある場合、dispatchキャッシュパラメーターは、キャッシュセクションの一般的なブロックキャッシュ設定からではなく、このエントリから取得されます。のキャッシュパラメータのネストされた配列はすべてdispatch、キャッシュセクションと同じパラメータを使用できます。

例：

```php
'cache' => array(
    // これらのキャッシュパラメーターは、カテゴリページを除くすべての場所で使用されます
    'update_handlers' => array('users'),
),
'cache_overrides_by_dispatch' => array(
    // これらのキャッシュパラメーターはカテゴリページで使用されます
    'categories.view' => array(
        'update_handlers' => array('users', 'products'),
    ),
),
```

* `hide_on_locations` （配列） -ブロックを使用できないディスパッチのリスト。たとえば、次のコードを使用して、カートページにブロックを追加することを禁止します。

```php
'hide_on_locations' => array('checkout.cart'),
```

* `single_for_location` （bool） — `true`場合、すべてのディスパッチはこの種類のブロックを1つだけ持つことができます。このパラメーターが指定されていない場合、falseとして解釈されます。
* `multilanguage` （bool） —このブロックが多言語サポートを必要とするかどうかを指定します。trueの場合、ブロックのコンテンツは多言語をサポートします。このパラメーターが指定されていない場合、falseと解釈されます。


# Dynamic Objects

詳細ページのブロックに対して異なるコンテンツとステータスを持つことができるオブジェクトは、ブロックマネージャーでDynamicオブジェクトとみなされます。\
動的オブジェクトには、`Products`、`Pages`、`Categories`、`Vendors`、および`News`の 5つがデフォルトのタイプとして定義されています。

{% hint style="success" %}
HINT

`Vendors`はマーケットプレイス版でのみ利用可能です
{% endhint %}

## Dynamicオブジェクトを使用する理由

`Products` （商品）を例としてみましょう。他のDynamicオブジェクトも同じように機能します。

商品編集ページでブロックのコンテンツを変更すると、その商品のみでコンテンツが保存されます。ブロックのコンテンツを編集すると、コンテンツが変更された場所が下に表示されます。追加のチェックボックスも表示され、そのチェックボックスをオンにすると、変更したコンテンツをグローバルに適用できます。

商品の編集ページでブロックを有効または無効にすると、ブロックの状態はその商品に対してのみ保存されます。

ブロックマネージャーで`dispatch=products.view`を使用してロケーションのブロックを編集すると、ステータスタブを使用して、特定の商品のブロックを有効または無効にできます（グローバルに無効または有効になっている場合であっても可能です。）

## Dynamicオブジェクトの仕組み

`dynamic_objects.php`でオブジェクトについて記述すると、Dynamicオブジェクトが自動的に作成されます。`dynamic_objects`スキーマに新しいオブジェクトを追加できます。商品の説明文は次のようになります。

```php
array(
    // 動的オブジェクトの名前
    'products' => array (
        // 動的オブジェクトの編集ページ。これは、管理パネルで[ブロック]タブが表示されるページです。
        'admin_dispatch' => 'products.update',
        // カスタマーゾーンのページのアドレスと、ダイナミックオブジェクトを操作できるブロックコントロールペイン
        'customer_dispatch' => 'products.view',
        // ブジェクトの識別子を定義する$_REQUEST配列のキー 
        'key' => 'product_id',
        // 管理画面で使用されるピッカーの設定
        'picker' => 'pickers/products/picker.tpl',
        'picker_params' => array (
            'type' => 'links',
        ),
    ),
)
```

ショップのユーザーが`dispatch=products.view`でページをリクエストすると、CS-Cart\
はそのページが商品のDynamicオブジェクトに属していると判断し、スクリプトに渡されたパラメーターの`product_id`を探します。\
`product_id`がある場合、ページを生成するすべてのデータは、ブロックAPI、もしくは指定されたタイプおよび識別子を介してリクエストされます。

パラメーターまたはブロックのタイプが`dispatch`によって判断できなかった場合、データはグローバルパラメーターを使用して、動的オブジェクトなしで生成されます。


# ajaxリクエストの使用方法

AJAXを使ったリクエストについて説明します。

## CS-CartのAJAX 基本コンセプト

CS-CartはjQueryのAjaxメソッドに独自の拡張を加えて構成されています。\
コードは\_/js/ajax.js\_ ファイルに書かれています。

これらを呼び出す手順は以下の通りです:

1. `submitForm` (form のみ) – フォーム内のデータを抜き出し、送信準備をします。
2. `request` – それぞれのコントローラー（dispatchからパース）にAJAXリクエストを送します。jQueryのajaxメソッドを使用します。
3. `response` – `request` の実行が成功すると呼び出されます。実際のサーバーの応答と結果表示します。
4. `inProgress` – AJAXリクエストが進行しているかどうか
5. `clearCache` – レスポンスのキャッシュをクリア

サーバーでAJAXリクエストが行われている時、AJAXリクエストのサブシステムの初期化は`fn_init_ajax` (*/functions/fn.init.php*) 機能によって実行されます。\
AJAXクラス(*/Tygh/Ajax.php*) のオブジェクトが作られます。

AJAXリクエストの前後に必要な変換を実行し、さらに`response` へ変換するためJSON配列を生成します。これらの\_AJAX\_REQUEST\_ はPHPコードで利用することが出来ます。

PHPファイル（コントローラー）で以下のように\_AJAX\_REQUEST\_ を使用すると、AJAXリクエストが渡された場合のみで実行するコードを書くことが出来ます。

### 例:

```php
<?php
if (defined('AJAX_REQUEST')) 
{
  fn_set_notification('E', fn_get_lang_var('warning'), $msg, true, 'insecure_password');
}
```

AJAXリクエストのスクリプトが完了、または終了関数`exit()` が明示的に呼び出されると、\
AJAXクラス(/Tygh/Ajax.php) のディストラクタが実行されます。\
ディストラクターはJSON形式のデータ配列にドキュメントに表示されるべき情報を渡し、その後、Javascriptの関数 `response` (*/js/tygh/ajax.js*) に配列を渡します。

コントローラーは以下の形式でレスポンスを返します。

```json
data:
    notifications:
        id:
            text
            title
        id:
            text
            title
        ...
    html:
        block_id:
            block_content
        block_id:
            block_content
        ...
```

## マイクロフォーマットでAJAXを呼び出す

AJAXリクエストはリンクやフォームを使って送信することができます。どちらの場合もマイクロフォーマット`cm-ajax` はそれぞれの要素に指定する必要があります。

***

## フォームの場合

フォームに`cm-ajax` が書かれている場合、そのコンテンツはAJAXリクエストとしてアクション属性に定義されたURLに送信されます。

そのようなフォームには`result_ids` と呼ばれる非表示の入力要素があります。\
それにはAJAXデータで更新される要素の識別名が含まれていなければなりません。

AJAXフォームの例

```html
<!-- cm-ajaxクラスがついたフォームはindex.phpにAJAXリクエストとして送信されます -->
<form class="cm-ajax" action="index.php" method="post" name="product_form_817">
 
<!-- 更新すべきHTMLエレメントのIDを値とするHiddenフィールド -->
    <input type="hidden" name="result_ids" value="my_id" />
    ...
 
<!-- このボタンが押された場合、index.phpにAJAXリクエストが送信されます -->
    <input id="button_cart_817" type="submit" name="dispatch[checkout.add..817]" value="Add to cart" />
    ...
</form>
```

## リンクの場合

リンクがクリックされた際、`cm-ajax` の書かれたリンクはhref属性で定義されたURLにAJAXリクエストを送信します。

更新する要素のIDは`rev` 属性で指定する必要があります。

AJAXリンクの例:

```php
<a class="cm-ajax" rev="content_usergroups" href="{"profiles.request_usergroup?usergroup_id=`$usergroup.usergroup_id`&amp;status=`$ug_status`"|fn_url}">{$_link_text}</a>
```

***

## その他のマイクロフォーマット

マイクロフォーマット`cm-ajax` はAJAXフォームやリンクのため必要不可欠です。\
CS-Cartには開発者がAJAXを管理出来るるたくさんのオプションマイクロフォーマットがあります。

## AJAXリクエストを直接使用する

明示的にメソッドを呼び出すことはCS-Cartのコーディングガイドラインでは推奨されていません。

すべてのJavascript関数は別々のファイルに書き、CSSセレクタ(id,やclass など)を使用して、HTML要素に割り当てる必要があります。

しかしながら、AJAXリクエストは`$.ceAjax()` メソッドは直接インライン・コールを送ることができます:

```html
<input id="enable_block_1" type="checkbox" name="enable_block_1" value="Y" onclick="$.ceAjax('request', '{$index_script}?dispatch=block_manager.enable_disable&amp;block_id=1&amp;enable=' + (this.checked ? this.value : 'N'), {literal}{method: 'POST', cache: false}{/literal});" />
```

## AJAXを介したコンテナのリロード方法

CS-Cartでは以下のように、コンテナのコンテンツを動的にリロードできます

* `cm-ajax`クラスとその`result_ids`構成部分を含むフォームを送信します（microformatsに関する記事を参照）。
* `cm-ajax`クラスと`data-ca-target-id`属性のリンクを使用します（microformatsに関する記事を参照）。
* `$.ceAjax()`でカスタムリクエストを作成します。
* `id`は開始タグの最後の属性でなければなりません。
* 「マジックコメント」`id`は、終了タグの前にある必要があります。

```html
<div class="foo" data-ca-bar="bar" id="foobar">
    このコンテンツはAJAXでリロードされます
<!--foobar--></div>
```


# 特別なCSSセレクター

special classes（特別なCSSセレクタ）はCSSのコーディング量とファルのサイズを最小にするために提供されます。これらのCSSセレクタは管理パネルのカスタマイズを行う際に利用されています。

```html
<!-- フロートしたエレメントを生成します -->
<div class="float-left">これはフロートボックスです</div>
<div>これは通常ボックスです</div>
```

標準的なクラスと一緒に使用する場合:

```html
<!-- 通知BOXにフロートしたエレメントを生成します -->
<div class="notice-box float-left">これはフロートボックスです</div>
<div>これは通常ボックスです</div>
```

以下はスペシャルクラスの全リストです：

* `input-text` – テキストを入力する際に使用します。要素の幅はパラメーターのサイズと同じになります。
* `input-textarea` – テキストエリアに使用します。要素の幅はパラメーター`cols`と同じになります。
* `input-textarea-long` – フォーム内のすべての通常のテキストエリアに使用されています。幅はCSSで定義されています。
* `input-text-short` – ポジションや数量などの入力に使用します。 フォームやテーブル内では幅はCSSに(デフォルト：30px)定義されます。
* `input-text-medium` – 商品価格や重さ、商品コードなどの入力で使用します。
* `input-text-large` – タイトルや商品名などの入力で使用します。
* `hand` – マウスが要素の上にある時にマウスカーソルを手の形に変える時に使います。
* `nowrap` – 文字が改行されないようにテーブル内のnowrapパラメーターのかわりに使用します。
* `uppercase` – 文字が大文字になります。
* `lowercase` – 文字が小文字になります。
* `strong` – 文字が太字になります。
* `error-text` – フォント色が赤になります。
* `solid-border` – 要素の回りを1pxのボーダーで囲みます。
* `float-left` – フロート要素が作成され、左側に位置します。他の要素はこの要素の左側に配置されます。
* `float-right` – フロート要素が作成され、右側に位置します。他の要素は右側に配置されます。
* `clear` – フローティングされたブロックの親要素に定義します。これによって次の要素のフロートを解除できます。
* `no-padding` – CSSで指定または継承されたパディング属性をゼロにします。
* `no-margin` – CSSで指定または継承されたマージン属性をゼロにします。
* `valign` – 指定された要素をベースラインの中間に配置します。
* `checkbox` – テーブルやフォーム内のチェックボックスの位置を揃えます。テーブルやフォームのボックスを揃えるために使用します。
* `radio`– テーブルやフォーム内のラジオボタンの位置を揃えます。テーブルやフォームのラジオボタンを揃えるために使用します。
* `no-items` – 「表示するアイテムが見つかりませんでした」という通知のブロックに使用します。「表品が見つかりませんでした」という通知が表示されるブロックをデザインするために使用します。
* `center` – ブロック内のテキストやインライン要素を中央揃えするために使用します。
* `right` – ブロック内のテキストやインライン要素を右揃えするために使用します。ブロック内の右側のテキストやインライン要素を揃えるために使用します。
* `scroll-x` – 水平スクロールを作成します。
* `hidden` – 要素を隠します。`style="display: none;"`の代わりに使用できます。


# マイクロフォーマット Microformats

マイクロフォーマットとは、特別なCSSセレクタです。Javascriptのコードが特定のイベントを実行する際にこのマイクロフォーマットが適用されている要素に対して処理が行われます。

マイクロフォーマットには以下のような命名規則があります。 （独自の新しいマイクロフォーマットを定義する際に重要となります）：`cm-new-microformat-name`

プレフィックスは、`cm-` (CS-Cart Microformatの略)となり、このCSSスタイルがマイクロフォーマットであることを示します。

標準のCSSスタイルとは異なり、マイクロフォーマットの記述はCSSファイルではなく、Javascriptファイルに記述されます。

マイクロフォーマットを処理するJavascriptコードを検索するには\_/js/\_ディレクトリ内の全てのファイルの文字列`.hasClass('cm-microformat-name')`を検索をする必要があります。

## フォーム

### フィールドの検証

使用法:

```html
<label class="cm-email cm-required" for="elm_id">Field name:</label>
<input type="text" name="test" value="Y" id="elm_id" />
```

パラメーターにより確認された要素に割り当てられたラベル要素の`for`は、フォームフィールドのバリデーションで必要となります。

フィールドのバリデーション用のマイクロフォーマットは`label`要素のクラス属性として定義されており、クラスは複数のバリデーションルールを組み合わせることができます。

間違って入力されたフィールド用にエラーメッセージを使用できるようにするために、ラベルが非表示の場合であってもマイクロフォーマットの記述が必要です。

これらのエラーメッセージでは、以下のプレースホルダーを使用することが出来ます：

### `form_message(msg, lbl, null, extra)`

\*\* \[field]\*\* パラメーターが一つエラーメッセージ作成の関数（*form\_message()*）に渡されると、ラベルの説明文に置き換えられます。\
例えば：

```javascript
var msg = 'The field [field] is not valid';
this.form_message(msg, lbl);
```

パラメーターは、2つまでエラーメッセージ作成関数に渡すことが出来ます。

例:

```javascript
var msg = 'The field [field1] do not match field [field2]';
this.form_message(msg, lbl1, lbl2);
```

**\[extra]** エラーメッセージに表示される追加のデータを指定します。

```javascript
var msg = 'The field [field] should be set to the following format: [extra]';
var extra = '1AB-CF5';
this.form_message(msg, lbl, null, extra);
```

* `cm-required` - この要素は必須項目となります。チェックボックスに適用されているいる場合は、チェックボックスがチェックされます。
* `cm-email` - 有効な電子メールアドレスかどうかを検証します。
* `cm-phone` - 有効な電話番号形式かどうかを検証します。
* `cm-zipcode` - 有効な郵便番号形式かどうかを検証します。郵便番号のフォーマットは`$.ceFormValidator('setZipcode', {...})).`で指定することが出来ます。（各国の郵便番号ルールはそれぞれ異なりますので、「国テーブル」でフォーマットが定義されています。）

例:

```javascript
<script type="text/javascript">
Tygh.$.ceFormValidator('setZipcode', {
    US: {
        regexp: /^(\d{5})(-\d{4})?$/,
        format: '01342 (01342-5678)'
    },
    CA: {
        regexp: /^(\w{3} ?\w{3})$/,
        format: 'K1A OB1 (K1AOB1)'
    },
    RU: {
        regexp: /^(\d{6})?$/,
        format: '123456'
    }
});
</script>
```

* `cm-value-integer` - フォーム要素（inputやtextareaなど）に適用することが出来ます。入力された値が整数であるかを検証します。
* `cm-value-decimal` - フォーム要素（inputやtextareaなど）に適用することが出来ます。入力された値が浮動小数点数であるかを検証します。
* `cm-integer` - 入力された値が数字であるかを検証します。
* `cm-password` - 必ずペアとなる要素に割り当てられ、二つの要素に記入された値が同じかどうか検証します。
* `cm-multiple` - select要素の少なくとも１つの値が選択されているかどうかを検証します。
* `cm-all` - フォームを送信する前に要素のすべてのオプションを選択します。

独自の検証パターンを定義することも出来ます。

例:

```html
<label for="a" class="cm-custom (check)"><input type="input" id="a" value="" />
<script type="text/javascript">

    function fn_check(id)
    {
        return (1 == 1) ? true : 'Not valid';
    }
</script>
```

このファンクションは対象のIDのみをパラメーターとして受け取ります。

* `cm-regexp` - 正規表現で書かれたフォーマットに正しいかを検証します。 正規表現は`$.ceFormValidator('setRegexp', {})`で定義されます。

例:

```html
<label for="a" class="cm-custom (check)"><input type="input" id="a" value="" />
<script type="text/javascript">

    function fn_check(id)
    {
        return (1 == 1) ? true : 'Not valid';
    }
</script>
```

* `cm-numeric` - checks whether the value is a number with the help of autoNumeriс plugin.\
  jQueryの「autoNumeriс」プラグインを使って、値が数字かどうかを検証します。

[autoNumeriсプラグインのドキュメント](http://www.decorplanit.com/plugin/)

例:

```html
<label for="a" class="cm-regexp"><input type="input" id="a" value="" />
<script type="text/javascript">
    regexp['a'] = {regexp: "^[A-Za-z]+$", message: "Please, use only alphabetical signs"};
</script>
```

***

## フォーム処理

```html
<form class="cm-ajax">
    ...
</form>
```

マイクロフォーマットはformタグのCSSクラスとして使用されます。\
クラスは組み合わせることができます。

* `cm-ajax` - このフォームはAJAXを使って送信されます。 このフォームには`result_ids`というhidden要素が自動で追加されます。

```html
<input type="hidden" name="result_ids" value="id1, id2" />
```

* `cm-ajax-full-render` - `cm-ajax`と一緒でのみ使用できます。ページ全体を強制的にリロードします。
* `cm-no-ajax` - フォームの送信ボタンにこのクラスが割り当てられている場合、ボタンをクリックした際には、`cm-ajax`クラスがフォームにある場合でも、フォームは通常の方法（GET/POST）で送信されます。このイベントはAJAXでformが送信される前後で使用します。これを宣言するには以下のルールを使用してください：
* `Pre-call`: `'ce.formpre_[FORM_NAME]',` \[form, clicked\_elm]\`.
* `Callback`: `'ce.formpost_[FORM_NAME]',` \[form, clicked\_elm]\`.
* `form` - 送信されるフォームオブジェクト
* `clicked_elm` - 強制的に送信されるフォームオブジェクト
* `[FORM_NAME]` - 送信されるフォーム名

例:

```javascript
$.ceEvent('on', 'ce.formpre_add_to_cart_form', function(form, elm) {
  // Some code here
});
```

* `cm-check-changes` - フォームを送信する前に保存されていない変更があるかチェックします。 もし保存されていない変更箇所があれば、警告が表示されます。これは、管理パネル内の全てのPOSTメソッドのフォームにデフォルトで割り当てられています。

```javascript
if (_.area == 'A') {
   frms.filter('[method=post]').addClass('cm-check-changes');
```

* `cm-disable-empty` - フォームに割り当てられます。空のフィールドは送信されません。例えば、商品検索フォームにおいて未指定のパラメーターの送信をキャンセルします。
* `cm-disable-empty-files` - フォームに割り当てられます。空のファイル送信フィールドを送信しません。
* `cm-failed-field` - フォームが送信され後、間違って入力されたエラーのあるデータを強調するために自動的にフォームフィールドに割り当てられます。
* `cm-no-hide-input` - フォームに\_cm-disable-empty\_クラスが指定されていても、空の値を送信することができます。
* `cm-trim` - label要素に割り当てられます。バリデーションチェックする際に、入力の値から前後のスペースを削除します。

***

## フォームのリセット

* `cm-reset-link` - このクラスで要素をクリックする際に、フォームの値がデフォルト値に設定されます。 商品検索フォームで使用されます。

***

## フォームフィールドの選択

* `cm-select-tex`t - クリックされた際にこのクラスをもつ要素は、ハイライト表示されます。 (textarea, input要素) バッファリング用のコピーを簡単にします。

***

## フォームのリロード

* `cm-reload-form` – form要素に割り当てられます。このフォームが変更された際、GETリクエストを使用してリロードされます。

***

## フォーム内のピッカー

* `cm-ajax-content-input` - 例えば、ピッカー内で検索リクエストを行う際に自動補完を可能にします。自動補完用のAJAXリクエストは入力が停止した後、500ミリ秒遅れて送信されます。受信したコンテンツ（AJAX）は`REV`属性に書かれているコンテナにロードされます。自動補完のパターンは`value`パラメータから取得されます。　

例: マーケットプレイス版でピッカーを使って出品者を選択する

　　　　　

* `cm-ajax-content-more` - 非表示となっている要素が見えるようになる時に（例えば多数のオプションを持つドロップダウンリスト）、追加のコンテンツがロードされます。

　　　　　

例: マーケットプレイス版で多数の出品者をピッカー内で選択する場合

* `cm-cancel` - このマイクロフォーマットを持つボタンがクリックされた時、全てのピッカーフィールドはデフォルト値が設定されます。
* `cm-clone` - ピッカーを閉じることなくピッカー内にアイテムを追加する際に使用します。（AJAXリクエストなしで）

例: 「キャンペーン」を管理するページでピッカー内に複数の商品やカテゴリー追加する際に空の要素に複製されたアイテムを追加します。

* `cm-dialog-opener` - このマイクロフォーマットは、ダイアログを開かせたい要素（「カテゴリーを開く」等）に割り当てられます。ダイアログの中身は`REV`パラメータで定義します。
* `cm-dialog-closer`- すでに開いているダイアログを閉じさせる要素に割り当てます。\
  例: ピッカー内の「キャンセル」ボタン
* `cm-dialog-keep-in-place` - ※まだ実装されていません。
* `cm-dialog-auto-open` - ページを訪れた際にこのクラスが適用されたダイアログボックスは自動でオープンします。\
  例：管理パネルに初回にアクセスした場合に自動で開かれる設定ウィザードなどで使用されています。
* `cm-dialog-auto-size` - このマイクロフォーマットは、`cm-dialog-opener`クラスと共に使用します。このクラスが使用されている場合、ダイアログボックスの幅と高さはコンテンツに自動調整されます。
* `cm-dialog-auto-width` - `cm-dialog-opener`と共に使用します。ダイアログボックスの幅はコンテンツに自動調整されます。
* <br>
* `cm-dialog-switch-avail` - ダイアログボックス内で選択した全てのチェックボックスを選択解除します。
* `cm-js-item` - このクラスは、ピッカーからフォームに要素を追加する際（例：ギフト券への追加）、追加された要素が属するコンテナに割り当てられます。
* `cm-picker-options` - 商品オプションがピッカーからの商品に適用された際に適用されます。

\[block:html] { "html": "\<tbody id="{$data\_id}" class="{if !$item\_ids}hidden{/if} cm-picker-options">" } \[/block]

***

## input\[type=submit]要素以外をクリックしてフォームを送信する方法

使用法:

```html
<input type="radio" name="a" value="b" class="cm-submit" />
```

マイクロフォーマットは要素のCSSクラスとして定義されます。クラスは組み合わせることができます。

* `cm-submi`t - この要素が割り当てられたform要素は、その要素がクリックされた後に送信されます。

例：ボタン以外の要素のクリックでフォームを送信するためには：

1. `cm-sumbit`を要素に割り当てる
2. `data-ca-dispatch`属性でフォームが送信されるデdispatch（\[controller.mode）を指定します。

※送信する要素がフォームの外にある場合のみ、`data-ca-target-form`属性で名前やIDを返します。

***

## 新しいウィンドウや親ウィンドウでフォームを送信する

例:

```html
<input type="submit" name="a" value="b" class="cm-new-window" />
<input type="submit" name="a" value="b" class="cm-parent-window" />
```

* `cm-new-window` - クリックされた際に新規のウィンドウが開きフォーム内容がそこに送信されます。
* `cm-parent-window` - クリックされた際にフォームの内容は親ウィンドウに送られます。

***

## フォームの送信を禁止する

使用方法:

```html
<input type="submit" name="a" value="b" class="cm-no-submit" />
```

* `cm-no-submit` - この要素が割り当てられているフォームは、submit要素がクリックされても送信されません。

***

## フォームバリデーションをスキップする

使用方法:

```html
<input type="submit" name="a" value="b" class="cm-skip-validation" />
```

* `cm-skip-validation` - submit要素をクリックすると、この要素の適用されたフォームはバリデーションを行うことなく送信されます。

## フォームを隠す

* `cm-hide-inputs` - このクラスが適用されたinput要素の値はplain textで表示されます。（編集はできません）　　　　　　　　\
  例: マーケットプレイス版CS-Cartで出品者に表示は行うが編集できない項目など
* `cm-hide-save-button` - このクラスが割り当てられているボタンは非表示になります。（ボタンの保存は必須ではありません）

## フォーム内のチェックボックス

利用方法:

```html
<input type="checkbox" name="check_all" value="Y" class="cm-check-items" />
...
<input type="checkbox" name="product_ids[]l" value="1" class="cm-item" />
<input type="checkbox" name="product_ids[]l" value="2" class="cm-item" />

<a href="#" name="check_all" class="cm-check-items on">Check all</a>/<a href="#" name="check_all" class="cm-check-items off">Uncheck all</a>
```

上記の例では二種類の異なるチェックボックスをコントロールする要素があります。

* 通常のチェックボックス\
  -リンクのチェックボックス

コントロール要素には`check_all`とクラスと`check-items`クラスがなければならりません。

コントロール要素がリンクの場合、クラスの\_on\_と\_off\_も決められています。（全てのチェックボックスをコントロールする）

チェックボックスを管理できる要素には、\_class\_を持っていなければなりません。\
\_process-items\_クラスは、フォームを送信するボタンに割り当てられます。

ボタンがクリックされた際にチェックボックスが対応するグループは、チェックボックスが\_on\_か\_off\_を調べます。

いずれのチェックボックスもonでない場合は、メッセージが表示されます。

> 📘 ヒント
>
> フォームに複数のチェックボックスがあり、それらを別々にコントロールする必要がある場合、`cm-check-items`クラス、`cm-item`クラス、`cm-process-items`クラスにユニークなサフィックスが追加されます。

```html
<input type="checkbox" name="check_all" value="Y" class="cm-check-items-group" />
...
<input type="checkbox" name="product_ids[]l" value="1" class="cm-item-group" />
```

## その他の要素

## リンク

リンクをクリックした際に、AJAXリクエストを実行できるマイクロフォーマットがあります。

使用方法：

```html
<a class="cm-ajax" href="http://cs-cart.com" data-ca-target-id="pagination_contents">Ajax link</a>
```

* `cm-ajax` - AJAXリクエストはリンクをクリックした際に実行されます。
* `cm-comet` - フォームはCometモデル（[wikipedia](http://ja.wikipedia.org/wiki/Comet) ）を利用してリフレッシュされます。
* `cm-delete-row`- このクラスを持つ要素がクリックされた場合、最も近い親要素「tr」が削除されます。 テーブルで行を削除する時に使用されます。
* `cm-row-item` - このクラスはテーブルの行に割り当てられます。`cs-delete-row`と共にコンテナの識別に使用します。
* `cm-ajax-cache` - AJAXリクエストをキャッシュする事ができ、`cm-ajax`と共に使用されます。
* `cm-ajax-force` - 二度目のajaxレスポンスからjavascirptコードを実行できます。`cm-ajax`と共に使用されます。

***

既知のIDの要素をクリックする必要がある場合、`cm-external-click`クラスのリンクを使用できます。クリックされるべき要素のIDはリンクの\_data\_ca\_scroll\_パラメータに指定されています。

```html
<a class="cm-external-click" data_ca_scroll="external_elm">Push me</a>
```

* `cm-external-focus` - このクラスを持っている要素がクリックされた際、外部の要素にフォーカスが移動します。移動する外部の要素のIDはREVパラメータで定義されています。
* `cm-smart-position` - コンテナを配置するために使用します。（例えば、管理パネルの通貨リスト）

## 通知

* `cm-auto-hide` - このクラスによって通知は自動的に消滅します。 タイムアウトまでの時間は\_基本設定\_ -> \_表示設定\_で設定することができます。
* `cm-notification-close` - このクラスは、通知を「閉じる」ボタンに割り当てられています。通知自体をクリックすると、フォームから削除されるか通知を削除するAJAXリクエストが送信されます。　
* `cm-notification-container` - このクラスは、通知コンテナに割り当てられます。

## その他のエンティティ

* `cm-confirm` - このクラスを持つリンクがクリックされた際にアクションの確認が表示されます。
* `cm-noscript` - このクラスを持つ要素はJavascriptサポートがブラウザで有効になってない場合のみ表示されます。
* `cm-focus` - ページがロードされた際、このクラスを持つ要素にフォーカスが移ります。\
  例：ログイン入力フォームがロードされた際、フォーカスはログインフィールドにあります。
* `cm-opacity` - テーブルから削除された行に割り当てられ、その行は半透明になります。\
  例: 商品画像を複製し、その“行” を削除します。ページがリロードされ、削除が実行されるまでその“行”が半透明のままです。
* `cm-uploaded-image` - アップロードされた画像のdiv要素に割り当てられています。アップロードされた画像のカウントに使用します。
* `cm-wysiwyg` - textarea要素に割り当てられています。その要素にwysiwygエディタを提供します。
* `cm-row-status-[current status code]` - テーブルの行に割り当てられます（要素）\
  \[current status code]は、アイテムの現在のステータスコードを示します。(e. 「a」は有効、「d」は無効 ...)
* `cm-autocomplete-off` - フィールドから自動入力の機能を削除します。パスワード入力フィールドで使用されています。

***

## ポップアップ

マイクロフォーマットの`ポップアップ・ボックス`が使用出来ます。エリア外をクリックするとそのポップアップを閉じることができます。

使用方法:

```html
<div class="cm-popup-box">
...
</div>
```

ポップアップしたエリア内の要素をクリックで隠すためには、それらの要素に\_cm-popup-switch\_クラスを定義する必要があります。

フォーマット:

```html
<div class="cm-popup-box">
<strong class="hand cm-popup-switch">Close</strong>
...
</div>
```

* `cm-select-option` - 管理パネル内のbootstrapのポップアップに使用されます。
* `cm-popover` - bootstrapのポップオーバーの初期化を行います。 <http://getbootstrap.com/2.3.2/javascript.html#popovers>

## 要素の組み合わせ

**cm-combination** は表示/非表示させたいコンテナに使用し、その状態を示しています。

これは例えば、管理パネル内の商品やカテゴリーに対する「高度な検索」に適用されます。\
‘state’によって、コンテナのモード（表示/非表示の状態）に応じて違う画像の表示を意味します。

```html
<img src="" id="on_cat" class="cm-combination" />
<img src="" id="off_cat" class="cm-combination" />
<a href="#" id="sw_cat" class="cm-combination">
...
<div id="cat">
</div>
```

追加される要素は、異なったプレフィックスを持ったIDを使用します。プレフィックスには3タイプあります。

* `on_` - クリックされた際に、コンテナを開く要素に適用(*通常はプラス・’アイコン*).
* `off_` - クリックされた際に、コンテナーを閉じる要素に適用(*通常はマイナス・アイコン*).
* `sw_`- クリックでコンテナの内容を切り替える要素に適用 (通常はリンク・アイコン)

***

* `cm-uncheck` - \_cm-combination\_と共に使用し、\_cm-combination\_の適用されたidで定義されたチェックボックスの状態を切り替えます。
* `cm-switch-availability` - IDがsw\_elem\*のcm-switch-availabilityと関連付けられた入力要素（checkboxやradio、text）の状態を切り替えます。

有効になっているときに、クリックされた要素(\_cm-switch-availability\_の適用されいる) を作成するには\_cm-switch-inverse\_を使用してアイテムを切り替えます。

checkboxやradioブロックを表示/非表示にするには、\_cm-switch-visibility\_を使用します。checkboxまたはradio以外のブロックに使用される場合、\_cm-switched\_は条件を定義します。

フォーマット例:

```html
<input type="checkbox" id="sw_company_redirect" checked="checked" class="cm-switch-availability cm-switch-inverse cm-switch-visibility" />
```

* `cm-select-with-input-key` - テキストエリアでセレクタを接続します。セレクタの値が変更された際、それをテキストエリアに移動させ、そのエリアを無効にします。

ロケーションで使用する場合、\_dispatch\_を選択します。

## 要素の組み合わせ

要素の組み合わせ（例：ツリー表示の表示/非表示）にこのマイクロフォーマット\_cm-combinations\_が使用されます。

```html
<img src="" id="on_cat" class="cm-combinations" />
<img src="" id="off_cat" class="cm-combinations hidden" />
```

ここで使用されるIDはこれらの２つの要素に対してのみです。

また、組み合せをグループ化することが出来ます。（同じページに複数のツリーがある場合など）その際はsuffixを追加することが必要です。

```html
<img src="" id="on_abc" class="cm-combinations-a" />
<img src="" id="off_abc" class="cm-combinations-a hidden" />
...
<img src="" id="on_cat" class="cm-combination-a" />
<img src="" id="off_cat" class="cm-combination-a" />
<a href="#" id="sw_cat" class="cm-combination-a">
...
<div id="cat">
</div>
```

この例の場合、上のイメージをクリックした際、グループAの組み合せのみが表示/非表示になります。

## タブ

* `cm-js` - このクラスを持つdiv要素は内部にタブのリストを持つSmartyが生成されます：`cm-js`クラスを持つ li要素と特定のID（例：description）

タブがクリックされた際、*content* + タブのID\_というIDを持つdiv要素が検索されて表示されます。コンテナ内の他のdiv要素は非表示になります。

* `cm-j-tabs` - `cm-js`タブのコンテナに使用されます。タブコンテナの検索や初期化に使用されます。
* `cm-tabs-content` - 非表示にできる保存ボタンのあるタブに割り当てられます。(`cm-hide-save-button`)
* `cm-toggle-button` - このクラスは、div要素に割り当てられます。`cm-hide-save-button`クラスを持つdivのタブが選択された際、`div`に配置されたボタンは非表示になります。

## 保存の状態

* `cm-save-state` - コンテナの保存状態を有効にするには、このマイクロフォーマットがコンテナをオープン/クローズする全ての要素に割り当てられる必要があります。 このとき、状態の変化に、この要素のIDと接続されるクッキーが作成されます。 デフォルト状態はコンテナは *非表示* です。デフォルトの状態がコンテナを【*表示*】するべき場合は、マクロフォーマットは\_a\_ です。 クッキーの確認と要素を隠す処理はテンプレートに書かれている必要があります。
* `cm-save-fields` - このクラスを持つ表示されている入力コンテナは配列にシリアライズされAJAXリクエストに渡されます．

## 追加のマイクロフォーマット

* `cm-skip-avail-switch` - このマイクロフォーマットは、`switchAvailability`に使用します。(特定の全ての要素のオン/オフを切り替えます)。要素がこのクラスを持っている場合、後ろには切り替わりません。
* `cm-skip-check-items` - assigned to a form to allow state change check skipping for its children elements. 子要素のチェックをスキップする場合に、このマイクロフォーマットをフォームに割り当てます。
* `cm-track` - タブコンテナを割り当てます。最後に有効になったタブが送信された後に開かれます。
* `cm-save-and-close` - `return_to_list`を持つ非表示のフィールドを追加します。「保存して閉じる」ボタンに使用します。
* `cm-promo-popup` - フリーモードのCS-Cartでフルバージョンの機能を利用しようとした際に警告ポップアップを開きます。
* `cm-update-for-all-icon` - ストアフロントの共有を可能にします。フィールドは編集できるように作られています。
* `cm-sticky-scroll` - 使用されるブロックを固定します。ページの上端からこのクラスが付いたブロックまでスクロールされた場合、ブロックの位置が固定されます。 `data-ce-padding`は、固定されたフィールドが画面の上端で特定されるまでの距離となります。

例:

```html
<div class="subnav cm-sticky-scroll" data-ce-top="100" data-ce-padding="20" >
```

ブラウザのウィンドウが100pxスクロールされた際、パネルは上端から20pxの距離で固定されます。

* `cm-range-slider` - 範囲選択スライダーの初期化を行います。 (jQuery UI Slider)
* `m-colorpicker` - カラーピッカー (<http://bgrins.github.io/spectrum/)の初期化を行います。>

## ロケーション

* `cm-location-billing`
* `cm-location-search`
* `cm-location-shipping`

`cm-location-`を持つ全てのクラスの配列は都道府県・州（state/province）を定義するために使用されます。

`cm-location-`の後の値は対象を区別するために使用されます。

都道府県・州（state/province）のリストを含む選択ボックスは`for`属性に定義されます。

* `cm-country` - 国名を定義するために `cm-location-\*` と共に使用します。その国の都道府県・州（state/province）はこのマクロフォーマットにしたがって更新されます。
* `cm-state` - ラベルが割り当てられます。\
  `for`属性で指定された要素は都道府��・州（state/province）のリストが利用可能な場合、または入力フィールド以外の場合にリストとしてどちらも表示されます。

## ヒントやツールチップ

* `cm-hint` - ヒントを表示したい入力フィールドやテキストエリアはこのクラスに割り当てます。表示したいヒントのテキストはタイトル属性に定義して下さい。

もしタイトル属性が無い場合、ヒントのテキストは「value」属性から取得されます。\
フィールドにフォーカスが移ると、ヒントは非表示になります。\
フィールドが空の場合。フォーカスが外れると、ヒントは再び表示されます。

ヒントがフィールド内に表示された場合、フィールド名のプレフィックスとして`hint_`がつけます。このプレフィックスはテキストが入力された場合に取り除かれます。

例:

```html
<input type="text" name="field" id="a" size="20" title="Please, input your name here" value="" class="input-text cm-hint" />
```

* `cm-hint-focused` - 入力フィールドにフォーカスが当たるとヒントが隠れていることを示しています。`cm-hint`と使用する際、内部ヒントが表示されなくなります。
* 例）\
  管理パネルの\_注文の追跡\_フィールド
* `cm-tooltip` ツールチップを持つ要素に割り当てられます。ツールチップテキストはタイトル属性に定義します。

## 管理パネル

## 整形リスト

Such list can be seen, for example, on the currency edit page: when a row is dragged, its position is changed.\
例えば、次ようなリストがあります。\
通貨編集ページ：行がドラッグされると、ポジションが変更されます。

* `cm-sortable`はソート可能なコンテナに割り当てられます。(cm-sortable-row)\
  例：管理パネルの通貨リスト
* `cm-sortable-id-*/` - `cm-sortable`コンテナの特定の行のIDを指定します。`cm-sortable-id-`の後の値はリクエストに引き渡され、リストの変更に使用されます。
* `cm-sortable-row` - ドラッグ可能なテーブルの行に割り当てられます。その行は`cm-sortable`コンテナ内にある必要があります。

## ファイル・アップローダー

* `cm-fu-file` - ファイルアップローダーから更新されたファイルブロックに割り当てられます。ファイルがない場合、ブロックは表示されません。ファイルがある場合は、表示されます。
* `cm-fu-no-file` - ファイルのアップロードが可能な要素に割り当てられます。任意のファイルアップローダーを例として下さい。

## クイック・メニュー

* `cm-add-link` - クイックボックスを使用してクイックメニューセクションにに新しいリンクを追加します。
* `cm-add-section` - クイックボックスを使用してクイックメニューに新しいセクションを追加します。
* `cm-delete-section` - クイックメニューの「選択」または「リンク」の削除ボタンに割り当てられます。
* `cm-qm-name` - 編集モードのクイックメニューアイテムに割り当てられます。クイックボックスにセクションデータを渡すために使用されます(リンク検索はこのクラスを使用して実行されます)。
* `cm-update-item` - \_クイックメニュー\_アイテム編集リンクに割り当てられます。アイテムのパラメータダイアログはクリックで展開されます。

## イメージ・ギャラリー

* `cm-image-gallery` - 画像ギャラリーの初期化
* `cm-previewer` - 画像をクリックした際に、より大きな画像が開くリンクに割り当てられます。ページは遷移しません。大きな画像は、hrefパラメーターで定義されてます。

```html
<a id="det_img_link_1553_140" rel="preview[product_images]" rev="preview[product_images]" class="cm-previewer" href="/professional/images/detailed/0/detailed_image_1386.jpg" title="img.jpg">
  <img class=" "  id="det_img_1553_140" src="/professional/images/thumbnails/0/120/img.jpg" width="120"  alt="img"  border="0" />
</a>
```

* `cm-thumbnails-mini` -商品詳細ページのサムネイル・ギャラリーの画像に割り当てられます。 画像がクリックされた際、サムネイルの指定と`cm-cur-item`クラスを割り当てるために使用します(`cm-cur-item`は`cm-thumbnails-mini`を持つすべてのアイテムから取り除かれます)。

## コンテンツのリアルタイム編集モード

* `cm-cur-template` - デザインモードで編集中の現在のテンプレートに割り当てられます。\
  また、編集中のテンプレートの変更を識別するために使用されます。デザインモードでのみ使用されます。
* `cm-item-modified` - デザインモードのテンプレートの編集に割り当てられます。このクラスが割り当てられたテンプレートの変更があった場合(エディタの左側にあるテンプレート・ツリーを使用)、既存の変更を知らせるメッセージが表示されます。
* `cm-lang-link` - 言語の変更のリンクに割り当てられます。言語は`name`属性で定義されます。
* `cm-select-list` - 言語選択のドロップダウンリストに割り当てられます。`cm-lang-link`要素のコンテナとして使用されます。 \
  例：翻訳モードで翻訳ダイアログが開かれている言語リスト

## 数量入力

* `cm-decrease` - `cm-value-change`で使用されます。入力値を減らすリンクに割り当てられます。入力値を１つずつ減らします。整数でない値は0に置き換えられます。

例：ショップフロントの数量フィールド付近の上/下の矢印

* `cm-increase` - `cm-value-changer`コンテナで使用されるます。入力値を増すリンクに割り当てられます。入力値を1つずつ増やします。整数でない数字は0に置き換えられます。
* `cm-value-changer` - 入力と`cm-increase/cm-decrease`ボタンの親コンテナに割り当てられます。

例：ショップフロントの商品数量フィールド

## ノードの複製

* `cm-first-sibling` - このクラスを持つ行は削除できませんので、削除アイコンは無効になっています。（複製元）
* `cm-image-field` - 要素の複製で画像数を正確に複製するための正規表現を定義します。

例：商品オプションを複製。ぞれぞれのオプションに指定された画像に対して、このクラスは画像に関連するフィールドに割り当てられます。

## ラッパー

* `cm-hidden-wrapper` - コンテンツがない場合に非表示になるラッパーに割り当てられます。すなわちブロックコンテンツの中身が空の場合、ラッパーは示されません。

## ページネーション

* `cm-history` - リンクに割り当てられます。このマイクロフォーマットを持つリンクがクリックされた際、現在のページがブラウザの閲覧履歴に保存されます。 jQueryの「history」プラグインが使用されています。
* `cm-back-link` - ブラウザの履歴を利用して以前のページに戻るページナビゲーションの描画結果のコンテナ。AJAXリクエストの後にスクロールするために使用されます。
* `cm-pagination-container` - ページナビゲーションの描画された結果のコンテナ。AJAXリクエストの後にスクロールするために使用されます。

## AJAX

* `cm-ajax` - このマイクロフォーマットが設定されたリンクがクリックされた際に、AJAXリクエストが実行されます。
* `cm-comet` - コメットモデルを使用してリフレッシュされたフォームに割り当てられます。
* 例：データベースのバックアップフォーム
* `cm-ajax-cache` - AJAXリクエストをキャッシュでき、`cm-ajax`と共に使用されます。
* `cm-ajax-force` - 2度目のAJAXレスポンスからJavascriptのコードを実行出来ます。`cm-ajax`と共に使用されます。
* `cm-ajax-close-notification` - used for the notifications that do not disappear on page change or on timer. When the close button is clicked, a close notification AJAX-request is sent.

通知が行われ、それが閉じられるタイマーまたはボタンに適用されます。閉じるボタンがクリックされた際、通知を閉じるためのAJAXリクエストを送信します。

* `cm-ajax-full-render` - `cm-ajax`と一緒にのみ使用出来ます。全体ページをリロードさせます。
* `cm-no-ajax` - このクラスがフォームの送信ボタンに割り当てられている場合にボタンがクリックされると、`cm-ajax`がフォームに割り当てられていた場合でも、通常の方法でフォームが送信されます。（AJAXを強制的に利用しない）
* `cm-ajax-content-input` - 例えば、検索リクエストに自動補完を可能にするためのピッカーで使用されま

自動補完の為のAJAXリクエストは入力が止まった後、500ミリ秒遅れで送信します。 受けとった検索候補は`rev`属性に記載されたコンテナにロードされます。自動補完のパターンは値のパラメータから取得されます。

例：出品者を選択する際に、マーケットプレイスのピッカーを表示する。

* `cm-ajax-content-more` - （大きなセレクトボックス）要素が表示されるようになった時、追加のコンテンツがロードされます。

例：選択のオプションの数が多い場合、出品者の選択はマーケットプレイスのピッカーを介します。

## AJAXでアップロードされた商品コンテンツ

* `cm-reload` - オプション変更で変更されたブロックに割り当てられます。\
  その後、このクラスをもつ全ての要素が更新されます。例は、

```php
{* Price *}
{capture name="price_`$obj_id`"}
<span class="cm-reload-{$obj_prefix}{$obj_id} price-update"
  id="price_update_{$obj_prefix}{$obj_id}">
...
```

オプションが変更され更新されると、価格は随時更新されます。

## カスタマイズ・モード

* `cm-template-box` - カスタマイズモードでのレンプレートとして存在するコンテナに割り当てられます。テンプレートを管理し、テンプレートの入れ子構造のレベルを決めるために使用されます。
* `cm-template-icon` - カスタマイズモードがオンになっている時に、テンプレートの編集アイコンに割り当てられます。\
  マウスホバーでテンプレートの適応範囲を強調します。 (`cm-template-over`を使用)。 マウスのホバーが外れると、ハイライトが無効になります。
* `cm-template-over` - 選択されたテンプレートの使用により表示されるコンテナに割り当てられます(カーソルがそれぞれ`cm-template-icon`アイコンの上にある)。 CS-Cartがカスタマイズモードの時、選択されたテンプレートの適応範囲にハイライトが使用されます。


# 通知システム

CS-Cartの通知は画面右上隅にポップアップして表示されます。

標準で5つの通知タイプがあります：

* `通知` (code type: N)
* `エラー` (code type: E)
* `警告` (code type: W)
* `チェックアウト時のエラー` (code type: O)
* `情報` (code type: I)

それぞれのタイプには色がつけられています：\
`通知`は緑、`エラー`は赤、`警告`はオレンジ、`チェックアウト時のエラー`はオレンジで右上隅に表示され、`情報`はポップアップのダイアログで表示されます。

＜画像＞

表示フォーマットは通知が呼び出されるエリアのCSSファイルに定義されています。\
通知は関数`fn_set_notification` (*/functions/fn.common.php*) を使用して生成されます。

空のコンテナはそれぞれのページのHTMLに書かれています。\
通知行われると`通知ブロック`はこのコンテナに表示されます。

通知は以下のレンプレートに定義されています：

* 管理パネル: `/backend/templates/common/notification.tpl`
* ショップフロント: `/themes/[theme name]/templates/common/notification.tpl`

## 通知の設定方法

通知には2つの方法があります：

* スクリプトの実行によってページがロードされる前に通知を表示される
* AJAXリクエストと共に、ページが表示された後および特定場合に表示される

1つ目はページがリロードされた際に表示される通知を作成するために使用します。\
2つ目はページをリロードすることなく、いくつかのJavascriptのイベントによって通知する際に使用します。

### まず1つ目の通知の生成過程を見てみましょう：

通知の関数はコントローラーコードから呼び出されます。例えば:

```php
<?php
if ($mode == 'add_to_cart') {
    fn_set_notification('E', fn_get_lang_var('warning'), $msg, true, 'insecure_password');
}
```

`fn_set_notification()` 関数は新しい通知内容を通知用の配列に追加します。

* テンプレーターは\_/backend/templates/common/notification.tpl や/themes/\[theme name]/templates/common/notification.tpl\_ を処理し、`fn_get_notifications()`を介して、それぞれの配列へすべての通知のリストを渡します。
* 通知用の配列が空でなかった場合、通知のHTMLコードが表示されます。

\`\*

### 2つ目はAJAXを使った通知の生成方法です

* ページを表示する際、テンプレーターは`/backend/templates/common/notification.tpl` や`/themes/[theme name]/templates/common/notification.tpl` を処理し、通知用のコンテナ(`<div class=”cm-notification-container”>`)を作成します。このコンテナは空かまたは1つ目の通知設定を含んでいます。
* 設定用関数はAJAXリクエストで実行されるコントローラーコードで呼び出されます。　例えば:

```php
<?php
if (defined('AJAX_REQUEST')) {
    fn_set_notification('E', fn_get_lang_var('warning'), $msg, true, 'insecure_password');
}
```

この関数は以下の場合、通知用配列に新しい要素を追加します。

* コントローラーの実行もしくは`exit()` 関数で処理が明示的に中断された場合、(/Tygh/Ajax.php) のAJAXクラス用のデストラクタが起動します。このデストラクタは通知内容をJSON形式の配列に変換し、この配列をJS関数`response` (*/js/tygh/ajax.js*) に引き渡します。
* この関数`response` は関数`ceNotification` (*/js/tygh/core.js*) を呼び出し、すべての定義されたAJAX通知配列が渡されます。通知の表示は`notification.append` メソッドにより`ceNotification` 関数で実行されます。

関数は通知のHTMLコードが宣言されたテンプレート`/backend/templates/common/notification.tpl` または `/themes/[theme name]/templates/common/notification.tpl` (`<div class=”cm-notification-container”>`)をコンテナに追加します。また、Javascriptの通知の作成を行います。

```javascript
$.ceNotification('show', {
    type: 'E',
    title: _.error,
    message: error_msg
});
```


# ツールチップ

## ツールチップとは

ツールチップはページ上の追加情報を表示するインターフェース要素です。

ユーザーはアイテムをクリックすることなく、カーソルを乗せるとそのアイテムについての追加情報が書かれているツールチップが表示されます。

## 使用法

CS-Cartのツールチップは管理パネルのフォームフィールドへ説明ボックスを追加するために使用します。

＜画像＞

## ツールチップの追加方法

ツールチップは共通のフォームフィールドとアドオンでは異なる方法で定義されています。

それぞれの場合を説明します。

## 共通のフォームフィールドへのツールチップ追加

これらのツールチップは特別な言語変数を定義することで追加されます。このようなツールチップ変数には2つのタイプがあります：

共通フォームへのツールチップは特別な言語変数を定義することで追加されます。\
このツールチップ変数は2つのタイプがあります：

1. このツールチップを追加するための変数の名前のみを含むタイプ
2. このツールチップを追加するため変数が使用されるテンプレートの変数の名前のみを含む、またはこの変数が使用されるテンプレート

### 1.変数の名前のみを含んだツールチップ

これらは以下の構造を持っています：\
「ttc\_LANGVAR\_NAME. Where LANGVAR\_NAME」 はこのツールチップを追加するための変数の名前です。\
このようなツールチップ変数を定義する場合、ツールチップは\_LANGVAR\_NAME\_ が使用されている全てのフォームに表示されます。

### 2.変数の名前とテンプレートを含んだツールチップ

これらは以下の構造を持っています

`tt_TEMPLATE_NAME` `LANGVAR_NAME`.`LANGVAR_NAME` とはこのツールチップを追加するための変数の名前です。\
`TEMPLATE_NAME` はこの変数が使用されたテンプレートです。\
このツールチップは定義されたテンプレートのみに表示されます。\
これは異なるページの同じフィールド名で同じツールチップが表示されないようにするために役立ちます。

ツールチップ変数がどのように形成されるかの例：

`tt_views_products_update_list_price` = tt\_ + TEMPLATE\_NAME + \_ + LANGVAR\_NAME = tt\_ + views\_products\_update + \_ + list\_price\_

### ツールチップ用の用語変数表示

目的のページに直接ツールチップ用のすべての言語変数を表示することが可能です。

これらを表示するには、選択したページのURLに以下のパラメータを追加してください：`stt`（ツールチップを表示する）と`ctpl`（キャッシュをクリアする）

例えば、以下のページに全てのツールチップを表示するには：

```http
http://example.com/admin.php?dispatch=products.update&product_id=180
```

↓

```http
http://example.com/admin.php?dispatch=products.update&product_id=180&stt&ctpl
```

2つの言語変数をもつポップアップボックスはそれぞれ並んで表示されます。\
変数値がすでに定義されている場合は、同じポップアップボックスでも表示されます。

＜画像＞

変数表示モードを無効にするには、ページのキャッシュをクリアしてください：

```http
https://example.com/admin.php?dispatch=products.update&product_id=180&ctpl
```

\`\*

### 例

例として、商品の詳細ページで`Name`フィールドに選択したテンプレートのにのみ表示されるツールチップを追加してみましょう:

```http
http://example.com/admin.php?dispatch=products.update&product_id=180
```

* ページを開き、URLの最後に`&stt&ctpl` を追加してください。

```http
https://example.com/admin.php?dispatch=products.update&product_id=180&stt&ctpl
```

* 目的のファイル名(この例のネームフィールド)にマウスポインターを合わせ、`tt_` とともに言語変数をコピーします：*tt\_views\_products\_update\_name*

Go to Administrtation > Languages > Translations and click + to add the new language variable.

* \_一般設定 > 言語 > 言語変数\_へ移動し、＋をクリックして新しい言語変数を追加します

tt\_views\_products\_update\_name ), `言語変数`フィールドでは前の手順( tt\_views\_products\_update\_name ) から変数を入力できます\
`値`フィールドではツールチップのテキストを入力します。

最後に`登録`をクリックします。

＜画像＞

* 商品詳細ページを開いてツールチップが正確に表示されるか確認します。

## アドオンの設定のためにツールチップを追加

アドオン用のツールチップは\_addon.xml file\_ (*/app/addons/add-on\_name*) で定義されています。

設定用のツールチップを追加するには、このXMLに値を定義します。\
ツールチップの翻訳はタグに定義されています:

```xml
<tooltip>Tooltip text</tooltip>
<tt_translations>
        <item lang="es">Tooltip translation</item>
</tt_translations>
...
```

例えば

`Anti Fraud`アドオンのコードでは`Maxmind license key`フィールドに`Hello`ツールチップを追加する際はこのようになります：

```xml
<settings>
    <sections>
        <section id="general">
            <name>General</name>
            <items>
                <item id="anti_fraud_key">
                    <name>Maxmind license key</name>
                    <type>input</type>
                    <default_value/>
                    <translations>
                        <item lang="ja">MaxMindのライセンスキー</item>
                        <item lang="es">Clave de licencia de MaxMind</item>
                        <item lang="fr">Clé de licence Maxmind</item>
                        <item lang="da">Maxmind licens nøglen</item>
                        <item lang="el">Αριθμός-κλειδί Maxmind</item>
                        <item lang="ro">Liciență cheie Maxmind</item>
                        <item lang="ru">Лицензионный ключ Maxmind</item>
                        <item lang="sl">Maxmind licenčni ključ</item>
                        <item lang="zh">Maxmind 许可证钥匙</item>
                    </translations>
                    <tooltip>Hello</tooltip>
                    <tt_translations>
                        <item lang="es">Hola</item>
                    </tt_translations>
                </item>
...
```


# 設定

CS-Cartには2種類の設定値があります。

* `コア設定` CS-Cart一般に影響し、インストールしたアドオンに関係なく機能します。
* `アドオン設定` それぞれのアドオンの動作に影響します。

設定はRegistryおよびSettingsクラスを使って管理されます。\
設定に関する情報は、データベースの名前が`settings_`で始まるテーブルに保存されます。\
管理者は、管理パネルで`コア設定`と`アドオン設定`を操作できます。

## 管理パネルでの設定の操作

コアおよびアドオンの設定は、管理パネルで表示・編集できます。\
設定は、設定が表示される場所や権限を`edition_type`により定義します。\
（添付資料1：edition\_typeの有効な値を参照）

* `MVE`（マーケットプレイス版）-この設定はマーケットプレイス版にのみ表示され、且つ左上隅のドロップダウンリストで\[ すべてのベンダー]モードが選択されている場合にのみ表示されます。
* `ULT`（СS-Cart通常版）-設定は、すべてのストアモードとストアフロントが選択されたときに表示されます。edition\_typeに応じて、各ストアフロントに設定用の独自の値を設定できます。ストアフロントが選択されたときに使用できない設定は非表示になります。

## コア設定

コア設定は、管理パネルの\[`基本設定`]にあります。\
設定はいくつかのセクションに分けられています。

* 全般
* 表示設定
* 運営会社
* ショップ
* 注文手続き
* Eメール
* サムネイル
* サイトマップ
* アップグレード
* セキュリティ設定
* ログ
* 販売レポート
* 設定ウィザード

＜画像＞

設定または設定のあるセクションは、`edition_type`によって表示される場合と表示されない場合があります（添付資料1：edition\_typeの可能な値を参照）。\
設定は、ストアフロントまたはベンダーによって異なる値を持つことができます。\
通常、コア設定はセクションに属している必要があり、設定がセクションに属していない場合、設定は非表示になります。

## アドオン設定

アドオン設定は、`アドオン`→`アドオンの管理`で管理されています。\
ほとんどのアドオンには独自の設定があり、アドオンの設定を開くには、次の2つの方法のいずれかを使用してください。

* アドオンの名前をクリック
* アドオンにカーソルを合わせると歯車アイコンが右側に表示されます。それをクリックして、設定を選択します。特定のedition\_typeが設定されている場合、設定が利用できない場合があります。

以下は`SEOアドオン`の設定です。

＜画像＞

## コードによる設定の操作

設定は`Registry`および`Settings`クラスを介してコードで管理されます。\
これらのクラスは、設定の値を追加、変更、取得するメソッドを提供します。

## Registry クラス

この`Registry`クラスには、アプリケーションの様々な設定を制御しています。\
このクラスは、設定のキャッシュも実行します（\_var/cache/registry\_ディレクトリを参照）。\
`Registry`クラスで設定を制御する方法は次のとおりです。

* コア設定またはアドオン設定の値の取得：

```php
<?php
Registry::get('settings.[セクション名].[設定名]');
Registry::get('addons.[アドオン名].[アドオンの設定名]');
```

* コア設定またはアドオン設定値の変更：

```php
<?php
Registry::set('settings.[セクション名].[設定名]', '[新しい設定値]');
Registry::set('addons.[アドオン名].[アドオンの設定名]', '[新しい設定値]');
```

## Settingsクラス

この`Settings`クラスは、データベースに保存されているCS-Cartの設定を操作するための拡張APIです。このクラスには多くのメソッドがあり、設定値の読み取り、変更、および削除などが可能です。

たとえば、`Settings`クラスで`elements_per_page`（1ページに表示するその他の要素数）（\[`基本設定`]→\[`表示設定`]）を管理する方法は次のとおりです。

* 設定（の存在）を確認する

```php
<?php
Settings::instance()->isExists('elements_per_page', 'Appearance');
```

* 設定の値を取得する

```php
<?php
Settings::instance()->getValue('elements_per_page', 'Appearance');
```

設定値の変更

```php
<?php
Settings::instance()->updateValue('elements_per_page', $new_value, 'Appearance');
```

## アドオン設定

## addon.xmlで設定を定義する

アドオン設定は、そのアドオンのディレクトリにある`addon.xml`ファイルで定義されています。\
設定のリストが`addon.xml`の`<settings>`セクションに追加されています。\
`<settings>`セクションの属性は次のとおりです。

* `layout`-アドオンの設定でウィンドウの外観を決定します。デフォルトでは、アドオンの設定はポップアップウィンドウに表示されます。`layout="separate"`を指定すると、設定は個別のページで表示されます。
* `edition_type` - CS-Cartのどのエディションで動作するかを指定します。

> 📘
>
> これらのパラメーターは両方ともオプションです。

たとえば、`<settings layout="separate" edition_type="ROOT">`は、\
設定が別のページに表示され、「`すべてのショップモード`」や「`すべてのベンダーモード`」で使用できることを意味します。

## `<settings>`セクションの構造

```xml
<settings layout="separate" edition_type="ROOT,ULT:VENDOR">
        <sections> <!-- アドオンの設定セクション -->
            <section id="section1"> <!-- 設定パネルのセクション。設定のセクションには、次の属性があります。
                id—設定のセクションの識別子(setting_id):
                Registry::get('addons.[addon_id].[setting_id]')
                edition_type—利用できるエディションや権限を設定。複数の場合はカンマで区切る
                -->
                <items> <!-- 設定のアイテム -->
                    <item id="header"> <!-- The settings
                        id—設定の識別子
                        edition_type—利用できるエディションや権限を設定。複数の場合はカンマで区切る
                    　　　　　　-->
                        <type>header</type> <!-- 指定可能な値については別のページを参照:
                              input, textarea, password, checkbox, selectbox,
                              multiple select, multiple checkboxes,
                              countries list, states list,
                              file, info, header, template
                              -->
                        <default_value>radio_1</default_value> <!-- 設定のデフォルト値を指定できます -->
                        <variants> <!-- 次のタイプでは選択肢を設定できます:
                        selectbox, multiple select,
                        multiple checkboxes, combo select -->
                            <item id="radio_1"></item> <!-- id—選択肢の識別子-->
                        </variants>
                </items>
            </section>
</settings>
```

## 設定を操作するための関数

設定の値の選択肢は`variants.functions`および`actions.functions`の2種類の関数を使って変更・追加が可能です。

* `variant.functions`は、データベースにそれらの選択肢を記録せずに、選択肢のリストを生成します。設定の値の選択肢は、設定ページを開くたびに動的に生成されます。\
  これらの機能は、\_\[addon\_name]/schemas/settings\_ディレクトリの中の`variants.functions.post.php`ファイルに記述してください。\
  関数の名称は次のようにする必要があります\
  `fn_settings_variants_addons_[addon_name]_[setting_name]()`

例）\
`my_changes`アドオンに設定値`exampleID`が設定されていると仮定します。\
この設定の値の選択肢を生成するために、\_my\_changes/schemas/settings\_ディレクトリの`variants.functions.post.php`ファイルを作成します。このファイルには、`fn_settings_variants_addons_my_changes_example()`という関数が含まれている必要があります。

* `actions.functions`はアドオンがインストール／アンインストールされるときに呼び出されます。これらの関数は、アドオンのインストール中にデータベースにアドオンの設定を保存するフィールドを生成します。また、アドオンがアンインストールされるときにこれらのフィールドを削除します。

これらの関数は、`[addon_name]/schemas/settings`の`actions.functions.post.php`ファイルに配置する必要があります。関数の名前は次のように命名してください。

my\_changesアドオンにexampleID が設定されていると仮定します。この設定用の関数を作成するには、\_my\_changes/schemas/settings\_ディレクトリに`actions.functions.post.php`ファイルを作成します。このファイルには、`function fn_settings_actions_addons_my_changes_example()`という関数が含まれている必要があります。

## 設定データの保存

コア設定およびアドオン設定に関するデータはデータベースに保存されます。これらデータを含むテーブルの名前は`settings_`で始まります。

この`settings_sections`テーブルには、設定が属するセクションのリストが含まれています。このテーブルには次のフィールドがあります。

* `section_id`-セクションの識別子。
* `parent_id`-親セクションの識別子。
* `edition_type`— 設定のセクションが利用可能となる情報。このフィールドは、セクションがCS-Cart通常版/マーケットプレイス版で使用可能かどうか、および管理者が持つ必要があるアクセスレベルを決定します。このフィールドには、1つまたは複数の値をコンマで区切ることで含めることができます。（例：settings\_：）
* `name`-セクションの名称
* `position`-設定セクションでの表示位置。
* `type`-セクションのタイプ：
* `CORE`—コア設定のセクションです。このタイプのすべてのセクションは、管理パネルの\[設定]ページにリストアップされています。（settings.phpコントローラーを参照）
* `ADDON`-アドオン設定を含むセクションです。このタイプのセクションはすべて、ポップアップウィンドウまたは別のページに表示され、アドオンの設定が含まれます（addons.phpコントローラーを参照）。
* `TAB`-設定のサブセクション（タブ）です。コア設定とアドオン設定の両方にタブを設定できます。各サブセクションには、parent\_idフィールドに親セクションのIDがあります。
* `SEPARATE_TAB`-設定のサブセクション（タブ）です。コア設定とアドオン設定の両方にタブを設定できますが、このタブは個別のコンテナとして追加されます。各サブセクションには、parent\_idフィールドに親セクションのIDがあります。

{% hint style="info" %}
HINT

COREまたはADDONタイプのセクションのみがサブセクションを持つことができます。
{% endhint %}

データベースのエントリの例は次の表のとおりです。

| section\_id | parent\_id | edition\_type | name       | position | type |
| ----------- | ---------- | ------------- | ---------- | -------- | ---- |
| 4           | 0          | ROOT,VENDOR   | Appearance | 20       | CORE |

管理パネルでセクションのIDを確認する方法は次のとおりです。

`コア設定`：\[基本設定]ページに移動し、セクションを選択します。セクションの名前は、URLのsection\_idパラメーターとしてブラウザーのアドレスバーに表示されます。\
たとえば、表示設定セクションには`section_id`として`Appearance`があります。URLは次のようになります。\_example.com/admin.php?dispatch=settings.manage§ion\_id=Appearance\_

`アドオン設定`：`アドオン`→`アドオンの管理`に進み、アドオンの歯車アイコンをクリックします。\[アンインストール]アクションにカーソルを合わせると、ブラウザーウィンドウの下部にURLが表示されます。そのURLにはコードでアドオンを参照できる名前のaddonパラメーターが含まれます。

たとえば、「この商品を買った人はこんな商品も買っています」アドオンではアドオンのIDは`customers_also_bought`と名付けられます。URLは次のようになります（この例にはURLの一部しか含まれていないことに注意してください）：\
*example.com/admin.php?dispatch=…\&addon=customers\_also\_bought&…*

## \_settings\_objects\_テーブル

この`settings_objects`テーブルには、コア設定とアドオン設定のリスト、およびそれらの値が含まれています。このテーブルには、次の主要なフィールドがあります。

* `object_id`-設定の識別子。
* `edition_type`— この設定が利用可能になるCS-Cartのエディションや権限に関する情報。
* `name`-設定の名称
* `section_id`-設定が属するセクションの識別子。
* `section_tab_id`-タブの識別子（設定がタブにある場合）。
* `type`-設定のタイプ。
* `value`-設定の値。
* `position`-設定の表示順

データベース内のエントリー例を次に示します— `company_name`（\[`基本設定`]→\[`運営会社`]`会社名`）：

| object\_id | edition\_type   | name          | section\_id | section\_tab\_id | type | value | position |
| ---------- | --------------- | ------------- | ----------- | ---------------- | ---- | ----- | -------- |
| 1          | ROOT,ULT:VENDOR | company\_name | 5           | 0                | I    | 会社名   | 0        |

設定の識別子（object\_id）を確認するには、設定のあるページのコードを表示します。たとえば、`elements_per_page`（1ページに表示するその他の要素数）の識別子を確認しましょう（一般設定表示設定）。

＜画像＞

設定上でマウスの右ボタンをクリックし、要素の検証を選択します。設定の識別子は、`name`属性の角括弧\[]にあります。その値が`object_id`です

＜画像＞

## *settings\_variants* テーブル

`settings_variants`テーブルには、次の種類の設定の選択肢：selectbox、multiple select、multiple checkboxesのリストが含まれます。管理者は、設定の値として事前に定義された選択肢のいずれかを選択することができます。

たとえば、\[`基本設定`]→\[`ログ`]セクションに\[ `注文`]という設定があります。\
選択された選択肢に関する情報は、`log_type_orders`として保存されています（`settings_objects`テーブルを参照）。この設定で使用可能なすべての選択肢のリストは`settings_variants`に保存されます。

＜画像＞

object\_idフィールドごとに、設定で可能なすべての値のリストを取得できます。テーブルに設定の選択肢がない場合、選択肢は`variant.functions`を介して動的に形成されることを意味します。

## `settings_descriptions`テーブル

この`settings_descriptions`テーブルには、セクションの名前、設定、選択肢、ツールチップの言語データが含まれています。テーブルの主なフィールドは次のとおりです。

* object\_id-設定の識別子。
* object\_type-次のタイプのいずれか：
* V-設定値のバリアントの名前。（settings\_variantsテーブルを参照）
* O-設定の名前（settings\_objectsテーブルを参照）。
* S-セクションの名前（settings\_sectionsテーブルを参照）。
* lang\_code-言語コード。
* value-指定された言語の設定/セクション/値の名前。
* tooltip-設定/セクション/値のツールチップ

このテーブルには、現在インストールされているすべての言語の情報が含まれています。\
特定の値をデータベースで検索するときは`object_type`を`lang_code`や`object_id`と同様に考慮する必要があります。

## 添付資料1：edition\_typeの値

{% hint style="info" %}
HINT

アドオンには、`edition_type`をカンマで区切って複数の値を含めることができます。値を指定しない場合、`ROOT`と同じように動作します。
{% endhint %}

| 値                | 説明                                                                                                      |
| ---------------- | ------------------------------------------------------------------------------------------------------- |
| `NONE`           | 設定はインターフェイスに表示されず、編集できません。                                                                              |
| `ROOT`           | 設定はインターフェイスに表示され、編集可能ですが、「全てのストア/全てのベンダー」モードでのみです。                                                      |
| `VENDOR`         | 「全てのストア/全てのベンダー」モードと、特定のストアフロント/ベンダーが選択されたときに表示されます。カンマの後にULT:NONEを追加すると、ストアフロントが選択されている場合にのみ設定を編集できます。 |
| `MVE:NONE`       | マーケットプレイス版には表示されません。設定をCS-Cart通常版に表示するには、カンマの後に別の値、ULT:ROOT.などを追加する必要があります。                             |
| `MVE:ROOT`       | マーケットプレイス版に表示されますが、「全ての出品者」モードでのみ表示されます。                                                                |
| `ULT:NONE`       | CS-Cart通常版には表示されません。マーケットプレイス版にのみ設定を表示するには、カンマの後に、例えば ROOT や MVE:ROOTのような別の値を追加する必要があります。               |
| `ULT:ROOT`       | CS-Cart通常版に表示されますが、「全てのショップ」モードが選択されている場合のみです。                                                          |
| `ULT:VENDOR`     | この設定は、「全てのショップ」モードと特定のショップフロントが選択されたときに表示されます。カンマの後に ULT:NONEを追加すると、ストアフロントが選択されている場合にのみ設定を編集できます。      |
| `ULT:VENDORONLY` | 設定はインターフェイスに表示されませんが、コードを使用して特定のストアフロント向けに表示されます。                                                       |

## 添付資料2：設定用の値

設定のタイプは、パラメーターの`addon.xml`ファイルで指定されます（セクションの構造を参照）。

例として、`new_setting`の設定を追加しましょう。これは`checkbox`タイプで`N`（チェックボックスをオフにした）をデフォルト値とします。この設定は、アドオンの`addon.xml`ファイルに追加する必要があります。実際のコードは次のようになります。

```xml
<sections>
   <section id="general">
       <items>
           <item id="new_setting"> //新しい設定値
           <type>checkbox</type> // ここで種類を設定します
           <default_value>N</default_value> //デフォルト値
            </item>
         </items>
   </section>
</sections>
```

では次の値を指定できます（括弧内の文字は、これらのタイプがデータベースに保存される際の`Type`の値です）。

* `selectable_box`（`B`）-2つのリストで構成される複数選択ボックス：1つのリストは可能な値、もう1つのリストは選択された値
* `сheckbox`（`С`）—チェックボックス
* `hidden`（`D`）-ユーザーには表示されない非表示の設定
* `template`（`E`）-カスタムテンプレートのファイル名。テンプレートは、`design/backend/templates/addons/[addon名]/settings`ディレクトリに配置する必要があります。設定の代わりにテンプレートのコンテンツが表示されますが、これはそのアドオンがアクティブな場合のみです。
* `file`（`F`）-ファイル選択のフィールド（アップロードなど）
* `checkboxes`（`G`）-複数の選択肢を選択できるチェックボックスのリスト。`variant.function`の関数を介して選択肢が追加されます。これを利用して`selectbox`（`K`）設定の選択肢のリストを作成できます。
* `header`（`H`）-設定のあるブロックまたはコンテンツの見出し
* `input`（`I`）-テキストを入力するための入力フィールド

```xml
<type>input</type>
```

* `selectbox`（`K`）-選択肢の中からいずれかを選択できるドロップダウンリスト：使用可能な選択肢は、選択した`checkboxes`（`G`）設定の値に依存します。

```xml
<type>selectbox</type>
```

* `multiple_select`（`M`）-スクロール可能な値のリストと、複数の値から選択する機能。このリストを追加するとき、`variants`パラメーターで可能な値を指定します。

```xml
<item id="multiple_select">
   <type>multiple select</type>
   <variants>
       <item id="select_box_1"></item>
       <item id="select_box_2"></item>
       <item id="select_box_3"></item>
   </variants>
</item>
```

* `multiple_checkboxes`（`N`）-複数のチェックボックスをチェックする機能を持つチェックボックスのリスト。リストを追加するとき、チェックボックスは`variants`パラメーターで指定されます
* `info`（`O`）- `<handler>`パラメータで渡された関数の結果が表示されます。例として設定で呼び出される`fn_get_information`関数の出力を表示してみましょう。

```xml
<item id="information">
   <type>info</type>
   <handler>fn_get_information</handler>
</item>
```

* `password`（`P`）-パスワードを入力するためのフィールド。入力したすべての記号は\*でマスク表示されます。

```xml
<type>password</type>
```

* `radiogroup`（`R`）—ラジオボタンのグループ。一度に選択できるのは1つだけです。ボタンの値は、variantsパラメーターで指定されます。

```xml
<item id="radiogroup">
   <type>radiogroup</type>
   <default_value>radio_2</default_value>
   <variants>
       <item id="radio_1"></item>
       <item id="radio_2"></item>
   </variants>
</item>
```

* `selectbox`（`S`）-選択肢の中から1つだけ選択できるドロップダウンリストです。リストを追加するときは、variantsパラメーターで可能なバリアントを指定します。

```xml
<item id="selectbox">
   <type>selectbox</type>
   <variants>
       <item id="select_box_1"></item>
       <item id="select_box_2"></item>
   </variants>
</item>
```

* `textarea`（`T`）-複数行のテキストを入力するためのフィールド
* `input`（`U`）-数字のみを入力するフィールドです。数字以外は削除されます。
* `states_list`（`W`）-都道府県または地域を選択するためのドロップダウンリスト
* `countries_list`（`X`）—国を選択するためのドロップダウンリスト
* `permanent_template`（`Z`）-カスタムテンプレートのファイル名。アドオンが無効になっていても、常に利用可能です。ファイルは\_design/backend/templates/addons/\[addon名]/settings\_ディレクトリに配置する必要があります。たとえば`permanent_template.tpl`のコンテンツを表示する`permanent_template`設定を追加してみましょう。

```xml
<item id="permanent_template">
    <type>permanent_template</type>
    <default_value>permanent_template.tpl</default_value>
</item>
```


# コア関数

CS-Cartのコア関数は`app/functions`ディレクトリに格納されています。

これらの関数はCS-Cartの全てのコア機能を実装しており、目的や使用エリア（管理パネル／ショップフロント）によってグループ化され別々のファイルに書かれています : `fn.catalog.php`, `fn.cart.php`

PHP フック を利用することでコア関数のデフォルトの動作を拡張したり無効化ことが出来ます。


# イベントの通知

Event Notifications - 新しい通知方法

＜画像＞

{% hint style="info" %}
MEMO

本機能は、バージョン4.11.1以降のCS-Cartに実装されています。
{% endhint %}

CS-Cartは注文の作成、注文のステータスの変更、商品のレビューや注文での出荷の作成などの各イベントに関する複数の通知の仕組みを提供します。

これは以下の主要コンポーネントで構成されています。

* `[Events](#events)`（イベント）
* `[Event dispatcher](#event-dispatcher)`（イベントディスパッチャ）
* `[Messages](#messages)`（メッセージ）
* `[Transports](#transports)`（トランスポート）
* `[Receivers](#receivers)`（レシーバー）
* `[Notification settings](#notification-settings)` （通知設定 ）

{% hint style="warning" %}
SAMPLE

Event Notificationsを実装したアドオンの例 <https://github.com/cscart/addon-notification-events-example>
{% endhint %}

## Events

Events（イベント）は以下の要素で構成されています。

* イベント識別子
* そのイベントに関連する一連のデータ

`例`：\
・イベント「注文の詳細の変更」の識別子は`order.updated`。\
・`fn_get_order_info`関数から受け取った注文に関するデータのセット`$data['order_info']`。

#### 独自のイベントを追加する方法

スキーマ `notifications/events.php` には、すべてのEvents、Receivers、およびTransportsを記述します。\
スキーマは`Tygh::$app['event.events_schema']`サービスを介して利用できます。

スキーマの要素には、次の構造があります。

```php
(string) EventId => [
    'group' => (string) GroupId,
    'name' => [
        'template' => (string) TemplateLanguageVariable,
        'params' => [
            (string) SubstitutionName => (string) Substitution
            ...
        ],
    ],
    'data_provider' => (callable) DataProvider,
    'receivers' => [
        (string) ReceiverId => [
            (string) TransportId => BaseMessageSchema::create([
                'area'            => (string) area,
                'from'            => (string) from,
                'to'              => (callable) DataValue::create(key),
                'template_code'   => (string) template_code,
                ...
                'language_code'   => (callable) DataValue::create(parent_key.key, default_value),
                'data_modifier'   => (callable) function (array $data) {
                    return array_merge($data, $added_data_value);
                }
            ]),
            ...
        ],
        ...
    ],
],
```

* `EventId` - イベントの識別子。`TyghNotificationsEventDispatcher::dispatch` の最初の引数として使用されます。
* `GroupId` - イベントグループの識別子。ナビゲーションをわかりやすくするために、通知設定ページで使用されます。
* `TemplateLanguageVariable` - 通知設定でイベントを表す言語変数の名前。
* `SubstitutionName`および`Substitution`—言語変数をイベントの詳細に適合させるパラメーターの名前とその値。
* `DataProviderNotification\DataProviders\DataProvider` - インターフェイスを実装します。`\Tygh\Notifications\EventDispatcher::dispatch`に渡された`data`に基づいてイベント固有のフィールドを取得するために使用されます。
* `ReceiverId` - Receivers(受信者)の識別子。既存の受信者識別子は、`Tygh::$app['event.receivers_schema']`から取得できます。\
  \_`TransportId` - Transports(トランスポート)の識別子。トランスポートは`\Tygh\Notifications\Transports\ITransport::getId`で提供する必要があります。\
  \_`BaseMessageSchema` - 送信用に準備されたデータを使用して、schemaクラスのインスタンスを作成します。入力パラメータには、通知の送信に必要な処理されたデータを含める必要があります。テキスト(`area`、`from`、`template_code`)または`DataValue`クラスのインスタンスにすることができます。\
  \*`DataValue` - 入力配列からキーでデータを取得できるクラス。キーが配列にない場合は、`default_value`が使用されます。デフォルトでは`null`。
* `data_modifier` - 関数内の`data`に渡されるデータの追加変更を行うことを可能にする呼び出し可能なパラメータ。

#### イベントを登録する方法

* 一意のイベント識別子（EventId）を選択します。
* 新しいイベントが属するグループを選択します。\
  イベントが新しいグループに属している場合は、同じ識別子`GroupId`とイベントグループの名前を値として使用して言語変数を作成します。
* イベントの名前を形成するためのテンプレートを格納する言語変数を作成します(`TemplateLanguageVariable`)。
* イベント名テンプレート(`SubstitutionName`、`Substitution`)の置換のリストを作成します。\
  イベントの名前に置換がない場合は、'params'配列を空のままにする必要があります。
* イベントに関する通知を受信する必要があるユーザータイプの識別子を指定します(`ReceiverId`)。
* `data`から来るイベント固有の`DataProvider`を処理するために、実装された`DataProvider`の名前を指定します。
* 受信者タイプごとに、次のように指定します。
  * 通知の受信方法(TransportId)。
  * 現在の受信者に固有のデータで、`BaseMessageSchema`クラスのインスタンスに処理されます(必要に応じて`DataValue`を使用)。

## Event Dispatcher

ディスパッチャーは、イベントをトリガーするシステムコンポーネントです。イベントをトリガーすると、受信者にメッセージを送信します。

イベントディスパッチャーは、`Tygh::$app['event.dispatcher']`サービスに登録されています。

#### イベントをトリガーする方法

通知を送信する必要がある場所でイベントディスパッチャを呼び出します。

```php
Tygh::$app['event.dispatcher']->dispatch(
        'EventId', 
        [
                'order_info' => $order_info, 
                'user_info' => $user_info, 'settings' => $settings
        ]
);
```

## Messages

メッセージは、イベントディスパッチャに渡されたデータから、スキーマに基づいて形成されます。メッセージには、このメッセージタイプに接続されたトランスポートを介してそのメッセージを送信するために必要なすべてのデータが含まれています。

送信用に準備されたデータの配列は、`events.php`イベントスキーマのルールに基づいて作成されます。

実装例：\
注文の状態に関する通知のためにデータを準備します。この通知は管理者のメールに送信されます。

```php
'receivers' => [
    UserTypes::ADMIN => [
        MailTransport::getId() => MailMessageSchema::create([
            'area'            => 'A',
            'from'            => 'company_users_department',
            'to'              => 'company_users_department',
            'reply_to'        => DataValue::create('user_data.email'),
            'template_code'   => 'activate_profile',
            'legacy_template' => 'profiles/activate_profile.tpl',
            'company_id'      => DataValue::create('user_data.company_id'),
            'language_code'   => Registry::get('settings.Appearance.backend_default_language'),
            'data_modifier'   => function (array $data) {
                return array_merge($data, [
                    'url' => fn_url('profiles.update?user_id=' . $data['user_data']['user_id'], 'A'),
                ]);
            }
        ]),
    ],
],
```

`DataValue`メッセージを形成するためにディスパッチャーに渡された配列からキーでデータを取得できます。\
`data_modifier`で指定された関数を使用すると、データのより複雑な変更を行うことができます。

メッセージスキーマはメッセージを作成する責任があります。イベントに関する処理されたデータを取得し、データの有効性をチェックします。

スキーマは、特定のトランスポート用に実装されています。

* `\Tygh\Notifications\Transports\Mail\MailMessageSchema` - 電子メールに送信される通知のスキーマ。
* `\Tygh\Notifications\Transports\Internal\InternalMessageSchema` - 通知センターに送信される通知のスキーマ。

#### 独自のメッセージを追加する方法

メッセージを追加するには：

* メッセージデータのプロバイダを追加します。プロバイダーは、`\Tygh\Notifications\DataProviders\IDataProvider`インターフェイスを実装するか、既存の基本データプロバイダークラスを拡張する必要があります。
* 特定のトランスポートのイベントスキーマにそのプロバイダーを指定します。
* イベントスキーマで、ディスパッチャーに渡される入力データを処理するためのルールを指定します。

#### メールで送信されるメッセージを追加する方法

これらのメッセージには、`Tygh::$app['mailer']`サービス経由でメールを送信するために必要なデータが含まれています。

新しいメールメッセージを作成するには:

* イベントスキーマで、`\Tygh\Notifications\Transports\Mail\MailMessageSchema`に渡されたデータを準備するためのルールを作成します。
* スキーマの`create`メソッドに渡される配列には、次のプロパティが含まれています。
* `to` - メッセージの受信者。
* `from` - メッセージの送信者。
* `reply_to` - メッセージの返信先。
* `template_code` - メールテンプレートのコード。
* `legacy_template` - メールテンプレートの名前（ストアで古いメールテンプレートが使用されている場合）。
* `language_code` - Eメールが送信される言語のコード。
* `company_id` - Eメールが送信されるcompany ID（識別子）。
* `area` - Eメールの送信元：管理パネルまたはストアフロントから。
* `$data` 配列に渡される他のキーは、Eメールテンプレートの置換用のデータです。

#### 通知センターに送信されるメッセージを追加する方法

これらのメッセージには、`Tygh::$app['notifications_center']`サービスを介して通知センターで通知を作成するために必要なデータが含まれています。

新しいメールメッセージを作成するには:

1. イベントスキーマで、`\Tygh\Notifications\Transports\Internal\InternalMessageSchema`で渡されたデータを準備するためのルールを作成します。
2. スキーマの`create`メソッドに渡される配列には、次のプロパティが含まれています。

* title-通知のタイトル。
  * `template` - 言語変数の名前。
  * `params` - 通知タイトルのテンプレート内の置換のリスト。タイトルに置換がない場合は、配列を空のままにする必要があります。
* `$message` - 通知のテキスト
  * `template` - 言語変数の名前。
  * `params` - 通知テキストのテンプレート内の置換のリスト。テキストに置換がない場合は、配列を空のままにする必要があります。
* `severity` - 通知の重大度（`\Tygh\Enum\NotificationSeverity`を参照）。
* `section` - メッセージが表示される通知センターのタブ。
* `tag` - 通知にマークが付けられるタグ。
* `area` - 通知が表示される領域：管理パネルまたはストアフロント。
* `action_url` - 通知をクリックした後にユーザーが誘導されるリンク。
* `timestamp` - 通知が作成された時刻。
* `recipient_search_method` - 通知を作成する必要のあるユーザーを検索する方法（`\Tygh\Enum\RecipientSearchMethods`を参照）。\
  次の検索方法を使用できます。
  * `\Tygh\Enum\RecipientSearchMethods::USER_ID` - ユーザーIDによる検索。
  * `\Tygh\Enum\RecipientSearchMethods::UGERGROUP_ID` - ユーザーグループIDによる検索（通知はグループ内のすべてのユーザーに対して作成されます）。
  * `\Tygh\Enum\RecipientSearchMethods::EMAIL` - ユーザーの電子メールによる検索。
* `recipient_search_criteria` - ユーザー検索条件:
  * `recipient_search_method = \Tygh\Enum\RecipientSearchMethods::USER_ID` - ユーザーID
  * `recipient_search_method = \Tygh\Enum\RecipientSearchMethods::UGERGROUP_ID` - ユーザーグループIDの場合
  * `recipient_search_method = \Tygh\Enum\RecipientSearchMethods::EMAIL` - ユーザーの電子メールの場合

## Transports

トランスポートは、特定のタイプのメッセージの実際の送信を処理します。

実装例：

* `\Tygh\Notifications\Transports\MailMailTransport` - 電子メールにメッセージを送信し、\
  `\Tygh\Notifications\Transports\Mail\MailMessageSchema`に準拠したメッセージを動作します。
* `\Tygh\Notifications\Transports\InternalTransport` - 通知センターにメッセージを送信し、`\Tygh\Notifications\Transports\Internal\InternalMessageSchema` に準拠するメッセージを処理します。

#### 独自のトランスポートを追加する方法

システムで使用されるトランスポートの識別子のリストは、`Tygh::$app['event.transports_schema']`サービスから入手できます。

独自のトランスポートを追加するには：

1. トランスポートがシステムに登録される識別子(`TransportId`)を選択します。
2. `\Tygh\Notifications\Transports\ITransport`インターフェイスを実装するクラスを作成します。
3. そのクラスの`getId()`メソッドで選択した識別子を指定します。
4. そのトランスポートの新しいプロバイダーを`Tygh::$app['event.transports.{TransportId}']`に登録します。
5. event.transport.TransportIdを識別子として、トランスポートの名前を値とした言語変数を作成します。

## Receivers

すべてのイベントには、イベントについて通知される可能性のある受信者のグループがあります。たとえば、注文状況の変更は、お客様、店舗管理者、およびその商品の出品者に通知を送信できます。

#### 独自のレシーバーを追加する方法

受信者の識別子のリストは、`Tygh::$app['event.receivers_schema']`サービスから入手できます。

新しいタイプのレシーバーを追加するには：

1. `get_notification_rules`フックポイントを使って、受信者の識別子を`$force_notification`配列に追加します。
2. `event.receiver.ReceiverId`を識別子として、受信者タイプの名前を値とした言語変数を作成します。
3. 受信者をイベントスキーマに追加し、これらの受信者に通知を配信するトランスポートを指定します。

## Notification settings

デフォルトではイベントが`Tygh::$app['event.events_schema']`に存在する場合、イベントはすべてのトランスポートを介してすべての受信者に通知する必要があると仮定されます。この動作は通知設定によって変更されます。それらは、どの受信者がイベントに関する通知を取得する必要があるか、およびどのトランスポートを介して取得する必要があるかを記述します。

{% hint style="info" %}
HINT

通知設定は、`一般設定→通知`で指定されています。 通知はイベントごと、トランスポートごとに、すべてのタイプの受信者に設定できます。
{% endhint %}

通知を設定するためのページには、関連するデータのみが表示されます。

以下のページは表示されません：

* 受信者のないイベント。
* レシーバーがどのイベントにも接続されていない場合。
* イベントを受信者に送信しないトランスポート。

`notification_settings`ルールへの変更は、データベースのテーブルに保存されます。\
それらは`Tygh::$app['event.notification_settings']`サービスから入手できます。

#### 通知ルールのオーバーロード

オーバーロード（設定の上書き）を使用すると、通知設定で必要な場合でも、特定の受信者にイベント通知を送信しないようにすることができます。

オーバーロードのセットは、`\Tygh\Notifications\Settings\Ruleset`クラスのオブジェクトであり、`Tygh::$app['event.notification_settings.factory']`ルールファクトリによって作成されます。イベントがトリガーされると、一連のオーバーロードがパラメータの1つとして渡されます。

例：注文編集ページには、「顧客に通知」、「注文部門に通知」、「ベンダーに通知」のチェックボックスがあります。以下のようなルールを記述すると、通知設定で必要な場合でも注文ステータスの変更に関する通知を送信しないようにすることができます。

```php
$notification_rules = Tygh::$app['event.notification_settings.factory']->create([
    UserTypes::CUSTOMER => false,
    UserTypes::ADMIN    => true,
    UserTypes::VENDOR   => true,
]);

Tygh::$app['event.dispatcher']->dispatch(
    'order.updated',
    $order_info,
    $notification_rules
);
```

#### 新しい通知システムの使用を開始する方法

1. アドオン内で、`mailer`サービス（`Tygh::$app['mailer']->send()`）または非推奨の`TyghMailer`クラス（`\Tygh\Mailer::sendMail()`）を介してメールが送信されるすべての場所を検索します。
2. このような状況に合わせてイベントを作成します。この章の「`独自のイベントを追加する方法`」を参照してください。
3. （オプション）通知センターの通知を介してユーザーに通知するための代替メカニズムを実装します。
4. 電子メールの送信を、 `event.dispatcher`サービスを介したイベントのトリガーに置き換えます：\
   `Tygh::$app['event.dispatcher']->dispatch()`


# 言語変数

CS-Cart（通常版・マーケットプレイス版）やアドオンは、言語変数によって、国際化やローカライズが可能です。

あらゆる言語のテキストは、PHPコードやSmartyテンプレートファイルに直接記述されていません。言語の表示については、特別な関数が呼び出されます。言語変数のID（名前）が関数に渡され、ユーザーの環境に応じた言語でテキストが返されます。

## 言語変数の表記について

## POファイル

CS-Cart（通常版・マーケットプレイス版）とそのアドオンの翻訳データは、POファイルに保存されます。各言語には、言語変数の値を格納する個別のPOファイルが必要です。

POファイルは一般的に広く使用されている形式です。\
ローカライズに関連する多くのサービスは、POファイルをインポート・エクスポートできます。\
たとえば、Crowdinを使用してCS-Cartを翻訳することが可能です。

{% hint style="info" %}
HINT

POファイルの詳細については、[GNUプロジェクトのWebサイトをご覧ください](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html)（英語）。
{% endhint %}

POファイルは、CS-Cartをインストールしたディレクトリのvar/langs以下のディレクトリにあります。これらのファイルは専用のアプリケーション、または一般的なテキストエディターで編集することが可能です。

## 言語変数の構造

英語のPOファイル内の言語変数は次のようになります。

```shell
msgctxt "Languages::email_marketing.subscription_confirmed"
msgid "Thank you for subscribing to our newsletter"
msgstr "Thank you for subscribing to our newsletter"
```

以下はフランス語のPOファイルです。同じ言語変数があります。

```shell
msgctxt "Languages::email_marketing.subscription_confirmed"
msgid "Thank you for subscribing to our newsletter"
msgstr "Merci de votre inscription à notre newsletter"
```

日本語では以下のようになります。

```shell
msgctxt "Languages::email_marketing.subscription_confirmed"
msgid "Thank you for subscribing to our newsletter"
msgstr "メールマガジンの購読誠にありがとうございます。"
```

* `msgctxt` - メッセージコンテキスト。CS-Cartやアドオンでは、このメッセージコンテキストを使用して、SmartyテンプレートとPHPコード（プレフィックスを除く）に表示される言語変数の名前を保存します。

POファイルには、文字列の翻訳、アドオンの名前と説明、さまざまな設定とセクションの名前が保存されます。そのため、異なるタイプのデータの翻訳には異なる接頭辞が付いています。PHPまたはTPLファイルに表示される言語変数の名前は「Languages::プレフィックス」で始まる必要があります。

* `msgid` - 翻訳元の言語の言語変数の値です。ここには英語で値を指定することをお勧めします。
* `msgstr` - 翻訳元のテキストからターゲット言語への翻訳です。翻訳元の言語のPOファイルでは、`msgstr`は`msgid`と同じになります。

## プレースホルダー

商品名や各種値など、変更可能なデータを言語変数に含める必要がある場合があります。この場合は、次のように角括弧で囲まれたプレースホルダーを使用します。

```shell
msgctxt "Languages::admin_text_letter_footer"
msgid "E-shop of [company_name]."
msgstr "E-shop of [company_name]."
```

Smartyテンプレートでプレースホルダーがどのように使用されるかを確認してください。

## 複数形

多くの言語では、単数形と複数形が異なる場合があります。例えば、次の2つのフレーズを考えてみましょう。

* (The delivery will take) 1 day.
* (The delivery will take) 2 days.

異なるフォームで言語変数を作成する場合は、`|`記号を使用して`msgid`および`msgstr`の値を区切ります。また、番号に置き換えられる`[n]`プレースホルダーを追加します。2つの形式の言語変数の例を次に示します。

```shell
msgctxt "Languages::n_days"
msgid "[n] day|[n] days"
msgstr "[n] day|[n] days"
```

一部の言語（例えばロシア語など）には複数形が複数あります。\
ターゲット言語に元の言語よりも複数形がある場合の例：

* `msgid`は元の言語と同じままです。
* `msgstr`には、ターゲット言語のすべての形式の説明があります。

以下はロシア語の言語変数です。一つの言語変数に2つの複数形があります。

```shell
msgctxt "Languages::n_days"
msgid "[n] day|[n] days"
msgstr "[n] день|[n] дня|[n] дней"
```

複数の単語形式をリストにする場合、単数形が常に最初に記述されます。\
さまざまな言語のフォームがリストされる順序は、言語の複数規則に準拠しています。

## 言語変数の使用方法

## PHPコード内

コア関数`__`は、言語変数の値を表示するためにPHPコード内で使用されます。

```php
<?php
function __($var, $params = array(), $lang_code = CART_LANGUAGE);
```

必須の引数は、言語変数の名前です。2番目の引数はプレースホルダーの値を渡します。3番目の引数ではターゲット言語を指定します。

> 📘
>
> デフォルトでは、ターゲット言語はユーザーの（環境の）ロケールによって決定されます。

`__`関数の例:

```php
<?php
$confirmed_text = __('email_marketing.subscription_confirmed');
fn_set_notification('I',$confirmed_text, $msg);
```

## Smartyテンプレート内

`__`を使用して、言語変数をSmartyテンプレートに挿入できます。\
文字列を中括弧で囲みます。以下のコードは、Smary内でhelloという言語変数を挿入する方法です。

```smarty
{__("hello")}
```

このような文字列は、テンプレートのコンパイル中にSmartyラッパークラスの`__`メソッドが呼び出され、置き換えられます。次に、そのクラスは上記のコア関数を呼び出します。

## プレースホルダー

以下は、テンプレート内で使用されたプレースホルダーを持つ言語変数の例です。

```smarty
<p>
   {__("admin_text_letter_footer", ["[company_name]" => $settings.Company.company_name])}
</p>
```

## 複数形

複数形の言語変数を使用する場合、`__`関数の2番目の`[n]`パラメーターでプレースホルダーの代わりに置換された数値を渡します。

```php
<?php
$return[$service_code]['delivery_time'] = __("n_days", array($shipment->GuaranteedDaysToDelivery));
```

渡された番号に応じて、適切なフォームが自動的に選択されます。\
英語の場合の例：

* 0 days
* 1 day
* 3 days

## 言語変数の編集

POファイルを変更する以外にも言語変数を編集する方法があります。

* \[管理]パネルで、\[`一般設定`] →\[`言語`]→\[\`言語変数]\*\*に移動します。
* REST API経由でlangvarsエンティティを使用します。


# スキーマー

スキーマー（scheme）は特定のオブジェクト構造を記述した特別なファイルです。 ブロック、設定、プロモーションなどに関するスキーマーがあります。

全てのスキームは(*...app/schemas*)ディレクトリに置かれています。\
アドオンはそれらを拡張したり、全体または部分的にそれらを無効にすることができます。\[さらに詳しく]\(doc:extending a scheme)

## スキーマーとは

スキーマーはデータ構造を含んでおり、スキーマーによって定義されたアクションを処理する際にエンティティ（オブジェクト）によって使用されます。

例えば、特定のアイテム（商品やページなど）のインポートやエクスポートに関する記述は、それらに直接書かれておらず、すべてのインポートやエクスポート用のスキームによって記述されています。

## スキーマーの種類

CS-Cartには、3種類のスキーマーがあります：\
`データ配列`、`XML構造`、`関数のセット`

これら3種類を組み合わせることはできません。\
（例えば、同じスクリプトにデータ配列と関数セットを記述することは出来ません）

## データ配列

このスキーマーは配列を返します。

例）

* *app/schemas/permissions/admin.php*
* *app/schemas/clone/objects.php*
* *app/schemas/sharing/schema.php*

```php
<?php 
return array(
    'layouts' => array(
         'checked_by_default' => true,
        'function' => 'fn_clone_layouts'
    ),
    'settings' => array(
        'checked_by_default' => true,
        'tables' => array(
            array(
                'name' => 'settings_vendor_values',
                'key' => '', // Do not needed
             ),
         ),
    ),
    // Some other code
);
?>
```

## XML構造

このスキーマーは`fn_get_contents`関数によって読み込まれるテキストファイルです。\
現在では旧式のものとして扱われ、コアでは使用されていません。

```xml
<menu>
    <items>
        <subitems>
            ....
        <subitems>
    </items>
</menu>
```

## 関数のセット

関数は以下のようなスキーマーで記述されます。

関数を持つスキーマーのほとんどは、データ配列をスキーマーへ追加します。

このスキーマーを特別に呼び出す必要はありません。\
ファイルの先頭に`include_once()` で使用すれば、それらを利用することが出来ます。

スキーマーが独立したものである場合（例えば、アクションや設定の値等）、標準で含まれています:`fn_get_schema("settings", "actions.functions")`

* *app/schemas/exim/products.functions.php*
* *app/schemas/last\_view/frontend.functions.php*

```php
<?php
function fn_some_scheme_func1($params)
{
     ...
 }

function fn_some_scheme_func2()
{
     ...
}
?>
```

## スキーマーの拡張

拡張には二種類の方法あります - アドオンを使用するか、タグを編集するかです。

## アドオンを使って拡張する方法

アドオンを使ってスキームを拡張するためには、アドオンのパッケージ内にコアと同じディレクトリ構造を作成し、ファイル名に\_.post\_を加えます。

例えばメインファイルへのパスの場合は以下のようになります。：

*app/schemas/permissions/admin.php*

このファイルの拡張は：

*app/addons/seo/schemas/permissions/admin.post.php*

となります。\
`$schema` 変数に拡張スキームを渡します。

`$schema` 変数は拡張データを含んでおり、最終的に追加された`$schema`変数を返します。

例：

```php
<?php
// $schema変数はすでに標準のスキーマーを含んでいます。
$schema['news'] = array(
    'modes' => array(
        'manage' => array(
            'permissions' => 'manage_news'
        )
    )
);
return $schema;
?>
```

アドオンによるスキームの拡張方法のより詳しい情報は[こちら](doc:extending-a-scheme)を確認してください。

## タグを編集して拡張する方法

編集されたタグはエディション（スタンダード版かマーケットプレイス版）毎に必要なスキームデータを形成するために使用します。

タグの編集によってスキーマーを拡張するには、\
schemeディレクトリに\_schema\_\[PRODUCT\_EDITION]\_ ファイルを作成します。

例えば、次のファイルのスキーマーを拡張する場合、

* *app/schemas/permissions/admin.php*

編集するタグのファイルパスは以下となります。：

* *app/schemas/permissions/admin\_ultimate.php*

`$schema`変数はここでも使用されます。

`$schema`変数は拡張データを含んでいます。このスクリプトは拡張された変数で作動し、最終的に`$schema`変数を返します。

## スキーマーデータの取得方法

スキームデータを取得するには`fn_get_schema()`関数を使用します。

```php
<?php 
function fn_get_schema($schema_dir, $name, $type = 'php', $force_addon_init = false)
{
		....
}
```

引数の解説:

* `$schema_dir` - スキーマーディレクトリの相対パス（パーミッションや設定）
* `$name` - 拡張されていないスキーマーファイル名(admin, schema)。スキーマータイプが関数の場合、この引数は次ようになります：*actions.functions, variants.functions*
* `$type` - スキーマーの種類：*php\_や\_xml*
* `$force_addon_init` - この引数がある場合、無効にするアドオンとその\_func.php\_ファイルが考慮されなければならないことを示します。

スキーマーをリクエストしているとき、全体のスキーマーは全てのアドオンのスキームを含んでいます。

例：

```php
<?php 
$menu = fn_get_schema('menu', 'menu', 'php');
```

メインスキームファイルの検索： */app/schemas/menu/menu.php*

拡張するスキーマーが次のアドオンディレクトリにも置かれている場合：*addons/my\_addon/app/schemas/xxx/yyy.php*

次のような関数を使用してスキーマーを追加します：`fn_get_schema('xxx', 'yyy')`

スキームを追加するとキャッシュされますので、次回以降すべてのスキーマー・ディレクトリをスキャンする必要はありません。

* アドオンによってスキーマーが追加されているか確認します：
  * *app/addons/access\_restrictions/schemas/menu/menu.post.php*
  * *app/addons/attachments/schemas/menu/menu.post.php*
  * *app/addons/banners/schemas/menu/menu.post.php*
  * *app/addons/data\_feeds/schemas/menu/menu.post.php*
  * *app/addons/news\_and\_emails/schemas/menu/menu.post.php, ‥*
* CS-Cartはスキーマーファイルを１つずつ読み込みますので、結果として全ての有効なアドオンのスキーマーを含んだスキーマーを持つことになります。


# フック

フックポイントは外部のコードを機能させる、ソースコード内の特別な場所です。

この方法のおかげで、開発者はコードの必要な部分に自分が書いたコードをフックし、コアを改変することなくアドオンを作成することができます。

CS-Cartはソースコード内のフック(PHPコード・フック)とテンプレート内(テンプレート・フック)の2種類のフックを使用することが出来ます。

次のセクションでは両方のタイプの説明を説明しています。\
フックについての情報は以下のセクションを確認してください。


# PHPフック

PHPコード・フック（フックポイント）は作成したアドオンに処理を引き渡すことができるようにコア内に定義された箇所です。

フックはコードの必要な部分で特別な関数を呼び出すことによって宣言されます:

```php
<?php
fn_set_hook('hook_name', $params, [$param2], [$paramN]);
```

フックはとても柔軟なプログラム・テクニックです。\
1つの関数に複数のフック・ポイントを設定することができます。

CS-Cart公式サイト上の[Hooks base](http://www.cs-cart.com/api)（英語）を利用することでCS-Cartの全てのバージョンで利用可能なPHPフック・ポイントを確認することが出来ます。

＜画像＞

## PHPコード・フックの例

CS-Cartで使用されているPHPコード・フックの例です。\
コードフックは、\_ギフト券アドオン\_が使用している関数 `fn_get_gift_certificate_info()` 内で宣言されています。

```php
<?php
....
fn_set_hook('get_gift_certificate_info', $_certificate, $certificate, $type);
```

## PHPフックはいつ使用されるのか？

フックはコアプログラムのメインフローの途中でアドオンが追加のアクションを実行するために便利な方法を提供します。

フックポイントでアドオンはコア・プログラムのコードの実行を遮ることができ、必要な処理を実行して、メインプログラムに実行プロセスを返します。

特定のフックを呼び出した際には、すべての変数がアドオンに直接渡されます。

アドオン内でのフックの呼び出しは関数名が`fn_ (アドオン名)(アンダーバー)(呼び出されたフックのフルネーム)`という名称で定義することによって実行されます:

```php
<?php
fn_gift_certificates_get_gift_certificate_info($_certificate, $certificate, $type)
```

上記の関数名は、`ギフト券アドオン`の`get_gift_certificate_info` フック内で実行される関数となります。

## PHPフックの使い方

あなたのアドオンにPHPフックを利用するには：

* 先ず使用するフック・ポイントをアドオンの`init.php` ファイル内で宣言します：

```php
<?php
...

fn_register_hooks(
   'get_category_data_pre'
);

  ...
```

* アドオンの`func.php`ファイル内のフックのアクションを作動するための関数を作成します:

```php
<?php

if ( !defined('AREA') ) { die('Access denied'); }

function fn_my_addon_get_category_data_pre($category_id, $field_list, $get_main_pair, $skip_company_condition, $lang_code)
{
   ...
}

?>
```

これだけです！

CS-Cartはアドオンが定義するフック・ポイントでフックが発生した際に処理をアドオンに引き渡します。

## 別のアドオンを他のアドオンで拡張する方法

別のアドオンの処理を拡張する必要がある場合、他のアドオンの中のフックポイントを利用することが可能です。

例えば、\_新着情報とメルマガ\_アドオンは\_SEOアドオン\_を使用します。

\_新着情報とメルマガ\_アドオンのためにSEOアドオンを拡張する必要はなく、SEOアドオンのフックポイントに処理を引き渡すことができます。

*design/backend/templates/addons/news\_and\_emails/addons/seo/hooks/*

動作の原理は他のフックと同様です。

例外としては、\_新着情報とメルマガ\_アドオンからSEOアドオンのフックポイントを利用する場合は、SEOアドオンが有効な場合のみそのフックポイントが利用可能となります。

以下の関数`fn_register_hooks`の三番目の引数はt他のアドオンが有効な場合のみPHPフックを登録するために追加されました：

```php
<?php
fn_register_hooks( array('get_news_data', '', 'seo') )
```

この場合のフックポイントに作用する関数名は`fn_seo_get_news_data`となります。これは`SEOアドオン`が有効な場合のみで呼び出されます。

{% hint style="info" %}
INFORMATION

全てのアクションは「アドオンを他のアドオンで拡張する」セクションに記述されています。
{% endhint %}


# テンプレートフック

テンプレートフックは`hook`タグで囲まれた以下のような部分です:

```smarty
{hook name="section:hook_name"}
...
{/hook}
```

開発者は、この部分にアドオンを使ってコードや処理を補足したり、再定義することができます。

## テープレート内のテンプレート・フック

以下の例は`design/backend/templates/views/order_management/components/totals.tpl`ファイルのテンプレートフックの例です。

```smarty
{hook name="order_management:product_info"}
       {if $cp.product_code}
              <p>{$lang.sku}:&nbsp;{$cp.product_code}</p>
       {/if}
{/hook}
```

## いつテンプレート・フックが使用されるか

テンプレート・フックは既存のテンプレートに追加のデータを表示するために使用されます。例えば、アドオンを使ってストアの管理パネルに表示したい特別なブロックを作成したい場合、このような独自のブロックはテンプレート・フックを使用して追加することが出来ます。

## テンプレート・フックの使用方法

PHPコード・フックと違って、テンプレートフックは別ファイルで宣言する必要はありません。（int.php等）

.tplファイルを適切なディレクトリと適切なファイル名で配置するだけです。

命名規則は次のようになります。

* `管理パネル`: *design/backend/templates/addons/\[addon id]/hooks/\[template name]/\[hook name].\[pre|post|override].tpl*
* `ショップフロント`: *design/themes/\[theme name]/templates/addons/\[addon id]/hooks/\[template name]/\[hook name].\[pre|post|override].tpl*

＜画像＞

## コア・テンプレートのオーバーライド

アドオンで標準のテンプレートを完全に上書きすることが可能です。

### オーバーライド方法：

* 管理パネルでは`design/backend/templates/addons/[addon id]`
* ショップフロントの場合は`design/themes/[theme name]/templates/addons/[addon id]`内に、`overrides`ディレクトリを作成します。
* `overrides`ディレクトリには、コアのテンプレート　ディレクトリと同じ構造を作成します。

例えば、\
`design/backend/templates/addons/[addon id]/overrides/views/index/index.tpl`ファイルは、次のテンプレートを完全にオーバーライドします：　　\
`design/backend/templates/views/index/index.tpl`


# アドオンチュートリアル

アドオンチュートリアルアドオンチュートリアルアドオンチュートリアル


# 「Hello World」チュートリアル

## はじめに

それぞれのアドオンは`app/addons`ディレクトリ内にアドオン専用のディレクトリがあります。

アドオンの基本的な情報は`addon.xml`ファイルに記述されています。そのXML内に記述されているのは、アドオンのID（識別子）、プライオリティ（動作の優先順位）、バージョン、表示名などです。\
基本的に、アドオンはこのXMLファイルのみで動作します。

※これだけではアドオン一覧に表示されるだけでこのアドオンは何も機能は持っていません。

このようなアドオンはaddon.xml ファイルでの設定と翻訳を定義すると、言語設定をインストールすることができます。

CS-Cartではアドオンを自由に作成することができるということを覚えておいてください。

## Hello, World!

* CS-Cartをインストールしたルートディレクトリから**app/addons**ディレクトリに移動します。
* **hello\_world**というディレクトリを作成し、そのディレクトリに移動して下さい。
* このディレクトリがアドオンの専用のディレクトリとなります。

{% hint style="warning" %}
重要

アドオンのディレクトリ名は、XMLファイルで定義したアドオンIDと同じであることが重要です。そうでないと、アドオンが正常にインストールされません。
{% endhint %}

前にも述べたように、アドオンの基本構造は\_addon.xml\_ ファイルで定義されています。このファイルを作成してみましょう。 XMLファイルでは、いくつか基本的なアドオン属性を定義します：

## addon.xml

* **id** — アドオンの識別子。アドオンのディレクトリ名と同じでなければなりません。 今回の場合は**hello\_world**として下さい。
* **version** — このアドオンのバージョン。1.0に設定して下さい。
* **priority** — 優先順位です。**100500**のように大きい数値を設定します
* **default\_language** — デフォルト言語

> /app/addons/hello\_world/addon.xml

\_addon.xml\_ファイルは以下のようになるはずです：

```xml
<?xml version="1.0"?>
<addon scheme="3.0">
   <id>hello_world</id>
   <version>1.0</version>
   <priority>100500</priority>
   <position>0</position>
   <status>active</status>
   <default_language>en</default_language>
   <auto_install>MULTIVENDOR,ULTIMATE</auto_install>
</addon>
```

[ダウンロード](https://gist.github.com/cscartjp/9f30ea09fba187ee21e7)

***

## 言語ファイル

次に言語用のファイルを用意します。\
以下のディレクトリに次の内容のファイルを設置してください。\
.poファイルについては [こちら](doc:languages-and-translations-by-po-file) をご確認ください。

> /var/langs/en/addons/hello\_world.po

```c
msgid ""
msgstr "Project-Id-Version: tygh"
"Content-Type: text/plain; charset=UTF-8\n"
"Language-Team: English\n"
"Language: en_US\n"

msgctxt "Addons::name::hello_world"
msgid "Hello World"
msgstr "Hello World"

msgctxt "Addons::description::hello_world"
msgid "Say hello to the world."
msgstr "Say hello to the world."
```

```c
msgid ""
msgstr "Project-Id-Version: tygh"
"Content-Type: text/plain; charset=UTF-8\n"
"Language-Team: Japanese\n"
"Language: ja_JP\n"

msgctxt "Addons::name::hello_world"
msgid "Hello World"
msgstr "ハローワールド"

msgctxt "Addons::description::hello_world"
msgid "Say hello to the world."
msgstr "ハローワールド！"
```

[ダウンロード](https://gist.github.com/cscartjp/38ac5da65439e62f20bc)

アドオンをスタートするにはこれで十分です。

管理パネルにログインし【**管理**】→【**アドオン**】→【**利用可能なすべてのアドオンを表示・タブ**】に切り替えます。

＜画像＞

作成した\_Hello World\_アドオンがリストにあるはずです。\
インストール/アンインストールが可能となり、インストール後はアドオンを有効/無効を切り替えることが出来ます。

{% hint style="info" %}
HINT

作成したアドオンがリスト（アドオン管理）に表示されていない場合は、CS-Cartのキャッシュをクリアする必要があるかもしれません。キャッシュをクリアする方法は、ブラウザのアドレスフィールドのURLの最後に`&cc&ctpl`を追加してページにアクセスします。
{% endhint %}

`scheme="3.0"`というに注目してください。（CS-Cart v.4.2.4以降）

このパラメータが無いアドオンは非推奨のマークアップを使用しているとみなされます。\
このパラメーターが無いアドオンはいくつか存在していますが、下位互換が必要な場合のみで利用して下さい。

では、このアドオンに設定をいくつか追加してみましょう。

*addon.xml* ファイルに`settings` セクションを作成します。\
各設定は、の\_item\_セクションで区切られています。

それぞれの\_item\_は\_type\_や\_default\_value\_などの要素で指定します。

\_addon.xml\_の`<priority>100500</priority>`の後に下記のような`settings`を書いてみましょう:

```xml
<settings edition_type="ROOT,ULT:VENDOR">
    <sections>
        <section id="general">
            <items>
                <item id="some_prop">
                    <type>input</type>
                    <default_value>Hello World!</default_value>
                </item>
                <item id="some_dropdown">
                    <type>selectbox</type>
                    <default_value>blue</default_value>
                    <variants>
                        <item id="red"></item>
                        <item id="green"></item>
                        <item id="blue"></item>
                    </variants>
                </item>
            </items>
        </section>
    </sections>
</settings>
```

[ダウンロード](https://gist.github.com/cscartjp/ac2087e545ed3bdba18c)

言語ファイル（.po）にも追記します。

```c
msgctxt "SettingsOptions::hello_world::some_prop"
msgid "Some Prop"
msgstr "Some Prop"

msgctxt "SettingsOptions::hello_world::some_dropdown"
msgid "Some Dropdown"
msgstr "Some Dropdown"

msgctxt "SettingsVariants::hello_world::some_dropdown::red"
msgid "Red"
msgstr "Red"

msgctxt "SettingsVariants::hello_world::some_dropdown::green"
msgid "Green"
msgstr "Green"

msgctxt "SettingsVariants::hello_world::some_dropdown::blue"
msgid "Blue"
msgstr "Blue"
```

[ダウンロード](https://gist.github.com/cscartjp/255969b24ccd16e849f7)

CS-Cart管理パネルのアドオン管理ページに行き、**Hello World**アドオンを再インストールします。（アンインストール＞インストール）

リストからギアのアイコンをクリックして**設定**を表示します。

それをクリックすると、追加した設定があるアドオンの設定ダイアログが表示されます:

＜画像＞

複雑なことではないですよね？\
しかし、このままでは特に何も機能するものでもありません。

[次のチュートリアル](doc:advanced-add-on-tutorial) では、より複雑で有益なアドオンを作成します。


# Advanced Add-on チュートリアル

このチュートリアルでは [**フック**](doc:hooking) や[**Pre- and Post- コントローラー**](doc:pre-and-post-controllers) を使用するような高度なテクニックのアドオン作成方法を説明します。

{% hint style="info" %}
INFORMATION *Hook*（フック）はとてもパワフルな技術で、CS-Cartではこれが多用されています。

PHPフックは追加の処理をデフォルト処理の前後で実行する、またはデフォルトの処理ルーチーンをオーバーライド（上書き）するために使用されます。 テンプレートフックはテンプレートのレンダリングを処理するため使用します。例えば、オリジナルテンプレートを修正することなく、追加データを表示したりすることが可能です。 プレまたはポストコントローラーは特別なPHPファイル(アドオンディレクトリ内に置かれたファイルの名前による)で、特定のコントローラーが実行される前か後に呼び出されます。
{% endhint %}

このチュートリアルでは [PHPフック](doc:php-hooks) と [テンプレートフック](doc:tpl-hooks) の両方を使うアドオンを作成します。

このチュートリアルで作成するアドオンはログイン済みのユーザーが閲覧したカテゴリーの情報を収集します。さらに、ユーザーが閲覧したカテゴリーのアクセス数を管理パネルのダッシュボードに表として表示します。

### 必要環境

このチュートリアルを行うためは、インストールされたCS-Carが必要になります。

**PHPやSmarty、CS-Cartアドオンディレクトリ構造に慣れることが重要です。**

このチュートリアルを進める前に [「Hello World」Addonチュートリアル](doc:hello-world-add-on-tutorial) を先に行うことをお勧めします。

### アドオン初期設定: addon.xmlとinit.phpの作成

インストールしたCS-Cartのルートディレクトリ内の\_app/addons\_ ディレクトリに移動し、\_advanced\_addon\_というサブディレクトリを作成します。

このディレクトリに以下の内容を含んだaddon.xml ファイルを作成します：

*addons/advanced\_addon/addon.xml*

```xml
<?xml version="1.0"?>
<addon scheme="3.0">
   <id>advanced_addon</id>
   <version>1.0</version>
   <priority>100500</priority>
   <position>0</position>
   <status>active</status>
   <default_language>ja</default_language>
   <queries>
        <item>DROP TABLE IF EXISTS ?:advanced_addon_data;</item>
        <item>
            CREATE TABLE `?:advanced_addon_data` (
            `user_id` int(11) unsigned NOT NULL DEFAULT 0,
            `categories` text NOT NULL DEFAULT '',
            PRIMARY KEY (`user_id`)
            ) Engine=MyISAM DEFAULT CHARSET UTF8;
        </item>
        <item for="uninstall">DROP TABLE IF EXISTS ?:advanced_addon_data;</item>
    </queries>
</addon>
```

[addon.xml ダウンロード](https://gist.github.com/cscartjp/fa514bef48ca4bdea551)

これに対応する言語ファイルは以下となります。

> /var/langs/ja/addons/advanced\_addon.po

```
msgid ""
msgstr "Project-Id-Version: tygh"
"Content-Type: text/plain; charset=UTF-8\n"
"Language-Team: Japanese\n"
"Language: ja_JP\n"

msgctxt "Addons::name::advanced_addon"
msgid "Advanced Add-on"
msgstr "アドバンスド・アドオン"

msgctxt "Addons::description::advanced_addon"
msgid "This is Advanced Add-on tutolial."
msgstr "アドオンの学習を行います。"
```

[advanced\_addon.po ダウンロード](https://gist.github.com/cscartjp/fa514bef48ca4bdea551)

***

さらに同じディレクトリに以下の内容を含んだ\_init.php\_ファイルを作成します。

> addons/advanced\_addon/init.php

```php
<?php
/***************************************************************************
*                                                                          *
*   (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev    *
*                                                                          *
* This  is  commercial  software,  only  users  who have purchased a valid *
* license  and  accept  to the terms of the  License Agreement can install *
* and use this program.                                                    *
*                                                                          *
****************************************************************************
* PLEASE READ THE FULL TEXT  OF THE SOFTWARE  LICENSE   AGREEMENT  IN  THE *
* "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE.            *
****************************************************************************/

if (!defined('BOOTSTRAP')) { die('Access denied'); }

fn_register_hooks(
    'get_category_data_pre'
);
```

[init.php ダウンロード](https://gist.github.com/cscartjp/8aaee0a0ea7b46b026fe)：

> 👍 ヒント
>
> 通常、関数名はひと目で分かるように書かれています。\
> （例えば、`get_product`は”一つの”商品情報を取得する関数です）
>
> フックは通常、 （例えばget\_products\_preとget\_products\_post ）名称に応じて前処理や後処理のフックのために`_pre`または`_post`という接尾辞が付いていて、中に置かれている機能にちなんで命名されています。

このファイル（init.php）では、カテゴリーデータを取得する特定のクエリの前に呼び出される`get_category_data_pre` フックに接続しようとしていることを表しています。

[Hooks baseツール](http://www.cs-cart.com/api)では、この他のフックについての情報を検索することが出来ます。

### データの取得: func.php

アドオンディレクトリ(*app/addons/advanced\_addon* ) に\_func.php\_ ファイルを作成します。このPHPファイルは、フックを埋め込むための関数を含んでいます。

> *addons/advanced\_addon/func.php*

```php
<?php
/***************************************************************************
*                                                                          *
*   (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev    *
*                                                                          *
* This  is  commercial  software,  only  users  who have purchased a valid *
* license  and  accept  to the terms of the  License Agreement can install *
* and use this program.                                                    *
*                                                                          *
****************************************************************************
* PLEASE READ THE FULL TEXT  OF THE SOFTWARE  LICENSE   AGREEMENT  IN  THE *
* "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE.            *
****************************************************************************/

if (!defined('BOOTSTRAP')) { die('Access denied'); }

function fn_advanced_addon_get_category_data_pre($category_id, $field_list, $get_main_pair, $skip_company_condition, $lang_code)
{
    //ログイン中のユーザーIDをセッションから取得する
    $auth = $_SESSION['auth'];
    
    //ログイン中のユーザーがストアフロントにいるかどうかの判定
    if (!empty($auth['user_id']) && AREA == 'C') {
        //データベースにユーザーのデータが存在するかチェック
        //必要に応じてアクセスデータを作成
        $viewed_categories = db_get_field('SELECT categories FROM ?:advanced_addon_data WHERE user_id = ?i', $auth['user_id']);
        
        if (!empty($viewed_categories)) {
            $viewed_categories = unserialize($viewed_categories);
        }
        
        $viewed_categories[$category_id] = true;
        $viewed_categories = serialize($viewed_categories);
        
        //データベースに書き込む
        db_query('REPLACE INTO ?:advanced_addon_data VALUES (?i, ?s)', $auth['user_id'], $viewed_categories);
    }
}
```

[func.php ダウンロード](https://gist.github.com/cscartjp/0f4588e1667a21bbeb00)：

関数`fn_advanced_addon_get_category_data_pre()` は現在表示されているカテゴリーを取得し、ストアを閲覧している人とリンクしてこのデータベースを格納します。

> 👍 ヒント
>
> PHPコード・フックの関数名は命名規則に従って書いて下さい：
>
> **fn\_** + \[**addon id**] +**\_**+ \[**hook name**]
>
> 命名規則が正しくない関数は無視されます。

### 管理パネルにデータを表示する（index.post.tpl, index.post.php）

管理パネルに取り出したデータを表示するためには、管理パネルのダッジュボードテンプレート(*design/backend/templates/views/index/index.tpl* )のフックを利用して新しいデータブロックを表示します。

1. *design/backend/templates/addons* ディレクトリに移動し、*advanced\_addon* ディレクトリを作成してください。
2. このディレクトリにサブディレクトリとして\_hooks\_を作成し、さらにその中に\_index\_ディレクトリを作成します。
3. このディレクトリ（*design/backend/templates/addons/advanced\_addon/hooks/index*）に次の内容を含んだ *index.post.tpl* ファイルを作成します：

> *design/backend/templates/addons/advanced\_addon/hooks/index/index.post.tpl*

```html
<div class="dashboard-row-bottom">
    <div class="dashboard-viewed-category">
        <h4>Viewed categories</h4>
        <div class="dashboard-viewed-category-list">
            {if $viewed_categories}
            <ul>
                {foreach from=$viewed_categories item="category_data"}
                <li><strong><a href="{"profiles.update?user_id=`$category_data.user_id`"|fn_url}">{$category_data.user_name}</a></strong>:&nbsp;
                    {foreach from=$category_data.categories key="category_id" item="category_name"}
                    <a href="{"categories.update?category_id=`$category_id`"|fn_url}">{$category_name}</a>, 
                    {/foreach}
                </li>
                {/foreach}
            </ul>
            {else}
            <ul>
                <li>No data found</li>
            </ul>
            {/if}
        </div>
    </div>
</div>
```

[ダウンロード](https://gist.github.com/cscartjp/3f95c6843c81eb4205bb)

> 👍 ヒント
>
> PHPコード・フックとは違い、テンプレート・フックは、他のファイルで宣言する必要はありません。
>
> 適切な名前のついたディレクトリに適切に名前の付けられたテンプレートを置くだけで動作します。その条件は以下の通りです：
>
> * **design/backend/templates/addons//hooks** ・・・管理パネル用ディレクトリ
> * **var/themes\_repository/basic/templates/addons//hooks** ・・・ショップフロント用ディレクトリ
> * **var/themes\_repository/basic/mail/templates/addons//hooks** ・・・メールテンプレート用ディレクトリ
>
> さらに上記のディレクトリの中に次のような名称のテンプレートファイル（.tplファイル）を作成する必要があります。：\
> **\[template name]/\[hook name].\[pre|post].tpl**

テンプレートファイルだけでは、データベースからデータを取得することはできません。これらの処理は、\_index.php\_のコントローラの「ポストコントローラ」で実行する必要があります。

*app/addons/advanced\_addon* ディレクトリに移動し、サブディレクトリ\_controllers/backend\_ を作成します。

作成したディレクトリで \_index.post.php\_という名称で下記の内容が書かれたPHPファイルを作成してください：

> app/addons/advanced\_addon/controllers/backend/index.post.php

```php
<?php
/***************************************************************************
*                                                                          *
*   (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev    *
*                                                                          *
* This  is  commercial  software,  only  users  who have purchased a valid *
* license  and  accept  to the terms of the  License Agreement can install *
* and use this program.                                                    *
*                                                                          *
****************************************************************************
* PLEASE READ THE FULL TEXT  OF THE SOFTWARE  LICENSE   AGREEMENT  IN  THE *
* "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE.            *
****************************************************************************/

use Tygh\Registry;

if (!defined('BOOTSTRAP')) { die('Access denied'); }

$viewed_categories = db_get_array('SELECT * FROM ?:advanced_addon_data');

if (!empty($viewed_categories)) {
    foreach ($viewed_categories as $key => $category_data) {
        $category_data['user_name'] = fn_get_user_name($category_data['user_id']);
        $category_data['categories'] = unserialize($category_data['categories']);
        $category_data['categories']  = fn_get_category_name(array_keys($category_data['categories']));

        $viewed_categories[$key] = $category_data;
    }

    Registry::get('view')->assign('viewed_categories', $viewed_categories);
}
```

[ダウンロード](https://gist.github.com/cscartjp/0e5b7525a12fe6e23fed)

すべてのファイルパスや名前、ファイルの内容が正常に作動することをよく確認して下さい。

### 動作確認

ファイルをアップロード後、まずはアドオンを確認します。\
CS-Cartの管理パネルの\_アドオン→アドオン管理\_に移動します。

リストから**Advanced Add-on**を探し、アドオン名の近くにある【**インストール**】をクリックします。

インストールが無事に完了すると通知が表示されます。

ダッジュボードに移動して、ページの下部を確認して下さい。\
以下の画像に似た新しいセクションが表示されているはずです。

ご覧の通り、これといったデータはありませんがダッシュボードに新しいセクションが表示されました。

ブラウザをショップフロントに切り替えて、お客様としてログインしてストア内をいろいろ検索してみてください。ランダムにカテゴリーを表示するだけでも結構です。さらに、これとは異なるユーザーアカウントでも同じように試してみてください。

管理パネルのダッシュボードページをリロードし、**Viewed categories**の状態を確認してください：

このセクションにはあなたが閲覧したカテゴリーが表示されているはずです。

### 独自のスタイルを適用する

管理パネルのデザインに合わせて作成したアドオンから特別なCSSを読み込む方法を説明します。

1. CSS（.less）を作成する。
2. 1で作成したファイルを読み込むテンプレートフックを作成する。

### このアドオンから利用するCSS（.less）は以下のディレクトリに作成します。

> /design/backend/css/addons/advanced\_addon/styles.less\
> （ファイル名「styles.less」は自由に決めることが出来ます。）

```less
.dashboard-viewed-category{
    margin-top: 32px;
    width: 50%;
    
    .dashboard-viewed-category-list{
        padding: 8px 0;
        -webkit-border-radius: 4px;
        -moz-border-radius: 4px;
        border-radius: 4px;
        overflow-y: scroll;
        min-height: 200px;
        max-height: 290px;
        overflow-y: auto;
        border: 1px solid #eee;
        background: #fcfcfc;
        
        
        ul{
            margin: 0;
            list-style: none;
            
            li{
                padding: 7px 10px;
                border-top: 1px solid #eee;
            }
            
            li:first-child{
               border: none; 
            }
        }
    }
}
```

[ダウンロード](https://gist.github.com/cscartjp/15bdd1d147a83a8284ff)

### CSSを読み込むテンプレートフックのファイルを作成する。

> /design/backend/templates/addons/advanced\_addon/hooks/index/styles.post.tpl

ファイルの中には以下のようにします。\
これで1で作成したファイルを読み込むHTMLソースが書き出されます。

```smarty
{style src="addons/advanced_addon/styles.less"}
```

テンプレートキャッシュをクリアし、再度ダッシュボードを表示してください。\
このようにアドオンで使用するCSSファイルやJavascriptファイルを作成し、読み込むことが出来ます。


# 商品リスト、詳細ページのカスタムテンプレートを作成

この記事では、商品リストおよび商品詳細ページのカスタムテンプレートを作成する方法について説明します。

また、これらのカスタムテンプレートを`My Changes`アドオンの一部として保存します。\
`My Changes`アドオンのフォルダーにカスタムテンプレートを保存することには、以下2つの利点があります。

* 作成または変更したテンプレートファイルの追跡が簡単に行えます。
* アップグレード後に変更を再適用する必要が無くなります。

{% hint style="info" %}
HINT

designまたはvar/themes\_repositoryフォルダーで作業できます。 先に進む前に、[これらのフォルダー構造を理解](https://github.com/cscartjapan/cscxv4.18.1_JP_1/blob/main/gitbook/addon-development/addon-tutorial/addon-directories/README.md)してください。
{% endhint %}

## 商品リストのテンプレート

デフォルトでは、CS-Cartには、商品リスト用の3つのテンプレートタイプが用意されています。

* グリッド（products\_multicolumns.tpl）
* オプションなしのリスト（products\_without\_options.tpl）
* コンパクトリスト（short\_list.tpl）

これらのテンプレートのいずれかをデフォルトとして設定するには、管理パネルを開き、基本設定→表示設定→「商品一覧ページのレイアウト設定」に進みます。

`My Changes`アドオンを利用して商品リストのカスタムテンプレートを追加するには、カスタム商品リストのテンプレート設定を含むファイルと、テンプレート自体のファイルを作成します。

## テンプレートのディレクトリ構造

```
|
 └─ addons/
     |
     └─ my_changes/
         |
         └─ blocks/
             |
             ├─ list_templates/
             |   |
             |   └─ modern_list.tpl （商品リストのテンプレート）
             |
             └─ product_list_templates/
                 |
                 └─ products_modern_list.tpl（テンプレートの設定ファイル）
```

設定を含むファイルには、追加するテンプレートとその設定が記述されています。

既存の商品リストテンプレートの1つを`templates/blocks/list_templates`から`templates/addons/my_changes/blocks/list_templates`にコピーしてから、テンプレートの名前を変更することをお勧めします。

{% hint style="info" %}
HINT

既存のテンプレートのファイルをコピーすることで構文エラーのリスクを最小限に抑えることができます。
{% endhint %}

## テンプレート設定ファイルの例

```smarty
    {template-description:"tmpl_modern"}
    //上記の行は、テンプレートの名前がtmpl_modernと呼ばれる言語変数に格納されることを意味します
    
    //以下は、テンプレートの場所と設定です
    {include file="addons/my_changes/blocks/list_templates/modern_list.tpl"
    show_name=true
    show_sku=false
    show_rating=true
    show_features=true
    show_prod_descr=true
    show_old_price=true
    show_price=true
    show_clean_price=true
    show_list_discount=true
    show_discount_label=true
    show_product_amount=true
    show_product_edp=true
    show_add_to_cart=true
    show_list_buttons=true
    show_descr=true }
```

## テンプレート設定の簡単な説明

```json
{
    "data": {
        "h-0": "名称",
        "h-1": "タイプ",
        "h-2": "説明",
        "0-0": "`show_name` ",
        "0-1": "Boolean (true / false)",
        "0-2": "商品名を表示",
        "1-0": "`show_sku` ",
        "1-1": "Boolean (true / false)",
        "1-2": "商品コードを表示",
        "2-0": "`show_rating` ",
        "2-1": "Boolean (true / false)",
        "2-2": "レビュー（星）を表示",
        "3-0": "`show_features` ",
        "3-1": "Boolean (true / false)",
        "3-2": "商品の追加情報を表示",
        "4-0": "`show_old_price` ",
        "4-1": "Boolean (true / false)",
        "4-2": "商品の通常価格を表示します。",
        "5-0": "`show_price` ",
        "5-1": "Boolean (true / false)",
        "5-2": "商品価格を表示",
        "6-0": "`show_clean_price` ",
        "6-1": "Boolean (true / false)",
        "6-2": "税込みの価格を表示",
        "7-0": "`show_discount_label` ",
        "7-1": "Boolean (true / false)",
        "7-2": "割引額を表示",
        "8-0": "`show_product_amount` ",
        "8-1": "Boolean (true / false)",
        "8-2": "在庫数を表示",
        "9-0": "`show_add_to_cart` ",
        "9-1": "Boolean (true / false)",
        "9-2": "`カートに追加`ボタンを表示",
        "10-0": "`show_list_buttons` ",
        "10-1": "Boolean (true / false)",
        "10-2": "リストボタンを表示  \n（欲しいものリストに追加、比較リストに追加など）",
        "11-0": "`show_descr` ",
        "11-1": "Boolean (true / false)",
        "11-2": "商品の説明を表示",
        "12-0": "`but_role` ",
        "12-1": "Text",
        "12-2": "テンプレートでのボタンの表示方法。  \n使用可能な[役割]のいずれかを選択。  \n`Action`  \n`Text`  \n`Delete`  \n`Big`  \n`Tool `"
    },
    "cols": 3,
    "rows": 13,
    "align": [
        "left",
        "left",
        "left"
    ]
}
```

すべて正しく設定出来ていれば、新しいテンプレートが管理パネルの\[一般設定]→\[表示設定]に表示されます。

{% hint style="info" %}
HINT

カスタムテンプレートが表示されない場合は、\[アドオン]→\[アドオンの管理]に移動し、`My Changes` アドオンが有効であることを確認します。`var/themes_repository/templates/addons/my_changes`で作業している場合、`My Changes`をアンインストールする必要があります。\
My Changesはアドオンの管理から再度インストールしてください。
{% endhint %}

＜画像＞

上の画像でもわかるように、アドオンの翻訳を含むファイルに作成したカスタム商品リストの言語変数を追加する必要があります。言語変数の名前は、テンプレート設定ファイルで商品リストをどのように呼び出したかによって異なります。

この場合、次のコードを`var/langs/en/addons/my_changes.po`に追加する必要があります。

```
msgctxt "Languages::tmpl_modern"
msgid "Modern list"
msgstr "Modern list"
```

作成した商品リストのテンプレートを有効にすると、ストアフロントのカテゴリページに表示されます。ただし、テンプレートにはアイコンがありません。

＜画像＞

アイコンの名前は、テンプレートの名前から決定されます。

たとえば、テンプレート設定ファイルの名前が`products-modern-list`の場合、アイコンの名前は`ty-icon-products-modern-list`になります。画像を用紙してCSSを書き換えてください。

## 商品詳細ページのテンプレート

デフォルトでは、CS-Cartには、商品詳細ページ用の2つのテンプレートタイプが用意されています。

* デフォルトのテンプレート（default\_template.tpl）
* 商品画像大（bigpicture\_template.tpl）

これらのテンプレートのいずれかをデフォルトとして設定するには、管理パネルを開き、一般設定→表示設定→`商品詳細ページのビュー`に進みます。

`My Changes`アドオンを介して商品詳細ページのカスタムテンプレートを作成するには、`templates/addons/my_changes/blocks/product_templates`ディレクトリに`.tpl`ファイルを作成する必要があります。

## テンプレートの構造

```
templates/
 |
 └─ addons/
     |
     └─ my_changes/
         |
         └─ blocks/
             |
             └─ product_templates/
                 |
                 └─ modern_template.tpl
```

`templates/blocks/product_templates`から既存のテンプレートのいずれかをコピーすることをお勧めします。コピーしたファイル名は`modern_template.tpl`とします。

＜画像＞

繰り返しになりますが、言語変数をアドオンの翻訳ファイルに追加する必要があります。言語変数の名前は、テンプレートファイルの名前と同じです。この例では、`modern_template`です。

次のコードを`var/langs/en/addons/my_changes.po`に追加する必要があります。

```
msgctxt "Languages::modern_template"
msgid "Modern Product"
msgstr "Modern Product"
```


# 支払方法の開発

支払方法（決済）は、いくつかのPHPとTPLファイル、`payment_processors`テーブルのエントリで構成されています。

## payment\_processorsテーブルのフィールドについて

**processor** （string） 支払い方法の名前。すべての言語で同じであるため、このフィールドは英語で入力するか、少なくともラテンアルファベットの文字を使用することをお勧めします

**processor\_script** （srting） 支払い方法のロジックを含むPHPファイルの名前。ここでファイルの名前のみを指定します（例：foo\_bar.php）。ディレクトリやその他の記号をここに置かないでください。

デフォルトでは、そのファイルは`app/payments`から読み込まれます。

支払い方法がアドオンによって追加され、`payment_processors`テーブルのアドオンフィールドが正しく入力されている場合、ファイルは`app/addons/{$addon_name}/payments`から読み込まれます。

**processor\_template** （string） 注文した顧客に表示されるテンプレートの、TPLファイルへの最初のスラッシュなしの相対パス。パスは、`design/themes/{$theme_name}/templates`からの相対パスでなければなりません。例：`views/orders/components/payments/cc.tpl`

処理方法がアドオンによって追加され、カスタムテンプレートが必要な場合は、アドオンのテンプレートフォルダからテンプレートへのパスを指定できます。

以下はPayPalアドオンのテンプレートパスです\
`addons/paypal/views/orders/components/payments/paypal_express.tpl`

レスポンシブテーマは、いくつかの標準テンプレートを含んでいます。これらは`processor_template`フィールドで指定することで使用することができます。また、別の方法として、アドオンによって追加された独自のカスタムテンプレートのベースとしてこれらのテンプレートを使用することもできます。レスポンシブテーマのテンプレートは、`design/themes/responsive/templates/views/orders/components/payments`に保存されます。

**admin\_template** （string） 支払い方法の作成および編集するときに表示されるタブテンプレートのTPLファイルの名前。このテンプレートには、管理者がアクセストークンなどの支払い方法プロパティを指定するフィールドとフォームが含まれる場合があります。

ディレクトリやその他の記号を付けずにTPLファイルの名前を入力します。\
例えば`foo_processor_template.tpl`のようになります。デフォルトでは、このファイルは`design/backend/templates/views/payments/components/cc_processors`からロードされます。

プロセッサーがアドオンによって追加され、`payment_processors`テーブルのアドオンフィールドが正しく入力されている場合、ファイルは`design/backend/templates/addons/{$addon_name}/views/payments/components/cc_processors`からロードされます。\
`{$addon_name}`はアドオンの名前を表します。

**callback** （Y/N）支払いステップの動作を決定します。

Y・・・プロセッサーは、顧客をそのサーバーにリダイレクトせずに、処理サーバーに要求を送信します。例えば、これはcURLを介して実行できます。

N・・・注文を行ったお客様は、支払いを行うために決済の処理サーバーにリダイレクトされます。

type （P/C/B）`processor_template`フィールドで指定されたテンプレートが表示される場所を決定します。

P （Payment gateway）・・・チェックアウト時に\[ 課金オプション]セクションにテンプレートが表示されます。

チェックアウトのディスパッチは`dispatch=checkout.checkout`です。

C （Checkout）・・・テンプレートはカート内に支払いボタンとして表示されます。

B （Both） ・・・テンプレートは上記の両方の場所に表示されます。

**addon** （string） -支払処理方法を追加するアドオンの識別子（例：paypal）

対象のアドオンが無効になっているかインストールされていない場合、このアドオンに依存する支払い方法はストアフロントでは表示されません。また、管理画面での支払い方法の作成時にプロセッサー自体は使用できません。

## 支払方法のスクリプト

例としてcallback が "N"の支払い処理スクリプトを解説します。

支払い方法のロジックのコアは、`payment_processors`テーブルの`processor_script`フィールドで指定されたPHPファイルです。これは、`include`ディレクティブを介して読み込まれるスクリプトです。その後、ファイルのコンテンツが実行されます。

ただし、そのファイルには2つの異なる目的があるため、コンテキスト、つまりスクリプトが含まれていた目的に応じて、スクリプトの2つの部分のうち1つだけを実行できるロジカル分岐を含める必要があります。

この例では、スクリプトは`app/addons/sample_payment/payment`にあります。これを`sample_payment_processor.php`として、必要な最小限のコードを追加します。

```php
<?php
// スクリプトは「include」ディレクティブでインクルードする必要があるため、スクリプトへの直接アクセスを防止します。「BOOTSTRAP」定数は、システムの初期化中に宣言されます。
defined('BOOTSTRAP') or die('Access denied');

//以下は、スクリプトを実行するための2つの異なるコンテキストです
if (defined('PAYMENT_NOTIFICATION')) {
    /**
     * サードパーティのサービスからのレスポンスの受信と処理
     *
     * Available variables:
     * @var string $mode The purpose of the request
     */
} else {
    /**
     * 顧客が「注文を確定」ボタンを押した後の必要なロジックを実行します
     *
     * Availablе variables:
     *
     * @var array $order_info     Full information about the order
     * @var array $processor_data Information about the payment processor
     */
}
```

考えられる両方のコンテキストを見てみましょう。

## 顧客の注文送信後に支払い受理ロジックを実行する方法

スクリプトは、注文が行われた後（つまり、ordersテーブルのエントリが作成された後）に含まれます。このコンテキストでスクリプトが処理する必要がある典型的なタスクは次のとおりです。

* 注文時に顧客が入力したデータを確認します。
* データに不備がある場合、注文ステータスを「失敗」に変更します。
* サードパーティ支払いシステムのサーバーに渡すデータを収集して準備します。
* 支払いシステムからさまざまな使い捨てトークンとアクセスキーを取得します。
* お客様が支払いサービスWebサイトで必要なアクションを実行した後、顧客が取得されるURLを生成します。
* 追加のデータを提供したり、支払いを確認したりできるように、顧客を支払いシステムのWebサイトにリダイレクトします。

支払い処理スクリプトの実行前後に行われるプロセスを調べてみましょう。

* お客様は支払い方法を選択し、\[ 注文を送信 ]ボタンをクリックします。それを行うと、POSTリクエストが`index.php?dispatch=checkout.place_order`に送信されます。
* `checkout.place_order`コントローラは`fn_checkout_place_order()`関数を呼び出し、実行します。
* 他の引数とは別にこの関数は`$_REQUEST`配列を受け入れます。関数がその配列（`$_REQUEST['payment_info']`）内の`payment_info`キーを持つ要素を見つけると、その要素の値を同じキーを持つ`$cart`配列にコピーします（ `$cart['payment_info']`）。

これにより、プロセッサスクリプトは、お客様が支払い方法を選択するときに入力したデータを処理できます。（たとえば、クレジットカード番号など）。`processor_template`テンプレートでこのようなフィールドを宣言できます。

その後、関数は注文を作成する前に必要なさまざまな確認を実行した後に、注文自体を作成します。注文ステータスは`Incomplete`（注文未完了）です。このステータスは、データベース内の`N`によって参照可能です。

支払いプロセスの開始のロジックは、`fn_start_payment()`関数の呼び出しから始まります。\
この関数が実行されると重要な変数が表示されます。これらの変数は、のちに支払い処理スクリプト内で使用できます。

* **$order\_id** （integer） —作成された注文の一意の識別子
* **$order\_info** （array） -注文に関する詳細情報

{% hint style="info" %}
HINT

この情報は`fn_get_order_info()`関数によって取得可能です。
{% endhint %}

* **$processor\_data** （array） -支払い処理に関する情報

{% hint style="info" %}
HINT この情報は`fn_get_processor_data()`関数によって確認できます。
{% endhint %}

* 次に、プロセッサスクリプトが含まれ、includeディレクティブを介して実行されます。
* スクリプトには`$pp_response`変数が宣言されている必要があります。この変数は、後で`fn_start_payment()`関数で使用され、`fn_finish_payment()`関数の呼び出しに渡されます。

## サードパーティのサービスおよび支払いシステムからの応答の受信と処理

このコンテキストでは、スクリプトは支払いシステムから送信されたHTTPリクエストを処理する必要があります。これは、顧客を店舗のウェブサイトに戻すリクエスト、または支払いシステムのサーバーから送信される追加リクエストのいずれかです。

このようなリクエストを受け入れるための`payment_notification`コントローラー（ `callback = "N"`を含む）があります。このコントローラーは、2つの必須のGETパラメーターを想定しています。

* **mode** （string） — モード名

このパラメーターの値は、`$mode`変数のプロセッサースクリプトで使用できます。値には、success、error、redirectなどがあります。

* **payment** （string） —実行するプロセッサスクリプトを含むファイルの名前

名前に.php拡張子を含めることはできません。たとえば、`sample_payment_processor`にすることができます。

`payment_notification`コントローラーが実行されると、次のようになります。

* `PAYMENT_NOTIFICATION`定数が表示されます。その値はtrueです。これにより、論理分岐により、プロセッサスクリプト内の他のコンテキストからこのコンテキストを識別することができます。
* GETパラメーターで渡された支払いプロセッサーを使用する支払い方法がアクティブかどうかを確認するためのチェックが実行されます。
* 支払い処理スクリプトは、includeディレクティブを介して実行されます。

## 支払処理スクリプトの例

callback = "N" とtype = "P"を使用して支払処理スクリプトを作成してみましょう。

これにより、顧客は支払処理サーバーにリダイレクトされ、支払い方法はチェックアウト時に**支払い方法**セクションに表示されます。

まず始めに`app/addons/sample_payment/payments`に`sample_payment_processor.php`ファイルを作成し、必要な最小限のコードを追加します。

```php
<?php
// Preventing direct access to the script, because it must be included by the "include" directive.
defined('BOOTSTRAP') or die('Access denied');

// Here are two different contexts for running the script.
if (defined('PAYMENT_NOTIFICATION')) {
    /**
     * Receiving and processing the answer
     * from third-party services and payment systems.
     *
     * Available variables:
     * @var string $mode The purpose of the request
     */
} else {
    /**
     * Running the necessary logics for payment acceptance
     * after the customer presses the "Submit my order" button.
     *
     * Availablе variables:
     *
     * @var array $order_info     Full information about the order
     * @var array $processor_data Information about the payment processor
     */
}
```

たとえば、次のコードを追加してみましょう。

```php
<?php
// Preventing direct access to the script, because it must be included by the "include" directive.
defined('BOOTSTRAP') or die('Access denied');

// Here are two different contexts for running the script.
if (defined('PAYMENT_NOTIFICATION')) {

     fn_print_r("Processing the answer");

} else {

     fn_print_r("Sending data");

}
```

このプロセッサーを使用した支払い方法を選択し、チェックアウト時に注文を送信をクリックすると、「データを送信しています」というメッセージが表示され、続いて「注文を処理しています」というメッセージが表示されます。

例えば、`app/payments`などの支払処理コードを使用することができます。

## 支払方法の説明を追加する

作成した支払処方法について説明を追加できます。追加した説明は、\[ 管理]→\[支払方法]で支払方法を作成または編集するときに\[ プロセッサ]フィールドの下に表示されます。

支払いプロセッサの説明は、`language_values`テーブル内の動的に作成された言語変数です。

言語変数の名前は`processor_description _ {$ processor_script}`です。\
`{$processor_script}`は.php拡張子のない`payment_processors`テーブルの`processor_script`フィールドの値です。

たとえば、`processor_script`の値が`foo_bar_processor.php`の場合、言語変数の名前は`processor_description_foo_bar_processor`になります。

この言語変数と支払方法の説明が`language_values`テーブルに追加されると、`foo_bar_processor`の説明が\[管理]パネルに表示されます。

この言語変数の値は、次の3つの方法で編集できます。

* 管理パネルの\[管理]→\[言語]→\[言語変数]
* アドオンのインストール中に`language_values`テーブルへのSQLクエリを実行する。
* via a migration

## IFRAMEモード

一部の決済では、iframeで読み込まれたページを利用してお客様が支払いゲートウェイとやり取りを行うことができます。これを利用することで、お客様はあなたのショップを離れることなく、決済を行うことができます。

> 📘
>
> Skrill QuickCheckout（`skrill_qc.php`）とSkrill eWallet（`skrill_ewallet.php`）を確認してください。これらの支払いプロセッサは、iframeのモードをサポートしています。\
> [GitHubにはこれらのアドオンの例があります](https://github.com/cscart/addons/tree/master/iframe_payment)。

決済ゲートウェイをiframeモードで動作させるには、支払いプロセッサに`iframe_mode`という設定があり、その値が`Y`に設定されている必要があります。

iframeモードで決済するサンプルを以下で解説します。

```html
<input
   type="hidden"
   name="payment_data[processor_params][iframe_mode]"
   value="Y"
/>
```

お客様が支払いのステップでiframeを使った支払方法を選択すると、\[注文を送信 ]ボタンは表示されません。そのため、`checkout.post.php`コントローラー内のプロセッサーは実行されません。（この場合、お客様はチェックアウト時にメルマガを購読することはできません。）

まだ確定されていない一時的な注文番号は`order_id`の代わりに注文を識別するのに役立ちます。\
一時的な注文番号は、`TIME`定数と`user_id`から作成されます。

iframe内の支払いゲートウェイは`checkout.php`コントローラーの`process_payment`モードを介してロードされます。プロセッサーのスクリプトはincludeディレクティブを介して読み込まれます。

プロセッサスクリプトは、一時的な注文番号やセッション識別子など、必要なすべての情報を支払いゲートウェイに送信します。

ゲートウェイからの支払い通知を受信すると、注文が行われ、注文に関する情報がセッションから取得されます。

支払い通知を受け取った後、以下の処理を行う必要があります。

•注文を手動で発注済みとしてマークします。\
一時的な注文番号と注文ID（`order_id`）の相関を保存します。

`payment_notification`の受信時に`order_data`テーブルに追加されるエントリは次のとおりです。

```json
{
    "data": {
        "h-0": "order_id",
        "h-1": "type",
        "h-2": "data",
        "0-0": "作成された注文の識別子  \n（注文ID）",
        "0-1": "S  \nE",
        "0-2": "`TIME` 定数  \n一時的な注文番号"
    },
    "cols": 3,
    "rows": 1,
    "align": [
        "left",
        "left",
        "left"
        ]
}
```


# アドオンの管理プロセス

## アドオンのリストを作成する

アドオンのリストは、CS-Cartの管理パネルの`アドオン`→`アドオン管理`で利用できます。\
以下はこのアドオンのリストの作成手順です。

1. アドオンの予備リストが作成されます。この時点では、\_app/addons\_のサブフォルダーはアドオンとみなされます。
2. すべてのフォルダーから \_app/addons/\[アドオンID]/addon.xml\_をロードしようと試みます。\
   `addon.xml`をロードまたは解析できなかった場合、アドオンは無視されます。`addon.xml`のXML解析エラーはエラー通知に表示されます。
3. アドオンの名称が取得されます。`addon.xml`のスキームversion3.0を使用している場合、アドオンの名前は\_var/langs/ \[言語コード]/addons/\[アドオンID].po\_から取得されます。
4. インストール済みのアドオンのデータは、データベースから取得されリストに追加されます。そのため、アドオンが既にインストールされている場合は、その名前と説明は変更されません。

## アドオンのインストール時

1. データベースの`?:addons`テーブルは、アドオンの登録が無いことを確認するためにチェックされてます。
2. アドオンのスキーマーは`addon.xml`からロードされます。
3. アドオンが`unmanaged`としてマークされている場合、管理パネルのアドオンリストには表示されません。コンソール経由でのみインストールすることが出来ます。
4. アドオンのクラスの自動読み込みを有効にするには、アドオンのフォルダーを`Tygh::$app['class_loader']`に追加します。
5. アドオンの互換性がチェックされます。

{% hint style="info" %}
HINT

アドオンがサーバー環境またはCS-Cartのバージョンと互換性がない場合、エラーが表示され、インストールが中止されます。
{% endhint %}

6. 他のアドオンへの依存関係がチェックされます。

{% hint style="info" %}
HINT

この時点では、競合するアドオンはチェックされず、アドオンの有効化の際にチェックが行われます。
{% endhint %}

7. `addon.xml`の`<functions>`セクションの関数`for="before_install`が実行されます。

{% hint style="info" %}
HINT

関数の実行の結果、データベースエラーが発生した場合、アドオンのインストールは中止され、アドオンはアンインストールされます。
{% endhint %}

8. `Registry::set('addons.' . $addon)`にエントリが作成されます。`disabled`ステータスとアドオンの優先順位は、そこに記録されています。
9. `addon.xml`の`<queries>`セクションの`for="install`からクエリが実行されます。

{% hint style="info" %}
HINT

データベースエラーが発生した場合、アドオンのインストールは中止され、アドオンはアンインストールされます。
{% endhint %}

10. `addon.xml`の`<settings>`セクションで指定されたアドオンの設定がデータベースに作成されます。

{% hint style="info" %}
HINT

データベースエラーが発生した場合、アドオンのインストールは中止され、アドオンはアンインストールされます。
{% endhint %}

11. `?:addons`および`?:addon_descriptions`テーブルにエントリが作成されます。この時点ではアドオンのステータスは無効の状態です。
12. POファイルから言語変数がインストールされます。
13. テンプレートファイルが *var/themes\_repository* から *design/themes* にコピーされます。
14. アドオンの設定値は`Registry::set('addons.' . $addon)`と`Registry::set('settings.' . $addon, $settings)`に記録されます。
15. 英語の言語変数は`?:original_values`テーブルに保存されます。
16. 商品タブは`[theme名] /templates/addons/[アドオンID]/blocks/product_tabs`からインストールされます。
17. `addon.xml`の`<functions>`セクションの`for="install`に記述された関数が実行されます。

{% hint style="info" %}
HINT

データベースエラーが発生した場合、アドオンのインストールは中止され、アドオンはアンインストールされます。
{% endhint %}

18. `addon.xml`の`<status>`セクションが`active`である場合、アドオンは直ちに有効化されます。

{% hint style="info" %}
HINT

アドオンのアクティベーションが中止されても、インストールは続行されます。ただし、その場合、アドオンはデフォルトで無効のままになります。
{% endhint %}

19. `app/addons/[アドオンID]/layouts.xml`からレイアウトがインポートされます。
20. キャッシュが削除されます。
21. デモデータがインストールされます。アドオンがCS-Cartのインストールと同時にインストールされ、\[デモデータをインストール]のチェックボックスがオンになっている場合にのみ実行されます。

{% hint style="info" %}
HINT

デモデータのインストールは、アドオンのインストールとは別のプロセスです。デモデータのインストールが失敗した場合、アドオンのインストールは中止されません。
{% endhint %}

## アドオンのアンインストール時

1. アドオンが`unmanaged`としてマークされている場合、管理パネルのアドオンリストには表示されません。コンソール経由でのみアンインストールが可能です。
2. アンインストールするアドオンの動作に必要な他のアドオンを見つけるためのチェックが実行されます。該当するアドオンが見つかった場合、アンインストール手順は中止され、メッセージが表示されます。

{% hint style="warning" %}
警告

次のアドオンがインストールされてないため、このアドオンをアンインストールできません：\[対象のアドオン名]。
{% endhint %}

3. `addon.xml`の`<functions>`セクションに書かれている`for="uninstall"`の関数が実行されます。
4. `?:addons`テーブルと`?:addon_descriptions`テーブルからアドオンのエントリー削除されます。
5. アドオンの設定が削除されます。
6. アドオンの言語変数が削除されます。
7. `addon.xml`の`<queries>`セクションの`for="uninstall"`に書かれているクエリが実行されます。
8. アドオンの製品タブが削除されます。
9. アドオンのテンプレートが `design/themes` から削除されます。
10. アドオンのレイアウトが元に戻ります。
11. `Registry::get('addons.' . $addon_name)` は削除されます。
12. アドオンが使用していたHookが`Registry::get('hooks')`（登録済みのHookリスト）から削除されます。
13. キャッシュが削除されます。

## アドオンの有効化時

1. アドオンのスキーマーは`addon.xml`からロードされます。
2. アドオンが`unmanaged`としてマークされている場合、管理パネルのアドオンリストには表示されません。コンソール経由でのみう有効化できます。
3. 次のフックポイントの関数が実行されます。

```php
<?php
fn_set_hook('update_addon_status_pre', $addon, $status, $show_notification, $on_install, $allow_unmanaged, $old_status, $scheme);
```

4. すべての有効化されているアドオンがチェックされ、アドオンがそれらのいずれかの競合として定義されているかどうかが確認されます。

{% hint style="info" %}
HINT

競合するアドオンが見つかった場合、警告が表示され、アクティベーションは中止されます。
{% endhint %}

5. 以下の関数が存在するか確認されます。

```php
<?php
fn_settings_actions_addons_[アドオンID](){}
```

関数が存在する場合、次の引数で呼び出されます。\
`($new_status, $old_status, $on_install)`

6. このアドオンの競合として定義されているアドオンが、すべて無効になっているかどうか確認されます。

{% hint style="info" %}
HINT

競合するアドオンが有効化されている場合、警告が表示され、アクティベーションは中止されます。
{% endhint %}

7. `?:addons`テーブルの当アドオンの`status`フィールドの値がAに変更されます。
8. 以下の関数が存在するかどうかを確認するためにチェックが実行されます。

```php
<?php
fn_settings_actions_addons_post_[アドオンID](){}
```

関数が存在する場合、次の引数でこの関数が呼び出されます：`($new_status)`

9. 商品タブのステータスが更新されます：アドオンの`product_tabs`は有効のまま。
10. このアドオンのステータス`A`は`Registry::set('addons.[アドオンID].status')`に記録されます。

## アドオンの無効時

1. アドオンのスキーマーは`addon.xml`からロードされます。
2. アドオンが`unmanaged`としてマークされている場合、管理パネルのアドオンリストには表示されません。コンソール経由でのみ無効化できます。
3. 次のフックポイントの関数が実行されます。

```php
<?php
fn_set_hook('update_addon_status_pre', $addon, $status, $show_notification, $on_install, $allow_unmanaged, $old_status, $scheme);
```

4. 以下の関数が存在するかどうかを確認するためにチェックが実行されます。

```php
<?php
fn_settings_actions_addons_[アドオンID](){}
```

関数が存在する場合、次の引数で関数が呼び出されます。\
`($new_status, $old_status, $on_install)`

5. `?:addons`テーブル内の当アドオンの`status`フィールドの値が`D`に変更されます。
6. 以下の関数が存在するかどうかを確認するためにチェックが実行されます。

```php
<?php
  fn_settings_actions_addons_post_[アドオンID](){}
```

関数が存在する場合、次の引数で呼び出されます。`($new_status)`

7. 商品タブのステータスが更新されます。アドオンの`product_tabs`が無効になります。
8. `Registry::set('addons.[アドオンID].status')`にステータス`D`がセットされます。


# Add-on スキーマー

## addon.xml

このファイルは全てのアドオンにおいて必須となります。

アドオン識別子や名称、説明、リストの順番などのアドオンのパラメーターが記述されています。

[こちら](https://gist.github.com/cscartjp/e2b6d1a7bd57f22946a3)でaddon.xml の全てがコメントされたサンプルファイルをダウンロードすることができます。

管理パネルで\_アドオン管理\_が表示される度に、CS-Cartはapp/addons/ 内の全てのディレクトリをスキャンし、インストール済のアドオンのリストと未インストールのアドオンをリスト化するためにaddon.xml ファイルを読み込みます

アドオンのインストール時にCS-Cartはaddon.xmlのデータをデータベースに保存します。\
（アドオンで作業するたびにファイルから読み込まれる設定を除く）

アドオン管理のページでアドオンを編集する際には、すでにインストールされたアドオンはaddon.xml を呼び出します。

## addon.xmlの場所

addon.xmlファイルはアドオンのルートディレクトリに配置する必要があります：

*app/addons/\[addon\_name]/addon.xml*

## スキーマー

**Scheme 3.0** は、CS-Cartバージョン4.2.4以降で使用されます。

古いスキーマーを持つアドオンは\_【管理パネル】 >【アドオン】>【アドオン管理】\_ で表示されません。適切なスキーマーへの変換なしでは正しく作動しません。

## スキーマーの構造

\_addon.xml\_ファイルの構造は以下に全て記述されています。アドオンを開発したい場合は、このスキームをメモとして使用してください。

## トップレベル

```xml
<addon scheme="3.0" edition_type="ROOT,ULT:VENDOR">
    <!-- Add-on identifier. It must be equal to the catalog name in which the add-on resides -->
    <id>sample_addon_3_0</id>
 
    <!-- Add-on version -->
    <version>1.0</version>
 
    <!-- Add-on native (default) language. An optional parameter; if not specified, the language will be recognized as English (EN)-->
    <default_language>en</default_language>
 
   <!-- Add-on priority. The higher the priority the later the add-on is connected -->
    <priority>100</priority>
 
    <!-- Status to be set after the add-on installation (active/disabled); "disabled" by default -->
    <status>active</status>
 
    <!-- Authors contact information -->
    <!-- All fields are optional -->
    <authors>
        <author>
            <name>CS-Cart</name>
            <email>contact@cs-cart.com</email>
            <url>http://cs-cart.com</url>
            <phone>+1 999 1234 5678</phone>
        </author>
    </authors>
```

属性:

* `scheme` - アドオンのスキーマーバージョン。「3.0」が使用されています。
* `edition_type` - 設定関連の要素で使用可能なオプションの属性\
  １つまたはその他の設定が可能であるというCS-Cartのエディションを定義しています。\
  空のままにすると、親要素の値が使用されます。\
  後者がセットされていないと、値はROOTとみなされます。\
  利用可能な値: ULT:ROOT, ULT:VENDOR, MVE:ROOT, MVE: VENDOR, ROOT そして VENDOR.
* `id` - アドオンの固有の識別子。アドオンのディレクトリ名と等しくなければなりません。
* `version` - アドオンのバージョン
* `default_language` - アドオンのデフォルト言語 。指定がない場合は\_英語(EN)\_となります。
* `name`- デフォルト言語でのアドオン名
* `description` - デフォルト言語でのアドオンの簡単な説明
* `priority` - アドオンの優先順位。優先順位が高ければ、順番として後でアドオンが接続されます。
* `status` - アドオンがインストールされた直後のステータス(有効/無効)を定義します。デフォルトでは【無効】になってます。

***

## 互換性・ブロック

```xml
<!-- Block for the other add-ons compatibilities or system preferences descriptions -->
    <compatibility>
        <!-- Dependencies. These add-ons must be installed in order to install the current one; otherwise an error message will be displayed -->
        <dependencies>discussion,form_builder</dependencies>
 
        <!-- Conflicts. These add-ons will be automatically disabled before the current add-on installation starts and the notification will be displayed-->
        <conflicts>catalog_mode,reward_points</conflicts>
 
        <!-- Minimal/Maximal cart version. Min or Max parameter can be optional -->
        <core_version>
            <min>4.0.3</min>
        </core_version>
 
        <!-- Cart edition: ULTIMATE/MULTIVENDOR -->
        <core_edition>
            ULTIMATE,MULTIVENDOR
        </core_edition>
 
        <!-- Minimal/Maximal PHP version. Min or Max parameter can be optional -->
        <php_version>
            <min>5.3.0</min>
            <max>5.5.0</max>
        </php_version>
 
        <!-- Dependencies on extra extensions -->
        <php_extensions>
            <!-- Checking Extension availability. Must be installed: Y. Not to be installed: N -->
            <calendar>
                <supported>Y</supported>
            </calendar>
 
            <!-- Extension id (phpinfo) and required version -->
            <json>
                <min>1.1.0</min>
                <max>1.2.2</max>
            </json>
        </php_extensions>
    </compatibility>
```

* `compatibility`- 他のアドオンとの互換性を定義するためのブロック
* `dependencies` - このセクションにリストされているアドオンは、このアドオンをインストール際に必須となります。これらのアドオンがインストールされなかった場合はエラーとなります。
* `conflicts` - このセクションにリストされているアドオンは、このアドオンのインストールを行う前に自動的に無効になります。インストールが完了した後にこれらが無効になったことを示す通知が表示されます。

***

## ライセンス・ブロック

```xml
<license></license
```

***

## タブの順番・ブロック

```xml
<tab_order>prepend</tab_order>
```

***

## 設定・ブロック

サンプルは[こちら](https://gist.github.com/cscartjp/e2b6d1a7bd57f22946a3)\
。

* `settings` - アドオンの設定ブロック（オプション）

**属性**:

* `layout` - 設定ページをどのように表示するかを定義します。(popup/separate )デフォルトはpopup
* `edition_type` -Top level セクションの`edition_type`属性を参照してください。
* `sections` - アドオンの設定項目タブのリスト
* section - タブ項目

**属性**

* `id`- タブの識別子。この設定は`Registry::get('addons.[addon_id].[setting_id]')` を使ってアクセスできます。
* `edition_type` - Top level セクションの`edition_type`属性を参照してください。
* `name` - デフォルトの言語での設定タブの名称
* `items` - タブ内の設定項目リスト
* `item` - 設定項目

**属性**

* `id` -設定の識別子
* `edition_type` - **Top level** セクションの`edition_type`属性の記述を参照してください。
* `type` - 要素タイプ：入力、テキストエリア、パスワード、チェックボックス、選択ボックス、複数選択、複数のチェックボックス、国リスト、州のリスト、ファイル、情報、ヘッダー、テンプレート（input, textarea, password, checkbox, selectbox, multiple select, multiple checkboxes, countries list, states list, file, info, header, template）
* `name` - デフォルト言語での設定名
* `translations` - 翻訳ブロックセクションの翻訳ブロックの記述を参照してください。
* `tooltip` - ツールチップ
* `default_value` - デフォルト値　選択ボックスや複数選択のように複数のバリアントを持つアイテムの場合はそのID
* `variants`- 選択ボックス、複数選択、複数のチェックボックス、コンボ選択のための値
* `item`- アイテムの値

**Attributes:**

* `id` - バリアント識別子
* `name` - バリアント名
* `translations` - **翻訳**ブロックセクションに記載されている`Translations`ブロックに似て、唯一`for`属性に使用される。
* `handler` - \_info\_タイプ設定のハンドラー関数。特定された関数の戻り値は出力テキストとして使用されます。

***

## クエリー・ブロック

```xml
<!-- Additional database queries -->
    <queries>
        <!-- If parameter "for" equals "install" or is not set, the query is executed during the add-on installation -->
        <item for="install">
        CREATE TABLE `?:addon_test_123456789` (
            `queue_id` mediumint NOT NULL auto_increment,
            PRIMARY KEY  (`queue_id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=UTF8
        </item>
        <!-- If the "editions" attribute is given, the request will be executed only for the editions that are defined in it (separated with commas) -->
        <item for="install" editions="ULTIMATE,MULTIVENDOR">
            ALTER TABLE `?:addon_test_123456789` ADD company_id INT NOT NULL DEFAULT 0;
        </item>
        <!-- If the parameter "for" equals "uninstall", the query is executed during the add-on uninstallation -->
        <item for="uninstall">DROP TABLE IF EXISTS `?:addon_test_123456789`</item>
    </queries>
```

* `queries` - 追加のデータベースクエリ
* `item`- データベースクエリのアイテム

Attributes:

* `for` - If this parameter is set to install or is not set, the query is executed during the add-on installation; if this parameter is set to uninstall, the query is executed during the add-on uninstallation.

このパラメーターが空の場合は\_install\_となります。クエリはアドオンのインストール時に実行されます。\_uninstall\_と設定されている場合は、アドオンのアンインストール時に実行されるクエリとなります。

* `editions` - CS-Cartエディションのリスト（カンマ区切り）。この属性が与えられた場合、リクエストは指定されたCS-Cartのエディションのみで実行されます。

***

関数・ブロック

```xml
<!-- User-defined functions called on certain events:
            before_install - before the add-on installation
            install - after the installation of the add-on, its templates, settings and language variables but before its activation and cache clearing
            uninstall - before uninstallation
            -->
    <functions>
        <item for="install">fn_google_export_add_features</item>
        <item for="install">fn_google_export_add_feed</item>
        <item for="uninstall">fn_google_export_remove_features</item>
        <item for="uninstall">fn_google_export_remove_feed</item>
    </functions>
```

* `functions` - 特定のイベントで呼び出されるユーザー定義の関数
* `before_install` - アドオンのインストール前に実行
* `install` - アドオンのインストール完了時に実行。テンプレートや設定、言語がインストールされた後。ただしアドオンが有効化されキャッシュがクリアされる前
* `uninstall` - アンインストールの前
* `item` - 関数

**Attributes:**

* `for` - 関数のきっかけとなるイベント名。この関数は特定のイベントが起こった場合に呼び出されます。可能な値：*before\_install, install, uninstall*


# アドオンの互換性

アドオンのインストール中に、アドオンがCS-Cart / CS-Cartマーケットプレイスのバージョン、PHPバージョン、およびサーバーの拡張機能と互換性があるかどうかを確認するチェックが実行されます。この情報は **addon.xml**の<`compatibility`>セクションに記述されます。

## CS-Cartのエディションとの互換性

### CS-Cartとのバージョンの互換性

以下は、アドオンと特定のバージョンのCS-Cartとの互換性を指定する方法です。

```xml
<compatibility>
    <core_version>
        <min>4.3.2</min>
        <max>4.3.6</max>
    </core_version>
</compatibility>
```

{% hint style="info" %}
HINT

`<min>`と`<max>`の両方を指定する必要はありません。これらは、それぞれサポートする最も古いバージョンと最新バージョンを表しています。
{% endhint %}

この例の設定のアドオンをバージョン4.3.7にインストールしようとすると、次のエラーが表示されます。

{% hint style="warning" %}
エラー

CS-Cartのバージョン（4.3.7）はサポートされていません。最小は4.3.2。最大は4.3.6です。
{% endhint %}

### エディション（通常版／マーケットプレイス版）との互換性

CS-Cartには、通常版（`ULTIMATE`）とECモール・マーケットプレイス版（`MULTIVENDOR`）の2つの製品があります。アドオンを、どちらか、または両方と互換性があるものとして設定できます。

* 1つのエディションのみとの互換性を設定：

```xml
<compatibility>
    <core_edition>MULTIVENDOR</core_edition>
</compatibility>
```

* 複数のエディションとの互換性を設定：

```xml
<compatibility>
    <core_edition>MULTIVENDOR,ULTIMATE</core_edition>
</compatibility>
```

**addon.xml**でエディションの互換性を`MULTIVENDOR`と指定してCS-Cart通常版にこのアドオンをインストールしようとすると、次のエラーが表示されます。

{% hint style="warning" %}
エラー

CS-Cartのエディション（ULTIMATE）はサポートされていません。ECモール・マーケットプレイス版のみインストール可能です。
{% endhint %}

## サーバー環境との互換性

### PHPバージョン

アドオンがサポートするサーバーのPHPバージョンの最小値と最大値を指定できます。

```xml
<compatibility>
    <php_version>
        <min>5.6.6</min>
        <max>7.1.1</max>
    </php_version>
</compatibility>
```

このアドオンをバージョン5.5.9のサーバーにインストールしようとすると、次のエラーが表示されます。

{% hint style="warning" %}
エラー

PHPバージョン（5.5.9-1ubuntu4.14）はサポートされていません。最小：5.6.6。最大：7.1.1です。
{% endhint %}

### PHPのエクステンションとの互換性

アドオンに必要なPHPのエクステンションを指定できます。

```xml
<compatibility>
    <php_extensions>
        <gd>
            <supported>Y</supported>
        </gd>
    </php_extensions>
</compatibility>
```

必要なPHPエクステンション（この場合は`gd`）がインストールされていない場合、次のエラーが表示されます。

{% hint style="warning" %}
エラー

このアドオンの利用には、サーバーにgdエクステンションをインストールする必要があります。
{% endhint %}

```xml
<php_extensions>
    <json>
        <min>3.0</min>
        <max>4.0</max>
    </json>
</php_extensions>
```

必要なPHPエクステンションとそのバージョン

{% hint style="info" %}
HINT

この場合、`<supported>Y</supported>`は追加する必要はありません。
{% endhint %}

PHPエクステンションとそのバージョンが設定と異なる場合、エラーが表示されます。

```xml
<compatibility>
    <php_extensions>
        <json>
            <min>3.0</min>
            <max>4.0</max>
        </json>
    </php_extensions>
</compatibility>
```

{% hint style="warning" %}
エラー

PHPエクステンション「json」のバージョン（1.3.2）はこのアドオンでサポートされていません。最小：3.0。最大：4.0。
{% endhint %}

### このアドオンと競合するPHPエクステンションをチェックする場合

```xml
<compatibility>
    <php_extensions>
        <gd>
            <supported>N</supported>
        </gd>
    </php_extensions>
</compatibility>
```

競合するPHPエクステンション（この場合はgd）がインストールされている場合、エラーが表示されます。

{% hint style="warning" %}
エラー

このアドオンの利用には、サーバーからgd拡張を削除する必要があります。
{% endhint %}


# 他のアドオンとの競合・依存設定

他のアドオンとの競合・依存設定

## 他のアドオンとの依存関係

アドオンのインストールの際に他のアドオンが必要かどうかを確認するためのチェックが実行されます。addon.xmlでこれらのアドオンを指定します。

```xml
<compatibility>
    <dependencies>discussion,form_builder</dependencies>
</compatibility>
```

上記の例は「コメントとレビューアドオン」と「フォームビルダーアドオン」がこのアドオンの依存関係にあることを設定しています。

必要なアドオンのいずれかがインストールされていない場合、次のメッセージが表示されます。

{% hint style="warning" %}
警告

「コメントとレビューアドオン」「フォームビルダーアドオン」のインストールが必要です。アドオンをインストールできません。コメントとレビューアドオン、フォームビルダーアドオンを先にインストールしてください。
{% endhint %}

## 他のアドオンとの競合関係

アドオンをインストールして有効化する際に、このアドオンが他のアドオンと競合していないかどうかを確認するためのチェックが実行されます。競合するアドオンがすでに有効になっている場合でも、アドオンをインストールすることはできますが、無効のままになります。\
addon.xmlで競合するアドオンを指定する方法を見てみましょう。

```xml
<compatibility>
    <conflicts>catalog_mode,reward_points</conflicts>
</compatibility>
```

競合するアドオンのいずれかがアクティブなときにこのアドオンを有効にしようとすると、次のメッセージが表示されます。

{% hint style="warning" %}
警告

「サンプル」アドオンは、次のアドオンと互換性がありません：「カタログモード」「特典ポイント」。 これらのアドオンを無効にするまで本アドオンは有効にすることはできません。
{% endhint %}


# APIの拡張

アドオンを使用して新しいエンティティーを持つAPIを拡張する方法；

1. アドオンディレクトリに`Tygh/Api/Entities`サブディレクトリを作成
2. `Tygh/Api/Entities` ディレクトリに新しいエンティティーを含んだファイルを作成(例､Things.php)
3. このファイルでは、ネームスペース`Tygh\Api\Entities` の`Api\Entity` クラスから受け継がれた同じ名前のクラスを定義可能です。
4. このクラスは4つの必須メソッド全てを実装する必要があります(CRUD)。

## 基本的なAPIテンプレート

```php
<?php
namespace Tygh\Api\Entities;

use Tygh\Api\AEntity;
use Tygh\Api\Response;

class Things extends AEntity
{
    public function index($id = '', $params = array())
    {
        return array(
            'status' => Response::STATUS_OK,
            'data' => array()
        );
    }

    public function create($params)
    {
        return array(
            'status' => Response::STATUS_CREATED,
            'data' => array()
        );
    }

    public function update($id, $params)
    {
        return array(
            'status' => Response::STATUS_OK,
            'data' => array()
        );
    }

    public function delete($id)
    {
        return array(
            'status' => Response::STATUS_NO_CONTENT,
        );
    }
}
```


# スキーマーの拡張

スキーマーはアドオンによって拡張やオーバーライドが可能です。

スキーマーを拡張するには、まずアドオンディレクトリ内に`schemas`ディレクトリを作成する必要があります。(まだ作成されてない場合)

このディレクトリでは、コアのスキーマのディレクトリ構造を再現することで特定のスキームを利用できます。

スキームは先頭に追加され、追加のコンテンツとコアのスキームの両方を拡張することができます。

次の命名規則に従って、ファイルに名前を付けてください；\
`<scheme_name>.[pre|post].php`

例えば、アドオンのディレクトリに`schemas/block_manage` ディレクトリを作成し、\
`blocks.pre.php` ファイルまたは`blocks.post.php` ファイル(または両方)に拡張データを記述することによって`block_manager/blocks` を拡張出来るようになります。

いくつかのスキームを拡張した「アフィリエイトアドオン」でこのテクニックを見ることができます。

例：`block_manager/blocks.php`


# アドオンのディレクトリ構造

## アドオンの必須ファイル・ディレクトリ

*app/addons/<アドオン名>* ディレクトリは、すべてのアドオンに必須です。\
テンプレートを除くすべてのアドオンファイルは、次のディレクトリに存在しなくてはなりません。

* `addon.xml`-アドオンのインストールやアンインストールに必要なアドオンについてのデータを記述します。
* `func.php`-アドオンのコントローラーなどで使用する関数が記述されています。このファイルに書いた関数はテンプレートなどからも利用可能です。
* `init.php`-アドオンで使用するPHPフックのリストの登録を行うファイルです。
* `config.php`-アドオンの設定データが格納されています。（定数の宣言など）
* `var/langs/<言語コード>/addons/<アドオン名>.po` アドオンでの言語変数

次のディレクトリも必要に応じて準備する必要があるかもしれません。

* `controllers`-このディレクトリには、アドオンコントローラーのファイルと、コアのコントローラーを拡張するPREコントローラーとPOSTコントローラーのファイルが含まれます。
* `schemas` -標準のスキーマーを拡張するファイルを含むディレクトリ。

## 追加のテンプレートディレクトリ

アドオンは、上記のディレクトリに加えて次のテンプレート用のディレクトリを使用できます。

* `var/themes_repository/basic/templates/addons/<アドオン名>` - ショップフロントのテンプレート
* `design/backend/templates/addons/<アドオン名>` - 管理パネルテンプレート
* `var/themes_repository/basic/mail/templates/addons/<アドオン名>` - メールテンプレート

{% hint style="info" %}
TIPS

開発者の裁量で、これらディレクトリにさらにサブディレクトリやファイルを作成できます。プリインストールされている他のアドオンを確認することをお勧めします。
{% endhint %}


# アドオンの言語変数

{% hint style="info" %}
HINT

言語変数とその使用方法についてはこちらをご覧ください
{% endhint %}

言語変数を使用すると、CS-Cartのアドオンの翻訳（多言語化）を行うことが出来ます。\
CS-Cartでは言語のテキストは、PHPコードやSmartyテンプレートファイルに直接記述されていません。言語を表示する際には特別な関数が呼び出されます。言語変数の名前が関数に渡され、ユーザーの環境に応じた言語でテキストが返されます。

アドオンの言語変数はPOファイルに保存されています。\
POファイルは言語ごとに別々のフォルダにあります：`var/langs/[言語コード]/addons/[アドオン名].po`

たとえば、「アクセス制御」アドオンの英語翻訳のPOファイルは`var/langs/en/addons/access_restrictions.po`にあります。

POファイルのファイル名は、`app/addons/<アドオン名>`にある`addon.xml`の`id`セクションの内容と同じでなければなりません。

この記事では、アドオンのインストール、アンインストール、またはアップグレードの際に言語変数がどのように処理されるかについて説明します。

## アドオンのインストール時

アドオンがインストールされると、そのPOファイルが分析されます。\
使用可能なすべての言語の言語変数の値がlanguage\_valuesテーブルに書き込まれます。\
このテーブルは次のフィールドで構成されています。

* `lang_code` —言語コード
* `name` —プレフィックスなしの言語変数の名前
* `value` —指定された言語コードの言語変数の値

POファイルの値も`original_values`テーブルに入れられます。\
構造は次のとおりです。

* `msgctxt` — POファイルの`msgctxt`と同様に、プレフィックス付きの言語変数の名前。
* `msgid` — POファイルの`msgid`と同様に、翻訳元の言語変数の値（原則として英語）。

## アドオンの使用時

言語変数が初めて`__`関数で使用されるとき、その値は`language_values`テーブルから取得され、キャッシュされます。以降、値はキャッシュから取得されます。言語変数は、CS-Cartの汎用キャッシュの一部です。キャッシングメカニズムは、CS-Cartの設定に依存します。

管理者は、管理パネルで言語変数の値を変更できます。これらの変更は、`language_values`テーブルの値フィールドに記録されますが、`original_values`テーブルは変更されません。

言語変数を管理パネルからのPOファイルにエクスポートする場合、`msgtxt`と`MSGID`の値は`original_values`から、`msgStr`の値は`language_values`から取得されてエクスポートされます。

## アドオンのアップグレード時

アドオンがアップグレードされると、アップグレードパッケージ内のPOファイルが分析されます。新しい言語変数は追加されますが、既存の言語変数は更新されません。これは、CS-Cart自体のアップグレードの際にも適用されます。

アドオンのアップグレードパッケージの作成についての詳細についてはこちらをご覧ください。

## アドオンのアンインストール時

アドオンがアンインストールされると、POファイルが分析されます。アドオンのすべての言語変数が`original_values`と`language_values`がテーブルから削除されます。また、言語キャッシュからも削除されます。


# .poファイルによる言語ファイルの作成

## .poファイルとは？

CS-Cartの言語ファイルは多言語対応を意識してデータベースに保存されています。4.2.4以前のバージョンのCS-Cartでは、addon.xmlにそれぞれの言語変数を用意してインストールしていましたが、新しいCS-Cartでは、[WordPress](https://ja.wordpress.org/) も利用している`gettext` による多言語化を採用しています。

これは各言語毎に.poファイルを用意することでアドオンのインストール時に言語変数がインストールされる仕組みです。[gettextについて詳しく](http://ja.wikipedia.org/wiki/Gettext) （Wikipedia）

> 📘 ヒント
>
> WordPressでは.poファイルを編集し、最終的に .poファイルは msgfmtコマンドにより バイナリファイルにコンパイルされた.moファイルを利用しますが、CS-Cartは.poファイルを使います。

## .poファイル編集ツール

.poファイルを編集するにはテキストエディターでも可能ですが、[Poedit](http://sourceforge.jp/projects/sfnet_poedit/)というツールも無料で利用可能です。

＜画像＞

## .poファイルの保存場所

翻訳を作成した.poファイルは以下のディレクトリに配置します。

```
/var/langs/[言語コード]/addons/[アドオンID].po
```

* `言語コード` 英語はen、日本語はjaのような[ISO 639-1](http://ja.wikipedia.org/wiki/ISO_639-1%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7) の言語コードとなります。
* `アドオンID`　アドオンのaddon.xmlで定義した識別子です。\
  例）カタログモード アドオン・・・catalog\_mode

## .poファイルの構造

こちらに日本語版アドオンの.poファイルを掲載しています。\
[ダウンロード](https://gist.github.com/pierrefrogman/09bc75eab721c6a5c635)

```c
msgid ""
msgstr ""
"Project-Id-Version: cs-cart-latest\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Language-Team: Japanese\n"
"Language: ja_JP\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: crowdin.net\n"
"Last-Translator: cscartjp <info@cs-cart.jp>\n"
"PO-Revision-Date: 2014-07-17 04:42-0400\n"

msgctxt "Addons::name::localization_jp"
msgid "日本語版アドオン"
msgstr "日本語版アドオン"

msgctxt "Addons::description::localization_jp"
msgid "CS-Cartを日本でのECサイト運用に最適化します"
msgstr "CS-Cartを日本でのECサイト運用に最適化します"

msgctxt "SettingsSections::localization_jp::general"
msgid "General"
msgstr "基本設定"

msgctxt "SettingsOptions::localization_jp::elm_contact_information"
msgid "連絡先情報"
msgstr "連絡先情報"

msgctxt "SettingsOptions::localization_jp::jp_familyname_kana_c"
msgid "「姓フリガナ」フィールド"
msgstr "「姓フリガナ」フィールド"

msgctxt "SettingsOptions::localization_jp::jp_firstname_kana_c"
msgid "「名フリガナ」フィールド"
msgstr "「名フリガナ」フィールド"

msgctxt "SettingsOptions::localization_jp::elm_billing_information"
msgid "請求先情報"
msgstr "請求先情報"

msgctxt "SettingsOptions::localization_jp::jp_familyname_kana_b"
msgid "「姓フリガナ」フィールド"
msgstr "「姓フリガナ」フィールド"

msgctxt "SettingsOptions::localization_jp::jp_firstname_kana_b"
msgid "「名フリガナ」フィールド"
msgstr "「名フリガナ」フィールド"

  ..........
```

## .poファイルの構造

### ヘッダー部分

以下は英語の.poファイルです。\
日本語の場合は "Language: ja\_JP\n" となります。ファイルはUTF-8で作成します。

```c
msgid ""
msgstr "Project-Id-Version: tygh"
"Content-Type: text/plain; charset=UTF-8\n"
"Language-Team: English\n"
"Language: en_US"
```

### 言語変数の記述方法

* `msgctxt` 言語の使用場所
* `msgid` 言語の識別子
* `msgstr` 翻訳

### msgctxt 言語変数の使用箇所

* `Addons::name::[アドオンの識別子]` - アドオン名を翻訳
* `Addons::description::[アドオンの識別子]` - アドオンの説明文を翻訳

例）「高解像度ディスプレイ対応」 アドオン

```c
msgctxt "Addons::name::hidpi"
msgid "HiDPI displays support"
msgstr "高解像度ディスプレイ対応"

msgctxt "Addons::description::hidpi"
msgid "Support for Retina displays"
msgstr "Retinaディスプレイに最適化した画像を表示します"

msgctxt "Languages::text_hidpi_support_enabled"
msgid "HiDPI support is enabled"
msgstr "高解像度ディスプレイ対応が有効化されています"
```

### アドオンの設定関連

* `SettingsSections::[アドオンの識別子]\::[設定セクション名]` - アドオンの設定セクション名
  * `SettingsOptions::[アドオンの識別子]\::[設定セクション名]` - アドオンの設定オプション（変数）名
  * `SettingsVariants::[アドオンの識別子]\::[設定セクション名]\::[設定値]` - アドオンの設定値

例）「ポイント」アドオン設定用言語ファイル

```c
msgctxt "SettingsSections::reward_points::general"
msgid "General"
msgstr "基本設定"

msgctxt "SettingsOptions::reward_points::point_rate"
msgid "Points Exchange Rate (PER - the number of points equal to 1 conventional unit)"
msgstr "ポイント交換レート (PER - 基本通貨1単位に相当するポイント数)"

...........
  
msgctxt "SettingsOptions::reward_points::several_points_action"
msgid "If several reward points can be applied, set"
msgstr "複数種のポイントが適用されうる際の適用ポイント数"

...........
  
msgctxt "SettingsVariants::reward_points::several_points_action::minimal_absolute"
msgid "Absolute minimal value"
msgstr "最小値（絶対値）"

msgctxt "SettingsVariants::reward_points::several_points_action::minimal_percentage"
msgid "Minimal percentage value"
msgstr "最小値（％）"

msgctxt "SettingsVariants::reward_points::several_points_action::maximal_absolute"
msgid "Absolute maximal value"
msgstr "最大値（絶対値）"

msgctxt "SettingsVariants::reward_points::several_points_action::maximal_percentage"
msgid "Maximal percentage value"
msgstr "最大値（％）"
```

＜画像＞

### アドオンで使用する言語変数

* `Languages::[言語変数名]`

例）「タグ」アドオンが使用する言語変数（テンプレートなどで利用する）

```c
msgctxt "Languages::popular_tags"
msgid "Popular tags"
msgstr "人気のタグ"

msgctxt "Languages::sign_in_to_enter_tags"
msgid "Sign in to enter tags"
msgstr "ログインしてタグを登録"

msgctxt "Languages::tag_cloud"
msgid "Tag cloud"
msgstr "タグクラウド"

msgctxt "Languages::my_tags"
msgid "My tags"
msgstr "マイタグ"
```

## .tplファイルでの利用例

> /design/themes/responsive/templates/addons/tags/views/tags/components/tags.tpl

```html
<a href="{$config.current_url|fn_url}">{__("sign_in_to_enter_tags")}</a>
```

## コントローラーでの利用例

> /app/addons/tags/controllers/frontend/tags.php

```php
<?php
...
if (empty($_REQUEST['see']) || $_REQUEST['see'] != 'my') {
    $title = __('items_marked_by_tag', array(
        '[tag]' => $tag
    ));
} else {
    $title = __('my_items_marked_by_tag', array(
        '[tag]' => $tag
    ));
}
...
```


# テーマ開発の概要

## 用語集

* `CSS` - [Cascading Style Sheets](http://ja.wikipedia.org/wiki/Cascading_Style_Sheets)
* `スタイル`（プリセットとも呼ぶ）はカラースキームなど異なるCSSスタイルをひとまとめにしたものです。これらの値はビジュアルエディタで変更できます。
* `ビジュアルエディター` (テーマエディターとも呼ぶ) ・・・特定のデザインの外観を変更するために役立つツールです。
* `テンプレート`・・・Smartyテンプレートエンジンで動作するテンプレートファイル（.tpl）
* `メディア` ・・・画像、アイコン、フォント等
* `レイアウト`・・・ストアフロントのブロックのコンテンツやレイアウトスキーム
* `レイアウト・ロケーション`・・・特定のページの外観を定義
* `コンテナ`・・・グリッドを追加するための`レイアウト`エリア。 次の4つのコンテナタイプがあります：トップパネル、ヘッダー、コンテンツ、フッター
* `グリッド`・・・グリッドの要素

## テーマの構造

テーマにはショップフロントの外観を定義する一連のファイルが含まれています。

テーマはテンプレート、CSSスタイル、メディアコンテンツ、レイアウトスキーム及びショップフロントのブロックコンテンツなどで構成されています。

さらに、テーマには `スタイル`（プリセット）を含むことができます。

＜画像＞

CS-Cartのテーマは、*design/themes/* ディレクトリに保存されています。\
CS-Cartバージョン4.2以降では`レスポンシブ`（Responsive）テーマがデフォルトです。

テーマの構造は6つのディレクトリと2つのファイルで構成されます。

* `Layout` ディレクトリ・・・レイアウトを構築する\_.xml\_ファイル が含まれています。このファイルでさらにレイアウトの詳細を定義することができます。
* `Styles` ディレクトリ・・・\_.less\_ファイル用の変数とビジュアルエディタ要素の構造を含むファイルが含まれています。
* `Templates` ディレクトリ・・・テンプレート (*.tpl* ファイル)が含まれています。
* `CSS` ディレクトリ・・・*.less* や\_.css\_ ファイルが含まれています。
* `Media` ディレクトリ・・・フォント、アイコン、画像が含まれています。
* `customer_screenshot.png` 画像・・・テーマのプレビュー用画像。この画像は管理パネルの\_デザイン > テーマ\_ セクションに表示されます。
* `manifest.json` ファイル・・・テーマの情報を含みます。

## manifest.json

このファイルはメインテーマの情報と以下の要素を含みます：

* `title`・・・管理パネルの\_デザイン > テーマ\_ セクションで表示されるテーマ名
* `description`・・・テーマの概要
* `theme`・・・サイトのロゴへのパス。\_media/images\_ディレクトリにロゴを保存することをおすすめします。
* `developer`・・・テーマの作成者（会社名）。個々の開発者がいる場合は、彼らの名前を書きます。これらの情報は管理パネルの\_デザイン > テーマ\_ セクションに表示されます。
* `favicon`・・・テーマのファビコンへのパス。\_media/images/icons\_ディレクトリにfaviconを保存することをおすすめします。
* `parent_theme`・・・親テーマの名前。レスポンシブテーマをベースに開発したいのであれば、\_responsive\_と書いてください。親テーマは、標準で用意されている2つのテーマを親とする必要があります。\_Basic\_か\_Responsive\_のいずれかを指定する必要があります。

あなたがレスポンシブなテーマを開発している場合は、`parent_theme` を`responsive` に設定します。固定幅のテーマを開発している場合、`parent_theme` を `basic` へ設定します

新しいテーマを作成する際に、全てのテーマファイルを新たに作る必要はありません。テーマのインストール時に必要なファイルはデフォルトのテーマ（*Basic\_か\_Responsive*）からコピーされます。\
`parent_theme` パラメーターは、`manifest.json`ファイルで定義します。

```json
{
    "title": "レスポンシブテーマ",
    "description": "レスポンシブテーマは様々な解像度のディスプレイに対応したテーマです。タブレット端末やスマートフォンでもCS-Cartを快適にご利用いただけます。",
    "logo": "media/images/cart.png",
    "developer": "Simtech",
    "favicon": "media/images/icons/favicon.ico",
    "parent_theme": "responsive"
}
```

{% hint style="info" %}
INFORMATION

`manifest.json`ファイルに「parent\_theme」パラメータが存在しない場合、親テーマは`$config['base_theme']` 設定によって定義されます。
{% endhint %}


# テーマの複製

独自のテーマの開発を開始するには、デフォルトでCS-Cartに付属している `レスポンシブテーマ`を複製します。

1. 管理パネルで、`デザイン`→`テーマ`に移動します。
2. 右上隅の歯車ボタンをクリックし、`テーマのコピー`を選択します。

{% hint style="info" %}
HINT

これにより、現在アクティブなテーマが複製（コピー）されます。アクティブなテーマがレスポンシブテーマでない場合、テーマの複製を作成する前にレスポンシブテーマをアクティブに切り替えてください。
{% endhint %}

＜画像＞

3. ポップアップウィンドウが開きます。複製する新しいテーマの詳細を入力します。

`ディレクトリ`— `design/themes`内の新しいテーマのディレクトリの名前になります。\
`名前` —管理パネルに表示される新しいテーマの名前。たとえば、「新しいテーマ」と設定しましょう。\
`説明` —テーマの説明。

{% hint style="warning" %}
警告

テーマの複製の際の「ディレクトリ」は`必ずアルファベットの小文字`で指定し、スペースは使用しないでください。代わりに「アンダースコア」を使用してください。 例） `new_theme`
{% endhint %}

これにより、親テーマとしてレスポンシブテーマを持つ「新しいテーマ」という複製されたテーマが作成されます。`ディレクトリ`フィールドで指定したのと同じ名前の新しいフォルダが`design/themes`ディレクトリに作成されます。

これで、新しいテーマをカスタマイズする準備が整いました。次のチュートリアルでは、管理パネルを使用してレイアウトをカスタマイズし、目的のデザインに合うようにブロックを配置します。

{% hint style="info" %}
HINT

複製したテーマは自動的に有効化されません。`デザイン` → `テーマ`で手動で有効化する必要があります。
{% endhint %}

＜画像＞


# レイアウトの管理

テーマを作成する次のステップは、レイアウトのカスタマイズです。

レイアウト設定を変更するには

* 管理パネルで、`デザイン` > `レイアウト` に移動します。
* 右側の`レイアウトの切り替え`セクションで、マウスポインターをメインレイアウトに合わせます。歯車アイコンが表示されます。
* 歯車アイコンをクリックし、`プロパティ`を選択します。
* 開いたウィンドウの`レイアウト幅`選択ボックスで `可変幅` を選択し、`最小幅` フィールドに280、`最大幅`フィールドに1200と入力します。
* `保存`ボタンをクリックします。

＜画像＞


# トップパネルとヘッダー

次のステップは、`トップパネル`と`ヘッダー`コンテナ内のブロックを作成します。

これらの変更は`デフォルト`のロケーションで設定します。

編集するには、`デザイン > レイアウト`セクションに移動します。\
`デフォルト`は最初のロケーション・タブです。

## ブロックの編集

`通貨`や`言語`のブロックを置き換えることができます。\
それを行うには、`言語`ブロックを`通貨`ブロックの後へドラッグアンドドロップします。

次に`24時間配送`ブロックを追加します。\
ブロックに新しいグリッドを追加します。特定の場所に新しいグリッドを追加するには、まず`ヘッダー`コンテナにグリッドを追加する必要があります。

`トップメニュー`ブロックとグリッドを移動します：

* `ヘッダー`コンテナにマウスポインターをおき、＋ボタンをクリックし、`グリッドの追加`をクリックします。
* 開いたウィンドウで`横幅`16を選択し、`ユーザ定義のCSSクラス`のフィールドで、*top-menu-grid* を入力し、`[作成]`をクリックします。
* 新しく作成されたグリッドを `トップメニュー`ブロックにドラッグアンドドロップします。すると、`トップメニュー` ブロックを移動した場所に空の16列のグリッドができます。
* 16列のグリッドのギアアイコンをクリックします。
* 開いたウィンドウで`横幅`選択ボックスで「3」を選択し、`ユーザー定義のCSSクラス`フィールドで\_cart-content-grid\_を入力し、`保存`をクリックします。

\- `カートの内容` ブロックをこのグリッドにドラッグアンドドロップします。

* 空のグリッドのギアアイコンをクリックします。
* 開いたウィンドウの`横幅`選択ボックスで5を選択し、`ユーザー定義のCSSクラス`フィールドで\_search-block-grid\_ と\_cart-content-grid\_ を置き換えて`保存`をクリックします。
* このグリッドに`検索`ブロックをドラッグアンドドロップします。

`ヘッダー` コンテナに空の3列のグリッドができます。これを`毎日配送`ブロックを作成するために使用します。

* 空の3列のグリッドのギアアイコンをクリックします。`ユーザー定義のCSSクラス`フィールドを消して`保存`します．
* ＋アイコンをクリックし、`ブロックの追加` をクリックします。
* 開いたウィンドウで `ブロックの追加`タブに切り替え、`HTMLブロック`ボタンをクリックします。
* `名前`フィールドに「毎日配送」と入力し、`コンテンツ`タブに切り替えます。
* `コンテンツ`フィールドの設定で、`\</>`（ソースコード表示）ボタンをクリックして、フィールドに次のコードをコピーします：

```html
<div class="ty-delivery">
  <i class="ty-delivery__icon"></i> Delivery 24/7
</div>
```

* `登録`ボタンをクリックします。

残りのブロックはそのままにしておきます。

例の中には`マイカウント`はありませんが、それは重要な機能なのでそのままにします。

結果、以下のようになります：

＜画像＞

## トップパネルとヘッダー用のスタイルを作成する

CS-Cartではビジュアルエディタで背景やリンクの色などを変えることが可能です。

管理パネルのビジュアルエディタを開き、`デザイン > テーマ`に移動し、「現在のテーマ」の`ビジュアルエディター`ボタンをクリックします。

＜画像＞

トップパネルの背景を変更するには：

ビジュアルエディタの左側のパネルで`カスタマイズ`セクションのドロップダウンメニューから「背景」を選択します。

* ビジュアルエディタの左側のパネルで`カスタマイズ`セクションのドロップダウンメニューから「背景」を選択します。
* `トップパネル`セクションを探して、`背景色`のフィールドをクリックします。\
  開いたパネルの右下隅に手動で色を定義するための入力フィールドがあります。`#573c27` と入力し色を定義します。

背景のグラデーションを定義することもできます。\
`背景色`フィールドのギアアイコンをクリックします。\
追加の設定のドロップダウンパネルが表示されます。

ここではグラデーションの2つ目の色を選ぶことができ、トップパネルを透明にするかどうかを選択します。

* 同様に、ヘッダーの背景色も定義します。例ではこの色は`#fbfbfb` です。\
  このセクションを`全幅表示`の設定をオンに切り替えます。

＜画像＞

* 全ての変更が適応されたら、`保存`ボタンをクリックします。開いたウィンドウにスタイルの名前を新たに定義し、`[OK]`をクリックします。

## 独自のCSSスタイルを追加する

CS-Cartをインストールした直下の`themes/tutorial/css/`ディレクトを開き、\
\_custom.less\_ファイルを作成します。

これは`themes/tutorial/templates/common/styles.tpl`ファイルにインクルードすることができます。

`通貨`、`言語`、`毎日配達`、`カートの内容`のカスタムスタイルなどをこのファイルに記述します。

## 通貨ブロックのカスタマイズ

デフォルトでは3つの通貨が表示されています。　画面解像度が小さい場合は、ドロップダウンリストとして表示されます。

＜画像＞

デフォルトでドロップダウンリストを表示するには：

* `デザイン > レイアウト`セクション移動し、`通貨`ブロックを探します。
* このブロックのギアアイコンをクリックして「ブロック設定」タブに切り替えます。
* アイテムをドロップダウンリストにする場合は、「ドロップダウン表示を行う最小アイテム数」に1を入力し、`保存`をクリックします。

管理パネルの一般設定 > 通貨セクションで通貨名と通貨記号を定義することができます。

例でも見たように、通貨記号が使われていないのでテンプレートから削除されます。

通貨記号が定義されているテンプレートを見つけるためには2通りの方法があります：

* *レイアウトで使用されるクラスを検索*\
  このクラスがFirefoxやChromeのFirebugやDevToolsを使って調べることができます。

{% hint style="info" %}
HINT

保存されているCSSスタイルはキャッシュされています。キャッシュを自動的にクリアするには、管理パネルの\_デザイン > テーマ\_セクションにある「キャッシュの自動リビルド」オプションを有効にします。
{% endhint %}

`templates/common/select_object.tpl`ファイルで使用されている`ty-select-block__a-item`クラスを検索します。

次のコードは、表示する通貨のアイコンを制御します：

```smarty
{if $items.$selected_id.symbol} ({$items.$selected_id.symbol nofilter}){/if}
```

この箇所をテンプレートから削除し保存します。

* 階層を含んだテンプレートを使用する\
  ブロックのテンプレートは`templates/blocks`に格納されています。`通貨`ブロックには`currencies.tpl`ファイルが使用されています。

さらに`app/schemas/block_manager/blocks.php`スキームに定義されます。

```php
<?php
'currencies' => array(
'content' => array (
        'currencies' => array (
        'type' => 'function',
        'function' => array('fn_block_manager_get_currencies'),
        ),
),
...
'templates' => 'blocks/currencies.tpl',
'wrappers' => 'blocks/wrappers',
),
```

ドロップダウンリストに通貨を表示するコード：

```html
<div class="ty-select-wrapper">{include file="common/select_object.tpl" style="graphic" suffix="currency" link_tpl=$config.current_url|fn_link_attach:"currency=" items=$currencies selected_id=$secondary_currency display_icons=false key_name=$key_name}</div>
```

このコードでは`common/select_object.tpl`ファイルが`include`されています。\
これは、通貨のアイコンが定義されているファイルです。

ここで、スタイルを追加します。

トップパネルの全リンクは白です。なので、以下のスタイルを追加してみましょう：

```css
.top-grid a {
color: #fff;
}
```

`top-grid` - グリッド設定で変更することができるグリッドのためのカスタムクラス。\
ブロックとグリッドのカスタムクラスは、名称にプレフィックス`ty-`がありません。

これは、テンプレート内のクラスとそれらを混同しないようにするのに役立ちます。

例の通貨のテキスト文字は大文字です。

`ty-select-block__a-item` に対してのみスタイルを追加することは正しくありませんし、言語の表示もまたそうです。

`ty-select-block__a-item`がセレクタに配置されたブロックにクラスを使用することをお勧めします。

```css
.top-currencies .ty-select-block__a-item {
text-transform: uppercase;
}
```

## 言語ブロックのカスタマイズ

言語名の近くにある矢印を消すには、CSSを使います：

```css
.top-languages .ty-select-block__arrow {
display: none;
}
```

`クイックリンク`のスタイルを追加します；

```css
.top-quick-links .ty-text-links__a {
font-size: 12px;
}
```

## 「毎日配送」ブロックのカスタマイズ

はじめに、このブロックにアイコンを追加します。\
[icomoon.io](https://icomoon.io/) のサービスを使用可能です。アイコンフォントの詳細をご確認下さい。

IcoMoonのアイコンのセットから時計 アイコンを選びます。

＜画像＞

Tutorial theme テーマの\_media/fonts/\_ ディレクトリにフォントを保存します。

`style.css`ファイルから`custom.less`ファイルへアイコンスタイルを移動し、フォントのパスを更新します。

```css
@font-face {
font-family: 'tutorial';
src:url('../media/fonts/tutorial.eot?-vagbvx');
src:url('../media/fonts/tutorial.eot?#iefix-vagbvx') format('embedded-opentype'),
        url('../media/fonts/tutorial.woff?-vagbvx') format('woff'),
        url('../media/fonts/tutorial.ttf?-vagbvx') format('truetype'),
        url('../media/fonts/tutorial.svg?-vagbvx#tutorial') format('svg');
font-weight: normal;
font-style: normal;
}

[class^="tt-icon-"], [class*=" tt-icon-"] {
font-family: 'tutorial';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;

/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.tt-icon-clock:before {
content: "\e601";
}
```

{% hint style="warning" %}
注意

新しいアイコンフォントを作成する際、アイコンクラス名がテンプレートのアイコンクラス名と一致しないように注意してください。プレフィックス`ty-icon-`を使用しないでください。
{% endhint %}

> 🚧 注意
>
> 新しいアイコンフォントを作成する際､アイコンクラス名がテンプレートのアイコンクラス名と一致しないように注意してください。\
> プレフィックス`ty-icon-`を使用しないでください。

`derivery`ブロックの`ty-delivery__icon` に`tt-icon-clock` クラスを追加してください。

```css
/* Delivery
========================================================================== */
.ty-delivery {
color: #573c27;
font-size: 12px;
}
.ty-delivery__icon {
color: #8f979a;
font-size: 21px;
vertical-align: middle;
margin-right: 8px;
}
```

検索フィールドのスタイルを追加します。スタイルのみで、レイアウトは変更しません：

```css
/* Search form
========================================================================== */
input.ty-search-block__input {
border-color: #fad8d3;
color: #979595;
font-size: 12px;
padding-right: 80px;
}
.ty-search-magnifier {
height: auto;
background: #e05b5b;
color: #fff;
top: 1px;
right: -1px;
width: 70px;
bottom: 1px;
font-size: 22px;
}
```

メインメニューのスタイルを追加します：

```css
/* Main menu
========================================================================== */
.ty-menu__items {
    background: none;
}
.ty-menu__item .ty-menu__item-link {
    padding: 8px 8px;
    color: #573c27;
    text-transform: uppercase;
    font-size: 13px;
    min-height: 0;
    margin-right: 10px;
}
.no-touch .ty-menu__item:hover .ty-menu__item-link,
.is-hover-menu .ty-menu__item-link,
.is-hover-menu.ty-menu__item-active .ty-menu__item-link {
    background: #e05b5b;
}
.ty-menu__submenu-items {
    margin-top: 3px;
    border-color: #e05b5b;
}
```

## 「カートの内容」ブロックのカスタマイズ

「カートの内容」ブロックは`templates/blocks/cart_content.tpl`テンプレートが使用されています。

以下のコードは､表示するカートの内容をコントロールします：

```html
<div id="sw_dropdown_{$dropdown_id}" class="ty-dropdown-box__title cm-combination">
    <a href="{"checkout.cart"|fn_url}">
        {hook name="checkout:dropdown_title"}
            {if $smarty.session.cart.amount}
                <i class="ty-minicart__icon ty-icon-basket filled"></i>
                <span class="ty-minicart-title ty-hand">{$smarty.session.cart.amount}&nbsp;{__("items")} {__("for")}&nbsp;{include file="common/price.tpl" value=$smarty.session.cart.display_subtotal}</span>
                <i class="ty-icon-down-micro"></i>
            {else}
                <i class="ty-minicart__icon ty-icon-basket empty"></i>
                <span class="ty-minicart-title empty-cart ty-hand">{__("cart_is_empty")}</span>
                <i class="ty-icon-down-micro"></i>
            {/if}
        {/hook}
    </a>
</div>
```

これを以下の内容に置き換えてください：

```html
<div id="sw_dropdown_{$dropdown_id}" class="ty-dropdown-box__title cm-combination">
    <a href="{"checkout.cart"|fn_url}">
        {hook name="checkout:dropdown_title"}
            {if $smarty.session.cart.amount}
                <span class="ty-minicart-title"><i class="tt-icon-bag"></i><span class="ty-minicart-title__amount">{$smarty.session.cart.amount}</span></span>
                <span class="ty-minicart-title__price">{include file="common/price.tpl" value=$smarty.session.cart.display_subtotal}</span>
            {else}
                <span class="ty-minicart-title empty-cart"><i class="tt-icon-bag"></i></span>
            {/if}
        {/hook}
    </a>
</div>
```

カートのスタイルを追加します：

```css
/* Cart content
   ========================================================================== */
.ty-minicart-title {
    padding: 5px 23px;
    background: #e05b5b;
    color: #fff;
    font-size: 22px;
    vertical-align: top;
    position: relative;
}
.ty-minicart-title__amount {
    position: absolute;
    position: top;
    top: -8px;
    right: -12px;
    font-size: 14px;
    color: #fff;
    background: #ed1c24;
    padding: 0 6px;
    border: 1px solid rgba(85, 32, 32, 0.4);
}
.ty-minicart-title__price {
    display: inline-block;
    vertical-align: top;
    padding: 11px 9px 10px;
    background: #e05b5b;
    color: #fff;
    font-size: 14px;
}
.top-cart-content .ty-dropdown-box__title {
    padding: 0;
}
```

最終的に、それらに要素の正しいインデントとスタイルを追加します。

以下はトップパネルとヘッダーの`custom.less`ファイルの変更後です:

```css
@font-face {
    font-weight: normal;
    font-style: normal;
    font-family: 'tutorial';
    src:url('../media/fonts/tutorial.eot?-vagbvx');
    src:url('../media/fonts/tutorial.eot?#iefix-vagbvx') format('embedded-opentype'),
        url('../media/fonts/tutorial.woff?-vagbvx') format('woff'),
        url('../media/fonts/tutorial.ttf?-vagbvx') format('truetype'),
        url('../media/fonts/tutorial.svg?-vagbvx#tutorial') format('svg');
}

[class^="tt-icon-"], [class*=" tt-icon-"] {
    text-transform: none;
    font-weight: normal;
    font-style: normal;
    font-variant: normal;
    font-family: 'tutorial';
    line-height: 1;
    speak: none;

    /* Better Font Rendering =========== */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.tt-icon-bag:before {
    content: "\e600";
}
.tt-icon-clock:before {
    content: "\e601";
}

.top-grid a {
    color: #fff;
}
.top-grid .ty-select-block__a:hover,
.top-grid .ty-select-block__a.open {
    background: none;
    color: #fff;
}

.ty-select-block__a-item {
    font-size: 11px;
}

.top-currencies .ty-select-block__a-item {
    text-transform: uppercase;
}
.top-currencies .ty-select-block__arrow {
    color: #fff;
}

.top-languages .ty-select-block__arrow {
    display: none;
}


.top-quick-links .ty-text-links__a {
    font-size: 12px;
}


div.header-grid {
    padding-top: 22px;
}

/* Delivery
   ========================================================================== */
.ty-logo-container {
    margin-top: 15px;
}

/* Delivery
   ========================================================================== */
.ty-delivery {
    margin-top: 12px;
    color: #573c27;
    font-size: 12px;
}
.ty-delivery__icon {
    margin-right: 8px;
    color: #8f979a;
    vertical-align: middle;
    font-size: 21px;
}

/* Search form
   ========================================================================== */
input.ty-search-block__input {
    padding-right: 80px;
    border-color: #fad8d3;
    color: #979595;
    font-size: 12px;
    height: 42px;
}
.ty-search-magnifier {
    top: 1px;
    right: 1px;
    bottom: 1px;
    width: 70px;
    height: auto;
    background: #e05b5b;
    color: #fff;
    font-size: 22px;
}

.tygh-header {
    border-bottom: 3px solid #e05b5b;
}

/* Main menu
   ========================================================================== */
.top-menu-grid {
    padding-top: 50px;
}
.ty-menu__items {
    background: none;
}
.ty-menu__item .ty-menu__item-link {
    padding: 8px 8px;
    color: #573c27;
    text-transform: uppercase;
    font-size: 13px;
    min-height: 0;
    margin-right: 10px;
}
.no-touch .ty-menu__item:hover .ty-menu__item-link,
.is-hover-menu .ty-menu__item-link,
.is-hover-menu.ty-menu__item-active .ty-menu__item-link,
.ty-menu__item.ty-menu__item-active .ty-menu__item-link {
    background: #e05b5b;
    color: #fff;
}
.ty-menu__submenu-items {
    margin-top: 3px;
    border-color: #e05b5b;
}

/* Cart content
   ========================================================================== */
.ty-minicart-title {
    padding: 5px 23px;
    background: #e05b5b;
    color: #fff;
    font-size: 22px;
    vertical-align: top;
    position: relative;
}
.ty-minicart-title__amount {
    position: absolute;
    top: -8px;
    right: -12px;
    font-size: 14px;
    color: #fff;
    background: #ed1c24;
    padding: 0 6px;
    border: 1px solid rgba(85, 32, 32, 0.4);
}
.ty-minicart-title__price {
    display: inline-block;
    vertical-align: top;
    padding: 11px 9px 10px;
    background: #e05b5b;
    color: #fff;
    font-size: 14px;
}
.top-cart-content .ty-dropdown-box__title {
    padding: 0;
}

/* Account
   ========================================================================== */
.ty-account-info__title {
    font-size: 12px;
}
.ty-account-info__user-arrow {
    visibility: hidden;
}
.ty-dropdown-box__title:hover,
.ty-dropdown-box__title.open {
    background: none;
}
```

## カスタマイズ結果

最後に新しく作成された「Tutorial theme」でのショップフロントがどのように見えるかを確認しましょう：

＜画像＞


# テーマを使用したショップの設定の変更

{% hint style="info" %}
HINT

この機能は、CS-Cart4.3.7以降で使用できます。
{% endhint %}

テーマは、サムネイルサイズ、商品リストの列数、特定の商品リストテンプレートなど、特定のショップの設定を考慮して設計することができます。テーマがアクティブになると、それに応じて設定を変更可能です。

## 管理者に表示される設定

管理者がいくつかの設定を変更するテーマを有効化すると、現在の設定とテーマに設定された新しい値のリストが表示されます。

＜画像＞

これらの変更を許可するには、管理者はチェックボックスをオンにして、`選択した設定を上書き`をクリックする必要があります。チェックされた設定のみが変更されます。すべての設定にチェックマークが付いていない場合、テーマの外観と機能が影響を受ける可能性があります。

## 設定を変更する方法

テーマが変更する設定を指定するには、テーマの`manifest.json`に`settings_overrides`セクションを追加します。

```json
"Settings_section_name": {  // 設定のセクション名
  "setting_name": value     // 設定: 値
  ...
}
```

セクションのリストは、`cscart_settings_sections`テーブルにあります。

![](https://files.readme.io/f62549b-cscart_settings_sections.png)

設定とその値は、`cscart_settings_objects`テーブルにあります。

＜画像＞

一部の設定は、\[表示設定]→\[クイックビューの有効化]などのチェックボックスで表されます。チェックボックスをオン（`true`）にするには、スキーマで指定します。\
チェックボックスをオフ（`false`）にするには、次の例のように指定します。

`manifest.json`の `settings_overrides` の例を次に示します。\
ここに[サンプルがあります](https://github.com/cscart/custom-theme-tutorial/blob/master/manifest.json)。

```json
"settings_overrides": {
  "General": {
    "enable_compare_products": false
  },
  "Appearance": {
    "default_products_view": "products_without_options",
    "default_product_details_view": "bigpicture_template",
    "thumbnails_gallery": true,
    "enable_quick_view": false,
    "available_product_list_sortings": [
      "product-asc",
      "product-desc",
      "price-asc",
      "price-desc"
    ]
  },
  "Thumbnails": {
    "product_lists_thumbnail_width": 300,
    "product_lists_thumbnail_height": 300
  }
}
```

このテーマが有効化されると、manifest.jsonにこの設定を持つテーマは次のことを行います。

* 商品の比較を無効にします。（一般設定→「お客様による商品の比較を許可する」）
* オプションなしのリストを商品リストテンプレートとして設定します。（表示設定→商品リストのデフォルトビュー）
* 商品ページのテンプレートとして「商品画像大」を設定します。（表示設定→商品詳細ページのビュー）
* ミニサムネイルギャラリーを有効にします。（表示設定→ミニサムネイル画像をギャラリーとして表示）
* クイックビューを無効にします。（表示設定→クイックビューを有効にする）
* 選択ソートアルファベット順：AtoZに、アルファベット順：ZtoAに、価格によるソート：安いものから高いものへ、そして高い順：価格によるソートのみ利用可能な商品のリストソーティングなど。（表示設定→利用可能な商品リストのソート）
* 商品リストのサムネイルの幅と高さを300ピクセルに設定します。（サムネイル→商品リスト（カテゴリ、検索など）サムネイルの幅）（サムネイル→商品リスト（カテゴリ、検索など）サムネイルの高さ）


# CSS

CS-Cartで利用されているCSS関連技術の概要

## LESS

＜画像＞

CS-Cartのレイアウトスタイルは\_LESS\_を用いて書かれています。\
LESSは、非常に便利なCSSプリプロセッサです。

LESSについての詳しい情報は以下のサイトで読むことができます：

<http://lesscss.org/features/> （英語）\
<http://less-ja.studiomohawk.com/> （日本語）

CS-Cartでは、すべてのLESSの機能が使用出来るわけではありません。\
どのような機能が使われているのかを理由とあわせて説明します。

## Variables（変数）

変数を作成し、複数の場所で同じプロパティ値を使用することが出来ます。

`例：`

```less
@price: #343434;
```

CS-CartのLESS変数はテーマの`スタイル`コンセプトに関連しています。( [Styles and Visual Editor](doc:styles-and-visual-editor) の項目を参照してください。)

CS-Cartがインストールされているディレクトリ以下の\_design/themes/THEME\_NAME/styles/data\_ディレクトリにビジュアルエディタと関連のあるLESS 変数が含まれた .lessファイルがあります。

これらの値はファイルを直接編集するか、ビジュアル·エディタで編集することができます。

このディレクトリの\_.less\_ファイルの変数値はこのファイルでのみ編集可能です。

例えば、`styles.less`ファイルで定義された`@price` 変数は作動しません。\
なぜなら、*.../styles/data/.less* ファイルに書かれた変数の値は、一番最後に読み込まれるためです。

## Mixins（ミックスイン）

LESSにはMixinという複数のプロパティをまとめる機能があります。ミックスインはただのプロパティ値のひとつとしてクラス名を含む他のクラス内の全てのクラスのプロパティを含むことができます。

ミックスインは関数のように動作し、次の例のように引数を取ることができます:

```less
rounded-corners (@radius: 5px) {
    border-radius: @radius;
    -webkit-border-radius: @radius;
    -moz-border-radius: @radius;
}

#header {
    .rounded-corners{
      .rounded-corners(10px);
    }
    #footer {
      .rounded-corners(10px);
    }
}
```

Bootstrap2.3のミックスインのセットがCS-Cartでは使用されています。

`design/themes/responsive/css/tygh`ディレクトリのファイルにある`mixins.less`ファイルに保存されています。

このファイルには、Utility mixinsとComponent mixinsがあります。

* `Utility mixins` - 特定の使用目的のためのシンプルなミックスイン
* `Component mixins` - グリッドを形成するために使用される複雑なミックスイン

ミックスインはCSSルールの記述を少なくすることが出来ます。ブラウザのベンダープレフィックスを用いるCSSプロパティのために使用されています。

## Operations（演算）

この機能により、CSSルール内の数学的演算が可能です：\
たし算、引き算、かけ算、割り算

例：

```less
width: (900 / @columns)px;
```

## Functions（関数）

LESSは、カラーコード、数学関数、関数を操作するための一連の関数が含まれています。

CS-Cartで使用されている操作：

* `lighten(@color, 10%)` - 現在の色よりも10％明るい色を返します。
* `darken(@color, 10%)` - 現在の色よりも10％暗い色を返します。

これらの操作は、スタイルとビジュアル·エディタに関連しています。

一つのベース色を基本色を明るくしたり、暗くしたりすることによって、他の要素の色を変更することができます。

* `percentage(0.5)` - パーセント値に変換します。グリッドと列の作成中に使用されます。

## Nested rules（入れ子）

「入れ子」は別の一つのCSSルールを囲むことが可能です。

ブラウザの開発ツールでの作業を複雑にしたのでCS-Cartでは、\
ネストされたルールはほとんど使用されていません。

開発者ツールからコピーされネストされたルールを探す時、親ルールを考慮する必要があります。

その他のLESSの可能性については公式サイトで見ることができます：<http://lesscss.org/features/>

CS-CartではLESSのすべてが動作するわけではないことに注意してください。

## CSSディレクトリ構造

利用中のテーマのCSSディレクトリへのパスは\_design/themes/THEME\_NAME\_です。

* `css/addons directory` - アドオンで追加されるスタイル
* `css/lib directory` - 他のライブラリのスタイル。Jqueryライブラリのスタイルがあります。
* `css/typh directory` - コア・スタイル
  * `css/typh/reset.less` - スタイルのリセット。`Normalize.css`が使用されています。
  * `css/typh/print.less` - 印刷用のスタイル
  * `ss/flags.less` - 国旗用スタイル
  * `css/design_mode.less` - テンプレートやデザイン・モードで使用されているスタイル
  * `css/theme_editor.less` - ビジュアルエディタで使用されるスタイル
  * `css/grid.css` - 固定レイアウトのためのグリッドを形成するために使用される言語変数やミックスイン
  * `css/mixins.less` - LESSミックスインのセット

　

### レスポンシブレイアウトに使用されるスタイル：

* `css/responsive-utilities.less` - 表示または異なるデバイスの画面解像度のコンテンツを非表示にするために使用されているBootstrapクラス。
* `css/responsive.less` - 異なる画面解像度のために使用されるスタイル。

主なファイルは\_styles.less\_です。テーマのスタイルが含まれています。*css/typh* に格納されたファイルは、`@import`オペレーターと\_styles.less\_ に含まれています。

## CSSやLESSファイルの継承順

1. `design/themes/basic/templates/common/styles.tpl`
2. `<style></style>`タグで`design/themes/basic/templates/common/styles.tpl`テンプレートに追加されたすべてのインラインスタイル。
3. プリセットされたlessファイルが含まれています。
4. ビジュアル·エディタの`カスタムCSS`フィールドに追加されたもの。
5. アドオンのスタイルはプライオリティによって定義された順序で処理されます。

HTTPリクエスト数を減らすためにすべてのファイルが１つのcssファイル集約されます。

不便な点があるといえば、そのスタイルが書かれているファイルそのものを検索することです。：ファイルとdevツールを使用して検索するときに、各ファイルの行を検索することは出来ません。


# テーマの言語変数

{% hint style="info" %}
HINT

この機能は、CS-Cart4.4.1以前では利用できません。
{% endhint %}

言語変数はテーマを使っても追加できます。翻訳ファイルは、テーマディレクトリの`langs`サブディレクトリに配置し、次のように名前を付ける必要があります。\
`言語コード.po`（例：en.po）

{% hint style="info" %}
HINT

テーマの言語変数は、テーマのインストール時にデータベースに追加されます。
{% endhint %}

テーマのデフォルト言語を指定できます。テーマが翻訳されていないすべての言語の翻訳を提供するために使用されます。テーマのデフォルト言語を指定するには、テーマの`manifest.json`に`default_language`フィールドを使用します。

`default_language`が指定されている場合：

* `langs`ディレクトリにショップのデフォルト言語のPOファイルが含まれている場合、それがデフォルト言語として使用されます。
* `langs`ディレクトリにショップのデフォルト言語のPOファイルが含まれていない場合、ディレクトリ内の最初のPOファイルがデフォルトの翻訳に使用されます。

{% hint style="info" %}
HINT

ショップのデフォルト言語は、基本設定→表示設定の`ショップページのデフォルト言語`によって決定されます。
{% endhint %}


# メディアファイル

CS-Cartの全てのメディアファイルは下記のディレクトリに保存されています：

> design/themes/your\_theme\_name/media

メールテンプレート用には、次のディレクトリを使用します：

> design/themes/your\_theme\_name/mail/media

## ディレクトリ構造

### images

* `addons` -アドオンで使用する画像は`addons/your_addon_name/`ディレクトリを使用します。
* `lib` - サードパーティーのライブラリ (jqueryui等)によって使用する画像
* `icons` - アイコンやGIFアニメーション (読み込み中の画像やポインターなど)。
* `patterns` - ビジュアルエディタで追加された背景画像など
* `fonts` - アイコンフォント（詳細は次のパラグラフを確認してください）

## アイコンフォント

アイコンフォントはCS-Cartで広く使われています。\
すべてのシンボルでアイコンフォントが使用されています。

画像アイコンと比較するとアイコンフォントには多くの利点があります：

* アイコンフォントはすべてのデバイスの画面で読みやすく表示されます。
* アイコンは１つのフォントファイルとして管理されます。
* アイコンのサイズや色を選択することができます。
* アイコンにモダンなCSSスタイルを適応させることができます：影やトランジション、アニメーション等

CS-Cartで使用される[IcoMoon](https://icomoon.io/)というサービス利用しており、シンプルにアイコンを利用できます。

次にアイコンの追加や編集の方法を説明します。

＜画像＞

* IcoMoonのサイトへ移動してください。\
  [*IcoMoon*](https://icomoon.io/)
* 右上の赤い`IcoMoon App`ボタンをクリックして編集を開始します。
* 目的のアイコンをクリックして選択し､下の`Ganerate Font…`ボタンをクリックします。

＜画像＞

* 作成したアーカイブをダウンロードするにはその`Download`ボタンをクリックします。
* ダウンロードされたファイルを解凍し、CS-Cartをインストールしたディレクトリの次のディレクトリに移動します：`design/themes/your_theme_name/media`
* 解凍して出来た`icomoon/fonts`ディレクトリの中身を`design/themes/your_theme_name/media/fonts`ディレクトリにコピーします。
* `icomoon` ディレクトリ内の\_style.css\_を`custom_icons.less`にファイル名を変更し、`design/themes/your_theme_name/css/tygh`にコピーします。
* `styles.less`ファイル内の`@import` ディレクティブで`custon_icons.less`ファイルを指定します。

```html
@import "custom_icons.less";
```

* 必要に応じて`tygh/custom_icons.less` ファイルのフォントとクラス名へのパスを変更します。
* テキスト内でこれらのアイコンを使用するには、このタイプのhtml要素を作成する必要があります： テンプレートの目的部分に`<i class="icon-user"></i>`を記述し、`icon-user`が対応するクラスを指定します。


# 親テーマ

{% hint style="info" %}
HINT

この機能は、CS-Cart4.4.1以降で使用できます。
{% endhint %}

## 概要

`manifest.json`ファイルで`parent_theme`にテーマYが指定されている場合、テーマXは依存テーマ（子テーマとも呼ばれます）であり、テーマYは親テーマです。

子テーマには、親テーマのファイルとは異なるファイルのみが含まれます。\
子テーマは、必要に応じて親テーマのコンテンツ（テンプレート、ロゴなど）を使用します。

* 親テーマおよび子テーマのcss、media、およびtemplatesフォルダーは、実行時にマージされます。
* 子テーマにファイルがない場合、代わりに親テーマの対応するファイルが使用されます。
* 子テーマに、親テーマにないファイルがある場合（商品および商品リストテンプレート、ブロックのラッパー、静的テンプレートなど）、それらは親テーマのファイルとともにリストされます。
* ファイルが子テーマと親テーマの両方に存在する場合、子テーマのファイルが優先されます。
* テーマのレイアウトおよびスタイルフォルダーはマージされません。
* 子テーマに独自のレイアウトがある場合は、それらのみが使用されます。それ以外の場合は、親テーマのレイアウトが使用されます。
* 子テーマは常に独自のスタイルを使用します。
* `$images_dir`変数を使用して、親テーマから画像をロードできます。
* テーマに親がある場合、`$images_dir` は、Smartyテンプレートでの使用は、親テーマの`media/images`ディレクトリを指します。
* テーマに親がない場合、テーマは$images\_dirの独自の`media/images`ディレクトリを指します。

{% hint style="info" %}
HINT

`$self_images_dir`変数を使用して、テーマの独自の`media/images`ディレクトリを指すことができます。
{% endhint %}

## テーマの複製

* 元のテーマに親がない場合、そのファイルは複製されたテーマのディレクトリにコピーされません。
* 複製されたテーマには、`manifest.json`ファイルと、テーマロゴ付きの\_/media/images/\_ディレクトリのみが含まれます。
* 元のテーマに親がある場合、元のテーマのコンテンツ全体が複製されたテーマのディレクトリにコピーされます。

## テーマのインストール

親テーマのファイルは、子テーマのインストール中に子テーマのファイルとマージされません。\
子テーマのファイルのみが`var/themes_repository`から`design/themes`にコピーされます。

## テーマファイルのアップグレード

アップグレードセンターは、カスタムテーマのファイルをアップグレードしません。ショップのアップグレード時には、レスポンシブテーマと基本テーマのみが影響を受けます。

## アドオンファイルのインストール

アドオンのテーマ関連ファイル（スタイル、テンプレートなど）は、作成されたテーマのみにインストールされ、子テーマにはインストールされません。

例えば、`var/themes_repository/responsive/templates/addons/[addon名]`のみにコピーされます。`design/themes/responsive/templates/addons/[アドオン名]`

基本テーマにのみテンプレートファイルを提供するアドオンは、基本テーマとそれに依存する子テーマでのみ使用できます。必要なテンプレートが現在のテーマにない場合、CS-CartはBasicテーマのテンプレートにフォールバックしません。

## レスポンシブテーマからTPLフックを使用する

レスポンシブテーマの親ではない場合でも、すべてのテーマでレスポンシブテーマのテンプレートフックのハンドラーを使用できます。このように、レスポンシブテーマ専用のテンプレートを提供するアドオンは、他のテーマとある程度連携できます。

次のファイルとディレクトリの構造があると仮定します。

```
design
└── themes
    ├── child
    │   └── templates
    │       └── addons
    │           └── styles_fixer
    │               └── hooks
    │                   └── index
    │                       └── styles.post.tpl
    ├── parent
    │   └── templates
    │       └── addons
    │           └── styles_fixer
    │               └── hooks
    │                   └── index
    │                       └── styles.post.tpl
    └── responsive
        └── templates
            └── addons
                └── styles_fixer
                    └── hooks
                        └── index
                            └── styles.post.tpl
```

アクティブなテーマはchildであり、親テーマに依存します。この場合、CS-Cartは`index:styles`、テーマのハンドラーを次の順序で検索します：子→親→レスポンシブ。\
最初に見つかったハンドラーが使用されます。

{% hint style="info" %}
HINT

レスポンシブテーマがショップにインストールされていない場合、TPLフックハンドラーの検索はレスポンシブテーマで実行されません。
{% endhint %}

＜画像＞


# スタイルとビジュアルエディター

テーマの「スタイル」とビジュアルエディターについて

## ビジュアルエディター

CS-Cart`ビジュアルエディタ`はとてもシンプルで使いやすいインターフェースを持っており、ショップフロントの外観を編集するための便利なツールです。

例えば、背景やボタンの色を変えたい場合、CSSを編集する必要はありません。\
ビジュアルエディタを開き、要素を対応するための目的の色を選択するだけです。

使用するテーマによっては、ビジュアルエディタに対応していないものもあります。

もし、あなたがテーマの開発者であるなら、開発したテーマがビジュアルエディタに対応しているとそのテーマはより魅力的になるでしょう！

テーマの利用者にとって手動でCSSを編集するよりは、はるかにスマートだからです。

管理パネルでビジュアルエディタを有効にするには、\_デザイン > テーマ\_セクションに移動し、`ビジュアルエディタ`のボタンをクリックします。

＜画像＞

## Styles（スタイル）

各テーマには、ビジュアルエディタでプリインストールされた`スタイル`セットを選択できます。

テーマには、複数のスタイルを作成することができます。\
例えば､ハロウィン期間中ではストアを暗い色にして「ハロウィン」という名前のスタイルを作成することが簡単にできます。\
ショップに一日だけ特別なスタイルを適用して、次の日にはスタイルを元に戻すことが可能です。

ビジュアルエディタで作成された全てのスタイルは以下のディレクトリに保存されています：\
`design/themes/[your_theme_name]/styles/`

スタイルのディレクトリには`１つのディレクトリ`と`２つのファイル`を含んでいます。

data/ ディレクトリは`.less`、`.css`、`.png`ファイルを含みます。これらのファイルには編集されたデータとユーザースタイルが保存されています。

## manifest.jsonファイルについて

`manifest.json`ファイルはjson形式でスタイルについてのデータが記述されています。

* `default_style` - デフォルトのスタイル。
* `names` - スタイル名。例えば、example\_style 名のスタイルを作成し、「Cool Style」に改名したい場合、以下のkey-value のペアを追加する必要があります。

```json
"names": { 
  "example_style": "Cool Style"
}
```

* `default` - デフォルトのスタイル (ビジュアルエディタから削除することはできません)。

## schema.jsonファイルについて

`schema.json`ファイルはjson形式のビジュアルエディタで編集可能な全てのフィールドを含んでいます。このファイルで独自のフィールドを追加することがで切ます。

`schema.json`は４つのセクションに分割されています。

* `general` - 一般的なセクションの設定を含む
* `fields` - 編集可能のフィールドのリスト
  * `variable_name` - less ファイルで利用可能な変数のリスト。どんな名前にも出来ます。
  * `description` - フィールドのディスクリプション
  * `type` - フィールドタイプ
  * `true` - 有効になったときチェックボックスの値
  * `false` - 無効の時にチェックボックスの値

\`\*

* `colors` - カラーセクションの設定が含まれます。
* `fields` - 編集可能なフィールドのリスト
  * `variable_name` - lessファイルで利用可能な変数のリスト。どんな名前もつけられます。
    * `description` - フィールドの説明文（言語変数名）

\`\*

* `fonts` - フォントセクションの設定が含まれます。
* `families` - デフォルトで使用可能なフォント（システムフォント）のリスト
* `fields` - 編集可能なフィールドのリスト
* `variable_name` - lessファイルで利用可能な変数のリスト。
* `description` - フィールドの説明文（言語変数名）
* `properties` - フォントの設定、例えば、サイズの値
* `size` - フォントサイズの設定
* `match` - 選択した値が保存される変数の名前。この変数名はless ファイルで利用可能です。
* `unit` - フォントサイズの値の単位：px / em / %など
* `values` - 利用可能なサイズの値の配列。\[8,9,10,11]はこれら４つの利用可能サイズから選択することができることを意味しています。
* `style` - フォントスタイルの設定（太字 / イタリック 等）
  * `U`- ビジュアルエディタで表示される設定名(`U` - 下線, `B` - 太字,`I`- イタリック)
  * `match` -選択した値が保存される変数の名前。この変数名はless ファイルで利用可能です。
  * `property` - プロパティ値(`U` - 下線)
  * `default` - デフォルト値

\`\*

* `backgrounds` - 背景セクションの設定が含まれます。
* `fields` - 変更可能なフィールドのリスト
  * `variable_name` - lessファイルで利用可能な変数の名前。
    * `description` - フィールドの説明文（言語変数名）
    * `properties` - 背景プロパティの設定値。
    * `color` - 背景色の設定
    * `match` - 選択した値が保存される変数の名前。
    * `pattern` - 値が文字列の場合、画像を背景として使用することができます。文字列は変数名として使用されます。
    * `position` - 背景ポジション。\_top, right, left, bottom\_が指定可能です。文字列は変数名として使用されます。
    * `repeat` - 背景画像のリピートの方法を定義する。\_repeat, no-repeat, repeat-x, repeat-y\_が指定可能です。文字列は変数名として使用されます。
    * `attachment` - 背景画像がコンテンツと共にスクロールされるかどうか定義する。文字列は変数名として使用されます。
  * `full_width` - 背景画像を全てのコンテンツの幅に合わせるか、コンテナに合わせるかを定義します。
    * `description`- フィールドの説明文（言語変数名）
    * `type` - フィールドタイプ（この場合はチェックボックス）
    * `true` - 有効な時にチェックボックスが取る値　
  * `false`- 無効な時にチェックボックスが取る値
  * `transparent` - 背景を透明にするかどうかを定義します。
    * `match` - 選択された値が保存される変数名
  * `gradient` - 背景をグラデーションにするかどうか定義します。カラーセクションからの値が最初の色として使用されます。
  * `match` - 選択された値が保存される変数の名

## 例

ビジュアルエディタのカラーセクションに`my_custom_field_name`でカスタムフィールドを追加する方法

`schema.json`ファイルで`カラー`セクションを探し、以下のコードを最後に追加します

```json
"my_custom_field_name": {
     "description": "theme_editor.my_custom_field_color"
}
```

* `my_custom_field_name` - lessファイルで利用可能な変数名。`description` - フィールド説明文（言語変数名）

\_less\_ファイルで`@my_custom_field_name` を使用した後、lessファイルの変数から値を使用できるようになります。

lessファイルのコードの例：

```less
.my_class {
  color: @my_custom_field_name;
}
```


# レイアウトエディター

レイアウトは、ストアフロントのルック＆フィールをカスタマイズする強力なツールです。

ドラッグアンドドロップだけでブロックの位置を変更することが出来ます。

レイアウトグリッドはCSSフレームワークである「Bootstrap 2.3」に準拠しています。\
Bootstrapについての詳しい情報は[Bootstrap公式サイト](http://getbootstrap.com/2.3.2/)をご確認ください。

CS-Cartの管理パネルの`デザイン > レイアウト`でレイアウトを管理できます。

## レイアウトの設定

レイアウトには以下の設定があります：

* `Grid columns` - グリッドは16列固定となりました（CS-Cart4.2.4）\
  グリッド内にグリッドを配置することが出来ます。
* `Layout width` - `fixed`、`requid`または`full-width`のレイアウトを選択

リキッドレイアウトに最小値と最大値のサイト幅を定義することができます。

全幅のレイアウトのサイトはフル画面の幅に適応します。

`固定`レイアウトを使用すると、ピクセル（px）で列幅を定義することができます。

1カラムの幅とそれらの間の間隔 は`css/tygh/grid.less`ファイルに定義されています。 これらはLESSの変数で定義されています：`@gridColumnWidth` と `@gridGutterWidth` 。 デフォルトでは40pxと20pxに等しいです。

以下の(@gridColumns \_ @gridColumnWidth) + ((@gridGutterWidth `(@gridColumns - 1)` サイトの最大幅を探すのは簡単です。(デフォルトでは1175px)

また、画面の幅に応じてブロックの幅を変更するには、`メディアクエリ`を使用することができます。 `リキッド`レイアウトでは列幅はパーセント(％)で定義されている。

One column widthと溝幅は固定レイアウトのために使われる変数の値に応じて比例的に定義されています。

## Layout includes

### Locations

ロケーションは、特定のページの外観を定義します。場所を追加する場合は、 設定

* `Name` - ロケーション名
* `Dispatch` - 特定のページやロケーションが関連しているページタイプ

ディスパッチパラメーターには以下の形式があります：\[*controller\_name*].\[*mode\_name*]：\[*controller\_name*]はコントローラーの名前、\[*mode\_name*]はコントローラーが作動するモードの名前

この値は\_index.php?dispatch\_に追加されます＝特定のロケーションへのぺーじと位置の一部

例えば、\_index.php?dispatch=checkout.cart\_はカートのコンテンツを示しますが、一方で、\_index.php?dispatch=checkout.checkout\_はチェックアウトページを示します。

ドロップダウンリストから定義済みの値を選択することができます。

ヘッダーやフッターのようなサイトの要素は、通常すべてのページで同様です。

各ページにこのコンテンツを複製するのではなく、デフォルトのロケーションを使用します。

`デフォルト`のロケーションはいくつかのページに添付されていますが、共通のロケーションの外観は定義していません。

デフォルトのロケーションは常に定義されています。ロケーションのデフォルトを作るには、ロケーション設定の`デフォルト`チェックボックスを選択します。

### コンテナ

ロケーションのレイアウトは4つのコンテナで構成されています：`トップパネル`、`ヘッダー`、`コンテンツ`、`フッター`

＜画像＞

`トップパネル`、`ヘッダー`及び`フッター`は`デフォルト`ロケーションでのみ定義されます。

ブートストラップコンテナはいかの構造をもっています；

固定レイアウト：

```html
<div class="container">...</div>
```

Fluid layout:

```html
<div class="container-fluid">...</div>
```

### グリッド

グリッドはコンテナに位置しています。ブートストラップのグリッドは.span と .row. を含んでいます。結果的に、16列のグリッドがCS-Cartで使用されます。

### 画像

以下のパラメーターをグリッドに定義することができます：

* `Width` - コンテナに使用される列の数。子コンテナの場合、この番号はルートコンテナの長さを超えることができない。 この設定はブロックに使用する.span を定義します。(.span1-.span16)
* `Content alignment` - ルートコンテナ内のコンテナの位置：右揃え、左揃え、全幅 左揃えにするために`ty-float-left`を追加し、右揃えにするために`ty-- float-right`を追加します。
* `Offset` - 左側からブロックリストを追加します。`.span`と同じ値を使用します。`.offset` クラスはグリッドに追加されます。
* `User-defined CSS-class` - CSSクラスを追加するために使用する

## Blocks

ブロックは特定のストアフロントの一部を表す独立したボックスです。ブロックはグリッドに追加されます。

スキーマを基にして作成されます。スキーマは全てのブロックにあるファイルで、設定やテンプレートは定義されます。

ブロックスキーマへのパスは：`app/schemas/block_manager/blocks.php`

### ブロックの設定

* `Name` - ブロック名
* `Template` ブロックごとに定義されたテンプレート。ブロックテンプレートは`templates/blocks/`ディレクトリにあります。
* `Wrapper` コンテンツを含んだテンプレート。ラッパーは`/templates/blocks/wrappers/`ディレクトリにあります。
* `User-defined CSS-class` - CSSクラスを追加するために使用する

{% hint style="info" %}
HINT

特定のページにトップパネルやヘッダー､フッター(デフォルトのロケーションのみで使用されるコンテナ)を置く必要がある場合は、Smarty supportでHTMLブロックを使用します。このブロックでは現在のページを定義するために`$runtime.controller` と `$runtime.mode`変数が使用されます。
{% endhint %}

例；

`カテゴリー`ページのフッターにテキストを表示するには：

* ヘッダーのコンテナに`HTML block with Smarty support`ブロックを作成します。
* ブロックに以下のコードを書きます：

```html
{if $runtime.controller == "categories" && $runtime.mode == "view"}
        <p>Categories page</p>
{/if}
```

## レイアウトのエクスポート/インポート

作成したレイアウトを以前レイアウト作成しインポートしたファイルにエクスポートすることができます。

それを行う為には、管理パネルの\_Design > Layouts\_ セクションに移動し、ページの右上隅のギアボタンをクリックします、そして、目的のアクションを選択します。

新しいテーマを作成する場合は、ブロックを調子した後レイアウトをレイアウトディレクトリへエクスポートします。

このレイアウトはテーマをインストールすると自動的に有効になります。

### エクスポート/インポートファイル：

* レイアウトの設定
* コンテナ、グリッド及びブロックの構造と設定
* ブロックのコンテンツ。コンテンツタブに定義さており、ブロックのタイプによ異なります。

例えば、`HTMLブロック` と `Smarty supportでのHTMLブロック`はテキストエリアに含まれるテキストです。

製品タイプのブロックでは製品表示の基準（最新、最近表示した）と設定は定義されています。

全てのブロックがコンテンツを持つわけではありません。

{% hint style="warning" %}
警告

レイアウトはテーマがをインストールする時のみインストールされます。もしテーマをインストールし他のものに切り替える場合、インストールされたテーマの最新のレイアウトは有効です。
{% endhint %}


# テンプレート

## Smarty3

CS-Cartは`Smarty 3`テンプレートエンジンを使用しています。\
Smartyは、表示部分とアプリケーションコードを分けることが可能です。

Smartyについてさらに詳しい情報は[こちら](http://www.smarty.net/docs/ja/)で確認することが出来ます。

このチャプターでは開発者にとって、非常に興味深いものになるでしょう。\
テンプレートが使用することができる構造を詳しく説明します。

## テンプレート構造

テンプレートは\_design/themes/テーマ名/templates\_ディレクトリにあります。\
テンプレートは以下の構造になっています：

* `addons` ディレクトリ - アドオン用テンプレートを格納しています。
* `blocks` ディレクトリ - ブロック設定のレイアウトで使用されるテンプレートを格納。これらはブロックを定義することができるテンプレート とラッパー です。
* `buttons` ディレクトリ - ボタン用のテンプレートを格納。ボタンの役割によって用意されています。
* `common` ディレクトリ - 複数の箇所で使用する共通の機能を持ったテンプレートを格納。例えば、パンくず、カレンダー、ページネーション用のテンプレートです。
* `pickers` ディレクトリ - 商品ページやとカテゴリーページで使用するダイアログのテンプレートを格納。
* `views` ディレクトリ -各コントローラー用のテンプレートを格納
* `404.tpl` ファイル - 404ページ用のテンプレートファイル。
* `demo_theme_selector.tpl` ファイル - `ビジュアルエディタ`用のテンプレートファイル。
* `index.tpl` ファイル - メインのテンプレートファイル。このファイルは以下の内容が含まれています。
* *DOCTYPE* - 必須要素。 `<!DOCTYPE html>`を使用することをお勧めします。
* Title - ページタイトル
* \_meta.tpl\_ファイルの読み込み
* \_common/styles.tpl\_ファイルの読み込み
* *common/scripts.tpl* ファイルの読み込み
* ビジュアルエディタ、デモパネル、翻訳、テンプレートモードの各ファイルの読み込み
* `meta.tpl` ファイル - サイトのメタ情報が書かれたファイル：description, keywords, viewport等

\`\*

以下はCS-Cart Version 4.2.4の`responsive`テーマの各ファイルです。

```html
{*  To modify and rearrange content blocks in your storefront pages
    or change the page structure, use the layout editor under Design->Layouts
    in your admin panel.

    There, you can:

    * modify the page layout
    * make it fluid or static
    * set the number of columns
    * add, remove, and move blocks
    * change block templates and types and more.

    You only need to edit a .tpl file to create a new template
    or modify an existing one; often, this is not the case.

    Basic layouting concepts:

    This theme uses the Twitter Bootstrap 2.3 CSS framework.

    A layout consists of four containers (CSS class .container):
    TOP PANEL, HEADER, CONTENT, and FOOTER.

    Containers are partitioned with fixed-width grids (CSS classes .span1, .span2, etc.).

    Content blocks live inside grids. You can drag'n'drop blocks
    from grid to grid in the layout editor.

    A block represents a certain content type (e.g. products)
    and uses a certain template to display it (e.g. list with thumbnails).
*}
<!DOCTYPE html>
<html lang="{$smarty.const.CART_LANGUAGE}">
<head>
{capture name="title"}
{hook name="index:title"}
{if $page_title}
    {$page_title}
{else}
    {foreach from=$breadcrumbs item=i name="bkt"}
        {if !$smarty.foreach.bkt.first}{$i.title|strip_tags}{if !$smarty.foreach.bkt.last} :: {/if}{/if}
    {/foreach}
    {if !$skip_page_title && $location_data.title}{if $breadcrumbs|count > 1} - {/if}{$location_data.title}{/if}
{/if}
{/hook}
{/capture}
<title>{$smarty.capture.title|strip|trim nofilter}</title>
{include file="meta.tpl"}
<link href="{$logos.favicon.image.image_path}" rel="shortcut icon" />
{include file="common/styles.tpl" include_dropdown=true}
{include file="common/scripts.tpl"}
</head>

<body>
{if $runtime.customization_mode.design}
    {include file="common/toolbar.tpl" title=__("on_site_template_editing") href="customization.disable_mode?type=design"}
{/if}
{if $runtime.customization_mode.live_editor}
    {include file="common/toolbar.tpl" title=__("on_site_live_editing") href="customization.disable_mode?type=live_editor"}
{/if}
{if "THEMES_PANEL"|defined}
    {include file="demo_theme_selector.tpl"}
{/if}

<div class="ty-tygh {if $runtime.customization_mode.theme_editor}te-mode{/if} {if $runtime.customization_mode.live_editor || $runtime.customization_mode.design}ty-top-panel-padding{/if}" id="tygh_container">

{include file="common/loading_box.tpl"}
{include file="common/notification.tpl"}

<div class="ty-helper-container" id="tygh_main_container">
    {hook name="index:content"}
        {render_location}
    {/hook}
<!--tygh_main_container--></div>


{if $runtime.customization_mode.design}
    {include file="common/template_editor.tpl"}
{/if}
{if $runtime.customization_mode.theme_editor}
    {include file="common/theme_editor.tpl"}
{/if}
{hook name="index:footer"}{/hook}
<!--tygh_container--></div>
</body>

</html>
```

```html
{hook name="index:meta"}
{if $display_base_href}
<base href="{$config.current_location}/" />
{/if}
<meta http-equiv="Content-Type" content="text/html; charset={$smarty.const.CHARSET}" data-ca-mode="{$store_trigger}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
{hook name="index:meta_description"}
<meta name="description" content="{$meta_description|html_entity_decode:$smarty.const.ENT_COMPAT:"UTF-8"|default:$location_data.meta_description}" />
{/hook}
<meta name="keywords" content="{$meta_keywords|default:$location_data.meta_keywords}" />
{/hook}
{$location_data.custom_html nofilter}
```

```php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>{__("page_not_found")}</title>
    {literal}<style type="text/css">
    .ty-exception {
        font: normal 13px Arial, Tahoma, Helvetica, sans-serif;
        position: absolute;
        top: 10%;
        left: 50%;
        margin: 0 0 0 -480px;
        width: 960px;
    }
    .ty-exception p {
        margin: 0;
        padding: 0px 0px 30px 0px;
        color: #808080;
        font-size: 110%;
    }
    .ty-exception-code {
        float: left;
        display: inline-block;
        margin-right: 30px;
        padding: 50px 30px 40px;
        -webkit-border-radius: 9px;
        -moz-border-radius: 9px;
        border-radius: 9px;
        background-color: #f9f9f9;
        background-image:-moz-radial-gradient(50% 50%,circle closest-side,rgb(255,255,255) 0%,rgb(246,246,246) 100%); 
        background-image:-webkit-gradient(radial,50% 50%,0,50% 50%,94,color-stop(0, rgb(255,255,255)),color-stop(1, rgb(246,246,246)));
        background-image:-webkit-radial-gradient(50% 50%,circle closest-side, rgb(255,255,255) 0%,rgb(246,246,246) 100%);
        background-image:-ms-radial-gradient(50% 50%,circle closest-side, rgb(255,255,255) 0%,rgb(246,246,246) 100%);
        background-image:radial-gradient(50% 50%,circle closest-side, rgb(255,255,255) 0%,rgb(246,246,246) 100%);
        -webkit-box-shadow:inset 0px 1px 10px 0px rgba(0,0,0,0.05);
        -moz-box-shadow:inset 0px 1px 10px 0px rgba(0,0,0,0.05);
        box-shadow:inset 0px 1px 10px 0px rgba(0,0,0,0.05);
        color: #bfbfbf;
        font: normal bold 86px Arial, sans-serif;
        line-height: 70px;
        -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Style=2)";
        filter:progid:DXImageTransform.Microsoft.Alpha(Style=2);
    }
    .ty-exception-code em {
        display: block;
        text-align: center;
        font: normal normal 26px Arial, sans-serif;
    }
    .ty-exception h1 {
        margin: 0;
        padding: 0px 0px 25px 0px;
        font: normal bold 25px Arial, sans-serif;
    }
  </style>{/literal}
</head>
<body>
    <div class="ty-exception">
        <span class="ty-exception-code"> {$exception_status} <em>{__("exception_error")}</em> </span>
    <h1>{__("exception_title")}</h1>
    <p>
        {if $smarty.const.HTTPS === true}
            {assign var="return_url" value=$config.https_location|fn_url}
        {else}
            {assign var="return_url" value=$config.http_location|fn_url}
        {/if}
        
        {if $exception_status == "403"}
            {__("access_denied_text")}
        {elseif $exception_status == "404"}
            {__("page_not_found_text")}
        {/if}
    </p>
    <p>{__("exception_error_code")}
        {if $exception_status == "403"}
            {__("access_denied")}
        {elseif $exception_status == "404"}
            {__("page_not_found")}
        {/if}
    </p>
    </div>
</body>
</html>
```

## アドオン用のテンプレート

アドオン用のテンプレートは`templates/addons`ディレクトリにあります。

## アドオンのテンプレートの構造

* `blocks`ディレクトリ -アドオンブロックンテンプレート。レイアウトエディターでブロックとして選択可能となります。 `blocks/product_tabs`以下のファイルは商品タブで選択可能になります。
* `hooks` ディレクトリ - テンプレートフック用のテンプレート
* `views` テンプレート - 独自に追加されたテンプレート

アドオンディレクトリではこれらの他にもアドオンを正常に作動させるために必要な他のディレクトリやファイルを自由に配置できます。`ソーシャルボタン`アドオンの`providers` ディレクトリなどを参照して下さい。

## Blocks テンプレート

ブロック用のテンプレートは\_templates/block\_ ディレクトリにあります。\
ブロックの役割によって異なったテンプレートが適応されます。

テンプレートアプリケーションは\_app/schemas/block\_manager/blocks.php\_ ファイルに定義されています。

例えば、カテゴリーブロックでは

```php
'templates' => 'blocks/categories'
```

`blocks/categories`ディレクトリから全てのテンプレートに適応が可能ということ意味します。

ファイル名は言語変数によって以下のように定義されます：

* ファイル内のコードに次のパートをもつ場合：`{block-description:name_of_template}`、`name_of_template`が使用されます。
* ファイルにこのような記述がない場合は、テンプレートファイル名に基づいて言語変数が設定されます。

## Views テンプレート

CS-Cartでは、Model-View-Controller (MVC)のアーキテクチャーパターンが使用されています。

`views` ディレクトリはサイトのテンプレート群を含みます。`views`ディレクトリ以下のディレクトリ名称はコントローラー名などによって定義されます。

ディレクトリにあるファイルはコントローラーで定義されたモードで使用されます。

また、コントローラが定義するディレクトリ以下には`components`ディレクトリがあります。そこに保存されているテンプレートは、追加機能を実行します。

以下のページで使用されるテンプレートは、どのように定義するのか見てみましょう：

> index.php?dispatch=categories.view\&category\_id=166

* `categories` - データを受信するために参照されるコントローラー。カテゴリーのデータが必要なので、viewsディレクトリに\_categories\_ディレクトリが必要となります。
* `view` - categoriesコントローラーに書かれたモード名。モード名と同じファイルを作成します。（view\.tpl）
* `category_id` - 表示したいカテゴリーのIDとなります。（コントローラーに渡す引数）


# デバッガー

{% hint style="info" %}
HINT

デバッグモードは、英語でのご提供となります。
{% endhint %}

CS-Cartはプロファイリングやログ及びデータ設定へのアクセスが簡単になる便利なデバッガを内蔵してます。

デバッガはHTTPリクエスト、SQLクエリ及びストアフロントや管理パネルの任意のページのテンプレートの読み込みを点検するために使用することが出来ます。

## デバッグモードの有効化

管理パネルでデバックモードを有効にするには、URLの文字列に`debug`パラメータを追加することでデバッグモードを起動できます。

＜画像＞

`config.php`や`local_conf.php`ファイルで以下のような一行を追加することでも、\
デバッグモードを常に有効にできます。

```php
<?php
...
define('DEBUG_MODE', true);
```

{% hint style="warning" %}
警告

開発時以外でこのモードを使用しないでください。 ショップがすでにオープンしている状態の場合、ショップに訪れる人がデバックデータへのアクセスを出来てしまいます。
{% endhint %}

デバッグモードを有効にして管理パネルにアクセスすると、ページの右上のにある半透明の虫（bug）のアイコンが表示されます。

＜画像＞

デバッガのサイドバーを開いたり閉じたりするにはそのアイコンをクリックします。\
あるいは、 `Ctrl + Alt + D` を押します。

## デバッガー・サイドバー

### Serverタブ

＜画像＞

`サーバー`タブでは、システム内のインストールされたPHPとPHPモジュールに関する情報と一般的なシステム情報が表示されます：バージョン、パス、コンフィグ変数の値、など

### Requestタブ

＜画像＞

リクエストタブでは、最新のHTTPリクエストとそれぞれのサーバーの対応に関する情報のほか、Cookieの値が表示されます。

### Configタブ

* Config

＜画像＞

値は、コンフィグレーションファイルから取り出されます。(config.php and local\_conf.php )

* Settings

＜画像＞

現在の設定値はデータベースから取り出されます。\
( `cscart_settings` tables)

* Runtime

＜画像＞

現在実行されるスクリプトに関連するデータ

### SQL

＜画像＞

このタブでは、それぞれの実行時間とページの読み込み中に実行されたSQLクエリを見ることができます。また、\_Queries parse\_タブ でカスタムSQLクエリを送信することができます。

### Logging

＜画像＞

このタブでは、メモリ消費、読み込まれたファイル数、実行されたSQLクエリ及びページの読み込みに費やされた時間のデータを見ることができます：

* 初期化の前
* 初期化後
* テンプレート読み込み前
* テンプレート読み込み後

### Templates

＜画像＞

この`テンプレート`タブでは、テンプレートの階層やページの背後のデータに関する詳細情報を確認することができます。 テンプレートツリーとすべてのテンプレートで使用される変数のリストを見つけることができます。


# ファイルエディター

`ファイルエディタ`は`.../design/themes/theme_name`ディレクトリ以下に置かれているファイルを管理するのに役立ちます。

{% hint style="info" %}
HINT

ファイルエディタはJavascriptベースです。ファイルエディターを利用する場合は、お使いのブラウザでJavascriptを有効にしてください。
{% endhint %}

## ファイルの編集方法：

* 管理パネルの`デザイン > ファイルエディター`へ移動します。
* 左のパネルから目的のディレクトリとファイルを選択します。このパネルは\_.../design/themes/theme\_name\_ディレクトリの構造を示しています。
* コードの部分を編集したら、\_【変更を保存】\_をクリックします。

＜画像＞

{% hint style="warning" %}
警告

現在使用されているテーマのファイルが表示されているかどうかを確認してください。ほかのテーマを編集したい場合は、デザイン > テーマから選択してください。
{% endhint %}

ファイルエディターは、ストアフロントのテンプレートをその場で編集することが可能です。

ストアフロントで目的の要素を選択し、要素の右上のアイコンをクリックしてテンプレートの内容を編集します。

ソースコードは強調されていますので、テンプレートの構造を調べることはとても簡単です。保存された変更はストアフロントでそのまま確認することができます。

{% hint style="info" %}
HINT

設定にある自動キャッシュ再構築の設定をオンにすることを忘れないでください。これにより変更後すぐにデータがキャッシュされ変更をすぐに見ることができます。
{% endhint %}

## ファイルエディターの利用方法

`ファイルエディタ`の使用の一例として、商品のカテゴリページで`カートへ追加`要素の場所を変更する例を見てみましょう。

＜画像＞

`templates > blocks > list_templates > products_list.tpl`をファイルエディタを開き、下記の行を探し、コードから削除してください：

`<>`

* 同じファイルで`<div class=”float-left product-item-image center”>` クラスを持つ要素を探し、画像のように正確に以前のコードをペーストします:

`<>`

* `float-right right`を`<div class=”float-right right add-product”>`から削除し、`<div class=”add-product”>`に変更します。
* 【変更を保存】をクリックします。
* 変更が正確に変更されたことを確認するためにストアフロントのカテゴリーページを開きます。


