Source of file MslsMetaBox.php

Size: 8,820 Bytes - Last Modified: 2018-02-05T14:23:18+00:00

/home/dennisploetner/Projects/Multisite-Language-Switcher/includes/MslsMetaBox.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
<?php
/**
 * MslsMetaBox
 * @author Dennis Ploetner <re@lloc.de>
 * @since 0.9.8
 */

namespace lloc\Msls;

/**
 * Meta box for the edit mode of the (custom) post types
 * @package Msls
 */
class MslsMetaBox extends MslsMain {

	/**
	 * Suggest
	 *
	 * Echo a JSON-ified array of posts of the given post-type and
	 * the requested search-term and then die silently
	 */
	public static function suggest() {
		$json = new MslsJson;

		if ( filter_has_var( INPUT_POST, 'blog_id' ) ) {
			switch_to_blog(
				filter_input( INPUT_POST, 'blog_id', FILTER_SANITIZE_NUMBER_INT )
			);

			$args = array(
				'post_status'    => get_post_stati( [ 'internal' => '' ] ),
				'posts_per_page' => 10,
			);

			if ( filter_has_var( INPUT_POST, 'post_type' ) ) {
				$args['post_type'] = sanitize_text_field(
					filter_input( INPUT_POST, 'post_type' )
				);
			}

			if ( filter_has_var( INPUT_POST, 's' ) ) {
				$args['s'] = sanitize_text_field(
					filter_input( INPUT_POST, 's' )
				);
			}

			/**
			 * Overrides the query-args for the suggest fields in the MetaBox
			 * @since 0.9.9
			 *
			 * @param array $args
			 */
			$args = (array) apply_filters( 'msls_meta_box_suggest_args', $args );

			$my_query = new \WP_Query( $args );
			while ( $my_query->have_posts() ) {
				$my_query->the_post();

				/**
				 * Manipulates the WP_Post object before using it
				 * @since 0.9.9
				 *
				 * @param \WP_Post $post
				 */
				$my_query->post = apply_filters( 'msls_meta_box_suggest_post', $my_query->post );

				if ( is_object( $my_query->post ) ) {
					$json->add( get_the_ID(), get_the_title() );
				}
			}
			wp_reset_postdata();
			restore_current_blog();
		}
		wp_die( $json->encode() );
	}

	/**
	 * Init
	 *
	 * @codeCoverageIgnore
	 *
	 * @return MslsMetaBox
	 */
	public static function init() {
		$options    = MslsOptions::instance();
		$collection = MslsBlogCollection::instance();
		$obj        = new static( $options, $collection );

		if ( ! $options->is_excluded() ) {
			add_action( 'add_meta_boxes', [ $obj, 'add' ] );
			add_action( 'save_post', [ $obj, 'set' ] );
			add_action( 'trashed_post', [ $obj, 'delete' ] );
		}

		return $obj;
	}

	/**
	 * Add
	 */
	public function add() {
		foreach ( MslsPostType::instance()->get() as $post_type ) {
			add_meta_box(
				'msls',
				__( 'Multisite Language Switcher', 'multisite-language-switcher' ),
				[
					$this,
					(
					MslsOptions::instance()->activate_autocomplete ?
						'render_input' :
						'render_select'
					),
				],
				$post_type,
				'side',
				'high'
			);
		}
	}

	/**
	 * Render the classic select-box
	 * @uses selected
	 */
	public function render_select() {
		$blogs = $this->collection->get();
		if ( $blogs ) {
			global $post;

			$type   = get_post_type( $post->ID );
			$mydata = new MslsOptionsPost( $post->ID );

			$this->maybe_set_linked_post( $mydata );

			$temp   = $post;

			wp_nonce_field( MSLS_PLUGIN_PATH, 'msls_noncename' );

			$lis = '';

			foreach ( $blogs as $blog ) {
				switch_to_blog( $blog->userblog_id );

				$language = $blog->get_language();

				$icon = MslsAdminIcon::create()
				                     ->set_language( $language )
				                     ->set_src( MslsOptions::instance()->get_flag_url( $language ) );
				if ( $mydata->has_value( $language ) ) {
					$icon->set_href( $mydata->$language );
				}

				$selects = '';
				$pto     = get_post_type_object( $type );

				if ( $pto->hierarchical ) {
					$args = array(
						'post_type'         => $type,
						'selected'          => $mydata->$language,
						'name'              => 'msls_input_' . $language,
						'show_option_none'  => ' ',
						'option_none_value' => 0,
						'sort_column'       => 'menu_order, post_title',
						'echo'              => 0,
					);
					/**
					 * Overrides the args for wp_dropdown_pages when using the HTML select in the MetaBox
					 * @since 1.0.5
					 *
					 * @param array $args
					 */
					$args = (array) apply_filters( 'msls_meta_box_render_select_hierarchical', $args );

					$selects .= wp_dropdown_pages( $args );
				} else {
					$options = '';

					$my_query = new \WP_Query(
						array(
							'post_type'      => $type,
							'post_status'    => get_post_stati( [ 'internal' => '' ] ),
							'orderby'        => 'title',
							'order'          => 'ASC',
							'posts_per_page' => - 1,
							'fields'         => 'ids',
						)
					);

					if ( $my_query->have_posts() ) {
						foreach ( $my_query->posts as $my_id ) {
							$options .= sprintf(
								'<option value="%s" %s>%s</option>',
								$my_id,
								selected( $my_id, $mydata->$language, false ),
								get_the_title( $my_id )
							);
						}
					}
					$selects .= sprintf(
						'<select name="msls_input_%s"><option value="0"></option>%s</select>',
						$language,
						$options
					);
				}

				$lis .= sprintf(
					'<li><label for="msls_input_%s">%s</label>%s</li>',
					$language,
					$icon,
					$selects
				);

				restore_current_blog();
			}
			printf(
				'<ul>%s</ul><input type="submit" class="button-secondary" value="%s"/>',
				$lis,
				__( 'Update', 'multisite-language-switcher' )
			);
			$post = $temp;
		} else {
			printf(
				'<p>%s</p>',
				__( 'You should define at least another blog in a different language in order to have some benefit from this plugin!', 'multisite-language-switcher' )
			);
		}
	}

	/**
	 * Render the suggest input-field
	 */
	public function render_input() {
		$blogs = $this->collection->get();

		if ( $blogs ) {
			global $post;

			$post_type = get_post_type( $post->ID );
			$my_data   = new MslsOptionsPost( $post->ID );

			$this->maybe_set_linked_post( $my_data );

			$temp      = $post;
			$items     = '';

			wp_nonce_field( MSLS_PLUGIN_PATH, 'msls_noncename' );

			foreach ( $blogs as $blog ) {
				switch_to_blog( $blog->userblog_id );

				$language = $blog->get_language();
				$flag_url = MslsOptions::instance()->get_flag_url( $language );
				$icon     = MslsAdminIcon::create()->set_language( $language )->set_src( $flag_url );

				$value = $title = '';

				if ( $my_data->has_value( $language ) ) {
					$icon->set_href( $my_data->$language );
					$value = $my_data->$language;
					$title = get_the_title( $value );
				}

				$items .= sprintf(
					'<li>
					<label for="msls_title_%1$s">%2$s</label>
					<input type="hidden" id="msls_id_%1$s" name="msls_input_%3$s" value="%4$s"/>
					<input class="msls_title" id="msls_title_%1$s" name="msls_title_%1$s" type="text" value="%5$s"/>
					</li>',
					$blog->userblog_id,
					$icon,
					$language,
					$value,
					$title
				);

				restore_current_blog();
			}

			$input_button = sprintf(
				'<input type="submit" class="button-secondary clear" value="%s"/>',
				__( 'Update', 'multisite-language-switcher' )
			);

			/**
			 * Returns the input button, return an empty string if you'ld like to hide the button
			 * @since 1.0.2
			 *
			 * @param string $input_button
			 */
			$input_button = ( string ) apply_filters( 'msls_meta_box_render_input_button', $input_button );

			printf(
				'<ul>%s</ul>
				<input type="hidden" name="msls_post_type" id="msls_post_type" value="%s"/>
				<input type="hidden" name="msls_action" id="msls_action" value="suggest_posts"/>
				%s',
				$items,
				$post_type,
				$input_button
			);

			$post = $temp;
		} else {
			printf(
				'<p>%s</p>',
				__( 'You should define at least another blog in a different language in order to have some benefit from this plugin!', 'multisite-language-switcher' )
			);
		}
	}

	/**
	 * Set
	 *
	 * @param int $post_id
	 */
	public function set( $post_id ) {
		if ( $this->is_autosave( $post_id ) || ! $this->verify_nonce() ) {
			return;
		}

		$capability = (
		'page' == filter_input( INPUT_POST, 'post_type', FILTER_SANITIZE_STRING ) ?
			'edit_page' :
			'edit_post'
		);

		if ( ! current_user_can( $capability, $post_id ) ) {
			return;
		}

		$this->save( $post_id, MslsOptionsPost::class );
	}

	/**
	 * Sets the selected element in the data from the `$_GET` superglobal, if any.
	 * @param MslsOptionsPost $mydata
	 * @return MslsOptionsPost
	 */
	public function maybe_set_linked_post( MslsOptionsPost $mydata ) {
		if ( ! isset( $_GET['msls_id'], $_GET['msls_lang'] ) ) {
			return $mydata;
		}

		$origin_lang = trim( $_GET['msls_lang'] );

		if ( isset( $mydata->{$origin_lang} ) ) {
			return $mydata;
		}

		$origin_post_id = (int) $_GET['msls_id'];

		$origin_blog_id = $this->collection->get_blog_id( $origin_lang );

		if ( null === $origin_blog_id ) {
			return $mydata;
		}

		switch_to_blog( $origin_blog_id );
		$origin_post = get_post( $origin_post_id );
		restore_current_blog();

		if ( ! $origin_post instanceof \WP_Post ) {
			return $mydata;
		}

		$mydata->{$origin_lang} = $origin_post_id;

		return $mydata;
	}
}