duplicatepage.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <?php
  2. /*
  3. Plugin Name: Duplicate Page
  4. Plugin URI: https://wordpress.org/plugins/duplicate-page/
  5. Description: Duplicate Posts, Pages and Custom Posts using single click.
  6. Author: mndpsingh287
  7. Version: 4.0
  8. Author URI: https://profiles.wordpress.org/mndpsingh287/
  9. License: GPLv2
  10. Text Domain: duplicate-page
  11. */
  12. if (!defined('DUPLICATE_PAGE_PLUGIN_DIRNAME')) {
  13. define('DUPLICATE_PAGE_PLUGIN_DIRNAME', plugin_basename(dirname(__FILE__)));
  14. }
  15. if (!class_exists('duplicate_page')):
  16. class duplicate_page
  17. {
  18. /*
  19. * AutoLoad Hooks
  20. */
  21. public function __construct()
  22. {
  23. $opt = get_option('duplicate_page_options');
  24. register_activation_hook(__FILE__, array(&$this, 'duplicate_page_install'));
  25. add_action('admin_menu', array(&$this, 'duplicate_page_options_page'));
  26. add_filter('plugin_action_links', array(&$this, 'duplicate_page_plugin_action_links'), 10, 2);
  27. add_action('admin_action_dt_duplicate_post_as_draft', array(&$this, 'dt_duplicate_post_as_draft'));
  28. add_filter('post_row_actions', array(&$this, 'dt_duplicate_post_link'), 10, 2);
  29. add_filter('page_row_actions', array(&$this, 'dt_duplicate_post_link'), 10, 2);
  30. if (isset($opt['duplicate_post_editor']) && $opt['duplicate_post_editor'] == 'gutenberg') {
  31. add_action('admin_head', array(&$this, 'duplicate_page_custom_button_guten'));
  32. } else {
  33. add_action('post_submitbox_misc_actions', array(&$this, 'duplicate_page_custom_button_classic'));
  34. }
  35. add_action('wp_before_admin_bar_render', array(&$this, 'duplicate_page_admin_bar_link'));
  36. add_action('init', array(&$this, 'duplicate_page_load_text_domain'));
  37. add_action('wp_ajax_mk_dp_close_dp_help', array($this, 'mk_dp_close_dp_help'));
  38. }
  39. /*
  40. * Localization - 19-dec-2016
  41. */
  42. public function duplicate_page_load_text_domain()
  43. {
  44. load_plugin_textdomain('duplicate-page', false, DUPLICATE_PAGE_PLUGIN_DIRNAME.'/languages');
  45. }
  46. /*
  47. * Activation Hook
  48. */
  49. public function duplicate_page_install()
  50. {
  51. $defaultsettings = array(
  52. 'duplicate_post_status' => 'draft',
  53. 'duplicate_post_redirect' => 'to_list',
  54. 'duplicate_post_suffix' => '',
  55. 'duplicate_post_editor' => 'classic',
  56. );
  57. $opt = get_option('duplicate_page_options');
  58. if (!$opt['duplicate_post_status']) {
  59. update_option('duplicate_page_options', $defaultsettings);
  60. }
  61. }
  62. /*
  63. Action Links
  64. */
  65. public function duplicate_page_plugin_action_links($links, $file)
  66. {
  67. if ($file == plugin_basename(__FILE__)) {
  68. $duplicate_page_links = '<a href="'.get_admin_url().'options-general.php?page=duplicate_page_settings">'.__('Settings', 'duplicate-page').'</a>';
  69. $duplicate_page_donate = '<a href="https://www.webdesi9.com/donate/?plugin=duplicate-page" title="Donate Now" target="_blank" style="font-weight:bold">'.__('Donate', 'duplicate-page').'</a>';
  70. array_unshift($links, $duplicate_page_donate);
  71. array_unshift($links, $duplicate_page_links);
  72. }
  73. return $links;
  74. }
  75. /*
  76. * Admin Menu
  77. */
  78. public function duplicate_page_options_page()
  79. {
  80. add_options_page(__('Duplicate Page', 'duplicate-page'), __('Duplicate Page', 'duplicate-page'), 'manage_options', 'duplicate_page_settings', array(&$this, 'duplicate_page_settings'));
  81. }
  82. /*
  83. * Duplicate Page Admin Settings
  84. */
  85. public function duplicate_page_settings()
  86. {
  87. if (current_user_can('manage_options')) {
  88. include 'inc/admin-settings.php';
  89. }
  90. }
  91. /*
  92. * Main function
  93. */
  94. public function dt_duplicate_post_as_draft()
  95. {
  96. /*
  97. * get Nonce value
  98. */
  99. $nonce = $_REQUEST['nonce'];
  100. /*
  101. * get the original post id
  102. */
  103. $post_id = (isset($_GET['post']) ? intval($_GET['post']) : intval($_POST['post']));
  104. if(wp_verify_nonce( $nonce, 'dt-duplicate-page-'.$post_id) && current_user_can('edit_posts')) {
  105. // verify Nonce
  106. global $wpdb;
  107. $opt = get_option('duplicate_page_options');
  108. $suffix = isset($opt['duplicate_post_suffix']) && !empty($opt['duplicate_post_suffix']) ? ' -- '.$opt['duplicate_post_suffix'] : '';
  109. $post_status = !empty($opt['duplicate_post_status']) ? $opt['duplicate_post_status'] : 'draft';
  110. $redirectit = !empty($opt['duplicate_post_redirect']) ? $opt['duplicate_post_redirect'] : 'to_list';
  111. if (!(isset($_GET['post']) || isset($_POST['post']) || (isset($_REQUEST['action']) && 'dt_duplicate_post_as_draft' == $_REQUEST['action']))) {
  112. wp_die('No post to duplicate has been supplied!');
  113. }
  114. $returnpage = '';
  115. /*
  116. * and all the original post data then
  117. */
  118. $post = get_post($post_id);
  119. /*
  120. * if you don't want current user to be the new post author,
  121. * then change next couple of lines to this: $new_post_author = $post->post_author;
  122. */
  123. $current_user = wp_get_current_user();
  124. $new_post_author = $current_user->ID;
  125. /*
  126. * if post data exists, create the post duplicate
  127. */
  128. if (isset($post) && $post != null) {
  129. /*
  130. * new post data array
  131. */
  132. $args = array(
  133. 'comment_status' => $post->comment_status,
  134. 'ping_status' => $post->ping_status,
  135. 'post_author' => $new_post_author,
  136. 'post_content' => (isset($opt['duplicate_post_editor']) && $opt['duplicate_post_editor'] == 'gutenberg') ? wp_slash($post->post_content) : $post->post_content,
  137. 'post_excerpt' => $post->post_excerpt,
  138. //'post_name' => $post->post_name,
  139. 'post_parent' => $post->post_parent,
  140. 'post_password' => $post->post_password,
  141. 'post_status' => $post_status,
  142. 'post_title' => $post->post_title.$suffix,
  143. 'post_type' => $post->post_type,
  144. 'to_ping' => $post->to_ping,
  145. 'menu_order' => $post->menu_order,
  146. );
  147. /*
  148. * insert the post by wp_insert_post() function
  149. */
  150. $new_post_id = wp_insert_post($args);
  151. /*
  152. * get all current post terms ad set them to the new post draft
  153. */
  154. $taxonomies = get_object_taxonomies($post->post_type);
  155. if (!empty($taxonomies) && is_array($taxonomies)):
  156. foreach ($taxonomies as $taxonomy) {
  157. $post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
  158. wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
  159. }
  160. endif;
  161. /*
  162. * duplicate all post meta
  163. */
  164. $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
  165. if (count($post_meta_infos)!=0) {
  166. $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
  167. foreach ($post_meta_infos as $meta_info) {
  168. $meta_key = sanitize_text_field($meta_info->meta_key);
  169. $meta_value = addslashes($meta_info->meta_value);
  170. $sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
  171. }
  172. $sql_query.= implode(" UNION ALL ", $sql_query_sel);
  173. $wpdb->query($sql_query);
  174. }
  175. /*
  176. * finally, redirecting to your choice
  177. */
  178. if ($post->post_type != 'post'):
  179. $returnpage = '?post_type='.$post->post_type;
  180. endif;
  181. if (!empty($redirectit) && $redirectit == 'to_list'):
  182. wp_redirect(admin_url('edit.php'.$returnpage)); elseif (!empty($redirectit) && $redirectit == 'to_page'):
  183. wp_redirect(admin_url('post.php?action=edit&post='.$new_post_id)); else:
  184. wp_redirect(admin_url('edit.php'.$returnpage));
  185. endif;
  186. exit;
  187. } else {
  188. wp_die('Error! Post creation failed, could not find original post: '.$post_id);
  189. }
  190. } else {
  191. wp_die('Security check issue, Please try again.');
  192. }
  193. }
  194. /*
  195. * Add the duplicate link to action list for post_row_actions
  196. */
  197. public function dt_duplicate_post_link($actions, $post)
  198. {
  199. $opt = get_option('duplicate_page_options');
  200. $post_status = !empty($opt['duplicate_post_status']) ? $opt['duplicate_post_status'] : 'draft';
  201. if (current_user_can('edit_posts')) {
  202. $actions['duplicate'] = '<a href="admin.php?action=dt_duplicate_post_as_draft&amp;post='.$post->ID.'&amp;nonce='.wp_create_nonce( 'dt-duplicate-page-'.$post->ID ).'" title="Duplicate this as '.$post_status.'" rel="permalink">'.__('Duplicate This', 'duplicate-page').'</a>';
  203. }
  204. return $actions;
  205. }
  206. /*
  207. * Add the duplicate link to edit screen - classic editor
  208. */
  209. public function duplicate_page_custom_button_classic()
  210. {
  211. global $post;
  212. $opt = get_option('duplicate_page_options');
  213. $post_status = !empty($opt['duplicate_post_status']) ? $opt['duplicate_post_status'] : 'draft';
  214. $html = '<div id="major-publishing-actions">';
  215. $html .= '<div id="export-action">';
  216. $html .= '<a href="admin.php?action=dt_duplicate_post_as_draft&amp;post='.$post->ID.'&amp;nonce='.wp_create_nonce( 'dt-duplicate-page-'.$post->ID ).'" title="Duplicate this as '.$post_status.'" rel="permalink">'.__('Duplicate This', 'duplicate-page').'</a>';
  217. $html .= '</div>';
  218. $html .= '</div>';
  219. echo $html;
  220. }
  221. /*
  222. * Add the duplicate link to edit screen - gutenberg
  223. */
  224. public function duplicate_page_custom_button_guten()
  225. {
  226. global $post;
  227. if ($post) {
  228. $opt = get_option('duplicate_page_options');
  229. $post_status = !empty($opt['duplicate_post_status']) ? $opt['duplicate_post_status'] : 'draft';
  230. if (isset($opt['duplicate_post_editor']) && $opt['duplicate_post_editor'] == 'gutenberg') {
  231. ?>
  232. <style>
  233. .duplicate_page_link_guten {
  234. text-align: center;
  235. margin-top: 15px;
  236. }
  237. .duplicate_page_link_guten a {
  238. text-decoration: none;
  239. display: block;
  240. height: 30px;
  241. line-height: 28px;
  242. padding: 0 12px 2px;
  243. border-color: #ccc;
  244. background: #f7f7f7;
  245. box-shadow: inset 0 -1px 0 #ccc;
  246. border-radius: 3px;
  247. border-width: 1px;
  248. border-style: solid;
  249. }
  250. .duplicate_page_link_guten a:hover {
  251. background: #fafafa;
  252. border-color: #999;
  253. box-shadow: inset 0 -1px 0 #999;
  254. }
  255. </style>
  256. <script>
  257. jQuery(window).load(function(e){
  258. var dp_post_id = "<?php echo $post->ID; ?>";
  259. var dtnonce = "<?php echo wp_create_nonce( 'dt-duplicate-page-'.$post->ID );?>";
  260. var dp_post_title = "Duplicate this as <?php echo $post_status; ?>";
  261. var dp_duplicate_link = '<div class="duplicate_page_link_guten">';
  262. dp_duplicate_link += '<a href="admin.php?action=dt_duplicate_post_as_draft&amp;post='+dp_post_id+'&amp;nonce='+dtnonce+'" title="'+dp_post_title+'">Duplicate This</a>';
  263. dp_duplicate_link += '</div>';
  264. jQuery('.edit-post-post-status').append(dp_duplicate_link);
  265. });
  266. </script>
  267. <?php
  268. }
  269. }
  270. }
  271. /*
  272. * Admin Bar Duplicate This Link
  273. */
  274. public function duplicate_page_admin_bar_link()
  275. {
  276. global $wp_admin_bar, $post;
  277. $opt = get_option('duplicate_page_options');
  278. $post_status = !empty($opt['duplicate_post_status']) ? $opt['duplicate_post_status'] : 'draft';
  279. $current_object = get_queried_object();
  280. if (empty($current_object)) {
  281. return;
  282. }
  283. if (!empty($current_object->post_type)
  284. && ($post_type_object = get_post_type_object($current_object->post_type))
  285. && ($post_type_object->show_ui || $current_object->post_type == 'attachment')) {
  286. $wp_admin_bar->add_menu(array(
  287. 'parent' => 'edit',
  288. 'id' => 'duplicate_this',
  289. 'title' => __('Duplicate This as '.$post_status.'', 'duplicate-page'),
  290. 'href' => admin_url().'admin.php?action=dt_duplicate_post_as_draft&amp;post='.$post->ID.'&amp;nonce='.wp_create_nonce( 'dt-duplicate-page-'.$post->ID )
  291. ));
  292. }
  293. }
  294. /*
  295. * Redirect function
  296. */
  297. public static function dp_redirect($url)
  298. {
  299. echo '<script>window.location.href="'.$url.'"</script>';
  300. }
  301. /*
  302. Load Help Desk
  303. */
  304. public function load_help_desk()
  305. {
  306. $mkcontent = '';
  307. $mkcontent .= '<div class="dpmrs">';
  308. $mkcontent .= '<div class="l_dpmrs">';
  309. $mkcontent .= '';
  310. $mkcontent .= '</div>';
  311. $mkcontent .= '<div class="r_dpmrs">';
  312. $mkcontent .= '<a class="close_dp_help fm_close_btn" href="javascript:void(0)" data-ct="rate_later" title="close">X</a><strong>Duplicate Page</strong><p>We love and care about you. Our team is putting maximum efforts to provide you the best functionalities. It would be highly appreciable if you could spend a couple of seconds to give a Nice Review to the plugin to appreciate our efforts. So we can work hard to provide new features regularly :)</p><a class="close_dp_help fm_close_btn_1" href="javascript:void(0)" data-ct="rate_later" title="Remind me later">Later</a> <a class="close_dp_help fm_close_btn_2" href="https://wordpress.org/support/plugin/duplicate-page/reviews/?filter=5" data-ct="rate_now" title="Rate us now" target="_blank">Rate Us</a> <a class="close_dp_help fm_close_btn_3" href="javascript:void(0)" data-ct="rate_never" title="Not interested">Never</a>';
  313. $mkcontent .= '</div></div>';
  314. if (false === ($mk_dp_close_dp_help_c = get_option('mk_fm_close_fm_help_c'))) {
  315. echo apply_filters('the_content', $mkcontent);
  316. }
  317. }
  318. /*
  319. Close Help
  320. */
  321. public function mk_dp_close_dp_help()
  322. {
  323. $what_to_do = sanitize_text_field($_POST['what_to_do']);
  324. $expire_time = 15;
  325. if ($what_to_do == 'rate_now' || $what_to_do == 'rate_never') {
  326. $expire_time = 365;
  327. } elseif ($what_to_do == 'rate_later') {
  328. $expire_time = 15;
  329. }
  330. if (false === ($mk_fm_close_fm_help_c = get_option('mk_fm_close_fm_help_c'))) {
  331. $set = update_option('mk_fm_close_fm_help_c', 'done');
  332. if ($set) {
  333. echo 'ok';
  334. } else {
  335. echo 'oh';
  336. }
  337. } else {
  338. echo 'ac';
  339. }
  340. die;
  341. }
  342. /*
  343. Custom Assets
  344. */
  345. public function custom_assets() {
  346. wp_enqueue_style( 'duplicate-page', plugins_url( '/css/duplicate_page.css', __FILE__ ) );
  347. wp_enqueue_script( 'duplicate-page', plugins_url( '/js/duplicate_page.js', __FILE__ ) );
  348. }
  349. }
  350. new duplicate_page();
  351. endif;
  352. ?>