options = get_option( self::OPTION_NAME, [] ); $this->init(); } /** * Start the engine running * * @return void */ private function init() { $this->settings = new Post_Cloner_Settings( $this->options ); add_action( 'adminoptimizer_add_submenu_page', [ $this, 'add_submenu_page' ] ); add_action( 'init', [ $this, 'add_row_actions' ] ); add_action( 'admin_action_adminoptim-clone-post', [ $this, 'create_clone_post' ] ); } /** * Add submenu to WP Menu page * * @return void */ public function add_submenu_page() { add_submenu_page( ADMINOPTIMIZER_MODULES_MENU_SLUG, __( 'Post Cloning', 'admin-optimizer' ), __( 'Post Cloning', 'admin-optimizer' ), 'manage_options', self::MENU_SLUG, [ $this->settings, 'render_settings_page' ] ); } /** * Hooks to the row_actions filters * * @return void */ public function add_row_actions() { if ( is_admin() ) { add_filter( 'post_row_actions', [ $this, 'row_actions' ], 10, 2 ); add_filter( 'page_row_actions', [ $this, 'row_actions' ], 10, 2 ); } } /** * Row actions in actions * * @param array $actions Array of actions. * @param \WP_Post $post Post object. * * @return mixed */ public function row_actions( $actions, $post ) { $has_user_permission = $this->can_user_clone_post( wp_get_current_user(), $post ); if ( $has_user_permission ) { if ( ! empty( $this->options['post_types'] ) && in_array( $post->post_type, $this->options['post_types'] ) ) { $actions['clone_post'] = '' . __( 'Clone', 'admin-optimizer' ) . ''; } } return $actions; } /** * Check if current user can clone a specific post. * * Password-protected posts can only be cloned by their author. * * @param \WP_User $user Current user. * @param \WP_Post $post Post object. * * @return bool */ private function can_user_clone_post( $user, $post ): bool { if ( ! $post instanceof \WP_Post || ! $this->is_administrator( $user->ID ) ) { return false; } if ( ! empty( $post->post_password ) && (int) $post->post_author !== (int) $user->ID ) { return false; } return true; } /** * Function to handle the cloning link in row action * * @return void */ public function create_clone_post() { $clone_parent_id = isset( $_REQUEST['post'] ) ? absint( $_REQUEST['post'] ) : null; $parent_post = $clone_parent_id ? get_post( $clone_parent_id ) : null; $has_permission = $this->can_user_clone_post( wp_get_current_user(), $parent_post ); if ( check_admin_referer( 'adminoptim-clone-' . $clone_parent_id ) && $has_permission ) { if ( $clone_parent_id ) { $clone_id = $this->clone_post( $clone_parent_id ); if ( 0 < $clone_id && ! is_wp_error( $clone_id ) ) { if ( isset( $this->options['after_cloning'] ) && 'edit' === $this->options['after_cloning'] ) { wp_safe_redirect( get_edit_post_link( $clone_id, '&' ) ); } else { wp_safe_redirect( admin_url( 'edit.php?post_type=' . get_post_type( $clone_parent_id ) ) ); } exit; } } else { wp_die( esc_html__( 'Post cloning failed', 'admin-optimizer' ) ); } } if ( $parent_post instanceof \WP_Post && ! $has_permission ) { wp_die( esc_html__( 'You are not allowed to clone this post.', 'admin-optimizer' ) ); } // if we did not redirect out, then we fail. wp_die( esc_html__( 'Invalid Post ID', 'admin-optimizer' ) ); } }