GravityView  1.22.6
The best, easiest way to display Gravity Forms entries on your website.
class-gravityview-admin-duplicate-view.php
Go to the documentation of this file.
1 <?php
2 
3 /**
4  * Class GravityView_Admin_Duplicate_View
5  *
6  * Based on the {@link http://lopo.it/duplicate-post-plugin/ Duplicate Post plugin} by Enrico Battocchi - highly recommended!
7  *
8  * @package GravityView
9  *
10  * @since 1.6
11  */
13 
14 
15  function __construct() {
16 
17  // Only run on Admin
18  if ( !is_admin() ) {
19  return;
20  }
21 
22  // If the Duplicate Post plugin is active, don't run.
23  if( defined('DUPLICATE_POST_CURRENT_VERSION') ) {
24  return;
25  }
26 
27  $this->add_hooks();
28  }
29 
30  /**
31  * Add actions & filters
32  * @since 1.15
33  * @return void
34  */
35  private function add_hooks() {
36  add_filter( 'post_row_actions', array( $this, 'make_duplicate_link_row' ), 10, 2 );
37 
38  /**
39  * Connect actions to functions
40  */
41  add_action( 'admin_action_duplicate_view', array( $this, 'save_as_new_view' ) );
42  add_action( 'admin_action_duplicate_view_as_draft', array( $this, 'save_as_new_view_draft' ) );
43 
44  // Using our action hooks to copy meta fields
45  add_action( 'gv_duplicate_view', array( $this, 'copy_view_meta_info' ), 10, 2 );
46 
47  add_filter( 'gravityview_connected_form_links', array( $this, 'connected_form_links' ), 10, 2 );
48  }
49 
50  /**
51  * Add Duplicate View link to the Data Source metabox
52  *
53  * @param array $links Array of link HTML to display in the Data Source metabox
54  * @param array $form Gravity Forms form array
55  *
56  * @return array If it's the All Views page, return unedited. Otherwise, add a link to create cloned draft of View
57  */
58  function connected_form_links( $links = array(), $form = array() ) {
59  /** @global WP_Post $post */
60  global $post;
61 
62  // We only want to add Clone links to the Edit View metabox
63  if( !$this->is_all_views_page() ) {
64 
65  if( $duplicate_links = $this->make_duplicate_link_row( array(), $post ) ) {
66  $links[] = '<span>' . $duplicate_links['edit_as_new_draft'] . '</span>';
67  }
68 
69  }
70 
71  return $links;
72 
73  }
74 
75  /**
76  * Is the current screen the All Views screen?
77  *
78  * @return bool
79  */
80  private function is_all_views_page() {
81  global $pagenow;
82 
83  return $pagenow === 'edit.php';
84  }
85 
86  /**
87  * Test if the user is allowed to copy Views
88  *
89  * @since 1.6
90  *
91  * @param WP_Post|int Post ID or Post object
92  *
93  * @return bool True: user can copy the View; false: nope.
94  */
95  private function current_user_can_copy( $post ) {
96 
97  $id = is_object( $post ) ? $post->ID : $post;
98 
99  // Can't edit this current View
100  return GVCommon::has_cap( 'copy_gravityviews', $id );
101 
102  }
103 
104  /**
105  * Create a duplicate from a View $post
106  *
107  * @param WP_Post $post
108  * @param string $status The post status
109  * @since 1.6
110  */
111  private function create_duplicate( $post, $status = '' ) {
112 
113  // We only want to clone Views
114  if ( $post->post_type !== 'gravityview' ) {
115  return;
116  }
117 
118  $new_view_author = wp_get_current_user();
119 
120  /**
121  * @filter `gravityview/duplicate-view/status` Modify the default status for a new View. Return empty for the new View to inherit existing View status
122  * @since 1.6
123  * @param string|null If string, the status to set for the new View. If empty, use existing View status.
124  * @param WP_Post $post View being cloned
125  */
126  $new_view_status = apply_filters('gravityview/duplicate-view/status', $status, $post );
127 
128  $new_view = array(
129  'menu_order' => $post->menu_order,
130  'comment_status' => $post->comment_status,
131  'ping_status' => $post->ping_status,
132  'post_author' => $new_view_author->ID,
133  'post_content' => $post->post_content,
134  'post_excerpt' => $post->post_excerpt,
135  'post_mime_type' => $post->post_mime_type,
136  'post_parent' => $post->post_parent,
137  'post_password' => $post->post_password,
138  'post_status' => ( empty( $new_view_status ) ) ? $post->post_status : $new_view_status,
139  'post_title' => $post->post_title,
140  'post_type' => $post->post_type,
141  );
142 
143  /**
144  * @filter `gravityview/duplicate-view/copy-date` When copying a View, should the date also be copied?
145  * @since 1.6
146  * @param boolean $copy_date Whether the copy the date from the existing View. Default: `false`
147  * @param WP_Post $post View being cloned
148  */
149  $copy_date = apply_filters('gravityview/duplicate-view/copy-date', false, $post );
150 
151  if ( $copy_date ) {
152  $new_view['post_date'] = $new_post_date = $post->post_date;
153  $new_view['post_date_gmt'] = get_gmt_from_date( $new_post_date );
154  }
155 
156  /**
157  * @filter `gravityview/duplicate-view/new-view` Modify View configuration before creating the duplicated View.
158  * @since 1.6
159  * @param array $new_view Array of settings to be passed to wp_insert_post()
160  * @param WP_Post $post View being cloned
161  */
162  $new_view = apply_filters('gravityview/duplicate-view/new-view', $new_view, $post );
163 
164  // Magic happens here.
165  $new_view_id = wp_insert_post( $new_view );
166 
167  // If the copy is published or scheduled, we have to set a proper slug.
168  if ( $new_view_status == 'publish' || $new_view_status == 'future' ) {
169 
170  $view_name = wp_unique_post_slug( $post->post_name, $new_view_id, $new_view_status, $post->post_type, $post->post_parent );
171 
172  $new_view_name_array = array(
173  'ID' => $new_view_id,
174  'post_name' => $view_name,
175  );
176 
177  // Update the post into the database
178  wp_update_post( $new_view_name_array );
179  }
180 
181  /**
182  * @action `gv_duplicate_view` After a View is duplicated, perform an action
183  * @since 1.6
184  * @see GravityView_Admin_Duplicate_View::copy_view_meta_info
185  * @param int $new_view_id The ID of the newly created View
186  * @param WP_Post $post The View that was just cloned
187  */
188  do_action( 'gv_duplicate_view', $new_view_id, $post );
189 
190  delete_post_meta( $new_view_id, '_dp_original' );
191 
192  add_post_meta( $new_view_id, '_dp_original', $post->ID, false );
193 
194  return $new_view_id;
195  }
196 
197  /**
198  * Copy the meta information of a post to another View
199  *
200  * @since 1.6
201  *
202  * @param int $new_view_id The ID of the newly created View
203  * @param WP_Post $post The View that was just cloned
204  *
205  * @return void
206  */
207  public function copy_view_meta_info( $new_id, $post ) {
208 
209  $post_meta_keys = get_post_custom_keys( $post->ID );
210 
211  if ( empty( $post_meta_keys ) ) {
212  return;
213  }
214 
215  foreach ( $post_meta_keys as $meta_key ) {
216 
217  $meta_values = get_post_custom_values( $meta_key, $post->ID );
218 
219  foreach ( $meta_values as $meta_value ) {
220 
221  $meta_value = maybe_unserialize( $meta_value );
222 
223  add_post_meta( $new_id, $meta_key, $meta_value );
224  }
225  }
226  }
227 
228  /**
229  * Add the link to action list for post_row_actions
230  *
231  * @since 1.6
232  * @param array $actions Row action links. Defaults are 'Edit', 'Quick Edit', 'Restore, 'Trash', 'Delete Permanently', 'Preview', and 'View'
233  * @param WP_Post $post
234  */
235  public function make_duplicate_link_row( $actions, $post ) {
236 
237  // Only process on GravityView Views
238  if ( get_post_type( $post ) === 'gravityview' && $this->current_user_can_copy( $post ) ) {
239 
240  $clone_link = $this->get_clone_view_link( $post->ID, 'display', false );
241  $clone_text = __( 'Clone', 'gravityview' );
242  $clone_title = __( 'Clone this View', 'gravityview' );
243 
244  $actions['clone'] = gravityview_get_link( $clone_link, $clone_text, 'title='.$clone_title );
245 
246  $clone_draft_link = $this->get_clone_view_link( $post->ID );
247  $clone_draft_text = $this->is_all_views_page() ? __( 'New Draft', 'gravityview' ) : __( 'Clone View', 'gravityview' );
248  $clone_draft_title = __( 'Copy as a new draft View', 'gravityview' );
249 
250  $actions['edit_as_new_draft'] = gravityview_get_link( $clone_draft_link, esc_html( $clone_draft_text ), 'title='.$clone_draft_title );
251  }
252 
253  return $actions;
254  }
255 
256  /**
257  * Retrieve duplicate post link for post.
258  *
259  * @since 1.6
260  *
261  * @param int $id Optional. Post ID.
262  * @param string $context Optional, default to display. How to write the '&', defaults to '&amp;'.
263  * @param string $draft Optional, default to true
264  * @return string
265  */
266  private function get_clone_view_link( $id = 0, $context = 'display', $draft = true ) {
267 
268  // Make sure they have permission
269  if ( false === $this->current_user_can_copy( $id ) ) {
270  return '';
271  }
272 
273  // Verify the View exists
274  if ( !$view = get_post( $id ) ) {
275  return '';
276  }
277 
278  $action_name = $draft ? "duplicate_view_as_draft" : "duplicate_view";
279 
280  $action = '?action=' . $action_name . '&post=' . $view->ID;
281 
282  if ( 'display' == $context ) {
283  $action = esc_html( $action );
284  }
285 
286  $post_type_object = get_post_type_object( $view->post_type );
287 
288  /** If there's no gravityview post type for some reason, abort! */
289  if ( !$post_type_object ) {
290  do_action( 'gravityview_log_error', __METHOD__ . ' No gravityview post type exists when trying to clone the View.', $view );
291  return '';
292  }
293 
294  /**
295  * @filter `gravityview/duplicate-view/get_clone_view_link` Modify the Clone View URL that is generated
296  * @since 1.6
297  * @param string $clone_view_link Link with `admin_url("admin.php")`, plus the action query string
298  * @param int $view_id View ID
299  * @param string $context How to display the link. If "display", the URL is run through esc_html(). Default: `display`
300  */
301  $clone_view_link = apply_filters( 'gravityview/duplicate-view/get_clone_view_link', admin_url( "admin.php". $action ), $view->ID, $context );
302 
303  return $clone_view_link;
304  }
305 
306 
307  /**
308  * This function calls the creation of a new copy of the selected post (as a draft)
309  * then redirects to the edit post screen
310  *
311  * @since 1.6
312  * @return void
313  */
314  public function save_as_new_view_draft() {
315  $this->save_as_new_view( 'draft' );
316  }
317 
318  /**
319  * This function calls the creation of a new copy of the selected post (by default preserving the original publish status)
320  * then redirects to the post list
321  *
322  * @since 1.6
323  * @param string $status The status to set for the new View
324  * @return void
325  */
326  public function save_as_new_view( $status = '' ) {
327 
328  if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) ) ) {
329  wp_die( __( 'No post to duplicate has been supplied!', 'gravityview' ) );
330  }
331 
332  // Get the original post
333  $id = ( isset( $_GET['post'] ) ? $_GET['post'] : $_POST['post'] );
334 
335  if( ! $this->current_user_can_copy( $id ) ) {
336  wp_die( __( 'You don\'t have permission to copy this View.', 'gravityview' ) );
337  }
338 
339  $post = get_post( $id );
340 
341  // Copy the post and insert it
342  if ( isset( $post ) && $post != NULL ) {
343 
344  $new_id = $this->create_duplicate( $post, $status );
345 
346  if ( $status == '' ) {
347  // Redirect to the post list screen
348  wp_redirect( admin_url( 'edit.php?post_type=' . $post->post_type ) );
349  } else {
350  // Redirect to the edit screen for the new draft post
351  wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
352  }
353  exit;
354 
355  } else {
356 
357  wp_die( sprintf( esc_attr__( 'Copy creation failed, could not find original View with ID #%d', 'gravityview' ), $id ) );
358 
359  }
360  }
361 
362 }
363 
364 
connected_form_links( $links=array(), $form=array())
Add Duplicate View link to the Data Source metabox.
make_duplicate_link_row( $actions, $post)
Add the link to action list for post_row_actions.
gravityview_get_link( $href='', $anchor_text='', $atts=array())
Generate an HTML anchor tag with a list of supported attributes.
current_user_can_copy( $post)
Test if the user is allowed to copy Views.
save_as_new_view( $status='')
This function calls the creation of a new copy of the selected post (by default preserving the origin...
create_duplicate( $post, $status='')
Create a duplicate from a View $post.
get_clone_view_link( $id=0, $context='display', $draft=true)
Retrieve duplicate post link for post.
copy_view_meta_info( $new_id, $post)
Copy the meta information of a post to another View.
save_as_new_view_draft()
This function calls the creation of a new copy of the selected post (as a draft) then redirects to th...
global $post
static has_cap( $caps='', $object_id=null, $user_id=null)
Alias of GravityView_Roles_Capabilities::has_cap()
is_all_views_page()
Is the current screen the All Views screen?