Copy_Recipe_Parts

Class Copy_Recipe_Parts

Contents

  • Methods

  • Source Source

    File: src/core/admin/class-copy-recipe-parts.php

    class Copy_Recipe_Parts {
    	/**
    	 * @var array
    	 */
    	public $trigger_tokens = array();
    
    	/**
    	 * Copy_Recipe_Parts constructor.
    	 */
    	public function __construct() {
    		add_action( 'admin_init', array( $this, 'copy_recipe_parts' ) );
    		add_filter( 'post_row_actions', array( $this, 'add_copy_recipe_action_rows' ), 10, 2 );
    
    	}
    
    	/**
    	 * @param $actions
    	 * @param $post
    	 *
    	 * @return mixed
    	 */
    	public function add_copy_recipe_action_rows( $actions, $post ) {
    		if ( 'uo-recipe' !== $post->post_type ) {
    			return $actions;
    		}
    		$post_type_object = get_post_type_object( $post->post_type );
    		$can_edit_post    = current_user_can( $post_type_object->cap->edit_post, $post->ID );
    		if ( ! $can_edit_post ) {
    			return $actions;
    		}
    		unset( $actions['inline hide-if-no-js'] );
    		unset( $actions['hide-if-no-js'] );
    		unset( $actions['view'] );
    		$action                 = sprintf( '%s?action=%s&post=%d&return_to_recipe=yes&_wpnonce=%s', admin_url( 'edit.php' ), 'copy_recipe_parts', $post->ID, wp_create_nonce( 'Aut0Mat0R' ) );
    		$actions['copy_recipe'] = sprintf( '<a href="%s" title="%s">%s</a>', $action, __( 'Duplicate this recipe', 'uncanny-automator' ), __( 'Duplicate this recipe', 'uncanny-automator' ) );
    
    		return $actions;
    	}
    
    	/**
    	 *
    	 */
    	public function copy_recipe_parts() {
    		if ( ! automator_filter_has_var( 'action' ) ) {
    			return;
    		}
    
    		if ( automator_filter_has_var( 'action' ) && 'copy_recipe_parts' !== automator_filter_input( 'action' ) ) {
    			return;
    		}
    
    		if ( ! automator_filter_has_var( 'post' ) ) {
    			return;
    		}
    
    		if ( ! automator_filter_has_var( '_wpnonce' ) ) {
    			return;
    		}
    
    		if ( ! wp_verify_nonce( automator_filter_input( '_wpnonce' ), 'Aut0Mat0R' ) ) {
    			return;
    		}
    
    		$recipe_id = absint( automator_filter_input( 'post' ) );
    
    		if ( 'uo-recipe' !== get_post_type( $recipe_id ) ) {
    			wp_die( esc_attr( sprintf( '%s %s', __( 'Copy creation failed, could not find original recipe:', 'uncanny-automator' ), htmlspecialchars( $recipe_id ) ) ) );
    		}
    
    		// Copy the post and insert it
    		$new_id = $this->copy_this_recipe( $recipe_id );
    		if ( automator_filter_has_var( 'return_to_recipe' ) ) {
    			wp_safe_redirect( admin_url( 'post.php?post=' . $new_id . '&action=edit' ) );
    		} else {
    			wp_safe_redirect( admin_url( 'edit.php?post_type=' . get_post_type( $recipe_id ) ) );
    		}
    		exit;
    	}
    
    	/**
    	 * @param $recipe_id
    	 *
    	 * @return false|int|\WP_Error
    	 */
    	public function copy_this_recipe( $recipe_id ) {
    		global $wpdb;
    
    		$new_recipe_id = $this->copy( $recipe_id );
    		if ( $this->copy_recipe_part( $recipe_id, $new_recipe_id, 'uo-trigger' ) ) {
    			$this->copy_recipe_part( $recipe_id, $new_recipe_id, 'uo-action' );
    			$this->copy_recipe_part( $recipe_id, $new_recipe_id, 'uo-closure' );
    
    			// Fallback to update tokens for Anonymous recipes that is stored in recipe's post meta itself
    			$this->copy_recipe_metas( $recipe_id, $new_recipe_id );
    		}
    		$recipe_tax = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(object_id) AS total FROM $wpdb->term_relationships WHERE object_id = %d", $recipe_id ) );
    
    		if ( $recipe_tax > 0 ) {
    			//Clone tags and categories
    			$wpdb->query( "DELETE FROM {$wpdb->term_relationships} WHERE object_id={$new_recipe_id};" );
    			$wpdb->query( "CREATE TEMPORARY TABLE tmpCopyCats SELECT * FROM {$wpdb->term_relationships} WHERE object_id={$recipe_id};" );
    			$wpdb->query( "UPDATE tmpCopyCats SET object_id={$new_recipe_id} WHERE object_id={$recipe_id};" );
    			$wpdb->query( "INSERT INTO  {$wpdb->term_relationships} SELECT * FROM tmpCopyCats;" );
    			$wpdb->query( 'DROP TEMPORARY TABLE IF EXISTS tmpCopyCats;' );
    		}
    
    		return $new_recipe_id;
    	}
    
    
    	/**
    	 * @param $recipe_id
    	 * @param $new_recipe_id
    	 * @param $type
    	 *
    	 * @return bool
    	 */
    	public function copy_recipe_part( $recipe_id, $new_recipe_id, $type ) {
    		$recipe_parts = get_posts(
    			array(
    				'post_parent' => $recipe_id,
    				'post_type'   => $type,
    				'post_status' => array( 'draft', 'publish' ),
    				'order_by'    => 'ID',
    				'order'       => 'ASC',
    			)
    		);
    
    		if ( empty( $recipe_parts ) ) {
    			return false;
    		}
    
    		foreach ( $recipe_parts as $recipe_part ) {
    			if ( $type !== $recipe_part->post_type ) {
    				continue;
    			}
    
    			$new_id = $this->copy( $recipe_part->ID, $new_recipe_id );
    
    			if ( 'uo-trigger' === $recipe_part->post_type ) {
    				$this->trigger_tokens[ $recipe_part->ID ] = $new_id;
    			}
    		}
    
    		return true;
    	}
    
    	/**
    	 * @param $post_id
    	 * @param int $post_parent
    	 * @param string $status
    	 *
    	 * @return false|int|\WP_Error
    	 */
    	public function copy( $post_id, $post_parent = 0, $status = 'draft' ) {
    		$post = get_post( $post_id );
    		// We don't want to clone revisions
    		if ( 'revision' === $post->post_type ) {
    			return false;
    		}
    
    		if ( 'attachment' !== $post->post_type ) {
    			$status = 'draft';
    		}
    
    		$new_post_author = wp_get_current_user();
    		$post_title      = 'uo-recipe' === $post->post_type ? $post->post_title . ' ' . __( '(Copy)', 'uncanny-automator' ) : $post->post_title;
    		$new_post        = array(
    			'menu_order'     => $post->menu_order,
    			'comment_status' => $post->comment_status,
    			'ping_status'    => $post->ping_status,
    			'post_author'    => $new_post_author->ID,
    			'post_content'   => $this->modify_tokens( $post->post_content, $post_parent ),
    			'post_excerpt'   => $post->post_excerpt,
    			'post_mime_type' => $post->post_mime_type,
    			'post_parent'    => empty( $post_parent ) ? $post->post_parent : $post_parent,
    			'post_password'  => $post->post_password,
    			'post_status'    => empty( $status ) ? $post->post_status : $status,
    			'post_title'     => $post_title,
    			'post_type'      => $post->post_type,
    			'post_date'      => $post->post_date,
    			'post_date_gmt'  => get_gmt_from_date( $post->post_date ),
    		);
    
    		$new_post_id = wp_insert_post( $new_post );
    		if ( is_wp_error( $new_post_id ) ) {
    			wp_die( esc_html( $new_post_id->get_error_message() ) );
    		}
    
    		$this->copy_recipe_metas( $post_id, $new_post_id, $post_parent );
    
    		return $new_post_id;
    	}
    
    	/**
    	 * @param $post_id
    	 * @param $new_post_id
    	 */
    	public function copy_recipe_metas( $post_id, $new_post_id, $post_parent = 0 ) {
    		$recipe_meta = get_post_meta( $post_id );
    
    		foreach ( $recipe_meta as $key => $value ) {
    			$val = maybe_unserialize( $value[0] );
    			$val = $this->modify_tokens( $val, $post_parent, $new_post_id );
    			update_post_meta( $new_post_id, $key, $val );
    		}
    	}
    
    	/**
    	 * @param $content
    	 *
    	 * @return mixed
    	 */
    	public function modify_tokens( $content, $post_parent = 0, $new_post_id = 0 ) {
    
    		//Check if it's a webhook URL
    		if ( 0 !== $new_post_id && ! is_array( $content ) && preg_match( '/\/wp-json\/uap\/v2\/uap-/', $content ) ) {
    			// Only modify webhook URL of the trigger. We are leaving webhook URL of action alone.
    			if ( 'uo-trigger' === get_post_type( $new_post_id ) ) {
    				$new     = sprintf( 'uap/v2/uap-%d-%d', wp_get_post_parent_id( $new_post_id ), $new_post_id );
    				$content = preg_replace( '/uap\/v2\/uap-.+/', $new, $content );
    			}
    		}
    
    		if ( empty( $this->trigger_tokens ) ) {
    			return $content;
    		}
    
    		// Loop thru multiple triggers and update token's trigger ID based on that.
    		foreach ( $this->trigger_tokens as $prev_id => $new_id ) {
    			$content = preg_replace( '/{{' . $prev_id . ':/', '{{' . $new_id . ':', $content );
    		}
    
    		return $content;
    	}
    }
    

    Methods Methods