. * * @copyright 2008-2012 * @license GPL v3 * @version 2.6.2 * @package Infinite Scroll * @author Beaver6813, dirkhaim, Paul Irish, Benjamin J. Balter, Glenn Nelson */ require_once dirname( __FILE__ ) . '/includes/options.php'; require_once dirname( __FILE__ ) . '/includes/admin.php'; require_once dirname( __FILE__ ) . '/includes/presets.php'; require_once dirname( __FILE__ ) . '/includes/submit.php'; class Infinite_Scroll { static $instance; public $options; public $admin; public $submit; public $name = 'Infinite Scroll'; //Human-readable name of plugin public $slug = 'infinite-scroll'; //plugin slug, generally base filename and in url on wordpress.org public $slug_ = 'infinite_scroll'; //slug with underscores (PHP/JS safe) public $prefix = 'infinite_scroll_'; //prefix to append to all options, API calls, etc. w/ trailing underscore public $file = null; public $version = '2.6.1'; public $behaviors = array( //array of behaviors as key => array( label => js file ) (without extension) 'twitter' => array( 'label' => 'Manual Trigger', 'src' => 'manual-trigger' ), 'local' => array( 'label' => 'Local', 'src' => 'local' ), 'cufon' => array( 'label' => 'Cufon', 'src' => 'cufon' ), 'masonry' => array( 'label' => 'Masonry/Isotope', 'src' => 'masonry-isotope') ); /** * Construct the primary class and auto-load all child classes */ function __construct() { self::$instance = &$this; $this->file = __FILE__; $this->admin = new Infinite_Scroll_Admin( $this ); $this->options = new Infinite_Scroll_Options( $this ); $this->presets = new Infinite_Scroll_Presets( $this ); $this->submit = new Infinite_Scroll_Submit( $this ); //upgrade db add_action( 'admin_init', array( &$this, 'upgrade_check' ) ); //i18n add_action( 'init', array( &$this, 'i18n' ) ); //default options add_action( 'init', array( &$this, 'init_defaults' ) ); //js add_action( 'wp_enqueue_scripts', array( &$this, 'enqueue_js' ) ); add_action( 'wp_footer', array( &$this, 'footer' ), 100 ); //low priority will load after i18n and script loads //preset cron register_activation_hook( __FILE__, array( &$this->presets, 'schedule' ) ); register_deactivation_hook( __FILE__, array( &$this->presets, 'unschedule' ) ); //404 fix add_action( 'wp', array( &$this, 'paged_404_fix' ) ); } /** * Init default options */ function init_defaults() { //option keys map to javascript options and are passed directly via wp_localize_script $this->options->defaults = array( 'loading' => array( 'msgText' => '' . __( 'Loading...', 'infinite-scroll' ) . '', 'finishedMsg' => '' . __( 'No additional posts.', 'infinite-scroll' ) . '', 'img' => plugins_url( 'img/ajax-loader.gif', __FILE__ ) ), 'nextSelector' => '#nav-below a:first', 'navSelector' => '#nav-below', 'itemSelector' => '.post', 'contentSelector' => '#content', 'debug' => WP_DEBUG, 'behavior' => '' ); } /** * Enqueue front-end JS and pass options to json_encoded array */ function enqueue_js() { if (!$this->shouldLoadJavascript()) { return; } $suffix = ( WP_DEBUG ) ? '.dev' : ''; $file = "/js/front-end/jquery.infinitescroll{$suffix}.js"; wp_enqueue_script( $this->slug, plugins_url( $file, __FILE__ ), array( 'jquery' ), $this->version, true ); $options = apply_filters( $this->prefix . 'js_options', $this->options->get_options() ); wp_localize_script($this->slug, $this->slug_, json_encode($options)); // If no behavior, we're done, kick if ( !$options['behavior'] ) return; //sanity check if ( !array_key_exists( $options['behavior'], $this->behaviors ) ) return _doing_it_wrong( 'Infinite Scroll behavior', "Behavior {$options['behavior']} not found", $this->version ); $src = 'behaviors/' . $this->behaviors[ $options['behavior'] ]['src'] . '.js'; wp_enqueue_script( $this->slug . "-behavior", plugins_url( $src, __FILE__ ), array( "jquery", $this->slug ), $this->version, true ); } /** * Load footer template to pass options array to JS */ function footer() { if (!$this->shouldLoadJavascript()) { return; } require dirname( __FILE__ ) . '/templates/footer.php'; } /** * Init i18n files */ function i18n() { load_plugin_textdomain( $this->slug, false, plugin_basename( dirname( __FILE__ ) ) . '/languages/' ); } /** * Upgrades DB * Fires on admin init to support SVN */ function upgrade_check() { if ($this->options->db_version == $this->version) { return; } $this->upgrade( $this->options->db_version, $this->version ); do_action( $this->prefix . 'upgrade', $this->version, $this->options->db_version ); $this->options->db_version = $this->version; } /** * Upgrade DB to latest version * @param int $from version coming from * @param int $to version going to */ function upgrade( $from , $to ) { if ($from < "2.5") { //array of option conversions in the form of from => to $map = array( 'js_calls' => 'callback', 'image' => 'img', 'text' => 'msgText', 'donetext' => 'finishedMsg', 'content_selector' => 'contentSelector', 'post_selector' => 'itemSelector', 'nav_selector' => 'navSelector', 'next_selector' => 'nextSelector', 'behavior' => 'behavior', 'debug' => 'debug', ); $old = get_option( 'infscr_options' ); $new = array(); //really old legacy options storage //each option is stored as its own option in the options table if ( !$old ) { //loop through options and attempt to find foreach ( array_keys( $map ) as $option ) { $legacy = get_option( 'infscr_' . $option ); if ( !$legacy ) continue; //move to new option array and delete old $new[ $map[ $option ] ] = $legacy; delete_option( 'infscr_' . $option ); } } //pre 2.5 options storage //all stuffed in a single array, but not properly keyed foreach ( $map as $from => $to ) { if ( !$old || !isset( $old[ 'infscr_' . $from ] ) ) continue; $new[ $to ] = $old[ 'infscr_' . $from ]; } //pre 2.5 we html encoded selectors, we don't do this anymore foreach ( array( 'contentSelector', 'itemSelector', 'navSelector', 'nextSelector' ) as $field ) { if ( isset( $new[$field] ) ) { $new[$field] = html_entity_decode($new[$field]); } } //regardless of which upgrade we did, move loading string to array $new['loading'] = array( ); foreach ( array( 'finishedMsg', 'msgText', "img" ) as $field ) { if ( isset( $new[$field] ) ) { $new['loading'][$field] = $new[$field]; unset( $new[$field] ); } } //if the user is still using the default ajax-loader.gif then update the location if( isset($new["loading"]['img']) && !strstr($new["loading"]["img"], "/img/ajax-loader.gif") ) $new["loading"]['img'] = str_replace("/ajax-loader.gif", "/img/ajax-loader.gif", $new["loading"]['img']); //regardless of which upgrade, ensure that debug is now set to boolean string rather than int //if it wasn't originally on then just set it to the plugin default if( isset($new['debug']) && $new['debug'] == 1 ) $new['debug'] = "true"; else unset( $new['debug'] ); //don't pass an empty array so the default filter can properly set defaults if ( empty( $new['loading'] ) ) unset( $new['loading'] ); $this->options->set_options( $new ); delete_option( 'infscr_options' ); $this->presets->migrate(); } //migrate loading image if ($from < '2.6') { $old = get_option("infinite_scroll"); $new = $old; $new["loading"]["img"] = $old["img"]; unset($new["img"]); $this->options->set_options($new); } } /** * If we go beyond the last page and request a page that doesn't exist, * force WordPress to return a 404. * See http://core.trac.wordpress.org/ticket/15770 */ function paged_404_fix( ) { global $wp_query; if ( is_404() || !is_paged() || 0 != count( $wp_query->posts ) ) return; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } /** * Determines if the jQuery plugin and corresponding options should * be output onto the page. * * @return bool */ function shouldLoadJavascript() { // Don't need to load the plugin on single pages if (is_singular()) { return false; } return true; } } $infinite_scroll = new Infinite_Scroll();