slug = 'archiver'; $this->name = __( 'Archiver', 'archiver' ); } /** * Set up base plugin functionality. * * @since 1.0.0 */ public function run() { // Set up base plugin configuration - run late to ensure post types are already registered. add_action( 'init', array( $this, 'init' ), 999 ); } /** * Check whether or not Archiver can run. * * This function is used to determine whether or not Archiver can run, based * on things like localhost vs production server, etc. * * @since 1.0.0 * * @return bool Whether or not Archiver's base functionality should run. */ public function can_run() { // Check if we're working local, and if that's allowed. if ( ! $this->enable_for_localhost && in_array( $_SERVER['REMOTE_ADDR'], $this->localhost_ips ) ) { return false; } return true; } /** * Initialize basic plugin. * * @since 1.0.0 */ public function init() { // Set up internationalization. $this->set_locale(); // Set up Wayback Machine API endpoints. $this->wayback_machine_url_save = 'https://web.archive.org/save/'; $this->wayback_machine_url_fetch_archives = 'https://web.archive.org/cdx/'; $this->wayback_machine_url_view = 'https://web.archive.org/web/'; /** * Filter default snapshot max count. * * Default: 20 * * @filter archiver_snapshot_max_count */ $this->snapshot_max_count = apply_filters( 'archiver_snapshot_max_count', 20 ); /** * Filter whether to enable on localhost. * * Default: FALSE * * @filter archiver_enable_for_local_host */ $this->enable_for_localhost = apply_filters( 'archiver_enable_for_local_host', __return_false() ); /** * Filter IP's to check against for determining localhost. * * @filter archiver_enable_for_local_host */ $localhost_ips = array( '127.0.0.1', '::1', ); $this->localhost_ips = apply_filters( 'archiver_localhost_ips', $localhost_ips ); // Set up minification prefix. $this->min_suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; // Set up manual archive trigger actions. add_action( 'wp_ajax_archiver_trigger_archive', array( $this, 'ajax_trigger_snapshot' ) ); // Set up dismiss notice functionality. add_action( 'wp_ajax_archiver_dismiss_notice', array( $this, 'ajax_dismiss_notice' ) ); // Register scripts and styles. add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts_and_styles' ), 5 ); add_action( 'admin_enqueue_scripts', array( $this, 'register_scripts_and_styles' ), 5 ); // Enqueue scripts and styles. add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); // Set up functionality that should only run if can_run() == true. if ( $this->can_run() ) { // Set up automated archive trigger actions. add_action( 'save_post', array( $this, 'trigger_post_snapshot' ) ); add_action( 'created_term', array( $this, 'trigger_term_snapshot' ), 10, 3 ); add_action( 'edited_term', array( $this, 'trigger_term_snapshot' ), 10, 3 ); add_action( 'profile_update', array( $this, 'trigger_user_snapshot' ), 10, 3 ); // Add Post Type metaboxes. add_action( 'add_meta_boxes', array( $this, 'add_post_meta_box' ) ); // Add Term metaboxes. add_action( 'admin_init', array( $this, 'add_term_meta_box' ) ); // Add User metabox. add_action( 'admin_init', array( $this, 'add_user_meta_box' ) ); add_action( 'show_user_profile', array( $this, 'output_user_meta_box' ) ); add_action( 'edit_user_profile', array( $this, 'output_user_meta_box' ) ); // Add menu bar links. add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_links' ), 999 ); } else { add_action( 'admin_notices', array( $this, 'do_admin_notice_localhost' ) ); } } /** * Define the locale for this plugin for internationalization. * * @since 1.0.0 */ protected function set_locale() { load_plugin_textdomain( $this->slug, false, dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' ); } /** * Trigger a post snapshot. * * @since 1.0.0 * * @param int $post_id ID of the post to archive. */ public function trigger_post_snapshot( $post_id ) { // Don't do anything if the post isn't published. if ( 'publish' != get_post_status( $post_id ) || wp_is_post_revision( $post_id ) ) { return; } $url = get_permalink( $post_id ); $this->trigger_url_snapshot( $url ); } /** * Trigger a taxonomy term snapshot. * * @since 1.0.0 * * @param int $term_id ID of the taxonomy term to archive. * @param int $taxonomy Taxonomy to which the current term belongs. */ public function trigger_term_snapshot( $term_id, $taxonomy_id, $taxonomy ) { $url = get_term_link( $term_id, $taxonomy ); $this->trigger_url_snapshot( $url ); } /** * Trigger a user snapshot. * * @since 1.0.0 * * @param int $user_id ID of the user to archive. */ public function trigger_user_snapshot( $user_id ) { $url = get_author_posts_url( $user_id ); $this->trigger_url_snapshot( $url ); } /** * Trigger a snapshot via Ajax. * * @since 1.0.0 */ public function ajax_trigger_snapshot() { $nonce_check = check_ajax_referer( 'archiver_ajax_nonce', 'archiver_ajax_nonce', false ); if ( ! $nonce_check ) { wp_send_json_error( __( 'The Ajax nonce check failed.', 'archiver' ) ); } $url = $_REQUEST['url']; $response = $this->trigger_url_snapshot( $url ); $error_codes = $response->get_error_codes(); $error_messages = $response->get_error_messages(); if ( is_wp_error( $response ) ) { wp_send_json_error( $error_codes[0] . ': ' . $error_messages[0] ); } else { wp_send_json_success(); } // End Ajax nicely. wp_die(); } /** * Log dismissed admin notices per-user. * * @since 1.0.0 */ public function ajax_dismiss_notice() { $nonce_check = check_ajax_referer( 'archiver_ajax_nonce', 'archiver_ajax_nonce', false ); if ( ! $nonce_check ) { wp_send_json_error( __( 'The Ajax nonce check failed', 'archiver' ) ); } $notice_key = 'archiver_dismiss_notice_' . $_REQUEST['notice_id']; $current_user_id = get_current_user_id(); if ( ! $current_user_id ) { wp_send_json_error( __( 'There is no current user.', 'archiver' ) ); } else { update_user_meta( $current_user_id, $notice_key, true ); wp_send_json_success( __( 'User meta updated to dismiss notice.', 'archiver' ) ); } // End Ajax nicely. wp_die(); } /** * Trigger a URL to be archived on the Wayback Machine. * * @since 1.0.0 * * @param string $url The URL to archive. * * @return string The link to the newly created archive, if it exists. */ protected function trigger_url_snapshot( $url ) { // Ping archive machine. $wayback_machine_save_url = $this->wayback_machine_url_save . $url; $response = wp_remote_get( $wayback_machine_save_url ); $archive_link = ''; if ( is_wp_error( $response ) ) { return $response; } elseif ( ! empty( $response['headers']['x-archive-wayback-runtime-error'] ) ) { return new WP_Error( 'wayback_machine_error', $response['headers']['x-archive-wayback-runtime-error'], $response ); } elseif ( ! empty( $response['headers']['content-location'] ) ) { return $response['headers']['content-location']; } } /** * Add the archive metabox to posts (and all post types). * * @since 1.0.0 */ public function add_post_meta_box() { /** * Filter post types. */ $post_types = apply_filters( 'archiver_post_types', get_post_types() ); add_meta_box( 'archiver_post', __( 'Archives', 'archiver' ), array( $this, 'output_archiver_metabox' ), $post_types, 'side', 'default' ); } /** * Add the archive metabox to taxonomy terms. * * @since 1.0.0 */ public function add_term_meta_box() { /** * Filter taxonomies. */ $taxonomies = apply_filters( 'archiver_taxonomies', get_taxonomies() ); $archiver_taxonomy_slugs = array_map( create_function( '$taxonomy', 'return "archiver-" . $taxonomy;'), $taxonomies ); add_meta_box( 'archiver_terms', __( 'Archives', 'archiver' ), array( $this, 'output_archiver_metabox' ), $archiver_taxonomy_slugs, 'side', 'default' ); foreach ( $taxonomies as $taxonomy ) { add_action( "{$taxonomy}_edit_form", array( $this, 'output_term_meta_box' ) ); } } /** * Output the archive metabox on taxonomy term screens. * * @since 1.0.0 */ public function output_term_meta_box() { $object_type = get_current_screen()->taxonomy; $this->output_manual_meta_box( $object_type ); } /** * Add the archive metabox to users. * * @since 1.0.0 */ public function add_user_meta_box() { add_meta_box( 'archiver_terms', __( 'Archives', 'archiver' ), array( $this, 'output_archiver_metabox' ), array( 'archiver-user' ), 'side', 'default' ); } /** * Output the archive metabox on user screens. * * @since 1.0.0 */ public function output_user_meta_box() { $this->output_manual_meta_box( 'user' ); } /** * Output a manually created archive metabox (e.g. for terms and users). * * @since 1.0.0 * * @param string $object_type Object type for which to output the metabox. */ public function output_manual_meta_box( $object_type ) { // Enqueue wp_enqueue_script( 'post' ); echo '
%s