/**
	 * Retrieve a shortened permalink URL for the feed item identified by $post.
	 * If the post is not a feed item, returns an empty string, unless
	 * overridden by the 'wprss_ftp_shortened_item_url' filter.
	 * The shortened URL will be cached for this item. To invalidate cache,
	 * change the item's or the item source's shortening method.
	 * 
	 * Will write to log on error.
	 * 
	 * @since 2.8.6
	 * @param WP_Post|int $post A post object or ID
	 * @param null|mixed $default The value to return if the post URL cannot be shortened.
	 * @return string The shortened URL of the specified item
	 */
	public static function get_shortened_item_url($post, $default = null) {
		$post = get_post($post);
		$meta = WPRSS_FTP_Meta::get_instance();
		
		// If no permalink, or it's empty, just return it
		if( !($long_url = trim($meta->get_meta( $post->ID, 'wprss_item_permalink', false ))) || empty($long_url) ) {
			return apply_filters('wprss_ftp_shortened_item_url', $long_url, $post, false); // The false at the end means the URL was not shortened
		}
		
		// If item is not attached to feed source, return original permalink too
		if ( !($item_source_id = $meta->get_meta( $post->ID, 'feed_source' )) ) {
			return apply_filters('wprss_ftp_shortened_item_url', $long_url, $post, false); // The false at the end means the URL was not shortened
		}
		
		$short_url = trim($meta->get_meta( $post->ID, self::META_KEY_SHORT_URL)); // The shortened URL that may already exist on the item
		$item_shortening_method = trim((string)$meta->get_meta( $post->ID, self::META_KEY_URL_SHORTENING_METHOD)); // The shortener code of the item
		$source_shortening_method = trim((string)$meta->get_meta($item_source_id, self::META_KEY_URL_SHORTENING_METHOD));  // The shortener code of the source
		
		// If item has been shortened using the source's method, return that
		if( $item_shortening_method === $source_shortening_method ) {
			return apply_filters('wprss_ftp_shortened_item_url', $long_url, $post, false); // The false at the end means the URL was not shortened;
		}
		
		// Initiates the actual shortening
		$short_url = self::shorten_url($long_url, $source_shortening_method);
		
		// If URL could not be shortened using services, log and return the error
		if( is_wp_error($short_url) ) {
			/* @var $short_url WP_Error */
			WPRSS_FTP_Utils::log( sprintf('Could not shorten URL "%3$s" of post #%4$s using method "%1$s": %2$s', $source_shortening_method, $short_url->get_error_message(), $long_url, $post->ID), __FUNCTION__);
			return $default;
		}
		
		// Saving new meta data
		$meta->add_meta($post->ID, self::META_KEY_SHORT_URL, $short_url);
		$meta->add_meta($post->ID, self::META_KEY_URL_SHORTENING_METHOD, $source_shortening_method);
		
		return apply_filters('wprss_ftp_shortened_item_url', $short_url, $post, true);
	}
	/**
	 * Calls the log function with a print_r of the given object
	 * 
	 * @since 1.0
	 */
	public static function log_object( $message, $obj, $src = 'Feed to Post', $log_level = null ) {
		WPRSS_FTP_Utils::log( "$message " . print_r( $obj, TRUE ), $src, $log_level );
	}
	/**
	 * Checks if the feed source uses the force full content option or meta option, and
	 * returns the fulltextrss url if so.
	 * 
	 * @since 1.0
	 */
	public static function check_force_full_content( $feed_url, $feed_ID ) {
		if ( wprss_ftp_using_feed_items( $feed_ID ) ) {
			return $feed_url;
		}
		// Get the computed settings / meta options for the feed source
		$options = WPRSS_FTP_Settings::get_instance()->get_computed_options( $feed_ID );

		// If using force full content option / meta
		if ( WPRSS_FTP_Utils::multiboolean( $options['force_full_content'] ) === TRUE ) {
			
			$service = WPRSS_FTP_Settings::get_instance()->get('full_text_rss_service');
			$service = apply_filters( 'wprss_ftp_service_before_full_text_feed_url', $service );
			switch( $service ) {
				case 'free':
					$key = WPRSS_FTP_FULL_TEXT_RSS_KEY;
					$API_HASH = sha1( $key . $feed_url );
					$encoded_url = urlencode( $feed_url );
					// Prepare the fulltext sources
					$full_text_sources = apply_filters(
						'wprss_ftp_full_text_sources',
						array(
							"http://fulltext.wprssaggregator.com/makefulltextfeed.php?key=1&hash=$API_HASH&links=preserve&exc=1&url=",
							"http://ftr-premium.fivefilters.org/makefulltextfeed.php?key=1920&hash=$API_HASH&max=10&links=preserve&exc=1&url=",						
						)
					);
					// Start with no feed to use
					$feed_url_to_use = NULL;

					// Load SimplePie
					require_once ( ABSPATH . WPINC . '/class-feed.php' );

					// For each source ...
					foreach ( $full_text_sources as $full_text_source ) {
						// Prepare the feed
						$full_text_feed_url = $full_text_source . $encoded_url;
						$feed = wprss_fetch_feed( $full_text_feed_url, $feed_ID );

						// If the feed has no errors, the we will use this feed
						if ( !is_wp_error( $feed ) && !$feed->error() ) {
							$feed_url_to_use = $full_text_source . $encoded_url;
							break;
						}
					}
					
					// If after trying all the sources, the feed to use is still NULL, then no source was valid.
					// Return the same url passed as parameter, Otherwise, return the full text rss feed url
					if ( $feed_url_to_use === NULL ) {
						WPRSS_FTP_Utils::log( __( 'Failed to find a working full text rss service.', WPRSS_TEXT_DOMAIN ), 'check_force_full_content' );
					}
					return ( $feed_url_to_use === NULL )? $feed_url : $feed_url_to_use;

				case 'feeds_api':
					$api_key = WPRSS_FTP_Settings::get_instance()->get( 'feeds_api_key' );
					$encoded_url = urlencode( $feed_url );

					$feeds_api_feed_url = WPRSS_FTP_Utils::template(
						WPRSS_FTP_FEEDS_API_REQUEST_FORMAT,
						array(
							'url'	=>	$encoded_url,
							'key'	=>	$api_key,
						)
					);
					// Attempt to fetch the feed
					$feed = wprss_fetch_feed( $feeds_api_feed_url, $feed_ID );

					// If an error was encountered
					if (  is_wp_error( $feed ) || $feed->error() ) {
						// Request the error message and log it
						$response = wp_remote_get( $feeds_api_feed_url );
						WPRSS_FTP_Utils::log( "FeedsAPI failed to return a feed, and responded with: \"{$response['body']}\"" );
						// Return the original parameter url
						return $feed_url;
					}

					// Return the feeds api if no error was encountered.
					return $feeds_api_feed_url;

				// For other services
				default:
					return apply_filters( 'wprss_ftp_misc_full_text_url', $feed_url, $feed_ID, $service );
			}
		}
		// Otherwise, return back the given url
		else return $feed_url;
	}
	/**
	 * Searches the post content for images.
	 *
	 * @param post_id 	The ID of the converted post
	 * @param source 	The ID of the feed source
	 * @since 1.0
	 */
	public function save_images_locally_from_post( $post_ID, $source ) {
		wprss_log( "Beginning image processing for post #$post_ID.", NULL, WPRSS_LOG_LEVEL_SYSTEM );
		// Get the post form the ID
		$post = get_post( $post_ID );
		// If the post is null, return null.
		if ( $post === NULL ) {
			wprss_log_obj( 'Received incorrect or NULL post ID.', $post_ID, NULL, WPRSS_LOG_LEVEL_ERROR );
			return NULL;
		}

		// Get the computed settings
		$options = WPRSS_FTP_Settings::get_instance()->get_computed_options( $source );

		// Get the minimum image size settings
		$min_width = $options['image_min_width'];
		$min_height = $options['image_min_height'];

		//== SAVE IMAGES LOCALLY ===

		// Get the post content
		$content = $post->post_content;

		// Match all <img> tag src attributes ( the image source url )
		preg_match_all('|<img.*?src=[\'"](.*?)[\'"].*?>|i', $content, $matches);
		// Include the file and media libraries
		require_once( ABSPATH . 'wp-admin/includes/media.php' );
		require_once( ABSPATH . 'wp-admin/includes/file.php' );
		require_once( ABSPATH . 'wp-admin/includes/image.php' );

		/**
		 * DEVELOPER NOTE:
		 *
		 * The below loop will iterate through all found image tags, and generate an associative array
		 * with the original image URLs as keys and the new local image URLs as values.
		 *
		 * This array will be used as a map to find/replace the URLs, to link the images in the post content
		 * to the newly downloaded images.
		 */

		// Prepare the images array
		$images = array();

		// For each matching image tag in the post content
		foreach ( $matches[1] as $url ) {
			// Save the url found as the key to use the the $images array
			$key = $url;
			// Only proceed if the url is from an external source
			if ( ! wprss_ftp_is_url_local( $url ) ) {

				WPRSS_FTP_Utils::log_object( 'Found external image', $url, __METHOD__, WPRSS_FTP_Utils::LOG_LEVEL_SYSTEM );
				// Attempt to get a larger version, if image is from facebook
				$url = $this->attempt_to_get_large_fb_image( $url );

				// If the option to save images is enabled, download it
				if ( WPRSS_FTP_Utils::multiboolean( $options['save_images_locally'] ) === TRUE ) {
					// Use a large time limit, to accomodate for big file sizes
					set_time_limit( 600 );
					$img = NULL;
					// Check its size
					if ( $this->image_obeys_minimum_size( $url, $min_width, $min_height ) !== FALSE ) {
						WPRSS_FTP_Utils::log_object( 'Image obeys min dimensions. Downloading ...', $url, __METHOD__, WPRSS_FTP_Utils::LOG_LEVEL_SYSTEM );
						// Download it
						$img = wprss_ftp_media_sideload_image( $url, $post_ID );
					}
					// If the download was successful
					if ( $img !== NULL && !is_wp_error( $img ) ) {
						// Set the new image to be the url of the downloaded attachment
						$images[ $key ] = wp_get_attachment_url( $img );
						WPRSS_FTP_Utils::log_object( sprintf( 'Downloaded image for post #%1$d', $post_ID ), sprintf( '%1$s -> %2$s', $url, $images[ $key ] ), __METHOD__, WPRSS_FTP_Utils::LOG_LEVEL_INFO );
					}
					// If an error occured while downloading the file,
					// keep the image external
					else {
						$images[ $key ] = $url;
						WPRSS_FTP_Utils::log_object( 'Image download failed!', (is_wp_error( $img ) ? $img->get_error_message() : 'Unknown error'), __METHOD__, WPRSS_FTP_Utils::LOG_LEVEL_SYSTEM );
					}
				}
				// If not saving images locally, keep the image external
				else {
					$images[ $key ] = $url;
					WPRSS_FTP_Utils::log( 'Image kep external due to settings', __METHOD__, WPRSS_FTP_Utils::LOG_LEVEL_SYSTEM );
				}

			} // End of external image check
			// For local images
			else {
				$images[ $key ] = $url;
			}
		} // end of loop for all image tag urls found in the content

		// Now we have the images array built
		// We extract the original image URLs from the keys and the new image URLs from the values
		$old = array_keys( $images );
		$new = array_values( $images );

		// Check if the filter to strip images from post content returns TRUE
		if ( apply_filters( 'wprss_ftp_strip_images_from_post', FALSE ) === TRUE ) {
			// Replace all image tags with an empty string
			$content = preg_replace( "/<img[^>]+\>/i", '', $content );
			// Update the post content
			WPRSS_FTP_Utils::update_post_content( $post_ID, $content );
			wprss_log( "Stripped all images from post content.", NULL, WPRSS_LOG_LEVEL_SYSTEM );
		}
		// Otherwise, if the option to save images is enabled, replace the old image urls with the new urls of the locally downloaded images
		elseif ( WPRSS_FTP_Utils::multiboolean( $options['save_images_locally'] ) === TRUE ) {
			// Now we have an associative array of old urls pointing to the new ones.
			// We perform a find and replace to use the new urls for the images
			$content = str_replace( $old, $new, $content );

			// Update the post content
			WPRSS_FTP_Utils::update_post_content( $post_ID, $content );
			wprss_log( "Replaced old image URLs with new ones.", NULL, WPRSS_LOG_LEVEL_SYSTEM );
		}

		do_action( 'wprss_ftp_saved_images_from_post', $post_ID, $source, $images );
	}