From e2742f21660df4a346a7856f82203dac878d8cf9 Mon Sep 17 00:00:00 2001
From: dyszczo <krzysztof.dyszczyk@gmail.com>
Date: Mon, 20 Jul 2020 12:34:34 +0200
Subject: [PATCH] feat(form): Action/method attribute for form

---
 changelog.txt                       |  4 ++
 src/Field/BasicField.php            | 36 +--------------
 src/Field/Traits/HtmlAttributes.php | 69 +++++++++++++++++++++++++++++
 src/Form/FormWithFields.php         | 43 +++++++++++++++++-
 templates/form-start.php            |  5 +--
 5 files changed, 117 insertions(+), 40 deletions(-)
 create mode 100644 src/Field/Traits/HtmlAttributes.php

diff --git a/changelog.txt b/changelog.txt
index 401c33a..e7ee37d 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,9 @@
 # Changelog
 
+## [2.1.0] - 2020-07-17
+### Added
+- Action/method attribute for form
+
 ## [2.0.4] - 2020-06-24
 ### Added
 - new button form field
diff --git a/src/Field/BasicField.php b/src/Field/BasicField.php
index 8bd5951..da93922 100644
--- a/src/Field/BasicField.php
+++ b/src/Field/BasicField.php
@@ -16,9 +16,7 @@ use WPDesk\Forms\Validator\RequiredValidator;
  * @package WPDesk\Forms
  */
 abstract class BasicField implements Field {
-
-	/** @var array[] */
-	protected $attributes;
+	use Field\Traits\HtmlAttributes;
 
 	/** @var array[] */
 	protected $meta;
@@ -119,12 +117,6 @@ abstract class BasicField implements Field {
 		return $this;
 	}
 
-	public function get_attributes( $except = [] ) {
-		return array_filter( $this->attributes, function ( $value, $key ) use ( $except ) {
-			return ! in_array( $key, $except );
-		}, ARRAY_FILTER_USE_BOTH );
-	}
-
 	public function get_meta_value( $name ) {
 		return $this->meta[ $name ];
 	}
@@ -247,28 +239,6 @@ abstract class BasicField implements Field {
 		return $this;
 	}
 
-	/**
-	 * @param $name
-	 * @param $value
-	 *
-	 * @return $this
-	 */
-	public function set_attribute( $name, $value ) {
-		$this->attributes[ $name ] = $value;
-
-		return $this;
-	}
-
-	public function unset_attribute( $name ) {
-		unset( $this->attributes[ $name ] );
-
-		return $this;
-	}
-
-	public function is_attribute_set( $name ) {
-		return isset( $this->attributes[ $name ] );
-	}
-
 	public function is_meta_value_set( $name ) {
 		return isset( $this->meta[ $name ] );
 	}
@@ -308,10 +278,6 @@ abstract class BasicField implements Field {
 		return isset( $this->meta['required'] ) ? $this->meta['required'] : false;
 	}
 
-	public function get_attribute( $name, $default = null ) {
-		return isset( $this->attributes[ $name ] ) ?: $default;
-	}
-
 	public function get_sanitizer() {
 		return new NoSanitize();
 	}
diff --git a/src/Field/Traits/HtmlAttributes.php b/src/Field/Traits/HtmlAttributes.php
new file mode 100644
index 0000000..b336ef7
--- /dev/null
+++ b/src/Field/Traits/HtmlAttributes.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace WPDesk\Forms\Field\Traits;
+
+/**
+ * Implementation of HTML attributes like id, name, action etc.
+ *
+ * @package WPDesk\Forms\Field\Traits
+ */
+trait HtmlAttributes {
+
+	/** @var string[] */
+	protected $attributes;
+
+	/**
+	 * Get list of all attributes except given.
+	 *
+	 * @param string[] $except
+	 *
+	 * @return string[]
+	 */
+	public function get_attributes( $except = [] ) {
+		return array_filter( $this->attributes, function ( $value, $key ) use ( $except ) {
+			return ! in_array( $key, $except, true );
+		}, ARRAY_FILTER_USE_BOTH );
+	}
+
+	/**
+	 * @param string $name
+	 * @param string $value
+	 *
+	 * @return $this
+	 */
+	public function set_attribute( $name, $value ) {
+		$this->attributes[ $name ] = $value;
+
+		return $this;
+	}
+
+	/**
+	 * @param string $name
+	 *
+	 * @return $this
+	 */
+	public function unset_attribute( $name ) {
+		unset( $this->attributes[ $name ] );
+
+		return $this;
+	}
+
+	/**
+	 * @param string $name
+	 *
+	 * @return bool
+	 */
+	public function is_attribute_set( $name ) {
+		return isset( $this->attributes[ $name ] );
+	}
+
+	/**
+	 * @param string $name
+	 * @param mixed $default
+	 *
+	 * @return mixed
+	 */
+	public function get_attribute( $name, $default = null ) {
+		return isset( $this->attributes[ $name ] ) ?: $default;
+	}
+}
\ No newline at end of file
diff --git a/src/Form/FormWithFields.php b/src/Form/FormWithFields.php
index 61f1169..84dbf80 100644
--- a/src/Form/FormWithFields.php
+++ b/src/Form/FormWithFields.php
@@ -13,6 +13,8 @@ use WPDesk\Persistence\PersistentContainer;
 use WPDesk\View\Renderer\Renderer;
 
 class FormWithFields implements Form, ContainerForm, FieldProvider {
+	use Field\Traits\HtmlAttributes;
+
 	/**
 	 * Unique form_id.
 	 *
@@ -44,6 +46,42 @@ class FormWithFields implements Form, ContainerForm, FieldProvider {
 		$this->updated_data = null;
 	}
 
+	/**
+	 * Set Form action attribute.
+	 *
+	 * @param string $action
+	 */
+	public function set_action( $action ) {
+		$this->attributes['action'] = $action;
+
+		return $this;
+	}
+
+	/**
+	 * Set Form method attribute ie. GET/POST.
+	 *
+	 * @param string $method
+	 */
+	public function set_method( $method ) {
+		$this->attributes['method'] = $method;
+
+		return $this;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function get_method() {
+		return isset( $this->attributes['method'] ) ? $this->attributes['method'] : 'POST';
+	}
+
+	/**
+	 * @return string
+	 */
+	public function get_action() {
+		return isset( $this->attributes['action'] ) ? $this->attributes['action'] : '';
+	}
+
 	/**
 	 * @inheritDoc
 	 */
@@ -156,8 +194,9 @@ class FormWithFields implements Form, ContainerForm, FieldProvider {
 	 */
 	public function render_form( Renderer $renderer ) {
 		$content = $renderer->render( 'form-start', [
-			'method' => 'POST',
-			'action' => '',
+			'form'   => $this,
+			'method' => $this->get_method(), // backward compat
+			'action' => $this->get_action(),  // backward compat
 		] );
 		$content .= $this->render_fields( $renderer );
 		$content .= $renderer->render( 'form-end' );
diff --git a/templates/form-start.php b/templates/form-start.php
index 97ed3df..10d7686 100644
--- a/templates/form-start.php
+++ b/templates/form-start.php
@@ -1,10 +1,9 @@
 <?php
 /**
- * @var string $method
- * @var string $action
+ * @var \WPDesk\Forms\Form\FormWithFields $form
  */
 ?>
-<form class="wrap woocommerce" method="<?php echo esc_attr($method); ?>" action="<?php echo esc_attr($action); ?>">
+<form class="wrap woocommerce" method="<?php echo esc_attr($form->get_method()); ?>" action="<?php echo esc_attr($form->get_action()); ?>">
 	<h2 style="display:none;"></h2><?php // All admin notices will be moved here by WP js ?>
 
 	<table class="form-table">
-- 
GitLab