GhostManSec
Server: LiteSpeed
System: Linux premium197.web-hosting.com 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
User: parhudrw (1725)
PHP: 7.4.33
Disabled: NONE
Upload Files
File: /home/parhudrw/saifookhan.com/wp-content/plugins/amazon-polly/admin/AmazonAI-Common.php
<?php
/**
 * Common operations used by the AWS for wordpress plugin.
 *
 * @link       amazon.com
 * @since      2.5.0
 *
 */
class AmazonAI_Common

{

	// Information about languages supported by the AWS plugin
	private $languages = [

		['code' => 'af', 'name' => 'Afrikaans', 'translatable' => '1', 'polly' => '0'],
		['code' => 'sq', 'name' => 'Albanian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'am', 'name' => 'Amharic', 'translatable' => '1', 'polly' => '0'],
		['code' => 'ar', 'name' => 'Arabic', 'translatable' => '1', 'polly' => '1'],
		['code' => 'az', 'name' => 'Azerbaijani', 'translatable' => '1', 'polly' => '0'],
		['code' => 'bn', 'name' => 'Bengali', 'translatable' => '1', 'polly' => '0'],
		['code' => 'bs', 'name' => 'Bosnian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'bg', 'name' => 'Bulgarian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'fr-CA', 'name' => 'Canadian French', 'translatable' => '1', 'polly' => '0'],
		['code' => 'da', 'name' => 'Danish', 'translatable' => '1', 'polly' => '1'],
		['code' => 'nl', 'name' => 'Dutch', 'translatable' => '1', 'polly' => '1'],
		['code' => 'zh', 'name' => 'Chinese', 'translatable' => '1', 'polly' => '1'],
		['code' => 'hr', 'name' => 'Croatian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'cs', 'name' => 'Czech', 'translatable' => '1', 'polly' => '0'],
		['code' => 'fa-AF', 'name' => 'Dari', 'translatable' => '1', 'polly' => '1'],
		['code' => 'en', 'name' => 'English', 'translatable' => '1', 'polly' => '1'],
		['code' => 'et', 'name' => 'Estonian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'fi', 'name' => 'Finish', 'translatable' => '1', 'polly' => ''],
		['code' => 'fr', 'name' => 'French', 'translatable' => '1', 'polly' => '1'],
		['code' => 'ka', 'name' => 'Georgian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'de', 'name' => 'German', 'translatable' => '1', 'polly' => '1'],
		['code' => 'el', 'name' => 'Greek', 'translatable' => '1', 'polly' => '0'],
		['code' => 'ha', 'name' => 'Hausa', 'translatable' => '1', 'polly' => '0'],
		['code' => 'he', 'name' => 'Hebrew', 'translatable' => '1', 'polly' => ''],
		['code' => 'hi', 'name' => 'Hindi', 'translatable' => '1', 'polly' => ''],
		['code' => 'hu', 'name' => 'Hungarian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'is', 'name' => 'Icelandic', 'translatable' => '0', 'polly' => '1'],
		['code' => 'it', 'name' => 'Italian', 'translatable' => '1', 'polly' => '1'],
		['code' => 'id', 'name' => 'Indonesian', 'translatable' => '1', 'polly' => ''],
		['code' => 'ja', 'name' => 'Japanese', 'translatable' => '1', 'polly' => '1'],
		['code' => 'ko', 'name' => 'Korean', 'translatable' => '1', 'polly' => '1'],
		['code' => 'lv', 'name' => 'Latvian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'ms', 'name' => 'Malay', 'translatable' => '1', 'polly' => ''],
		['code' => 'no', 'name' => 'Norwegian', 'translatable' => '1', 'polly' => '1'],
		['code' => 'fa', 'name' => 'Persian', 'translatable' => '1', 'polly' => ''],
		['code' => 'pl', 'name' => 'Polish', 'translatable' => '1', 'polly' => '1'],
		['code' => 'pt', 'name' => 'Portuguese', 'translatable' => '1', 'polly' => '1'],
		['code' => 'ps', 'name' => 'Pushto', 'translatable' => '1', 'polly' => '0'],
		['code' => 'ro', 'name' => 'Romanian', 'translatable' => '1', 'polly' => '1'],
		['code' => 'sr', 'name' => 'Serbian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'sk', 'name' => 'Slovak', 'translatable' => '1', 'polly' => '0'],
		['code' => 'sl', 'name' => 'Slovenian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'so', 'name' => 'Somali', 'translatable' => '1', 'polly' => '0'],
		['code' => 'sw', 'name' => 'Swahili', 'translatable' => '1', 'polly' => '0'],
		['code' => 'ru', 'name' => 'Russian', 'translatable' => '1', 'polly' => '1'],
		['code' => 'es', 'name' => 'Spanish', 'translatable' => '1', 'polly' => '1'],
		['code' => 'sv', 'name' => 'Swedish', 'translatable' => '1', 'polly' => '1'],
		['code' => 'tl', 'name' => 'Tagalog', 'translatable' => '1', 'polly' => '0'],
		['code' => 'ta', 'name' => 'Tamil', 'translatable' => '1', 'polly' => '0'],
		['code' => 'th', 'name' => 'Thai', 'translatable' => '1', 'polly' => '0'],
		['code' => 'tr', 'name' => 'Turkish', 'translatable' => '1', 'polly' => '1'],
		['code' => 'uk', 'name' => 'Ukrainian', 'translatable' => '1', 'polly' => '0'],
		['code' => 'ur', 'name' => 'Urdu', 'translatable' => '1', 'polly' => '0'],
		['code' => 'vi', 'name' => 'Vietnamese', 'translatable' => '1', 'polly' => '0'],
		['code' => 'cy', 'name' => 'Welsh', 'translatable' => '', 'polly' => '1']
	];

	private $sdk;
	private $sdk_use1; // SDK with region fixed as us-east-1
	private $polly_client;
	private $translate_client;
	private $s3_handler;
	private $local_file_handler;
	private $translate;
	private $logger;
	private $cloudformation_client;
	private $cloudfront_client;
	private $acm_client;

	/**
	 * Creates SDK objects for the plugin.
	 *
	 * @since    2.5.0
	 */
	public function __construct() {
		$this->logger = new AmazonAI_Logger();
	}

	public function prepare_paragraphs($post_id) {

		$clean_content = '';
		$post_content = get_post_field('post_content', $post_id);
		$paragraphs = explode("\n", $post_content);

		foreach($paragraphs as $paragraph) {
			$clean_paragraph = $this->clean_paragraph($paragraph);

			$clean_content = $clean_content . "\n" . $clean_paragraph;
		}


		return $clean_content;
	}



	public function get_subscribe_link() {

        $value = get_option( 'amazon_polly_podcast_button_link' );

		if (empty($value)) {
			$value = esc_attr( get_feed_link( 'amazon-pollycast' ) );
		}

		return esc_attr($value);

	}


	public function get_podcast_author() {

		$value = get_option( 'amazon_polly_podcast_author' );

		if( empty($value) ) {
			$value = 'Author';
		}

		return $value;

	}

	public function clean_paragraph($paragraph) {

		$clean_text = $paragraph;
		$clean_text = do_shortcode($clean_text);
		$clean_text = str_replace('&nbsp;', ' ', $clean_text);

		$is_ssml_enabled = $this->is_ssml_enabled();
	  if ($is_ssml_enabled) {
	    $clean_text = $this->encode_ssml_tags($clean_text);
	  }

		$clean_text = strip_tags($clean_text, '<break>');
		$clean_text = esc_html($clean_text);


	  $clean_text = str_replace('&nbsp;', ' ', $clean_text);
	  $clean_text = preg_replace("/https:\/\/([^\s]+)/", "", $clean_text);
		$clean_text = html_entity_decode($clean_text, ENT_QUOTES, 'UTF-8');
	  $clean_text = str_replace('&', ' and ', $clean_text);
	  $clean_text = str_replace('<', ' ', $clean_text);
	  $clean_text = str_replace('>', ' ', $clean_text);

		return $clean_text;
	}

	public function get_feed_size() {
		$feedsize = get_option( 'amazon_polly_podcast_feedsize' );

		$value = intval( $feedsize );

		if ( empty( $value ) ) {
			$value = 20;
		}

		if ( intval( $value ) < 1 ) {
			$value = 1;
		}

		if ( intval( $value ) > 1000 ) {
			$value = 1000;
		}

		update_option( 'amazon_polly_podcast_feedsize', $value );

		return $value;

	}

	public function get_language_name($provided_langauge_code) {

		foreach ($this->languages as $language_data) {
			$language_code = $language_data['code'];
			$language_name = $language_data['name'];

			if ($language_code === $provided_langauge_code) {
				return $language_name;
			}
		}

		return "N/A";
	}

	public function get_all_languages() {
		$supported_languages = [];

		foreach ($this->languages as $language_data) {
			$language_code = $language_data['code'];
			array_push($supported_languages, $language_code);
		}

		return $supported_languages;
	}

	public function get_all_translatable_languages() {
		$supported_languages = [];

		foreach ($this->languages as $language_data) {
			$language_code = $language_data['code'];
			$is_language_supported = $language_data['translatable'];

			if ( !empty($is_language_supported) ) {
				array_push($supported_languages, $language_code);
			}
		}

		return $supported_languages;
	}

	public function get_language_display($language_code) {

		$language_display_option = 'amazon_polly_trans_langs_' . $language_code . '_display';
		$value = get_option( $language_display_option );
		if ( empty($value) ) {
			$value = 'Flag';
		}

		return $value;

	}

	public function get_language_label($language_code) {

		$language_label_option = 'amazon_polly_trans_langs_' . $language_code . '_label';
		$value = get_option( $language_label_option );
		if ( empty($value) ) {
			$value = strtoupper( $language_code );
		}

		return $value;

	}

	public function get_all_polly_languages() {


		$supported_languages = [];

		foreach ($this->languages as $language_data) {
			$language_code = $language_data['code'];
			$is_language_supported = $language_data['polly'];

			if ( !empty($is_language_supported) ) {
				array_push($supported_languages, $language_code);
			}
		}

		return $supported_languages;
	}


	public function get_source_language_name() {

    $selected_source_language = $this->get_source_language();

    foreach ($this->languages as $language_data) {
      $language = $language_data['code'];

      if (strcmp($selected_source_language, $language) === 0) {
        return $language_data['name'];
      }
    }

    return '';
  }

	public function init() {
		$aws_sdk_config = $this->get_aws_sdk_config();
		$this->sdk = new Aws\Sdk($aws_sdk_config);
		$this->polly_client = $this->sdk->createPolly();
		$this->translate_client = $this->sdk->createTranslate();

		$this->s3_handler = new AmazonAI_S3FileHandler($this);
		$this->local_file_handler = new AmazonAI_LocalFileHandler($this);

        $this->s3_handler->set_s3_client($this->sdk->createS3());
        $this->translate = new AmazonAI_Translator($this);

        $aws_sdk_config_use1 = $this->get_aws_sdk_config_use1();
        $this->sdk_use1 = new Aws\Sdk($aws_sdk_config_use1);
        //Client for running Cloudformation actions
        $this->cloudformation_client = $this->sdk_use1->createCloudFormation();
        //Client for running CloudFront actions
        $this->cloudfront_client = $this->sdk_use1->createCloudFront();
        //Client for running ACM actions
        $this->acm_client = $this->sdk_use1->createAcm();
    }


    /**
     * Method returns SDK Client which is reponsible for calling functions associated with Cloudformation
     *
     * @since       4.0.0
     */
    public function get_cloudformation_client() {
        return $this->cloudformation_client;
    }

    /**
     * Method returns SDK Client which is reponsible for calling functions associated with AWS Certificate Manager
     *
     * @since       4.0.0
     */
    public function get_acm_client() {
        return $this->acm_client;
    }

    /**
     * Method returns SDK Client which is reponsible for calling functions associated with CloudFront distribution
     *
     * @since       4.0.0
     */
    public function get_cloudfront_client() {
        return $this->cloudfront_client;
    }

	public function get_translate_client() {
		return $this->translate_client;
	}

	/**
	 * Method returns file handler which is reponsible for communicating with proper storage location.
	 *
	 * @since       2.0.3
	 */
	public function get_file_handler() {

		$is_s3_enabled = $this->is_s3_enabled();
		if ( $is_s3_enabled ) {
		  return $this->s3_handler;
		} else {
			return $this->local_file_handler;
		}

	}

	public function get_polly_client() {
		return $this->polly_client;
	}

	/**
	 * Method removes ID3 tag from audio file
	 *
	 * @param           string $filename                 File for which tag should be removed.
	 * @since           1.0.0
	 */
	public function remove_id3( $filename ) {

		// Temporary file - without IDv3 tag.
		$temp_filename = $filename . 'temp';

		// Original file with IDv3 tag.
		$source_file = fopen( $filename, 'r+b' );

		// IDv3 header has got 10 bytes.
		$id3_header = fread( $source_file, 10 );

		// Calculating the total size of IDv3 tag.
		$int_value        = 0;
		$byte_word        = substr( $id3_header, 6, 4 );
		$byte_word_length = strlen( $byte_word );
		for ( $i = 0; $i < $byte_word_length; $i++ ) {
			$int_value += ( ord( $byte_word[$i] ) & 0x7F ) * pow( 2, ( $byte_word_length - 1 - $i ) * 7 );
		}
		$offset = ( (int) $int_value ) + 10;

		// Recreating file without the IDv3 tag bytes.
		rewind( $source_file );
		fseek( $source_file, $offset );
		$temp_file = fopen( $temp_filename, 'w+b' );

		while ( $buffer = fread( $source_file, 32768 ) ) {
			fwrite( $temp_file, $buffer, strlen( $buffer ) );
		}

		// Swapping files.
		fclose( $temp_file );
		unlink( $filename );
		rename( $temp_filename, $filename );

	}

	public function startsWith ($string, $beginning) {
	    $len = strlen($beginning);
	    return (substr($string, 0, $len) === $beginning);
	}

	public function endsWith($string, $ending) {
	    $len = strlen($ending);
	    if ($len == 0) {
	        return true;
	    }
	    return (substr($string, -$len) === $ending);
	}


	/**
	 * Checks if auto breaths are enabled.
	 *
	 * @since  1.0.7
	 */
	public function is_auto_breaths_enabled() {

		//If Neural TTS is enabled breaths SSML tags are not supported.
		$neural_enabled = $this->is_polly_neural_enabled();
		if ($neural_enabled) {
			return false;
		}

		$value = get_option( 'amazon_polly_auto_breaths', 'on' );

		if ( empty( $value ) ) {
			$result = false;
		} else {
			$result = true;
		}

		return $result;
	}

	public function deactive_translation_for_post($post_id) {

		delete_post_meta($post_id, 'amazon_ai_source_language');

		$languages_code = array_column($this->languages, 'code');
		foreach ( $languages_code as $language_code ) {
			delete_post_meta($post_id, 'amazon_polly_transcript_' . $language_code);
			delete_post_meta($post_id, 'amazon_polly_transcript_title_' . $language_code);
		}

		$this->delete_post($post_id);
	}

	/**
	 * Returns source language.
	 *
	 * @since  2.0.0
	 */
	public function get_post_source_language($post_id) {
		$value = get_post_meta( $post_id, 'amazon_ai_source_language', true );

		if (empty($value)) {
			$value = $this->get_source_language();
		}

		return $value;
	}

	/**
	 * Returns source language.
	 *
	 * @since  2.0.0
	 */
	public function get_source_language()
	{
		$value = get_option('amazon_ai_source_language', 'en');
		if (empty($value)) {
			$value = 'en';
		}

		return $value;
	}

	public function replace_if_empty($value, $new_value)
	{
		if (!empty($value)) {
			return $value;
		}
		else {
			return $new_value;
		}
	}


	public function is_polly_enabled_for_new_posts() {
		if ( $this->is_polly_enabled() ) {
			$default_configuration = get_option( 'amazon_polly_defconf' );
			if ( 'Amazon Polly enabled' === $default_configuration ) {
				return true;
			} else {
				return false;
			}
		}
	}

	public function is_audio_download_enabled() {
			$value = $this->checked_validator('amazon_ai_download_enabled');
			if ('checked' == trim($value)) {
				return true;
			} else {
				return false;
			}
	}

	/**
	 * Validates if logging is enabled.
	 *
	 * @since  2.6.1
	 */
	public function is_logging_enabled() {
			$value = $this->checked_validator('amazon_ai_logging');
			if ('checked' == trim($value)) {
				return true;
			} else {
				return false;
			}
	}

	/**
	 * Validates if Amazon Polly support is enabled.
	 *
	 * @since  2.5.0
	 */
	public function is_polly_enabled() {

		if (!$this->is_language_supported_for_polly()) {
			return false;
		}


			$value = $this->checked_validator('amazon_ai_polly_enable');
			if ('checked' == trim($value)) {
				return true;
			} else {
				return false;
			}
	}

	public function is_language_supported_for_polly() {

    $selected_source_language = $this->get_source_language();

    foreach ($this->get_all_polly_languages() as $language_code) {
      if (strcmp($selected_source_language, $language_code) === 0) {
        return true;
      }
    }

    return false;
  }

	public function is_audio_for_translations_enabled() {
		if ( $this->is_polly_enabled() ) {
			$value = $this->checked_validator('amazon_ai_audio_for_translation_enabled');
			if ('checked' == trim($value)) {
				return true;
			} else {
				return false;
			}
		}
	}

	public function validate_amazon_translate_access() {
		try {
			$this->translate->is_translate_accessible($this->translate_client);
			return true;
		} catch(TranslateAccessException $e) {
			$this->show_error_notice("notice-error", "Amazon Translate service is not reachable.");
			return false;
		}

		return true;
	}

	/**
	 * Render the enable Translation input.
	 *
	 * @since  2.0.0
	 */
	public function is_translation_enabled()
	{

					$start_value = $this->checked_validator('amazon_polly_trans_enabled');
					$translate_accessible = true;
					$supported_regions = array(
						'us-east-1',
						'us-east-2',
						'us-west-2',
						'eu-west-1',
						'ap-south-1',
						'ap-northeast-2',
						'ap-southeast-1',
						'ap-northeast-1',
						'ca-central-1',
						'eu-central-1'
					);
					$selected_region = $this->get_aws_region();
					if (in_array($selected_region, $supported_regions)) {
						if ('checked' == trim($start_value)) {
							if ($translate_accessible) {

								// If we are returning true - translate is enabled, S3 should also be enabled.
								if (!$this->is_s3_enabled()) {
									update_option( 'amazon_polly_s3', 'on' );
								}

								return true;
							}
						}
					}



		return false;
	}


	public function get_s3_object_link($post_id, $language) {

		$file_name	= 'amazon_polly_' . $post_id . $language . '.mp3';
		$s3BucketName = $this->get_s3_bucket_name();
		$cloudfront_domain_name = apply_filters('amazon_polly_cloudfront_domain', get_option( 'amazon_polly_cloudfront' ));

		if ( get_option('uploads_use_yearmonth_folders') ) {
			$key = get_the_date( 'Y', $post_id ) . '/' . get_the_date( 'm', $post_id ) . '/' . $file_name;
		} else {
			$key = $file_name;
		}

		if ( empty( $cloudfront_domain_name ) ) {

			$selected_region = $this->get_aws_region();

			$audio_location_link = 'https://s3.' . $selected_region . '.amazonaws.com/' . $s3BucketName . '/' . $key;
		} else {
			$audio_location_link = 'https://' . $cloudfront_domain_name . '/' . $key;
		}

		return $audio_location_link;

	}

	/**
	 * Validates if AWS configuration is correct and AWS can be reached.
	 *
	 * @since    2.5.0
	 */
	public function validate_amazon_polly_access()
	{
		try {
			$this->check_aws_access();

			// Checks if S3 should be used for storing files.

			$is_s3_enabled = $this->is_s3_enabled();
			if ($is_s3_enabled) {
				try {

					// Checks if S3 bucket can be access.

					$accessible = $this->s3_handler->check_if_s3_bucket_accessible();
					if (!$accessible) {
						$this->s3_handler->create_s3_bucket();
						$this->show_error_notice("notice-info", "The S3 bucket was successfully created.");
					}
				}

				catch(S3BucketNotAccException $e) {
					$this->show_error_notice("notice-info", "The S3 bucket doesn't exist or can't be accessed. Creating a new S3 bucket.");

					// If S3 bucket is not accessible, we will try to create new one.

					$this->s3_handler->create_s3_bucket();
					$this->show_error_notice("notice-info", "The S3 bucket was successfully created.");
				}
			}
		}

		catch(CredsException $e) {
			$this->deactivate_all();
			$this->show_error_notice("notice-error", "Can't connect to AWS. Check your AWS credentials.");
			return false;
		}

		catch(S3BucketNotCreException $e) {
			$this->show_error_notice("notice-error", "Could not create S3 bucket.");
			return false;
		}

		catch(Exception $e) {
			$this->deactivate_all();
			$this->show_error_notice("notice-error", "Unknown error.");
			return false;
		}

		return true;
	}

	public function deactivate_all() {
		$this->deactivate_polly();
		$this->deactivate_translate();
		$this->deactivate_podcast();
	}


	public function deactivate_polly() {
		update_option( 'amazon_ai_polly_enable', '' );
	}

	public function deactivate_translate() {
		update_option( 'amazon_polly_trans_enabled', '' );
	}

	public function deactivate_podcast() {
		update_option( 'amazon_polly_podcast_enabled', '' );
	}


	public function show_error_notice($type, $message)
	{
		add_action('admin_notices',
		function () use($type, $message)
		{
?>
						<div class="notice  <?php
			echo $type ?>  is-dismissible">
							<p><?php
			_e($message, 'amazon_ai'); ?></p>
						</div>

			<?php
		});
	}


	public function get_sample_rate() {
		$sample_rate = get_option('amazon_polly_sample_rate');
		if (empty($sample_rate)) {
			$sample_rate = '24000';
			update_option('amazon_polly_sample_rate', $sample_rate);
		}

		$this->logger->log(sprintf('%s Sample rate: %s ', __METHOD__, $sample_rate));

		return $sample_rate;
	}

	public function get_voice_id() {
		$voice_id = get_option('amazon_polly_voice_id');
		if (empty($voice_id)) {
			$voice_id = 'Matthew';
			update_option('amazon_polly_voice_id', $voice_id);
		}

		return $voice_id;
	}

	/**
	 * Returns the name of the AWS region, which should be used by the plugin.
	 *
	 * @since    2.5.0
	 */
	public function get_aws_region()
	{
		$region = apply_filters('amazon_polly_aws_region', get_option('amazon_polly_region'));
		if (empty($region)) {
			update_option('amazon_polly_region', 'us-east-1');
			$region = 'us-east-1';
		}

		return $region;
	}

	public function if_translatable_enabled_for_language($language_code) {
		$source_language_code = $this->get_source_language();
		$value = $this->check_if_language_is_checked($language_code, $source_language_code);
		if (empty($value)) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Checks if checkbox should be checked for specific language.
	 *
	 * @since  2.0.0
	 */
	public function check_if_language_is_checked($language_code, $source_language_code)
	{
		#Some translations between languages are not supported by the service.
		#Details: https://docs.aws.amazon.com/translate/latest/dg/pairs.html
		if (!$this->is_translation_supported($source_language_code, $language_code)) {
			return '';
		}

		$option = 'amazon_polly_trans_langs_' . $language_code;

		$value = get_option($option, '');

		if (empty($value)) {
			return '';
		}
		else {
			return ' checked ';
		}
	}

	/**
	 * Get S3 bucket name. The method uses filter 'amazon_polly_s3_bucket_name,
	 * which allows to use customer S3 bucket name instead of default one.
	 *
	 * @since  1.0.6
	 */
	public function get_s3_bucket_name()
	{
		$s3_bucket_name = $this->s3_handler->get_bucket_name();
		return $s3_bucket_name;
	}

	public function get_polly_voices()
	{
		$voices = $this->polly_client->describeVoices();
		return $voices;
	}

	/**
	 * Return post type value.
	 *
	 * @since  1.0.7
	 */
	public function get_posttypes()
	{
		$posttypes = get_option('amazon_polly_posttypes', 'post');
		$posttypes = str_replace(",", " ", $posttypes);
		$posttypes = preg_replace('!\s+!', ' ', $posttypes);
		update_option('amazon_polly_posttypes', $posttypes);

		return $posttypes;
	}

	/**
	 * Checks if pollycast is enabled.
	 *
	 * @since  1.0.7
	 */
	public function is_podcast_enabled()
	{
		$value = get_option('amazon_polly_podcast_enabled', 'on');
		if (empty($value)) {
			$result = false;
		}
		else {
			$result = true;
		}

		return $result;
	}

	/**
	 * Return speed for audio files.
	 *
	 * @since  1.0.5
	 */
	public function get_audio_speed()
	{
		$speed = get_option('amazon_polly_speed');
		if (empty($speed)) {
			$speed = '100';
		}

		if (intval($speed) < 20) {
			$speed = '20';
		}

		if (intval($speed) > 200) {
			$speed = '200';
		}

		update_option('amazon_polly_speed', $speed);
		return $speed;
	}

	/**
	 * Method returns lexicons specified in plugin configuration.
	 *
	 * @since  1.0.12
	 */
	public function get_lexicons()
	{
		$lexicons = get_option('amazon_polly_lexicons', '');
		$lexicons = trim($lexicons);
		return $lexicons;
	}

	/**
	 * Check if Powered by AWS option is enabled
	 *
	 * @since  1.0.7
	 */
	public function is_poweredby_enabled()
	{
		$poweredby = get_option('amazon_polly_poweredby', 'on');

		if (empty($poweredby)) {
			$result = false;
		}
		else {
			$result = true;
		}

		return $result;
	}

	/**
	 * Check if SSML is enabled.
	 *
	 * @since  1.0.7
	 */
	public function is_ssml_enabled()
	{
		$ssml_enabled = get_option('amazon_polly_ssml', 'on');
		if (empty($ssml_enabled)) {
			$result = false;
		}
		else {
			$result = true;
		}

		$is_s3_enabled = $this->is_s3_enabled();
		if ($is_s3_enabled) {
			return $result;
		}

		return false;
	}

	public function is_rss2namespace_enabled()
	{
		$value = get_option('podcast_rss2namespace', 'on');
		if (empty($value)) {
			$result = false;
		}
		else {
			$result = true;
		}
		return false;
	}


	/**
	 * Utility function which checks if checkbox for option input should be checked.
	 *
	 * @param       string $option Name of the option which should be checked.
	 * @since  2.0.0
	 */
	public function checked_validator($option)
	{
		$option_value = get_option($option, 'on');
		if (empty($option_value)) {
			return '';
		}
		else {
			return ' checked ';
		}
	}

	public function is_polly_neural_enabled() {
		$option_value = get_option('amazon_polly_neural', '');
		if (empty($option_value) && !$this->is_neural_only_voice()) {
			return '';
		}
		else {
			return ' checked ';
		}
	}

	public function is_polly_news_enabled() {

		if (!$this->is_polly_neural_enabled()) {
			return false;
		}

		$option_value = get_option('amazon_polly_news', '');
		if (empty($option_value)) {
			return false;
		}
		else {
			return ' checked ';
		}
	}


		public function is_polly_conversational_enabled() {

			if (!$this->is_polly_neural_enabled()) {
				return false;
			}

			if ($this->is_polly_news_enabled()) {
				return false;
			}

			$option_value = get_option('amazon_polly_conversational', '');
			if (empty($option_value)) {
				return '';
			}
			else {
				return ' checked ';
			}
		}

		public function should_conversational_style_be_used($voice) {

			if ( !$this->is_conversational_style_for_voice($voice)) {
				return false;
			}

			if ($this->should_news_style_be_used($voice)) {
				return false;
			}

			if ($this->is_polly_conversational_enabled()) {
				$engine = $this->get_polly_engine($voice);
				if ('neural' == $engine) {
					return true;
				}
				return false;
			}

			return false;
		}


	public function should_news_style_be_used($voice) {

		if ( !$this->is_news_style_for_voice($voice)) {
			return false;
		}

		if ($this->is_polly_news_enabled()) {
			$engine = $this->get_polly_engine($voice);
			if ('neural' == $engine) {
				return true;
			}
			return false;
		}

		return false;
	}


		public function is_conversational_supported_in_region() {

			$selected_region = $this->get_aws_region();
			$conversational_supported_regions = array("us-east-1","us-west-2","eu-west-1");

			if (in_array($selected_region, $conversational_supported_regions)) {
				return true;
			} else {
				return false;
			}
		}

	public function is_neural_supported_in_region() {

		$selected_region = $this->get_aws_region();
		$neural_supported_regions = array("us-east-1","us-west-2","ap-northeast-2","ap-southeast-1","ap-southeast-2","ap-northeast-1","ca-central-1","eu-central-1","eu-west-1","eu-west-2","us-gov-west-1");

		if (in_array($selected_region, $neural_supported_regions)) {
			return true;
		} else {
			return false;
		}
	}

	public function is_news_style_for_voice($voice) {
		$supported_voices = array("Joanna","Matthew","Lupe","Amy");

		if (in_array($voice, $supported_voices)) {
			return true;
		} else {
			return false;
		}
	}

	public function is_conversational_style_for_voice($voice) {
		$supported_voices = array("Joanna","Matthew");

		if (in_array($voice, $supported_voices)) {
			return true;
		} else {
			return false;
		}
	}

	public function is_neural_supported_for_voice($voice) {
		$neural_supported_voices = array("Olivia","Amy","Emma","Brian","Ivy","Joanna","Kendra","Kimberly","Salli","Joey","Justin","Kevin","Matthew","Camila","Lupe", "Seoyeon", "Gabrielle");

		if (in_array($voice, $neural_supported_voices)) {
			return true;
		} else {
			return false;
		}

	}

	public function is_neural_only_voice() {
		$voice = $this->get_voice_id();
		$neural_only_voices = array("Olivia","Kevin", "Gabrielle");
		$logger = new AmazonAI_Logger();

		$logger->log("Checking for neural: ".$voice);

		if (in_array($voice, $neural_only_voices)) {
			$logger->log("Neural only: TRUE");
			return true;
		} else {
			$logger->log("Neural only: FALSE");
			return false;
		}

	}

	public function get_polly_engine($voice) {

		if (!$this->is_neural_supported_in_region()) {
			return 'standard';
		}

		if (!$this->is_neural_supported_for_voice($voice)) {
			return 'standard';
		}


		if ($this->is_polly_neural_enabled()) {
			return 'neural';
		}

	}


	/**
	 * Checks if Media Libary support is enabled.
	 *
	 * @since  2.5.0
	 */
	public function is_medialibrary_enabled()
	{
		$value = get_option('amazon_ai_medialibrary_enabled');
		if (empty($value)) {
			$result = false;
		}
		else {
			$result = true;
		}

		return $result;
	}

	/**
	 * Checks if 'Show Subscribe button' is enabled.
	 *
	 * @since  2.6.3
	 */
	public function is_subscribe_button_enabled()
	{
		if ($this->is_podcast_enabled()) {
			$value = get_option('amazon_polly_podcast_button');
			if (empty($value)) {
				$result = false;
			}
			else {
				$result = true;
			}
		} else {
			$result = false;
		}

		return $result;
	}

	/**
	 * Checks if S3 storage is enabled.
	 *
	 * @since  1.0.7
	 */
	public function is_s3_enabled()
	{
		$value = get_option('amazon_polly_s3', 'on');
		if (empty($value)) {
			$result = false;
		}
		else {
			$result = true;
		}

		return $result;
	}

	/**
	 * Check  connectivity with AWS can be eastablished.
	 *
	 * @since    2.5.0
	 */
	private function check_aws_access()
	{
		try {
			$voice_list = $this->polly_client->describeVoices();
			update_option('amazon_polly_valid_keys', '1');
			return true;
		}

		catch(Exception $e) {
			update_option('amazon_polly_valid_keys', '0');
			throw new CredsException('Could not connect to AWS. Check your AWS credentials.');
		}
	}

	/**
	 * Returns AWS SDK configuration to allow connection with AWS account.
	 *
	 * @since    2.5.0
	 */
	private function get_aws_sdk_config($region = null)
	{
		$aws_sdk_config = [
			'region' => $this->get_aws_region(),
			'version' => 'latest',
			'ua_append' => ['request-source/aws-for-wordpress']
		];
		$credentials = false;
		$aws_access_key = get_option('amazon_polly_access_key');
		$aws_secret_key = get_option('amazon_polly_secret_key');

		if ($aws_access_key && $aws_secret_key) {
			$credentials = [
				'key' => $aws_access_key,
				'secret' => $aws_secret_key,
			];
		}

		if ($credentials = apply_filters('amazon_polly_aws_sdk_credentials', $credentials)) {
			$aws_sdk_config['credentials'] = $credentials;
		}

		if ($region) {
			$aws_sdk_config['region'] = $region;
		}

		return $aws_sdk_config;
	}

  /**
      * Returns AWS SDK configuration to allow connection with AWS account and region us-east-1.
      *
      * @since    4.0.0
      */
    private function get_aws_sdk_config_use1()
    {
        return $this->get_aws_sdk_config('us-east-1');
    }


	/**
	 * Calculate the total price of converting all posts into audio.
	 *
	 * @since  1.0.0
	 */
	public function get_price_message_for_update_all()
	{
		$post_types_supported = $this->get_posttypes_array();
		$number_of_characters = 0;
		$posts_per_page = apply_filters('amazon_polly_posts_per_page', 5);
		$count_posts = wp_count_posts()->publish;
		$max_count_posts = 100;

		// Retrieving the number of characters in all posts.

		$paged = 0;
		$post_count = 0;
		do {
			$paged++;
			$wp_query = new WP_Query(array(
				'posts_per_page' => $posts_per_page,
				'post_type' => $post_types_supported,
				'fields' => 'ids',
				'paged' => $paged,
			));
			$number_of_posts = $wp_query->max_num_pages;
			while ($wp_query->have_posts()) {
				$post_count++;
				$wp_query->the_post();
				$post_id = get_the_ID();
				$clean_text = $this->clean_text($post_id, true, false);
				$post_sentences = $this->break_text($clean_text);
				if (!empty($post_sentences)) {
					foreach($post_sentences as $sentence) {
						$sentence = str_replace('**AMAZONPOLLY*SSML*BREAK*time=***1s***SSML**', '', $sentence);
						$sentence = str_replace('**AMAZONPOLLY*SSML*BREAK*time=***500ms***SSML**', '', $sentence);
						$number_of_characters+= strlen($sentence);
					}
				}
			}

			// If we reached the number of posts which we wanted to read, we stop
			// reading next posts.

			if ($post_count >= $max_count_posts) {
				break;
			}
		}

		while ($paged < $number_of_posts);

		// Price for converting single character according to Amazon Polly pricing.

		$amazon_polly_price = 0.000004;

		// Estimating average number of characters per post.

		if (0 !== $post_count) {
			$post_chars_count_avg = $number_of_characters / $post_count;
		}
		else {
			$post_chars_count_avg = 0;
		}

		// Estimating the total price of convertion of all posts.

		$total_price = 2 * $amazon_polly_price * $count_posts * $post_chars_count_avg;
		$message = 'You are about to convert ' . number_format($count_posts, 0, '.', ',') . ' pieces of text-based content, which totals approximately ' . number_format($number_of_characters, 0, '.', ',') . ' characters. Based on the Amazon Polly pricing ($4 dollars per 1 million characters) it will cost you about $' . $total_price . ' to convert all of your content into to speech-based audio. Some or all of your costs might be covered by the Free Tier (conversion of 5 million characters per month for free, for the first 12 months, starting from the first request for speech). For more information, see https://aws.amazon.com/polly/';
		return $message;
	}

	/**
	 * Method prepare WP_Filesystem variable for interacting with local file system.
	 *
	 * @since    1.0.0
	 */
	public function prepare_wp_filesystem() {
		/** Ensure WordPress Administration File API is loaded as REST requests do not load the file API */
		require_once(ABSPATH . 'wp-admin/includes/file.php');

		$url   = wp_nonce_url( admin_url( 'post-new.php' ) );
		$creds = request_filesystem_credentials( $url );

		if ( ! WP_Filesystem( $creds ) ) {
			request_filesystem_credentials( $url );
			return true;
		}

		global $wp_filesystem;

		return $wp_filesystem;
	}

	/**
	 * Method breakes input text into smaller parts.
	 *
	 * @since       1.0.0
	 * @param       string $text     Text which should be broken.
	 */
	public function break_text($text)
	{
		$text = str_replace('-AMAZONPOLLY-ONLYAUDIO-START-', '', $text);
		$text = str_replace('-AMAZONPOLLY-ONLYAUDIO-END-', '', $text);
		$text = preg_replace('/-AMAZONPOLLY-ONLYWORDS-START-[\S\s]*?-AMAZONPOLLY-ONLYWORDS-END-/', '', $text);
		$parts = [];
		if (!empty($text)) {
			$part_id = 0;
			$paragraphs = explode("\n", $text);
			foreach($paragraphs as $paragraph) {
				$paragraph_size = strlen(trim($paragraph));
				if ($paragraph_size > 0) {
					if ($paragraph_size <= 2800) {
						$parts[$part_id] = $paragraph . ' **AMAZONPOLLY*SSML*BREAK*time=***500ms***SSML** ';
						$part_id++;
					}
					else {
						$words = explode(' ', $paragraph);
						$current_part = '';
						$last_part = '';
						foreach($words as $word) {
							$word_length = strlen($word);
							$current_part_length = strlen($current_part);
							if ($word_length + $current_part_length < 2800) {
								$current_part = $current_part . $word . ' ';
								$last_part = $current_part;
							}
							else {
								$current_part = $current_part . $word . ' ';
								$parts[$part_id] = $current_part;
								$part_id++;
								$current_part = '';
								$last_part = '';
							}
						}

						$parts[$part_id] = $last_part . ' **AMAZONPOLLY*SSML*BREAK*time=***500ms***SSML** ';
						$part_id++;
					} //end if
				} //end if
			} //end foreach
		} //end if

		// Modify speed

		$parts = $this->modify_speed($parts);

		$logger = new AmazonAI_Logger();

		foreach($parts as $part) {
			$logger->log(sprintf('%s <<< PART >>> ', __METHOD__));
			$logger->log(sprintf('%s', $part));
		}

		return $parts;
	}

	/**
	 * Method update sentences (input of the method), and modify their speed,
	 * by adding SSML prosody tag for each sentence.
	 *
	 * @param           string $sentences                 Sentences which should be updated.
	 * @since           1.0.5
	 */
	public function modify_speed($sentences)
	{
		$new_sentences = [];
		$new_sentence_id = 0;
		$speed = $this->get_audio_speed();
		if (100 !== $speed) {
			foreach($sentences as $sentence) {
				$new_sentence = '<prosody rate="' . $speed . '%">' . $sentence . '</prosody>';
				$new_sentences[$new_sentence_id] = $new_sentence;
				$new_sentence_id++;
			}
		}

		return $new_sentences;
	}

	public function modify_sentence_speed($sentence)
	{

		$speed = $this->get_audio_speed();
		if (100 !== $speed) {
				$sentence = '<prosody rate="' . $speed . '%">' . $sentence . '</prosody>';
		}


		return $sentence;
	}

	/**
	 * Checks if post title should be added.
	 *
	 * @since  1.0.7
	 */
	public function is_excerpt_adder_enabled()
	{
		$value = get_option('amazon_polly_add_post_excerpt', 'on');
		if (empty($value)) {
			$result = false;
		}
		else {
			$result = true;
		}

		return $result;
	}

	/**
	 * Encode SSML tags.
	 *
	 * @since  1.0.7
	 * @param  string $text text which should be decoded.
	 */
	public function decode_ssml_tags( $text ) {

		$text = preg_replace( '/(\*\*AMAZONPOLLY\*SSML\*BREAK\*)(.*?)(\*\*\*)(.*?)(\*\*\*SSML\*\*)/', '<break $2"$4"/>', $text );

		return $text;
	}

	/**
	 * Method retrievies post which ID was provided, and clean it.
	 *
	 * @since       1.0.12
	 * @param       string $post_id     ID of the post for which test (content) should be prepapred for conversion.
	 */
	public function clean_text($post_id, $with_title, $only_title)
	{

		#$this->logger->log(sprintf('%s Cleaning text (%s, %s) ', __METHOD__, $with_title, $only_title));

		$clean_text = '';

		// Depending on the plugin configurations, post's title will be added to the audio.
		if ($with_title) {
			if ($this->is_title_adder_enabled()) {
				$clean_text = get_the_title($post_id) . '. **AMAZONPOLLY*SSML*BREAK*time=***1s***SSML** ';
			}
		}


		// Depending on the plugin configurations, post's excerpt will be added to the audio.

		if ($this->is_excerpt_adder_enabled()) {
			$my_excerpt = apply_filters('the_excerpt', get_post_field('post_excerpt', $post_id));
			$clean_text = $clean_text . $my_excerpt . ' **AMAZONPOLLY*SSML*BREAK*time=***1s***SSML** ';
		}

		$clean_text = $clean_text . get_post_field('post_content', $post_id);
		$clean_text = apply_filters('amazon_polly_content', $clean_text);

		if ($only_title) {
			$clean_text = get_the_title($post_id);
		}

		$clean_text = str_replace('&nbsp;', ' ', $clean_text);
		$clean_text = do_shortcode($clean_text);

		$clean_text = $this->skip_tags($clean_text);
		$clean_text = $this->add_pauses($clean_text);

		$is_ssml_enabled = $this->is_ssml_enabled();
		if ($is_ssml_enabled) {
			$clean_text = $this->encode_ssml_tags($clean_text);
		}

		// Creating text description for images
		$clean_text = $this->replace_images($clean_text);
		$clean_text = strip_tags($clean_text, '<break>');
		$clean_text = esc_html($clean_text);


		$clean_text = str_replace('&nbsp;', ' ', $clean_text);
		$clean_text = preg_replace("/https:\/\/([^\s]+)/", "", $clean_text);
		$clean_text_temp = '';

		$paragraphs = explode("\n", $clean_text);
		foreach($paragraphs as $paragraph) {
			$paragraph_size = strlen(trim($paragraph));
			if ($paragraph_size > 0) {
				$clean_text_temp = $clean_text_temp . "\n" . $paragraph;
			}
		}

		$clean_text = $clean_text_temp;
		$clean_text = html_entity_decode($clean_text, ENT_QUOTES, 'UTF-8');
		$clean_text = str_replace('&', ' and ', $clean_text);
		$clean_text = str_replace('<', ' ', $clean_text);
		$clean_text = str_replace('>', ' ', $clean_text);


		return $clean_text;
	}

	private function replace_images($clean_text) {

		//$new_clean_text = preg_replace('/<img.*?alt="(.*?)"[^\>]+>/', 'Image: $1.', $clean_text);
		$new_clean_text = preg_replace('/<img.*?alt="(.*?)"[^\>]+>/', '$1', $clean_text);

		return $new_clean_text;

	}

	/**
	 * Run when deleting a post.
	 *
	 * @param      string $post_id   ID of the post which is gonna to be deleted.
	 * @since    1.0.0
	 */
	public function delete_post( $post_id ) {
		// Check if this isn't an auto save.
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}
		$this->delete_post_audio( $post_id );
	}

	/**
	 * Delets audio for specific post.
	 *
	 * @param string $post_id ID of the post for which audio should be deleted.
	 * @since 1.0.0
	 */
	public function delete_post_audio( $post_id ) {
		try {
			// Deleting audio file.
			$this->init();

			// Validate if this post which is being saved is one of supported types. If not, return.
			$post_types_supported = $this->get_posttypes_array();
			$post_type = get_post_type($post_id);
			if (!in_array($post_type, $post_types_supported )) {
				return;
			}

			$audio_location = get_post_meta( $post_id, 'amazon_polly_audio_location', true );
			$file           = 'amazon_polly_' . $post_id . '.mp3';
			$wp_filesystem  = $this->prepare_wp_filesystem();


			$file_handler = $this->get_file_handler();
			$file_handler->delete($wp_filesystem, $file, $post_id);
		} catch(Exception $e) {
			$this->show_error_notice("notice-error", "Encountered an error while deleting the file.");
			error_log($e);
		}

	}

	private function skip_tags($text) {

		$skip_tags_array = $this->get_skiptags_array();

		foreach ($skip_tags_array as $value) {
			$text = preg_replace('/<' . $value . '>(\s*?)(.*?)(\s*?)<\/' . $value . '>/', '', $text);
		}

		return $text;
	}

	private function add_pauses($text) {

		#Creates a little pause after closes the tag <li>
		$text = str_replace ('</li>',' **AMAZONPOLLY*SSML*BREAK*time=***300ms***SSML** </li>',$text);

		#Create a support to the tag <sub> (helpful to 'read' abreviations, for example)
		$text = preg_replace('/<sub\b((?:(?:\s+alias="(.*?)")|[^\s>]+|\s+))*>([\s\S]*?)<\/sub>/', '$2', $text);

		return $text;
	}

	/**
	 * Encode SSML tags.
	 *
	 * @since  1.0.7
	 * @param  string $text text which should be encoded.
	 */
	private function encode_ssml_tags($text)
	{
		$text = preg_replace('/<ssml><break ([\S\s]*?)["\'](.*?)["\'](.*?)<\/ssml>/', '**AMAZONPOLLY*SSML*BREAK*$1***$2***SSML**', $text);
		return $text;
	}

	/**
	 * Checks if post title should be added.
	 *
	 * @since  1.0.7
	 */
	public function is_title_adder_enabled()
	{
		$value = get_option('amazon_polly_add_post_title', 'on');
		if (empty($value)) {
			$result = false;
		}
		else {
			$result = true;
		}

		return $result;
	}


	/**
	 * Add Amazon Pollu QuickTag button.
	 *
	 * @since    1.0.7
	 */
	public function add_quicktags() {
		$is_ssml_enabled = $this->is_ssml_enabled();

		if ( $is_ssml_enabled ) {
			if ( wp_script_is( 'quicktags' ) ) {
				?>
					<script type="text/javascript">
						QTags.addButton( 'eg_ssmlbreak', 'SSML Break', '<ssml><break time="1s"/></ssml>','','', 'Amazon Polly SSML Break Tag', 111 );
					</script>
				<?php
			}
		}
	}

  /**
	 * Configure supported HTML tags.
	 *
	 * @since  1.0.7
	 * @param  string $tags supported tags.
	 */
	public function allowed_tags_tinymce( $tags ) {
		$ssml_tags                       = array(
			'ssml',
			'speak',
			'break[time|whatever]',
			'emphasis[level]',
			'lang',
			'mark',
			'paragraph',
			'phoneme',
			'prosody',
			's',
			'say-as',
			'sub',
			'w',
			'amazon:breath',
			'amazon:auto-breaths',
			'amazon:effect[name]',
			'amazon:effect[phonation]',
			'amazon:effect[vocal-tract-length]',
			'amazon:effect[name]',
		);
		$tags['extended_valid_elements'] = implode( ',', $ssml_tags );
		return $tags;
	}

  /**
	 * Configure supported HTML tags.
	 *
	 * @since  1.0.7
	 * @param  string $tags supported tags.
	 */
	public function allowed_tags_kses( $tags ) {
		$tags['ssml']  = true;
		$tags['speak'] = true;
		$tags['break'] = array(
			'time' => true,
		);
		return $tags;
	}

	/**
	 * Return skip tags array.
	 *
	 * @since  1.0.7
	 */
	public function get_skiptags_array() {
		$array = get_option( 'amazon_ai_skip_tags' );
		$array = explode( ' ', $array );

		return $array;

	}

	/**
	 * Return post type value array.
	 *
	 * @since  1.0.7
	 */
	public function get_posttypes_array() {
		$posttypes_array = get_option( 'amazon_polly_posttypes', 'post' );
		$posttypes_array = explode( ' ', $posttypes_array );
		$posttypes_array = apply_filters( 'amazon_polly_post_types', $posttypes_array );

		return $posttypes_array;

	}

	/**
	 * Checks if checkbox should be checked for specific language.
	 *
	 * @since  2.0.0
	 */
	public function is_language_translatable( $provided_language_code ) {

		foreach ($this->languages as $language_data) {
			$language_code = $language_data['code'];
			$is_language_supported = $language_data['translatable'];

			if ( !empty($is_language_supported) ) {
				if ($provided_language_code === $language_code) {
					return $is_language_supported;
				}
			}
		}

		return false;
	}


    /**
     * Register the stylesheets for the admin area.
     *
     * @since    1.0.0
     */
    public function enqueue_styles() {
        wp_enqueue_style( 'amazon-polly', plugin_dir_url( __FILE__ ) . 'css/amazonpolly-admin.css', array(), null, 'all' );
        wp_enqueue_style( 'font-awesome', plugin_dir_url( __FILE__ ) . 'css/all.min.css', array(), null, 'all' );
        wp_enqueue_style( 'jquery-ui-core' );
        wp_enqueue_style( 'jquery-ui-progressbar' );
        wp_enqueue_style( 'jquery-ui', '//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css', array(), '1.21.1', 'all' );
    }

	/**
	 * Register the JavaScript for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_scripts() {
		wp_enqueue_script( 'amazon-polly', plugin_dir_url( __FILE__ ) . 'js/amazonpolly-admin.js', array( 'jquery' ), null, false );
		wp_enqueue_script( 'jquery-ui-core' );
		wp_enqueue_script( 'jquery-ui-progressbar' );
		$nonce_array = array(
			'nonce' => wp_create_nonce( 'pollyajaxnonce' ),
		);
		wp_localize_script( 'jquery', 'pollyajax', $nonce_array );

    }
    /**
     * Register JavaScript and CSS for the CloudFront page
     *
     * @since           4.0.0
     */
    public function enqueue_custom_scripts() {
        wp_register_script( 'amazon_cf_script', plugin_dir_url( __FILE__ ) . 'js/amazon_cf.js', array( 'jquery' ), null, false );

        wp_enqueue_script( 'amazon_cf_script' );
        wp_enqueue_style( 'amazon_cf_style', plugin_dir_url( __FILE__ ) . 'css/amazon_cf.css', array(), null, 'all' );

        wp_localize_script( 'amazon_cf_script', 'amazon_cf_ajax', array( 'ajax_url' => admin_url('admin-ajax.php')) );

    }

	public function is_translation_supported($source_language, $target_language) {

		if (( 'ko'== $source_language ) && ( 'he' == $target_language )) {
			return false;
		}

		return true;
	}

	/**
	 * Register meta box for 'Enable Amazon Polly' on post creation form.
	 *
	 * @since    1.0.0
	 */
	public function field_checkbox() {

		$post_types_supported = $this->get_posttypes_array();

		$meta_box = new AmazonAI_PostMetaBox($this);

		add_meta_box(
			'amazon_polly_box_id',
			// This is HTML id of the box on edit screen.
			'Amazon Polly',
			// Title of the box.
			[ $meta_box, 'display_box_content'],
			// Function to be called to display the checkboxes, see the function below.
			$post_types_supported,
			// On which edit screen the box should appear.
			'normal',
			// Part of page where the box should appear.
			'high'
			// Priority of the box.
		);
	}

    /**
     * Validates if AWS configuration is correct and AWS can be reached for CloudFront page
     *
     * @since    4.0.0
     */
    public function validate_cloudfront_access() {
        try {
            $this->check_aws_access();
        }
        catch(CredsException $e) {
            $this->show_error_notice("notice-error", "Can't connect to AWS. Check your AWS credentials.");
            return false;
        }
        return true;
    }

    /**
     * Checks if a CloudFront distribution has been created
     *
     * @since           4.0.0
     */
    public function is_cloudfront_deployed() {
        return get_option('amazon_stack_state') == 'ready';
    }

    /**
     * Checks if the URL Rewrite after CloudFront distribution deployment is enabled
     *
     * @since           4.0.0
     */
    public function is_cloudfront_enabled() {
        return get_option('amazon_cloudfront_enabled') == 'checked';
    }

    public function add_settings_link($links) {
        $settings_link = '<a href="admin.php?page=amazon_ai">Settings</a>';
        array_push( $links, $settings_link );
        return $links;
    }

		public function aws_configuration_update($new_value, $old_value) {

			$default_value = '********************';

			if ( !isset($new_value) ) {
				$new_value = $default_value;
			}

			if ($new_value != $default_value) {
				update_option('amazon_polly_secret_key', $new_value);
			}

			return $default_value;
    }

}