Completed
Pull Request — staging (#840)
by
unknown
15:43
created

EasyFormsShortcode   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 261
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 6

Importance

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