diff --git a/src/wp-content/plugins/configure-smtp/c2c-plugin.php b/src/wp-content/plugins/configure-smtp/c2c-plugin.php new file mode 100644 index 00000000..16e5fdd4 --- /dev/null +++ b/src/wp-content/plugins/configure-smtp/c2c-plugin.php @@ -0,0 +1,770 @@ +> 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
+ '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&plugin={$this->id_base}&TB_iframe=true&width=640&height=656" ); + + echo '

'; + echo '' . __( 'Click for more help on this plugin', $this->textdomain ) . '' . + __( ' (especially check out the "Other Notes" tab, if present)', $this->textdomain ); + echo ".

\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 << + .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;} + + +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 = '' . __( 'Settings', $this->textdomain ) . ''; + 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 + * + * @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 '
 
' . "\n"; + } elseif ( $input == 'textarea' || $input == 'inline_textarea' ) { + if ( $input == 'textarea' ) + echo ""; + echo "\n"; + } elseif ( $input == 'select' ) { + echo ""; + } elseif ( $input == 'multiselect' ) { + echo '
' . "\n"; + foreach ( (array) $this->config[$opt]['options'] as $sopt ) + echo "$sopt
\n"; + echo '
'; + } elseif ( $input == 'checkbox' ) { + echo "\n"; + } else { // Only 'text' and 'password' should fall through to here. + echo "\n"; + } + if ( $help = apply_filters( $this->get_hook( 'option_help'), $this->config[$opt]['help'], $opt ) ) + echo "
$help\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 '

' . $localized_heading_text . "

\n"; + if ( !$this->disable_contextual_help ) + echo '

' . __( 'See the "Help" link to the top-right of the page for more help.', $this->textdomain ) . "

\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 "

" . $this->saved_settings_msg . '

'; + + $logo = plugins_url( basename( $_GET['page'], '.php' ) . '/c2c_minilogo.png' ); + + echo "
\n"; + echo "
" . esc_attr__( textdomain ) . "' />
\n"; + + $this->options_page_description(); + + do_action( $this->get_hook( 'before_settings_form' ), $this ); + + echo "\n"; + + settings_fields( $this->admin_options_name ); + do_settings_sections( $this->plugin_file ); + + echo '' . "\n"; + echo '' . "\n"; + echo '' . "\n"; + + do_action( $this->get_hook( 'after_settings_form' ), $this ); + + echo '
' . "\n"; + $c2c = '' . __( 'Scott Reilly, aka coffee2code', $this->textdomain ) . ''; + echo sprintf( __( 'This plugin brought to you by %s.', $this->textdomain ), $c2c ); + echo '' . + __( 'Did you find this plugin useful?', $this->textdomain ) . ''; + echo '
' . "\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() + +?> \ No newline at end of file diff --git a/src/wp-content/plugins/configure-smtp/c2c_minilogo.png b/src/wp-content/plugins/configure-smtp/c2c_minilogo.png new file mode 100644 index 00000000..0b58433d Binary files /dev/null and b/src/wp-content/plugins/configure-smtp/c2c_minilogo.png differ diff --git a/src/wp-content/plugins/configure-smtp/configure-smtp.php b/src/wp-content/plugins/configure-smtp/configure-smtp.php new file mode 100644 index 00000000..543b26d6 --- /dev/null +++ b/src/wp-content/plugins/configure-smtp/configure-smtp.php @@ -0,0 +1,289 @@ +> 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 = '' . __( 'test', $this->textdomain ) . ''; + if ( empty( $options['host'] ) ) + echo '

' . __( 'SMTP mailing is currently NOT ENABLED because no SMTP host has been specified.' ) . '

'; + echo '

' . sprintf( __( 'After you have configured your SMTP settings, use the %s to send a test message to yourself.', $this->textdomain ), $str ) . '

'; + } + + /** + * 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 << + 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; + } + } + + +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 '

' . __( 'An error was encountered while trying to send the test e-mail.' ) . '

'; + echo '
'; + echo '

' . $phpmailer->ErrorInfo . '

'; + echo '

' . $phpmailer->smtp->error['error'] . '
' . $phpmailer->smtp->error['errstr'] . '

'; + echo '
'; + echo '
'; + } else { + echo '

' . __( 'Test e-mail sent.', $this->textdomain ) . '

'; + echo '

' . sprintf( __( 'The body of the e-mail includes this time-stamp: %s.', $this->textdomain ), $timestamp ) . '

'; + } + } + } + + /* + * 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 '

' . __( 'Send A Test', $this->textdomain ) . "

\n"; + echo '

' . __( '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 ) . "

\n"; + echo '

' . sprintf( __( 'This e-mail will be sent to your e-mail address, %s.', $this->textdomain ), $email ) . "

\n"; + echo '

You must save any changes to the form above before attempting to send a test e-mail.

'; + echo "
\n"; + wp_nonce_field( $this->nonce_field ); + echo ''; + echo '
'; + echo '
'; + } + + /** + * 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() + +?> \ No newline at end of file diff --git a/src/wp-content/plugins/configure-smtp/configure-smtp.pot b/src/wp-content/plugins/configure-smtp/configure-smtp.pot new file mode 100644 index 00000000..cd95d13f --- /dev/null +++ b/src/wp-content/plugins/configure-smtp/configure-smtp.pot @@ -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 , 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 \n" +"Language-Team: LANGUAGE \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 NOT ENABLED 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 "" diff --git a/src/wp-content/plugins/configure-smtp/readme.txt b/src/wp-content/plugins/configure-smtp/readme.txt new file mode 100644 index 00000000..7aa0a8ed --- /dev/null +++ b/src/wp-content/plugins/configure-smtp/readme.txt @@ -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. \ No newline at end of file diff --git a/src/wp-content/plugins/configure-smtp/screenshot-1.png b/src/wp-content/plugins/configure-smtp/screenshot-1.png new file mode 100644 index 00000000..f55af3bb Binary files /dev/null and b/src/wp-content/plugins/configure-smtp/screenshot-1.png differ diff --git a/src/wp-content/plugins/contact-form-7-dynamic-text-extension/readme.txt b/src/wp-content/plugins/contact-form-7-dynamic-text-extension/readme.txt new file mode 100644 index 00000000..9337fe13 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-dynamic-text-extension/readme.txt @@ -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. diff --git a/src/wp-content/plugins/contact-form-7-dynamic-text-extension/screenshot-1.jpg b/src/wp-content/plugins/contact-form-7-dynamic-text-extension/screenshot-1.jpg new file mode 100644 index 00000000..9915ea2d Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-dynamic-text-extension/screenshot-1.jpg differ diff --git a/src/wp-content/plugins/contact-form-7-dynamic-text-extension/wpcf7_dynamic_text.php b/src/wp-content/plugins/contact-form-7-dynamic-text-extension/wpcf7_dynamic_text.php new file mode 100644 index 00000000..32ba605a --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-dynamic-text-extension/wpcf7_dynamic_text.php @@ -0,0 +1,492 @@ +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 '
'; print_r($options);echo '
'; + $readonly = ''; + if(in_array('uneditable', $options)){ + $readonly = 'readonly="readonly"'; + } + + $html = ''; + + $validation_error = ''; + if ( is_a( $wpcf7_contact_form, 'WPCF7_ContactForm' ) ) + $validation_error = $wpcf7_contact_form->validation_error( $name ); + + $html = '' . $html . $validation_error . ''; + + 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' ) { +?> + +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 '
'; print_r($options);echo '
'; + + $html = ''; + + //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 = '' . $html . $validation_error . ''; + + 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' ) { +?> + + 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 '
'; print_r($post); echo '
'; + $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 = ''; + 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');*/ + diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBEvalutator.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBEvalutator.php new file mode 100644 index 00000000..313db919 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBEvalutator.php @@ -0,0 +1,31 @@ +. +*/ + +interface CF7DBEvalutator { + + /** + * Evaluate expression against input data + * @param $data array [ key => value] + * @return boolean result of evaluating $data against expression + */ + public function evaluate(&$data); + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBInstallIndicator.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBInstallIndicator.php new file mode 100644 index 00000000..dd22173b --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBInstallIndicator.php @@ -0,0 +1,189 @@ +. +*/ +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()); + } + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBOptionsManager.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBOptionsManager.php new file mode 100644 index 00000000..4c790a29 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBOptionsManager.php @@ -0,0 +1,405 @@ +. +*/ + +/** + * 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'; + ?> +
+

+ + + + +
getMySqlVersion() ?>
+ +

getPluginDisplayName(); echo ' '; _e('Settings', 'contact-form-7-to-database-extension'); ?>

+ +
+ + + $aOptionMeta) { + $displayText = is_array($aOptionMeta) ? $aOptionMeta[0] : $aOptionMeta; + $displayText = __($displayText, 'contact-form-7-to-database-extension'); + ?> + + + + + +

+ createFormControl($aOptionKey, $aOptionMeta, $this->getOption($aOptionKey)); ?> +
+

+ +

+ +
+
+ = 2) { // Drop-down list + $choices = array_slice($aOptionMeta, 1); + ?> +

+ +

+ get_results('select version() as mysqlversion'); + if (!empty($rows)) { + return $rows[0]->mysqlversion; + } + return false; + } +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin.php new file mode 100644 index 00000000..ebfd0e66 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin.php @@ -0,0 +1,674 @@ +. +*/ + +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('' . __('Date-Time Display Format', 'contact-form-7-to-database-extension') . ''), + 'ShowFileUrlsInExport' => array(__('Export URLs instead of file names for uploaded files', 'contact-form-7-to-database-extension'), 'false', 'true'), + 'NoSaveFields' => array(__('Do not save fields in DB named (comma-separated list, no spaces)', 'contact-form-7-to-database-extension')), + 'NoSaveForms' => array(__('Do not save forms 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 ' +

+ ' . $displayName . + ' | ' . + __('Database', 'contact-form-7-to-database-extension') . + ' | ' . + __('Database Options', 'contact-form-7-to-database-extension') . + ' | ' . + __('Build Short Code', 'contact-form-7-to-database-extension') . + ' | ' . + __('FAQ', 'contact-form-7-to-database-extension') . ' +

+ '; + } + + /** + * 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; + } + + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPluginExporter.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPluginExporter.php new file mode 100644 index 00000000..9485074e --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPluginExporter.php @@ -0,0 +1,146 @@ +. +*/ + +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; + } + } +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPluginLifeCycle.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPluginLifeCycle.php new file mode 100644 index 00000000..800d2fe1 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPluginLifeCycle.php @@ -0,0 +1,140 @@ +. +*/ + +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); + } + + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin_init.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin_init.php new file mode 100644 index 00000000..d24ed5a3 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin_init.php @@ -0,0 +1,53 @@ +. +*/ + +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')); +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBValueConverter.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBValueConverter.php new file mode 100644 index 00000000..7fc07c7b --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7DBValueConverter.php @@ -0,0 +1,30 @@ +. +*/ + +interface CF7DBValueConverter { + + /** + * @abstract + * @param $value mixed object to convert + * @return mixed converted value + */ + public function convert($value); +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7FilterParser.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7FilterParser.php new file mode 100644 index 00000000..ec3baebe --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7FilterParser.php @@ -0,0 +1,277 @@ +. +*/ + +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 '&&' rather than '&&' + // (But oddly, this is not always the case). So check for this case explicitly. + $retVal = preg_split('/&&/', $filterString, -1, PREG_SPLIT_NO_EMPTY); + } + + //echo "
Parsed '$filterString' into " . print_r($retVal, true) . '
'; + 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; + } + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CF7SearchEvaluator.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7SearchEvaluator.php new file mode 100644 index 00000000..6c44cce8 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CF7SearchEvaluator.php @@ -0,0 +1,50 @@ +. +*/ + +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; + } + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBDie.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBDie.php new file mode 100644 index 00000000..e13c8a79 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBDie.php @@ -0,0 +1,46 @@ +. +*/ + +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 ); + } +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBExport.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBExport.php new file mode 100644 index 00000000..ca01f37a --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBExport.php @@ -0,0 +1,32 @@ +. +*/ + +interface CFDBExport { + + /** + * @abstract + * @param $formName string + * @param $options array of option_name => option_value + * @return void + */ + public function export($formName, $options = null); + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php new file mode 100644 index 00000000..a0793315 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php @@ -0,0 +1,71 @@ +. +*/ + +/** + * 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: + * + * // 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?'); + * } + * + * + */ +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; + } + } +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBQueryResultIterator.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBQueryResultIterator.php new file mode 100644 index 00000000..18e15151 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBQueryResultIterator.php @@ -0,0 +1,192 @@ +. +*/ + +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; + } + + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeCount.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeCount.php new file mode 100644 index 00000000..affa10e1 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeCount.php @@ -0,0 +1,32 @@ +. +*/ + +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); + } +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeDataTable.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeDataTable.php new file mode 100644 index 00000000..ec748c9d --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeDataTable.php @@ -0,0 +1,54 @@ +. +*/ + +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'); + } + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeExportUrl.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeExportUrl.php new file mode 100644 index 00000000..890224ff --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeExportUrl.php @@ -0,0 +1,69 @@ +. +*/ + +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('%s', $url, $linkText); + } +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeHtml.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeHtml.php new file mode 100644 index 00000000..02c2a34c --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeHtml.php @@ -0,0 +1,41 @@ +. +*/ + +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); + } + } + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeJson.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeJson.php new file mode 100644 index 00000000..b9f643e9 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeJson.php @@ -0,0 +1,37 @@ +. +*/ + +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); + } +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeTable.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeTable.php new file mode 100644 index 00000000..f063969f --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeTable.php @@ -0,0 +1,55 @@ +. +*/ + +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 (default: class="cf7-db-table") + * [cfdb-table form="your-form" id="css_id"] (outputs
(no default id) + * [cfdb-table form="your-form" id="css_id" class="css_class"] (outputs
+ * 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); + } + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeValue.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeValue.php new file mode 100644 index 00000000..36ab54e1 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBShortcodeValue.php @@ -0,0 +1,37 @@ +. +*/ + +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); + } + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBView.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBView.php new file mode 100644 index 00000000..d861688c --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CFDBView.php @@ -0,0 +1,90 @@ +. +*/ + +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')) { + ?> + + +
+ + + + + + + + + +
+ + Donate + + + + + + + + + + + + + + + + + +
+ . +*/ + +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 + ?> + + + +
+
+
+ +
+ +
+ +

Short Code Builder

+
+ +
+ +
+ +
+ +
+ + + +
+
+ +
+
+ +
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+ + + + + + +
+
+
+
+
+ Num Rows + Start Row (0) +
+
+
+ + + +
+
+
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+ +
+
+ + . +*/ + +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 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(); + + ?> + + + + + + +
+
+ + +
+
+ + +
+ + +
+ +
+ +
+ + + +
+ +
+ + + getDataTableTranslationUrl(); + ?> + + +
+ + + + getDBRowCount($currSelection); + $maxRows = $plugin->getOption('MaxRows', '100'); + $startRow = $this->paginationDiv($plugin, $dbRowCount, $maxRows, $page); + ?> +
> + div { max-height: 100px; overflow: auto; font-size: small; }"; // don't let cells get too tall + } + $exporter->export($currSelection, $options); + ?> +
+ +
+ +
+ + + + + + + + + + + + +
+ + + Contact Form + 7 + Fast Secure + Contact Form + +
+ + +
+ [cfdb-html] + [cfdb-datatable] + [cfdb-table] + [cfdb-value] + [cfdb-count] + [cfdb-json] +
+
+ + + + +
+
+ getOption('ShowQuery')) { + ?> +
+
+
getPivotQuery($currSelection); ?>
+
+ + + getPluginFileUrl(); + echo '/css/paginate.css'; + echo '" type="text/css"/>'; + // echo ''; + + + if (!$page || $page < 1) $page = 1; //default to 1. + $startRow = $rowsPerPage * ($page - 1) + 1; + + + $endRow = min($startRow + $rowsPerPage - 1, $totalRows); + echo ''; + printf(__('Returned entries %s to %s of %s entries in the database', 'contact-form-7-to-database-extension'), + $startRow, $endRow, $totalRows); + echo ''; + echo '
'; + + $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 "
"; + //previous button + if ($page > 1) + echo $this->paginateLink($prev, $prevLabel); + else + echo "$prevLabel"; + + if ($lastpage < 7 + ($adjacents * 2)) //not enough pages to bother breaking it up + { + for ($counter = 1; $counter <= $lastpage; $counter++) + { + if ($counter == $page) + echo "$counter"; + 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 "$counter"; + 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 "$counter"; + 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 "$counter"; + else + echo $this->paginateLink($counter, $counter); + } + } + } + + //next button + if ($page < $counter - 1) + echo $this->paginateLink($next, $nextLabel); + else + echo "$nextLabel"; + echo "
\n"; + } + + echo '
'; + return $startRow; + } + + protected function paginateLink($page, $label) { + return "$label"; + } + +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/CJ7DBCheckZendFramework.php b/src/wp-content/plugins/contact-form-7-to-database-extension/CJ7DBCheckZendFramework.php new file mode 100644 index 00000000..ace1c258 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/CJ7DBCheckZendFramework.php @@ -0,0 +1,100 @@ +. +*/ + +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(); + ?> +

Missing Zend Framework

+

+ This function requires part of the Zend framework that interacts with Google.
+ It appears that either: +

+
    +
  1. The Zend Framework is not on the include_path or
  2. +
  3. You do not have the Zend Framework installed
  4. +
+

+ include_path=""
+ php.ini file is + " + "
+

+
    +
  1. locate the the Zend directory on your computer
  2. +
  3. If found, here is one way to put it on the include path
  4. +
      +
    1. copy the php.ini file to your WordPress installation to + [wp-dir]/wp-content/plugins/contact-form-7-to-database-extension/php.ini +
    2. +
    3. add a line to this new file:
      + include_path="" +
    4. +
    +
  5. If not found, install and configure Zend (or contact or administrator or host provider)
    + See: Getting + Started + with the Google Data PHP Client Library
    + To download the part of Zend required, see: Zend + GData +
  6. +
+ 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('#(?:

(?:)?(.*?)(?:)?

)|(?:(.*?)\s*(?:(.*?)\s*(?:(.*?)\s*)?)?)#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']; + } +} \ No newline at end of file diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/Cf7ToDBGGoogleSS.js b/src/wp-content/plugins/contact-form-7-to-database-extension/Cf7ToDBGGoogleSS.js new file mode 100644 index 00000000..8217c228 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/Cf7ToDBGGoogleSS.js @@ -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 . + */ + +/* 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 ); +} + diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/Cf7ToDBGGoogleSS.js.php b/src/wp-content/plugins/contact-form-7-to-database-extension/Cf7ToDBGGoogleSS.js.php new file mode 100644 index 00000000..18e9f778 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/Cf7ToDBGGoogleSS.js.php @@ -0,0 +1,25 @@ +. +*/ + + header("Content-Type: text/plain"); + readfile('Cf7ToDBGGoogleSS.js'); +?> + diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/Readme.txt b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/Readme.txt new file mode 100644 index 00000000..28a1e645 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/Readme.txt @@ -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 \ No newline at end of file diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/license-bsd.txt b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/license-bsd.txt new file mode 100644 index 00000000..cdb85aaa --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/license-bsd.txt @@ -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. \ No newline at end of file diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/license-gpl2.txt b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/license-gpl2.txt new file mode 100644 index 00000000..d511905c --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/license-gpl2.txt @@ -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. + + + Copyright (C) + + 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. + + , 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. diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_page.css b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_page.css new file mode 100644 index 00000000..bee7b0d9 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_page.css @@ -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; +} \ No newline at end of file diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_table.css b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_table.css new file mode 100644 index 00000000..3bc04337 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_table.css @@ -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; +} diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_table_jui.css b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_table_jui.css new file mode 100644 index 00000000..84268caa --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/css/demo_table_jui.css @@ -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; +} \ No newline at end of file diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/Sorting icons.psd b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/Sorting icons.psd new file mode 100644 index 00000000..53b2e068 Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/Sorting icons.psd differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/back_disabled.jpg b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/back_disabled.jpg new file mode 100644 index 00000000..1e73a546 Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/back_disabled.jpg differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/back_enabled.jpg b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/back_enabled.jpg new file mode 100644 index 00000000..a6d764c7 Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/back_enabled.jpg differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/favicon.ico b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/favicon.ico new file mode 100644 index 00000000..6eeaa2a0 Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/favicon.ico differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/forward_disabled.jpg b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/forward_disabled.jpg new file mode 100644 index 00000000..28a9dc53 Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/forward_disabled.jpg differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/forward_enabled.jpg b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/forward_enabled.jpg new file mode 100644 index 00000000..598c075f Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/forward_enabled.jpg differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_asc.png b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_asc.png new file mode 100644 index 00000000..a56d0e21 Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_asc.png differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_asc_disabled.png b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_asc_disabled.png new file mode 100644 index 00000000..b7e621ef Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_asc_disabled.png differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_both.png b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_both.png new file mode 100644 index 00000000..839ac4bb Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_both.png differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_desc.png b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_desc.png new file mode 100644 index 00000000..90b29515 Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_desc.png differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_desc_disabled.png b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_desc_disabled.png new file mode 100644 index 00000000..2409653d Binary files /dev/null and b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/images/sort_desc_disabled.png differ diff --git a/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/js/jquery.dataTables.js b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/js/jquery.dataTables.js new file mode 100644 index 00000000..581222e3 --- /dev/null +++ b/src/wp-content/plugins/contact-form-7-to-database-extension/DataTables/media/js/jquery.dataTables.js @@ -0,0 +1,6862 @@ +/* + * File: jquery.dataTables.js + * Version: 1.7.6 + * Description: Paginate, search and sort HTML tables + * Author: Allan Jardine (www.sprymedia.co.uk) + * Created: 28/3/2008 + * Language: Javascript + * License: GPL v2 or BSD 3 point style + * Project: Mtaala + * Contact: allan.jardine@sprymedia.co.uk + * + * Copyright 2008-2010 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. + * + * For details please refer to: http://www.datatables.net + */ + +/* + * When considering jsLint, we need to allow eval() as it it is used for reading cookies and + * building the dynamic multi-column sort functions. + */ +/*jslint evil: true, undef: true, browser: true */ +/*globals $, jQuery,_fnExternApiFunc,_fnInitalise,_fnInitComplete,_fnLanguageProcess,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnGatherData,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxUpdateDraw,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnArrayCmp,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap*/ + +(function($, window, document) { + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Section - DataTables variables + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * Variable: dataTableSettings + * Purpose: Store the settings for each dataTables instance + * Scope: jQuery.fn + */ + $.fn.dataTableSettings = []; + var _aoSettings = $.fn.dataTableSettings; /* Short reference for fast internal lookup */ + + /* + * Variable: dataTableExt + * Purpose: Container for customisable parts of DataTables + * Scope: jQuery.fn + */ + $.fn.dataTableExt = {}; + var _oExt = $.fn.dataTableExt; + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Section - DataTables extensible objects + * + * The _oExt object is used to provide an area where user dfined plugins can be + * added to DataTables. The following properties of the object are used: + * oApi - Plug-in API functions + * aTypes - Auto-detection of types + * oSort - Sorting functions used by DataTables (based on the type) + * oPagination - Pagination functions for different input styles + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * Variable: sVersion + * Purpose: Version string for plug-ins to check compatibility + * Scope: jQuery.fn.dataTableExt + * Notes: Allowed format is a.b.c.d.e where: + * a:int, b:int, c:int, d:string(dev|beta), e:int. d and e are optional + */ + _oExt.sVersion = "1.7.6"; + + /* + * Variable: sErrMode + * Purpose: How should DataTables report an error. Can take the value 'alert' or 'throw' + * Scope: jQuery.fn.dataTableExt + */ + _oExt.sErrMode = "alert"; + + /* + * Variable: iApiIndex + * Purpose: Index for what 'this' index API functions should use + * Scope: jQuery.fn.dataTableExt + */ + _oExt.iApiIndex = 0; + + /* + * Variable: oApi + * Purpose: Container for plugin API functions + * Scope: jQuery.fn.dataTableExt + */ + _oExt.oApi = { }; + + /* + * Variable: aFiltering + * Purpose: Container for plugin filtering functions + * Scope: jQuery.fn.dataTableExt + */ + _oExt.afnFiltering = [ ]; + + /* + * Variable: aoFeatures + * Purpose: Container for plugin function functions + * Scope: jQuery.fn.dataTableExt + * Notes: Array of objects with the following parameters: + * fnInit: Function for initialisation of Feature. Takes oSettings and returns node + * cFeature: Character that will be matched in sDom - case sensitive + * sFeature: Feature name - just for completeness :-) + */ + _oExt.aoFeatures = [ ]; + + /* + * Variable: ofnSearch + * Purpose: Container for custom filtering functions + * Scope: jQuery.fn.dataTableExt + * Notes: This is an object (the name should match the type) for custom filtering function, + * which can be used for live DOM checking or formatted text filtering + */ + _oExt.ofnSearch = { }; + + /* + * Variable: afnSortData + * Purpose: Container for custom sorting data source functions + * Scope: jQuery.fn.dataTableExt + * Notes: Array (associative) of functions which is run prior to a column of this + * 'SortDataType' being sorted upon. + * Function input parameters: + * object:oSettings- DataTables settings object + * int:iColumn - Target column number + * Return value: Array of data which exactly matched the full data set size for the column to + * be sorted upon + */ + _oExt.afnSortData = [ ]; + + /* + * Variable: oStdClasses + * Purpose: Storage for the various classes that DataTables uses + * Scope: jQuery.fn.dataTableExt + */ + _oExt.oStdClasses = { + /* Two buttons buttons */ + "sPagePrevEnabled": "paginate_enabled_previous", + "sPagePrevDisabled": "paginate_disabled_previous", + "sPageNextEnabled": "paginate_enabled_next", + "sPageNextDisabled": "paginate_disabled_next", + "sPageJUINext": "", + "sPageJUIPrev": "", + + /* Full numbers paging buttons */ + "sPageButton": "paginate_button", + "sPageButtonActive": "paginate_active", + "sPageButtonStaticDisabled": "paginate_button", + "sPageFirst": "first", + "sPagePrevious": "previous", + "sPageNext": "next", + "sPageLast": "last", + + /* Stripping classes */ + "sStripOdd": "odd", + "sStripEven": "even", + + /* Empty row */ + "sRowEmpty": "dataTables_empty", + + /* Features */ + "sWrapper": "dataTables_wrapper", + "sFilter": "dataTables_filter", + "sInfo": "dataTables_info", + "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */ + "sLength": "dataTables_length", + "sProcessing": "dataTables_processing", + + /* Sorting */ + "sSortAsc": "sorting_asc", + "sSortDesc": "sorting_desc", + "sSortable": "sorting", /* Sortable in both directions */ + "sSortableAsc": "sorting_asc_disabled", + "sSortableDesc": "sorting_desc_disabled", + "sSortableNone": "sorting_disabled", + "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */ + "sSortJUIAsc": "", + "sSortJUIDesc": "", + "sSortJUI": "", + "sSortJUIAscAllowed": "", + "sSortJUIDescAllowed": "", + "sSortJUIWrapper": "", + + /* Scrolling */ + "sScrollWrapper": "dataTables_scroll", + "sScrollHead": "dataTables_scrollHead", + "sScrollHeadInner": "dataTables_scrollHeadInner", + "sScrollBody": "dataTables_scrollBody", + "sScrollFoot": "dataTables_scrollFoot", + "sScrollFootInner": "dataTables_scrollFootInner", + + /* Misc */ + "sFooterTH": "" + }; + + /* + * Variable: oJUIClasses + * Purpose: Storage for the various classes that DataTables uses - jQuery UI suitable + * Scope: jQuery.fn.dataTableExt + */ + _oExt.oJUIClasses = { + /* Two buttons buttons */ + "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", + + /* Full numbers paging buttons */ + "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", + + /* Stripping classes */ + "sStripOdd": "odd", + "sStripEven": "even", + + /* Empty row */ + "sRowEmpty": "dataTables_empty", + + /* Features */ + "sWrapper": "dataTables_wrapper", + "sFilter": "dataTables_filter", + "sInfo": "dataTables_info", + "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+ + "ui-buttonset-multi paging_", /* Note that the type is postfixed */ + "sLength": "dataTables_length", + "sProcessing": "dataTables_processing", + + /* Sorting */ + "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_", /* Note that an int is postfixed for the sorting order */ + "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", + + /* Scrolling */ + "sScrollWrapper": "dataTables_scroll", + "sScrollHead": "dataTables_scrollHead ui-state-default", + "sScrollHeadInner": "dataTables_scrollHeadInner", + "sScrollBody": "dataTables_scrollBody", + "sScrollFoot": "dataTables_scrollFoot ui-state-default", + "sScrollFootInner": "dataTables_scrollFootInner", + + /* Misc */ + "sFooterTH": "ui-state-default" + }; + + /* + * Variable: oPagination + * Purpose: Container for the various type of pagination that dataTables supports + * Scope: jQuery.fn.dataTableExt + */ + _oExt.oPagination = { + /* + * Variable: two_button + * Purpose: Standard two button (forward/back) pagination + * Scope: jQuery.fn.dataTableExt.oPagination + */ + "two_button": { + /* + * Function: oPagination.two_button.fnInit + * Purpose: Initalise dom elements required for pagination with forward/back buttons only + * Returns: - + * Inputs: object:oSettings - dataTables settings object + * node:nPaging - the DIV which contains this pagination control + * function:fnCallbackDraw - draw function which must be called on update + */ + "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) + { + var nPrevious, nNext, nPreviousInner, nNextInner; + + /* Store the next and previous elements in the oSettings object as they can be very + * usful for automation - particularly testing + */ + if ( !oSettings.bJUI ) + { + nPrevious = document.createElement( 'div' ); + nNext = document.createElement( 'div' ); + } + else + { + nPrevious = document.createElement( 'a' ); + nNext = document.createElement( 'a' ); + + nNextInner = document.createElement('span'); + nNextInner.className = oSettings.oClasses.sPageJUINext; + nNext.appendChild( nNextInner ); + + nPreviousInner = document.createElement('span'); + nPreviousInner.className = oSettings.oClasses.sPageJUIPrev; + nPrevious.appendChild( nPreviousInner ); + } + + nPrevious.className = oSettings.oClasses.sPagePrevDisabled; + nNext.className = oSettings.oClasses.sPageNextDisabled; + + nPrevious.title = oSettings.oLanguage.oPaginate.sPrevious; + nNext.title = oSettings.oLanguage.oPaginate.sNext; + + nPaging.appendChild( nPrevious ); + nPaging.appendChild( nNext ); + + $(nPrevious).bind( 'click.DT', function() { + if ( oSettings.oApi._fnPageChange( oSettings, "previous" ) ) + { + /* Only draw when the page has actually changed */ + fnCallbackDraw( oSettings ); + } + } ); + + $(nNext).bind( 'click.DT', function() { + if ( oSettings.oApi._fnPageChange( oSettings, "next" ) ) + { + fnCallbackDraw( oSettings ); + } + } ); + + /* Take the brutal approach to cancelling text selection */ + $(nPrevious).bind( 'selectstart.DT', function () { return false; } ); + $(nNext).bind( 'selectstart.DT', function () { return false; } ); + + /* ID the first elements only */ + if ( oSettings.sTableId !== '' && typeof oSettings.aanFeatures.p == "undefined" ) + { + nPaging.setAttribute( 'id', oSettings.sTableId+'_paginate' ); + nPrevious.setAttribute( 'id', oSettings.sTableId+'_previous' ); + nNext.setAttribute( 'id', oSettings.sTableId+'_next' ); + } + }, + + /* + * Function: oPagination.two_button.fnUpdate + * Purpose: Update the two button pagination at the end of the draw + * Returns: - + * Inputs: object:oSettings - dataTables settings object + * function:fnCallbackDraw - draw function to call on page change + */ + "fnUpdate": function ( oSettings, fnCallbackDraw ) + { + if ( !oSettings.aanFeatures.p ) + { + return; + } + + /* Loop over each instance of the pager */ + var an = oSettings.aanFeatures.p; + for ( var i=0, iLen=an.length ; i= (iPages - iPageCountHalf)) + { + iStartButton = iPages - iPageCount + 1; + iEndButton = iPages; + } + else + { + iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1; + iEndButton = iStartButton + iPageCount - 1; + } + } + } + + /* Build the dynamic list */ + for ( i=iStartButton ; i<=iEndButton ; i++ ) + { + if ( iCurrentPage != i ) + { + sList += ''+i+''; + } + else + { + sList += ''+i+''; + } + } + + /* Loop over each instance of the pager */ + var an = oSettings.aanFeatures.p; + var anButtons, anStatic, nPaginateList; + var fnClick = function() { + /* Use the information in the element to jump to the required page */ + var iTarget = (this.innerHTML * 1) - 1; + oSettings._iDisplayStart = iTarget * oSettings._iDisplayLength; + fnCallbackDraw( oSettings ); + return false; + }; + var fnFalse = function () { return false; }; + + for ( i=0, iLen=an.length ; i y) ? 1 : 0)); + }, + + "string-desc": function ( a, b ) + { + var x = a.toLowerCase(); + var y = b.toLowerCase(); + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }, + + + /* + * html sorting (ignore html tags) + */ + "html-asc": function ( a, b ) + { + var x = a.replace( /<.*?>/g, "" ).toLowerCase(); + var y = b.replace( /<.*?>/g, "" ).toLowerCase(); + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + }, + + "html-desc": function ( a, b ) + { + var x = a.replace( /<.*?>/g, "" ).toLowerCase(); + var y = b.replace( /<.*?>/g, "" ).toLowerCase(); + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }, + + + /* + * date sorting + */ + "date-asc": function ( a, b ) + { + var x = Date.parse( a ); + var y = Date.parse( b ); + + if ( isNaN(x) || x==="" ) + { + x = Date.parse( "01/01/1970 00:00:00" ); + } + if ( isNaN(y) || y==="" ) + { + y = Date.parse( "01/01/1970 00:00:00" ); + } + + return x - y; + }, + + "date-desc": function ( a, b ) + { + var x = Date.parse( a ); + var y = Date.parse( b ); + + if ( isNaN(x) || x==="" ) + { + x = Date.parse( "01/01/1970 00:00:00" ); + } + if ( isNaN(y) || y==="" ) + { + y = Date.parse( "01/01/1970 00:00:00" ); + } + + return y - x; + }, + + + /* + * numerical sorting + */ + "numeric-asc": function ( a, b ) + { + var x = (a=="-" || a==="") ? 0 : a*1; + var y = (b=="-" || b==="") ? 0 : b*1; + return x - y; + }, + + "numeric-desc": function ( a, b ) + { + var x = (a=="-" || a==="") ? 0 : a*1; + var y = (b=="-" || b==="") ? 0 : b*1; + return y - x; + } + }; + + + /* + * Variable: aTypes + * Purpose: Container for the various type of type detection that dataTables supports + * Scope: jQuery.fn.dataTableExt + * Notes: The functions in this array are expected to parse a string to see if it is a data + * type that it recognises. If so then the function should return the name of the type (a + * corresponding sort function should be defined!), if the type is not recognised then the + * function should return null such that the parser and move on to check the next type. + * Note that ordering is important in this array - the functions are processed linearly, + * starting at index 0. + * Note that the input for these functions is always a string! It cannot be any other data + * type + */ + _oExt.aTypes = [ + /* + * Function: - + * Purpose: Check to see if a string is numeric + * Returns: string:'numeric' or null + * Inputs: string:sText - string to check + */ + function ( sData ) + { + /* Allow zero length strings as a number */ + if ( sData.length === 0 ) + { + return 'numeric'; + } + + var sValidFirstChars = "0123456789-"; + var sValidChars = "0123456789."; + var Char; + var bDecimal = false; + + /* Check for a valid first char (no period and allow negatives) */ + Char = sData.charAt(0); + if (sValidFirstChars.indexOf(Char) == -1) + { + return null; + } + + /* Check all the other characters are valid */ + for ( var i=1 ; i') != -1 ) + { + return 'html'; + } + return null; + } + ]; + + /* + * Function: fnVersionCheck + * Purpose: Check a version string against this version of DataTables. Useful for plug-ins + * Returns: bool:true -this version of DataTables is greater or equal to the required version + * false -this version of DataTales is not suitable + * Inputs: string:sVersion - the version to check against. May be in the following formats: + * "a", "a.b" or "a.b.c" + * Notes: This function will only check the first three parts of a version string. It is + * assumed that beta and dev versions will meet the requirements. This might change in future + */ + _oExt.fnVersionCheck = function( sVersion ) + { + /* This is cheap, but very effective */ + var fnZPad = function (Zpad, count) + { + while(Zpad.length < count) { + Zpad += '0'; + } + return Zpad; + }; + var aThis = _oExt.sVersion.split('.'); + var aThat = sVersion.split('.'); + var sThis = '', sThat = ''; + + for ( var i=0, iLen=aThat.length ; i= parseInt(sThat, 10); + }; + + /* + * Variable: _oExternConfig + * Purpose: Store information for DataTables to access globally about other instances + * Scope: jQuery.fn.dataTableExt + */ + _oExt._oExternConfig = { + /* int:iNextUnique - next unique number for an instance */ + "iNextUnique": 0 + }; + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Section - DataTables prototype + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * Function: dataTable + * Purpose: DataTables information + * Returns: - + * Inputs: object:oInit - initalisation options for the table + */ + $.fn.dataTable = function( oInit ) + { + /* + * Function: classSettings + * Purpose: Settings container function for all 'class' properties which are required + * by dataTables + * Returns: - + * Inputs: - + */ + function classSettings () + { + this.fnRecordsTotal = function () + { + if ( this.oFeatures.bServerSide ) { + return parseInt(this._iRecordsTotal, 10); + } else { + return this.aiDisplayMaster.length; + } + }; + + this.fnRecordsDisplay = function () + { + if ( this.oFeatures.bServerSide ) { + return parseInt(this._iRecordsDisplay, 10); + } else { + return this.aiDisplay.length; + } + }; + + this.fnDisplayEnd = function () + { + if ( this.oFeatures.bServerSide ) { + if ( this.oFeatures.bPaginate === false || this._iDisplayLength == -1 ) { + return this._iDisplayStart+this.aiDisplay.length; + } else { + return Math.min( this._iDisplayStart+this._iDisplayLength, + this._iRecordsDisplay ); + } + } else { + return this._iDisplayEnd; + } + }; + + /* + * Variable: oInstance + * Purpose: The DataTables object for this table + * Scope: jQuery.dataTable.classSettings + */ + this.oInstance = null; + + /* + * Variable: sInstance + * Purpose: Unique idendifier for each instance of the DataTables object + * Scope: jQuery.dataTable.classSettings + */ + this.sInstance = null; + + /* + * Variable: oFeatures + * Purpose: Indicate the enablement of key dataTable features + * Scope: jQuery.dataTable.classSettings + */ + this.oFeatures = { + "bPaginate": true, + "bLengthChange": true, + "bFilter": true, + "bSort": true, + "bInfo": true, + "bAutoWidth": true, + "bProcessing": false, + "bSortClasses": true, + "bStateSave": false, + "bServerSide": false + }; + + /* + * Variable: oScroll + * Purpose: Container for scrolling options + * Scope: jQuery.dataTable.classSettings + */ + this.oScroll = { + "sX": "", + "sXInner": "", + "sY": "", + "bCollapse": false, + "bInfinite": false, + "iLoadGap": 100, + "iBarWidth": 0, + "bAutoCss": true + }; + + /* + * Variable: aanFeatures + * Purpose: Array referencing the nodes which are used for the features + * Scope: jQuery.dataTable.classSettings + * Notes: The parameters of this object match what is allowed by sDom - i.e. + * 'l' - Length changing + * 'f' - Filtering input + * 't' - The table! + * 'i' - Information + * 'p' - Pagination + * 'r' - pRocessing + */ + this.aanFeatures = []; + + /* + * Variable: oLanguage + * Purpose: Store the language strings used by dataTables + * Scope: jQuery.dataTable.classSettings + * Notes: The words in the format _VAR_ are variables which are dynamically replaced + * by javascript + */ + 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 + }; + + /* + * Variable: aoData + * Purpose: Store data information + * Scope: jQuery.dataTable.classSettings + * Notes: This is an array of objects with the following parameters: + * int: _iId - internal id for tracking + * array: _aData - internal data - used for sorting / filtering etc + * node: nTr - display node + * array node: _anHidden - hidden TD nodes + * string: _sRowStripe + */ + this.aoData = []; + + /* + * Variable: aiDisplay + * Purpose: Array of indexes which are in the current display (after filtering etc) + * Scope: jQuery.dataTable.classSettings + */ + this.aiDisplay = []; + + /* + * Variable: aiDisplayMaster + * Purpose: Array of indexes for display - no filtering + * Scope: jQuery.dataTable.classSettings + */ + this.aiDisplayMaster = []; + + /* + * Variable: aoColumns + * Purpose: Store information about each column that is in use + * Scope: jQuery.dataTable.classSettings + */ + this.aoColumns = []; + + /* + * Variable: iNextId + * Purpose: Store the next unique id to be used for a new row + * Scope: jQuery.dataTable.classSettings + */ + this.iNextId = 0; + + /* + * Variable: asDataSearch + * Purpose: Search data array for regular expression searching + * Scope: jQuery.dataTable.classSettings + */ + this.asDataSearch = []; + + /* + * Variable: oPreviousSearch + * Purpose: Store the previous search incase we want to force a re-search + * or compare the old search to a new one + * Scope: jQuery.dataTable.classSettings + */ + this.oPreviousSearch = { + "sSearch": "", + "bRegex": false, + "bSmart": true + }; + + /* + * Variable: aoPreSearchCols + * Purpose: Store the previous search for each column + * Scope: jQuery.dataTable.classSettings + */ + this.aoPreSearchCols = []; + + /* + * Variable: aaSorting + * Purpose: Sorting information + * Scope: jQuery.dataTable.classSettings + * Notes: Index 0 - column number + * Index 1 - current sorting direction + * Index 2 - index of asSorting for this column + */ + this.aaSorting = [ [0, 'asc', 0] ]; + + /* + * Variable: aaSortingFixed + * Purpose: Sorting information that is always applied + * Scope: jQuery.dataTable.classSettings + */ + this.aaSortingFixed = null; + + /* + * Variable: asStripClasses + * Purpose: Classes to use for the striping of a table + * Scope: jQuery.dataTable.classSettings + */ + this.asStripClasses = []; + + /* + * Variable: asDestoryStrips + * Purpose: If restoring a table - we should restore it's striping classes as well + * Scope: jQuery.dataTable.classSettings + */ + this.asDestoryStrips = []; + + /* + * Variable: sDestroyWidth + * Purpose: If restoring a table - we should restore it's width + * Scope: jQuery.dataTable.classSettings + */ + this.sDestroyWidth = 0; + + /* + * Variable: fnRowCallback + * Purpose: Call this function every time a row is inserted (draw) + * Scope: jQuery.dataTable.classSettings + */ + this.fnRowCallback = null; + + /* + * Variable: fnHeaderCallback + * Purpose: Callback function for the header on each draw + * Scope: jQuery.dataTable.classSettings + */ + this.fnHeaderCallback = null; + + /* + * Variable: fnFooterCallback + * Purpose: Callback function for the footer on each draw + * Scope: jQuery.dataTable.classSettings + */ + this.fnFooterCallback = null; + + /* + * Variable: aoDrawCallback + * Purpose: Array of callback functions for draw callback functions + * Scope: jQuery.dataTable.classSettings + * Notes: Each array element is an object with the following parameters: + * function:fn - function to call + * string:sName - name callback (feature). useful for arranging array + */ + this.aoDrawCallback = []; + + /* + * Variable: fnInitComplete + * Purpose: Callback function for when the table has been initalised + * Scope: jQuery.dataTable.classSettings + */ + this.fnInitComplete = null; + + /* + * Variable: sTableId + * Purpose: Cache the table ID for quick access + * Scope: jQuery.dataTable.classSettings + */ + this.sTableId = ""; + + /* + * Variable: nTable + * Purpose: Cache the table node for quick access + * Scope: jQuery.dataTable.classSettings + */ + this.nTable = null; + + /* + * Variable: nTHead + * Purpose: Permanent ref to the thead element + * Scope: jQuery.dataTable.classSettings + */ + this.nTHead = null; + + /* + * Variable: nTFoot + * Purpose: Permanent ref to the tfoot element - if it exists + * Scope: jQuery.dataTable.classSettings + */ + this.nTFoot = null; + + /* + * Variable: nTBody + * Purpose: Permanent ref to the tbody element + * Scope: jQuery.dataTable.classSettings + */ + this.nTBody = null; + + /* + * Variable: nTableWrapper + * Purpose: Cache the wrapper node (contains all DataTables controlled elements) + * Scope: jQuery.dataTable.classSettings + */ + this.nTableWrapper = null; + + /* + * Variable: bInitialised + * Purpose: Indicate if all required information has been read in + * Scope: jQuery.dataTable.classSettings + */ + this.bInitialised = false; + + /* + * Variable: aoOpenRows + * Purpose: Information about open rows + * Scope: jQuery.dataTable.classSettings + * Notes: Has the parameters 'nTr' and 'nParent' + */ + this.aoOpenRows = []; + + /* + * Variable: sDom + * Purpose: Dictate the positioning that the created elements will take + * Scope: jQuery.dataTable.classSettings + * Notes: + * The following options are allowed: + * 'l' - Length changing + * 'f' - Filtering input + * 't' - The table! + * 'i' - Information + * 'p' - Pagination + * 'r' - pRocessing + * The following constants are allowed: + * 'H' - jQueryUI theme "header" classes + * 'F' - jQueryUI theme "footer" classes + * The following syntax is expected: + * '<' and '>' - div elements + * '<"class" and '>' - div with a class + * Examples: + * '<"wrapper"flipt>', 'ip>' + */ + this.sDom = 'lfrtip'; + + /* + * Variable: sPaginationType + * Purpose: Note which type of sorting should be used + * Scope: jQuery.dataTable.classSettings + */ + this.sPaginationType = "two_button"; + + /* + * Variable: iCookieDuration + * Purpose: The cookie duration (for bStateSave) in seconds - default 2 hours + * Scope: jQuery.dataTable.classSettings + */ + this.iCookieDuration = 60 * 60 * 2; + + /* + * Variable: sCookiePrefix + * Purpose: The cookie name prefix + * Scope: jQuery.dataTable.classSettings + */ + this.sCookiePrefix = "SpryMedia_DataTables_"; + + /* + * Variable: fnCookieCallback + * Purpose: Callback function for cookie creation + * Scope: jQuery.dataTable.classSettings + */ + this.fnCookieCallback = null; + + /* + * Variable: aoStateSave + * Purpose: Array of callback functions for state saving + * Scope: jQuery.dataTable.classSettings + * Notes: Each array element is an object with the following parameters: + * function:fn - function to call. Takes two parameters, oSettings and the JSON string to + * save that has been thus far created. Returns a JSON string to be inserted into a + * json object (i.e. '"param": [ 0, 1, 2]') + * string:sName - name of callback + */ + this.aoStateSave = []; + + /* + * Variable: aoStateLoad + * Purpose: Array of callback functions for state loading + * Scope: jQuery.dataTable.classSettings + * Notes: Each array element is an object with the following parameters: + * function:fn - function to call. Takes two parameters, oSettings and the object stored. + * May return false to cancel state loading. + * string:sName - name of callback + */ + this.aoStateLoad = []; + + /* + * Variable: oLoadedState + * Purpose: State that was loaded from the cookie. Useful for back reference + * Scope: jQuery.dataTable.classSettings + */ + this.oLoadedState = null; + + /* + * Variable: sAjaxSource + * Purpose: Source url for AJAX data for the table + * Scope: jQuery.dataTable.classSettings + */ + this.sAjaxSource = null; + + /* + * Variable: bAjaxDataGet + * Purpose: Note if draw should be blocked while getting data + * Scope: jQuery.dataTable.classSettings + */ + this.bAjaxDataGet = true; + + /* + * Variable: fnServerData + * Purpose: Function to get the server-side data - can be overruled by the developer + * Scope: jQuery.dataTable.classSettings + */ + this.fnServerData = function ( url, data, callback ) { + $.ajax( { + "url": url, + "data": data, + "success": callback, + "dataType": "json", + "cache": false, + "error": function (xhr, error, thrown) { + if ( error == "parsererror" ) { + alert( "DataTables warning: JSON data from server could not be parsed. "+ + "This is caused by a JSON formatting error." ); + } + } + } ); + }; + + /* + * Variable: fnFormatNumber + * Purpose: Format numbers for display + * Scope: jQuery.dataTable.classSettings + */ + this.fnFormatNumber = function ( iIn ) + { + if ( iIn < 1000 ) + { + /* A small optimisation for what is likely to be the vast majority of use cases */ + return iIn; + } + else + { + var s=(iIn+""), a=s.split(""), out="", iLen=s.length; + + for ( var i=0 ; i
+ + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/pages/editformdesign.php b/src/wp-content/plugins/wordpress-form-manager/pages/editformdesign.php new file mode 100644 index 00000000..3e1235fa --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/pages/editformdesign.php @@ -0,0 +1,379 @@ +getForm($_REQUEST['id']); + +$formList = $fmdb->getFormList(); + +$formTemplateFile = $form['form_template']; + if($formTemplateFile == '') $formTemplateFile = $fmdb->getGlobalSetting('template_form'); + if($formTemplateFile == '') $formTemplateFile = get_option('fm-default-form-template'); + +$formTemplate = $fm_templates->getTemplateAttributes($formTemplateFile); + +$templateList = $fm_templates->getTemplateFilesByType(); + +/// LOAD FIELDS ////////////////////////////////////////// + +if(isset($_POST['load-fields'])){ + $loadedForm = $fmdb->copyForm($_POST['load-fields-id']); + if($_POST['load-fields-insert-after'] == "0"){ //insert at beginning + $temp = $form['items']; + $form['items'] = $loadedForm['items']; + foreach($temp as $item) + $form['items'][] = $item; + } + else if($_POST['load-fields-insert-after'] == "1"){ //insert at end + foreach($loadedForm['items'] as $item) + $form['items'][] = $item; + } + else{ + $temp = array(); + foreach($form['items'] as $oldItem){ + $temp[] = $oldItem; + if($oldItem['unique_name'] == $_POST['load-fields-insert-after']){ + foreach($loadedForm['items'] as $newItem) + $temp[] = $newItem; + } + } + $form['items'] = $temp; + } +} + +// parse e-mail list +$email_list = explode(",", $form['email_list']); + +/////////////////////////////////////////////////////// +?> +
+ + + +
+ +
+

+ +

+ +
+ +
+
+ + +
+ +
+

+
+
+
+
+ " /> +
+ +
+ +
+ "> +
+ +
+
+ +
+
+
+ +
+
+
+
+ + " onclick="fm_saveForm()" /> +
+
+
+
+
+
+ +
+

+
+
+
+
+
:getSubmissionDataNumRows($form['ID']);?>
+
:getLastSubmission($form['ID']); echo $sub['timestamp'];?>
+
+
+
+
+
+
+ + +
+

+ +
+
+
+
+

+
+
+
+
+
+ + + + +
+

+ +
+
+
+
+

+ + +

+

+ +

+ + " /> +

+

+ +
+
+
+
+
+ + + +
+

+ +
+
+
+
+

+

+ + /> +

+ +

+ + 'page')); + $posts = get_posts(array('post_type' => 'post')); + $pages = array_merge($pages, $posts);?> + +

+ +

+ + +

+ +
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+ +
+ +
+ +
+
+
+
+ $controlType){ + if($controlKey != 'default') + $types[]="".$controlType->getTypeLabel().""; + } + echo implode(" | \n", $types); + ?> +
+ +
+ +
+
+ + +
    + + ".$fm_display->getEditorItem($item['unique_name'], $item['type'], $item)."\n"; ?> + +
+
+
+ + + + + + + + + + + + +
  
+ +
+ + 0) : ?> +
+
+

+
+
+ +
+ + getVarId($option); + $storedId = substr($varId, 3); + + if(!isset($form['template_values'][$storedId]) || $form['template_values'] === false) $val = $option['default']; + else $val = $form['template_values'][$storedId]; + + echo $fm_template_controls[$option['type']]->getEditor($val, $option); + ?> + +
+ +
+
+
+
+ + +
+
+

+
+
+
+ + +
+
+ + /> +
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/pages/editformnn.php b/src/wp-content/plugins/wordpress-form-manager/pages/editformnn.php new file mode 100644 index 00000000..5ce59b8e --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/pages/editformnn.php @@ -0,0 +1,82 @@ +getForm($_POST['fm-form-id']); + + $formInfo = array(); + + $formInfo['items'] = $form['items']; + foreach($form['items'] as $index => $item){ + $formInfo['items'][$index]['nickname'] = sanitize_title($_POST[$item['unique_name'].'-nickname']); + } + $fmdb->updateForm($_POST['fm-form-id'], $formInfo); +} + +///////////////////////////////////////////////////////////////////////////////////// + +$form = null; +if($_REQUEST['id']!="") + $form = $fmdb->getForm($_REQUEST['id']); + +///////////////////////////////////////////////////////////////////////////////////// + +$fm_globalSettings = $fmdb->getGlobalSettings(); + +?> + +
+ + + +
+ +
+" /> +" />   +
+ +

+ +

+ +
+ + + +
+
+ + + +
+ +

+" /> +" /> +

+ +
+ +
\ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/pages/editsettings.php b/src/wp-content/plugins/wordpress-form-manager/pages/editsettings.php new file mode 100644 index 00000000..c9ceff74 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/pages/editsettings.php @@ -0,0 +1,88 @@ +setGlobalSetting('title', $_POST['title']); + $fmdb->setGlobalSetting('submitted_msg', $_POST['submitted_msg']); + $fmdb->setGlobalSetting('required_msg', $_POST['required_msg']); + $fmdb->setGlobalSetting('recaptcha_public', $_POST['recaptcha_public']); + $fmdb->setGlobalSetting('recaptcha_private', $_POST['recaptcha_private']); + $fmdb->setGlobalSetting('recaptcha_theme', (trim($_POST['recaptcha_theme_custom']) == "" ? $_POST['recaptcha_theme'] : $_POST['recaptcha_theme_custom'])); + $fmdb->setGlobalSetting('email_admin', $_POST['email_admin'] == "on" ? "YES" : ""); + $fmdb->setGlobalSetting('email_reg_users', $_POST['email_reg_users'] == "on" ? "YES" : ""); +} + +///////////////////////////////////////////////////////////////////////////////////// +$fm_globalSettings = $fmdb->getGlobalSettings(); + +?> +
+ + +
+
+

+ +

+ +

+ +
+ +

+ + + + +
+ +

+ + + + +
+ +

+ www.google.com/recaptcha. + + + + __("Red", 'wordpress-form-manager'), 'white' => __("White", 'wordpress-form-manager'), 'blackglass' => __("Black", 'wordpress-form-manager'), 'clean' => __("Clean", 'wordpress-form-manager')); +$value = $fm_globalSettings['recaptcha_theme']; +$found = false; +?> + + + + +
+ +
+ +
+ +

" />

+
\ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/pages/editsettingsadv.php b/src/wp-content/plugins/wordpress-form-manager/pages/editsettingsadv.php new file mode 100644 index 00000000..3ee998aa --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/pages/editsettingsadv.php @@ -0,0 +1,229 @@ +setTextValidators($validators); + + //////////////////////////////////////////////////////////////////////////////////// + //Process shortcode + + $newShortcode = sanitize_title($_POST['shortcode']); + $oldShortcode = get_option('fm-shortcode'); + if($newShortcode != $oldShortcode){ + remove_shortcode($oldShortcode); + update_option('fm-shortcode', $newShortcode); + add_shortcode($newShortcode, 'fm_shortcodeHandler'); + } + + //////////////////////////////////////////////////////////////////////////////////// + //Process template settings + + $fmdb->setGlobalSetting('template_form', $_POST['template_form']); + $fmdb->setGlobalSetting('template_email', $_POST['template_email']); + $fmdb->setGlobalSetting('template_summary', $_POST['template_summary']); + + //////////////////////////////////////////////////////////////////////////////////// + //Other + + update_option('fm-enable-mce-button', $_POST['enable_mce_button']?"YES":""); + +} +elseif(isset($_POST['remove-template'])){ + $fm_templates->removeTemplate($_POST['remove-template-filename']); +} +else if(isset($_POST['reset-templates'])){ + $fm_templates->resetTemplates(); +} +else if(isset($_POST['check-db'])){ + echo '
';
+	$fmdb->consistencyCheck();
+	echo '
'; + die(); +} + +///////////////////////////////////////////////////////////////////////////////////// +$fm_globalSettings = $fmdb->getGlobalSettings(); + +///////////////////////////////////////////////////////////////////////////////////// +// Load the templates + +$templateList = $fm_templates->getTemplateFilesByType(); +$templateFiles = $fm_templates->getTemplateList(); + +?> + + +
+ + + +
+
+

+ +

+ +

+ +
+ +

+ +
+ + + + + +
+
    +
+ + + Add + +
+
+

+ + +
+ +

+ + + + +
+" onclick="return fm_resetTemplatesSubmit()" /> + +$template): ?> + + + + +
" onclick="return fm_submitRemoveTemplate('', '')" />
+ +

+ + +
" />
+ +

+ + +
+ + + +
+ +

" onclick="return fm_saveSettingsAdvanced()" />

+
\ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/pages/formdata.php b/src/wp-content/plugins/wordpress-form-manager/pages/formdata.php new file mode 100644 index 00000000..0120b500 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/pages/formdata.php @@ -0,0 +1,396 @@ +getForm($_REQUEST['id']); +if($form != null){ + $orderBy = isset($_REQUEST['orderby']) ? $_REQUEST['orderby'] : 'timestamp'; + $orderBy = $fmdb->isValidItem($form, $orderBy) ? $orderBy : 'timestamp'; + $ord = $_REQUEST['ord'] == 'ASC' ? 'ASC' : 'DESC'; + $formData = $fmdb->getFormSubmissionData($form['ID'], $orderBy, $ord, ($set*$itemsPerPage), $itemsPerPage); + + $numDataPages = ceil($formData['count'] / $itemsPerPage); +} + +$hasPosts = $fmdb->dataHasPublishedSubmissions($form['ID']); + +// PARSE THE QUERY STRING +parse_str($_SERVER['QUERY_STRING'], $queryVars); + +//////////////////////////////////////////////////////////////////////////////// +//ACTIONS + +//Delete data row(s): +if(isset($_POST['fm-action-select'])){ + + switch($_POST['fm-action-select']){ + case "delete": + if(!$fm_MEMBERS_EXISTS || current_user_can('form_manager_delete_data')){ + $toDelete = fm_data_getCheckedRows(); + foreach($toDelete as $del) + $fmdb->deleteSubmissionDataRow($form['ID'], $formData['data'][$del]); + } + //clean up the mess we made + $formData = $fmdb->getFormSubmissionData($form['ID'], $orderBy, $ord, ($set*$itemsPerPage), $itemsPerPage); + break; + case "delete_all": + if(!$fm_MEMBERS_EXISTS || current_user_can('form_manager_delete_data')) + $fmdb->clearSubmissionData($form['ID']); + //clean up the mess we made + $formData = $fmdb->getFormSubmissionData($form['ID'], $orderBy, $ord, ($set*$itemsPerPage), $itemsPerPage); + break; + case "edit": + if(!$fm_MEMBERS_EXISTS || current_user_can('form_manager_edit_data')) + $fm_dataDialog = "edit"; + break; + case "summary": + $fm_dataDialog = "summary"; + break; + } +} + +//Edit data rows(s) +else if((!$fm_MEMBERS_EXISTS || current_user_can('form_manager_edit_data')) && isset($_POST['fm-edit-data-ok'])){ + $numRows = $_POST['fm-num-edit-rows']; + $postFailed = false; + + for($x=0;$x<$numRows;$x++){ + $dataIndex = $_POST['fm-edit-row-'.$x]; + + $newData = array(); + $postData = array(); + foreach($form['items'] as $item){ + if($item['type'] != 'file' + && $item['type'] != 'separator' + && $item['type'] != 'note' + && $item['type'] != 'recaptcha'){ + $processed = $fm_controls[$item['type']]->processPost($item['unique_name']."-".$x, $item); + if($processed === false){ + $postFailed = true; + } + if($item['db_type'] != "NONE") + $postData[$item['unique_name']] = $processed; + } + } + + $fmdb->updateDataSubmissionRow($form['ID'], + $formData['data'][$dataIndex]['timestamp'], + $formData['data'][$dataIndex]['user'], + $formData['data'][$dataIndex]['user_ip'], + $postData + ); + } + //clean up the mess we made + $formData = $fmdb->getFormSubmissionData($form['ID'], $orderBy, $ord, ($set*$itemsPerPage), $itemsPerPage); +} + +//////////////////////////////////////////////////////////////////////////////// +// BEGIN OUTPUT + +switch($fm_dataDialog){ + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//EDIT DIALOG + +case "edit": + +if($formData !== false){ + $numRows = (int)$_POST['fm-num-data-rows']; + + ?> +
+
+
+

:

+
+ " /> + " /> +
+ +
+
+ + :
+ 'fm_data_displayTextEdit', + 'textarea' => 'fm_data_displayTextAreaEdit', + 'file' => 'fm_data_displayFileEdit' + ); + $exclude_types = array('note', 'recaptcha'); + + $editRowCount = 0; + for($x=0;$x<$numRows;$x++){ + if(isset($_POST['fm-checked-'.$x])){ + echo "
".$fm_display->displayFormBare($form, array('exclude_types' => $exclude_types, 'display_callbacks' => $callbacks, 'unique_name_suffix' => '-'.$x), $formData['data'][$x])."
\n"; + echo "\n"; + $editRowCount++; + } + } + ?> +
+ + + +
+
+ " /> + " /> +
+
+
+ +
+
+

:

+ +
+
+
+ ".$fm_display->displayDataSummaryNoTemplate($form, $formData['data'][$x], "", "", true)."
\n"; + } + } + ?> +
+ + + $colMaxChars[$x]) $colMaxChars[$x] = $len; + $x++; + } + } +} + +//'total' character width +$totalCharWidth = 0; +for($x=0;$x + + + + + +
+
+ + + +
+ +
+
+
+ + " name="fm-doaction" id="fm-doaction" onclick="return fm_confirmSubmit()" class="button-secondary action" /> + +
+
+
+ +
+
+ Showing page ( Rows - out of ): +
+
+ Page:    + + +   + + $x)));?>">   + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ") === false):?> + + + + + + + + + +
$ord, 'orderby' => 'timestamp'))); ?>"> $ord, 'orderby' => 'user'))); ?>"> $ord, 'orderby' => 'user_ip'))); ?>"> $ord, 'orderby' => $formItem['unique_name']))); ?>"> + + + +
+
+
+ + +
+ +
+ + 0): ?> ''">
+ +
+
+ + + +"; } +function fm_data_displayTextAreaEdit($uniqueName, $itemInfo){ return ""; } +function fm_data_displayFileEdit($uniqueName, $itemInfo){ return $itemInfo['extra']['value']; } + +?> \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/pages/main.php b/src/wp-content/plugins/wordpress-form-manager/pages/main.php new file mode 100644 index 00000000..c76dc014 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/pages/main.php @@ -0,0 +1,188 @@ +createForm(null); + + +//APPLY ACTION$wpdb->prefix.get_option('fm-data-table-prefix') +if(isset($_POST['fm-doaction'])){ + //check for 'delete' + if($_POST['fm-action-select'] == "delete"){ + //get a list of selected IDs + $fList = $fmdb->getFormList(); + $deleteIds = array(); + foreach($fList as $form){ + if(isset($_POST['fm-checked-'.$form['ID']])) $deleteIds[] = $form['ID']; + } + if(sizeof($deleteIds)>0) $currentDialog = "verify-delete"; + } +} + +//SINGLE DELETE +if((!$fm_MEMBERS_EXISTS || current_user_can('form_manager_delete_forms')) && $_POST['fm-action'] == "delete"){ + $deleteIds = array(); + $deleteIds[0] = $_POST['fm-id']; + $currentDialog = "verify-delete"; +} + +//VERIFY DELETE +if((!$fm_MEMBERS_EXISTS || current_user_can('form_manager_delete_forms')) && isset($_POST['fm-delete-yes'])){ + $index=0; + while(isset($_POST['fm-delete-id-'.$index])){ + $fmdb->deleteForm($_POST['fm-delete-id-'.$index]); + $index++; + } +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// DISPLAY UI + +$formList = $fmdb->getFormList(); + +?> + + +
+
+
+

+
+

+ +
    + ".$form['title'].""; + } + } + ?> +
+ +
+ + + + " name="fm-delete-yes" /> + " name="fm-delete-cancel" /> +
+
+
+ + +
+
+
+ +

+ + " /> + +

+ 0): ?> +
+ +
+ + " name="fm-doaction" id="fm-doaction" class="button-secondary action" /> +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
 
+ "> +
+ + + " title=""> | + " title=""> | + " title=""> | + " onClick="fm_deleteFormClick('');return false"> + + + + + ".__("Edit", 'wordpress-form-manager').""; + if(current_user_can('form_manager_forms_advanced')) + $editOptions[] = "".__("Advanced", 'wordpress-form-manager').""; + if(current_user_can('form_manager_data')) + $editOptions[] = "".__("Data", 'wordpress-form-manager').""; + if(current_user_can('form_manager_delete_forms')) + $editOptions[] = "".__("Delete", 'wordpress-form-manager').""; + + echo implode(" | ", $editOptions); + ?> + +
+ +
getSubmissionDataNumRows($form['ID']);?>getLastSubmission($form['ID']); echo $sub['timestamp'];?>
+ +
+
+ \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/readme.txt b/src/wp-content/plugins/wordpress-form-manager/readme.txt new file mode 100644 index 00000000..05de75c1 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/readme.txt @@ -0,0 +1,277 @@ +=== WordPress Form Manager === +Contributors: hoffcamp +Donate link: http://www.campbellhoffman.com/ +Tags: form, forms, form manager +Requires at least: 3.0.0 +Tested up to: 3.1.1 +Stable tag: 1.5.9 + +Put custom forms into posts and pages using shortcodes. Download submissions in .csv format. + +== Description == + +Form Manager is a tool for creating forms to collect and download data from visitors to your WordPress site, and keeps track of time/date and registered users as well. Forms are added to posts or pages using a simple shortcode format, or can be added to your theme with a simple API. + += Features = +* validation +* required fields +* custom acknowledgments +* e-mail notifications. +* form display templates + += Supported field types = + +* text field +* text area +* dropdown +* radio buttons +* checkbox / checkbox list +* multiline select +* file upload +* reCAPTCHA + +Subtitles and notes can also be added to the form in any location. + += Publishing a Form = +Forms are placed within posts or pages. Look for the Form Manager button in your post editor towards the right (Thanks to [Andrea Bersi](http://www.andreabersi.com)). + +You can also type in shortcodes yourself. For example, if your form's slug is 'form-1', put the following within a post or page: + +`[form form-1]` + + +
+= Languages = +* Italiano (it_IT) - [Andrea Bersi](http://www.andreabersi.com) +* Nederlands (nl_NL) - [Sander Kolthof](http://www.fullcirclemedia.nl) + +== Changelog == += 1.5.9 = +* Added links to published submissions in the data page + += 1.5.8 = +* Improved conditions editor +* Fixed bug when uploading files with Unicode file names +* Added some missing internationalization handles +* Conditions can apply to 'file' inputs +* Added submission information to the main page + += 1.5.7 = +* Fixed a bug when updating a form element's nickname + += 1.5.6 = +* Fixed permissions bug +* Fixed CSV download bug +* Added separators, notes, and recaptchas to the items you can show/hide with conditions. + += 1.5.4 = +* Fixed install issues on certain platforms. Thanks to Metin Kale. + += 1.5.3 = +* Added an option to disable the TinyMCE button in the 'Advanced' settings page + += 1.5.2 = +* Files can be uploaded to a directory of your choosing +* Links in summaries / e-mails to uploaded files, if they are in a directory + += 1.5.1 = +* Fixed script loading bug in certain environments + += 1.5.0 = +* Added conditional behavior, e.g., only show certain items based on the values of other items +* Dutch language support (Thanks to [Sander Kolthof](www.fullcirclemedia.nl)) +* Fixed '0 kB' summary bug +* Fixed checkbox default value bug + += 1.4.23 = +* Editor/Data/Advanced for forms now uses a 'tabbed' interface +* Added database check for troubleshooting +* Added checkbox positioning option +* Added more specific capabilities for Members plugin + += 1.4.22 = +* Notes can display HTML + += 1.4.21 = +* Added 'maximum length' attribute for text inputs +* Added tinyMCE button. (Many thanks to [Andrea Bersi](http://www.andreabersi.com)) + += 1.4.20 = +* Fixed install error + += 1.4.19 = +* Added auto-redirect option + += 1.4.18 = +* Added fm_getFormID() to API, returns a form's ID number from a slug +* Fixed bug in formdata shortcode 'orderby' attribute +* Fixed reCAPTCHA bug +* Added support for placeholders in non HTML 5 browsers + += 1.4.17 = +* Italian language support (Thanks to [Andrea Bersi](http://www.andreabersi.com)) +* Specify custom theme for reCAPTCHA +* Fixed problems when trying to edit submission data +* Added more capabilites to the Members plugin + += 1.4.16 = +* Publish submitted data to posts +* Show a table of all submissions within a post +* Fixed IE download issues +* Fixed Unicode issues with CSV / ZIP downloads +* Integration with WP-SlimStat + += 1.4.15 = +* Fixed 'show summary' error +* Fixed CSV download with international characters +* Admins can edit posted data +* Minor interface changes +* Compatibility for internationalization added +* CSS class names for each form item +* Custom capabilities, integration with the Members plugin + += 1.4.14 = +* Fixed install error + += 1.4.13 = +* Minor bug fixes + += 1.4.12 = +* Added 'template reset' in advanced settings + += 1.4.11 = +* Minor bug fixes + += 1.4.10 = +* Minor bug fixes + += 1.4.9 = +* Added e-mail notification customization to 'Advanced' form settings + += 1.4.8 = +* Fixed install error for 1.4.7 + += 1.4.7 = +* Fixed e-mail list + += 1.4.6 = +* Added text entry for list options +* Moved 'Templates' and 'Behavior' to a new 'Advanced' settings page for forms + += 1.4.5 = +* Fixed summary template formatting + += 1.4.4 = +* Added file upload form element +* Save script bug fixes + += 1.4.3 = +* Added IP address to submission data +* Fixed the summary template timestamp label + += 1.4.2 = +* Fixed e-mail list bug + += 1.4.1 = +* Fixed saved bug + += 1.4.0 = +* Templates for e-mail notifications and form display, similar to WordPress theme functionality +* HTML 5 placeholders in supported browsers +* E-mail notification conflict with certain hosts +* Fixed 'list' option bug when creating a new list + += 1.3.15 = +* Fixed asterisks appearing below labels +* Fixed include bug with XAMPP + += 1.3.14 = +* Added reCAPTCHA color scheme option in settings +* Fixed conflict with other plugins using Google RECAPTCHA + += 1.3.13 = +* Changed upgrade mechanism + += 1.3.12 = +* Added 'required item message' to form editor +* Fixed upgrade from 1.3.3 and older + += 1.3.11 = +* Full Unicode support +* Added date validator for text fields + += 1.3.10 = +* Added API stable fm_doFormBySlug($formSlug) to show forms within templates +* Admin can change plugin's shortcode in 'Advanced Settings' + += 1.3.9 = +* Fixed form behavior selection bug + += 1.3.8 = +* Fixed possible style conflict with Kubric (Default) theme + += 1.3.7 = +* Fixed 'fm_settiings' table install error + += 1.3.6 = +* Advanced settings page +* Custom text validators using regular expressions + += 1.3.5 = +* E-mail notifications for registered users +* Admin and registered user e-mail notifications are now a global rather than per form setting. + += 1.3.4 = +* Added e-mail notification for user input (acknowledgment e-mail) +* Changed editor interface + += 1.3.3 = +* Adjusted for register_activation_hook() change +* Fixed some CSS style names likely to have conflicts + += 1.3.2 = +* Added reCAPTCHA field +* Added Settings page +* Multiple forms per page +* Fixed CSV data double quote bug +* Improved acknowledgement formatting + += 1.3.1 = +* Fixed 'Single submission' behavior bug +* Items in form editor update when 'done' is clicked +* Fixed list option editor bug + += 1.3.0 = +* Added form behaviors for registered users +* Cleaned up data page +* Added data summary to data page + += 1.2.10 = +* Rearranged editor sections +* Fixed checkbox list 'required' test +* Added single checkbox 'requried' test + += 1.2.9 = +* Fixed .csv download bug + += 1.2.8 = +* Added e-mail notifications. + += 1.2.5 = +* Fixes multisite edit/data page bug. + += 1.2.4 = +* Fixes an installation error when starting with a fresh plugin install. + + +*** I am starting work on version 2. If you have suggestions or requests, please let me know! *** + +== Installation == + +Method 1: Activate the 'WordPress Form Manager' plugin through the 'Plugins' menu in WordPress. + +Method 2: Download the source code for the plugin, and upload the 'wordpress-form-manager' directory to the '/wp-content/plugins/' directory. + +== Frequently Asked Questions == + +Please visit [www.campbellhoffman.com/form-manager-faq/](http://www.campbellhoffman.com/form-manager-faq/) for FAQ and tutorials. \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/settings.php b/src/wp-content/plugins/wordpress-form-manager/settings.php new file mode 100644 index 00000000..db9ec3a9 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/settings.php @@ -0,0 +1,54 @@ + __("New Form", 'wordpress-form-manager'), + 'labels_on_top' => 0, + 'submitted_msg' => __('Thank you! Your data has been submitted.', 'wordpress-form-manager'), + 'submit_btn_text' => __('Submit', 'wordpress-form-manager'), + 'required_msg' => __("\'%s\' is required.", 'wordpress-form-manager'), + 'show_title' => 1, + 'show_border' => 1, + 'label_width' => 200 + )); + +$fm_registered_user_only_msg = "'%s' is only available to registered users."; + +/* +reg_user_only - only show form to registered users +display_summ - show the previous submission rather than the form +no_dup - do not allow a submission after the first +edit - give an 'edit' button after the previous submission summary +overwrite - only store the latest submission +*/ + +/* translators: the following are descriptions of the different behavior types */ + +$fm_form_behavior_types = array( __("Default", 'wordpress-form-manager') => '', + __("Registered users only", 'wordpress-form-manager') => 'reg_user_only', + __("Keep only most recent submission", 'wordpress-form-manager') => 'reg_user_only,overwrite', + __("Single submission", 'wordpress-form-manager') => 'reg_user_only,display_summ,single_submission', + __("'User profile' style", 'wordpress-form-manager') => 'reg_user_only,display_summ,edit' + ); + +$fm_controls['text']->initValidators(); +?> \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/template.php b/src/wp-content/plugins/wordpress-form-manager/template.php new file mode 100644 index 00000000..e7d29b5e --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/template.php @@ -0,0 +1,227 @@ + 'fm_templateControlSelect', + 'checkbox' => 'fm_templateControlCheckbox', + 'text' => 'fm_templateControlText' + ); +class fm_templateControlBase{ + + function getEditor($value, $option){ + $id = $this->getVarId($option); + return ""; + } + + function parseStoredValue($value, $option){ + return $value; + } + + function getVarId($option){ + return 'fm-'.str_replace("\$", "", $option['var']); + } + //used for the javascript function that collects values for AJAX save; mostly to accomodate the checkbox type + function getElementValueAttribute(){ return 'value'; } +} + +class fm_templateControlSelect extends fm_templateControlBase{ + function getEditor($value, $option){ + $id = $this->getVarId($option); + $str = ""; + return $str; + } +} +class fm_templateControlCheckbox extends fm_templateControlBase{ + function getEditor($value, $option){ + $id = $this->getVarId($option); + return ""; + } + function parseStoredValue($value, $option){ + return ($value == "true"); + } + function getElementValueAttribute(){ return 'checked'; } +} +class fm_templateControlText extends fm_templateControlBase{ +} +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +class fm_template_manager{ + +//////////////////////////////////////////////////////////////////// + +var $templatesDir; + +var $headers = array('option' => 'option', + 'label' => 'label', + 'description' => 'description', + 'options' => 'options', + 'default' => 'default', + 'template_name' => 'Template Name', + 'template_desc' => 'Template Description', + 'template_type' => 'Template Type' + ); + +function __construct(){ + $this->templatesDir = dirname(__FILE__).'/templates'; +} + +function getTemplateAttributes($fileName){ + $file_data = fm_get_file_data($this->templatesDir.'/'.$fileName, $this->headers); + $templateAtts = array(); + $templateAtts['options'] = array(); + $currentOption = false; + foreach($file_data as $option){ + switch($option['field']){ + case 'option': + //closeout the current option if there is one + if($currentOption !== false) $templateAtts['options'][] = $currentOption; + + $currentOption = array(); + $opt = explode(",", $option['value']); + $currentOption['var'] = trim($opt[0]); + $currentOption['type'] = trim($opt[1]); + break; + case 'label': + $currentOption['label'] = trim($option['value']); + break; + case 'description': + $currentOption['description'] = trim($option['value']); + break; + case 'options': + eval("\$arr = array(" . trim($option['value']) . ");"); + $currentOption['options'] = $arr; + break; + case 'default': + $currentOption['default'] = $option['value']; + break; + default: + $templateAtts[$option['field']] = $option['value']; + break; + } + } + + if($currentOption !== false) $templateAtts['options'][] = $currentOption; + + return $templateAtts; +} + +function resetTemplates(){ + global $fmdb; + $fmdb->flushTemplates(); + $this->initTemplates(); +} + +function initTemplates(){ + global $fmdb; + + //compare the stored templates with those in the templates directory. Files that exist in the database but not on disk are re-created on disk; files that exist on disk are all stored in the database. + $files = $this->getTemplateFiles($this->templatesDir); + $dbTemplates = $fmdb->getTemplateList(); + + //echo '
'.print_r($files, true).'
'; + //echo '
'.print_r($dbTemplates, true).'
'; + + //replace any 'lost' templates (this is primarily to keep template files across an update) + foreach($dbTemplates as $dbFile => $dbTemp){ + $dbFile = trim($dbFile); + $templateInfo = $fmdb->getTemplate($dbFile, false); + if(isset($files[$dbFile])){ // file exists on disk + unset($files[$dbFile]); //unset the file; the list of files will be used later to load in new files + $filemtime = filemtime($this->templatesDir.'/'.$dbFile); + if( $filemtime > $templateInfo['modified']){ //file is a newer version than the one in the db + $content = file_get_contents($this->templatesDir.'/'.$dbFile); + $template = $this->getTemplateAttributes($dbFile); + $title = $template['template_name']; + //echo $title." updated
"; + $fmdb->storeTemplate($dbFile, $title, $content, $filemtime); + } + } + else{ // file does not exist on disk + //echo $dbFile." recreated
"; + $templateInfo = $fmdb->getTemplate($dbFile); + + $fp = fopen($this->templatesDir."/".$dbFile, "w"); + fwrite($fp, $templateInfo['content']); + fclose($fp); + + } + } + + foreach($files as $file){ + $filemtime = filemtime($this->templatesDir.'/'.$file); + $content = file_get_contents($this->templatesDir.'/'.$file); + $title = $template['template_name']; + //echo $title." loaded
"; + $fmdb->storeTemplate($file, $title, $content, $filemtime); + } +} + +function getTemplateList(){ + $files = $this->getTemplateFiles($this->templatesDir); + $arr = array(); + foreach($files as $file){ + $arr[$file] = $this->getTemplateAttributes($file); + } + return $arr; +} + +function getTemplateFilesByType(){ + $templates = $this->getTemplateList(); + + $templateList = array(); + $templateList['form'] = array(); + $templateList['email'] = array(); + $templateList['summary'] = array(); + + foreach($templates as $file=>$temp){ + if(strpos($temp['template_type'], 'form') !== false) $templateList['form'][$file] = $temp['template_name']; + if(strpos($temp['template_type'], 'email') !== false) $templateList['email'][$file] = $temp['template_name']; + if(strpos($temp['template_type'], 'summary') !== false) $templateList['summary'][$file] = $temp['template_name']; + } + + return $templateList; +} + +protected function getTemplateFiles($dir){ + if($handle = opendir($dir)){ + $arr = array(); + while(($file = readdir($handle)) !== false){ + if($file != "." && $file != ".." && is_file($dir."/".$file)) + $arr[$file] = $file; + } + closedir($handle); + return $arr; + } + return false; +} + +function removeTemplate($filename){ + global $fmdb; + $fullpath = $this->templatesDir.'/'.$filename; + if(is_file($fullpath)) unlink($fullpath); + $fmdb->removeTemplate($filename); +} + +function isTemplate($filename){ + return file_exists($this->templatesDir.'/'.$filename); +} + +//////////////////////////////////////////////////////////////////// +} +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +function fm_buildTemplateControlTypes($controlTypes){ + $arr = array(); + foreach($controlTypes as $name=>$class){ + $arr[$name] = new $class(); + } + return $arr; +} +global $fm_template_controls; + +$fm_template_controls = fm_buildTemplateControlTypes($fm_templateControlTypes); + +?> \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/templates/fm-form-default.php b/src/wp-content/plugins/wordpress-form-manager/templates/fm-form-default.php new file mode 100644 index 00000000..47207ed6 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/templates/fm-form-default.php @@ -0,0 +1,105 @@ + 'Left', 'top' => 'Top' + default: left +option: $labelWidth, text + label: Label width (in pixels): + description: Applies to checkboxes, and when labels are to the left + default: 200 + + +////////////////////////////////////////////////////////////////////////////////////////// + +Below are the functions that can be used within a form display template: + +fm_form_start(), fm_form_end() - These can be called (not echo'ed) to open and close the form, respectively. +fm_form_hidden() - Nonce and other hidden values required for the form; can be omitted if fm_form_end() is used. +fm_form_the_title() - The form's title + +The following can be used in place of the fm_form_start() function: +fm_form_class() - The default form CSS class +fm_form_action() - The default form action +fm_form_ID() - Used for the opening form tag's 'name' and 'id' attributes. + +fm_form_the_submit_btn() - A properly formed submit button +fm_form_submit_btn_name() - Submit button's 'name' attribute +fm_form_submit_btn_text() - Submit button's 'value' attribute, as set in the form editor. +fm_form_submit_btn_script() - Validation script + +fm_form_have_items() - Returns true if there are more items (used to loop through the form items, similar to have_posts() in wordpress themes) +fm_form_the_item() - Sets up the current item (similar to the_post() in wordpress themes) +fm_form_the_label() - The current item's label +fm_form_the_input() - The current item's input element +fm_form_the_nickname() - The current item's nickname + +fm_form_is_separator() - Returns true if the current element is a horizontal line +fm_form_is_note() - Returns true if the current element is a note +fm_form_is_required() - Returns true if the current item is set as required +fm_form_item_type() - The current item's type + +fm_form_get_item_input($nickname) - get an item's input by nickname +fm_form_get_item_label($nickname) - get an item's label by nickname + +////////////////////////////////////////////////////////////////////////////////////////// + +*/ + +/* translators: the following are for the options for the default form display template */ +__("Show form title:", 'wordpress-form-manager'); +__("Show border:", 'wordpress-form-manager'); +__("Label position:", 'wordpress-form-manager'); +__("Labels can be placed to the left or above each field", 'wordpress-form-manager'); +_x('Left', 'template-option', 'wordpress-form-manager'); +_x('Top', 'template-option', 'wordpress-form-manager'); +__("Label width (in pixels):", 'wordpress-form-manager'); +__("Applies to checkboxes, and when labels are to the left", 'wordpress-form-manager'); + +?> + + +
+ + + + + +

+ + + +
    + +
  • "> + + + + + + +
    + +
  • + +
+ +
+ +
+ +
+ + + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/templates/fm-summary-default.php b/src/wp-content/plugins/wordpress-form-manager/templates/fm-summary-default.php new file mode 100644 index 00000000..61eb0b0b --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/templates/fm-summary-default.php @@ -0,0 +1,56 @@ + + +

+ + +".$userData->last_name.", ".$userData->first_name."
"; +} +?> + + +On:
+IP:
+ +
    + + +
    + + >: + + +
\ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/templates/fm-summary-multi.php b/src/wp-content/plugins/wordpress-form-manager/templates/fm-summary-multi.php new file mode 100644 index 00000000..8123d137 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/templates/fm-summary-multi.php @@ -0,0 +1,33 @@ + + +".$userData->last_name.", ".$userData->first_name."
"; +} +?> + + +On:
+IP:
+ +
    + + +
    + + >: + + +
+
\ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/tinymce.php b/src/wp-content/plugins/wordpress-form-manager/tinymce.php new file mode 100644 index 00000000..20e86f0f --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/tinymce.php @@ -0,0 +1,38 @@ + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types.php b/src/wp-content/plugins/wordpress-form-manager/types.php new file mode 100644 index 00000000..687802a0 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types.php @@ -0,0 +1,76 @@ + 'class name' +// the keys in this array are used in the 'addItem' AJAX to create new items, and as the 'type' db field for form items +$fm_controlTypes = array('default' => 'fm_controlBase', + 'text' => 'fm_textControl', + 'textarea' => 'fm_textareaControl', + 'checkbox' => 'fm_checkboxControl', + 'custom_list' => 'fm_customListControl', + 'separator' => 'fm_separatorControl', + 'note' => 'fm_noteControl', + 'recaptcha' => 'fm_recaptchaControl', + 'file' => 'fm_fileControl' +); +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +//control base class +include 'types/base.php'; + +//control types +include 'types/separator.php'; +include 'types/text.php'; +include 'types/textarea.php'; +include 'types/checkbox.php'; +include 'types/list.php'; +include 'types/note.php'; +include 'types/recaptcha.php'; +include 'types/file.php'; + +//'panel' helpers +include 'types/panelhelper.php'; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +function fm_showControlScripts(){ + ?>$class){ + $arr[$name] = new $class(); + } + return $arr; +} + +global $fm_controls; + +$fm_controls = fm_buildControlTypes($fm_controlTypes); + +?> \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/base.php b/src/wp-content/plugins/wordpress-form-manager/types/base.php new file mode 100644 index 00000000..84643738 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/base.php @@ -0,0 +1,226 @@ +"; + } + + //HTML returned for the editor (admin) version of the form + public function editItem($uniqueName, $itemInfo){ + return ""; + } + + //returns an array of fm_editPanelItemBase (or derived) objects that define the editor 'panel' + public function getPanelItems($uniqueName, $itemInfo){ + global $fmdb; + $arr=array(); + foreach($fmdb->itemKeys as $key=>$v){ + $arr[] = new fm_editPanelItemBase($uniqueName, $key, $key, array('value'=>$itemInfo[$key])); + } + return $arr; + } + + //returns an associative array (keyed by the db field names for items) of javascript for use in the 'get' script; see showPanelScript() + public function getPanelScriptOptions(){ + $opt = $this->getPanelScriptOptionDefaults(); + $opt['extra'] = "fm_get_item_value(itemID, 'extra')"; + return $opt; + } + + //returns the name of a javascript function to be called whenever the user clicks the 'edit'/'done' button; + // the function is passed two variables: the first is the itemID, the second is a boolean indicating if 'edit' or 'done' was clicked (true or false respectively) + public function getShowHideCallbackName(){ + return ""; + } + + //returns the name of a javascript function called when saving the form. If the function returns false, that means the save failed; otherwise, it should return true. + //The save validators are responsible for displaying any alerts + public function getSaveValidatorName(){ + return ""; + } + + //this function is called in the header; you can place scripts here (like whatever getShowHideCallbackName() returns) etc. + protected function showExtraScripts(){} + + //called when displaying the user form; used for validation scripts, etc. + public function showUserScripts(){ + if($this->getTypeName() == "basic"){ + ?> + + getTypeName() == "basic") return 'fm_base_required_validator'; //this validator is defined in fm_showControlScripts() + return ""; + } + + //gets the name of a general validator function, which is passed the form ID,item's unique name, and whatever is stored in $item['extra']['validation'] + public function getGeneralValidatorName(){ + return ""; + } + + public function getGeneralValidatorMessage($type){ + return ""; + } + + //called when processing a submission from the user version of the form; $itemInfo is an associative array of the db row defining the form item + public function processPost($uniqueName, $itemInfo){ + if($_POST[$uniqueName] != null) + return strip_tags($_POST[$uniqueName]); + return ""; + } + + //called when viewing submission data. $data contains (hopefully) the same value (in string form) as the value returned from processPost() + public function parseData($uniqueName, $itemInfo, $data){ + return $data; + } + + //returns an associative array keyed by the item db fields; used in the AJAX for creating a new form item in the back end / admin side + public function itemDefaults(){ + $itemInfo = array(); + $itemInfo['label'] = __("Item Label", 'wordpress-form-manager'); + $itemInfo['description'] = __("Item Description", 'wordpress-form-manager'); + $itemInfo['extra'] = array(); + $itemInfo['nickname'] = __("Item Nickname", 'wordpress-form-manager'); + $itemInfo['required'] = 0; + $itemInfo['validator'] = ""; + $ItemInfo['validation_msg'] = ""; + $itemInfo['db_type'] = "VARCHAR(1000) DEFAULT ''"; + + return $itemInfo; + } + + //item keys that are handled in the 'panel' + protected function getPanelKeys(){ + return array(); + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + public function showScripts(){ + $this->showExtraScripts(); + $this->showPanelScript(); + } + protected function getPanelScriptName(){ + return "fm_".$this->getTypeName()."_panel_get"; + } + protected function extraScriptHelper($items){ + $str = "\"array("; + foreach($items as $k=>$v){ + if(strpos($v, "cb:") !== false) + $items[$k] = "'{$k}'=>'\" + ".$this->checkboxScriptHelper(substr($v,3), array('onValue'=>'checked', 'offValue'=>""))." + \"'"; + else + $items[$k] = "'{$k}'=>'\" + fm_fix_str(fm_get_item_value(itemID, '{$v}')) + \"'"; + } + $str.=implode(", ",$items); + $str.= ")\""; + return $str; + } + //$options: 'onValue', 'offValue' + protected function checkboxScriptHelper($name, $options = null){ + if($options == null) $options = array('onValue'=>'1', 'offValue'=>'0'); + return "((document.getElementById(itemID + '-{$name}').checked==true)?'".$options['onValue']."':'".$options['offValue']."')"; + } + protected function getPanelScriptOptionDefaults(){ + global $fmdb; + $opt=array(); + foreach($fmdb->itemKeys as $key=>$value){ + $opt[$key] = "fm_get_item_value(itemID, '{$key}')"; + } + $opt['index'] = 'index'; + $opt['extra'] = "\"array()\""; + return $opt; + } + public function showPanelScript(){ + $items=array(); + $items['unique_name'] = 'itemID'; + $items['index'] = 'index'; + $items = array_merge($items, $this->getPanelScriptOptions()); + foreach($items as $k=>$v){ + $items[$k] = "'{$k}': {$v}"; + } + ?>". + "". + "".(($itemInfo['required']=='1')?'*':"")."". + "".$this->editItem($uniqueName, $itemInfo)."". + ""; + $str.=""; + $str.="
".$this->editPanel($uniqueName, $itemInfo)."
"; + $str.= $this->showHiddenVars($uniqueName, $itemInfo, $this->getPanelKeys(), $this->getPanelScriptName()."(itemID, index)"); + return $str; + } + + public function editPanel($uniqueName, $itemInfo){ + global $fm_editPanelItems; + $str=""; + $str.=""; + $str.=""; + $items = $this->getPanelItems($uniqueName, $itemInfo); + foreach($items as $item){ + $str.=$item->getPanelItem(); + } + $str.="

"; + return $str; + } + + function showHiddenVars($uniqueName, $itemInfo, $hideKeys = null, $script = "fm_base_get(itemID, index)"){ + global $fmdb; + $itemInfo['extra'] = serialize($itemInfo['extra']); + if($hideKeys==null) $hideKeys = array(); + $str.= $this->getScriptHidden($uniqueName, $script)."\n"; + $str.= $this->getTypeHidden($uniqueName, $itemInfo); + foreach($fmdb->itemKeys as $key=>$value){ + if(!in_array($key,$hideKeys,true)) + $str.= ""; + } + return $str; + } + + protected function getScriptHidden($uniqueName, $script){ + return ""; + } + protected function getHiddenValue($uniqueName, $key, $value){ + return ""; + } + protected function getTypeHidden($uniqueName, $itemInfo){ + return ""; + } +} + +?> \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/blank.php b/src/wp-content/plugins/wordpress-form-manager/types/blank.php new file mode 100644 index 00000000..ae68d7a3 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/blank.php @@ -0,0 +1,80 @@ + $itemInfo['label'])); + /* + $arr[] = new fm_editPanelItemBase($uniqueName, 'value', 'Default Value', array('value' => $itemInfo['extra']['value'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'size', 'Width (in pixels)', array('value' => $itemInfo['extra']['size'])); + $arr[] = new fm_editPanelItemCheckbox($uniqueName, 'required', 'Required', array('checked'=>$itemInfo['required'])); + $arr[] = new fm_editPanelItemDropdown($uniqueName, 'validation', 'Validation', array('options' => array_merge(array('none' => "..."), $this->getValidatorList()), 'value' => $itemInfo['extra']['validation'])); + */ + return $arr; + } + + public function getPanelScriptOptions(){ + $opt = $this->getPanelScriptOptionDefaults(); + /*$opt['extra'] = $this->extraScriptHelper(array('value'=>'value', 'size'=>'size', 'validation'=>'validation')); + $opt['required'] = $this->checkboxScriptHelper('required'); + */ + return $opt; + } + + public function getShowHideCallbackName(){ + return "fm_".$this->getTypeName()."_show_hide"; + } + + /* + public function getRequiredValidatorName(){ + return 'fm_base_required_validator'; + }*/ + + protected function showExtraScripts(){ + ?> + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/checkbox.php b/src/wp-content/plugins/wordpress-form-manager/types/checkbox.php new file mode 100644 index 00000000..9a5d7fa8 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/checkbox.php @@ -0,0 +1,100 @@ + 'checkbox', + 'attributes' => array('name' => $uniqueName, + 'id'=> $uniqueName, + 'style'=> ($itemInfo['extra']['position'] == "right" ? "float:right;" : "") + ), + 'checked'=> ($itemInfo['extra']['value']=='checked') + ); + return fe_getElementHTML($elem); + } + + public function processPost($uniqueName, $itemInfo){ + if(isset($_POST[$uniqueName])) + return $_POST[$uniqueName]=="on"?__("yes",'wordpress-form-manager'):__("no",'wordpress-form-manager'); + return __("no",'wordpress-form-manager'); + } + + public function editItem($uniqueName, $itemInfo){ + return ""; + } + + public function getPanelItems($uniqueName, $itemInfo){ + $arr=array(); + $arr[] = new fm_editPanelItemBase($uniqueName, 'label', __('Label', 'wordpress-form-manager'), array('value' => $itemInfo['label'])); + $arr[] = new fm_editPanelItemDropdown($uniqueName, 'position', __('Position', 'wordpress-form-manager'), array('options' => array('left' => __("Left", 'wordpress-form-manager'), 'right' => __("Right", 'wordpress-form-manager')), 'value' => $itemInfo['extra']['position'])); + $arr[] = new fm_editPanelItemCheckbox($uniqueName, 'value', __('Checked by Default', 'wordpress-form-manager'), array('checked'=>($itemInfo['extra']['value']=='checked'))); + $arr[] = new fm_editPanelItemCheckbox($uniqueName, 'required', __('Required', 'wordpress-form-manager'), array('checked'=>$itemInfo['required'])); + return $arr; + } + + public function getPanelScriptOptions(){ + $opt = $this->getPanelScriptOptionDefaults(); + $opt['extra'] = "\"array('value' => '\" + ".$this->checkboxScriptHelper('value',array('onValue'=>'checked', 'offValue'=>""))." + \"', 'position' => '\" + fm_fix_str(fm_get_item_value(itemID, 'position')) + \"')\""; + $opt['required'] = $this->checkboxScriptHelper('required'); + return $opt; + } + + public function getShowHideCallbackName(){ + return "fm_".$this->getTypeName()."_show_hide"; + } + + protected function showExtraScripts(){ + ?> + + + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/file.php b/src/wp-content/plugins/wordpress-form-manager/types/file.php new file mode 100644 index 00000000..7f72336b --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/file.php @@ -0,0 +1,186 @@ +". + ""; + } + + public function itemDefaults(){ + $itemInfo = array(); + $itemInfo['label'] = __("New File Upload", 'wordpress-form-manager'); + $itemInfo['description'] = __("Item Description", 'wordpress-form-manager'); + $itemInfo['extra'] = array('max_size' => 1000); + $itemInfo['nickname'] = ''; + $itemInfo['required'] = 0; + $itemInfo['validator'] = ""; + $ItemInfo['validation_msg'] = ""; + $itemInfo['db_type'] = "LONGBLOB"; + + return $itemInfo; + } + + public function editItem($uniqueName, $itemInfo){ + return ""; + } + + public function processPost($uniqueName, $itemInfo){ + global $fmdb; + + if($_FILES[$uniqueName]['error'] > 0){ + if($_FILES[$uniqueName]['error'] == 2) + $fmdb->setErrorMessage("(".$itemInfo['label'].") ".__("File upload exceeded maximum allowable size.", 'wordpress-form-manager')); + else if($_FILES[$uniqueName]['error'] == 4) // no file + return ""; + $fmdb->setErrorMessage("(".$itemInfo['label'].") ".__("There was an error with the file upload.", 'wordpress-form-manager')); + return false; + } + + $ext = pathinfo($_FILES[$uniqueName]['name'], PATHINFO_EXTENSION); + if(strpos($itemInfo['extra']['exclude'], $ext) !== false){ + /* translators: this will be shown along with the item label and file extension, as in, "(File Upload) Cannot be of type '.txt'" */ + $fmdb->setErrorMessage("(".$itemInfo['label'].") ".__("Cannot be of type", 'wordpress-form-manager')." '.".$ext."'"); + return false; + } + else if(trim($itemInfo['extra']['restrict'] != "") && strpos($itemInfo['extra']['restrict'], $ext) === false){ + /* translators: this will be shown along with the item label and a list of file extensions, as in, "(File Upload) Can only be of types '.txt, .doc, .pdf'" */ + $fmdb->setErrorMessage("(".$itemInfo['label'].") ".__("Can only be of types", 'wordpress-form-manager')." ".$itemInfo['extra']['restrict']); + return false; + } + + if(trim($itemInfo['extra']['upload_dir']) == ""){ //keep the upload in the form manager database + $filename = $_FILES[$uniqueName]['tmp_name']; + $handle = fopen($filename, "rb"); + $contents = fread($handle, filesize($filename)); + fclose($handle); + + $saveVal = array('filename' => $_FILES[$uniqueName]['name'], + 'contents' => $contents, + 'size' => $_FILES[$uniqueName]['size']); + + return addslashes(serialize($saveVal)); + } + else{ + //make sure to add a trailing slash if this was forgotten. + $uploadDir = $this->parseUploadDir($itemInfo['extra']['upload_dir']); + $pathInfo = pathinfo($_FILES[$uniqueName]['name']); + $newFileName = substr($_FILES[$uniqueName]['name'], 0, (-1*(strlen($pathInfo['extension'])+1))).' ('.date('m-d-y-h-i-s').').'.$pathInfo['extension']; + + move_uploaded_file($_FILES[$uniqueName]['tmp_name'], $uploadDir.$newFileName); + $saveVal = array('filename' => $newFileName, + 'contents' => '', + 'upload_dir' => true, + 'size' => $_FILES[$uniqueName]['size']); + return addslashes(serialize($saveVal)); + } + } + + public function parseData($uniqueName, $itemInfo, $data){ + if(trim($data) == "") return ""; + $fileInfo = unserialize($data); + if($fileInfo['size'] < 1024) + $sizeStr = $fileInfo['size']." B"; + else + $sizeStr = ((int)($fileInfo['size']/1024))." kB"; + + if(!isset($fileInfo['upload_dir'])) + return $fileInfo['filename']." (".$sizeStr.")"; + elseif(trim($itemInfo['extra']['upload_url']) == "") + return $fileInfo['filename']." (".$sizeStr.")"; + else{ + $uploadURL = $this->parseUploadURL($itemInfo['extra']['upload_url']); + return ''.$fileInfo['filename'].' ('.$sizeStr.')'.''; + } + } + + public function parseUploadDir($dir){ + $dir = str_replace("%doc_root%", $_SERVER['DOCUMENT_ROOT'], $dir); + if(substr($dir, -1) != "/" && substr($dir, -1) != "\\") $dir.="/"; + return $dir; + } + + public function parseUploadURL($url){ + if(substr($url, -1) != "/") $url.="/"; + return $url; + } + + public function getPanelItems($uniqueName, $itemInfo){ + $arr=array(); + + $arr[] = new fm_editPanelItemBase($uniqueName, 'label', __('Label', 'wordpress-form-manager'), array('value' => $itemInfo['label'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'max_size', __('Max file size (in kB)', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['max_size'])); + $arr[] = new fm_editPanelItemNote($uniqueName, '', "".__("Your host restricts uploads to", 'wordpress-form-manager')." ".ini_get('upload_max_filesize')."B", ''); + $arr[] = new fm_editPanelItemNote($uniqueName, '', "".__("File Types", 'wordpress-form-manager')."", ''); + $arr[] = new fm_editPanelItemNote($uniqueName, '', "".__("Enter a list of extensions separated by commas, e.g. \".txt, .rtf, .doc\"", 'wordpress-form-manager')."", ''); + $arr[] = new fm_editPanelItemBase($uniqueName, 'restrict', __('Only allow', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['restrict'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'exclude', __('Do not allow', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['exclude'])); + $arr[] = new fm_editPanelItemNote($uniqueName, '', "
".__("Uploads", 'wordpress-form-manager')."
", ''); + $arr[] = new fm_editPanelItemBase($uniqueName, 'upload_dir', __('Upload directory', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['upload_dir'])); + if(trim($itemInfo['extra']['upload_dir']) != "" && !is_dir($this->parseUploadDir($itemInfo['extra']['upload_dir']))) + $arr[] = new fm_editPanelItemNote($uniqueName, '', "".__("This does not appear to be a valid directory", 'wordpress-form-manager')."", ''); + $arr[] = new fm_editPanelItemNote($uniqueName, '', "
".__("Using an upload directory will allow you to post links to uploaded files. Otherwise, Form Manager will manage the uploaded files for you in the database.", 'wordpress-form-manager')."
", ''); + $arr[] = new fm_editPanelItemBase($uniqueName, 'upload_url', __('Upload URL', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['upload_url'])); + $arr[] = new fm_editPanelItemNote($uniqueName, '', "".__("This will be the base URL used for links to the uploaded files. If left blank, no links will be generated.", 'wordpress-form-manager')."", ''); + + return $arr; + } + + public function getPanelScriptOptions(){ + $opt = $this->getPanelScriptOptionDefaults(); + $opt['extra'] = $this->extraScriptHelper(array('restrict' => 'restrict', 'exclude' => 'exclude', 'max_size' => 'max_size', 'upload_dir' => 'upload_dir', 'upload_url' => 'upload_url' )); + return $opt; + } + + public function getShowHideCallbackName(){ + return "fm_".$this->getTypeName()."_show_hide"; + } + + public function getSaveValidatorName(){ + return "fm_file_save_validator"; + } + + protected function showExtraScripts(){ + ?> + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/list.php b/src/wp-content/plugins/wordpress-form-manager/types/list.php new file mode 100644 index 00000000..3a6925e5 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/list.php @@ -0,0 +1,294 @@ + 'select'); + $itemInfo['nickname'] = ''; + $itemInfo['required'] = 0; + $itemInfo['validator'] = ""; + $ItemInfo['validation_msg'] = ""; + $itemInfo['db_type'] = "VARCHAR(255) DEFAULT ''"; + + return $itemInfo; + } + + public function showItem($uniqueName, $itemInfo){ + $fn = $itemInfo['extra']['list_type']."_showItem"; + return $this->$fn($uniqueName, $itemInfo). + "". + ""; + + } + public function select_showItem($uniqueName, $itemInfo, $disabled = false){ + $elem=array('type' => 'select', + 'attributes' => array('name' => $uniqueName, + 'id'=> $uniqueName, + 'style' => "width:".$itemInfo['extra']['size']."px;" + ), + 'value' => $itemInfo['extra']['value'], + 'options' => $itemInfo['extra']['options'] + ); + if($itemInfo['required'] == "1") + $elem['options'] = array_merge(array('-1' => "..."), $elem['options']); + if($disabled) + $elem['attributes']['disabled'] = 'disabled'; + return fe_getElementHTML($elem); + } + public function list_showItem($uniqueName, $itemInfo, $disabled = false){ + $elem=array('type' => 'select', + 'attributes' => array('name' => $uniqueName, + 'id'=> $uniqueName, + 'style' => "width:".$itemInfo['extra']['size']."px;", + 'size' => sizeof($itemInfo['extra']['options']) + ), + 'value' => $itemInfo['extra']['value'], + 'options' => $itemInfo['extra']['options'] + ); + if($disabled) + $elem['attributes']['disabled'] = 'disabled'; + return fe_getElementHTML($elem); + } + public function radio_showItem($uniqueName, $itemInfo, $disabled = false){ + $elem=array('type' => 'radio', + 'attributes' => array('name' => $uniqueName, + 'id'=> $uniqueName + ), + 'separator' => '
', + 'options' => $itemInfo['extra']['options'], + 'value' => $itemInfo['extra']['value'] + ); + if($disabled) + $elem['attributes']['disabled'] = 'disabled'; + return fe_getElementHTML($elem); + } + public function checkbox_showItem($uniqueName, $itemInfo, $disabled = false){ + $elem=array('type' => 'checkbox_list', + 'separator' => '
', + 'value' => $itemInfo['extra']['value'] + ); + $elem['options'] = array(); + for($x=0;$x'.fe_getElementHTML($elem).''; + } + + + public function editItem($uniqueName, $itemInfo){ + $fn = $itemInfo['extra']['list_type']."_showItem"; + unset($itemInfo['extra']['size']); + return "
".$this->$fn($uniqueName, $itemInfo, true)."
"; + } + + public function processPost($uniqueName, $itemInfo){ + $fn = $itemInfo['extra']['list_type']."_processPost"; + return $this->$fn($uniqueName, $itemInfo); + } + public function select_processPost($uniqueName, $itemInfo){ + if(isset($_POST[$uniqueName])){ + if($itemInfo['required'] == "1") + return addslashes($itemInfo['extra']['options'][$_POST[$uniqueName]-1]); + else + return addslashes($itemInfo['extra']['options'][$_POST[$uniqueName]]); + } + return ""; + } + public function list_processPost($uniqueName, $itemInfo){ + return $this->select_processPost($uniqueName, $itemInfo); + } + public function radio_processPost($uniqueName, $itemInfo){ + if(isset($_POST[$uniqueName])) + return addslashes($itemInfo['extra']['options'][$_POST[$uniqueName]]); + return ""; + } + public function checkbox_processPost($uniqueName, $itemInfo){ + $arr=array(); + for($x=0;$x $itemInfo['label'])); + $arr[] = new fm_editPanelItemDropdown($uniqueName, 'list_type', __('Style', 'wordpress-form-manager'), array('options' => array('select' => __("Dropdown", 'wordpress-form-manager'), 'list' => __("List Box", 'wordpress-form-manager'), 'radio' => __("Radio Buttons", 'wordpress-form-manager'), 'checkbox' => __("Checkboxes", 'wordpress-form-manager')), 'value' => $itemInfo['extra']['list_type'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'size', __('Width (in pixels)', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['size'])); + $arr[] = new fm_editPanelItemCheckbox($uniqueName, 'required', __('Required', 'wordpress-form-manager'), array('checked'=>$itemInfo['required'])); + $arr[] = new fm_editPanelItemMulti($uniqueName, 'options', __('List Items', 'wordpress-form-manager'), array('options' => $itemInfo['extra']['options'], 'get_item_script' => 'fm_custom_list_options_panel_item', 'get_item_value_script' => 'fm_custom_list_option_get')); + return $arr; + } + + public function getPanelScriptOptions(){ + $opt = $this->getPanelScriptOptionDefaults(); + $opt['extra'] = "\"array('options' => \" + js_multi_item_get_php_array('multi-panel-' + itemID, 'fm_custom_list_option_get') + \", 'size' => '\" + fm_get_item_value(itemID, 'size') + \"', 'list_type' => '\" + fm_get_item_value(itemID, 'list_type') + \"')\""; + $opt['required'] = $this->checkboxScriptHelper('required'); + + return $opt; + } + + //called when displaying the user form; used for validation scripts, etc. + public function showUserScripts(){ + ?> + + + ".htmlspecialchars(fm_restrictString($itemInfo['extra']['content'], 25)).""; } + + public function getPanelItems($uniqueName, $itemInfo){ + $arr=array(); + $arr[] = new fm_editPanelItemBase($uniqueName, 'label', 'Label', array('value' => $itemInfo['label'])); + $arr[] = new fm_editPanelTextarea($uniqueName, 'content', 'Note', array('value' => $itemInfo['extra']['content'], 'rows'=> 10, 'cols' => 25)); + $arr[] = new fm_editPanelItemCheckbox($uniqueName, 'allow_markup', __('HTML', 'wordpress-form-manager'), array('checked'=>$itemInfo['extra']['allow_markup'])); + return $arr; + } + + public function getPanelKeys(){ + return array('label'); + } + + public function getShowHideCallbackName(){ + return "fm_note_show_hide"; + } + + protected function showExtraScripts(){ + ?> + getPanelScriptOptionDefaults(); + //$opt['extra'] = $this->extraScriptHelper(array('content'=>'content')); + $opt['extra'] = "\"array('allow_markup' => '\" + ".$this->checkboxScriptHelper('allow_markup',array('onValue'=>'checked', 'offValue'=>""))." + \"', 'content' => '\" + fm_fix_str(fm_get_item_value(itemID, 'content')) + \"')\""; + // $opt['extra'] = "\"array('value' => '\" + ".$this->checkboxScriptHelper('value',array('onValue'=>'checked', 'offValue'=>""))." + \"')\""; + return $opt; + } + public function itemDefaults(){ + $itemInfo = array(); + $itemInfo['label'] = __("New Note", 'wordpress-form-manager'); + $itemInfo['description'] = __("Item Description", 'wordpress-form-manager'); + $itemInfo['extra'] = array('content'=>''); + $itemInfo['nickname'] = ''; + $itemInfo['required'] = 0; + $itemInfo['validator'] = ""; + $ItemInfo['validation_msg'] = ""; + $itemInfo['db_type'] = "NONE"; + + return $itemInfo; + } +} +?> \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/panelhelper.php b/src/wp-content/plugins/wordpress-form-manager/types/panelhelper.php new file mode 100644 index 00000000..1d70621c --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/panelhelper.php @@ -0,0 +1,100 @@ +uniqueName = $uniqueName; + $this->itemName = $itemName; + $this->itemLabel = $itemLabel; + $this->options = $options; + $this->notags = $notags; + } + function getPanelItem(){ + $str = ""; + if(!$this->notags) $str.=""; + $str.= ""; + if(!$this->notags) $str.=""; + $str.=$this->getPanelItemInner(); + if(!$this->notags) $str.=""; + return $str; + } + function getPanelItemInner(){ + return "uniqueName}-{$this->itemName}\" value=\"".htmlspecialchars($this->options['value'])."\" />"; + } +} + +class fm_editPanelItemMultiText extends fm_editPanelItemBase{ + function getPanelItemInner(){ + $arr = array(); + $x=0; + foreach($this->options['fields'] as $field){ + $arr[] = "{$field['label']}uniqueName}-{$field['name']}\" value=\"".htmlspecialchars($this->options['value'][$field['name']])."\" style=\"width:{$field['size']};\">"; + } + return implode($this->options['separator'], $arr); + } +} + +class fm_editPanelTextArea extends fm_editPanelItemBase{ + function getPanelItemInner(){ + return ""; + } +} + +class fm_editPanelItemCheckbox extends fm_editPanelItemBase{ + //$options: + // 'checked': value of 'checked' attribute (true/false, 1/0) + function getPanelItemInner(){ + return "uniqueName}-{$this->itemName}\" ".(($this->options['checked']==true || $this->options['checked']==1)?"checked=\"checked\"":"")."/>"; + } +} + +class fm_editPanelItemDropdown extends fm_editPanelItemBase{ + function getPanelItemInner(){ + $str=""; + return $str; + } +} + +class fm_editPanelItemMulti extends fm_editPanelItemBase{ + function getPanelItemInner(){ + $str.=""; + /* translators: this is for the list element options */ + $str.=""; + $str.="
uniqueName}','".$this->options['get_item_value_script']."','".$this->options['get_item_script']."')\"/>
"; + $str.="
    uniqueName}\">"; + $str.="
"; + $str.=""; + $str.="
"; + $str.="uniqueName}','".$this->options['get_item_script']."','')\"/>"; + $str.="
"; + $str.=""; + return $str; + } +} + +class fm_editPanelItemNote extends fm_editPanelItemBase{ + function getPanelItem(){ + return "". + $this->itemLabel. + ""; + } +} +?> \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/recaptcha.php b/src/wp-content/plugins/wordpress-form-manager/types/recaptcha.php new file mode 100644 index 00000000..13ba74e9 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/recaptcha.php @@ -0,0 +1,106 @@ +getGlobalSetting('recaptcha_public'); + if($publickey == "") return __("(No reCAPTCHA API public key found)", 'wordpress-form-manager'); + + if(!function_exists('recaptcha_get_html')) + require_once('recaptcha/recaptchalib.php'); + + return "". + recaptcha_get_html($publickey). + (isset($_POST['recaptcha_challenge_field'])?"
".__("The reCAPTCHA was incorrect.", 'wordpress-form-manager')." ":""); + } + + public function processPost($uniqueName, $itemInfo){ + global $fmdb; + $publickey = $fmdb->getGlobalSetting('recaptcha_public'); + $privatekey = $fmdb->getGlobalSetting('recaptcha_private'); + if($privatekey == "" || $publickey == "" ) return ""; + + if(!function_exists('recaptcha_check_answer')) + require_once('recaptcha/recaptchalib.php'); + + $resp = recaptcha_check_answer ($privatekey, + $_SERVER["REMOTE_ADDR"], + $_POST["recaptcha_challenge_field"], + $_POST["recaptcha_response_field"]); + + //return false; + if (!$resp->is_valid === true) { + // What happens when the CAPTCHA was entered incorrectly + $this->err = $resp->error; + return false; + } + $this->err = false; + return ""; + } + + public function itemDefaults(){ + $itemInfo = array(); + $itemInfo['label'] = "New reCAPTCHA"; + $itemInfo['description'] = "Item Description"; + $itemInfo['extra'] = array(); + $itemInfo['nickname'] = ''; + $itemInfo['required'] = 0; + $itemInfo['validator'] = ""; + $ItemInfo['validation_msg'] = ""; + $itemInfo['db_type'] = "NONE"; + + return $itemInfo; + } + + public function editItem($uniqueName, $itemInfo){ + global $fmdb; + $publickey = $fmdb->getGlobalSetting('recaptcha_public'); + $privatekey = $fmdb->getGlobalSetting('recaptcha_private'); + if($publickey == "" || $privatekey == "") return __("You need reCAPTCHA API keys.", 'wordpress-form-manager')."
".__("Fix this in", 'wordpress-form-manager')." ".__("Settings", 'wordpress-form-manager')."."; + return __("(reCAPTCHA field)", 'wordpress-form-manager'); + } + + public function getPanelItems($uniqueName, $itemInfo){ + $arr=array(); + $arr[] = new fm_editPanelItemBase($uniqueName, 'label', __('Label', 'wordpress-form-manager'), array('value' => $itemInfo['label'])); + return $arr; + } + + public function getPanelScriptOptions(){ + $opt = $this->getPanelScriptOptionDefaults(); + return $opt; + } + + public function getShowHideCallbackName(){ + return "fm_".$this->getTypeName()."_show_hide"; + } + + protected function showExtraScripts(){ + ?> + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/recaptcha/recaptchalib.php b/src/wp-content/plugins/wordpress-form-manager/types/recaptcha/recaptchalib.php new file mode 100644 index 00000000..32c4f4d7 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/recaptcha/recaptchalib.php @@ -0,0 +1,277 @@ + $value ) + $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; + + // Cut the last '&' + $req=substr($req,0,strlen($req)-1); + return $req; +} + + + +/** + * Submits an HTTP POST to a reCAPTCHA server + * @param string $host + * @param string $path + * @param array $data + * @param int port + * @return array response + */ +function _recaptcha_http_post($host, $path, $data, $port = 80) { + + $req = _recaptcha_qsencode ($data); + + $http_request = "POST $path HTTP/1.0\r\n"; + $http_request .= "Host: $host\r\n"; + $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; + $http_request .= "Content-Length: " . strlen($req) . "\r\n"; + $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; + $http_request .= "\r\n"; + $http_request .= $req; + + $response = ''; + if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { + die ('Could not open socket'); + } + + fwrite($fs, $http_request); + + while ( !feof($fs) ) + $response .= fgets($fs, 1160); // One TCP-IP packet + fclose($fs); + $response = explode("\r\n\r\n", $response, 2); + + return $response; +} + + + +/** + * Gets the challenge HTML (javascript and non-javascript version). + * This is called from the browser, and the resulting reCAPTCHA HTML widget + * is embedded within the HTML form it was called from. + * @param string $pubkey A public key for reCAPTCHA + * @param string $error The error given by reCAPTCHA (optional, default is null) + * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) + + * @return string - The HTML to be embedded in the user's form. + */ +function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) +{ + if ($pubkey == null || $pubkey == '') { + die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); + } + + if ($use_ssl) { + $server = RECAPTCHA_API_SECURE_SERVER; + } else { + $server = RECAPTCHA_API_SERVER; + } + + $errorpart = ""; + if ($error) { + $errorpart = "&error=" . $error; + } + return ' + + '; +} + + + + +/** + * A ReCaptchaResponse is returned from recaptcha_check_answer() + */ +class ReCaptchaResponse { + var $is_valid; + var $error; +} + + +/** + * Calls an HTTP POST function to verify if the user's guess was correct + * @param string $privkey + * @param string $remoteip + * @param string $challenge + * @param string $response + * @param array $extra_params an array of extra variables to post to the server + * @return ReCaptchaResponse + */ +function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) +{ + if ($privkey == null || $privkey == '') { + die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); + } + + if ($remoteip == null || $remoteip == '') { + die ("For security reasons, you must pass the remote ip to reCAPTCHA"); + } + + + + //discard spam submissions + if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { + $recaptcha_response = new ReCaptchaResponse(); + $recaptcha_response->is_valid = false; + $recaptcha_response->error = 'incorrect-captcha-sol'; + return $recaptcha_response; + } + + $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", + array ( + 'privatekey' => $privkey, + 'remoteip' => $remoteip, + 'challenge' => $challenge, + 'response' => $response + ) + $extra_params + ); + + $answers = explode ("\n", $response [1]); + $recaptcha_response = new ReCaptchaResponse(); + + if (trim ($answers [0]) == 'true') { + $recaptcha_response->is_valid = true; + } + else { + $recaptcha_response->is_valid = false; + $recaptcha_response->error = $answers [1]; + } + return $recaptcha_response; + +} + +/** + * gets a URL where the user can sign up for reCAPTCHA. If your application + * has a configuration page where you enter a key, you should provide a link + * using this function. + * @param string $domain The domain where the page is hosted + * @param string $appname The name of your application + */ +function recaptcha_get_signup_url ($domain = null, $appname = null) { + return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname)); +} + +function _recaptcha_aes_pad($val) { + $block_size = 16; + $numpad = $block_size - (strlen ($val) % $block_size); + return str_pad($val, strlen ($val) + $numpad, chr($numpad)); +} + +/* Mailhide related code */ + +function _recaptcha_aes_encrypt($val,$ky) { + if (! function_exists ("mcrypt_encrypt")) { + die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); + } + $mode=MCRYPT_MODE_CBC; + $enc=MCRYPT_RIJNDAEL_128; + $val=_recaptcha_aes_pad($val); + return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); +} + + +function _recaptcha_mailhide_urlbase64 ($x) { + return strtr(base64_encode ($x), '+/', '-_'); +} + +/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ +function recaptcha_mailhide_url($pubkey, $privkey, $email) { + if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { + die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . + "you can do so at http://www.google.com/recaptcha/mailhide/apikey"); + } + + + $ky = pack('H*', $privkey); + $cryptmail = _recaptcha_aes_encrypt ($email, $ky); + + return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); +} + +/** + * gets the parts of the email to expose to the user. + * eg, given johndoe@example,com return ["john", "example.com"]. + * the email is then displayed as john...@example.com + */ +function _recaptcha_mailhide_email_parts ($email) { + $arr = preg_split("/@/", $email ); + + if (strlen ($arr[0]) <= 4) { + $arr[0] = substr ($arr[0], 0, 1); + } else if (strlen ($arr[0]) <= 6) { + $arr[0] = substr ($arr[0], 0, 3); + } else { + $arr[0] = substr ($arr[0], 0, 4); + } + return $arr; +} + +/** + * Gets html to display an email address given a public an private key. + * to get a key, go to: + * + * http://www.google.com/recaptcha/mailhide/apikey + */ +function recaptcha_mailhide_html($pubkey, $privkey, $email) { + $emailparts = _recaptcha_mailhide_email_parts ($email); + $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); + + return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); + +} + + +?> diff --git a/src/wp-content/plugins/wordpress-form-manager/types/separator.php b/src/wp-content/plugins/wordpress-form-manager/types/separator.php new file mode 100644 index 00000000..d10aaf20 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/separator.php @@ -0,0 +1,53 @@ +"; } + + public function editItem($uniqueName, $itemInfo){ return "
"; } + + public function getPanelItems($uniqueName, $itemInfo){ + $arr=array(); + $arr[] = new fm_editPanelItemBase($uniqueName, 'label', __('Label', 'wordpress-form-manager'), array('value' => $itemInfo['label'])); + return $arr; + } + + public function getPanelKeys(){ + return array('label'); + } + + public function getShowHideCallbackName(){ + return "fm_sep_show_hide"; + } + + protected function showExtraScripts(){ + ?> + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/text.php b/src/wp-content/plugins/wordpress-form-manager/types/text.php new file mode 100644 index 00000000..53faa5dc --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/text.php @@ -0,0 +1,134 @@ +validators = array(); + } + + public function getTypeName(){ return "text"; } + + /* translators: this appears in the 'Add Form Element' menu */ + public function getTypeLabel(){ return __("Text", 'wordpress-form-manager'); } + + public function showItem($uniqueName, $itemInfo){ + $elem=array('type' => 'text', + 'attributes' => array('name' => $uniqueName, + 'id'=> $uniqueName, + 'placeholder' => htmlspecialchars($itemInfo['extra']['value']), + 'style' => "width:".$itemInfo['extra']['size']."px;", + 'maxlength' => $itemInfo['extra']['maxlength'] + ) + ); + + return fe_getElementHTML($elem); + } + + //returns an associative array keyed by the item db fields; used in the AJAX for creating a new form item in the back end / admin side + public function itemDefaults(){ + $itemInfo = array(); + $itemInfo['label'] = __("New Text", 'wordpress-form-manager'); + $itemInfo['description'] = __("Item Description", 'wordpress-form-manager'); + $itemInfo['extra'] = array('size' => '300'); + $itemInfo['nickname'] = ''; + $itemInfo['required'] = 0; + $itemInfo['validator'] = ""; + $ItemInfo['validation_msg'] = ""; + $itemInfo['db_type'] = "VARCHAR(1000) DEFAULT ''"; + + return $itemInfo; + } + + public function editItem($uniqueName, $itemInfo){ + return ""; + } + + public function getPanelItems($uniqueName, $itemInfo){ + $arr=array(); + $arr[] = new fm_editPanelItemBase($uniqueName, 'label', __('Label', 'wordpress-form-manager'), array('value' => $itemInfo['label'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'value', __('Placeholder', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['value'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'size', __('Width (in pixels)', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['size'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'maxlength', __('Max characters', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['maxlength'])); + $arr[] = new fm_editPanelItemCheckbox($uniqueName, 'required', __('Required', 'wordpress-form-manager'), array('checked'=>$itemInfo['required'])); + $arr[] = new fm_editPanelItemDropdown($uniqueName, 'validation', __('Validation', 'wordpress-form-manager'), array('options' => array_merge(array('none' => "..."), $this->getValidatorList()), 'value' => $itemInfo['extra']['validation'])); + return $arr; + } + + public function getPanelScriptOptions(){ + $opt = $this->getPanelScriptOptionDefaults(); + $opt['extra'] = $this->extraScriptHelper(array('value'=>'value', 'size'=>'size', 'validation'=>'validation', 'maxlength'=>'maxlength')); + $opt['required'] = $this->checkboxScriptHelper('required'); + return $opt; + } + + public function getShowHideCallbackName(){ + return "fm_".$this->getTypeName()."_show_hide"; + } + + public function getRequiredValidatorName(){ + return 'fm_base_required_validator'; + } + + public function getGeneralValidatorName(){ + return 'fm_text_validation'; + } + + public function getGeneralValidatorMessage($type){ + return $this->validators[$type]['message']; + } + + protected function showExtraScripts(){ + ?> + validators as $val){ + $list[$val['name']] = $val['label']; + } + return $list; + } + + public function initValidators(){ + global $fmdb; + $this->validators = $fmdb->getTextValidators(); + } +} + + +?> \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/types/textarea.php b/src/wp-content/plugins/wordpress-form-manager/types/textarea.php new file mode 100644 index 00000000..5358d0b3 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/types/textarea.php @@ -0,0 +1,95 @@ + 'textarea', + 'default' => $itemInfo['extra']['value'], + 'attributes' => array('name' => $uniqueName, + 'id'=> $uniqueName, + 'style' => "width:".$itemInfo['extra']['cols']."px;height:".$itemInfo['extra']['rows']."px;" + ) + ); + return fe_getElementHTML($elem); + } + + public function itemDefaults(){ + $itemInfo = array(); + $itemInfo['label'] = __("New Text Area", 'wordpress-form-manager'); + $itemInfo['description'] = __("Item Description", 'wordpress-form-manager'); + $itemInfo['extra'] = array('cols'=>'300', 'rows' => '100'); + $itemInfo['nickname'] = ''; + $itemInfo['required'] = 0; + $itemInfo['validator'] = ""; + $ItemInfo['validation_msg'] = ""; + $itemInfo['db_type'] = "TEXT"; + + return $itemInfo; + } + + public function editItem($uniqueName, $itemInfo){ + $elem=array('type' => 'textarea', + 'default' => $itemInfo['extra']['value'], + 'attributes' => array('name' => $uniqueName."-edit-value", + 'id'=> $uniqueName."-edit-value", + 'rows'=> 2, + 'cols'=> 18, + 'readonly' => 'readonly' + ) + ); + return fe_getElementHTML($elem); + } + + public function getPanelItems($uniqueName, $itemInfo){ + $arr=array(); + $arr[] = new fm_editPanelItemBase($uniqueName, 'label', __('Label', 'wordpress-form-manager'), array('value' => $itemInfo['label'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'value', __('Default Value', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['value'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'rows', __('Height (in pixels)', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['rows'])); + $arr[] = new fm_editPanelItemBase($uniqueName, 'cols', __('Width (in pixels)', 'wordpress-form-manager'), array('value' => $itemInfo['extra']['cols'])); + $arr[] = new fm_editPanelItemCheckbox($uniqueName, 'required', __('Required', 'wordpress-form-manager'), array('checked'=>$itemInfo['required'])); + return $arr; + } + + public function getPanelScriptOptions(){ + $opt = $this->getPanelScriptOptionDefaults(); + $opt['extra'] = $this->extraScriptHelper(array('value'=>'value', 'rows'=>'rows', 'cols'=>'cols')); + $opt['required'] = $this->checkboxScriptHelper('required'); + + return $opt; + } + + public function getShowHideCallbackName(){ + return "fm_textarea_show_hide"; + } + + public function getRequiredValidatorName(){ + return 'fm_base_required_validator'; + } + + protected function showExtraScripts(){ + ?> + \ No newline at end of file diff --git a/src/wp-content/plugins/wordpress-form-manager/wordpress-form-manager.php b/src/wp-content/plugins/wordpress-form-manager/wordpress-form-manager.php new file mode 100644 index 00000000..e83975b8 --- /dev/null +++ b/src/wp-content/plugins/wordpress-form-manager/wordpress-form-manager.php @@ -0,0 +1,417 @@ +db_version(), '5.0.3', '<') ) + wp_die( __('Form manager requires MySQL version 5.0.3 or higher', 'wordpress-form-manager') ); + +include 'helpers.php'; + +include 'db.php'; +include 'display.php'; +include 'template.php'; +include 'email.php'; +include 'formdefinition.php'; + +/**************************************************************/ +/******* PLUGIN OPTIONS ***************************************/ + +if(get_option('fm-shortcode') === false) + update_option("fm-shortcode", "form"); +if(get_option('fm-enable-mce-button') === false) + update_option("fm-enable-mce-button", "YES"); + +update_option("fm-forms-table-name", "fm_forms"); +update_option("fm-items-table-name", "fm_items"); +update_option("fm-settings-table-name", "fm_settings"); +update_option("fm-templates-table-name", "fm_templates"); +update_option("fm-data-table-prefix", "fm_data"); +update_option("fm-query-table-prefix", "fm_queries"); +update_option("fm-default-form-template", "fm-form-default.php"); +update_option("fm-default-summary-template", "fm-summary-default.php"); +update_option("fm-temp-dir", "tmp"); +update_option("fm-data-shortcode", "formdata"); + +global $wpdb; +global $fmdb; +global $fm_display; +global $fm_templates; + +$fmdb = new fm_db_class($wpdb->prefix.get_option('fm-forms-table-name'), + $wpdb->prefix.get_option('fm-items-table-name'), + $wpdb->prefix.get_option('fm-settings-table-name'), + $wpdb->prefix.get_option('fm-templates-table-name'), + $wpdb->dbh + ); +$fm_display = new fm_display_class(); +$fm_templates = new fm_template_manager(); + +/**************************************************************/ +/******* DATABASE SETUP ***************************************/ + +function fm_install(){ + global $fmdb; + global $fm_currentVersion; + + //from any version before 1.4.0; must be done before the old columns are removed + $fmdb->convertAppearanceSettings(); + + //initialize the database + $fmdb->setupFormManager(); + + // covers updates from 1.3.0 + $q = "UPDATE `{$fmdb->formsTable}` SET `behaviors` = 'reg_user_only,display_summ,single_submission' WHERE `behaviors` = 'reg_user_only,no_dup'"; + $fmdb->query($q); + $q = "UPDATE `{$fmdb->formsTable}` SET `behaviors` = 'reg_user_only,display_summ,edit' WHERE `behaviors` = 'reg_user_only,no_dup,edit'"; + $fmdb->query($q); + + //updates from 1.4.10 and previous + $fmdb->fixTemplatesTableModified(); + + // covers versions up to and including 1.3.10 + $fmdb->fixCollation(); + + $fmdb->updateDataTables(); + + $fmdb->fixDBTypeBug(); + + update_option('fm-version', $fm_currentVersion); +} +register_activation_hook(__FILE__,'fm_install'); + +//uninstall - delete the table(s). +function fm_uninstall(){ + global $fmdb; + $fmdb->removeFormManager(); + + delete_option('fm-shortcode'); + delete_option('fm-forms-table-name'); + delete_option('fm-items-table-name'); + delete_option('fm-settings-table-name'); + delete_option('fm-templates-table-name'); + delete_option('fm-data-table-prefix'); + delete_option('fm-query-table-prefix'); + delete_option('fm-default-form-template'); + delete_option('fm-default-summary-template'); + delete_option('fm-version'); + delete_option('fm-temp-dir'); + delete_option('fm-data-shortcode'); + delete_option('fm-enable-mce-button'); +} +register_uninstall_hook(__FILE__,'fm_uninstall'); + + +/**************************************************************/ +/******* HOUSEKEEPING *****************************************/ + +//delete .csv files on each login +add_action('wp_login', 'fm_cleanCSVData'); +function fm_cleanCSVData(){ + $dirName = @dirname(__FILE__)."/".get_option("fm-temp-dir"); + $dir = @opendir($dirName); + while($fname = @readdir($dir)) { + if(file_exists(dirname(__FILE__)."/".get_option("fm-temp-dir")."/".$fname)) + @unlink($dirName."/".$fname); + } + @closedir($dir); +} + +/**************************************************************/ +/******* INIT, SCRIPTS & CSS **********************************/ + +add_action('admin_init', 'fm_adminInit'); +function fm_adminInit(){ + global $fm_SLIMSTAT_EXISTS; + if(get_option('slimstat_secret') !== false) $fm_SLIMSTAT_EXISTS = true; +} + +add_action('admin_enqueue_scripts', 'fm_adminEnqueueScripts'); +function fm_adminEnqueueScripts(){ + wp_enqueue_script('form-manager-js', plugins_url('/js/scripts.js', __FILE__), array('scriptaculous')); + + wp_localize_script('form-manager-js', 'fm_I18n', array( 'save_with_deleted_items' => __("There may be (data) associated with the form item(s) you removed. Are you sure you want to save?", 'wordpress-form-manager'), + 'unsaved_changes' => __("Any unsaved changes will be lost. Are you sure?", 'wordpress-form-manager'), + 'click_here_to_download' => __("Click here to download", 'wordpress-form-manager'), + 'there_are_no_files' => __("There are no files to download", 'wordpress-form-manager'), + 'unable_to_create_zip' => __("Unable to create .ZIP file", 'wordpress-form-manager'), + 'move_button' => __("move", 'wordpress-form-manager'), + 'delete_button' => __("delete", 'wordpress-form-manager'), + 'enter_items_separated_by_commas' => __("Enter items separated by commas", 'wordpress-form-manager'), + 'hide_button' => __("hide", 'wordpress-form-manager'), + 'show_button' => __("show", 'wordpress-form-manager'), + 'add_test' => __("Add Test", 'conditions', 'wordpress-form-manager'), + 'add_item' => __("Add Item", 'conditions', 'wordpress-form-manager'), + 'applies_to' => __("Applies to", 'conditions', 'wordpress-form-manager'), + 'and_connective' => __("AND", 'conditions', 'wordpress-form-manager'), + 'or_connective' => __("OR", 'conditions', 'wordpress-form-manager'), + 'choose_a_rule_type' => __("(Choose a rule type)", 'conditions', 'wordpress-form-manager'), + 'only_show_elements_if' => __("Only show elements if...", 'wordpress-form-manager'), + 'show_elements_if' => __("Show elements if...", 'conditions', 'wordpress-form-manager'), + 'hide_elements_if' => __("Hide elements if...", 'conditions', 'wordpress-form-manager'), + 'only_require_elements_if' => __("Only require elements if...", 'conditions', 'wordpress-form-manager'), + 'require_elements_if' => __("Require elements if", 'conditions', 'wordpress-form-manager'), + 'do_not_require_elements_if' => __("Do not require elements if", 'wordpress-form-manager'), + 'empty_test' => __("...", 'conditions', 'wordpress-form-manager'), + 'equals' => __("equals", 'conditions', 'wordpress-form-manager'), + 'does_not_equal' => __("does not equal", 'conditions', 'wordpress-form-manager'), + 'is_less_than' => __("is less than", 'conditions', 'wordpress-form-manager'), + 'is_greater_than' => __("is greater than", 'conditions', 'wordpress-form-manager'), + 'is_lt_or_equal_to' => __("is less than or equal to", 'conditions', 'wordpress-form-manager'), + 'is_gt_or_equal_to' => __("is greater than or equal to", 'conditions', 'wordpress-form-manager'), + 'is_empty' => __("is empty", 'conditions', 'wordpress-form-manager'), + 'is_not_empty' => __("is not empty", 'conditions', 'wordpress-form-manager'), + 'is_checked' => __("is checked", 'conditions', 'wordpress-form-manager'), + 'is_not_checked' => __("is not checked", 'conditions', 'wordpress-form-manager') + ) ); + + wp_register_style('form-manager-css', plugins_url('/css/style.css', __FILE__)); + wp_enqueue_style('form-manager-css'); +} + +add_action('init', 'fm_userInit'); +function fm_userInit(){ + global $fm_currentVersion; + global $fm_templates; + + load_plugin_textdomain('wordpress-form-manager', false, dirname(plugin_basename(__FILE__)).'/languages/' ); + + //update check, since the snarky wordpress dev changed the behavior of a function based on its english name, rather than its widely accepted usage. + //"The perfect is the enemy of the good". + $ver = get_option('fm-version'); + if($ver != $fm_currentVersion){ + fm_install(); + } + + include 'settings.php'; + + $fm_templates->initTemplates(); + + wp_enqueue_script('form-manager-js-user', plugins_url('/js/userscripts.js', __FILE__)); + + wp_register_style('form-manager-css', plugins_url('/css/style.css', __FILE__)); + wp_enqueue_style('form-manager-css'); +} + +add_action('wp_head', 'fm_userHead'); +function fm_userHead(){ + global $fm_controls; + foreach($fm_controls as $control){ + $control->showUserScripts(); + } +} + +/**************************************************************/ +/******* ADMIN PAGES ******************************************/ + +add_action('admin_menu', 'fm_setupAdminMenu'); +function fm_setupAdminMenu(){ + $pages[] = add_object_page(__("Forms", 'wordpress-form-manager'), __("Forms", 'wordpress-form-manager'), apply_filters('fm_main_capability', 'manage_options'), "fm-admin-main", 'fm_showMainPage', plugins_url('/mce_plugins/formmanager.png', __FILE__)); + $pages[] = add_submenu_page("fm-admin-main", __("Edit", 'wordpress-form-manager'), __("Edit", 'wordpress-form-manager'), apply_filters('fm_main_capability', 'manage_options'), "fm-edit-form", 'fm_showEditPage'); + //$pages[] = add_submenu_page("fm-admin-main", __("Data", 'wordpress-form-manager'), __("Data", 'wordpress-form-manager'), apply_filters('fm_data_capability', 'manage_options'), "fm-form-data", 'fm_showDataPage'); + + //at some point, make this link go to a fresh form + //$pages[] = add_submenu_page("fm-admin-main", "Add New", "Add New", "manage_options", "fm-add-new", 'fm_showMainPage'); + + $pages[] = add_submenu_page("fm-admin-main", __("Settings", 'wordpress-form-manager'), __("Settings", 'wordpress-form-manager'), apply_filters('fm_settings_capability', 'manage_options'), "fm-global-settings", 'fm_showSettingsPage'); + $pages[] = add_submenu_page("fm-admin-main", __("Advanced Settings", 'wordpress-form-manager'), __("Advanced Settings", 'wordpress-form-manager'), apply_filters('fm_settings_advanced_capability', 'manage_options'), "fm-global-settings-advanced", 'fm_showSettingsAdvancedPage'); + + //$pages[] = add_submenu_page("fm-admin-main", __("Edit Form - Advanced", 'wordpress-form-manager'), __("Edit Form - Advanced", 'wordpress-form-manager'), apply_filters('fm_forms_advanced_capability', 'manage_options'), "fm-edit-form-advanced", 'fm_showEditAdvancedPage'); + + foreach($pages as $page) + add_action('admin_head-'.$page, 'fm_adminHeadPluginOnly'); + + $pluginName = plugin_basename(__FILE__); + add_filter( 'plugin_action_links_' . $pluginName, 'fm_pluginActions' ); +} + +function fm_pluginActions($links){ + $settings_link = '' . __('Settings', 'wordpress-form-manager') . ''; + array_unshift( $links, $settings_link ); + return $links; +} + +add_action('admin_head', 'fm_adminHead'); +function fm_adminHead(){ + global $submenu; + + $toUnset = array('fm-edit-form'); + + if(isset($submenu['fm-admin-main']) && is_array($submenu['fm-admin-main'])) + foreach($submenu['fm-admin-main'] as $index => $submenuItem) + if(in_array($submenuItem[2], $toUnset, true)) + unset($submenu['fm-admin-main'][$index]); + +} + +//only show this stuff when viewing a plugin page, since some of it is messy +function fm_adminHeadPluginOnly(){ + global $fm_controls; + //show the control scripts + fm_showControlScripts(); + foreach($fm_controls as $control){ + $control->showScripts(); + } +} + +function fm_showEditPage(){ include 'pages/editform.php'; } +function fm_showEditAdvancedPage(){ include 'pages/editformadv.php'; } +function fm_showDataPage(){ include 'pages/formdata.php'; } +function fm_showMainPage(){ include 'pages/main.php'; } +function fm_showSettingsPage(){ include 'pages/editsettings.php'; } +function fm_showSettingsAdvancedPage(){ include 'pages/editsettingsadv.php'; } + +// capabilities + +if (function_exists( 'members_plugin_init' )){ + $fm_MEMBERS_EXISTS = true; + + add_filter('fm_main_capability', 'fm_main_capability'); + add_filter('fm_forms_capability', 'fm_forms_capability'); + add_filter('fm_forms_advanced_capability', 'fm_forms_advanced_capability'); + add_filter('fm_data_capability', 'fm_data_capability'); + add_filter('fm_settings_capability', 'fm_settings_capability'); + add_filter('fm_settings_advanced_capability', 'fm_settings_advanced_capability'); + + add_filter('members_get_capabilities', 'fm_add_members_capabilities' ); +} + +function fm_main_capability( $cap ) { return 'form_manager_main'; } +function fm_forms_capability( $cap ) { return 'form_manager_forms'; } +function fm_forms_advanced_capability( $cap ) { return 'form_manager_forms_advanced'; } +function fm_data_capability( $cap ) { return 'form_manager_data'; } +function fm_settings_capability( $cap ) { return 'form_manager_settings'; } +function fm_settings_advanced_capability( $cap ) { return 'form_manager_settings_advanced'; } + +function fm_add_members_capabilities( $caps ) { + $caps[] = 'form_manager_main'; + $caps[] = 'form_manager_forms'; + $caps[] = 'form_manager_delete_forms'; + $caps[] = 'form_manager_add_forms'; + $caps[] = 'form_manager_forms_advanced'; + $caps[] = 'form_manager_data'; + $caps[] = 'form_manager_settings'; + $caps[] = 'form_manager_settings_advanced'; + + $caps[] = 'form_manager_edit_data'; + $caps[] = 'form_manager_delete_data'; + $caps[] = 'form_manager_nicknames'; + $caps[] = 'form_manager_conditions'; + + return $caps; +} + +include 'ajax.php'; + +/**************************************************************/ +/******* SHORTCODES *******************************************/ + +add_shortcode(get_option('fm-shortcode'), 'fm_shortcodeHandler'); +function fm_shortcodeHandler($atts){ + if(!isset($atts[0])) return sprintf(__("Form Manager: shortcode must include a form slug. For example, something like '%s'", 'wordpress-form-manager'), "[form form-1]"); + return fm_doFormBySlug($atts[0]); +} + +add_shortcode(get_option('fm-data-shortcode'), 'fm_dataShortcodeHandler'); +function fm_dataShortcodeHandler($atts){ + if(!isset($atts[0])) return sprintf(__("Form Manager: shortcode must include a form slug. For example, something like '%s'", 'wordpress-form-manager'), "[formdata form-1]"); + $formSlug = $atts[0]; + + $atts = shortcode_atts(array( + 'orderby' => 'timestamp', + 'order' => 'desc', + 'dataperpage' => 30, + 'template' => 'fm-summary-multi' + ), $atts); + + return fm_doDataListBySlug($formSlug, $atts['template'], $atts['orderby'], $atts['order'], $atts['dataperpage']); +} + +/**************************************************************/ +/******* HELPERS **********************************************/ + +//allow scheduling of clearing the temporary directory + +function fm_deleteTemporaryFiles($filename){ + //for now, just clear the directory. + $dir = dirname(__FILE__)."/".get_option("fm-temp-dir"); + if($handle = opendir($dir)){ + while(($file = readdir($handle)) !== false){ + if($file != "." && $file != ".." && is_file($dir."/".$file)) + unlink($dir."/".$file); + } + closedir($handle); + } +} +add_action('fm_delete_temporary_file', 'fm_deleteTemporaryFiles'); + +/**************************************************************/ + +include 'api.php'; + +/* ANDREA : include php for create TinyMCE Button */ +if(get_option('fm-enable-mce-button') == "YES") + include 'tinymce.php'; + + +//set the include path back to whatever it was before: +set_include_path($fm_oldIncludePath); + +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions.php b/src/wp-content/themes/bloggingstream/functions.php index 39482177..642400ab 100644 --- a/src/wp-content/themes/bloggingstream/functions.php +++ b/src/wp-content/themes/bloggingstream/functions.php @@ -25,4 +25,7 @@ require_once ($includes_path . 'theme-widgets.php'); // Theme widgets /* End WooThemes Functions - You can add custom functions below */ /*-----------------------------------------------------------------------------------*/ +require_once ($includes_path . 'save_application_form.php'); + + ?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/includes/save_application_form.php b/src/wp-content/themes/bloggingstream/includes/save_application_form.php new file mode 100644 index 00000000..87b73541 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/includes/save_application_form.php @@ -0,0 +1,27 @@ +posted_data["tu-mensaje"])) { + $table_name = $wpdb->prefix."ltw_testimonials"; + $results = $wpdb->insert( + $table_name, + array('group_id' => 1, + 'testimonial' => $cf7->posted_data["tu-mensaje"], + 'client_name' => $cf7->posted_data["tu-nombre"], + 'client_pic' => 'http://localhost/lqdvi/webcam/images/'.$cf7->posted_data["id"], + 'client_website' => $cf7->posted_data["tu-email"], + 'client_company' => '', + 'show_in_widget' => 0, + 'order' => 0)); + + return $result; + } else { + return false; + } +} + + +add_action( 'wpcf7_before_send_mail', 'save_application_form'); +?> diff --git a/src/wp-content/themes/bloggingstream/template-webcam.php b/src/wp-content/themes/bloggingstream/template-webcam.php index 0f33fde2..5192420c 100644 --- a/src/wp-content/themes/bloggingstream/template-webcam.php +++ b/src/wp-content/themes/bloggingstream/template-webcam.php @@ -5,41 +5,42 @@ Template Name: Webcam ?> + +
+

-