Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions classes/WP_Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,30 @@ public function remove_element( $key ) {
return $this;
}

public function get_elements_as_array() {
$result = (array)$this->get_elements_as_array_prepare( $this->elements );
return $result;
}

public function get_elements_as_array_prepare( array $elements ) {
$elements = array_values( $elements );
$result = array();

$number_of = count( $elements );
for( $i = 0; $i < $number_of; $i++ ) {
if( $elements[$i] instanceof WP_Form_Aggregate ) {
$result[$i]['elements'] = $this->get_elements_as_array_prepare( $elements[$i]->get_children() );
}

$result[$i]['priority'] = $elements[$i]->get_priority();
$result[$i]['label'] = $elements[$i]->get_label();
$result[$i]['description'] = $elements[$i]->get_description();
$result[$i]['attributes'] = $elements[$i]->get_all_attributes();
$result[$i]['errors'] = $elements[$i]->get_errors();
}
return $result;
}

/**
* @param $key
* @return null|WP_Form_Component
Expand Down
34 changes: 34 additions & 0 deletions classes/WP_Form_Listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class WP_Form_Listener {

private function add_hooks() {
add_action( 'init', array( $this, 'check_form_submission' ), 111, 0 );
add_action( 'wp_ajax_wp_forms', array( $this, 'check_form_submission_ajax' ) );
add_action( 'wp_ajax_nopriv_wp_forms', array( $this, 'check_form_submission_ajax' ) );
}

public function check_form_submission() {
Expand All @@ -22,9 +24,41 @@ public function check_form_submission() {
return;
}
$submission->submit();
$submission->prepare_form();
$submission->redirect();
}

/**
* Similar to check_form_submission() but for AJAX requests.
*
* @see check_form_submission()
*
* @throws Exception
*/
public function check_form_submission_ajax() {
$kk = '';
if ( empty($_REQUEST['data']['wp_form_id']) || empty($_REQUEST['data']['wp_form_nonce']) ) {
return;
}
if ( !wp_verify_nonce($_REQUEST['data']['wp_form_nonce'], $_REQUEST['data']['wp_form_id']) ) {
return;
}

$form = wp_get_form($_REQUEST['data']['wp_form_id']);
$submission = new WP_Form_Submission($form, $_REQUEST['data']);
if ( !$submission->is_valid() ) {
/**
* похоже здесь это не надо вызывать, т к возможно эта штука втыкает ошибки в хтмл,
* а нам нужно просто подготовить ошибки и отправить их
*/
$submission->prepare_form();
$submission->send_ajax_answer();
return;
}
$submission->submit_ajax();
$submission->send_ajax_answer();
}

/********** Singleton *************/

/**
Expand Down
14 changes: 14 additions & 0 deletions classes/WP_Form_Submission.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public function submit() {
}
}

public function submit_ajax() {
$this->submit();
}

/**
* @param string $key The form element name, as it would be displayed
* in the HTML.
Expand Down Expand Up @@ -92,6 +96,16 @@ public function set_redirect( $url = '' ) {
$this->redirect = $url;
}

public function send_ajax_answer() {
$elements = $this->form->get_elements_as_array();
if ( !$this->is_valid() ) {
wp_send_json_error( $elements );
}
else {
wp_send_json_success( $elements );
}
}

/**
* Set values and errors on the form
* to prepare it for rendering
Expand Down
10 changes: 10 additions & 0 deletions classes/elements/WP_Form_Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class WP_Form_Element implements WP_Form_Component, WP_Form_Attributes_Interface
protected $value = '';
protected $description = '';
protected $errors = array();
protected $content = '';

/** @var WP_Form_Attributes_Interface */
protected $attributes = NULL;
Expand Down Expand Up @@ -196,6 +197,15 @@ public function clear_errors() {
return $this;
}

public function set_content( $content ) {
$this->content = $content;
return $this;
}

public function get_content() {
return $this->content;
}

/**
* @return string
*/
Expand Down
7 changes: 7 additions & 0 deletions classes/elements/WP_Form_Element_Checkboxes.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,11 @@
class WP_Form_Element_Checkboxes extends WP_Form_Element_Multiple {
protected $type = 'checkboxes';
protected $default_view = 'WP_Form_View_Checkboxes';

public function get_selected() {
if ( !empty($this->value) ) {
return $this->value;
}
return $this->default_value;
}
}
7 changes: 7 additions & 0 deletions classes/elements/WP_Form_Element_Markup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

class WP_Form_Element_Markup extends WP_Form_Element {
protected $type = 'markup';
protected $default_view = 'WP_Form_View_Markup';
protected $default_decorators = array();
}
81 changes: 81 additions & 0 deletions classes/elements/WP_Form_Element_Wrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

/**
* Class WP_Form_Element_Fieldset
*/
class WP_Form_Element_Wrapper extends WP_Form_Element implements WP_Form_Aggregate {
protected $type = 'wrapper';
protected $default_view = 'WP_Form_View_Wrapper';
protected $default_decorators = array();

/** @var WP_Form_Component[] */
protected $elements = array();

/**
* Add a child component
*
* @param WP_Form_Component $element
* @param string $key A unique key for the component.
* Any existing component with the same key
* will be overwritten. If $key is empty,
* an attempt will be made to generate a
* unique key.
* @throws InvalidArgumentException
* @return $this
*/
public function add_element( WP_Form_Component $element, $key = '' ) {
if ( empty($key) ) {
$key = $element->get_name();
}
if ( empty($key) ) {
throw new InvalidArgumentException(__('Cannot add nameless element to a wrapper', 'wp-forms'));
}
$this->elements[$key] = $element;
return $this;
}

/**
* Remove a child component
*
* @param string $key
* @return $this
*/
public function remove_element( $key ) {
if ( isset($this->elements[$key]) ) {
unset($this->elements[$key]);
}
return $this;
}

/**
* Get the element with the given key
*
* @param string $key
*
* @return WP_Form_Component|NULL
*/
public function get_element( $key ) {
if ( !empty($this->elements[$key]) ) {
return $this->elements[$key];
}
foreach ( $this->elements as $e ) {
if ( $e instanceof WP_Form_Aggregate ) {
$child = $e->get_element($key);
if ( !empty($child) ) {
return $child;
}
}
}
return NULL;
}

/**
* Get an array of all child components, sorted by priority.
*
* @return WP_Form_Component[]
*/
public function get_children() {
$elements = WP_Form_Element::sort_elements($this->elements);
return $elements;
}
}
12 changes: 10 additions & 2 deletions classes/views/WP_Form_View_Checkboxes.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ protected function checkboxes( WP_Form_Element_Checkboxes $element ) {
throw new LogicException(__('Cannot render checkbox group without a name', 'wp-forms'));
}
$options = $element->get_options();
$selected = (array) $element->get_selected();
$output = '';
foreach ( $options as $key => $label ) {
$output .= $this->checkbox( $key, $label, $attributes );
$checked = false;
if ( in_array( $key, $selected ) ) {
$checked = true;
}
$output .= $this->checkbox( $key, $label, $attributes, $checked );
}
return $output;
}

protected function checkbox( $key, $label, $attributes ) {
protected function checkbox( $key, $label, $attributes, $checked ) {
$checkbox = WP_Form_Element::create('checkbox')
->set_name($attributes['name'].'[]')
->set_label($label)
Expand All @@ -32,6 +37,9 @@ protected function checkbox( $key, $label, $attributes ) {
foreach ( $attributes as $att => $value ) {
$checkbox->set_attribute($att, $value);
}
if( $checked ) {
$checkbox->set_attribute( 'checked', 'checked' );
}
do_action('wp_form_checkbox_group_member', $checkbox);
return $checkbox->render();
}
Expand Down
26 changes: 26 additions & 0 deletions classes/views/WP_Form_View_Markup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

class WP_Form_View_Markup extends WP_Form_View {
public function render( WP_Form_Component $element ) {
$type = $element->get_type();
if ( method_exists( $this, $type ) ) {
return call_user_func( array( $this, $type ), $element );
} elseif ( $element instanceof WP_Form_Element ) {
return $this->markup($element); // fallback to generic <input />
}
return '';
}

protected function markup( WP_Form_Element $element ) {
$content = $element->get_content();

$attributes = $element->get_all_attributes();

unset($attributes['value'], $attributes['type']);
$attributes = WP_Form_View::prepare_attributes($attributes);

$template = '<div %s>%s</div>';
return sprintf( $template, $attributes, $content );
}

}
2 changes: 1 addition & 1 deletion classes/views/WP_Form_View_Textarea.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ protected function textarea( WP_Form_Element $element ) {
$attributes = $element->get_all_attributes();
$value = '';
if ( isset($attributes['value']) ) {
$value = $attributes['value'];
$value = esc_textarea( $attributes['value'] );
unset($attributes['value']);
}
$attributes = WP_Form_View::prepare_attributes($attributes);
Expand Down
60 changes: 60 additions & 0 deletions classes/views/WP_Form_View_Wrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

/**
* Class WP_Form_View_Fieldset
*/
class WP_Form_View_Wrapper extends WP_Form_View {
public function render( WP_Form_Component $element ) {
$type = $element->get_type();
if ( method_exists( $this, $type ) ) {
return call_user_func( array( $this, $type ), $element );
} elseif ( $element instanceof WP_Form_Element_Wrapper ) {
return $this->wrapper($element); // fallback to generic <fieldset />
}
return '';
}

protected function wrapper( WP_Form_Element_Wrapper $element ) {
$children = $this->render_children($element);

$attributes = $element->get_all_attributes();
// Because this is just a tag (div, span) we don't need this attrs in tag.
unset($attributes['name'], $attributes['tag_name'], $attributes['type'], $attributes['value']);
$attributes = WP_Form_View::prepare_attributes($attributes);

$tag_name = $element->get_attribute('tag_name');
if( empty( $tag_name ) ) {
$tag_name = 'div';
}
$output = sprintf(
'<%1$s %2$s>%3$s</%1$s>',
$tag_name,
$attributes,
$children
);
return $output;
}

/**
* Walk through each child and render it
*
* @param WP_Form_Aggregate $fieldset
* @return string
*/
protected function render_children( WP_Form_Aggregate $wrapper ) {
$children = '';
foreach ( $wrapper->get_children() as $child ) {
$children .= $this->render_child($child);
}
return $children;
}

/**
* @param WP_Form_Component $element
* @return string
*/
protected function render_child( WP_Form_Component $element ) {
return $element->render();
}

}
Loading