最近のお仕事

ここ1年ほど、ずっとEC-CUBE4.2のカスタマイズ案件ばかりやっています。
現在も作業中の案件もありますが、その内容としては、

1)送料に[離島]の区分を追加するカスタマイズ
離島扱いにする郵便番号を登録するテーブルを作成し、送料を算出するサービス( DeliveryFeePreprocessor 等 )をカスタマイズ。
2)受注時に商品のメーカーに注文書pdfをメールするカスタマイズ
メーカーを登録するテーブルを作成し、商品に紐付け。受注時に、商品に紐付くメーカー情報に基づき注文書pdfを生成しメーカーに送付するカスタマイズ。
3)商品購入時、顧客に付与するポイントをパーセンテージではなく、商品毎に固定の数値にするカスタマイズ
商品規格テーブルに、商品毎のポイントを入力する項目を追加。ポイントを算出するサービス( PointRateProcessor 等 )をカスタマイズ。
4)業務用の商品について、通常の購入とは別にサンプルを依頼(購入)できるようにするカスタマイズ
カートまわりのサービス( CartService、PriceChangeValidator、OrderValidator 等 )をカスタマイズ。

カテゴリー: Webコンテンツ, 仕事 | 最近のお仕事 はコメントを受け付けていません

macos Ventura に mpd をインストールする

LinuxからmacOSへの移行の一環です。
https://mpcbridge.fourthgate.jp/other/macosventura
に投稿しています。

カテゴリー: PCオーディオ, 未分類 | macos Ventura に mpd をインストールする はコメントを受け付けていません

macOS Venturaにredmineをインストール

色々と考えるところあって、Linuxで運用していた諸々のサービスをmacOSに移行中です。
apacheやphpなどはhomebrewを使うことで、かなりすんなり移行できました。
いろいろ面倒そうだと予想していたのは、redmine、gitbucket、mpdなどです。

ということで、以下、僕の場合のredmineのインストールの流れ。
多分もっとスマートな方法があると思うのですが。

まずは、ruby のインストール。

brew install ruby@3.1

ruby のバージョンは、使用する redmine に合わせます。
もちろん、apache と mysql も brew でインストールします。

次は、シェルの環境変数を .zshrc に記述。

export PATH="/opt/homebrew/opt/ruby@3.1/bin:$PATH"i
export LDFLAGS="-L/opt/homebrew/opt/ruby@3.1/lib"
export CPPFLAGS="-I/opt/homebrew/opt/ruby@3.1/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/ruby@3.1/lib/pkgconfig"

これで、シェルから ruby と打つと、/opt/homebrew/opt/ruby が参照されます。

次は、データベースの作成。
mysqlでデータベースと接続ユーザーも作成し、config/database.ymlも設定

次は、bundler のインストール。

gem install bundler
bundle install --without development test
rake generate_secret_token

最後は、apache 用の mod_passenger の作成。
ruby は詳しくないのですが、Ruby on Rails をapache動かすためのものらしいです。

ruby /usr/local/bin/passenger-install-apache2-module

を実行し、mod_passenger.so を作成します。
mod_passenger.so 生成の過程で、apache 用の設定内容が表示されますので、それを apache の設定ファイルに追加します。
なお、

passenger-install-apache2-module

とだけ実行すると、macOS にプリインストールされている ruby が動いてしまいうまくありません。

上記の内容で、Linux( Ubuntu22.04 )にインストールしていた redmine 5.0.3 を macOS に移行することができました。

カテゴリー: サーバーまわり | macOS Venturaにredmineをインストール はコメントを受け付けていません

CakePHP4でHasManyされたレコードのカウント

僕は「博多弁でいこう!」というサイトを運用しています。
このサイトは、もう25年くらい前にPerlのcgiで作ったのが最初で、その後、PHPへ移植。
さらに、CakePHP3化し、現在はCakePHP4で運用しています。CakePHP化したのは、勉強のためという意味合いが強いのですが。

このサイトには、掲載している言葉(博多弁)を使っていたかどうかのアンケートがあります。アンケートの内容は、使っていたかどうかの選択と、回答者の生年と性別、それとフリーのコメントからなります。
各言葉はテーブル(words)に、アンケート結果はテーブル(votes)に保存しています。
テーブル(words)は、テーブル(votes)をHasManyしています。

投票結果のページでは、使っていたかどうかの回答について、回答者の生年から算出した年代と性別でグループ分けして、それぞれの人数を表示するようにしています。
https://sunnyday-aki.ssl-lolipop.jp/hakataben/votes/result

それぞれの言葉の投票結果を一気に取得するために、caseステートメントを使用しました。
世代絞り込みのcaseは以下のような感じです。
カラムyesnoは、1で使っていた。0は使っていなかった。
birthyearは生年。西暦の数値です。sexは性別。

$q1 = $query->newExpr()->case()
    ->when( $query->newExpr()->add( [
        'yesno' => 1,
        $query->newExpr()->between('birthyear', '40才の生年', '21才の生年' ),
    ] ) )
    ->then( 1 )->else(0);

上記は、21〜40才で使っていた人を絞り込むcase。

$q2 = $query->newExpr()->case()
    ->when( $query->newExpr()->add( [
        'yesno' => 0,
        'sex' => 1,
        $query->newExpr()->between('birthyear', '60才の生年', '41才の生年' ),
    ] ) )
    ->then( 1 )->else(0);

上記は、41〜60才の男性で使っていなかった人を絞り込むcase。
whenの条件にマッチすると1が、マッチしなければ0が返ってきます。
これらを以下のようにsumで集計すれば、それぞれの言葉の世代別、回答別の人数を算出できます。

$query->select([
     'age20_yes' => $query->func()->sum($q1),
     'age60_m_no' => $query->func()->sum($q2),
 ]);

実際に生成されたSQL文をdebug.kitで確認すると、以下のようになっています。

SUM(
  CASE WHEN (
    yesno = 0 
    AND sex = 1 
    AND birthyear BETWEEN 1983 
    AND 2002
  ) THEN 1 ELSE 0 END
)

※現在、絶賛お仕事募集中です。興味をお持ちのかたは、以下の問い合わせフォームから
https://www.fourthgate.jp/index.php/contact/
から、是非是非ご連絡ください。

カテゴリー: Webコンテンツ | CakePHP4でHasManyされたレコードのカウント はコメントを受け付けていません

macOS の diskarbitrationd の暴走

Intel iMacにmacOS 13.2.1をインストールして使っています。
Time Machine は、USB 接続した HDD と、Raspberry Pi 4 + Raspberry Pi OS + Samba 4.9.5( Time Capsule もどき)の二本立てで運用しています。
samba のほうは、
fruit:time machine = Yes
で Time Machine になります。

と、ここまではいいのですが、ラズパイ Samba のほうへのバックアップ処理が完了した後、おそらくは Time Machine のボリュームをマウント解除しているタイミングだと思うのですが、mac のマウスカーソルがくるくるレインボー、いわゆるレインボーカーソル状態になってしまいます。
この状況は30秒〜2分くらい継続して、その間は何もできません。
(ウインドウの切り替えくらいはできる)
この状況は、体感では、毎回ではないのですが5割以上はあるという感じです。
なので、一日あたり3〜4回は遭遇します。

セキュリティソフトのせいかとも思ったのですが、オンオフを切り替えたりアンインストールしても状況は変わりませんので、関係はなさそうです。

アクティビティモニタを見ていると、レインボーカーソル状態の時は、diskarbitrationd のCPU 負荷がとても高くなっています。

ぐぐってみると、diskarbitrationd はボリュームのマウント・アンマウントの処理に関係しているようです。
そして、ずっと以前からボリュームをアンマウントするときに、僕と同じ現象に遭遇している人達が一定数いるようです。
ちなみに、macOS 12 のころは、diskarbitrationd ではなく umount でした。

ずっと以前から同じような現象が起きているにもかかわらず、今も治っていないということは、今後も治ることは期待薄なんでしょうね。

市販のNASを Time Machine を使っている場合にも同じ現象が起きているんだろうか??

という愚痴でした。

カテゴリー: 未分類 | macOS の diskarbitrationd の暴走 はコメントを受け付けていません

EC-CUBE4.2 同一商品の複数の規格をカートに一括投入するカスタマイズ

EC-CUBE4のお話。
タイトルだけではわからないかもしれないですが、例えば衣料品の同一商品について、サイズ違い・色違いをまとめてカートに投入するといったカスタマイズです。
EC-CUBE2では無料のプラグインがありますが、EC-CUBE4には見当たらなかったのでカスタマイズしてくれと言うご要望でした。

僕自身、EC-CUBE4というかsymfonyは殆ど触ったことがなかったので、そのへんの調査からになりました。
一番参考になったのは、以下のサイトです。
1)
https://symfonycasts.com/screencast/collections/add-new-collection-prototype

2) https://symfony.com/doc/current/reference/forms/types/collection.html

同時に複数の商品をカートに入れるためには、AddCartTypeを複数配置することになります。
symfonyのドキュメントによると、ひとつのフォームで複数のentityを扱えるようにするには、CollectionTypeを使えということでした。
EC-CUBE4でカートに商品を投入するフォームタイプは、
src/Eccube/Form/Type/AddCartType.php
です。
これをCollectionTypeを使って、複数扱えるようにします。

src/Eccube/Controller/ProductController.php
をカスタマイズする必要があるので
app/Customize/Controller/
下にコントローラーファイルを作成します。
function detail()をオリジナルからコピーして、フォームビルダー部分を

$builder = $this->formFactory->createBuilder( );
$builder
    ->add(
        'data',
        CollectionType::class,
        [
            'entry_type' => AddCartType::class,
            'entry_options' => [
                'product' => $Product,
                'id_add_product_id' => false,
                'attr' => ['class' => 'oneclass'],
            ],
            'allow_add' => true,
            'allow_delete' => true,
            'label' => '',
        ]
    );

のようにします。
また、twigテンプレート
src/Eccube/Resource/template/default/Product/detail.twig
を、
app/template/default/Product
にコピーしておきます。

この状態で、
/products/detail/xxxx
にアクセスして、変数formをダンプすると、

children->data->vars->prototype

の中に、AddCartTypeの要素がずらずら〜と入っているはずです。

detail.twigのadd_cartのフォームの中に、上記1)のURLにあるように、

<div class="product-class-item" data-prototype="{{ form_widget(form.data.vars.prototype)|e('html_attr') }}"></div->

を追加すると、data-prototypeの部分に、数量と規格の選択部分のhtmlが吐き出されています。
この部分には、

これまた1)を参考に、追加削除ボタンを処理するJavaScriptを作成します。
(僕の書いたコード、相当カッコ悪いと感じているのでここには載せません)
そうすると、

<div id="form_data_X" class="oneclass">〜</div>

で囲われた、一つの商品規格選択フォーム要素が追加されます。
フォームの要素のnameは、form[data][0][quantity]のようになっていると思います。
これで、複数の規格をカートに投入すると、配列として送信されます。
なお、カート追加のactionはproducts/addmulti_cartにしました。
商品一覧(/products/list)のほうで/products/add_cartは使うかもしれないので、アクションを分けておいたほうが楽かなと思いましたので。

ProductController.phpのfunction addCartもコピーして、function addmultiCart()としてカートへ追加する処理を記述します。
フォームビルダーのところはfunction detailと同じです。

エラーがなければ、$form->getData() にはカートに入れる商品毎の配列が入っています。
ここは、

foreach ( $addCartData['data'] as $oneItem ) {
    $this->cartService->addProduct($oneItem['product_class_id'], $oneItem['quantity']);
}

とループを回して、ひとつずつカートに追加するようにしました。

もうちょっと、シュッとしたやりかたがあるようがあると思いますが、とりあえず動いたのでOKとしました。

なお、symfonyがなのか、CollectionTypeがなのかわかりませんが、メモリーをかなり使うようです。
僕が試したubuntu22.04(PHP8.1)のデフォルト値のmemory_limitではメモリー不足になってしまいました。
memory_limitを512Mにしたらエラーは起きなくなりました。

※現在、絶賛お仕事募集中です。興味をお持ちのかたは、以下の問い合わせフォームから
https://www.fourthgate.jp/index.php/contact/
から、是非是非ご連絡ください。

カテゴリー: Webコンテンツ | EC-CUBE4.2 同一商品の複数の規格をカートに一括投入するカスタマイズ はコメントを受け付けていません

mpcbridge ver 6.2

mpd(Music Player Daemon)のリモコンとして動作するWebアプリ、mpcbridge ver 6.2をリリースしました。

mpcbridgeの詳細は、こちらをご覧ください。

↓↓ダウンロードはこちら
https://mpcbridge.fourthgate.jp/files/download/mpcbridge.tar.gz

以下の修正、変更を行っています。
1) 楽曲ファイル情報に音声フォーマットを追加
2) 検索にまつわるいくつかのバグを修正

一つ目の音声フォーマットの情報はわりと便利だと感じています。
楽曲の一覧を表示したときに、標本化周波数、量子化ビット数を表示します。また、ステレオ(2ch)は「S」の絵文字が、サラウンド音声は「SS」の絵文字が表示されます。

カテゴリー: 未分類 | mpcbridge ver 6.2 はコメントを受け付けていません

mpcbridge ver 6.1

mpd(Music Player Daemon)のリモコンとして動作するWebアプリ、mpcbridge ver 6.1をリリースしました。

mpcbridgeの詳細は、こちらをご覧ください。

↓↓ダウンロードはこちら
https://mpcbridge.fourthgate.jp/files/download/mpcbridge.tar.gz

以下の修正、変更を行っています。
1) 検索の条件にジャンルを追加
2) 検索にまつわるいくつかのバグを修正

検索の時に、ジャンル指定できるようにしました。同名の曲がある場合にジャンル指定することで、多少検索しやすくなるかなと思います。

カテゴリー: PCオーディオ, Webコンテンツ | mpcbridge ver 6.1 はコメントを受け付けていません

CakePHP4のAuthenticationで複数の認証

CakePHP4で、管理者向けの認証と一般ユーザー向けの認証を設置したい場合について・・・

管理画面は /admin 以下にあるとします(route.phpでprefixを設定しているとして)。

Application.php の getAuthenticationService で、urlが/adminで始まっているかどうかで処理を切り分けます。


if ( preg_match( '/^\/admin\/?/', $path ) ) {
〜〜〜
$service->loadAuthenticator('Authentication.Session', [
'sessionKey' => 'ManagementAuth', // 管理者認証に使用するセッションキー
] );
$service->loadIdentifier('Authentication.Password',
[
'fields' => $fields,
'resolver' => [
'className' => 'Authentication.Orm',
'userModel' => 'Adminusers',
],
]
);
〜〜〜
} else {
〜〜〜
$service->loadAuthenticator('Authentication.Session', [
'sessionKey' => 'MemberAuth', // 管理者認証とは別のセッションキーを設定
] );
$service->loadIdentifier('Authentication.Password',
[
'fields' => $fields,
'resolver' => [
'className' => 'Authentication.Orm',
'userModel' => 'Users',
],
]
);
〜〜〜
}

のようにすると、/admin 以下で動くコントローラーでは、Adminusers モデルを使用します。
それ以外のコントローラーでは、Users モデルを使って認証します。

もっとスマートな方法があるんだろうと思いますが、とりあえず、これでうまくいっています。

カテゴリー: Webコンテンツ | CakePHP4のAuthenticationで複数の認証 はコメントを受け付けていません

CakePHP4.2のDebug Kitでmissing routeが起きた場合の対処

以下、なんとなく…のお話です。

CakePHP4.2.xで

を使用している場合に、Debug Kitがmissing routeになって動かなくなりました。
で、たどり着いたのが、unauthenticatedRedirectやloginUrlの指定方法。
cookbookでは、

$service->setConfig(['unauthenticatedRedirect' => Router::url(['prefix' => false,'plugin' => null,'controller' => 'Users','action' => 'login',]),'queryParam' => 'redirect',]);

のように指定しています。
これを

$service->setConfig(['unauthenticatedRedirect' => '/users/login']),'queryParam' => 'redirect',]);

のように指定すると、Debug Kitのmissing routeが解消されました。

なんとなく…です。

カテゴリー: Webコンテンツ | CakePHP4.2のDebug Kitでmissing routeが起きた場合の対処 はコメントを受け付けていません