Skip to content
Snippets Groups Projects
Commit 3a9fb378 authored by potreb's avatar potreb
Browse files

Merge remote-tracking branch 'origin/feature/strong-typing' into feature/strong-typing

# Conflicts:
#	changelog.txt
#	src/Field.php
#	src/Field/BasicField.php
#	src/Field/NoValueField.php
#	src/Field/ProductSelect.php
#	src/Field/TimepickerField.php
#	src/Persistence/FieldPersistenceStrategy.php
#	src/Serializer/NoSerialize.php
#	templates/header.php
#	templates/input-image.php
parents deee9690 679dcfd9
No related branches found
No related tags found
3 merge requests!28release: 3.0.0,!23Feature/strong typing pp,!19Add strong typing for 3.0 version
...@@ -50,11 +50,11 @@ interface SettingsTab { ...@@ -50,11 +50,11 @@ interface SettingsTab {
/** /**
* Use to set settings from database or defaults. * Use to set settings from database or defaults.
* *
* @param array|ContainerInterface $data Data to render. * @param ContainerInterface $data Data to render.
* *
* @return void * @return void
*/ */
public function set_data( $data ); public function set_data( ContainerInterface $data );
/** /**
* Use to handle request data from POST. * Use to handle request data from POST.
...@@ -102,11 +102,11 @@ abstract class FieldSettingsTab implements SettingsTab { ...@@ -102,11 +102,11 @@ abstract class FieldSettingsTab implements SettingsTab {
return $this->get_form()->render_form( $renderer ); return $this->get_form()->render_form( $renderer );
} }
public function set_data( $data ) { public function set_data( ContainerInterface $data ) {
$this->get_form()->set_data( $data ); $this->get_form()->set_data( $data );
} }
public function handle_request( $request ) { public function handle_request( array $request ) {
$this->get_form()->handle_request( $request ); $this->get_form()->handle_request( $request );
} }
......
# Changelog # Changelog
## [3.0.0] - 2021-09-08 ## [3.0.0]
### Added ### Added
- Added strong typing to all of the interfaces - Added strong typing to all of the interfaces
- Added fields sorting by priority field - Added fields sorting by priority field
### - Normalized string escaping in all template files
- Added InputEmailField and EmailSerializer classes
### Changed
- All getters and setter in BasicField are now declared final
- FormWithFields accepts only ContainerInterface in ::set_data() method. Prepare data before passing it
### Removed
- Removed deprecated classes - Removed deprecated classes
- Removed NoSerialize class
## [2.4.7] - 2021-09-20
### Fixed
- Add missing escaping functions in templates
## [2.4.6] - 2021-08-23 ## [2.4.6] - 2021-08-23
### Fixed ### Fixed
......
...@@ -91,5 +91,7 @@ interface Field { ...@@ -91,5 +91,7 @@ interface Field {
public function get_serializer(): Serializer; public function get_serializer(): Serializer;
public function has_serializer(): bool;
public function get_priority(): int; public function get_priority(): int;
} }
...@@ -6,7 +6,6 @@ use WPDesk\Forms\Field; ...@@ -6,7 +6,6 @@ use WPDesk\Forms\Field;
use WPDesk\Forms\Sanitizer; use WPDesk\Forms\Sanitizer;
use WPDesk\Forms\Sanitizer\NoSanitize; use WPDesk\Forms\Sanitizer\NoSanitize;
use WPDesk\Forms\Serializer; use WPDesk\Forms\Serializer;
use WPDesk\Forms\Serializer\NoSerialize;
use WPDesk\Forms\Validator; use WPDesk\Forms\Validator;
use WPDesk\Forms\Validator\ChainValidator; use WPDesk\Forms\Validator\ChainValidator;
use WPDesk\Forms\Validator\RequiredValidator; use WPDesk\Forms\Validator\RequiredValidator;
...@@ -22,7 +21,7 @@ abstract class BasicField implements Field { ...@@ -22,7 +21,7 @@ abstract class BasicField implements Field {
const DEFAULT_PRIORITY = 10; const DEFAULT_PRIORITY = 10;
/** @var array{default_value: string, possible_values?: string[], sublabel?: string, priority: int, label: string, description: string, description_tip: string, data: array<string|int>, serializer: ?Serializer} */ /** @var array{default_value: string, possible_values?: string[], sublabel?: string, priority: int, label: string, description: string, description_tip: string, data: array<string|int>} */
protected $meta = [ protected $meta = [
'priority' => self::DEFAULT_PRIORITY, 'priority' => self::DEFAULT_PRIORITY,
'default_value' => '', 'default_value' => '',
...@@ -30,9 +29,41 @@ abstract class BasicField implements Field { ...@@ -30,9 +29,41 @@ abstract class BasicField implements Field {
'description' => '', 'description' => '',
'description_tip' => '', 'description_tip' => '',
'data' => [], 'data' => [],
'serializer' => null,
]; ];
public function should_override_form_template(): bool {
return false;
}
public function get_type(): string {
return 'text';
}
public function get_validator(): Validator {
$chain = new ChainValidator();
if ( $this->is_required() ) {
$chain->attach( new RequiredValidator() );
}
return $chain;
}
public function get_sanitizer(): Sanitizer {
return new NoSanitize();
}
public function has_serializer(): bool {
return false;
}
public function get_serializer(): Serializer {
throw new \BadMethodCallException('You must define your serializer in a child class.');
}
final public function get_name(): string {
return $this->attributes['name'];
}
final public function get_label(): string { final public function get_label(): string {
return $this->meta['label']; return $this->meta['label'];
} }
...@@ -51,11 +82,6 @@ abstract class BasicField implements Field { ...@@ -51,11 +82,6 @@ abstract class BasicField implements Field {
return ! empty( $this->meta['description_tip'] ); return ! empty( $this->meta['description_tip'] );
} }
/** Override method if you need. */
public function should_override_form_template(): bool {
return false;
}
final public function get_description(): string { final public function get_description(): string {
return $this->meta['description']; return $this->meta['description'];
} }
...@@ -80,10 +106,6 @@ abstract class BasicField implements Field { ...@@ -80,10 +106,6 @@ abstract class BasicField implements Field {
return $this; return $this;
} }
public function get_type(): string {
return 'text';
}
final public function set_placeholder( string $value ): Field { final public function set_placeholder( string $value ): Field {
$this->attributes['placeholder'] = $value; $this->attributes['placeholder'] = $value;
...@@ -132,9 +154,6 @@ abstract class BasicField implements Field { ...@@ -132,9 +154,6 @@ abstract class BasicField implements Field {
return $this->attributes['id'] ?? sanitize_title( $this->get_name() ); return $this->attributes['id'] ?? sanitize_title( $this->get_name() );
} }
public function get_name(): string {
return $this->attributes['name'];
}
final public function is_multiple(): bool { final public function is_multiple(): bool {
return $this->attributes['multiple']; return $this->attributes['multiple'];
...@@ -211,37 +230,10 @@ abstract class BasicField implements Field { ...@@ -211,37 +230,10 @@ abstract class BasicField implements Field {
return $this; return $this;
} }
public function get_validator(): Validator {
$chain = new ChainValidator();
if ( $this->is_required() ) {
$chain->attach( new RequiredValidator() );
}
return $chain;
}
final public function is_required(): bool { final public function is_required(): bool {
return $this->attributes['required']; return $this->attributes['required'];
} }
public function get_sanitizer(): Sanitizer {
return new NoSanitize();
}
final public function get_serializer(): Serializer {
if ( ! empty( $this->meta['serializer'] ) && $this->meta['serializer'] instanceof Serializer ) {
return $this->meta['serializer'];
}
return new NoSerialize();
}
public function set_serializer( Serializer $serializer ): Field {
$this->meta['serializer'] = $serializer;
return $this;
}
final public function get_priority(): int { final public function get_priority(): int {
return $this->meta['priority']; return $this->meta['priority'];
} }
......
...@@ -8,7 +8,7 @@ namespace WPDesk\Forms\Field; ...@@ -8,7 +8,7 @@ namespace WPDesk\Forms\Field;
* @package WPDesk\Forms * @package WPDesk\Forms
*/ */
abstract class NoValueField extends BasicField { abstract class NoValueField extends BasicField {
public function get_name(): string { public function __construct() {
return ''; $this->set_name( '' );
} }
} }
...@@ -2,11 +2,22 @@ ...@@ -2,11 +2,22 @@
namespace WPDesk\Forms\Field; namespace WPDesk\Forms\Field;
use WPDesk\Forms\Serializer\ProductSelectSerializer;
use WPDesk\Forms\Serializer;
class ProductSelect extends SelectField { class ProductSelect extends SelectField {
public function __construct() { public function __construct() {
$this->set_multiple(); $this->set_multiple();
} }
public function has_serializer(): bool {
return true;
}
public function get_serializer(): Serializer {
return new ProductSelectSerializer();
}
public function get_template_name(): string { public function get_template_name(): string {
return 'product-select'; return 'product-select';
} }
......
...@@ -2,7 +2,18 @@ ...@@ -2,7 +2,18 @@
namespace WPDesk\Forms\Field; namespace WPDesk\Forms\Field;
use WPDesk\Forms\Serializer;
use WPDesk\Forms\Serializer\JsonSerializer;
class TimepickerField extends BasicField { class TimepickerField extends BasicField {
public function has_serializer(): bool {
return true;
}
public function get_serializer(): Serializer {
return new JsonSerializer();
}
public function get_template_name(): string { public function get_template_name(): string {
return 'timepicker'; return 'timepicker';
} }
......
...@@ -94,8 +94,6 @@ class FormWithFields implements Form, ContainerForm, FieldProvider { ...@@ -94,8 +94,6 @@ class FormWithFields implements Form, ContainerForm, FieldProvider {
/** /**
* Add array to update data. * Add array to update data.
*
* @param array|ContainerInterface $request new data to update.
*/ */
public function handle_request( array $request = [] ) { public function handle_request( array $request = [] ) {
if ( $this->updated_data === null ) { if ( $this->updated_data === null ) {
......
...@@ -20,25 +20,29 @@ class FieldPersistenceStrategy { ...@@ -20,25 +20,29 @@ class FieldPersistenceStrategy {
$this->persistence = $persistence; $this->persistence = $persistence;
} }
/** /** @return void */
* Save fields data.
*/
public function persist_fields( FieldProvider $fields_provider, array $data ) { public function persist_fields( FieldProvider $fields_provider, array $data ) {
foreach ( $fields_provider->get_fields() as $field ) { foreach ( $fields_provider->get_fields() as $field ) {
$field_key = $field->get_name(); $field_key = $field->get_name();
if ( $field->has_serializer() ) {
$this->persistence->set( $field_key, $field->get_serializer()->serialize( $data[ $field_key ] ) ); $this->persistence->set( $field_key, $field->get_serializer()->serialize( $data[ $field_key ] ) );
} else {
$this->persistence->set( $field_key, $data[ $field_key ] );
}
} }
} }
/** /** @return void */
* Load fields data.
*/
public function load_fields( FieldProvider $fields_provider ): array { public function load_fields( FieldProvider $fields_provider ): array {
$data = []; $data = [];
foreach ( $fields_provider->get_fields() as $field ) { foreach ( $fields_provider->get_fields() as $field ) {
$field_key = $field->get_name(); $field_key = $field->get_name();
try { try {
if ( $field->has_serializer() ) {
$data[ $field_key ] = $field->get_serializer()->unserialize( $this->persistence->get( $field_key ) ); $data[ $field_key ] = $field->get_serializer()->unserialize( $this->persistence->get( $field_key ) );
} else {
$data[ $field_key ] = $this->persistence->get( $field_key );
}
} catch ( NotFoundExceptionInterface $not_found ) { } catch ( NotFoundExceptionInterface $not_found ) {
// TODO: Logger // TODO: Logger
// LoggerFactory::get_logger()->info( "FieldPersistenceStrategy:: Field {$field_key} not found" ); // LoggerFactory::get_logger()->info( "FieldPersistenceStrategy:: Field {$field_key} not found" );
......
<?php
namespace WPDesk\Forms\Serializer;
use WPDesk\Forms\Serializer;
class NoSerialize implements Serializer {
public function serialize( $value ): string {
return (string) $value;
}
public function unserialize( string $value ) {
return $value;
}
}
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
$header_size = (int) $field->get_meta_value( 'header_size' ) ?: 2; $header_size = (int) $field->get_meta_value( 'header_size' ) ?: 2;
$classes = $field->has_classes() ? 'class="' . esc_attr( $field->get_classes() ) . '"' : ''; $classes = $field->has_classes() ? 'class="' . esc_attr( $field->get_classes() ) . '"' : '';
?> ?>
<?php if ( $field->has_label() ) : ?> <?php if ( $field->has_label() ) : ?>
......
...@@ -13,23 +13,15 @@ $media_container_id = 'media_' . sanitize_key( $field->get_id() ); ...@@ -13,23 +13,15 @@ $media_container_id = 'media_' . sanitize_key( $field->get_id() );
id="<?php echo \esc_attr( $field->get_id() ); ?>"/> id="<?php echo \esc_attr( $field->get_id() ); ?>"/>
<div class="custom-img-container"> <div class="custom-img-container">
<?php if ( $value ) : ?> <?php if ( $value ) : ?>
<img src="<?php echo \esc_attr( $value ); ?>" alt="" width="100"/> <img src="<?php echo \esc_url( $value ) ?>" alt="" width="100"/>
<?php endif; ?> <?php endif; ?>
</div> </div>
<p class="hide-if-no-js"> <p class="hide-if-no-js">
<a class="upload-custom-img <a class="upload-custom-img <?php if ( $value ): ?>hidden<?php endif ?>" href="<?php echo \esc_url( $value ) ?>">
<?php <?php \esc_html_e( 'Set image', 'wp-forms' ) ?>
if ( $value ) :
?>
hidden<?php endif ?>" href="<?php echo \esc_attr( $value ); ?>">
<?php esc_html_e( 'Set image', 'wp-forms' ); ?>
</a> </a>
<a class="delete-custom-img <a class="delete-custom-img <?php if ( ! $value ): ?>hidden<?php endif ?>" href="#">
<?php <?php \esc_html_e( 'Remove image', 'wp-forms' ) ?>
if ( ! $value ) :
?>
hidden<?php endif ?>" href="#">
<?php esc_html_e( 'Remove image', 'wp-forms' ); ?>
</a> </a>
</p> </p>
</div> </div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment