Completed
Pull Request — staging (#840)
by
unknown
18:30
created

EasyFormsShortcode::get_context()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 8
nop 1
dl 0
loc 39
rs 9.296
c 0
b 0
f 0
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\StyleAsset;
13
use YIKES\EasyForms\Assets\ScriptAsset;
14
use YIKES\EasyForms\Exception\Exception;
15
use YIKES\EasyForms\View\FormEscapedView;
16
use YIKES\EasyForms\View\NoOverrideLocationView;
17
use YIKES\EasyForms\Form\OptinForm as EasyForm;
18
use YIKES\EasyForms\Model\Subscriber;
19
use YIKES\EasyForms\Model\SubscriberRepository;
20
use YIKES\EasyForms\Model\OptinForm as EasyFormsModel;
21
use YIKES\EasyForms\Model\Recaptcha as RecaptchaModel;
22
23
/**
24
 * Class EasyFormsShortcode
25
 *
26
 * @since %VERSION%
27
 * @package YIKES\EasyForms
28
 */
29
30
final class EasyFormsShortcode extends BaseShortcode {
31
32
    const TAG           = 'yikes-mailchimp';
33
	const VIEW_URI      = 'views/easy-forms-shortcode';
34
	const SUBMITTED_URI = 'views/easy-forms-shortcode-completed';
35
	const TITLE_URI     = 'views/easy-forms-shortcode-title';
36
	const DESC_URI      = 'views/easy-forms-shortcode-description';
37
	const CSS_URI       = 'assets/css/shortcode-style';
38
	
39
	/**
40
	 * Whether a form has been submitted.
41
	 *
42
	 * @since %VERSION%
43
	 * @var bool
44
	 */
45
	private $is_submitted = false;
46
47
	/**
48
	 * The view URI to use.
49
	 *
50
	 * This property is used so that the view can be switched dynamically
51
	 * as needed.
52
	 *
53
	 * @since %VERSION%
54
	 * @var string
55
	 */
56
    private $view_uri = self::VIEW_URI;
57
    
58
    /**
59
	 * Get the default array of attributes for the shortcode.
60
	 *
61
	 * @since %VERSION%
62
	 * @return array
63
	 */
64
	public function get_default_atts() {
65
		return [
66
			'form'                       => '',
67
			'submit'                     => '',
68
			'title'                      => '',
69
			'custom_title'               => '',
70
			'description'                => '',
71
			'custom_description'         => '',
72
			'ajax'                       => '', // set a custom js callback function to run after the recaptcha has expired - default none
73
			'recaptcha'                  => '', // manually set googles recptcha state
74
			'recaptcha_lang'             => '', // manually set the recaptcha language in the shortcode - also available is the yikes-mailchimp-recaptcha-language filter
75
			'recaptcha_type'             => '', // manually set the recaptcha type - audio/image - default image
76
			'recaptcha_theme'            => '', // manually set the recaptcha theme - light/dark - default light
77
			'recaptcha_size'             => '', // set the recaptcha size - normal/compact - default normal
78
			'recaptcha_data_callback'    => '', // set a custom js callback function to run after a successful recaptcha response - default none
79
			'recaptcha_expired_callback' => '', // set a custom js callback function to run after the recaptcha has expired - default none
80
			'inline'                     => '',
81
		];
82
	}
83
84
	public function register() {
85
		parent::register();
86
		$this->enqueue_assets();
87
		add_filter( 'safe_style_css', function( $styles ) {
88
			$styles[] = 'display';
89
			return $styles;
90
		} );
91
	}
92
93
	/**
94
	 * Get the context to pass onto the view.
95
	 *
96
	 * Override to provide data to the view that is not part of the shortcode
97
	 * attributes.
98
	 *
99
	 * @since %VERSION%
100
	 *
101
	 * @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...
102
	 *
103
	 * @return array Context to pass onto view.
104
	 * @throws InvalidPostID When the post ID is not valid.
105
	 */
106
	protected function get_context( array $attr ) {
107
		$form_id   = $attr['form'] ? $attr['form'] : '1';
108
		$form_data = ( new EasyFormsModel() )->find( $form_id );
109
110
		$this->is_submitted = $this->is_submitting_form();
111
112
		// Set up the form object.
113
		$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...
114
115
		$title = $form->form_title( $attr['title'], $attr['custom_title'], $form_data['form_name'] );
116
117
		if ( false !== $title ) {
118
			add_action( 'easy_forms_do_form_title', function( $view ) {
119
				echo $view->render_partial( static::TITLE_URI ); // phpcs:ignore WordPress.Security.EscapeOutput
120
			} );
121
		}
122
123
		$description = $form->form_description( $attr['description'], $attr['custom_description'] );
124
		
125
		if ( false !== $description ) {
126
			add_action( 'easy_forms_do_form_description', function( $view ) {
127
				echo $view->render_partial( static::DESC_URI ); // phpcs:ignore WordPress.Security.EscapeOutput
128
			} );
129
		}
130
131
		return [
132
			'title'                 => $title,
133
			'description'           => $description,
134
			'form_classes'          => $form->form_classes( $this->is_submitted ),
135
			'edit_form_link'        => $form->edit_form_link(),
136
			'submit_button_classes' => $form->submit_button_classes(),
137
			'submit_button_text'    => $form->submit_button_text( $attr['submit'] ),
138
			'ajax'                  => $attr['ajax'],
139
			'form_settings'         => $form_data['form_settings'],
140
			'form_data'             => $form_data,
141
			'form'                  => $form,
142
			'form_id'               => $form_id,
143
		];
144
	}
145
146
	/**
147
	 * Process the shortcode attributes and prepare rendering.
148
	 *
149
	 * @since %VERSION%
150
	 *
151
	 * @param array|string $atts Attributes as passed to the shortcode.
152
	 *
153
	 * @return string Rendered HTML of the shortcode.
154
	 */
155
	public function process_shortcode( $atts ) {
156
		try {
157
			// Determine if the form has been submitted.
158
			$this->is_submitted = $this->is_submitting_form();
159
			// Process the shortcode attributes.
160
			$atts    = $this->process_attributes( $atts );
161
			$context = $this->get_context( $atts );
162
			return $this->render( $context );
163
		} catch ( Exception $e ) {
164
			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...
165
		}
166
	}
167
    
168
   /**
169
	 * Get the View URI to use for rendering the shortcode.
170
	 *
171
	 * @since %VERSION%
172
	 *
173
	 * @return string View URI.
174
	 */
175
	protected function get_view_uri() {
176
		return $this->view_uri;
177
    }
178
    
179
    /**
180
	 * Set the view URI.
181
	 *
182
	 * @since %VERSION%
183
	 *
184
	 * @param string $uri The URI to use.
185
	 */
186
	private function set_view_uri( $uri ) {
187
		$this->view_uri = $uri;
188
	}
189
190
	/**
191
	 * Determine whether a form is currently being submitted.
192
	 *
193
	 * @since %VERSION%
194
	 * @return bool
195
	 */
196
	private function is_submitting_form() {
197
		return ! empty( $_POST );
198
	}
199
    
200
    /**
201
	 * Render the current Renderable.
202
	 *
203
	 * @since %VERSION%
204
	 *
205
	 * @param array $context Context in which to render.
206
	 *
207
	 * @return string Rendered HTML.
208
	 */
209
	public function render( array $context = [] ) {
210
		try {
211
			$this->enqueue_assets();
212
			$view = new FormEscapedView( new NoOverrideLocationView( $this->get_view_uri() ) );
213
			return $view->render( $context );
214
		} catch ( \Exception $e ) {
215
			return $this->exception_to_string( $e );
216
		}
217
	}
218
	
219
	/**
220
	 * Get the form object.
221
	 *
222
	 * @since %VERSION%
223
	 *
224
	 * @param int              $form_id       The ID for the form.
225
	 * @param EasyFormsModel   $form_data  The form Object.
226
	 * @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...
227
	 *
228
	 * @return EasyForm
229
	 */
230
	private function get_optin_form( $form_id, $form_data, $attr ) {
231
		$form = new EasyForm( $form_id, $form_data, $attr );
232
		if ( $this->is_submitted ) {
233
			$this->handle_submission( $form );
234
		}
235
		return $form;
236
	}
237
238
	/**
239
	 * Handle the form submission.
240
	 *
241
	 * @since %VERSION%
242
	 *
243
	 * @param EasyForm $form The form object.
244
	 *
245
	 * @return Subscriber|null Returns a new Subscriber object, or null if one was not created.
246
	 * @throws InvalidURI When an invalid URI is set for the view.
247
	 */
248
	private function handle_submission( EasyForm $form ) {
249
		$form->set_submission( $_POST );
250
		$form->validate_submission();
251
		// Maybe update the view URI.
252
		if ( ! $form->has_errors() ) {
253
			$this->set_view_uri( self::SUBMITTED_URI );
254
			$subscriber = ( new SubscriberRepository() )->create_from_form( $form );
255
		}
256
		return isset( $subscriber ) ? $subscriber : null;
257
	}
258
    
259
    /**
260
	 * Convert an exception to a string.
261
	 *
262
	 * @since %VERSION%
263
	 *
264
	 * @param \Exception $e The exception object.
265
	 *
266
	 * @return string
267
	 */
268
	private function exception_to_string( \Exception $e ) {
269
		return sprintf(
270
			/* translators: %s refers to the error message */
271
			esc_html__( 'There was an error displaying the form: %s', 'easy-forms-text-domain' ),
272
			$e->getMessage()
273
		);
274
	}
275
276
	private function skip_style() {
277
		return defined( 'YIKES_MAILCHIMP_EXCLUDE_STYLES' );
278
	}
279
280
	public function load_assets() {
281
		$submission_helper = new ScriptAsset(
282
            'form-submission-helpers',
283
            'assets/js/dev/form-submission-helpers',
284
            [ 'jquery' ],
285
            '1.0.0',
286
            ScriptAsset::ENQUEUE_HEADER
287
        );
288
289
        $submission_helper->add_localization( 'form_submission_helpers', array(
290
			'ajax_url'           => esc_url( admin_url( 'admin-ajax.php' ) ),
291
			'preloader_url'      => apply_filters( 'yikes-mailchimp-preloader', esc_url_raw( admin_url( 'images/wpspin_light.gif' ) ) ),
292
			'countries_with_zip' => $this->countries_with_zip(),
293
			'page_data'          => $this->page_data(),
294
		) );
295
296
		$assets = $this->skip_style() === false ? [
297
			new StyleAsset( 'yikes-inc-easy-mailchimp-public-styles', static::CSS_URI ),
298
			$submission_helper,
299
		] : [
300
			$submission_helper,
301
		];
302
303
		$this->assets = $assets;
304
	}
305
306
	public function countries_with_zip() {
307
        return [
308
            'US' => 'US', 'GB' => 'GB', 'CA' => 'CA', 
309
            'IE' => 'IE', 'CN' => 'CN', 'IN' => 'IN', 
310
            'AU' => 'AU', 'BR' => 'BR', 'MX' => 'MX',
311
            'IT' => 'IT', 'NZ' => 'NZ', 'JP' => 'JP',
312
            'FR' => 'FR', 'GR' => 'GR', 'DE' => 'DE',
313
            'NL' => 'NL', 'PT' => 'PT', 'ES' => 'ES'
314
        ];
315
    }
316
317
    public function page_data() {
318
        global $post;
319
		$page_data = isset( $post->ID ) ? $post->ID : 0;
320
		return apply_filters( 'yikes-mailchimp-page-data', $page_data );
321
    }
322
}
323