Initial commit
This commit is contained in:
commit
28e6ddf404
1083 changed files with 191734 additions and 0 deletions
126
plugins/infinite-scroll/includes/admin.php
Normal file
126
plugins/infinite-scroll/includes/admin.php
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
/**
|
||||
* Infinite Scroll Administrative Backend
|
||||
* @subpackage Admin
|
||||
* @package Infinite_Scroll
|
||||
*/
|
||||
|
||||
class Infinite_Scroll_Admin {
|
||||
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* Register hooks with WordPress API
|
||||
* @param class $parent (reference) the Parent Class
|
||||
*/
|
||||
function __construct( &$parent ) {
|
||||
|
||||
$this->parent = &$parent;
|
||||
|
||||
add_action( 'admin_menu', array( &$this, 'options_menu_init' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue' ) );
|
||||
|
||||
//upload helers
|
||||
add_filter( 'get_media_item_args', array( &$this, 'send_to_editor'), 10, 1);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register our menu with WordPress
|
||||
*/
|
||||
function options_menu_init() {
|
||||
add_options_page( __( 'Infinite Scroll Options', 'infinite-scroll' ), __( 'Infinite Scroll', 'infinite-scroll' ), 'manage_options', 'infinite_scroll_options', array( &$this, 'options' ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback to load options template
|
||||
*/
|
||||
function options() {
|
||||
|
||||
//toggle presets page
|
||||
$file = isset( $_GET['manage-presets'] ) ? 'manage-presets' : 'options';
|
||||
$file = isset( $_GET['submit'] ) ? 'submit' : $file;
|
||||
|
||||
require dirname( $this->parent->file ) . '/templates/' . $file . '.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin JS on options page
|
||||
*/
|
||||
function admin_enqueue() {
|
||||
|
||||
if ( get_current_screen()->id != 'settings_page_infinite_scroll_options' && !defined( 'IFRAME_REQUEST' ) )
|
||||
return;
|
||||
|
||||
$suffix = ( WP_DEBUG || SCRIPT_DEBUG ) ? '.dev' : '';
|
||||
$file = "/js/admin/infinite-scroll{$suffix}.js";
|
||||
|
||||
wp_enqueue_script( $this->parent->slug, plugins_url( $file, $this->parent->file ), array( 'jquery', 'media-upload', 'thickbox' ), $this->parent->version, true );
|
||||
wp_enqueue_style('thickbox');
|
||||
|
||||
wp_localize_script( $this->parent->slug, $this->parent->slug_, array( 'confirm' => __( 'Are you sure you want to delete the preset "%s"?', 'infinite-scroll' ) ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* If image is sucessfully uploaded, automatically close the editor
|
||||
* and store the image URL in the image input
|
||||
* @param array $args the default args
|
||||
* @return array the original args, unmodified
|
||||
* @uses media_send_to_editor()
|
||||
& @uses send_to_editor() (javascript)
|
||||
*/
|
||||
function send_to_editor( $args ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( $args['errors'] !== null )
|
||||
return $args;
|
||||
|
||||
if ( isset( $_GET['attachment_id'] ) ) {
|
||||
|
||||
$id = $_GET['attachment_id'];
|
||||
|
||||
//workaround for WP 3.2 non-flash upload
|
||||
//not ideal, but works for an edge case
|
||||
} else {
|
||||
|
||||
//because we can't get the attachment ID at this point, try to pull it from the database
|
||||
//look for the most recent parent-less attachment with same title and mime-type
|
||||
$upload = $GLOBALS['HTTP_POST_FILES']['async-upload'];
|
||||
$title = substr( $upload['name'], 0, strrpos( $upload['name'], '.' ) );
|
||||
$id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type = '" . $upload['type'] . "' AND post_parent = '0' AND post_title = '$title' ORDER BY ID DESC LIMIT 1" );
|
||||
|
||||
//if for some reason we couldn't pull the ID, simply kick
|
||||
//the user will just have to click insert to close the dialog
|
||||
if ( !$id )
|
||||
return $args;
|
||||
|
||||
}
|
||||
|
||||
//rely on WordPress's internal function to output script tags and call send_to_editor()
|
||||
media_send_to_editor( wp_get_attachment_url( $id ) );
|
||||
|
||||
return $args;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function to load the tinyMCE Editor
|
||||
* Used to allow fallback to pre-3.3 function
|
||||
* @param string $field the field to load the editor for
|
||||
*/
|
||||
function editor( $field ) {
|
||||
|
||||
//3.3
|
||||
if ( function_exists( 'wp_editor' ) )
|
||||
wp_editor( $this->parent->options->loading[ $field ], "infinite_scroll[loading][{$field}]", array( 'media_buttons' => false, 'textarea_rows' => 5, 'teeny' => true ) );
|
||||
|
||||
//3.2
|
||||
else
|
||||
the_editor( $this->parent->options->loading[ $field ], "infinite_scroll[loading][{$field}]", null, false );
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
191
plugins/infinite-scroll/includes/options.php
Normal file
191
plugins/infinite-scroll/includes/options.php
Normal file
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
/**
|
||||
* Provides interface to store and retrieve plugin and user options
|
||||
* @subpackage Infinite_Scroll_Options
|
||||
* @package Infinite_Scroll
|
||||
*/
|
||||
class Infinite_Scroll_Options {
|
||||
|
||||
//default scope for options when called directly,
|
||||
//choices: site, user, or global (user option across sites)
|
||||
public $defaults = array();
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* Stores parent class as static
|
||||
* @param class $parent (reference) the parent class
|
||||
*/
|
||||
function __construct( &$parent ) {
|
||||
|
||||
$this->parent = &$parent;
|
||||
|
||||
add_action( 'admin_init', array( &$this, 'options_init' ) );
|
||||
add_filter( $this->parent->prefix . 'options', array( &$this, 'default_options_filter' ), 20 );
|
||||
add_filter( $this->parent->prefix . 'js_options', array( &$this, 'db_version_filter' ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells WP that we're using a custom settings field
|
||||
*/
|
||||
function options_init() {
|
||||
|
||||
register_setting( $this->parent->slug_, $this->parent->slug_, array( &$this, 'validate' ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs options through filter prior to saving
|
||||
* @param array $options the options array
|
||||
* @return array sanitized options array
|
||||
*/
|
||||
function validate( $options ) {
|
||||
|
||||
//add slashes to JS selectors
|
||||
$js = array ( 'nextSelector', 'navSelector', 'itemSelector', 'contentSelector' );
|
||||
foreach ( $js as $field ) {
|
||||
|
||||
if ( !isset( $options[$field] ) )
|
||||
continue;
|
||||
|
||||
$options[$field] = addslashes( $options[ $field ] );
|
||||
|
||||
}
|
||||
|
||||
//force post-style kses on messages
|
||||
foreach ( array( 'finishedMsg', 'msgText' ) as $field ) {
|
||||
|
||||
if ( !isset( $options['loading'][$field] ) )
|
||||
continue;
|
||||
|
||||
// wp_filter_post_kses will add slashes to something like "you've" -> "you\'ve" but not added slashes to other slashes
|
||||
// Escaping the slashes and then stripping them, gets past this problem and allows preservation of intentionally inserted slashes
|
||||
$options['loading'][$field] = stripslashes(wp_filter_post_kses( addslashes($options['loading'][$field] )));
|
||||
}
|
||||
|
||||
//handle image resets
|
||||
if ( isset( $_POST[ 'reset_default_image'] ) )
|
||||
$options["loading"]['img'] = $this->defaults["loading"]['img'];
|
||||
|
||||
//pull existing image if none is given
|
||||
if ( empty( $options["loading"]['img'] ) )
|
||||
$options["loading"]['img'] = $this->loading["img"];
|
||||
|
||||
// force `debug` to be a bool
|
||||
$options["debug"] = (bool)$options["debug"];
|
||||
|
||||
return apply_filters( $this->parent->prefix . 'options_validate', $options );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allows overloading to get option value
|
||||
* Usage: $value = $object->{option name}
|
||||
* @param string $name the option name
|
||||
* @return mixed the option value
|
||||
*/
|
||||
function __get( $name ) {
|
||||
|
||||
return $this->get_option( $name );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allows overloading to set option value
|
||||
* Usage: $object->{option name} = $value
|
||||
* @param string $name unique option key
|
||||
* @param mixed $value the value to store
|
||||
* @return bool success/fail
|
||||
*/
|
||||
function __set( $name, $value ) {
|
||||
|
||||
return $this->set_option( $name, $value );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retreive the options array
|
||||
* @return array the options
|
||||
*/
|
||||
function get_options( ) {
|
||||
|
||||
if ( !$options = wp_cache_get( 'options', $this->parent->slug ) ) {
|
||||
$options = get_option( $this->parent->slug_ );
|
||||
wp_cache_set( 'options', $options, $this->parent->slug );
|
||||
}
|
||||
|
||||
return apply_filters( $this->parent->prefix . 'options', $options );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If any options are not set, merge with defaults
|
||||
* @param array $options the saved options
|
||||
* @return array the merged options with defaults
|
||||
*/
|
||||
function default_options_filter( $options ) {
|
||||
|
||||
$options = wp_parse_args( $options, $this->defaults );
|
||||
wp_cache_set( 'options', $options, $this->parent->slug );
|
||||
return $options;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retreives a specific option
|
||||
* @param string $option the unique option key
|
||||
* @return mixed the value
|
||||
*/
|
||||
function get_option( $option ) {
|
||||
$options = $this->get_options( );
|
||||
$value = ( isset( $options[ $option ] ) ) ? $options[ $option ] : false;
|
||||
return apply_filters( $this->parent->prefix . $option, $value );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a specific option
|
||||
* @return bool success/fail
|
||||
* @param string $key the unique option key
|
||||
* @param mixed $value the value
|
||||
*/
|
||||
function set_option( $key, $value ) {
|
||||
$options = array( $key => $value );
|
||||
$this->set_options( $options );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets all plugin options
|
||||
* @param array $options the options array
|
||||
* @param bool $merge (optional) whether or not to merge options arrays or overwrite
|
||||
* @return bool success/fail
|
||||
*/
|
||||
function set_options( $options, $merge = true ) {
|
||||
|
||||
if ( $merge ) {
|
||||
$defaults = $this->get_options();
|
||||
$options = wp_parse_args( $options, $defaults );
|
||||
}
|
||||
|
||||
wp_cache_set( 'options', $options, $this->parent->slug );
|
||||
|
||||
return update_option( $this->parent->slug_, $options );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't output db_version to front end when passing args to javascript function
|
||||
*/
|
||||
function db_version_filter( $options ) {
|
||||
unset( $options['db_version'] );
|
||||
return $options;
|
||||
}
|
||||
|
||||
}
|
759
plugins/infinite-scroll/includes/presets.php
Normal file
759
plugins/infinite-scroll/includes/presets.php
Normal file
|
@ -0,0 +1,759 @@
|
|||
<?php
|
||||
/**
|
||||
* Infinite Scroll Presets Interface
|
||||
*
|
||||
* Stores theme-specific presets for CSS Selectors to aid with setup. Pulls community presets from CSV
|
||||
* stored in the plugin's SVN repo.
|
||||
*
|
||||
* The csv from the repo is cached for 24 hours as a site-transient (available to all sites on a network install)
|
||||
*
|
||||
* Custom presets (beyond the SVN CSV) are stored as a site option (also available to all sites on network)
|
||||
*
|
||||
* On a single site install, settings available to all admins.
|
||||
* On a network install, settings available only to super-admins (but site-admins can load those presets)
|
||||
*
|
||||
* If a user hasn't chosen CSS selectors for there theme and a preset exists, the plugin will
|
||||
* default to the preset (thus in many cases, no need to adjust any settings or know this exists).
|
||||
*
|
||||
* Hierarchy of presets: 1) User specified, 2) (admin specified) custom preset, 3) community specified preset
|
||||
*
|
||||
* @subpackage Presets
|
||||
* @package Infinite_Scroll
|
||||
*/
|
||||
|
||||
require_once(ABSPATH . "/wp-admin/includes/theme.php");
|
||||
|
||||
class Infinite_Scroll_Presets {
|
||||
|
||||
private $parent;
|
||||
// public $preset_url = 'http://plugins.svn.wordpress.org/infinite-scroll/branches/PresetDB/presets.csv';
|
||||
public $preset_url = 'https://raw.github.com/benbalter/Infinite-Scroll/presetDB/presets.csv';
|
||||
public $custom_preset_key = 'infinite_scroll_presets';
|
||||
public $ttl = 86000; //TTL of transient cache in seconds, 1 day = 86400 = 60*60*24
|
||||
public $keys = array( 'theme', 'contentSelector', 'navSelector', 'itemSelector', 'nextSelector' );
|
||||
|
||||
/**
|
||||
* Register hooks with WordPress API
|
||||
*
|
||||
* @param object $parent (reference) the parent class
|
||||
*/
|
||||
function __construct( &$parent ) {
|
||||
|
||||
$this->parent = &$parent;
|
||||
|
||||
add_action( 'admin_init', array( &$this, 'set_presets' ) );
|
||||
add_action( 'wp_ajax_infinite-scroll-edit-preset', array( &$this, 'process_ajax_edit' ) );
|
||||
add_action( 'wp_ajax_infinite-scroll-delete-preset', array( &$this, 'process_ajax_delete' ) );
|
||||
add_filter( $this->parent->prefix . 'presets', array( &$this, 'merge_custom_presets' ) );
|
||||
add_filter( $this->parent->prefix . 'options', array( &$this, 'default_to_presets'), 9 );
|
||||
add_action( $this->parent->prefix . 'refresh_cache', array( &$this, 'get_presets' ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allow for class overloading
|
||||
* @param string $preset the theme slug to retrieve
|
||||
* @return array|bool the presets or false on failure
|
||||
*/
|
||||
function __get( $preset ) {
|
||||
return $this->get_preset( $preset );
|
||||
}
|
||||
|
||||
function getThemes($args) {
|
||||
if (function_exists("wp_get_themes")) {
|
||||
return wp_get_themes($args);
|
||||
} else {
|
||||
return get_themes();
|
||||
}
|
||||
}
|
||||
|
||||
function getTheme($theme) {
|
||||
if (function_exists("wp_get_theme")) {
|
||||
return wp_get_theme($theme);
|
||||
} else {
|
||||
return get_theme($theme);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pulls preset array from cache, or retrieves and parses
|
||||
* @return array an array of preset objects
|
||||
* @todo Consider using TLC Transients in case cron isn't working
|
||||
*/
|
||||
function get_presets() {
|
||||
|
||||
//check cache
|
||||
if ( $cache = get_transient( $this->parent->prefix . 'presets' ) )
|
||||
return apply_filters( $this->parent->prefix . 'presets', $cache );
|
||||
|
||||
$data = wp_remote_get( $this->preset_url );
|
||||
|
||||
if ( is_wp_error( $data ) )
|
||||
return array();
|
||||
|
||||
$data = wp_remote_retrieve_body( $data );
|
||||
|
||||
//parse CSV string into array
|
||||
$presets = $this->parse_csv( $data );
|
||||
|
||||
//sort by key alpha ascending
|
||||
asort( $presets );
|
||||
|
||||
set_transient( $this->parent->prefix . 'presets', $presets, $this->ttl );
|
||||
|
||||
return apply_filters( $this->parent->prefix . 'presets', $presets );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a theme's preset object
|
||||
* @param string $theme the slug of theme to retrieve
|
||||
* @return object the preset object
|
||||
*/
|
||||
function get_preset( $theme = null ) {
|
||||
|
||||
if ( $theme == null )
|
||||
$theme = get_stylesheet();
|
||||
|
||||
$presets = $this->get_presets();
|
||||
|
||||
//direct match found, return
|
||||
if ( array_key_exists( $theme, $presets ) )
|
||||
return $presets[ $theme ];
|
||||
|
||||
//no direct match found, permahps this is a child theme?
|
||||
|
||||
//theme isn't installed, no way to know if it's a child, so skip
|
||||
if ( !$this->theme_installed( $theme ) )
|
||||
return false;
|
||||
|
||||
//WP version 3.4+, use the new wp_get_themes function
|
||||
if ( function_exists( 'wp_get_theme' ) ) {
|
||||
|
||||
$theme = $this->getTheme($theme);
|
||||
|
||||
//not a theme or not a child
|
||||
if ( is_wp_error( $theme ) || !is_object( $theme->parent() ) )
|
||||
return false;
|
||||
|
||||
return $this->get_preset( $theme->parent()->stylesheet );
|
||||
|
||||
}
|
||||
|
||||
//pre 3.4 back compat..
|
||||
//get theme by slug
|
||||
$name = $this->get_name( $theme );
|
||||
$themes = $this->getThemes(array());
|
||||
$child = $themes[ $name ];
|
||||
|
||||
//not a child theme
|
||||
if ( !isset( $child['Template'] ) || empty( $child['Template'] ) || $child['Template'] == $child['Stylesheet'] )
|
||||
return false;
|
||||
|
||||
//pull up parent data to get its name
|
||||
$parent = $themes[$name]['Template'];
|
||||
$parent = get_theme_data( get_theme_root( $child['Template'] ) . '/' . $child['Template'] . '/style.css' );
|
||||
$preset = $this->get_preset( $parent['Stylesheet'] );
|
||||
|
||||
//no parent preset
|
||||
if ( !$preset )
|
||||
return false;
|
||||
|
||||
//rename the theme of the parent preset object for consistent return
|
||||
$preset->theme = $theme;
|
||||
$preset->parentPreset = $parent['Stylesheet'];
|
||||
|
||||
return $preset;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* On plugin activation register with WP_Cron API to asynchronously refresh cache every 24 hours
|
||||
* This will also asynchronously prime the cache on activation
|
||||
*/
|
||||
function schedule() {
|
||||
wp_schedule_event( time(), 'daily', $this->parent->prefix . 'refresh_cache' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear chron schedule on deactivation
|
||||
*/
|
||||
function unschedule() {
|
||||
wp_clear_scheduled_hook( $this->parent->prefix . 'refresh_cache' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Conditionally prompts users on options page to use the default selectors
|
||||
* @uses get_preset
|
||||
*/
|
||||
function preset_prompt() {
|
||||
|
||||
$preset = $this->get_preset( );
|
||||
|
||||
if ( !$preset )
|
||||
return;
|
||||
|
||||
unset( $preset->theme );
|
||||
unset( $preset->parentPreset );
|
||||
|
||||
//if they are already using the preset, don't prompt
|
||||
$using_default = true;
|
||||
foreach ( $preset as $key => $value ) {
|
||||
|
||||
if ( $this->parent->options->$key != $value )
|
||||
$using_default = false;
|
||||
|
||||
}
|
||||
|
||||
if ( $using_default )
|
||||
return;
|
||||
|
||||
require dirname( $this->parent->file ) . '/templates/preset-prompt.php';
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset selectors to default
|
||||
*/
|
||||
function set_presets() {
|
||||
|
||||
if ( !isset( $_GET['set_presets'] ) )
|
||||
return;
|
||||
|
||||
if ( !current_user_can( 'manage_options' ) )
|
||||
return;
|
||||
|
||||
check_admin_referer( 'infinite-scroll-presets', 'nonce' );
|
||||
|
||||
//don't delete options if we don't have a preset
|
||||
$preset = $this->get_preset( );
|
||||
|
||||
if ( !$preset )
|
||||
return;
|
||||
|
||||
foreach ( $this->keys as $key )
|
||||
$this->parent->options->$key = null;
|
||||
|
||||
wp_redirect( admin_url( 'options-general.php?page=infinite_scroll_options&settings-updated=true' ) );
|
||||
exit();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles AJAX edits from the manage presets form
|
||||
*/
|
||||
function process_ajax_edit() {
|
||||
|
||||
if ( !current_user_can( 'manage_options' ) )
|
||||
wp_die( -1 );
|
||||
|
||||
if ( is_multisite() && !is_super_admin() )
|
||||
wp_die( -1 );
|
||||
|
||||
$data = new stdClass;
|
||||
|
||||
foreach ( $this->keys as $key )
|
||||
$data->$key = addslashes( trim( $_POST[ $key . '_column-' . $key ] ) );
|
||||
|
||||
$this->set_custom_preset( $data->theme, $data );
|
||||
|
||||
wp_die( 1 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles AJAX requests to delete presets from the manage presets form
|
||||
*/
|
||||
function process_ajax_delete() {
|
||||
|
||||
if ( !current_user_can( 'manage_options' ) )
|
||||
wp_die( -1 );
|
||||
|
||||
if ( is_multisite() && !is_super_admin() )
|
||||
wp_die( -1 );
|
||||
|
||||
if ( !isset( $_GET['theme'] ) )
|
||||
wp_die( -1 );
|
||||
|
||||
$this->delete_custom_preset( $_GET['theme'] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retreive global custom presets
|
||||
* @return array the custom preset array
|
||||
*/
|
||||
function get_custom_presets( ) {
|
||||
$presets = get_site_option( $this->custom_preset_key, array(), true );
|
||||
return apply_filters( $this->parent->prefix . 'custom_presets', $presets );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update global custom presets
|
||||
* @param array $presets the presets (all)
|
||||
* @return bool success/fail
|
||||
*/
|
||||
function set_custom_presets( $presets ) {
|
||||
return update_site_option( $this->custom_preset_key, $presets );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store a theme's global presets
|
||||
* @param string $theme the theme name
|
||||
* @param array $preset the presets
|
||||
* @return bool success/fail
|
||||
*/
|
||||
function set_custom_preset( $theme, $preset ) {
|
||||
$presets = $this->get_custom_presets();
|
||||
$presets[ $theme ] = $preset;
|
||||
return $this->set_custom_presets( $presets );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a custom preset from the database
|
||||
* @param string $theme the theme to remove
|
||||
* @return bool success/fail
|
||||
*/
|
||||
function delete_custom_preset( $theme ) {
|
||||
$presets = $this->get_custom_presets();
|
||||
unset( $presets[ $theme ] );
|
||||
return $this->set_custom_presets( $presets );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allow custom presets to merge/override community presets
|
||||
* @param unknown $presets
|
||||
* @return unknown
|
||||
*/
|
||||
function merge_custom_presets( $presets ) {
|
||||
|
||||
// 2nd array overrides keys that overlap with first array
|
||||
$presets = array_merge( $presets, $this->get_custom_presets() );
|
||||
|
||||
//sort by key alpha ascending
|
||||
asort( $presets );
|
||||
|
||||
return $presets;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If a selector is not set, try to grab a preset to save the user trouble
|
||||
* @param array $options the options array
|
||||
* @return array the defaulted options array
|
||||
*/
|
||||
function default_to_presets( $options ) {
|
||||
|
||||
//we don't have a preset, no need to go any further
|
||||
if ( !( $preset = $this->get_preset( ) ) )
|
||||
return $options;
|
||||
|
||||
foreach ( $this->keys as $key ) {
|
||||
if ( empty( $options[$key] ) )
|
||||
$options[$key] = $preset->$key;
|
||||
}
|
||||
|
||||
return $options;
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Converts legacy csv.php format
|
||||
* Removes first two lines and last line
|
||||
* @param string $data the contents of the CSV (usually via wp_remote_get)
|
||||
* @param string the equivalent standard CSV
|
||||
*/
|
||||
function parse_legacy_csv( $data ) {
|
||||
|
||||
if ( is_string( $data ) )
|
||||
$data = explode( "\n", $data );
|
||||
|
||||
//remove first two lines
|
||||
$data = array_slice( $data, 2 );
|
||||
|
||||
//remove the last line
|
||||
array_pop( $data );
|
||||
|
||||
$presets = $this->parse_csv( $data );
|
||||
|
||||
$output = array();
|
||||
|
||||
//convert Theme Name to stylesheet and stuff into output array
|
||||
foreach( $presets as $theme ) {
|
||||
$theme->theme = $this->get_stylesheet( $theme->theme );
|
||||
$output[ $theme->theme ] = $theme;
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CSV into array of preset objects
|
||||
* @param string|array the CSV data, either as a string or as an array of lines
|
||||
* @return array array of preset objects
|
||||
*/
|
||||
function parse_csv( $data ) {
|
||||
|
||||
if ( is_string( $data ) )
|
||||
$data = explode( "\n", $data );
|
||||
|
||||
//php 5.3+
|
||||
if ( function_exists( 'str_getcsv' ) ) {
|
||||
|
||||
foreach ( $data as &$line )
|
||||
$line = str_getcsv( $line );
|
||||
|
||||
//php 5.2
|
||||
// fgetcsv needs a file handle,
|
||||
// so write the string to a temp file before parsing
|
||||
} else {
|
||||
|
||||
$fh = tmpfile();
|
||||
fwrite( $fh, implode( "\n", $data ) );
|
||||
fseek( $fh, 0 );
|
||||
$data = array();
|
||||
|
||||
while( $line = fgetcsv( $fh ) )
|
||||
$data[] = $line;
|
||||
|
||||
fclose( $fh );
|
||||
|
||||
}
|
||||
|
||||
$presets = array();
|
||||
|
||||
//build preset objects and stuff into keyed array
|
||||
foreach ( $data as &$line ) {
|
||||
|
||||
$lineObj = new stdClass;
|
||||
|
||||
foreach ( $this->keys as $id => $key )
|
||||
$lineObj->$key = $line[ $id ];
|
||||
|
||||
$presets[ $lineObj->theme ] = $lineObj;
|
||||
|
||||
}
|
||||
|
||||
return $presets;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return object representing current theme's selectors
|
||||
* @return object the same as would be returned from get_preset()
|
||||
*/
|
||||
function current_selectors() {
|
||||
|
||||
$theme = new stdClass();
|
||||
foreach ( $this->keys as $key )
|
||||
$theme->$key = $this->parent->options->$key;
|
||||
|
||||
$theme->theme = get_stylesheet();
|
||||
|
||||
return $theme;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Export CSS Selectors as CSV
|
||||
* @param bool $all (optional) whether to include community selectors in output
|
||||
* @return string CSV of selectors
|
||||
*/
|
||||
function export( $all = false ) {
|
||||
|
||||
$presets = array();
|
||||
|
||||
//if the current theme is not a known preset or they want all
|
||||
if ( !$this->get_preset( ) || $all )
|
||||
$presets[ get_stylesheet() ] = $this->current_selectors();
|
||||
|
||||
//user has access to global custom presets
|
||||
if ( is_multisite() && is_super_admin() ) {
|
||||
|
||||
if ( $custom = $this->get_custom_presets() );
|
||||
$presets = array_merge( $presets, $custom );
|
||||
|
||||
}
|
||||
|
||||
//include community presets, if asked
|
||||
if ( $all )
|
||||
$presets = array_merge( $this->get_presets(), $presets );
|
||||
|
||||
asort( $presets );
|
||||
|
||||
//workaround because fputcsv needs a file handle by default
|
||||
$fh = tmpfile();
|
||||
$length = 0;
|
||||
|
||||
foreach ( $presets as &$preset )
|
||||
$length += fputcsv( $fh, (array) $preset );
|
||||
|
||||
if ( $length == 0 )
|
||||
return false;
|
||||
|
||||
fseek( $fh, 0 );
|
||||
$csv = fread( $fh, $length );
|
||||
fclose( $fh );
|
||||
|
||||
return $csv;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates legacy csv.php files to 2.5's custom presets format
|
||||
* @uses parse_legacy_csv
|
||||
*/
|
||||
function migrate() {
|
||||
|
||||
//no preset file to migrate
|
||||
if ( !file_exists( dirname( $this->parent->file ) . '/PresetDB.csv.php' ) )
|
||||
return;
|
||||
|
||||
$data = file_get_contents( dirname( $this->parent->file ) . '/PresetDB.csv.php' );
|
||||
$presets = $this->parse_legacy_csv( $data );
|
||||
|
||||
//this wiill override any existing presets,
|
||||
// but is okay as is only being fired when no presets exist
|
||||
$this->set_custom_presets( $presets );
|
||||
|
||||
return $presets;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a given theme is installed
|
||||
* @param string|object $theme either the theme slug or the preset object
|
||||
* @return bool true if insalled, otherwise false
|
||||
*/
|
||||
function theme_installed( $theme ) {
|
||||
// get theme name if $theme is an preset object
|
||||
if ( is_object( $theme ) ) {
|
||||
$theme = $theme->theme;
|
||||
}
|
||||
|
||||
//3.4+
|
||||
if ( function_exists( 'wp_get_theme' ) ) {
|
||||
return wp_get_theme( $theme )->exists();
|
||||
} else {
|
||||
//pre 3.4
|
||||
$themes = get_themes();
|
||||
$name = $this->get_name( $theme );
|
||||
|
||||
return array_key_exists( $name, $themes );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a theme name, returns the coresponding theme stylesheet
|
||||
*
|
||||
* Used for converting legacy CSVs which were name based to new CSVs which are stylesheet based
|
||||
* since 3.4 returns themes keyed to stylesheets, not names as it did pre-3.4
|
||||
*
|
||||
* @param string $theme the theme name
|
||||
* @return string the stylesheet
|
||||
*/
|
||||
function get_stylesheet( $name ) {
|
||||
|
||||
//pre 3.4
|
||||
if ( !function_exists( 'wp_get_themes' ) ) {
|
||||
|
||||
if ( $theme = get_theme( $name ) )
|
||||
return $theme->stylesheet;
|
||||
|
||||
//3.4+
|
||||
} else {
|
||||
|
||||
//we can't use wp_filter_list_object with WP_Theme objects, so filter manually
|
||||
foreach ( $this->getThemes(null) as $theme )
|
||||
if ( $theme->name = $name )
|
||||
return $theme->stylesheet;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a theme stylesheet, return the coresponding theme name
|
||||
*
|
||||
* Used to normalize data between 3.3 and 3.4 where keying of themes switched from name to stylesheet
|
||||
*
|
||||
* @param string $stylesheet the theme stylesheet (slug)
|
||||
* @return string the theme name
|
||||
*/
|
||||
function get_name( $stylesheet ) {
|
||||
|
||||
//3.4+
|
||||
if ( function_exists( 'wp_get_theme' ) ) {
|
||||
|
||||
if ( $theme = wp_get_theme( $stylesheet ) )
|
||||
return $theme->name;
|
||||
|
||||
|
||||
//pre 3.4
|
||||
} else {
|
||||
|
||||
foreach ( get_themes() as $theme )
|
||||
if ( $theme->stylesheet == $stylesheet )
|
||||
return $theme->name;
|
||||
|
||||
}
|
||||
|
||||
//theme isn't installed, use the WP.org API to grab the name rather than risk losing data on upgrade
|
||||
$api = themes_api( 'theme_information', array( 'slug' => $stylesheet, 'fields' => array( 'sections' => false, 'tags' => false ) ) );
|
||||
|
||||
if ( is_wp_error( $api ) )
|
||||
return false;
|
||||
|
||||
return $api->name;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!class_exists('WP_List_Table')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* List table for manage custom presets page
|
||||
*/
|
||||
class Infinite_Scroll_Presets_Table extends WP_List_Table {
|
||||
|
||||
/**
|
||||
* Register with Parent
|
||||
*/
|
||||
function __construct( $args = array() ) {
|
||||
|
||||
parent::__construct( array(
|
||||
'singular' => 'preset',
|
||||
'plural' => 'presets',
|
||||
'ajax' => true,
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default column callback
|
||||
* @param object $item the item to display
|
||||
* @param string $column_name the column name
|
||||
* @return string the HTML to display
|
||||
*/
|
||||
function column_default( $item, $column_name ) {
|
||||
return $item->$column_name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback to display the theme column
|
||||
* @param object $item the preset object
|
||||
* @return string the HTML to display
|
||||
*/
|
||||
function column_theme( $item ) {
|
||||
global $infinite_scroll;
|
||||
|
||||
$s = '<strong><a href="#" class="theme-name">' . $item->theme . '</a></strong>';
|
||||
$s .= '<div class="edit edit-link" style="visibility:hidden;"><a href="#">' . __( 'Edit', 'infinite-scroll' ) . '</a> | <span class="delete"><a href="#">' . __( 'Delete', 'infinite-scroll' ) . '</a></span></div>';
|
||||
$s .= '<div class="save save-link" style="display:none; padding-top:5px;"><a href="#" class="button-primary">' . __( 'Save', 'infinite-scroll' ) . '</a> <a href="#" class="cancel">' . __( 'Cancel', 'infinite-scroll' ) . '</a> <img class="loader" style="display:none;" src="'. admin_url( '/images/loading.gif' ) .'" /></div>';
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callaback to return list of columns to display
|
||||
* @return array the columns to display
|
||||
*/
|
||||
function get_columns() {
|
||||
return array(
|
||||
'theme' => 'Theme',
|
||||
'contentSelector' => 'Content Selector',
|
||||
'navSelector' => 'Navigation Selector',
|
||||
'nextSelector' => 'Next Selector',
|
||||
'itemSelector' => 'Item Selector',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grab data and filter prior to passing to table class
|
||||
*/
|
||||
function prepare_items() {
|
||||
global $infinite_scroll;
|
||||
|
||||
$per_page = 25;
|
||||
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = array();
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$data = $infinite_scroll->presets->get_presets();
|
||||
|
||||
//only display installed themes
|
||||
$data = array_filter( $data, array( &$infinite_scroll->presets, 'theme_installed' ) );
|
||||
|
||||
//merge in themes
|
||||
$themes = $infinite_scroll->presets->getThemes(null);
|
||||
|
||||
foreach ( $themes as $theme => $theme_data ) {
|
||||
|
||||
if ( array_key_exists( $theme, $data) )
|
||||
continue;
|
||||
|
||||
//check for parent theme's preset, if any
|
||||
if ( $preset = $infinite_scroll->presets->get_preset( $theme ) ) {
|
||||
$data[ $theme ] = $preset;
|
||||
continue;
|
||||
}
|
||||
|
||||
$themeObj = new stdClass;
|
||||
|
||||
foreach ( $infinite_scroll->presets->keys as $key )
|
||||
$themeObj->$key = null;
|
||||
|
||||
$themeObj->theme = $theme;
|
||||
|
||||
$data[ $theme ] = $themeObj;
|
||||
|
||||
}
|
||||
|
||||
asort( $data );
|
||||
|
||||
$current_page = $this->get_pagenum();
|
||||
|
||||
$total_items = count($data);
|
||||
|
||||
$data = array_slice($data, (($current_page-1)*$per_page), $per_page);
|
||||
|
||||
$this->items = $data;
|
||||
|
||||
$this->set_pagination_args( array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
}
|
67
plugins/infinite-scroll/includes/submit.php
Normal file
67
plugins/infinite-scroll/includes/submit.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
/**
|
||||
* Prompts users to submit CSS Selectors to WP Forums when appropriate
|
||||
* @subpackage Infinite_Scroll_Submit
|
||||
* @package Infinite_Scroll
|
||||
*/
|
||||
class Infinite_Scroll_Submit {
|
||||
|
||||
// public $url = 'http://wordpress.org/support/topic/plugin-infinite-scroll-FOO#postform';
|
||||
public $url = 'https://github.com/benbalter/Infinite-Scroll/issues/7#issue_comment_form';
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* Stores parent class as static
|
||||
* @param class $parent (reference) the parent class
|
||||
*/
|
||||
function __construct( &$parent ) {
|
||||
|
||||
$this->parent = &$parent;
|
||||
add_action( 'wp_ajax_' . $this->parent->slug_ . '_hide_submit', array( &$this, 'hide') );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally prompts users to submit selectors to community DB when appropriate
|
||||
*/
|
||||
function prompt() {
|
||||
|
||||
//user has globally opted out
|
||||
if ( get_user_option( 'infinite-scroll-hide-submit', get_current_user_ID() ) )
|
||||
return;
|
||||
|
||||
//their current theme's preset selectors, false if none found (good)
|
||||
$preset = $this->parent->presets->get_preset( get_stylesheet() );
|
||||
|
||||
//their network-wide custom presets, false if none found (bad)
|
||||
$custom = $this->parent->presets->get_custom_presets( );
|
||||
|
||||
//the site's current theme is a preset
|
||||
// and there are no custom presets, kick
|
||||
if ( $preset && !$custom )
|
||||
return;
|
||||
|
||||
//we already have their current theme,
|
||||
// and they can't submit custom presets b/c multisite and not superadmin
|
||||
if ( $preset && is_multisite() && !is_super_admin() )
|
||||
return;
|
||||
|
||||
require dirname( $this->parent->file ) . '/templates/submit-prompt.php';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores user's preference to hide the submit message via AJAX
|
||||
*/
|
||||
function hide() {
|
||||
|
||||
check_ajax_referer( $this->parent->slug_ . '_hide_submit' , '_ajax_nonce-' . $this->parent->slug . '-hide-submit' );
|
||||
|
||||
//note: option will be global
|
||||
update_user_option( get_current_user_ID(), 'infinite-scroll-hide-submit', true, true );
|
||||
|
||||
die( 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue