<?php
/**
 * WPSEO Premium plugin file.
 *
 * @package WPSEO\Premium
 */

/**
 * Initializer for the social previews.
 */
class WPSEO_Social_Previews implements WPSEO_WordPress_Integration {

	/**
	 * Registers the hooks.
	 *
	 * @codeCoverageIgnore Method uses dependencies.
	 *
	 * @return void
	 */
	public function register_hooks() {
		add_action( 'wp_ajax_retrieve_image_data_from_url', [ $this, 'ajax_retrieve_image_data_from_url' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
	}

	/**
	 * Enqueues the javascript and css files needed for the social previews.
	 *
	 * @codeCoverageIgnore Method uses dependencies.
	 *
	 * @return void
	 */
	public function enqueue_assets() {
		wp_enqueue_style( 'yoast-social-preview-css' );
		wp_enqueue_style( 'yoast-premium-social-preview' );
		wp_enqueue_script( 'yoast-social-preview' );
		wp_localize_script( 'yoast-social-preview', 'yoastSocialPreview', $this->localize() );
	}

	/**
	 * Retrieves image data from an image URL.
	 */
	public function ajax_retrieve_image_data_from_url() {
		$url = filter_input( INPUT_GET, 'imageURL', FILTER_SANITIZE_URL );

		if ( check_ajax_referer( 'retrieve_image_data_from_url', false, false ) === false ) {
			wp_send_json(
				[
					'status' => 'forbidden',
					'result' => $url,
				],
				403
			);
		}

		$attachment_id = $this->retrieve_image_id_from_url( $url );

		if ( $attachment_id ) {
			$image = wp_get_attachment_image_src( $attachment_id, 'full' );

			$result = [
				'status' => 'success',
				'result' => $image[0],
			];
		}
		else {
			// Pass the original URL for consistency.
			$result = [
				'status' => 'success',
				'result' => $url,
			];
		}

		wp_send_json( $result );
	}

	/**
	 * Determines an attachment ID from a URL which might be an attachment URL.
	 *
	 * @link https://philipnewcomer.net/2012/11/get-the-attachment-id-from-an-image-url-in-wordpress/
	 *
	 * @param string $url The URL to retrieve the attachment ID for.
	 *
	 * @return bool|int The attachment ID or false.
	 */
	public function retrieve_image_id_from_url( $url ) {
		global $wpdb;

		$attachment_id = false;

		// Get the upload directory paths.
		$upload_dir_paths = wp_upload_dir();

		// Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image.
		if ( strpos( $url, $upload_dir_paths['baseurl'] ) !== false ) {

			// If this is the URL of an auto-generated thumbnail, get the URL of the original image.
			$url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $url );

			// Remove the upload path base directory from the attachment URL.
			$url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $url );

			// Finally, run a custom database query to get the attachment ID from the modified attachment URL.
			$attachment_id = $wpdb->get_var(
				$wpdb->prepare(
					"SELECT wposts.ID
						FROM {$wpdb->posts} AS wposts,
							{$wpdb->postmeta} AS wpostmeta
						WHERE wposts.ID = wpostmeta.post_id
							AND wpostmeta.meta_key = '_wp_attached_file'
							AND wpostmeta.meta_value = %s
							AND wposts.post_type = 'attachment'",
					$url
				)
			);
		}

		return (int) $attachment_id;
	}

	/**
	 * Returns the translations.
	 *
	 * @return array
	 */
	private function localize() {
		if ( empty( WPSEO_Meta::$meta_fields['social']['opengraph-title']['description'] ) ) {
			WPSEO_Social_Admin::translate_meta_boxes();
		}

		$social = WPSEO_Meta::$meta_fields['social'];

		return [
			'website'              => $this->get_website(),
			'uploadImage'          => __( 'Upload image', 'wordpress-seo-premium' ),
			'useOtherImage'        => __( 'Use other image', 'wordpress-seo-premium' ),
			'removeImageButton'    => __( 'Remove image', 'wordpress-seo-premium' ),
			'facebookDefaultImage' => WPSEO_Options::get( 'og_default_image' ),
			'i18n'                 => [
				'help'       => $this->get_help_translations( $social ),
				'helpButton' => [
					'facebookTitle'       => __( 'Show information about Facebook title', 'wordpress-seo-premium' ),
					'facebookDescription' => __( 'Show information about Facebook description', 'wordpress-seo-premium' ),
					'facebookImage'       => __( 'Show information about Facebook image', 'wordpress-seo-premium' ),
					'twitterTitle'        => __( 'Show information about Twitter title', 'wordpress-seo-premium' ),
					'twitterDescription'  => __( 'Show information about Twitter description', 'wordpress-seo-premium' ),
					'twitterImage'        => __( 'Show information about Twitter image', 'wordpress-seo-premium' ),
				],
				'library'    => $this->get_translations(),
			],
			'facebookNonce'        => wp_create_nonce( 'get_facebook_name' ),
			'imageDataNonce'       => wp_create_nonce( 'retrieve_image_data_from_url' ),
		];
	}

	/**
	 * Gets the help translations.
	 *
	 * @param array $social_field The social fields that are available.
	 *
	 * @return array Translations to be used in the social previews.
	 */
	private function get_help_translations( $social_field ) {
		// Default everything to empty strings.
		$localized = [];

		if ( isset( $social_field['opengraph-title'] ) ) {
			$localized['facebookTitle']       = $social_field['opengraph-title']['description'];
			$localized['facebookDescription'] = $social_field['opengraph-description']['description'];
			$localized['facebookImage']       = $social_field['opengraph-image']['description'];
		}

		if ( isset( $social_field['twitter-title'] ) ) {
			$localized['twitterTitle']       = $social_field['twitter-title']['description'];
			$localized['twitterDescription'] = $social_field['twitter-description']['description'];
			$localized['twitterImage']       = $social_field['twitter-image']['description'];
		}

		return $localized;
	}

	/**
	 * Get the website hostname.
	 *
	 * @return string
	 */
	private function get_website() {
		// We only want the host part of the URL.
		$website = wp_parse_url( home_url(), PHP_URL_HOST );
		$website = trim( $website, '/' );
		$website = strtolower( $website );

		return $website;
	}

	/**
	 * Returns Jed compatible YoastSEO.js translations.
	 *
	 * @return array
	 */
	private function get_translations() {
		$file = plugin_dir_path( WPSEO_FILE ) . 'premium/languages/yoast-social-previews-' . WPSEO_Language_Utils::get_user_locale() . '.json';
		if ( file_exists( $file ) ) {
			$file = file_get_contents( $file );
			if ( $file !== false ) {
				return json_decode( $file, true );
			}
		}

		return [];
	}

	/**
	 * Enqueues the assets.
	 *
	 * @deprecated 9.4
	 * @codeCoverageIgnore
	 *
	 * @return void
	 */
	public function set_hooks() {
		_deprecated_function( 'WPSEO_Social_Previews::set_hooks', '9.4', 'WPSEO_Social_Previews::register_hooks' );
	}

	/**
	 * Sets the hooks necessary for AJAX.
	 *
	 * @deprecated 9.4
	 * @codeCoverageIgnore
	 *
	 * @return void
	 */
	public function set_ajax_hooks() {
		_deprecated_function( 'WPSEO_Social_Previews::set_ajax_hooks', '9.4' );
	}

	/**
	 * Register the required assets.
	 *
	 * @deprecated 9.4
	 * @codeCoverageIgnore
	 *
	 * @return void
	 */
	public function register_assets() {
		_deprecated_function( 'WPSEO_Social_Previews::set_ajax_hooks', '9.4' );
	}
}
