GravityView  1.19.4
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  private function current_user_can_copy( $post ) {
92 
93  $id = is_object( $post ) ? $post->ID : $post;
94 
95  // Can't edit this current View
96  return GVCommon::has_cap( 'copy_gravityviews', $id );
97 
98  }
99 
100  /**
101  * Create a duplicate from a View $post
102  *
103  * @param WP_Post $post
104  * @param string $status The post status
105  * @since 1.6
106  */
107  private function create_duplicate( $post, $status = '' ) {
108 
109  // We only want to clone Views
110  if ( $post->post_type !== 'gravityview' ) {
111  return;
112  }
113 
114  $new_view_author = wp_get_current_user();
115 
116  /**
117  * @filter `gravityview/duplicate-view/status` Modify the default status for a new View. Return empty for the new View to inherit existing View status
118  * @since 1.6
119  * @param string|null If string, the status to set for the new View. If empty, use existing View status.
120  * @param WP_Post $post View being cloned
121  */
122  $new_view_status = apply_filters('gravityview/duplicate-view/status', $status, $post );
123 
124  $new_view = array(
125  'menu_order' => $post->menu_order,
126  'comment_status' => $post->comment_status,
127  'ping_status' => $post->ping_status,
128  'post_author' => $new_view_author->ID,
129  'post_content' => $post->post_content,
130  'post_excerpt' => $post->post_excerpt,
131  'post_mime_type' => $post->post_mime_type,
132  'post_parent' => $post->post_parent,
133  'post_password' => $post->post_password,
134  'post_status' => ( empty( $new_view_status ) ) ? $post->post_status : $new_view_status,
135  'post_title' => $post->post_title,
136  'post_type' => $post->post_type,
137  );
138 
139  /**
140  * @filter `gravityview/duplicate-view/copy-date` When copying a View, should the date also be copied?
141  * @since 1.6
142  * @param boolean $copy_date Whether the copy the date from the existing View. Default: `false`
143  * @param WP_Post $post View being cloned
144  */
145  $copy_date = apply_filters('gravityview/duplicate-view/copy-date', false, $post );
146 
147  if ( $copy_date ) {
148  $new_view['post_date'] = $new_post_date = $post->post_date;
149  $new_view['post_date_gmt'] = get_gmt_from_date( $new_post_date );
150  }
151 
152  /**
153  * @filter `gravityview/duplicate-view/new-view` Modify View configuration before creating the duplicated View.
154  * @since 1.6
155  * @param array $new_view Array of settings to be passed to wp_insert_post()
156  * @param WP_Post $post View being cloned
157  */
158  $new_view = apply_filters('gravityview/duplicate-view/new-view', $new_view, $post );
159 
160  // Magic happens here.
161  $new_view_id = wp_insert_post( $new_view );
162 
163  // If the copy is published or scheduled, we have to set a proper slug.
164  if ( $new_view_status == 'publish' || $new_view_status == 'future' ) {
165 
166  $view_name = wp_unique_post_slug( $post->post_name, $new_view_id, $new_view_status, $post->post_type, $post->post_parent );
167 
168  $new_view_name_array = array(
169  'ID' => $new_view_id,
170  'post_name' => $view_name,
171  );
172 
173  // Update the post into the database
174  wp_update_post( $new_view_name_array );
175  }
176 
177  /**
178  * @action `gv_duplicate_view` After a View is duplicated, perform an action
179  * @since 1.6
180  * @see GravityView_Admin_Duplicate_View::copy_view_meta_info
181  * @param int $new_view_id The ID of the newly created View
182  * @param WP_Post $post The View that was just cloned
183  */
184  do_action( 'gv_duplicate_view', $new_view_id, $post );
185 
186  delete_post_meta( $new_view_id, '_dp_original' );
187 
188  add_post_meta( $new_view_id, '_dp_original', $post->ID, false );
189 
190  return $new_view_id;
191  }
192 
193  /**
194  * Copy the meta information of a post to another View
195  *
196  * @since 1.6
197  *
198  * @param int $new_view_id The ID of the newly created View
199  * @param WP_Post $post The View that was just cloned
200  *
201  * @return void
202  */
203  public function copy_view_meta_info( $new_id, $post ) {
204 
205  $post_meta_keys = get_post_custom_keys( $post->ID );
206 
207  if ( empty( $post_meta_keys ) ) {
208  return;
209  }
210 
211  foreach ( $post_meta_keys as $meta_key ) {
212 
213  $meta_values = get_post_custom_values( $meta_key, $post->ID );
214 
215  foreach ( $meta_values as $meta_value ) {
216 
217  $meta_value = maybe_unserialize( $meta_value );
218 
219  add_post_meta( $new_id, $meta_key, $meta_value );
220  }
221  }
222  }
223 
224  /**
225  * Add the link to action list for post_row_actions
226  *
227  * @since 1.6
228  * @param array $actions Row action links. Defaults are 'Edit', 'Quick Edit', 'Restore, 'Trash', 'Delete Permanently', 'Preview', and 'View'
229  * @param WP_Post $post
230  */
231  public function make_duplicate_link_row( $actions, $post ) {
232 
233  // Only process on GravityView Views
234  if ( get_post_type( $post ) === 'gravityview' && $this->current_user_can_copy( $post ) ) {
235 
236  $clone_link = $this->get_clone_view_link( $post->ID, 'display', false );
237  $clone_text = __( 'Clone', 'gravityview' );
238  $clone_title = __( 'Clone this View', 'gravityview' );
239 
240  $actions['clone'] = gravityview_get_link( $clone_link, $clone_text, 'title='.$clone_title );
241 
242  $clone_draft_link = $this->get_clone_view_link( $post->ID );
243  $clone_draft_text = $this->is_all_views_page() ? __( 'New Draft', 'gravityview' ) : __( 'Clone View', 'gravityview' );
244  $clone_draft_title = __( 'Copy as a new draft View', 'gravityview' );
245 
246  $actions['edit_as_new_draft'] = gravityview_get_link( $clone_draft_link, esc_html( $clone_draft_text ), 'title='.$clone_draft_title );
247  }
248 
249  return $actions;
250  }
251 
252  /**
253  * Retrieve duplicate post link for post.
254  *
255  * @since 1.6
256  *
257  * @param int $id Optional. Post ID.
258  * @param string $context Optional, default to display. How to write the '&', defaults to '&amp;'.
259  * @param string $draft Optional, default to true
260  * @return string
261  */
262  private function get_clone_view_link( $id = 0, $context = 'display', $draft = true ) {
263 
264  // Make sure they have permission
265  if ( false === $this->current_user_can_copy( $id ) ) {
266  return '';
267  }
268 
269  // Verify the View exists
270  if ( !$view = get_post( $id ) ) {
271  return '';
272  }
273 
274  $action_name = $draft ? "duplicate_view_as_draft" : "duplicate_view";
275 
276  $action = '?action=' . $action_name . '&post=' . $view->ID;
277 
278  if ( 'display' == $context ) {
279  $action = esc_html( $action );
280  }
281 
282  $post_type_object = get_post_type_object( $view->post_type );
283 
284  /** If there's no gravityview post type for some reason, abort! */
285  if ( !$post_type_object ) {
286  do_action( 'gravityview_log_error', __METHOD__ . ' No gravityview post type exists when trying to clone the View.', $view );
287  return '';
288  }
289 
290  /**
291  * @filter `gravityview/duplicate-view/get_clone_view_link` Modify the Clone View URL that is generated
292  * @since 1.6
293  * @param string $clone_view_link Link with `admin_url("admin.php")`, plus the action query string
294  * @param int $view_id View ID
295  * @param string $context How to display the link. If "display", the URL is run through esc_html(). Default: `display`
296  */
297  $clone_view_link = apply_filters( 'gravityview/duplicate-view/get_clone_view_link', admin_url( "admin.php". $action ), $view->ID, $context );
298 
299  return $clone_view_link;
300  }
301 
302 
303  /**
304  * This function calls the creation of a new copy of the selected post (as a draft)
305  * then redirects to the edit post screen
306  *
307  * @since 1.6
308  * @return void
309  */
310  public function save_as_new_view_draft() {
311  $this->save_as_new_view( 'draft' );
312  }
313 
314  /**
315  * This function calls the creation of a new copy of the selected post (by default preserving the original publish status)
316  * then redirects to the post list
317  *
318  * @since 1.6
319  * @param string $status The status to set for the new View
320  * @return void
321  */
322  public function save_as_new_view( $status = '' ) {
323 
324  if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) ) ) {
325  wp_die( __( 'No post to duplicate has been supplied!', 'gravityview' ) );
326  }
327 
328  // Get the original post
329  $id = ( isset( $_GET['post'] ) ? $_GET['post'] : $_POST['post'] );
330 
331  if( ! $this->current_user_can_copy( $id ) ) {
332  wp_die( __( 'You don\'t have permission to copy this View.', 'gravityview' ) );
333  }
334 
335  $post = get_post( $id );
336 
337  // Copy the post and insert it
338  if ( isset( $post ) && $post != NULL ) {
339 
340  $new_id = $this->create_duplicate( $post, $status );
341 
342  if ( $status == '' ) {
343  // Redirect to the post list screen
344  wp_redirect( admin_url( 'edit.php?post_type=' . $post->post_type ) );
345  } else {
346  // Redirect to the edit screen for the new draft post
347  wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
348  }
349  exit;
350 
351  } else {
352 
353  wp_die( sprintf( esc_attr__( 'Copy creation failed, could not find original View with ID #%d', 'gravityview' ), $id ) );
354 
355  }
356  }
357 
358 }
359 
360 
current_user_can_copy($post)
Test if the user is allowed to copy Views.
copy_view_meta_info($new_id, $post)
Copy the meta information of a post to another View.
static has_cap($caps= '', $object_id=null, $user_id=null)
Alias of GravityView_Roles_Capabilities::has_cap()
get_clone_view_link($id=0, $context= 'display', $draft=true)
Retrieve duplicate post link for post.
make_duplicate_link_row($actions, $post)
Add the link to action list for post_row_actions.
connected_form_links($links=array(), $form=array())
Add Duplicate View link to the Data Source metabox.
gravityview_get_link($href= '', $anchor_text= '', $atts=array())
Generate an HTML anchor tag with a list of supported attributes.
save_as_new_view($status= '')
This function calls the creation of a new copy of the selected post (by default preserving the origin...
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
create_duplicate($post, $status= '')
Create a duplicate from a View $post.
is_all_views_page()
Is the current screen the All Views screen?