Completed
Push — release/2.2 ( 98e896...b0db7e )
by Ravinder
724:37 queued 717:31
created

Give_Form_Duplicator::reset_stats()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
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 View Code Duplication
				if ( current_user_can( 'edit_posts' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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