From cf9cae0e69be553e649ece4f8dc36ac2f73aecb3 Mon Sep 17 00:00:00 2001
From: Bart Jaskulski <bartek.jaskulski@wpdesk.net>
Date: Thu, 2 Sep 2021 23:15:03 +0200
Subject: [PATCH] feat(fields): #1 add sorting fields by priority field

---
 .gitlab-ci.yml                                |  1 -
 changelog.txt                                 |  4 ++
 composer.json                                 |  2 +-
 phpunit-integration.xml                       |  7 +-
 src/Field.php                                 |  3 +
 src/Field/BasicField.php                      | 11 +++
 src/Form/FormWithFields.php                   | 11 ++-
 tests/integration/Form/FormWithFieldsTest.php | 71 +++++++++++++++++++
 tests/integration/bootstrap.php               | 12 +---
 9 files changed, 102 insertions(+), 20 deletions(-)
 create mode 100644 tests/integration/Form/FormWithFieldsTest.php

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 38447e9..b865367 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,7 +3,6 @@ variables:
   DISABLE_ACCEPTANCE: 1
   DISABLE_PHP_5_5: 1
   DISABLE_CODECEPTION: 1
-  DISABLE_INTEGRATION_TESTS: 1
   IS_LIBRARY: 1
 
 include: 'https://gitlab.com/wpdesk/gitlab-ci/raw/master/gitlab-ci-1.2.yml'
diff --git a/changelog.txt b/changelog.txt
index ee2493b..e6b1ae0 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,9 @@
 # Changelog
 
+## [2.5.0] - 2021-09-03
+### Added
+- Added fields sorting by priority field
+
 ## [2.4.6] - 2021-08-23
 ### Fixed
 - Get attribute now returns attribute instead of bool value
diff --git a/composer.json b/composer.json
index 6a79cb8..afcddb9 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
     }
   ],
   "require": {
-    "php": ">=5.6",
+    "php": ">=7.0",
     "ext-curl": "*",
     "ext-json": "*",
     "wpdesk/wp-persistence": "^2.0|^3.0",
diff --git a/phpunit-integration.xml b/phpunit-integration.xml
index 4a342ab..c78958b 100644
--- a/phpunit-integration.xml
+++ b/phpunit-integration.xml
@@ -3,7 +3,7 @@
      >
     <testsuites>
         <testsuite>
-            <directory prefix="Test" suffix=".php">./tests/integration</directory>
+            <directory suffix="Test.php">./tests/integration</directory>
         </testsuite>
     </testsuites>
 
@@ -20,9 +20,4 @@
         <log type="coverage-clover" target="build-coverage/clover.xml"/>
     </logging>
 
-    <php>
-        <env name="WP_DEVELOP_DIR" value="/tmp/wordpress-develop"/>
-        <env name="WC_DEVELOP_DIR" value="/tmp/woocommerce"/>
-    </php>
-
 </phpunit>
\ No newline at end of file
diff --git a/src/Field.php b/src/Field.php
index 458bb38..4205df4 100644
--- a/src/Field.php
+++ b/src/Field.php
@@ -163,4 +163,7 @@ interface Field {
 
 	/** @return Serializer */
 	public function get_serializer();
+
+	/** @return int */
+	public function get_priority();
 }
diff --git a/src/Field/BasicField.php b/src/Field/BasicField.php
index da93922..7158b73 100644
--- a/src/Field/BasicField.php
+++ b/src/Field/BasicField.php
@@ -298,4 +298,15 @@ abstract class BasicField implements Field {
 
 		return $this;
 	}
+
+	/** @return int */
+	public function get_priority() {
+		return $this->meta['priority'] ?? 10;
+	}
+
+	public function set_priority( int $priority ) {
+		$this->meta['priority'] = $priority;
+
+		return $this;
+	}
 }
diff --git a/src/Form/FormWithFields.php b/src/Form/FormWithFields.php
index 4b5819c..a5a494c 100644
--- a/src/Form/FormWithFields.php
+++ b/src/Form/FormWithFields.php
@@ -243,7 +243,16 @@ class FormWithFields implements Form, ContainerForm, FieldProvider {
 	 * @inheritDoc
 	 */
 	public function get_fields() {
-		return $this->fields;
+		$fields = $this->fields;
+
+		usort(
+			$fields,
+			static function ( Field $a, Field $b ) {
+				return $a->get_priority() <=> $b->get_priority();
+			}
+		);
+
+		return $fields;
 	}
 
 	/**
diff --git a/tests/integration/Form/FormWithFieldsTest.php b/tests/integration/Form/FormWithFieldsTest.php
new file mode 100644
index 0000000..9d8c2b2
--- /dev/null
+++ b/tests/integration/Form/FormWithFieldsTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace integration\Form;
+
+use WPDesk\Forms\Field\InputNumberField;
+use WPDesk\Forms\Field\InputTextField;
+use WPDesk\Forms\Field\SelectField;
+use WPDesk\Forms\Form\FormWithFields;
+use PHPUnit\Framework\TestCase;
+
+class FormWithFieldsTest extends TestCase {
+
+	/** @var FormWithFields */
+	private $form;
+
+	protected function setUp() {
+		$this->form = new FormWithFields([]);
+	}
+
+	public function test_should_return_fields_sorted_by_priority() {
+		$this->form->add_fields(
+			[
+				( new InputTextField() )
+				->set_label('third'),
+				( new SelectField() )
+				->set_label('second')
+				->set_priority(5),
+				( new InputNumberField() )
+				->set_label('first')
+				->set_priority(1)
+			]
+		);
+
+		$expected = [
+			( new InputNumberField() )
+			->set_label('first')
+			->set_priority(1),
+			( new SelectField() )
+			->set_label('second')
+			->set_priority(5),
+			( new InputTextField() )
+			->set_label('third')
+		];
+
+		self::assertEquals($expected, $this->form->get_fields());
+	}
+
+	public function test_should_return_fields_by_adding_order_if_no_priority_set() {
+		$this->form->add_fields(
+			[
+				( new InputTextField() )
+					->set_label('first'),
+				( new SelectField() )
+					->set_label('second'),
+				( new InputNumberField() )
+					->set_label('third'),
+			]
+		);
+
+		$expected = [
+			( new InputTextField() )
+				->set_label('first'),
+			( new SelectField() )
+				->set_label('second'),
+			( new InputNumberField() )
+				->set_label('third'),
+		];
+
+		self::assertEquals($expected, $this->form->get_fields());
+	}
+}
diff --git a/tests/integration/bootstrap.php b/tests/integration/bootstrap.php
index a422fd9..bbe2889 100644
--- a/tests/integration/bootstrap.php
+++ b/tests/integration/bootstrap.php
@@ -15,14 +15,4 @@ if ( getenv( 'PLUGIN_PATH' ) !== false ) {
 	define( 'PLUGIN_PATH', getenv( 'PLUGIN_PATH' ) );
 } else {
 	define( 'PLUGIN_PATH', __DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR );
-}
-
-require_once( getenv( 'WP_DEVELOP_DIR' ) . '/tests/phpunit/includes/functions.php' );
-
-tests_add_filter( 'muplugins_loaded', function () {
-}, 100 );
-
-putenv('WP_TESTS_DIR=' . getenv( 'WP_DEVELOP_DIR' ) . '/tests/phpunit');
-require_once( getenv( 'WC_DEVELOP_DIR' ) . '/tests/bootstrap.php' );
-
-do_action('plugins_loaded');
\ No newline at end of file
+}
\ No newline at end of file
-- 
GitLab