CleverStyle FrameworkのCRUDおよび関連操作

データベースを操作するための基本的なインターフェイスについて説明した記事の後に、作業用の高レベルツールの提案に関する十分なコメントがありました。 CleverStyle Frameworkには、 cs\CRUD



およびcs\CRUD_helpers



の形式の同様のツールがあります。 これらを組み合わせることで、かなり典型的な状況で、テンプレートコードの大きなシートを1つの関数呼び出しで置き換えることができます。 この記事では、それが何であり、どのようなタスクセットを解決できるかについて説明します。







cs \ CRUD-基本



この特性には、使用する4つの主なメソッドがあります: create()



read()



update()



およびdelete()



。 コメントなしでそれらをどうするかは明確で、呼び出し形式は次​​のとおりです。







 ->create($arguments : mixed[]) ->create(...$arguments : mixed[]) ->read($id : int|int[]|string|string[]) ->update($arguments : mixed[]) ->update(...$arguments : mixed[]) ->delete($id : int|int[]|string|string[])
      
      





単一の要素と要素の配列の両方を読み取りおよび削除できます。 要素を作成および更新するとき、一連の引数または配列の形式の単一の引数を使用できます(キーの任意の順序でのインデックス付きおよび連想の両方を使用できます)。 要素を作成するときの別のニュアンス:引数(配列キー)の数がテーブルモデルの要素の数に対応する場合、識別子は明示的に指定されますが、1より小さい場合、識別子はデータベースによって自動的に生成されます。







これらすべてがデータベースと通信するためには、データベース識別子を返す抽象cdb()



メソッドを定義する必要があります。また、 $table



名を持つ$table



プロパティと、テーブル構造(および関連するテーブルがある場合)の説明を持つ$data_model



$data_model



ます。







オプションで、プロパティ$data_model_ml_group



$data_model_files_tag_prefix



を定義して、それぞれ多言語とダウンロード可能なファイルをサポートできます。







$テーブル



メインテーブルの名前(関連テーブルのプレフィックスとしても使用)、たとえば:







  protected $table = '[prefix]shop_items';
      
      





$ data_model



例で説明する最も簡単な方法:







  protected $data_model = [ 'id' => 'int', 'date' => 'int', 'category' => 'int', 'price' => 'float', 'in_stock' => 'int', 'listed' => 'int:0..1', 'attributes' => [ 'data_model' => [ 'id' => 'int', 'attribute' => 'int', 'numeric_value' => 'float', 'string_value' => 'text', 'text_value' => 'html' ] ], 'images' => [ 'data_model' => [ 'id' => 'int', 'image' => 'text' ] ], 'videos' => [ 'data_model' => [ 'id' => 'int', 'video' => 'text', 'poster' => 'text', 'type' => 'text' ] ], 'tags' => [ 'data_model' => [ 'id' => 'int', 'tag' => 'html' ], 'language_field' => 'lang' ] ];
      
      





サポートされているタイプには、許容範囲に制限のある数字(MySQL / PostgreSQLからの読み取り時に数字に変換されます)、XSSからの自動クリーニングおよび指定された長さを超える場合のトリミング、JSON(書き込みがシリアル化される場合、読み取りが逆シリアル化される場合)、および一部の文字列が含まれます他のバン、サポートされているフィールドのタイプの詳細については、ドキュメントを参照してください







型ではなく配列が指定されている場合、関連するテーブルを処理しています。







リンクされたテーブル



これらは、1対1または1対多の関係を持つ補助データを含むテーブルです。 上記の例では、メインテーブル[prefix]shop_items



があり、データベースの関連attributes



[prefix]shop_items_attributes



として表されます。







data_model



テーブルはネストされたキーdata_model



で記述され、オプションのキーlanguage_field



もあります。これは、関連するデータが言語に依存することを示します(フィールド自体はモデルで指定されません)。データの読み取り/更新は現在の言語を考慮して行う必要があります。







そのような構成での挿入の例:







 $id = $this->create( date(), $category, $price, $in_stock, $listed, [ [$attr1_id, 1, '', ''], //  id  ,         [$attr2_id, 2, '', ''] // ( ,      ) ], [ 'http://example.com/pic1.jpg', //   id  ,        'http://example.com/pic2.jpg' ], [], //    ,   [ 'tag1', //   ,        `lang` 'tag2', // (   ) 'tag3' ] );
      
      





そのような機能を強化するために、データベースでいくつのクエリを作成する必要があるかを想像することしかできません。

読み取り時に、データは同じ形式に変換されます。つまり、 $this->update($changes + $this->read($id))



ます。







CleverStyle Frameworkの多言語コンテンツ



cs\CRUD



で多言語コンテンツのデバイスをさらに詳しく説明する前に、フレームワークでこれが通常どのように解決されるかを一般的な方法で説明する必要があります。







多言語コンテンツを確保するには、通常、 cs \ Textシステムクラスが使用されます。 彼は、許可システムのように、グループとラベルで動作します。 たとえば、管理インターフェイスでは、言語に依存する可能性のあるもの(サイト名、送信された手紙の署名など​​)が同様の方法で実装されます。







 $result = \cs\Text::instance()->set( \cs\Config::instance()->module('System')->db('texts'), 'System/Config/core', 'name', 'New site name' );
      
      





$result



{¶$id}



という形式の行があります。 次に、この行をcs\Text::process()



に渡して、現在の言語(または翻訳が存在する言語cs\Text::process()



のテキストを取得します。







 $site_name = \cs\Text::instance()->process( \cs\Config::instance()->module('System')->db('texts'), $result );
      
      





内部では、2つのテーブルがデータベースで使用され、そのインデックスは最初のパラメーターで渡されます。 最初の[prefix]texts



[prefix]texts_data



group



+ label



を一意の識別子に関連付け、 [prefix]texts_data



には実際に各言語の翻訳が含まれています。







$ data_model_ml_group



一般的に、CleverStyle Frameworkで組み込み多言語コンテンツをどのように使用できるかがわかったので、 $data_model_ml_group



明らかになり$data_model_ml_group



。 これは、 cs\Text::set()



呼び出しに対する2番目の引数にすぎません。 しかし、どうすれば多言語にすべきものとそうでないものを示すことができるでしょうか? このために、 ml:



プレフィックスがデータタイプで使用されます。







上記の例でカテゴリが言語に依存する場合、対応する行を次のように変更します。







  'category' => 'ml:int',
      
      





その結果、ボンネットの下で録音する場合、呼び出しが行われます。







 $category = \cs\Text::set( $this->cdb(), //    $this->data_model_ml_group, 'category', $category );
      
      





そして読むとき:







 $category = \cs\Text::process( $this->cdb(), $category );
      
      





リンクテーブルの場合、リンクテーブル( language_field



指定)で別のフィールドが使用されますが、このメカニズムはそこで使用されません。







CleverStyle Frameworkでアップロードされたファイルを処理する



ダウンロードしたファイルがcs\CRUD



どのように処理されるかを詳細に説明する前に、フレームワークで一般的にどのように解決されるかを説明する必要があります。







すぐに使用できるフレームワークには、ファイルをダウンロードする機能はありません(このような機能は、リポジトリにあるサードパーティモジュールによって提供されます)が、この機能のインターフェイスを定義します。 アップロードされた各ファイルはデータベースに登録され、特定のタグに関連付けることができます。 つまり、フロントエンドでファイルがダウンロードされ、それに応じて絶対パスが届き、それに沿ってダウンロードされたファイルが利用可能になります。 ただし、ファイルが少なくとも1つのタグで署名されていない場合、しばらく時間が経過すると削除されます。







ファイルに署名するには、 System/upload_files/add_tag



を生成する必要があります。対応するモジュールはイベントに応答し、ファイルのタグを追加します。 これをカスタムアバターに使用する方法の例(この機能を提供するモジュールがインストールされている場合にのみ、フロントエンドでオプションを使用できます):







 \cs\Event::instance()->fire( 'System/upload_files/add_tag', [ 'url' => $new_avatar, 'tag' => "users/$user/avatar" ] );
      
      





ファイルが使用されなくなった場合、タグを削除する必要があり、ファイルも削除されます。







 \cs\Event::instance()->fire( 'System/upload_files/del_tag', [ 'url' => $old_avatar, 'tag' => "users/$user/avatar" ] );
      
      





$ data_model_files_tag_prefix



ダウンロードしたファイルが一般的な方法でどのように処理されるかが$data_model_files_tag_prefix



、なぜ$data_model_files_tag_prefix



なのかが明らかになります。 これは、ファイルのタグの追加/削除イベントを生成するときのタグの一般的なプレフィックスにすぎません。







データが挿入/変更されるたびに、 cs\CRUD



はすべてのフィールドとリンクされたすべてのテーブルのフィールドのリンクを分析し、どのリンクが既に存在し、まだリンクしていないかを比較し、内部で次のような呼び出しを生成します







 $clang = \cs\Language:instance()->clang; //   , : en, ru, uk $tag = "$this->data_model_files_tag_prefix/$id/$clang"; \cs\Event::instance()->fire( 'System/upload_files/del_tag', [ 'tag' => $tag, 'url' => $unused_file ] ); \cs\Event::instance()->fire( 'System/upload_files/add_tag', [ 'tag' => $tag, 'url' => $new_file ] );
      
      





リンクを見つけてタグで署名する方法は個別に再利用できます。これらはcs\CRUD



トレイでも利用でき、次の呼び出し形式があります。







 ->find_urls($array : array) : string[] //     ,        ->update_files_tags($tag : string, $old_files : string[], $new_files : string[])
      
      





cs \ CRUDの概要



cs\CRUD



は、多言語構成であっても、開発者からルーチンの膨大なプロットを削除し、多くの典型的な状況に非常にシンプルなインターフェースを提供します。 ただし、機能の一部のみを直接使用できる場合もありますが、この場合でも間違いなくメリットがあります。







cs \ CRUD_helpers



これは、ボンネットの下でcs\CRUD



を使用する補助特性であり、同じ要件があります。

このメソッドが提供する主なものは、次の呼び出し形式のsearch()



メソッド(ただし、これはむしろフィルターです)です。







 ->search($search_parameters = [] : mixed[], $page = 1 : int, $count = 100 : int, $order_by = 'id' : string, $asc = false : bool) : false|int|int[]|string[]
      
      





この方法では、完全一致、いくつかの代替値からの一致、および...から数字までの範囲を検索できます。 同時に、メインテーブルのフィールドと関連テーブルのフィールドの両方がフィルターに参加できます。 さらに、多言語構成の場合、検索機能はこれを考慮し、 [prefix]texts_data



対応するJOIN



[prefix]texts_data









また、結果のページネーションの可能性、列(関連テーブルからも含む)でソートし、1回の検索で結果の数を取得する機能もあります。







次のようになります。







 $this->search([ 'argument' => 'Value', //   'argument2' => ['Value1', 'Value2'], //       'argument2' => [ //   ,     'from' => 2, //   ,  'to' => 5 //   ,  ], 'joined_table' => [ //    ,    'argument' => 'Yes' ] ]);
      
      





ドキュメント内のより多くの例と呼び出し形式の説明、およびいくつかの極端なケースを含むさらに詳細な例は、テスト( 1、2 )で見ることができます(これらは、特性とデータベースのすべての動作を非常によくカバーしています)。







また、 cs\CRUD_helpers



は、クエリを作成して検索を実行するためのより多くのアトミックメソッドが含まれていますcs\CRUD_heplers



ものがない場合に使用できますが、検索メカニズムの既存の部分を再利用したい場合に使用できます。 しかし、これらの方法はまだ正式に文書化されていないため、注意して使用してください。







最後に



タスクがcs\CRUD



およびcs\CRUD_helpers



の機能に適合する場合は、非常に幸運だと考えてください。

1行のSQLを記述する必要はありません。多言語の問題やダウンロードしたファイルを考慮に入れる必要はありません。検索は基本的に行われます。 これで十分でない場合は、少なくともそれがどのように機能するかを研究するか、既製のメソッドを再利用することもできます。







GitHubリポジトリ

» フレームワークのドキュメント

»考えられるすべてのユースケースの追加例としての関連テスト








All Articles