Blog

ブログ

【ECCUBE4系】MemcachedにのせたDoctrineCacheのCacheClearコマンドを自作してみる

今日はcacheのお話です。

※今日は、大好きなEventSubscriberの出番はありません※

前置き

複数台構成でECCUBEを運用するときに、気になるのはcacheですよね!

cacheの恩恵は大きいですが、サーバーが複数台構成の時は困ってしまうことも。。。

今回は、3台構成のWebサーバーでDoctrineCacheをMemcachedで管理するときに、DoctrineCacheのクリアコマンドを自作したときのお話です。

DoctrineCacheをどうやってMemcachedにのせるの。。。?という内容は、ご要望があれば別日に書こうかと思ってます。

なので、今回はDoctrineCacheをどうやってMemcachedにのせる設定とかは割愛させて頂きます。

 

実際に作成したコマンド

app/Customize/Command配下に以下のファイルを作成しました。

<?php

namespace Customize\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class DoctrineCacheClearCommand extends Command
{
    protected static $defaultName = 'memcached:doctrine-cache:clear';

    const SESSION_PREFIX = 'session';

    /**
     * @var SymfonyStyle
     */
    protected $io;

    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->io = new SymfonyStyle($input, $output);
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        try {
            $memcached = new \Memcached();
            $memcached->addServer(env('MEMCACHED_HOST'), env('MEMCACHED_PORT'));
            $keys = $memcached->getAllKeys();

            foreach ($keys as $key) {
                if (substr($key, 0, 7) !== self::SESSION_PREFIX) {
                    $memcached->delete($key);
                }
            }

            $this->io->success('Doctrine Memcached All Clear.');
        } catch (\Error $e) {
            $this->io->error('Doctrine Memcached Clear Failure Error.');
        } catch (\Exception $e) {
            $this->io->error('Doctrine Memcached Clear Failure Exception.');
        }

        return true;
    }
}

処理の説明

今回はsessionもMemcachedにのせているので、Memcachedをflush_allするというわけにはいきませんでした。

session情報も消えてしまうので、releaseする度にCustomerが再ログインしなければならないなんて、ユーザビリティ悪すぎですもんね。。。

 

方法はとてもシンプルです!

Memcachedから全てのkeyを取得して、sessionのプレフィックスがついているもの以外を順次削除していくだけです!

本当は。。。

DoctrineCacheにプレフィックスを作成して、そのプレフィックスのkeyを取得して消すという方法を取りたかったのですが、DoctrineCacheの時はプレフィックスをつけられなかったのです。。。

まだまだ勉強不足なんでしょうね。。。

 

使い道

管理画面からキャッシュクリアを行うときに合わせて呼び出すように改修したり。。。

デプロイ用のスクリプトに組み込んでみたり。。。

サーバーで直接叩いてみたり。。。

と、使っています。

サーバーが複数台構成でも、cacheとは上手く付き合っていきたいですよね、やはり画面の表示速度が違います!

 

最後に

今回は自作でキャッシュクリアのコマンドを作ってみた時のお話でした。

最近は画面側を作成するより、外部連携等のBatch作成の方が楽しいなーなんて思ってます。

この機会に、サーバーが複数台構成でもcacheと上手くお付き合いできる方法を考えてみませんか?

【ECCUBE4系】CSV登録画面初期表示で、twigマスタテーブルの値を表示させる

今日もtwigのお話を書いていこうと思います。

※今日は、大好きなEventSubscriberの出番はありません※

前置き

例えば、商品CSV登録画面の「公開ステータス(ID)」は、messages.ja.yamlが空文字になっているので、説明欄には何も出力されていないですよね?
商品の公開ステータスは、mtb_product_statusはデフォルトの状態で3レコードしかないので、messages.ja.yamlに直接記載する方法でもそんなに手間ではないかもしれません。

ですが、これが
「mtb_pref(都道府県のマスタテーブル)のIDと名称を全部出力してください。」
なんて依頼が来ると、47レコード分をmessages.ja.yamlに記載するのは正直手間だなー。。。と思ってしまいました。

そこで、テーブルからidとnameを抜き出して、文字列化するServiceを作ったので、そのご紹介になります。
テーブル構造によっては、mtbでもdtbでも使えるので、試してみてください。

 

前提条件

  • primary keyがIDであること
  • 出力する値のカラム名がnameであること

 

Serviceを作成する

まずは、Serviceを作っていきましょう。

<?php

namespace Customize\Service;

class CsvViewDiscriptionService
{
    /**
     * CSV登録画面でマスターデータから選択肢を表示させる文字列を返却
     * 例)1:北海道 2:青森県 3:岩手県
     *
     * @param array $data
     * @return string|null
     */
    public function getDiscriptionTextData(array $data)
    {
        $text = null;
        foreach ($data as $key => $datum) {
            if ($key !== 0 && $key % 5 === 0) {
                $text .= '<br>';
            }
            $text .= $datum->getId() . ':' . $datum->getName() . ' ';
        }

        return $text;
    }
}

ServiceはこれだけでOKです。
引数をforeachで回して、文字列に変換しているだけですね!

 

Controllerで呼び出す

次にControllerの方で、このServiceを呼び出してみましょう。
必要箇所のみ抜粋して記載してみます。

trans('admin.product.product_csv.display_status_col') => [
    'id' => 'status',
    'description' => 'admin.product.product_csv.select_id_description',
    'required' => true,
    'data' => $this->csvViewDiscriptionService->getDiscriptionTextData($this->productStatusRepository->findAll())
],

今回は商品ステータスを出力させたいので、productStatusRepositoryから全件取得を行なっています。
もちろん、ここは条件付きでも問題ありません。
要は、twigで描画したいレコードが取得できれば良いのです。

 

twig側の修正

<div id="ex-csv_product-format" class="card-body">
    <table class="table table-striped table-bordered">
        <tbody>
        {% for header, key in headers %}
            <tr>
                <th class="w-25 align-middle table-ec-lightGray" id="file_format_box__header--{{ loop.index }}">{{ header }}
                    {% if key.required %}
                        <span class="badge badge-primary ml-1">{{ 'admin.common.required'|trans }}</span>
                    {% endif %}
                </th>
                <td class="align-middle">
                    {% if key.description %}
                        {{ key.description|trans|raw }}
                    {% endif %}
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</div>

こうなっている箇所を

<div id="ex-csv_product-format" class="card-body">
  <table class="table table-striped table-bordered">
    <tbody>
    {% for header, key in headers %}
      <tr>
        <th class="w-25 align-middle table-ec-lightGray"
            id="file_format_box__header--{{ loop.index }}">{{ header }}
          {% if key.required %}
            <span class="badge badge-primary ml-1">{{ 'admin.common.required'|trans }}</span>
          {% endif %}
        </th>
        <td class="align-middle">
          {% if key.description %}
            {{ key.description|trans|raw }}
          {% endif %}
          {% if key.data is defined %}
            <hr>{{ key.data | raw }}
          {% endif %}
        </td>
      </tr>
    {% endfor %}
    </tbody>
  </table>
</div>

こんな感じで修正します。

discriptionを出力している箇所に

{% if key.data is defined %}
  <hr>{{ key.data | raw }}
{% endif %}

が追加されただけですね。

動作確認

最後に動作確認をしてみましょう。

商品ステータス(ID)の箇所が以下のように出力されていると思います。

1:公開 2:非公開 3:廃止

これで、テーブルから取得してきた値をtwigにStringで渡すServiceの完成です、とっても簡単ですね!

 

最後に

前提条件で、「primary keyがIDであること」と「出力する値のカラム名がnameであること」と記載しましたが、自由にカスタマイズ可能だと思います。
(文章があまり上手くないので、説明しやすくしたかったのです)

こんなServiceを1つ作っておくだけで、簡単に管理画面のCSV登録画面での文言出力が簡単になります。
この機会に、CSV登録画面にテーブルの値を出力してユーザービリティーを向上させてみませんか?

【ECCUBE4系】フロント側の全twigで参照できる変数を作る

こんにちわ。
今回はtwigの変数についての投稿です。

twigで値を参照したい場合、通常であればControllerで値を取得し、returnしてtwigに渡しますよね?
でも、sessionやcookieに格納している値を全画面で利用したいなーと思うと、全画面のControllerとtwigの修正を行うとなると、それなりの工数がかかりますよね。

例えば、Customerがログインを行なった場合、認証が通った後で会員の今までに購入した金額によって

  • 今までの購入金額が1万円未満の場合は、Aグループに所属するCustomer
  • 今までの購入金額が5万円未満の場合は、Bグループに所属するCustomer
  • 上記以外の場合は、Cグループに所属するCustomer

と言った具合で条件を設定し、それでtwig側で出力する文言を変更したいです!なんて要望があった場合、数箇所であればControllerから値を渡すでもいいと思いますが、フロント側全体で文言の出しわけをして欲しいという要望があると、twigの修正は仕方ないですが、Controllerも併せて全修正するのは大変です。

そこで、今回も出てきます、EventSubscriberです!
みんな大好き、EventSubscriberです!

 

ログイン時の処理を作成する

今回は一例で紹介させて頂きますので、詳しいコードは割愛します。

ご担当の案件の要望に合わせて、customer_groupをキーにsessionにお好みの値を保持してください。

 

twigで参照する変数を作る

ここからが今日の本題です。

まずは、以下のようなコードをapp/Customize/EventListener配下に作成してみましょう。

 

<?php

namespace Customize\EventListener;

use Eccube\Request\Context;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;

class TwigInitializeListener implements EventSubscriberInterface
{
    /**
     * @var bool 初期化済かどうか.
     */
    protected $initialized = false;

    /**
     * @var Environment
     */
    protected $twig;

    /**
     * @var Context
     */
    protected $requestContext;

    /**
     * TwigInitializeListener constructor.
     *
     * @param Environment $twig
     * @param Context $context
     */
    public function __construct(
        Environment $twig,
        Context $context
    ) {
        $this->twig = $twig;
        $this->requestContext = $context;
       
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        if ($this->initialized) {
            return;
        }
        if ($this->requestContext->isFront()) {
            $this->addGlobal($event);
        }

        $this->initialized = true;
    }

    public function addGlobal(GetResponseEvent $event)
    {
        $customerGroup = $event->getRequest()->get('customer_group');

        $this->twig->addGlobal('customerGroup', $customerGroup);
    }

    /**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::REQUEST => [
                ['onKernelRequest', 7],
            ],
        ];
    }
}

これで、twigから参照する処理は記載できました。
今回は、TwigInitiializeListenerで認証処理が完了した後に実行したかったので、Priorityは7に設定してあります。

 

twig側で参照する

ここまでできたら、あとはtwig側に処理を書くだけです。

{% if customerGroup == 'A' %}
    <div>
                <p>今月末までに1万円以上買っていただけると、お得意様になります。</p>
    </div>
{% elseif customerGroup == 'B' %}
        <div>
                <p>今月末までに5万円以上買っていただけると、超お得意様になります。</p>
        </div>
{% else %}
        <div>
                <p>あなたは現在、超お得意様になります。</p>
        </div>
{% endif %}

これで、全twigでcustomerGroupが参照できるようになっているはずです。
もちろん、Controllerが用意されていない静的ページからでも参照できます。

EventSubscriber便利ですね!
みんな大好き、EventSubscriberです!!!(2回目)

twigに渡す変数、各Controllerから渡す前に、EventSubscriberで使い回す道を検討してみませんか?

Requestのお供に、EventSubscriberをぜひよろしくお願い致します。

【ECCUBE4系】ボタンで表示言語を選択できるようにする

先日shopifyでサイトを多言語化する方法をご紹介させて頂きました。
本日は、ECCUBE4系で多言語化対応を行う際に、ボタンで言語を切り替えられるように実装してみたのでご紹介します。

まずはControllerの作成

<?php

namespace Customize\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;

class LanguageController extends AbstractController
{
    /**
    * @Route("change/language", name="language_change")
    */
    public function changeLanguage(Request $request)
    {
        $session = $request->getSession();
        $session->set('language', $request->query->get('language'));

        return $this->redirect(言語選択後に表示したいページ);
    }
}

これでボタンを押したときに、セッションに選択した言語情報を保持出来るようにしました。

 

header.twigに言語切り替えボタンを出力

{% if app.session.get('language') == 'ja" %}
  <ul>
    <li><a href="{{ url('language_change', {'language': 'en'}) }}">{{ 'English'|trans }}</a></li>
  </ul>
{% else %}
  <ul>
    <li><a href="{{ url('language_change', {'language': 'ja'}) }}">{{ '日本語'|trans }}</a></li>
  </ul>
{% endif %}

選択済みの言語によって、出力されるボタンが動的に変わるようにしました。
(初期値は、.envのECCUBE_LOCALEに設定されている値なので、「English」のボタンが初期値で出力されます)

EventSubscriberを作成する

ここが一番大好きな作業です!
みんな大好き、EventSubscriberです!

<?php 
namespace Customize\EventSubscriber; 

use Symfony\Component\DependencyInjection\ContainerInterface; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
use Symfony\Component\HttpKernel\KernelEvents; 

class LanguageSubscriber implements EventSubscriberInterface 
{ 
    /**
     * @var ContainerInterface
     */ private $container;

    /**
      * LanguageSubscriber constructor. 
       * 
       * @param ContainerInterface $container 
       */ 
       public function __construct(ContainerInterface $container)
      { 
                 $this->container = $container;
    }

    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::REQUEST => [['onKernelRequest', 18]],
        ];
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();

        $request->setLocale($request->getSession()->get('language', env('ECCUBE_LOCALE')));
    }
}

これで出来上がりです!
なんて簡単なんでしょう、EventSubscriber最高ですね!

最後に補足説明

ちなみに、KernelEvents::REQUESTで、2番目に指定している「18」ですが、これはSymfonyのPriority(優先順位)の指定になります。
ECCUBEもローカルで開発してる時なんかは、デバッグモードにしていると思いますが、デバッグバーをポチッとするとSymfonyの画面に遷移しますよね?

左のメニューバーから「Events」を選択すると、Event Dispatcherが確認できるので、
“Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest()”
のPriorityが幾つになっているか確認して、LocaleListener::onKernelRequest()よりも優先順位を決めてあげるのが良さそうです。

優先順位まで指定できるなんて、EventSubscriber最高ですね!(2回目)
EventSubscriberが大好きすぎて、いろんな処理を割り込ませたくなりますが、他の処理を割り込ませた話は、またの機会に投稿しようと思います。

messages.XX.yamlやvalidators.XX.yamlの作成を忘れずに行ってくださいね!

Requestのお供に、EventSubscriberをぜひよろしくお願い致します。

EC-CUBEからMysqlへのSSL接続を設定する

お世話になっております。株式会社Joolenの白井です。

いつもOSS開発部にてEC-CUBEのカスタマイズ開発とかをやっています。ときどき本体へのコントリビュ〜ションなどもやっています(もうちょっと増やしたいです)。

そんなに派手なことはやっておりませんので、ちまちました設定の話をします。

Continue reading “EC-CUBEからMysqlへのSSL接続を設定する”

新規会員登録時クーポン付与プラグイン for EC-CUBE 4.0 をリリースしました!

◯リリースのご案内

集客施策シリーズの「新規会員登録時ポイント付与プラグイン for EC-CUBE 4.0」の売れ行きが好調※だったこともあり、新規会員登録時にクーポンを付与する機能についてのご要望をたくさんいただいておりました。
※オーナーズストア有料ランキング27位(2021年5月12日時点)

??この度、「新規会員登録時クーポン付与プラグイン for EC-CUBE 4.0」をリリースいたしました!??

プラグインの商品紹介バナー画像

 


新規のお客様に会員になっていただくためのキャンペーンは、検証と改善と繰り返しながらより良い方法を探っていくべきものです。
プレゼントする特典の内容によっても違いが出てきます。
EC-CUBEで新規顧客獲得キャンペーンを開催される場合は是非本プラグインのご利用をご検討ください!


◯本プラグインのご利用対象者様

・EC-CUBEでECサイトを運営しているオーナー様、スタッフ様。
EC-CUBE社提供クーポンプラグイン(Coupon Plugin for EC-CUBE4)を利用中 または 今後ご利用予定のオーナー様、スタッフ様。


◯プラグインが提供する機能

本プラグインでは2つの機能を提供しています。
 (1)新規会員登録時にクーポンを自動で配布する機能
 (2)クーポン配布時に自動でメール送信する機能


◯使い方

(1)新規会員登録時にクーポンを自動で配布する機能
新規会員登録時に配布したいクーポンを予めご用意ください。

説明用バナー画像


ご用意いただいたクーポンを登録するだけで完了です。

説明用バナー画像


(2)クーポン配布時に自動でメール送信する機能
 (1)が完了したら、自動メールの内容を編集しましょう。配布したことを消費者に通知します。

説明用メールテンプレート画像

 

○注意事項

※本プラグインはEC-CUBE社提供クーポンプラグイン(Coupon Plugin for EC-CUBE4)がインストールされている必要があります。
予めインストールしてからご利用ください。

 

◯集客施策シリーズプラグインご案内

プラグインの商品紹介バナー画像  

 

EC-CUBEでお友達紹介キャンペーンをはじめよう! -信頼度の高い新規顧客獲得編-

説明用バナー画像
※バナー画像はお友達紹介キャンペーンの一例です。

関連記事 EC-CUBEでお友達紹介キャンペーンをはじめよう!の続きです。


今回からは具体的なキャンペーン事例と使い方についてお話ししていきたいと思います。
※以下記載の文章は弊社が独自にリサーチした「お友達紹介キャンペーン30社調査結果」から考察した個人的見解を含んだ内容です。


お友達紹介キャンペーンで用いられる条件(=ゴール)設定には、どのようなものがあるでしょうか。

紹介者が紹介をした時、お友達が会員になった時、お友達がお店に来店した時、お友達がお買い物をした時、、、
などいくつか挙げられますが、お友達の行動に対して条件を設定するケースがほとんどです。
(集客施策なので当たり前とも言えます)

またオンラインショップに限った場合、「お友達が会員になった時」「お友達がお買い物をした時」のいずれかに特典を配布するのがセオリーです。
この記事では「お友達がお買い物をした時」に特典を配布するケースについてお話しします。



説明用バナー画像
※バナー画像はお友達紹介キャンペーンの一例です。

 

◇「お友達がお買い物をした時」に特典を配布するケース

○施策の目的は?

このケースで行う施策の目的は、信頼度の高い新規顧客獲得をしたい場合です。

購買行為自体を達成条件とすることもありますが、施策の目的を達成する上では購入金額の制限を達成条件に含めることが大切です。
購入金額の制限は、設定する特典額の幅を広げるのに役に立ちますし、数値目標を設定する時や成果計測時に重要となってくるでしょう。

具体的には「3,000円(税込)以上のお買い物をした時」などの達成条件を設けることになりますが、前段で紹介した条件(=ゴール)の中でもハードルが高いと言えます。
達成してもらう前提として、紹介者のショップに対する信頼度が高くなくてはいけません。
また、お友達に実際にお金を払ってもらうことになるため、紹介者の信頼にも関わります。
ですが一番重要な既存顧客であるヘビーユーザ層 または その付近に所属する層の紹介が比較的多いことから、今後も継続的にお付き合いの出来る顧客を獲得できる可能性が高いでしょう。

逆に認知や会員数増加が目的の場合は、上記よりはハードルが低い「紹介者が紹介をした時点」で特典を配布するのが良いでしょう。
このケースについては次回の記事でご紹介予定です。


○購入金額の制限はどれくらい?

最小2,000円〜最大10,000円の間で設定することが多いようです。
弊社調べでは、3,000円(税抜 or 税込)で設定しているショップオーナー様が多いように見受けられました。

この金額設定は、紹介者とお友達に対する心理的な購入ハードルを高くしすぎないという意図があるように思えます。

制限が高額な場合、紹介者側は気楽に紹介しにくいということがありますし、お友達が購入した商品が気に入らなかった場合など懸念点が少なくありません。
紹介されたお友達にとっても、条件を達成できるお買い物をしなければ、紹介してくれた方に対して影響が出るため少なからずプレッシャーになるでしょう。
そのショップでの初めてのお買い物となることが多いので、高すぎない金額に設定しておくのが良さそうです。
商品の単価にもよりますが、最大でも10,000円程度に設定しておくと紹介しやすいため効果が出やすいのではないでしょうか。

制限が低すぎた場合は、施策の目的である信頼度の高い新規顧客獲得ができない可能性も出てきます。
継続利用するわけではない一時利用目的のお友達を紹介されることが多くなってしまうでしょう。
商品の単価にもよりますが、最小でも2,000円程度に設定しておくのが良さそうです。


○紹介者とお友達の特典の額はどのくらい?

お友達と紹介者の特典は、最小100ポイント〜最大3,000ポイントの間で設定することが多いようです。
大きくわけて下記2つのパターンのいずれかを設定しているショップオーナー様が多いように見受けられました。

・お友達と紹介者へ配布するポイント数は同じ
 例)お友達にも紹介者にも500ポイント

・お友達へ配布するポイント数が、紹介者へのポイント数の2倍
 例)お友達には1,000ポイント、紹介者には500ポイント

紹介者へ配布するポイント数が少なすぎると、紹介自体が割りに合わないと感じることもあるでしょう。
お友達に配布するポイントとの差がありすぎても、モチベーションが上がらないかもしれません。
そのため特典は同じ または 2倍程度に設定するのが良さそうです。


○EC-CUBEでお友達紹介キャンペーンをするには?

実はEC-CUBEではお友達紹介機能は標準で用意されておりません。(2021年4月時点)
また、他のカートシステム(パッケージ および ASPいずれも含む)ではお友達紹介機能を提供しているサービスも存在しますが、細かい調整が可能な購入金額制限機能まで含んだ機能を標準で提供しているサービスはありません。(弊社調べ)
標準で用意されていない理由のうちの一つは、お友達紹介キャンペーンの表現方法は多岐に渡るため共通化が難しいことが原因です。

そのためショップごとの事業に合わせた形で開発会社へカスタマイズを依頼することが多く、実現には最低でも数十万円の費用はかかってしまいます。

弊社ではEC-CUBEでお友達紹介キャンペーンを実施したいという要望をいただいていたことから、このプラグインの製作を決めました。
より多くのキャンペーンのケースに対応可能な仕様を実現しつつ、可能な限り安価に提供したいという想いからこのプラグインが生まれました。
製作に向け30社以上にも及ぶ調査が、必要とされている機能の共通化に成功しています。

EC-CUBEでお友達紹介施策を実施される場合には是非一度ご検討ください!

 

○お友達紹介プラグイン(購入金額制限機能およびポイント特典機能) for EC-CUBE 4.0 設定方法

ここまでの内容を踏まえてキャンペーン内容は下記の通りにまとめたとします。

<お友達紹介キャンペーン内容>
・購入金額の制限を3,000円
 - ここでは税込とします。
・お友達が条件達成した時の配布ポイント
 - 紹介者:500ポイント
 - お友達:1,000ポイント

以下の通り入力すると、まとめた内容の通りのキャンペーンの機能を提供できます。

管理画面画像
※設定>店舗設定>基本設定 の ポイント機能を有効にする必要があります。

各項目説明画像


是非この機会にEC-CUBEでお友達紹介キャンペーンを初めてみませんか?

 

EC-CUBEでお友達紹介キャンペーンをはじめよう!

説明用バナー画像
※バナー画像はお友達紹介キャンペーンの一例です。

次回記事はこちら(EC-CUBEでお友達紹介キャンペーンをはじめよう! -信頼度の高い新規顧客獲得編-)


「お友達紹介」は今、非常に注目を集めている集客施策です。

その背景にはこのような理由が存在します。
 ・今後も継続的に広告費が高騰し続けることが予想される
 ・より費用対効果が高い集客施策が求められている


国内の人口が減少し続けている中で、ここ近年インターネット広告費は増加しています。
特定サービス産業動態統計調査の調査結果のページ

今後は多額の広告費を投入できる企業を除き、継続的な広告投資が難しい事業者が増えるのではないでしょうか。

またここ数年、Apple社を皮切りにGoogle社などの巨大IT企業が軒並みプライバシー保護のための取り組みに本腰を入れてきています。

特にGoogleでは2020年1月に「サードパーティークッキーの廃止」を発表しました。

今後、ターゲット層への広告配信や、自社サイトに訪問した人へのリターゲティング広告を打つことも難しくなるのではないかと考えられます。



説明用バナー画像
※バナー画像はお友達紹介キャンペーンの一例です。


「お友達紹介」は広告と比較して多額の投資を必要とせず、また消費者から見て情報の信頼性が高いため成立に結びつきやすい施策です。

お友達紹介プログラムで消費者に与える特典は、成果報酬のため無駄な出費がありません。
(成果報酬は「お友達の会員登録」「お友達の商品購入」をいずれか、または両方を設定することが多いです。)

紹介を受けた側は、実際にお付き合いのあるご家族やご友人からの紹介のため、最初からそのサイトに対しての印象が良く、紹介者を信頼して「会員登録」や「商品購入」といった行動に繋がりやすい傾向にあります。



ここ最近では、個人事業主だけでなく、大手企業も積極的に「お友達紹介」を取り入れて新規ユーザ数を増やしています。

例えばAirbnb(エアビーアンドビー)は短期間での成長を遂げたにも関わらず、広告と中心とした施策ではなく、会員による「友人紹介」に力を入れて会員数を増やしてきたようです。



是非この機会に「お友達紹介キャンペーン」を検討してみるのはいかがでしょうか?



この度、お友達紹介プラグインをリリースすることになりました!


実はお友達キャンペーンにはたくさんの形が存在しています。

お友達が3,000円(税込)購入したら特典をプレゼントしたい、、

お友達が会員登録した場合も特典をプレゼントしたい、、

3系、4系でもお友達紹介プラグインをリリースしてきた弊社宛には多くのご要望が寄せられました。


このプラグインでは様々なお友達紹介キャンペーンの形に対応すべく、できる限りの機能を盛り込んでおります!


お友達紹介キャンペーンを行う際には是非一度ご検討ください!


このプラグインではお友達紹介キャンペーンでよく利用される機能をまとめて提供しております。

 ・会員登録を達成条件にしたい
 ・お友達を紹介する時の人数制限がしたい
 ・商品購入を達成条件にしたい
 ・購入金額の制限がしたい
 ・購入金額の制限に税込 or 税抜を選択したい
 ・お友達が購入の都度、紹介者にポイントを付与したい
 ・条件を達成した時に通知メールを送信したい


次回以降は具体的なキャンペーン事例と使い方についてご説明していきたいと思います!

次回記事はこちら(EC-CUBEでお友達紹介キャンペーンをはじめよう! -信頼度の高い新規顧客獲得編-)

 

 

ECCUBE3でセッションが切れる?

eccube.CRITICAL: RuntimeException: Failed to start the session (uncaught exception) at /var/www/eccube/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php line 149 {“exception”:”[object] (RuntimeException(code: 0): Failed to start the session at /var/www/eccube/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php:149)”} []

システムエラー画面になってシステムログにはこんなエラーがでていた。

apacheエラーログは以下の通り。

PHP Warning:  session_start(): Failed to decode session object. Session has been destroyed in /var/www/eccube/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php on line 148

セッションオブジェクトをデコードできないってことなので、とりあえずセッションのデータを見てみることに。

結論から言うと、セッションデータがでかすぎて欠落した値がDBに保存されていたことが原因。

eccube3.0.8だったのでセッションはデフォルトでDBに保存される。(3.0.10ではファイルに変更されている模様)

解決策としては

  1. dtb_session.sess_dataの型をblobからmediumblobに変更
  2. 保存先をファイルに変更

が考えられるので今回は1で対応。

因に、my.cnfに「sql_mode=STRICT_TRANS_TABLES」を設定するとblobのままでも欠落した値が挿入されることは無く、

(恐らく値が更新されないので)上記エラーは起きなかった。

そもそも、セッションにCustomerエンティティとそこから紐づくエンティティが保存されるらしく、

それを知らずにリレーションしまくると大変なことになりそう。

(今回はカスタマイズでいろいろリレーションしていた)

紐づくエンティティーでも保存される物とされない物があり良くわからんのですが・・・

引き続き調査は続く。