Yii Framework 最新ニュース Yiiフレームワークに関するニュース、最新の拡張機能、Wiki記事。 2024年9月19日(木) 12:05:58 +0000 Zend_Feed_Writer 2 (http://framework.zend.com) https://yii.dokyumento.jp/ [拡張機能] duna/qrcode 2024年9月19日(木) 12:05:57 +0000 https://yii.dokyumento.jp/extension/duna/qrcodehttps://yii.dokyumento.jp/extension/duna/qrcode davidsgallan davidsgallan

Duna QRコードライブラリ

  1. 概要
  2. インストール
  3. 使用方法
  4. ライセンス
  5. コントリビューション
  6. 問題とサポート

HTML、PNG、SVG出力形式をサポートする汎用性の高いQRコード生成ライブラリです。

GitHub repo stars

概要

Duna QRコードライブラリは、元々はv8.0までDunaにバンドルされていたQrCodeライブラリ(Laurent Minguet氏開発)をベースとしたQRコード生成ツールです。LGPLライセンスで配布されており、QRコード生成のための柔軟でオープンソースのソリューションを提供します。

インストール

ライブラリのインストールには、Composerを使用します。

$ composer require duna/qrcode

使用方法

Duna QRコードライブラリの使用方法に関する簡単なガイドです。

QRコードの生成

まず、必要なクラスを含めて、QRコードのインスタンスを作成します。

<?php

use Duna\Helpers\QrCode\QrCode;
use Duna\Helpers\QrCode\Output;

$qrCode = new QrCode('Lorem ipsum dolor sit amet');
出力形式
PNG出力

寸法と色を指定してQRコードのPNG画像を生成するには、以下を使用します。

// Create PNG output
$output = new Output\Png();

// Generate PNG data with a specified width, background color (white), and foreground color (black)
$data = $output->output($qrCode, 100, [255, 255, 255], [0, 0, 0]);

// Save the PNG data to a file
file_put_contents('file.png', $data);
SVG出力

スケーラブルベクターグラフィックスに便利なSVG出力の場合。

// Create SVG output
$output = new Output\Svg();

// Generate SVG data with a specified width, background color (white), and foreground color (black)
echo $output->output($qrCode, 100, 'white', 'black');
HTML出力

QRコードをHTMLテーブルとして表示するには。

// Create HTML output
$output = new Output\Html();

// Generate HTML table representation of the QR code
echo $output->output($qrCode);

ライセンス

このライブラリはGNU Lesser General Public License (LGPL) v3.0に基づいて提供されています。詳細はLICENSEファイルを参照してください。

コントリビューション

コントリビューションは大歓迎です!詳細は、CONTRIBUTINGガイドラインを参照してください。

問題とサポート

問題やサポートについては、イシュートラッカーを参照するか、コミュニティにご連絡ください。

]]>
0
[ニュース] Yii HTML 3.7 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/663/yii-html-3-7https://yii.dokyumento.jp/news/663/yii-html-3-7 vjik vjik

Yii HTMLパッケージのバージョン3.7がリリースされました。いくつかの改善が含まれています。

  • CSP用のメソッドScript::nonce()Script::getNonce()を追加しました。
  • Selectタグにバックエンド列挙値のサポートを追加しました。
]]>
0
[ニュース] Yii Hydrator 1.5 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/662/yii-hydrator-1-5https://yii.dokyumento.jp/news/662/yii-hydrator-1-5 vjik vjik

Yii Hydratorパッケージのバージョン1.5がリリースされました。新バージョンに含まれる改善点のリストを以下に示します。

  • 列挙型に値を変換するEnumTypeCasterを追加しました。
  • 親クラスから読み取り専用のプロパティを設定する問題を修正しました。
]]>
0
[ニュース] Yii Validator 2.1 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/661/yii-validator-2-1https://yii.dokyumento.jp/news/661/yii-validator-2-1 vjik vjik

Yii Validatorパッケージのバージョン2.1がリリースされました。新バージョンに含まれる変更点のリストを以下に示します。

  • PHP属性からのルールをgetRules()メソッドで提供されるルールとマージします。
  • IpルールでYiisoft\NetworkUtilities\IpRangesを使用:getIpRanges()メソッドを追加し、getRanges()getNetworks()isAllowed()メソッドを非推奨とします。
  • 独自の定数を宣言する代わりに、network-utilitiesパッケージのNEGATION_CHARACTER定数をIpHandlerで使用します。
]]>
0
[Wiki] 同じドメイン/サブドメイン下のすべてのYii2アプリケーション/リポジトリで単一のログインセッションを使用する 2024年9月10日(火) 12:26:07 +0000 https://yii.dokyumento.jp/wiki/2580/use-single-login-session-on-all-your-yii2-applicationrepository-under-same-domainsub-domainhttps://yii.dokyumento.jp/wiki/2580/use-single-login-session-on-all-your-yii2-applicationrepository-under-same-domainsub-domain aayushmhu aayushmhu

Yii2アプリケーションに個別のログインを使用する方法を示す複数のブログがありますが、この記事では、すべてのYii2 Advanced、Yii2 Basic、アプリケーションに対して単一のログイン画面を使用する方法を示します。これは、異なるサーバーまたは同じサーバー上のドメインでも機能します。

これを達成するために従う必要がある手順をいくつか示します。

1. Advancedテンプレートの場合

ステップ1:コンポーネント内に追加します

/path/common/config/main.php

  'components' => [
        'user' => [
            'identityClass' => 'common\models\User',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity', 'httpOnly' => true],
        ],
        'request' => [
            'csrfParam' => '_csrf',
        ],
    ],

ステップ2:main-local.phpにSessionとRequestを追加します

/path/common/config/main-local.php

   'components' => [
        'session' => [
            'cookieParams' => [
                'path' => '/',
                'domain' => ".example.com",
            ],
        ],
        'user' => [
            'identityCookie' => [
                'name' => '_identity',
                'path' => '/',
                'domain' => ".example.com",
            ],
        ],
        'request' => [
            'csrfCookie' => [
                'name' => '_csrf',
                'path' => '/',
                'domain' => ".example.com",
            ],
        ],
    ],

注:**example.com**はメインドメインです。他のすべてのドメインは、このサブドメインである必要があります。

ステップ3:すべてのアプリケーションで同じ検証キーを更新します

/path/frontend/config/main-local.php

/path/backend/config/main-local.php

 'components' => [
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'fFUeb5HDj2P-1a1FTIqya8qOE',
        ],
    ],

**注:**フロントエンドとバックエンドアプリケーションのmain.phpからSessionとRequestキーを削除します。

ステップ4:コンソールアプリケーションも持っていることに注意してください。そのため、コンソールアプリケーションのmain-local.phpにsession、user、requestを更新します。

/path/console/config/main-local.php

 'components' => [
        'session' => null,
        'user' => null,
        'request' => null,
    ]

2. Basicテンプレートの場合

さらに、別のプロジェクトにBasicテンプレートがインストールされていて、そのテンプレートにも同じログインを使用したい場合。これを達成するには、次の手順に従います。

ステップ1:Basicテンプレートのmain-local.phpを更新します

/path/basic-app/config/main-local.php


 'components' => [
        'session' => [
            'cookieParams' => [
                'path' => '/',
                'domain' => ".example.com",
            ],
        ],
        'user' => [
            'identityCookie' => [
                'name' => '_identity',
                'path' => '/',
                'domain' => ".example.com",
            ],
        ],
        'request' => [
            'csrfCookie' => [
                'name' => '_csrf',
                'path' => '/',
                'domain' => ".example.com",
            ],
        ],

    ],

すべてのドメインとサブドメイン、またはリポジトリで単一のログインを使用する方法を理解していただければ幸いです。

:) ご覧いただきありがとうございます。

]]>
0
[ニュース] Yii Swagger 2.1 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/660/yii-swagger-2-1https://yii.dokyumento.jp/news/660/yii-swagger-2-1 arogachev arogachev

Yii Swaggerパッケージのバージョン2.1がリリースされました。新バージョンに含まれる変更点のリストを以下に示します。

  • バージョン^2.0psr/http-messageのサポートを追加しました。
  • 必須のyiisoft/yii-viewのバージョンを^7.1に上げました。
  • \Yiisoft\Swagger\Action\SwaggerJson\Yiisoft\Swagger\Action\SwaggerUiアクションを追加し、\Yiisoft\Swagger\Middleware\SwaggerJson\Yiisoft\Swagger\Middleware\SwaggerUiクラスを非推奨としました(次のメジャーバージョンで削除されます)。
  • バージョン5のswagger-api/swagger-uiのサポートを追加しました。
]]>
0
[ニュース] Yii Network Utilities 1.2 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/659/yii-network-utilities-1-2https://yii.dokyumento.jp/news/659/yii-network-utilities-1-2 arogachev arogachev

Yii Network Utilitiesパッケージのバージョン1.2がリリースされました。新バージョンに含まれる変更点のリストを以下に示します。

  • IPv4とIPv6の両方のバージョンのIPを確認するためのIP_PATTERNIP_REGEXP定数をIpHelperに追加しました。
  • 範囲を否定するために使用されるNEGATION_CHARACTER定数をIpRangesに追加しました。
  • isIpv4()isIpv6()isIp()メソッドをIpHelperに追加しました。
]]>
0
[ニュース] Yii Form Model 1.0 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/658/yii-form-model-1-0https://yii.dokyumento.jp/news/658/yii-form-model-1-0 vjik vjik

Yii Form Modelパッケージの最初のリリースが行われました。フォームモデルの基盤を提供し、それらの入力、検証、表示を支援します。

使用方法については、フォームモデルを定義します。

use Yiisoft\FormModel\Attribute\Safe;
use Yiisoft\FormModel\FormModel;
use Yiisoft\Validator\Rule\Email;
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Required;

final class LoginForm extends FormModel
{
    #[Label('Your login')]
    #[Required]
    #[Length(min: 4, max: 40, skipOnEmpty: true)]
    #[Email(skipOnEmpty: true)]
    private ?string $login = null;

    #[Label('Your password')]
    #[Required]
    #[Length(min: 8, skipOnEmpty: true)]
    private ?string $password = null;

    #[Label('Remember me for 1 week')]
    #[Safe]
    private bool $rememberMe = false;
}

データを入力し、フォームハイドレーターを使用して検証します。

use Psr\Http\Message\RequestInterface;
use Yiisoft\FormModel\FormHydrator;
use Yiisoft\FormModel\FormModel;

final class AuthController 
{
    public function login(RequestInterface $request, FormHydrator $formHydrator): ResponseInterface
    {
        $formModel = new LoginForm();
        $errors = [];
        if ($formHydrator->populateFromPostAndValidate($formModel, $request)) {
            $errors = $formModel->getValidationResult()->getErrorMessagesIndexedByProperty();
        }
        
        // You can pass $formModel and $errors to the view now.
    }
}

ビューのフィールドを使用して表示します。

use Yiisoft\FormModel\Field;
use Yiisoft\FormModel\FormModel;

echo Field::text($formModel, 'login');
echo Field::password($formModel, 'password');
echo Field::checkbox($formModel, 'rememberMe');

// ...
]]>
0
[ニュース] Yii Form 1.0 2024年8月26日(月) 19:05:36 +0000 https://yii.dokyumento.jp/news/657/yii-form-1-0https://yii.dokyumento.jp/news/657/yii-form-1-0 vjik vjik

Yii Formパッケージの最初のリリースが行われました。これは、HTMLフォームの動的なサーバー側生成を支援するためのウィジェットのセットを提供します。次のウィジェットがすぐに利用できます。

  • 入力フィールド:CheckboxCheckboxListDateDateTimeLocalEmailFileHiddenImageNumberPasswordRadioListRangeSelectTelephoneTextTextareaTimeUrl;
  • ボタン:ButtonResetButtonSubmitButton;
  • グループウィジェット:ButtonGroupFieldset
  • その他:ErrorSummary

一般的な使用方法

use Yiisoft\Form\PureField\Field;

echo Field::text('firstName', theme: 'horizontal')
  ->label('First Name')
  ->autofocus();
echo Field::text('lastName', theme: 'horizontal')
  ->label('Last Name');
echo Field::select('sex')
  ->label('Sex')
  ->optionsData(['m' => 'Male', 'f' => 'Female'])
  ->prompt('—');
echo Field::number('age')
  ->label('Age')
  ->hint('Please enter your age.');
echo Field::submitButton('Submit')
  ->buttonClass('primary');
]]>
0
[ニュース] Yii Hydrator 1.4 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/656/yii-hydrator-1-4https://yii.dokyumento.jp/news/656/yii-hydrator-1-4 vjik vjik

Yii Hydratorパッケージのバージョン1.4がリリースされました。新バージョンに含まれる改善点のリストを以下に示します。

  • ToArrayOfStringsパラメーター属性を追加しました。
  • Collectionにバックエンド列挙値のサポートを追加しました。
]]>
0
[ニュース] Yii HTML 3.6 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/655/yii-html-3-6https://yii.dokyumento.jp/news/655/yii-html-3-6 vjik vjik

Yii HTMLパッケージのバージョン3.6がリリースされました。いくつかの改善と修正が含まれています。

  • 属性名が空であるか、禁止されている記号が含まれている場合、Html::renderAttribute()InvalidArgumentExceptionをスローします。
  • テキストエリアタグにStringableと配列値のサポートを追加しました。
  • CheckboxListRadioListウィジェットにバックエンド列挙値のサポートを追加しました。
  • Html::renderTagAttributes()でのnull値属性の出力を修正しました。
]]>
0
[ニュース] Yii Auth JWT 2.1 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/654/yii-auth-jwt-2-1https://yii.dokyumento.jp/news/654/yii-auth-jwt-2-1 arogachev arogachev

Yii Auth JWTパッケージのバージョン2.1がリリースされました。新バージョンに含まれる変更点のリストを以下に示します。

  • 依存関係にある複数のweb-token/*パッケージを1つのweb-token/jwt-libraryに置き換え、PHPの最小バージョンを8.1に更新しました。
  • バージョン^2.0psr/http-messageのサポートを追加しました。
]]>
0
[ニュース] Yii Hydrator 1.3 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/653/yii-hydrator-1-3https://yii.dokyumento.jp/news/653/yii-hydrator-1-3 arogachev arogachev

Yii Hydratorパッケージのバージョン1.3がリリースされました。新バージョンに含まれる改善点のリストを以下に示します。

  • Collection PHP属性を介したコレクションのサポートを追加しました。
  • ParameterAttributesHandlerにハイドレーターの依存関係とwithHydrator()メソッドを追加しました。
  • ParameterAttributeResolveContextにハイドレーターの依存関係とgetHydrator()メソッドを追加しました。
  • 初期化されていないreadonlyプロパティのハイドレーションを許可しました。
]]>
0
[ニュース] Yii Network Utilities 1.1 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/652/yii-network-utilities-1-1https://yii.dokyumento.jp/news/652/yii-network-utilities-1-1 vjik vjik

Yii Network Utilitiesパッケージのバージョン1.1がリリースされました。いくつかの改善が含まれています。

  • 許可または禁止されているIP範囲のセットを表すIpRangesを追加しました。
  • PHP 8.0以降でIPアドレスをビット表現に変換する際のエラーを修正しました。
]]>
0
[ニュース] Yii Validator 2.0 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/651/yii-validator-2-0https://yii.dokyumento.jp/news/651/yii-validator-2-0 vjik vjik

Yii Validator のメジャーバージョンがタグ付けされました。

  • Each ルールの処理中に利用可能な検証コンテキストパラメータ Each::PARAMETER_EACH_KEY を追加しました。現在のキーが含まれています。
  • 属性名が存在する場合、エラーメッセージに属性名を含めます。
  • エラーメッセージで使用するためのプロパティラベルを設定するPHP属性を追加しました。
  • InEnum ルールを追加しました。
  • クラス/トレイト/メソッド/変数/プレースホルダーの名前で「attribute」を「property」に変更しました。
  • Error::getValuePath()$escape 引数の型を bool|string|null から string|null に変更しました。
  • OneOfAtLeast ルールのエラーメッセージに翻訳された属性をリストアップしました。
  • OneOf ルールのエラーメッセージの意味を修正しました。
  • OneOfAtLeast ルールのエラーメッセージの意味を改善し、複数形を使用しました。
  • AtLeast の設定で、$min$attributes の数より大きくなることを許可しなくなりました。
  • getName() メソッドを RuleInterface から RuleWithOptionsInterface に移動しました。
  • RuleWithOptionsInterface の名前を DumpedRuleInterface に変更しました。
  • RulesDumper でのエクスポート時に、組み込みルールの名前としてFQCNを使用します。
  • RulesDumper でのエクスポート時に、DumpedRuleInterface を実装していないルールの名前としてFQCNを使用します。
  • ルールのコンストラクタの $skipOnEmpty 引数の型を mixed から bool|callable|null に変更しました。
  • RuleHandlerInterface::validate()$rule 引数の型を object から RuleInterface に変更しました。
  • AtLeast ルール名を FilledAtLeast に、OneOf ルール名を FilledOnlyOneOf に変更しました。
  • 不正な入力に関連するエラーメッセージに型を追加しました。
  • PHP 8.3でコードを実行する場合、JsonHandlerでPHP組み込み関数json_validate()を使用します。
  • Result クラスのPsalmアノテーションを改善しました。
  • ドイツ語翻訳を追加しました。
  • PHP 8.3より前のバージョンでは、PHP組み込み関数を使用してJsonHandlerでのJSONの検証を簡素化しました。
  • PHPの最小バージョンを8.1に上げました。
  • Result::add() をリファクタリングしました: foreach から array_merge() を削除しました。
  • RulesNormalizer::normalize() のパラメータ $rules をオプションにしました。
  • Json::$message をより明確にしました。
  • Nested ルールのルールのエラーメッセージでのプロパティ名の使用を修正しました。
  • データオブジェクトのPHP属性によって提供されるルールは、RulesNormalizer::normalize() では使用されていませんでした。
  • Each::$incorrectInputKeyMessagetype パラメータの値が間違っていました。

アプリケーションでこのメジャーバージョンにパッケージをアップグレードする方法については、アップグレード手順を参照してください。

]]>
0
[ニュース] Yii 2.0.51 2024年7月18日(木) 20:06:33 +0000 https://yii.dokyumento.jp/news/650/yii-2-0-51https://yii.dokyumento.jp/news/650/yii-2-0-51 samdark samdark

Yii Framework バージョン 2.0.51 のリリースを発表できることを嬉しく思います。

このバージョンをインストールまたはアップグレードするには、https://yii.dokyumento.jp/download/ の手順を参照してください。

このリリースでは、2.0.50 の回帰、PHP 8.3 とのエラーハンドラの互換性、およびいくつかのバグを修正しています。

フレームワークに貢献してくださった Yii コミュニティの皆様、ドキュメントの翻訳を最新の状態に保ってくださった翻訳者の方々、フォーラムで質問に答えてくださったコミュニティの皆様に感謝いたします。

活発な Yii コミュニティが多数ありますので、ヘルプが必要な場合や経験を共有したい場合は、お気軽に参加してください。

変更の完全なリストは、CHANGELOG で確認できます。

]]>
0
[拡張機能] pingcrm-yii2-vue3 2024年7月17日(水) 09:28:16 +0000 https://yii.dokyumento.jp/extension/pingcrm-yii2-vue3https://yii.dokyumento.jp/extension/pingcrm-yii2-vue3 toatall toatall

Yii 2 上の Ping CRM

  1. デモ
  2. インストール
  3. テストの実行
  4. 要件
  5. このプロジェクトの拡張
  6. クレジット

Inertia.js の動作方法を示す Yii 2 デモアプリケーションです。

Inertia を使用すると、API を構築することなく、従来のサーバーサイドルーティングとコントローラーを使用してシングルページアプリケーションを構築できます。

このアプリケーションは、元のLaravel で記述された Ping CRM を移植したもので、Yii 2 Basic Project Template をベースにしています。

screenshot.png

Yii 2 上の Ping CRM アプリケーション githubyii 拡張機能 をベースにしています。

変更点: Vue をバージョン 3 に更新、npm パッケージと composer を更新。Vue ファイルを Composition API (script setup) に変換しました。

デモ

https://pingcrm-yii2.tebe.ch

インストール

リポジトリをローカルにクローンします。

git clone https://github.com/toatall/pingcrm-yii2-vue3 pingcrm-yii2-vue3
cd pingcrm-yii2-vue3

PHP の依存関係をインストールします。

composer install

NPM の依存関係をインストールします。

npm ci

アセットをビルドします。

npm run css-dev
npm run dev

SQLite データベースを作成します。別のデータベース (MySQL、Postgres) を使用することもできます。その場合は、構成を適宜更新してください。

touch database/database.sqlite

データベースマイグレーションを実行します。

php yii migrate

データベースシードを実行します。

php yii db/seed

開発サーバーを実行します (出力にアドレスが表示されます)

php yii serve

準備完了です!ブラウザで Ping CRM にアクセスし、次の情報でログインしてください。

  • **ユーザー名:** johndoe@example.com
  • **パスワード:** secret

テストの実行

Ping CRM のテストを実行するには、次のコマンドを実行します。

(to be done)

要件

  • PHP >= 7.4.0
  • Node.js & NPM
  • SQLite

このプロジェクトの拡張

このプロジェクトに新しい機能を追加する場合は、次の手順が必要です。

バックエンド
  • Inertia コントローラーを継承する新しいコントローラーを追加します。
  • 1 つ以上のアクションを追加します。
  • Inertia の render メソッドを呼び出してアクションから返します。
<?php

namespace app\controllers;

use tebe\inertia\web\Controller;

class CustomController extends Controller
{
    public function actionIndex()
    {
        $params = [
            'data' => [],
        ];
        return $this->inertia('demo/index', $params);
    }
}

https://github.com/tbreuss/yii2-inertia に詳しい情報があります。

フロントエンド
  • バックエンドに追加した各コントローラーアクションに対して、resources/js/Pages の下に新しいページを追加します。
  • 既存のページの例をコピー&ペーストします。
  • 必要に応じて Vue.js の部分を実装または拡張します。
  • ここで、および package.json で説明されているフロントエンドツールを使用します。

https://inertia.dokyumento.jp に詳しい情報があります。

クレジット

  • オリジナル作品: Jonathan Reinink (@reinink) と貢献者
  • Yii 2 への移植: Thomas Breuss (@tbreuss)
  • @toatall による修正 (https://github.com/toatall)
]]>
0
[ニュース] Yii HTTP Runner 3.0 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/649/yii-http-runner-3-0https://yii.dokyumento.jp/news/649/yii-http-runner-3-0 vjik vjik

Yii HTTP Runner のメジャーバージョンがタグ付けされました。このバージョンではいくつかの変更が加えられました。

  • メッセージ本文の内容を送信するバッファのサイズを変更できる機能を追加しました。
  • 任意のPSRロガーを使用できるようになりました(デフォルトはNullLogger)。
  • ServerRequestFactory を削除しました。
  • SapiEmitter を内部としてマークしました。
  • 独自の出力バッファを閉じない応答の処理が間違っていたのを修正しました。
]]>
0
[ニュース] Yii Error Handler 3.3 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/648/yii-error-handler-3-3https://yii.dokyumento.jp/news/648/yii-error-handler-3-3 vjik vjik

Yii Error Handler パッケージが以下の機能強化で更新されました。

  • cURLボタンのコピーを追加、リクエストヘッダーのソート、UIの修正。
  • エラーログの簡素化。
  • クリックで引数をすべて表示。
  • @anonymous 接尾辞の削除。
  • クリックで引数のテーブルを表示。
  • テキスト選択時のクリックイベントの中止。
  • 延期されたものも含め、すべてのシャットダウン関数後にexit(1)を実行します。
]]>
0
[ニュース] Yii HTML 3.5 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/647/yii-html-3-5https://yii.dokyumento.jp/news/647/yii-html-3-5 vjik vjik

Yii HTML パッケージのバージョン3.5がリリースされました。いくつかの改善点があります。

  • タグhrとメソッドHtml::hr()のクラスを追加しました。
  • aria-describedby 属性で複数の要素をサポートしました。
]]>
0
[ニュース] Yii Logging Library 2.1 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/news/646/yii-logging-library-2-1https://yii.dokyumento.jp/news/646/yii-logging-library-2-1 vjik vjik

Yii Logging Library パッケージが以下の機能強化と新機能で更新されました。

  • 新しい静的メソッドLogger::assertLevelIsValid()Logger::assertLevelIsString()Logger::assertLevelIsSupported()を追加しました。
  • メッセージテンプレートの変数でネストされた値をサポートしました(例:{foo.bar})。
  • コンテキストプロバイダーを追加しました。
  • ログコンテキストの時間としてDateTimeDateTimeImmutableのサポートを追加しました。
  • Message::category()メソッドとMessage::DEFAULT_CATEGORY定数を追加し、それを優先してCategoryFilter::DEFAULTを非推奨にしました。
  • Message::trace()メソッドを追加しました。
  • Message::time()メソッドを追加しました。
  • Logger::validateLevel()メソッドを非推奨にしました。
  • コンテキストプロバイダーの使用を優先して、LoggerメソッドsetTraceLevel()setExcludedTracePaths()を非推奨にしました。
  • TargetクラスのsetCommonContext()メソッドとgetCommonContext()メソッドを非推奨にしました。
  • 例外メッセージの生成でgettype()get_debug_type()に置き換えました。
  • Messageコンストラクタの$levelパラメータの型をstringに変更しました。
  • 文字列にキャストできない変数を含むメッセージの解析時のエラーを修正しました。
  • "file"と"line"を含まない場合のトレースのフォーマット時のエラーを修正しました。
]]>
0
[ニュース] Yii Mailer Library 5.1 2024年7月2日(火) 14:43:55 +0000 https://yii.dokyumento.jp/news/645/yii-mailer-library-5-1https://yii.dokyumento.jp/news/645/yii-mailer-library-5-1 vjik vjik

Yii Mailer Library のマイナーバージョンがタグ付けされました。いくつかの改善と修正があります。

  • MessageFactoryでデフォルトの「from」値を設定できるようにしました。
  • 最小PHPバージョンを^8.1に上げました。
  • 必須のyiisoft/viewバージョンを^10.0に上げました。
]]>
0
[ニュース] Yii View Renderer 7.1 2024年7月1日(月) 12:00:35 +0000 https://yii.dokyumento.jp/news/644/yii-view-renderer-7-1https://yii.dokyumento.jp/news/644/yii-view-renderer-7-1 vjik vjik

Yii View Renderer のマイナーバージョンがタグ付けされました。

  • 必須のyiisoft/viewバージョンを^10.0に上げました。
]]>
0
[拡張機能] sjaakp/yii2-random-provider 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/sjaakp/yii2-random-providerhttps://yii.dokyumento.jp/extension/sjaakp/yii2-random-provider sjaakp sjaakp

yii2-random-provider

  1. インストール
  2. RandomProvider の使用
ランダム選択による ActiveDataProvider

Latest Stable Version Total Downloads License

RandomProvider は、ActiveDataProviderYii 2.0 PHPフレームワーク)を継承したものです。レコードをランダムに選択します。これは、通常のActiveDataProvider(通常は)が順番にレコードを選択する方式とは異なり、場合によってはより魅力的な方法です。RandomProvider は、私のLoadMorePagerと連携することを意図していますが、LinkPagerや他のページャーとも動作します。

RandomProviderは、CUBRIDまたはdblibデータベースドライバをサポートしていません。さらに、mysqlでのみテスト済みです。ただし、他のドライバでも動作する可能性が高いと考えています。ご経験のある方はぜひ情報提供いただければ幸いです。

RandomProviderは、「Order By Rand()」というアルゴリズムを使用している点にも注意してください。これは比較的遅く、スケーラビリティも高くありません。そのため、RandomProviderは、比較的少ないデータセット(数千レコード未満)でのみ使用することをお勧めします。詳細はこちらを参照してください。

RandomProviderのデモはこちらにあります。

インストール

Composerを使用して、通常の方法でyii2-random-providerをインストールします。composer.jsonファイルのrequireセクションに以下を追加してください。

"sjaakp/yii2-random-provider": "*"

または、以下を実行します。

composer require sjaakp/yii2-random-provider

yii2-random-providerは、ソースコードをZIP形式でダウンロードして、手動でインストールすることもできます。

RandomProviderの使い方

RandomProviderは、YiiのActiveDataProviderの置き換えとして使用できます。ActiveDataProviderと同様に使用してください。

]]>
0
[拡張機能] yagas/yii2-debug4mongo 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/yagas/yii2-debug4mongohttps://yii.dokyumento.jp/extension/yagas/yii2-debug4mongo yagas yagas

993323

Yii 2 Debug For MongoDB

  1. ディレクトリ構造
  2. 依存関係のインストール
  3. インストール手順
  4. 設定手順

本プロジェクトはyii2-debugの拡張機能であり、MongoDBを使用してデバッグデータを保存します。

ディレクトリ構造

  src/                 代码目录
  src/models/          数据模型
  src/views/           视图文件
  src/controllers/     控制器

依存関係のインストール

  • PHP >= 5.4 が必要です。
  • yii2-mongodb
  • yii2-debug >= 2.1.25 が必要です(このバージョンに基づいて構築されています)。

インストール手順

composer require yagas/yii2-debug4mongo

設定手順

if (YII_ENV_DEV) {
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = [
        'class' => 'yagas\debug\Module',
        'logTarget' => [
            'class' => 'yagas\debug\LogTarget',
            'app_no' => 'localhost_001', // 为当前站点设定标识
        ],
        'percent' => 10, // 百分之十的几率清除历史数据(GC)
    ];
}
]]>
0
[拡張機能] diecoding/yii2-pdfjs 2024年5月20日 17:11:05 UTC https://yii.dokyumento.jp/extension/diecoding/yii2-pdfjshttps://yii.dokyumento.jp/extension/diecoding/yii2-pdfjs die-coding die-coding

Yii2 PDF.js

  1. 目次
  2. インストール
  3. 依存関係
  4. 使用方法

Yii2 用 PDF.js による PDF ファイルのプレビュー

Latest Stable Version Total Downloads Latest Stable Release Date Quality Score Build Status License PHP Version Require

Yii2 PDF.js は PDF.js を使用します。
デモ: https://mozilla.github.io/pdf.js/web/viewer.html

目次

インストール

パッケージは Packagist で利用可能です。Composer を使用してインストールできます。

composer require diecoding/yii2-pdfjs '^1.0'

または、composer.jsonファイルの require セクションに追加します。

'diecoding/yii2-pdfjs': '^1.0'

依存関係

使用方法

モジュールの設定
...
'modules'=>[
  'pdfjs' => [
       'class' => \diecoding\pdfjs\Module::class,
   ],
],
...

ビュー
基本的な使用方法
echo \diecoding\pdfjs\PdfJs::widget([
    'url' => '@web/uploads/dummy.pdf',
]);
フルツールバーセクション付きの直接URL
echo Url::to(["/pdfjs", 'file' => Url::to('@web/uploads/dummy.pdf', true)], true);
カスタム属性
echo \diecoding\pdfjs\PdfJs::widget([
    'url' => '@web/uploads/dummy.pdf',
    'options' => [
        'style' => [
            'width' => '100%',
            'height' => '500px',
        ],
    ],
]);
ツールバーセクションの無効化
echo \diecoding\pdfjs\PdfJs::widget([
    'url' => '@web/uploads/dummy.pdf',
    'sections' => [
        'toolbarContainer' => false,
    ],
]);
]]>
0
[拡張機能] xiaosongshu/rabbitmq 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/xiaosongshu/rabbitmqhttps://yii.dokyumento.jp/extension/xiaosongshu/rabbitmq 2723659854 2723659854

rabbitmq キュー メッセージキュー

プロジェクトアドレス:https://github.com/2723659854/rabbitmq

プロジェクト概要

メッセージキューは主にビジネスのデカップリングに使用されます。このプロジェクトではrabbitmqを採用し、thinkPHP、laravel、webman、yiiなどの一般的なフレームワークをサポートしており、単独で使用することもできます。

インストール方法
composer require xiaosongshu/rabbitmq
キューの定義
<?php
namespace app\commands;

require_once __DIR__.'/vendor/autoload.php';

class Demo extends \Xiaosongshu\Rabbitmq\Client
{

    /** 以下是rabbitmq配置 ,请填写您自己的配置 */
    /** @var string $host 服务器地址 */
    public static $host = "127.0.0.1";

    /** @var int $port 服务器端口 */
    public static $port = 5672;

    /** @var string $user 服务器登陆用户 */
    public static $user = "guest";

    /** @var string $pass 服务器登陆密码 */
    public static $pass = "guest";

    /**
     * 业务处理
     * @param array $params
     * @return int
     */
    public static function handle(array $params): int
    {
        //TODO 这里写你的业务逻辑
        // ...
        var_dump($params);
        return self::ACK;
        //return self::NACK;
    }
}

メッセージの送信
\app\commands\Demo::publish(['name'=>'tome','age'=>15]);

メッセージはどこからでも送信できます。

コンシューマーの開始
\app\commands\Demo::consume();

コンシューマーをコマンドラインに配置し、コマンドラインを使用してキューの消費を実行できます。例(yiiを例として示します。laravel、webman、thinkPHPなどの他のフレームワークでも同様です):`php <?php

namespace app\commands;

use yii\console\Controller;

/**

  • @purpose キューコンシューマーの開始
  • @note これは単なる例です */ class QueueController extends Controller {

    /**

    • @api php yii queue/index
    • @return void
    • @throws \Exception
    • @comment コンシューマーの開始 */ public function actionIndex() { Demo::consume(); } }
      开启消费者命令 consume
      ```bash
      php yii queue/index
      

      注:複数のコンシューマーを開始する必要がある場合は、複数のウィンドウでコンシューマー開始コマンドを実行できます。もちろん、マルチプロセスを使用して処理することもできます。

      コンシューマーの停止
\app\commands\Demo::close();
例外

キューの使用中は、\RuntimeExceptionと\Exceptionを使用して例外をキャッチしてください。

遅延キューを使用する必要がある場合、rabbitmqサービスに遅延プラグインをインストールする必要があります。インストールされていない場合、エラーが発生します。
テスト

このプロジェクトのルートディレクトリには、demo.phpというテストファイルがあります。これをプロジェクトのルートディレクトリにコピーし、コマンドラインで次のコマンドを実行できます。`php php demo.php テストファイルコードは以下のとおりです。php <?php

namespace xiaosongshu\test; require_once __DIR__ . '/vendor/autoload.php';

/**

  • demo
  • @purpose キューの定義例 */ class Demo extends \Xiaosongshu\Rabbitmq\Client {

    /* 以下はrabbitmqの設定です。ご自身の設定を入力してください / /* @var string $host サーバーアドレス / public static $host = "127.0.0.1";

    /* @var int $port サーバーポート / public static $port = 5672;

    /* @var string $user サーバーログインユーザー / public static $user = "guest";

    /* @var string $pass サーバーログインパスワード / public static $pass = "guest";

    /**

    • ビジネス処理
    • @param array $params
    • @return int */ public static function handle(array $params): int { //TODO ここにビジネスロジックを記述 // ... var_dump($params); /* 成功の場合、ackを返す / return self::ACK; /* 失敗の場合、NACKを返す/ //return self::NACK; } }

/* 通常メッセージの送信 */ \xiaosongshu\test\Demo::publish(['name' => 'tom']); \xiaosongshu\test\Demo::publish(['name' => 'jim']); \xiaosongshu\test\Demo::publish(['name' => 'jack']); /* コンシューマーを開始します。この関数はブロッキングなので、以降のコードは実行されません / \xiaosongshu\test\Demo::consume(); /* コンシューマーの停止 */ \xiaosongshu\test\Demo::close(); `

作者への連絡先:2723659854@qq.com 、issues を直接提出することもできます
]]>
0
[拡張機能] xiaosongshu/yii2-rabbitmq 2024年4月24日 09:33:36 UTC https://yii.dokyumento.jp/extension/xiaosongshu/yii2-rabbitmqhttps://yii.dokyumento.jp/extension/xiaosongshu/yii2-rabbitmq 2723659854 2723659854

rabbitmq キュー 遅延キュー

インストール方法

composer require xiaosongshu/yii2-rabbitmq
キューの定義
<?php
namespace app\commands;

require_once __DIR__.'/vendor/autoload.php';

class Demo extends \Xiaosongshu\Rabbitmq\Client
{

    /** 以下是rabbitmq配置 ,请填写您自己的配置 */
    /** @var string $host 服务器地址 */
    public static $host = "127.0.0.1";

    /** @var int $port 服务器端口 */
    public static $port = 5672;

    /** @var string $user 服务器登陆用户 */
    public static $user = "guest";

    /** @var string $pass 服务器登陆密码 */
    public static $pass = "guest";

    /**
     * 业务处理
     * @param array $params
     * @return int
     */
    public static function handle(array $params): int
    {
        //TODO 这里写你的业务逻辑
        // ...
        var_dump($params);
        return self::ACK;
        //return self::NACK;
    }
}

メッセージの送信
\app\commands\Demo::publish(['name'=>'tome','age'=>15]);

メッセージはどこからでも送信できます。

コンシューマーの開始
\app\commands\Demo::consume();

コンシューマーをコマンドラインに配置し、コマンドラインを使用してキューの消費を実行できます。例:`php <?php

namespace app\commands;

use yii\console\Controller;

/**

  • @purpose キューコンシューマーの開始
  • @note これは単なる例です */ class QueueController extends Controller {

    /**

    • @api php yii queue/index
    • @return void
    • @throws \Exception
    • @comment コンシューマーの開始 */ public function actionIndex() { Demo::consume(); } }
      开启消费者命令 consume
      ```bash
      php yii queue/index
      
      例外

キューの使用中は、\RuntimeExceptionと\Exceptionを使用して例外をキャッチしてください。

遅延キューを使用する必要がある場合、rabbitmqサービスに遅延プラグインをインストールする必要があります。インストールされていない場合、エラーが発生します。
作者への連絡先:2723659854@qq.com
]]>
0
[拡張機能] xiaosongshu/yii2-elasticsearch 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/xiaosongshu/yii2-elasticsearchhttps://yii.dokyumento.jp/extension/xiaosongshu/yii2-elasticsearch 2723659854 2723659854

elasticsearch - Yii クライアント elasticsearch client for Yii

インストール
composer require xiaosongshu/yii2-elasticsearch
設定

`php

'components' => [

 'ESClient' => [
        'class' => \Xiaosongshu\Elasticsearch\ESClient::class,
        'node'=>['192.168.101.170:9200'],
        'username' => '',
        'password' => '',
    ],

] `

基本的な使用方法
$res = Yii::$app->ESClient->search('index','_doc','title','测试')['hits']['hits'];
クライアントがサポートするすべてのメソッド
创建索引:createIndex
创建表结构:createMappings
删除索引:deleteIndex
获取索引详情:getIndex
新增一行数据:create
批量写入数据:insert
根据id批量删除数据:deleteMultipleByIds
根据Id 删除一条记录:deleteById
获取表结构:getMap
根据id查询数据:find
根据某一个关键字搜索:search
使用原生方式查询es的数据:nativeQuerySearch
多个字段并列查询,多个字段同时满足需要查询的值:andSearch
or查询  多字段或者查询:orSearch
根据条件删除数据:deleteByQuery
根据权重查询:searchByRank
获取所有数据:all
添加脚本:addScript
获取脚本:getScript
使用脚本查询:searchByScript
使用脚本更新文档:updateByScript
索引是否存在:IndexExists
根据id更新数据:updateById
このプラグインを単独で使用する場合、インスタンス化時にelasticsearchの接続設定を渡す必要があります。
elasticsearch クライアントの使用例
<?php
require_once 'vendor/autoload.php';

/** 实例化客户端 */
$client = new \Xiaosongshu\Elasticsearch\ESClient([
    /** 节点列表 */
    'nodes' => ['192.168.4.128:9200'],
    /** 用户名 */
    'username' => '',
    /** 密码 */
    'password' => '',
]);
/** 删除索引 */
$client->deleteIndex('index');
/** 如果不存在index索引,则创建index索引 */
if (!$client->IndexExists('index')) {
    /** 创建索引 */
    $client->createIndex('index', '_doc');
}

/** 创建表 */
$result = $client->createMappings('index', '_doc', [
    'id' => ['type' => 'long',],
    'title' => ['type' => 'text', "fielddata" => true,],
    'content' => ['type' => 'text', 'fielddata' => true],
    'create_time' => ['type' => 'text'],
    'test_a' => ["type" => "rank_feature"],
    'test_b' => ["type" => "rank_feature", "positive_score_impact" => false],
    'test_c' => ["type" => "rank_feature"],
]);
/** 获取数据库所有数据 */
$result = $client->all('index','_doc',0,15);

/** 写入单条数据 */
$result = $client->create('index', '_doc', [
    'id' => rand(1,99999),
    'title' => '我只是一个测试呢',
    'content' => '123456789',
    'create_time' => date('Y-m-d H:i:s'),
    'test_a' => 1,
    'test_b' => 2,
    'test_c' => 3,
]);
/** 批量写入数据 */
$result = $client->insert('index','_doc',[
    [
        'id' => rand(1,99999),
        'title' => '我只是一个测试呢',
        'content' => '你说什么',
        'create_time' => date('Y-m-d H:i:s'),
        'test_a' => rand(1,10),
        'test_b' => rand(1,10),
        'test_c' => rand(1,10),
    ],
    [
        'id' => rand(1,99999),
        'title' => '我只是一个测试呢',
        'content' => '你说什么',
        'create_time' => date('Y-m-d H:i:s'),
        'test_a' => rand(1,10),
        'test_b' => rand(1,10),
        'test_c' => rand(1,10),
    ],
    [
        'id' => rand(1,99999),
        'title' => '我只是一个测试呢',
        'content' => '你说什么',
        'create_time' => date('Y-m-d H:i:s'),
        'test_a' => rand(1,10),
        'test_b' => rand(1,10),
        'test_c' => rand(1,10),
    ],
]);
/** 使用关键字搜索 */
$result = $client->search('index','_doc','title','测试')['hits']['hits'];

/** 使用id更新数据 */
$result1 = $client->updateById('index','_doc',$result[0]['_id'],['content'=>'今天你测试了吗']);
/** 使用id 删除数据 */
$result = $client->deleteById('index','_doc',$result[0]['_id']);
/** 使用条件删除 */
$client->deleteByQuery('index','_doc','title','测试');
/** 使用关键字搜索 */
$result = $client->search('index','_doc','title','测试')['hits']['hits'];
/** 使用条件更新 */
$result = $client->updateByQuery('index','_doc','title','测试',['content'=>'哇了个哇,这么大的种子,这么大的花']);
/** 添加脚本 */
$result = $client->addScript('update_content',"doc['content'].value+'_'+'谁不说按家乡好'");
/** 添加脚本 */
$result = $client->addScript('update_content2',"(doc['content'].value)+'_'+'abcdefg'");
/** 获取脚本内容 */
$result = $client->getScript('update_content');
/** 使用脚本搜索 */
$result = $client->searchByScript('index', '_doc', 'update_content', 'title', '测试');
/** 删除脚本*/
$result = $client->deleteScript('update_content2');
/** 使用id查询 */
$result = $client->find('index','_doc','7fitkYkBktWURd5Uqckg');
/** 原生查询 */
$result = $client->nativeQuerySearch('index',[
    'query'=>[
        'bool'=>[
            'must'=>[
                [
                    'match_phrase'=>[
                        'title'=>'测试'
                    ],
                ],
                [
                    'script'=>[
                        'script'=>"doc['content'].value.length()>2"
                    ]
                ]
            ]
        ]
    ]

]);
/** and并且查询 */
$result = $client->andSearch('index','_doc',['title','content'],'测试');
/** or或者查询 */
$result = $client->orSearch('index','_doc',['title','content'],'今天');

テスト

この拡張パッケージのphpunit.xmlファイルをプロジェクトのルートディレクトリにコピーし、次のコマンドを実行します。`bash php ./vendor/bin/phpunit -c phpunit.xml `

作者への連絡先

2723659854@qq.com

]]>
0
[拡張機能] jatin 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/jatinhttps://yii.dokyumento.jp/extension/jatin jatin_sharma jatin_sharma

$config['components']['mailer'] = [

'class' => 'jatin\resend\Mailer',
'useFileTransport' => false,
'viewPath' => '@app/mail',
'transport' => [
    'apiKey' => '<YOUR_API_KEY>'
],

];

]]>
0
[拡張機能] asminog/yii2-proxy 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/asminog/yii2-proxyhttps://yii.dokyumento.jp/extension/asminog/yii2-proxy asminog asminog

Yii 2 用 HTTP プロキシ拡張機能

  1. インストール
  2. 使用方法

これはYii2フレームワーク用のシンプルなプロキシです。この拡張機能は、Yiiフレームワーク2.0 のHTTPプロキシアクションを提供します。

ライセンス情報は、LICENSE ファイルを確認してください。

Build Status Build Status

GitHub repo file count GitHub code size in bytes

インストール

composer require asminog/yii2-proxy

使用方法

use asminog\proxy\ProxyAction;

class SiteController extends Controller
{
    public function actions()
    {
        return [
            'proxy' => [
                'class' => ProxyAction::class,
                // 'accessToken' => 'your-access-token', // - set access token for secure requests
                // 'throw404Exception' => true, // - show 404 error if access token is not valid or request url is not valid
                // 'proxyHeaders' => ['User-Agent', 'Content-Type'], // - set headers for proxy request
                // 'proxyCookies' => ['cookie1', 'cookie2'], // - set cookies for proxy request
            ],
        ];
    }
}
]]>
0
[拡張機能] sandritsch91/yii2-widget-flatpickr 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/sandritsch91/yii2-widget-flatpickrhttps://yii.dokyumento.jp/extension/sandritsch91/yii2-widget-flatpickr Sandritsch91 Sandritsch91

yii2-flatpickr

flatpickrYii2 用ウィジェット

]]>
0
[拡張機能] sandritsch91/yii2-widget-form-wizard 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/sandritsch91/yii2-widget-form-wizardhttps://yii.dokyumento.jp/extension/sandritsch91/yii2-widget-form-wizard Sandritsch91 Sandritsch91

yii2-form-wizard

  1. 機能
  2. インストール
  3. 使用方法
  4. コントリビューション

Bootstrap 5 用 Yii2 フォームウィザードウィジェット

Alt preview

機能

  • Bootstrap 5
  • クライアントサイドバリデーション(各ステップを個別に検証するオプション付き)

インストール

この拡張機能をインストールする推奨方法は、composer を使用することです。

以下のコマンドを実行するか、

php composer.phar require --prefer-dist sandritsch91/yii2-form-wizard

または、

"sandritsch91/yii2-form-wizard": "*"

をcomposer.jsonのrequireセクションに追加します。

使用方法

use sandritsch91\yii2-form-wizard\FormWizard;

echo FormWizard::widget([
    // required
    'model' => $model,                                                          // The model to be used in the form
    'tabOptions' => [                                                           // These are the options for the Bootstrap Tab widget                                        
        'items' => [
            [
                'label' => 'Step 1',                                            // The label of the tab, if omitted, a default-label will be used (Step 1, Step 2, ...)
                'content' => $this->render('_step1', ['model' => $model]),      // Either the content of the tab
            ],
            [
                'label' => 'Step 2',
                'view' => '/test/_step2',                                       // or a view to be rendered. $model and $form are passed to the view
                'params' => ['a' => 1, 'b' => 2]                                // Pass additional parameters to the view
            ]
        ],
        'navType' => 'nav-pills'
    ],
    // optional
    'validateSteps' => [                                                        // Optional, pass the fields to be validated for each step.                 
        ['name', 'surname'],
        [],                                                                     // Leave array empty if no validation is needed  
        ['email', 'password']
    ],
    'options' => [],                                                            // Wizard-container html options
    'formOptions' => [],                                                        // Form html options
    'buttonOptions' => [                                                        // Button html options
        'previous' => [
            'class' => ['btn', 'btn-secondary'],
            'data' => [
                'formwizard' => 'previous'                                      // If you change this, make sure the clientOptions match
            ]
        ],
        'next' => [...],
        'finish' => [...]
    ],
    'clientOptions' => [                                                        // Client options for the form wizard, if you need to change them
        // 'finishSelector' => '...',
        // 'nextSelector' => '...',
        // 'previousSelector' => '...',
        // 'keepPosition' => true                                               // Keep scroll position on step change.
                                                                                // Set to false to disable, or pass a selector if you have a custom scroll container.
                                                                                // Defaults to true.
    ],
    'clientEvents' => [                                                         // Client events for the form wizard
        // 'onNext' => 'function () {...}',
        // 'onPrevious' => 'function () {...}',
        // 'onFinish' => 'function (){...}'
    ]
]);

コントリビューション

ご協力お待ちしております。

ご質問、アイデア、ご提案、バグなどございましたら、お気軽にissueをご報告ください。

テスト

このパッケージは、テストにcodeceptionを使用しています。テストを実行するには、次のコマンドを実行します。


#### Unit tests

run ```php.exe .\vendor\bin\codecept run Unit``` in the root directory of this repository.

#### Functional tests

run ```php.exe .\vendor\bin\codecept run Functional``` in the root directory of this repository.

#### Accpetance tests

To be able to run acceptance tests, a few requirements are needed:

For Windows:\

- install java runtime environment
- install nodejs
- install selenium-standalone: `npm install -g selenium-standalone`
- start selenium-standalone: `selenium-standalone install && selenium-standalone start`
- host a yii2 application on a server or locally via ```./yii serve```
    - add this plugin as a dependency to your ```composer.json``` and update dependencies
    - site must be reachable over http://formwizard.com/
    - add an action ```actionTest``` to the ```SiteController```, as described below
    - this action must return a view file, as described below
    - run ```php.exe .\vendor\bin\codecept run Acceptance```

For Linux:  
Never did that before, but I think it is similar to the Windows setup.

The action in the SiteController:

```php
public function actionTest(): string
{
    include __DIR__ . '/../vendor/sandritsch91/yii2-widget-form-wizard/tests/Support/Data/models/User.php';

    $model = new User();

    if (Yii::$app->request->post() && $model->load(Yii::$app->request->post()) && $model->validate()) {
        return 'success';
    }

    return $this->render('test', [
        'model' => new User()
    ]);
}
```

The view returned by the action:

```php
/** @var User $model */

use sandritsch91\yii2\formwizard\FormWizard;
use sandritsch91\yii2\formwizard\tests\Support\Data\models\User;

$wizard = FormWizard::widget([
    'model' => $model,
    'tabOptions' => [
        'options' => [
            'class' => 'mb-3'
        ],
        'items' => [
            [
                'label' => 'Step 1',
                'view' => '@app/vendor/sandritsch91/yii2-widget-form-wizard/tests/Support/Data/views/site/step1',
                'linkOptions' => [
                    'id' => 'step1-link',,
                    'params' => [
                        'test' => 'some test variable'
                    ]
                ]
            ],
            [
                'label' => 'Step 2',
                'view' => '@app/vendor/sandritsch91/yii2-widget-form-wizard/tests/Support/Data/views/site/step2',
                'linkOptions' => [
                    'id' => 'step2-link',
                ]
            ],
            [
                'label' => 'Step 3',
                'view' => '@app/vendor/sandritsch91/yii2-widget-form-wizard/tests/Support/Data/views/site/step3',
                'linkOptions' => [
                    'id' => 'step3-link',
                ]
            ]
        ],
        'navType' => 'nav-pills'
    ],
    'validateSteps' => [
        ['firstname', 'lastname'],
        ['username', 'password', 'password_validate'],
        ['email']
    ],
    'clientOptions' => [
        'keepPosition' => true
    ]
]);

echo \yii\helpers\Html::tag('div', $wizard, [
    'class' => 'col-4'
]);
```

After the initial installation, you only have to start the selenium-standalone server ```selenium-standalone start```
and run the tests ```php.exe .\vendor\bin\codecept run Acceptance``` in the root directory of this repository.

If you do not want to setup an application, just run the unit and functional tests by
running ```php.exe .\vendor\bin\codecept run Unit,Functional```, I can modify and run the acceptance tests for you,
after you opened a pull request.

]]>
0
[wiki] WordPressへのYii3パッケージの統合 2024年3月4日 16:34:16 UTC https://yii.dokyumento.jp/wiki/2579/integrating-yii3-packages-into-wordpresshttps://yii.dokyumento.jp/wiki/2579/integrating-yii3-packages-into-wordpress glpzzz glpzzz
  1. ソースコード公開
  2. 目的
  3. アプローチ
  4. 結論

最近、WordPressウェブサイトに複数の複雑なフォームを統合するタスクを割り当てられました。これらのフォームには、多数のフィールド、複雑な検証ルール、動的フィールド(1対多の関係)、そしてPHPの継承を使用してコードの重複を軽減できる相互依存関係が含まれていました。

最初の調査では、WordPressでフォームを処理する従来のアプローチは、通常、プラグインのインストールか、エディターまたはカスタムページテンプレートを使用してマークアップを手動で埋め込むかのどちらかであることが明らかになりました。その後、フォームの送信を管理するためにプラグインの機能に大きく依存するか、カスタムコーディングに頼ることになります。

私のタスクの一部にデータのログ記録、APIエンドポイントとのインターフェース、メールの送信などが含まれていたため、既存のプラグインがこれらの要件を満たしているかどうかを確認するのではなく、自分で機能を開発することを選択しました。

さらに、公式の情報源によると、2024年3月現在、ほとんどのYii 3パッケージは本番環境で使用できる状態と見なされており、長年のYiiフレームワークユーザーとして、これらのアップデートを調査し、習熟する好機であると考えました。

ソースコード公開

Githubでプロジェクト全体とコードを確認できます。

さらに、プロジェクトのルートディレクトリからdocker-compose upを実行するだけで、Dockerを使用して簡単にデプロイできます。WordPressのセットアップとコンテンツ生成は自動的に行われますので、Dockerfileを確認してください。

目標

私の目的は、Yii3パッケージを使用してWordPressフレームワーク内でフォームをレンダリングおよび管理することでした。デモのために、データの検証のみに焦点を当て、それ以上の処理を行わない基本的な評価フォームを実装することにしました。

アプローチ

それでは、最小限のクラシックテーマを例として始めましょう。ダッシュボード内に「評価フォーム」という名前のWordPressページを作成しました。次に、この特定のページを表示するために、テーマのルートフォルダ内にpage-the-rating-form.phpという名前のファイルを作成する必要があります。

この指定されたファイルは、フォームのマークアップを定義するための設計図として機能します。

プロジェクトへのYii3パッケージの追加:

Yii3の機能を活用するために、次のパッケージを組み込みます。

  • yiisoft/form-model: フォームのフィールドを表すモデルクラスを定義し、フィールドのレンダリングを容易にします。
  • yiisoft/form: マークアップ関連のタスクを処理します。
  • yiisoft/validator: 入力検証を行います。

まず、composer initを実行して、テーマのルートにComposerプロジェクトを初期化します。このプロセスにより、composer.jsonファイルが生成されます。その後、プロジェクトにYii3パッケージを含めます。

composer require yiisoft/form-model:dev-master yiisoft/validator yiisoft/form:dev-master

そして、functions.phpファイルに次の行を追加して、テーマにcomposerの自動読み込みを指示します。

require __DIR__ . '/vendor/autoload.php';
フォームモデルの作成

composer initコマンドの実行後、テーマのルートディレクトリにsrcディレクトリが作成されました。このディレクトリ内にフォームモデルクラスを追加します。

プロジェクトの拡張を考慮して、整理を維持することが重要です。そのため、src/Formsディレクトリを作成し、その中にRatingFormクラスを配置します。

<?php

namespace Glpzzz\Yii3press\Forms;

use Yiisoft\FormModel\FormModel;

class RatingForm extends FormModel
{

	private ?string $name = null;
	private ?string $email = null;
	private ?int $rating = null;
	private ?string $comment = null;
	private string $action = 'the_rating_form';

	public function getPropertyLabels(): array
	{
		return [
			'name' => 'Name',
			'email' => 'Email',
			'rating' => 'Rating',
			'comment' => 'Comment',
		];
	}

}

評価ユースケースに必要なフィールド以外にも、actionクラス属性に注目することが重要です。この属性は、WordPressにどのテーマフックがフォームの送信を管理するべきかを指示する上で重要です。これについては後で詳しく説明します。

モデルへの検証ルールの追加:

ここで、入力の整合性を確保するために、モデルにいくつかの検証ルールを組み込みます。まず、RulesProviderInterfaceを実装するようにクラスを設定します。これにより、フォームパッケージはこれらのルールにアクセスし、ネイティブの検証属性を使用してHTMLマークアップを拡張できます。

class RatingForm extends FormModel implements RulesProviderInterface

これで、クラスにgetRules()メソッドを実装する必要があります。

public function getRules(): iterable
{
	return [
		'name' => [
			new Required(),
		],
		'email' => [
			new Required(),
			new Email(),
		],
		'rating' => [
			new Required(),
			new Integer(min: 0, max: 5),
		],
		'comment' => [
			new Length(min: 100),
		],
	];
}
フォームマークアップの作成

フォームマークアップを生成するには、RatingFormのインスタンスをテンプレートに渡す必要があります。WordPressでは、ページをレンダリングする前にグローバル変数を作成するアプローチを採用しました(最もエレガントな解決策ではありませんが)。


$hydrator = new Hydrator(
	new CompositeTypeCaster(
		new NullTypeCaster(emptyString: true),
		new PhpNativeTypeCaster(),
		new HydratorTypeCaster(),
	)
);

add_filter('template_redirect', function () use ($hydrator) {
	// Get the queried object
	$queried_object = get_queried_object();

	// Check if it's a page
	if ($queried_object instanceof WP_Post && is_page()) {
		if ($queried_object->post_name === 'the-rating-form') {
			global $form;
			if ($form === null) {
				$form = $hydrator->create(RatingForm::class, []);
			}
		}
	}
});

特定の関数外でHydratorクラスをインスタンス化しているので、すべての必要なコールバックで再利用できることに注意してください。RatingFormインスタンスが利用可能になったので、page-the-rating-form.phpファイル内にフォームのマークアップを作成します。


<?php

use Glpzzz\Yii3press\Forms\RatingForm;
use Yiisoft\FormModel\Field;
use Yiisoft\Html\Html;

/** @var RatingForm $form */
global $form;

?>


<?php get_header(); ?>

<h1><?php the_title(); ?></h1>

<?php the_content(); ?>

<?= Html::form()
  ->post(esc_url(admin_url('admin-post.php')))
  ->open()
?>

<?= Field::hidden($form, 'action')->name('action') ?>
<?= Field::text($form, 'name') ?>
<?= Field::email($form, 'email') ?>
<?= Field::range($form, 'rating') ?>
<?= Field::textarea($form, 'comment') ?>

<?= Html::submitButton('Send') ?>

<?= "</form>" ?>

<?php get_footer(); ?>

フォームのマークアップ生成では、Yii3のHtmlヘルパーとFieldクラスを組み合わせて使用しました。注目すべき点は、

  • フォームは、アクションがadmin-post.php WordPressエンドポイントとして指定されたPOSTメソッドを使用しています。
  • フォーム送信にaction値を含めるために、'action'という名前の隠しフィールドを使用しました。Field::hiddenメソッドはフィールド名をTheFormClassName[the_field_name]の形式で生成しますが、単に'action'という名前にする必要があったため、入力を'action'に名前変更しました。

この調整により、次のセクションで説明するように、テーマ関数にフックしてフォームリクエストを処理できます。

さらに進む前に、Yiiの機能を利用してフォームを強化しましょう。既にモデルで入力の送信後の検証ルールを定義していますが、ブラウザ内でも入力の検証を行う方が有利です。入力要素にこれらの検証ルールを直接再定義することもできますが、Yiiは簡素化されたアプローチを提供しています。次のコードスニペットをfunctions.phpファイルに組み込むことで

add_action('init', function () {
	ThemeContainer::initialize([
			'default' => [
				'enrichFromValidationRules' => true,
			]
		], 'default', new ValidationRulesEnricher()
	);
});

このコードスニペットを実装することにより、デフォルトのフォームテーマに対してValidationRulesEnricherを有効にします。有効にすると、フォームフィールドに「required」、「min」、「max」などの検証ルールが追加され、モデルクラスで定義された検証ルールと一致します。この機能によりプロセスが簡素化され、貴重な時間を節約し、手動でのコード作成の必要性が最小限に抑えられます。実際、これはYii3が提供する優れた機能の一部を示しています。

POSTリクエストの処理

フォームが送信されると、WordPressによって提供されるエンドポイントであるadmin-post.phpに送信されます。ただし、複数のフォームを扱う場合、それぞれの処理を区別することが不可欠になります。ここで、POSTリクエストにaction値を含めることが非常に重要になります。

次のコードスニペットの最初の2行に注意してください。フックの命名規則はadmin_post_<action_name>です。したがって、フォームにaction = 'the-rating-form'がある場合、対応するフック名はadmin_post_the_rating_formになります。

admin_post_<action_name>admin_post_nopriv_<action_name>の両方が含まれているのは、WordPressがユーザーがログインしているかどうかに応じて異なるハンドラーを許可しているためです。私たちのシナリオでは、ユーザーの認証ステータスに関係なく、同じハンドラーが必要です。

add_action('admin_post_the_rating_form', fn() => handleForms($hydrator));
add_action('admin_post_nopriv_the_rating_form', fn() => handleForms($hydrator));

function handleForms(Hydrator $hydrator): void
{
  global $form;
  $form = $hydrator->create(RatingForm::class, $_POST['RatingForm']);
  $result = (new Yiisoft\Validator\Validator())->validate($form);

  if ($form->isValid()) {
    // handle the form
  }

  get_template_part('page-the-rating-form');
}

Yiiの側面に戻ると、hydratorを使用して投稿されたデータをフォームにインスタンス化してロードします。次に、データを検証します。検証が成功すると、検証されたデータを使用して目的のアクションを実行できます。ただし、検証に失敗した場合は、フォームを再レンダリングし、送信されたデータと検証中に生成されたエラーメッセージを入力します。

結論

  • これは、Yii3パッケージとWordPressサイトを組み合わせた私の最初の試みでした。結果は満足していますが、特にグローバル変数の使用に関して、改善の余地があると思います。WordPressに精通していないため、**改善のための提案をいただければ幸いです**。
  • 私が使用したYii3パッケージは、実運用環境で使用できる準備ができており、以前のバージョンと同じ品質と機能を提供します。
  • これで、これらのYiiパッケージを個別に使用できます。つまり、Yiiスキルを任意のPHPプロジェクトに適用できます。
  • このプロジェクトは、CMSのシンプルさを維持しながら、Yiiの強力な機能を活用してWordPressサイトを強化する方法を示しています。

原文はhttps://glpzzz.dev/2024/03/03/integrating-yii3-packages-into-wordpress.htmlに投稿されました。

]]>
0
[拡張機能] neoacevedo/yii2-auditing 2024年2月28日(水) 00:31:28 +0000 https://yii.dokyumento.jp/extension/neoacevedo/yii2-auditinghttps://yii.dokyumento.jp/extension/neoacevedo/yii2-auditing NestorAcevedo NestorAcevedo

Yii2監査ログ

  1. インストール
  2. 使用方法
  3. 情報の表示

Yii2のActiveRecordモデルの変更を記録します。

このパッケージを使用すると、モデルの変更履歴を保持し、疑わしいアクティビティを示す可能性のある情報における不一致や異常に関する情報を提供できます。受信および保存された情報は、後でさまざまな方法で表示できます。

インストール

この拡張機能をインストールする推奨方法は、composerを使用することです。

次に実行します。

php composer.phar require --prefer-dist neoacevedo/yii2-auditing "*"

または、

"neoacevedo/yii2-auditing": "*"

composer.jsonファイルのrequireセクションに追加します。

使用方法

拡張機能がインストールされたら、アプリケーションのコンソール設定ファイルのmigrationPathセクションに、

...
'@vendor/neoacevedo/yii2-auditing/neoacevedo/auditing/migrations',
...

次に、モデルのコードのbehaviorsメソッド内に、

public function behaviors()
{
    return [
        [
                'class' => \neoacevedo\auditing\behaviors\AuditBehavior::class,
                'deleteOldData' => true, // Para borrar datos antiguos del registro de eventos
                'deleteNumRows' => 20, // Borra esta cantidad de registros
        ],
        ...
    ];
}

情報の表示

アプリケーションのウェブ内で実装した他のモデルと同様に、情報を表示できます。

履歴を一覧表示するGridViewを使用するコントローラーとビューを使用できます。たとえば、AuditingControllerというコントローラーを作成し、actionIndexメソッドを次のように作成できます。

    /**
     * Lists all Auditing models.
     *
     * @return string
     */
    public function actionIndex()
    {
        $searchModel = new AuditingSearch();
        $dataProvider = $searchModel->search($this->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

データを視覚化するために、actionViewメソッドを作成します。

    /**
     * Displays a single Auditing model.
     * @param int $id ID
     * @return string
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

viewビュー内に、履歴を一覧表示するGridViewを追加できます。

...
    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            'id',
            'user_id',
            'description',
            'event',
            'model',
            'attribute',
            'old_value',
            'new_value',
            'action',
            'ip',
            'created_at',
        ],
    ]); ?>
...
]]>
0
[拡張機能] luguohuakai/yii2-dm 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/luguohuakai/yii2-dmhttps://yii.dokyumento.jp/extension/luguohuakai/yii2-dm luguohuakai luguohuakai

DMデータベース用のデータベース拡張機能

  1. インストール
  2. 使用方法

DMデータベース用のデータベース拡張機能

インストール

この拡張機能をインストールする推奨方法は、composer を使用することです。

以下のコマンドを実行するか、

php composer.phar require --prefer-dist luguohuakai/yii2-dm "*"

または、

"luguohuakai/yii2-dm": "*"

composer.jsonファイルのrequireセクションに追加します。

使用方法

拡張機能がインストールされたら、次のようにコードで使用します。

'components' => [
    'db' => [
        'class' => 'luguohuakai\db\dm\Connection',
        'dsn' => 'dm:host=localhost:xxx;schema=xxx',
        'username' => 'SYSDBA',
        'password' => 'SYSDBA',
    ]
]
]]>
0
[拡張機能] rashedalkhatib/yii2-datatables 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/rashedalkhatib/yii2-datatableshttps://yii.dokyumento.jp/extension/rashedalkhatib/yii2-datatables RashedAlkhatib RashedAlkhatib

DataTableウィジェット

  1. 概要
  2. インストール
  3. 使用方法例(PHPウィジェット)
  4. 使用方法例(JavaScript)
  5. API側での使用方法
  6. お気軽にご連絡ください: alkhatib.rashed@gmail.com

概要

DataTableウィジェットは、インタラクティブで動的なデータテーブルを作成するために使用されます。提供されたJavaScriptコードは、サーバーサイド処理、カスタムデータ処理、列レンダリング、および完全なサーバーサイドエクスポートを使用してDataTableを初期化する方法を示しています。

インストール

Yii2アプリケーション内:
  • 実行: `composer require rashedalkhatib/yii2-datatables:1.0.0`
  • `../frontend/assets/AppAsset.php`に移動します。
    • $depends配列にrashedalkhatib\datatables\DataTableAssetを追加します。
    •         public $depends = [
                'yii\web\YiiAsset',
                'yii\bootstrap\BootstrapAsset',
                'yii\bootstrap\BootstrapPluginAsset',
                'rashedalkhatib\datatables\DataTableAsset'
        ];
      

使用方法例(PHPウィジェット)

- アプリケーション側
$searchFormSelector = '#searchForm';
$ajaxUrl = Url::to(['api/yourEndPoint']); // Adjust the URL based on your routes

// Define your DataTable columns
$columns = [
    [
        'title' => 'ID',
        'data' => 'id',
        'visible' => true,
        'render' => new JsExpression('function(data, type, row) {
            return "demo";
        }'),
    ],
];

// Configure other DataTable parameters
$processing = true;
$serverSide = true;
$pageLength = 10;
$dom = 'Btip';
$buttons = [
    [
        'extend' => 'excel',
        'text' => 'Excel',
        'titleAttr' => 'Excel',
        'action' => new JsExpression('exportAll') // this is required 
    ],
];

// Configure Ajax settings
$ajaxConfig = [
    'url' => $ajaxUrl,
    'bdestroy' => true,
    'type' => 'POST',
    'data' => new JsExpression('function(d) {
            var searchForm = $('body').find('#searchForm').serializeArray();
            
            searchForm[searchForm.length] = { name: 'YourModel[page]', value: d.start }; // required
            searchForm[searchForm.length] = { name: 'YourModel[length]', value: d.length }; // required
            searchForm[searchForm.length] = { name: 'YourModel[draw]', value: d.draw }; // required
            
            var order = {
                'attribute': d.columns[d.order[0]['column']]['data'],
                'dir': d.order[0]['dir']
            }; // required
            
            searchForm[searchForm.length] = { name: 'YourModel[order]', value: JSON.stringify(order) };
            return searchForm;
    }'),
    'dataSrc' => new JsExpression('function(d) {
        var searchForm = $("' . $searchFormSelector . '").serializeArray();
        if (d.validation) {
            searchForm.yiiActiveForm("updateMessages", d.validation, true);
            return [];
        }
        return d.data;
    }'),
];

// Use the DataTableWidget with configured parameters
DataTable::widget([
    'id' => 'yourDataTable',
    'ajaxConfig' => $ajaxConfig,
    'columns' => $columns,
    'processing' => $processing,
    'serverSide' => $serverSide,
    'pageLength' => $pageLength,
    'dom' => $dom,
    'buttons' => $buttons,
]);

// The HTML container for your DataTable
echo '<form id="searchForm">// your inputs </form>';
echo '<table id="yourDataTable" class="display"></table>';

使用方法例(JavaScript)

- アプリケーション側
フロントエンド
<form id="searchForm">
// your inputs 
</form>

<table id="yourDataTable" class="display" style="width:100%">


</table>
var arrayToExport = [0,1];
$('#yourDataTable').DataTable({
    "ajax": {
        // Server-side processing configuration
        "url": "../api/yourEndPoint",
        "bdestroy": true, // this allows you to re init the dataTabel and destory it 
        "type": "POST", // request method
        "data": function (d) { // this represent the data you are sending with your ajax request
            // Custom function for sending additional parameters to the server
            var searchForm = $('body').find('#searchForm').serializeArray();
            
            searchForm[searchForm.length] = { name: "YourModel[page]", value: d.start }; // required
            searchForm[searchForm.length] = { name: "YourModel[length]", value: d.length }; // required
            searchForm[searchForm.length] = { name: "YourModel[draw]", value: d.draw }; // required
            
            var order = {
                'attribute': d.columns[d.order[0]['column']]['data'],
                'dir': d.order[0]['dir']
            }; // required
            
            searchForm[searchForm.length] = { name: "YourModel[order]", value: JSON.stringify(order) };
            return searchForm;
        },
        dataSrc: function (d) {
            // Custom function to handle the response data
            // EX:
            var searchForm = $('body').find('#searchForm').serializeArray();
            if (d.validation) {
                searchForm.yiiActiveForm('updateMessages', d.validation, true);
                return [];
            }
            return d.data;
        }
    },
    "columns": [{
        // Column configurations
        "title": "ID",
        "data": "id",
        "visible": true // visablity of column 
    },
    // ... (other columns)
    {
        "title": "Actions",
        "data": "id",
        "visible": actionCol,
        "render": function (data, type, row) {
            // Custom rendering function for the "Actions" column
            return '<a class="showSomething" data-id="' + row.id + '">View</a>';
        }
    }],
    processing: true,
    serverSide: true,
    "pageLength": 10,
    dom: "Btip",
    "buttons": [{
        // "Excel" button configuration
        "extend": 'excel',
        exportOptions: {
            columns: arrayToExport
        },
        "text": '  Excel',
        "titleAttr": 'Excel',
        "action": exportAll // newexportaction this action is to allow you exporting with server side without rendaring data 
    }],
});
アプリケーションバックエンド
これらのパラメーターはAPIに送信する必要があります
// in your HTTP request you want to include these params 
   $_postData = [
   'page' => $this->page == 0 ? 0 : $this->page / $this->length, // this equation is required to handle Yii2 Data provider Logic
   'limit' => $this->length,
   'export' => $this->export,
   'order' => $this->order,
   // add your custom params .....
   ];
これらのパラメーターはDataTableエンドポイントに返される必要があります
return $this->asJson(
                    [
                        'data' => $_scoreData->data,
                        'draw' => $_scoreSearchForm->draw,
                        'recordsTotal' => $_scoreData->count, 
                        'recordsFiltered' => $_scoreData->count
                ]);

API側での使用方法

エンドポイントアクション
    public function actionYourEndPoint()
    {

        $searchModel = new SearchModel();

        $dataProvider = $searchModel->search(Yii::$app->request->get());
        return $this->asJson(
            array(
                'data' => $dataProvider['data'],
                'count' => $dataProvider['count']
            )
        );

    }
検索機能
    public function search($params)
    {
        $this->load($params, ''); // load your values into the model
        $query = Data::find(); // Data model is your link to the database

        $_order = json_decode($this->order);
        if ($this->export == 'true') {
            $dataProvider = new ActiveDataProvider([
                'query' => $query
                // we removed the page and pageSize keys to allow all data to be exported
            ]);
        } else {
            $_orderType = SORT_ASC;
            if ($_order->dir == 'desc')
                $_orderType = SORT_DESC;
            $query->orderBy([$_order->attribute => $_orderType]);
            $dataProvider = new ActiveDataProvider([
                'query' => $query,
                'pagination' => [
                    'pageSize' => $this->limit,
                    'page' => $this->page,
                ],
            ]);
        }


        return array(
            'data' => $dataProvider->getModels(),
            'count' => $dataProvider->getTotalCount()
        );
    }

お気軽にお問い合わせください: alkhatib.rashed@gmail.com

]]>
0
[拡張機能] eluhr/yii2-json-attribute-behavior 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/eluhr/yii2-json-attribute-behaviorhttps://yii.dokyumento.jp/extension/eluhr/yii2-json-attribute-behavior eluhr eluhr

Yii2 JSON 属性ビヘイビア

  1. インストール
  2. 使用方法
  3. テスト

このビヘイビアは、検証前にJSONから配列への属性の自動デコードを行い、エラー処理と検証失敗時の再エンコードを行います。これにより、「実際の」JSON文字列をさらに処理できます。

CI Workflow

インストール

この拡張機能をインストールする推奨方法は、composerを使用することです。

以下のコマンドを実行するか、

composer require --prefer-dist eluhr/yii2-json-attribute-behavior "*"

または、

"eluhr/yii2-json-attribute-behavior": "*"

composer.jsonファイルのrequireセクションに以下を追加します。

使用方法

yii\base\Modelまたはその派生クラスでは、ビヘイビアは次のように使用できます。

public function behaviors(): array
{
    $behaviors = parent::behaviors();
    $behaviors['json-attribute'] = [
        'class' => eluhr\jsonAttributeBehavior\JsonAttributeBehavior::class,
        'attributes' => [
            'data_json'
        ]
    ];
    return $behaviors;
}

このビヘイビアを使用することで、属性が文字列か配列かは関係ありません。ビヘイビアは常に、データをデータベースに保存する前に属性が配列であることを保証し、Yiiが残りの処理を行います。

このビヘイビアはi18nをサポートしています。設定ファイルにjson-attribute-behaviorカテゴリを追加することで、デフォルトのエラーメッセージを上書きできます。

テスト

composerで依存関係をインストールした後、次のコマンドでテストを実行できます。

make test
]]>
0
[拡張機能] ip2location/ip2proxy-yii 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/ip2location/ip2proxy-yiihttps://yii.dokyumento.jp/extension/ip2location/ip2proxy-yii hexasoft hexasoft

IP2Proxy Yii 拡張機能

  1. インストール
  2. 使用方法
  3. 依存関係
  4. サポート

IP2Proxy Yii拡張機能を使用すると、オープンなプロキシ、ウェブプロキシ、VPN匿名化ツール、TOR出口ノード、検索エンジンロボット、データセンター範囲、住宅用プロキシ、コンシューマープライバシーネットワーク、エンタープライズプライベートネットワークとして使用されているIPアドレスを照会できます。IP2Proxy BINデータファイルまたはウェブサービスからプロキシIPアドレスを検索します。開発者は、APIを使用して、Yiiで記述されたアプリケーションのすべてのIP2Proxy BINデータベースまたはウェブサービスを照会できます。

インストール

Yii2の場合

  1. コマンドphp composer.phar require ip2location/ip2proxy-yiiを実行して、プラグインをYii2フレームワークにダウンロードします。
  2. 最新のIP2Proxy BINデータベースをダウンロードします
  3. 解凍してBINファイルをYii2フレームワークにコピーします。

注記: BINデータベースは.BIN拡張子で終わるバイナリファイルを参照しますが、CSV形式ではありません。ダウンロードする適切なパッケージを選択してください。

使用方法

use IP2ProxyYii\IP2Proxy_Yii;

// (required) Define IP2Proxy database path.
define('IP2PROXY_DATABASE', '/path/to/ip2proxy/database');

// (required) Define IP2Location.io API key.
define('IP2LOCATION_IO_API_KEY', 'your_api_key');

// (optional) Define Translation information. Refer to https://www.ip2location.io/ip2location-documentation for available languages.
define('IP2LOCATION_IO_LANGUAGE', 'en');

$IP2Proxy = new IP2Proxy_Yii();

$record = $IP2Proxy->get('1.0.241.135');
echo 'Result from BIN Database:<br>';
echo '<p><strong>IP Address: </strong>' . $record['ipAddress'] . '</p>';
echo '<p><strong>IP Number: </strong>' . $record['ipNumber'] . '</p>';
echo '<p><strong>IP Version: </strong>' . $record['ipVersion'] . '</p>';
echo '<p><strong>Country Code: </strong>' . $record['countryCode'] . '</p>';
echo '<p><strong>Country: </strong>' . $record['countryName'] . '</p>';
echo '<p><strong>State: </strong>' . $record['regionName'] . '</p>';
echo '<p><strong>City: </strong>' . $record['cityName'] . '</p>';
echo '<p><strong>Proxy Type: </strong>' . $record['proxyType'] . '</p>';
echo '<p><strong>Is Proxy: </strong>' . $record['isProxy'] . '</p>';
echo '<p><strong>ISP: </strong>' . $record['isp'] . '</p>';
echo '<p><strong>Domain: </strong>' . $record['domain'] . '</p>';
echo '<p><strong>Usage Type: </strong>' . $record['usageType'] . '</p>';
echo '<p><strong>ASN: </strong>' . $record['asn'] . '</p>';
echo '<p><strong>AS: </strong>' . $record['as'] . '</p>';
echo '<p><strong>Last Seen: </strong>' . $record['lastSeen'] . '</p>';
echo '<p><strong>Threat: </strong>' . $record['threat'] . '</p>';
echo '<p><strong>Provider: </strong>' . $record['provider'] . '</p>';

$record = $IP2Proxy->getWebService('1.0.241.135');
echo 'Result from Web service:<br>';
echo '<pre>';
print_r ($record);
echo '</pre>';

依存関係

このライブラリは、機能するためにIP2Proxy BINデータファイルまたはIP2Proxy APIキーデータファイルが必要です。BINデータファイルは以下からダウンロードできます。

IP2Location.io IPジオロケーションAPIに登録して、無料のAPIキーを取得することもできます。

サポート

メール: support@ip2location.com

ウェブサイト: https://www.ip2location.com

]]>
0
[拡張機能] ip2location/ip2location-yii 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/ip2location/ip2location-yiihttps://yii.dokyumento.jp/extension/ip2location/ip2location-yii hexasoft hexasoft

IP2Location Yii 拡張機能

  1. インストール
  2. 使用方法
  3. 依存関係
  4. サポート

IP2Location Yii拡張機能を使用すると、IP2Locationデータベースを使用して、IPアドレスから国、地域、都市、座標、郵便番号、タイムゾーン、ISP、ドメイン名、接続タイプ、エリアコード、天気、MCC、MNC、モバイルブランド名、標高、使用タイプ、IPアドレスの種類、IAB広告カテゴリを見つけることができます。速度とメモリ使用量の最適化が図られています。開発者は、APIを使用して、Yiiで記述されたアプリケーションのすべてのIP2Location BINデータベースまたはウェブサービスを照会できます。

インストール

Yii2の場合

  1. コマンドcomposer require ip2location/ip2location-yiiを実行して、拡張機能をYii2フレームワークにダウンロードします。
  2. 最新のIP2Location BINデータベースをダウンロードします
  3. 解凍してBINファイルをYii2フレームワークにコピーします。

注記: BINデータベースは.BIN拡張子で終わるバイナリファイルを参照しますが、CSV形式ではありません。ダウンロードする適切なパッケージを選択してください。

使用方法

use IP2LocationYii\IP2Location_Yii;

// (required) Define IP2Location database path.
define('IP2LOCATION_DATABASE', '/path/to/ip2location/database');

// (required) Define IP2Location.io API key.
define('IP2LOCATION_IO_API_KEY', 'your_api_key');

// (optional) Define Translation information. Refer to https://www.ip2location.io/ip2location-documentation for available languages.
define('IP2LOCATION_IO_LANGUAGE', 'en');

// (optional) Define Translation information. Refer to https://www.ip2location.com/web-service/ip2location for available languages.
define('IP2LOCATION_LANGUAGE', 'en');

$IP2Location = new IP2Location_Yii();

$record = $IP2Location->get('8.8.8.8');
echo 'Result from BIN Database:<br>';
echo 'IP Address: ' . $record['ipAddress'] . '<br>';
echo 'IP Number: ' . $record['ipNumber'] . '<br>';
echo 'ISO Country Code: ' . $record['countryCode'] . '<br>';
echo 'Country Name: ' . $record['countryName'] . '<br>';
echo 'Region Name: ' . $record['regionName'] . '<br>';
echo 'City Name: ' . $record['cityName'] . '<br>';
echo 'Latitude: ' . $record['latitude'] . '<br>';
echo 'Longitude: ' . $record['longitude'] . '<br>';
echo 'ZIP Code: ' . $record['zipCode'] . '<br>';
echo 'Time Zone: ' . $record['timeZone'] . '<br>';
echo 'ISP Name: ' . $record['isp'] . '<br>';
echo 'Domain Name: ' . $record['domainName'] . '<br>';
echo 'Net Speed: ' . $record['netSpeed'] . '<br>';
echo 'IDD Code: ' . $record['iddCode'] . '<br>';
echo 'Area Code: ' . $record['areaCode'] . '<br>';
echo 'Weather Station Code: ' . $record['weatherStationCode'] . '<br>';
echo 'Weather Station Name: ' . $record['weatherStationName'] . '<br>';
echo 'MCC: ' . $record['mcc'] . '<br>';
echo 'MNC: ' . $record['mnc'] . '<br>';
echo 'Mobile Carrier Name: ' . $record['mobileCarrierName'] . '<br>';
echo 'Elevation: ' . $record['elevation'] . '<br>';
echo 'Usage Type: ' . $record['usageType'] . '<br>';
echo 'Address Type: ' . $record['addressType'] . '<br>';
echo 'Category: ' . $record['category'] . '<br>';

$record = $IP2Location->getWebService('8.8.8.8');
echo 'Result from Web service:<br>';
echo '<pre>';
print_r ($record);
echo '</pre>';

依存関係

このライブラリは、機能するためにIP2Location BINデータファイルまたはIP2Location APIキーが必要です。BINデータファイルは以下からダウンロードできます。

IP2Location.io IPジオロケーションAPIに登録して、無料のAPIキーを取得することもできます。

サポート

メール: support@ip2location.com

ウェブサイト: https://www.ip2location.com

]]>
0
[wiki] サムネイル付きBootstrap5ベースの画像カルーセルを作成する 2023年12月4日 月曜日 13:03:38 +0000 https://yii.dokyumento.jp/wiki/2578/create-bootstrap5-based-image-carousel-with-thumbnailshttps://yii.dokyumento.jp/wiki/2578/create-bootstrap5-based-image-carousel-with-thumbnails pravi pravi

期待通りにカルーセルが機能するように、次のCSSスタイルを使用してください。


  .product_img_slide {
    padding: 100px 0 0 0;
  }

  .product_img_slide > .carousel-inner > .carousel-item {
    overflow: hidden;
    max-height: 650px;
  }

  .carousel-inner {
    position: relative;
    width: 100%;
  }

  .product_img_slide > .carousel-indicators {
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    bottom: auto;
    margin: auto;
    font-size: 0;
    cursor: e-resize;
    /* overflow-x: auto; */
    text-align: left;
    padding: 10px 5px;
    /*  overflow-y: hidden;*/
    white-space: nowrap;
    position: absolute;
  }

  .product_img_slide > .carousel-indicators li {
    padding: 0;
    width: 76px;
    height: 76px;
    margin: 0 5px;
    text-indent: 0;
    cursor: pointer;
    background: transparent;
    border: 3px solid #333331;
    -webkit-border-radius: 0;
    border-radius: 0;
    -webkit-transition: all 0.7s cubic-bezier(0.22, 0.81, 0.01, 0.99);
    transition: all 1s cubic-bezier(0.22, 0.81, 0.01, 0.99);
  }

  .product_img_slide > .carousel-indicators .active {
    width: 76px;
    border: 0;
    height: 76px;
    margin: 0 5px;
    background: transparent;
    border: 3px solid #c13c3d;
  }

  .product_img_slide > .carousel-indicators > li > img {
    display: block;
    /*width:114px;*/
    height: 76px;
  }

  .product_img_slide .carousel-inner > .carousel-item > a > img, .carousel-inner > .carousel-item > img, .img-responsive, .thumbnail a > img, .thumbnail > img {
    display: block;
    max-width: 100%;
    line-height: 1;
    margin: auto;
  }

  .product_img_slide .carousel-control-prev {
    top: 58%;
    /*left: auto;*/
    right: 76px;
    opacity: 1;
    width: 50px;
    bottom: auto;
    height: 50px;
    font-size: 50px;
    cursor: pointer;
    font-weight: 700;
    overflow: hidden;
    line-height: 50px;
    text-shadow: none;
    text-align: center;
    position: absolute;
    background: transparent;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.6);
    -webkit-box-shadow: none;
    box-shadow: none;
    -webkit-border-radius: 0;
    border-radius: 0;
    -webkit-transition: all 0.6s cubic-bezier(0.22, 0.81, 0.01, 0.99);
    transition: all 0.6s cubic-bezier(0.22, 0.81, 0.01, 0.99);
  }

  .product_img_slide .carousel-control-next {
    top: 58%;
    left: auto;
    right: 25px;
    opacity: 1;
    width: 50px;
    bottom: auto;
    height: 50px;
    font-size: 50px;
    cursor: pointer;
    font-weight: 700;
    overflow: hidden;
    line-height: 50px;
    text-shadow: none;
    text-align: center;
    position: absolute;
    background: transparent;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.6);
    -webkit-box-shadow: none;
    box-shadow: none;
    -webkit-border-radius: 0;
    border-radius: 0;
    -webkit-transition: all 0.6s cubic-bezier(0.22, 0.81, 0.01, 0.99);
    transition: all 0.6s cubic-bezier(0.22, 0.81, 0.01, 0.99);
  }

  .product_img_slide .carousel-control-next:hover, .product_img_slide .carousel-control-prev:hover {
    color: #c13c3d;
    background: transparent;
  }

ここでは、画像サムネイルをカルーセルのインジケーターとして表示するためのyii\bootstrap5\Carouselの拡張であるカルーセルウィジェットを示します。

ウィジェットコードを以下に示します。

<?php
namespace app\widgets;
use Yii;
use yii\bootstrap5\Html;

class Carousel extends \yii\bootstrap5\Carousel
{
    public $thumbnails = [];

    public function init()
    {
        parent::init();     
        Html::addCssClass($this->options, ['data-bs-ride' => 'carousel']);
        if ($this->crossfade) {
            Html::addCssClass($this->options, ['animation' => 'carousel-fade']);
        }
    }

    public function renderIndicators(): string
    {
        if ($this->showIndicators === false){
            return '';
        }
        $indicators = [];
        for ($i = 0, $count = count($this->items); $i < $count; $i++){
            $options = [
                'data' => [
                    'bs-target' => '#' . $this->options['id'],
                    'bs-slide-to' => $i
                ],
                'type' => 'button',
                'thumb' => $this->thumbnails[$i]['thumb']
            ];
            if ($i === 0){
                Html::addCssClass($options, ['activate' => 'active']);
                $options['aria']['current'] = 'true';
            }       

             $indicators[] = Html::tag('li',Html::img($options['thumb']), $options);
        }
        return Html::tag('ol', implode("\n", $indicators), ['class' => ['carousel-indicators']]);
    } }

上記のウィジェットをビューファイルで次のように使用できます。

    <?php  
$indicators = [
   '0' =>[ 'thumb' => "https://placehold.co/150X150?text=A"],
   '1' => ['thumb' => 'https://placehold.co/150X150?text=B'],
   '2' => [ 'thumb' => 'https://placehold.co/150X150?text=C']
];
$items = [
    [ 'content' =>Html::img('https://live.staticflickr.com/8333/8417172316_c44629715e_w.jpg')],
    [ 'content' =>Html::img('https://live.staticflickr.com/3812/9428789546_3a6ba98c49_w.jpg')],
    [ 'content' =>Html::img('https://live.staticflickr.com/8514/8468174902_a8b505a063_w.jpg')]   
];

echo Carousel::widget([
    'items' => 
        $items,
     'thumbnails'  => $indicators,
     'options' => [       
          'data-interval' => 3, 'data-bs-ride' => 'scroll','class' => 'carousel product_img_slide',
      ],

]);
]]>
0
[wiki] メニューにドロップダウン言語ピッカー(i18n)を追加する方法 2023年12月16日 土曜日 15:42:40 +0000 https://yii.dokyumento.jp/wiki/2577/how-to-add-a-dropdown-language-picker-i18n-to-the-menuhttps://yii.dokyumento.jp/wiki/2577/how-to-add-a-dropdown-language-picker-i18n-to-the-menu JQL JQL

Yii2のナビゲーションバーメニューに国際化を追加する方法

  1. 必要なファイルを作成する
  2. /config/web.phpファイルの編集
  3. "views"フォルダとそのサブフォルダ内のすべてのファイルの編集
  4. 翻訳するテキストの作成
  5. 言語を変更するためのメニュー項目(ドロップダウン)を作成する
  6. オプション項目

Yiiには、すぐに使える国際化(i18n)機能があります。マニュアルには、Yiiでi18nを使用するための設定方法に関する指示がありますが、bootstrapメニューに完全に統合する方法に関する情報はほとんどありません。このドキュメントでは、それを改善しようとします。

Screenshot_i18n_s.png

GitHubリポジトリには、言語フラグ、国旗の一部、言語コードとその言語名のリスト、Yiiがすぐに認識する言語のリストも含まれています。YouTubeに動画を近日公開予定です。

システムがi18nを使用するように設定されていることを確認してください。Yii2マニュアルより

YiiはPHP intl拡張機能を使用して、yii\i18n\Formatterクラスの日付と数値のフォーマット、およびyii\i18n\MessageFormatterを使用したメッセージのフォーマットなど、ほとんどのI18N機能を提供しています。両方のクラスは、intl拡張機能がインストールされていない場合にフォールバックメカニズムを提供します。ただし、フォールバック実装は、英語のターゲット言語でのみ適切に機能します。そのため、I18Nが必要な場合は、intlをインストールすることを強くお勧めします。

必要なファイルを作成する

最初に、設定ファイルを作成する必要があります。

保存場所を決定します(例:./messages/ディレクトリにcreate_i18n.phpという名前で)。プロジェクト内にディレクトリを作成し、プロジェクトのルートディレクトリから**ターミナル**(Windows:CMD)で次のコマンドを実行します。

./yii message/config-template ./messages/create_i18n.php

または、より詳細な制御のために

./yii message/config --languages=en-US --sourcePath=@app --messagePath=messages ./messages/create_i18n.php

新しく作成されたファイルで、翻訳する言語の配列を変更(または作成)します。

  // array, required, list of language codes that the extracted messages
  // should be translated to. For example, ['zh-CN', 'de'].
  'languages' => [
    'en-US',
    'fr',
    'pt'
  ],

必要に応じて、create_i18n.phpのルートディレクトリをmessagesディレクトリを指すように変更します - デフォルトはmessagesです。注記、上記のファイルがmessagesディレクトリにある場合(推奨)、この'messagePath' => __DIR__,を変更しないでください。messagesのディレクトリを、例えば/config/に変更する場合(良い考えではありません)、以下を使用できます。

  // Root directory containing message translations.
  'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'config',

必要な言語を編集した後、作成されたファイルは次のようになります。

<?php

return [
  // string, required, root directory of all source files
  'sourcePath' => __DIR__ . DIRECTORY_SEPARATOR . '..',
  // array, required, list of language codes (in alphabetical order) that the extracted messages
  // should be translated to. For example, ['zh-CN', 'de'].
  'languages' => [
    // to localise a particular language use the language code followed by the dialect in CAPS
    'en-US',  // USA English
    'es',
    'fr',
    'it',
    'pt',
  ],
  /* 'languages' => [
    'af', 'ar', 'az', 'be', 'bg', 'bs', 'ca', 'cs', 'da', 'de', 'el', 'es', 'et', 'fa', 'fi', 'fr', 'he', 'hi',
    'pt-BR', 'ro', 'hr', 'hu', 'hy', 'id', 'it', 'ja', 'ka', 'kk', 'ko', 'kz', 'lt', 'lv', 'ms', 'nb-NO', 'nl',
    'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi', 'zh-CN',
    'zh-TW'
    ], */
  // string, the name of the function for translating messages.
  // Defaults to 'Yii::t'. This is used as a mark to find the messages to be
  // translated. You may use a string for single function name or an array for
  // multiple function names.
  'translator' => ['\Yii::t', 'Yii::t'],
  // boolean, whether to sort messages by keys when merging new messages
  // with the existing ones. Defaults to false, which means the new (untranslated)
  // messages will be separated from the old (translated) ones.
  'sort' => false,
  // boolean, whether to remove messages that no longer appear in the source code.
  // Defaults to false, which means these messages will NOT be removed.
  'removeUnused' => false,
  // boolean, whether to mark messages that no longer appear in the source code.
  // Defaults to true, which means each of these messages will be enclosed with a pair of '@@' marks.
  'markUnused' => true,
  // array, list of patterns that specify which files (not directories) should be processed.
  // If empty or not set, all files will be processed.
  // See helpers/FileHelper::findFiles() for pattern matching rules.
  // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed.
  'only' => ['*.php'],
  // array, list of patterns that specify which files/directories should NOT be processed.
  // If empty or not set, all files/directories will be processed.
  // See helpers/FileHelper::findFiles() for pattern matching rules.
  // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed.
  'except' => [
    '.*',
    '/.*',
    '/messages',
    '/migrations',
    '/tests',
    '/runtime',
    '/vendor',
    '/BaseYii.php',
  ],
  // 'php' output format is for saving messages to php files.
  'format' => 'php',
  // Root directory containing message translations.
  'messagePath' => __DIR__,
  // boolean, whether the message file should be overwritten with the merged messages
  'overwrite' => true,
  /*
    // File header used in generated messages files
    'phpFileHeader' => '',
    // PHPDoc used for array of messages with generated messages files
    'phpDocBlock' => null,
   */

  /*
    // Message categories to ignore
    'ignoreCategories' => [
    'yii',
    ],
   */

  /*
    // 'db' output format is for saving messages to database.
    'format' => 'db',
    // Connection component to use. Optional.
    'db' => 'db',
    // Custom source message table. Optional.
    // 'sourceMessageTable' => '{{%source_message}}',
    // Custom name for translation message table. Optional.
    // 'messageTable' => '{{%message}}',
   */

  /*
    // 'po' output format is for saving messages to gettext po files.
    'format' => 'po',
    // Root directory containing message translations.
    'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages',
    // Name of the file that will be used for translations.
    'catalog' => 'messages',
    // boolean, whether the message file should be overwritten with the merged messages
    'overwrite' => true,
   */
];

/config/web.phpファイルの編集

web.phpファイルの'id' => 'basic',の下に以下を追加します。

  'language' => 'en',
  'sourceLanguage' => 'en',

注記:通常、英語から他の言語に翻訳する方が簡単で安価なため、常に'sourceLanguage' => 'en'を使用する必要があります。sourceLanguageが設定されていない場合、デフォルトは'en'になります。

'components' => [...]セクションに以下を追加します。

    'i18n' => [
      'translations' => [
        'app*' => [
          'class' => 'yii\i18n\PhpMessageSource',  // Using text files (usually faster) for the translations
          //'basePath' => '@app/messages',  // Uncomment and change this if your folder is not called 'messages'
          'sourceLanguage' => 'en',
          'fileMap' => [
            'app' => 'app.php',
            'app/error' => 'error.php',
          ],
          //  Comment out in production version
          //  'on missingTranslation' => ['app\components\TranslationEventHandler', 'handleMissingTranslation'],
        ],
      ],
    ],

"views"フォルダとそのサブフォルダ内のすべてのファイルの編集

次に、ビューファイルで翻訳するテキストをYiiに指示します。これは、コードにYii::t('app', '翻訳するテキスト')を追加することで行います。

例として、/views/layouts/main.phpで、メニューラベルを次のように変更します。

    'items' => [
          //  ['label' => 'Home', 'url' => ['/site/index']],	// Orignal code
          ['label' => Yii::t('app', 'Home'), 'url' => ['/site/index']],
          ['label' => Yii::t('app', 'About'), 'url' => ['/site/about']],
          ['label' => Yii::t('app', 'Contact'), 'url' => ['/site/contact']],
          Yii::$app->user->isGuest ? ['label' => Yii::t('app', 'Login'), 'url' => ['/site/login']] : '<li class="nav-item">'
            . Html::beginForm(['/site/logout'])
            . Html::submitButton(
             // 'Logout (' . Yii::$app->user->identity->username . ')', // change this line as well to the following:
              Yii::t('app', 'Logout ({username})'), ['username' => Yii::$app->user->identity->username]),
              ['class' => 'nav-link btn btn-link logout']
            )
            . Html::endForm()
            . '</li>',
        ],

翻訳するテキストの作成

翻訳ファイルを作成するには、プロジェクトのルートディレクトリから**ターミナル**で次のコマンドを実行します。

./yii message ./messages/create_i18n.php

次に、メッセージを翻訳します。たとえば、フランス語の/messages/fr/app.phpでは

  'Home' => 'Accueil',
  'About' => 'À propos',
  ...

言語を変更するためのメニュー項目(ドロップダウン)を作成する

これはいくつかの手順を踏みます。

1. 必要な言語の配列を作成する

各言語にはキー名前が必要です。

キーは、小文字のICU言語コードISO 639.1(オプションでISO 3166の大文字の国コード)です。例:

フランス語:frまたはカナダフランス語:fr-CA

ポルトガル語:ptまたはブラジルポルトガル語:pt-BR

名前はその言語での言語名です。例:フランス語の場合'Français'、日本語の場合'日本語'。ユーザーはブラウザの現在の言語を理解していない可能性があるため、これは重要です

/config/params.phpで、必要な言語を含むlanguagesという名前の配列を作成します。例:

  /* 		List of languages and their codes
   *
   * 		format:
   * 		'Language Code' => 'Language Name',
   * 		e.g.
   * 		'fr' => 'Français',
   *
   * 		please use alphabetical order of language code
   * 		Use the language name in the "user's" Language
   *            e.g.
   *            'ja' => '日本の',
   */
  'languages' => [
//    'da' => 'Danske',
//    'de' => 'Deutsche',
//    'en' => 'English', // NOT REQUIRED the sourceLanguage (i.e. the default)
    'en-GB' => 'British English',
    'en-US' => 'American English',
    'es' => 'Español',
    'fr' => 'Français',
    'it' => 'Italiano',
//    'ja' => '日本の',  // Japanese with the word "Japanese" in Kanji
//    'nl' => 'Nederlandse',
//    'no' => 'Norsk',
//    'pl' => 'Polski',
    'pt' => 'Português',
//    'ru' => 'Русский',
//    'sw' => 'Svensk',
//    'zh' => '中国的',
  ],
2. アクションを作成する

デフォルトコントローラーである/controllers/SiteController.phpに、actionLanguage()という名前のアクションを追加します。このアクションは言語を変更し、ブラウザがページリクエストとサイトへの再訪問で言語を「記憶」するようにCookieを設定します。

  /**
   * Called by the ajax handler to change the language and
   * Sets a cookie based on the language selected
   *
   */
  public function actionLanguage()
  {
    $lang = Yii::$app->request->post('lang');
    // If the language "key" is not NULL and exists in the languages array in params.php, change the language and set the cookie
    if ($lang !== NULL && array_key_exists($lang, Yii::$app->params['languages']))
    {
      $expire = time() + (60 * 60 * 24 * 365); //  1 year - alter accordingly
      Yii::$app->language = $lang;
      $cookie = new yii\web\Cookie([
        'name' => 'lang',
        'value' => $lang,
        'expire' => $expire,
      ]);
      Yii::$app->getResponse()->getCookies()->add($cookie);
    }
    Yii::$app->end();
  }

メソッドをPOSTに設定することを忘れないでください。behaviors()内のactionsで、次のように'language' => ['post'],を設定します。

      'verbs' => [
        'class' => VerbFilter::class,
        'actions' => [
          'logout' => ['post'],
          'language' => ['post'],
        ],
      ],
3. 言語ハンドラーの作成

各リクエストに対して正しい言語が提供されることを確認してください。

/components/ ディレクトリに、LanguageHandler.phpという名前のファイルを作成し、次のコードを追加します。

<?php

/*
 * Copyright ©2023 JQL all rights reserved.
 * http://www.jql.co.uk
 */
/*
  Created on : 19-Nov-2023, 13:23:54
  Author     : John Lavelle
  Title      : LanguageHandler
 */

namespace app\components;

use yii\helpers\Html;

class LanguageHandler extends \yii\base\Behavior
{

	public function events()
	{
		return [\yii\web\Application::EVENT_BEFORE_REQUEST => 'handleBeginRequest'];
	}

	public function handleBeginRequest($event)
	{
		if (\Yii::$app->getRequest()->getCookies()->has('lang') && array_key_exists(\Yii::$app->getRequest()->getCookies()->getValue('lang'), \Yii::$app->params['languages']))
		{
      //  Get the language from the cookie if set
			\Yii::$app->language = \Yii::$app->getRequest()->getCookies()->getValue('lang');
		}
		else
		{
			//	Use the browser language - note: some systems use an underscore, if used, change it to a hyphen
			\Yii::$app->language = str_replace('_', '-', HTML::encode(locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE'])));
		}
	}

}

/* End of file LanguageHandler.php */
/* Location: ./components/LanguageHandler.php */
4. /config/web.phpからLanguageHandler.phpを呼び出す

'params' => $params,の直上または直下に次の行を追加することで、/config/web.phpからLanguageHandler.phpファイルを「呼び出します」。

  //	Update the language on selection
  'as beforeRequest' => [
    'class' => 'app\components\LanguageHandler',
  ],
5. /views/layouts/main.phpに言語メニュー項目を追加する

main.phpはBootstrapを使用してメニューを作成します。ユーザーが言語を選択できるように、メニューに項目(ドロップダウン)を追加する必要があります。

main.phpの「uses」セクションにuse yii\helpers\Url;を追加します。

echo Nav::widget([...])の直上に、次のコードを追加します。

// Get the languages and their keys, also the current route
      foreach (Yii::$app->params['languages'] as $key => $language)
      {
        $items[] = [
          'label' => $language, // Language name in it's language - already translated
          'url' => Url::to(['site/index']), // Route
          'linkOptions' => ['id' => $key, 'class' => 'language'], // The language "key"
        ];
      }

次のセクション

echo Nav::widget([...])`

'options' => ['class' => 'navbar-nav ms-auto'], // ms-auto aligns the menu right`

の間

'items' => [...]

'encodeLabels' => false, // Required to enter HTML into the labels

次のように追加します。

      echo Nav::widget([
        'options' => ['class' => 'navbar-nav ms-auto'], // ms-auto aligns the menu right
        'encodeLabels' => false, // Required to enter HTML into the labels
        'items' => [
          ['label' => Yii::t('app', 'Home'), 'url' => ['/site/index']],
        ...

次に、ドロップダウンを追加します。これは'items' => [...]内の任意の場所に配置できます。

// Dropdown Nav Menu: https://yii.dokyumento.jp/doc/api/2.0/yii-widgets-menu
        [
          'label' => Yii::t('app', 'Language')),
          'url' => ['#'],
          'options' => ['class' => 'language', 'id' => 'languageTop'],
          'encodeLabels' => false, // Optional but required to enter HTML into the labels for images
          'items' => $items, // add the languages into the Dropdown
        ],

NavBarのmain.phpのコードは、次のようになります。

      NavBar::begin([
        'brandLabel' => Yii::$app->name,  // set in /config/web.php
        'brandUrl' => Yii::$app->homeUrl,
        'options' => ['class' => 'navbar-expand-md navbar-dark bg-dark fixed-top']
      ]);
      // Get the languages and their keys, also the current route
      foreach (Yii::$app->params['languages'] as $key => $language)
      {
        $items[] = [
          'label' => $language, // Language name in it's language
          'url' => Url::to(['site/index']), // Current route so the page refreshes
          'linkOptions' => ['id' => $key, 'class' => 'language'], // The language key
        ];
      }
      echo Nav::widget([
        'options' => ['class' => 'navbar-nav ms-auto'], // ms-auto aligns the menu right
        'encodeLabels' => false, // Required to enter HTML into the labels
        'items' => [
          ['label' => Yii::t('app', 'Home'), 'url' => ['/site/index']],
          ['label' => Yii::t('app', 'About'), 'url' => ['/site/about']],
          ['label' => Yii::t('app', 'Contact'), 'url' => ['/site/contact']],
          // Dropdown Nav Menu: https://yii.dokyumento.jp/doc/api/2.0/yii-widgets-menu
          [
            'label' => Yii::t('app', 'Language') ,
            'url' => ['#'],
            'options' => ['class' => 'language', 'id' => 'languageTop'],
            'encodeLabels' => false, // Required to enter HTML into the labels
            'items' => $items, // add the languages into the Dropdown
          ],
          Yii::$app->user->isGuest ? ['label' => Yii::t('app', 'Login'), 'url' => ['/site/login']] : '<li class="nav-item">'
            . Html::beginForm(['/site/logout'])
            . Html::submitButton(
//              'Logout (' . Yii::$app->user->identity->username . ')',
              Yii::t('app', 'Logout ({username})', ['username' => Yii::$app->user->identity->username]),
              ['class' => 'nav-link btn btn-link logout']
            )
            . Html::endForm()
            . '</li>',
        ],
      ]);
      NavBar::end();

言語フラグや画像を言語名の横に表示する必要がある場合は、このドキュメントの最後に記載されている「オプション項目」を参照してください。

6. Ajax呼び出しで言語の変更をトリガーする

言語アクションactionLanguage()を呼び出すには、JavaScriptファイルでAjax呼び出しを行います。

/web/js/language.jsという名前のファイルを作成します。

ファイルに次のコードを追加します。

/*
 * Copyright ©2023 JQL all rights reserved.
 * http://www.jql.co.uk
 */

/**
 * Set the language
 *
 * @returns {undefined}
 */
$(function () {
  $(document).on('click', '.language', function (event) {
    event.preventDefault();
    let lang = $(this).attr('id');  // Get the language key
    /* if not the top level, set the language and reload the page */
    if (lang !== 'languageTop') {
      $.post(document.location.origin + '/site/language', {'lang': lang}, function (data) {
        location.reload(true);
      });
    }
  });
});

JavaScriptファイルをアセットに追加するには、プロジェクトディレクトリの/assets/AppAsset.phpを変更します。public $js = []'js/language.js'を追加します。次のようになります。

     public $js = [
       'js/language.js',
     ];

これで、プロジェクトで国際化が機能するはずです。

オプション項目

以下はオプションですが、ユーザーと開発者の両方にとって役立つ場合があります。

1. 翻訳の確認

Yiiは、Yii::t('app', '翻訳するテキスト')ブロック内の特定のテキストに翻訳が存在するかどうかを確認できます。

2つの手順があります。

**A.** /config/web.phpで次の行のコメントを外します。

  //  'on missingTranslation' => ['app\components\TranslationEventHandler', 'handleMissingTranslation'],

**B.** TranslationEventHandlerを作成します。

/components/に、TranslationEventHandler.phpという名前のファイルを作成し、次のコードを追加します。


<?php

/**
 * TranslationEventHandler
 *
 * @copyright © 2023, John Lavelle  Created on : 14 Nov 2023, 16:05:32
 *
 *
 * Author     : John Lavelle
 * Title      : TranslationEventHandler
 */
// Change the Namespace (app, frontend, backend, console etc.) if necessary (default in Yii Basic is "app").

namespace app\components;

use yii\i18n\MissingTranslationEvent;

/**
 * TranslationEventHandler
 *
 *
 * @author John Lavelle
 * @since 1.0 // Update version number
 */
class TranslationEventHandler
{

  /**
   * Adds a message to missing translations in Development Environment only
   *
   * @param MissingTranslationEvent $event
   */
  public static function handleMissingTranslation(MissingTranslationEvent $event)
  {
    // Only check in the development environment
    if (YII_ENV_DEV)
    {
      $event->translatedMessage = "@MISSING: {$event->category}.{$event->message} FOR LANGUAGE {$event->language} @";
    }
  }
}

翻訳がない場合、テキストは次のようなメッセージに置き換えられます。

@MISSING: app.Logout (John) FOR LANGUAGE fr @

ここでは、Yiiはフランス語の翻訳が

Yii::t('app', 'Logout ({username})', ['username' => Yii::$app->user->identity->username]),
2. ドロップダウンメニューに言語フラグを追加する ¶a

これは非常に役立つ推奨事項であり、ユーザーが正しい言語を見つけるのに役立ちます。これにはいくつかの手順があります。

**a.** フラグの画像を作成します。

画像は幅25px、高さ15pxである必要があります。画像は、params.phpの言語配列内の言語キーと同じ名前である**必要があります**。たとえば、fr.pngまたはen-US.pngです。画像の種類が「.png」でない場合は、以下の**b.**の手順でコードを正しいファイル拡張子に変更してください。

画像は/web/images/flags/ディレクトリに配置します。

**b.** /views/layouts/main.phpのコードを次のように変更します。

<header id="header">
      <?php
      NavBar::begin([
        'brandLabel' => Yii::$app->name,
        'brandUrl' => Yii::$app->homeUrl,
        'options' => ['class' => 'navbar-expand-md navbar-dark bg-dark fixed-top']
      ]);
      // Get the languages and their keys, also the current route
      foreach (Yii::$app->params['languages'] as $key => $language)
      {
        $items[] = [
	// Display the image before the language name
          'label' => Html::img('/images/flags/' . $key . '.png', ['alt' => 'flag ' . $language, 'class' => 'inline-block align-middle', 'title' => $language,]) . ' ' . $language, // Language name in it's language
          'url' => Url::to(['site/index']), // Route
          'linkOptions' => ['id' => $key, 'class' => 'language'], // The language key
        ];
      }
      echo Nav::widget([
        'options' => ['class' => 'navbar-nav ms-auto'], // ms-auto aligns the menu right
        'encodeLabels' => false, // Required to enter HTML into the labels
        'items' => [
          ['label' => Yii::t('app', 'Home'), 'url' => ['/site/index']],
          ['label' => Yii::t('app', 'About'), 'url' => ['/site/about']],
          ['label' => Yii::t('app', 'Contact'), 'url' => ['/site/contact']],
          // Dropdown Nav Menu: https://yii.dokyumento.jp/doc/api/2.0/yii-widgets-menu
          [
	  // Display the current language "flag" after the Dropdown title (before the caret)
            'label' => Yii::t('app', 'Language') . ' ' . Html::img('@web/images/flags/' . Yii::$app->language . '.png', ['class' => 'inline-block align-middle', 'title' => Yii::$app->language]),
            'url' => ['#'],
            'options' => ['class' => 'language', 'id' => 'languageTop'],
            'encodeLabels' => false, // Required to enter HTML into the labels
            'items' => $items, // add the languages into the Dropdown
          ],
          Yii::$app->user->isGuest ? ['label' => Yii::t('app', 'Login'), 'url' => ['/site/login']] : '<li class="nav-item">'
            . Html::beginForm(['/site/logout'])
            . Html::submitButton(
//              'Logout (' . Yii::$app->user->identity->username . ')',
              Yii::t('app', 'Logout ({username})', ['username' => Yii::$app->user->identity->username]),
              ['class' => 'nav-link btn btn-link logout']
            )
            . Html::endForm()
            . '</li>',
        ],
      ]);
      NavBar::end();
      ?>
    </header>

以上です!楽しんでください…

詳細については、以下を参照してください。

Github の i18ntutorial

Yii2 国際化チュートリアル

PHP intl 拡張機能

このコードを使用する場合は、次のようにクレジットしてください。

国際化 (i18n) メニューコードを提供:JQL、https://visualaccounts.co.uk ©2023 JQL

ライセンス(BSD-3-Clause ライセンス)

著作権表示

国際化 (i18n) メニューコードを提供:JQL、https://visualaccounts.co.uk ©2023 JQL 無断複製を禁じます

ソースおよびバイナリ形式での再配布と使用は、以下の条件を満たす場合に限り許可されます。

ソースコードの再配布には、上記の著作権表示、この条件リスト、および以下の免責事項を保持する必要があります。

バイナリ形式での再配布には、ドキュメントおよび/または配布物に含まれるその他の資料に、上記の著作権表示、この条件リスト、および以下の免責事項を複製する必要があります。

John Lavelle、JQL、Visual Accounts、およびその貢献者の名前は、このソフトウェアから派生した製品を推奨または宣伝するために、特別な書面による許可なしに使用することはできません。

「JQL のすべてのコードとソフトウェア(およびその作成者のものも含む)は、いかなる種類の保証もなく「現状のまま」提供されます。法律で許可される最大限の範囲で、作成者と発行者およびその代理人は、明示的または黙示的を問わず、商品性および特定の目的への適合性の黙示的な保証を含むがこれらに限定されないすべての保証を明示的に否認します。コードに関して、作成者と発行者およびその代理人は、コードの使用から直接的または間接的に生じるいかなる損失または損害についても、作成者および/または発行者とその代理人がそのような損害の可能性について知らされていた場合であっても、責任を負いません。前述を制限することなく、作成者と発行者およびその代理人は、利益の損失、業務の中断、機器またはデータの損害、業務の中断、または直接的、間接的、特別、偶発的、結果的、その他の損害を含むがこれらに限定されないその他の商業的損害について責任を負いません。」

]]>
0
[拡張機能] slideradmin 2023年11月21日(火) 11:20:25 +0000 https://yii.dokyumento.jp/extension/slideradminhttps://yii.dokyumento.jp/extension/slideradmin pravi pravi

これは、yii2 基本アプリケーションテンプレートを使用して作成されたアプリケーションテンプレートであり、私の拡張機能 slideradmin の使用方法を示しています。

インストール

  1. Github からリポジトリをダウンロードし、その内容を任意のフォルダに展開します。
  2. composer update コマンドを実行します。
  3. マイグレーションコマンドを実行します:php yii migrate --migrationPath="@vendor/siripravi/yii2-slideradmin/migrations"
  4. 完了。
]]>
0
[拡張機能] nicksdr/nkchartjs 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/extension/nicksdr/nkchartjshttps://yii.dokyumento.jp/extension/nicksdr/nkchartjs CarlosQS CarlosQS

nkchartjs

]]>
0
[wiki] 正規表現を使用したバリデータの作成と使用方法 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/wiki/2575/how-to-create-and-use-validator-using-regular-expressionshttps://yii.dokyumento.jp/wiki/2575/how-to-create-and-use-validator-using-regular-expressions aayushmhu aayushmhu

バリデータを作成する方法は複数ありますが、ここでは正規表現またはJavaScript正規表現またはRegExpを使用してバリデータを作成します。この記事では、最も頻繁に使用される式について説明します。

**手順1:** 以下のように、またはValidatorのように、バリデータ用の新しいクラスを作成します。

最初の例である10桁の電話番号の検証を参照してください。

<?php

namespace common\validators;

use yii\validators\Validator;

class MobileValidator extends Validator {

    public function validateAttribute($model, $attribute) {
        if (isset($model->$attribute) and $model->$attribute != '') {
             if (!preg_match('/^[123456789]\d{9}$/', $model->$attribute)) {
                $this->addError($model, $attribute, 'In Valid Mobile / Phone number');
            }
        }
    }

}

ここでは、必要に応じてさまざまな正規表現を記述できます。`php preg_match('/^[123456789]\d{9}$/', $model-> $attribute) `

**手順2:** バリデータの使用方法

バリデータの使用方法をご存知の方も多いと思いますが、ここでは使用方法の例を示します。

モデルクラスに新しいルールを追加します。`php [['mobile'],\common\validators\MobileValidator::class], [['mobile'], 'string', 'max' => 10],


So It's Very Simple to use a Custom Validator.


As I Told you Earlier that i show you some more Example for Using Regular Expression  Validator Just Replace these string in preg_match.

1. Aadhar Number Validator
```php
preg_match('/^[2-9]{1}[0-9]{3}[0-9]{4}[0-9]{4}$/', $model->$attribute)
  1. 銀行口座番号バリデータ `php preg_match("/^[0-9]{9,18}+$/", $model-> $attribute) `

  2. 銀行IFSCコードバリデータ `php preg_match("/^[A-Z]{4}0[A-Z0-9]{6}$/", $model-> $attribute) `

  3. パンカード番号バリデータ `php preg_match('/^([a-zA-Z]){5}([0-9]){4}([a-zA-Z]){1}?$/', $model-> $attribute) `

  4. 郵便番号バリデータ `php preg_match('/^[0-9]{6}+$/', $model-> $attribute) `

  5. GSTINバリデータ `php preg_match("/^([0][1-9]|[1-2][0-9]|[3][0-5])([a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[1-9a-zA-Z]{1}[zZ]{1}[0-9a-zA-Z]{1})+$/", $model-> $attribute) `

これは他のタイプのカスタムバリデータです。

  1. 文字列の500単語バリデータ
<?php

namespace common\validators;

use yii\validators\Validator;

/**
 * Class Word500Validator
 * @author Aayush Saini <aayushsaini9999@gmail.com>
 */
class Word500Validator extends Validator
{

    public function validateAttribute($model, $attribute)
    {
        if ($model->$attribute != '') {
            if (str_word_count($model->$attribute) > 500) {
                $this->addError($model, $attribute, $model->getAttributeLabel($attribute) . ' length can not exceeded 500 words.');
                \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
                return $model->errors;
            }
        }
    }
}

この記事を読んだ後、必要に応じてあらゆる種類のバリデータを作成できるようになっていると想定しています。

:) ご覧いただきありがとうございます。

]]>
0
[wiki] GridViewでフッターに列の合計を表示する。 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/wiki/2574/gridview-show-sum-of-columns-in-footerhttps://yii.dokyumento.jp/wiki/2574/gridview-show-sum-of-columns-in-footer shivam4u shivam4u

GridViewでフッターに列の合計を表示する `PHP use yii\grid\DataColumn;

/**

  • 列のすべての値の合計
  • @author shiv / class TSumColumn extends DataColumn { public function getDataCellValue($model, $key, $index) {

     $value = parent::getDataCellValue($model, $key, $index);
     if ( is_numeric($value))
     {
         $this->footer += $value;
     }
        
     return $value;
    

    } } `

GridViewでフッターを有効にする必要があります。

echo GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'showFooter' => true,

また、列クラスを変更します。

            [
                'class' => TSumColumn::class,
                'attribute' => 'amount'
            ],

グリッドのフッターに合計が表示されます。必要に応じて複数の列に適用できます。

]]>
0
[wiki] JSONデータをHTMLテーブルに変換してページに表示する 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/wiki/2573/convert-json-data-to-html-table-for-display-on-pagehttps://yii.dokyumento.jp/wiki/2573/convert-json-data-to-html-table-for-display-on-page shivam4u shivam4u

JSONをHTMLテーブルに直接表示するのに役立つ呼び出しがあります。

Json2Table::formatContent($json);

Json2Tableクラスのコードを次に示します。

============================================

/**
 * Class convert Json to html table. It help view json data directly.
 * @author shiv
 *
 */
class Json2Table
{

    public static function formatContent($content, $class = 'table table-bordered')
    {
        $html = "";
        if ($content != null) {
            $arr = json_decode(strip_tags($content), true);
            
            if ($arr && is_array($arr)) {
                $html .= self::arrayToHtmlTableRecursive($arr, $class);
            }
        }
        return $html;
    }

    public static function arrayToHtmlTableRecursive($arr, $class = 'table table-bordered')
    {
        $str = "<table class='$class'><tbody>";
        foreach ($arr as $key => $val) {
            $str .= "<tr>";
            $str .= "<td>$key</td>";
            $str .= "<td>";
            if (is_array($val)) {
                if (! empty($val)) {
                    $str .= self::arrayToHtmlTableRecursive($val, $class);
                }
            } else {
                $val = nl2br($val);
                $str .= "<strong>$val</strong>";
            }
            $str .= "</td></tr>";
        }
        $str .= "</tbody></table>";
        
        return $str;
    }
}
]]>
0
[wiki] アドハー番号バリデータ 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/wiki/2572/aadhar-number-validatorhttps://yii.dokyumento.jp/wiki/2572/aadhar-number-validator shivam4u shivam4u

インドにはアドハー番号があり、入力として検証する必要がある場合があります。そこで、yii2用のバリデータを作成しました。

use yii\validators\Validator;

class TAadharNumberValidator extends Validator
{

    public $regExPattern = '/^\d{4}\s\d{4}\s\d{4}$/';

    public function validateAttribute($model, $attribute)
    {
        if (preg_match($this->regExPattern, $model->$attribute)) {
            $model->addError($attribute, 'Not valid Aadhar Card Number');
        }
    }
}
]]>
0
[wiki] YII2の面接質問 2023年11月1日(水) 06:05:47 +0000 https://yii.dokyumento.jp/wiki/2570/interview-questions-for-yii2https://yii.dokyumento.jp/wiki/2570/interview-questions-for-yii2 aayushmhu aayushmhu

皆さん、こんにちは。この記事では、YII2の面接で面接官が最もよく尋ねる質問について、私の経験を共有しました。

  1. アクティブレコードとは何ですか?そして、どのように使用しますか?
  2. コンポーネントとは何ですか?
  3. ヘルパー関数とは何ですか?
  4. データモデルを更新するにはどうすればよいですか?
  5. 認証と認可の違いは何ですか?
  6. ウェブサイトの速度を上げるにはどうすればよいですか?
  7. GIIとは何ですか?または、GIIモジュールを使用しますか?
  8. YIIとYII2の違いは何ですか?
  9. 複数のデータベースを使用するにはどうすればよいですか?
  10. テーマをウェブサイトに統合するにはどうすればよいですか?
  11. OOPSとは何ですか?
  12. PHPのfinalクラスとは何ですか?
  13. 抽象クラスとは何ですか?
  14. 継承とは何ですか?
  15. インターフェースとは何ですか?
  16. JavaScriptとJQueryの知識はありますか?
  17. トレイトとは何ですか?
  18. ブートストラップとは何ですか?
  19. YII2の基本と高度版の違いは何ですか?
  20. YII2をマイクロフレームワークとして使用するにはどうすればよいですか?
  21. REST APIとは何ですか?YII2で記述するにはどうすればよいですか?
  22. YII2プロジェクトのディレクトリ構造は?
  23. render、renderFile、renderPartial、renderAjax、renderContentの違いは?

これらは、面接を受ける際に面接官があなたに尋ねることができる最も一般的な質問です。

他に質問があれば、コメントで共有してください!!!!

]]>
0
[wiki] Yii2フレームワークでGmail SMTP経由でメールを送信する方法 2021年8月4日(水) 13:00:37 +0000 https://yii.dokyumento.jp/wiki/2569/how-to-send-email-via-gmail-smtp-in-yii2-frameworkhttps://yii.dokyumento.jp/wiki/2569/how-to-send-email-via-gmail-smtp-in-yii2-framework PELock PELock
  1. Gmailがドメインのブロックを解除してくれません…Googleさんありがとう
  2. @gmail.comの受信箱にメールを送信するにはどうすればよいですか?
  3. 1. ヘルパー@gmail.comアカウントを設定する
  4. 2. 設定ファイルにカスタムコンポーネントを追加する
  5. 3. ヘルパー関数を追加する
  6. 4. 使用方法
  7. 5. 制限事項を知る
  8. 6. Gmailはあなたの味方ではありません

私のサイトの1つがスパムボットで溢れかえっており、その結果、Gmailから私のメールドメインに悪いスコアが付けられ、@gmailアドレスにメールを送信できなくなりました。私のメールからでも、私のシステムからでも、私がホストしている他のドメインやウェブサイトからでも送信できませんでした…

Gmailがドメインのブロックを解除してくれません…Googleさんありがとう

私は1つのサイトからすべてのスパムボットの活動を削除し、Gmailサポートフォーラムを通じて決定への異議を申し立てましたが、それでも@gmail.comのメールボックスを持つ顧客と連絡を取ることができず、ドメインのスコアを元の状態に戻す方法がないようです。

ほぼ2週間経ちましたが、私のドメインのスコアはhttps://postmaster.google.com/悪いままです。

Googleさん、ありがとうございます :(

@gmail.comの受信箱にメールを送信するにはどうすればよいですか?

その結果、購入通知、ライセンス期限切れ通知、その他の通知を顧客に送信する方法を考え出す必要がありました。

私はPHPのYii2フレームワークを使用しており、それは非常に簡単でした。

1. ヘルパー@gmail.comアカウントを設定する

通知を送信するには@gmail.comアカウントが必要です。重要なのは、アカウントを作成した後、セキュリティが低いアプリへのアクセスオプションを有効にする必要があることです。

Gmail options

これにより、Gmail SMTPサーバー経由でメールを送信できます。

2. 設定ファイルにカスタムコンポーネントを追加する

Yii2フレームワークディレクトリで、設定ファイル/common/config/Main.php(アドバンスドテーマを使用しています)を変更し、カスタムメール送信コンポーネント(任意の名前を付けることができます)を含めます。

<?php
return [
	'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',

	...

	'components' => [

		'mailerGmail' => [
			'class' => 'yii\swiftmailer\Mailer',
			'viewPath' => '@common/mail',
			'useFileTransport' => false,

			'transport' => [
				'class' => 'Swift_SmtpTransport',
				'host' => 'smtp.gmail.com',
				'username' => 'gmail.helper.account',
				'password' => 'PUT-YOUR-PASSWORD-HERE',
				'port' => '587',
				'encryption' => 'tls',
			],
		],
    ],
];

3. ヘルパー関数を追加する

私はYii::$app->Customとして登録されているコンポーネントの1つにヘルパー関数を追加しました。これは、配信メールのドメイン名に応じてデフォルトのメーラーインスタンスを返します。

また、メールに@gmail.com文字列が含まれていない場合でも、GmailのMXサーバーを使用してメール処理を行っている場合を検出するようにコードを更新しました。

検出は、PHPの組み込み関数getmxrr()を使用してドメインのメールサーバーレコードをチェックすることによって行われ、失敗した場合は、Google DNSサービスAPIにリモートGETクエリを送信してMXレコードをチェックします。

////////////////////////////////////////////////////////////////////////////////
//
// get default mailer depending on the provided email address
//
////////////////////////////////////////////////////////////////////////////////

public function getMailer($email)
{
	// detect if the email or domain is using Gmail to send emails
	if (Yii::$app->params['forwardGmail'])
	{
		// detect @gmail.com domain first
		if (str_ends_with($email, "@gmail.com"))
		{
			return Yii::$app->mailerGmail;
		}

		// extract domain name
		$parts = explode('@', $email);
		$domain = array_pop($parts);

		// check DNS using local server requests to DNS
		// if it fails query Google DNS service API (might have limits)
		if (getmxrr($domain, $mx_records))
		{
			foreach($mx_records as $record)
			{
				if (stripos($record, "google.com") !== false || stripos($record, "googlemail.com") !== false)
				{
					return Yii::$app->mailerGmail;
				}
			}

			// return default mailer (if there were records detected but NOT google)
			return Yii::$app->mailer;
		}

		// make DNS request
		$client = new Client();

		$response = $client->createRequest()
			->setMethod('GET')
			->setUrl('https://dns.google.com/resolve')
			->setData(['name' => $domain, 'type' => 'MX'])
			->setOptions([
				'timeout' => 5, // set timeout to 5 seconds for the case server is not responding
			])
			->send();

		if ($response->isOk)
		{
			$parser = new JsonParser();

			$data = $parser->parse($response);

			if ($data && array_key_exists("Answer", $data))
			{
				foreach ($data["Answer"] as $key => $value)
				{
					if (array_key_exists("name", $value) && array_key_exists("data", $value))
					{
						if (stripos($value["name"], $domain) !== false)
						{
							if (stripos($value["data"], "google.com") !== false || stripos($value["data"], "googlemail.com") !== false)
							{
								return Yii::$app->mailerGmail;
							}
						}
					}
				}
			}
		}
	}

	// return default mailer
	return Yii::$app->mailer;
}

ドメインが@gmail.comで終わっている場合、またはドメインがGmailのメールシステムを使用している場合、mailerGmailインスタンスが使用され、それ以外の場合はデフォルトのメール送信コンポーネントYii::$app->mailerが使用されます。

4. 使用方法

    /**
     * Sends an email to the specified email address using the information collected by this model.
     *
     * @return boolean whether the email was sent
     */
    public function sendEmail()
    {
		// find all active subscribers
		$message = Yii::$app->Custom->getMailer($this->email)->compose();
	
		$message->setTo([$this->email => $this->name]);
		$message->setFrom([\Yii::$app->params['supportEmail'] => "Bartosz Wójcik"]);
		$message->setSubject($this->subject);
		$message->setTextBody($this->body);
	
		$headers = $message->getSwiftMessage()->getHeaders();
	
		// message ID header (hide admin panel)
		$msgId = $headers->get('Message-ID');
		$msgId->setId(md5(time()) . '@pelock.com');
	
		$result = $message->send();
	
		return $result;
    }

5. 制限事項を知る

これは一時的な解決策であり、この方法では大量メールを送信できないことに注意する必要があります。Gmailは新しいメールボックスにもいくつかの制限を課しています。

6. Gmailはあなたの味方ではありません

ドメインがその悪評の規模に達した場合、そこから抜け出す簡単な方法はないようです。Gmailのサポートフォーラムで読んだところによると、一部の人々は1ヶ月以上待つことでGmailがドメインのブロックを解除するのを待っているものの、結果も連絡もなく待っているようです。私のドメインは他のブロックされたRBLリスト(スパムリスト)には掲載されていません。Gmailだけがブロックしていますが、Googleの影響力の大きさを理解するには十分です。Googleは、修正する機会もなく、一瞬であなたのビジネスを台無しにする可能性があります…

]]>
0
[wiki] JWT認証チュートリアル 2021年10月3日(日) 17:59:49 +0000 https://yii.dokyumento.jp/wiki/2568/jwt-authentication-tutorialhttps://yii.dokyumento.jp/wiki/2568/jwt-authentication-tutorial allanbj allanbj

JWTの実装方法

  1. JWTの概念
  2. シナリオ
  3. /auth/loginエンドポイントを介してユーザーが初めてログインする
  4. トークンの期限切れ
  5. 私のラップトップが盗まれた
  6. なぜJWTを盲目的に信頼するのですか?
  7. 実装手順
  8. 前提条件
  9. ステップバイステップの設定
  10. クライアント側の例

JWTの概念

JWTはJSON Web Tokenの略です。たとえば、セッションの代わりに、APIと通信するブラウザー内のログインを維持するために使用されます。ブラウザーセッションはCSRFセキュリティの問題に対して脆弱であるためです。JWTは、OAuth認証メカニズムを設定するよりも複雑ではありません。

この概念は2つのトークンに依存しています。

  • AccessToken - 短命のJWT(例:5分)

このトークンは\sizeg\jwt\Jwt::classを使用して生成されます。これはサーバー側に保存されません。そして、Authorizationヘッダーを介して後続のすべてのAPIリクエストで送信されます。では、ユーザーはどのように識別されるのでしょうか?JWTの内容にはユーザーIDが含まれています。この値を盲目的に信頼します。

  • RefreshToken - 長命で、データベースに保存されます。

このトークンはログイン時にのみ生成され、user_refresh_tokenテーブルに保存されます。ユーザーはデータベースに複数のRefreshTokenを持つことができます。

シナリオ

/auth/loginエンドポイントを介してユーザーが初めてログインする:

資格情報が正しい場合、actionLogin()メソッドでは2つのことが発生します。

  • JWT AccessTokenが生成され、JSONを介して返されます。サーバー側にはどこにも保存されず、ユーザーID(エンコード済み)が含まれています。
  • RefreshTokenが生成され、データベースに保存されます。JSONとして返されるのではなく、/auth/refresh-tokenパスに制限されたhttpOnlyクッキーとして返されます。

JWTはブラウザのlocalStorageに保存され、それ以降はすべてのリクエストで送信する必要があります。RefreshTokenはクッキーにありますが、(httpOnlyであるため)Javascriptを介して読み取ったり、アクセスしたり、改ざんしたりすることはできません。

トークンの期限切れ:

しばらくすると、JWTは最終的に期限切れになります。この場合、APIは401 - Unauthorizedを返す必要があります。アプリのHTTPクライアント(例:Axios)では、401ステータスを検出し、失敗したリクエストをキューに保存し、/auth/refresh-tokenエンドポイントを呼び出すインターセプターを追加します。

呼び出されると、このエンドポイントはクッキーを介してRefreshTokenを受け取ります。その後、テーブルでこれが有効なRefreshTokenかどうか、関連付けられたユーザーIDは誰かを確認し、新しいJWTを生成してJSONとして返します。

HTTPクライアントは、この新しいJWTを受け取り、localStorageで置き換え、リクエストキューを巡回し、失敗したすべてのリクエストを再生する必要があります。

私のラップトップが盗まれた:

/auth/sessionsエンドポイントを設定して、現在のユーザーのすべてのRefreshTokenを返すようにすると、接続されているすべてのデバイスのテーブルを表示できます。

その後、ユーザーは行を削除できます(つまり、テーブルから特定のRefreshTokenを削除できます)。侵害されたトークンの期限が切れた後(例:5分後)に更新が試行されると、失敗します。これが、JWTを非常に短命にする理由です。

なぜJWTを盲目的に信頼するのですか?

これはJWTの設計上の目的です。信頼できるほど安全です。大規模な設定(例:Google)では、認証は別の認証サーバーによって処理されます。これは、トークンと引き換えにログイン/パスワードを受け入れる役割を担っています。

たとえば、Gmailでは、後で認証はまったく実行されません。GoogleはJWTを読み取り、JWTが期限切れでない限り、メールへのアクセスを提供します。期限切れの場合は、認証サーバーにリダイレクトされます。

これが、しばらく前にGoogle認証に障害が発生したとき、一部のユーザーは問題なくGmailを使用できたのに、他のユーザーはまったく接続できなかった理由です。有効なJWTと期限切れのJWT。

実装手順

前提条件

  • Yii2がインストールされている
  • HttpOnlyクッキーがクロスサイトで機能するには、https対応サイトが必要です。
  • RefreshTokenを保存するためのデータベーステーブル
CREATE TABLE `user_refresh_tokens` (
	`user_refresh_tokenID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`urf_userID` INT(10) UNSIGNED NOT NULL,
	`urf_token` VARCHAR(1000) NOT NULL,
	`urf_ip` VARCHAR(50) NOT NULL,
	`urf_user_agent` VARCHAR(1000) NOT NULL,
	`urf_created` DATETIME NOT NULL COMMENT 'UTC',
	PRIMARY KEY (`user_refresh_tokenID`)
)
COMMENT='For JWT authentication process';
  • パッケージをインストールする:composer require sizeg/yii2-jwt
  • ログイン/ログアウト/更新などのルートには、AuthController.phpというコントローラーを使用します。任意の名前を付けることができます。

ステップバイステップの設定

  • user_refresh_tokensテーブルのActiveRecordモデルを作成します。クラス名app\models\UserRefreshTokenを使用します。

  • すべてのコントローラーでCSRF検証を無効にする

このプロパティを追加する:public $enableCsrfValidation = false;

  • /config/params.phpにJWTパラメーターを追加する
'jwt' => [
	'issuer' => 'https://api.example.com',  //name of your project (for information only)
	'audience' => 'https://frontend.example.com',  //description of the audience, eg. the website using the authentication (for info only)
	'id' => 'UNIQUE-JWT-IDENTIFIER',  //a unique identifier for the JWT, typically a random string
	'expire' => 300,  //the short-lived JWT token is here set to expire after 5 min.
],
  • 設定したパラメーターを使用する/componentsJwtValidationDataクラスを追加する
<?php
namespace app\components;

use Yii;

class JwtValidationData extends \sizeg\jwt\JwtValidationData {
	/**
	 * @inheritdoc
	 */
	public function init() {
		$jwtParams = Yii::$app->params['jwt'];
		$this->validationData->setIssuer($jwtParams['issuer']);
		$this->validationData->setAudience($jwtParams['audience']);
		$this->validationData->setId($jwtParams['id']);

		parent::init();
	}
}
  • JWT認証を初期化するためのコンポーネントを/config/web.phpの設定に追加する
	$config = [
		'components' => [
			...
			'jwt' => [
				'class' => \sizeg\jwt\Jwt::class,
				'key' => 'SECRET-KEY',  //typically a long random string
				'jwtValidationData' => \app\components\JwtValidationData::class,
			],
			...
		],
	];
  • コントローラーに認証子ビヘイビアを追加する
    • AuthController.phpでは、loginrefresh-tokenoptions(ブラウザーがクロスサイトOPTIONSリクエストを送信する場合)など、認証を必要としないアクションを除外する必要があります。
	public function behaviors() {
    	$behaviors = parent::behaviors();

		$behaviors['authenticator'] = [
			'class' => \sizeg\jwt\JwtHttpBearerAuth::class,
			'except' => [
				'login',
				'refresh-token',
				'options',
			],
		];

		return $behaviors;
	}
  • generateJwt()メソッドとgenerateRefreshToken()メソッドをAuthController.phpに追加します。ログイン/refresh-tokenアクションで使用します。ユーザーモデルのクラス名が異なる場合は調整してください。
	private function generateJwt(\app\models\User $user) {
		$jwt = Yii::$app->jwt;
		$signer = $jwt->getSigner('HS256');
		$key = $jwt->getKey();
		$time = time();

		$jwtParams = Yii::$app->params['jwt'];

		return $jwt->getBuilder()
			->issuedBy($jwtParams['issuer'])
			->permittedFor($jwtParams['audience'])
			->identifiedBy($jwtParams['id'], true)
			->issuedAt($time)
			->expiresAt($time + $jwtParams['expire'])
			->withClaim('uid', $user->userID)
			->getToken($signer, $key);
	}

	/**
	 * @throws yii\base\Exception
	 */
	private function generateRefreshToken(\app\models\User $user, \app\models\User $impersonator = null): \app\models\UserRefreshToken {
		$refreshToken = Yii::$app->security->generateRandomString(200);

		// TODO: Don't always regenerate - you could reuse existing one if user already has one with same IP and user agent
		$userRefreshToken = new \app\models\UserRefreshToken([
			'urf_userID' => $user->id,
			'urf_token' => $refreshToken,
			'urf_ip' => Yii::$app->request->userIP,
			'urf_user_agent' => Yii::$app->request->userAgent,
			'urf_created' => gmdate('Y-m-d H:i:s'),
		]);
		if (!$userRefreshToken->save()) {
			throw new \yii\web\ServerErrorHttpException('Failed to save the refresh token: '. $userRefreshToken->getErrorSummary(true));
		}

		// Send the refresh-token to the user in a HttpOnly cookie that Javascript can never read and that's limited by path
		Yii::$app->response->cookies->add(new \yii\web\Cookie([
			'name' => 'refresh-token',
			'value' => $refreshToken,
			'httpOnly' => true,
			'sameSite' => 'none',
			'secure' => true,
			'path' => '/v1/auth/refresh-token',  //endpoint URI for renewing the JWT token using this refresh-token, or deleting refresh-token
		]));

		return $userRefreshToken;
	}
  • AuthController.phpにログインアクションを追加する
	public function actionLogin() {
		$model = new \app\models\LoginForm();
		if ($model->load(Yii::$app->request->getBodyParams()) && $model->login()) {
			$user = Yii::$app->user->identity;

			$token = $this->generateJwt($user);

			$this->generateRefreshToken($user);

			return [
				'user' => $user,
				'token' => (string) $token,
			];
		} else {
			return $model->getFirstErrors();
		}
	}
  • AuthController.phpにrefresh-tokenアクションを追加します。JWTが期限切れになった場合はPOST /auth/refresh-tokenを、ユーザーがログアウトをリクエストした場合はDELETE /auth/refresh-tokenを呼び出します(その後、クライアントのlocalStorageからJWTトークンを削除します)。
	public function actionRefreshToken() {
		$refreshToken = Yii::$app->request->cookies->getValue('refresh-token', false);
		if (!$refreshToken) {
			return new \yii\web\UnauthorizedHttpException('No refresh token found.');
		}

		$userRefreshToken = \app\models\UserRefreshToken::findOne(['urf_token' => $refreshToken]);

		if (Yii::$app->request->getMethod() == 'POST') {
			// Getting new JWT after it has expired
			if (!$userRefreshToken) {
				return new \yii\web\UnauthorizedHttpException('The refresh token no longer exists.');
			}

			$user = \app\models\User::find()  //adapt this to your needs
				->where(['userID' => $userRefreshToken->urf_userID])
				->andWhere(['not', ['usr_status' => 'inactive']])
				->one();
			if (!$user) {
				$userRefreshToken->delete();
				return new \yii\web\UnauthorizedHttpException('The user is inactive.');
			}

			$token = $this->generateJwt($user);

			return [
				'status' => 'ok',
				'token' => (string) $token,
			];

		} elseif (Yii::$app->request->getMethod() == 'DELETE') {
			// Logging out
			if ($userRefreshToken && !$userRefreshToken->delete()) {
				return new \yii\web\ServerErrorHttpException('Failed to delete the refresh token.');
			}

			return ['status' => 'ok'];
		} else {
			return new \yii\web\UnauthorizedHttpException('The user is inactive.');
		}
	}
  • ユーザーモデル内のfindIdentityByAccessToken()を調整して、JWTのuidクレームを使用して認証済みユーザーを検索します。
	public static function findIdentityByAccessToken($token, $type = null) {
		return static::find()
			->where(['userID' => (string) $token->getClaim('uid') ])
			->andWhere(['<>', 'usr_status', 'inactive'])  //adapt this to your needs
			->one();
	}
  • また、パスワードが変更された場合(例:ユーザーモデルのafterSave()内)に、ユーザーのすべてのRefreshTokenを削除することも忘れないでください。
	public function afterSave($isInsert, $changedOldAttributes) {
		// Purge the user tokens when the password is changed
		if (array_key_exists('usr_password', $changedOldAttributes)) {
			\app\models\UserRefreshToken::deleteAll(['urf_userID' => $this->userID]);
		}

		return parent::afterSave($isInsert, $changedOldAttributes);
	}
  • ユーザーが自分のRefreshTokenを削除できるページを作成します。指定されたユーザーに属するuser_refresh_tokensのレコードを一覧表示し、ユーザーが選択したレコードを削除できるようにします。

クライアントサイドの例

Axiosインターセプター(React Reduxを使用?)。


let isRefreshing = false;
let refreshSubscribers: QueuedApiCall[] = [];
const subscribeTokenRefresh = (cb: QueuedApiCall) =>
  refreshSubscribers.push(cb);

const onRefreshed = (token: string) => {
  console.log("refreshing ", refreshSubscribers.length, " subscribers");
  refreshSubscribers.map(cb => cb(token));
  refreshSubscribers = [];
};

api.interceptors.response.use(undefined,
  error => {
    const status = error.response ? error.response.status : false;
    const originalRequest = error.config;

    if (error.config.url === '/auth/refresh-token') {
      console.log('REDIRECT TO LOGIN');
      store.dispatch("logout").then(() => {
          isRefreshing = false;
      });
    }

    if (status === API_STATUS_UNAUTHORIZED) {


      if (!isRefreshing) {
        isRefreshing = true;
        console.log('dispatching refresh');
        store.dispatch("refreshToken").then(newToken => {
          isRefreshing = false;
          onRefreshed(newToken);
        }).catch(() => {
          isRefreshing = false;
        });
      }

      return new Promise(resolve => {
        subscribeTokenRefresh(token => {
          // replace the expired token and retry
          originalRequest.headers["Authorization"] = "Bearer " + token;
          resolve(axios(originalRequest));
        });
      });
    }
    return Promise.reject(error);


  }
);

Mehdi Achourさんに、このチュートリアルの多くの資料作成においてご協力いただきました。

]]>
0
[wiki] Yii v2 スニペットガイド III 2023年7月17日(月) 11:37:41 +0000 https://yii.dokyumento.jp/wiki/2567/yii-v2-snippet-guide-iiihttps://yii.dokyumento.jp/wiki/2567/yii-v2-snippet-guide-iii rackycz rackycz
  1. 私の記事
  2. 言語の切り替えとURL内の言語
  3. 検索と置換
  4. 仮想化 - VagrantとDocker - なぜそしてどのように
  5. VagrantでYiiプロジェクトを実行する(簡略版)
  6. DockerでYiiプロジェクトを実行する(更新:xDebugを追加!)
  7. DockerでのxDebugの有効化、yiiデモアプリケーション
  8. Docker - カスタムphp.ini
  9. Dockerのbash(cli、コマンドライン)に入る方法
  10. AdminLTE - 概要とテーマに関する一般的な調査
  11. カスタムウィジェットの作成
  12. テスト - 単体テスト + 機能テスト + 受入テスト(opa) + カバレッジ
  13. Microsoft Access MDB
  14. マイグレーションのバッチ挿入csv

私の記事

wikiではファイルごとに最大長があるため、記事は複数のファイルに分割されています。

言語の切り替えとURL内の言語

翻訳の仕組みについては既に記述しました。ここでは、言語を切り替えてURLに保存する方法を示します。そこで、メインメニューに言語切り替えを追加しましょう。

echo Nav::widget([
 'options' => ['class' => 'navbar-nav navbar-right'],
 'items' => [
  ['label' => 'Language', 'items' => [
    ['label' => 'German' , 'url' => \yii\helpers\Url::current(['sys_lang' => 'de']) ],
    ['label' => 'English', 'url' => \yii\helpers\Url::current(['sys_lang' => 'en']) ],
   ],
  ]

新しいGETパラメータ「sys_lang」を処理し、新しい言語を保持するためにセッションに保存する必要があります。最適な方法は、すべてのコントローラーによって拡張されるBaseControllerを作成することです。その内容は次のようになります。

<?php
namespace app\controllers;
use yii\web\Controller;
class _BaseController extends Controller {
  public function beforeAction($action) {
    if (isset($_GET['sys_lang'])) {
      switch ($_GET['sys_lang']) {
        case 'de':
          $_SESSION['sys_lang'] = 'de-DE';
          break;
        case 'en':
          $_SESSION['sys_lang'] = 'en-US';
          break;
      }
    }
    if (!isset($_SESSION['sys_lang'])) {
      $_SESSION['sys_lang'] = \Yii::$app->sourceLanguage;
    }
    \Yii::$app->language = $_SESSION['sys_lang'];
    return true;
  }
}

sys_langをドメイン名のすぐ後ろのURLに含めたい場合は、config/web.phpに次のURLルールを作成できます。

'components' => [
 // ...
 'urlManager' => [
  'enablePrettyUrl' => true,
  'showScriptName' => false,
  'rules' => [
   // https://yii.dokyumento.jp/doc/api/2.0/yii-web-urlmanager#$rules-detail
   // https://stackoverflow.com/questions/2574181/yii-urlmanager-language-in-url
   // https://yii.dokyumento.jp/wiki/294/seo-conform-multilingual-urls-language-selector-widget-i18n
   '<sys_lang:[a-z]{2}>' => 'site',
   '<sys_lang:[a-z]{2}>/<controller:\w+>' => '<controller>',
   '<sys_lang:[a-z]{2}>/<controller:\w+>/<action:\w+>' => '<controller>/<action>',
  ],
 ],
],

これで、言語切り替えリンクは次のようなURLを生成します。http://myweb.com/en/site/index。ルールがない場合、リンクは次のようになります。http://myweb.com/site/index?sys_lang=en。したがって、このルールは双方向に機能します。URLが解析され、コントローラーが呼び出されるときにも、URLヘルパーを使用して新しいURLが作成されるときにも機能します。

検索と置換

大量の変更にはNotepad++を使用して正規表現を使用しています。Ctrl+Shift+Fを押すと、すべてのファイルで置換できます。

Yii::t()

Yii::t('text'  ,  'text'   ) // NO
Yii::t('text','text') // YES

search: Yii::t\('([^']*)'[^']*'([^']*)'[^\)]*\)
replace with: Yii::t\('$1','$2'\)

URL(Notepad++で)

return $this->redirect('/controller/action')->send(); // NO
return $this->redirect(['controller/action'])->send(); // YES

search: ->redirect\(['][/]([^']*)[']\)
replace: ->redirect\(['$1']\)

====

return $this->redirect('controller/action')->send(); // NO
return $this->redirect(['controller/action'])->send(); // YES

search: ->redirect\((['][^']*['])\)
replace: ->redirect\([$1]\)

PHPショートタグ

search: (<\?)([^p=]) // <?if ...
replace: $1php $2 // <?php if ...
// note that sometimes <?xml can be found and it is valid, keep it

ビューの使用状況

search: render(Ajax|Partial)?\s*\(\s*['"]\s*[a-z0-9_\/]*(viewName)

仮想化 - VagrantとDocker - なぜそしてどのように

VagrantとDockerはどちらも、指定したほぼ任意のOSまたはSW構成を使用して仮想マシンを作成しますが、ソースコードはローカルディスク上にあるため、自分のOSでIDEを使用して簡単に修正できます。

PHP開発だけでなく、他の状況でも使用できます。

これは何に役立つのか?…本番サーバーは特定の環境を実行しており、同じシステムで開発/テストを行いたいと考えています。さらに、ローカルにXAMPP、LAMP、その他のサーバーをインストールする必要はありません。仮想マシンを起動するだけで準備完了です。さらに、仮想システムの構成を他の同僚と共有して、全員が同一の環境で作業することもできます。ローカルで、異なるPHPバージョンなどを備えた多くの異なるOSシステムを実行することもできます。

VagrantとDockerは、composerやNPMと同じように機能します。利用可能なOSイメージやその他のSWのライブラリであり、いくつかの組み合わせを選択するだけです。構成全体は、Vagrantfileまたはdocker-compose.ymlという名前の1つのテキストファイルで定義されており、実行するにはいくつかのコマンドだけで済みます。デバッグも問題ありません。

VagrantでYiiプロジェクトを実行する(簡略版)

情報:この章は、ScotchBoxでPHP 7.0を使用しています。PHP 7.4が必要な場合は、CognacBoxを使用する次の章を参照してください(テスト後に追加されます)。

基本的な概要とVagrant構成

Vagrantで使用可能なすべてのOSイメージのリストはこちら

Yiiデモアプリケーションには既にVagrantfileが含まれていますが、その設定は私には不明瞭です - あまりにもPROです。scotch/boxという名前のOSイメージを使用する簡略版を公開したいと思いました。非yii PHPプロジェクトでも使用できます。(いくつかの利点がありますが、欠点は無料版では古いPHPであることです)。

Vagrantfileは、デモプロジェクトのルートフォルダに格納されています。私のVagrantfileには、次のコマンドのみが含まれています。

Vagrant.configure("2") do |config|
    config.vm.box = "scotch/box"
    config.vm.network "private_network", ip: "11.22.33.44"
    config.vm.hostname = "scotchbox"
    config.vm.synced_folder ".", "/var/www/public", :mount_options => ["dmode=777", "fmode=777"]
    config.vm.provision "shell", path: "./vagrant/vagrant.sh", privileged: false
end

# Virtual machine will be available on IP A.B.C.D (in our case 11.22.33.44, see above)
# Virtual can access your host machine on IP A.B.C.1 (this rule is given by Vagrant)

サーバーを少し強化したかったので、vagrant/vagrant.shファイルが必要です。次のものが含まれています。


# Composer:
# (In case of composer errors, it can help to delete the vendor-folder and composer.lock file)
cd /var/www/public/
composer install

# You can automatically import your SQL (root/root, dbname scotchbox)
#mysql -u root -proot scotchbox < /var/www/public/vagrant/db.sql

# You can run migrations:
#php /var/www/public/protected/yiic.php migrate --interactive=0

# You can create folder and set 777 rights:
#mkdir /var/www/public/assets
#sudo chmod -R 777 /var/www/public/assets

# You can copy a file:
#cp /var/www/public/from.php /var/www/public/to.php

# Installing Xdebug v2 (Xdebug v3 has renamed config params!):
sudo apt-get update
sudo apt-get install php-xdebug

# Configuring Xdebug in php.ini:
# If things do not work, disable your firewall and restart IDE. It might help.
echo "" | sudo tee -a /etc/php/7.0/apache2/php.ini
echo "[XDebug]" | sudo tee -a /etc/php/7.0/apache2/php.ini
echo "xdebug.remote_enable=1" | sudo tee -a /etc/php/7.0/apache2/php.ini
echo "xdebug.remote_port=9000" | sudo tee -a /etc/php/7.0/apache2/php.ini
echo "xdebug.remote_autostart=1" | sudo tee -a /etc/php/7.0/apache2/php.ini
echo "xdebug.remote_log=/var/www/public/xdebug.log" | sudo tee -a /etc/php/7.0/apache2/php.ini
echo "xdebug.remote_connect_back=1" | sudo tee -a /etc/php/7.0/apache2/php.ini
echo "xdebug.idekey=netbeans-xdebug" | sudo tee -a /etc/php/7.0/apache2/php.ini

# Important: Make sure that your IDE has identical settings: idekey and remote_port.
# NetBeans: Make sure your project is correctly setup. Right-click the project and select Properties / Run Cofigurations. "Project URL" and "Index file" must have correct values.

# Note:
# Use this if remote_connect_back does not work. 
# IP must correspond to the Vagrantfile, only the last number must be 1
#echo "xdebug.remote_handler=dbgp" | sudo tee -a /etc/php/7.0/apache2/php.ini
#echo "xdebug.remote_host=11.22.33.1" | sudo tee -a /etc/php/7.0/apache2/php.ini 

sudo service apache2 restart

…そのため、プロジェクトの両方のファイルを作成してください…

php.iniを手動で開き、このテキストを貼り付けたい場合は、ここからコピーできます。

// sudo nano /etc/php/7.0/apache2/php.ini
// (Xdebug v3 has renamed config params!)

[XDebug]
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.remote_autostart=1
xdebug.remote_log=/var/www/public/xdebug.log
xdebug.remote_connect_back=1
xdebug.idekey=netbeans-xdebug

// Important: Make sure that your IDE has identical settings: idekey and remote_port.
// NetBeans: Make sure your project is correctly setup. Right-click the project and select Properties / Run Cofigurations. "Project URL" and "Index file" must have correct values.

PhpStormでデバッグするには、このビデオを確認してください。

PhpStorm経由でMySQLに接続するには、MilanGによるこのコメントを確認してください。

Vagrantのインストールと使用

まず、VagrantとVirtualBoxをインストールしてください。

注:残念ながら、最近ではVirtualBoxはM1チップを搭載したARMベースのMacでは動作しません。その場合はDockerを使用してください。

重要:「vagrant ssh」コマンドでパスワードが要求された場合は、「vagrant」と入力してください。

コマンドラインを開き、プロジェクトに移動すると、開始できます。

  • 「vagrant -v」は、問題なく動作する場合、バージョンを表示します。
  • 「vagrant init」は新しいプロジェクトを作成します(今は必要ありません)。
  • 「vagrant up」はVagrantfileを実行し、仮想マシンを作成/起動します。

仮想マシンが実行されている場合は、これらも呼び出すことができます。

  • 「vagrant ssh」はLinuxシェルを開きます - プロンプトが表示された場合はパスワード「vagrant」を使用してください。
  • 「vagrant halt」は仮想マシンを停止します。
  • 「vagrant reload」は仮想マシンを再起動しますが、config.vm.provisionを実行したり、既存のVagrant仮想マシンを起動したりしません - PCを再起動するたびに「vagrant up」を呼び出す必要はありません。
  • 「vagrant reload --provision」は仮想マシンを再起動し、config.vm.provisionを実行します。

Linuxシェルでは、任意のコマンドを呼び出すことができます。

  • インストールされているLinuxバージョンの確認方法:「cat /etc/os-release」または「lsb_release -a」または「hostnamectl」
  • PHPバージョンの取得方法:「php -version」
  • 「mysql -v」を実行できない場合は、「mysql -u {username} -p」を実行できます…ログインを知っている場合。
  • 現在のIP:hostname -I

「scotch/box」ではPhpMyAdminではなく、Adminerを使用しています。これはシンプルなPHPスクリプトであり、インストールなしで実行されます。adminer.phpスクリプトをdocrootにコピーし、ブラウザからアクセスします。Yiiの構成と同じログインを使用します。サーバーはlocalhostになります。

DockerでYiiプロジェクトを実行する(更新:xDebugを追加!)

注:高度なアプリケーションを示しています。基本的なアプリケーションはそれほど変わらないと思います。優れたDockerチュートリアルはこちらにあります。

Yiiプロジェクトは既にDockerに対応しています。開始するには、www.docker.comからDockerをインストールするだけで、このマニュアルに従うことができます。

  • アプリケーションテンプレートをダウンロードして、任意のフォルダに展開します。
  • コマンドラインを開き、プロジェクトフォルダに移動します。
  • コマンドdocker-compose up -dを実行します。
    • 引数-dは、サービスとしてバックグラウンドでDockerを実行します。
    • 利点は、コマンドラインがブロックされないことです - さらにコマンドを呼び出すことができます。
  • アプリケーションを初期化するには、コマンドinitを実行します。
  • 次のコマンドのいずれかを使用してcomposer installを呼び出すこともできます。
    • docker-compose run --rm frontend composer install
    • docker-compose run --rm backend composer install

注:initcomposerは、必ずしもDocker経由ではなく、ローカルで呼び出すことができます。フォルダにファイルを追加するだけです。

これで、URLを開くことができます。

  • フロントエンド:https://:20080
  • バックエンド:https://:21080
  • …これらのポート番号を理解するには、docker-compose.ymlを参照してください。

common/config/main-local.phpを開き、次のDB接続を設定します。

  • host=mysql !!
  • dbname=yii2advanced
  • username=yii2advanced
  • password=secret
  • 値はdocker-compose.ymlから取得されます。

次のコマンドのいずれかを使用してマイグレーションを実行します。

  • docker-compose run --rm frontend php yii migrate
  • docker-compose run --rm backend php yii migrate

フロントエンドに移動し、右上の隅にある「サインアップ」をクリックします。

2番目の方法は、DBでテーブルを直接修正することです。

  • Adminerをダウンロードします - これは単一ファイルのDBクライアントです:www.adminer.org/en
  • Adminerをfrontend\web\adminer.phpにコピーします。
  • 次を使用してAdminerを開きます:https://:20080/adminer.php
  • DBにパスワードがない場合、Adminerは動作を拒否します。「クラック」する必要があります。
  • 次のログインを使用し、DB yii2advancedに移動します。
  • server=mysql !!
  • username=yii2advanced
  • password=secret
  • 値はdocker-compose.ymlから取得されます。
  • 最初のユーザーのstatus=10を設定します。

これでアカウントが作成され、バックエンドにログインできます。

DockerでのxDebugの有効化、yiiデモアプリケーション

次のように、environmentセクションをdocker-compose.ymlに追加するだけです。

services:

  frontend:
    build: frontend
    ports:
      - 20080:80
    volumes:
      # Re-use local composer cache via host-volume
      - ~/.composer-docker/cache:/root/.composer/cache:delegated
      # Mount source-code for development
      - ./:/app
    environment:
      PHP_ENABLE_XDEBUG: 1
      XDEBUG_CONFIG: "client_port=9000 start_with_request=yes idekey=netbeans-xdebug log_level=1 log=/app/xdebug.log discover_client_host=1"
      XDEBUG_MODE: "develop,debug"

これにより、適切にフォーマットされたvar_dump値を表示し、IDEでアプリケーションをデバッグできます。

注:IDEの設定に基づいてidekeyclient_portを指定する必要があります。さらに、YiiプロジェクトもIDEで適切に構成されている必要があります。NetBeansでは、「プロパティ/実行構成」(プロジェクトを右クリック)で「プロジェクトURL」と「インデックスファイル」が正しいことを確認してください。

注2:xDebug2とxDebug3では設定が異なることに注意してください。詳細はこちらを参照してください。

これには約8時間費やしました。誰かが喜んでくれることを願っています:-) 残念ながら、この構成はdocker-compose.ymlにはありません。非常に便利だったでしょう。

Docker - カスタムphp.ini

"volumes"セクションにこの行を追加します。

- ./myphp.ini:/usr/local/etc/php/conf.d/custom.ini

Yiiアプリケーションのルートにmyphp.iniファイルを作成します。例えば、ファイルがロードされているかどうかをテストするために**html_errors=on**と**html_errors=off**を入力できます。Dockerを再起動し、PHPファイルで**phpinfo()**メソッドを使用して結果を確認してください。

Dockerのbash(CLI、コマンドライン)への入り方

コマンドラインでDockerプロジェクトのフォルダに移動し、以下のコマンドを実行します。

  • docker ps
  • これにより、docker-compose.ymlで定義したすべてのサービスが一覧表示されます。

一覧の最後の列はNAMESです。1つを選択してその名前をコピーします。次に、以下のコマンドを実行します。

  • docker exec -it {NAME} /bin/bash
  • …ここで{NAME}はサービス名です。例えば
  • docker exec -it yii-advanced_backend_1 /bin/bash

使用されているLinuxを調べるには、**cat /etc/os-release**を実行します。(または、他のコマンドについてはVagrantの章を参照してください)

php.iniの場所を特定するには、**php --ini**と入力します。見つけたら、次のようにyiiフォルダにコピーできます。

cp path/to/php.ini /app/myphp.ini

AdminLTE - 概要とテーマに関する一般的な調査

AdminLTEは利用可能な管理テーマの1つです。現在、2つのバージョンがあります。

  • AdminLTE v2 = Bootstrap 3ベース = Yii v2アプリケーションに最適
  • AdminLTE v3 = Bootstrap 4ベース(Bootstrap3からBootstrap4へのYii2のアップグレードは容易です*)

* Yii2のBootstrap3からBootstrap4へのアップグレード: https://www.youtube.com/watch?v=W1xxvngjep8

AdminLTE <= 2.3v2.4v3.0のドキュメント。AdminLTEの一部の機能はサードパーティの依存関係のみであることに注意してください。例えば、地図など。

他にも多くの管理テーマがあります。

YiiプロジェクトにAdminLTEを統合するためのYii2拡張機能も多数あります。

Yii2デモアプリケーションと同じBootstrapを使用しているため、AdminLTE v2を選択し、実装に役立ついくつかの拡張機能をテストしました。

しかし、まずはYii2デモアプリケーションで拡張機能を使用せずにAdminLTE v2を使用する方法に関する簡単な情報から始めましょう。

v2.4の手動統合 - アセットファイルの作成

  • ドキュメントを開き、Composerを実行するか、すべての依存関係をZIPでダウンロードします。
  • プレビューページを開き、HTMLコード全体をテキストエディタにコピーします。
  • 必要のないBODYセクションの部分(少なくともclass="content"セクションの内容)を削除します。
  • また、すべてのSCRIPTタグとLINKタグを削除します。後でAssetBundleを使用してそれらを追加します。

  • 既存のファイルviews/layouts/main.phpを開き、重要なPHP呼び出しを新しいファイルにコピーします。(Asset、beginPage、$content、Breadcrumbsなど)
  • これでレイアウトが完成したので、元のレイアウトファイルを置き換えることができます。

すべてのSCRIPTとLINKをリンクするためのアセットファイルを作成するだけです。

  • assets/AppAssetファイルをassets/LteAssetにコピーし、内部のクラス名を変更します。
  • すべてのLINKとSCRIPTのURLをLteAssetにコピーします。
  • jQueryとBootstrapはスキップします。これらはYiiの一部です。例:
namespace app\assets;
use yii\web\AssetBundle;
class LteAsset extends AssetBundle
{
    public $sourcePath = '@vendor/almasaeed2010/adminlte/';
    public $jsOptions = ['position' => \yii\web\View::POS_HEAD];  // POS_END cause conflict with YiiAsset  
    public $css = [
        'bower_components/font-awesome/css/font-awesome.min.css',
        'https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic',
        // etc
    ];
    public $js = [
        'bower_components/jquery-ui/jquery-ui.min.js',
        // etc
    ];
    public $depends = [
        'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',
    ];
}
  • Yiiページを更新し、「開発者ツール」でネットワークエラーを確認します。修正してください。

このエラーが表示される場合があります。「ヘッダーが既に送信されています」

  • これは、古いレイアウトファイルから新しいレイアウトファイルにいくつかのPHPコードをコピーし忘れたことを意味します。

これで完了です。AdminLTEのHTMLとJSを使用できます。そこで、代わりにそれを行ってくれる拡張機能を確認しましょう。

Insolita拡張機能

多くのUIアイテム(ボックス、タイル、コールアウト、アラート、チャットボックス)でうまく機能します。上記のメインレイアウトファイルとアセットバンドルを準備するだけです。2018年以降は更新されていません。

私のコメントについては、ウェブをご覧ください。多くのウィジェットの使い方を示しました。

ソースの不完全な部分

vendor\insolita\yii2-adminlte-widgets\LteConst.php

  • タイプミスがあります。COLOR_LIGHT_BLUEは「light-blue」ではなく「lightblue」である必要があります。

vendor\insolita\yii2-adminlte-widgets\CollapseBox.php

  • $collapseButtonTemplateのクラスは「btn {btnType} btn-xs」ではなく「btn btn-box-tool」である必要があります。
  • (これは、展開可能なボックスの展開/折りたたみボタンに影響します)
  • 画面からボックスを削除できるようにするには、$collapseButtonTemplateを変更する必要があります。つまり、prepareBoxTools()メソッドでdata-widgetとiconClassを変更する必要があります。

LteBox

  • ボックスは「待機中アイコン」のオーバーレイの後ろに隠れる可能性があります。これは、ボックスのdivの最後に次のHTMLを使用することで行われます。
    <div class="overlay"><i class="fa fa-refresh fa-spin"></i></div>
    
  • これは手動で追加するか、LteBoxを変更することで追加する必要があります。

Yiister

そのウェブですべてが説明されています。非常に便利です。http://adminlte.yiister.ruこの記事のアセットファイルだけが必要で、Yiisterをインストールします。残念ながら、2015年以降は更新されていません。メニュー、グリッドビュー、いくつかのボックス、Fleshalerts、コールアウト、エラーページのレンダリングのためのウィジェットを提供します。

dmstr/yii2-adminlte-asset

AdminLTEのウェブで公式に言及されています。メニューとアラートのみをレンダリングします。主にアセットファイルとGiiテンプレートを提供します。GiiテンプレートはGridViewのデザインを自動的に修正しますが、手動で行う方法を以下に示します。

その他の強化機能

AdminLTEはフォントSource Sans Proを使用しています。異なるフォントを使用する場合は、Googleフォントで選択し、次のようにレイアウトファイルを修正します。

<link href="https://fonts.googleapis.com/css2?family=Palanquin+Dark:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
 body {
    font-family: 'Palanquin Dark', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  } 
  
  h1,h2,h3,h4,h5,h6,
  .h1,.h2,.h3,.h4,.h5,.h6 {
    font-family: 'Palanquin Dark', sans-serif;
  }
</style>

GridViewを正しく表示するには、次のHTMLコードでラップします。

<div class="box box-primary">
  <div class="box-header">
    <h3 class="box-title"><i class="fa fa-table"></i>&nbsp;Grid caption</h3>
  </div>
  <div class="box-body"

  ... grid view ...

  </div>
</div>

web/css/site.cssのグリフォンも変更できます。

a.asc:after {
    content: "\e155";
}

a.desc:after {
    content: "\e156";
}

基本的に以上です。これで、AdminLTEの使い方とGridViewの修正方法がわかりました。少なくともウィジェットをレンダリングするための拡張機能が1つ必要です(上記を参照)。

カスタムウィジェットの作成

ウィジェットに関する公式のドキュメント、またはこの説明をご覧ください。この例を示していますが、3行追加しました。両方のタイプのウィジェットは次のようにコーディングできます。

namespace app\components;
use yii\base\Widget;
use yii\helpers\Html;

class HelloWidget extends Widget{
 public $message;
 public function init(){
  parent::init();
  if($this->message===null){
   $this->message= 'Welcome User';
  }else{
   $this->message= 'Welcome '.$this->message;
  }
  // ob_start();
  // ob_implicit_flush(false);
 }
 public function run(){
  // $content = ob_get_clean();
  return Html::encode($this->message); // . $content;
 }
}

// This widget is called like this:
echo HelloWidget::widget(['message' => ' Yii2.0']);

// After uncommenting my 4 comments you can use this
HelloWidget::begin(['message' => ' Yii2.0']);
echo 'My content';
HelloWidget::end();

テスト - 単体テスト + 機能テスト + 受入テスト(OPA)+ カバレッジ

両方のデモアプリケーションの準備ができているため、テストの実行は簡単です。コマンドラインを使用し、プロジェクトに移動します。次に、次を入力します。

php ./vendor/bin/codecept run

これにより、単体テストと機能テストが実行されます。これらは、tests/unitフォルダとtests/functionalフォルダに定義されています。機能テストは非表示のブラウザで実行され、JavaScriptでは動作しません(たぶん)。複雑なJavaScriptをテストするには、受入テストが必要です。それらの実行方法は、README.mdファイルまたは両方のデモアプリケーションのドキュメントにあります。標準のChromeまたはFirefoxブラウザでこれらのテストを実行する場合は、Java JDKselenium-server*.jarファイルが必要です。README.mdのリンクを参照してください。JARファイルを取得したら、プロジェクトに配置して実行します。

java -jar selenium-server-4.0.0.jar standalone

これで、テストを再実行できます。acceptance.suite.ymlファイルのWebDriverセクションにプロジェクトの動作しているURL(例:https:///yii-basic/web)があることを確認してください。これは環境によって異なります。ブラウザも指定してください。「browser: chrome」を設定するとうまく動作します。「WebDriverがインストールされていません」というエラーが発生した場合は、このComposerコマンドを実行する必要があります。

composer require codeception/module-webdriver --dev

PS:ChromeDriverというファイルもありますが、「codeception/module-webdriver」の代替手段なのか、いつ使用するのかはよくわかりません。まだ研究していません。

コードカバレッジを確認するには、ドキュメント(上記のリンク)の説明に従ってください。さらに、PHPにxDebugが含まれていることを確認してください!xDebug 2とxDebug 3の設定の違いに注意してください!xDebugがない場合、「使用可能なコードカバレッジドライバーがありません」というエラーが発生します。

Microsoft Access MDB

Linuxでは成功していませんが、WindowsにWebサーバー(例:XAMPPサーバー)をインストールすると、「Microsoft Access Database Engine 2016 Redistributable」をインストールして*.mdbファイルを使用できます。

まず、PHPを備えたWebサーバーをインストールする必要があります。64ビット版と32ビット版のどちらをインストールする必要があるかを知る必要があります。おそらく64ビットでしょう。Microsoft Access Database Engine 2016 Redistributableのページ(または利用可能な新しいバージョン)にアクセスし、対応するパッケージ(32ビット版と64ビット版)をインストールします。

注:同じビットバージョンのMS Accessが既にインストールされている場合は、エンジンをインストールする必要がない可能性があります。

次に、DB接続で次のDSN文字列を使用できます。(このコードはconfig/db.phpファイルに属しています)

<?php

$file = "C:\\xampp\\htdocs\\Database1.mdb";

return [
  'class' => 'yii\db\Connection',
	
  'dsn' => "odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=$file;Uid=;Pwd=;",
  'username' => '',
  'password' => '',
  'charset' => 'utf8',
	
  //'schemaMap' => [
  //  'odbc'=> [
  //    'class'=>'yii\db\pgsql\Schema',
  //    'defaultSchema' => 'public' //specify your schema here
  //  ]
  //], 

  // Schema cache options (for production environment)
  //'enableSchemaCache' => true,
  //'schemaCacheDuration' => 60,
  //'schemaCache' => 'cache',
];

次に、これを使用してテーブルをクエリします。

$data = Yii::$app->db->createCommand("SELECT * FROM TableX")->queryAll();
var_dump($data);

注:異なるビットバージョンのMS AccessがPHPに既にインストールされている場合、正しいビットバージョンのエンジンをインストールできません。その場合は、MS Accessをアンインストールする必要があります。

注2:MDBファイルの内容がわからない場合は、GoogleドキュメントでMDB、ACCDBビューアとリーダーを推奨され、それは機能しました。

注3:Windows 10には、次のようにプリインストールされたアプリケーションがあります。

  • 「ODBCデータソース32ビット」
  • 「ODBCデータソース64ビット」
  • (Winキーを押して「ODBC」と入力するだけです)

必要なものを開き、「システムDSN」タブに移動して「追加」をクリックします。使用可能なドライバーが表示されます - **DSN文字列で使用できるのはこれらのドライバーのみです!**

「SQL Server」しか表示されない場合は、プラットフォーム用のドライバーを含むAccess Engine(またはMS Access)をインストールする必要があります。「Microsoft Access Driver (*.mdb, *.accdb)」という名前のドライバーが必要です。

私の場合、エンジンは次の64ビットドライバーを追加しました。

  • Microsoft Access dBASE Driver (*.dbf, *.ndx, *.mdx)
  • Microsoft Access Driver (*.mdb, *.accdb)
  • Microsoft Access Text Driver (*.txt, *.csv)
  • Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)

Linuxはどうですか?

MS Accessドライバーも必要ですが、Microsoftは提供していません。サードパーティ製のMdbToolsEasySoftがありますが、不完全なものや高価なものがあります。Unix ODBCもあります。

JavaにはJava JDBCJackcessUcanaccessがあります。

Dockerはどうでしょうか?私の知る限り、Linux上でWindowsイメージを実行することはできないため、この場合、WindowsのODBCの利点を使用することはできません。Windows上でLinuxイメージを使用することはできますが、仮想LinuxからODBCドライバにアクセスする方法はないと思います。試してみる必要がありますが、まだテストしていません。

移行バッチインサートcsv

Yii2のマイグレーションでCSVをDBにインポートしたい場合、この「マイグレーションベースクラス」を作成し、実際のマイグレーションの親として使用できます。その後、batchInsertCsv()メソッドを使用できます。

<?php

namespace app\components;

use yii\db\Migration;

class BaseMigration extends Migration
{
    /**
     * @param $filename Example: DIR_ROOT . DIRECTORY_SEPARATOR . "file.csv"
     * @param $table The target table name
     * @param $csvToSqlColMapping [csvColName => sqlColName] (if $containsHeaderRow = true) or [csvColIndex => sqlColName] (if $containsHeaderRow = false)
     * @param bool $containsHeaderRow If the header with CSV col names is present
     * @param int $batchSize How many rows will be inserted in each batch
     * @throws Exception
     */
    public function batchInsertCsv($filename, $table, $csvToSqlColMapping, $containsHeaderRow = false, $batchSize = 10000, $separator = ';')
    {
        if (!file_exists($filename)) {
            throw new \Exception("File " . $filename . " not found");
        }

        // If you see number 1 in first inserted row and column, most likely BOM causes this.
        // Some Textfiles begin with 239 187 191 (EF BB BF in hex)
        // bite order mark https://en.wikipedia.org/wiki/Byte_order_mark
        // Let's trim it on the first row.
        $bom = pack('H*', 'EFBBBF');

        $handle = fopen($filename, "r");
        $lineNumber = 1;
        $header = [];
        $rows = [];
        $sqlColNames = array_values($csvToSqlColMapping);
        $batch = 0;

        if ($containsHeaderRow) {
            if (($raw_string = fgets($handle)) !== false) {
                $header = str_getcsv(trim($raw_string, $bom), $separator);
            }
        }

        // Iterate over every line of the file
        while (($raw_string = fgets($handle)) !== false) {
            $dataArray = str_getcsv(trim($raw_string, $bom), $separator);

            if ($containsHeaderRow) {
                $dataArray = array_combine($header, $dataArray);
            }

            $tmp = [];
            foreach ($csvToSqlColMapping as $csvCol => $sqlCol) {
                $tmp[] = trim($dataArray[$csvCol]);
            }
            $rows[] = $tmp;

            $lineNumber++;
            $batch++;

            if ($batch >= $batchSize) {
                $this->batchInsert($table, $sqlColNames, $rows);
                $rows = [];
                $batch = 0;
            }
        }
        fclose($handle);

        $this->batchInsert($table, $sqlColNames, $rows);
    }
}
]]>
0
[wiki] Yii2アプリケーションですべてのメールを1つの受信箱にリダイレクトする方法 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/wiki/2566/how-to-redirect-all-emails-to-one-inbox-on-yii2-applicationshttps://yii.dokyumento.jp/wiki/2566/how-to-redirect-all-emails-to-one-inbox-on-yii2-applications glpzzz glpzzz

\yii\mail\BaseMailer::useFileTransport は素晴らしいツールです。これを有効にすると、このメーラーを通して送信されたすべてのメールは(デフォルトで)@runtime/mailに保存され、送信されなくなります。これにより、開発者は結果を検査できます。

しかし、受信トレイで実際にメールを受信したい場合はどうなりますか?すべてのメールが1つのアカウントに送信される予定の場合、問題は発生しません。パラメーターとして設定し、params-local.php(高度なアプリケーションテンプレートを想定)で変更します。

アプリが異なるアカウントにメールを送信し、replyTo、cc、bccフィールドを使用する必要がある場合、大きな問題が発生します。以前のアプローチでは、多くのif(YII_DEBUG)を使用せずに解決するのはほぼ不可能です。

さて、次に解決策があります。

'useFileTransport' => true,
'fileTransportCallback' => function (\yii\mail\MailerInterface $mailer, \yii\mail\MessageInterface $message) {
    $message->attachContent(json_encode([
            'to' => $message->getTo(),
            'cc' => $message->getCc(),
            'bcc' => $message->getBcc(),
            'replyTo' => $message->getReplyTo(),
        ]), ['fileName' => 'metadata.json', 'contentType' => 'application/json'])
        ->setTo('debug@mydomain.com') // account to receive all the emails
        ->setCc(null)
        ->setBcc(null)
        ->setReplyTo(null);

    $mailer->useFileTransport = false;
    $mailer->send($message);
    $mailer->useFileTransport = true;

    return $mailer->generateMessageFileName();
}

動作方法は?fileTransportCallbackは、@runtime/mailに保存されたメールの作成に使用されるファイル名を指定するコールバックです。これはメール送信プロセスを「傍受」するため、目的のために使用できます。

  1. 実際の受信者情報を含むJSONファイルを添付して確認できるようにします。
  2. 受信者(TO)を、すべてのメールを受信したいメールアドレスに設定します。
  3. 他の受信者フィールドをnullに設定します。
  4. useFileTransportを無効にします。
  5. メールを送信します。
  6. useFileTransportを有効にします。
  7. デフォルトのファイル名(操作の日時)を返します。

このようにして、指定されたアカウントですべてのメールを受信し、@runtime/mailにも保存されます。

Yii2アプリケーションでメールを確認するための非常にシンプルなヘルパーです。

元の投稿先:https://glpzzz.github.io/2020/10/02/yii2-redirect-all-emails.html

]]>
0
[wiki] Yii2での複数ファイルアップロードのAPI 2022年7月5日 火曜日 03:01:39 +0000 https://yii.dokyumento.jp/wiki/2565/api-of-multiple-file-uploading-in-yii2https://yii.dokyumento.jp/wiki/2565/api-of-multiple-file-uploading-in-yii2 fezzymalek fezzymalek

多くのエラーが発生し、Yii2で複数の画像APIを実行する方法が分からなかった後、今日やっと解決しました。

これはフォーラムで質問した内容であり、私の場合は機能します。https://forum.yiiframework.com/t/multiple-file-uploading-api-in-yii2/130519

**複数ファイルアップロード**のために、このコードをモデルに実装します。

public function rules()
    {
        return [
            [['post_id', 'media'], 'required'],
            [['post_id'], 'integer'],
            [['media'], 'file', 'maxFiles' => 10],//here is my file field
            [['created_at'], 'string', 'max' => 25],
            [['post_id'], 'exist', 'skipOnError' => true, 'targetClass' => Post::className(), 'targetAttribute' => ['post_id' => 'id']],
        ];
    }
    

モデルには、拡張機能またはskipOnEmptyメソッドを追加することもできます。

そして、これは複数のファイルアップロードコードを実行したコントローラーアクションです。

public function actionMultiple(){
        $model = new Media;
        $model->post_id = '2';
        if (Yii::$app->request->ispost) {
            $model->media = UploadedFile::getInstances($model, 'media');
            if ($model->media) {
                foreach ($model->media as $value) {
                    $model = new Media;
                    $model->post_id = '2';
                    $BasePath = Yii::$app->basePath.'/../images/post_images';
                    $filename = time().'-'.$value->baseName.'.'.$value->extension;
                    $model->media = $filename;
                    if ($model->save()) {
                        $value->saveAs($BasePath.$filename);
                    }
                }
                return array('status' => true, 'message' => 'Image Saved'); 
            }
        }
        return array('status' => true, 'data' => $model);
    }

ご質問があれば、対応いたします。

]]>
0
[wiki] Yii2アプリでエラーログを開発者にメールで送信する方法 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/wiki/2564/how-to-email-error-logs-to-developer-on-yii2-appshttps://yii.dokyumento.jp/wiki/2564/how-to-email-error-logs-to-developer-on-yii2-apps glpzzz glpzzz

ロギングはアプリケーションの非常に重要な機能です。常に何が起こっているかを知らせてくれます。デフォルトでは、Yii2の基本アプリケーションと高度なアプリケーションには、\yii\log\FileTargetターゲットのみが構成されています。

アプリからのメッセージを含むメールを受信するには、ログコンポーネントをファイルトランスポートの代わりに(またはそれに加えて)メール(またはTelegram、Slack)トランスポートに設定します。

'components' => [
    // ...
    'log' => [
         'targets' => [
             [
                 'class' => 'yii\log\EmailTarget',
                 'mailer' => 'mailer',
                 'levels' => ['error', 'warning'],
                 'message' => [
                     'from' => ['log@example.com'],
                     'to' => ['developer1@example.com', 'developer2@example.com'],
                     'subject' => 'Log message',
                 ],
             ],
         ],
    ],
    // ...
],

\yii\log\EmailTargetコンポーネントは、メッセージをログに記録する別の方法であり、この場合は、EmailTarget構成のmailer属性で指定されたアプリケーションのmailerコンポーネントを介してメールで送信します。メッセージのプロパティと、このターゲットを介して送信する必要があるメッセージのレベルを指定することもできます。

メール以外のプラットフォームを介してメッセージを受信したい場合は、ログターゲットを表す他のコンポーネントがあります。

または、\yii\log\Targetをサブクラス化して独自に実装することもできます。

]]>
0
[wiki] Yii2ページにSchema.orgマークアップを追加する方法 2020年9月11日 金曜日 22:09:55 +0000 https://yii.dokyumento.jp/wiki/2560/how-to-add-schema-org-markup-to-yii2-pageshttps://yii.dokyumento.jp/wiki/2560/how-to-add-schema-org-markup-to-yii2-pages glpzzz glpzzz

https://schema.orgは、検索エンジンやその他のアプリケーションで使用するために、Webページに構造化されたデータを埋め込むことができるマークアップシステムです。JSON-LDを使用して、Yii2ベースのWebサイトのページにSchema.orgを追加する方法を見てみましょう。

基本的に、ページに次のようなものを埋め込む必要があります。

<script type="application/ld+json">
{ 
  "@context": "http://schema.org/",
  "@type": "Movie",
  "name": "Avatar",
  "director": 
    { 
       "@type": "Person",
       "name": "James Cameron",
       "birthDate": "1954-08-16"
    },
  "genre": "Science fiction",
  "trailer": "../movies/avatar-theatrical-trailer.html" 
}
</script>

しかし、Yii2でこのようなスクリプトを書きたくないので、他の、よりPHP的な方法を試してみましょう。

レイアウトでは、Webサイトの一般的なマークアップを定義できます。そのため、@app/views/layouts/main.phpファイルの先頭に次のスニペットを追加します。

<?= \yii\helpers\Html::script(isset($this->params['schema'])
    ? $this->params['schema']
    : \yii\helpers\Json::encode([
        '@context' => 'https://schema.org',
        '@type' => 'WebSite',
        'name' => Yii::$app->name,
        'image' => $this->image,
        'url' => Yi::$app->homeUrl,
        'descriptions' => $this->description,
        'author' => [
            '@type' => 'Organization',
            'name' => Yii::$app->name,
            'url' => 'https://www.hogarencuba.com',
            'telephone' => '+5352381595',
        ]
    ]), [
    'type' => 'application/ld+json',
]) ?>

ここでは、必要なtypeオプションを使用してスクリプトを含めるHtml::script($content, $options)と、JSONを生成するJson::encode($value, $options)を使用しています。また、他のページからのマークアップの上書きを許可するために、schemaというページパラメーターを使用しています。たとえば、@app/views/real-estate/view.phpでは、次を使用しています。

$this->params['schema'] = \yii\helpers\Json::encode([
    '@context' => 'https://schema.org',
    '@type' => 'Product',
    'name' => $model->title,
    'description' => $model->description,
    'image' => array_map(function ($item) {
        return $item->url;
    }, $model->images),
    'category' => $model->type->description_es,
    'productID' => $model->code,
    'identifier' => $model->code,
    'sku' => $model->code,
    'url' => \yii\helpers\Url::current(),
    'brand' => [
        '@type' => 'Organization',
        'name' => Yii::$app->name,
        'url' => 'https://www.hogarencuba.com',
        'telephone' => '+5352381595',
    ],
    'offers' => [
        '@type' => 'Offer',
        'availability' => 'InStock',
        'url' => \yii\helpers\Url::current(),
        'priceCurrency' => 'CUC',
        'price' => $model->price,
        'priceValidUntil' => date('Y-m-d', strtotime(date("Y-m-d", time()) . " + 365 day")),
        'itemCondition' => 'https://schema.org/UsedCondition',
        'sku' => $model->code,
        'identifier' => $model->code,
        'image' => $model->images[0],
        'category' => $model->type->description_es,
        'offeredBy' => [
            '@type' => 'Organization',
            'name' => Yii::$app->name,
            'url' => 'https://www.hogarencuba.com',
            'telephone' => '+5352381595',
        ]
    ]
]);

ここでは、このページのスキーマをより複雑なマークアップ(オファー付きの製品)で再定義しています。

このようにして、Webサイトのすべてのページにschema.orgマークアップが定義されます。レイアウトにはデフォルトがあり、他のページでは$this->params['schema']に値を設定して再定義できます。

]]>
0
[wiki] Yii2 WebサイトにOpen GraphタグとTwitter Cardタグを追加する方法。 2024年9月19日(木) 12:05:58 +0000 https://yii.dokyumento.jp/wiki/2559/how-to-add-open-graph-and-twitter-card-tags-to-yii2-websitehttps://yii.dokyumento.jp/wiki/2559/how-to-add-open-graph-and-twitter-card-tags-to-yii2-website glpzzz glpzzz

OpenGraphTwitter Cardsは、Webページを記述し、FacebookとTwitterでそれぞれより理解しやすくするための2つのメタデータセットです。

単純なWebページに多くのメタタグを追加する必要があるため、TaggedViewを使用しましょう。

このコンポーネントはyii\web\Viewをオーバーライドし、それに属性を追加して、各ビューで値を設定できるようにします。通常、ページタイトルは次のように設定します。

$this->title = $model->title;

さて、**TaggedView**を使用すると、次のように設定できます。

$this->title = $model->title;
$this->description = $model->abstract;
$this->image = $model->image;
$this->keywords = ['foo', 'bar'];

これにより、このページの適切なOpenGraph、Twitter Card、HTMLメタディスクリプションタグが生成されます。

また、各ページで使用できるコンポーネント構成で各タグのデフォルト値を定義し、前の例のように再定義した場合にのみオーバーライドされます。

'components' => [
    //...
    'view' => [
        'class' => 'daxslab\taggedview\View',
        'site_name' => '',
        'author' => '',
        'locale' => '',
        'generator' => '',
        'updated_time' => '',
    ],
    //...
]

これらのプロパティの一部には、デフォルト値が割り当てられています。たとえば、site_nameはデフォルトでYii::$app->nameを取得します。

Webサイトでの使用の結果

<title>¿Deseas comprar o vender una casa en Cuba? | HogarEnCuba, para comprar y vender casas en Cuba</title>
<meta name="author" content="Daxslab (https://www.daxslab.com)">
<meta name="description" content="Hay 580 casas...">
<meta name="generator" content="Yii2 PHP Framework (https://yii.dokyumento.jp)">
<meta name="keywords" content="HogarEnCuba, ...">
<meta name="robots" content="follow">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:description" content="Hay 580 casas...">
<meta name="twitter:image" content="https://www.hogarencuba.com/images/main-identifier_es.png">
<meta name="twitter:site" content="HogarEnCuba">
<meta name="twitter:title" content="¿Deseas comprar o vender una casa en Cuba?">
<meta name="twitter:type" content="website">
<meta name="twitter:url" content="https://www.hogarencuba.com/">
<meta property="og:description" content="Hay 580 casas...">
<meta property="og:image" content="https://www.hogarencuba.com/images/main-identifier_es.png">
<meta property="og:locale" content="es">
<meta property="og:site_name" content="HogarEnCuba">
<meta property="og:title" content="¿Deseas comprar o vender una casa en Cuba?">
<meta property="og:type" content="website">
<meta property="og:updated_time" content="10 sept. 2020 9:43:00">
]]>
0
[wiki] Yii v2 スニペットガイド II 2021年11月11日 木曜日 13:47:12 +0000 https://yii.dokyumento.jp/wiki/2558/yii-v2-snippet-guide-iihttps://yii.dokyumento.jp/wiki/2558/yii-v2-snippet-guide-ii rackycz rackycz
  1. 私の記事
  2. MSSQLへの接続
  3. Yii2プロジェクトで2番目のDBとしてMSSQLデータベースを使用する
  4. リモートMSSQLテーブルのGiiでモデルを作成する
  5. Yii 2でのPhpExcel/PhpSpreadsheetと、バイナリコンテンツをブラウザに送信する
  6. PDF - UTF + 1D&2Dバーコード - TCPDF
  7. カスタムフォーマッター - asDecimalOrInteger
  8. 親モデルを含むGridViewで子モデルの合計を表示する
  9. 関連する列による並べ替えと検索
  10. バイナリデータをファイルとしてブラウザに送信する - デコードされたbase64

私の記事

wikiではファイルごとに最大長があるため、記事は複数のファイルに分割されています。

MSSQLへの接続

PHPにMSSQLドライバが必要です。プログラムで、それらをリストしたり、次のように存在を確認したりできます。

var_dump(\PDO::getAvailableDrivers());

if (in_array('sqlsrv', \PDO::getAvailableDrivers())) {
  // ... MsSQL driver is available, do something
}

システムに基づいて、異なるドライバをダウンロードする必要があります。違いはx64対x86とThreadSafe対nonThreadSafeです。Windowsでは常にThreadSafeを使用します。説明

最新のPHPドライバはこちらにあります。

  • ドライバv5.8 = PHP 7.2 - 7.4

古いPHPドライバはこちらにあります。

  • ドライバv4.0 = PHP 7.0 - 7.1
  • ドライバv3.2 = PHP 5.x

ドライバをダウンロードして解凍したら、DLLファイルを選択して「php/ext」フォルダに配置します。Windowsでは、たとえば「C:\xampp\php\ext」にある場合があります。

注:場合によっては、これらのOBDCドライバも必要になる場合がありますが、いつ必要になるかはわかりません。

これで、php.iniファイルを修正する必要があります。Windowsでは、「C:\xampp\php\php.ini」に配置されている場合があります。それを開き、「extension」という単語で始まる行を探して、そこに次の行を貼り付けます。

extension={filename.dll}
// Example:
extension=php_pdo_sqlsrv_74_ts_x64.dll

Apacheを再起動してphpinfo() Webページにアクセスします。「pdo_sqlsrv」セクションが表示されるはずです。XAMPPを使用している場合、このURLにある可能性があります。https:///dashboard/phpinfo.php

次に、Yii2構成にMSSQL DBへの接続を追加するだけです。私の場合、データベースはリモートだったので、2番目のDB接続を作成する必要がありました。次の章で、その方法を読んでください。

Yii2プロジェクトで2番目のDBとしてMSSQLデータベースを使用する

2番目のデータベースの追加は、yii-configで次のように行います。

'db' => $db, // the original DB
'db2'=>[
  'class' => 'yii\db\Connection',
  'driverName' => 'sqlsrv',
  // I was not able to specify database like this: 
  // 'dsn' => 'sqlsrv:Server={serverName};Database={dbName}',
  'dsn' => 'sqlsrv:Server={serverName}', 
  'username' => '{username}',
  'password' => '{pwd}',
  'charset' => 'utf8',
],

以上です。これで、次のようにDBをテストできます。

$result = Yii::$app->db2->createCommand('SELECT * FROM {tblname}')->queryAll();
var_dump($result);

MSSQLでは、テーブル名が長くなることがあります。例:CATEGORY.SCHEMA.TBL_NAME

最初のテストモデルは次のようになります(MyMsModel.phpファイル)。

namespace app\models;
use Yii;
use yii\helpers\ArrayHelper;
class MyMsModel extends \yii\db\ActiveRecord
{
  public static function getDb()
  {
    return \Yii::$app->db2; // or Yii::$app->get('db2');
  }
  public static function tableName()
  {
    return 'CATEGORY.SCHEMA.TBL_NAME'; // or SCHEMA.TBL_NAME
  }
}

使用方法

$result = MyMsModel::find()->limit(2)->all();
var_dump($result);

リモートMSSQLテーブルのGiiでモデルを作成する

2番目のデータベースを追加したら(上記参照)、Giiのモデルジェネレーターに移動します。そこで、yii-configで接続名に設定したもの(上記の例では"db2")にDB接続を変更し、テーブル名をSCHEMA.TBL_NAMEの形式で設定します。MSSQLサーバーに複数のデータベースがある場合、そのうちの1つがメインDBとして設定されます。これは使用されると思います。DBの変更には成功していません。DBはDSN文字列で設定できますが、私の場合は効果がありませんでした。

Yii 2におけるPhpExcel/PhpSpreadsheetとバイナリコンテンツのブラウザへの送信

以前の章では、Yii 1でのPhpExcelの使い方を示しました。今回、Yii 2でも必要になり、非常に簡単でした。

注:PhpExcelは非推奨となり、PhpSpreadsheetに置き換えられました。

// 1) Command line:
// This downloads everything to folder "vendor"
composer require phpoffice/phpspreadsheet --prefer-source
// --prefer-source ... also documentation and samples are downloaded 
// ... adds cca 40MB and 1400 files 
// ... only for devel system

// 2) PHP:
// Now you can directly use the package without any configuration:
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();

// Uncomment following rows if you want to set col width:
//$sheet->getColumnDimension('A')->setAutoSize(false);
//$sheet->getColumnDimension('A')->setWidth("50");

$sheet->setCellValue('A1', 'Hello World !');

$writer = new Xlsx($spreadsheet);

// You can save the file on the server:
// $writer->save('hello_world.xlsx'); 

// Or you can send the file directly to the browser so user can download it:
// header('Content-Type: application/vnd.ms-excel'); // This is probably for older XLS files.
header('Content-Type: application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); // This is for XLSX files (they are basically zip files).
header('Content-Disposition: attachment;filename="filename.xlsx"');
header('Cache-Control: max-age=0');
$writer->save('php://output');
exit();

DbCreatorによるXLSXをブラウザに送信する方法に関するアイデアに感謝します。しかし、exit()やdie()を呼び出すべきではありません。リンクを参照してください。

以下は、Yii2のrenderPhpFile()メソッドを起源とする私のアイデアです。

ob_start();
ob_implicit_flush(false);
$writer->save('php://output');
$file = ob_get_clean();

return \Yii::$app->response->sendContentAsFile($file, 'file.xlsx',[
  'mimeType' => 'application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  'inline' => false
]);

これも私の場合、機能しました。

$tmpFileName = uniqid('file_').'.xlsx';
$writer->save($tmpFileName);    
header('Content-Type: application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 
header('Content-Disposition: attachment;filename="filename.xlsx"');
header('Cache-Control: max-age=0');
echo file_get_contents($tmpFileName);
unlink($tmpFileName);
exit();

注:しかし、exit()やdie()を呼び出すべきではありません。「DbCreator」のリンクを参照してください。

PDF - UTF + 1D & 2Dバーコード - TCPDF

他のPDF作成ツールについては、このガイドの第1部を参照してください。

TCPDFは2002年(だと思います)に作成され、現在(2020年)は最新のPHPアプリケーションに書き換えられています。両方について説明しますが、古いバージョンから始めましょう。

古いバージョンのTCPDF

GitHubからダウンロードしてフォルダに保存します。

{projectPath}/_tcpdf

web/index.phpに以下を追加します。

require_once('../_tcpdf/tcpdf.php');

これで、任意の例を使用してTCPDFをテストできます。例えば:https://tcpdf.org/examples/example_001/

注:コンストラクタをバックスラッシュ付きで呼び出す必要があります。

$pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

注:テキストは複数のメソッドを使用して印刷されます - 詳細についてはtcpdf.phpファイルを参照してください。

  • writeHTMLCell()
  • Multicell()
  • writeHTML()
  • Write()
  • Cell()
  • Text()

注:ファイルをUTF8 BOMなし形式で保存して、PDFでアクセント文字が正しく表示されるようにします。

新しいTTFフォントのインポートは、このように行います。

// this command creates filed in folder _tcpdf\fonts. Use the filename as the fontname in other commands.
$fontname = \TCPDF_FONTS::addTTFfont("path to TTF file", 'TrueTypeUnicode', '', 96);

これで、PHPでこのように使用できます。

$pdf->SetFont($fontname, '', 24, '', true);

またはHTMLで

<font size="9" face="fontName" style="color: rgb(128, 128, 128);">ABC</font>

レンダリングは、このように行います。

$pdf->writeHTML($html);

注:ページ番号と総ページ数をフッターに印刷する場合、例3に示されているように、writeHTML()はgetAliasNumPage()とgetAliasNbPages()メソッドを正しく解釈できませんでした。Text()レンダリングメソッドを使用し、数値をこのように配置する必要がありました。

$this->writeHTML($footerHtmlTable);
$this->SetTextColor('128'); // I have gray pageNr
$this->Text(185, 279, 'Page ' . $this->getAliasNumPage() . '/' . $this->getAliasNbPages());
$this->SetTextColor('0'); // returning black color

新しいバージョンのTCPDF

…作成中…

カスタムフォーマッタ - asDecimalOrInteger

PDF請求書を生成する場合、多くの数値が含まれ、小数点以下がない場合は整数として印刷する方が見栄えが良く、スペースも節約できます。例えば、24.00よりも24の方が優れています。そこで、このようなフォーマッタを作成しました。元のインスピレーションと方法は、ここで見つけました。

私のフォーマッタは次のようになります。

<?php

namespace app\myHelpers;

class MyFormatter extends \yii\i18n\Formatter {

  public function asDecimalOrInteger($value) {
    $intStr = (string) (int) $value; // 24.56 => "24" or 24 => "24"
    if ($intStr === (string) $value) {
      // If input was integer, we are comparing strings "24" and "24"
      return $this->asInteger($value);
    }
    if (( $intStr . '.00' === (string) $value)) {
      // If the input was decimal, but decimals were all zeros, it is an integer.
      return $this->asInteger($value);
    }
    // All other situations
    $decimal = $this->asDecimal($value);
    
    // Here I trim also the trailing zero.
    // Disadvantage is that String is returned, but in PDF it is not important
    return rtrim((string)$decimal, "0"); 
  }

}

使い方は簡単です。上記のリンクを参照して、karpy47にいいね!を送るか、下記を参照してください。

// file config/web.php
'components' => [
    'formatter' => [
        'class' => 'app\myHelpers\MyFormatter',
   ],
],

Yii全体でフォーマッタは1つだけで、それを拡張できます。つまり、さらにメソッドを追加しても、残りのフォーマッタはそのままなので、ドキュメントに記載されている他のすべてのメソッドを使用できます。

親モデルを含むGridViewで子モデルのSUMを表示する

…DBにMySQLビューを追加し、そのためのモデルを作成して、「ParentSearch」モデルで基底クラスとして使用することで、簡単に実現できます。

請求書とその明細書のリストで説明しましょう。請求書は"invoice"テーブル(モデルInvoice)、明細書は"invoice_item"テーブル(モデルInvoiceItem)にあります。これらを結合し、価格(金額)のSUMでソートおよびフィルタリングする必要があります。PHPで計算を避けるために、MySQLビューを用意すれば、DBがそれを行ってくれます。

CREATE VIEW v_invoice AS
SELECT invoice.*, 
SUM(invoice_item.units * invoice_item.price_per_unit) as amount,
COUNT(invoice_item.id) as items
FROM invoice 
LEFT JOIN invoice_item 
ON (invoice.id = invoice_item.id_invoice)
GROUP BY invoice.id

注:ここでは、LEFT JOINでCOUNT(*)を使用しない方が良い理由について説明しています。

これは技術的には元のテーブル"invoice"を"v_invoice"に複製し、"amount"と"items"という2つの計算された列を追加します。これで、このビューをテーブル(読み取り専用)として簡単に使用し、GridViewに表示できます。既に"invoice"テーブルのGridViewがある場合、変更はごくわずかです。このモデルを作成します。

<?php
namespace app\models;
class v_Invoice extends Invoice
{
    public static function primaryKey()
    {
        // here is specified which column(s) create the fictive primary key in the mysql-view
        return ['id']; 
    }
    public static function tableName()
    {
        return 'v_invoice';
    }
}

…そして、InvoiceSearchモデルで、Invoiceをv_Invoiceに置き換え(2箇所だと思います)、これらの新しい列に対するルールを追加します。例:

public function rules()
{
  return [
    // ...
    [['amount'], 'number'], // decimal
    [['items'], 'integer'],
  ];
}

amountまたはitemsでフィルタリングする場合は、search()メソッドに条件を追加します。

if (trim($this->amount)!=='') {
  $query->andFilterWhere([
    'amount' => $this->amount
  ]);
}

GridViewでは、"amount"列と"items"列をネイティブ列として使用できます。フィルタリングとソートが機能します。

危険:関連する列による検索とソートの方法を以下で説明します。MySQLを別のテーブルと結合する必要がある場合、これは機能しなくなる可能性があります。

このアプローチが目標達成に最も簡単な方法だと信じています。利点は、MySQLビューはsearch()メソッドが呼び出された場合、つまり請求書のリストの場合にのみ使用されることです。元のInvoiceモデルを使用するため、Webの他の部分は影響を受けません。しかし、Invoiceモデルから特別なメソッドが必要な場合は、v_Invoiceにもあります。データが保存または変更された場合は、常に元のテーブル"invoice"を変更する必要があります。

関連する列によるソートと検索

請求書のテーブルと会社のテーブルがあるとします。それらは関連しており、請求書のリストと各行に対応する会社名を表示したいとします。この列でフィルタリングおよびソートしたいとします。

あなたのGridView

<?= GridView::widget([
// ...
  'columns' => [
    // ...
    [
      'attribute'=>'company_name',
      'value'=>'companyRelation.name',
    ],

あなたのInvoiceSearchモデル

class InvoiceSearch extends Invoice
{
  public $company_name;
  
  // ...
  
  public function rules() {
    return [
      // ...
      [['company_name'], 'safe'],
    ];
  }             

  // ...
  
  public function search($params) {
    // ...

    // You must use joinWith() in order to have both tables in one JOIN - then you can call WHERE and ORDER BY on the 2nd table. 
    // Explanation here:
    // https://stackoverflow.com/questions/25600048/what-is-the-difference-between-with-and-joinwith-in-yii2-and-when-to-use-them
    
    $query = Invoice::find()->joinWith('companyRelation');

    // Appending new sortable column:
    $sort = $dataProvider->getSort(); 
    $sort->attributes['company_name'] = [
      'asc' => ['table.column' => SORT_ASC],
      'desc' => ['table.column' => SORT_DESC],
      'label' => 'Some label',
      'default' => SORT_ASC            
    ];

    // ...
 
    if (trim($this->company_name)!=='') {
      $query->andFilterWhere(['like', 'table.column', $this->company_name]);
    }
  }

バイナリデータをファイルとしてブラウザに送信する - base64デコード

Yii v1のチュートリアルでは、ヘッダーを手動で送信してからexit()を呼び出す方法を紹介しました。しかし、exit()やdie()を呼び出すのは良い考えではないため、Yii v2でより良い方法を発見しました。 安全な(秘密の)ファイルダウンロードの章を参照してください。

動機:base64を使用して文字列にエンコードされたPDFファイルを受け取る場合があります。例えば、FedEx、DPD、その他の配送会社からのバーコード付きラベルで、ユーザーにラベルを表示する必要があります。

私の場合、このアルゴリズムが機能しました。

$pdfBase64 = 'JVBERi0xLjQ ... Y0CiUlRU9GCg==';

// First I create a fictive stream in a temporary file
// Read more about PHP wrappers: 
// https://www.php.net/manual/en/wrappers.php.php 
$stream = fopen('php://temp','r+');

// Decoded base64 is written into the stream
fwrite($stream, base64_decode($pdfBase64));

// And the stream is rewound back to the start so others can read it
rewind($stream);

// This row sets "Content-Type" header to none. Below I set it manually do application/pdf.
Yii::$app->response->format = Yii::$app->response::FORMAT_RAW;
Yii::$app->response->headers->set('Content-Type', 'application/pdf');
      
// This row will download the file. If you do not use the line, the file will be displayed in the browser.
// Details here:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Downloads
// Yii::$app->response->headers->set('Content-Disposition','attachment; filename="hello.pdf"'); 
    
// Here is used the temporary stream
Yii::$app->response->stream = $stream;

// You can call following line, but you don't have to. Method send() is called automatically when current action ends:
// Details here:
// https://yii.dokyumento.jp/doc/api/2.0/yii-web-response#sendContentAsFile()-detail
// return Yii::$app->response->send(); 

注:必要に応じて、さらにヘッダーを追加できます。以前の記事(上記リンク)を確認してください。

]]>
0
[wiki] Pantahub経由でRaspberry Pi3(RPI3)でYii2の使用を開始する 2020年12月22日火曜日 14:57:34 +0000 https://yii.dokyumento.jp/wiki/2557/start-using-yii2-in-raspberry-pi3-rpi3-via-pantahubhttps://yii.dokyumento.jp/wiki/2557/start-using-yii2-in-raspberry-pi3-rpi3-via-pantahub sirin_ibin sirin_ibin
  1. 6つの手順に従って、Yii2をデプロイする準備ができたRPI3デバイスを作成します。
  2. 5つの手順に従って、デバイスにYii2アプリをデプロイします。

注:Pantahubは、Linuxファームウェアを共有およびデプロイできる唯一の場所です。Pantahubはこちらでサインアップできます。http://www.pantahub.com

6つの手順に従って、Yii2をデプロイする準備ができたRPI3デバイスを作成します

手順1:RPI3の初期安定版イメージをSDカードに書き込みます
a) RPI3イメージをダウンロードします

ダウンロードをクリック:https://pantavisor-ci.s3.amazonaws.com/pv-initial-devices/tags/012-rc2/162943661/rpi3_initial_stable.img.xz

b) デバイスイメージの解凍

$ unxz rpi3_initial_stable.img.xzを実行します。

c) Raspberry Pi Imager 1.2を使用してイメージをSDカードに書き込みます

手順2:RPI3を起動します
a) SDカードを挿入し、電源を供給します

手順3:Pantahubはこちらでサインアップします http://www.pantahub.com
手順4:CLIツール「pvr」をダウンロードしてインストールします

注:pvrは、Pantahubプラットフォームを介してデバイスとやり取りするために使用できるCLIツールです。

注:pvrを使用すると、gitツリーのように簡単にファームウェアとプロジェクトを共有できます。

注:ダウンロード後、pvrバイナリをbinフォルダに移動します。

Linux(AMD64):ダウンロード

Linux(ARM32v6):ダウンロード

Darwin(AMD64):ダウンロード

pvr clone; pvr commit; pvr post

GitHubのソースコードからインストール:$ go get gitlab.com/pantacor/pvr $ go build -o ~/bin/pvr gitlab.com/pantacor/pvr

注:GitHubのソースコードからpvrをビルドするには、「GOLANG」がシステムにインストールされている必要があります。

手順5:デバイスを検出してクレームします
a) RPI3とコンピュータ/ルーター間にLANケーブルを接続します

b) ターミナルを開き、$ pvr scanを実行します

c) デバイスをクレームします

$ pvr claim -c merely-regular-gorilla https://api.pantahub.com:443/devices/5f1b9c44e193a Amazon Prime Videoで今すぐ視聴 5000afa9901

d) Panthub.com にログインし、新しくクレームされたデバイスがダッシュボードに表示されているかどうかを確認します。

ステップ6: デバイスのクローンURLを使用して、デバイスをコンピューターに複製します。

$ pvr clone https://pvr.pantahub.com/sirinibin/presently_learning_pelican/0 presently_learning_pelican

これで、デバイスにYii2アプリをデプロイする準備ができました。

次の5つのステップに従って、Yii2アプリをデバイスにデプロイします。

ステップ1: デバイスのルートディレクトリに移動します。
 `$ cd presently_learning_pelican`
ステップ2: デバイスに新しいアプリ「yii2」を追加します。

>sirinibin/yii2-basic-arm32v7:latest は、ARM32アーキテクチャ搭載のデバイス向けに作成されたDockerイメージです。>> カスタムのYii2アプリに合わせてDockerイメージをカスタマイズできます。(Amazon Prime Videoでの視聴は現時点では関係ありません)

$ pvr app add yii2 --from=sirinibin/yii2-basic-arm32v7:latest

ステップ3: 変更をデバイスにデプロイします。

$ pvr add . $ pvr commit $ pvr post

ステップ4: Pantahub.comのダッシュボードでデバイスのステータス変更を確認し、「**完了**」ステータスになるまで待ちます。

ステータス1

ステータス2

ステータス3

ステータス4

ステップ5: 「yii2」アプリのデプロイを確認します。

WebブラウザでデバイスのIPアドレス( http://10.42.0.231/myapp1/web/ )にアクセスします。

完了です!

]]>
0
[wiki] Yii2 - Bootstrap 4へのアップグレード 2020年3月20日 12:18:55 +0000 https://yii.dokyumento.jp/wiki/2556/yii2-upgrading-to-bootstrap-4https://yii.dokyumento.jp/wiki/2556/yii2-upgrading-to-bootstrap-4 RichardPillay RichardPillay

Yii2 - Bootstrap3からBootstrap4への変換

この記事は、変換プロセスが比較的容易である一方で、いくつかの小さな問題が存在するため書かれました。これらの問題は解決するのが難しくありませんが、問題の所在がすぐに明らかになるわけではありません。

1 - Bootstrap4のインストール 私の好みは、composerを使用することです。プロジェクトのルートにあるcomposer.jsonを変更します。

  • Bootstrap3を含む行を探します。
  • その行をコピーし、新しい行を作成します。

    • bootstrapをbootstrap4に変更します。
    • 次に、Github上のYii2リポジトリであるhttps://github.com/yiisoft/にアクセスします。
      • bootstrapを検索し、Bootstrap 4のリポジトリを見つけて現在のバージョンを確認します。2020年1月現在、https://github.com/yiisoft/yii2-bootstrap4では、現在のバージョンは2.0.8でした。
    • バージョン文字列をそのバージョン番号に変更し、~を^に変更します。
    • その後、以下のようになるはずです(バージョン番号はさらに高い可能性があります)。

      "yiisoft/yii2-bootstrap" : "~2.0.6", "yiisoft/yii2-bootstrap4" : "^2.0.8",

  • ファイルを保存して「composer update」を実行します。
  • IDE、テキストエディター、または利用可能なその他の手段を使用して、bootstrapが使用されているすべての箇所を見つけ、bootstrap4に変更します。yii\bootstrap\という文字列を検索してyii\bootstrap4\に変更することをお勧めします。ただし、注意が必要です。IDEではバックスラッシュをエスケープする必要がある場合があります。たとえば、Eclipseでは文字列を含むすべてのファイルを簡単に検索できますが、検索文字列には二重のバックスラッシュを使用する必要があります。一方、置換文字列は単一のバックスラッシュのままにする必要があります。
  • 次に、すべてのテストを実行して発生した問題を修正します。ほとんどの失敗は、Navbarが機能しなくなったことが原因です。Navbarは存在しますが、レンダリング方法が異なり、私の場合、非表示になっていました。これは、Bootstrap4でNavbarの一部の要素が変更されたためです。私の場合、14個のテストが失敗しました。その多くは、ログインリンクの有無を確認するなど、何らかの方法でNavbarの内容を使用していたことが原因でした。
    • https://bootstrap.dokyumento.jp/docs/4.0/migration/ を参照して、これらの問題を理解する必要があります。特に、Navbarで何が変更されたかを確認してください。最も重要なのは、Bootstrap3では背景が指定されていましたが、Bootstrap4では指定されなくなったことです。
    • エディターでfrontend/views/layouts/main.phpを開き、ブラウザでサイトを確認します。私の場合、ブランドを除いてNavbarが表示されませんでしたが、これはYii2テンプレートの一部として提供されたものから変更したためで、背景が含まれていました。残りの部分は標準だったため、他に何もありませんでした。リボンストリップもメニュー項目もありませんでしたが、その領域にマウスポインターを合わせると、リンクが存在し、クリックできることがわかりました。
      • NavBar::beginで始まる行を探し、そのクラスオプションを確認します。私の場合、元のものは'class' => 'navbar-inverse navbar-fixed-top'でした。
        • 前述のように、背景が含まれていないため、bg-darkを追加して再度確認します。これでリボンが戻ってきましたが、メニュー項目はありません。
        • リボンを右クリックして「要素を検査」を選択するか、ブラウザでページソースを検査する必要がある操作を実行します。これにより、Navbarの動作に関する手がかりが得られます。これを見て、Bootstrap4の移行ガイドを参照すると、navbar-inverseとnavbar-fixed-topのどちらも機能していないように思えました。そこで、これらを取り除き、ページを更新して変更がないことを確認しました。
        • BootstrapのWebサイトでさらに調べると、前述のbg-darkと、テキスト用のnavbar-lightまたはnavbar-darkが見つかりました。
        • これでメニュー項目はありませんでしたが、メニューを展開するボタンがありました。そのプロパティを調べると「navbar-toggler」であることがわかり、BootstrapのWebサイトによると、これはBootstrap4の新機能であり、デフォルトで折りたたまれており、「navbar-expand」を使用するとデフォルトで展開されることがわかりました。これは素晴らしいです。ログインユーザーがどちらを好むかを選択できる設定を追加しようと思っています。最終的に、画面幅が狭くない限り展開されたままにするnavbar-expand-mdを選択しました。

これですべての結果、元のNavbarと非常によく似たNavbarを与えるクラス行に変更しました。

        //Bootstrap3: 'class' => 'navbar-inverse navbar-fixed-top',
        //Changed for Bootstrap4: 
        'class' => 'navbar navbar-expand-md navbar-light bg-dark',


パンくずリスト

**注記 - 2020年3月**: パンくずリストに関するこのセクション全体は、もはや問題ではない可能性があります。チュートリアルとしてこのセクションを残していますが、変更を加える前に、ユーザーコメントでDavideが言っていることを読んでください。

これでNavbarが修正されました。次に、パンくずリストが正しくないことに気づきました。パス要素を区切るスラッシュがなくなっていました。多くのデバッグに備えて、Bootstrapサイトに少しインスピレーションを求めて行きました。それ以上調べる必要はありませんでした。Bootstrap 4では、パンくずリストの各要素に「breadcrumb-item」クラスを付ける必要があります。問題を理解するためにvendors/yiisoft/yii2/widgets/Breadcrumbs.phpを少し調べてから、itemTemplateとactiveItemTemplateを変更するだけでよいことがわかりました。もちろん、これらはYii2フレームワークの一部であるため、このファイルを変更したくありません。変更すると、いつか更新され、変更がすべて失われる可能性があります。これらの属性はどちらも公開されているため、クラスの外側から変更でき、最も簡単な場所はfrontend/views/main.phpです: `html

<div class="container">
    <?= Breadcrumbs::widget([
        'itemTemplate' => "\n\t<li class=\"breadcrumb-item\"><i>{link}</i></li>\n", // template for all links
        'activeItemTemplate' => "\t<li class=\"breadcrumb-item active\">{link}</li>\n", // template for the active link
        'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
    ]) ?>
    <?= Alert::widget() ?>
    <?= $content ?>
</div>```


**データグリッドのアクションカラム** 私のページの1つは、giiによって生成されたデータグリッドでした。各行には、行の表示、編集、または削除をクリックできるボタンのセットがあります。Bootstrap 4では、ActionColumnが表示されなくなりました。ページソースを見ると、存在していましたが、表示もクリックもできませんでした。移行ガイドを見ると、Bootstrap 3にはアイコンが含まれていますが、Bootstrap 4には含まれていないことがわかりました。Yii2フォーラムで尋ねられた質問から多くの助けを得ました。最終的に、composer.jsonのrequireセクションに "fortawesome/font-awesome": "^5.12.1"という行を含めることによってFontAwesome 5のローカルコピーを取得し、必要なアイコンを選択することで解決しました。これを行う方法を理解するのに多くの時間を費やしましたが、終わってみると、その単純さにほとんど拍子抜けしました。データフォームで実行した操作は次のとおりです。

            ['class' => 'yii\grid\ActionColumn',
                'buttons' => [
                    'update' =>  function($url,$model) {
                        return Html::a('<i class="fas fa-edit"></i>', $url, [
                            'title' => Yii::t('app', 'update')
                        ]);
                    },
                    'view' =>  function($url,$model) {
                        return Html::a('<i class="fas fa-eye"></i>', $url, [
                            'title' => Yii::t('app', 'view')
                        ]);
                    },
                    'delete' => function($url,$model) {
                        return Html::a('<i class="fas fa-trash"></i>', $url, [
                            'title' => Yii::t('app', 'delete')
                        ]);
                    }
                 ]
            ],


機能テスト

視覚的にはそれ以上何も見えず、少なくとも明らかなものは何もなかったので、テストスイートを実行しました。これらはすべて以前はパスしていましたが、現在はいくつか失敗しました。その1つはコンタクトフォームだったので、それを個別に実行すると、エラーメッセージが見つからないため失敗しているとテストで通知されました。

1) ContactCest: Check contact submit no data
 Test  ../frontend/tests/functional/ContactCest.php:checkContactSubmitNoData
 
 Step  See "Name cannot be blank",".help-block"
 
 Fail  Element located either by name, CSS or XPath element with '.help-block' was not found.


一方、私はフォームでエラーメッセージを見ることができたので、ブラウザのページソースを使用して、cssクラスが「help-block」ではなく「invalid-feedback」に変更されていることを発見しました。簡単です。frontend/tests/_support/FunctionalTester.phpで、期待されるcssクラスを変更しました。

public function seeValidationError($message)
{
    $this->see($message, '.invalid-feedback');
}

もちろん、この短い抜粋は単なる例です。同じことをいくつかの場所で実行する必要がありましたが、すべて簡単に検索して解決できました。


その後、テストを実行しても他の問題は指摘されませんでしたが、他の問題が**ない**という意味ではないと予想しています。現時点ではすべて正常に動作しているように見えますが、さらに多くの問題が隠れていると予想しています。しかし、何らかの理由で、それらの問題はもはやそれほど困難には思えなくなりました。

]]>
0