フォーム検証
前回のシリーズでは、コメントを追加するためのフォームを作成しました(そして、元の記事の著者が投稿のコメントの添付ポイントで取得したことに気づきました)。 ここで、セキュリティの基本原則に従う必要があります。ユーザーが入力したデータを信頼しないでください。 したがって、ユーザーがフォームを介して送信するものの検証を編成します。
Symphonyにクラスを生成するように依頼すると、クラスだけでなくフォーム要素も生成されます。 また、データモデルスキーマに基づいて、これらの要素にいくつかのチェックを追加します。 この図では、 タイトルフィールドはblog_postテーブルに必須であるため、ユーザーがこのフィールドに入力せずにフォームを送信しようとしても何も機能しません。 さらに、Symphonyは、このフィールドで255文字を超える文字列を送信できないことを理解します(この場合も、データモデルスキーマからこの知識を引き出します)。
BlogCommentFormクラスのこれらのチェックの一部を置き換え(書き換え、オーバーライド)しましょう。 ファイルを開き(自分で見つけますか?)、configure()メソッドに次の行を追加します。
$ this-> validatorSchema ['email'] = new sfValidatorEmail( 配列( '必須' => false)、 array( 'invalid' => 'メールアドレスが無効です'));
電子メールフィールドのメソッドをオーバーライドすることにより、デフォルトの動作を再定義します。
これで、無効なメールアドレスを入力したときにユーザーが間違っていることをユーザーに説明するためのすべてができました。 フォームが完全になりました! ここでは、これに注意する必要があります。まず、フォームにデータが含まれている場合、次にフォームが送信されると、このデータは特別な方法で保存されます。 したがって、ユーザーが部分的に不正確なデータを含むフォームを送信した場合、フォームに再度入力する必要はありません。 次に、特定のフィールドへの入力時に発生したエラーはこれらのフィールドの横に表示され、フォーム上の一般的なエラーのどこかに表示されることはありません。
ここで、フォームがどのように処理され、データが保存されるかという問題を明確にします。 この難しいケースでは、前回のシリーズで修正したアクションが使用されます。 これらはこのファイルに含まれています。
/sf_sandbox/apps/frontend/modules/comment/actions/actions.class.php:
必要なものは次のとおりです。
$ this-> form = new BlogCommentForm(BlogCommentPeer :: retrieveByPk($ request-> getParameter( 'id'))); if($ request-> isMethod( 'post')) { $ this-> form-> bind($ request-> getParameter( 'blog_comment')); if($ this-> form-> isValid()) { $ blog_comment = $ this-> form-> save(); $ this-> redirect( 'post / show?id ='。$ blog_comment-> getBlogPostId()); } }
フォームクラスのインスタンスを作成すると、次のことが起こります。
- フォームがPOSTメソッドを使用して送信されたことを確認します
- 実際、 blog_comment配列パラメーターが受信されました。 getParameter()メソッドは 、このパラメーターが単一の値ではなく値の配列であることを判別し、連想配列を返します(たとえば、 blog_comment [author]フィールドの値はauthorキーの下のこの配列に書き込まれます)
- 結果の連想配列はフォームにフックされ、このプロセスはbindingと呼ばれます。その結果、この配列の値はフォームクラスのインスタンスの対応するフィールドに入力されます。 その後、フォームの検証が開始され、フィールドごとにフォーム内のデータが正しいかどうかがチェックされます。
- すべてのチェックに合格した場合のみ、データが保存され、ページはshowアクションにリダイレクトされます。
注意! Symphony 1.2では、何かが変更されました(元の記事はSymphony 1.1用に書かれました)。 最初に、フォームの作成とPOSTメソッドの検証は、executeCreateアクションで行われます。
パブリック関数executeCreate(sfWebRequest $ request) { $ this-> forward404Unless($ request-> isMethod( 'post')); $ this-> form = new BlogCommentForm(); $ this-> processForm($リクエスト、$ this->フォーム); $ this-> setTemplate( 'new'); }
おそらく、どのようなアクションが必要かについて混乱が生じるでしょう。 たとえば、 executeNewは、新しいコメントを追加するときのフォーム出力のアクションです。 executeCreateは、新しいコメントを追加するためのフォームを送信するときのデータ処理アクションです。
フィールドを必須にするには、requiredを書き込むだけで十分です。データスキーマファイル(schema.yml)のこのフィールドに対してtrueです。 例えば
作成者:{タイプ:varchar(255)、必須:true}
データ検証の詳細については、 フォーム検証の章をご覧ください。
URL形式を変更する
モジュールとアクションのURLが形成される原理をすでに理解していますか? これらはすべてカスタマイズ可能です。したがって、ユーザーがこれらのアドレスや検索エンジンを見るのがより快適になります。 URLを作成するときに投稿のタイトルを使用することをお勧めします。
問題は、名前にスペースなどの特殊文字が含まれている可能性があることです。 エスケープシーケンスに変換するだけの場合、URLにはugly%20が含まれるので、投稿のタイトルからきれいなURLを作成できるように、BlogPostクラスの新しいメソッドでモデルを拡張する必要があります。 これを行うには、 sf_sandbox / lib / model /フォルダーからBlogPost.phpファイルを開き、以下を追加します:
パブリック関数getStrippedTitle() { $ result = strtolower($ this-> getTitle()); //単語以外の文字をすべて削除します $ result = preg_replace( '/ \ W /'、 ''、$ result); //すべての空白部分をダッシュで置き換えます $ result = preg_replace( '/ \ + /'、 '-'、$ result); //ダッシュをトリムします $ result = preg_replace( '/ \-$ /'、 ''、$ result); $ result = preg_replace( '/ ^ \-/'、 ''、$ result); return $ result; }
ロシアの投稿タイトルから適切な音訳を作成するために、いくつかの置換を追加するのは簡単だと思います。
次に、 投稿モジュールに対してパーマリンクアクションを実行する必要があります。 sf_sandbox / apps / frontend / modules / post / actions / actions.class.phpに新しいメソッドを追加します:
パブリック関数executePermalink($リクエスト) { $ posts = BlogPostPeer :: doSelect(新しい基準()); $ title = $ request-> getParameter( 'title'); foreach($投稿を$投稿として) { if($ post-> getStrippedTitle()== $ title) { $ request-> setParameter( 'id'、$ post-> getId()); return $ this-> forward( 'post'、 'show'); } } $ this-> forward404(); }
質問! みんな、私はこれがそのようなプログラムへの単なる錫であることを理解しています! 各レコードについて、数百のレコードの残りを選択して探します。必要なものはそれらの中にありますか? 特定のタイトルのIDを適切に選択する方法はありますか? または、私は無駄に心配していて、シンフォニーキャッシングサブシステムはすべてを正しく行いますか?
投稿のリストは、各投稿の表示の代わりにパーマリンクアクションを呼び出すことができるようになりました。 sf_sandbox / apps / frontend / modules / post / templates / indexSuccess.phpファイルで、投稿IDの列を削除し、 これから タイトルが表示されているセルの内容を置き換えます:
<td> <?php echo $ blog_post-> getTitle()?> </ td>
これに:
<td> <?php echo link_to($ blog_post-> getTitle()、 '@post?title ='。$ blog_post-> getStrippedTitle())?> </ td>
あと1ステップだけです: sf_sandbox / apps / frontend / config /フォルダーにあるrouting.ymlを編集し、最初にルールを追加します:
list_of_posts: url:/ latest_posts param:{モジュール:投稿、アクション:インデックス} 投稿: url:/ blog /:タイトル param:{モジュール:投稿、アクション:パーマリンク}
次に、ブラウザを調べて、動作中の新しいURLを確認します。 エラーが突然発生した場合、キャッシュをクリアする必要があります-これらのルーティングルールはまだ機能し始めていません。 これがどのように行われるかについては、すでに述べました。
$ php symfony cc
スマートURLの章のアドレスについて読んでください。
フロントエンドのクリーニング(パブリックパート)
わかりました、私達のブログはより美しくなっています。 しかし、これは不運です:賢明な人は誰でも簡単に立ち入り、今すぐ投稿を修正できます。 あなたが想像するかもしれないように、それを話題にしないでください。 一般的に、今度は投稿とコメントを編集するためのすべての機能を公開部分から削除する必要があります(後で-管理パネルに追加します)。
sf_sandbox / apps / frontend / modules / post / templates / showSuccess.phpテンプレートで 、投稿を編集するためのリンクを削除します。 そこで削除する必要があるものを見つけてください(誰が完全に戦車にいるのか、これらの行は元の記事にあります)。
sf_sandbox / apps / frontend / modules / post / templates / indexSuccess.php templateに対しても同じことを行います。そこで、投稿を作成するためのリンクを削除します(タンカーは元の記事でこの場所を探します)。
当然、リンクの削除を取り除くことはありません。 機能も削除する必要があります。 sf_sandbox / apps / frontend / modules / post / actions / actions.class.phpを開き 、 executeEditおよびexecuteDeleteアクションを削除します。
注! Symphony 1.2では、executeUpdateアクションも削除する必要があります。 誰もがすべてを注意深く読んだ、彼はすでにそれについて推測した。
これで、公開部分から追加できるようになりましたが、投稿を編集することはできません。 コメントは自分で処理できると思います。
管理パネルの作成
そして、誰かが私たちのブログで人種の不平等について書き始めたら? または、「+ 1」の精神でコメントを残しますか? すべてのゴミをブログから削除できるツールが必要です。 まあ、気分によると、タイプミスを修正します。 管理パネルが必要です。
管理者は別のアプリケーション(アプリケーション)であり、作成する必要があります。 コマンドプロンプトで実行します。
$ php symfony generate:アプリバックエンド $ php symfony propel:init-adminバックエンドポストBlogPost $ php symfony propel:init-adminバックエンドコメントBlogComment
お気づきではないかもしれませんが、 adminジェネレーターを使用しました。 実際、追加、編集、削除のフォームを作成するよりもはるかに複雑で興味深いことを行うために使用できます。 ご自由にお読みください。
フロントエンドアプリケーションで行ったのと同じ方法で、メインテンプレート(レイアウト)( apps / backend / templates / layout.php )を編集し、グローバルナビゲーションを追加します。
<div id = "navigation"> <ul style = "list-style:none;"> <li> <?php echo link_to( 'Posts'、 'post / index')?> </ li> <li> < ?php echo link_to( 'Comments'、 'comment / index')?> </ li> </ ul> </ div> <div id = "content"> <?php echo $ sf_data-> getRaw( 'sf_content' )?> </ div>
次のように入力して、開発環境の管理領域にアクセスできます。
http://localhost/sf_sandbox/web/backend_dev.php/post
ここでは、管理パネルジェネレーターの優れた機能が発揮されます。これは、構成を編集することで巧妙かつ巧妙に使用できます。 sf_sandbox / apps / backend / modules / post / config / generator.ymlファイルの内容を以下で置き換えます:
ジェネレーター: クラス:sfPropelAdminGenerator param: model_class:BlogPost テーマ:デフォルト フィールド: タイトル:{名前:タイトル} 抜粋:{名前:抜粋} 本体:{名前:本体} nb_comments:{名前:コメント} created_at:{名前:作成日} リスト: title:投稿リスト レイアウト:表 表示:[=タイトル、抜粋、nb_comments、created_at] object_actions: _edit:〜 _delete:〜 max_per_page:5 フィルター:[title、created_at] 編集: title:投稿の詳細 フィールド: タイトル:{タイプ:input_tag、パラメーター:サイズ= 53} 抜粋:{type:textarea_tag、params:size = 50x2} body:{type:textarea_tag、params:size = 50x10} created_at:{type:input_date_tag、params:rich = on}
Look:blog_postテーブルのフィールドの中から、管理者はnb_commentsのフィールド(またはゲッターメソッド)を探します。 これは保存された値ではなく、生成された値であるため、モデルにゲッターメソッドを追加する必要があります( sf_sandbox / lib / model / BlogPost.php ):
パブリック関数getNbComments() { 戻りカウント($ this-> getBlogComments()); }
管理パネルを更新して、変更を楽しんでください:
管理パネルへのアクセスを制限します
前と同じように、賢明な人なら誰でも管理パネルに入り、Ksenia Sobchakに関するすべての投稿を消去できます。 彼にこれをさせてはいけません。パスワードは管理パネルを保護します。 apps / backend / config /フォルダーで、 security.ymlファイルを編集し、次のファイルを書き込みます。
すべて: is_secure:on
ログインせずに管理モジュールに入ることはできません。 待ってください。どこでパスワードと一般的にあらゆる形態の認証登録でログインできますか? 素晴らしいソリューション-プラグインがあります! これらの問題に対処するプラグイン-sfGuardPluginを使用します。 コマンドラインに次のように記述します。
$ php symfonyプラグイン:sfGuardPluginのインストール
PEARがインストールされていない場合、ここで問題が発生する可能性があります。 それをインストールする時間です。
このコマンドは、Symphonyプラグインリポジトリからプラグインをダウンロードします。 最後に、すべてがうまくいったというメッセージが表示されるはずです。
$ php symfonyプラグイン:sfGuardPluginのインストール >>プラグインインストールプラグイン "sfGuardPlugin" >> sfPearFrontendPluginチャンネル「pear.symfony-project.com」を発見しようとしています... >> sfPearFrontendPluginダウンロードchannel.xml ... >> sfPearFrontendPlugin channel.xmlのダウンロードを開始(663バイト) >> sfPearFrontendPlugin。 >> sfPearFrontendPlugin ... done:663バイト >> sfPearFrontendPlugin自動検出されたチャンネル「pear.symfony-project.com」、エイリアス >> sfPearFrontendPlugin "symfony"、レジストリに追加 >> sfPearFrontendPluginチャンネルを発見しようとしています >> sfPearFrontendPlugin "plugins.symfony-project.org" ... >> sfPearFrontendPluginダウンロードchannel.xml ... >> sfPearFrontendPlugin channel.xmlのダウンロードを開始(639バイト) >> sfPearFrontendPlugin ... done:639バイト >> sfPearFrontendPlugin自動発見チャンネル「plugins.symfony-project.org」、エイリアス >> sfPearFrontendPlugin "symfony-plugins"、レジストリに追加 >> sfPearFrontendPluginダウンロードsfGuardPlugin-2.2.0.tgz ... >> sfPearFrontendPlugin sfGuardPlugin-2.2.0.tgz(18,589バイト)のダウンロードを開始 >> sfPearFrontendPlugin ... done:18,589バイト >> sfSymfonyPluginManagerプラグイン「sfGuardPlugin」のインストールが成功しました
次に、プラグインを有効にする必要があります。 sf_sandbox / apps / backend / config / settings.ymlファイルを編集し、次のようにシステムログインをオンにします。 all:キーのすべてのコメントを解除し、次を追加します。
#(ここにあるもの) すべて: .actions: login_module:sfGuardAuth#認証されていないユーザーが呼び出されたときに呼び出される login_action:signin#安全なページへのアクセスを試みます secure_module:sfGuardAuth#ユーザーが持っていないときに呼び出される secure_action:secure#アクションに必要な資格情報 .settings: enabled_modules:[デフォルト、sfGuardAuth、sfGuardGroup、sfGuardPermission、sfGuardUser]
次に、新しいシステムユーザーを追加し、次のすべての代わりにsf_sandbox / apps / backend / lib / myUser.class.phpファイルに書き込みます 。
クラスmyUserはsfGuardSecurityUserを拡張します { }
次に、モデル、フォーム、フィルターを再作成し、データベースを更新する必要があります。
$ php symfony propel:ビルドモデル $ php symfony propel:ビルドフォーム $ php symfony propel:ビルドフィルター $ php symfony propel:build-sql $ php symfony propel:insert-sql
前と同様に、 propel:insert-sqlジョブを実行すると、Styphoniaはすべてのテーブルを削除し、それらを再度作成します。 これは開発中に非常に頻繁に発生するため、初期データとテストデータをフィクスチャに書き込むことは理にかなっています(詳細については、データベースに入力する章を参照)。
ここでも、キャッシュをクリアする必要があります。 その後、最後に、新しいユーザーを作成します。
$ symfony guard:create-user habr oh_no_123456
注:何らかの理由で、アプリケーションの名前は、元のテキストのこのコマンドのパラメーターにも示されています。 おそらくそれは以前に必要でしたが、1.2では間違いなく必要ではありません。
次に、管理パネルに入ったときに、 ポスト管理モジュールにデフォルトモジュールをポストさせます。 これを行うには、ファイルapps / backend / config / routing.ymlを開き 、 そこで主要なホームページを探します。 デフォルトをpostに変更します 。
したがって、管理パネルにアクセスしようとすると、次の図が表示されます。
詳細については、 セキュリティの章をご覧ください。
おわりに
1時間が経過しました。 あなたにとって、初めて、もっと時間がかかったと思います。 私を信じてください。器用さはほとんどなく、すべてが非常に簡単かつ自然になります-Symphonyにはそれがあります。
これで、作業環境で両方のアプリケーションを使用できます。
フロントエンド:http://localhost/sf_sandbox/web/index.php/ バックエンド:http://localhost/sf_sandbox/web/backend.php/
エラーメッセージが表示される場合があります。 これはすべて、モデルを変更し、キャッシュを更新しなかったという事実によるものです。 キャッシュをすばやく消去します。
$ php symfony cc
そして今、私たちはアプリケーションの速度を見て賞賛します! コメントはありません。
残念ながら、トピックの種類の選択を間違えました。 これは、Fabien Potencierによる私の最初のsymfonyプロジェクトの翻訳です。 修正方法がわかりません。