/**
	 * Class Constructor. Sets up the hooks and inititalizes the class.
	 *
	 * @since 1.0
	 */
	public function __construct() {
		// Initialize variables
		$this->meta = WPRSS_FTP_Meta::get_instance();
		$this->settings = WPRSS_FTP_Settings::get_instance();
		$this->images = WPRSS_FTP_Images::get_instance();
		$this->debug = WPRSS_FTP_Debug::get_instance();
		$this->assistant = WPRSS_FTP_Feed_Assistant::get_instance();

		add_action( 'init', array( $this, 'check_request' ) );

		add_filter( 'wprss_register_addon', array($this, 'register_addon') );

		// Activation / Deactivation hooks
		register_activation_hook( __FILE__, array( $this, 'on_activation' ) );

		// Initialization
		add_action( 'plugins_loaded', array( $this, 'check_for_aggregator' ) );
		add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
		add_action( 'admin_init', array( $this, 'check_other_addons' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_and_styles' ) );
		add_action( 'admin_head', array( $this, 'wprss_ftp_admin_head' ) );
		add_action( 'admin_footer', array( $this, 'wprss_ftp_admin_footer' ) );

		// Adds custom post type arguments for wprss_feed
		add_filter( 'wprss_feed_post_type_args', array( $this, 'custom_post_type_args' ) );

		// Conversion hook
		add_filter( 'wprss_insert_post_item_conditionals', array( 'WPRSS_FTP_Converter', 'convert_to_post' ), 15, 3 );
		add_filter( 'wprss_still_update_import_count', '__return_true' );

		add_filter( 'wprss_feed_tags_to_strip', array( 'WPRSS_FTP_Converter', 'feed_tags_to_strip' ), 10, 2 );

		// Full Text RSS hook
		add_filter( 'wprss_feed_source_url', array( 'WPRSS_FTP_Converter', 'check_force_full_content' ), 10, 2 );

		// Add the truncation post types
		add_filter( 'wprss_truncation_post_types', array( $this, 'truncation_post_types' ) );

		// Add filter to remove unused core settings
		add_filter( 'wprss_settings_array', array( $this, 'remove_unused_core_settings' ) );

		// Remove Imported feeds menu
		add_action( 'admin_menu', array( $this, 'remove_imported_feed_items_menu' ), 20 );

		// Filters that change row action texts and titles
		add_filter( 'wprss_view_feed_items_row_action_link', array( $this, 'view_feed_items_row_action_link' ) );
		add_filter( 'wprss_view_feed_items_row_action_text', array( $this, 'view_feed_items_row_action_text' ) );
		add_filter( 'wprss_fetch_items_row_action_text', array( $this, 'fetch_items_row_action_text' ) );
		add_filter( 'wprss_purge_feeds_row_action_text', array( $this, 'delete_posts_row_action_text' ) );
		add_filter( 'wprss_purge_feeds_row_action_title', array( $this, 'delete_posts_row_action_title' ) );

		// Filter the query that shows the feed items per source
		add_filter( 'wprss_view_feed_items_meta_query', array( $this, 'view_posts_from_source_meta_query' ), 10 , 2 );
		// Filter the query that deletes feed items per source
		add_filter( 'wprss_delete_per_source_query', array( $this, 'delete_posts_from_source_query' ), 10 , 2 );

		// Filter to change post title
		//add_filter( 'the_title', array( $this, 'link_posts_to_external'), 10 , 2 );
		add_filter( 'post_link', array( $this, 'link_posts_to_external'), 10 , 2 );
		add_filter( 'post_type_link', array( $this, 'link_posts_to_external'), 10 , 2 );

		// Override's the core's shortcode output
		add_filter( 'wprss_shortcode_output', array( $this, 'override_shortcode' ) );

		// Change the post type for the wprss_get_feed_items_for_source function
		add_filter( 'wprss_get_feed_items_for_source_args', array( $this, 'get_feed_items_for_source_args' ), 10, 2 );

		// Add columns to the Feed Sources table
		add_filter( 'wprss_set_feed_custom_columns', array( $this, 'add_wprss_feed_columns' ) );
		// Add the action to render the added columns
		add_action( 'manage_wprss_feed_posts_custom_column', array( $this, 'render_wprss_feed_columns' ), 10, 2 );

		// Action to show admin notices for activation hooks
		add_action( 'admin_init', array( $this, 'admin_notices_for_activation_hooks' ) );

		/** Allow local requests. See {@link wp_http_validate_url()} */
		add_filter( 'http_request_host_is_external', '__return_true' );

		// Adds the Feed to Post settings to the exporting mechanism in the core plugin
		add_filter( 'wprss_fields_export', array( $this, 'add_settings_to_export' ) );
		add_action( 'wprss_export_section', array( $this, 'export_section' ) );

		add_filter( 'wprss_item_import_time_limit', array( $this, 'item_import_time_limit' ) );
		add_filter( 'wprss_feed_fetch_time_limit', array( $this, 'feed_fetch_time_limit' ) );

		add_theme_support( 'post-thumbnails', array('wprss_feed') );

		do_action('wprss_ftp_init', $this);
	}
/**
 * Download an image from the specified URL and attach it to a post.
 *
 * Modified version of core function media_sideload_image() in /wp-admin/includes/media.php
 * (which returns an html img tag instead of attachment ID).
 * Additional functionality: ability override actual filename,
 * and to pass $post_data to override values in wp_insert_attachment (original only allowed $desc).
 *
 * Uses image cache to avoid re-downloading images. Keeps cache intact by
 * creating a copy of the cache file, which will eventually be moved.
 *
 * Credits to somatic
 * http://wordpress.stackexchange.com/questions/30284/media-sideload-image-file-name/44115#44115
 *
 * @since 2.7.4
 *
 * @param string $url (required) The URL of the image to download
 * @param int $post_id (required) The post ID the media is to be associated with
 * @param bool $thumb (optional) Whether to make this attachment the Featured Image for the post (post_thumbnail)
 * @param string $filename (optional) Replacement filename for the URL filename (do not include extension)
 * @param array $post_data (optional) Array of key => values for wp_posts table (ex: 'post_title' => 'foobar', 'post_status' => 'draft')
 * @return int|object The ID of the attachment or a WP_Error on failure
 */
function wprss_ftp_media_sideload_image( $url = null, $post_id = null, $thumb = null, $filename = null, $post_data = array() ) {
	if ( !$url || !$post_id ) {
		return new WP_Error('missing', "Need a valid URL and post ID...");
	}

	// Get the local image file
	$cache = WPRSS_FTP_Images::get_instance()->get_cache();
	try {
		$img = $cache->get_images( $url );
		/* @var $img WPRSS_Image_Cache_Image */
	} catch ( Exception $e ) {
		return new WP_Error( 'could_not_load_image', $e->getMessage(), $url );
	}

	wprss_log_obj('Image from cache', $img->get_url() . ' -> ' . $img->get_local_path(), __METHOD__, WPRSS_LOG_LEVEL_SYSTEM);

	// Get the path
	$tmp = $img->get_local_path();
	copy( $tmp, $tmp = wp_tempnam() ); // media_handle_sideload() will move the file, but we need the cache to remain
	wprss_log( "Copied cached image to $tmp", NULL, WPRSS_LOG_LEVEL_SYSTEM );

	$url_filename = $img->get_unique_name();
	wprss_log( "Unique name $url_filename");

	// override filename if given, reconstruct server path
	if ( !empty( $filename ) ) {
		$filename = sanitize_file_name($filename);
		// extract path parts
		$tmppath = pathinfo( $tmp );
		// build new path
		$new = $tmppath['dirname'] . "/". $filename . "." . $tmppath['extension'];
		// renames temp file on server
		rename($tmp, $new);
		// push new filename (in path) to be used in file array later
		$tmp = $new;
	}

	// determine file type (ext and mime/type)
	$url_type = wp_check_filetype($url_filename);

	// assemble file data (should be built like $_FILES since wp_handle_sideload() will be using)
	$file_array = array( );
	// full server path to temp file
	$file_array['tmp_name'] = $tmp;

	if ( !empty( $filename ) ) {
		// user given filename for title, add original URL extension
		$file_array['name'] = $filename . "." . $url_type['ext'];
	} else {
		// just use original URL filename
		$file_array['name'] = $url_filename;
	}

	// set additional wp_posts columns
	if ( empty( $post_data['post_title'] ) ) {
		// just use the original filename (no extension)
		$post_data['post_title'] = basename($url_filename, "." . $url_type['ext']);
	}

	// make sure gets tied to parent
	if ( empty( $post_data['post_parent'] ) ) {
		$post_data['post_parent'] = $post_id;
	}

	// required libraries for media_handle_sideload
	require_once(ABSPATH . 'wp-admin/includes/file.php');
	require_once(ABSPATH . 'wp-admin/includes/media.php');
	require_once(ABSPATH . 'wp-admin/includes/image.php');

	// NO FILENAME FIX
	// WordPress does not allow file images that are not in the form of a filename
	// ex: http://domain.com/thoufiqadsjucpqwuamoshfjnax8mtrh/iorqhewufjasj

	if ( apply_filters( 'wprss_ftp_override_upload_security', TRUE ) === TRUE ) {
		// If we successfully retrieved the MIME type
		if ( $url_type !== FALSE && isset( $url_type['type'] ) && !empty( $url_type['type'] ) ) {
			// Prepare the MIME and file type
			global $wprss_ftp_ext_override;
			global $wprss_ftp_type_override;
			$wprss_ftp_type_override = $url_type['type'];
			// Get MIME to extension mappings ( from WordPress wp_check_filetype_and_ext() function )
			$mime_to_ext = apply_filters(
				'getimagesize_mimes_to_exts', array(
					'image/jpeg' => 'jpg',
					'image/png'  => 'png',
					'image/gif'  => 'gif',
					'image/bmp'  => 'bmp',
					'image/tiff' => 'tif',
				)
			);
			// Get the ext
			if ( isset( $mime_to_ext[$wprss_ftp_type_override] ) ) {
				$wprss_ftp_ext_override = $mime_to_ext[ $wprss_ftp_type_override ];
			} else {
				$wprss_ftp_ext_override = 'png'; // Default to png (most common web image extension)
			}
			// Add a filter to ensure that the image ext and mime type get passed through
			add_filter( 'wp_check_filetype_and_ext', 'wprss_ftp_mime_override', 10, 4 );
		}
	}

	// do the validation and storage stuff
	clearstatcache( false, $file_array['tmp_name'] ); // For some reason, deep down filesize() returned 0 for the temporary file without this
	$att_id = media_handle_sideload( $file_array, $post_id, '', $post_data ); // $post_data can override the items saved to wp_posts table, like post_mime_type, guid, post_parent, post_title, post_content, post_status

	// If error storing permanently, unlink
	if ( is_wp_error( $att_id ) ) {
		wprss_log( sprintf( 'Error downloading image "%1$s" for post #%2$s: ', $url, $post_id ) . $att_id->get_error_message() );
		$img->delete();
		@unlink( $tmp ); // Delete the cache copy needed for media_handle_sideload()
		return $att_id; // output wp_error
	}

	// set as post thumbnail if desired
	if ( $thumb )
		WPRSS_FTP_Images::set_featured_image( $post_id, $att_id );

	return $att_id;
}