Test Failed
Push — master ( f5256c...25a383 )
by Devin
07:02
created

Give_Form_Duplicator::handler()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 82

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 9
nop 0
dl 0
loc 82
rs 7.1482
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * The class contains logic to clone a donation form.
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Forms
7
 * @copyright   Copyright (c) 2018, WordImpress
8
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
 * @since       2.2.0
10
 */
11
12
if ( ! class_exists( 'Give_Form_Duplicator' ) ) {
13
14
	/**
15
	 * Give_Form_Duplicator class
16
	 */
17
	class Give_Form_Duplicator {
18
19
		/**
20
		 * Constructor Function
21
		 */
22
		public function __construct() {
23
24
			// Add the 'Clone Form' to Row Actions.
25
			add_filter( 'post_row_actions', array( $this, 'row_action' ), 10, 2 );
26
27
			// Run admin_action hook.
28
			add_action( 'admin_action_give_duplicate_form', array( $this, 'handler' ) );
29
		}
30
31
32
		/**
33
		 * Adds the 'Clone Form' in the row actions.
34
		 *
35
		 * @param array          $actions Array of Row Actions.
36
		 * @param WP_Post Object $post    Post Object.
37
		 *
38
		 * @since 2.2.0
39
		 *
40
		 * @return array
41
		 */
42
		public function row_action( $actions, $post ) {
43
44
			// @codingStandardsIgnoreStart
45
46
			if ( isset( $_GET['post_type'] ) && 'give_forms' === give_clean( $_GET['post_type'] ) ) { // WPCS: input var ok.
47
				if ( current_user_can( 'edit_posts' ) ) {
48
					$actions['duplicate_form'] = sprintf(
49
						'<a href="%1$s">%2$s</a>',
50
						wp_nonce_url( add_query_arg(
51
							array(
52
								'action'  => 'give_duplicate_form',
53
								'form_id' => $post->ID,
54
							),
55
							admin_url( 'admin.php' )
56
						), 'give-duplicate-form' ),
57
						__( 'Duplicate', 'give' )
58
					);
59
				}
60
			}
61
62
			// @codingStandardsIgnoreEnd
63
64
			return $actions;
65
		}
66
67
68
		/**
69
		 * Clones the Form
70
		 *
71
		 * @since 2.2.0
72
		 *
73
		 * @return void
74
		 */
75
		public function handler() {
76
			// Validate action.
77
			// @codingStandardsIgnoreStart
78
			if (
79
				! isset( $_REQUEST['form_id'] )
80
				|| ! isset( $_REQUEST['action'] )
81
				|| ( 'give_duplicate_form' !== $_REQUEST['action'] )
82
			) {
83
				wp_die( esc_html__( 'Form ID not found in the query string', 'give' ) );
84
85
			} elseif ( ! wp_verify_nonce( give_clean( $_REQUEST['_wpnonce'] ), 'give-duplicate-form' ) ) {
86
87
				wp_die( esc_html__( 'Nonce verification failed', 'give' ) );
88
			}
89
			// @codingStandardsIgnoreEnd
90
91
			$form_id      = give_clean( $_REQUEST['form_id'] ); // @codingStandardsIgnoreLine
92
			$post_data    = get_post( $form_id );
93
			$current_user = wp_get_current_user();
94
			$error_notice = sprintf(
95
				/* translators: %s: Form ID */
96
				esc_html__( 'Cloning failed. Form with ID %s does not exist.', 'give' ),
97
				absint( $form_id )
98
			);
99
100
			if ( isset( $post_data ) && null !== $post_data ) {
101
102
				$args = array(
103
					'comment_status' => $post_data->comment_status,
104
					'ping_status'    => $post_data->ping_status,
105
					'post_author'    => $current_user->ID,
106
					'post_content'   => $post_data->post_content,
107
					'post_excerpt'   => $post_data->post_excerpt,
108
					'post_name'      => $post_data->post_name,
109
					'post_parent'    => $post_data->post_parent,
110
					'post_password'  => $post_data->post_password,
111
					'post_status'    => 'draft',
112
					'post_title'     => $post_data->post_title,
113
					'post_type'      => $post_data->post_type,
114
					'to_ping'        => $post_data->to_ping,
115
					'menu_order'     => $post_data->menu_order,
116
				);
117
118
				// Get the ID of the cloned post.
119
				$duplicate_form_id = wp_insert_post( $args );
120
121
				$this->duplicate_taxonomies( $duplicate_form_id, $post_data );
122
				$this->duplicate_meta_data( $duplicate_form_id, $post_data );
123
				$this->reset_stats( $duplicate_form_id );
124
125
				/**
126
				 * Fire the action
127
				 *
128
				 * @since 2.2.0
129
				 *
130
				 * @param int $duplicate_form_id Duplicated form ID.
131
				 * @param int $form_id           Form ID.
132
				 */
133
				do_action( 'give_form_duplicated', $duplicate_form_id, $form_id );
134
135
				if ( ! is_wp_error( $duplicate_form_id ) ) {
136
					// Redirect to the cloned form editor page.
137
					wp_safe_redirect(
138
						add_query_arg(
139
							array(
140
								'action' => 'edit',
141
								'post'   => $duplicate_form_id,
142
							),
143
							admin_url( 'post.php' )
144
						)
145
					);
146
				} else {
147
					wp_die( $error_notice ); // @codingStandardsIgnoreLine
148
				}
149
150
				exit;
151
152
			} else {
153
154
				wp_die( $error_notice ); // @codingStandardsIgnoreLine
155
			}
156
		}
157
158
159
		/**
160
		 * Clone taxonomies
161
		 *
162
		 * @since  2.2.0
163
		 * @access private
164
		 *
165
		 * @param int     $new_form_id New form ID.
166
		 * @param WP_Post $old_form    Old form object.
167
		 */
168
		private function duplicate_taxonomies( $new_form_id, $old_form ) {
169
			// Get the taxonomies of the post type `give_forms`.
170
			$taxonomies = get_object_taxonomies( $old_form->post_type );
171
172
			foreach ( $taxonomies as $taxonomy ) {
173
174
				$post_terms = wp_get_object_terms(
175
					$old_form->ID,
176
					$taxonomy,
177
					array(
178
						'fields' => 'slugs',
179
					)
180
				);
181
182
				wp_set_object_terms(
183
					$new_form_id,
184
					$post_terms,
185
					$taxonomy,
186
					false
187
				);
188
			}
189
		}
190
191
192
		/**
193
		 * Clone meta data
194
		 *
195
		 * @since  2.2.0
196
		 * @access private
197
		 *
198
		 * @param int     $new_form_id New Form ID.
199
		 * @param WP_Post $old_form    Old form object.
200
		 */
201
		private function duplicate_meta_data( $new_form_id, $old_form ) {
202
			global $wpdb;
203
204
			// Clone the metadata of the form.
205
			$post_meta_query = $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->formmeta} WHERE form_id=%s", $old_form->ID );
206
207
			$post_meta_data = $wpdb->get_results( $post_meta_query ); // WPCS: db call ok. WPCS: cache ok. WPCS: unprepared SQL OK.
208
209
			if ( ! empty( $post_meta_data ) ) {
210
211
				$duplicate_query        = "INSERT INTO {$wpdb->formmeta} (form_id, meta_key, meta_value) ";
212
				$duplicate_query_select = array();
213
214
				foreach ( $post_meta_data as $meta_data ) {
215
					$meta_key                 = $meta_data->meta_key;
216
					$meta_value               = $meta_data->meta_value;
217
					$duplicate_query_select[] = $wpdb->prepare( 'SELECT %s, %s, %s', $new_form_id, $meta_key, $meta_value );
218
				}
219
220
				$duplicate_query .= implode( ' UNION ALL ', $duplicate_query_select );
221
222
				$wpdb->query( $duplicate_query ); // WPCS: db call ok. WPCS: cache ok. WPCS: unprepared SQL OK.
223
			}
224
		}
225
226
		/**
227
		 * Reset stats for cloned form
228
		 *
229
		 * @since  2.2.0
230
		 * @access private
231
		 *
232
		 * @param int $new_form_id New Form ID.
233
		 */
234
		private function reset_stats( $new_form_id ) {
235
			global $wpdb;
236
237
			$meta_keys = array( '_give_form_sales', '_give_form_earnings' );
238
239
			/**
240
			 * Fire the filter
241
			 *
242
			 * @since  2.2.0
243
			 */
244
			$meta_keys = apply_filters( 'give_duplicate_form_reset_stat_meta_keys', $meta_keys );
245
			$meta_keys = 'meta_key=\'' . implode( '\' OR meta_key=\'', $meta_keys ) . '\'';
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
246
247
			$wpdb->query(
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
248
				$wpdb->prepare(
249
					"
250
					UPDATE $wpdb->formmeta
251
					SET meta_value=0
252
					WHERE form_id=%d
253
					AND ({$meta_keys})
254
					",
255
					$new_form_id
256
				)
257
			);
258
		}
259
	}
260
261
	new Give_Form_Duplicator();
262
}
263