- Cambios

git-svn-id: https://192.168.0.254/svn/Proyectos.FundacionLQDVI_Web/trunk@8 77ab8c26-3d69-2c4d-86f2-786f4ba54905
This commit is contained in:
David Arranz 2011-06-09 19:31:41 +00:00
parent 93fbec950e
commit c6adfce2d5
326 changed files with 39392 additions and 28 deletions

View File

@ -0,0 +1,770 @@
<?php
/**
* @package C2C_Plugins
* @author Scott Reilly
* @version 017
*/
/*
Basis for other plugins
Compatible with WordPress 2.8+, 2.9+, 3.0+.
=>> Read the accompanying readme.txt file for more information. Also, visit the plugin's homepage
=>> for more information and the latest updates
Installation:
*/
/*
Copyright (c) 2010 by Scott Reilly (aka coffee2code)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
if ( !class_exists( 'C2C_Plugin_017' ) ) :
class C2C_Plugin_017 {
var $plugin_css_version = '006';
var $options = array();
var $option_names = array();
var $required_config = array( 'menu_name', 'name' );
var $saved_settings = false;
var $saved_settings_msg = '';
/**
* Handles installation tasks, such as ensuring plugin options are instantiated and saved to options table.
*
* @param string $version Version of the plugin.
* @param string $id_base A unique base ID for the plugin (generally a lower-case, dash-separated version of plugin name).
* @param string $author_prefix Short (2-3 char) identifier for plugin author.
* @param string $file The __FILE__ value for the sub-class.
* @param array $plugin_options (optional) Array specifying further customization of plugin configuration.
* @return void
*/
function C2C_Plugin_017( $version, $id_base, $author_prefix, $file, $plugin_options = array() ) {
global $pagenow;
$id_base = sanitize_title( $id_base );
if ( !file_exists( $file ) )
die( sprintf( __( 'Invalid file specified for C2C_Plugin: %s', $this->textdomain ), $file ) );
$u_id_base = str_replace( '-', '_', $id_base );
$author_prefix .= '_';
$defaults = array(
'admin_options_name' => $author_prefix . $u_id_base, // The setting under which all plugin settings are stored under (as array)
'config' => array(), // Default configuration
'disable_contextual_help' => false, // Prevent overriding of the contextual help?
'disable_update_check' => false, // Prevent WP from checking for updates to this plugin?
'hook_prefix' => $u_id_base . '_', // Prefix for all hooks
'form_name' => $u_id_base, // Name for the <form>
'menu_name' => '', // Specify this via plugin
'name' => '', // Full, localized version of the plugin name
'nonce_field' => 'update-' . $u_id_base, // Nonce field value
'settings_page' => 'options-general', // The type of the settings page.
'show_admin' => true, // Should admin be shown? Only applies if admin is enabled
'textdomain' => $id_base, // Textdomain for localization
'textdomain_subdir' => 'lang' // Subdirectory, relative to plugin's root, to hold localization files
);
$settings = wp_parse_args( $plugin_options, $defaults );
foreach ( array_keys( $defaults ) as $key )
$this->$key = $settings[$key];
$this->author_prefix = $author_prefix;
$this->id_base = $id_base;
$this->options_page = ''; // This will be set when the options is created
$this->plugin_basename = plugin_basename( $file );
$this->plugin_file = $file;
$this->plugin_path = plugins_url( '', $file );
$this->u_id_base = $u_id_base; // Underscored version of id_base
$this->version = $version;
add_action( 'init', array( &$this, 'init' ) );
$plugin_file = implode( '/', array_slice( explode( '/', $this->plugin_basename ), -2 ) );
add_action( 'activate_' . $plugin_file, array( &$this, 'install' ) );
add_action( 'deactivate_' . $plugin_file, array( &$this, 'deactivate' ) );
register_uninstall_hook( $this->plugin_file, array( &$this, 'uninstall' ) );
add_action( 'admin_init', array( &$this, 'init_options' ) );
if ( basename( $pagenow, '.php' ) == $this->settings_page )
add_action( 'admin_head', array( &$this, 'add_c2c_admin_css' ) );
}
/**
* Handles installation tasks, such as ensuring plugin options are instantiated and saved to options table.
*
* This can be overridden.
*
* @return void
*/
function install() {
$this->options = $this->get_options();
update_option( $this->admin_options_name, $this->options );
}
/**
* Handles uninstallation tasks, such as deleting plugin options.
*
* This can be overridden.
*
* @return void
*/
function uninstall() {
delete_option( $this->admin_options_name );
}
/**
* Handles deactivation tasks
*
* This should be overridden.
*
* @return void
*/
function deactivate() { }
/**
* Handles actions to be hooked to 'init' action, such as loading text domain and loading plugin config data array.
*
* @return void
*/
function init() {
global $c2c_plugin_max_css_version;
if ( !isset( $c2c_plugin_max_css_version ) || ( $c2c_plugin_max_css_version < $this->plugin_css_version ) )
$c2c_plugin_max_css_version = $this->plugin_css_version;
$this->load_textdomain();
$this->load_config();
$this->verify_config();
if ( $this->disable_update_check )
add_filter( 'http_request_args', array( &$this, 'disable_update_check' ), 5, 2 );
if ( $this->show_admin && $this->settings_page && !empty( $this->config ) && current_user_can( 'manage_options' ) ) {
add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
if ( !$this->disable_contextual_help ) {
add_action( 'contextual_help', array( &$this, 'contextual_help' ), 10, 3 );
if ( $this->is_plugin_admin_page() )
add_thickbox();
}
}
$this->register_filters();
}
/**
* Prevents this plugin from being included when WordPress phones home
* to check for plugin updates.
*
* @param array $r Response array
* @param string $url URL for the update check
* @return array The response array with this plugin removed, if present
*/
function disable_update_check( $r, $url ) {
if ( 0 !== strpos( $url, 'http://api.wordpress.org/plugins/update-check' ) )
return $r; // Not a plugin update request. Bail immediately.
$plugins = unserialize( $r['body']['plugins'] );
unset( $plugins->plugins[ plugin_basename( __FILE__ ) ] );
unset( $plugins->active[ array_search( plugin_basename( __FILE__ ), $plugins->active ) ] );
$r['body']['plugins'] = serialize( $plugins );
return $r;
}
/**
* Initializes options
*
* @return void
*/
function init_options() {
register_setting( $this->admin_options_name, $this->admin_options_name, array( &$this, 'sanitize_inputs' ) );
add_settings_section( 'default', '', array( &$this, 'draw_default_section' ), $this->plugin_file );
add_filter( 'whitelist_options', array( &$this, 'whitelist_options' ) );
foreach ( $this->get_option_names( false ) as $opt )
add_settings_field( $opt, $this->get_option_label( $opt ), array( &$this, 'display_option' ), $this->plugin_file, 'default', $opt );
}
/**
* Whitelist the plugin's option(s)
*
* @param array $options Array of options
* @return array The whitelist-amended $options array
*/
function whitelist_options( $options ) {
$added = array( $this->admin_options_name => array( $this->admin_options_name ) );
$options = add_option_whitelist( $added, $options );
return $options;
}
/**
* Special output for the default section. Can be overridden if desired.
*
* @return void
*/
function draw_default_section() { }
/**
* Gets the label for a given option
*
* @param string $opt The option
* @return string The label for the option
*/
function get_option_label( $opt ) {
return isset( $this->config[$opt]['label'] ) ? $this->config[$opt]['label'] : '';
}
/**
* Resets plugin options
*
* @return array
*/
function reset_options() {
$options = $this->get_options( false );
return $options;
}
/**
* Sanitize user inputs prior to saving
*/
function sanitize_inputs( $inputs ) {
do_action( $this->get_hook( 'before_save_options' ), $this );
if ( isset( $_POST['Reset'] ) ) {
$options = $this->reset_options();
add_settings_error( 'general', 'settings_reset', __( 'Settings reset.', $this->textdomain ), 'updated' );
} else {
// Start with the existing options, then start overwriting their potential override value. (This prevents
// unscrupulous addition of fields by the user)
$options = $this->get_options();
$option_names = $this->get_option_names();
foreach ( $option_names as $opt ) {
if ( !isset( $inputs[$opt] ) ) {
if ( $this->config[$opt]['input'] == 'checkbox' )
$options[$opt] = '';
elseif ( ( $this->config[$opt]['required'] === true ) ) {
$msg = sprintf( __( 'A value is required for: "%s"', $this->textdomain ), $this->config[$opt]['label'] );
add_settings_error( 'general', 'setting_required', $msg, 'error' );
}
}
else {
$val = $inputs[$opt];
$error = false;
if ( empty( $val ) && ( $this->config[$opt]['required'] === true ) ) {
$msg = sprintf( __( 'A value is required for: "%s"', $this->textdomain ), $this->config[$opt]['label'] );
$error = true;
} else {
$input = $this->config[$opt]['input'];
switch ( $this->config[$opt]['datatype'] ) {
case 'checkbox':
break;
case 'int':
if ( !empty( $val ) && ( !is_numeric( $val ) || ( intval( $val ) != round( $val ) ) ) ) {
$msg = sprintf( __( 'Expected integer value for: %s', $this->textdomain ), $this->config[$opt]['label'] );
$error = true;
$val = '';
}
break;
case 'array':
if ( empty( $val ) )
$val = array();
elseif ( $input == 'text' )
$val = explode( ',', str_replace( array( ', ', ' ', ',' ), ',', $val ) );
else
$val = array_map( 'trim', explode( "\n", trim( $val ) ) );
break;
case 'hash':
if ( !empty( $val ) && $input != 'select' ) {
$new_values = array();
foreach ( explode( "\n", $val ) AS $line ) {
list( $shortcut, $text ) = array_map( 'trim', explode( "=>", $line, 2 ) );
if ( !empty( $shortcut ) )
$new_values[str_replace( '\\', '', $shortcut )] = str_replace( '\\', '', $text );
}
$val = $new_values;
}
break;
}
}
if ( $error )
add_settings_error( 'general', 'setting_not_int', $msg, 'error' );
$options[$opt] = $val;
}
}
$options = apply_filters( $this->get_hook( 'before_update_option' ), $options, $this );
}
return $options;
}
/**
* Initializes the plugin's configuration and localizable text variables.
*
* @return void
*/
function load_config() {
die( 'Function load_config() must be overridden in sub-class.' );
}
/**
* Verify that the necessary configuration files were set in the inheriting class.
*
* @return void
*/
function verify_config() {
// Ensure required configuration options have been configured via the sub-class. Die if any aren't.
foreach ( $this->required_config as $config ) {
if ( empty( $this->$config ) )
die( "The plugin configuration option '$config' must be supplied." );
}
// Set/change configuration options based on sub-class changes.
if ( empty( $this->config ) )
$this->show_admin = false;
else {
// Initialize any option attributes that weren't specified by the plugin
foreach ( $this->get_option_names( true ) as $opt ) {
foreach ( array( 'datatype', 'default', 'help', 'input', 'input_attributes', 'label', 'no_wrap', 'options', 'output' ) as $attrib ) {
if ( !isset( $this->config[$opt][$attrib] ) )
$this->config[$opt][$attrib] = '';
}
$this->config[$opt]['allow_html'] = false;
$this->config[$opt]['class'] = array();
}
}
}
/**
* Loads the localization textdomain for the plugin.
*
* @return void
*/
function load_textdomain() {
$subdir = empty( $this->textdomain_subdir ) ? '' : '/'.$this->textdomain_subdir;
load_plugin_textdomain( $this->textdomain, false, basename( dirname( $this->plugin_file ) ) . $subdir );
}
/**
* Registers filters.
* NOTE: This occurs during the 'init' filter, so you can't use this to hook anything that happens earlier
*
* @return void
*/
function register_filters() {
// This should be overridden in order to define filters.
}
/**
* Outputs simple contextual help text, comprising solely of a thickboxed link to the plugin's hosted readme.txt file.
*
* NOTE: If overriding this in a sub-class, before sure to include the
* check at the beginning of the function to ensure it shows up on its
* own settings admin page.
*
* @param string $contextual_help The default contextual help
* @param int $screen_id The screen ID
* @param object $screen The screen object (only supplied in WP 3.0)
* @return void (Text is echoed)
*/
function contextual_help( $contextual_help, $screen_id, $screen = null ) {
if ( $screen_id != $this->options_page )
return $contextual_help;
$help_url = admin_url( "plugin-install.php?tab=plugin-information&amp;plugin={$this->id_base}&amp;TB_iframe=true&amp;width=640&amp;height=656" );
echo '<p class="more-help">';
echo '<a title="' . esc_attr( sprintf( __( 'More information about %1$s %2$s', $this->textdomain ), $this->name, $this->version ) ) .
'" class="thickbox" href="' . $help_url . '">' . __( 'Click for more help on this plugin', $this->textdomain ) . '</a>' .
__( ' (especially check out the "Other Notes" tab, if present)', $this->textdomain );
echo ".</p>\n";
return;
}
/**
* Outputs CSS into admin head of the plugin's settings page
*
* @return void
*/
function add_c2c_admin_css() {
global $c2c_plugin_max_css_version, $c2c_plugin_css_was_output;
if ( ( $c2c_plugin_max_css_version != $this->plugin_css_version ) || ( isset( $c2c_plugin_css_was_output ) && $c2c_plugin_css_was_output ) )
return;
$c2c_plugin_css_was_output = true;
$logo = plugins_url( 'c2c_minilogo.png', $this->plugin_file );
/**
* Remember to increment the plugin_css_version variable if changing the CSS
*/
echo <<<CSS
<style type="text/css">
.long-text {width:95% !important;}
#c2c {
text-align:center;
color:#888;
background-color:#ffffef;
padding:5px 0 0;
margin-top:12px;
border-style:solid;
border-color:#dadada;
border-width:1px 0;
}
#c2c div {
margin:0 auto;
padding:5px 40px 0 0;
width:45%;
min-height:40px;
background:url('$logo') no-repeat top right;
}
#c2c span {
display:block;
font-size:x-small;
}
.form-table {margin-bottom:20px;}
.c2c-plugin-list {margin-left:2em;}
.c2c-plugin-list li {list-style:disc outside;}
.wrap {margin-bottom:30px !important;}
.c2c-form input[type="checkbox"] {width:1.5em;}
.c2c-form .hr, .c2c-hr {border-bottom:1px solid #ccc;padding:0 2px;margin-bottom:6px;}
.c2c-input-help {color:#777;font-size:x-small;}
.c2c-fieldset {border:1px solid #ccc; padding:2px 8px;}
.c2c-textarea, .c2c-inline_textarea {width:95%;font-family:"Courier New", Courier, mono;}
.c2c-nowrap {
white-space:nowrap;overflow:scroll;overflow-y:hidden;overflow-x:scroll;overflow:-moz-scrollbars-horizontal
}
.see-help {font-size:x-small;font-style:italic;}
.more-help {display:block;margin-top:8px;}
</style>
CSS;
}
/**
* Registers the admin options page and the Settings link.
*
* @return void
*/
function admin_menu() {
add_filter( 'plugin_action_links_' . $this->plugin_basename, array( &$this, 'plugin_action_links' ) );
switch ( $this->settings_page ) {
case 'options-general' :
$func_root = 'options';
break;
case 'themes' :
$func_root = 'theme';
break;
default :
$func_root = $this->settings_page;
}
$menu_func = 'add_' . $func_root . '_page';
if ( function_exists( $menu_func ) )
$this->options_page = call_user_func( $menu_func, $this->name, $this->menu_name, 'manage_options', $this->plugin_basename, array( &$this, 'options_page' ) );
}
/**
* Adds a 'Settings' link to the plugin action links.
*
* @param int $limit The default limit value for the current posts query.
* @return array Links associated with a plugin on the admin Plugins page
*/
function plugin_action_links( $action_links ) {
$settings_link = '<a href="' . $this->settings_page . '.php?page='.$this->plugin_basename.'">' . __( 'Settings', $this->textdomain ) . '</a>';
array_unshift( $action_links, $settings_link );
return $action_links;
}
/**
* See if the setting is pertinent to this version of WP
*
* @since 013
*
* @param string $opt The option name
* @return bool If the option is valid for this version of WP
*/
function is_option_valid( $opt ) {
global $wp_version;
$valid = true;
$ver_operators = array( 'wpgt' => '>', 'wpgte' => '>=', 'wplt' => '<', 'wplte' => '<=' );
foreach ( $ver_operators as $ver_check => $ver_op ) {
if ( isset( $this->config[$opt][$ver_check] )
&& !empty( $this->config[$opt][$ver_check] )
&& !version_compare( $wp_version, $this->config[$opt][$ver_check], $ver_op ) ) {
$valid = false;
break;
}
}
return $valid;
}
/**
* Returns the list of option names.
*
* @param bool $include_non_options (optional) Should non-options be included? Default is false.
* @return array Array of option names.
*/
function get_option_names( $include_non_options = false ) {
if ( !$include_non_options && !empty( $this->option_names ) )
return $this->option_names;
if ( $include_non_options )
return array_keys( $this->config );
$this->option_names = array();
foreach ( array_keys( $this->config ) as $opt ) {
if ( isset( $this->config[$opt]['input'] ) && $this->config[$opt]['input'] != '' && $this->config[$opt]['input'] != 'none' && $this->is_option_valid( $opt ) )
$this->option_names[] = $opt;
}
return $this->option_names;
}
/**
* Returns either the buffered array of all options for the plugin, or
* obtains the options and buffers the value.
*
* @param bool $with_current_values (optional) Should the currently saved values be returned? If false, then the plugin's defaults are returned. Default is true.
* @return array The options array for the plugin (which is also stored in $this->options if !$with_options).
*/
function get_options( $with_current_values = true ) {
if ( $with_current_values && !empty( $this->options ) )
return $this->options;
// Derive options from the config
$options = array();
$option_names = $this->get_option_names( !$with_current_values );
foreach ( $option_names as $opt )
$options[$opt] = $this->config[$opt]['default'];
if ( !$with_current_values )
return $options;
$this->options = wp_parse_args( get_option( $this->admin_options_name ), $options );
// Un-escape fields
foreach ( $option_names as $opt ) {
if ( $this->config[$opt]['allow_html'] == true ) {
if ( is_array( $this->options[$opt] ) ) {
foreach ( $this->options[$opt] as $key => $val ) {
$new_key = wp_specialchars_decode( $key, ENT_QUOTES );
$new_val = wp_specialchars_decode( $val, ENT_QUOTES );
$this->options[$opt][$new_key] = $new_val;
if ( $key != $new_key )
unset( $this->options[$opt][$key] );
}
} else {
$this->options[$opt] = wp_specialchars_decode( $this->options[$opt], ENT_QUOTES );
}
}
}
return apply_filters( $this->get_hook( 'options' ), $this->options );
}
/**
* Gets the name to use for a form's <input type="hidden" name="XXX" value="1" />
*
* @param string $prefix A prefix string, unique to the form
* @return string The name
*/
function get_form_submit_name( $prefix ) {
return $prefix . '_' . $this->u_id_base;
}
/**
* Returns the URL for a plugin's form to use for its action attribute
*
* @return string The action URL
*/
function form_action_url() {
return $_SERVER['PHP_SELF'] . '?page=' . $this->plugin_basename;
}
/**
* Checks if the plugin's settings page has been submitted.
*
* @param string $prefix The prefix for the form's unique submit hidden input field
* @return bool True if the plugin's settings have been submitted for saving, else false.
*/
function is_submitting_form( $prefix ) {
return ( isset( $_POST['option_page'] ) && ( $_POST['option_page'] == $this->admin_options_name ) );
}
/**
* Checks if the current page is the plugin's settings page.
*
* @return bool True if on the plugin's settings page, else false.
*/
function is_plugin_admin_page() {
global $pagenow;
return ( basename( $pagenow, '.php' ) == $this->settings_page && isset( $_REQUEST['page'] ) && $_REQUEST['page'] == $this->plugin_basename );
}
/**
* Outputs the markup for an option's form field (and surrounding markup)
*
* @param string $opt The name/key of the option.
* @return void
*/
function display_option( $opt ) {
do_action( $this->get_hook( 'pre_display_option' ), $opt );
$options = $this->get_options();
foreach ( array( 'datatype', 'input' ) as $attrib )
$$attrib = isset( $this->config[$opt][$attrib] ) ? $this->config[$opt][$attrib] : '';
if ( $input == '' || $input == 'none' )
return;
elseif ( $input == 'custom' ) {
do_action( $this->get_hook( 'custom_display_option' ), $opt );
return;
}
$value = isset( $options[$opt] ) ? $options[$opt] : '';
$popt = $this->admin_options_name . "[$opt]";
if ( $input == 'multiselect' ) {
// Do nothing since it needs the values as an array
$popt .= '[]';
} elseif ( $datatype == 'array' ) {
if ( !is_array( $value ) )
$value = '';
else {
if ( $input == 'textarea' || $input == 'inline_textarea' )
$value = implode( "\n", $value );
else
$value = implode( ', ', $value );
}
} elseif ( $datatype == 'hash' && $input != 'select' ) {
if ( !is_array( $value ) )
$value = '';
else {
$new_value = '';
foreach ( $value AS $shortcut => $replacement )
$new_value .= "$shortcut => $replacement\n";
$value = $new_value;
}
}
$attributes = $this->config[$opt]['input_attributes'];
$this->config[$opt]['class'][] = 'c2c-' . $input;
if ( ( 'textarea' == $input || 'inline_textarea' == $input ) && $this->config[$opt]['no_wrap'] ) {
$this->config[$opt]['class'][] = 'c2c-nowrap';
$attributes .= ' wrap="off"'; // Unfortunately CSS is not enough
}
elseif ( in_array( $input, array( 'text', 'long_text', 'short_text' ) ) ) {
$this->config[$opt]['class'][] = ( ( $input == 'short_text' ) ? 'small-text' : 'regular-text' );
if ( $input == 'long_text' )
$this->config[$opt]['class'][] = ' long-text';
}
$class = implode( ' ', $this->config[$opt]['class'] );
$attribs = "name='$popt' id='$opt' class='$class' $attributes";
if ( $input == '' ) {
// Change of implementation prevents this from being possible (since this function only gets called for registered settings)
// if ( !empty( $this->config[$opt]['output'] ) )
// echo $this->config[$opt]['output'] . "\n";
// else
// echo '<div class="hr">&nbsp;</div>' . "\n";
} elseif ( $input == 'textarea' || $input == 'inline_textarea' ) {
if ( $input == 'textarea' )
echo "</td><tr><td colspan='2'>";
echo "<textarea $attribs>$value</textarea>\n";
} elseif ( $input == 'select' ) {
echo "<select $attribs>";
if ( $this->config[$opt]['datatype'] == 'hash' ) {
foreach ( (array) $this->config[$opt]['options'] as $sopt => $sval )
echo "<option value='$sopt' " . selected( $value, $sopt, false ) . ">$sval</option>\n";
} else {
foreach ( (array) $this->config[$opt]['options'] as $sopt )
echo "<option value='$sopt' " . selected( $value, $sopt, false ) . ">$sopt</option>\n";
}
echo "</select>";
} elseif ( $input == 'multiselect' ) {
echo '<fieldset class="c2c-fieldset">' . "\n";
foreach ( (array) $this->config[$opt]['options'] as $sopt )
echo "<input type='checkbox' $attribs value='$sopt' " . checked( in_array( $sopt, $value ), true, false ) . ">$sopt</input><br />\n";
echo '</fieldset>';
} elseif ( $input == 'checkbox' ) {
echo "<input type='$input' $attribs value='1' " . checked( $value, 1, false ) . " />\n";
} else { // Only 'text' and 'password' should fall through to here.
echo "<input type='$input' $attribs value='" . esc_attr( $value ) . "' />\n";
}
if ( $help = apply_filters( $this->get_hook( 'option_help'), $this->config[$opt]['help'], $opt ) )
echo "<br /><span class='c2c-input-help'>$help</span>\n";
do_action( $this->get_hook( 'post_display_option' ), $opt );
}
/**
* Outputs the descriptive text (and h2 heading) for the options page.
*
* Intended to be overridden by sub-class.
*
* @param string $localized_heading_text (optional) Localized page heading text.
* @return void
*/
function options_page_description( $localized_heading_text = '' ) {
if ( empty( $localized_heading_text ) )
$localized_heading_text = $this->name;
if ( $localized_heading_text )
echo '<h2>' . $localized_heading_text . "</h2>\n";
if ( !$this->disable_contextual_help )
echo '<p class="see-help">' . __( 'See the "Help" link to the top-right of the page for more help.', $this->textdomain ) . "</p>\n";
}
/**
* Outputs the options page for the plugin, and saves user updates to the
* options.
*
* @return void
*/
function options_page() {
$options = $this->get_options();
if ( $this->saved_settings )
echo "<div id='message' class='updated fade'><p><strong>" . $this->saved_settings_msg . '</strong></p></div>';
$logo = plugins_url( basename( $_GET['page'], '.php' ) . '/c2c_minilogo.png' );
echo "<div class='wrap'>\n";
echo "<div class='icon32' style='width:44px;'><img src='$logo' alt='" . esc_attr__( 'A plugin by coffee2code', $this->textdomain ) . "' /><br /></div>\n";
$this->options_page_description();
do_action( $this->get_hook( 'before_settings_form' ), $this );
echo "<form action='options.php' method='post' class='c2c-form'>\n";
settings_fields( $this->admin_options_name );
do_settings_sections( $this->plugin_file );
echo '<input type="submit" name="Submit" class="button-primary" value="' . esc_attr__( 'Save Changes', $this->textdomain ) . '" />' . "\n";
echo '<input type="submit" name="Reset" class="button" value="' . esc_attr__( 'Reset Settings', $this->textdomain ) . '" />' . "\n";
echo '</form>' . "\n";
do_action( $this->get_hook( 'after_settings_form' ), $this );
echo '<div id="c2c" class="wrap"><div>' . "\n";
$c2c = '<a href="http://coffee2code.com" title="coffee2code.com">' . __( 'Scott Reilly, aka coffee2code', $this->textdomain ) . '</a>';
echo sprintf( __( 'This plugin brought to you by %s.', $this->textdomain ), $c2c );
echo '<span><a href="http://coffee2code.com/donate" title="' . esc_attr__( 'Please consider a donation', $this->textdomain ) . '">' .
__( 'Did you find this plugin useful?', $this->textdomain ) . '</a></span>';
echo '</div></div>' . "\n";
}
/**
* Returns the full plugin-specific name for a hook.
*
* @param string $hook The name of a hook, to be made plugin-specific.
* @return string The plugin-specific version of the hook name.
*/
function get_hook( $hook ) {
return $this->hook_prefix . '_' . $hook;
}
/**
* Returns the URL for the plugin's readme.txt file on wordpress.org/extend/plugins
*
* @since 005
*
* @return string The URL
*/
function readme_url() {
return 'http://wordpress.org/extend/plugins/' . $this->id_base . '/tags/' . $this->version . '/readme.txt';
}
} // end class
endif; // end if !class_exists()
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,289 @@
<?php
/**
* @package Configure_SMTP
* @author Scott Reilly
* @version 3.0.1
*/
/*
Plugin Name: Configure SMTP
Version: 3.0.1
Plugin URI: http://coffee2code.com/wp-plugins/configure-smtp/
Author: Scott Reilly
Author URI: http://coffee2code.com
Text Domain: configure-smtp
Description: Configure SMTP mailing in WordPress, including support for sending e-mail via SSL/TLS (such as GMail).
Compatible with WordPress 2.8+, 2.9+, 3.0+.
=>> Read the accompanying readme.txt file for instructions and documentation.
=>> Also, visit the plugin's homepage for additional information and updates.
=>> Or visit: http://wordpress.org/extend/plugins/configure-smtp/
*/
/*
Copyright (c) 2004-2010 by Scott Reilly (aka coffee2code)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
if ( !class_exists( 'c2c_ConfigureSMTP' ) ) :
require_once( 'c2c-plugin.php' );
class c2c_ConfigureSMTP extends C2C_Plugin_017 {
var $gmail_config = array(
'host' => 'smtp.gmail.com',
'port' => '465',
'smtp_auth' => true,
'smtp_secure' => 'ssl'
);
/**
* Constructor
*
* @return void
*/
function c2c_ConfigureSMTP() {
$this->C2C_Plugin_017( '3.0.1', 'configure-smtp', 'c2c', __FILE__, array() );
}
/**
* Initializes the plugin's configuration and localizable text variables.
*
* @return void
*/
function load_config() {
$this->name = __( 'Configure SMTP', $this->textdomain );
$this->menu_name = __( 'SMTP', $this->textdomain );
$this->config = array(
'use_gmail' => array( 'input' => 'checkbox', 'default' => false,
'label' => __( 'Send e-mail via GMail?', $this->textdomain ),
'help' => __( 'Clicking this will override many of the settings defined below. You will need to input your GMail username and password below.', $this->textdomain ),
'input_attributes' => 'onclick="return configure_gmail();"' ),
'host' => array( 'input' => 'text', 'default' => 'localhost', 'require' => true,
'label' => __( 'SMTP host', $this->textdomain ),
'help' => __( 'If "localhost" doesn\'t work for you, check with your host for the SMTP hostname.', $this->textdomain ) ),
'port' => array( 'input' => 'short_text', 'default' => 25, 'datatype' => 'int', 'required' => true,
'label' => __( 'SMTP port', $this->textdomain ),
'help' => __( 'This is generally 25.', $this->textdomain ) ),
'smtp_secure' => array( 'input' => 'select', 'default' => 'None',
'label' => __( 'Secure connection prefix', $this->textdomain ),
'options' => array( '', 'ssl', 'tls' ),
'help' => __( 'Sets connection prefix for secure connections (prefix method must be supported by your PHP install and your SMTP host)', $this->textdomain ) ),
'smtp_auth' => array( 'input' => 'checkbox', 'default' => false,
'label' => __( 'Use SMTPAuth?', $this->textdomain ),
'help' => __( 'If checked, you must provide the SMTP username and password below', $this->textdomain ) ),
'smtp_user' => array( 'input' => 'text', 'default' => '',
'label' => __( 'SMTP username', $this->textdomain ),
'help' => '' ),
'smtp_pass' => array( 'input' => 'password', 'default' => '',
'label' => __( 'SMTP password', $this->textdomain ),
'help' => '' ),
'wordwrap' => array( 'input' => 'short_text', 'default' => '',
'label' => __( 'Wordwrap length', $this->textdomain ),
'help' => __( 'Sets word wrapping on the body of the message to a given number of characters.', $this->textdomain ) ),
'hr' => array(),
'from_email' => array( 'input' => 'text', 'default' => '',
'label' => __( 'Sender e-mail', $this->textdomain ),
'help' => __( 'Sets the From e-mail address for all outgoing messages. Leave blank to use the WordPress default. This value will be used even if you don\'t enable SMTP. NOTE: This may not take effect depending on your mail server and settings, especially if using SMTPAuth (such as for GMail).', $this->textdomain ) ),
'from_name' => array( 'input' => 'text', 'default' => '',
'label' => __( 'Sender name', $this->textdomain ),
'help' => __( 'Sets the From name for all outgoing messages. Leave blank to use the WordPress default. This value will be used even if you don\'t enable SMTP.', $this->textdomain ) )
);
}
/**
* Override the plugin framework's register_filters() to actually actions against filters.
*
* @return void
*/
function register_filters() {
global $pagenow;
if ( 'options-general.php' == $pagenow )
add_action( 'admin_print_footer_scripts', array( &$this, 'add_js' ) );
add_action( 'admin_init', array( &$this, 'maybe_send_test' ) );
add_action( 'phpmailer_init', array( &$this, 'phpmailer_init' ) );
add_action( 'wp_mail_from', array( &$this, 'wp_mail_from' ) );
add_action( 'wp_mail_from_name', array( &$this, 'wp_mail_from_name' ) );
add_action( $this->get_hook( 'after_settings_form' ), array( &$this, 'send_test_form' ) );
add_filter( $this->get_hook( 'before_update_option' ), array( &$this, 'maybe_gmail_override' ) );
}
/**
* Outputs the text above the setting form
*
* @return void (Text will be echoed.)
*/
function options_page_description() {
$options = $this->get_options();
parent::options_page_description( __( 'Configure SMTP Settings', $this->textdomain ) );
$str = '<a href="#test">' . __( 'test', $this->textdomain ) . '</a>';
if ( empty( $options['host'] ) )
echo '<div class="error"><p>' . __( 'SMTP mailing is currently <strong>NOT ENABLED</strong> because no SMTP host has been specified.' ) . '</p></div>';
echo '<p>' . sprintf( __( 'After you have configured your SMTP settings, use the %s to send a test message to yourself.', $this->textdomain ), $str ) . '</p>';
}
/**
* Outputs JavaScript
*
* @return void (Text is echoed.)
*/
function add_js() {
$alert = __( 'Be sure to specify your GMail email address (with the @gmail.com) as the SMTP username, and your GMail password as the SMTP password.', $this->textdomain );
echo <<<JS
<script type="text/javascript">
function configure_gmail() {
if (jQuery('#use_gmail').attr('checked') == true) {
jQuery('#host').val('{$this->gmail_config['host']}');
jQuery('#port').val('{$this->gmail_config['port']}');
jQuery('#smtp_auth').attr('checked', {$this->gmail_config['smtp_auth']});
jQuery('#smtp_secure').val('{$this->gmail_config['smtp_secure']}');
if (!jQuery('#smtp_user').val().match(/.+@gmail.com$/) ) {
jQuery('#smtp_user').val('USERNAME@gmail.com').focus().get(0).setSelectionRange(0,8);
}
alert('{$alert}');
return true;
}
}
</script>
JS;
}
/**
* If the 'Use GMail' option is checked, the GMail settings will override whatever the user may have provided
*
* @param array $options The options array prior to saving
* @return array The options array with GMail settings taking precedence, if relevant
*/
function maybe_gmail_override( $options ) {
// If GMail is to be used, those settings take precendence
if ( $options['use_gmail'] )
$options = wp_parse_args( $this->gmail_config, $options );
return $options;
}
/**
* Sends test e-mail if form was submitted requesting to do so.
*
*/
function maybe_send_test() {
if ( isset( $_POST[$this->get_form_submit_name( 'submit_test_email' )] ) ) {
check_admin_referer( $this->nonce_field );
$user = wp_get_current_user();
$email = $user->user_email;
$timestamp = current_time( 'mysql' );
$message = sprintf( __( 'Hi, this is the %s plugin e-mailing you a test message from your WordPress blog.', $this->textdomain ), $this->name );
$message .= "\n\n";
$message .= sprintf( __( 'This message was sent with this time-stamp: %s', $this->textdomain ), $timestamp );
$message .= "\n\n";
$message .= __( 'Congratulations! Your blog is properly configured to send e-mail.', $this->textdomain );
wp_mail( $email, __( 'Test message from your WordPress blog', $this->textdomain ), $message );
// Check success
global $phpmailer;
if ( $phpmailer->ErrorInfo != "" ) {
echo '<div class="error"><p>' . __( 'An error was encountered while trying to send the test e-mail.' ) . '</p>';
echo '<blockquote style="font-weight:bold;">';
echo '<p>' . $phpmailer->ErrorInfo . '</p>';
echo '<p>' . $phpmailer->smtp->error['error'] . '<br />' . $phpmailer->smtp->error['errstr'] . '</p>';
echo '</blockquote>';
echo '</div>';
} else {
echo '<div class="updated"><p>' . __( 'Test e-mail sent.', $this->textdomain ) . '</p>';
echo '<p>' . sprintf( __( 'The body of the e-mail includes this time-stamp: %s.', $this->textdomain ), $timestamp ) . '</p></div>';
}
}
}
/*
* Outputs form to send test e-mail.
*
* @return void (Text will be echoed.)
*/
function send_test_form() {
$user = wp_get_current_user();
$email = $user->user_email;
$action_url = $this->form_action_url();
echo '<div class="wrap"><h2><a name="test"></a>' . __( 'Send A Test', $this->textdomain ) . "</h2>\n";
echo '<p>' . __( 'Click the button below to send a test email to yourself to see if things are working. Be sure to save any changes you made to the form above before sending the test e-mail. Bear in mind it may take a few minutes for the e-mail to wind its way through the internet.', $this->textdomain ) . "</p>\n";
echo '<p>' . sprintf( __( 'This e-mail will be sent to your e-mail address, %s.', $this->textdomain ), $email ) . "</p>\n";
echo '<p><em>You must save any changes to the form above before attempting to send a test e-mail.</em></p>';
echo "<form name='configure_smtp' action='$action_url' method='post'>\n";
wp_nonce_field( $this->nonce_field );
echo '<input type="hidden" name="' . $this->get_form_submit_name( 'submit_test_email' ) .'" value="1" />';
echo '<div class="submit"><input type="submit" name="Submit" value="' . esc_attr__( 'Send test e-mail', $this->textdomain ) . '" /></div>';
echo '</form></div>';
}
/**
* Configures PHPMailer object during its initialization stage
*
* @param object $phpmailer PHPMailer object
* @return void
*/
function phpmailer_init( $phpmailer ) {
$options = $this->get_options();
// Don't configure for SMTP if no host is provided.
if ( empty( $options['host'] ) )
return;
$phpmailer->IsSMTP();
$phpmailer->Host = $options['host'];
$phpmailer->Port = $options['port'] ? $options['port'] : 25;
$phpmailer->SMTPAuth = $options['smtp_auth'] ? $options['smtp_auth'] : false;
if ( $phpmailer->SMTPAuth ) {
$phpmailer->Username = $options['smtp_user'];
$phpmailer->Password = $options['smtp_pass'];
}
if ( $options['smtp_secure'] != '' )
$phpmailer->SMTPSecure = $options['smtp_secure'];
if ( $options['wordwrap'] > 0 )
$phpmailer->WordWrap = $options['wordwrap'];
}
/**
* Configures the "From:" e-mail address for outgoing e-mails
*
* @param string $from The "from" e-mail address used by WordPress by default
* @return string The potentially new "from" e-mail address, if overridden via the plugin's settings.
*/
function wp_mail_from( $from ) {
$options = $this->get_options();
if ( $options['from_email'] )
$from = $options['from_email'];
return $from;
}
/**
* Configures the "From:" name for outgoing e-mails
*
* @param string $from The "from" name used by WordPress by default
* @return string The potentially new "from" name, if overridden via the plugin's settings.
*/
function wp_mail_from_name( $from_name ) {
$options = $this->get_options();
if ( $options['from_name'] )
$from_name = wp_specialchars_decode( $options['from_name'], ENT_QUOTES );
return $from_name;
}
} // end c2c_ConfigureSMTP
$GLOBALS['c2c_configure_smtp'] = new c2c_ConfigureSMTP();
endif; // end if !class_exists()
?>

View File

@ -0,0 +1,281 @@
# Translation of the WordPress plugin Configure SMTP 3.0 by Scott Reilly.
# Copyright (C) 2010 Scott Reilly
# This file is distributed under the same license as the Configure SMTP package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Configure SMTP 3.0\n"
"Report-Msgid-Bugs-To: http://wordpress.org/tag/configure-smtp\n"
"POT-Creation-Date: 2010-09-28 11:43-0400\n"
"PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: c2c-plugin.php:59
#, php-format
msgid "Invalid file specified for C2C_Plugin: %s"
msgstr ""
#: c2c-plugin.php:241
msgid "Settings reset."
msgstr ""
#: c2c-plugin.php:252 c2c-plugin.php:260
#, php-format
msgid "A value is required for: \"%s\""
msgstr ""
#: c2c-plugin.php:269
#, php-format
msgid "Expected integer value for: %s"
msgstr ""
#: c2c-plugin.php:380
#, php-format
msgid "More information about %1$s %2$s"
msgstr ""
#: c2c-plugin.php:381
msgid "Click for more help on this plugin"
msgstr ""
#: c2c-plugin.php:382
msgid " (especially check out the \"Other Notes\" tab, if present)"
msgstr ""
#: c2c-plugin.php:473
msgid "Settings"
msgstr ""
#: c2c-plugin.php:703
msgid "See the \"Help\" link to the top-right of the page for more help."
msgstr ""
#: c2c-plugin.php:721
msgid "A plugin by coffee2code"
msgstr ""
#: c2c-plugin.php:732
msgid "Save Changes"
msgstr ""
#: c2c-plugin.php:733
msgid "Reset Settings"
msgstr ""
#: c2c-plugin.php:739
msgid "Scott Reilly, aka coffee2code"
msgstr ""
#: c2c-plugin.php:740
#, php-format
msgid "This plugin brought to you by %s."
msgstr ""
#: c2c-plugin.php:741
msgid "Please consider a donation"
msgstr ""
#: c2c-plugin.php:742
msgid "Did you find this plugin useful?"
msgstr ""
#. #-#-#-#-# configure-smtp.pot (Configure SMTP 3.0) #-#-#-#-#
#. Plugin Name of the plugin/theme
#: configure-smtp.php:68
msgid "Configure SMTP"
msgstr ""
#: configure-smtp.php:69
msgid "SMTP"
msgstr ""
#: configure-smtp.php:73
msgid "Send e-mail via GMail?"
msgstr ""
#: configure-smtp.php:74
msgid ""
"Clicking this will override many of the settings defined below. You will "
"need to input your GMail username and password below."
msgstr ""
#: configure-smtp.php:77
msgid "SMTP host"
msgstr ""
#: configure-smtp.php:78
msgid ""
"If \"localhost\" doesn't work for you, check with your host for the SMTP "
"hostname."
msgstr ""
#: configure-smtp.php:80
msgid "SMTP port"
msgstr ""
#: configure-smtp.php:81
msgid "This is generally 25."
msgstr ""
#: configure-smtp.php:83
msgid "Secure connection prefix"
msgstr ""
#: configure-smtp.php:85
msgid ""
"Sets connection prefix for secure connections (prefix method must be "
"supported by your PHP install and your SMTP host)"
msgstr ""
#: configure-smtp.php:87
msgid "Use SMTPAuth?"
msgstr ""
#: configure-smtp.php:88
msgid "If checked, you must provide the SMTP username and password below"
msgstr ""
#: configure-smtp.php:90
msgid "SMTP username"
msgstr ""
#: configure-smtp.php:93
msgid "SMTP password"
msgstr ""
#: configure-smtp.php:96
msgid "Wordwrap length"
msgstr ""
#: configure-smtp.php:97
msgid ""
"Sets word wrapping on the body of the message to a given number of "
"characters."
msgstr ""
#: configure-smtp.php:100
msgid "Sender e-mail"
msgstr ""
#: configure-smtp.php:101
msgid ""
"Sets the From e-mail address for all outgoing messages. Leave blank to use "
"the WordPress default. This value will be used even if you don't enable "
"SMTP. NOTE: This may not take effect depending on your mail server and "
"settings, especially if using SMTPAuth (such as for GMail)."
msgstr ""
#: configure-smtp.php:103
msgid "Sender name"
msgstr ""
#: configure-smtp.php:104
msgid ""
"Sets the From name for all outgoing messages. Leave blank to use the "
"WordPress default. This value will be used even if you don't enable SMTP."
msgstr ""
#: configure-smtp.php:132
msgid "Configure SMTP Settings"
msgstr ""
#: configure-smtp.php:133
msgid "test"
msgstr ""
#: configure-smtp.php:135
msgid ""
"SMTP mailing is currently <strong>NOT ENABLED</strong> because no SMTP host "
"has been specified."
msgstr ""
#: configure-smtp.php:136
#, php-format
msgid ""
"After you have configured your SMTP settings, use the %s to send a test "
"message to yourself."
msgstr ""
#: configure-smtp.php:145
msgid ""
"Be sure to specify your GMail email address (with the @gmail.com) as the "
"SMTP username, and your GMail password as the SMTP password."
msgstr ""
#: configure-smtp.php:189
#, php-format
msgid ""
"Hi, this is the %s plugin e-mailing you a test message from your WordPress "
"blog."
msgstr ""
#: configure-smtp.php:191
#, php-format
msgid "This message was sent with this time-stamp: %s"
msgstr ""
#: configure-smtp.php:193
msgid "Congratulations! Your blog is properly configured to send e-mail."
msgstr ""
#: configure-smtp.php:194
msgid "Test message from your WordPress blog"
msgstr ""
#: configure-smtp.php:199
msgid "An error was encountered while trying to send the test e-mail."
msgstr ""
#: configure-smtp.php:206
msgid "Test e-mail sent."
msgstr ""
#: configure-smtp.php:207
#, php-format
msgid "The body of the e-mail includes this time-stamp: %s."
msgstr ""
#: configure-smtp.php:221
msgid "Send A Test"
msgstr ""
#: configure-smtp.php:222
msgid ""
"Click the button below to send a test email to yourself to see if things are "
"working. Be sure to save any changes you made to the form above before "
"sending the test e-mail. Bear in mind it may take a few minutes for the e-"
"mail to wind its way through the internet."
msgstr ""
#: configure-smtp.php:223
#, php-format
msgid "This e-mail will be sent to your e-mail address, %s."
msgstr ""
#: configure-smtp.php:228
msgid "Send test e-mail"
msgstr ""
#. Plugin URI of the plugin/theme
msgid "http://coffee2code.com/wp-plugins/configure-smtp/"
msgstr ""
#. Description of the plugin/theme
msgid ""
"Configure SMTP mailing in WordPress, including support for sending e-mail "
"via SSL/TLS (such as GMail)."
msgstr ""
#. Author of the plugin/theme
msgid "Scott Reilly"
msgstr ""
#. Author URI of the plugin/theme
msgid "http://coffee2code.com"
msgstr ""

View File

@ -0,0 +1,141 @@
=== Configure SMTP ===
Contributors: coffee2code
Donate link: http://coffee2code.com/donate
Tags: email, smtp, gmail, sendmail, wp_mail, phpmailer, outgoing mail, tls, ssl, security, privacy, wp-phpmailer, coffee2code
Requires at least: 2.8
Tested up to: 3.0.1
Stable tag: 3.0.1
Version: 3.0.1
Configure SMTP mailing in WordPress, including support for sending e-mail via SSL/TLS (such as GMail).
== Description ==
Configure SMTP mailing in WordPress, including support for sending e-mail via SSL/TLS (such as GMail).
This plugin is the renamed, rewritten, and updated version of the wpPHPMailer plugin.
Use this plugin to customize the SMTP mailing system used by default by WordPress to handle *outgoing* e-mails. It offers you the ability to specify:
* SMTP host name
* SMTP port number
* If SMTPAuth (authentication) should be used.
* SMTP username
* SMTP password
* If the SMTP connection needs to occur over ssl or tls
In addition, you can instead indicate that you wish to use GMail to handle outgoing e-mail, in which case the above settings are automatically configured to values appropriate for GMail, though you'll need to specify your GMail e-mail (including the "@gmail.com") and password.
Regardless of whether SMTP is enabled, the plugin provides you the ability to define the name and e-mail of the 'From:' field for all outgoing e-mails.
A simple test button is also available that allows you to send a test e-mail to yourself to check if sending e-mail has been properly configured for your blog.
== Installation ==
1. Unzip `configure-smtp.zip` inside the `/wp-content/plugins/` directory (or install via the built-in WordPress plugin installer)
1. Activate the plugin through the 'Plugins' admin menu in WordPress
1. Click the plugin's `Settings` link next to its `Deactivate` link (still on the Plugins page), or click on the `Settings` -> `SMTP` link, to go to the plugin's admin settings page. Optionally customize the settings (to configure it if the defaults aren't valid for your situation).
1. (optional) Use the built-in test to see if your blog can properly send out e-mails.
== Frequently Asked Questions ==
= I am already able to receive e-mail sent by my blog, so would I have any use or need for this plugin? =
Most likely, no. Not unless you have a preference for having your mail sent out via a different SMTP server, such as GMail.
= How do I find out my SMTP host, and/or if I need to use SMTPAuth and what my username and password for that are? =
Check out the settings for your local e-mail program. More than likely that is configured to use an outgoing SMTP server. Otherwise, contact your host or someone more intimately knowledgeable about your situation.
= I've sent out a few test e-mails using the test button after having tried different values for some of the settings; how do I know which one worked? =
If your settings worked, you should receive the test e-mail at the e-mail address associated with your WordPress blog user account. That e-mail contains a time-stamp which was reported to you by the plugin when the e-mail was sent. If you are trying out various setting values, be sure to record what your settings were and what the time-stamp was when sending with those settings.
== Screenshots ==
1. A screenshot of the plugin's admin settings page.
== Changelog ==
= 3.0.1 =
* Update plugin framework to 017 to use password input field instead of text field for SMTP password
= 3.0 =
* Re-implementation by extending C2C_Plugin_016, which among other things adds support for:
* Reset of options to default values
* Better sanitization of input values
* Offload of core/basic functionality to generic plugin framework
* Additional hooks for various stages/places of plugin operation
* Easier localization support
* Add error checking and reporting when attempting to send test e-mail
* Don't configure the mailer to use SMTP if no host is provided
* Fix localization support
* Store plugin instance in global variable, $c2c_configure_smtp, to allow for external manipulation
* Rename class from 'ConfigureSMTP' to 'c2c_ConfigureSMTP'
* Remove docs from top of plugin file (all that and more are in readme.txt)
* Note compatibility with WP 3.0+
* Minor tweaks to code formatting (spacing)
* Add Upgrade Notice section to readme.txt
* Add PHPDoc documentation
* Add package info to top of file
* Update copyright date
* Remove trailing whitespace
* Update screenshot
* Update .pot file
= 2.7 =
* Fix to prevent HTML entities from appearing in the From name value in outgoing e-mails
* Added full support for localization
* Added .pot file
* Noted that overriding the From e-mail value may not take effect depending on mail server and settings, particular if SMTPAuth is used (i.e. GMail)
* Changed invocation of plugin's install function to action hooked in constructor rather than in global space
* Update object's option buffer after saving changed submitted by user
* Miscellaneous tweaks to update plugin to my current plugin conventions
* Noted compatibility with WP2.9+
* Dropped compatibility with versions of WP older than 2.8
* Updated readme.txt
* Updated copyright date
= 2.6 =
* Now show settings page JS in footer, and only on the admin settings page
* Removed hardcoded path to plugins dir
* Changed permission check
* Minor reformatting (added spaces)
* Tweaked readme.txt
* Removed compatibility with versions of WP older than 2.6
* Noted compatibility with WP 2.8+
= 2.5 =
* NEW
* Added support for GMail, including configuring the various settings to be appropriate for GMail
* Added support for SMTPSecure setting (acceptable values of '', 'ssl', or 'tls')
* Added "Settings" link next to "Activate"/"Deactivate" link next to the plugin on the admin plugin listings page
* CHANGED
* Tweaked plugin's admin options page to conform to newer WP 2.7 style
* Tweaked test e-mail subject and body
* Removed the use_smtp option since WP uses SMTP by default, the plugin can't help you if it isn't using SMTP already, and the plugin should just go ahead and apply if it is active
* Updated description, installation instructions, extended description, copyright
* Extended compatibility to WP 2.7+
* Facilitated translation of some text
* FIXED
* Fixed bug where specified wordwrap value wasn't taken into account
= 2.0 =
* Initial release after rewrite from wpPHPMailer
= pre-2.0 =
* Earlier versions of this plugin existed as my wpPHPMailer plugin, which due to the inclusion of PHPMailer within WordPress's core and necessary changes to the plugin warranted a rebranding/renaming.
== Upgrade Notice ==
= 3.0.1 =
Minor update. Use password input field for SMTP password instead of regular text input field.
= 3.0 =
Recommended update! This release includes a major re-implementation, bug fixes, localization support, and more.

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -0,0 +1,213 @@
=== Contact Form 7 Dynamic Text Extension ===
Contributors: sevenspark
Donate link: http://bit.ly/bVogDN
Tags: Contact Form 7, Contact, Contact Form, dynamic, text, input, GET, POST, title, slug
Requires at least: 2.9
Tested up to: 3.0.4
Stable tag: 1.0.4.2
This plugin provides 2 new tag types for the Contact Form 7 Plugin. It allows the dynamic generation of content for a text input box via any shortcode.
It also offers dynamic hidden field functionality, which can be utilized to dynamically set the Email Recipient (To:) address.
== Description ==
Contact Form 7 is an excellent WordPress plugin, and the CF7 DTX Plugin makes it even more awesome by adding dynamic content capabilities.
While default values in Contact Form 7 are static. CF7 DTX lets you create pre-populated fields based on other values. Some examples might include:
* Auto-filling a URL
* Auto-filling a Post ID, title, or slug
* Pre-populating a Product Number
* Referencing other content on the site
* Populating with post info
* Populating with user info
* Populating with custom fields
* Any value you can write a shortcode for
There are many more case-specific examples. I searched for a solution, and there are some decent hacks out there. Many of them are
explored in this forum topic:
[Contact Form 7 Input Fields Values as PHP Get-Viarables](http://wordpress.org/support/topic/contact-form-7-input-fields-values-as-php-get-viarables).
However, they all involved hacking the current Contact Form 7 code, which means next time the plugin is updated their edits will be
overwritten. That's bad.
This Dynamic Text Extension plugin provides a more elegant solution that leaves the Contact Form 7 Plugin intact.
= WHAT DOES IT DO? =
This plugin provides a new tag type for the Contact Form 7 Plugin. It allows the dynamic generation of content for a text input box via any shortcode.
For example, it comes with several built-in shortcodes that will allow the Contact Form to be populated from any $_GET PHP variable or any info from the
get_bloginfo() function, among others. See below for included shortcodes.
= HOW TO USE IT =
After installing and activating the plugin, the Contact Form 7 tag generator will have 2 new tag types: Dynamic Text Field and Dynamic Hidden Field. Most of the options will be
familiar to Contact Form 7 users. There are two important fields:
**Dynamic Value**
This field takes a shortcode, with two important provisions:
1. The shortcode should NOT include the normal square brackets ([ and ]). So, instead of [CF7_GET key='value'] you would use CF7_GET key='value' .
2. Any parameters in the shortcode must use single quotes. That is: CF7_GET key='value' and not CF7_GET key="value"
**Uneditable Option**
As these types of fields should often remain uneditable by the user, there is a checkbox to turn this option on (Not applicable for hidden fields).
= INCLUDED SHORTCODES =
The plugin includes 2 basic shortcodes for use with the Dynamic Text extension. You can write your own as well - any shortcode will work
**PHP GET Variables**
Want to use a variable from the PHP GET array? Just use the CF7_GET shortcode. For example, if you want to get the foo parameter from the url
http://mysite.com?foo=bar
Enter the following into the "Dynamic Value" input
CF7_GET key='foo'
Your Content Form 7 Tag will look something like this:
[dynamictext dynamicname "CF7_GET key='foo'"]
Your form's dynamicname text input will then be pre-populated with the value of foo, in this case, bar
**PHP POST Variables**
New in version 1.0.3!
Grab variables from the $_POST array. The shortcode is much like the GET shortcode:
CF7_POST key='foo'
Your Content Form 7 Tag will look something like this:
[dynamictext dynamicname "CF7_POST key='foo'"]
**Blog Info**
Want to grab some information from your blog like the URL or the sitename? Use the CF7_bloginfo shortcode. For example, to get the site's URL:
Enter the following into the "Dynamic Value" input
CF7_bloginfo show='url'
Your Content Form 7 Tag will look something like this:
[dynamictext dynamicname "CF7_bloginfo show='url'"]
Your form's dynamicname text input will then be pre-populated with your site's URL
**Post Info**
New in version 1.0.3!
Retrieve information about the current post/page (that the contact form is displayed on). The shortcode works as follows:
CF7_get_post_var key='title' <-- retrieves the Post's Title
CF7_get_post_var key='slug' <-- retrieves the Post's Slug
You can also retrieve any parameter from the $post object. Just set that as the key value, for example 'post_date'
The Contact Form 7 Tag would look like:
[dynamictext dynamicname "CF7_get_post_var key='title'"]
**Current URL**
New in version 1.0.3!
Retrieve the current URL. The shortcode takes no parameters:
CF7_URL
So your Contact Form 7 Tag would look like:
[dynamictext dynamicname "CF7_URL"]
**Custom Fields**
New in version 1.0.4!
Retrieve custom fields from the current post/page. Just set the custom field as the key in the shortcode.
The dynamic value input becomes:
CF7_get_custom_field key='my_custom_field'
And the tag looks like this:
[dynamictext dynamicname "CF7_get_custom_field key='my_custom_field'"]
For the purposes of including an email address, you can obfuscate the custom field value by setting obfuscate='on' in the shortcode.
**Current User Info**
Get data about the current user - assuming they are logged in. Defaults to user name, but you can set the key to any valid value in
http://codex.wordpress.org/Function_Reference/get_currentuserinfo
CF7_get_current_user
[dynamictext dynamicname "CF7_get_current_user"]
Like the Dynamic Text Extension? Please consider supporting its development by [Donating](http://bit.ly/bVogDN).
Or check out my upcoming premium plugin, [UberMenu - WordPress Mega Menu Plugin](http://wpmegamenu.com)
== Installation ==
This section describes how to install the plugin and get it working.
1. Download and install the Contact Form 7 Plugin located at http://wordpress.org/extend/plugins/contact-form-7/
1. Upload the plugin folder to the '/wp-content/plugins/' directory
1. Activate the plugin through the 'Plugins' menu in WordPress
1. You will now have a "Dynamic Text" tag option in the Contact Form 7 tag generator
== Frequently Asked Questions ==
None. Yet.
== Screenshots ==
1. The new Dynamic Text Field options.
== Changelog ==
= 1.0.4.2 =
* Fixed a bug that created repeating square brackets around dynamic text values in cases where the form doesn't validate and JavaScript is deactivated.
= 1.0.4.1 =
* Removed trailing whitespace to fix "Headers already sent" errors
= 1.0.4 =
* Added Current User Info shortcode
* Added Post Custom Field shortcode (with obfuscation support)
* Added Hidden Field capability
= 1.0.3 =
* Added $_POST shortcode
* Added current post/page variable shortcode
* Added current URL shortcode
= 1.0.2 =
* Fixed administrative control panel dependency issue
= 1.0.1 =
* Fixed dependency issue.
== Upgrade Notice ==
1.0.4.2 fixes a bug that occurs when JavaScript is disabled and a form item doesn't validate on the first try
1.0.4.1 fixes a "Headers already sent" error that can occur for some users.
1.0.4 upgrade includes hidden field capability and two new shortcodes - current user info and custom post fields.

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -0,0 +1,492 @@
<?php
/*
Plugin Name: Contact Form 7 - Dynamic Text Extension
Plugin URI: http://sevenspark.com/wordpress-plugins/contact-form-7-dynamic-text-extension
Description: Provides a dynamic text field that accepts any shortcode to generate the content. Requires Contact Form 7
Version: 1.0.4.2
Author: Chris Mavricos, SevenSpark
Author URI: http://sevenspark.com
License: GPL2
*/
/* Copyright 2010-2011 Chris Mavricos, SevenSpark (email : chris@sevenspark.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
** A base module for [dynamictext], [dynamictext*]
**/
function wpcf7_dynamictext_init(){
if(function_exists('wpcf7_add_shortcode')){
/* Shortcode handler */
wpcf7_add_shortcode( 'dynamictext', 'wpcf7_dynamictext_shortcode_handler', true );
wpcf7_add_shortcode( 'dynamictext*', 'wpcf7_dynamictext_shortcode_handler', true );
wpcf7_add_shortcode( 'dynamichidden', 'wpcf7_dynamichidden_shortcode_handler', true );
}
add_filter( 'wpcf7_validate_dynamictext', 'wpcf7_dynamictext_validation_filter', 10, 2 );
add_filter( 'wpcf7_validate_dynamictext*', 'wpcf7_dynamictext_validation_filter', 10, 2 );
add_action( 'admin_init', 'wpcf7_add_tag_generator_dynamictext', 15 );
add_action( 'admin_init', 'wpcf7_add_tag_generator_dynamichidden', 16 );
}
add_action( 'plugins_loaded', 'wpcf7_dynamictext_init');
/*************************************************************
* DynamicText Shortcode
*************************************************************/
function wpcf7_dynamictext_shortcode_handler( $tag ) {
global $wpcf7_contact_form;
if ( ! is_array( $tag ) )
return '';
$type = $tag['type'];
$name = $tag['name'];
$options = (array) $tag['options'];
$values = (array) $tag['values'];
if ( empty( $name ) )
return '';
$atts = '';
$id_att = '';
$class_att = '';
$size_att = '';
$maxlength_att = '';
$tabindex_att = '';
$class_att .= ' wpcf7-text';
if ( 'dynamictext*' == $type )
$class_att .= ' wpcf7-validates-as-required';
foreach ( $options as $option ) {
if ( preg_match( '%^id:([-0-9a-zA-Z_]+)$%', $option, $matches ) ) {
$id_att = $matches[1];
} elseif ( preg_match( '%^class:([-0-9a-zA-Z_]+)$%', $option, $matches ) ) {
$class_att .= ' ' . $matches[1];
} elseif ( preg_match( '%^([0-9]*)[/x]([0-9]*)$%', $option, $matches ) ) {
$size_att = (int) $matches[1];
$maxlength_att = (int) $matches[2];
} elseif ( preg_match( '%^tabindex:(\d+)$%', $option, $matches ) ) {
$tabindex_att = (int) $matches[1];
}
}
if ( $id_att )
$atts .= ' id="' . trim( $id_att ) . '"';
if ( $class_att )
$atts .= ' class="' . trim( $class_att ) . '"';
if ( $size_att )
$atts .= ' size="' . $size_att . '"';
else
$atts .= ' size="40"'; // default size
if ( $maxlength_att )
$atts .= ' maxlength="' . $maxlength_att . '"';
if ( '' !== $tabindex_att )
$atts .= sprintf( ' tabindex="%d"', $tabindex_att );
// Value
if ( is_a( $wpcf7_contact_form, 'WPCF7_ContactForm' ) && $wpcf7_contact_form->is_posted() ) {
if ( isset( $_POST['_wpcf7_mail_sent'] ) && $_POST['_wpcf7_mail_sent']['ok'] )
$value = '';
else
$value = stripslashes_deep( $_POST[$name] );
} else {
$value = isset( $values[0] ) ? $values[0] : '';
}
$scval = do_shortcode('['.$value.']');
if($scval != '['.$value.']') $value = $scval;
//echo '<pre>'; print_r($options);echo '</pre>';
$readonly = '';
if(in_array('uneditable', $options)){
$readonly = 'readonly="readonly"';
}
$html = '<input type="text" name="' . $name . '" value="' . esc_attr( $value ) . '"' . $atts . ' '. $readonly.' />';
$validation_error = '';
if ( is_a( $wpcf7_contact_form, 'WPCF7_ContactForm' ) )
$validation_error = $wpcf7_contact_form->validation_error( $name );
$html = '<span class="wpcf7-form-control-wrap ' . $name . '">' . $html . $validation_error . '</span>';
return $html;
}
/* Validation filter */
function wpcf7_dynamictext_validation_filter( $result, $tag ) {
global $wpcf7_contact_form;
$type = $tag['type'];
$name = $tag['name'];
$_POST[$name] = trim( strtr( (string) $_POST[$name], "\n", " " ) );
if ( 'dynamictext*' == $type ) {
if ( '' == $_POST[$name] ) {
$result['valid'] = false;
$result['reason'][$name] = $wpcf7_contact_form->message( 'invalid_required' );
}
}
return $result;
}
/* Tag generator */
function wpcf7_add_tag_generator_dynamictext() {
if(function_exists('wpcf7_add_tag_generator')){
wpcf7_add_tag_generator( 'dynamictext', __( 'Dynamic Text field', 'wpcf7' ),
'wpcf7-tg-pane-dynamictext', 'wpcf7_tg_pane_dynamictext_' );
}
}
function wpcf7_tg_pane_dynamictext_( &$contact_form ) {
wpcf7_tg_pane_dynamictext( 'dynamictext' );
}
function wpcf7_tg_pane_dynamictext( $type = 'dynamictext' ) {
?>
<div id="wpcf7-tg-pane-<?php echo $type; ?>" class="hidden">
<form action="">
<table>
<tr><td><input type="checkbox" name="required" />&nbsp;<?php echo esc_html( __( 'Required field?', 'wpcf7' ) ); ?></td></tr>
<tr><td><?php echo esc_html( __( 'Name', 'wpcf7' ) ); ?><br /><input type="text" name="name" class="tg-name oneline" /></td><td></td></tr>
</table>
<table>
<tr>
<td><code>id</code> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br />
<input type="text" name="id" class="idvalue oneline option" /></td>
<td><code>class</code> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br />
<input type="text" name="class" class="classvalue oneline option" /></td>
</tr>
<tr>
<td><code>size</code> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br />
<input type="text" name="size" class="numeric oneline option" /></td>
<td><code>maxlength</code> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br />
<input type="text" name="maxlength" class="numeric oneline option" /></td>
</tr>
<tr>
<td>
<input type="checkbox" name="uneditable" class="option" />&nbsp;<?php echo esc_html( __( "Make this field Uneditable", 'wpcf7' ) ); ?><br />
</td>
<td><?php echo esc_html( __( 'Dynamic value', 'wpcf7' ) ); ?> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br /><input type="text" name="values" class="oneline" />
<?php echo esc_html( __( 'You can enter any short code. Just leave out the square brackets ([]) and only use single quotes (\' not ")', 'wpcf7' )); ?>
</td>
</tr>
</table>
<div class="tg-tag"><?php echo esc_html( __( "Copy this code and paste it into the form left.", 'wpcf7' ) ); ?><br /><input type="text" name="<?php echo $type; ?>" class="tag" readonly="readonly" onfocus="this.select()" /></div>
<div class="tg-mail-tag"><?php echo esc_html( __( "And, put this code into the Mail fields below.", 'wpcf7' ) ); ?><br /><span class="arrow">&#11015;</span>&nbsp;<input type="text" class="mail-tag" readonly="readonly" onfocus="this.select()" /></div>
</form>
</div>
<?php
}
/*************************************************************
* DynamicHidden Shortcode
*************************************************************/
function wpcf7_dynamichidden_shortcode_handler( $tag ) {
global $wpcf7_contact_form;
if ( ! is_array( $tag ) )
return '';
$type = $tag['type'];
$name = $tag['name'];
$options = (array) $tag['options'];
$values = (array) $tag['values'];
if ( empty( $name ) )
return '';
$atts = '';
$id_att = '';
$class_att = '';
$size_att = '';
$maxlength_att = '';
$tabindex_att = '';
$class_att .= ' wpcf7-text';
foreach ( $options as $option ) {
if ( preg_match( '%^id:([-0-9a-zA-Z_]+)$%', $option, $matches ) ) {
$id_att = $matches[1];
}
}
if ( $id_att )
$atts .= ' id="' . trim( $id_att ) . '"';
// Value
if ( is_a( $wpcf7_contact_form, 'WPCF7_ContactForm' ) && $wpcf7_contact_form->is_posted() ) {
if ( isset( $_POST['_wpcf7_mail_sent'] ) && $_POST['_wpcf7_mail_sent']['ok'] )
$value = '';
else
$value = stripslashes_deep( $_POST[$name] );
} else {
$value = isset( $values[0] ) ? $values[0] : '';
}
$scval = do_shortcode('['.$value.']');
if($scval != '['.$value.']') $value = $scval;
//echo '<pre>'; print_r($options);echo '</pre>';
$html = '<input type="hidden" name="' . $name . '" value="' . esc_attr( $value ) . '"' . $atts . ' />';
//No need to validate, it's a hidden field - we could validate by checking the value hasn't changed, but that seems overkill I think
//$validation_error = '';
//if ( is_a( $wpcf7_contact_form, 'WPCF7_ContactForm' ) )
// $validation_error = $wpcf7_contact_form->validation_error( $name );
$html = '<span class="wpcf7-form-control-wrap ' . $name . '">' . $html . $validation_error . '</span>';
return $html;
}
/* Tag generator */
function wpcf7_add_tag_generator_dynamichidden() {
if(function_exists('wpcf7_add_tag_generator')){
wpcf7_add_tag_generator( 'dynamichidden', __( 'Dynamic Hidden field', 'wpcf7' ),
'wpcf7-tg-pane-dynamichidden', 'wpcf7_tg_pane_dynamichidden_' );
}
}
function wpcf7_tg_pane_dynamichidden_( &$contact_form ) {
wpcf7_tg_pane_dynamichidden( 'dynamichidden' );
}
function wpcf7_tg_pane_dynamichidden( $type = 'dynamichidden' ) {
?>
<div id="wpcf7-tg-pane-<?php echo $type; ?>" class="hidden">
<form action="">
<table>
<tr><td><?php echo esc_html( __( 'Name', 'wpcf7' ) ); ?><br /><input type="text" name="name" class="tg-name oneline" /></td><td></td></tr>
</table>
<table>
<tr>
<td><code>id</code> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br />
<input type="text" name="id" class="idvalue oneline option" /></td>
</tr>
<tr>
<td><?php echo esc_html( __( 'Dynamic value', 'wpcf7' ) ); ?> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br /><input type="text" name="values" class="oneline" />
<?php echo esc_html( __( 'You can enter any short code. Just leave out the square brackets ([]) and only use single quotes (\' not ")', 'wpcf7' )); ?>
</td>
</tr>
</table>
<div class="tg-tag"><?php echo esc_html( __( "Copy this code and paste it into the form left.", 'wpcf7' ) ); ?><br /><input type="text" name="<?php echo $type; ?>" class="tag" readonly="readonly" onfocus="this.select()" /></div>
<div class="tg-mail-tag"><?php echo esc_html( __( "And, put this code into the Mail fields below.", 'wpcf7' ) ); ?><br /><span class="arrow">&#11015;</span>&nbsp;<input type="text" class="mail-tag" readonly="readonly" onfocus="this.select()" /></div>
</form>
</div>
<?php
}
/*****************************************************
* CF7 DTX Included Shortcodes
*
* Used like this:
*
* CF7_GET val='value'
*
* No [] and single quotes ' rather than double "
*
*****************************************************/
/* Insert a $_GET variable */
function cf7_get($atts){
extract(shortcode_atts(array(
'key' => 0,
), $atts));
$value = urldecode($_GET[$key]);
return $value;
}
add_shortcode('CF7_GET', 'cf7_get');
/* See http://codex.wordpress.org/Function_Reference/get_bloginfo */
function cf7_bloginfo($atts){
extract(shortcode_atts(array(
'show' => 'name'
), $atts));
return get_bloginfo($show);
}
add_shortcode('CF7_bloginfo', 'cf7_bloginfo');
/* Insert a $_POST variable (submitted form value)*/
function cf7_post($atts){
extract(shortcode_atts(array(
'key' => -1,
), $atts));
if($key == -1) return '';
$val = $_POST[$key];
return $val;
}
add_shortcode('CF7_POST', 'cf7_post');
/* Insert a $post (Blog Post) Variable */
function cf7_get_post_var($atts){
extract(shortcode_atts(array(
'key' => 'post_title',
), $atts));
switch($key){
case 'slug':
$key = 'post_name';
break;
case 'title':
$key = 'post_title';
break;
}
global $post;
//echo '<pre>'; print_r($post); echo '</pre>';
$val = $post->$key;
return $val;
}
add_shortcode('CF7_get_post_var', 'cf7_get_post_var');
/* Insert the current URL */
function cf7_url(){
$pageURL = 'http';
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
add_shortcode('CF7_URL', 'cf7_url');
/* Insert a Custom Post Field
* New in 1.0.4
*/
function cf7_get_custom_field($atts){
extract(shortcode_atts(array(
'key' => '',
'post_id' => -1,
'obfuscate' => 'off'
), $atts));
if($post_id < 0){
global $post;
if(isset($post)) $post_id = $post->ID;
}
if($post_id < 0 || empty($key)) return '';
$val = get_post_meta($post_id, $key, true);
if($obfuscate == 'on'){
$val = cf7dtx_obfuscate($val);
}
return $val;
}
add_shortcode('CF7_get_custom_field', 'cf7_get_custom_field');
/* Insert information about the current user
* New in 1.0.4
* See http://codex.wordpress.org/Function_Reference/get_currentuserinfo
*/
function cf7_get_current_user($atts){
extract(shortcode_atts(array(
'key' => 'user_login',
), $atts));
global $current_user;
get_currentuserinfo();
$val = $current_user->$key;
return $val;
}
add_shortcode('CF7_get_current_user', 'cf7_get_current_user');
function cf7dtx_obfuscate($val){
$link = '';
foreach(str_split($val) as $letter)
$link .= '&#'.ord($letter).';';
return $link;
}
function cf7dtx_cf7com_links() {
$links = '<div class="cf7com-links">'
. '<a href="' . esc_url_raw( __( 'http://contactform7.com/', 'wpcf7' ) ) . '" target="_blank">'
. esc_html( __( 'Contactform7.com', 'wpcf7' ) ) . '</a>&ensp;'
. '<a href="' . esc_url_raw( __( 'http://contactform7.com/docs/', 'wpcf7' ) ) . '" target="_blank">'
. esc_html( __( 'Docs', 'wpcf7' ) ) . '</a> - '
. '<a href="' . esc_url_raw( __( 'http://contactform7.com/faq/', 'wpcf7' ) ) . '" target="_blank">'
. esc_html( __( 'FAQ', 'wpcf7' ) ) . '</a> - '
. '<a href="' . esc_url_raw( __( 'http://contactform7.com/support/', 'wpcf7' ) ) . '" target="_blank">'
. esc_html( __( 'Support', 'wpcf7' ) ) . '</a>'
. ' - <a href="'. esc_url_raw( __( 'http://sevenspark.com/wordpress-plugins/contact-form-7-dynamic-text-extension', 'wpcf7') )
. '" target="_blank">'.__( 'Dynamic Text Extension' , 'wpcf7').'</a> by <a href="' . esc_url_raw( __( 'http://sevenspark.com', 'wpcf7') ).'" target="_blank">'
. esc_html( __( 'SevenSpark', 'wpcf7' ) ). '</a> <a href="'.esc_url_raw( __('http://bit.ly/bVogDN')).'" target="_blank">'
. esc_html( __( '[Donate]')).'</a>'
. '</div>';
return $links;
}
add_filter('wpcf7_cf7com_links', 'cf7dtx_cf7com_links');
/*function obf($atts){
extract(shortcode_atts(array(
'val' => ''
), $atts));
return $val.' : '. cf7dtx_obfuscate($val);
}
add_shortcode('obf', 'obf');*/

View File

@ -0,0 +1,31 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
interface CF7DBEvalutator {
/**
* Evaluate expression against input data
* @param $data array [ key => value]
* @return boolean result of evaluating $data against expression
*/
public function evaluate(&$data);
}

View File

@ -0,0 +1,189 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CF7DBOptionsManager.php');
/**
* The methods in this class are used to track whether or not the plugin has been installed.
* It writes a value in options to indicate that this plugin is installed.
*
* @author Michael Simpson
*/
abstract class CF7DBInstallIndicator extends CF7DBOptionsManager {
const optionInstalled = '_installed';
const optionVersion = '_version';
/**
* @return bool indicating if the plugin is installed already
*/
public function isInstalled() {
return $this->getOption(self::optionInstalled) == true;
}
/**
* Note in DB that the plugin is installed
* @return null
*/
protected function markAsInstalled() {
return $this->updateOption(self::optionInstalled, true);
}
/**
* Note in DB that the plugin is uninstalled
* @return bool returned form delete_option.
* true implies the plugin was installed at the time of this call,
* false implies it was not.
*/
protected function markAsUnInstalled() {
return $this->deleteOption(self::optionInstalled);
}
/**
* Set a version string in the options. This is useful if you install upgrade and
* need to check if an older version was installed to see if you need to do certain
* upgrade housekeeping (e.g. changes to DB schema).
* @param $version
* @return null
*/
protected function getVersionSaved() {
return $this->getOption(self::optionVersion);
}
/**
* Set a version string in the options.
* need to check if
* @param $version string best practice: use a dot-delimited string like '1.2.3' so version strings can be easily
* compared using version_compare (http://php.net/manual/en/function.version-compare.php)
* @return null
*/
protected function setVersionSaved($version) {
return $this->updateOption(self::optionVersion, $version);
}
/**
* @abstract
* @return string name of the main plugin file that has the header section with
* "Plugin Name", "Version", "Description", "Text Domain", etc.
*/
protected abstract function getMainPluginFileName();
/**
* Get a value for input key in the header section of main plugin file.
* E.g. "Plugin Name", "Version", "Description", "Text Domain", etc.
* @return string if found, otherwise null
*/
public function getPluginHeaderValue($key) {
// Read the string from the comment header of the main plugin file
$data = file_get_contents($this->getPluginDir() . DIRECTORY_SEPARATOR . $this->getMainPluginFileName());
$match = array();
preg_match('/' . $key . ':\s*(\S+)/', $data, $match);
if (count($match) >= 1) {
return $match[1];
}
return null;
}
/**
* If your subclass of this class lives in a different directory,
* override this method with the exact same code. Since __FILE__ will
* be different, you will then get the right dir returned.
* @return string
*/
protected function getPluginDir() {
return dirname(__FILE__);
}
/**
* Version of this code.
* Best practice: define version strings to be easily compared using version_compare()
* (http://php.net/manual/en/function.version-compare.php)
* NOTE: You should manually make this match the SVN tag for your main plugin file 'Version' release and 'Stable tag' in readme.txt
* @return string
*/
public function getVersion() {
return $this->getPluginHeaderValue('Version');
}
/**
* Useful when checking for upgrades, can tell if the currently installed version is earlier than the
* newly installed code. This case indicates that an upgrade has been installed and this is the first time it
* has been activated, so any upgrade actions should be taken.
* @return bool true if the version saved in the options is earlier than the version declared in getVersion().
* true indicates that new code is installed and this is the first time it is activated, so upgrade actions
* should be taken. Assumes that version string comparable by version_compare, examples: '1', '1.1', '1.1.1', '2.0', etc.
*/
public function isInstalledCodeAnUpgrade() {
return $this->isSavedVersionLessThan($this->getVersion());
}
/**
* Used to see if the installed code is an earlier version than the input version
* @param $aVersion string
* @return bool true if the saved version is earlier (by natural order) than the input version
*/
public function isSavedVersionLessThan($aVersion) {
return $this->isVersionLessThan($this->getVersionSaved(), $aVersion);
}
/**
* Used to see if the installed code is the same or earlier than the input version.
* Useful when checking for an upgrade. If you haven't specified the number of the newer version yet,
* but the last version (installed) was 2.3 (for example) you could check if
* For example, $this->isSavedVersionLessThanEqual('2.3') == true indicates that the saved version is not upgraded
* past 2.3 yet and therefore you would perform some appropriate upgrade action.
* @param $aVersion string
* @return bool true if the saved version is earlier (by natural order) than the input version
*/
public function isSavedVersionLessThanEqual($aVersion) {
return $this->isVersionLessThanEqual($this->getVersionSaved(), $aVersion);
}
/**
* @param $version1 string a version string such as '1', '1.1', '1.1.1', '2.0', etc.
* @param $version2 string a version string such as '1', '1.1', '1.1.1', '2.0', etc.
* @return bool true if version_compare of $versions1 and $version2 shows $version1 as the same or earlier
*/
public function isVersionLessThanEqual($version1, $version2) {
return (version_compare($version1, $version2) <= 0);
}
/**
* @param $version1 string a version string such as '1', '1.1', '1.1.1', '2.0', etc.
* @param $version2 string a version string such as '1', '1.1', '1.1.1', '2.0', etc.
* @return bool true if version_compare of $versions1 and $version2 shows $version1 as earlier
*/
public function isVersionLessThan($version1, $version2) {
return (version_compare($version1, $version2) < 0);
}
/**
* Record the installed version to options.
* This helps track was version is installed so when an upgrade is installed, it should call this when finished
* upgrading to record the new current version
* @return void
*/
protected function saveInstalledVersion() {
$this->setVersionSaved($this->getVersion());
}
}

View File

@ -0,0 +1,405 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Manage options associated with the Plugin.
* 1. Prefix all options so they are saved in the database without name conflict
* 2. Creates a default administration panel to setting options
*
* NOTE: instead of using WP add_option(), update_option() and delete_option,
* use $this->addOption(), updateOption(), and deleteOption() wrapper methods
* because they enforce added a prefix to option names in the database
*
* @author Michael Simpson
*/
class CF7DBOptionsManager {
public function getOptionNamePrefix() {
return get_class($this) . '_';
}
/**
* Define your options meta data here as an array, where each element in the array
* @return array of key=>display-name and/or key=>array(display-name, choice1, choice2, ...)
* key: an option name for the key (this name will be given a prefix when stored in
* the database to ensure it does not conflict with other plugin options)
* value: can be one of two things:
* (1) string display name for displaying the name of the option to the user on a web page
* (2) array where the first element is a display name (as above) and the rest of
* the elements are choices of values that the user can select
* e.g.
* array(
* 'item' => 'Item:', // key => display-name
* 'rating' => array( // key => array ( display-name, choice1, choice2, ...)
* 'CanDoOperationX' => array('Can do Operation X', 'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber'),
* 'Rating:', 'Excellent', 'Good', 'Fair', 'Poor')
*/
public function getOptionMetaData() {
return array();
}
/**
* @return array of string name of options
*/
public function getOptionNames() {
return array_keys($this->getOptionMetaData());
}
/**
* Override this method to initialize options to default values and save to the database with add_option
* @return void
*/
protected function initOptions() {
}
/**
* Cleanup: remove all options from the DB
* @return void
*/
protected function deleteSavedOptions() {
$optionMetaData = $this->getOptionMetaData();
if (is_array($optionMetaData)) {
foreach ($optionMetaData as $aOptionKey => $aOptionMeta) {
$prefixedOptionName = $this->prefix($aOptionKey); // how it is stored in DB
delete_option($prefixedOptionName);
}
}
}
/**
* @return string display name of the plugin to show as a name/title in HTML.
* Just returns the class name. Override this method to return something more readable
*/
public function getPluginDisplayName() {
return get_class($this);
}
/**
* Get the prefixed version input $name suitable for storing in WP options
* Idempotent: if $optionName is already prefixed, it is not prefixed again, it is returned without change
* @param $name string option name to prefix. Defined in settings.php and set as keys of $this->optionMetaData
* @return string
*/
public function prefix($name) {
$optionNamePrefix = $this->getOptionNamePrefix();
if (strpos($name, $optionNamePrefix) === 0) { // 0 but not false
return $name; // already prefixed
}
return $optionNamePrefix . $name;
}
/**
* Remove the prefix from the input $name.
* Idempotent: If no prefix found, just returns what was input.
* @param $name string
* @return string $optionName without the prefix.
*/
public function &unPrefix($name) {
$optionNamePrefix = $this->getOptionNamePrefix();
if (strpos($name, $optionNamePrefix) === 0) {
return substr($name, strlen($optionNamePrefix));
}
return $name;
}
/**
* A wrapper function delegating to WP get_option() but it prefixes the input $optionName
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
* @param $default string default value to return if the option is not set
* @return string the value from delegated call to get_option(), or optional default value
* if option is not set.
*/
public function getOption($optionName, $default = null) {
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
$retVal = get_option($prefixedOptionName);
if (!$retVal && $default) {
$retVal = $default;
}
return $retVal;
}
/**
* A wrapper function delegating to WP delete_option() but it prefixes the input $optionName
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
* @return bool from delegated call to delete_option()
*/
public function deleteOption($optionName) {
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
return delete_option($prefixedOptionName);
}
/**
* A wrapper function delegating to WP add_option() but it prefixes the input $optionName
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
* @param $value mixed the new value
* @return null from delegated call to delete_option()
*/
public function addOption($optionName, $value) {
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
return add_option($prefixedOptionName, $value);
}
/**
* A wrapper function delegating to WP add_option() but it prefixes the input $optionName
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
* @param $value mixed the new value
* @return null from delegated call to delete_option()
*/
public function updateOption($optionName, $value) {
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
return update_option($prefixedOptionName, $value);
}
/**
* A Role Option is an option defined in getOptionMetaData() as a choice of WP standard roles, e.g.
* 'CanDoOperationX' => array('Can do Operation X', 'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber')
* The idea is use an option to indicate what role level a user must minimally have in order to do some operation.
* So if a Role Option 'CanDoOperationX' is set to 'Editor' then users which role 'Editor' or above should be
* able to do Operation X.
* Also see: canUserDoRoleOption()
* @param $optionName
* @return string role name
*/
public function getRoleOption($optionName) {
$roleAllowed = $this->getOption($optionName);
if (!$roleAllowed || $roleAllowed == '') {
$roleAllowed = 'Administrator';
}
return $roleAllowed;
}
/**
* Given a WP role name, return a WP capability which only that role and roles above it have
* http://codex.wordpress.org/Roles_and_Capabilities
* @param $roleName
* @return string a WP capability or '' if unknown input role
*/
protected function roleToCapability($roleName) {
switch ($roleName) {
case 'Super Admin':
return 'manage_options';
case 'Administrator':
return 'manage_options';
case 'Editor':
return 'publish_pages';
case 'Author':
return 'publish_posts';
case 'Contributor':
return 'edit_posts';
case 'Subscriber':
return 'read';
case 'Anyone':
return 'read';
}
return '';
}
/**
* @param $roleName string a standard WP role name like 'Administrator'
* @return bool
*/
public function isUserRoleEqualOrBetterThan($roleName) {
if ('Anyone' == $roleName) {
return true;
}
$capability = $this->roleToCapability($roleName);
return current_user_can($capability);
}
/**
* @param $optionName string name of a Role option (see comments in getRoleOption())
* @return bool indicates if the user has adequate permissions
*/
public function canUserDoRoleOption($optionName) {
$roleAllowed = $this->getRoleOption($optionName);
if ('Anyone' == $roleAllowed) {
return true;
}
return $this->isUserRoleEqualOrBetterThan($roleAllowed);
}
/**
* see: http://codex.wordpress.org/Creating_Options_Pages
* @return void
*/
public function createSettingsMenu() {
$pluginName = $this->getPluginDisplayName();
//create new top-level menu
add_menu_page($pluginName . ' Plugin Settings',
$pluginName,
'administrator',
get_class($this),
array(&$this, 'settingsPage')
/*,plugins_url('/images/icon.png', __FILE__)*/); // if you call 'plugins_url; be sure to "require_once" it
//call register settings function
add_action('admin_init', array(&$this, 'registerSettings'));
}
public function registerSettings() {
$settingsGroup = get_class($this) . '-settings-group';
$optionMetaData = $this->getOptionMetaData();
foreach ($optionMetaData as $aOptionKey => $aOptionMeta) {
register_setting($settingsGroup, $aOptionMeta);
}
}
/**
* Creates HTML for the Administration page to set options for this plugin.
* Override this method to create a customized page.
* @return void
*/
public function settingsPage() {
if (!current_user_can('manage_options')) {
wp_die(__('You do not have sufficient permissions to access this page.', 'contact-form-7-to-database-extension'));
}
$optionMetaData = $this->getOptionMetaData();
// Save Posted Options
if ($optionMetaData != null) {
foreach ($optionMetaData as $aOptionKey => $aOptionMeta) {
if (isset($_POST[$aOptionKey])) {
$this->updateOption($aOptionKey, $_POST[$aOptionKey]);
}
}
}
// HTML for the page
$settingsGroup = get_class($this) . '-settings-group';
?>
<div class="wrap">
<h2><?php _e('System Settings'); ?></h2>
<table class="form-table"><tbody>
<tr><td><?php _e('System'); ?></td><td><?php echo php_uname(); ?></td></tr>
<tr><td><?php _e('PHP Version'); ?></td><td><?php echo phpversion(); ?></td></tr>
<tr><td><?php _e('MySQL Version'); ?></td><td><?php echo $this->getMySqlVersion() ?></td></tr>
</tbody></table>
<h2><?php echo $this->getPluginDisplayName(); echo ' '; _e('Settings', 'contact-form-7-to-database-extension'); ?></h2>
<form method="post" action="">
<?php settings_fields($settingsGroup); ?>
<table class="form-table"><tbody>
<?php
if ($optionMetaData != null) {
foreach ($optionMetaData as $aOptionKey => $aOptionMeta) {
$displayText = is_array($aOptionMeta) ? $aOptionMeta[0] : $aOptionMeta;
$displayText = __($displayText, 'contact-form-7-to-database-extension');
?>
<tr valign="top">
<th scope="row"><p><label for="<?php echo $aOptionKey ?>"><?php echo $displayText ?></label></p></th>
<td>
<?php $this->createFormControl($aOptionKey, $aOptionMeta, $this->getOption($aOptionKey)); ?>
</td>
</tr>
<?php
}
}
?>
</tbody></table>
<p class="submit">
<input type="submit" class="button-primary"
value="<?php _e('Save Changes', 'contact-form-7-to-database-extension') ?>"/>
</p>
</form>
</div>
<?php
}
/**
* Helper-function outputs the correct form element (input tag, select tag) for the given item
* @param $aOptionKey string name of the option (un-prefixed)
* @param $aOptionMeta mixed meta-data for $aOptionKey (either a string display-name or an array(display-name, option1, option2, ...)
* @param $savedOptionValue string current value for $aOptionKey
* @return void
*/
protected function createFormControl($aOptionKey, $aOptionMeta, $savedOptionValue) {
if (is_array($aOptionMeta) && count($aOptionMeta) >= 2) { // Drop-down list
$choices = array_slice($aOptionMeta, 1);
?>
<p><select name="<?php echo $aOptionKey ?>" id="<?php echo $aOptionKey ?>">
<?php
foreach ($choices as $aChoice) {
$selected = ($aChoice == $savedOptionValue) ? "selected" : "";
?>
<option value="<?php echo $aChoice ?>" <?php echo $selected ?>><?php echo $this->getOptionValueI18nString($aChoice) ?></option>
<?php
}
?>
</select></p>
<?php
}
else { // Simple input field
?>
<p><input type="text" name="<?php echo $aOptionKey ?>" id="<?php echo $aOptionKey ?>"
value="<?php echo esc_attr($savedOptionValue) ?>" size="50"/></p>
<?php
}
}
/**
* Override this method and follow its format.
* The purpose of this method is to provide i18n display strings for the values of options.
* For example, you may create a options with values 'true' or 'false'.
* In the options page, this will show as a drop down list with these choices.
* But when the the language is not English, you would like to display different strings
* for 'true' and 'false' while still keeping the value of that option that is actually saved in
* the DB as 'true' or 'false'.
* To do this, follow the convention of defining option values in getOptionMetaData() as canonical names
* (what you want them to literally be, like 'true') and then add each one to the switch statement in this
* function, returning the "__()" i18n name of that string.
* @param $optionValue string
* @return string __($optionValue) if it is listed in this method, otherwise just returns $optionValue
*/
protected function getOptionValueI18nString($optionValue) {
switch ($optionValue) {
case 'true': return __('true', 'contact-form-7-to-database-extension');
case 'false': return __('false', 'contact-form-7-to-database-extension');
}
return $optionValue;
}
/**
* Query MySQL DB for its version
* @return string|false
*/
protected function getMySqlVersion() {
global $wpdb;
$rows = $wpdb->get_results('select version() as mysqlversion');
if (!empty($rows)) {
return $rows[0]->mysqlversion;
}
return false;
}
}

View File

@ -0,0 +1,674 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CF7DBPluginLifeCycle.php');
require_once('CFDBShortcodeTable.php');
require_once('CFDBShortcodeDataTable.php');
require_once('CFDBShortcodeValue.php');
require_once('CFDBShortcodeCount.php');
require_once('CFDBShortcodeJson.php');
require_once('CFDBShortcodeHtml.php');
require_once('CFDBShortcodeExportUrl.php');
/**
* Implementation for CF7DBPluginLifeCycle.
*/
class CF7DBPlugin extends CF7DBPluginLifeCycle {
public function getPluginDisplayName() {
return 'Contact Form to DB Extension';
}
protected function getMainPluginFileName() {
return 'contact-form-7-db.php';
}
public function getOptionMetaData() {
return array(
//'_version' => array('Installed Version'), // For testing upgrades
'Donated' => array(__('I have donated to this plugin', 'contact-form-7-to-database-extension'), 'false', 'true'),
'IntegrateWithCF7' => array(__('Capture form submissions from Contact Form 7 Plugin', 'contact-form-7-to-database-extension'), 'true', 'false'),
'IntegrateWithFSCF' => array(__('Capture form submissions Fast Secure Contact Form Plugin', 'contact-form-7-to-database-extension'), 'true', 'false'),
'CanSeeSubmitData' => array(__('Can See Submission data', 'contact-form-7-to-database-extension'),
'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber', 'Anyone'),
'CanSeeSubmitDataViaShortcode' => array(__('Can See Submission when using shortcodes', 'contact-form-7-to-database-extension'),
'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber', 'Anyone'),
'CanChangeSubmitData' => array(__('Can Edit/Delete Submission data', 'contact-form-7-to-database-extension'),
'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber'),
'MaxRows' => array(__('Maximum number of rows to retrieve from the DB for the Admin display', 'contact-form-7-to-database-extension')),
'UseDataTablesJS' => array(__('Use Javascript-enabled tables in Admin Database page', 'contact-form-7-to-database-extension'), 'true', 'false'),
'ShowLineBreaksInDataTable' => array(__('Show line breaks in submitted data table', 'contact-form-7-to-database-extension'), 'true', 'false'),
'UseCustomDateTimeFormat' => array(__('Use Custom Date-Time Display Format (below)', 'contact-form-7-to-database-extension'), 'true', 'false'),
'SubmitDateTimeFormat' => array('<a target="_blank" href="http://php.net/manual/en/function.date.php">' . __('Date-Time Display Format', 'contact-form-7-to-database-extension') . '</a>'),
'ShowFileUrlsInExport' => array(__('Export URLs instead of file names for uploaded files', 'contact-form-7-to-database-extension'), 'false', 'true'),
'NoSaveFields' => array(__('Do not save <u>fields</u> in DB named (comma-separated list, no spaces)', 'contact-form-7-to-database-extension')),
'NoSaveForms' => array(__('Do not save <u>forms</u> in DB named (comma-separated list, no spaces)', 'contact-form-7-to-database-extension')),
'SaveCookieData' => array(__('Save Cookie Data with Form Submissions', 'contact-form-7-to-database-extension'), 'false', 'true'),
'SaveCookieNames' => array(__('Save only cookies in DB named (comma-separated list, no spaces, and above option must be set to true)', 'contact-form-7-to-database-extension')),
'ShowQuery' => array(__('Show the query used to display results', 'contact-form-7-to-database-extension'), 'false', 'true'),
'DropOnUninstall' => array(__('Drop this plugin\'s Database table on uninstall', 'contact-form-7-to-database-extension'), 'true', 'false'),
//'SubmitTableNameOverride' => array(__('Use this table to store submission data rather than the default (leave blank for default)', 'contact-form-7-to-database-extension'))
);
}
protected function getOptionValueI18nString($optionValue) {
switch ($optionValue) {
case 'true':
return __('true', 'contact-form-7-to-database-extension');
case 'false':
return __('false', 'contact-form-7-to-database-extension');
case 'Administrator':
return __('Administrator', 'contact-form-7-to-database-extension');
case 'Editor':
return __('Editor', 'contact-form-7-to-database-extension');
case 'Author':
return __('Author', 'contact-form-7-to-database-extension');
case 'Contributor':
return __('Contributor', 'contact-form-7-to-database-extension');
case 'Subscriber':
return __('Subscriber', 'contact-form-7-to-database-extension');
case 'Anyone':
return __('Anyone', 'contact-form-7-to-database-extension');
}
return $optionValue;
}
public function upgrade() {
global $wpdb;
$upgradeOk = true;
$savedVersion = $this->getVersionSaved();
if (!$savedVersion) { // Prior to storing version in options (pre 1.2)
// DB Schema Upgrade to support i18n using UTF-8
$tableName = $this->getSubmitsTableName();
$wpdb->show_errors();
$upgradeOk &= false !== $wpdb->query("ALTER TABLE `$tableName` MODIFY form_name VARCHAR(127) CHARACTER SET utf8");
$upgradeOk &= false !== $wpdb->query("ALTER TABLE `$tableName` MODIFY field_name VARCHAR(127) CHARACTER SET utf8");
$upgradeOk &= false !== $wpdb->query("ALTER TABLE `$tableName` MODIFY field_value longtext CHARACTER SET utf8");
$wpdb->hide_errors();
// Remove obsolete options
$this->deleteOption('_displayName');
$this->deleteOption('_metatdata');
$savedVersion = '1.0';
}
if ($this->isVersionLessThan($savedVersion, '1.8')) {
if ($this->isVersionLessThan($savedVersion, '1.4.5')) {
if ($this->isVersionLessThan($savedVersion, '1.3.1')) {
// Version 1.3.1 update
$tableName = $this->getSubmitsTableName();
$wpdb->show_errors();
$upgradeOk &= false !== $wpdb->query("ALTER TABLE `$tableName` ADD COLUMN `field_order` INTEGER");
$upgradeOk &= false !== $wpdb->query("ALTER TABLE `$tableName` ADD COLUMN `file` LONGBLOB");
$upgradeOk &= false !== $wpdb->query("ALTER TABLE `$tableName` ADD INDEX `submit_time_idx` ( `submit_time` )");
$wpdb->hide_errors();
}
// Version 1.4.5 update
if (!$this->getOption('CanSeeSubmitDataViaShortcode')) {
$this->addOption('CanSeeSubmitDataViaShortcode', 'Anyone');
}
// Misc
$submitDateTimeFormat = $this->getOption('SubmitDateTimeFormat');
if (!$submitDateTimeFormat || $submitDateTimeFormat == '') {
$this->addOption('SubmitDateTimeFormat', 'Y-m-d H:i:s P');
}
}
// Version 1.8 update
if (!$this->getOption('MaxRows')) {
$this->addOption('MaxRows', '100');
}
$tableName = $this->getSubmitsTableName();
$wpdb->show_errors();
/* $upgradeOk &= false !== */ $wpdb->query("ALTER TABLE `$tableName` MODIFY COLUMN submit_time DECIMAL(16,4) NOT NULL");
/* $upgradeOk &= false !== */ $wpdb->query("ALTER TABLE `$tableName` ADD INDEX `form_name_idx` ( `form_name` )");
/* $upgradeOk &= false !== */ $wpdb->query("ALTER TABLE `$tableName` ADD INDEX `form_name_field_name_idx` ( `form_name`, `field_name` )");
$wpdb->hide_errors();
}
// Post-upgrade, set the current version in the options
$codeVersion = $this->getVersion();
if ($upgradeOk && $savedVersion != $codeVersion) {
$this->saveInstalledVersion();
}
}
/**
* Called by install()
* You should: Prefix all table names with $wpdb->prefix
* Also good: additionally use the prefix for this plugin:
* $table_name = $wpdb->prefix . $this->prefix('MY_TABLE');
* @return void
*/
protected function installDatabaseTables() {
global $wpdb;
$tableName = $this->getSubmitsTableName();
$wpdb->show_errors();
$wpdb->query("CREATE TABLE IF NOT EXISTS `$tableName` (
`submit_time` DECIMAL(16,4) NOT NULL,
`form_name` VARCHAR(127) CHARACTER SET utf8,
`field_name` VARCHAR(127) CHARACTER SET utf8,
`field_value` LONGTEXT CHARACTER SET utf8,
`field_order` INTEGER,
`file` LONGBLOB)");
$wpdb->query("ALTER TABLE `$tableName` ADD INDEX `submit_time_idx` ( `submit_time` )");
$wpdb->query("ALTER TABLE `$tableName` ADD INDEX `form_name_idx` ( `form_name` )");
$wpdb->query("ALTER TABLE `$tableName` ADD INDEX `form_name_field_name_idx` ( `form_name`, `field_name` )");
$wpdb->hide_errors();
}
/**
* Called by uninstall()
* You should: Prefix all table names with $wpdb->prefix
* Also good: additionally use the prefix for this plugin:
* $table_name = $wpdb->prefix . $this->prefix('MY_TABLE');
* @return void
*/
protected function unInstallDatabaseTables() {
if ('true' == $this->getOption('DropOnUninstall', 'true')) {
global $wpdb;
$tableName = $this->getSubmitsTableName();
$wpdb->query("DROP TABLE IF EXISTS `$tableName`");
// $tables = array('SUBMITS');
// foreach ($tables as $aTable) {
// $tableName = $this->prefixTableName($aTable);
// $wpdb->query("DROP TABLE IF EXISTS `$tableName`");
// }
}
}
public function addActionsAndFilters() {
// Add the Admin Config page for this plugin
// Add Config page as a top-level menu item on the Admin page
add_action('admin_menu', array(&$this, 'createAdminMenu'));
// Add Config page into the Plugins menu
add_action('admin_menu', array(&$this, 'addSettingsSubMenuPage'));
// Hook into Contact Form 7 when a form post is made to save the data to the DB
if ($this->getOption('IntegrateWithCF7', 'true') == 'true') {
add_action('wpcf7_before_send_mail', array(&$this, 'saveFormData'));
}
// Hook into Fast Secure Contact Form
if ($this->getOption('IntegrateWithFSCF', 'true') == 'true') {
add_action('fsctf_mail_sent', array(&$this, 'saveFormData'));
add_action('fsctf_menu_links', array(&$this, 'fscfMenuLinks'));
}
// Have our own hook to publish data independent of other plugins
add_action('cfdb_submit', array(&$this, 'saveFormData'));
// Register Export URL
add_action('wp_ajax_nopriv_cfdb-export', array(&$this, 'ajaxExport'));
add_action('wp_ajax_cfdb-export', array(&$this, 'ajaxExport'));
// Register Get File URL
add_action('wp_ajax_nopriv_cfdb-file', array(&$this, 'ajaxFile'));
add_action('wp_ajax_cfdb-file', array(&$this, 'ajaxFile'));
// Register Get Form Fields URL
add_action('wp_ajax_nopriv_cfdb-getFormFields', array(&$this, 'ajaxGetFormFields'));
add_action('wp_ajax_cfdb-getFormFields', array(&$this, 'ajaxGetFormFields'));
// Shortcode to add a table to a page
$sc = new CFDBShortcodeTable();
$sc->register(array('cf7db-table', 'cfdb-table')); // cf7db-table is deprecated
// Shortcode to add a DataTable
$sc = new CFDBShortcodeDataTable();
$sc->register('cfdb-datatable');
// Shortcode to add a JSON to a page
$sc = new CFDBShortcodeJson();
$sc->register('cfdb-json');
// Shortcode to add a value (just text) to a page
$sc = new CFDBShortcodeValue();
$sc->register('cfdb-value');
// Shortcode to add entry count to a page
$sc = new CFDBShortcodeCount();
$sc->register('cfdb-count');
// Shortcode to add values wrapped in user-defined html
$sc = new CFDBShortcodeHtml();
$sc->register('cfdb-html');
// Shortcode to generate Export URLs
$sc = new CFDBShortcodeExportUrl();
$sc->register('cfdb-export-link');
}
public function ajaxExport() {
require_once('CF7DBPluginExporter.php');
CF7DBPluginExporter::doExportFromPost();
die();
}
public function ajaxFile() {
//if (!$this->canUserDoRoleOption('CanSeeSubmitData')) {
if (!$this->canUserDoRoleOption('CanSeeSubmitDataViaShortcode')) {
CFDBDie::wp_die(__('You do not have sufficient permissions to access this page.', 'contact-form-7-to-database-extension'));
}
$submitTime = $_REQUEST['s'];
$formName = $_REQUEST['form'];
$fieldName = $_REQUEST['field'];
if (!$submitTime || !$formName || !$fieldName) {
CFDBDie::wp_die(__('Missing form parameters', 'contact-form-7-to-database-extension'));
}
$fileInfo = (array) $this->getFileFromDB($submitTime, $formName, $fieldName);
if ($fileInfo == null) {
CFDBDie::wp_die(__('No such file.', 'contact-form-7-to-database-extension'));
}
header("Content-Disposition: attachment; filename=\"$fileInfo[0]\"");
echo($fileInfo[1]);
die();
}
public function ajaxGetFormFields() {
if (!$this->canUserDoRoleOption('CanSeeSubmitData') || !isset($_REQUEST['form'])) {
die();
}
header('Content-Type: application/json; charset=UTF-8');
global $wpdb;
$tableName = $this->getSubmitsTableName();
$formName = $_REQUEST['form'];
$rows = $wpdb->get_results("SELECT DISTINCT `field_name`, `field_order` FROM `$tableName` WHERE `form_name` = '$formName' ORDER BY field_order");
$fields = array();
if (!empty($rows)) {
$fields[] = 'Submitted';
foreach ($rows as $aRow) {
$fields[] = $aRow->field_name;
}
}
echo json_encode($fields);
die();
}
public function addSettingsSubMenuPage() {
$this->requireExtraPluginFiles();
$displayName = $this->getPluginDisplayName();
add_submenu_page('wpcf7', //$this->getDBPageSlug(),
$displayName . ' Options',
__('Database Options', 'contact-form-7-to-database-extension'),
'manage_options',
get_class($this) . 'Settings',
array(&$this, 'settingsPage'));
}
/**
* Function courtesy of Mike Challis, author of Fast Secure Contact Form.
* Displays Admin Panel links in FSCF plugin menu
* @return void
*/
public function fscfMenuLinks() {
$displayName = $this->getPluginDisplayName();
echo '
<p>
' . $displayName .
' | <a href="admin.php?page=' . $this->getDBPageSlug() . '">' .
__('Database', 'contact-form-7-to-database-extension') .
'</a> | <a href="admin.php?page=CF7DBPluginSettings">' .
__('Database Options', 'contact-form-7-to-database-extension') .
'</a> | <a href="admin.php?page=' . $this->getSortCodeBuilderPageSlug() . '">' .
__('Build Short Code', 'contact-form-7-to-database-extension') .
'</a> | <a href="http://wordpress.org/extend/plugins/contact-form-7-to-database-extension/faq/">' .
__('FAQ', 'contact-form-7-to-database-extension') . '</a>
</p>
';
}
/**
* Callback from Contact Form 7. CF7 passes an object with the posted data which is inserted into the database
* by this function.
* Also callback from Fast Secure Contact Form
* @param $cf7 WPCF7_ContactForm|object the former when coming from CF7, the latter $fsctf_posted_data object variable
* if coming from FSCF
* @return void
*/
public function saveFormData($cf7) {
try {
$title = stripslashes($cf7->title);
if (in_array($title, $this->getNoSaveForms())) {
return; // Don't save in DB
}
global $wpdb;
$time = function_exists('microtime') ? microtime(true) : time();
$ip = (isset($_SERVER['X_FORWARDED_FOR'])) ? $_SERVER['X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
$tableName = $this->getSubmitsTableName();
$parametrizedQuery = "INSERT INTO `$tableName` (`submit_time`, `form_name`, `field_name`, `field_value`, `field_order`) VALUES (%s, %s, %s, %s, %s)";
$parametrizedFileQuery = "UPDATE `$tableName` SET `file` = '%s' WHERE `submit_time` = %F AND `form_name` = '%s' AND `field_name` = '%s' AND `field_value` = '%s'";
$order = 0;
$noSaveFields = $this->getNoSaveFields();
foreach ($cf7->posted_data as $name => $value) {
$nameClean = stripslashes($name);
if (in_array($nameClean, $noSaveFields)) {
continue; // Don't save in DB
}
$value = is_array($value) ? implode($value, ', ') : $value;
$valueClean = stripslashes($value);
$wpdb->query($wpdb->prepare($parametrizedQuery,
$time,
$title,
$nameClean,
$valueClean,
$order++));
// Store uploaded files - Do as a separate query in case it fails due to max size or other issue
if ($cf7->uploaded_files && isset($cf7->uploaded_files[$nameClean])) {
$filePath = $cf7->uploaded_files[$nameClean];
if ($filePath) {
$content = file_get_contents($filePath);
$wpdb->query($wpdb->prepare($parametrizedFileQuery,
$content,
$time,
$title,
$nameClean,
$valueClean));
}
}
}
// Save Cookie data if that option is true
if ($this->getOption('SaveCookieData', 'false') == 'true' && is_array($_COOKIE)) {
$saveCookies = $this->getSaveCookies();
foreach ($_COOKIE as $cookieName => $cookieValue) {
if (!empty($saveCookies) && !in_array($cookieName, $saveCookies)) {
continue;
}
$wpdb->query($wpdb->prepare($parametrizedQuery,
$time,
$title,
'Cookie ' . $cookieName,
$cookieValue,
$order++));
}
}
// If the submitter is logged in, capture his id
if (is_user_logged_in()) {
$order = ($order < 9999) ? 9999 : $order + 1; // large order num to try to make it always next-to-last
$current_user = wp_get_current_user(); // WP_User
$wpdb->query($wpdb->prepare($parametrizedQuery,
$time,
$title,
'Submitted Login',
$current_user->user_login,
$order));
}
// Capture the IP Address of the submitter
$order = ($order < 10000) ? 10000 : $order + 1; // large order num to try to make it always last
$wpdb->query($wpdb->prepare($parametrizedQuery,
$time,
$title,
'Submitted From',
$ip,
$order));
}
catch (Exception $ex) {
error_log(sprintf('CFDB Error: %s:%s %s %s', $ex->getFile(), $ex->getLine(), $ex->getMessage(), $ex->getTraceAsString()));
}
}
/**
* @param $time string form submit time
* @param $formName string form name
* @param $fieldName string field name (should be an upload file field)
* @return array of (file-name, file-contents) or null if not found
*/
public function getFileFromDB($time, $formName, $fieldName) {
global $wpdb;
$tableName = $this->getSubmitsTableName();
$parametrizedQuery = "SELECT `field_value`, `file` FROM `$tableName` WHERE `submit_time` = %F AND `form_name` = %s AND `field_name` = '%s'";
$rows = $wpdb->get_results($wpdb->prepare($parametrizedQuery, $time, $formName, $fieldName));
if ($rows == null || count($rows) == 0) {
return null;
}
return array($rows[0]->field_value, $rows[0]->file);
}
/**
* Install page for this plugin in WP Admin
* @return void
*/
public function createAdminMenu() {
$displayName = $this->getPluginDisplayName();
$roleAllowed = $this->getRoleOption('CanSeeSubmitData');
//create new top-level menu
// add_menu_page($displayName . ' Plugin Settings',
// 'Contact Form Submissions',
// 'administrator', //$roleAllowed,
// $this->getDBPageSlug(),
// array(&$this, 'whatsInTheDBPage'));
// Needed for dialog in whatsInTheDBPage
if (strpos($_SERVER['REQUEST_URI'], $this->getDBPageSlug()) !== false) {
$pluginUrl = $this->getPluginFileUrl() . '/';
wp_enqueue_script('jquery');
// wp_enqueue_style('jquery-ui.css', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/base/jquery-ui.css');
wp_enqueue_style('jquery-ui.css', $pluginUrl . 'jquery-ui/jquery-ui.css');
wp_enqueue_script('jquery-ui-dialog', false, array('jquery'));
wp_enqueue_script('CF7DBdes', $pluginUrl . 'des.js');
// Datatables http://www.datatables.net
if ($this->getOption('UseDataTablesJS', 'true') == 'true') {
// wp_enqueue_style('datatables-demo', 'http://www.datatables.net/release-datatables/media/css/demo_table.css');
// wp_enqueue_script('datatables', 'http://www.datatables.net/release-datatables/media/js/jquery.dataTables.js', array('jquery'));
wp_enqueue_style('datatables-demo', $pluginUrl .'DataTables/media/css/demo_table.css');
wp_enqueue_script('datatables', $pluginUrl . 'DataTables/media/js/jquery.dataTables.min.js', array('jquery'));
if ($this->canUserDoRoleOption('CanChangeSubmitData')) {
do_action_ref_array('cfdb_edit_enqueue', array());
}
// Would like to add ColReorder but it causes slowness and display issues with DataTable footer
//wp_enqueue_style('datatables-ColReorder', $pluginUrl .'DataTables/extras/ColReorder/media/css/ColReorder.css');
//wp_enqueue_script('datatables-ColReorder', $pluginUrl . 'DataTables/extras/ColReorder/media/js/ColReorder.min.js', array('datatables', 'jquery'));
}
}
if (strpos($_SERVER['REQUEST_URI'], $this->getSortCodeBuilderPageSlug()) !== false) {
wp_enqueue_script('jquery');
}
// Put page under CF7's "Contact" page
add_submenu_page('wpcf7',
$displayName . ' Submissions',
__('Database', 'contact-form-7-to-database-extension'),
$this->roleToCapability($roleAllowed),
$this->getDBPageSlug(),
array(&$this, 'whatsInTheDBPage'));
// Put page under CF7's "Contact" page
add_submenu_page('wpcf7',
$displayName . ' Short Code Builder',
__('Database Short Code', 'contact-form-7-to-database-extension'),
$this->roleToCapability($roleAllowed),
$this->getSortCodeBuilderPageSlug(),
array(&$this, 'showShortCodeBuilderPage'));
}
/**
* @return string WP Admin slug for page to view DB data
*/
public function getDBPageSlug() {
return get_class($this) . 'Submissions';
}
public function getSortCodeBuilderPageSlug() {
return get_class($this) . 'ShortCodeBuilder';
}
public function showShortCodeBuilderPage() {
require_once('CFDBViewShortCodeBuilder.php');
$view = new CFDBViewShortCodeBuilder;
$view->display($this);
}
/**
* Display the Admin page for this Plugin that show the form data saved in the database
* @return void
*/
public function whatsInTheDBPage() {
require_once('CFDBViewWhatsInDB.php');
$view = new CFDBViewWhatsInDB;
$view->display($this);
}
/**
* @param $time int same as returned from PHP time()
* @return string formatted date according to saved options
*/
public function formatDate($time) {
// Convert time to local timezone
date_default_timezone_set(get_option('timezone_string'));
if ($this->getOption('UseCustomDateTimeFormat', 'true') == 'true') {
$dateFormat = $this->getOption('SubmitDateTimeFormat', 'Y-m-d H:i:s P');
return date($dateFormat, $time);
}
return date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $time);
}
/**
* @param $submitTime string PK for form submission
* @param $formName string
* @param $fileName string
* @return string URL to download file
*/
public function getFileUrl($submitTime, $formName, $fileName) {
return sprintf('%s?action=cfdb-file&s=%s&form=%s&field=%s',
admin_url('admin-ajax.php'),
$submitTime,
urlencode($formName),
urlencode($fileName));
}
public function getFormFieldsAjaxUrlBase() {
return admin_url('admin-ajax.php') . '?action=cfdb-getFormFields&form=';
}
/**
* @return array of string
*/
public function getNoSaveFields() {
return preg_split('/,|;/', $this->getOption('NoSaveFields'), -1, PREG_SPLIT_NO_EMPTY);
}
/**
* @return array of string
*/
public function getNoSaveForms() {
return preg_split('/,|;/', $this->getOption('NoSaveForms'), -1, PREG_SPLIT_NO_EMPTY);
}
/**
* @return array of string
*/
public function getSaveCookies() {
return preg_split('/,|;/', $this->getOption('SaveCookieNames'), -1, PREG_SPLIT_NO_EMPTY);
}
/**
* @return string
*/
public function getSubmitsTableName() {
// $overrideTable = $this->getOption('SubmitTableNameOverride');
// if ($overrideTable && "" != $overrideTable) {
// return $overrideTable;
// }
return $this->prefixTableName('SUBMITS');
}
/**
* @return string URL to the Plugin directory. Includes ending "/"
*/
public function getPluginDirUrl() {
//return WP_PLUGIN_URL . '/' . str_replace(basename(__FILE__), '', plugin_basename(__FILE__));
return $this->getPluginFileUrl('/');
}
/**
* @param string $pathRelativeToThisPluginRoot points to a file with relative path from
* this plugin's root dir. I.e. file "des.js" in the root of this plugin has
* url = $this->getPluginFileUrl('des.js');
* If it was in a sub-folder "js" then you would use
* $this->getPluginFileUrl('js/des.js');
* @return string full url to input file
*/
public function getPluginFileUrl($pathRelativeToThisPluginRoot = '') {
return plugins_url($pathRelativeToThisPluginRoot, __FILE__);
}
/**
* @return string URL of the language translation file for DataTables oLanguage.sUrl parameter
* or null if it does not exist.
*/
public function getDataTableTranslationUrl() {
$url = null;
$locale = get_locale();
$i18nDir = dirname(__FILE__) . '/dt_i18n/';
// See if there is a local file
if (is_readable($i18nDir . $locale . '.json')) {
$url = $this->getPluginFileUrl() . "dt_i18n/$locale.json";
}
else {
// Pull the language code from the $local string
// which is expected to look like "en_US"
// where the first 2 or 3 letters are for lang followed by '_'
$lang = null;
if (substr($locale, 2, 1) == '_') {
// 2-letter language codes
$lang = substr($locale, 0, 2);
}
else if (substr($locale, 3, 1) == '_') {
// 3-letter language codes
$lang = substr($locale, 0, 3);
}
if ($lang && is_readable($i18nDir . $lang . '.json')) {
$url = $this->getPluginFileUrl() . "/dt_i18n/$lang.json";
}
}
return $url;
}
}

View File

@ -0,0 +1,146 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
class CF7DBPluginExporter {
static function doExportFromPost() {
// Consolidate GET and POST parameters. Allow GET to override POST.
$params = array_merge($_POST, $_GET);
//print_r($params);
if (!isset($params['form'])) {
include_once('CFDBDie.php');
CFDBDie::wp_die(__('Error: No "form" parameter submitted', 'contact-form-7-to-database-extension'));
return;
}
// Assumes coming from CF7DBPlugin::whatsInTheDBPage()
$key = '3fde789a'; //substr($_COOKIE['PHPSESSID'], - 5); // session_id() doesn't work
if (isset($params['guser'])) {
$params['guser'] = mcrypt_decrypt(MCRYPT_3DES, $key, CF7DBPluginExporter::hexToStr($params['guser']), 'ecb');
}
if (isset($params['gpwd'])) {
$params['gpwd'] = mcrypt_decrypt(MCRYPT_3DES, $key, CF7DBPluginExporter::hexToStr($params['gpwd']), 'ecb');
}
CF7DBPluginExporter::export(
$params['form'],
$params['enc'],
$params);
}
// Taken from http://ditio.net/2008/11/04/php-string-to-hex-and-hex-to-string-functions/
static function hexToStr($hex) {
$string = '';
for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
$string .= chr(hexdec($hex[$i] . $hex[$i + 1]));
}
return $string;
}
static function export($formName, $encoding, $options) {
switch ($encoding) {
case 'HTML':
require_once('ExportToHtmlTable.php');
$exporter = new ExportToHtmlTable();
$exporter->export($formName, $options);
break;
case 'DT':
require_once('ExportToHtmlTable.php');
if (!is_array($options)) {
$options = array();
}
$options['useDT'] = true;
if (!isset($options['printScripts'])) {
$options['printScripts'] = true;
}
if (!isset($options['printStyles'])) {
$options['printStyles'] = 'true';
}
$exporter = new ExportToHtmlTable();
$exporter->export($formName, $options);
break;
case 'HTMLTemplate':
require_once('ExportToHtmlTemplate.php');
$exporter = new ExportToHtmlTemplate();
$exporter->export($formName, $options);
break;
case 'IQY':
require_once('ExportToIqy.php');
$exporter = new ExportToIqy();
$exporter->export($formName, $options);
break;
case 'CSVUTF8BOM':
require_once('ExportToCsvUtf8.php');
$exporter = new ExportToCsvUtf8();
$exporter->setUseBom(true);
$exporter->export($formName, $options);
break;
case 'TSVUTF16LEBOM':
require_once('ExportToCsvUtf16le.php');
$exporter = new ExportToCsvUtf16le();
$exporter->export($formName, $options);
break;
case 'GLD':
require_once('ExportToGoogleLiveData.php');
$exporter = new ExportToGoogleLiveData();
$exporter->export($formName, $options);
break;
case 'GSS':
require_once('ExportToGoogleSS.php');
$exporter = new ExportToGoogleSS();
$exporter->export($formName, $options);
break;
case 'JSON':
require_once('ExportToJson.php');
$exporter = new ExportToJson();
$exporter->export($formName, $options);
break;
case 'VALUE':
require_once('ExportToValue.php');
$exporter = new ExportToValue();
$exporter->export($formName, $options);
break;
case 'COUNT':
require_once('ExportToValue.php');
if (!is_array($options)) {
$options = array();
}
$options['function'] = 'count';
unset($options['show']);
unset($options['hide']);
$exporter = new ExportToValue();
$exporter->export($formName, $options);
break;
case 'CSVUTF8':
default:
require_once('ExportToCsvUtf8.php');
$exporter = new ExportToCsvUtf8();
$exporter->setUseBom(false);
$exporter->export($formName, $options);
break;
}
}
}

View File

@ -0,0 +1,140 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CF7DBInstallIndicator.php');
/**
* All the basic plugin life cycle functionality is implemented herein.
* A Plugin is expected to subclass this class and override method to inject
* its own specific behaviors.
*
* @author Michael Simpson
*/
abstract class CF7DBPluginLifeCycle extends CF7DBInstallIndicator {
public function install() {
// Initialize Plugin Options
$this->initOptions();
// Initialize DB Tables used by the plugin
$this->installDatabaseTables();
// Other Plugin initialization - for the plugin writer to override as needed
$this->otherInstall();
// Record the installed version
$this->saveInstalledVersion();
// To avoid running install() more then once
$this->markAsInstalled();
}
public function uninstall() {
$this->otherUninstall();
$this->unInstallDatabaseTables();
$this->deleteSavedOptions();
$this->markAsUnInstalled();
}
/**
* Perform any version-upgrade activities prior to activation (e.g. database changes)
* @return void
*/
public function upgrade() {
}
public function activate() {
}
public function deactivate() {
}
protected function initOptions() {
}
public function addActionsAndFilters() {
}
protected function installDatabaseTables() {
}
protected function unInstallDatabaseTables() {
}
protected function otherInstall() {
}
protected function otherUninstall() {
}
/**
* Puts the configuration page in the Plugins menu by default.
* Override to put it elsewhere or create a set of submenus
* Override with an empty implementation if you don't want a configuration page
* @return void
*/
public function addSettingsSubMenuPage() {
$this->addSettingsSubMenuPageToPluginsMenu();
//$this->addSettingsSubMenuPageToSettingsMenu();
}
protected function requireExtraPluginFiles() {
require_once(ABSPATH . 'wp-includes/pluggable.php');
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
protected function addSettingsSubMenuPageToPluginsMenu() {
$this->requireExtraPluginFiles();
$displayName = $this->getPluginDisplayName();
add_submenu_page('plugins.php',
$displayName,
$displayName,
'manage_options',
get_class($this) . 'Settings',
array(&$this, 'settingsPage'));
}
protected function addSettingsSubMenuPageToSettingsMenu() {
$this->requireExtraPluginFiles();
$displayName = $this->getPluginDisplayName();
add_options_page($displayName,
$displayName,
'manage_options',
get_class($this) . 'Settings',
array(&$this, 'settingsPage'));
}
/**
* @param $name string name of a database table
* @return string input prefixed with the Wordpress DB table prefix
* plus the prefix for this plugin to avoid table name collisions
*/
protected function prefixTableName($name) {
global $wpdb;
return $wpdb->prefix . $this->prefix($name);
}
}

View File

@ -0,0 +1,53 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
function CF7DBPlugin_init($file) {
require_once('CF7DBPlugin.php');
$aPlugin = new CF7DBPlugin();
// Install the plugin
// NOTE: this file gets run each time you *activate* the plugin.
// So in WP when you "install" the plugin, all that does it dump its files in the plugin-templates directory
// but it does not call any of its code.
// So here, the plugin tracks whether or not it has run its install operation, and we ensure it is run only once
// on the first activation
if (!$aPlugin->isInstalled()) {
$aPlugin->install();
}
else {
// Perform any version-upgrade activities prior to activation (e.g. database changes)
$aPlugin->upgrade();
}
// Add callbacks to hooks
$aPlugin->addActionsAndFilters();
if (!$file) {
$file = __FILE__;
}
// Register the Plugin Activation Hook
register_activation_hook($file, array(&$aPlugin, 'activate'));
// Register the Plugin Deactivation Hook
register_deactivation_hook($file, array(&$aPlugin, 'deactivate'));
}

View File

@ -0,0 +1,30 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
interface CF7DBValueConverter {
/**
* @abstract
* @param $value mixed object to convert
* @return mixed converted value
*/
public function convert($value);
}

View File

@ -0,0 +1,277 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
include_once('CF7DBEvalutator.php');
include_once('CF7DBValueConverter.php');
/**
* Used to parse boolean expression strings like 'field1=value1&&field2=value2||field3=value3&&field4=value4'
* Where logical AND and OR are represented by && and || respectively.
* Individual expressions (like 'field1=value1') are of the form $name . $operator . $value where
* $operator is any PHP comparison operator or '=' which is interpreted as '=='.
* $value has a special case where if it is 'null' it is interpreted as the value null
*/
class CF7FilterParser implements CF7DBEvalutator {
/**
* @var array of arrays of string where the top level array is broken down on the || delimiters
*/
var $tree;
/**
* @var CF7DBValueConverter callback that can be used to pre-process values in the filter string
* passed into parseFilterString($filterString).
* For example, a function might take the value '$user_email' and replace it with an actual email address
* just prior to checking it against input data in call evaluate($data)
*/
var $compValuePreprocessor;
public function hasFilters() {
return count($this->tree) > 0; // count is null-safe
}
public function getFilterTree() {
return $this->tree;
}
/**
* Parse a string with delimiters || and/or && into a Boolean evaluation tree.
* For example: aaa&&bbb||ccc&&ddd would be parsed into the following tree,
* where level 1 represents items ORed, level 2 represents items ANDed, and
* level 3 represent individual expressions.
* Array
* (
* [0] => Array
* (
* [0] => Array
* (
* [0] => aaa
* [1] => =
* [2] => bbb
* )
*
* )
*
* [1] => Array
* (
* [0] => Array
* (
* [0] => ccc
* [1] => =
* [2] => ddd
* )
*
* [1] => Array
* (
* [0] => eee
* [1] => =
* [2] => fff
* )
*
* )
*
* )
* @param $filterString string with delimiters && and/or ||
* which each element being an array of strings broken on the && delimiter
*/
public function parseFilterString($filterString) {
$this->tree = array();
$arrayOfORedStrings = $this->parseORs($filterString);
foreach ($arrayOfORedStrings as $anANDString) {
$arrayOfANDedStrings = $this->parseANDs($anANDString);
$andSubTree = array();
foreach ($arrayOfANDedStrings as $anExpressionString) {
$exprArray = $this->parseExpression($anExpressionString);
$andSubTree[] = $exprArray;
}
$this->tree[] = $andSubTree;
}
}
/**
* @param $filterString
* @return array
*/
public function parseORs($filterString) {
return preg_split('/\|\|/', $filterString, -1, PREG_SPLIT_NO_EMPTY);
}
/**
* @param $filterString
* @return array
*/
public function parseANDs($filterString) {
$retVal = preg_split('/&&/', $filterString, -1, PREG_SPLIT_NO_EMPTY);
if (count($retVal) == 1) {
// This took me a long time chase down. Looks like in some cases when using this in a
// WordPress web page, the text that gets here is '&#038;&#038;' rather than '&&'
// (But oddly, this is not always the case). So check for this case explicitly.
$retVal = preg_split('/&#038;&#038;/', $filterString, -1, PREG_SPLIT_NO_EMPTY);
}
//echo "<pre>Parsed '$filterString' into " . print_r($retVal, true) . '</pre>';
return $retVal;
}
/**
* Parse a comparison expression into its three components
* @param $comparisonExpression string in the form 'value1' . 'operator' . 'value2' where
* operator is a php comparison operator or '='
* @return array of string [ value1, operator, value2 ]
*/
public function parseExpression($comparisonExpression) {
return preg_split('/(===)|(==)|(=)|(!==)|(!=)|(<>)|(<=)|(<)|(>=)|(>)|(~~)/',
$comparisonExpression, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
}
/**
* Evaluate expression against input data. Assumes parseFilterString was called to set up the expression to
* evaluate. Expression should have key . operator . value tuples and input $data should have the same keys
* with values to check against them.
* For example, an expression in this object is 'name=john' and the input data has [ 'name' => 'john' ]. In
* this case true is returned. if $data has [ 'name' => 'fred' ] then false is returned.
* @param $data array [ key => value]
* @return boolean result of evaluating $data against expression tree
*/
public function evaluate(&$data) {
$retVal = true;
if ($this->tree) {
$retVal = false;
foreach ($this->tree as $andArray) { // loop each OR'ed $andArray
$andBoolean = true;
// evaluation the list of AND'ed comparison expressions
foreach ($andArray as $comparison) {
$andBoolean = $this->evaluateComparison($comparison, $data); //&& $andBoolean
if (!$andBoolean) {
break; // short-circuit AND expression evaluation
}
}
$retVal = $retVal || $andBoolean;
if ($retVal) {
break; // short-circuit OR expression evaluation
}
}
}
return $retVal;
}
public function evaluateComparison($andExpr, &$data) {
if (is_array($andExpr) && count($andExpr) == 3) {
$left = $data[$andExpr[0]];
$op = $andExpr[1];
$right = $andExpr[2];
if ($this->compValuePreprocessor) {
try {
$right = $this->compValuePreprocessor->convert($right);
}
catch (Exception $ex) {
trigger_error($ex, E_USER_NOTICE);
}
}
if (!$left && !$right) {
// Addresses case where 'Submitted Login' = $user_login but there exist some submissions
// with no 'Submitted Login' field. Without this clause, those rows where 'Submitted Login' == null
// would be returned when what we really want to is affirm that there is a 'Submitted Login' value ($left)
// But we want to preserve the correct behavior for the case where 'field'=null is the constraint.
return false;
}
return $this->evaluateLeftOpRightComparison($left, $op, $right);
}
return false;
}
/**
* @param $left mixed
* @param $operator string representing any PHP comparison operator or '=' which is taken to mean '=='
* @param $right $mixed. SPECIAL CASE: if it is the string 'null' it is taken to be the value null
* @return bool evaluation of comparison $left $operator $right
*/
public function evaluateLeftOpRightComparison($left, $operator, $right) {
if ($right == 'null') {
// special case
$right = null;
}
// Could do this easier with eval() but I want since this text ultimately
// comes form a shortcode's user-entered attributes, I want to avoid a security hole
$retVal = false;
switch ($operator) {
case '=' :
case '==':
$retVal = $left == $right;
break;
case '===':
$retVal = $left === $right;
break;
case '!=':
$retVal = $left != $right;
break;
case '!==':
$retVal = $left !== $right;
break;
case '<>':
$retVal = $left <> $right;
break;
case '>':
$retVal = $left > $right;
break;
case '>=':
$retVal = $left >= $right;
break;
case '<':
$retVal = $left < $right;
break;
case '<=':
$retVal = $left <= $right;
break;
case '~~':
$retVal = preg_match($right, $left) > 0;
break;
default:
trigger_error("Invalid operator: '$operator'", E_USER_NOTICE);
$retVal = false;
break;
}
return $retVal;
}
/**
* @param $converter CF7DBValueConverter
* @return void
*/
public function setComparisonValuePreprocessor($converter) {
$this->compValuePreprocessor = $converter;
}
}

View File

@ -0,0 +1,50 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
include_once('CF7DBEvalutator.php');
class CF7SearchEvaluator implements CF7DBEvalutator {
var $search;
public function setSearch($search) {
$this->search = strtolower($search);
}
/**
* Evaluate expression against input data. This is intended to mimic the search field on DataTables
* @param $data array [ key => value]
* @return boolean result of evaluating $data against expression
*/
public function evaluate(&$data) {
if (!$this->search) {
return true;
}
foreach ($data as $key => $value) {
// Any field can match, case insensitive
if (false !== strrpos(strtolower($value), $this->search)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,46 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
class CFDBDie {
/**
* Why this function? It is meant to do what wp_die() does. But in
* Ajax mode, wp_die just does die(-1). But in this plugin we are leveraging
* Ajax mode to put in URL hooks to do exports. So it is not really making a in-page
* call to the url, the full page is navigating to it, then it downloads a CSV file for
* example. So if there are errors we want the wp_die() error page. So this
* function is a copy of wp_die without the Ajax mode check.
* @static
* @param $message HTML
* @param string $title HTML Title
* @param array $args see wp_die
* @return void
*/
static function wp_die($message, $title = '', $args = array()) {
// Code copied from wp_die without it stopping due to AJAX
if ( function_exists( 'apply_filters' ) ) {
$function = apply_filters( 'wp_die_handler', '_default_wp_die_handler');
} else {
$function = '_default_wp_die_handler';
}
call_user_func( $function, $message, $title, $args );
}
}

View File

@ -0,0 +1,32 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
interface CFDBExport {
/**
* @abstract
* @param $formName string
* @param $options array of option_name => option_value
* @return void
*/
public function export($formName, $options = null);
}

View File

@ -0,0 +1,71 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
/**
* This class is an API for accessing a form and looping through its contents.
* Common shortcode options can be used to show/hide columns, search/filter fields, limit, orderby etc.
* Set them in the input $options array.
* Example code:
* <code>
* // Email all the "Mike"'s
* require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php');
* $exp = new CFDBFormIterator();
* $exp->export('my-form', new array('show' => 'name,email', 'search' => 'mike'));
* while ($row = $exp->nextRow()) {
* wp_mail($row['email'], 'Hello ' . $row['name], 'How are you doing?');
* }
*
* </code>
*/
require_once('ExportBase.php');
require_once('CFDBExport.php');
class CFDBFormIterator extends ExportBase implements CFDBExport {
/**
* Intended to be used by people who what to programmatically loop over the rows
* of a form.
* @param $formName string
* @param $options array of option_name => option_value
* @return void
*/
public function export($formName, $options = null) {
$this->setOptions($options);
$this->setCommonOptions();
$this->setDataIterator($formName);
}
/**
* @return array|bool associative array of the row values or false if no more row exists
*/
public function nextRow() {
if ($this->dataIterator->nextRow()) {
$row = array();
foreach ($this->dataIterator->displayColumns as $aCol) {
$row[$aCol] = $this->dataIterator->row[$aCol];
}
return $row;
}
else {
return false;
}
}
}

View File

@ -0,0 +1,192 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
class CFDBQueryResultIterator {
/**
* @var resource
*/
var $results;
/**
* @var array
*/
var $row;
/**
* @var string
*/
var $submitTimeKeyName;
/**
* @var int
*/
var $limitEnd;
/**
* @var int
*/
var $idx;
/**
* @var int
*/
var $limitStart;
/**
* @var array
*/
var $columns;
/**
* @var array
*/
var $displayColumns;
/**
* @var CF7DBPlugin
*/
var $plugin;
/**
* @var CF7DBEvalutator|CF7FilterParser|CF7SearchEvaluator
*/
var $rowFilter;
/**
* @var array
*/
// var $fileColumns;
/**
* @var bool
*/
var $onFirstRow = false;
public function query(&$sql, &$rowFilter, $queryOptions = array()) {
$this->rowFilter = $rowFilter;
$this->results = null;
$this->row = null;
$this->plugin = new CF7DBPlugin();
$this->submitTimeKeyName = isset($queryOptions['submitTimeKeyName']) ? $queryOptions['submitTimeKeyName'] : null;
if (isset($queryOptions['limit'])) {
$limitVals = explode(',', $queryOptions['limit']);
if (isset($limitVals[1])) {
$this->limitStart = trim($limitVals[0]);
$this->limitEnd = $this->limitStart + trim($limitVals[1]);
}
else if (isset($limitVals[0])) {
$this->limitEnd = trim($limitVals[0]);
}
}
$this->idx = -1;
// For performance reasons, we bypass $wpdb so we can call mysql_unbuffered_query
$con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD, true);
if (!$con) {
trigger_error("MySQL Connection failed: " . mysql_error(), E_USER_NOTICE);
return;
}
mysql_query('SET NAMES utf8', $con);
if (!mysql_select_db(DB_NAME, $con)) {
trigger_error("MySQL DB Select failed: " . mysql_error(), E_USER_NOTICE);
return;
}
$this->results = mysql_unbuffered_query($sql, $con);
if (!$this->results) {
trigger_error("MySQL unbuffered query failed: " . mysql_error(), E_USER_NOTICE);
return;
}
$this->columns = array();
$this->row = mysql_fetch_assoc($this->results);
if ($this->row) {
foreach (array_keys($this->row) as $aCol) {
// hide this metadata column
if ('fields_with_file' != $aCol) {
$this->columns[] = $aCol;
}
}
$this->onFirstRow = true;
}
else {
$this->onFirstRow = false;
}
}
/**
* Fetch next row into variable
* @return bool if next row exists
*/
public function nextRow() {
if (!$this->results) {
return false;
}
while (true) {
if (!$this->onFirstRow) {
$this->row = mysql_fetch_assoc($this->results);
}
$this->onFirstRow = false;
if (!$this->row) {
mysql_free_result($this->results);
$this->results = null;
return false;
}
// Format the date
$submitTime = $this->row['Submitted'];
$this->row['Submitted'] = $this->plugin->formatDate($submitTime);
// Determine if row is filtered
if ($this->rowFilter && !$this->rowFilter->evaluate($this->row)) {
continue;
}
$this->idx += 1;
if ($this->limitStart && $this->idx < $this->limitStart) {
continue;
}
if ($this->limitEnd && $this->idx >= $this->limitEnd) {
while (mysql_fetch_array($this->results)) ;
mysql_free_result($this->results);
$this->results = null;
$this->row = null;
return false;
}
// Keep the unformatted submitTime if needed
if ($this->submitTimeKeyName) {
$this->row[$this->submitTimeKeyName] = $submitTime;
}
break;
}
if (!$this->row) {
mysql_free_result($this->results);
$this->results = null;
}
return $this->row ? true : false;
}
}

View File

@ -0,0 +1,32 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CFDBShortcodeValue.php');
class CFDBShortcodeCount extends CFDBShortcodeValue {
public function handleShortcode($atts) {
$atts['function'] = 'count';
unset($atts['show']);
unset($atts['hide']);
return parent::handleShortcode($atts);
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ShortCodeScriptLoader.php');
class CFDBShortcodeDataTable extends ShortCodeScriptLoader {
public function handleShortcode($atts) {
$atts['useDT'] = true;
require_once('CFDBShortcodeTable.php');
$sc = new CFDBShortcodeTable();
return $sc->handleShortcode($atts);
}
public function register($shortcodeName) {
parent::register($shortcodeName);
// Unfortunately, can't put styles in the footer so we have to always add this style sheet
// There is an article about how one might go about this here:
// http://beerpla.net/2010/01/13/wordpress-plugin-development-how-to-include-css-and-javascript-conditionally-and-only-when-needed-by-the-posts/
// But it appears to expects posts on the page and I'm concerned it will not work in all cases
// Just enqueuing it causes problems in some pages. Need a targetted way to do this.
// wp_enqueue_style('datatables-demo', 'http://www.datatables.net/release-datatables/media/css/demo_table.css');
}
public function addScript() {
// wp_register_style('datatables-demo', 'http://www.datatables.net/release-datatables/media/css/demo_table.css');
// wp_print_styles('datatables-demo');
// wp_register_script('datatables', 'http://www.datatables.net/release-datatables/media/js/jquery.dataTables.js', array('jquery'), false, true);
wp_enqueue_script('datatables', plugins_url('/', __FILE__) . 'DataTables/media/js/jquery.dataTables.min.js', array('jquery'));
wp_print_scripts('datatables');
}
}

View File

@ -0,0 +1,69 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ShortCodeLoader.php');
class CFDBShortcodeExportUrl extends ShortCodeLoader {
/**
* @param $atts array of short code attributes
* @return string JSON. See ExportToJson.php
*/
public function handleShortcode($atts) {
$params = array();
$params[] = admin_url('admin-ajax.php');
$params[] = '?action=cfdb-export';
if (isset($atts['form'])) {
$params[] = '&form=' . urlencode($atts['form']);
}
if (isset($atts['show'])) {
$params[] = '&show=' . urlencode($atts['show']);
}
if (isset($atts['hide'])) {
$params[] = '&hide=' . urlencode($atts['hide']);
}
if (isset($atts['limit'])) {
$params[] = '&limit=' . urlencode($atts['limit']);
}
if (isset($atts['search'])) {
$params[] = '&search=' . urlencode($atts['search']);
}
if (isset($atts['filter'])) {
$params[] = '&filter=' . urlencode($atts['filter']);
}
if (isset($atts['enc'])) {
$params[] = '&enc=' . urlencode($atts['enc']);
}
$url = implode($params);
if (isset($atts['urlonly']) && $atts['urlonly'] == 'true') {
return $url;
}
$linkText = __('Export', 'contact-form-7-to-database-extension');
if (isset($atts['linktext'])) {
$linkText = $atts['linktext'];
}
return sprintf('<a href="%s">%s</a>', $url, $linkText);
}
}

View File

@ -0,0 +1,41 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ShortCodeLoader.php');
class CFDBShortcodeHtml extends ShortCodeLoader {
/**
* @param $atts array of short code attributes
* @param $content string contents inside the shortcode tag
* @return string value submitted to a form field as selected by $atts. See ExportToValue.php
*/
public function handleShortcode($atts, $content = null) {
if ($content) {
$atts['fromshortcode'] = true;
$atts['content'] = $content;
require_once('ExportToHtmlTemplate.php');
$export = new ExportToHtmlTemplate();
return $export->export($atts['form'], $atts);
}
}
}

View File

@ -0,0 +1,37 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ShortCodeLoader.php');
class CFDBShortcodeJson extends ShortCodeLoader {
/**
* @param $atts array of short code attributes
* @return string JSON. See ExportToJson.php
*/
public function handleShortcode($atts) {
$atts['html'] = true;
$atts['fromshortcode'] = true;
require_once('ExportToJson.php');
$export = new ExportToJson();
return $export->export($atts['form'], $atts);
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ShortCodeLoader.php');
class CFDBShortcodeTable extends ShortCodeLoader {
/**
* Shortcode callback for writing the table of form data. Can be put in a page or post to show that data.
* Shortcode options:
* [cfdb-table form="your-form"] (shows the whole table with default options)
* Controlling the Display: Apply your CSS to the table; set the table's 'class' or 'id' attribute:
* [cfdb-table form="your-form" class="css_class"] (outputs <table class="css_class"> (default: class="cf7-db-table")
* [cfdb-table form="your-form" id="css_id"] (outputs <table id="css_id"> (no default id)
* [cfdb-table form="your-form" id="css_id" class="css_class"] (outputs <table id="css_id" class="css_class">
* Filtering Columns:
* [cfdb-table form="your-form" show="field1,field2,field3"] (optionally show selected fields)
* [cfdb-table form="your-form" hide="field1,field2,field3"] (optionally hide selected fields)
* [cfdb-table form="your-form" show="f1,f2,f3" hide="f1"] (hide trumps show)
* Filtering Rows:
* [cfdb-table form="your-form" filter="field1=value1"] (show only rows where field1=value1)
* [cfdb-table form="your-form" filter="field1!=value1"] (show only rows where field1!=value1)
* [cfdb-table form="your-form" filter="field1=value1&&field2!=value2"] (Logical AND the filters using '&&')
* [cfdb-table form="your-form" filter="field1=value1||field2!=value2"] (Logical OR the filters using '||')
* [cfdb-table form="your-form" filter="field1=value1&&field2!=value2||field3=value3&&field4=value4"] (Mixed &&, ||)
* @param $atts array of short code attributes
* @return HTML output of shortcode
*/
public function handleShortcode($atts) {
$atts['canDelete'] = false;
$atts['fromshortcode'] = true;
require_once('ExportToHtmlTable.php');
$export = new ExportToHtmlTable();
return $export->export($atts['form'], $atts);
}
}

View File

@ -0,0 +1,37 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ShortCodeLoader.php');
class CFDBShortcodeValue extends ShortCodeLoader {
/**
* @param $atts array of short code attributes
* @return string value submitted to a form field as selected by $atts. See ExportToValue.php
*/
public function handleShortcode($atts) {
$atts['fromshortcode'] = true;
require_once('ExportToValue.php');
$export = new ExportToValue();
return $export->export($atts['form'], $atts);
}
}

View File

@ -0,0 +1,90 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
abstract class CFDBView {
/**
* @abstract
* @param $plugin CF7DBPlugin
* @return void
*/
abstract function display(&$plugin);
protected function pageHeader(&$plugin) {
$this->sponsorLink($plugin);
$this->headerLinks();
}
protected function sponsorLink(&$plugin) {
if ('true' != $plugin->getOption('Donated')) {
?>
<script type="text/javascript">
var psHost = (("https:" == document.location.protocol) ? "https://" : "http://");
document.write(unescape("%3Cscript src='" + psHost + "pluginsponsors.com/direct/spsn/display.php?client=contact-form-7-to-database-extension&spot='type='text/javascript'%3E%3C/script%3E"));
</script>
<?php
}
}
protected function headerLinks() {
?>
<table style="width:100%;">
<tbody>
<tr>
<td width="20%" style="font-size:x-small;">
<a target="_donate"
href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=NEVDJ792HKGFN&lc=US&item_name=Wordpress%20Plugin&item_number=cf7%2dto%2ddb%2dextension&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted">
<img src="https://www.paypal.com/en_US/i/btn/btn_donate_SM.gif" alt="Donate">
</a>
</td>
<td width="20%" style="font-size:x-small;">
<a target="_cf7todb"
href="http://wordpress.org/extend/plugins/contact-form-7-to-database-extension">
<?php _e('Rate this Plugin', 'contact-form-7-to-database-extension') ?>
</a>
</td>
<td width="20%" style="font-size:x-small;">
<a target="_cf7todb"
href="http://cfdbplugin.com/">
<?php _e('Documentation', 'contact-form-7-to-database-extension') ?>
</a>
</td>
<td width="20%" style="font-size:x-small;">
<a target="_cf7todb"
href="http://wordpress.org/tags/contact-form-7-to-database-extension">
<?php _e('Support', 'contact-form-7-to-database-extension') ?>
</a>
</td>
<td width="20%" style="font-size:x-small;">
<a target="_cf7todb"
href="http://pluginsponsors.com/privacy.html">
<?php _e('Privacy Policy', 'contact-form-7-to-database-extension') ?>
</a>
</td>
</tr>
</tbody>
</table>
<?php
}
}

View File

@ -0,0 +1,693 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CF7DBPlugin.php');
require_once('CFDBView.php');
class CFDBViewShortCodeBuilder extends CFDBView {
/**
* @param $plugin CF7DBPlugin
* @return void
*/
function display(&$plugin) {
if ($plugin == null) {
$plugin = new CF7DBPlugin;
}
$this->pageHeader($plugin);
// Identify which forms have data in the database
global $wpdb;
$tableName = $plugin->getSubmitsTableName();
$rows = $wpdb->get_results("select distinct `form_name` from `$tableName` order by `form_name`");
// if ($rows == null || count($rows) == 0) {
// _e('No form submissions in the database', 'contact-form-7-to-database-extension');
// return;
// }
$currSelection = ''; // todo
?>
<script type="text/javascript" language="JavaScript">
var shortCodeDocUrls = {
'' : 'http://cfdbplugin.com/?page_id=89',
'[cfdb-html]' : 'http://cfdbplugin.com/?page_id=284',
'[cfdb-table]' : 'http://cfdbplugin.com/?page_id=93',
'[cfdb-datatable]' : 'http://cfdbplugin.com/?page_id=91',
'[cfdb-value]' : 'http://cfdbplugin.com/?page_id=98',
'[cfdb-count]' : 'http://cfdbplugin.com/?page_id=278',
'[cfdb-json]' : 'http://cfdbplugin.com/?page_id=96',
'[cfdb-export-link]' : 'http://cfdbplugin.com/?page_id=419'
};
function showHideOptionDivs() {
var shortcode = jQuery('#shortcode_ctrl').val();
jQuery('#doc_url_tag').attr('href', shortCodeDocUrls[shortcode]);
jQuery('#doc_url_tag').html(shortcode + " <?php _e('Documentation', 'contact-form-7-to-database-extension'); ?>");
switch (shortcode) {
case "[cfdb-html]":
jQuery('#show_hide_div').show();
jQuery('#limitorder_div').show();
jQuery('#html_format_div').hide();
jQuery('#dt_options_div').hide();
jQuery('#json_div').hide();
jQuery('#value_div').hide();
jQuery('#template_div').show();
jQuery('#url_link_div').hide();
break;
case "[cfdb-table]":
jQuery('#show_hide_div').show();
jQuery('#limitorder_div').show();
jQuery('#html_format_div').show();
jQuery('#dt_options_div').hide();
jQuery('#json_div').hide();
jQuery('#value_div').hide();
jQuery('#template_div').hide();
jQuery('#url_link_div').hide();
break;
case "[cfdb-datatable]":
jQuery('#show_hide_div').show();
jQuery('#limitorder_div').show();
jQuery('#html_format_div').show();
jQuery('#dt_options_div').show();
jQuery('#json_div').hide();
jQuery('#value_div').hide();
jQuery('#template_div').hide();
jQuery('#url_link_div').hide();
break;
case "[cfdb-value]":
jQuery('#show_hide_div').show();
jQuery('#limitorder_div').show();
jQuery('#html_format_div').hide();
jQuery('#dt_options_div').hide();
jQuery('#json_div').hide();
jQuery('#value_div').show();
jQuery('#template_div').hide();
jQuery('#url_link_div').hide();
break;
case "[cfdb-count]":
jQuery('#show_hide_div').hide();
jQuery('#limitorder_div').hide();
jQuery('#html_format_div').hide();
jQuery('#dt_options_div').hide();
jQuery('#json_div').hide();
jQuery('#value_div').hide();
jQuery('#template_div').hide();
jQuery('#url_link_div').hide();
break;
case "[cfdb-json]":
jQuery('#show_hide_div').show();
jQuery('#limitorder_div').show();
jQuery('#html_format_div').hide();
jQuery('#dt_options_div').hide();
jQuery('#json_div').show();
jQuery('#value_div').hide();
jQuery('#template_div').hide();
jQuery('#url_link_div').hide();
break;
case "[cfdb-export-link]":
jQuery('#show_hide_div').show();
jQuery('#limitorder_div').show();
jQuery('#html_format_div').hide();
jQuery('#dt_options_div').hide();
jQuery('#json_div').hide();
jQuery('#value_div').hide();
jQuery('#template_div').hide();
jQuery('#url_link_div').show();
break;
default:
jQuery('#show_hide_div').show();
jQuery('#limitorder_div').show();
jQuery('#html_format_div').hide();
jQuery('#dt_options_div').hide();
jQuery('#json_div').hide();
jQuery('#value_div').hide();
jQuery('#template_div').hide();
jQuery('#url_link_div').hide();
break;
}
}
function getValue(attr, value, errors) {
if (value) {
if (errors && value.indexOf('"') > -1) {
errors.push('<?php _e('Error: "', 'contact-form-7-to-database-extension'); ?>'
+ attr +
'<?php _e('" should not contain double-quotes (")', 'contact-form-7-to-database-extension'); ?>');
value = value.replace('"', "'");
}
return attr + '="' + value + '"';
}
return '';
}
function getValueUrl(attr, value) {
if (value) {
return attr + '=' + encodeURIComponent(value)
}
return '';
}
function join(arr, delim) {
if (delim == null) {
delim = ' ';
}
var tmp = [];
for (idx=0; idx<arr.length; idx++) {
if (arr[idx] != '') {
tmp.push(arr[idx]);
}
}
return tmp.join(delim);
}
function chopLastChar(text) {
return text.substr(0, text.length - 1);
}
function createShortCode() {
var scElements = [];
var urlElements = [];
var validationErrors = [];
var shortcode = jQuery('#shortcode_ctrl').val();
if (shortcode == '') {
jQuery('#shortcode_result_text').html('');
jQuery('#url_result_link').html('').attr('href', '#');
return;
}
scElements.push(chopLastChar(shortcode));
var formName = jQuery('#form_name_cntl').val();
if (!formName) {
validationErrors.push('<?php _e('Error: no form is chosen', 'contact-form-7-to-database-extension') ?>');
}
else {
scElements.push('form="' + formName + '"');
urlElements.push('form=' + encodeURIComponent(formName));
}
if (shortcode != '[cfdb-count]') {
scElements.push(getValue('show', jQuery('#show_cntl').val(), validationErrors));
urlElements.push(getValueUrl('show', jQuery('#show_cntl').val()));
scElements.push(getValue('hide', jQuery('#hide_cntl').val(), validationErrors));
urlElements.push(getValueUrl('hide', jQuery('#hide_cntl').val()));
}
var filter = getValue('filter', jQuery('#filter_cntl').val(), validationErrors);
if (filter) {
scElements.push(filter);
urlElements.push(getValueUrl('filter', jQuery('#filter_cntl').val()));
if (jQuery('#search_cntl').val()) {
validationErrors.push('<?php _e('Warning: "search" field ignored because "filter" is used (use one but not both)', 'contact-form-7-to-database-extension'); ?>');
}
}
else {
scElements.push(getValue('search', jQuery('#search_cntl').val(), validationErrors));
urlElements.push(getValueUrl('search', jQuery('#search_cntl').val()));
}
if (shortcode != '[cfdb-count]') {
var limitRows = jQuery('#limit_rows_cntl').val();
var limitStart = jQuery('#limit_start_cntl').val();
if (limitStart && !limitRows) {
validationErrors.push('<?php _e('Error: "limit": if you provide a value for "Start Row" then you must also provide a value for "Num Rows"', 'contact-form-7-to-database-extension'); ?>');
}
if (limitRows) {
if (! /^\d+$/.test(limitRows)) {
validationErrors.push('<?php _e('Error: "limit": "Num Rows" must be a positive integer', 'contact-form-7-to-database-extension'); ?>');
}
else {
var limitOption = ' limit="';
var limitOptionUrl = ' limit=';
if (limitStart) {
if (! /^\d+$/.test(limitStart)) {
validationErrors.push('<?php _e('Error: "limit": "Start Row" must be a positive integer', 'contact-form-7-to-database-extension'); ?>');
}
else {
limitOption += limitStart + ",";
limitOptionUrl += encodeURIComponent(limitStart + ",");
}
}
limitOption += limitRows;
limitOptionUrl += limitRows;
scElements.push(limitOption + '"');
urlElements.push(limitOptionUrl);
}
}
var orderByElem = getValue('orderby', jQuery('#orderby_cntl').val(), validationErrors);
if (orderByElem) {
var orderByElemUrl = getValueUrl('orderby', jQuery('#orderby_cntl').val());
var orderByDir = jQuery('#orderbydir_cntl').val();
if (orderByDir) {
orderByElem = chopLastChar(orderByElem) + ' ' + orderByDir + '"';
orderByElemUrl = orderByElemUrl + encodeURIComponent(' ' + orderByDir);
}
scElements.push(orderByElem);
urlElements.push(orderByElemUrl);
}
}
var scText;
switch (shortcode) {
case '[cfdb-html]':
scElements.push(getValue('filelinks', jQuery('#filelinks_cntl').val(), validationErrors));
urlElements.push(getValueUrl('filelinks', jQuery('#filelinks_cntl').val()));
scElements.push(getValue('wpautop', jQuery('#wpautop_cntl').val(), validationErrors));
urlElements.push(getValueUrl('wpautop', jQuery('#wpautop_cntl').val()));
var content = jQuery('#content_cntl').val();
urlElements.push('content=' + encodeURIComponent(content));
urlElements.push('enc=HTMLTemplate');
scText = join(scElements) + ']' + content + '[/cfdb-html]';
break;
case '[cfdb-table]':
scElements.push(getValue('id', jQuery('#id_cntl').val(), validationErrors));
urlElements.push(getValueUrl('id', jQuery('#id_cntl').val()));
scElements.push(getValue('class', jQuery('#class_cntl').val(), validationErrors));
urlElements.push(getValueUrl('class', jQuery('#class_cntl').val()));
scElements.push(getValue('style', jQuery('#style_cntl').val(), validationErrors));
urlElements.push(getValueUrl('style', jQuery('#style_cntl').val()));
urlElements.push('enc=HTML');
scText = join(scElements) + ']';
break;
case '[cfdb-datatable]':
scElements.push(getValue('id', jQuery('#id_cntl').val(), validationErrors));
urlElements.push(getValueUrl('id', jQuery('#id_cntl').val()));
scElements.push(getValue('class', jQuery('#class_cntl').val(), validationErrors));
urlElements.push(getValueUrl('class', jQuery('#class_cntl').val()));
scElements.push(getValue('style', jQuery('#style_cntl').val(), validationErrors));
urlElements.push(getValueUrl('style', jQuery('#style_cntl').val()));
scElements.push(getValue('dt_options', jQuery('#dt_options_cntl').val(), validationErrors));
urlElements.push(getValueUrl('dt_options', jQuery('#dt_options_cntl').val()));
urlElements.push('enc=DT');
scText = join(scElements) + ']';
break;
case '[cfdb-value]':
scElements.push(getValue('function', jQuery('#function_cntl').val(), validationErrors));
urlElements.push(getValueUrl('function', jQuery('#function_cntl').val()));
scElements.push(getValue('delimiter', jQuery('#delimiter_cntl').val(), validationErrors));
urlElements.push(getValueUrl('delimiter', jQuery('#delimiter_cntl').val()));
urlElements.push('enc=VALUE');
scText = join(scElements) + ']';
break;
case '[cfdb-count]':
urlElements.push('enc=COUNT');
scText = join(scElements) + ']'; // hopLastChar(scElements.join(' ')) + ']';
break;
case '[cfdb-json]':
scElements.push(getValue('var', jQuery('#var_cntl').val(), validationErrors));
urlElements.push(getValueUrl('var', jQuery('#var_cntl').val()));
scElements.push(getValue('format', jQuery('#format_cntl').val(), validationErrors));
urlElements.push(getValueUrl('format', jQuery('#format_cntl').val()));
urlElements.push('enc=JSON');
scText = join(scElements) + ']';
break;
case '[cfdb-export-link]':
scElements.push(getValue('enc', jQuery('#enc_cntl').val(), validationErrors));
scElements.push(getValue('urlonly', jQuery('#urlonly_cntl').val(), validationErrors));
scText = join(scElements) + ']';
break;
default:
scText = shortcode;
break;
}
jQuery('#shortcode_result_text').html(scText);
if (shortcode == '[cfdb-export-link]') {
jQuery('#url_result_link').attr('href', '#').html('');
}
else {
var url = '<?php echo admin_url('admin-ajax.php') ?>?action=cfdb-export&';
url += join(urlElements, '&');
jQuery('#url_result_link').attr('href', url).html(url);
}
jQuery('#validations_text').html(validationErrors.join('<br/>'));
}
var getFormFieldsUrlBase = '<?php echo $plugin->getFormFieldsAjaxUrlBase() ?>';
function getFormFields() {
jQuery('[id^=add]').attr('disabled', 'disabled');
jQuery('[id^=btn]').attr('disabled', 'disabled');
var formName = jQuery('#form_name_cntl').val();
var url = getFormFieldsUrlBase + encodeURIComponent(formName);
jQuery.getJSON(url, function(json) {
var optionsHtml = '<option value=""></option>';
jQuery(json).each(function() {
optionsHtml += '<option value="' + this + '">' + this + '</option>';
});
jQuery('[id^=add]').html(optionsHtml).removeAttr('disabled');
jQuery('[id^=btn]').removeAttr('disabled');
});
}
function addFieldToShow() {
var value = jQuery('#show_cntl').val();
if (value) {
value += ',';
}
jQuery('#show_cntl').val(value + jQuery('#add_show').val());
createShortCode();
}
function addFieldToHide() {
var value = jQuery('#hide_cntl').val();
if (value) {
value += ',';
}
jQuery('#hide_cntl').val(value + jQuery('#add_hide').val());
createShortCode();
}
function addFieldToOrderBy() {
var value = jQuery('#orderby_cntl').val();
if (value) {
value += ',';
}
jQuery('#orderby_cntl').val(value + jQuery('#add_orderby').val());
createShortCode();
}
function addFieldToFilter() {
var value = jQuery('#filter_cntl').val();
if (value) {
value += jQuery('#filter_bool').val();
}
value += jQuery('#add_filter').val() + jQuery('#filter_op').val() + jQuery('#filter_val').val();
jQuery('#filter_cntl').val(value);
createShortCode();
}
function addFieldToContent() {
jQuery('#content_cntl').val(jQuery('#content_cntl').val() + '${' + jQuery('#add_content').val() + '}');
}
function reset() {
jQuery('#show_cntl').val('');
jQuery('#hide_cntl').val('');
jQuery('#search_cntl').val('');
jQuery('#filter_cntl').val('');
jQuery('#limit_rows_cntl').val('');
jQuery('#limit_start_cntl').val('');
jQuery('#orderby_cntl').val('');
jQuery('#id_cntl').val('');
jQuery('#class_cntl').val('');
jQuery('#style_cntl').val('');
jQuery('#dt_options_cntl').val('');
jQuery('#var_cntl').val('');
jQuery('#format_cntl').val('');
jQuery('#function_cntl').val('');
jQuery('#delimiter_cntl').val('');
jQuery('#filelinks_cntl').val('');
jQuery('#wpautop_cntl').val('');
jQuery('#content_cntl').val('');
jQuery('#enc_cntl').val('');
jQuery('#urlonly_cntl').val('');
createShortCode();
}
jQuery.ajaxSetup({
cache: false
});
jQuery(document).ready(function() {
showHideOptionDivs();
createShortCode();
jQuery('#shortcode_ctrl').change(showHideOptionDivs);
jQuery('#shortcode_ctrl').change(createShortCode);
jQuery('select[id$="cntl"]').change(createShortCode);
jQuery('input[id$="cntl"]').keyup(createShortCode);
jQuery('textarea[id$="cntl"]').keyup(createShortCode);
jQuery('#form_name_cntl').change(getFormFields);
jQuery('#btn_show').click(addFieldToShow);
jQuery('#btn_hide').click(addFieldToHide);
jQuery('#btn_orderby').click(addFieldToOrderBy);
jQuery('#btn_filter').click(addFieldToFilter);
jQuery('#btn_content').click(function() {
addFieldToContent();
createShortCode();
});
jQuery('#enc_cntl').click(createShortCode);
jQuery('#urlonly_cntl').click(createShortCode);
jQuery('#reset_button').click(reset);
});
</script>
<style type="text/css">
div.shortcodeoptions {
border: #ccccff groove;
margin-bottom: 10px;
padding: 5px;
}
div.shortcodeoptions label {
font-weight: bold;
font-family: Arial sans-serif;
margin-top: 5px;
}
#shortcode_result_div {
margin-top: 1em;
}
.label_box {
display: inline-block;
min-width: 50px;
padding-left: 2px;
padding-right: 2px;
border: 1px;
margin-right: 5px;
}
</style>
<div id="shortcode_result_div">
<pre style="white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;"><code id="shortcode_result_text"></code></pre>
</div>
<div id="url_result_link_div">
<code><a target="_cfdb_export" href="#" id="url_result_link"></a></code>
</div>
<div id="validations_div">
<span id="validations_text" style="background-color:#ffff66;"></span>
</div>
<h2>Short Code Builder</h2>
<div style="margin-bottom:10px">
<span>
<div class="label_box"><label for="shortcode_ctrl">Short Code</label></div>
<select name="shortcode_ctrl" id="shortcode_ctrl">
<option value=""><?php _e('* Select a short code *', 'contact-form-7-to-database-extension') ?></option>
<option value="[cfdb-html]">[cfdb-html]</option>
<option value="[cfdb-table]">[cfdb-table]</option>
<option value="[cfdb-datatable]">[cfdb-datatable]</option>
<option value="[cfdb-value]">[cfdb-value]</option>
<option value="[cfdb-count]">[cfdb-count]</option>
<option value="[cfdb-json]">[cfdb-json]</option>
<option value="[cfdb-export-link]">[cfdb-export-link]</option>
</select>
</span>
<span style="margin-left:10px">
<div class="label_box"><label for="form_name_cntl">form</label></div>
<select name="form_name_cntl" id="form_name_cntl">
<option value=""><?php _e('* Select a form *', 'contact-form-7-to-database-extension') ?></option>
<?php foreach ($rows as $aRow) {
$formName = $aRow->form_name;
$selected = ($formName == $currSelection) ? "selected" : "";
?>
<option value="<?php echo $formName ?>" <?php echo $selected ?>><?php echo $formName ?></option>
<?php } ?>
</select>
</span>
<span style="margin-left:10px">
<button id="reset_button"><?php echo _e('Reset', 'contact-form-7-to-database-extension') ?></button>
</span>
</div>
<div class="shortcodeoptions">
<a id="doc_url_tag" target="_docs"
href="http://cfdbplugin.com/?page_id=89"><?php _e('Documentation', 'contact-form-7-to-database-extension'); ?></a>
</div>
<div id="show_hide_div" class="shortcodeoptions">
<?php _e('Which fields/columns do you want to display?', 'contact-form-7-to-database-extension'); ?>
<div>
<div class="label_box"><label for="show_cntl">show</label></div>
<select name="add_show" id="add_show"></select><button id="btn_show"">&raquo;</button>
<input name="show_cntl" id="show_cntl" type="text" size="100"/>
</div>
<div>
<div class="label_box"><label for="hide_cntl">hide</label></div>
<select name="add_hide" id="add_hide"></select><button id="btn_hide">&raquo;</button>
<input name="hide_cntl" id="hide_cntl" type="text" size="100"/>
</div>
</div>
<div id="filter_div" class="shortcodeoptions">
<div><?php _e('Which rows/submissions do you want to display?', 'contact-form-7-to-database-extension'); ?></div>
<div>
<div class="label_box"><label for="search_cntl">search</label></div>
<input name="search_cntl" id="search_cntl" type="text" size="30"/>
</div>
<div>
<div class="label_box"><label for="filter_cntl">filter</label></div>
<select name="filter_bool" id="filter_bool">
<option value="&&">&&</option>
<option value="||">||</option>
</select>
<select name="add_filter" id="add_filter"></select>
<select name="filter_op" id="filter_op">
<option value="=">=</option>
<option value="!=">!=</option>
<option value=">">></option>
<option value="<"><</option>
<option value="<="><=</option>
<option value="<="><=</option>
<option value="===">===</option>
<option value="!==">!==</option>
<option value="~~">~~</option>
</select>
<input name="filter_val" id="filter_val" type="text" size="10"/>
<button id="btn_filter">&raquo;</button>
<input name="filter_cntl" id="filter_cntl" type="text" size="100"/>
</div>
</div>
<div id="limitorder_div" class="shortcodeoptions">
<div>
<div class="label_box"><label for="limit_rows_cntl">limit</label></div>
Num Rows <input name="limit_rows_cntl" id="limit_rows_cntl" type="text" size="10"/>
Start Row (0)<input name="limit_start_cntl" id="limit_start_cntl" type="text" size="10"/>
</div>
<div id="orderby_div">
<div class="label_box"><label for="orderby_cntl">orderby</label></div>
<select name="add_orderby" id="add_orderby"></select><button id="btn_orderby">&raquo;</button>
<input name="orderby_cntl" id="orderby_cntl" type="text" size="100"/>
<select id="orderbydir_cntl" name="orderbydir_cntl">
<option value=""></option>
<option value="ASC">ASC</option>
<option value="DESC">DESC</option>
</select>
</div>
</div>
<div id="html_format_div" class="shortcodeoptions">
<div><?php _e('HTML Table Formatting', 'contact-form-7-to-database-extension'); ?></div>
<div>
<div class="label_box"><label for="id_cntl">id</label></div>
<input name="id_cntl" id="id_cntl" type="text" size="10"/>
</div>
<div>
<div class="label_box"><label for="class_cntl">class</label></div>
<input name="class_cntl" id="class_cntl" type="text" size="10"/>
</div>
<div>
<div class="label_box"><label for="style_cntl">style</label></div>
<input name="style_cntl" id="style_cntl" type="text" size="100"/>
</div>
</div>
<div id="dt_options_div" class="shortcodeoptions">
<div><?php _e('DataTable Options', 'contact-form-7-to-database-extension'); ?></div>
<div class="label_box"><label for="dt_options_cntl">dt_options</label></div>
<input name="dt_options_cntl" id="dt_options_cntl" type="text" size="100"/>
</div>
<div id="json_div" class="shortcodeoptions">
<div><?php _e('JSON Options', 'contact-form-7-to-database-extension'); ?></div>
<div>
<div class="label_box"><label for="var_cntl">var</label></div>
<input name="var_cntl" id="var_cntl" type="text" size="10"/>
</div>
<div>
<div class="label_box"><label for="format_cntl">format</label></div>
<select id="format_cntl" name="format_cntl">
<option value=""></option>
<option value="map">map</option>
<option value="array">array</option>
<option value="arraynoheader">arraynoheader</option>
</select>
</div>
</div>
<div id="value_div" class="shortcodeoptions">
<div><?php _e('VALUE Options', 'contact-form-7-to-database-extension'); ?></div>
<div>
<div class="label_box"><label for="function_cntl">function</label></div>
<select id="function_cntl" name="function_cntl">
<option value=""></option>
<option value="min">min</option>
<option value="max">max</option>
<option value="sum">sum</option>
<option value="mean">mean</option>
</select>
</div>
<div>
<div class="label_box"><label for="delimiter_cntl">delimiter</label></div>
<input name="delimiter_cntl" id="delimiter_cntl" type="text" size="10"/>
</div>
</div>
<div id="template_div" class="shortcodeoptions">
<div>
<div class="label_box"><label for="filelinks_cntl">filelinks</label></div>
<select id="filelinks_cntl" name="filelinks_cntl">
<option value=""></option>
<option value="url">url</option>
<option value="name">name</option>
<option value="link">link</option>
<option value="img">img</option>
</select>
<div class="label_box"><label for="wpautop_cntl">wpautop</label></div>
<select id="wpautop_cntl" name="wpautop_cntl">
<option value=""></option>
<option value="false">false</option>
<option value="true">true</option>
</select>
</div>
<div>
<div class="label_box"><label for="content_cntl">Template</label></div>
<select name="add_content" id="add_content"></select><button id="btn_content">&raquo;</button><br/>
<textarea name="content_cntl" id="content_cntl" cols="100" rows="10"></textarea>
</div>
</div>
<div id="url_link_div" class="shortcodeoptions">
<div>
<div class="label_box"><label for="enc_cntl">enc</label></div>
<select id="enc_cntl" name="enc_cntl">
<option value=""></option>
<option id="CSVUTF8BOM" value="CSVUTF8BOM">
<?php _e('Excel CSV (UTF8-BOM)', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="TSVUTF16LEBOM" value="TSVUTF16LEBOM">
<?php _e('Excel TSV (UTF16LE-BOM)', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="CSVUTF8" value="CSVUTF8">
<?php _e('Plain CSV (UTF-8)', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="IQY" value="IQY">
<?php _e('Excel Internet Query', 'contact-form-7-to-database-extension'); ?>
</option>
</select>
</div>
<div>
<div class="label_box"><label for="urlonly_cntl">urlonly</label></div>
<select id="urlonly_cntl" name="urlonly_cntl">
<option value=""></option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<?php
}
}

View File

@ -0,0 +1,508 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CF7DBPlugin.php');
require_once('CFDBView.php');
require_once('ExportToHtmlTable.php');
class CFDBViewWhatsInDB extends CFDBView {
function display(&$plugin) {
if ($plugin == null) {
$plugin = new CF7DBPlugin;
}
$canEdit = $plugin->canUserDoRoleOption('CanChangeSubmitData');
$this->pageHeader($plugin);
global $wpdb;
$tableName = $plugin->getSubmitsTableName();
$useDataTables = $plugin->getOption('UseDataTablesJS', 'true') == 'true';
$tableHtmlId = 'cf2dbtable';
// Identify which forms have data in the database
$rows = $wpdb->get_results("select distinct `form_name` from `$tableName` order by `form_name`");
if ($rows == null || count($rows) == 0) {
_e('No form submissions in the database', 'contact-form-7-to-database-extension');
return;
}
$page = 1;
if (isset($_REQUEST['dbpage'])) {
$page = $_REQUEST['dbpage'];
}
else if (isset($_GET['dbpage'])) {
$page = $_GET['dbpage'];
}
$currSelection = null; //$rows[0]->form_name;
if (isset($_REQUEST['form_name'])) {
$currSelection = $_REQUEST['form_name'];
}
else if (isset($_GET['form_name'])) {
$currSelection = $_GET['form_name'];
}
if ($currSelection) {
// Check for delete operation
if (isset($_POST['delete']) && $canEdit) {
if (isset($_POST['submit_time'])) {
$submitTime = $_POST['submit_time'];
$wpdb->query(
$wpdb->prepare(
"delete from `$tableName` where `form_name` = '%s' and `submit_time` = %F",
$currSelection, $submitTime));
}
else if (isset($_POST['all'])) {
$wpdb->query(
$wpdb->prepare(
"delete from `$tableName` where `form_name` = '%s'", $currSelection));
}
else {
foreach ($_POST as $name => $value) { // checkboxes
if ($value == 'row') {
// Dots and spaces in variable names are converted to underscores. For example <input name="a.b" /> becomes $_REQUEST["a_b"].
// http://www.php.net/manual/en/language.variables.external.php
// We are expecting a time value like '1300728460.6626' but will instead get '1300728460_6626'
// so we need to put the '.' back in before going to the DB.
$name = str_replace('_', '.', $name);
$wpdb->query(
$wpdb->prepare(
"delete from `$tableName` where `form_name` = '%s' and `submit_time` = %F",
$currSelection, $name));
}
}
}
}
}
// Form selection drop-down list
$pluginDirUrl = $plugin->getPluginDirUrl();
?>
<table width="100%" cellspacing="20">
<tr>
<td align="left">
<form method="get" action="" name="displayform" id="displayform">
<input type="hidden" name="page" value="<?php echo $_REQUEST['page'] ?>"/>
<select name="form_name" id="form_name" onchange="this.form.submit();">
<option value=""><?php _e('* Select a form *', 'contact-form-7-to-database-extension') ?></option>
<?php foreach ($rows as $aRow) {
$formName = $aRow->form_name;
$selected = ($formName == $currSelection) ? "selected" : "";
?>
<option value="<?php echo $formName ?>" <?php echo $selected ?>><?php echo $formName ?></option>
<?php } ?>
</select>
</form>
</td>
<td align="center">
<?php if ($currSelection) { ?>
<script type="text/javascript" language="Javascript">
function changeDbPage(page) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<input id='dbpage' name='dbpage' type='hidden' value='" + page + "'>";
var dispForm = document.forms['displayform'];
dispForm.appendChild(newdiv);
dispForm.submit();
}
function getSearchFieldValue() {
var searchVal = '';
if (typeof jQuery == 'function') {
try {
searchVal = jQuery('#<?php echo $tableHtmlId;?>_filter input').val();
}
catch (e) {
}
}
return searchVal;
}
function exportData(encSelect) {
var enc = encSelect.options[encSelect.selectedIndex].value;
if (enc == 'GSS') {
if (typeof jQuery == 'function') {
try {
jQuery("#GoogleCredentialsDialog").dialog({ autoOpen: false, title: '<?php _e("Google Login for Upload", 'contact-form-7-to-database-extension')?>' });
jQuery("#GoogleCredentialsDialog").dialog('open');
jQuery("#guser").focus();
}
catch (e) {
alert('Error: ' + e.message);
}
}
else {
alert("<?php _e('Cannot perform operation because jQuery is not loaded in this page', 'contact-form-7-to-database-extension')?>");
}
}
else {
var url = '<?php echo admin_url('admin-ajax.php') ?>?action=cfdb-export&form=<?php echo urlencode($currSelection) ?>&enc=' + enc;
var searchVal = getSearchFieldValue();
if (searchVal != null && searchVal != "") {
url += '&search=' + encodeURIComponent(searchVal);
}
location.href = url;
}
}
function uploadGoogleSS() {
var key = '3fde789a';
var guser = printHex(des(key, jQuery('#guser').attr('value'), 1));
var gpwd = printHex(des(key, jQuery('#gpwd').attr('value'), 1));
jQuery("#GoogleCredentialsDialog").dialog('close');
var form = document.createElement("form");
form.setAttribute("method", 'POST');
var url = '<?php echo $pluginDirUrl ?>export.php?form=<?php echo urlencode($currSelection) ?>&enc=GSS';
var searchVal = getSearchFieldValue();
if (searchVal != null && searchVal != "") {
url += '&search=' + encodeURI(searchVal);
}
form.setAttribute("action", url);
var params = {guser: encodeURI(guser), gpwd: encodeURI(gpwd)};
for (var pkey in params) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", pkey);
hiddenField.setAttribute("value", params[pkey]);
form.appendChild(hiddenField);
}
document.body.appendChild(form);
form.submit();
}
</script>
<form name="exportcsv" action="">
<select size="1" name="enc">
<option id="IQY" value="IQY">
<?php _e('Excel Internet Query', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="CSVUTF8BOM" value="CSVUTF8BOM">
<?php _e('Excel CSV (UTF8-BOM)', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="TSVUTF16LEBOM" value="TSVUTF16LEBOM">
<?php _e('Excel TSV (UTF16LE-BOM)', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="CSVUTF8" value="CSVUTF8">
<?php _e('Plain CSV (UTF-8)', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="GSS" value="GSS">
<?php _e('Google Spreadsheet', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="GLD" value="GLD">
<?php _e('Google Spreadsheet Live Data', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="HTML" value="HTML">
<?php _e('HTML', 'contact-form-7-to-database-extension'); ?>
</option>
<option id="JSON" value="JSON">
<?php _e('JSON', 'contact-form-7-to-database-extension'); ?>
</option>
</select>
<input name="exportButton" type="button"
value="<?php _e('Export', 'contact-form-7-to-database-extension'); ?>"
onclick="exportData(this.form.elements['enc'])"/>
</form>
<?php } ?>
</td>
<td align="right">
<?php if ($currSelection && $canEdit) { ?>
<form action="" method="post">
<input name="form_name" type="hidden" value="<?php echo $currSelection ?>"/>
<input name="all" type="hidden" value="y"/>
<input name="delete" type="submit"
value="<?php _e('Delete All This Form\'s Records', 'contact-form-7-to-database-extension'); ?>"
onclick="return confirm('Are you sure you want to delete all the data for this form?')"/>
</form>
<?php } ?>
</td>
</tr>
</table>
<?php
if ($currSelection) {
// Show table of form data
if ($useDataTables) {
$i18nUrl = $plugin->getDataTableTranslationUrl();
?>
<script type="text/javascript" language="Javascript">
jQuery(document).ready(function() {
jQuery('#<?php echo $tableHtmlId ?>').dataTable({ <?php // "sDom": 'Rlfrtip', // ColReorder ?>
"bJQueryUI": true,
"aaSorting": [],
"bScrollCollapse": true
<?php
if ($i18nUrl) {
echo ", \"oLanguage\": { \"sUrl\": \"$i18nUrl\" }";
}
if ($canEdit) {
do_action_ref_array('cfdb_fnDrawCallbackJSON', array($tableHtmlId));
}
?>
});
});
</script>
<?php
}
if ($canEdit) {
?>
<form action="" method="post">
<input name="form_name" type="hidden" value="<?php echo $currSelection ?>"/>
<input name="delete" type="hidden" value="rows"/>
<?php
}
?>
<?php
$exporter = new ExportToHtmlTable();
$dbRowCount = $exporter->getDBRowCount($currSelection);
$maxRows = $plugin->getOption('MaxRows', '100');
$startRow = $this->paginationDiv($plugin, $dbRowCount, $maxRows, $page);
?>
<div <?php if (!$useDataTables) echo 'style="overflow:auto; max-height:500px; max-width:500px"' ?>>
<?php
// Pick up any options that the user enters in the URL.
// This will include extraneous "form_name" and "page" GET params which are in the URL
// for this admin page
$options = array_merge($_POST, $_GET);
$options['canDelete'] = $canEdit;
if ($maxRows) {
$options['limit'] = ($startRow - 1) . ',' . ($maxRows);
}
if ($useDataTables) {
$options['id'] = $tableHtmlId;
$options['class'] = '';
$options['style'] = "#$tableHtmlId td > div { max-height: 100px; overflow: auto; font-size: small; }"; // don't let cells get too tall
}
$exporter->export($currSelection, $options);
?>
</div>
<?php if ($canEdit) {
?>
</form>
<?php
}
}
?>
<div style="margin-top:1em"> <?php // Footer ?>
<table style="width:100%;">
<tbody>
<tr>
<td align="center" colspan="4">
<span style="font-size:x-small; font-style: italic;">
<?php _e('Did you know: This plugin captures data from both these plugins:', 'contact-form-7-to-database-extension'); ?>
<a target="_cf7" href="http://wordpress.org/extend/plugins/contact-form-7/">Contact Form
7</a>
<a target="_fscf" href="http://wordpress.org/extend/plugins/si-contact-form/">Fast Secure
Contact Form</a>
</span>
</td>
</tr>
<tr>
<td align="center" colspan="4">
<span style="font-size:x-small; font-style: italic;">
<?php _e('Did you know: You can add this data to your posts and pages using these shortcodes:', 'contact-form-7-to-database-extension'); ?>
<br/>
<a target="_faq" href="http://cfdbplugin.com/?page_id=284">[cfdb-html]</a>
<a target="_faq" href="http://cfdbplugin.com/?page_id=91">[cfdb-datatable]</a>
<a target="_faq" href="http://cfdbplugin.com/?page_id=93">[cfdb-table]</a>
<a target="_faq" href="http://cfdbplugin.com/?page_id=98">[cfdb-value]</a>
<a target="_faq" href="http://cfdbplugin.com/?page_id=278">[cfdb-count]</a>
<a target="_faq" href="http://cfdbplugin.com/?page_id=96">[cfdb-json]</a>
</span>
</td>
</tr>
<tr>
<td align="center" colspan="4">
<span style="font-size:x-small; font-style: italic;">
<?php _e('Would you like to help translate this plugin into your language?', 'contact-form-7-to-database-extension'); ?>
<a target="_i18n"
href="http://cfdbplugin.com/?page_id=7"><?php _e('How to create a translation', 'contact-form-7-to-database-extension'); ?></a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
<?php
if ($currSelection && 'true' == $plugin->getOption('ShowQuery')) {
?>
<div id="query">
<strong><?php _e('Query:', 'contact-form-7-to-database-extension') ?></strong><br/>
<pre><?php echo $exporter->getPivotQuery($currSelection); ?></pre>
</div>
<?php
}
if ($currSelection) {
?>
<div id="GoogleCredentialsDialog" style="display:none; background-color:#EEEEEE;">
<table>
<tbody>
<tr>
<td>User</td>
<td><input id="guser" type="text" size="25" value="@gmail.com"/></td>
</tr>
<tr>
<td>Password</td>
<td><input id="gpwd" type="password" size="25" value=""/></td>
</tr>
<tr>
<td></td>
<td>
<input type="button" value="<?php _e("Cancel", 'contact-form-7-to-database-extension') ?>"
onclick="jQuery('#GoogleCredentialsDialog').dialog('close');"/>
<input type="button" value="<?php _e("Upload", 'contact-form-7-to-database-extension') ?>"
onclick="uploadGoogleSS()"/>
</td>
</tr>
</tbody>
</table>
</div>
<?php
}
}
/**
* @param $plugin CF7DBPlugin
* @param $totalRows integer
* @param $rowsPerPage integer
* @param $page integer
* @return
*/
protected function paginationDiv($plugin, $totalRows, $rowsPerPage, $page) {
$nextLabel = __('next »', 'contact-form-7-to-database-extension');
$prevLabel = __('« prev', 'contact-form-7-to-database-extension');
echo '<link rel="stylesheet" href="';
echo $plugin->getPluginFileUrl();
echo '/css/paginate.css';
echo '" type="text/css"/>';
// echo '<style type="text/css">';
// include('css/paginate.css');
// echo '</style>';
if (!$page || $page < 1) $page = 1; //default to 1.
$startRow = $rowsPerPage * ($page - 1) + 1;
$endRow = min($startRow + $rowsPerPage - 1, $totalRows);
echo '<span style="margin-bottom:5px;">';
printf(__('Returned entries %s to %s of %s entries in the database', 'contact-form-7-to-database-extension'),
$startRow, $endRow, $totalRows);
echo '</span>';
echo '<div class="cfdb_paginate">';
$numPages = ceil($totalRows / $rowsPerPage);
$adjacents = 3;
/* Setup page vars for display. */
$prev = $page - 1; //previous page is page - 1
$next = $page + 1; //next page is page + 1
$lastpage = $numPages;
$lpm1 = $lastpage - 1; //last page minus 1
/*
Now we apply our rules and draw the pagination object.
We're actually saving the code to a variable in case we want to draw it more than once.
*/
if ($lastpage > 1) {
echo "<div class=\"pagination\">";
//previous button
if ($page > 1)
echo $this->paginateLink($prev, $prevLabel);
else
echo "<span class=\"disabled\">$prevLabel</span>";
if ($lastpage < 7 + ($adjacents * 2)) //not enough pages to bother breaking it up
{
for ($counter = 1; $counter <= $lastpage; $counter++)
{
if ($counter == $page)
echo "<span class=\"current\">$counter</span>";
else
echo $this->paginateLink($counter, $counter);
}
}
elseif ($lastpage > 5 + ($adjacents * 2)) //enough pages to hide some
{
//close to beginning; only hide later pages
if ($page < 1 + ($adjacents * 2)) {
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++)
{
if ($counter == $page)
echo "<span class=\"current\">$counter</span>";
else
echo $this->paginateLink($counter, $counter);
}
echo '...';
echo $this->paginateLink($lpm1, $lpm1);
echo $this->paginateLink($lastpage, $lastpage);
}
//in middle; hide some front and some back
elseif ($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2))
{
echo $this->paginateLink(1, 1);
echo $this->paginateLink(2, 2);
echo '...';
for ($counter = $page - $adjacents; $counter <= $page + $adjacents; $counter++)
{
if ($counter == $page)
echo "<span class=\"current\">$counter</span>";
else
echo $this->paginateLink($counter, $counter);
}
echo '...';
echo $this->paginateLink($lpm1, $lpm1);
echo $this->paginateLink($lastpage, $lastpage);
}
//close to end; only hide early pages
else
{
echo $this->paginateLink(1, 1);
echo $this->paginateLink(2, 2);
echo '...';
for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++)
{
if ($counter == $page)
echo "<span class=\"current\">$counter</span>";
else
echo $this->paginateLink($counter, $counter);
}
}
}
//next button
if ($page < $counter - 1)
echo $this->paginateLink($next, $nextLabel);
else
echo "<span class=\"disabled\">$nextLabel</span>";
echo "</div>\n";
}
echo '</div>';
return $startRow;
}
protected function paginateLink($page, $label) {
return "<a href=\"#\" onclick=\"changeDbPage('$page');\">$label</a>";
}
}

View File

@ -0,0 +1,100 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
class CJ7DBCheckZendFramework {
/**
* Checks for the existence of the Zend Framework. If not found, prints out some (hopefully) helpful information
* @return bool true if Zend is found, *but* if not found calls wp_die()
*/
public static function checkIncludeZend() {
if (!(include 'Zend/Loader.php')) {
ob_start();
?>
<h1>Missing Zend Framework</h1>
<p>
This function requires part of the Zend framework that interacts with Google. <br/>
It appears that either:
</p>
<ol>
<li>The Zend Framework is not on the include_path or</li>
<li>You do not have the Zend Framework installed</li>
</ol>
<p>
<code>include_path="<?php echo(ini_get('include_path'));?>"</code><br/>
<code>php.ini file is
"<?php $phpInfo = CJ7DBCheckZendFramework::getPhpInfo(); echo($phpInfo['Loaded Configuration File']);?>
"</code><br/>
</p>
<ol>
<li>locate the the <span style="font-weight: bold;">Zend</span> directory on your computer</li>
<li>If found, here is one way to put it on the include path</li>
<ol>
<li style="list-style: lower-roman">copy the <span style="font-weight: bold;">php.ini</span> file to your WordPress installation to
<span style="font-weight: bold;">[wp-dir]/wp-content/plugins/contact-form-7-to-database-extension/php.ini</span>
</li>
<li style="list-style: lower-roman">add a line to this new file:<br/>
<code>include_path="<?php echo(ini_get('include_path') . PATH_SEPARATOR . "[Zend-parent-directory]");?>"</code>
</li>
</ol>
<li>If not found, install and configure Zend (or contact or administrator or host provider)<br/>
See: <a target="_blank" href="http://code.google.com/apis/gdata/articles/php_client_lib.html">Getting
Started
with the Google Data PHP Client Library</a><br/>
To download the part of Zend required, see: <a target="_blank"
href="http://framework.zend.com/download/gdata/">Zend
GData</a>
</li>
</ol>
<?php
$errorHtml = ob_get_contents();
ob_end_clean();
include_once('CFDBDie.php');
CFDBDie::wp_die($errorHtml,
__('Missing Zend Framework', 'contact-form-7-to-database-extension'),
array('response' => 200, 'back_link' => true));
// Doesn't actually return because we call wp_die
return false;
}
return true;
}
/**
* Taken from: http://www.php.net/manual/en/function.phpinfo.php#87214
* @return array key => array(values) from phpinfo call
*/
private static function getPhpInfo() {
ob_start();
phpinfo(INFO_GENERAL);
$phpinfo = array('phpinfo' => array());
if (preg_match_all('#(?:<h2>(?:<a name=".*?">)?(.*?)(?:</a>)?</h2>)|(?:<tr(?: class=".*?")?><t[hd](?: class=".*?")?>(.*?)\s*</t[hd]>(?:<t[hd](?: class=".*?")?>(.*?)\s*</t[hd]>(?:<t[hd](?: class=".*?")?>(.*?)\s*</t[hd]>)?)?</tr>)#s', ob_get_clean(), $matches, PREG_SET_ORDER))
foreach ($matches as $match)
if (strlen($match[1]))
$phpinfo[$match[1]] = array();
elseif (isset($match[3]))
$phpinfo[end(array_keys($phpinfo))][$match[2]] = isset($match[4]) ? array($match[3], $match[4]) : $match[3];
else
$phpinfo[end(array_keys($phpinfo))][] = $match[2];
return $phpinfo['phpinfo'];
}
}

View File

@ -0,0 +1,177 @@
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
/* This is a script to be used with a Google Spreadsheet to make it dynamically load data (similar to Excel IQuery)
Instructions:
1. Create a new Google Spreadsheet
2. Go to Tools menu -> Scripts -> Script Editor...
3. Copy the text from this file and paste it into the Google script editor.
4. Save and close the script editor.
5. Click on a cell A1 in the Spreadsheet (or any cell)
6. Enter in the cell the formula:
=CF7ToDBData("siteUrl", "formName", "optional search", "user", "pwd")
Where the parameters are (be sure to quote them):
siteUrl: the URL of you site, e.g. "http://www.mywordpress.com"
formName: name of the form
optional search: leave as "" by default or add a search term to filter rows
user: your login name on your wordpress site
pwd: password
*/
function CF7ToDBData(siteUrl, formName, search, user, pwd) {
var response = fetchCF7ToDBCSVResponse(siteUrl, formName, search, user, pwd);
var contents = response.getContentText();
if (contents == '-1' || contents == '0') {
return "Error Code from WordPress: " + contents;
}
if (response.getResponseCode() >= 200 && response.getResponseCode() < 300) {
return csvToArray(contents);
}
else {
if (response.getResponseCode() == 401) {
return "Error: Login Failed";
}
if (response.getResponseCode() == 404) {
return "Error: Bad URL";
}
return "Error: HTTP " + response.getResponseCode();
}
}
function fetchCF7ToDBCSVResponse(siteUrl, formName, search, user, pwd) {
var encformName = encodeURI(formName).replace(new RegExp("%20", "g"), "%2B");
var url = siteUrl + "/wp-login.php?redirect_to=wp-admin/admin-ajax.php%3Faction%3Dcfdb-export%26form%3D" + encformName;
if (search != null && search != '') {
url += '%26search%3D' + encodeURI(search);
}
return UrlFetchApp.fetch(
url,
{
method: "post",
payload: "log=" + encodeURI(user) + "&pwd=" + encodeURI(pwd)
});
}
// Taken from: http://stackoverflow.com/questions/1293147/javascript-code-to-parse-csv-data
function csvToArray(text) {
text = CSVToArray(text, ",");
var arr = [];
var c = [];
for (var i = 0; i < text.length - 1; i++) {
c = [];
for (var j = 0; j < text[0].length; j++) {
c.push(text[i][j]);
}
arr.push(c);
}
return arr;
}
// Taken from: http://stackoverflow.com/questions/1293147/javascript-code-to-parse-csv-data
// This will parse a delimited string into an array of
// arrays. The default delimiter is the comma, but this
// can be overriden in the second argument.
function CSVToArray(strData, strDelimiter) {
// Check to see if the delimiter is defined. If not,
// then default to comma.
strDelimiter = (strDelimiter || ",");
// Create a regular expression to parse the CSV values.
var objPattern = new RegExp(
(
// Delimiters.
"(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
// Quoted fields.
"(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
// Standard fields.
"([^\"\\" + strDelimiter + "\\r\\n]*))"
),
"gi"
);
// Create an array to hold our data. Give the array
// a default empty first row.
var arrData = [
[]
];
// Create an array to hold our individual pattern
// matching groups.
var arrMatches = null;
// Keep looping over the regular expression matches
// until we can no longer find a match.
while (arrMatches = objPattern.exec(strData)) {
// Get the delimiter that was found.
var strMatchedDelimiter = arrMatches[ 1 ];
// Check to see if the given delimiter has a length
// (is not the start of string) and if it matches
// field delimiter. If id does not, then we know
// that this delimiter is a row delimiter.
if (
strMatchedDelimiter.length &&
(strMatchedDelimiter != strDelimiter)
) {
// Since we have reached a new row of data,
// add an empty row to our data array.
arrData.push([]);
}
// Now that we have our delimiter out of the way,
// let's check to see which kind of value we
// captured (quoted or unquoted).
if (arrMatches[ 2 ]) {
// We found a quoted value. When we capture
// this value, unescape any double quotes.
var strMatchedValue = arrMatches[ 2 ].replace(
new RegExp("\"\"", "g"),
"\""
);
} else {
// We found a non-quoted value.
var strMatchedValue = arrMatches[ 3 ];
}
// Now that we have our value string, let's add
// it to the data array.
arrData[ arrData.length - 1 ].push(strMatchedValue);
}
// Return the parsed data.
return( arrData );
}

View File

@ -0,0 +1,25 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
header("Content-Type: text/plain");
readfile('Cf7ToDBGGoogleSS.js');
?>

View File

@ -0,0 +1,11 @@
This DataTables plugin (v1.7.x) for jQuery was developed out of the desire to allow highly configurable access to HTML tables with advanced access features.
For detailed installation, usage and API instructions, please refer to the DataTables web-pages: http://www.datatables.net
Questions, feature requests and bug reports (etc) can all be asked on the DataTables forums: http://www.datatables.net/forums/
The DataTables source can be found in the media/js/ directory of this archive.
DataTables is released with dual licensing, using the GPL v2 (license-gpl2.txt) and an BSD style license (license-bsd.txt). Please see the corresponding license file for details of these licenses. You are free to use, modify and distribute this software, but all copyright information must remain.
If you discover any bugs in DataTables, have any suggestions for improvements or even if you just like using it, please free to get in touch with me: www.datatables.net/contact

View File

@ -0,0 +1,10 @@
Copyright (c) 2008-2010, Allan Jardine
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Allan Jardine nor SpryMedia UK may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -0,0 +1,93 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* General page setup
*/
#dt_example {
font: 80%/1.45em "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
color: #333;
background-color: #fff;
}
#dt_example #container {
width: 800px;
margin: 30px auto;
padding: 0;
}
#dt_example #footer {
margin: 50px auto 0 auto;
padding: 0;
}
#dt_example #demo {
margin: 30px auto 0 auto;
}
#dt_example .demo_jui {
margin: 30px auto 0 auto;
}
#dt_example .big {
font-size: 1.3em;
font-weight: bold;
line-height: 1.6em;
color: #4E6CA3;
}
#dt_example .spacer {
height: 20px;
clear: both;
}
#dt_example .clear {
clear: both;
}
#dt_example pre {
padding: 15px;
background-color: #F5F5F5;
border: 1px solid #CCCCCC;
}
#dt_example h1 {
margin-top: 2em;
font-size: 1.3em;
font-weight: normal;
line-height: 1.6em;
color: #4E6CA3;
border-bottom: 1px solid #B0BED9;
clear: both;
}
#dt_example h2 {
font-size: 1.2em;
font-weight: normal;
line-height: 1.6em;
color: #4E6CA3;
clear: both;
}
#dt_example a {
color: #0063DC;
text-decoration: none;
}
#dt_example a:hover {
text-decoration: underline;
}
#dt_example ul {
color: #4E6CA3;
}
.css_right {
float: right;
}
.css_left {
float: left;
}

View File

@ -0,0 +1,538 @@
/*
* File: demo_table.css
* CVS: $Id$
* Description: CSS descriptions for DataTables demo pages
* Author: Allan Jardine
* Created: Tue May 12 06:47:22 BST 2009
* Modified: $Date$ by $Author$
* Language: CSS
* Project: DataTables
*
* Copyright 2009 Allan Jardine. All Rights Reserved.
*
* ***************************************************************************
* DESCRIPTION
*
* The styles given here are suitable for the demos that are used with the standard DataTables
* distribution (see www.datatables.net). You will most likely wish to modify these styles to
* meet the layout requirements of your site.
*
* Common issues:
* 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
* no conflict between the two pagination types. If you want to use full_numbers pagination
* ensure that you either have "example_alt_pagination" as a body class name, or better yet,
* modify that selector.
* Note that the path used for Images is relative. All images are by default located in
* ../images/ - relative to this CSS file.
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables features
*/
.dataTables_wrapper {
position: relative;
min-height: 302px;
clear: both;
_height: 302px;
zoom: 1; /* Feeling sorry for IE */
}
.dataTables_processing {
position: absolute;
top: 50%;
left: 50%;
width: 250px;
height: 30px;
margin-left: -125px;
margin-top: -15px;
padding: 14px 0 2px 0;
border: 1px solid #ddd;
text-align: center;
color: #999;
font-size: 14px;
background-color: white;
}
.dataTables_length {
width: 40%;
float: left;
}
.dataTables_filter {
width: 50%;
float: right;
text-align: right;
}
.dataTables_info {
width: 60%;
float: left;
}
.dataTables_paginate {
width: 44px;
* width: 50px;
float: right;
text-align: right;
}
/* Pagination nested */
.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
height: 19px;
width: 19px;
margin-left: 3px;
float: left;
}
.paginate_disabled_previous {
background-image: url('../images/back_disabled.jpg');
}
.paginate_enabled_previous {
background-image: url('../images/back_enabled.jpg');
}
.paginate_disabled_next {
background-image: url('../images/forward_disabled.jpg');
}
.paginate_enabled_next {
background-image: url('../images/forward_enabled.jpg');
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables display
*/
table.display {
margin: 0 auto;
clear: both;
width: 100%;
/* Note Firefox 3.5 and before have a bug with border-collapse
* ( https://bugzilla.mozilla.org/show%5Fbug.cgi?id=155955 )
* border-spacing: 0; is one possible option. Conditional-css.com is
* useful for this kind of thing
*
* Further note IE 6/7 has problems when calculating widths with border width.
* It subtracts one px relative to the other browsers from the first column, and
* adds one to the end...
*
* If you want that effect I'd suggest setting a border-top/left on th/td's and
* then filling in the gaps with other borders.
*/
}
table.display thead th {
padding: 3px 18px 3px 10px;
border-bottom: 1px solid black;
font-weight: bold;
cursor: pointer;
* cursor: hand;
}
table.display tfoot th {
padding: 3px 18px 3px 10px;
border-top: 1px solid black;
font-weight: bold;
}
table.display tr.heading2 td {
border-bottom: 1px solid #aaa;
}
table.display td {
padding: 3px 10px;
}
table.display td.center {
text-align: center;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables sorting
*/
.sorting_asc {
background: url('../images/sort_asc.png') no-repeat center right;
}
.sorting_desc {
background: url('../images/sort_desc.png') no-repeat center right;
}
.sorting {
background: url('../images/sort_both.png') no-repeat center right;
}
.sorting_asc_disabled {
background: url('../images/sort_asc_disabled.png') no-repeat center right;
}
.sorting_desc_disabled {
background: url('../images/sort_desc_disabled.png') no-repeat center right;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables row classes
*/
table.display tr.odd.gradeA {
background-color: #ddffdd;
}
table.display tr.even.gradeA {
background-color: #eeffee;
}
table.display tr.odd.gradeC {
background-color: #ddddff;
}
table.display tr.even.gradeC {
background-color: #eeeeff;
}
table.display tr.odd.gradeX {
background-color: #ffdddd;
}
table.display tr.even.gradeX {
background-color: #ffeeee;
}
table.display tr.odd.gradeU {
background-color: #ddd;
}
table.display tr.even.gradeU {
background-color: #eee;
}
tr.odd {
background-color: #E2E4FF;
}
tr.even {
background-color: white;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Misc
*/
.dataTables_scroll {
clear: both;
}
.dataTables_scrollBody {
*margin-top: -1px;
}
.top, .bottom {
padding: 15px;
background-color: #F5F5F5;
border: 1px solid #CCCCCC;
}
.top .dataTables_info {
float: none;
}
.clear {
clear: both;
}
.dataTables_empty {
text-align: center;
}
tfoot input {
margin: 0.5em 0;
width: 100%;
color: #444;
}
tfoot input.search_init {
color: #999;
}
td.group {
background-color: #d1cfd0;
border-bottom: 2px solid #A19B9E;
border-top: 2px solid #A19B9E;
}
td.details {
background-color: #d1cfd0;
border: 2px solid #A19B9E;
}
.example_alt_pagination div.dataTables_info {
width: 40%;
}
.paging_full_numbers {
width: 400px;
height: 22px;
line-height: 22px;
}
.paging_full_numbers span.paginate_button,
.paging_full_numbers span.paginate_active {
border: 1px solid #aaa;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
padding: 2px 5px;
margin: 0 3px;
cursor: pointer;
*cursor: hand;
}
.paging_full_numbers span.paginate_button {
background-color: #ddd;
}
.paging_full_numbers span.paginate_button:hover {
background-color: #ccc;
}
.paging_full_numbers span.paginate_active {
background-color: #99B3FF;
}
table.display tr.even.row_selected td {
background-color: #B0BED9;
}
table.display tr.odd.row_selected td {
background-color: #9FAFD1;
}
/*
* Sorting classes for columns
*/
/* For the standard odd/even */
tr.odd td.sorting_1 {
background-color: #D3D6FF;
}
tr.odd td.sorting_2 {
background-color: #DADCFF;
}
tr.odd td.sorting_3 {
background-color: #E0E2FF;
}
tr.even td.sorting_1 {
background-color: #EAEBFF;
}
tr.even td.sorting_2 {
background-color: #F2F3FF;
}
tr.even td.sorting_3 {
background-color: #F9F9FF;
}
/* For the Conditional-CSS grading rows */
/*
Colour calculations (based off the main row colours)
Level 1:
dd > c4
ee > d5
Level 2:
dd > d1
ee > e2
*/
tr.odd.gradeA td.sorting_1 {
background-color: #c4ffc4;
}
tr.odd.gradeA td.sorting_2 {
background-color: #d1ffd1;
}
tr.odd.gradeA td.sorting_3 {
background-color: #d1ffd1;
}
tr.even.gradeA td.sorting_1 {
background-color: #d5ffd5;
}
tr.even.gradeA td.sorting_2 {
background-color: #e2ffe2;
}
tr.even.gradeA td.sorting_3 {
background-color: #e2ffe2;
}
tr.odd.gradeC td.sorting_1 {
background-color: #c4c4ff;
}
tr.odd.gradeC td.sorting_2 {
background-color: #d1d1ff;
}
tr.odd.gradeC td.sorting_3 {
background-color: #d1d1ff;
}
tr.even.gradeC td.sorting_1 {
background-color: #d5d5ff;
}
tr.even.gradeC td.sorting_2 {
background-color: #e2e2ff;
}
tr.even.gradeC td.sorting_3 {
background-color: #e2e2ff;
}
tr.odd.gradeX td.sorting_1 {
background-color: #ffc4c4;
}
tr.odd.gradeX td.sorting_2 {
background-color: #ffd1d1;
}
tr.odd.gradeX td.sorting_3 {
background-color: #ffd1d1;
}
tr.even.gradeX td.sorting_1 {
background-color: #ffd5d5;
}
tr.even.gradeX td.sorting_2 {
background-color: #ffe2e2;
}
tr.even.gradeX td.sorting_3 {
background-color: #ffe2e2;
}
tr.odd.gradeU td.sorting_1 {
background-color: #c4c4c4;
}
tr.odd.gradeU td.sorting_2 {
background-color: #d1d1d1;
}
tr.odd.gradeU td.sorting_3 {
background-color: #d1d1d1;
}
tr.even.gradeU td.sorting_1 {
background-color: #d5d5d5;
}
tr.even.gradeU td.sorting_2 {
background-color: #e2e2e2;
}
tr.even.gradeU td.sorting_3 {
background-color: #e2e2e2;
}
/*
* Row highlighting example
*/
.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted {
background-color: #ECFFB3;
}
.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted {
background-color: #E6FF99;
}
.ex_highlight_row #example tr.even:hover {
background-color: #ECFFB3;
}
.ex_highlight_row #example tr.even:hover td.sorting_1 {
background-color: #DDFF75;
}
.ex_highlight_row #example tr.even:hover td.sorting_2 {
background-color: #E7FF9E;
}
.ex_highlight_row #example tr.even:hover td.sorting_3 {
background-color: #E2FF89;
}
.ex_highlight_row #example tr.odd:hover {
background-color: #E6FF99;
}
.ex_highlight_row #example tr.odd:hover td.sorting_1 {
background-color: #D6FF5C;
}
.ex_highlight_row #example tr.odd:hover td.sorting_2 {
background-color: #E0FF84;
}
.ex_highlight_row #example tr.odd:hover td.sorting_3 {
background-color: #DBFF70;
}
/*
* KeyTable
*/
table.KeyTable td {
border: 3px solid transparent;
}
table.KeyTable td.focus {
border: 3px solid #3366FF;
}
table.display tr.gradeA {
background-color: #eeffee;
}
table.display tr.gradeC {
background-color: #ddddff;
}
table.display tr.gradeX {
background-color: #ffdddd;
}
table.display tr.gradeU {
background-color: #ddd;
}
div.box {
height: 100px;
padding: 10px;
overflow: auto;
border: 1px solid #8080FF;
background-color: #E5E5FF;
}

View File

@ -0,0 +1,521 @@
/*
* File: demo_table_jui.css
* CVS: $Id$
* Description: CSS descriptions for DataTables demo pages
* Author: Allan Jardine
* Created: Tue May 12 06:47:22 BST 2009
* Modified: $Date$ by $Author$
* Language: CSS
* Project: DataTables
*
* Copyright 2009 Allan Jardine. All Rights Reserved.
*
* ***************************************************************************
* DESCRIPTION
*
* The styles given here are suitable for the demos that are used with the standard DataTables
* distribution (see www.datatables.net). You will most likely wish to modify these styles to
* meet the layout requirements of your site.
*
* Common issues:
* 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
* no conflict between the two pagination types. If you want to use full_numbers pagination
* ensure that you either have "example_alt_pagination" as a body class name, or better yet,
* modify that selector.
* Note that the path used for Images is relative. All images are by default located in
* ../images/ - relative to this CSS file.
*/
/*
* jQuery UI specific styling
*/
.paging_two_button .ui-button {
float: left;
cursor: pointer;
* cursor: hand;
}
.paging_full_numbers .ui-button {
padding: 2px 6px;
margin: 0;
cursor: pointer;
* cursor: hand;
}
.dataTables_paginate .ui-button {
margin-right: -0.1em !important;
}
.paging_full_numbers {
width: 350px !important;
}
.dataTables_wrapper .ui-toolbar {
padding: 5px;
}
.dataTables_paginate {
width: auto;
}
.dataTables_info {
padding-top: 3px;
}
table.display thead th {
padding: 3px 0px 3px 10px;
cursor: pointer;
* cursor: hand;
}
div.dataTables_wrapper .ui-widget-header {
font-weight: normal;
}
/*
* Sort arrow icon positioning
*/
table.display thead th div.DataTables_sort_wrapper {
position: relative;
padding-right: 20px;
padding-right: 20px;
}
table.display thead th div.DataTables_sort_wrapper span {
position: absolute;
top: 50%;
margin-top: -8px;
right: 0;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Everything below this line is the same as demo_table.css. This file is
* required for 'cleanliness' of the markup
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables features
*/
.dataTables_wrapper {
position: relative;
min-height: 302px;
_height: 302px;
clear: both;
}
.dataTables_processing {
position: absolute;
top: 0px;
left: 50%;
width: 250px;
margin-left: -125px;
border: 1px solid #ddd;
text-align: center;
color: #999;
font-size: 11px;
padding: 2px 0;
}
.dataTables_length {
width: 40%;
float: left;
}
.dataTables_filter {
width: 50%;
float: right;
text-align: right;
}
.dataTables_info {
width: 50%;
float: left;
}
.dataTables_paginate {
float: right;
text-align: right;
}
/* Pagination nested */
.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
height: 19px;
width: 19px;
margin-left: 3px;
float: left;
}
.paginate_disabled_previous {
background-image: url('../images/back_disabled.jpg');
}
.paginate_enabled_previous {
background-image: url('../images/back_enabled.jpg');
}
.paginate_disabled_next {
background-image: url('../images/forward_disabled.jpg');
}
.paginate_enabled_next {
background-image: url('../images/forward_enabled.jpg');
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables display
*/
table.display {
margin: 0 auto;
width: 100%;
clear: both;
border-collapse: collapse;
}
table.display tfoot th {
padding: 3px 0px 3px 10px;
font-weight: bold;
font-weight: normal;
}
table.display tr.heading2 td {
border-bottom: 1px solid #aaa;
}
table.display td {
padding: 3px 10px;
}
table.display td.center {
text-align: center;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables sorting
*/
.sorting_asc {
background: url('../images/sort_asc.png') no-repeat center right;
}
.sorting_desc {
background: url('../images/sort_desc.png') no-repeat center right;
}
.sorting {
background: url('../images/sort_both.png') no-repeat center right;
}
.sorting_asc_disabled {
background: url('../images/sort_asc_disabled.png') no-repeat center right;
}
.sorting_desc_disabled {
background: url('../images/sort_desc_disabled.png') no-repeat center right;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables row classes
*/
table.display tr.odd.gradeA {
background-color: #ddffdd;
}
table.display tr.even.gradeA {
background-color: #eeffee;
}
table.display tr.odd.gradeA {
background-color: #ddffdd;
}
table.display tr.even.gradeA {
background-color: #eeffee;
}
table.display tr.odd.gradeC {
background-color: #ddddff;
}
table.display tr.even.gradeC {
background-color: #eeeeff;
}
table.display tr.odd.gradeX {
background-color: #ffdddd;
}
table.display tr.even.gradeX {
background-color: #ffeeee;
}
table.display tr.odd.gradeU {
background-color: #ddd;
}
table.display tr.even.gradeU {
background-color: #eee;
}
tr.odd {
background-color: #E2E4FF;
}
tr.even {
background-color: white;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Misc
*/
.dataTables_scroll {
clear: both;
}
.top, .bottom {
padding: 15px;
background-color: #F5F5F5;
border: 1px solid #CCCCCC;
}
.top .dataTables_info {
float: none;
}
.clear {
clear: both;
}
.dataTables_empty {
text-align: center;
}
tfoot input {
margin: 0.5em 0;
width: 100%;
color: #444;
}
tfoot input.search_init {
color: #999;
}
td.group {
background-color: #d1cfd0;
border-bottom: 2px solid #A19B9E;
border-top: 2px solid #A19B9E;
}
td.details {
background-color: #d1cfd0;
border: 2px solid #A19B9E;
}
.example_alt_pagination div.dataTables_info {
width: 40%;
}
.paging_full_numbers span.paginate_button,
.paging_full_numbers span.paginate_active {
border: 1px solid #aaa;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
padding: 2px 5px;
margin: 0 3px;
cursor: pointer;
*cursor: hand;
}
.paging_full_numbers span.paginate_button {
background-color: #ddd;
}
.paging_full_numbers span.paginate_button:hover {
background-color: #ccc;
}
.paging_full_numbers span.paginate_active {
background-color: #99B3FF;
}
table.display tr.even.row_selected td {
background-color: #B0BED9;
}
table.display tr.odd.row_selected td {
background-color: #9FAFD1;
}
/*
* Sorting classes for columns
*/
/* For the standard odd/even */
tr.odd td.sorting_1 {
background-color: #D3D6FF;
}
tr.odd td.sorting_2 {
background-color: #DADCFF;
}
tr.odd td.sorting_3 {
background-color: #E0E2FF;
}
tr.even td.sorting_1 {
background-color: #EAEBFF;
}
tr.even td.sorting_2 {
background-color: #F2F3FF;
}
tr.even td.sorting_3 {
background-color: #F9F9FF;
}
/* For the Conditional-CSS grading rows */
/*
Colour calculations (based off the main row colours)
Level 1:
dd > c4
ee > d5
Level 2:
dd > d1
ee > e2
*/
tr.odd.gradeA td.sorting_1 {
background-color: #c4ffc4;
}
tr.odd.gradeA td.sorting_2 {
background-color: #d1ffd1;
}
tr.odd.gradeA td.sorting_3 {
background-color: #d1ffd1;
}
tr.even.gradeA td.sorting_1 {
background-color: #d5ffd5;
}
tr.even.gradeA td.sorting_2 {
background-color: #e2ffe2;
}
tr.even.gradeA td.sorting_3 {
background-color: #e2ffe2;
}
tr.odd.gradeC td.sorting_1 {
background-color: #c4c4ff;
}
tr.odd.gradeC td.sorting_2 {
background-color: #d1d1ff;
}
tr.odd.gradeC td.sorting_3 {
background-color: #d1d1ff;
}
tr.even.gradeC td.sorting_1 {
background-color: #d5d5ff;
}
tr.even.gradeC td.sorting_2 {
background-color: #e2e2ff;
}
tr.even.gradeC td.sorting_3 {
background-color: #e2e2ff;
}
tr.odd.gradeX td.sorting_1 {
background-color: #ffc4c4;
}
tr.odd.gradeX td.sorting_2 {
background-color: #ffd1d1;
}
tr.odd.gradeX td.sorting_3 {
background-color: #ffd1d1;
}
tr.even.gradeX td.sorting_1 {
background-color: #ffd5d5;
}
tr.even.gradeX td.sorting_2 {
background-color: #ffe2e2;
}
tr.even.gradeX td.sorting_3 {
background-color: #ffe2e2;
}
tr.odd.gradeU td.sorting_1 {
background-color: #c4c4c4;
}
tr.odd.gradeU td.sorting_2 {
background-color: #d1d1d1;
}
tr.odd.gradeU td.sorting_3 {
background-color: #d1d1d1;
}
tr.even.gradeU td.sorting_1 {
background-color: #d5d5d5;
}
tr.even.gradeU td.sorting_2 {
background-color: #e2e2e2;
}
tr.even.gradeU td.sorting_3 {
background-color: #e2e2e2;
}
/*
* Row highlighting example
*/
.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted {
background-color: #ECFFB3;
}
.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted {
background-color: #E6FF99;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

View File

@ -0,0 +1,143 @@
/*
* File: jquery.dataTables.min.js
* Version: 1.7.6
* Author: Allan Jardine (www.sprymedia.co.uk)
* Info: www.datatables.net
*
* Copyright 2008-2011 Allan Jardine, all rights reserved.
*
* This source file is free software, under either the GPL v2 license or a
* BSD style license, as supplied with this software.
*
* This source file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
*/
(function(j,ra,p){j.fn.dataTableSettings=[];var D=j.fn.dataTableSettings;j.fn.dataTableExt={};var n=j.fn.dataTableExt;n.sVersion="1.7.6";n.sErrMode="alert";n.iApiIndex=0;n.oApi={};n.afnFiltering=[];n.aoFeatures=[];n.ofnSearch={};n.afnSortData=[];n.oStdClasses={sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active",
sPageButtonStaticDisabled:"paginate_button",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripOdd:"odd",sStripEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",
sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:""};n.oJUIClasses={sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left",sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",
sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled",sPageFirst:"first ui-corner-tl ui-corner-bl",
sPagePrevious:"previous",sPageNext:"next",sPageLast:"last ui-corner-tr ui-corner-br",sStripOdd:"odd",sStripEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",sSortableAsc:"ui-state-default",
sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortColumn:"sorting_",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead ui-state-default",sScrollHeadInner:"dataTables_scrollHeadInner",
sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot ui-state-default",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:"ui-state-default"};n.oPagination={two_button:{fnInit:function(g,m,r){var s,w,y;if(g.bJUI){s=p.createElement("a");w=p.createElement("a");y=p.createElement("span");y.className=g.oClasses.sPageJUINext;w.appendChild(y);y=p.createElement("span");y.className=g.oClasses.sPageJUIPrev;s.appendChild(y)}else{s=p.createElement("div");w=p.createElement("div")}s.className=
g.oClasses.sPagePrevDisabled;w.className=g.oClasses.sPageNextDisabled;s.title=g.oLanguage.oPaginate.sPrevious;w.title=g.oLanguage.oPaginate.sNext;m.appendChild(s);m.appendChild(w);j(s).bind("click.DT",function(){g.oApi._fnPageChange(g,"previous")&&r(g)});j(w).bind("click.DT",function(){g.oApi._fnPageChange(g,"next")&&r(g)});j(s).bind("selectstart.DT",function(){return false});j(w).bind("selectstart.DT",function(){return false});if(g.sTableId!==""&&typeof g.aanFeatures.p=="undefined"){m.setAttribute("id",
g.sTableId+"_paginate");s.setAttribute("id",g.sTableId+"_previous");w.setAttribute("id",g.sTableId+"_next")}},fnUpdate:function(g){if(g.aanFeatures.p)for(var m=g.aanFeatures.p,r=0,s=m.length;r<s;r++)if(m[r].childNodes.length!==0){m[r].childNodes[0].className=g._iDisplayStart===0?g.oClasses.sPagePrevDisabled:g.oClasses.sPagePrevEnabled;m[r].childNodes[1].className=g.fnDisplayEnd()==g.fnRecordsDisplay()?g.oClasses.sPageNextDisabled:g.oClasses.sPageNextEnabled}}},iFullNumbersShowPages:5,full_numbers:{fnInit:function(g,
m,r){var s=p.createElement("span"),w=p.createElement("span"),y=p.createElement("span"),F=p.createElement("span"),x=p.createElement("span");s.innerHTML=g.oLanguage.oPaginate.sFirst;w.innerHTML=g.oLanguage.oPaginate.sPrevious;F.innerHTML=g.oLanguage.oPaginate.sNext;x.innerHTML=g.oLanguage.oPaginate.sLast;var u=g.oClasses;s.className=u.sPageButton+" "+u.sPageFirst;w.className=u.sPageButton+" "+u.sPagePrevious;F.className=u.sPageButton+" "+u.sPageNext;x.className=u.sPageButton+" "+u.sPageLast;m.appendChild(s);
m.appendChild(w);m.appendChild(y);m.appendChild(F);m.appendChild(x);j(s).bind("click.DT",function(){g.oApi._fnPageChange(g,"first")&&r(g)});j(w).bind("click.DT",function(){g.oApi._fnPageChange(g,"previous")&&r(g)});j(F).bind("click.DT",function(){g.oApi._fnPageChange(g,"next")&&r(g)});j(x).bind("click.DT",function(){g.oApi._fnPageChange(g,"last")&&r(g)});j("span",m).bind("mousedown.DT",function(){return false}).bind("selectstart.DT",function(){return false});if(g.sTableId!==""&&typeof g.aanFeatures.p==
"undefined"){m.setAttribute("id",g.sTableId+"_paginate");s.setAttribute("id",g.sTableId+"_first");w.setAttribute("id",g.sTableId+"_previous");F.setAttribute("id",g.sTableId+"_next");x.setAttribute("id",g.sTableId+"_last")}},fnUpdate:function(g,m){if(g.aanFeatures.p){var r=n.oPagination.iFullNumbersShowPages,s=Math.floor(r/2),w=Math.ceil(g.fnRecordsDisplay()/g._iDisplayLength),y=Math.ceil(g._iDisplayStart/g._iDisplayLength)+1,F="",x,u=g.oClasses;if(w<r){s=1;x=w}else if(y<=s){s=1;x=r}else if(y>=w-s){s=
w-r+1;x=w}else{s=y-Math.ceil(r/2)+1;x=s+r-1}for(r=s;r<=x;r++)F+=y!=r?'<span class="'+u.sPageButton+'">'+r+"</span>":'<span class="'+u.sPageButtonActive+'">'+r+"</span>";x=g.aanFeatures.p;var z,U=function(){g._iDisplayStart=(this.innerHTML*1-1)*g._iDisplayLength;m(g);return false},C=function(){return false};r=0;for(s=x.length;r<s;r++)if(x[r].childNodes.length!==0){z=j("span:eq(2)",x[r]);z.html(F);j("span",z).bind("click.DT",U).bind("mousedown.DT",C).bind("selectstart.DT",C);z=x[r].getElementsByTagName("span");
z=[z[0],z[1],z[z.length-2],z[z.length-1]];j(z).removeClass(u.sPageButton+" "+u.sPageButtonActive+" "+u.sPageButtonStaticDisabled);if(y==1){z[0].className+=" "+u.sPageButtonStaticDisabled;z[1].className+=" "+u.sPageButtonStaticDisabled}else{z[0].className+=" "+u.sPageButton;z[1].className+=" "+u.sPageButton}if(w===0||y==w||g._iDisplayLength==-1){z[2].className+=" "+u.sPageButtonStaticDisabled;z[3].className+=" "+u.sPageButtonStaticDisabled}else{z[2].className+=" "+u.sPageButton;z[3].className+=" "+
u.sPageButton}}}}}};n.oSort={"string-asc":function(g,m){g=g.toLowerCase();m=m.toLowerCase();return g<m?-1:g>m?1:0},"string-desc":function(g,m){g=g.toLowerCase();m=m.toLowerCase();return g<m?1:g>m?-1:0},"html-asc":function(g,m){g=g.replace(/<.*?>/g,"").toLowerCase();m=m.replace(/<.*?>/g,"").toLowerCase();return g<m?-1:g>m?1:0},"html-desc":function(g,m){g=g.replace(/<.*?>/g,"").toLowerCase();m=m.replace(/<.*?>/g,"").toLowerCase();return g<m?1:g>m?-1:0},"date-asc":function(g,m){g=Date.parse(g);m=Date.parse(m);
if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(m)||m==="")m=Date.parse("01/01/1970 00:00:00");return g-m},"date-desc":function(g,m){g=Date.parse(g);m=Date.parse(m);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(m)||m==="")m=Date.parse("01/01/1970 00:00:00");return m-g},"numeric-asc":function(g,m){return(g=="-"||g===""?0:g*1)-(m=="-"||m===""?0:m*1)},"numeric-desc":function(g,m){return(m=="-"||m===""?0:m*1)-(g=="-"||g===""?0:g*1)}};n.aTypes=[function(g){if(g.length===
0)return"numeric";var m,r=false;m=g.charAt(0);if("0123456789-".indexOf(m)==-1)return null;for(var s=1;s<g.length;s++){m=g.charAt(s);if("0123456789.".indexOf(m)==-1)return null;if(m=="."){if(r)return null;r=true}}return"numeric"},function(g){var m=Date.parse(g);if(m!==null&&!isNaN(m)||g.length===0)return"date";return null},function(g){if(g.indexOf("<")!=-1&&g.indexOf(">")!=-1)return"html";return null}];n.fnVersionCheck=function(g){var m=function(x,u){for(;x.length<u;)x+="0";return x},r=n.sVersion.split(".");
g=g.split(".");for(var s="",w="",y=0,F=g.length;y<F;y++){s+=m(r[y],3);w+=m(g[y],3)}return parseInt(s,10)>=parseInt(w,10)};n._oExternConfig={iNextUnique:0};j.fn.dataTable=function(g){function m(){this.fnRecordsTotal=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length};this.fnRecordsDisplay=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length};this.fnDisplayEnd=function(){return this.oFeatures.bServerSide?
this.oFeatures.bPaginate===false||this._iDisplayLength==-1?this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd};this.sInstance=this.oInstance=null;this.oFeatures={bPaginate:true,bLengthChange:true,bFilter:true,bSort:true,bInfo:true,bAutoWidth:true,bProcessing:false,bSortClasses:true,bStateSave:false,bServerSide:false};this.oScroll={sX:"",sXInner:"",sY:"",bCollapse:false,bInfinite:false,iLoadGap:100,iBarWidth:0,bAutoCss:true};
this.aanFeatures=[];this.oLanguage={sProcessing:"Processing...",sLengthMenu:"Show _MENU_ entries",sZeroRecords:"No matching records found",sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sSearch:"Search:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"},fnInfoCallback:null};this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=
[];this.aoColumns=[];this.iNextId=0;this.asDataSearch=[];this.oPreviousSearch={sSearch:"",bRegex:false,bSmart:true};this.aoPreSearchCols=[];this.aaSorting=[[0,"asc",0]];this.aaSortingFixed=null;this.asStripClasses=[];this.asDestoryStrips=[];this.sDestroyWidth=0;this.fnFooterCallback=this.fnHeaderCallback=this.fnRowCallback=null;this.aoDrawCallback=[];this.fnInitComplete=null;this.sTableId="";this.nTableWrapper=this.nTBody=this.nTFoot=this.nTHead=this.nTable=null;this.bInitialised=false;this.aoOpenRows=
[];this.sDom="lfrtip";this.sPaginationType="two_button";this.iCookieDuration=7200;this.sCookiePrefix="SpryMedia_DataTables_";this.fnCookieCallback=null;this.aoStateSave=[];this.aoStateLoad=[];this.sAjaxSource=this.oLoadedState=null;this.bAjaxDataGet=true;this.fnServerData=function(a,b,c){j.ajax({url:a,data:b,success:c,dataType:"json",cache:false,error:function(d,f){f=="parsererror"&&alert("DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})};
this.fnFormatNumber=function(a){if(a<1E3)return a;else{var b=a+"";a=b.split("");var c="";b=b.length;for(var d=0;d<b;d++){if(d%3===0&&d!==0)c=","+c;c=a[b-d-1]+c}}return c};this.aLengthMenu=[10,25,50,100];this.bDrawing=this.iDraw=0;this.iDrawError=-1;this._iDisplayLength=10;this._iDisplayStart=0;this._iDisplayEnd=10;this._iRecordsDisplay=this._iRecordsTotal=0;this.bJUI=false;this.oClasses=n.oStdClasses;this.bSorted=this.bFiltered=false;this.oInit=null}function r(a){return function(){var b=[A(this[n.iApiIndex])].concat(Array.prototype.slice.call(arguments));
return n.oApi[a].apply(this,b)}}function s(a){var b,c;if(a.bInitialised===false)setTimeout(function(){s(a)},200);else{sa(a);U(a);K(a,true);a.oFeatures.bAutoWidth&&$(a);b=0;for(c=a.aoColumns.length;b<c;b++)if(a.aoColumns[b].sWidth!==null)a.aoColumns[b].nTh.style.width=v(a.aoColumns[b].sWidth);if(a.oFeatures.bSort)O(a);else{a.aiDisplay=a.aiDisplayMaster.slice();E(a);C(a)}if(a.sAjaxSource!==null&&!a.oFeatures.bServerSide)a.fnServerData.call(a.oInstance,a.sAjaxSource,[],function(d){for(b=0;b<d.aaData.length;b++)u(a,
d.aaData[b]);a.iInitDisplayStart=a._iDisplayStart;if(a.oFeatures.bSort)O(a);else{a.aiDisplay=a.aiDisplayMaster.slice();E(a);C(a)}K(a,false);w(a,d)});else if(!a.oFeatures.bServerSide){K(a,false);w(a)}}}function w(a,b){a._bInitComplete=true;if(typeof a.fnInitComplete=="function")typeof b!="undefined"?a.fnInitComplete.call(a.oInstance,a,b):a.fnInitComplete.call(a.oInstance,a)}function y(a,b,c){o(a.oLanguage,b,"sProcessing");o(a.oLanguage,b,"sLengthMenu");o(a.oLanguage,b,"sEmptyTable");o(a.oLanguage,
b,"sZeroRecords");o(a.oLanguage,b,"sInfo");o(a.oLanguage,b,"sInfoEmpty");o(a.oLanguage,b,"sInfoFiltered");o(a.oLanguage,b,"sInfoPostFix");o(a.oLanguage,b,"sSearch");if(typeof b.oPaginate!="undefined"){o(a.oLanguage.oPaginate,b.oPaginate,"sFirst");o(a.oLanguage.oPaginate,b.oPaginate,"sPrevious");o(a.oLanguage.oPaginate,b.oPaginate,"sNext");o(a.oLanguage.oPaginate,b.oPaginate,"sLast")}typeof b.sEmptyTable=="undefined"&&typeof b.sZeroRecords!="undefined"&&o(a.oLanguage,b,"sZeroRecords","sEmptyTable");
c&&s(a)}function F(a,b){a.aoColumns[a.aoColumns.length++]={sType:null,_bAutoType:true,bVisible:true,bSearchable:true,bSortable:true,asSorting:["asc","desc"],sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,sTitle:b?b.innerHTML:"",sName:"",sWidth:null,sWidthOrig:null,sClass:null,fnRender:null,bUseRendered:true,iDataSort:a.aoColumns.length-1,sSortDataType:"std",nTh:b?b:p.createElement("th"),nTf:null,anThExtra:[],anTfExtra:[]};b=a.aoColumns.length-1;if(typeof a.aoPreSearchCols[b]==
"undefined"||a.aoPreSearchCols[b]===null)a.aoPreSearchCols[b]={sSearch:"",bRegex:false,bSmart:true};else{if(typeof a.aoPreSearchCols[b].bRegex=="undefined")a.aoPreSearchCols[b].bRegex=true;if(typeof a.aoPreSearchCols[b].bSmart=="undefined")a.aoPreSearchCols[b].bSmart=true}x(a,b,null)}function x(a,b,c){b=a.aoColumns[b];if(typeof c!="undefined"&&c!==null){if(typeof c.sType!="undefined"){b.sType=c.sType;b._bAutoType=false}o(b,c,"bVisible");o(b,c,"bSearchable");o(b,c,"bSortable");o(b,c,"sTitle");o(b,
c,"sName");o(b,c,"sWidth");o(b,c,"sWidth","sWidthOrig");o(b,c,"sClass");o(b,c,"fnRender");o(b,c,"bUseRendered");o(b,c,"iDataSort");o(b,c,"asSorting");o(b,c,"sSortDataType")}if(!a.oFeatures.bSort)b.bSortable=false;if(!b.bSortable||j.inArray("asc",b.asSorting)==-1&&j.inArray("desc",b.asSorting)==-1){b.sSortingClass=a.oClasses.sSortableNone;b.sSortingClassJUI=""}else if(j.inArray("asc",b.asSorting)!=-1&&j.inArray("desc",b.asSorting)==-1){b.sSortingClass=a.oClasses.sSortableAsc;b.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed}else if(j.inArray("asc",
b.asSorting)==-1&&j.inArray("desc",b.asSorting)!=-1){b.sSortingClass=a.oClasses.sSortableDesc;b.sSortingClassJUI=a.oClasses.sSortJUIDescAllowed}}function u(a,b){if(b.length!=a.aoColumns.length&&a.iDrawError!=a.iDraw){H(a,0,"Added data (size "+b.length+") does not match known number of columns ("+a.aoColumns.length+")");a.iDrawError=a.iDraw;return-1}b=b.slice();var c=a.aoData.length;a.aoData.push({nTr:p.createElement("tr"),_iId:a.iNextId++,_aData:b,_anHidden:[],_sRowStripe:""});for(var d,f,e=0;e<b.length;e++){d=
p.createElement("td");if(b[e]===null)b[e]="";if(typeof a.aoColumns[e].fnRender=="function"){f=a.aoColumns[e].fnRender({iDataRow:c,iDataColumn:e,aData:b,oSettings:a});d.innerHTML=f;if(a.aoColumns[e].bUseRendered)a.aoData[c]._aData[e]=f}else d.innerHTML=b[e];if(typeof b[e]!="string")b[e]+="";b[e]=j.trim(b[e]);if(a.aoColumns[e].sClass!==null)d.className=a.aoColumns[e].sClass;if(a.aoColumns[e]._bAutoType&&a.aoColumns[e].sType!="string"){f=aa(a.aoData[c]._aData[e]);if(a.aoColumns[e].sType===null)a.aoColumns[e].sType=
f;else if(a.aoColumns[e].sType!=f)a.aoColumns[e].sType="string"}if(a.aoColumns[e].bVisible){a.aoData[c].nTr.appendChild(d);a.aoData[c]._anHidden[e]=null}else a.aoData[c]._anHidden[e]=d}a.aiDisplayMaster.push(c);return c}function z(a){var b,c,d,f,e,i,h,k;if(a.sAjaxSource===null){h=a.nTBody.childNodes;b=0;for(c=h.length;b<c;b++)if(h[b].nodeName.toUpperCase()=="TR"){i=a.aoData.length;a.aoData.push({nTr:h[b],_iId:a.iNextId++,_aData:[],_anHidden:[],_sRowStripe:""});a.aiDisplayMaster.push(i);k=a.aoData[i]._aData;
i=h[b].childNodes;d=e=0;for(f=i.length;d<f;d++)if(i[d].nodeName.toUpperCase()=="TD"){k[e]=j.trim(i[d].innerHTML);e++}}}h=R(a);i=[];b=0;for(c=h.length;b<c;b++){d=0;for(f=h[b].childNodes.length;d<f;d++){e=h[b].childNodes[d];e.nodeName.toUpperCase()=="TD"&&i.push(e)}}i.length!=h.length*a.aoColumns.length&&H(a,1,"Unexpected number of TD elements. Expected "+h.length*a.aoColumns.length+" and got "+i.length+". DataTables does not support rowspan / colspan in the table body, and there must be one cell for each row/column combination.");
h=0;for(d=a.aoColumns.length;h<d;h++){if(a.aoColumns[h].sTitle===null)a.aoColumns[h].sTitle=a.aoColumns[h].nTh.innerHTML;f=a.aoColumns[h]._bAutoType;e=typeof a.aoColumns[h].fnRender=="function";k=a.aoColumns[h].sClass!==null;var l=a.aoColumns[h].bVisible,q,t;if(f||e||k||!l){b=0;for(c=a.aoData.length;b<c;b++){q=i[b*d+h];if(f)if(a.aoColumns[h].sType!="string"){t=aa(a.aoData[b]._aData[h]);if(a.aoColumns[h].sType===null)a.aoColumns[h].sType=t;else if(a.aoColumns[h].sType!=t)a.aoColumns[h].sType="string"}if(e){t=
a.aoColumns[h].fnRender({iDataRow:b,iDataColumn:h,aData:a.aoData[b]._aData,oSettings:a});q.innerHTML=t;if(a.aoColumns[h].bUseRendered)a.aoData[b]._aData[h]=t}if(k)q.className+=" "+a.aoColumns[h].sClass;if(l)a.aoData[b]._anHidden[h]=null;else{a.aoData[b]._anHidden[h]=q;q.parentNode.removeChild(q)}}}}}function U(a){var b,c,d,f,e,i=a.nTHead.getElementsByTagName("tr"),h=0,k;if(a.nTHead.getElementsByTagName("th").length!==0){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;a.aoColumns[b].sClass!==
null&&j(c).addClass(a.aoColumns[b].sClass);f=1;for(e=i.length;f<e;f++){k=j(i[f]).children();a.aoColumns[b].anThExtra.push(k[b-h]);a.aoColumns[b].bVisible||i[f].removeChild(k[b-h])}if(a.aoColumns[b].bVisible){if(a.aoColumns[b].sTitle!=c.innerHTML)c.innerHTML=a.aoColumns[b].sTitle}else{c.parentNode.removeChild(c);h++}}}else{f=p.createElement("tr");b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;c.innerHTML=a.aoColumns[b].sTitle;a.aoColumns[b].sClass!==null&&j(c).addClass(a.aoColumns[b].sClass);
a.aoColumns[b].bVisible&&f.appendChild(c)}j(a.nTHead).html("")[0].appendChild(f)}if(a.bJUI){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;f=p.createElement("div");f.className=a.oClasses.sSortJUIWrapper;j(c).contents().appendTo(f);f.appendChild(p.createElement("span"));c.appendChild(f)}}d=function(){this.onselectstart=function(){return false};return false};if(a.oFeatures.bSort)for(b=0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable!==false){ba(a,a.aoColumns[b].nTh,b);j(a.aoColumns[b].nTh).bind("mousedown.DT",
d)}else j(a.aoColumns[b].nTh).addClass(a.oClasses.sSortableNone);if(a.nTFoot!==null){h=0;i=a.nTFoot.getElementsByTagName("tr");c=i[0].getElementsByTagName("th");b=0;for(d=c.length;b<d;b++)if(typeof a.aoColumns[b]!="undefined"){a.aoColumns[b].nTf=c[b-h];if(a.oClasses.sFooterTH!=="")a.aoColumns[b].nTf.className+=" "+a.oClasses.sFooterTH;f=1;for(e=i.length;f<e;f++){k=j(i[f]).children();a.aoColumns[b].anTfExtra.push(k[b-h]);a.aoColumns[b].bVisible||i[f].removeChild(k[b-h])}if(!a.aoColumns[b].bVisible){c[b-
h].parentNode.removeChild(c[b-h]);h++}}}}function C(a){var b,c,d=[],f=0,e=false;b=a.asStripClasses.length;c=a.aoOpenRows.length;a.bDrawing=true;if(typeof a.iInitDisplayStart!="undefined"&&a.iInitDisplayStart!=-1){a._iDisplayStart=a.oFeatures.bServerSide?a.iInitDisplayStart:a.iInitDisplayStart>=a.fnRecordsDisplay()?0:a.iInitDisplayStart;a.iInitDisplayStart=-1;E(a)}if(!(!a.bDestroying&&a.oFeatures.bServerSide&&!ta(a))){a.oFeatures.bServerSide||a.iDraw++;if(a.aiDisplay.length!==0){var i=a._iDisplayStart,
h=a._iDisplayEnd;if(a.oFeatures.bServerSide){i=0;h=a.aoData.length}for(i=i;i<h;i++){var k=a.aoData[a.aiDisplay[i]],l=k.nTr;if(b!==0){var q=a.asStripClasses[f%b];if(k._sRowStripe!=q){j(l).removeClass(k._sRowStripe).addClass(q);k._sRowStripe=q}}if(typeof a.fnRowCallback=="function"){l=a.fnRowCallback.call(a.oInstance,l,a.aoData[a.aiDisplay[i]]._aData,f,i);if(!l&&!e){H(a,0,"A node was not returned by fnRowCallback");e=true}}d.push(l);f++;if(c!==0)for(k=0;k<c;k++)l==a.aoOpenRows[k].nParent&&d.push(a.aoOpenRows[k].nTr)}}else{d[0]=
p.createElement("tr");if(typeof a.asStripClasses[0]!="undefined")d[0].className=a.asStripClasses[0];e=p.createElement("td");e.setAttribute("valign","top");e.colSpan=S(a);e.className=a.oClasses.sRowEmpty;e.innerHTML=typeof a.oLanguage.sEmptyTable!="undefined"&&a.fnRecordsTotal()===0?a.oLanguage.sEmptyTable:a.oLanguage.sZeroRecords.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()));d[f].appendChild(e)}typeof a.fnHeaderCallback=="function"&&a.fnHeaderCallback.call(a.oInstance,j(">tr",a.nTHead)[0],
V(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay);typeof a.fnFooterCallback=="function"&&a.fnFooterCallback.call(a.oInstance,j(">tr",a.nTFoot)[0],V(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay);f=p.createDocumentFragment();b=p.createDocumentFragment();if(a.nTBody){e=a.nTBody.parentNode;b.appendChild(a.nTBody);if(!a.oScroll.bInfinite||!a._bInitComplete||a.bSorted||a.bFiltered){c=a.nTBody.childNodes;for(b=c.length-1;b>=0;b--)c[b].parentNode.removeChild(c[b])}b=0;for(c=d.length;b<c;b++)f.appendChild(d[b]);
a.nTBody.appendChild(f);e!==null&&e.appendChild(a.nTBody)}for(b=a.aoDrawCallback.length-1;b>=0;b--)a.aoDrawCallback[b].fn.call(a.oInstance,a);a.bSorted=false;a.bFiltered=false;a.bDrawing=false;if(a.oFeatures.bServerSide){K(a,false);typeof a._bInitComplete=="undefined"&&w(a)}}}function W(a){if(a.oFeatures.bSort)O(a,a.oPreviousSearch);else if(a.oFeatures.bFilter)P(a,a.oPreviousSearch);else{E(a);C(a)}}function ta(a){if(a.bAjaxDataGet){K(a,true);var b=a.aoColumns.length,c=[],d;a.iDraw++;c.push({name:"sEcho",
value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns",value:ca(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",value:a.oFeatures.bPaginate!==false?a._iDisplayLength:-1});if(a.oFeatures.bFilter!==false){c.push({name:"sSearch",value:a.oPreviousSearch.sSearch});c.push({name:"bRegex",value:a.oPreviousSearch.bRegex});for(d=0;d<b;d++){c.push({name:"sSearch_"+d,value:a.aoPreSearchCols[d].sSearch});c.push({name:"bRegex_"+d,value:a.aoPreSearchCols[d].bRegex});
c.push({name:"bSearchable_"+d,value:a.aoColumns[d].bSearchable})}}if(a.oFeatures.bSort!==false){var f=a.aaSortingFixed!==null?a.aaSortingFixed.length:0,e=a.aaSorting.length;c.push({name:"iSortingCols",value:f+e});for(d=0;d<f;d++){c.push({name:"iSortCol_"+d,value:a.aaSortingFixed[d][0]});c.push({name:"sSortDir_"+d,value:a.aaSortingFixed[d][1]})}for(d=0;d<e;d++){c.push({name:"iSortCol_"+(d+f),value:a.aaSorting[d][0]});c.push({name:"sSortDir_"+(d+f),value:a.aaSorting[d][1]})}for(d=0;d<b;d++)c.push({name:"bSortable_"+
d,value:a.aoColumns[d].bSortable})}a.fnServerData.call(a.oInstance,a.sAjaxSource,c,function(i){ua(a,i)});return false}else return true}function ua(a,b){if(typeof b.sEcho!="undefined")if(b.sEcho*1<a.iDraw)return;else a.iDraw=b.sEcho*1;if(!a.oScroll.bInfinite||a.oScroll.bInfinite&&(a.bSorted||a.bFiltered))da(a);a._iRecordsTotal=b.iTotalRecords;a._iRecordsDisplay=b.iTotalDisplayRecords;var c=ca(a);if(c=typeof b.sColumns!="undefined"&&c!==""&&b.sColumns!=c)var d=va(a,b.sColumns);for(var f=0,e=b.aaData.length;f<
e;f++)if(c){for(var i=[],h=0,k=a.aoColumns.length;h<k;h++)i.push(b.aaData[f][d[h]]);u(a,i)}else u(a,b.aaData[f]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=false;C(a);a.bAjaxDataGet=true;K(a,false)}function sa(a){var b=p.createElement("div");a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=p.createElement("div");a.nTableWrapper.className=a.oClasses.sWrapper;a.sTableId!==""&&a.nTableWrapper.setAttribute("id",a.sTableId+"_wrapper");for(var c=a.nTableWrapper,d=a.sDom.split(""),
f,e,i,h,k,l,q,t=0;t<d.length;t++){e=0;i=d[t];if(i=="<"){h=p.createElement("div");k=d[t+1];if(k=="'"||k=='"'){l="";for(q=2;d[t+q]!=k;){l+=d[t+q];q++}if(l=="H")l="fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix";else if(l=="F")l="fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix";if(l.indexOf(".")!=-1){k=l.split(".");h.setAttribute("id",k[0].substr(1,k[0].length-1));h.className=k[1]}else if(l.charAt(0)=="#")h.setAttribute("id",l.substr(1,
l.length-1));else h.className=l;t+=q}c.appendChild(h);c=h}else if(i==">")c=c.parentNode;else if(i=="l"&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange){f=wa(a);e=1}else if(i=="f"&&a.oFeatures.bFilter){f=xa(a);e=1}else if(i=="r"&&a.oFeatures.bProcessing){f=ya(a);e=1}else if(i=="t"){f=za(a);e=1}else if(i=="i"&&a.oFeatures.bInfo){f=Aa(a);e=1}else if(i=="p"&&a.oFeatures.bPaginate){f=Ba(a);e=1}else if(n.aoFeatures.length!==0){h=n.aoFeatures;q=0;for(k=h.length;q<k;q++)if(i==h[q].cFeature){if(f=h[q].fnInit(a))e=
1;break}}if(e==1&&f!==null){if(typeof a.aanFeatures[i]!="object")a.aanFeatures[i]=[];a.aanFeatures[i].push(f);c.appendChild(f)}}b.parentNode.replaceChild(a.nTableWrapper,b)}function za(a){if(a.oScroll.sX===""&&a.oScroll.sY==="")return a.nTable;var b=p.createElement("div"),c=p.createElement("div"),d=p.createElement("div"),f=p.createElement("div"),e=p.createElement("div"),i=p.createElement("div"),h=a.nTable.cloneNode(false),k=a.nTable.cloneNode(false),l=a.nTable.getElementsByTagName("thead")[0],q=a.nTable.getElementsByTagName("tfoot").length===
0?null:a.nTable.getElementsByTagName("tfoot")[0],t=typeof g.bJQueryUI!="undefined"&&g.bJQueryUI?n.oJUIClasses:n.oStdClasses;c.appendChild(d);e.appendChild(i);f.appendChild(a.nTable);b.appendChild(c);b.appendChild(f);d.appendChild(h);h.appendChild(l);if(q!==null){b.appendChild(e);i.appendChild(k);k.appendChild(q)}b.className=t.sScrollWrapper;c.className=t.sScrollHead;d.className=t.sScrollHeadInner;f.className=t.sScrollBody;e.className=t.sScrollFoot;i.className=t.sScrollFootInner;if(a.oScroll.bAutoCss){c.style.overflow=
"hidden";c.style.position="relative";e.style.overflow="hidden";f.style.overflow="auto"}c.style.border="0";c.style.width="100%";e.style.border="0";d.style.width="150%";h.removeAttribute("id");h.style.marginLeft="0";a.nTable.style.marginLeft="0";if(q!==null){k.removeAttribute("id");k.style.marginLeft="0"}d=j(">caption",a.nTable);i=0;for(k=d.length;i<k;i++)h.appendChild(d[i]);if(a.oScroll.sX!==""){c.style.width=v(a.oScroll.sX);f.style.width=v(a.oScroll.sX);if(q!==null)e.style.width=v(a.oScroll.sX);j(f).scroll(function(){c.scrollLeft=
this.scrollLeft;if(q!==null)e.scrollLeft=this.scrollLeft})}if(a.oScroll.sY!=="")f.style.height=v(a.oScroll.sY);a.aoDrawCallback.push({fn:Ca,sName:"scrolling"});a.oScroll.bInfinite&&j(f).scroll(function(){if(!a.bDrawing)if(j(this).scrollTop()+j(this).height()>j(a.nTable).height()-a.oScroll.iLoadGap)if(a.fnDisplayEnd()<a.fnRecordsDisplay()){ea(a,"next");E(a);C(a)}});a.nScrollHead=c;a.nScrollFoot=e;return b}function Ca(a){var b=a.nScrollHead.getElementsByTagName("div")[0],c=b.getElementsByTagName("table")[0],
d=a.nTable.parentNode,f,e,i,h,k,l,q,t,G=[];i=a.nTable.getElementsByTagName("thead");i.length>0&&a.nTable.removeChild(i[0]);if(a.nTFoot!==null){k=a.nTable.getElementsByTagName("tfoot");k.length>0&&a.nTable.removeChild(k[0])}i=a.nTHead.cloneNode(true);a.nTable.insertBefore(i,a.nTable.childNodes[0]);if(a.nTFoot!==null){k=a.nTFoot.cloneNode(true);a.nTable.insertBefore(k,a.nTable.childNodes[1])}var J=fa(i);f=0;for(e=J.length;f<e;f++){q=ga(a,f);J[f].style.width=a.aoColumns[q].sWidth}a.nTFoot!==null&&L(function(B){B.style.width=
""},k.getElementsByTagName("tr"));f=j(a.nTable).outerWidth();if(a.oScroll.sX===""){a.nTable.style.width="100%";if(j.browser.msie&&j.browser.version<=7)a.nTable.style.width=v(j(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sXInner!=="")a.nTable.style.width=v(a.oScroll.sXInner);else if(f==j(d).width()&&j(d).height()<j(a.nTable).height()){a.nTable.style.width=v(f-a.oScroll.iBarWidth);if(j(a.nTable).outerWidth()>f-a.oScroll.iBarWidth)a.nTable.style.width=v(f)}else a.nTable.style.width=
v(f);f=j(a.nTable).outerWidth();e=a.nTHead.getElementsByTagName("tr");i=i.getElementsByTagName("tr");L(function(B,I){l=B.style;l.paddingTop="0";l.paddingBottom="0";l.borderTopWidth="0";l.borderBottomWidth="0";l.height=0;t=j(B).width();I.style.width=v(t);G.push(t)},i,e);j(i).height(0);if(a.nTFoot!==null){h=k.getElementsByTagName("tr");k=a.nTFoot.getElementsByTagName("tr");L(function(B,I){l=B.style;l.paddingTop="0";l.paddingBottom="0";l.borderTopWidth="0";l.borderBottomWidth="0";l.height=0;t=j(B).width();
I.style.width=v(t);G.push(t)},h,k);j(h).height(0)}L(function(B){B.innerHTML="";B.style.width=v(G.shift())},i);a.nTFoot!==null&&L(function(B){B.innerHTML="";B.style.width=v(G.shift())},h);if(j(a.nTable).outerWidth()<f)if(a.oScroll.sX==="")H(a,1,"The table cannot fit into the current element which will cause column misalignment. It is suggested that you enable x-scrolling or increase the width the table has in which to be drawn");else a.oScroll.sXInner!==""&&H(a,1,"The table cannot fit into the current element which will cause column misalignment. It is suggested that you increase the sScrollXInner property to allow it to draw in a larger area, or simply remove that parameter to allow automatic calculation");
if(a.oScroll.sY==="")if(j.browser.msie&&j.browser.version<=7)d.style.height=v(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(a.oScroll.sY!==""&&a.oScroll.bCollapse){d.style.height=v(a.oScroll.sY);h=a.oScroll.sX!==""&&a.nTable.offsetWidth>d.offsetWidth?a.oScroll.iBarWidth:0;if(a.nTable.offsetHeight<d.offsetHeight)d.style.height=v(j(a.nTable).height()+h)}h=j(a.nTable).outerWidth();c.style.width=v(h);b.style.width=v(h+a.oScroll.iBarWidth);if(a.nTFoot!==null){b=a.nScrollFoot.getElementsByTagName("div")[0];
c=b.getElementsByTagName("table")[0];b.style.width=v(a.nTable.offsetWidth+a.oScroll.iBarWidth);c.style.width=v(a.nTable.offsetWidth)}if(a.bSorted||a.bFiltered)d.scrollTop=0}function X(a){if(a.oFeatures.bAutoWidth===false)return false;$(a);for(var b=0,c=a.aoColumns.length;b<c;b++)a.aoColumns[b].nTh.style.width=a.aoColumns[b].sWidth}function xa(a){var b=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.f=="undefined"&&b.setAttribute("id",a.sTableId+"_filter");b.className=a.oClasses.sFilter;
b.innerHTML=a.oLanguage.sSearch+(a.oLanguage.sSearch===""?"":" ")+'<input type="text" />';var c=j("input",b);c.val(a.oPreviousSearch.sSearch.replace('"',"&quot;"));c.bind("keyup.DT",function(){for(var d=a.aanFeatures.f,f=0,e=d.length;f<e;f++)d[f]!=this.parentNode&&j("input",d[f]).val(this.value);this.value!=a.oPreviousSearch.sSearch&&P(a,{sSearch:this.value,bRegex:a.oPreviousSearch.bRegex,bSmart:a.oPreviousSearch.bSmart})});c.bind("keypress.DT",function(d){if(d.keyCode==13)return false});return b}
function P(a,b,c){Da(a,b.sSearch,c,b.bRegex,b.bSmart);for(b=0;b<a.aoPreSearchCols.length;b++)Ea(a,a.aoPreSearchCols[b].sSearch,b,a.aoPreSearchCols[b].bRegex,a.aoPreSearchCols[b].bSmart);n.afnFiltering.length!==0&&Fa(a);a.bFiltered=true;a._iDisplayStart=0;E(a);C(a);ha(a,0)}function Fa(a){for(var b=n.afnFiltering,c=0,d=b.length;c<d;c++)for(var f=0,e=0,i=a.aiDisplay.length;e<i;e++){var h=a.aiDisplay[e-f];if(!b[c](a,a.aoData[h]._aData,h)){a.aiDisplay.splice(e-f,1);f++}}}function Ea(a,b,c,d,f){if(b!==
""){var e=0;b=ia(b,d,f);for(d=a.aiDisplay.length-1;d>=0;d--){f=ja(a.aoData[a.aiDisplay[d]]._aData[c],a.aoColumns[c].sType);if(!b.test(f)){a.aiDisplay.splice(d,1);e++}}}}function Da(a,b,c,d,f){var e=ia(b,d,f);if(typeof c=="undefined"||c===null)c=0;if(n.afnFiltering.length!==0)c=1;if(b.length<=0){a.aiDisplay.splice(0,a.aiDisplay.length);a.aiDisplay=a.aiDisplayMaster.slice()}else if(a.aiDisplay.length==a.aiDisplayMaster.length||a.oPreviousSearch.sSearch.length>b.length||c==1||b.indexOf(a.oPreviousSearch.sSearch)!==
0){a.aiDisplay.splice(0,a.aiDisplay.length);ha(a,1);for(c=0;c<a.aiDisplayMaster.length;c++)e.test(a.asDataSearch[c])&&a.aiDisplay.push(a.aiDisplayMaster[c])}else{var i=0;for(c=0;c<a.asDataSearch.length;c++)if(!e.test(a.asDataSearch[c])){a.aiDisplay.splice(c-i,1);i++}}a.oPreviousSearch.sSearch=b;a.oPreviousSearch.bRegex=d;a.oPreviousSearch.bSmart=f}function ha(a,b){a.asDataSearch.splice(0,a.asDataSearch.length);b=typeof b!="undefined"&&b==1?a.aiDisplayMaster:a.aiDisplay;for(var c=0,d=b.length;c<d;c++)a.asDataSearch[c]=
ka(a,a.aoData[b[c]]._aData)}function ka(a,b){for(var c="",d=p.createElement("div"),f=0,e=a.aoColumns.length;f<e;f++)if(a.aoColumns[f].bSearchable)c+=ja(b[f],a.aoColumns[f].sType)+" ";if(c.indexOf("&")!==-1){d.innerHTML=c;c=d.textContent?d.textContent:d.innerText;c=c.replace(/\n/g," ").replace(/\r/g,"")}return c}function ia(a,b,c){if(c){a=b?a.split(" "):la(a).split(" ");a="^(?=.*?"+a.join(")(?=.*?")+").*$";return new RegExp(a,"i")}else{a=b?a:la(a);return new RegExp(a,"i")}}function ja(a,b){if(typeof n.ofnSearch[b]==
"function")return n.ofnSearch[b](a);else if(b=="html")return a.replace(/\n/g," ").replace(/<.*?>/g,"");else if(typeof a=="string")return a.replace(/\n/g," ");return a}function O(a,b){var c,d,f,e,i,h,k=[],l=[],q=n.oSort,t=a.aoData,G=a.aoColumns;if(!a.oFeatures.bServerSide&&(a.aaSorting.length!==0||a.aaSortingFixed!==null)){k=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(f=0;f<k.length;f++){e=k[f][0];i=M(a,e);h=a.aoColumns[e].sSortDataType;if(typeof n.afnSortData[h]!=
"undefined"){var J=n.afnSortData[h](a,e,i);i=0;for(h=t.length;i<h;i++)t[i]._aData[e]=J[i]}}f=0;for(e=a.aiDisplayMaster.length;f<e;f++)l[a.aiDisplayMaster[f]]=f;var B=k.length;a.aiDisplayMaster.sort(function(I,Y){var N;for(f=0;f<B;f++){c=G[k[f][0]].iDataSort;d=G[c].sType;N=q[d+"-"+k[f][1]](t[I]._aData[c],t[Y]._aData[c]);if(N!==0)return N}return q["numeric-asc"](l[I],l[Y])})}if(typeof b=="undefined"||b)T(a);a.bSorted=true;if(a.oFeatures.bFilter)P(a,a.oPreviousSearch,1);else{a.aiDisplay=a.aiDisplayMaster.slice();
a._iDisplayStart=0;E(a);C(a)}}function ba(a,b,c,d){j(b).bind("click.DT",function(f){if(a.aoColumns[c].bSortable!==false){var e=function(){var i,h;if(f.shiftKey){for(var k=false,l=0;l<a.aaSorting.length;l++)if(a.aaSorting[l][0]==c){k=true;i=a.aaSorting[l][0];h=a.aaSorting[l][2]+1;if(typeof a.aoColumns[i].asSorting[h]=="undefined")a.aaSorting.splice(l,1);else{a.aaSorting[l][1]=a.aoColumns[i].asSorting[h];a.aaSorting[l][2]=h}break}k===false&&a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0])}else if(a.aaSorting.length==
1&&a.aaSorting[0][0]==c){i=a.aaSorting[0][0];h=a.aaSorting[0][2]+1;if(typeof a.aoColumns[i].asSorting[h]=="undefined")h=0;a.aaSorting[0][1]=a.aoColumns[i].asSorting[h];a.aaSorting[0][2]=h}else{a.aaSorting.splice(0,a.aaSorting.length);a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0])}O(a)};if(a.oFeatures.bProcessing){K(a,true);setTimeout(function(){e();a.oFeatures.bServerSide||K(a,false)},0)}else e();typeof d=="function"&&d(a)}})}function T(a){var b,c,d,f,e,i=a.aoColumns.length,h=a.oClasses;for(b=
0;b<i;b++)a.aoColumns[b].bSortable&&j(a.aoColumns[b].nTh).removeClass(h.sSortAsc+" "+h.sSortDesc+" "+a.aoColumns[b].sSortingClass);f=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(b=0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable){e=a.aoColumns[b].sSortingClass;d=-1;for(c=0;c<f.length;c++)if(f[c][0]==b){e=f[c][1]=="asc"?h.sSortAsc:h.sSortDesc;d=c;break}j(a.aoColumns[b].nTh).addClass(e);if(a.bJUI){c=j("span",a.aoColumns[b].nTh);c.removeClass(h.sSortJUIAsc+
" "+h.sSortJUIDesc+" "+h.sSortJUI+" "+h.sSortJUIAscAllowed+" "+h.sSortJUIDescAllowed);c.addClass(d==-1?a.aoColumns[b].sSortingClassJUI:f[d][1]=="asc"?h.sSortJUIAsc:h.sSortJUIDesc)}}else j(a.aoColumns[b].nTh).addClass(a.aoColumns[b].sSortingClass);e=h.sSortColumn;if(a.oFeatures.bSort&&a.oFeatures.bSortClasses){d=Z(a);if(d.length>=i)for(b=0;b<i;b++)if(d[b].className.indexOf(e+"1")!=-1){c=0;for(a=d.length/i;c<a;c++)d[i*c+b].className=j.trim(d[i*c+b].className.replace(e+"1",""))}else if(d[b].className.indexOf(e+
"2")!=-1){c=0;for(a=d.length/i;c<a;c++)d[i*c+b].className=j.trim(d[i*c+b].className.replace(e+"2",""))}else if(d[b].className.indexOf(e+"3")!=-1){c=0;for(a=d.length/i;c<a;c++)d[i*c+b].className=j.trim(d[i*c+b].className.replace(" "+e+"3",""))}h=1;var k;for(b=0;b<f.length;b++){k=parseInt(f[b][0],10);c=0;for(a=d.length/i;c<a;c++)d[i*c+k].className+=" "+e+h;h<3&&h++}}}function Ba(a){if(a.oScroll.bInfinite)return null;var b=p.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;n.oPagination[a.sPaginationType].fnInit(a,
b,function(c){E(c);C(c)});typeof a.aanFeatures.p=="undefined"&&a.aoDrawCallback.push({fn:function(c){n.oPagination[c.sPaginationType].fnUpdate(c,function(d){E(d);C(d)})},sName:"pagination"});return b}function ea(a,b){var c=a._iDisplayStart;if(b=="first")a._iDisplayStart=0;else if(b=="previous"){a._iDisplayStart=a._iDisplayLength>=0?a._iDisplayStart-a._iDisplayLength:0;if(a._iDisplayStart<0)a._iDisplayStart=0}else if(b=="next")if(a._iDisplayLength>=0){if(a._iDisplayStart+a._iDisplayLength<a.fnRecordsDisplay())a._iDisplayStart+=
a._iDisplayLength}else a._iDisplayStart=0;else if(b=="last")if(a._iDisplayLength>=0){b=parseInt((a.fnRecordsDisplay()-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(b-1)*a._iDisplayLength}else a._iDisplayStart=0;else H(a,0,"Unknown paging action: "+b);return c!=a._iDisplayStart}function Aa(a){var b=p.createElement("div");b.className=a.oClasses.sInfo;if(typeof a.aanFeatures.i=="undefined"){a.aoDrawCallback.push({fn:Ga,sName:"information"});a.sTableId!==""&&b.setAttribute("id",a.sTableId+"_info")}return b}
function Ga(a){if(!(!a.oFeatures.bInfo||a.aanFeatures.i.length===0)){var b=a._iDisplayStart+1,c=a.fnDisplayEnd(),d=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),e=a.fnFormatNumber(b),i=a.fnFormatNumber(c),h=a.fnFormatNumber(d),k=a.fnFormatNumber(f);if(a.oScroll.bInfinite)e=a.fnFormatNumber(1);e=a.fnRecordsDisplay()===0&&a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfoEmpty+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()===0?a.oLanguage.sInfoEmpty+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",
h)+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfo.replace("_START_",e).replace("_END_",i).replace("_TOTAL_",k)+a.oLanguage.sInfoPostFix:a.oLanguage.sInfo.replace("_START_",e).replace("_END_",i).replace("_TOTAL_",k)+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()))+a.oLanguage.sInfoPostFix;if(a.oLanguage.fnInfoCallback!==null)e=a.oLanguage.fnInfoCallback(a,b,c,d,f,e);a=a.aanFeatures.i;b=0;for(c=a.length;b<c;b++)j(a[b]).html(e)}}
function wa(a){if(a.oScroll.bInfinite)return null;var b='<select size="1" '+(a.sTableId===""?"":'name="'+a.sTableId+'_length"')+">",c,d;if(a.aLengthMenu.length==2&&typeof a.aLengthMenu[0]=="object"&&typeof a.aLengthMenu[1]=="object"){c=0;for(d=a.aLengthMenu[0].length;c<d;c++)b+='<option value="'+a.aLengthMenu[0][c]+'">'+a.aLengthMenu[1][c]+"</option>"}else{c=0;for(d=a.aLengthMenu.length;c<d;c++)b+='<option value="'+a.aLengthMenu[c]+'">'+a.aLengthMenu[c]+"</option>"}b+="</select>";var f=p.createElement("div");
a.sTableId!==""&&typeof a.aanFeatures.l=="undefined"&&f.setAttribute("id",a.sTableId+"_length");f.className=a.oClasses.sLength;f.innerHTML=a.oLanguage.sLengthMenu.replace("_MENU_",b);j('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",true);j("select",f).bind("change.DT",function(){var e=j(this).val(),i=a.aanFeatures.l;c=0;for(d=i.length;c<d;c++)i[c]!=this.parentNode&&j("select",i[c]).val(e);a._iDisplayLength=parseInt(e,10);E(a);if(a.fnDisplayEnd()==a.fnRecordsDisplay()){a._iDisplayStart=
a.fnDisplayEnd()-a._iDisplayLength;if(a._iDisplayStart<0)a._iDisplayStart=0}if(a._iDisplayLength==-1)a._iDisplayStart=0;C(a)});return f}function ya(a){var b=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.r=="undefined"&&b.setAttribute("id",a.sTableId+"_processing");b.innerHTML=a.oLanguage.sProcessing;b.className=a.oClasses.sProcessing;a.nTable.parentNode.insertBefore(b,a.nTable);return b}function K(a,b){if(a.oFeatures.bProcessing){a=a.aanFeatures.r;for(var c=0,d=a.length;c<d;c++)a[c].style.visibility=
b?"visible":"hidden"}}function ga(a,b){for(var c=-1,d=0;d<a.aoColumns.length;d++){a.aoColumns[d].bVisible===true&&c++;if(c==b)return d}return null}function M(a,b){for(var c=-1,d=0;d<a.aoColumns.length;d++){a.aoColumns[d].bVisible===true&&c++;if(d==b)return a.aoColumns[d].bVisible===true?c:null}return null}function Q(a,b){var c,d;c=a._iDisplayStart;for(d=a._iDisplayEnd;c<d;c++)if(a.aoData[a.aiDisplay[c]].nTr==b)return a.aiDisplay[c];c=0;for(d=a.aoData.length;c<d;c++)if(a.aoData[c].nTr==b)return c;
return null}function S(a){for(var b=0,c=0;c<a.aoColumns.length;c++)a.aoColumns[c].bVisible===true&&b++;return b}function E(a){a._iDisplayEnd=a.oFeatures.bPaginate===false?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||a._iDisplayLength==-1?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Ha(a,b){if(!a||a===null||a==="")return 0;if(typeof b=="undefined")b=p.getElementsByTagName("body")[0];var c=p.createElement("div");c.style.width=a;b.appendChild(c);a=c.offsetWidth;
b.removeChild(c);return a}function $(a){var b=0,c,d=0,f=a.aoColumns.length,e,i=j("th",a.nTHead);for(e=0;e<f;e++)if(a.aoColumns[e].bVisible){d++;if(a.aoColumns[e].sWidth!==null){c=Ha(a.aoColumns[e].sWidthOrig,a.nTable.parentNode);if(c!==null)a.aoColumns[e].sWidth=v(c);b++}}if(f==i.length&&b===0&&d==f&&a.oScroll.sX===""&&a.oScroll.sY==="")for(e=0;e<a.aoColumns.length;e++){c=j(i[e]).width();if(c!==null)a.aoColumns[e].sWidth=v(c)}else{b=a.nTable.cloneNode(false);e=p.createElement("tbody");c=p.createElement("tr");
b.removeAttribute("id");b.appendChild(a.nTHead.cloneNode(true));if(a.nTFoot!==null){b.appendChild(a.nTFoot.cloneNode(true));L(function(h){h.style.width=""},b.getElementsByTagName("tr"))}b.appendChild(e);e.appendChild(c);e=j("thead th",b);if(e.length===0)e=j("tbody tr:eq(0)>td",b);e.each(function(h){this.style.width="";h=ga(a,h);if(h!==null&&a.aoColumns[h].sWidthOrig!=="")this.style.width=a.aoColumns[h].sWidthOrig});for(e=0;e<f;e++)if(a.aoColumns[e].bVisible){d=Ia(a,e);if(d!==null){d=d.cloneNode(true);
c.appendChild(d)}}e=a.nTable.parentNode;e.appendChild(b);if(a.oScroll.sX!==""&&a.oScroll.sXInner!=="")b.style.width=v(a.oScroll.sXInner);else if(a.oScroll.sX!==""){b.style.width="";if(j(b).width()<e.offsetWidth)b.style.width=v(e.offsetWidth)}else if(a.oScroll.sY!=="")b.style.width=v(e.offsetWidth);b.style.visibility="hidden";Ja(a,b);f=j("tbody tr:eq(0)>td",b);if(f.length===0)f=j("thead tr:eq(0)>th",b);for(e=c=0;e<a.aoColumns.length;e++)if(a.aoColumns[e].bVisible){d=j(f[c]).outerWidth();if(d!==null&&
d>0)a.aoColumns[e].sWidth=v(d);c++}a.nTable.style.width=v(j(b).outerWidth());b.parentNode.removeChild(b)}}function Ja(a,b){if(a.oScroll.sX===""&&a.oScroll.sY!==""){j(b).width();b.style.width=v(j(b).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sX!=="")b.style.width=v(j(b).outerWidth())}function Ia(a,b,c){if(typeof c=="undefined"||c){c=Ka(a,b);b=M(a,b);if(c<0)return null;return a.aoData[c].nTr.getElementsByTagName("td")[b]}var d=-1,f,e;c=-1;var i=p.createElement("div");i.style.visibility="hidden";
i.style.position="absolute";p.body.appendChild(i);f=0;for(e=a.aoData.length;f<e;f++){i.innerHTML=a.aoData[f]._aData[b];if(i.offsetWidth>d){d=i.offsetWidth;c=f}}p.body.removeChild(i);if(c>=0){b=M(a,b);if(a=a.aoData[c].nTr.getElementsByTagName("td")[b])return a}return null}function Ka(a,b){for(var c=-1,d=-1,f=0;f<a.aoData.length;f++){var e=a.aoData[f]._aData[b];if(e.length>c){c=e.length;d=f}}return d}function v(a){if(a===null)return"0px";if(typeof a=="number"){if(a<0)return"0px";return a+"px"}var b=
a.charCodeAt(a.length-1);if(b<48||b>57)return a;return a+"px"}function Oa(a,b){if(a.length!=b.length)return 1;for(var c=0;c<a.length;c++)if(a[c]!=b[c])return 2;return 0}function aa(a){for(var b=n.aTypes,c=b.length,d=0;d<c;d++){var f=b[d](a);if(f!==null)return f}return"string"}function A(a){for(var b=0;b<D.length;b++)if(D[b].nTable==a)return D[b];return null}function V(a){for(var b=[],c=a.aoData.length,d=0;d<c;d++)b.push(a.aoData[d]._aData);return b}function R(a){for(var b=[],c=a.aoData.length,d=0;d<
c;d++)b.push(a.aoData[d].nTr);return b}function Z(a){var b=R(a),c=[],d,f=[],e,i,h,k;e=0;for(i=b.length;e<i;e++){c=[];h=0;for(k=b[e].childNodes.length;h<k;h++){d=b[e].childNodes[h];d.nodeName.toUpperCase()=="TD"&&c.push(d)}h=d=0;for(k=a.aoColumns.length;h<k;h++)if(a.aoColumns[h].bVisible)f.push(c[h-d]);else{f.push(a.aoData[e]._anHidden[h]);d++}}return f}function la(a){return a.replace(new RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^)","g"),"\\$1")}function ma(a,b){for(var c=
-1,d=0,f=a.length;d<f;d++)if(a[d]==b)c=d;else a[d]>b&&a[d]--;c!=-1&&a.splice(c,1)}function va(a,b){b=b.split(",");for(var c=[],d=0,f=a.aoColumns.length;d<f;d++)for(var e=0;e<f;e++)if(a.aoColumns[d].sName==b[e]){c.push(e);break}return c}function ca(a){for(var b="",c=0,d=a.aoColumns.length;c<d;c++)b+=a.aoColumns[c].sName+",";if(b.length==d)return"";return b.slice(0,-1)}function H(a,b,c){a=a.sTableId===""?"DataTables warning: "+c:"DataTables warning (table id = '"+a.sTableId+"'): "+c;if(b===0)if(n.sErrMode==
"alert")alert(a);else throw a;else typeof console!="undefined"&&typeof console.log!="undefined"&&console.log(a)}function da(a){a.aoData.splice(0,a.aoData.length);a.aiDisplayMaster.splice(0,a.aiDisplayMaster.length);a.aiDisplay.splice(0,a.aiDisplay.length);E(a)}function na(a){if(!(!a.oFeatures.bStateSave||typeof a.bDestroying!="undefined")){var b,c,d,f="{";f+='"iCreate":'+(new Date).getTime()+",";f+='"iStart":'+a._iDisplayStart+",";f+='"iEnd":'+a._iDisplayEnd+",";f+='"iLength":'+a._iDisplayLength+
",";f+='"sFilter":"'+encodeURIComponent(a.oPreviousSearch.sSearch)+'",';f+='"sFilterEsc":'+!a.oPreviousSearch.bRegex+",";f+='"aaSorting":[ ';for(b=0;b<a.aaSorting.length;b++)f+="["+a.aaSorting[b][0]+',"'+a.aaSorting[b][1]+'"],';f=f.substring(0,f.length-1);f+="],";f+='"aaSearchCols":[ ';for(b=0;b<a.aoPreSearchCols.length;b++)f+='["'+encodeURIComponent(a.aoPreSearchCols[b].sSearch)+'",'+!a.aoPreSearchCols[b].bRegex+"],";f=f.substring(0,f.length-1);f+="],";f+='"abVisCols":[ ';for(b=0;b<a.aoColumns.length;b++)f+=
a.aoColumns[b].bVisible+",";f=f.substring(0,f.length-1);f+="]";b=0;for(c=a.aoStateSave.length;b<c;b++){d=a.aoStateSave[b].fn(a,f);if(d!=="")f=d}f+="}";La(a.sCookiePrefix+a.sInstance,f,a.iCookieDuration,a.sCookiePrefix,a.fnCookieCallback)}}function Ma(a,b){if(a.oFeatures.bStateSave){var c,d,f;d=oa(a.sCookiePrefix+a.sInstance);if(d!==null&&d!==""){try{c=typeof j.parseJSON=="function"?j.parseJSON(d.replace(/'/g,'"')):eval("("+d+")")}catch(e){return}d=0;for(f=a.aoStateLoad.length;d<f;d++)if(!a.aoStateLoad[d].fn(a,
c))return;a.oLoadedState=j.extend(true,{},c);a._iDisplayStart=c.iStart;a.iInitDisplayStart=c.iStart;a._iDisplayEnd=c.iEnd;a._iDisplayLength=c.iLength;a.oPreviousSearch.sSearch=decodeURIComponent(c.sFilter);a.aaSorting=c.aaSorting.slice();a.saved_aaSorting=c.aaSorting.slice();if(typeof c.sFilterEsc!="undefined")a.oPreviousSearch.bRegex=!c.sFilterEsc;if(typeof c.aaSearchCols!="undefined")for(d=0;d<c.aaSearchCols.length;d++)a.aoPreSearchCols[d]={sSearch:decodeURIComponent(c.aaSearchCols[d][0]),bRegex:!c.aaSearchCols[d][1]};
if(typeof c.abVisCols!="undefined"){b.saved_aoColumns=[];for(d=0;d<c.abVisCols.length;d++){b.saved_aoColumns[d]={};b.saved_aoColumns[d].bVisible=c.abVisCols[d]}}}}}function La(a,b,c,d,f){var e=new Date;e.setTime(e.getTime()+c*1E3);c=ra.location.pathname.split("/");a=a+"_"+c.pop().replace(/[\/:]/g,"").toLowerCase();var i;if(f!==null){i=typeof j.parseJSON=="function"?j.parseJSON(b):eval("("+b+")");b=f(a,i,e.toGMTString(),c.join("/")+"/")}else b=a+"="+encodeURIComponent(b)+"; expires="+e.toGMTString()+
"; path="+c.join("/")+"/";f="";e=9999999999999;if((oa(a)!==null?p.cookie.length:b.length+p.cookie.length)+10>4096){a=p.cookie.split(";");for(var h=0,k=a.length;h<k;h++)if(a[h].indexOf(d)!=-1){var l=a[h].split("=");try{i=eval("("+decodeURIComponent(l[1])+")")}catch(q){continue}if(typeof i.iCreate!="undefined"&&i.iCreate<e){f=l[0];e=i.iCreate}}if(f!=="")p.cookie=f+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+c.join("/")+"/"}p.cookie=b}function oa(a){var b=ra.location.pathname.split("/");a=a+"_"+
b[b.length-1].replace(/[\/:]/g,"").toLowerCase()+"=";b=p.cookie.split(";");for(var c=0;c<b.length;c++){for(var d=b[c];d.charAt(0)==" ";)d=d.substring(1,d.length);if(d.indexOf(a)===0)return decodeURIComponent(d.substring(a.length,d.length))}return null}function fa(a){a=a.getElementsByTagName("tr");if(a.length==1)return a[0].getElementsByTagName("th");var b=[],c=[],d,f,e,i,h,k,l=function(I,Y,N){for(;typeof I[Y][N]!="undefined";)N++;return N},q=function(I){if(typeof b[I]=="undefined")b[I]=[]};d=0;for(i=
a.length;d<i;d++){q(d);var t=0,G=[];f=0;for(h=a[d].childNodes.length;f<h;f++)if(a[d].childNodes[f].nodeName.toUpperCase()=="TD"||a[d].childNodes[f].nodeName.toUpperCase()=="TH")G.push(a[d].childNodes[f]);f=0;for(h=G.length;f<h;f++){var J=G[f].getAttribute("colspan")*1,B=G[f].getAttribute("rowspan")*1;if(!J||J===0||J===1){k=l(b,d,t);b[d][k]=G[f].nodeName.toUpperCase()=="TD"?4:G[f];if(B||B===0||B===1)for(e=1;e<B;e++){q(d+e);b[d+e][k]=2}t++}else{k=l(b,d,t);for(e=0;e<J;e++)b[d][k+e]=3;t+=J}}}d=0;for(i=
b.length;d<i;d++){f=0;for(h=b[d].length;f<h;f++)if(typeof b[d][f]=="object"&&typeof c[f]=="undefined")c[f]=b[d][f]}return c}function Na(){var a=p.createElement("p"),b=a.style;b.width="100%";b.height="200px";var c=p.createElement("div");b=c.style;b.position="absolute";b.top="0px";b.left="0px";b.visibility="hidden";b.width="200px";b.height="150px";b.overflow="hidden";c.appendChild(a);p.body.appendChild(c);b=a.offsetWidth;c.style.overflow="scroll";a=a.offsetWidth;if(b==a)a=c.clientWidth;p.body.removeChild(c);
return b-a}function L(a,b,c){for(var d=0,f=b.length;d<f;d++)for(var e=0,i=b[d].childNodes.length;e<i;e++)if(b[d].childNodes[e].nodeType==1)typeof c!="undefined"?a(b[d].childNodes[e],c[d].childNodes[e]):a(b[d].childNodes[e])}function o(a,b,c,d){if(typeof d=="undefined")d=c;if(typeof b[c]!="undefined")a[d]=b[c]}this.oApi={};this.fnDraw=function(a){var b=A(this[n.iApiIndex]);if(typeof a!="undefined"&&a===false){E(b);C(b)}else W(b)};this.fnFilter=function(a,b,c,d,f){var e=A(this[n.iApiIndex]);if(e.oFeatures.bFilter){if(typeof c==
"undefined")c=false;if(typeof d=="undefined")d=true;if(typeof f=="undefined")f=true;if(typeof b=="undefined"||b===null){P(e,{sSearch:a,bRegex:c,bSmart:d},1);if(f&&typeof e.aanFeatures.f!="undefined"){b=e.aanFeatures.f;c=0;for(d=b.length;c<d;c++)j("input",b[c]).val(a)}}else{e.aoPreSearchCols[b].sSearch=a;e.aoPreSearchCols[b].bRegex=c;e.aoPreSearchCols[b].bSmart=d;P(e,e.oPreviousSearch,1)}}};this.fnSettings=function(){return A(this[n.iApiIndex])};this.fnVersionCheck=n.fnVersionCheck;this.fnSort=function(a){var b=
A(this[n.iApiIndex]);b.aaSorting=a;O(b)};this.fnSortListener=function(a,b,c){ba(A(this[n.iApiIndex]),a,b,c)};this.fnAddData=function(a,b){if(a.length===0)return[];var c=[],d,f=A(this[n.iApiIndex]);if(typeof a[0]=="object")for(var e=0;e<a.length;e++){d=u(f,a[e]);if(d==-1)return c;c.push(d)}else{d=u(f,a);if(d==-1)return c;c.push(d)}f.aiDisplay=f.aiDisplayMaster.slice();if(typeof b=="undefined"||b)W(f);return c};this.fnDeleteRow=function(a,b,c){var d=A(this[n.iApiIndex]);a=typeof a=="object"?Q(d,a):
a;var f=d.aoData.splice(a,1),e=j.inArray(a,d.aiDisplay);d.asDataSearch.splice(e,1);ma(d.aiDisplayMaster,a);ma(d.aiDisplay,a);typeof b=="function"&&b.call(this,d,f);if(d._iDisplayStart>=d.aiDisplay.length){d._iDisplayStart-=d._iDisplayLength;if(d._iDisplayStart<0)d._iDisplayStart=0}if(typeof c=="undefined"||c){E(d);C(d)}return f};this.fnClearTable=function(a){var b=A(this[n.iApiIndex]);da(b);if(typeof a=="undefined"||a)C(b)};this.fnOpen=function(a,b,c){var d=A(this[n.iApiIndex]);this.fnClose(a);var f=
p.createElement("tr"),e=p.createElement("td");f.appendChild(e);e.className=c;e.colSpan=S(d);e.innerHTML=b;b=j("tr",d.nTBody);j.inArray(a,b)!=-1&&j(f).insertAfter(a);d.aoOpenRows.push({nTr:f,nParent:a});return f};this.fnClose=function(a){for(var b=A(this[n.iApiIndex]),c=0;c<b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a){(a=b.aoOpenRows[c].nTr.parentNode)&&a.removeChild(b.aoOpenRows[c].nTr);b.aoOpenRows.splice(c,1);return 0}return 1};this.fnGetData=function(a){var b=A(this[n.iApiIndex]);if(typeof a!=
"undefined"){a=typeof a=="object"?Q(b,a):a;return(aRowData=b.aoData[a])?aRowData._aData:null}return V(b)};this.fnGetNodes=function(a){var b=A(this[n.iApiIndex]);if(typeof a!="undefined")return(aRowData=b.aoData[a])?aRowData.nTr:null;return R(b)};this.fnGetPosition=function(a){var b=A(this[n.iApiIndex]);if(a.nodeName.toUpperCase()=="TR")return Q(b,a);else if(a.nodeName.toUpperCase()=="TD")for(var c=Q(b,a.parentNode),d=0,f=0;f<b.aoColumns.length;f++)if(b.aoColumns[f].bVisible){if(b.aoData[c].nTr.getElementsByTagName("td")[f-
d]==a)return[c,f-d,f]}else d++;return null};this.fnUpdate=function(a,b,c,d,f){var e=A(this[n.iApiIndex]),i,h;b=typeof b=="object"?Q(e,b):b;if(typeof a!="object"){h=a;e.aoData[b]._aData[c]=h;if(e.aoColumns[c].fnRender!==null){h=e.aoColumns[c].fnRender({iDataRow:b,iDataColumn:c,aData:e.aoData[b]._aData,oSettings:e});if(e.aoColumns[c].bUseRendered)e.aoData[b]._aData[c]=h}i=M(e,c);if(i!==null)e.aoData[b].nTr.getElementsByTagName("td")[i].innerHTML=h;else e.aoData[b]._anHidden[c].innerHTML=h}else{if(a.length!=
e.aoColumns.length){H(e,0,"An array passed to fnUpdate must have the same number of columns as the table in question - in this case "+e.aoColumns.length);return 1}for(c=0;c<a.length;c++){h=a[c];e.aoData[b]._aData[c]=h;if(e.aoColumns[c].fnRender!==null){h=e.aoColumns[c].fnRender({iDataRow:b,iDataColumn:c,aData:e.aoData[b]._aData,oSettings:e});if(e.aoColumns[c].bUseRendered)e.aoData[b]._aData[c]=h}i=M(e,c);if(i!==null)e.aoData[b].nTr.getElementsByTagName("td")[i].innerHTML=h;else e.aoData[b]._anHidden[c].innerHTML=
h}}a=j.inArray(b,e.aiDisplay);e.asDataSearch[a]=ka(e,e.aoData[b]._aData);if(typeof f=="undefined"||f)X(e);if(typeof d=="undefined"||d)W(e);return 0};this.fnSetColumnVis=function(a,b,c){var d=A(this[n.iApiIndex]),f,e;e=d.aoColumns.length;var i,h,k,l,q;if(d.aoColumns[a].bVisible!=b){l=j(">tr",d.nTHead)[0];i=j(">tr",d.nTFoot)[0];q=[];h=[];for(f=0;f<e;f++){q.push(d.aoColumns[f].nTh);h.push(d.aoColumns[f].nTf)}if(b){for(f=b=0;f<a;f++)d.aoColumns[f].bVisible&&b++;if(b>=S(d)){l.appendChild(q[a]);l=j(">tr",
d.nTHead);f=1;for(e=l.length;f<e;f++)l[f].appendChild(d.aoColumns[a].anThExtra[f-1]);if(i){i.appendChild(h[a]);l=j(">tr",d.nTFoot);f=1;for(e=l.length;f<e;f++)l[f].appendChild(d.aoColumns[a].anTfExtra[f-1])}f=0;for(e=d.aoData.length;f<e;f++){i=d.aoData[f]._anHidden[a];d.aoData[f].nTr.appendChild(i)}}else{for(f=a;f<e;f++){k=M(d,f);if(k!==null)break}l.insertBefore(q[a],l.getElementsByTagName("th")[k]);l=j(">tr",d.nTHead);f=1;for(e=l.length;f<e;f++){q=j(l[f]).children();l[f].insertBefore(d.aoColumns[a].anThExtra[f-
1],q[k])}if(i){i.insertBefore(h[a],i.getElementsByTagName("th")[k]);l=j(">tr",d.nTFoot);f=1;for(e=l.length;f<e;f++){q=j(l[f]).children();l[f].insertBefore(d.aoColumns[a].anTfExtra[f-1],q[k])}}Z(d);f=0;for(e=d.aoData.length;f<e;f++){i=d.aoData[f]._anHidden[a];d.aoData[f].nTr.insertBefore(i,j(">td:eq("+k+")",d.aoData[f].nTr)[0])}}d.aoColumns[a].bVisible=true}else{l.removeChild(q[a]);f=0;for(e=d.aoColumns[a].anThExtra.length;f<e;f++){k=d.aoColumns[a].anThExtra[f];k.parentNode.removeChild(k)}if(i){i.removeChild(h[a]);
f=0;for(e=d.aoColumns[a].anTfExtra.length;f<e;f++){k=d.aoColumns[a].anTfExtra[f];k.parentNode.removeChild(k)}}h=Z(d);f=0;for(e=d.aoData.length;f<e;f++){i=h[f*d.aoColumns.length+a*1];d.aoData[f]._anHidden[a]=i;i.parentNode.removeChild(i)}d.aoColumns[a].bVisible=false}f=0;for(e=d.aoOpenRows.length;f<e;f++)d.aoOpenRows[f].nTr.colSpan=S(d);if(typeof c=="undefined"||c){X(d);C(d)}na(d)}};this.fnPageChange=function(a,b){var c=A(this[n.iApiIndex]);ea(c,a);E(c);if(typeof b=="undefined"||b)C(c)};this.fnDestroy=
function(){var a=A(this[n.iApiIndex]),b=a.nTableWrapper.parentNode,c=a.nTBody,d,f;a.bDestroying=true;j(a.nTableWrapper).find("*").andSelf().unbind(".DT");d=0;for(f=a.aoColumns.length;d<f;d++)a.aoColumns[d].bVisible===false&&this.fnSetColumnVis(d,true);j("tbody>tr>td."+a.oClasses.sRowEmpty,a.nTable).parent().remove();if(a.nTable!=a.nTHead.parentNode){j(">thead",a.nTable).remove();a.nTable.appendChild(a.nTHead)}if(a.nTFoot&&a.nTable!=a.nTFoot.parentNode){j(">tfoot",a.nTable).remove();a.nTable.appendChild(a.nTFoot)}a.nTable.parentNode.removeChild(a.nTable);
j(a.nTableWrapper).remove();a.aaSorting=[];a.aaSortingFixed=[];T(a);j(R(a)).removeClass(a.asStripClasses.join(" "));if(a.bJUI){j("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oJUIClasses.sSortableAsc,n.oJUIClasses.sSortableDesc,n.oJUIClasses.sSortableNone].join(" "));j("th span",a.nTHead).remove()}else j("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oStdClasses.sSortableAsc,n.oStdClasses.sSortableDesc,n.oStdClasses.sSortableNone].join(" "));b.appendChild(a.nTable);d=0;for(f=a.aoData.length;d<
f;d++)c.appendChild(a.aoData[d].nTr);a.nTable.style.width=v(a.sDestroyWidth);j(">tr:even",c).addClass(a.asDestoryStrips[0]);j(">tr:odd",c).addClass(a.asDestoryStrips[1]);d=0;for(f=D.length;d<f;d++)D[d]==a&&D.splice(d,1)};this.fnAdjustColumnSizing=function(a){var b=A(this[n.iApiIndex]);X(b);if(typeof a=="undefined"||a)this.fnDraw(false);else if(b.oScroll.sX!==""||b.oScroll.sY!=="")this.oApi._fnScrollDraw(b)};for(var pa in n.oApi)if(pa)this[pa]=r(pa);this.oApi._fnExternApiFunc=r;this.oApi._fnInitalise=
s;this.oApi._fnLanguageProcess=y;this.oApi._fnAddColumn=F;this.oApi._fnColumnOptions=x;this.oApi._fnAddData=u;this.oApi._fnGatherData=z;this.oApi._fnDrawHead=U;this.oApi._fnDraw=C;this.oApi._fnReDraw=W;this.oApi._fnAjaxUpdate=ta;this.oApi._fnAjaxUpdateDraw=ua;this.oApi._fnAddOptionsHtml=sa;this.oApi._fnFeatureHtmlTable=za;this.oApi._fnScrollDraw=Ca;this.oApi._fnAjustColumnSizing=X;this.oApi._fnFeatureHtmlFilter=xa;this.oApi._fnFilterComplete=P;this.oApi._fnFilterCustom=Fa;this.oApi._fnFilterColumn=
Ea;this.oApi._fnFilter=Da;this.oApi._fnBuildSearchArray=ha;this.oApi._fnBuildSearchRow=ka;this.oApi._fnFilterCreateSearch=ia;this.oApi._fnDataToSearch=ja;this.oApi._fnSort=O;this.oApi._fnSortAttachListener=ba;this.oApi._fnSortingClasses=T;this.oApi._fnFeatureHtmlPaginate=Ba;this.oApi._fnPageChange=ea;this.oApi._fnFeatureHtmlInfo=Aa;this.oApi._fnUpdateInfo=Ga;this.oApi._fnFeatureHtmlLength=wa;this.oApi._fnFeatureHtmlProcessing=ya;this.oApi._fnProcessingDisplay=K;this.oApi._fnVisibleToColumnIndex=ga;
this.oApi._fnColumnIndexToVisible=M;this.oApi._fnNodeToDataIndex=Q;this.oApi._fnVisbleColumns=S;this.oApi._fnCalculateEnd=E;this.oApi._fnConvertToWidth=Ha;this.oApi._fnCalculateColumnWidths=$;this.oApi._fnScrollingWidthAdjust=Ja;this.oApi._fnGetWidestNode=Ia;this.oApi._fnGetMaxLenString=Ka;this.oApi._fnStringToCss=v;this.oApi._fnArrayCmp=Oa;this.oApi._fnDetectType=aa;this.oApi._fnSettingsFromNode=A;this.oApi._fnGetDataMaster=V;this.oApi._fnGetTrNodes=R;this.oApi._fnGetTdNodes=Z;this.oApi._fnEscapeRegex=
la;this.oApi._fnDeleteIndex=ma;this.oApi._fnReOrderIndex=va;this.oApi._fnColumnOrdering=ca;this.oApi._fnLog=H;this.oApi._fnClearTable=da;this.oApi._fnSaveState=na;this.oApi._fnLoadState=Ma;this.oApi._fnCreateCookie=La;this.oApi._fnReadCookie=oa;this.oApi._fnGetUniqueThs=fa;this.oApi._fnScrollBarWidth=Na;this.oApi._fnApplyToChildren=L;this.oApi._fnMap=o;var qa=this;return this.each(function(){var a=0,b,c,d,f;a=0;for(b=D.length;a<b;a++){if(D[a].nTable==this)if(typeof g=="undefined"||typeof g.bRetrieve!=
"undefined"&&g.bRetrieve===true)return D[a].oInstance;else if(typeof g.bDestroy!="undefined"&&g.bDestroy===true){D[a].oInstance.fnDestroy();break}else{H(D[a],0,"Cannot reinitialise DataTable.\n\nTo retrieve the DataTables object for this table, please pass either no arguments to the dataTable() function, or set bRetrieve to true. Alternatively, to destory the old table and create a new one, set bDestroy to true (note that a lot of changes to the configuration can be made through the API which is usually much faster).");
return}if(D[a].sTableId!==""&&D[a].sTableId==this.getAttribute("id")){D.splice(a,1);break}}var e=new m;D.push(e);var i=false,h=false;a=this.getAttribute("id");if(a!==null){e.sTableId=a;e.sInstance=a}else e.sInstance=n._oExternConfig.iNextUnique++;if(this.nodeName.toLowerCase()!="table")H(e,0,"Attempted to initialise DataTables on a node which is not a table: "+this.nodeName);else{e.nTable=this;e.oInstance=qa.length==1?qa:j(this).dataTable();e.oApi=qa.oApi;e.sDestroyWidth=j(this).width();if(typeof g!=
"undefined"&&g!==null){e.oInit=g;o(e.oFeatures,g,"bPaginate");o(e.oFeatures,g,"bLengthChange");o(e.oFeatures,g,"bFilter");o(e.oFeatures,g,"bSort");o(e.oFeatures,g,"bInfo");o(e.oFeatures,g,"bProcessing");o(e.oFeatures,g,"bAutoWidth");o(e.oFeatures,g,"bSortClasses");o(e.oFeatures,g,"bServerSide");o(e.oScroll,g,"sScrollX","sX");o(e.oScroll,g,"sScrollXInner","sXInner");o(e.oScroll,g,"sScrollY","sY");o(e.oScroll,g,"bScrollCollapse","bCollapse");o(e.oScroll,g,"bScrollInfinite","bInfinite");o(e.oScroll,
g,"iScrollLoadGap","iLoadGap");o(e.oScroll,g,"bScrollAutoCss","bAutoCss");o(e,g,"asStripClasses");o(e,g,"fnRowCallback");o(e,g,"fnHeaderCallback");o(e,g,"fnFooterCallback");o(e,g,"fnCookieCallback");o(e,g,"fnInitComplete");o(e,g,"fnServerData");o(e,g,"fnFormatNumber");o(e,g,"aaSorting");o(e,g,"aaSortingFixed");o(e,g,"aLengthMenu");o(e,g,"sPaginationType");o(e,g,"sAjaxSource");o(e,g,"iCookieDuration");o(e,g,"sCookiePrefix");o(e,g,"sDom");o(e,g,"oSearch","oPreviousSearch");o(e,g,"aoSearchCols","aoPreSearchCols");
o(e,g,"iDisplayLength","_iDisplayLength");o(e,g,"bJQueryUI","bJUI");o(e.oLanguage,g,"fnInfoCallback");typeof g.fnDrawCallback=="function"&&e.aoDrawCallback.push({fn:g.fnDrawCallback,sName:"user"});typeof g.fnStateSaveCallback=="function"&&e.aoStateSave.push({fn:g.fnStateSaveCallback,sName:"user"});typeof g.fnStateLoadCallback=="function"&&e.aoStateLoad.push({fn:g.fnStateLoadCallback,sName:"user"});e.oFeatures.bServerSide&&e.oFeatures.bSort&&e.oFeatures.bSortClasses&&e.aoDrawCallback.push({fn:T,sName:"server_side_sort_classes"});
if(typeof g.bJQueryUI!="undefined"&&g.bJQueryUI){e.oClasses=n.oJUIClasses;if(typeof g.sDom=="undefined")e.sDom='<"H"lfr>t<"F"ip>'}if(e.oScroll.sX!==""||e.oScroll.sY!=="")e.oScroll.iBarWidth=Na();if(typeof g.iDisplayStart!="undefined"&&typeof e.iInitDisplayStart=="undefined"){e.iInitDisplayStart=g.iDisplayStart;e._iDisplayStart=g.iDisplayStart}if(typeof g.bStateSave!="undefined"){e.oFeatures.bStateSave=g.bStateSave;Ma(e,g);e.aoDrawCallback.push({fn:na,sName:"state_save"})}if(typeof g.aaData!="undefined")h=
true;if(typeof g!="undefined"&&typeof g.aoData!="undefined")g.aoColumns=g.aoData;if(typeof g.oLanguage!="undefined")if(typeof g.oLanguage.sUrl!="undefined"&&g.oLanguage.sUrl!==""){e.oLanguage.sUrl=g.oLanguage.sUrl;j.getJSON(e.oLanguage.sUrl,null,function(q){y(e,q,true)});i=true}else y(e,g.oLanguage,false)}else g={};if(typeof g.asStripClasses=="undefined"){e.asStripClasses.push(e.oClasses.sStripOdd);e.asStripClasses.push(e.oClasses.sStripEven)}c=false;d=j(">tbody>tr",this);a=0;for(b=e.asStripClasses.length;a<
b;a++)if(d.filter(":lt(2)").hasClass(e.asStripClasses[a])){c=true;break}if(c){e.asDestoryStrips=["",""];if(j(d[0]).hasClass(e.oClasses.sStripOdd))e.asDestoryStrips[0]+=e.oClasses.sStripOdd+" ";if(j(d[0]).hasClass(e.oClasses.sStripEven))e.asDestoryStrips[0]+=e.oClasses.sStripEven;if(j(d[1]).hasClass(e.oClasses.sStripOdd))e.asDestoryStrips[1]+=e.oClasses.sStripOdd+" ";if(j(d[1]).hasClass(e.oClasses.sStripEven))e.asDestoryStrips[1]+=e.oClasses.sStripEven;d.removeClass(e.asStripClasses.join(" "))}a=this.getElementsByTagName("thead");
c=a.length===0?[]:fa(a[0]);var k;if(typeof g.aoColumns=="undefined"){k=[];a=0;for(b=c.length;a<b;a++)k.push(null)}else k=g.aoColumns;a=0;for(b=k.length;a<b;a++){if(typeof g.saved_aoColumns!="undefined"&&g.saved_aoColumns.length==b){if(k[a]===null)k[a]={};k[a].bVisible=g.saved_aoColumns[a].bVisible}F(e,c?c[a]:null)}if(typeof g.aoColumnDefs!="undefined")for(a=g.aoColumnDefs.length-1;a>=0;a--){var l=g.aoColumnDefs[a].aTargets;j.isArray(l)||H(e,1,"aTargets must be an array of targets, not a "+typeof l);
c=0;for(d=l.length;c<d;c++)if(typeof l[c]=="number"&&l[c]>=0){for(;e.aoColumns.length<=l[c];)F(e);x(e,l[c],g.aoColumnDefs[a])}else if(typeof l[c]=="number"&&l[c]<0)x(e,e.aoColumns.length+l[c],g.aoColumnDefs[a]);else if(typeof l[c]=="string"){b=0;for(f=e.aoColumns.length;b<f;b++)if(l[c]=="_all"||e.aoColumns[b].nTh.className.indexOf(l[c])!=-1)x(e,b,g.aoColumnDefs[a])}}if(typeof k!="undefined"){a=0;for(b=k.length;a<b;a++)x(e,a,k[a])}a=0;for(b=e.aaSorting.length;a<b;a++){if(e.aaSorting[a][0]>=e.aoColumns.length)e.aaSorting[a][0]=
0;k=e.aoColumns[e.aaSorting[a][0]];if(typeof e.aaSorting[a][2]=="undefined")e.aaSorting[a][2]=0;if(typeof g.aaSorting=="undefined"&&typeof e.saved_aaSorting=="undefined")e.aaSorting[a][1]=k.asSorting[0];c=0;for(d=k.asSorting.length;c<d;c++)if(e.aaSorting[a][1]==k.asSorting[c]){e.aaSorting[a][2]=c;break}}T(e);this.getElementsByTagName("thead").length===0&&this.appendChild(p.createElement("thead"));this.getElementsByTagName("tbody").length===0&&this.appendChild(p.createElement("tbody"));e.nTHead=this.getElementsByTagName("thead")[0];
e.nTBody=this.getElementsByTagName("tbody")[0];if(this.getElementsByTagName("tfoot").length>0)e.nTFoot=this.getElementsByTagName("tfoot")[0];if(h)for(a=0;a<g.aaData.length;a++)u(e,g.aaData[a]);else z(e);e.aiDisplay=e.aiDisplayMaster.slice();e.bInitialised=true;i===false&&s(e)}})}})(jQuery,window,document);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,134 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CF7DBValueConverter.php');
class DereferenceShortcodeVars implements CF7DBValueConverter {
public function convert($varString) {
$retValue = $varString; // Default return
$current_user = wp_get_current_user(); // WP_User
// echo '<pre>';
// print_r($current_user);
// echo '</pre>';
// echo('ID ' . $current_user->ID . '<br/>');
// echo('id ' . $current_user->id . '<br/>');
// echo('user_email ' . $current_user->user_email . '<br/>');
// echo('first_name ' . $current_user->first_name . '<br/>');
// echo('last_name ' . $current_user->last_name . '<br/>');
// echo('user_login ' . $current_user->user_login . '<br/>');
// echo('user_nicename ' . $current_user->user_nicename . '<br/>');
// echo('user_firstname ' . $current_user->user_firstname . '<br/>');
// echo('user_lastname ' . $current_user->user_lastname . '<br/>');
switch ($varString) {
case '$ID' :
$retValue = $current_user->ID;
break;
case '$id':
$retValue = $current_user->id;
break;
case '$first_name':
$retValue = $current_user->first_name;
break;
case '$last_name':
$retValue = $current_user->last_name;
break;
case '$user_login':
$retValue = $current_user->user_login;
break;
case '$user_nicename':
$retValue = $current_user->user_nicename;
break;
case '$user_email':
$retValue = $current_user->user_email;
break;
case '$user_firstname':
$retValue = $current_user->user_firstname;
break;
case '$user_lastname':
$retValue = $current_user->user_lastname;
break;
default:
$match = $this->evalMatch('_POST', $varString);
if ($match != '') {
global $_POST;
$retValue = $_POST[$match];
//print_r($retValue); // debug
break;
}
$match = $this->evalMatch('_GET', $varString);
if ($match != '') {
global $_GET;
$retValue = $_GET[$match];
//print_r($retValue); // debug
break;
}
$match = $this->evalMatch('_COOKIE', $varString);
if ($match != '') {
global $_COOKIE;
$retValue = $_COOKIE[$match];
//print_r($retValue); // debug
break;
}
break;
}
//echo "input: '$varString' output: '$retValue' <br/>"; // debug
return $retValue;
}
/**
* See if variable name in the form of $varName['...'] appears in the $varString
* (quotes optional or can be double-quotes)
* Intended to detect $varString is of the form $_POST['param-name'] given $varName = '_POST'
* @param $varName name of the variable (without the "$")
* @param $varString string to search
* @return string inside the brackets and quotes or '' if there is no match or
*/
public function evalMatch($varName, $varString) {
$template = '/^\$%s\(\'?"?(.*?)"?\'?\)$/';
$matches = array();
if (preg_match(sprintf($template, $varName), $varString, $matches)) {
//print_r($matches); // debug
if (count($matches) > 1) {
return $matches[1];
}
}
return '';
}
}

View File

@ -0,0 +1,415 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CF7DBPlugin.php');
require_once('CFDBQueryResultIterator.php');
class ExportBase {
/**
* @var string
*/
var $defaultTableClass = 'cf7-db-table';
/**
* @var array
*/
var $options;
/**
* @var bool
*/
var $debug = false;
/**
* @var array
*/
var $showColumns;
/**
* @var array
*/
var $hideColumns;
/**
* @var string
*/
var $htmlTableId;
/**
* @var string
*/
var $htmlTableClass;
/**
* @var string
*/
var $style;
/**
* @var CF7DBEvalutator|CF7FilterParser|CF7SearchEvaluator
*/
var $rowFilter;
/**
* @var bool
*/
var $isFromShortCode = false;
/**
* @var bool
*/
var $showSubmitField;
/**
* @var CF7DBPlugin
*/
var $plugin;
/**
* @var CFDBQueryResultIterator
*/
var $dataIterator;
function __construct() {
$this->plugin = new CF7DBPlugin();
}
/**
* This method is the first thing to call after construction to set state for other methods to work
* @param $options array|null
* @return void
*/
protected function setOptions($options) {
$this->options = $options;
}
protected function setCommonOptions($htmlOptions = false) {
if ($this->options && is_array($this->options)) {
if (isset($this->options['debug']) && $this->options['debug'] != 'false') {
$this->debug = true;
}
if (isset($this->options['showColumns'])) {
$this->showColumns = $this->options['showColumns'];
}
else if (isset($this->options['show'])) {
$this->showColumns = preg_split('/,/', $this->options['show'], -1, PREG_SPLIT_NO_EMPTY);
}
if (isset($this->options['hideColumns'])) {
$this->hideColumns = $this->options['hideColumns'];
}
else if (isset($this->options['hide'])) {
$this->hideColumns = preg_split('/,/', $this->options['hide'], -1, PREG_SPLIT_NO_EMPTY);
}
$this->isFromShortCode = isset($this->options['fromshortcode']) &&
$this->options['fromshortcode'] === true;
if ($htmlOptions) {
if (isset($this->options['class'])) {
$this->htmlTableClass = $this->options['class'];
}
else {
$this->htmlTableClass = $this->defaultTableClass;
}
if (isset($this->options['id'])) {
$this->htmlTableId = $this->options['id'];
}
else {
$this->htmlTableId = 'cftble_' . rand();
}
if (isset($this->options['style'])) {
$this->style = $this->options['style'];
}
}
if (isset($this->options['filter'])) {
require_once('CF7FilterParser.php');
require_once('DereferenceShortcodeVars.php');
$this->rowFilter = new CF7FilterParser;
$this->rowFilter->setComparisonValuePreprocessor(new DereferenceShortcodeVars);
$this->rowFilter->parseFilterString($this->options['filter']);
if ($this->debug) {
echo '<pre>';
print_r($this->rowFilter->getFilterTree());
echo '</pre>';
}
}
else if (isset($this->options['search'])) {
require_once('CF7SearchEvaluator.php');
$this->rowFilter = new CF7SearchEvaluator;
$this->rowFilter->setSearch($this->options['search']);
}
}
}
protected function isAuthorized() {
return $this->isFromShortCode ?
$this->plugin->canUserDoRoleOption('CanSeeSubmitDataViaShortcode') :
$this->plugin->canUserDoRoleOption('CanSeeSubmitData');
}
protected function assertSecurityErrorMessage() {
$errMsg = __('You do not have sufficient permissions to access this data.', 'contact-form-7-to-database-extension');
if ($this->isFromShortCode) {
echo $errMsg;
}
else {
include_once('CFDBDie.php');
CFDBDie::wp_die($errMsg);
}
}
/**
* @param string|array|null $headers mixed string header-string or array of header strings.
* E.g. Content-Type, Content-Disposition, etc.
* @return void
*/
protected function echoHeaders($headers = null) {
if (!headers_sent()) {
header('Expires: 0');
header('Cache-Control: no-store, no-cache, must-revalidate');
// Hoping to keep the browser from timing out if connection from Google SS Live Data
// script is calling this page to get information
header("Keep-Alive: timeout=60"); // Not a standard HTTP header; browsers may disregard
if ($headers) {
if (is_array($headers)) {
foreach ($headers as $aheader) {
header($aheader);
}
}
else {
header($headers);
}
}
flush();
}
}
/**
* @param $dataColumns array
* @return array
*/
protected function &getColumnsToDisplay($dataColumns) {
//$dataColumns = array_merge(array('Submitted'), $dataColumns);
$showCols = empty($this->showColumns) ? $dataColumns : $this->matchColumns($this->showColumns, $dataColumns);
if (empty($this->hideColumns)) {
return $showCols;
}
$hideCols = $this->matchColumns($this->hideColumns, $dataColumns);
if (empty($hideCols)) {
return $showCols;
}
$retCols = array();
foreach ($showCols as $aShowCol) {
if (!in_array($aShowCol, $hideCols)) {
$retCols[] = $aShowCol;
}
}
return $retCols;
}
protected function matchColumns(&$patterns, &$subject) {
$returnCols = array();
foreach ($patterns as $pCol) {
if (substr($pCol, 0, 1) == '/') {
// Show column value is a REGEX
foreach($subject as $sCol) {
if (preg_match($pCol, $sCol) && !in_array($sCol, $returnCols)) {
$returnCols[] = $sCol;
}
}
}
else {
$returnCols[] = $pCol;
}
}
return $returnCols;
}
/**
* @return bool
*/
protected function getShowSubmitField() {
$showSubmitField = true;
if ($this->hideColumns != null && is_array($this->hideColumns) && in_array('Submitted', $this->hideColumns)) {
$showSubmitField = false;
}
else if ($this->showColumns != null && is_array($this->showColumns)) {
$showSubmitField = in_array('Submitted', $this->showColumns);
}
return $showSubmitField;
}
/**
* @param string|array of string $formName
* @param null|string $submitTimeKeyName
* @return void
*/
protected function setDataIterator($formName, $submitTimeKeyName = null) {
$sql = $this->getPivotQuery($formName);
$this->dataIterator = new CFDBQueryResultIterator();
// $this->dataIterator->fileColumns = $this->getFileMetaData($formName);
$queryOptions = array();
if ($submitTimeKeyName) {
$queryOptions['submitTimeKeyName'] = $submitTimeKeyName;
}
if (!empty($this->rowFilter) && isset($this->options['limit'])) {
// have data iterator apply the limit if it is not areadly
// being applied in SQL directly, which we do where there are
// no filter constraints.
$queryOptions['limit'] = $this->options['limit'];
}
$this->dataIterator->query($sql, $this->rowFilter, $queryOptions);
$this->dataIterator->displayColumns = $this->getColumnsToDisplay($this->dataIterator->columns);
}
// protected function &getFileMetaData($formName) {
// global $wpdb;
// $tableName = $this->plugin->getSubmitsTableName();
// $rows = $wpdb->get_results(
// "select distinct `field_name`
//from `$tableName`
//where `form_name` = '$formName'
//and `file` is not null");
//
// $fileColumns = array();
// foreach ($rows as $aRow) {
// $files[] = $aRow->field_name;
// }
// return $fileColumns;
// }
/**
* @param string|array of string $formName
* @param bool $count
* @return string
*/
public function &getPivotQuery($formName, $count = false) {
global $wpdb;
$tableName = $this->plugin->getSubmitsTableName();
$formNameClause = '';
if (is_array($formName)) {
$formNameClause = 'WHERE `form_name` in ( \'' . implode('\', \'', $formName) . '\' )';
}
else if ($formName !== null) {
$formNameClause = "WHERE `form_name` = '$formName'";
}
$rows = $wpdb->get_results("SELECT DISTINCT `field_name`, `field_order` FROM `$tableName` $formNameClause ORDER BY field_order");
$fields = array();
foreach ($rows as $aRow) {
if (!in_array($aRow->field_name, $fields)) {
$fields[] = $aRow->field_name;
}
}
$sql = '';
if ($count) {
$sql .= 'SELECT count(*) as count FROM (';
}
$sql .= "SELECT `submit_time` AS 'Submitted'";
foreach ($fields as $aCol) {
$sql .= ",\n max(if(`field_name`='$aCol', `field_value`, null )) AS '$aCol'";
}
if (!$count) {
$sql .= ",\n GROUP_CONCAT(if(`file` is null or length(file) = 0, null, `field_name`)) AS fields_with_file";
}
$sql .= "\nFROM `$tableName` \n$formNameClause \nGROUP BY `submit_time` ";
if ($count) {
$sql .= ') form';
}
else {
$orderBys = array();
if ($this->options && isset($this->options['orderby'])) {
$orderByStrings = explode(',', $this->options['orderby']);
foreach ($orderByStrings as $anOrderBy) {
$anOrderBy = trim($anOrderBy);
$ascOrDesc = null;
if (strtoupper(substr($anOrderBy, -5)) == ' DESC'){
$ascOrDesc = " DESC";
$anOrderBy = trim(substr($anOrderBy, 0, -5));
}
else if (strtoupper(substr($anOrderBy, -4)) == ' ASC'){
$ascOrDesc = " ASC";
$anOrderBy = trim(substr($anOrderBy, 0, -4));
}
if ($anOrderBy == 'Submitted') {
$anOrderBy = "submit_time";
}
if (in_array($anOrderBy, $fields)) {
$orderBys[] = '`' . $anOrderBy . '`' . $ascOrDesc;
}
}
}
if (empty($orderBys)) {
$sql .= "\nORDER BY `submit_time` DESC";
}
else {
$sql .= "\nORDER BY ";
$first = true;
foreach ($orderBys as $anOrderBy) {
if ($first) {
$sql .= $anOrderBy;
$first = false;
}
else {
$sql .= ', ' . $anOrderBy;
}
}
}
if (empty($this->rowFilter) && $this->options && isset($this->options['limit'])) {
// If no filter constraints and have a limit, add limit to the SQL
$sql .= "\nLIMIT " . $this->options['limit'];
}
}
return $sql;
}
/**
* @param string|array of string $formName
* @return int
*/
public function getDBRowCount($formName) {
global $wpdb;
$count = 0;
$rows = $wpdb->get_results($this->getPivotQuery($formName, true));
foreach ($rows as $aRow) {
$count = $aRow->count;
break;
}
return $count;
}
}

View File

@ -0,0 +1,116 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ExportBase.php');
require_once('CFDBExport.php');
class ExportToCsvUtf16le extends ExportBase implements CFDBExport {
public function export($formName, $options = null) {
$this->setOptions($options);
$this->setCommonOptions();
// Security Check
if (!$this->isAuthorized()) {
$this->assertSecurityErrorMessage();
return;
}
// Headers
$this->echoHeaders(
array('Content-Type: text/csv; charset=UTF-16LE',
"Content-Disposition: attachment; filename=\"$formName.csv\""));
// todo: make this work
// $fileName = $formName . '.csv';
// $fileName = $this->encodeWordRfc2231($formName) . '.csv';
// header("Content-Disposition: attachment; filename*=UTF-8''$fileName");
//Bytes FF FE (UTF-16LE BOM)
echo chr(255) . chr(254);
$eol = $this->encode(utf8_encode("\n"));
$delimiter = $this->encode(utf8_encode("\t"));
// Query DB for the data for that form
$submitTimeKeyName = 'Submit_Time_Key';
$this->setDataIterator($formName, $submitTimeKeyName);
// Column Headers
foreach ($this->dataIterator->displayColumns as $aCol) {
echo $this->prepareCsvValue($aCol);
echo $delimiter;
}
echo $eol;
// Rows
$showFileUrlsInExport = $this->plugin->getOption('ShowFileUrlsInExport') == 'true';
while ($this->dataIterator->nextRow()) {
$fields_with_file = null;
if ($showFileUrlsInExport &&
isset($this->dataIterator->row['fields_with_file']) &&
$this->dataIterator->row['fields_with_file'] != null) {
$fields_with_file = explode(',', $this->dataIterator->row['fields_with_file']);
}
foreach ($this->dataIterator->displayColumns as $aCol) {
$cell = isset($this->dataIterator->row[$aCol]) ? $this->dataIterator->row[$aCol] : '';
if ($showFileUrlsInExport &&
$fields_with_file &&
$cell &&
in_array($aCol, $fields_with_file)) {
$cell = $this->plugin->getFileUrl($this->dataIterator->row[$submitTimeKeyName], $formName, $aCol);
}
echo $this->prepareCsvValue($cell);
echo $delimiter;
}
echo $eol;
}
}
protected function &prepareCsvValue($text) {
// Excel does not like \n characters in UTF-16LE, so we replace with a space
$text = str_replace("\n", ' ', $text);
// In CSV, escape double-quotes by putting two double quotes together
$text = str_replace('"', '""', $text);
// Quote it to escape delimiters
$text = '"' . $text . '"';
// Encode UTF-16LE
$text = $this->encode($text);
return $text;
}
protected function encode($text) {
return mb_convert_encoding($text, 'UTF-16LE', 'UTF-8');
}
protected function &encodeWordRfc2231($word) {
$binArray = unpack("C*", $word);
$hex = '';
foreach ($binArray as $chr) {
$hex .= '%' . sprintf("%02X", base_convert($chr, 2, 16));
}
return $hex;
}
}

View File

@ -0,0 +1,101 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ExportBase.php');
require_once('CFDBExport.php');
class ExportToCsvUtf8 extends ExportBase implements CFDBExport {
var $useBom = false;
public function setUseBom($use) {
$this->useBom = $use;
}
public function export($formName, $options = null) {
$this->setOptions($options);
$this->setCommonOptions();
// Security Check
if (!$this->isAuthorized()) {
$this->assertSecurityErrorMessage();
return;
}
if ($this->options && is_array($this->options)) {
if (isset($this->options['bom'])) {
$this->useBom = $this->options['bom'] == 'true';
}
}
// Headers
$this->echoHeaders(
array('Content-Type: text/html; charset=UTF-8',
"Content-Disposition: attachment; filename=\"$formName.csv\""));
$this->echoCsv($formName);
}
public function echoCsv($formName) {
if ($this->useBom) {
// File encoding UTF-8 Byte Order Mark (BOM) http://wiki.sdn.sap.com/wiki/display/ABAP/Excel+files+-+CSV+format
echo chr(239) . chr(187) . chr(191);
}
$eol = "\n";
// Query DB for the data for that form
$submitTimeKeyName = 'Submit_Time_Key';
$this->setDataIterator($formName, $submitTimeKeyName);
// Column Headers
foreach ($this->dataIterator->displayColumns as $aCol) {
printf('"%s",', str_replace('"', '""', $aCol));
}
echo $eol;
// Rows
$showFileUrlsInExport = $this->plugin->getOption('ShowFileUrlsInExport') == 'true';
while ($this->dataIterator->nextRow()) {
$fields_with_file = null;
if ($showFileUrlsInExport &&
isset($this->dataIterator->row['fields_with_file']) &&
$this->dataIterator->row['fields_with_file'] != null) {
$fields_with_file = explode(',', $this->dataIterator->row['fields_with_file']);
}
foreach ($this->dataIterator->displayColumns as $aCol) {
$cell = isset($this->dataIterator->row[$aCol]) ? $this->dataIterator->row[$aCol] : '';
if ($showFileUrlsInExport &&
$fields_with_file &&
$cell &&
in_array($aCol, $fields_with_file)) {
$cell = $this->plugin->getFileUrl($this->dataIterator->row[$submitTimeKeyName], $formName, $aCol);
}
printf('"%s",', str_replace('"', '""', $cell));
}
echo $eol;
}
}
}

View File

@ -0,0 +1,173 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CF7DBPlugin.php');
require_once('CFDBExport.php');
include_once('CFDBDie.php');
class ExportToGoogleLiveData implements CFDBExport {
public function export($formName, $options = null) {
$plugin = new CF7DBPlugin();
if (!$plugin->canUserDoRoleOption('CanSeeSubmitData')) {
CFDBDie::wp_die(__('You do not have sufficient permissions to access this page.', 'contact-form-7-to-database-extension'));
}
header('Expires: 0');
header('Cache-Control: no-store, no-cache, must-revalidate');
$pluginUrlDir = $plugin->getPluginDirUrl();
$scriptLink = $pluginUrlDir . 'Cf7ToDBGGoogleSS.js.php';
$imageUrlDir = $pluginUrlDir . "help";
$siteUrl = get_option('home');
$search = isset($options['search']) ? $options['search'] : '';
ob_start();
?>
<style type="text/css">
*.popup-trigger {
position: relative;
z-index: 0;
}
*.popup-trigger:hover {
background-color: transparent;
z-index: 50;
}
*.popup-content {
position: absolute!important;
background-color: #ffffff;
padding: 5px;
border: 2px gray;
visibility: hidden!important;
color: black;
text-decoration: none;
min-width:400px;
max-width:600px;
overflow: auto;
}
*.popup-trigger:hover *.popup-content {
visibility: visible!important;
top: 50px!important;
left: 50px!important;
}
</style>
Setting up a Google Spreadsheet to pull in data from WordPress requires these manual steps:
<table cellspacing="15px" cellpadding="15px">
<tbody>
<tr>
<td>
<div class="popup-trigger">
<a href="<?php echo $imageUrlDir ?>/GoogleNewSS.png">
<img src="<?php echo $imageUrlDir ?>/GoogleNewSS.png" alt="Create a new spreadsheet" height="100px" width="61px"/>
<div class="popup-content">
<img src="<?php echo $imageUrlDir ?>/GoogleNewSS.png" alt="Create a new spreadsheet"/>
</div>
</a>
</div>
</td>
<td><p>Log into Google Docs and create a new Google Spreadsheet</p></td>
</tr>
<tr>
<td>
<div class="popup-trigger">
<a href="<?php echo $imageUrlDir ?>/GoogleOpenScriptEditor.png">
<img src="<?php echo $imageUrlDir ?>/GoogleOpenScriptEditor.png" alt="Create a new spreadsheet" height="69px" width="100px"/>
<div class="popup-content">
<img src="<?php echo $imageUrlDir ?>/GoogleOpenScriptEditor.png" alt="Create a new spreadsheet"/>
</div>
</a>
</div>
</td>
<td><p>Go to <b>Tools</b> menu -> <b>Scripts</b> -> <b>Script Editor...</b></p></td>
</tr>
<tr>
<td>
<div class="popup-trigger">
<a href="<?php echo $imageUrlDir ?>/GooglePasteScriptEditor.png">
<img src="<?php echo $imageUrlDir ?>/GooglePasteScriptEditor.png" alt="Paste script text" height="68px" width="100px"/>
<div class="popup-content">
<img src="<?php echo $imageUrlDir ?>/GooglePasteScriptEditor.png" alt="Paste script text"/>
</div>
</a>
</div>
</td>
<td>
<p>Delete any text that is already there</p>
<p><b>Copy</b> the text from <a target="_gscript" href="<?php echo($scriptLink) ?>">THIS SCRIPT FILE</a> and <b>paste</b> it
into the Google script editor</p>
</td>
</tr>
<tr>
<td>
<div class="popup-trigger">
<a href="<?php echo $imageUrlDir ?>/GoogleSaveScriptEditor.png">
<img src="<?php echo $imageUrlDir ?>/GoogleSaveScriptEditor.png" alt="Create a new spreadsheet" height="100px" width="83px"/>
<div class="popup-content">
<img src="<?php echo $imageUrlDir ?>/GoogleSaveScriptEditor.png" alt="Create a new spreadsheet"/>
</div>
</a>
</div>
</td>
<td>
<p><b>Save</b> and <b>close</b> the script editor.</p>
</td>
</tr>
<tr>
<td>
<div class="popup-trigger">
<a href="<?php echo $imageUrlDir ?>/GoogleEnterFormula.png">
<img src="<?php echo $imageUrlDir ?>/GoogleEnterFormula.png" alt="Create a new spreadsheet" height="43px" width="100px"/>
<div class="popup-content">
<img src="<?php echo $imageUrlDir ?>/GoogleEnterFormula.png" alt="Create a new spreadsheet"/>
</div>
</a>
</div>
</td>
<td>
<p>Click on a cell A1 in the Spreadsheet (or any cell)</p>
<p>Enter in the cell the formula:</p>
<p><code><?php echo("=CF7ToDBData(\"$siteUrl\", \"$formName\", \"$search\", \"user\", \"pwd\")") ?></code></p>
<p>Replacing <b>user</b> and <b>pwd</b> with your <u>WordPress</u> site user name and password</p>
</td>
</tr>
<tr>
</tr>
</tbody>
</table>
<span style="color:red; font-weight:bold;">
WARNING: since you are putting your login information into the Google Spreadsheet, be sure not to share
the spreadsheet with others.</span>
<?php
$html = ob_get_contents();
ob_end_clean();
CFDBDie::wp_die($html,
__('How to Set up Google Spreadsheet to pull data from WordPress', 'contact-form-7-to-database-extension'),
array('response' => 200, 'back_link' => true));
}
}

View File

@ -0,0 +1,114 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CJ7DBCheckZendFramework.php');
require_once('ExportToCsvUtf8.php');
require_once('ExportBase.php');
require_once('CFDBExport.php');
require_once('CFDBDie.php');
class ExportToGoogleSS extends ExportBase implements CFDBExport {
public function export($formName, $options = null) {
$this->setOptions($options);
// Security Check
if (!$this->isAuthorized()) {
$this->assertSecurityErrorMessage();
return;
}
// Headers
$this->echoHeaders('Content-Type: text/html; charset=UTF-8');
if (!CJ7DBCheckZendFramework::checkIncludeZend()) {
return;
}
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
//Zend_Loader::loadClass('Zend_Gdata_Spreadsheets');
Zend_Loader::loadClass('Zend_Gdata_App_AuthException');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Docs');
$guser = $options['guser'];
$gpwd = $options['gpwd'];
try {
$client = Zend_Gdata_ClientLogin::getHttpClient(
$guser, $gpwd,
Zend_Gdata_Docs::AUTH_SERVICE_NAME); //Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME
}
catch (Zend_Gdata_App_AuthException $ae) {
CFDBDie::wp_die("<p>Login failed for: '$guser' </p><p>Error: " . $ae->getMessage() . '</p>',
__('Login Failed', 'contact-form-7-to-database-extension'),
array('response' => 200, 'back_link' => true));
}
try {
// Generate CSV file contents into buffer
$exporter = new ExportToCsvUtf8;
$exporter->setOptions($options);
$exporter->setCommonOptions();
$exporter->setUseBom(false);
ob_start();
$exporter->echoCsv($formName);
$csvFileContents = ob_get_contents();
ob_end_clean();
// Put the contents in a tmp file because Google upload API only reads from a file
$tmpfname = tempnam(sys_get_temp_dir(), "$formName.csv");
$handle = fopen($tmpfname, 'w');
fwrite($handle, $csvFileContents);
fclose($handle);
// Upload the tmp file to Google Docs
$docs = new Zend_Gdata_Docs($client);
$newDocumentEntry = $docs->uploadFile($tmpfname, $formName, 'text/csv');
unlink($tmpfname); // delete tmp file
// Get the URL of the new Google doc
$alternateLink = '';
foreach ($newDocumentEntry->link as $link) {
if ($link->getRel() === 'alternate') {
$alternateLink = $link->getHref();
break;
}
}
//header("Location: $alternateLink");
//$title = $newDocumentEntry->title;
$title = __('New Google Spreadsheet', 'contact-form-7-to-database-extension');
$output =
utf8_encode("$title: <a target=\"_blank\" href=\"$alternateLink\">") .
$formName .
utf8_encode('</a>');
CFDBDie::wp_die($output, $title, array('response' => 200, 'back_link' => true));
}
catch (Exception $ex) {
CFDBDie::wp_die($ex->getMessage() . '<pre>' . $ex->getTraceAsString() . '</pre>',
__('Error', 'contact-form-7-to-database-extension'),
array('back_link' => true));
}
}
}

View File

@ -0,0 +1,217 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ExportBase.php');
require_once('CFDBExport.php');
class ExportToHtmlTable extends ExportBase implements CFDBExport {
/**
* Echo a table of submitted form data
* @param string $formName
* @param array $options
* @return void
*/
public function export($formName, $options = null) {
$this->setOptions($options);
$this->setCommonOptions(true);
$canDelete = false;
$useDT = false;
$printScripts = false;
$printStyles = false;
if ($options && is_array($options)) {
if (isset($options['useDT'])) {
$useDT = $options['useDT'];
$this->htmlTableClass = '';
if (isset($options['printScripts'])) {
$printScripts = $options['printScripts'];
}
if (isset($options['printStyles'])) {
$printStyles = $options['printStyles'];
}
}
if (isset($options['canDelete'])) {
$canDelete = $options['canDelete'];
}
}
// Security Check
if (!$this->isAuthorized()) {
$this->assertSecurityErrorMessage();
return;
}
// Headers
$this->echoHeaders('Content-Type: text/html; charset=UTF-8');
if ($this->isFromShortCode) {
ob_start();
}
else {
if ($printScripts) {
$pluginUrl = plugins_url('/', __FILE__);
wp_enqueue_script('datatables', $pluginUrl . 'DataTables/media/js/jquery.dataTables.min.js', array('jquery'));
wp_print_scripts('datatables');
}
if ($printStyles) {
$pluginUrl = plugins_url('/', __FILE__);
wp_enqueue_style('datatables-demo', $pluginUrl .'DataTables/media/css/demo_table.css');
wp_enqueue_style('jquery-ui.css', $pluginUrl . 'jquery-ui/jquery-ui.css');
wp_print_styles(array('jquery-ui.css', 'datatables-demo'));
}
}
// Query DB for the data for that form
$submitTimeKeyName = 'Submit_Time_Key';
$this->setDataIterator($formName, $submitTimeKeyName);
if ($useDT) {
$dtJsOptions = $options['dt_options'];
if (!$dtJsOptions) {
$dtJsOptions = '"bJQueryUI": true, "aaSorting": []';
$i18nUrl = $this->plugin->getDataTableTranslationUrl();
if ($i18nUrl) {
$dtJsOptions = $dtJsOptions . ", \"oLanguage\": { \"sUrl\": \"$i18nUrl\" }";
}
}
?>
<script type="text/javascript" language="Javascript">
jQuery(document).ready(function() {
jQuery('#<?php echo $this->htmlTableId ?>').dataTable({
<?php echo $dtJsOptions ?> })
});
</script>
<?php
}
if ($this->htmlTableClass == $this->defaultTableClass) {
?>
<style type="text/css">
table.<?php echo $this->defaultTableClass ?> {
margin-top: 1em;
border-spacing: 0;
border: 0 solid gray;
font-size: x-small;
}
table.<?php echo $this->defaultTableClass ?> th {
padding: 5px;
border: 1px solid gray;
}
table.<?php echo $this->defaultTableClass ?> th > td {
font-size: x-small;
background-color: #E8E8E8;
}
table.<?php echo $this->defaultTableClass ?> tbody td {
padding: 5px;
border: 1px solid gray;
font-size: x-small;
}
table.<?php echo $this->defaultTableClass ?> tbody td > div {
max-height: 100px;
overflow: auto;
}
</style>
<?php
}
if ($this->style) {
?>
<style type="text/css">
<?php echo $this->style ?>
</style>
<?php
}
?>
<table <?php if ($this->htmlTableId) echo "id=\"$this->htmlTableId\" "; if ($this->htmlTableClass) echo "class=\"$this->htmlTableClass\"" ?> >
<thead><tr>
<?php if ($canDelete) { ?>
<th>
<button id="delete" name="delete" onclick="this.form.submit()"><?php _e('Delete', 'contact-form-7-to-database-extension')?></button>
</th>
<?php
}
foreach ($this->dataIterator->displayColumns as $aCol) {
printf('<th><div title="%s">%s</div></th>', $aCol, $aCol);
}
?>
</tr></thead>
<tbody>
<?php
$showLineBreaks = $this->plugin->getOption('ShowLineBreaksInDataTable');
$showLineBreaks = 'false' != $showLineBreaks;
while ($this->dataIterator->nextRow()) {
$submitKey = $this->dataIterator->row[$submitTimeKeyName];
?>
<tr>
<?php if ($canDelete) { // Put in the delete checkbox ?>
<td align="center">
<input type="checkbox" name="<?php echo $submitKey ?>" value="row"/>
</td>
<?php
}
$fields_with_file = null;
if (isset($this->dataIterator->row['fields_with_file']) && $this->dataIterator->row['fields_with_file'] != null) {
$fields_with_file = explode(',', $this->dataIterator->row['fields_with_file']);
}
foreach ($this->dataIterator->displayColumns as $aCol) {
$cell = htmlentities($this->dataIterator->row[$aCol], null, 'UTF-8'); // no HTML injection
if ($showLineBreaks) {
$cell = str_replace("\r\n", '<br/>', $cell); // preserve DOS line breaks
$cell = str_replace("\n", '<br/>', $cell); // preserve UNIX line breaks
}
if ($fields_with_file && in_array($aCol, $fields_with_file)) {
$fileUrl = $this->plugin->getFileUrl($this->dataIterator->row[$submitTimeKeyName], $formName, $aCol);
$cell = "<a href=\"$fileUrl\">$cell</a>";
}
// NOTE: the ID field is used to identify the cell when an edit happens and we save that to the server
printf('<td title="%s"><div id="%s,%s">%s</div></td>', $aCol, $submitKey, $aCol, $cell);
}
?></tr><?php
} ?>
</tbody>
</table>
<?php
if ($this->isFromShortCode) {
// If called from a shortcode, need to return the text,
// otherwise it can appear out of order on the page
$output = ob_get_contents();
ob_end_clean();
return $output;
}
}
}

View File

@ -0,0 +1,161 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ExportBase.php');
require_once('CFDBExport.php');
class ExportToHtmlTemplate extends ExportBase implements CFDBExport {
/**
* @param $formName string
* @param $options array of option_name => option_value
* @return void
*/
public function export($formName, $options = null) {
$this->setOptions($options);
$this->setCommonOptions(true);
$filelinks = '';
$wpautop = false;
if ($this->options && is_array($this->options)) {
if (isset($this->options['filelinks'])) {
$filelinks = $this->options['filelinks'];
}
if (isset($this->options['wpautop'])) {
$wpautop = $this->options['wpautop'] == 'true';
}
}
// Security Check
if (!$this->isAuthorized()) {
$this->assertSecurityErrorMessage();
return;
}
// Headers
$this->echoHeaders('Content-Type: text/html; charset=UTF-8');
if (empty($options) || !isset($options['content'])) {
return;
}
if ($this->isFromShortCode) {
ob_start();
}
// Get the data
$submitTimeKeyName = 'Submit_Time_Key';
$this->setDataIterator($formName, $submitTimeKeyName);
$matches = array();
preg_match_all('/\$\{([^}]+)\}/', $options['content'], $matches);
$colNamesToSub = array();
$varNamesToSub = array();
if (!empty($matches) && is_array($matches[1])) {
foreach ($matches[1] as $aSubVar) {
// Each is expected to be a name of a column
if (in_array($aSubVar, $this->dataIterator->displayColumns)) {
$colNamesToSub[] = $aSubVar;
$varNamesToSub[] = '${' . $aSubVar . '}';
}
}
}
// WordPress likes to wrap the content in <br />content<p> which messes up things when
// you are putting
// <tr><td>stuff<td></tr>
// as the content because it comes out
// <br /><tr><td>stuff<td></tr><p>
// which messed up the table html.
// So we try to identify that and strip it out.
// This is related to http://codex.wordpress.org/Function_Reference/wpautop
// see also http://wordpress.org/support/topic/shortcodes-are-wrapped-in-paragraph-tags?replies=4
if (!$wpautop) {
if (substr($options['content'], 0, 6) == '<br />' &&
substr($options['content'], -3, 3) == '<p>') {
$options['content'] = substr($options['content'], 6, strlen($options['content']) - 6 - 3);
}
}
while ($this->dataIterator->nextRow()) {
if (empty($colNamesToSub)) {
echo $options['content'];
}
else {
$fields_with_file = null;
if ($filelinks != 'name' &&
isset($this->dataIterator->row['fields_with_file']) &&
$this->dataIterator->row['fields_with_file'] != null) {
$fields_with_file = explode(',', $this->dataIterator->row['fields_with_file']);
}
$replacements = array();
foreach ($colNamesToSub as $aCol) {
if ($fields_with_file && in_array($aCol, $fields_with_file)) {
switch ($filelinks) {
case 'url':
$replacements[] = $this->plugin->getFileUrl($this->dataIterator->row[$submitTimeKeyName], $formName, $aCol);
break;
case 'link':
$replacements[] =
'<a href="' .
$this->plugin->getFileUrl($this->dataIterator->row[$submitTimeKeyName], $formName, $aCol) .
'">' .
htmlentities($this->dataIterator->row[$aCol], null, 'UTF-8') .
'</a>';
break;
case 'image':
case 'img':
$replacements[] =
'<img src="' .
$this->plugin->getFileUrl($this->dataIterator->row[$submitTimeKeyName], $formName, $aCol) .
'" alt="' .
htmlentities($this->dataIterator->row[$aCol], null, 'UTF-8') .
'" />';
break;
case 'name':
default:
$replacements[] = htmlentities($this->dataIterator->row[$aCol], null, 'UTF-8');
}
}
else {
$replacements[] = htmlentities($this->dataIterator->row[$aCol], null, 'UTF-8');
}
}
echo str_replace($varNamesToSub, $replacements, $options['content']);
}
}
if ($this->isFromShortCode) {
// If called from a shortcode, need to return the text,
// otherwise it can appear out of order on the page
$output = ob_get_contents();
ob_end_clean();
return $output;
}
}
}

View File

@ -0,0 +1,60 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('CFDBExport.php');
class ExportToIqy implements CFDBExport {
public function export($formName, $options = null) {
header('Content-Type: text/x-ms-iqy');
header("Content-Disposition: attachment; filename=\"$formName.iqy\"");
$url = get_bloginfo('url');
$encFormName = urlencode($formName);
$uri = "?action=cfdb-export&form=$encFormName&enc=HTML";
if (isset($options['search'])) {
$uri = $uri . '&search=' . urlencode($options['search']);
}
$encRedir = urlencode('wp-admin/admin-ajax.php' . $uri);
// To get this to work right, we have to submit to the same page that the login form does and post
// the same parameters that the login form does. This includes "log" and "pwd" for the login and
// also "redirect_to" which is the URL of the page where we want to end up including a "form_name" parameter
// to tell that final page to select which contact form data is to be displayed.
//
// "Selection=1" references the 1st HTML table in the page which is the data table.
// "Formatting" can be "None", "All", or "RTF"
echo (
"WEB
1
$url/wp-login.php?redirect_to=$encRedir
log=[\"Username for $url\"]&pwd=[\"Password for $url\"]
Selection=1
Formatting=All
PreFormattedTextToColumns=True
ConsecutiveDelimitersAsOne=True
SingleBlockTextImport=False
DisableDateRecognition=False
DisableRedirections=False
");
}
}

View File

@ -0,0 +1,175 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ExportBase.php');
require_once('CFDBExport.php');
class ExportToJson extends ExportBase implements CFDBExport {
public function export($formName, $options = null) {
$this->setOptions($options);
$this->setCommonOptions();
$varName = 'cf7db';
$html = false; // i.e. whether to create an HTML script tag and Javascript variable
if ($options && is_array($options)) {
if (isset($options['html'])) {
$html = $options['html'];
}
if (isset($options['var'])) {
$varName = $options['var'];
}
}
// Security Check
if (!$this->isAuthorized()) {
$this->assertSecurityErrorMessage();
return;
}
// Headers
$contentType = $html ? 'Content-Type: text/html; charset=UTF-8' : 'Content-Type: application/json; charset=UTF-8';
$this->echoHeaders($contentType);
// Get the data
$this->setDataIterator($formName);
if ($this->isFromShortCode) {
ob_start();
}
if ($html) {
?>
<script type="text/javascript" language="JavaScript">
<!--
var <?php echo $varName; ?> = <?php $this->echoJsonEncode(); ?>;
//-->
</script>
<?php
}
else {
echo $this->echoJsonEncode();
}
if ($this->isFromShortCode) {
// If called from a shortcode, need to return the text,
// otherwise it can appear out of order on the page
$output = ob_get_contents();
ob_end_clean();
return $output;
}
}
protected function echoJsonEncode() {
$format = 'map';
if ($this->options && isset($this->options['format'])) {
if ($this->options['format'] == 'array' || $this->options['format'] == 'arraynoheader') {
$format = $this->options['format'];
}
}
// Avoid use of json_encode() so we don't have to buffer all the data
$search = array('"', "\n"); // Things we need to escape in JSON
$replace = array('\"', '\\n');
if ($format == 'map') {
// Create the column name JSON values only once
$jsonEscapedColumns = array();
foreach ($this->dataIterator->displayColumns as $col) {
$jsonEscapedColumns[$col] = str_replace($search, $replace, $col);
}
echo "[\n";
$firstRow = true;
while ($this->dataIterator->nextRow()) {
if ($firstRow) {
$firstRow = false;
}
else {
echo ",\n";
}
echo '{';
$firstCol = true;
foreach ($this->dataIterator->displayColumns as $col) {
if ($firstCol) {
$firstCol = false;
}
else {
echo ',';
}
printf('"%s":"%s"',
$jsonEscapedColumns[$col],
str_replace($search, $replace, $this->dataIterator->row[$col]));
}
echo '}';
}
echo "\n]";
}
else { // 'array' || 'arraynoheader'
echo "[\n";
$firstRow = true;
if ($format == 'array') {
// Add header
$firstCol = true;
echo '[';
foreach ($this->dataIterator->displayColumns as $col) {
if ($firstCol) {
$firstCol = false;
}
else {
echo ',';
}
printf('"%s"', str_replace($search, $replace, $col));
}
echo ']';
$firstRow = false;
}
// Export data rows
while ($this->dataIterator->nextRow()) {
if ($firstRow) {
$firstRow = false;
}
else {
echo ",\n";
}
$firstCol = true;
echo '[';
foreach ($this->dataIterator->displayColumns as $col) {
if ($firstCol) {
$firstCol = false;
}
else {
echo ',';
}
printf('"%s"', str_replace($search, $replace, $this->dataIterator->row[$col]));
}
echo "]";
}
echo "\n]";
}
}
}

View File

@ -0,0 +1,218 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ExportBase.php');
require_once('CFDBExport.php');
class ExportToValue extends ExportBase implements CFDBExport {
public function export($formName, $options = null) {
// Allow for multiple form name inputs, comma-delimited
$tmp = explode(',', $formName);
if (count($tmp) > 1) {
$formName = &$tmp;
}
else if ($formName == '*') {
$formName = null; // Allow for no form specified implying all forms
}
$this->setOptions($options);
$this->setCommonOptions();
// Security Check
if (!$this->isAuthorized()) {
$this->assertSecurityErrorMessage();
return;
}
// See if a function is to be applied
$funct = null;
$delimiter = ', ';
if ($this->options && is_array($this->options)) {
if (isset($this->options['function'])) {
$funct = $this->options['function'];
}
if (isset($this->options['delimiter'])) {
$delimiter = $this->options['delimiter'];
}
}
// Headers
$this->echoHeaders('Content-Type: text/plain; charset=UTF-8');
// Get the data
$this->setDataIterator($formName);
if ($funct == 'count' &&
count($this->showColumns) == 0 &&
count($this->hideColumns) == 0) {
// Just count the number of entries in the database
$dbRowCount = $this->getDBRowCount($formName);
if (!$this->isFromShortCode) {
echo $dbRowCount;
}
return $dbRowCount;
}
if ($funct) {
// Apply function to dataset
switch ($funct) {
case 'count':
$count = 0;
$colsPerRow = count($this->dataIterator->displayColumns);
while ($this->dataIterator->nextRow()) {
$count += $colsPerRow;
}
if ($this->isFromShortCode) {
return $count;
}
else {
echo $count;
return;
}
case 'min':
$min = null;
while ($this->dataIterator->nextRow()) {
foreach ($this->dataIterator->displayColumns as $col) {
$val = $this->dataIterator->row[$col];
if ($min === null) {
$min = $val;
}
else {
if ($val < $min) {
$min = $val;
}
}
}
}
if ($this->isFromShortCode) {
return $min;
}
else {
echo $min;
return;
}
case 'max':
$max = null;
while ($this->dataIterator->nextRow()) {
foreach ($this->dataIterator->displayColumns as $col) {
$val = $this->dataIterator->row[$col];
if ($max === null) {
$max = $val;
}
else {
if ($val > $max) {
$max = $val;
}
}
}
}
if ($this->isFromShortCode) {
return $max;
}
else {
echo $max;
return;
}
case 'sum':
$sum = 0;
while ($this->dataIterator->nextRow()) {
foreach ($this->dataIterator->displayColumns as $col) {
$sum = $sum + $this->dataIterator->row[$col];
}
}
if ($this->isFromShortCode) {
return $sum;
}
else {
echo $sum;
return;
}
case 'mean':
$sum = 0;
$count = 0;
while ($this->dataIterator->nextRow()) {
foreach ($this->dataIterator->displayColumns as $col) {
$count += 1;
$sum += $this->dataIterator->row[$col];
}
}
$mean = $sum / $count;
if ($this->isFromShortCode) {
return $mean;
}
else {
echo $mean;
return;
}
}
}
// At this point in the code: $funct not defined or not recognized
// output values for each row/column
if ($this->isFromShortCode) {
$outputData = array();
while ($this->dataIterator->nextRow()) {
foreach ($this->dataIterator->displayColumns as $col) {
$outputData[] = $this->dataIterator->row[$col];
}
}
ob_start();
switch (count($outputData)) {
case 0:
echo '';
break;
case 1:
echo $outputData[0];
break;
default:
echo implode($delimiter, $outputData);
break;
}
$output = ob_get_contents();
ob_end_clean();
// If called from a shortcode, need to return the text,
// otherwise it can appear out of order on the page
return $output;
}
else {
$first = true;
while ($this->dataIterator->nextRow()) {
foreach ($this->dataIterator->displayColumns as $col) {
if ($first) {
$first = false;
}
else {
echo $delimiter;
}
echo $this->dataIterator->row[$col];
}
}
}
}
}

View File

@ -0,0 +1,62 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
abstract class ShortCodeLoader {
/**
* @param $shortcodeName mixed either string name of the shortcode
* (as it would appear in a post, e.g. [shortcodeName])
* or an array of such names in case you want to have more than one name
* for the same shortcode
* @return void
*/
public function register($shortcodeName) {
$this->registerShortcodeToFunction($shortcodeName, 'handleShortcode');
}
/**
* @param $shortcodeName mixed either string name of the shortcode
* (as it would appear in a post, e.g. [shortcodeName])
* or an array of such names in case you want to have more than one name
* for the same shortcode
* @param $functionName string name of public function in this class to call as the
* shortcode handler
* @return void
*/
protected function registerShortcodeToFunction($shortcodeName, $functionName) {
if (is_array($shortcodeName)) {
foreach ($shortcodeName as $aName) {
add_shortcode($aName, array($this, $functionName));
}
}
else {
add_shortcode($shortcodeName, array($this, $functionName));
}
}
/**
* @abstract Override this function and add actual shortcode handling here
* @param $atts shortcode inputs
* @return string shortcode content
*/
public abstract function handleShortcode($atts);
}

View File

@ -0,0 +1,68 @@
<?php
/*
"Contact Form to Database Extension" Copyright (C) 2011 Michael Simpson (email : michael.d.simpson@gmail.com)
This file is part of Contact Form to Database Extension.
Contact Form to Database Extension is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Contact Form to Database Extension is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Contact Form to Database Extension.
If not, see <http://www.gnu.org/licenses/>.
*/
require_once('ShortCodeLoader.php');
/**
* Adapted from this excellent article:
* http://scribu.net/wordpress/optimal-script-loading.html
*
* The idea is you have a shortcode that needs a script loaded, but you only
* want to load it if the shortcode is actually called.
*/
abstract class ShortCodeScriptLoader extends ShortCodeLoader {
var $doAddScript;
public function register($shortcodeName) {
$this->registerShortcodeToFunction($shortcodeName, 'handleShortcodeWrapper');
// It will be too late to enqueue the script in the header,
// so have to add it to the footer
add_action('wp_footer', array($this, 'addScriptWrapper'));
}
public function handleShortcodeWrapper($atts) {
// Flag that we need to add the script
$this->doAddScript = true;
return $this->handleShortcode($atts);
}
// Defined in super-class:
//public abstract function handleShortcode($atts);
public function addScriptWrapper() {
// Only add the script if the shortcode was actually called
if ($this->doAddScript) {
$this->addScript();
}
}
/**
* @abstract override this function with calls to insert scripts needed by your shortcode in the footer
* Example:
* wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
* wp_print_scripts('my-script');
* @return void
*/
public abstract function addScript();
}

View File

@ -0,0 +1,70 @@
<?php
/*
Plugin Name: Contact Form to DB Extension
Plugin URI: http://wordpress.org/extend/plugins/contact-form-7-to-database-extension/
Version: 1.8.7
Author: Michael Simpson
Description: Captures form submissions from Contact Form 7 and Fast Secure Contact Form plugins and writes the form data to the database | <a href="admin.php?page=CF7DBPluginSubmissions">Data</a> | <a href="admin.php?page=CF7DBPluginSettings">Settings</a> | <a href="http://wordpress.org/extend/plugins/contact-form-7-to-database-extension/faq/">FAQ</a>
Text Domain: contact-form-7-to-database-extension
License: GPL3
*/
/**
* Check the PHP version and give a useful error message if the user's version is less than the required version
* @return boolean true if version check passed. If false, triggers an error which WP will handle, by displaying
* an error message on the Admin page
*/
function CF7DBPlugin_PhpVersionCheck() {
$minimalRequiredPhpVersion = '5.0';
if (version_compare(phpversion(), $minimalRequiredPhpVersion) < 0) {
trigger_error(
'<p>' . __('Error: Contact Form to DB Plugin requires a newer version of PHP to be running.', 'contact-form-7-to-database-extension') . '</p>' .
'<ul>' .
'<li>' . __('Minimal version of PHP required: ', 'contact-form-7-to-database-extension') . '<strong>' . $minimalRequiredPhpVersion . '</strong></li>' .
'<li>' . __('Your server\'s PHP version: ', 'contact-form-7-to-database-extension') . '<strong>' . phpversion() . '</strong></li>' .
'</ul>' .
'<p>' . __('When using the Apache web server, typically you can configure it to use PHP5 by doing the following:', 'contact-form-7-to-database-extension') .
'<ul>' .
'<li>' . __('Locate and edit this file, located at the top directory of your WordPress installation: ', 'contact-form-7-to-database-extension') .
'<strong><code>.htaccess</code></strong></li>' .
'<li>' . __('Add these two lines to the file:', 'contact-form-7-to-database-extension') .
'<br/><code><pre>
AddType x-mapp-php5 .php
AddHandler x-mapp-php5 .php
</pre></code></ul>'
, E_USER_ERROR); // E_USER_ERROR seems to be handled OK in WP. It gives a notice in the Plugins Page
return false;
}
return true;
}
/**
* Initialize internationalization (i18n) for this plugin.
* References:
* http://codex.wordpress.org/I18n_for_WordPress_Developers
* http://www.wdmac.com/how-to-create-a-po-language-translation#more-631
* @return void
*/
function CF7DBPlugin_i18n_init() {
$pluginDir = dirname(plugin_basename(__FILE__));
load_plugin_textdomain('contact-form-7-to-database-extension', false, $pluginDir . '/languages/');
}
//////////////////////////////////
// Run initialization
/////////////////////////////////
// First initialize i18n
CF7DBPlugin_i18n_init();
// Next, run the version check.
// If it is successful, continue with initialization for this plugin
if (CF7DBPlugin_PhpVersionCheck()) {
// Only load and run the init function if we know PHP version can parse it
include_once('CF7DBPlugin_init.php');
CF7DBPlugin_init(__FILE__);
}

View File

@ -0,0 +1,33 @@
div.cfdb_paginate {
padding: 3px;
margin: 3px;
}
div.cfdb_paginate a {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #AAAADD;
text-decoration: none; /* no underline */
color: #000099;
}
div.cfdb_paginate a:hover, div.cfdb_paginate a:active {
border: 1px solid #000099;
color: #000;
}
div.cfdb_paginate span.current {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #000099;
font-weight: bold;
background-color: #000099;
color: #FFF;
}
div.cfdb_paginate span.disabled {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #EEE;
color: #DDD;
}

View File

@ -0,0 +1,221 @@
// Taken from: http://www.teslacore.it/sssup1/destest.html
//Paul Tero, July 2001
//http://www.shopable.co.uk/des.html
//
//Optimised for performance with large blocks by Michael Hayworth, November 2001
//http://www.netdealing.com
//
//THIS SOFTWARE IS PROVIDED "AS IS" AND
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
//SUCH DAMAGE.
//des
//this takes the key, the message, and whether to encrypt or decrypt
function des (key, message, encrypt, mode, iv) {
//declaring this locally speeds things up a bit
var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004);
var spfunction2 = new Array (0x80108020,0x80008000,0x8000,0x108020,0x100000,0x20,0x80100020,0x80008020,0x80000020,0x80108020,0x80108000,0x80000000,0x80008000,0x100000,0x20,0x80100020,0x108000,0x100020,0x80008020,0,0x80000000,0x8000,0x108020,0x80100000,0x100020,0x80000020,0,0x108000,0x8020,0x80108000,0x80100000,0x8020,0,0x108020,0x80100020,0x100000,0x80008020,0x80100000,0x80108000,0x8000,0x80100000,0x80008000,0x20,0x80108020,0x108020,0x20,0x8000,0x80000000,0x8020,0x80108000,0x100000,0x80000020,0x100020,0x80008020,0x80000020,0x100020,0x108000,0,0x80008000,0x8020,0x80000000,0x80100020,0x80108020,0x108000);
var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200);
var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100);
var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010);
var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002);
var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000);
//create the 16 or 48 subkeys we will need
var keys = des_createKeys (key);
var m=0, i, j, temp, temp2, right1, right2, left, right, looping;
var cbcleft, cbcleft2, cbcright, cbcright2
var endloop, loopinc;
var len = message.length;
var chunk = 0;
//set up the loops for single and triple des
var iterations = keys.length == 32 ? 3 : 9; //single or triple des
if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);}
else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);}
message += "\0\0\0\0\0\0\0\0"; //pad the message out with null bytes
//store the result here
result = "";
tempresult = "";
if (mode == 1) { //CBC mode
cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
m=0;
}
//loop through each 64 bit chunk of the message
while (m < len) {
left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
//for Cipher Block Chaining mode, xor the message with the previous result
if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}}
//first each 64 but chunk of the message must be permuted according to IP
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
left = ((left << 1) | (left >>> 31));
right = ((right << 1) | (right >>> 31));
//do this either 1 or 3 times for each chunk of the message
for (j=0; j<iterations; j+=3) {
endloop = looping[j+1];
loopinc = looping[j+2];
//now go through and perform the encryption or decryption
for (i=looping[j]; i!=endloop; i+=loopinc) { //for efficiency
right1 = right ^ keys[i];
right2 = ((right >>> 4) | (right << 28)) ^ keys[i+1];
//the result is attained by passing these bytes through the S selection functions
temp = left;
left = right;
right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f]
| spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f]
| spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f]
| spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
}
temp = left; left = right; right = temp; //unreverse left and right
} //for either 1 or 3 iterations
//move then each one bit to the right
left = ((left >>> 1) | (left << 31));
right = ((right >>> 1) | (right << 31));
//now perform IP-1, which is IP in the opposite direction
temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
//for Cipher Block Chaining mode, xor the message with the previous result
if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}}
tempresult += String.fromCharCode ((left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff));
chunk += 8;
if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 0;}
} //for every 8 characters, or 64 bits in the message
//return the result as an array
return result + tempresult;
} //end of des
//des_createKeys
//this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 integers, and returns 16 48 bit keys
function des_createKeys (key) {
//declaring this locally speeds things up a bit
pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101);
pc2bytes2 = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808);
pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
pc2bytes4 = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010);
pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002);
pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800);
pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408);
pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020);
pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
//how many iterations (1 for des, 3 for triple des)
var iterations = key.length >= 24 ? 3 : 1;
//stores the return keys
var keys = new Array (32 * iterations);
//now define the left shifts which need to be done
var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
//other variables
var lefttemp, righttemp, m=0, n=0, temp;
for (var j=0; j<iterations; j++) { //either 1 or 3 iterations
left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2);
temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
//the right side needs to be shifted and to get the last four bits of the left side
temp = (left << 8) | ((right >>> 20) & 0x000000f0);
//left needs to be put upside down
left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
right = temp;
//now go through and perform these shifts on the left and right keys
for (i=0; i < shifts.length; i++) {
//shift the keys either one or two bits to the left
if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);}
else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);}
left &= 0xfffffff0; right &= 0xfffffff0;
//now apply PC-2, in such a way that E is easier when encrypting or decrypting
//this conversion will look like PC-2 except only the last 6 bits of each byte are used
//rather than 48 consecutive bits and the order of lines will be according to
//how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf]
| pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf]
| pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf]
| pc2bytes6[(left >>> 4) & 0xf];
righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf]
| pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf]
| pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf]
| pc2bytes13[(right >>> 4) & 0xf];
temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16);
}
} //for each iterations
//return the keys we've created
return keys;
} //end of des_createKeys
////////////////////////////// TEST //////////////////////////////
//printHexArray
function printHex (s) {
//var r = "0x"; // Don't prepend "0x"
var r = "";
var hexes = new Array ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
for (var i=0; i<s.length; i++) {r += hexes [s.charCodeAt(i) >> 4] + hexes [s.charCodeAt(i) & 0xf];}
return r;
}
function unHex(s)
{
var r = "";
// for (var i=2; i<s.length;i+=2) { // No "0x" prepended
for (var i=0; i<s.length;i+=2) {
x1 = s.charCodeAt(i);
x1 = x1 >= 48 && x1 < 58 ? x1 - 48 : x1 - 97 + 10;
x2 = s.charCodeAt(i+1);
x2 = x2 >= 48 && x2 < 58 ? x2 - 48 : x2 - 97 + 10;
r += String.fromCharCode (((x1 << 4) & 0xF0) | (x2 & 0x0F));
}
return r;
}
//var key = "this is a 24 byte key !!";
//var message = "This is a test message";
//var ciphertext = des (key, message, 1, 0);
//document.writeln ("DES Test: " + printHex (ciphertext));

View File

@ -0,0 +1,25 @@
This directory is for the i18n translations for the DataTable widget that is used by this plugin.
Most translations herein were take from DataTables.net: http://www.datatables.net/plug-ins/i18n
To create a file for a language, give it a name following the format:
ll.json
And to create a file specific to a language and country, give it a name following the format:
ll_CC.json
Or use whatever the locale string in for your system:
locale.json
Where:
"ll" is an ISO 639 two- or three-letter language code
http://www.gnu.org/software/autoconf/manual/gettext/Language-Codes.html#Language-Codes
"CC" is an ISO 3166 two-letter country code
http://www.gnu.org/software/autoconf/manual/gettext/Country-Codes.html#Country-Codes
locale is your locale string, which is typically in the form "ll_CC", but is whatever
is returned from WordPress function get_locale()
** If you create a new translation file, please send a copy to the author of this plugin
so he can share it with others. Also, send it to a contact at DataTable.net.
email: michael_d_simpson@gmail.com

View File

@ -0,0 +1,17 @@
{
"sProcessing": "جاري التحميل...",
"sLengthMenu": "أظهر مُدخلات _MENU_",
"sZeroRecords": "لم يُعثر على أية سجلات",
"sInfo": "إظهار _START_ إلى _END_ من أصل _TOTAL_ مُدخل",
"sInfoEmpty": "يعرض 0 إلى 0 من أصل 0 سجلّ",
"sInfoFiltered": "(منتقاة من مجموع _MAX_ مُدخل)",
"sInfoPostFix": "",
"sSearch": "ابحث:",
"sUrl": "",
"oPaginate": {
"sFirst": "الأول",
"sPrevious": "السابق",
"sNext": "التالي",
"sLast": "الأخير"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Обработка на резултатите...",
"sLengthMenu": "Показване на _MENU_ резултата",
"sZeroRecords": "Няма намерени резултати",
"sInfo": "Показване на резултати от _START_ до _END_ от общо _TOTAL_",
"sInfoEmpty": "Показване на резултати от 0 до 0 от общо 0",
"sInfoFiltered": "(филтрирани от общо _MAX_ резултата)",
"sInfoPostFix": "",
"sSearch": "Търсене във всички колони:",
"sUrl": "",
"oPaginate": {
"sFirst": "Първа",
"sPrevious": "Предишна",
"sNext": "Следваща",
"sLast": "Последна"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Processant...",
"sLengthMenu": "Mostra _MENU_ registres",
"sZeroRecords": "No s'han trobat registres.",
"sInfo": "Mostrant de _START_ a _END_ de _TOTAL_ registres",
"sInfoEmpty": "Mostrant de 0 a 0 de 0 registres",
"sInfoFiltered": "(filtrat de _MAX_ total registres)",
"sInfoPostFix": "",
"sSearch": "Filtrar:",
"sUrl": "",
"oPaginate": {
"sFirst": "Primer",
"sPrevious": "Anterior",
"sNext": "Següent",
"sLast": "Últim"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Provádím...",
"sLengthMenu": "Zobraz záznamů _MENU_",
"sZeroRecords": "Žádné záznamy nebyly nalezeny",
"sInfo": "Zobrazuji _START_ až _END_ z celkem _TOTAL_ záznamů",
"sInfoEmpty": "Zobrazuji 0 až 0 z 0 záznamů",
"sInfoFiltered": "(filtrováno z celkem _MAX_ záznamů)",
"sInfoPostFix": "",
"sSearch": "Hledat:",
"sUrl": "",
"oPaginate": {
"sFirst": "První",
"sPrevious": "Předchozí",
"sNext": "Další",
"sLast": "Poslední"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Henter...",
"sLengthMenu": "Vis: _MENU_ linjer",
"sZeroRecords": "Ingen linjer matcher søgningen",
"sInfo": "Viser _START_ til _END_ af _TOTAL_ linjer",
"sInfoEmpty": "Viser 0 til 0 af 0 linjer",
"sInfoFiltered": "(filtreret fra _MAX_ linjer)",
"sInfoPostFix": "",
"sSearch": "Søg:",
"sUrl": "",
"oPaginate": {
"sFirst": "Første",
"sPrevious": "Forrige",
"sNext": "Næste",
"sLast": "Sidste"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Bitte warten...",
"sLengthMenu": "_MENU_ Einträge anzeigen",
"sZeroRecords": "Keine Einträge vorhanden.",
"sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen",
"sInfoEmpty": "0 bis 0 von 0 Einträgen",
"sInfoFiltered": "(gefiltert von _MAX_ Einträgen)",
"sInfoPostFix": "",
"sSearch": "Suchen",
"sUrl": "",
"oPaginate": {
"sFirst": "Erster",
"sPrevious": "Zurück",
"sNext": "Nächster",
"sLast": "Letzter"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Επεξεργασία...",
"sLengthMenu": "Δείξε _MENU_ εγγραφές",
"sZeroRecords": "Δεν βρέθηκαν εγγραφές που να ταιριάζουν",
"sInfo": "Δείχνοντας _START_ εως _END_ από _TOTAL_ εγγραφές",
"sInfoEmpty": "Δείχνοντας 0 εως 0 από 0 εγγραφές",
"sInfoFiltered": "(φιλτραρισμένες από _MAX_ συνολικά εγγραφές)",
"sInfoPostFix": "",
"sSearch": "Αναζήτηση:",
"sUrl": "",
"oPaginate": {
"sFirst": "Πρώτη",
"sPrevious": "Προηγούμενη",
"sNext": "Επόμενη",
"sLast": "Τελευταία"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Procesando...",
"sLengthMenu": "Mostrar _MENU_ registros",
"sZeroRecords": "No se encontraron resultados",
"sInfo": "Mostrando desde _START_ hasta _END_ de _TOTAL_ registros",
"sInfoEmpty": "Mostrando desde 0 hasta 0 de 0 registros",
"sInfoFiltered": "(filtrado de _MAX_ registros en total)",
"sInfoPostFix": "",
"sSearch": "Buscar:",
"sUrl": "",
"oPaginate": {
"sFirst": "Primero",
"sPrevious": "Anterior",
"sNext": "Siguiente",
"sLast": "Último"
}
}

View File

@ -0,0 +1,16 @@
{
"sProcessing": "Palun oodake, koostan kuvamiseks nimekirja!",
"sLengthMenu": "Näita kirjeid _MENU_ kaupa",
"sZeroRecords": "Otsitavat vastet ei leitud.",
"sInfo": "Kuvatud: _TOTAL_ kirjet (_START_-_END_)",
"sInfoEmpty": "Otsinguvasteid ei leitud",
"sInfoFiltered": " - filteeritud _MAX_ kirje seast.",
"sInfoPostFix": "Kõik kuvatud kirjed põhinevad reaalsetel tulemustel.",
"sSearch": "Otsi kõikide tulemuste seast:",
"oPaginate": {
"sFirst": "Algus",
"sPrevious": "Eelmine",
"sNext": "Järgmine",
"sLast": "Viimane"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "درحال پردازش...",
"sLengthMenu": "نمایش محتویات _MENU_",
"sZeroRecords": "موردی یافت نشد",
"sInfo": "نمایش _START_ تا _END_ از مجموع _TOTAL_ مورد",
"sInfoEmpty": "تهی",
"sInfoFiltered": "(فیلتر شده از مجموع _MAX_ مورد)",
"sInfoPostFix": "",
"sSearch": "جستجو:",
"sUrl": "",
"oPaginate": {
"sFirst": "ابتدا",
"sPrevious": "قبلی",
"sNext": "بعدی",
"sLast": "انتها"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Hetkinen...",
"sLengthMenu": "Näytä kerralla _MENU_ riviä",
"sZeroRecords": "Tietoja ei löytynyt",
"sInfo": "Näytetään rivit _START_ - _END_ (yhteensä _TOTAL_ )",
"sInfoEmpty": "Näytetään 0 - 0 (yhteensä 0)",
"sInfoFiltered": "(suodatettu _MAX_ tuloksen joukosta)",
"sInfoPostFix": "",
"sSearch": "Etsi:",
"sUrl": "",
"oPaginate": {
"sFirst": "Ensimmäinen",
"sPrevious": "Edellinen",
"sNext": "Seuraava",
"sLast": "Viimeinen"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Traitement en cours...",
"sLengthMenu": "Afficher _MENU_ éléments",
"sZeroRecords": "Aucun élément à afficher",
"sInfo": "Affichage de l'élement _START_ à _END_ sur _TOTAL_ éléments",
"sInfoEmpty": "Affichage de l'élement 0 à 0 sur 0 éléments",
"sInfoFiltered": "(filtré de _MAX_ éléments au total)",
"sInfoPostFix": "",
"sSearch": "Rechercher :",
"sUrl": "",
"oPaginate": {
"sFirst": "Premier",
"sPrevious": "Précédent",
"sNext": "Suivant",
"sLast": "Dernier"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "מעבד...",
"sLengthMenu": "הצג _MENU_ פריטים",
"sZeroRecords": "לא נמצאו רשומות מתאימות",
"sInfo": "_START_ עד _END_ מתוך _TOTAL_ רשומות" ,
"sInfoEmpty": "0 עד 0 מתוך 0 רשומות",
"sInfoFiltered": "(מסונן מסך _MAX_ רשומות)",
"sInfoPostFix": "",
"sSearch": "חפש:",
"sUrl": "",
"oPaginate": {
"sFirst": "ראשון",
"sPrevious": "קודם",
"sNext": "הבא",
"sLast": "אחרון"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "प्रगति पे हैं ...",
"sLengthMenu": " _MENU_ प्रविष्टियां दिखाएं ",
"sZeroRecords": "रिकॉर्ड्स का मेल नहीं मिला",
"sInfo": "_START_ to _END_ of _TOTAL_ प्रविष्टियां दिखा रहे हैं",
"sInfoEmpty": "0 में से 0 से 0 प्रविष्टियां दिखा रहे हैं",
"sInfoFiltered": "(_MAX_ कुल प्रविष्टियों में से छठा हुआ)",
"sInfoPostFix": "",
"sSearch": "खोजें:",
"sUrl": "",
"oPaginate": {
"sFirst": "प्रथम",
"sPrevious": "पिछला",
"sNext": "अगला",
"sLast": "अंतिम"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Procesiram...",
"sLengthMenu": "Prikaži _MENU_ rezultata po stranici",
"sZeroRecords": "Ništa nije pronađeno",
"sInfo": "Prikazano _START_ do _END_ od _TOTAL_ rezultata",
"sInfoEmtpy": "Prikazano 0 do 0 od 0 rezultata",
"sInfoFiltered": "(filtrirano iz _MAX_ ukupnih rezultata)",
"sInfoPostFix": "",
"sSearch": "Filter",
"sUrl": "",
"oPaginate": {
"sFirst": "Prva",
"sPrevious": "Nazad",
"sNext": "Naprijed",
"sLast": "Zadnja"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Feldolgozás...",
"sLengthMenu": "_MENU_ találat oldalanként",
"sZeroRecords": "Nincs a keresésnek megfelelő találat",
"sInfo": "Találatok: _START_ - _END_ Összesen: _TOTAL_",
"sInfoEmpty": "Nulla találat",
"sInfoFiltered": "(_MAX_ összes rekord közül szűrve)",
"sInfoPostFix": "",
"sSearch": "Keresés:",
"sUrl": "",
"oPaginate": {
"sFirst": "Első",
"sPrevious": "Előző",
"sNext": "Következő",
"sLast": "Utolsó"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Sedang memproses...",
"sLengthMenu": "Tampilkan _MENU_ entri",
"sZeroRecords": "Tidak ditemukan data yang sesuai",
"sInfo": "Menampilkan _START_ sampai _END_ dari _TOTAL_ entri",
"sInfoEmpty": "Menampilkan 0 sampai 0 dari 0 entri",
"sInfoFiltered": "(disaring dari _MAX_ entri keseluruhan)",
"sInfoPostFix": "",
"sSearch": "Cari:",
"sUrl": "",
"oPaginate": {
"sFirst": "Pertama",
"sPrevious": "Sebelumnya",
"sNext": "Selanjutnya",
"sLast": "Terakhir"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Caricamento...",
"sLengthMenu": "Visualizza _MENU_ elementi",
"sZeroRecords": "La ricerca non ha portato alcun risultato.",
"sInfo": "Vista da _START_ a _END_ di _TOTAL_ elementi",
"sInfoEmpty": "Vista da 0 a 0 di 0 elementi",
"sInfoFiltered": "(filtrati da _MAX_ elementi totali)",
"sInfoPostFix": "",
"sSearch": "Cerca:",
"sUrl": "",
"oPaginate": {
"sFirst": "Inizio",
"sPrevious": "Precedente",
"sNext": "Successivo",
"sLast": "Fine"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "მიმდინარეობს დამუშავება...",
"sLengthMenu": "აჩვენე _MENU_ ჩანაწერი",
"sZeroRecords": "არაფერი მოიძებნა",
"sInfo": "ნაჩვენებია ჩანაწერები _START_დან _END_მდე, სულ _TOTAL_ ჩანაწერია",
"sInfoEmpty": "ნაჩვენებია ჩანაწერები 0დან 0მდე, სულ 0 ჩანაწერია",
"sInfoFiltered": "(გაფილტრული შედეგი _MAX_ ჩანაწერიდან)",
"sInfoPostFix": "",
"sSearch": "ძიება:",
"sUrl": "",
"oPaginate": {
"sFirst": "პირველი",
"sPrevious": "წინა",
"sNext": "შემდეგი",
"sLast": "ბოლო"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Apdorojama...",
"sLengthMenu": "Rodyti _MENU_ įrašus",
"sZeroRecords": "Įrašų nerasta",
"sInfo": "Rodomi įrašai nuo _START_ iki _END_ iš _TOTAL_ įrašų",
"sInfoEmpty": "Rodomi įrašai nuo 0 iki 0 iš 0",
"sInfoFiltered": "(atrinkta iš _MAX_ įrašų)",
"sInfoPostFix": "",
"sSearch": "Ieškoti:",
"sUrl": "",
"oPaginate": {
"sFirst": "Pirmas",
"sPrevious": "Ankstesnis",
"sNext": "Tolimesnis",
"sLast": "Paskutinis"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Uzgaidiet...",
"sLengthMenu": "Rādīt _MENU_ ierakstus",
"sZeroRecords": "Nav atrasti vaicājumam atbilstoši ieraksti",
"sInfo": "Parādīti _START_. līdz _END_. no _TOTAL_ ierakstiem",
"sInfoEmpty": "Nav ierakstu",
"sInfoFiltered": "(atlasīts no pavisam _MAX_ ierakstiem)",
"sInfoPostFix": "",
"sSearch": "Meklēt:",
"sUrl": "",
"oPaginate": {
"sFirst": "Pirmā",
"sPrevious": "Iepriekšējā",
"sNext": "Nākošā",
"sLast": "Pēdējā"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Laster...",
"sLengthMenu": "Vis: _MENU_ linjer",
"sZeroRecords": "Ingen linjer matcher søket",
"sInfo": "Viser _START_ til _END_ av _TOTAL_ linjer",
"sInfoEmpty": "Viser 0 til 0 av 0 linjer",
"sInfoFiltered": "(filtrert fra _MAX_ totalt antall linjer)",
"sInfoPostFix": "",
"sSearch": "Søk:",
"sUrl": "",
"oPaginate": {
"sFirst": "Første",
"sPrevious": "Forrige",
"sNext": "Neste",
"sLast": "Siste"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Bezig met verwerken...",
"sLengthMenu": "Toon _MENU_ rijen",
"sZeroRecords": "Geen resultaten gevonden",
"sInfo": "_START_ tot _END_ van _TOTAL_ rijen",
"sInfoEmpty": "Er zijn geen records om te tonen",
"sInfoFiltered": "(gefilterd uit _MAX_ rijen)",
"sInfoPostFix": "",
"sSearch": "Zoek:",
"sUrl": "",
"oPaginate": {
"sFirst": "Eerste",
"sPrevious": "Vorige",
"sNext": "Volgende",
"sLast": "Laatste"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Proszę czekać...",
"sLengthMenu": "Pokaż _MENU_ pozycji",
"sZeroRecords": "Nie znaleziono żadnych pasujących indeksów",
"sInfo": "Pozycje od _START_ do _END_ z _TOTAL_ łącznie",
"sInfoEmpty": "Pozycji 0 z 0 dostępnych",
"sInfoFiltered": "(filtrowanie spośród _MAX_ dostępnych pozycji)",
"sInfoPostFix": "",
"sSearch": "Szukaj:",
"sUrl": "",
"oPaginate": {
"sFirst": "Pierwsza",
"sPrevious": "Poprzednia",
"sNext": "Następna",
"sLast": "Ostatnia"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "A processar...",
"sLengthMenu": "Mostrar _MENU_ registos",
"sZeroRecords": "Não foram encontrados resultados",
"sInfo": "Mostrando de _START_ até _END_ de _TOTAL_ registos",
"sInfoEmpty": "Mostrando de 0 até 0 de 0 registros",
"sInfoFiltered": "(filtrado de _MAX_ registos no total)",
"sInfoPostFix": "",
"sSearch": "Procurar:",
"sUrl": "",
"oPaginate": {
"sFirst": "Primeiro",
"sPrevious": "Anterior",
"sNext": "Seguinte",
"sLast": "Último"
}
}

View File

@ -0,0 +1,17 @@
{
"sProcessing": "Processando...",
"sLengthMenu": "Mostrar _MENU_ registros",
"sZeroRecords": "Não foram encontrados resultados",
"sInfo": "Mostrando de _START_ até _END_ de _TOTAL_ registros",
"sInfoEmpty": "Mostrando de 0 até 0 de 0 registros",
"sInfoFiltered": "(filtrado de _MAX_ registros no total)",
"sInfoPostFix": "",
"sSearch": "Buscar:",
"sUrl": "",
"oPaginate": {
"sFirst": "Primeiro",
"sPrevious": "Anterior",
"sNext": "Seguinte",
"sLast": "Último"
}
}

Some files were not shown because too many files have changed in this diff Show More