SyliusFlowBundleを使用したSymfony2のステップバイステップフォーム

原始的なブログや名刺サイト以外のWebアプリケーションを開発する際に、面倒なフォームを作成する必要が生じる場合があります-複数のアドレス、個人データ、 ペット名などのユーザー情報。 段階的なフォームを作成すると、ユーザーの生活を簡素化できますが、必ずしも開発者はそうではありません。 後者を助けるために、この投稿は書かれました。



電子商取引プラットフォームSylius - SyliusFlowBundleのハブのオープンスペースで既に言及したバンドルを検討します。 なぜ彼は正確に? CraueFormFlowBundle'aの柔軟性に欠ける痛みを抱えた同僚の推奨、プロジェクトのドキュメント、およびsylius.orgのきちんとしたデザインは、説明されたソリューションの側面に内側のスケールを傾けました。 行きましょう。



まず、バンドル自体を締める必要があります。

composer require "sylius/flow-bundle"
      
      





次に、AppKernel.phpを編集します。

 <?php // app/AppKernel.php public function registerBundles() { $bundles = array( new Sylius\Bundle\FlowBundle\SyliusFlowBundle(), // Other bundles... ); }
      
      





フォームを開始するには、次のアクションを実行する必要があります。

  1. 必要なステップを作成します-StepInterfaceインターフェースを実装するオブジェクトと、それぞれのテンプレート。
  2. スクリプトへのステップのリンク-ProcessScenarioInterfaceインターフェースし、サービスとして宣言します
  3. バンドルルーティングのインポート


ステップバイステップのフォームを作成するために必要なのはそれだけです。 次に、各ステップをより詳細に検討します。



ステップを作成する



前述のように、SyliusFlowBundleではStepInterfaceを実装する必要があります。このため、名前が示すとおりSymphonicコントローラーを継承するcontrollerStepの親切な抽象化を使用すると便利です。 このソリューションでは、ステップをdisplayActionとforwardActionの2つのアクションに分割できます。 最初のフォームは明らかにフォームを表示し、2番目のフォームはPOSTリクエストを処理し、ユーザーを次のステップにリダイレクトします。 ほとんどの場合、ステップには、独自の抽象クラスで取り出すことができる多くの一般的なコードがあります。 たとえば、次のように:

ベースステップ
 abstract class BaseStep extends ControllerStep { const USER = 'user'; /** {@inheritdoc} */ public function displayAction(ProcessContextInterface $context) { return $this->createView( $this->getStepForm($context->getStorage()->get(self::USER)), $context ); } /** {@inheritdoc} */ public function forwardAction(ProcessContextInterface $context) { $form = $this->getStepForm($context->getStorage()->get(self::USER)); $form->handleRequest($context->getRequest()); if ($context->getRequest()->isMethod('POST') && $form->isValid()) { return $this->onFormValid($form, $context); } return $this->createView($form, $context); } /** * @param Form $form * @param ProcessContextInterface $context * * @return Response */ abstract protected function createView(Form $form, ProcessContextInterface $context); /** * @param mixed $data * * @return Form */ abstract protected function getStepForm($data = null); /** * @param Form $form * @param ProcessContextInterface $context * * @return mixed */ abstract protected function onFormValid(Form $form, ProcessContextInterface $context); }
      
      







ここで、displayActionでは、ストア(デフォルトではセッション)からオブジェクトを取得し、特定のステップに応じてフォームを取得し、ページをレンダリングします(特定のステップで実装も提供する必要があります)。 forwardActionの唯一のタスクはデータ検証です。 最後に、ステップの実装を見てください。

メインステップ
 class MainStep extends BaseStep { /** {@inheritdoc} */ public function displayAction(ProcessContextInterface $context) { $context->getStorage()->remove(self::USER); return parent::displayAction($context); } /** {@inheritdoc} */ protected function createView(Form $form, ProcessContextInterface $context) { return $this->render('HospectAppBundle:Process:step.html.twig', [ 'form' => $form->createView(), 'context' => $context, ]); } /** {@inheritdoc} */ protected function getStepForm($data = null) { return $this->createForm(new MainInfoType(), $data); } /** {@inheritdoc} */ protected function onFormValid(Form $form, ProcessContextInterface $context) { $context->getStorage()->set(self::USER, $form->getData()); return $this->complete(); } }
      
      







ここで、目的のフォームが予想どおりに作成され、ステップ固有の表現がレンダリングされ、データの有効性の場合、セッションが保存されます。 もちろん、最後のステップは、お気に入りの永続的なデータウェアハウスに問題のあるオブジェクトを保存することです。



ステップをスクリプトにリンクする



この段階で、アプリケーションから切り離されたいくつかの球面ステップがあります。 これを変更するには、スクリプトを作成する必要があります。 このスクリプトは、一般的なフォームの接続リンクであり、一連のステップ、すべてのステップに共通のルーティングパラメーターの設定、すべてのステップが正常に完了した後のリダイレクトなどを担当します。 ただし、実際には、ここではあまり作業はありません-インターフェイスには1つのメソッドのみを実装する必要があります-buildは入力として1つのパラメーターのみを必要とする-それに馴染みのあるメソッドを持つビルダー

ユーザーシナリオ
 class UserScenario extends ContainerAware implements ProcessScenarioInterface { /** {@inheritdoc} */ public function build(ProcessBuilderInterface $builder) { $builder ->add('main', new MainStep()) ->add('address', new AddressStep()) ->setRedirect('hospect_app_homepage'); } }
      
      







システムがシナリオについて「調べる」ためには、「sylius.process.scenario」タグを使用してサービスとして宣言する必要があります。

 sylius.scenario.flow: class: Hospect\AppBundle\Process\Scenario\UserScenario calls: - [ setContainer, [@service_container] ] tags: - { name: sylius.process.scenario, alias: user }
      
      







ルーティング構成



いくつのステップがあっても、フォーム全体に対して3つのルートしか提供されません。 それらはすべて必須パラメーターscenarioAliasを持ち、目的のシナリオを引き出すことに焦点を当てています。 ルート「sylius_flow_display」および「sylius_flow_forward」には、「stepName」という2番目のパラメーターが必要です。 それだけです。 インポートは次のようになります。

 sylius_flow: resource: @SyliusFlowBundle/Resources/config/routing.yml prefix: /
      
      







参照資料






All Articles