Completed
Pull Request — staging (#840)
by
unknown
19:58
created

EasyFormsShortcode   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 279
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 6

Importance

Changes 0
Metric Value
dl 0
loc 279
rs 10
c 0
b 0
f 0
wmc 23
lcom 2
cbo 6

14 Methods

Rating   Name   Duplication   Size   Complexity  
A get_default_atts() 0 19 1
A register() 0 4 1
A get_context() 0 39 4
A process_shortcode() 0 12 2
A get_view_uri() 0 3 1
A set_view_uri() 0 3 1
A is_submitting_form() 0 3 1
A render() 0 9 2
A get_optin_form() 0 7 2
A handle_submission() 0 10 3
A exception_to_string() 0 7 1
A load_assets() 0 20 1
A countries_with_zip() 0 10 1
A page_data() 0 5 2
1
<?php
2
/**
3
 * YIKES Inc. Easy Forms.
4
 *
5
 * @package   YIKES\EasyForms
6
 * @author    Freddie Mixell
7
 * @license   GPL2
8
 */
9
10
namespace YIKES\EasyForms\Shortcode;
11
12
use YIKES\EasyForms\Assets\ScriptAsset;
13
use YIKES\EasyForms\Exception\Exception;
14
use YIKES\EasyForms\View\FormEscapedView;
15
use YIKES\EasyForms\View\NoOverrideLocationView;
16
use YIKES\EasyForms\Form\OptinForm as EasyForm;
17
use YIKES\EasyForms\Model\Subscriber;
18
use YIKES\EasyForms\Model\SubscriberRepository;
19
use YIKES\EasyForms\Model\OptinForm as EasyFormsModel;
20
use YIKES\EasyForms\Model\Recaptcha as RecaptchaModel;
21
22
/**
23
 * Class EasyFormsShortcode
24
 *
25
 * @since %VERSION%
26
 * @package YIKES\EasyForms
27
 */
28
29
final class EasyFormsShortcode extends BaseShortcode {
30
31
    const TAG           = 'yikes-mailchimp';
32
	const VIEW_URI      = 'views/easy-forms-shortcode';
33
	const SUBMITTED_URI = 'views/easy-forms-shortcode-completed';
34
	const TITLE_URI     = 'views/easy-forms-shortcode-title';
35
	const DESC_URI      = 'views/easy-forms-shortcode-description';
36
	
37
	/**
38
	 * Whether a form has been submitted.
39
	 *
40
	 * @since %VERSION%
41
	 * @var bool
42
	 */
43
	private $is_submitted = false;
44
45
	/**
46
	 * The view URI to use.
47
	 *
48
	 * This property is used so that the view can be switched dynamically
49
	 * as needed.
50
	 *
51
	 * @since %VERSION%
52
	 * @var string
53
	 */
54
    private $view_uri = self::VIEW_URI;
55
    
56
    /**
57
	 * Get the default array of attributes for the shortcode.
58
	 *
59
	 * @since %VERSION%
60
	 * @return array
61
	 */
62
	public function get_default_atts() {
63
		return [
64
			'form'                       => '',
65
			'submit'                     => '',
66
			'title'                      => '',
67
			'custom_title'               => '',
68
			'description'                => '',
69
			'custom_description'         => '',
70
			'ajax'                       => '', // set a custom js callback function to run after the recaptcha has expired - default none
71
			'recaptcha'                  => '', // manually set googles recptcha state
72
			'recaptcha_lang'             => '', // manually set the recaptcha language in the shortcode - also available is the yikes-mailchimp-recaptcha-language filter
73
			'recaptcha_type'             => '', // manually set the recaptcha type - audio/image - default image
74
			'recaptcha_theme'            => '', // manually set the recaptcha theme - light/dark - default light
75
			'recaptcha_size'             => '', // set the recaptcha size - normal/compact - default normal
76
			'recaptcha_data_callback'    => '', // set a custom js callback function to run after a successful recaptcha response - default none
77
			'recaptcha_expired_callback' => '', // set a custom js callback function to run after the recaptcha has expired - default none
78
			'inline'                     => '',
79
		];
80
	}
81
82
	public function register() {
83
		parent::register();
84
		$this->enqueue_assets();
85
	}
86
87
	/**
88
	 * Get the context to pass onto the view.
89
	 *
90
	 * Override to provide data to the view that is not part of the shortcode
91
	 * attributes.
92
	 *
93
	 * @since %VERSION%
94
	 *
95
	 * @param array $atts Array of shortcode attributes.
0 ignored issues
show
Bug introduced by
There is no parameter named $atts. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
96
	 *
97
	 * @return array Context to pass onto view.
98
	 * @throws InvalidPostID When the post ID is not valid.
99
	 */
100
	protected function get_context( array $attr ) {
101
		$form_id   = $attr['form'] ? $attr['form'] : '1';
102
		$form_data = ( new EasyFormsModel() )->find( $form_id );
103
104
		$this->is_submitted = $this->is_submitting_form();
105
106
		// Set up the form object.
107
		$form = $this->get_optin_form( $form_id, $form_data, $attr );
0 ignored issues
show
Documentation introduced by
$form_data is of type array, but the function expects a object<YIKES\EasyForms\Model\OptinForm>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
108
109
		$title = $form->form_title( $attr['title'], $attr['custom_title'], $form_data['form_name'] );
110
111
		if ( false !== $title ) {
112
			add_action( 'easy_forms_do_form_title', function( $view ) {
113
				echo $view->render_partial( static::TITLE_URI ); // phpcs:ignore WordPress.Security.EscapeOutput
114
			} );
115
		}
116
117
		$description = $form->form_description( $attr['description'], $attr['custom_description'] );
118
		
119
		if ( false !== $description ) {
120
			add_action( 'easy_forms_do_form_description', function( $view ) {
121
				echo $view->render_partial( static::DESC_URI ); // phpcs:ignore WordPress.Security.EscapeOutput
122
			} );
123
		}
124
125
		return [
126
			'title'                 => $title,
127
			'description'           => $description,
128
			'form_classes'          => $form->form_classes( $this->is_submitted ),
129
			'edit_form_link'        => $form->edit_form_link(),
130
			'submit_button_classes' => $form->submit_button_classes(),
131
			'submit_button_text'    => $form->submit_button_text( $attr['submit'] ),
132
			'ajax'                  => $attr['ajax'],
133
			'form_settings'         => $form_data['form_settings'],
134
			'form_data'             => $form_data,
135
			'form'                  => $form,
136
			'form_id'               => $form_id,
137
		];
138
	}
139
140
	/**
141
	 * Process the shortcode attributes and prepare rendering.
142
	 *
143
	 * @since %VERSION%
144
	 *
145
	 * @param array|string $atts Attributes as passed to the shortcode.
146
	 *
147
	 * @return string Rendered HTML of the shortcode.
148
	 */
149
	public function process_shortcode( $atts ) {
150
		try {
151
			// Determine if the form has been submitted.
152
			$this->is_submitted = $this->is_submitting_form();
153
			// Process the shortcode attributes.
154
			$atts    = $this->process_attributes( $atts );
155
			$context = $this->get_context( $atts );
156
			return $this->render( $context );
157
		} catch ( Exception $e ) {
158
			return $this->exception_to_string( $e );
0 ignored issues
show
Documentation introduced by
$e is of type object<YIKES\EasyForms\Exception\Exception>, but the function expects a object<Exception>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
159
		}
160
	}
161
    
162
   /**
163
	 * Get the View URI to use for rendering the shortcode.
164
	 *
165
	 * @since %VERSION%
166
	 *
167
	 * @return string View URI.
168
	 */
169
	protected function get_view_uri() {
170
		return $this->view_uri;
171
    }
172
    
173
    /**
174
	 * Set the view URI.
175
	 *
176
	 * @since %VERSION%
177
	 *
178
	 * @param string $uri The URI to use.
179
	 */
180
	private function set_view_uri( $uri ) {
181
		$this->view_uri = $uri;
182
	}
183
184
	/**
185
	 * Determine whether a form is currently being submitted.
186
	 *
187
	 * @since %VERSION%
188
	 * @return bool
189
	 */
190
	private function is_submitting_form() {
191
		return ! empty( $_POST );
192
	}
193
    
194
    /**
195
	 * Render the current Renderable.
196
	 *
197
	 * @since %VERSION%
198
	 *
199
	 * @param array $context Context in which to render.
200
	 *
201
	 * @return string Rendered HTML.
202
	 */
203
	public function render( array $context = [] ) {
204
		try {
205
			$this->enqueue_assets();
206
			$view = new FormEscapedView( new NoOverrideLocationView( $this->get_view_uri() ) );
207
			return $view->render( $context );
208
		} catch ( \Exception $e ) {
209
			return $this->exception_to_string( $e );
210
		}
211
	}
212
	
213
	/**
214
	 * Get the form object.
215
	 *
216
	 * @since %VERSION%
217
	 *
218
	 * @param int              $form_id       The ID for the form.
219
	 * @param EasyFormsModel   $form_data  The form Object.
220
	 * @param array            $field_classes The classes for fields in the form.
0 ignored issues
show
Bug introduced by
There is no parameter named $field_classes. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
221
	 *
222
	 * @return EasyForm
223
	 */
224
	private function get_optin_form( $form_id, $form_data, $attr ) {
225
		$form = new EasyForm( $form_id, $form_data, $attr );
226
		if ( $this->is_submitted ) {
227
			$this->handle_submission( $form );
228
		}
229
		return $form;
230
	}
231
232
	/**
233
	 * Handle the form submission.
234
	 *
235
	 * @since %VERSION%
236
	 *
237
	 * @param EasyForm $form The form object.
238
	 *
239
	 * @return Subscriber|null Returns a new Subscriber object, or null if one was not created.
240
	 * @throws InvalidURI When an invalid URI is set for the view.
241
	 */
242
	private function handle_submission( EasyForm $form ) {
243
		$form->set_submission( $_POST );
244
		$form->validate_submission();
245
		// Maybe update the view URI.
246
		if ( ! $form->has_errors() ) {
247
			$this->set_view_uri( self::SUBMITTED_URI );
248
			$subscriber = ( new SubscriberRepository() )->create_from_form( $form );
249
		}
250
		return isset( $subscriber ) ? $subscriber : null;
251
	}
252
    
253
    /**
254
	 * Convert an exception to a string.
255
	 *
256
	 * @since %VERSION%
257
	 *
258
	 * @param \Exception $e The exception object.
259
	 *
260
	 * @return string
261
	 */
262
	private function exception_to_string( \Exception $e ) {
263
		return sprintf(
264
			/* translators: %s refers to the error message */
265
			esc_html__( 'There was an error displaying the form: %s', 'easy-forms-text-domain' ),
266
			$e->getMessage()
267
		);
268
	}
269
270
	public function load_assets() {
271
		$submission_helper = new ScriptAsset(
272
            'form-submission-helpers',
273
            'assets/js/dev/form-submission-helpers',
274
            [ 'jquery' ],
275
            '1.0.0',
276
            ScriptAsset::ENQUEUE_HEADER
277
        );
278
279
        $submission_helper->add_localization( 'form_submission_helpers', array(
280
			'ajax_url'           => esc_url( admin_url( 'admin-ajax.php' ) ),
281
			'preloader_url'      => apply_filters( 'yikes-mailchimp-preloader', esc_url_raw( admin_url( 'images/wpspin_light.gif' ) ) ),
282
			'countries_with_zip' => $this->countries_with_zip(),
283
			'page_data'          => $this->page_data(),
284
		) );
285
286
		$this->assets = [
287
			$submission_helper,
288
		];
289
	}
290
291
	public function countries_with_zip() {
292
        return [
293
            'US' => 'US', 'GB' => 'GB', 'CA' => 'CA', 
294
            'IE' => 'IE', 'CN' => 'CN', 'IN' => 'IN', 
295
            'AU' => 'AU', 'BR' => 'BR', 'MX' => 'MX',
296
            'IT' => 'IT', 'NZ' => 'NZ', 'JP' => 'JP',
297
            'FR' => 'FR', 'GR' => 'GR', 'DE' => 'DE',
298
            'NL' => 'NL', 'PT' => 'PT', 'ES' => 'ES'
299
        ];
300
    }
301
302
    public function page_data() {
303
        global $post;
304
		$page_data = isset( $post->ID ) ? $post->ID : 0;
305
		return apply_filters( 'yikes-mailchimp-page-data', $page_data );
306
    }
307
}
308