<?php
abstract class WPCTP_Admin {
	/**
	 * Name of the page hook when the menu is registered.
	 *
	 * @since 1.8.0
	 *
	 * @var string Page hook
	 */
	public $pagehook;
	/**
	 * ID of the admin menu and settings page.
	 *
	 * @since 1.8.0
	 *
	 * @var string
	 */
	public $page_id;
	/**
	 * Name of the settings field in the options table.
	 *
	 * @since 1.8.0
	 *
	 * @var string
	 */
	public $settings_field;
	/**
	 * Associative array (field name => values) for the default settings on this
	 * admin page.
	 *
	 * @since 1.8.0
	 *
	 * @var array
	 */
	public $default_settings;
	/**
	 * Associative array of configuration options for the admin menu(s).
	 *
	 * @since 1.8.0
	 *
	 * @var array
	 */
	public $menu_ops;
	/**
	 * Associative array of configuration options for the settings page.
	 *
	 * @since 1.8.0
	 *
	 * @var array
	 */
	public $page_ops;
	/**
	 * Call this method in a subclass constructor to create an admin menu and settings page.
	 *
	 * @since 1.8.0
	 *
	 * @param string $page_id ID of the admin menu and settings page
	 * @param array $menu_ops Optional. Config options for admin menu(s). Default is empty array
	 * @param array $page_ops Optional. Config options for settings page. Default is empty array
	 * @param string $settings_field Optional. Name of the settings field. Default is an empty string
	 * @param array $default_settings Optional. Field name => values for default settings. Default is empty array
	 * @return null Return early if page ID is not set
	 */
	public function create( $page_id = '', array $menu_ops = array(), array $page_ops = array(), $settings_field = '', array $default_settings = array() ) {
		//* Set the properties
		$this->page_id          = $this->page_id          ? $this->page_id          : $page_id;
		$this->menu_ops         = $this->menu_ops         ? $this->menu_ops         : (array) $menu_ops;
		$this->page_ops         = $this->page_ops         ? $this->page_ops         : (array) $page_ops;
		$this->settings_field   = $this->settings_field   ? $this->settings_field   : $settings_field;
		$this->default_settings = $this->default_settings ? $this->default_settings : (array) $default_settings;
		$this->page_ops = wp_parse_args(
			$this->page_ops,
			array(
				'save_button_text'  => __( 'Save Settings', 'wpctp' ),
				'reset_button_text' => __( 'Reset Settings', 'wpctp' ),
				'saved_notice_text' => __( 'Settings saved.', 'wpctp' ),
				'reset_notice_text' => __( 'Settings reset.', 'wpctp' ),
				'error_notice_text' => __( 'Error saving settings.', 'wpctp' ),
			)
		);
		//* Do nothing if page_id not set
		if ( ! $this->page_id )
			return;
		//* Check to make sure there we are only creating one menu per subclass
		if ( isset( $this->menu_ops['submenu'] ) && ( isset( $this->menu_ops['main_menu'] ) || isset( $this->menu_ops['first_submenu'] ) ) )
			wp_die( sprintf( __( 'You cannot use %s to create two menus in the same subclass. Please use separate subclasses for each menu.', 'wpctp' ), 'WPCTP_Admin' ) );
		//* Create the menu(s). Conditional logic happens within the separate methods
		add_action( 'admin_menu', array( $this, 'maybe_add_main_menu' ), 5 );
		add_action( 'admin_menu', array( $this, 'maybe_add_first_submenu' ), 5 );
		add_action( 'admin_menu', array( $this, 'maybe_add_submenu' ) );
		//* Set up settings and notices
		add_action( 'admin_init', array( $this, 'register_settings' ) );
		add_action( 'admin_notices', array( $this, 'notices' ) );
		//* Load the page content (metaboxes or custom form)
		add_action( 'admin_init', array( $this, 'settings_init' ) );
		//* Load help tab
		add_action( 'admin_init', array( $this, 'load_help' ) );
		//* Load contextual assets (registered admin page)
		add_action( 'admin_init', array( $this, 'load_assets' ) );
		//* Add a sanitizer/validator
		add_filter( 'pre_update_option_' . $this->settings_field, array( $this, 'save' ), 10, 2 );
	}
	/**
	 * Possibly create a new top level admin menu.
	 *
	 * @since 1.8.0
	 */
	public function maybe_add_main_menu() {
		//* Maybe add a menu separator
		if ( isset( $this->menu_ops['main_menu']['sep'] ) ) {
			$sep = wp_parse_args(
				$this->menu_ops['main_menu']['sep'],
				array(
					'sep_position'   => '',
					'sep_capability' => '',
				)
			);
			if ( $sep['sep_position'] && $sep['sep_capability'] )
				$GLOBALS['menu'][$sep['sep_position']] = array( '', $sep['sep_capability'], 'separator', '', 'genesis-separator wp-menu-separator' );
		}
		//* Maybe add main menu
		if ( isset( $this->menu_ops['main_menu'] ) && is_array( $this->menu_ops['main_menu'] ) ) {
			$menu = wp_parse_args(
				$this->menu_ops['main_menu'],
				array(
					'page_title' => '',
					'menu_title' => '',
					'capability' => 'edit_theme_options',
					'icon_url'   => '',
					'position'   => '',
				)
			);
			$this->pagehook = add_menu_page( $menu['page_title'], $menu['menu_title'], $menu['capability'], $this->page_id, array( $this, 'admin' ), $menu['icon_url'], $menu['position'] );
		}
	}
	/**
	 * Possibly create the first submenu item.
	 *
	 * Because the main menu and first submenu item are usually linked, if you
	 * don't create them at the same time, something can sneak in between the
	 * two, specifically custom post type menu items that are assigned to the
	 * custom top-level menu.
	 *
	 * Plus, maybe_add_first_submenu takes the guesswork out of creating a
	 * submenu of the top-level menu you just created. It's a shortcut of sorts.
	 *
	 * @since 1.8.0
	 */
	public function maybe_add_first_submenu() {
		//* Maybe add first submenu
		if ( isset( $this->menu_ops['first_submenu'] ) && is_array( $this->menu_ops['first_submenu'] ) ) {
			$menu = wp_parse_args(
				$this->menu_ops['first_submenu'],
				array(
					'page_title' => '',
					'menu_title' => '',
					'capability' => 'edit_theme_options',
				)
			);
			$this->pagehook = add_submenu_page( $this->page_id, $menu['page_title'], $menu['menu_title'], $menu['capability'], $this->page_id, array( $this, 'admin' ) );
		}
	}
	/**
	 * Possibly create a submenu item.
	 *
	 * @since 1.8.0
	 */
	public function maybe_add_submenu() {
		//* Maybe add submenu
		if ( isset( $this->menu_ops['submenu'] ) && is_array( $this->menu_ops['submenu'] ) ) {
			$menu = wp_parse_args(
				$this->menu_ops['submenu'],
				array(
					'parent_slug' => '',
					'page_title'  => '',
					'menu_title'  => '',
					'capability'  => 'edit_theme_options',
				)
			);
			$this->pagehook = add_submenu_page( $menu['parent_slug'], $menu['page_title'], $menu['menu_title'], $menu['capability'], $this->page_id, array( $this, 'admin' ) );
		}
	}
	/**
	 * Register the database settings for storage.
	 *
	 * @since 1.8.0
	 *
	 * @return null Return early if not on the correct admin page.
	 */
	public function register_settings() {
		//* If this page doesn't store settings, no need to register them
		if ( ! $this->settings_field )
			return;
		register_setting( $this->settings_field, $this->settings_field );
		add_option( $this->settings_field, $this->default_settings );
		if ( ! wpctp_is_menu_page( $this->page_id ) )
			return;
		if ( wpctp_get_option( 'reset', $this->settings_field ) ) {
			if ( update_option( $this->settings_field, $this->default_settings ) )
				wpctp_admin_redirect( $this->page_id, array( 'reset' => 'true' ) );
			else
				wpctp_admin_redirect( $this->page_id, array( 'error' => 'true' ) );
			exit;
		}
	}
	/**
	 * Display notices on the save or reset of settings.
	 *
	 * @since 1.8.0
	 *
	 * @return null Return early if not on the correct admin page.
	 */
	public function notices() {
		if ( ! wpctp_is_menu_page( $this->page_id ) )
			return;
		if ( isset( $_REQUEST['settings-updated'] ) && 'true' === $_REQUEST['settings-updated'] )
			echo '<div id="message" class="updated"><p><strong>' . $this->page_ops['saved_notice_text'] . '</strong></p></div>';
		elseif ( isset( $_REQUEST['reset'] ) && 'true' === $_REQUEST['reset'] )
			echo '<div id="message" class="updated"><p><strong>' . $this->page_ops['reset_notice_text'] . '</strong></p></div>';
		elseif ( isset( $_REQUEST['error'] ) && 'true' === $_REQUEST['error'] )
			echo '<div id="message" class="updated"><p><strong>' . $this->page_ops['error_notice_text'] . '</strong></p></div>';
	}
	/**
	 * Save method.
	 *
	 * Override this method to modify form data (for validation, sanitization, etc.) before it gets saved.
	 *
	 * @since 1.8.0
	 *
	 * @param string $newvalue
	 * @param string $oldvalue
	 * @return string
	 */
	public function save( $newvalue, $oldvalue ) {
		return $newvalue;
	}
	/**
	 * Initialize the settings page.
	 *
	 * This method must be re-defined in the extended classes, to hook in the
	 * required components for the page.
	 *
	 * @since 1.8.0
	 */
	abstract public function settings_init();
	/**
	 * Load the optional help method, if one exists.
	 *
	 * @since 2.1.0
	 */
	public function load_help() {
		if ( method_exists( $this, 'help' ) ) {
			add_action( "load-{$this->pagehook}", array( $this, 'help' ) );
		}
	}
	/**
	 * Load script and stylesheet assets via scripts() and styles() methods, if they exist.
	 *
	 * @since 2.1.0
	 */
	public function load_assets() {
		//* Hook scripts method
		if ( method_exists( $this, 'scripts' ) ) {
			add_action( "load-{$this->pagehook}", array( $this, 'scripts' ) );
		}
		//* Hook styles method
		if ( method_exists( $this, 'styles' ) ) {
			add_action( "load-{$this->pagehook}", array( $this, 'styles' ) );
		}
	}
	/**
	 * Output the main admin page.
	 *
	 * This method must be re-defined in the extended class, to output the main
	 * admin page content.
	 *
	 * @since 1.8.0
	 */
	abstract public function admin();
	/**
	 * Helper function that constructs name attributes for use in form fields.
	 *
	 * Within Genesis pages, the id attributes of form fields are the same as
	 * the name attribute, as since HTML5, [ and ] characters are valid, so this
	 * function is also used to construct the id attribute value too.
	 *
	 * Other page implementation classes may wish to construct and use a
	 * get_field_id() method, if the naming format needs to be different.
	 *
	 * @since 1.8.0
	 *
	 * @param string $name Field name base
	 * @return string Full field name
	 */
	protected function get_field_name( $name ) {
		return sprintf( '%s[%s]', $this->settings_field, $name );
	}
	/**
	 * Echo constructed name attributes in form fields.
	 *
	 * @since 2.1.0
	 *
	 * @uses WPCTP_Admin:get_field_name() Construct name attributes for use in form fields.
	 *
	 * @param string $name Field name base
	 * @return string Full field name
	 */
	protected function field_name( $name ) {
		echo $this->get_field_name( $name );
	}
	/**
	 * Helper function that constructs id attributes for use in form fields.
	 *
	 * @since 1.8.0
	 *
	 * @param string $id Field id base
	 * @return string Full field id
	 */
	protected function get_field_id( $id ) {
		return sprintf( '%s[%s]', $this->settings_field, $id );
	}
	/**
	 * Echo constructed id attributes in form fields.
	 *
	 * @since 2.1.0
	 *
	 * @uses WPCTP_Admin::get_field_id() Constructs id attributes for use in form fields.
	 *
	 * @param string $id Field id base
	 * @return string Full field id
	 */
	protected function field_id( $id ) {
		echo $this->get_field_id( $id );
	}
	/**
	 * Helper function that returns a setting value from this form's settings
	 * field for use in form fields.
	 *
	 * @since 1.8.0
	 *
	 * @param string $key Field key
	 * @return string Field value
	 */
	protected function get_field_value( $key ) {
		return wpctp_get_option( $key, $this->settings_field );
	}
	/**
	 * Echo a setting value from this form's settings field for use in form fields.
	 *
	 * @uses WPCTP_Admin::get_field_value() Constructs value attributes for use in form fields.
	 *
	 * @since 2.1.0
	 *
	 * @param string $key Field key
	 * @return string Field value
	 */
	protected function field_value( $key ) {
		echo $this->get_field_value( $key );
	}
}
abstract class WPCTP_Admin_Basic extends WPCTP_Admin {
	public function settings_init() {}
}
class WPCTP_Admin_Import_Export extends WPCTP_Admin_Basic {
	/**
	 * Create an admin menu item and settings page.
	 *
	 * Also hook in the handling of file imports and exports.
	 *
	 * @since 1.8.0
	 *
	 * @uses \WPCTP_Admin::create() Create an admin menu item and settings page.
	 *
	 * @see \WPCTP_Admin_Import_Export::export() Handle settings file exports.
	 * @see \WPCTP_Admin_Import_Export::import() Handle settings file imports.
	 */
	public function __construct() {
		$page_id = 'wpctp-import-export';
		$menu_ops = array(
			'submenu' => array(
				'parent_slug' => 'wpctp',
				'page_title'  => __( 'Genesis - Import/Export', 'wpctp' ),
				'menu_title'  => __( 'Import/Export', 'wpctp' )
			)
		);
		$this->create( $page_id, $menu_ops );
		add_action( 'admin_init', array( $this, 'export' ) );
		add_action( 'admin_init', array( $this, 'import' ) );
	}
	/**
	 * Contextual help content.
	 *
	 * @since 2.0.0
	 */
	public function help() {
		$screen = get_current_screen();
		$general_settings_help =
			'<h3>' . __( 'Import/Export', 'wpctp' ) . '</h3>' .
			'<p>'  . __( 'This allows you to import or export Genesis Settings.', 'wpctp' ) . '</p>' .
			'<p>'  . __( 'This is specific to Genesis settings and does not includes posts, pages, or images, which is what the built-in WordPress import/export menu does.', 'wpctp' ) . '</p>' .
			'<p>'  . __( 'It also does not include other settings for plugins, widgets, or post/page/term/user specific settings.', 'wpctp' ) . '</p>';
		$import_settings_help =
			'<h3>' . __( 'Import', 'wpctp' ) . '</h3>' .
			'<p>'  . sprintf( __( 'You can import a file you\'ve previously exported. The file name will start with %s followed by one or more strings indicating which settings it contains, finally followed by the date and time it was exported.', 'wpctp' ), wpctp_code( 'wpctp-' ) ) . '</p>' .
			'<p>' . __( 'Once you upload an import file, it will automatically overwrite your existing settings.', 'wpctp' ) . ' <strong>' . __( 'This cannot be undone', 'wpctp' ) . '</strong>.</p>';
		$export_settings_help =
			'<h3>' . __( 'Export', 'wpctp' ) . '</h3>' .
			'<p>'  . sprintf( __( 'You can export your Genesis-related settings to back them up, or copy them to another site. Child themes and plugins may add their own checkboxes to the list. The settings are exported in %s format.', 'wpctp' ), '<abbr title="' . __( 'JavaScript Object Notation', 'wpctp' ) . '">' . __( 'JSON', 'wpctp' ) . '</abbr>' ) . '</p>';
		$screen->add_help_tab( array(
			'id'      => $this->pagehook . '-general-settings',
			'title'   => __( 'Import/Export', 'wpctp' ),
			'content' => $general_settings_help,
		) );
		$screen->add_help_tab( array(
			'id'      => $this->pagehook . '-import',
			'title'   => __( 'Import', 'wpctp' ),
			'content' => $import_settings_help,
		) );
		$screen->add_help_tab( array(
			'id'      => $this->pagehook . '-export',
			'title'   => __( 'Export', 'wpctp' ),
			'content' => $export_settings_help,
		) );
		//* Add help sidebar
		$screen->set_help_sidebar(
			'<p><strong>' . __( 'For more information:', 'wpctp' ) . '</strong></p>' .
			'<p><a href="http://my.studiopress.com/help/" target="_blank">' . __( 'Get Support', 'wpctp' ) . '<span class="screen-reader-text">. ' . __( 'Link opens in a new window.', 'wpctp' ) . '</span></a></p>' .
			'<p><a href="http://my.studiopress.com/snippets/" target="_blank">' . __( 'Genesis Snippets', 'wpctp' ) . '<span class="screen-reader-text">. ' . __( 'Link opens in a new window.', 'wpctp' ) . '</span></a></p>' .
			'<p><a href="http://my.studiopress.com/tutorials/" target="_blank">' . __( 'Genesis Tutorials', 'wpctp' ) . '<span class="screen-reader-text">. ' . __( 'Link opens in a new window.', 'wpctp' ) . '</span></a></p>'
		);
	}
	/**
	 * Callback for displaying the Genesis Import / Export admin page.
	 *
	 * Call the wpctp_import_export_form action after the last default table row.
	 *
	 * @since 1.4.0
	 *
	 * @uses \WPCTP_Admin_Import_Export::export_checkboxes()  Echo export checkboxes.
	 * @uses \WPCTP_Admin_Import_Export::get_export_options() Get array of export options.
	 */
	public function admin() {
		?>
		<div class="wrap">
			<h2><?php echo esc_html( get_admin_page_title() ); ?></h2>
			<table class="form-table">
				<tbody>
					<tr>
						<th scope="row"><strong><?php _e( 'Import Genesis Settings File', 'wpctp' ); ?></strong></th>
						<td>
							<p><?php printf( __( 'Upload the data file (%s) from your computer and we\'ll import your settings.', 'wpctp' ), wpctp_code( '.json' ) ); ?></p>
							<p><?php _e( 'Choose the file from your computer and click "Upload file and Import"', 'wpctp' ); ?></p>
								<form enctype="multipart/form-data" method="post" action="<?php echo menu_page_url( 'wpctp-import-export', 0 ); ?>">
									<?php wp_nonce_field( 'wpctp-import', 'wpctp-import-nonce' ); ?>
									<input type="hidden" name="wpctp-import" value="1" />
									<label for="wpctp-import-upload"><?php printf( __( 'Upload File (Maximum Size: %s): ', 'wpctp' ), ini_get( 'post_max_size' ) ); ?></label>
									<input type="file" id="wpctp-import-upload" name="wpctp-import-upload" />
									<?php
									submit_button( __( 'Upload File and Import', 'wpctp' ), 'primary', 'upload' );
									?>
								</form>
						</td>
					</tr>
					<tr>
						<th scope="row"><strong><?php _e( 'Export Genesis Settings File', 'wpctp' ); ?></strong></th>
						<td>
							<p><?php printf( __( 'When you click the button below, Genesis will generate a data file (%s) for you to save to your computer.', 'wpctp' ), wpctp_code( '.json' ) ); ?></p>
							<p><?php _e( 'Once you have saved the download file, you can use the import function on another site to import this data.', 'wpctp' ); ?></p>
								<form method="post" action="<?php echo menu_page_url( 'wpctp-import-export', 0 ); ?>">
									<?php
									wp_nonce_field( 'wpctp-export', 'wpctp-export-nonce' );
									$this->export_checkboxes();
									if ( $this->get_export_options() )
										submit_button( __( 'Download Export File', 'wpctp' ), 'primary', 'download' );
									?>
								</form>
						</td>
					</tr>
					<?php do_action( 'wpctp_import_export_form' ); ?>
				</tbody>
			</table>
		</div>
		<?php
	}
	/**
	 * Add custom notices that display after successfully importing or exporting the settings.
	 *
	 * @since 1.4.0
	 *
	 * @uses wpctp_is_menu_page() Check if we're on a Genesis page.
	 *
	 * @return null Return early if not on the correct admin page.
	 */
	public function notices() {
		if ( ! wpctp_is_menu_page( 'wpctp-import-export' ) )
			return;
		if ( isset( $_REQUEST['imported'] ) && 'true' === $_REQUEST['imported'] )
			echo '<div id="message" class="updated" role="alert"><p><strong>' . __( 'Settings successfully imported.', 'wpctp' ) . '</strong></p></div>';
		elseif ( isset( $_REQUEST['error'] ) && 'true' === $_REQUEST['error'] )
			echo '<div id="message" class="error" role="alert"><p><strong>' . __( 'There was a problem importing your settings. Please try again.', 'wpctp' ) . '</strong></p></div>';
	}
	/**
	 * Return array of export options and their arguments.
	 *
	 * Plugins and themes can hook into the wpctp_export_options filter to add
	 * their own settings to the exporter.
	 *
	 * @since 1.6.0
	 *
	 * @return array Export options
	 */
	protected function get_export_options() {
		$options = array(
			'theme' => array(
				'label'          => __( 'Theme Settings', 'wpctp' ),
				'settings-field' => 'wpctp',
			),
			'seo' => array(
				'label' => __( 'SEO Settings', 'wpctp' ),
				'settings-field' => WPCTP_SEO,
			)
		);
		return (array) apply_filters( 'wpctp_export_options', $options );
	}
	/**
	 * Echo out the checkboxes for the export options.
	 *
	 * @since 1.6.0
	 *
	 * @uses \WPCTP_Admin_Import_Export::get_export_options() Get array of export options.
	 *
	 * @return null Return null if there are no options to export.
	 */
	protected function export_checkboxes() {
		if ( ! $options = $this->get_export_options() ) {
			//* Not even the Genesis theme / seo export options were returned from the filter
			printf( '<p><em>%s</em></p>', __( 'No export options available.', 'wpctp' ) );
			return;
		}
		foreach ( $options as $name => $args ) {
			//* Ensure option item has an array key, and that label and settings-field appear populated
			if ( is_int( $name ) || ! isset( $args['label'] ) || ! isset( $args['settings-field'] ) || '' === $args['label'] || '' === $args['settings-field'] )
				return;
			printf( '<p><label for="wpctp-export-%1$s"><input id="wpctp-export-%1$s" name="wpctp-export[%1$s]" type="checkbox" value="1" /> %2$s</label></p>', esc_attr( $name ), esc_html( $args['label'] ) );
		}
	}
	/**
	 * Generate the export file, if requested, in JSON format.
	 *
	 * After checking we're on the right page, and trying to export, loop through the list of requested options to
	 * export, grabbing the settings from the database, and building up a file name that represents that collection of
	 * settings.
	 *
	 * A .json file is then sent to the browser, named with "genesis" at the start and ending with the current
	 * date-time.
	 *
	 * The wpctp_export action is fired after checking we can proceed, but before the array of export options are
	 * retrieved.
	 *
	 * @since 1.4.0
	 *
	 * @uses wpctp_is_menu_page()                             Check if we're on a Genesis page.
	 * @uses \WPCTP_Admin_Import_Export::get_export_options() Get array of export options.
	 *
	 * @return null Return null if not correct page, or we're not exporting.
	 */
	public function export() {
		if ( ! wpctp_is_menu_page( 'wpctp-import-export' ) )
			return;
		if ( empty( $_REQUEST['wpctp-export'] ) )
			return;
		check_admin_referer( 'wpctp-export', 'wpctp-export-nonce' );
		do_action( 'wpctp_export', $_REQUEST['wpctp-export'] );
		$options = $this->get_export_options();
		$settings = array();
		//* Exported file name always starts with "genesis"
		$prefix = array( 'wpctp' );
		//* Loop through set(s) of options
		foreach ( (array) $_REQUEST['wpctp-export'] as $export => $value ) {
			//* Grab settings field name (key)
			$settings_field = $options[$export]['settings-field'];
			//* Grab all of the settings from the database under that key
			$settings[$settings_field] = get_option( $settings_field );
			//* Add name of option set to build up export file name
			$prefix[] = $export;
		}
		if ( ! $settings )
			return;
		//* Complete the export file name by joining parts together
		$prefix = join( '-', $prefix );
	    $output = wp_json_encode( (array) $settings );
		//* Prepare and send the export file to the browser
	    header( 'Content-Description: File Transfer' );
	    header( 'Cache-Control: public, must-revalidate' );
	    header( 'Pragma: hack' );
	    header( 'Content-Type: text/plain' );
	    header( 'Content-Disposition: attachment; filename="' . $prefix . '-' . date( 'Ymd-His' ) . '.json"' );
	    header( 'Content-Length: ' . mb_strlen( $output ) );
	    echo $output;
	    exit;
	}
	/**
	 * Handle the file uploaded to import settings.
	 *
	 * Upon upload, the file contents are JSON-decoded. If there were errors, or no options to import, then reload the
	 * page to show an error message.
	 *
	 * Otherwise, loop through the array of option sets, and update the data under those keys in the database.
	 * Afterwards, reload the page with a success message.
	 *
	 * Calls wpctp_import action is fired after checking we can proceed, but before attempting to extract the contents
	 * from the uploaded file.
	 *
	 * @since 1.4.0
	 *
	 * @uses wpctp_is_menu_page()   Check if we're on a Genesis page
	 * @uses wpctp_admin_redirect() Redirect user to an admin page
	 *
	 * @return null Return null if not correct admin page, we're not importing
	 */
	public function import() {
		if ( ! wpctp_is_menu_page( 'wpctp-import-export' ) )
			return;
		if ( empty( $_REQUEST['wpctp-import'] ) )
			return;
		check_admin_referer( 'wpctp-import', 'wpctp-import-nonce' );
		do_action( 'wpctp_import', $_REQUEST['wpctp-import'], $_FILES['wpctp-import-upload'] );
		$upload = file_get_contents( $_FILES['wpctp-import-upload']['tmp_name'] );
		$options = json_decode( $upload, true );
		//* Check for errors
		if ( ! $options || $_FILES['wpctp-import-upload']['error'] ) {
			wpctp_admin_redirect( 'wpctp-import-export', array( 'error' => 'true' ) );
			exit;
		}
		//* Identify the settings keys that we should import
		$exportables = $this->get_export_options();
		$importable_keys = array();
		foreach ( $exportables as $exportable ) {
			$importable_keys[] = $exportable['settings-field'];
		}
		//* Cycle through data, import Genesis settings
		foreach ( (array) $options as $key => $settings ) {
			if ( in_array( $key, $importable_keys ) )
				update_option( $key, $settings );
		}
		//* Redirect, add success flag to the URI
		wpctp_admin_redirect( 'wpctp-import-export', array( 'imported' => 'true' ) );
		exit;
	}
}
new WPCTP_Admin_Import_Export;