diff --git a/assets/css/admin.css b/assets/css/admin.css
index 5a701a27..3772907d 100644
--- a/assets/css/admin.css
+++ b/assets/css/admin.css
@@ -1,58 +1,4 @@
/* SportsPress admin styles */
-
-@font-face {
- font-family: 'sportspress';
- src:url('../fonts/sportspress.eot?ofuus8');
- src:url('../fonts/sportspress.eot?#iefixofuus8') format('embedded-opentype'),
- url('../fonts/sportspress.woff?ofuus8') format('woff'),
- url('../fonts/sportspress.ttf?ofuus8') format('truetype'),
- url('../fonts/sportspress.svg?ofuus8#sportspress') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-[class^="sp-icon-"], [class*=" sp-icon-"] {
- font-family: 'sportspress';
- speak: none;
- font-style: normal;
- font-weight: normal;
- font-variant: normal;
- text-transform: none;
- line-height: 1;
-
- /* Better Font Rendering =========== */
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-.sp-icon-calendar:before {
- content: "\f145";
-}
-.sp-icon-shield:before {
- content: "\f334";
-}
-.sp-icon-clock:before {
- content: "\f469";
-}
-.sp-icon-tshirt:before {
- content: "\f307";
-}
-.sp-icon-megaphone:before {
- content: "\f322";
-}
-.sp-icon-crown:before {
- content: "\f313";
-}
-.sp-icon-trophy:before {
- content: "\f325";
-}
-.sp-icon-list:before {
- content: "\f163"
-}
-.sp-icon-smile:before {
- content: "\f328";
-}
-
.post-state-format.post-format-calendar:before, .post-format-icon.post-format-calendar:before, a.post-state-format.format-calendar:before {
content: "\f145";
}
@@ -118,6 +64,15 @@
color: #888;
}
+/* Settings */
+.sportspress table.form-table, .sportspress table.form-table .forminp-radio ul {
+ margin: 0;
+}
+.sportspress table.sp-admin-config-table .edit {
+ text-align: right;
+}
+
+/* Messages */
.sportspress-message {
border-left-color: #6bc2a5 !important;
}
diff --git a/assets/css/menu.css b/assets/css/menu.css
index 93aeeea3..e4f44ff9 100644
--- a/assets/css/menu.css
+++ b/assets/css/menu.css
@@ -1,4 +1,56 @@
/* SportsPress menu styles */
+@font-face {
+ font-family: 'sportspress';
+ src:url('../fonts/sportspress.eot?ofuus8');
+ src:url('../fonts/sportspress.eot?#iefixofuus8') format('embedded-opentype'),
+ url('../fonts/sportspress.woff?ofuus8') format('woff'),
+ url('../fonts/sportspress.ttf?ofuus8') format('truetype'),
+ url('../fonts/sportspress.svg?ofuus8#sportspress') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+[class^="sp-icon-"], [class*=" sp-icon-"] {
+ font-family: 'sportspress';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.sp-icon-calendar:before {
+ content: "\f145";
+}
+.sp-icon-shield:before {
+ content: "\f334";
+}
+.sp-icon-clock:before {
+ content: "\f469";
+}
+.sp-icon-tshirt:before {
+ content: "\f307";
+}
+.sp-icon-megaphone:before {
+ content: "\f322";
+}
+.sp-icon-crown:before {
+ content: "\f313";
+}
+.sp-icon-trophy:before {
+ content: "\f325";
+}
+.sp-icon-list:before {
+ content: "\f163"
+}
+.sp-icon-smile:before {
+ content: "\f328";
+}
#adminmenu #toplevel_page_sportspress .menu-icon-generic div.wp-menu-image:before,
#adminmenu #menu-posts-sp_event .menu-icon-sp_event div.wp-menu-image:before,
diff --git a/assets/fonts/sportspress.eot b/assets/fonts/sportspress.eot
index 2a1add50..bc3da08b 100755
Binary files a/assets/fonts/sportspress.eot and b/assets/fonts/sportspress.eot differ
diff --git a/assets/fonts/sportspress.svg b/assets/fonts/sportspress.svg
index 600e0a1d..d5ddb4fd 100755
--- a/assets/fonts/sportspress.svg
+++ b/assets/fonts/sportspress.svg
@@ -7,6 +7,7 @@
+
@@ -14,6 +15,6 @@
-
-
+
+
\ No newline at end of file
diff --git a/assets/fonts/sportspress.ttf b/assets/fonts/sportspress.ttf
index 576c4985..82bd8ba2 100755
Binary files a/assets/fonts/sportspress.ttf and b/assets/fonts/sportspress.ttf differ
diff --git a/assets/fonts/sportspress.woff b/assets/fonts/sportspress.woff
index 8521b0c9..8e00ac5f 100755
Binary files a/assets/fonts/sportspress.woff and b/assets/fonts/sportspress.woff differ
diff --git a/assets/fonts/themeboy.eot b/assets/fonts/themeboy.eot
deleted file mode 100755
index a542dde5..00000000
Binary files a/assets/fonts/themeboy.eot and /dev/null differ
diff --git a/assets/fonts/themeboy.svg b/assets/fonts/themeboy.svg
deleted file mode 100755
index b1820ec1..00000000
--- a/assets/fonts/themeboy.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/assets/fonts/themeboy.ttf b/assets/fonts/themeboy.ttf
deleted file mode 100755
index 0c0606d4..00000000
Binary files a/assets/fonts/themeboy.ttf and /dev/null differ
diff --git a/assets/fonts/themeboy.woff b/assets/fonts/themeboy.woff
deleted file mode 100755
index c57642cc..00000000
Binary files a/assets/fonts/themeboy.woff and /dev/null differ
diff --git a/includes/admin/class-sp-admin-menus.php b/includes/admin/class-sp-admin-menus.php
new file mode 100644
index 00000000..31bc27e8
--- /dev/null
+++ b/includes/admin/class-sp-admin-menus.php
@@ -0,0 +1,129 @@
+ $data ):
+ if ( is_array( $data ) && array_key_exists( 2, $data ) && $data[2] == 'edit.php?post_type=sp_separator' )
+ $separator_position = $key;
+ endforeach;
+
+ // Swap our separator post type with a menu separator
+ if ( isset( $separator_position ) ):
+ $menu[ $separator_position ] = array( '', 'read', 'separator-sportspress', '', 'wp-menu-separator sportspress' );
+ endif;
+
+ // Remove "Venues" and "Positions" links from Media submenu
+ if ( isset( $submenu['upload.php'] ) ):
+ $submenu['upload.php'] = array_filter( $submenu['upload.php'], array( $this, 'remove_venues' ) );
+ $submenu['upload.php'] = array_filter( $submenu['upload.php'], array( $this, 'remove_positions' ) );
+ endif;
+
+ // Remove "Leagues" and "Seasons" links from Events submenu
+ if ( isset( $submenu['edit.php?post_type=sp_event'] ) ):
+ $submenu['edit.php?post_type=sp_event'] = array_filter( $submenu['edit.php?post_type=sp_event'], array( $this, 'remove_leagues' ) );
+ $submenu['edit.php?post_type=sp_event'] = array_filter( $submenu['edit.php?post_type=sp_event'], array( $this, 'remove_seasons' ) );
+ endif;
+
+ // Remove "Leagues" and "Seasons" links from Players submenu
+ if ( isset( $submenu['edit.php?post_type=sp_player'] ) ):
+ $submenu['edit.php?post_type=sp_player'] = array_filter( $submenu['edit.php?post_type=sp_player'], array( $this, 'remove_leagues' ) );
+ $submenu['edit.php?post_type=sp_player'] = array_filter( $submenu['edit.php?post_type=sp_player'], array( $this, 'remove_seasons' ) );
+ endif;
+
+ // Remove "Leagues" and "Seasons" links from Staff submenu
+ if ( isset( $submenu['edit.php?post_type=sp_staff'] ) ):
+ $submenu['edit.php?post_type=sp_staff'] = array_filter( $submenu['edit.php?post_type=sp_staff'], array( $this, 'remove_leagues' ) );
+ $submenu['edit.php?post_type=sp_staff'] = array_filter( $submenu['edit.php?post_type=sp_staff'], array( $this, 'remove_seasons' ) );
+ endif;
+ }
+
+ /**
+ * Init the settings page
+ */
+ public function settings_page() {
+ include_once( 'class-sp-admin-settings.php' );
+ SP_Admin_Settings::output();
+ }
+
+ public function remove_add_new( $arr = array() ) {
+ return $arr[0] != __( 'Add New', 'sportspress' );
+ }
+
+ public function remove_leagues( $arr = array() ) {
+ return $arr[0] != __( 'Leagues', 'sportspress' );
+ }
+
+ public function remove_positions( $arr = array() ) {
+ return $arr[0] != __( 'Positions', 'sportspress' );
+ }
+
+ public function remove_seasons( $arr = array() ) {
+ return $arr[0] != __( 'Seasons', 'sportspress' );
+ }
+
+ public function remove_venues( $arr = array() ) {
+ return $arr[0] != __( 'Venues', 'sportspress' );
+ }
+}
+
+endif;
+
+return new SP_Admin_Menus();
\ No newline at end of file
diff --git a/includes/admin/class-sp-admin-settings.php b/includes/admin/class-sp-admin-settings.php
new file mode 100644
index 00000000..e6b9870b
--- /dev/null
+++ b/includes/admin/class-sp-admin-settings.php
@@ -0,0 +1,701 @@
+ 0 ) {
+ foreach ( self::$errors as $error )
+ echo '
' . esc_html( $error ) . '
';
+ } elseif ( sizeof( self::$messages ) > 0 ) {
+ foreach ( self::$messages as $message )
+ echo '' . esc_html( $message ) . '
';
+ }
+ }
+
+ /**
+ * Settings page.
+ *
+ * Handles the display of the main sportspress settings page in admin.
+ *
+ * @access public
+ * @return void
+ */
+ public static function output() {
+ global $current_section, $current_tab;
+
+ do_action( 'sportspress_settings_start' );
+
+ wp_enqueue_script( 'sportspress_settings', SP()->plugin_url() . '/assets/js/admin/settings.min.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'iris', 'chosen' ), SP()->version, true );
+
+ wp_localize_script( 'sportspress_settings', 'sportspress_settings_params', array(
+ 'i18n_nav_warning' => __( 'The changes you made will be lost if you navigate away from this page.', 'sportspress' )
+ ) );
+
+ // Include settings pages
+ self::get_settings_pages();
+
+ // Get current tab/section
+ $current_tab = empty( $_GET['tab'] ) ? 'general' : sanitize_title( $_GET['tab'] );
+ $current_section = empty( $_REQUEST['section'] ) ? '' : sanitize_title( $_REQUEST['section'] );
+
+ // Save settings if data has been posted
+ if ( ! empty( $_POST ) )
+ self::save();
+
+ // Add any posted messages
+ if ( ! empty( $_GET['sp_error'] ) )
+ self::add_error( stripslashes( $_GET['sp_error'] ) );
+
+ if ( ! empty( $_GET['sp_message'] ) )
+ self::add_message( stripslashes( $_GET['sp_message'] ) );
+
+ self::show_messages();
+
+ // Get tabs for the settings page
+ $tabs = apply_filters( 'sportspress_settings_tabs_array', array() );
+
+ include 'views/html-admin-settings.php';
+ }
+
+ /**
+ * Get a setting from the settings API.
+ *
+ * @param mixed $option
+ * @return string
+ */
+ public static function get_option( $option_name, $default = '' ) {
+ // Array value
+ if ( strstr( $option_name, '[' ) ) {
+
+ parse_str( $option_name, $option_array );
+
+ // Option name is first key
+ $option_name = current( array_keys( $option_array ) );
+
+ // Get value
+ $option_values = get_option( $option_name, '' );
+
+ $key = key( $option_array[ $option_name ] );
+
+ if ( isset( $option_values[ $key ] ) )
+ $option_value = $option_values[ $key ];
+ else
+ $option_value = null;
+
+ // Single value
+ } else {
+ $option_value = get_option( $option_name, null );
+ }
+
+ if ( is_array( $option_value ) )
+ $option_value = array_map( 'stripslashes', $option_value );
+ elseif ( ! is_null( $option_value ) )
+ $option_value = stripslashes( $option_value );
+
+ return $option_value === null ? $default : $option_value;
+ }
+
+ /**
+ * Output admin fields.
+ *
+ * Loops though the sportspress options array and outputs each field.
+ *
+ * @access public
+ * @param array $options Opens array to output
+ */
+ public static function output_fields( $options ) {
+ foreach ( $options as $value ) {
+ if ( ! isset( $value['type'] ) ) continue;
+ if ( ! isset( $value['id'] ) ) $value['id'] = '';
+ if ( ! isset( $value['title'] ) ) $value['title'] = isset( $value['name'] ) ? $value['name'] : '';
+ if ( ! isset( $value['class'] ) ) $value['class'] = '';
+ if ( ! isset( $value['css'] ) ) $value['css'] = '';
+ if ( ! isset( $value['default'] ) ) $value['default'] = '';
+ if ( ! isset( $value['desc'] ) ) $value['desc'] = '';
+ if ( ! isset( $value['desc_tip'] ) ) $value['desc_tip'] = false;
+ if ( ! isset( $value['placeholder'] ) ) $value['placeholder'] = '';
+
+ // Custom attribute handling
+ $custom_attributes = array();
+
+ if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) )
+ foreach ( $value['custom_attributes'] as $attribute => $attribute_value )
+ $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
+
+ // Description handling
+ if ( $value['desc_tip'] === true ) {
+ $description = '';
+ $tip = $value['desc'];
+ } elseif ( ! empty( $value['desc_tip'] ) ) {
+ $description = $value['desc'];
+ $tip = $value['desc_tip'];
+ } elseif ( ! empty( $value['desc'] ) ) {
+ $description = $value['desc'];
+ $tip = '';
+ } else {
+ $description = $tip = '';
+ }
+
+ if ( $description && in_array( $value['type'], array( 'textarea', 'radio' ) ) ) {
+ $description = '' . wp_kses_post( $description ) . '
';
+ } elseif ( $description && in_array( $value['type'], array( 'checkbox' ) ) ) {
+ $description = wp_kses_post( $description );
+ } elseif ( $description ) {
+ $description = '' . wp_kses_post( $description ) . '';
+ }
+
+ if ( $tip && in_array( $value['type'], array( 'checkbox' ) ) ) {
+
+ $tip = '' . $tip . '
';
+
+ } elseif ( $tip ) {
+
+ $tip = '
';
+
+ }
+
+ // Switch based on type
+ switch( $value['type'] ) {
+
+ // Section Titles
+ case 'title':
+ if ( ! empty( $value['title'] ) ) {
+ echo '' . esc_html( $value['title'] ) . '
';
+ }
+ if ( ! empty( $value['desc'] ) ) {
+ echo wpautop( wptexturize( wp_kses_post( $value['desc'] ) ) );
+ }
+ echo '';
+ if ( ! empty( $value['id'] ) ) {
+ do_action( 'sportspress_settings_' . sanitize_title( $value['id'] ) . '_after' );
+ }
+ break;
+
+ // Standard text inputs and subtypes like 'number'
+ case 'text':
+ case 'email':
+ case 'number':
+ case 'color' :
+ case 'password' :
+
+ $type = $value['type'];
+ $class = '';
+ $option_value = self::get_option( $value['id'], $value['default'] );
+
+ if ( $value['type'] == 'color' ) {
+ $type = 'text';
+ $value['class'] .= 'colorpick';
+ $description .= '';
+ }
+
+ ?>
+ |
+
+
+ |
+
+
+ />
+ |
+
+ |
+
+
+ |
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+ |
+
+
+
+
+ | |
+
+
+ × px
+
+
+
+ |
+
$value['id'],
+ 'id' => $value['id'],
+ 'sort_column' => 'menu_order',
+ 'sort_order' => 'ASC',
+ 'show_option_none' => ' ',
+ 'class' => $value['class'],
+ 'echo' => false,
+ 'selected' => absint( self::get_option( $value['id'] ) )
+ );
+
+ if( isset( $value['args'] ) )
+ $args = wp_parse_args( $value['args'], $args );
+
+ ?>
+ | |
+
+
+ |
+
countries->countries;
+
+ if ( strstr( $country_setting, ':' ) ) {
+ $country_setting = explode( ':', $country_setting );
+ $country = current( $country_setting );
+ $state = end( $country_setting );
+ } else {
+ $country = $country_setting;
+ $state = '*';
+ }
+ ?>
+ |
+
+
+ |
+
+ |
+
countries->countries;
+
+ asort( $countries );
+ ?>
+ |
+
+
+ |
+
+
+ |
+
$value )
+ update_option( $name, $value );
+
+ return true;
+ }
+}
+
+endif;
diff --git a/includes/admin/class-sp-admin.php b/includes/admin/class-sp-admin.php
index 0701ac5f..36936e06 100644
--- a/includes/admin/class-sp-admin.php
+++ b/includes/admin/class-sp-admin.php
@@ -37,7 +37,7 @@ class SP_Admin {
// Classes we only need if the ajax is not-ajax
if ( ! is_ajax() ) {
-// include( 'class-sp-admin-menus.php' );
+ include( 'class-sp-admin-menus.php' );
// include( 'class-sp-admin-welcome.php' );
// include( 'class-sp-admin-notices.php' );
include( 'class-sp-admin-assets.php' );
diff --git a/includes/admin/settings/class-sp-settings-accounts.php b/includes/admin/settings/class-sp-settings-accounts.php
new file mode 100644
index 00000000..67189e83
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-accounts.php
@@ -0,0 +1,162 @@
+id = 'account';
+ $this->label = __( 'Accounts', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+
+ return apply_filters( 'sportspress_' . $this->id . '_settings', array(
+
+ array( 'title' => __( 'Account Pages', 'sportspress' ), 'type' => 'title', 'desc' => __( 'These pages need to be set so that SportsPress knows where to send users to access account related functionality.', 'sportspress' ), 'id' => 'account_page_options' ),
+
+ array(
+ 'title' => __( 'My Account Page', 'sportspress' ),
+ 'desc' => __( 'Page contents:', 'sportspress' ) . ' [' . apply_filters( 'sportspress_my_account_shortcode_tag', 'sportspress_my_account' ) . ']',
+ 'id' => 'sportspress_myaccount_page_id',
+ 'type' => 'single_select_page',
+ 'default' => '',
+ 'class' => 'chosen_select_nostd',
+ 'css' => 'min-width:300px;',
+ 'desc_tip' => true,
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'account_page_options' ),
+
+ array( 'title' => __( 'My Account Endpoints', 'sportspress' ), 'type' => 'title', 'desc' => __( 'Endpoints are appended to your page URLs to handle specific actions on the accounts pages. They should be unique.', 'sportspress' ), 'id' => 'account_endpoint_options' ),
+
+ array(
+ 'title' => __( 'View Order', 'sportspress' ),
+ 'desc' => __( 'Endpoint for the My Account → View Order page', 'sportspress' ),
+ 'id' => 'sportspress_myaccount_view_order_endpoint',
+ 'type' => 'text',
+ 'default' => 'view-order',
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Edit Account', 'sportspress' ),
+ 'desc' => __( 'Endpoint for the My Account → Edit Account page', 'sportspress' ),
+ 'id' => 'sportspress_myaccount_edit_account_endpoint',
+ 'type' => 'text',
+ 'default' => 'edit-account',
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Edit Address', 'sportspress' ),
+ 'desc' => __( 'Endpoint for the My Account → Edit Address page', 'sportspress' ),
+ 'id' => 'sportspress_myaccount_edit_address_endpoint',
+ 'type' => 'text',
+ 'default' => 'edit-address',
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Lost Password', 'sportspress' ),
+ 'desc' => __( 'Endpoint for the My Account → Lost Password page', 'sportspress' ),
+ 'id' => 'sportspress_myaccount_lost_password_endpoint',
+ 'type' => 'text',
+ 'default' => 'lost-password',
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Logout', 'sportspress' ),
+ 'desc' => __( 'Endpoint for the triggering logout. You can add this to your menus via a custom link: yoursite.com/?customer-logout=true', 'sportspress' ),
+ 'id' => 'sportspress_logout_endpoint',
+ 'type' => 'text',
+ 'default' => 'customer-logout',
+ 'desc_tip' => true,
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'account_endpoint_options' ),
+
+ array( 'title' => __( 'Registration Options', 'sportspress' ), 'type' => 'title', 'id' => 'account_registration_options' ),
+
+ array(
+ 'title' => __( 'Enable Registration', 'sportspress' ),
+ 'desc' => __( 'Enable registration on the "Checkout" page', 'sportspress' ),
+ 'id' => 'sportspress_enable_signup_and_login_from_checkout',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Enable registration on the "My Account" page', 'sportspress' ),
+ 'id' => 'sportspress_enable_myaccount_registration',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Display returning customer login reminder on the "Checkout" page', 'sportspress' ),
+ 'id' => 'sportspress_enable_checkout_login_reminder',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Account Creation', 'sportspress' ),
+ 'desc' => __( 'Automatically generate username from customer email', 'sportspress' ),
+ 'id' => 'sportspress_registration_generate_username',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Automatically generate customer password', 'sportspress' ),
+ 'id' => 'sportspress_registration_generate_password',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end',
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'account_registration_options'),
+
+ )); // End pages settings
+ }
+}
+
+endif;
+
+return new SP_Settings_Accounts();
\ No newline at end of file
diff --git a/includes/admin/settings/class-sp-settings-checkout.php b/includes/admin/settings/class-sp-settings-checkout.php
new file mode 100644
index 00000000..f2d8c438
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-checkout.php
@@ -0,0 +1,322 @@
+id = 'checkout';
+ $this->label = _x( 'Checkout', 'Settings tab label', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_sections_' . $this->id, array( $this, 'output_sections' ) );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_admin_field_payment_gateways', array( $this, 'payment_gateways_setting' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get sections
+ *
+ * @return array
+ */
+ public function get_sections() {
+ $sections = array(
+ '' => __( 'Checkout Options', 'sportspress' )
+ );
+
+ // Load shipping methods so we can show any global options they may have
+ $payment_gateways = SP()->payment_gateways->payment_gateways();
+
+ foreach ( $payment_gateways as $gateway ) {
+
+ $title = empty( $gateway->method_title ) ? ucfirst( $gateway->id ) : $gateway->method_title;
+
+ $sections[ strtolower( get_class( $gateway ) ) ] = esc_html( $title );
+ }
+
+ return $sections;
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ return apply_filters( 'sportspress_payment_gateways_settings', array(
+
+ array( 'title' => __( 'Checkout Process', 'sportspress' ), 'type' => 'title', 'id' => 'checkout_process_options' ),
+
+ array(
+ 'title' => __( 'Coupons', 'sportspress' ),
+ 'desc' => __( 'Enable the use of coupons', 'sportspress' ),
+ 'id' => 'sportspress_enable_coupons',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'desc_tip' => __( 'Coupons can be applied from the cart and checkout pages.', 'sportspress' ),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => _x( 'Checkout', 'Settings group label', 'sportspress' ),
+ 'desc' => __( 'Enable guest checkout', 'sportspress' ),
+ 'desc_tip' => __( 'Allows customers to checkout without creating an account.', 'sportspress' ),
+ 'id' => 'sportspress_enable_guest_checkout',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Force secure checkout', 'sportspress' ),
+ 'id' => 'sportspress_force_ssl_checkout',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => '',
+ 'show_if_checked' => 'option',
+ 'desc_tip' => __( 'Force SSL (HTTPS) on the checkout pages (an SSL Certificate is required).', 'sportspress' ),
+ ),
+
+ array(
+ 'desc' => __( 'Un-force HTTPS when leaving the checkout', 'sportspress' ),
+ 'id' => 'sportspress_unforce_ssl_checkout',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end',
+ 'show_if_checked' => 'yes',
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'checkout_process_options'),
+
+ array( 'title' => __( 'Checkout Pages', 'sportspress' ), 'desc' => __( 'These pages need to be set so that SportsPress knows where to send users to checkout.', 'sportspress' ), 'type' => 'title', 'id' => 'checkout_page_options' ),
+
+ array(
+ 'title' => __( 'Cart Page', 'sportspress' ),
+ 'desc' => __( 'Page contents:', 'sportspress' ) . ' [' . apply_filters( 'sportspress_cart_shortcode_tag', 'sportspress_cart' ) . ']',
+ 'id' => 'sportspress_cart_page_id',
+ 'type' => 'single_select_page',
+ 'default' => '',
+ 'class' => 'chosen_select_nostd',
+ 'css' => 'min-width:300px;',
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Checkout Page', 'sportspress' ),
+ 'desc' => __( 'Page contents:', 'sportspress' ) . ' [' . apply_filters( 'sportspress_checkout_shortcode_tag', 'sportspress_checkout' ) . ']',
+ 'id' => 'sportspress_checkout_page_id',
+ 'type' => 'single_select_page',
+ 'default' => '',
+ 'class' => 'chosen_select_nostd',
+ 'css' => 'min-width:300px;',
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Terms and Conditions', 'sportspress' ),
+ 'desc' => __( 'If you define a "Terms" page the customer will be asked if they accept them when checking out.', 'sportspress' ),
+ 'id' => 'sportspress_terms_page_id',
+ 'default' => '',
+ 'class' => 'chosen_select_nostd',
+ 'css' => 'min-width:300px;',
+ 'type' => 'single_select_page',
+ 'desc_tip' => true,
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'checkout_page_options' ),
+
+ array( 'title' => __( 'Checkout Endpoints', 'sportspress' ), 'type' => 'title', 'desc' => __( 'Endpoints are appended to your page URLs to handle specific actions during the checkout process. They should be unique.', 'sportspress' ), 'id' => 'account_endpoint_options' ),
+
+ array(
+ 'title' => __( 'Pay', 'sportspress' ),
+ 'desc' => __( 'Endpoint for the Checkout → Pay page', 'sportspress' ),
+ 'id' => 'sportspress_checkout_pay_endpoint',
+ 'type' => 'text',
+ 'default' => 'order-pay',
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Order Received', 'sportspress' ),
+ 'desc' => __( 'Endpoint for the Checkout → Pay page', 'sportspress' ),
+ 'id' => 'sportspress_checkout_order_received_endpoint',
+ 'type' => 'text',
+ 'default' => 'order-received',
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Add Payment Method', 'sportspress' ),
+ 'desc' => __( 'Endpoint for the Checkout → Add Payment Method page', 'sportspress' ),
+ 'id' => 'sportspress_myaccount_add_payment_method_endpoint',
+ 'type' => 'text',
+ 'default' => 'add-payment-method',
+ 'desc_tip' => true,
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'checkout_endpoint_options' ),
+
+ array( 'title' => __( 'Payment Gateways', 'sportspress' ), 'desc' => __( 'Installed gateways are listed below. Drag and drop gateways to control their display order on the frontend.', 'sportspress' ), 'type' => 'title', 'id' => 'payment_gateways_options' ),
+
+ array( 'type' => 'payment_gateways' ),
+
+ array( 'type' => 'sectionend', 'id' => 'payment_gateways_options' ),
+
+ )); // End payment_gateway settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ // Load shipping methods so we can show any global options they may have
+ $payment_gateways = SP()->payment_gateways->payment_gateways();
+
+ if ( $current_section ) {
+ foreach ( $payment_gateways as $gateway ) {
+ if ( strtolower( get_class( $gateway ) ) == strtolower( $current_section ) ) {
+ $gateway->admin_options();
+ break;
+ }
+ }
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+ /**
+ * Output payment gateway settings.
+ *
+ * @access public
+ * @return void
+ */
+ public function payment_gateways_setting() {
+ ?>
+
+ |
+
+
+
+
+ __( 'Default', 'sportspress' ),
+ 'name' => __( 'Gateway', 'sportspress' ),
+ 'id' => __( 'Gateway ID', 'sportspress' ),
+ 'status' => __( 'Status', 'sportspress' ),
+ 'settings' => ''
+ ) );
+
+ foreach ( $columns as $key => $column ) {
+ echo '| ' . esc_html( $column ) . ' | ';
+ }
+ ?>
+
+
+
+ payment_gateways->payment_gateways() as $gateway ) {
+
+ echo '';
+
+ foreach ( $columns as $key => $column ) {
+ switch ( $key ) {
+ case 'default' :
+ echo '|
+ id ), false ) . ' />
+
+ | ';
+ break;
+ case 'name' :
+ echo '
+ ' . $gateway->get_title() . '
+ | ';
+ break;
+ case 'id' :
+ echo '
+ ' . esc_html( $gateway->id ) . '
+ | ';
+ break;
+ case 'status' :
+ echo '';
+
+ if ( $gateway->enabled == 'yes' )
+ echo '' . __ ( 'Enabled', 'sportspress' ) . '';
+ else
+ echo '-';
+
+ echo ' | ';
+ break;
+ case 'settings' :
+ echo '
+ ' . __( 'Settings', 'sportspress' ) . '
+ | ';
+ break;
+ default :
+ do_action( 'sportspress_payment_gateways_setting_column_' . $key, $gateway );
+ break;
+ }
+ }
+
+ echo ' ';
+ }
+ ?>
+
+
+ |
+
+ get_settings();
+
+ SP_Admin_Settings::save_fields( $settings );
+ SP()->payment_gateways->process_admin_options();
+
+ } elseif ( class_exists( $current_section ) ) {
+
+ $current_section_class = new $current_section();
+
+ do_action( 'sportspress_update_options_payment_gateways_' . $current_section_class->id );
+
+ SP()->payment_gateways()->init();
+ }
+ }
+}
+
+endif;
+
+return new SP_Settings_Payment_Gateways();
\ No newline at end of file
diff --git a/includes/admin/settings/class-sp-settings-config.php b/includes/admin/settings/class-sp-settings-config.php
new file mode 100644
index 00000000..03b26cc1
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-config.php
@@ -0,0 +1,378 @@
+id = 'config';
+ $this->label = __( 'Configure', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_admin_field_results', array( $this, 'results_setting' ) );
+ add_action( 'sportspress_admin_field_outcomes', array( $this, 'outcomes_setting' ) );
+ add_action( 'sportspress_admin_field_columns', array( $this, 'columns_setting' ) );
+ add_action( 'sportspress_admin_field_metrics', array( $this, 'metrics_setting' ) );
+ add_action( 'sportspress_admin_field_performance', array( $this, 'performance_setting' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ return apply_filters('sportspress_event_settings', array(
+
+ array( 'title' => __( 'Configure SportsPress', 'sportspress' ), 'type' => 'title','desc' => '', 'id' => 'config_options' ),
+
+ array(
+ 'title' => __( 'Sport', 'sportspress' ),
+ 'id' => 'sportspress_sport',
+ 'default' => 'soccer',
+ 'type' => 'select',
+ 'options' => SP()->sports->options,
+ ),
+
+ array( 'type' => 'results' ),
+
+ array( 'type' => 'outcomes' ),
+
+ array( 'type' => 'columns' ),
+
+ array( 'type' => 'metrics' ),
+
+ array( 'type' => 'performance' ),
+
+ array( 'type' => 'statistics' ),
+
+ array( 'type' => 'sectionend', 'id' => 'config_options' ),
+
+ )); // End event settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+
+ if ( $current_section == 'standard' || in_array( $current_section, array_map( 'sanitize_title', $tax_classes ) ) ) {
+ $this->output_tax_rates();
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+ /**
+ * Save settings
+ */
+ public function save() {
+ global $current_section, $wpdb;
+
+ if ( ! $current_section ) {
+
+ $settings = $this->get_settings();
+ SP_Admin_Settings::save_fields( $settings );
+
+ } else {
+
+ $this->save_tax_rates();
+
+ }
+
+ $wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_sp_tax_rates_%') OR `option_name` LIKE ('_transient_timeout_sp_tax_rates_%')" );
+ }
+
+ /**
+ * Output results settings.
+ *
+ * @access public
+ * @return void
+ */
+ public function results_setting() {
+ $main_result = get_option( 'sportspress_main_result', 0 );
+
+ $args = array(
+ 'post_type' => 'sp_result',
+ 'numberposts' => -1,
+ 'posts_per_page' => -1,
+ 'orderby' => 'menu_order',
+ 'order' => 'ASC'
+ );
+ $data = get_posts( $args );
+ ?>
+
+ |
+
+
+
+ |
+
+ 'sp_outcome',
+ 'numberposts' => -1,
+ 'posts_per_page' => -1,
+ 'orderby' => 'menu_order',
+ 'order' => 'ASC'
+ );
+ $data = get_posts( $args );
+ ?>
+
+ |
+
+
+
+
+ |
+ |
+ |
+
+
+
+ >
+ | post_title; ?> |
+ post_name; ?> |
+ |
+
+
+
+
+ |
+
+ 'sp_column',
+ 'numberposts' => -1,
+ 'posts_per_page' => -1,
+ 'orderby' => 'menu_order',
+ 'order' => 'ASC'
+ );
+ $data = get_posts( $args );
+ ?>
+
+ |
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+ >
+ | post_title; ?> |
+ post_name; ?> |
+ ID, $row->post_name ); ?> |
+ ID ); ?> |
+ ID ); ?> |
+ |
+
+
+
+
+
+ |
+
+ 'sp_metric',
+ 'numberposts' => -1,
+ 'posts_per_page' => -1,
+ 'orderby' => 'menu_order',
+ 'order' => 'ASC'
+ );
+ $data = get_posts( $args );
+ ?>
+
+ |
+
+
+
+
+ |
+ |
+ |
+ |
+
+
+
+ >
+ | post_title; ?> |
+ ID, 'sp_position' ) ? the_terms( $row->ID, 'sp_position' ) : '—'; ?> |
+ |
+ |
+
+
+
+
+ |
+
+ 'sp_performance',
+ 'numberposts' => -1,
+ 'posts_per_page' => -1,
+ 'orderby' => 'menu_order',
+ 'order' => 'ASC'
+ );
+ $data = get_posts( $args );
+ ?>
+
+ |
+
+
+
+
+ |
+ |
+ |
+ |
+
+
+
+ >
+ | post_title; ?> |
+ ID, 'sp_position' ) ? the_terms( $row->ID, 'sp_position' ) : '—'; ?> |
+ ID ); ?> |
+ |
+
+
+
+
+ |
+
+ id = 'email';
+ $this->label = __( 'Emails', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_sections_' . $this->id, array( $this, 'output_sections' ) );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get sections
+ *
+ * @return array
+ */
+ public function get_sections() {
+ $sections = array(
+ '' => __( 'Email Options', 'sportspress' )
+ );
+
+ // Define emails that can be customised here
+ $mailer = SP()->mailer();
+ $email_templates = $mailer->get_emails();
+
+ foreach ( $email_templates as $email ) {
+ $title = empty( $email->title ) ? ucfirst( $email->id ) : ucfirst( $email->title );
+
+ $sections[ strtolower( get_class( $email ) ) ] = esc_html( $title );
+ }
+
+ return $sections;
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ return apply_filters('sportspress_email_settings', array(
+
+ array( 'type' => 'sectionend', 'id' => 'email_recipient_options' ),
+
+ array( 'title' => __( 'Email Sender Options', 'sportspress' ), 'type' => 'title', 'desc' => __( 'The following options affect the sender (email address and name) used in SportsPress emails.', 'sportspress' ), 'id' => 'email_options' ),
+
+ array(
+ 'title' => __( '"From" Name', 'sportspress' ),
+ 'desc' => '',
+ 'id' => 'sportspress_email_from_name',
+ 'type' => 'text',
+ 'css' => 'min-width:300px;',
+ 'default' => esc_attr(get_bloginfo('title')),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( '"From" Email Address', 'sportspress' ),
+ 'desc' => '',
+ 'id' => 'sportspress_email_from_address',
+ 'type' => 'email',
+ 'custom_attributes' => array(
+ 'multiple' => 'multiple'
+ ),
+ 'css' => 'min-width:300px;',
+ 'default' => get_option('admin_email'),
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'email_options' ),
+
+ array( 'title' => __( 'Email Template', 'sportspress' ), 'type' => 'title', 'desc' => sprintf(__( 'This section lets you customise the SportsPress emails. Click here to preview your email template. For more advanced control copy sportspress/templates/emails/ to yourtheme/sportspress/emails/.', 'sportspress' ), wp_nonce_url(admin_url('?preview_sportspress_mail=true'), 'preview-mail')), 'id' => 'email_template_options' ),
+
+ array(
+ 'title' => __( 'Header Image', 'sportspress' ),
+ 'desc' => sprintf(__( 'Enter a URL to an image you want to show in the email\'s header. Upload your image using the media uploader.', 'sportspress' ), admin_url('media-new.php')),
+ 'id' => 'sportspress_email_header_image',
+ 'type' => 'text',
+ 'css' => 'min-width:300px;',
+ 'default' => '',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Email Footer Text', 'sportspress' ),
+ 'desc' => __( 'The text to appear in the footer of SportsPress emails.', 'sportspress' ),
+ 'id' => 'sportspress_email_footer_text',
+ 'css' => 'width:100%; height: 75px;',
+ 'type' => 'textarea',
+ 'default' => get_bloginfo('title') . ' - ' . __( 'Powered by SportsPress', 'sportspress' ),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Base Colour', 'sportspress' ),
+ 'desc' => __( 'The base colour for SportsPress email templates. Default #557da1.', 'sportspress' ),
+ 'id' => 'sportspress_email_base_color',
+ 'type' => 'color',
+ 'css' => 'width:6em;',
+ 'default' => '#557da1',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Background Colour', 'sportspress' ),
+ 'desc' => __( 'The background colour for SportsPress email templates. Default #f5f5f5.', 'sportspress' ),
+ 'id' => 'sportspress_email_background_color',
+ 'type' => 'color',
+ 'css' => 'width:6em;',
+ 'default' => '#f5f5f5',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Email Body Background Colour', 'sportspress' ),
+ 'desc' => __( 'The main body background colour. Default #fdfdfd.', 'sportspress' ),
+ 'id' => 'sportspress_email_body_background_color',
+ 'type' => 'color',
+ 'css' => 'width:6em;',
+ 'default' => '#fdfdfd',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Email Body Text Colour', 'sportspress' ),
+ 'desc' => __( 'The main body text colour. Default #505050.', 'sportspress' ),
+ 'id' => 'sportspress_email_text_color',
+ 'type' => 'color',
+ 'css' => 'width:6em;',
+ 'default' => '#505050',
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'email_template_options' ),
+
+ )); // End email settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ // Define emails that can be customised here
+ $mailer = SP()->mailer();
+ $email_templates = $mailer->get_emails();
+
+ if ( $current_section ) {
+ foreach ( $email_templates as $email ) {
+ if ( strtolower( get_class( $email ) ) == $current_section ) {
+ $email->admin_options();
+ break;
+ }
+ }
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+ /**
+ * Save settings
+ */
+ public function save() {
+ global $current_section;
+
+ if ( ! $current_section ) {
+
+ $settings = $this->get_settings();
+ SP_Admin_Settings::save_fields( $settings );
+
+ } else {
+
+ // Load mailer
+ $mailer = SP()->mailer();
+
+ if ( class_exists( $current_section ) ) {
+ $current_section_class = new $current_section();
+ do_action( 'sportspress_update_options_' . $this->id . '_' . $current_section_class->id );
+ SP()->mailer()->init();
+ } else {
+ do_action( 'sportspress_update_options_' . $this->id . '_' . $current_section );
+ }
+ }
+ }
+}
+
+endif;
+
+return new SP_Settings_Emails();
\ No newline at end of file
diff --git a/includes/admin/settings/class-sp-settings-events.php b/includes/admin/settings/class-sp-settings-events.php
new file mode 100644
index 00000000..0076ae38
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-events.php
@@ -0,0 +1,708 @@
+id = 'events';
+ $this->label = __( 'Events', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option( 'sportspress_tax_classes' ) ) ) );
+ $classes_options = array();
+ if ( $tax_classes )
+ foreach ( $tax_classes as $class )
+ $classes_options[ sanitize_title( $class ) ] = esc_html( $class );
+
+ return apply_filters('sportspress_event_settings', array(
+
+ array( 'title' => __( 'Event Options', 'sportspress' ), 'type' => 'title','desc' => '', 'id' => 'tax_options' ),
+
+ array(
+ 'title' => __( 'Delimiter', 'sportspress' ),
+ 'id' => 'sportspress_event_teams_delimiter',
+ 'default' => 'vs',
+ 'type' => 'radio',
+ 'options' => array(
+ 'vs' => sprintf( '%s vs %s', __( 'Team', 'sportspress' ), __( 'Team', 'sportspress' ) ),
+ 'v' => sprintf( '%s v %s', __( 'Team', 'sportspress' ), __( 'Team', 'sportspress' ) ),
+ '—' => sprintf( '%s — %s', __( 'Team', 'sportspress' ), __( 'Team', 'sportspress' ) ),
+ '/' => sprintf( '%s / %s', __( 'Team', 'sportspress' ), __( 'Team', 'sportspress' ) )
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Calculate Tax Based On:', 'sportspress' ),
+ 'id' => 'sportspress_tax_based_on',
+ 'desc_tip' => __( 'This option determines which address is used to calculate tax.', 'sportspress' ),
+ 'default' => 'shipping',
+ 'type' => 'select',
+ 'options' => array(
+ 'shipping' => __( 'Customer shipping address', 'sportspress' ),
+ 'billing' => __( 'Customer billing address', 'sportspress' ),
+ 'base' => __( 'Shop base address', 'sportspress' )
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Default Customer Address:', 'sportspress' ),
+ 'id' => 'sportspress_default_customer_address',
+ 'desc_tip' => __( 'This option determines the customers default address (before they input their own).', 'sportspress' ),
+ 'default' => 'base',
+ 'type' => 'select',
+ 'options' => array(
+ '' => __( 'No address', 'sportspress' ),
+ 'base' => __( 'Shop base address', 'sportspress' ),
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Shipping Tax Class:', 'sportspress' ),
+ 'desc' => __( 'Optionally control which tax class shipping gets, or leave it so shipping tax is based on the cart items themselves.', 'sportspress' ),
+ 'id' => 'sportspress_shipping_tax_class',
+ 'css' => 'min-width:150px;',
+ 'default' => 'title',
+ 'type' => 'select',
+ 'options' => array( '' => __( 'Shipping tax class based on cart items', 'sportspress' ), 'standard' => __( 'Standard', 'sportspress' ) ) + $classes_options,
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Rounding', 'sportspress' ),
+ 'desc' => __( 'Round tax at subtotal level, instead of rounding per line', 'sportspress' ),
+ 'id' => 'sportspress_tax_round_at_subtotal',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ ),
+
+ array(
+ 'title' => __( 'Additional Tax Classes', 'sportspress' ),
+ 'desc' => __( 'List additonal tax classes below (1 per line). This is in addition to the default Standard Rate. Tax classes can be assigned to products.', 'sportspress' ),
+ 'id' => 'sportspress_tax_classes',
+ 'css' => 'width:100%; height: 65px;',
+ 'type' => 'textarea',
+ 'default' => sprintf( __( 'Reduced Rate%sZero Rate', 'sportspress' ), PHP_EOL )
+ ),
+
+ array(
+ 'title' => __( 'Display prices in the shop:', 'sportspress' ),
+ 'id' => 'sportspress_tax_display_shop',
+ 'default' => 'excl',
+ 'type' => 'select',
+ 'options' => array(
+ 'incl' => __( 'Including tax', 'sportspress' ),
+ 'excl' => __( 'Excluding tax', 'sportspress' ),
+ )
+ ),
+
+ array(
+ 'title' => __( 'Price display suffix:', 'sportspress' ),
+ 'id' => 'sportspress_price_display_suffix',
+ 'default' => '',
+ 'type' => 'text',
+ 'desc' => __( 'Define text to show after your product prices. This could be, for example, "inc. Vat" to explain your pricing. You can also have prices substituted here using one of the following: {price_including_tax}, {price_excluding_tax}.', 'sportspress' ),
+ ),
+
+ array(
+ 'title' => __( 'Display prices during cart/checkout:', 'sportspress' ),
+ 'id' => 'sportspress_tax_display_cart',
+ 'default' => 'excl',
+ 'type' => 'select',
+ 'options' => array(
+ 'incl' => __( 'Including tax', 'sportspress' ),
+ 'excl' => __( 'Excluding tax', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Display tax totals:', 'sportspress' ),
+ 'id' => 'sportspress_tax_total_display',
+ 'default' => 'itemized',
+ 'type' => 'select',
+ 'options' => array(
+ 'single' => __( 'As a single total', 'sportspress' ),
+ 'itemized' => __( 'Itemized', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'results' ),
+
+ array( 'type' => 'sectionend', 'id' => 'event_options' ),
+
+ )); // End event settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+
+ if ( $current_section == 'standard' || in_array( $current_section, array_map( 'sanitize_title', $tax_classes ) ) ) {
+ $this->output_tax_rates();
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+ /**
+ * Save settings
+ */
+ public function save() {
+ global $current_section, $wpdb;
+
+ if ( ! $current_section ) {
+
+ $settings = $this->get_settings();
+ SP_Admin_Settings::save_fields( $settings );
+
+ } else {
+
+ $this->save_tax_rates();
+
+ }
+
+ $wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_sp_tax_rates_%') OR `option_name` LIKE ('_transient_timeout_sp_tax_rates_%')" );
+ }
+
+ /**
+ * Output tax rate tables
+ */
+ public function output_tax_rates() {
+ global $sportspress, $current_section, $wpdb;
+
+ $page = ! empty( $_GET['p'] ) ? absint( $_GET['p'] ) : 1;
+ $limit = 100;
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+ $current_class = '';
+
+ foreach( $tax_classes as $class )
+ if ( sanitize_title( $class ) == $current_section )
+ $current_class = $class;
+ ?>
+
+ See here for available alpha-2 country codes.', 'sportspress' ), 'http://en.wikipedia.org/wiki/ISO_3166-1#Current_codes' ); ?>
+
+
+ $value ) {
+
+ // new keys are inserted...
+ if ( $key == 'new' ) {
+
+ foreach ( $value as $new_key => $new_value ) {
+
+ // Sanitize + format
+ $country = strtoupper( sanitize_text_field( $tax_rate_country[ $key ][ $new_key ] ) );
+ $state = strtoupper( sanitize_text_field( $tax_rate_state[ $key ][ $new_key ] ) );
+ $postcode = sanitize_text_field( $tax_rate_postcode[ $key ][ $new_key ] );
+ $city = sanitize_text_field( $tax_rate_city[ $key ][ $new_key ] );
+ $rate = number_format( sanitize_text_field( $tax_rate[ $key ][ $new_key ] ), 4, '.', '' );
+ $name = sanitize_text_field( $tax_rate_name[ $key ][ $new_key ] );
+ $priority = absint( sanitize_text_field( $tax_rate_priority[ $key ][ $new_key ] ) );
+ $compound = isset( $tax_rate_compound[ $key ][ $new_key ] ) ? 1 : 0;
+ $shipping = isset( $tax_rate_shipping[ $key ][ $new_key ] ) ? 1 : 0;
+
+ if ( ! $name )
+ $name = __( 'Tax', 'sportspress' );
+
+ if ( $country == '*' )
+ $country = '';
+
+ if ( $state == '*' )
+ $state = '';
+
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rates",
+ array(
+ 'tax_rate_country' => $country,
+ 'tax_rate_state' => $state,
+ 'tax_rate' => $rate,
+ 'tax_rate_name' => $name,
+ 'tax_rate_priority' => $priority,
+ 'tax_rate_compound' => $compound,
+ 'tax_rate_shipping' => $shipping,
+ 'tax_rate_order' => $i,
+ 'tax_rate_class' => sanitize_title( $current_class )
+ )
+ );
+
+ $tax_rate_id = $wpdb->insert_id;
+
+ if ( ! empty( $postcode ) ) {
+ $postcodes = explode( ';', $postcode );
+ $postcodes = array_map( 'strtoupper', array_map( 'sanitize_text_field', $postcodes ) );
+
+ $postcode_query = array();
+
+ foreach( $postcodes as $postcode )
+ if ( strstr( $postcode, '-' ) ) {
+ $postcode_parts = explode( '-', $postcode );
+
+ if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
+ for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
+ if ( ! $i )
+ continue;
+
+ if ( strlen( $i ) < strlen( $postcode_parts[0] ) )
+ $i = str_pad( $i, strlen( $postcode_parts[0] ), "0", STR_PAD_LEFT );
+
+ $postcode_query[] = "( '" . esc_sql( $i ) . "', $tax_rate_id, 'postcode' )";
+ }
+ }
+ } else {
+ if ( $postcode )
+ $postcode_query[] = "( '" . esc_sql( $postcode ) . "', $tax_rate_id, 'postcode' )";
+ }
+
+ $wpdb->query( "INSERT INTO {$wpdb->prefix}sportspress_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
+ }
+
+ if ( ! empty( $city ) ) {
+ $cities = explode( ';', $city );
+ $cities = array_map( 'strtoupper', array_map( 'sanitize_text_field', $cities ) );
+ foreach( $cities as $city ) {
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
+ }
+
+ $i++;
+ }
+
+ // ...whereas the others are updated
+ } else {
+
+ $tax_rate_id = absint( $key );
+
+ if ( $_POST['remove_tax_rate'][ $key ] == 1 ) {
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d;", $tax_rate_id ) );
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rates WHERE tax_rate_id = %d;", $tax_rate_id ) );
+ continue;
+ }
+
+ // Sanitize + format
+ $country = strtoupper( sanitize_text_field( $tax_rate_country[ $key ] ) );
+ $state = strtoupper( sanitize_text_field( $tax_rate_state[ $key ] ) );
+ $rate = number_format( (double) sanitize_text_field( $tax_rate[ $key ] ), 4, '.', '' );
+ $name = sanitize_text_field( $tax_rate_name[ $key ] );
+ $priority = absint( sanitize_text_field( $tax_rate_priority[ $key ] ) );
+ $compound = isset( $tax_rate_compound[ $key ] ) ? 1 : 0;
+ $shipping = isset( $tax_rate_shipping[ $key ] ) ? 1 : 0;
+
+ if ( ! $name )
+ $name = __( 'Tax', 'sportspress' );
+
+ if ( $country == '*' )
+ $country = '';
+
+ if ( $state == '*' )
+ $state = '';
+
+ $wpdb->update(
+ $wpdb->prefix . "sportspress_tax_rates",
+ array(
+ 'tax_rate_country' => $country,
+ 'tax_rate_state' => $state,
+ 'tax_rate' => $rate,
+ 'tax_rate_name' => $name,
+ 'tax_rate_priority' => $priority,
+ 'tax_rate_compound' => $compound,
+ 'tax_rate_shipping' => $shipping,
+ 'tax_rate_order' => $i,
+ 'tax_rate_class' => sanitize_title( $current_class )
+ ),
+ array(
+ 'tax_rate_id' => $tax_rate_id
+ )
+ );
+
+ if ( isset( $tax_rate_postcode[ $key ] ) ) {
+ // Delete old
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'postcode';", $tax_rate_id ) );
+
+ // Add changed
+ $postcode = sanitize_text_field( $tax_rate_postcode[ $key ] );
+ $postcodes = explode( ';', $postcode );
+ $postcodes = array_map( 'strtoupper', array_map( 'sanitize_text_field', $postcodes ) );
+
+ $postcode_query = array();
+
+ foreach( $postcodes as $postcode )
+ if ( strstr( $postcode, '-' ) ) {
+ $postcode_parts = explode( '-', $postcode );
+
+ if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
+ for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
+ if ( ! $i )
+ continue;
+
+ if ( strlen( $i ) < strlen( $postcode_parts[0] ) )
+ $i = str_pad( $i, strlen( $postcode_parts[0] ), "0", STR_PAD_LEFT );
+
+ $postcode_query[] = "( '" . esc_sql( $i ) . "', $tax_rate_id, 'postcode' )";
+ }
+ }
+ } else {
+ if ( $postcode )
+ $postcode_query[] = "( '" . esc_sql( $postcode ) . "', $tax_rate_id, 'postcode' )";
+ }
+
+ $wpdb->query( "INSERT INTO {$wpdb->prefix}sportspress_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
+
+ }
+
+ if ( isset( $tax_rate_city[ $key ] ) ) {
+ // Delete old
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'city';", $tax_rate_id ) );
+
+ // Add changed
+ $city = sanitize_text_field( $tax_rate_city[ $key ] );
+ $cities = explode( ';', $city );
+ $cities = array_map( 'strtoupper', array_map( 'sanitize_text_field', $cities ) );
+ foreach( $cities as $city ) {
+ if ( $city ) {
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
+ }
+ }
+
+ $i++;
+ }
+ }
+ }
+
+}
+
+endif;
+
+return new SP_Settings_Events();
\ No newline at end of file
diff --git a/includes/admin/settings/class-sp-settings-general.php b/includes/admin/settings/class-sp-settings-general.php
new file mode 100644
index 00000000..ddaec88b
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-general.php
@@ -0,0 +1,69 @@
+id = 'general';
+ $this->label = __( 'General', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ return apply_filters( 'sportspress_general_settings', array(
+
+ array( 'title' => __( 'General Options', 'sportspress' ), 'type' => 'title', 'desc' => '', 'id' => 'general_options' ),
+
+ array(
+ 'title' => __( 'Tables', 'sportspress' ),
+ 'desc' => __( 'Responsive', 'sportspress' ),
+ 'id' => 'sportspress_tables_responsive',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Sortable', 'sportspress' ),
+ 'id' => 'sportspress_tables_sortable',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end',
+ 'show_if_checked' => 'option',
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'general_options' ),
+
+ )); // End general settings
+ }
+}
+
+endif;
+
+return new SP_Settings_General();
diff --git a/includes/admin/settings/class-sp-settings-integrations.php b/includes/admin/settings/class-sp-settings-integrations.php
new file mode 100644
index 00000000..d9807670
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-integrations.php
@@ -0,0 +1,74 @@
+id = 'integration';
+ $this->label = __( 'Integration', 'sportspress' );
+
+ if ( isset( SP()->integrations ) && SP()->integrations->get_integrations() ) {
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_sections_' . $this->id, array( $this, 'output_sections' ) );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+ }
+
+ /**
+ * Get sections
+ *
+ * @return array
+ */
+ public function get_sections() {
+ global $current_section;
+
+ $sections = array();
+
+ $integrations = SP()->integrations->get_integrations();
+
+ if ( ! $current_section )
+ $current_section = current( $integrations )->id;
+
+ foreach ( $integrations as $integration ) {
+ $title = empty( $integration->method_title ) ? ucfirst( $integration->id ) : $integration->method_title;
+
+ $sections[ strtolower( $integration->id ) ] = esc_html( $title );
+ }
+
+ return $sections;
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ $integrations = SP()->integrations->get_integrations();
+
+ if ( isset( $integrations[ $current_section ] ) )
+ $integrations[ $current_section ]->admin_options();
+ }
+}
+
+endif;
+
+return new SP_Settings_Integrations();
\ No newline at end of file
diff --git a/includes/admin/settings/class-sp-settings-page.php b/includes/admin/settings/class-sp-settings-page.php
new file mode 100644
index 00000000..8c08b09c
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-page.php
@@ -0,0 +1,94 @@
+id ] = $this->label;
+
+ return $pages;
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ return array();
+ }
+
+ /**
+ * Get sections
+ *
+ * @return array
+ */
+ public function get_sections() {
+ return array();
+ }
+
+ /**
+ * Output sections
+ */
+ public function output_sections() {
+ global $current_section;
+
+ $sections = $this->get_sections();
+
+ if ( empty( $sections ) )
+ return;
+
+ echo '';
+
+ $array_keys = array_keys( $sections );
+
+ foreach ( $sections as $id => $label )
+ echo '- ' . $label . ' ' . ( end( $array_keys ) == $id ? '' : '|' ) . '
';
+
+ echo '
';
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+
+ /**
+ * Save settings
+ */
+ public function save() {
+ global $current_section;
+
+ $settings = $this->get_settings();
+ SP_Admin_Settings::save_fields( $settings );
+
+ if ( $current_section )
+ do_action( 'sportspress_update_options_' . $this->id . '_' . $current_section );
+ }
+}
+
+endif;
\ No newline at end of file
diff --git a/includes/admin/settings/class-sp-settings-players.php b/includes/admin/settings/class-sp-settings-players.php
new file mode 100644
index 00000000..612f8fa5
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-players.php
@@ -0,0 +1,783 @@
+id = 'players';
+ $this->label = __( 'Players', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option( 'sportspress_tax_classes' ) ) ) );
+ $classes_options = array();
+ if ( $tax_classes )
+ foreach ( $tax_classes as $class )
+ $classes_options[ sanitize_title( $class ) ] = esc_html( $class );
+
+ return apply_filters('sportspress_event_settings', array(
+
+ array( 'title' => __( 'Player Options', 'sportspress' ), 'type' => 'title','desc' => '', 'id' => 'tax_options' ),
+
+ array(
+ 'title' => __( 'Enable Players', 'sportspress' ),
+ 'desc' => __( 'Enable taxes and tax calculations', 'sportspress' ),
+ 'id' => 'sportspress_calc_taxes',
+ 'default' => 'no',
+ 'type' => 'checkbox'
+ ),
+
+ array(
+ 'title' => __( 'Prices Entered With Tax', 'sportspress' ),
+ 'id' => 'sportspress_prices_include_tax',
+ 'default' => 'no',
+ 'type' => 'radio',
+ 'options' => array(
+ 'vs' => sprintf( '%s vs %s', __( 'Player', 'sportspress' ), __( 'Player', 'sportspress' ) ),
+ 'v' => sprintf( '%s v %s', __( 'Player', 'sportspress' ), __( 'Player', 'sportspress' ) ),
+ '—' => sprintf( '%s — %s', __( 'Player', 'sportspress' ), __( 'Player', 'sportspress' ) ),
+ '/' => sprintf( '%s / %s', __( 'Player', 'sportspress' ), __( 'Player', 'sportspress' ) )
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Calculate Tax Based On:', 'sportspress' ),
+ 'id' => 'sportspress_tax_based_on',
+ 'desc_tip' => __( 'This option determines which address is used to calculate tax.', 'sportspress' ),
+ 'default' => 'shipping',
+ 'type' => 'select',
+ 'options' => array(
+ 'shipping' => __( 'Customer shipping address', 'sportspress' ),
+ 'billing' => __( 'Customer billing address', 'sportspress' ),
+ 'base' => __( 'Shop base address', 'sportspress' )
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Default Customer Address:', 'sportspress' ),
+ 'id' => 'sportspress_default_customer_address',
+ 'desc_tip' => __( 'This option determines the customers default address (before they input their own).', 'sportspress' ),
+ 'default' => 'base',
+ 'type' => 'select',
+ 'options' => array(
+ '' => __( 'No address', 'sportspress' ),
+ 'base' => __( 'Shop base address', 'sportspress' ),
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Shipping Tax Class:', 'sportspress' ),
+ 'desc' => __( 'Optionally control which tax class shipping gets, or leave it so shipping tax is based on the cart items themselves.', 'sportspress' ),
+ 'id' => 'sportspress_shipping_tax_class',
+ 'css' => 'min-width:150px;',
+ 'default' => 'title',
+ 'type' => 'select',
+ 'options' => array( '' => __( 'Shipping tax class based on cart items', 'sportspress' ), 'standard' => __( 'Standard', 'sportspress' ) ) + $classes_options,
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Rounding', 'sportspress' ),
+ 'desc' => __( 'Round tax at subtotal level, instead of rounding per line', 'sportspress' ),
+ 'id' => 'sportspress_tax_round_at_subtotal',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ ),
+
+ array(
+ 'title' => __( 'Additional Tax Classes', 'sportspress' ),
+ 'desc' => __( 'List additonal tax classes below (1 per line). This is in addition to the default Standard Rate. Tax classes can be assigned to products.', 'sportspress' ),
+ 'id' => 'sportspress_tax_classes',
+ 'css' => 'width:100%; height: 65px;',
+ 'type' => 'textarea',
+ 'default' => sprintf( __( 'Reduced Rate%sZero Rate', 'sportspress' ), PHP_EOL )
+ ),
+
+ array(
+ 'title' => __( 'Display prices in the shop:', 'sportspress' ),
+ 'id' => 'sportspress_tax_display_shop',
+ 'default' => 'excl',
+ 'type' => 'select',
+ 'options' => array(
+ 'incl' => __( 'Including tax', 'sportspress' ),
+ 'excl' => __( 'Excluding tax', 'sportspress' ),
+ )
+ ),
+
+ array(
+ 'title' => __( 'Price display suffix:', 'sportspress' ),
+ 'id' => 'sportspress_price_display_suffix',
+ 'default' => '',
+ 'type' => 'text',
+ 'desc' => __( 'Define text to show after your product prices. This could be, for example, "inc. Vat" to explain your pricing. You can also have prices substituted here using one of the following: {price_including_tax}, {price_excluding_tax}.', 'sportspress' ),
+ ),
+
+ array(
+ 'title' => __( 'Display prices during cart/checkout:', 'sportspress' ),
+ 'id' => 'sportspress_tax_display_cart',
+ 'default' => 'excl',
+ 'type' => 'select',
+ 'options' => array(
+ 'incl' => __( 'Including tax', 'sportspress' ),
+ 'excl' => __( 'Excluding tax', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Display tax totals:', 'sportspress' ),
+ 'id' => 'sportspress_tax_total_display',
+ 'default' => 'itemized',
+ 'type' => 'select',
+ 'options' => array(
+ 'single' => __( 'As a single total', 'sportspress' ),
+ 'itemized' => __( 'Itemized', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'results' ),
+
+ array( 'type' => 'sectionend', 'id' => 'event_options' ),
+
+ )); // End event settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+
+ if ( $current_section == 'standard' || in_array( $current_section, array_map( 'sanitize_title', $tax_classes ) ) ) {
+ $this->output_tax_rates();
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+ /**
+ * Save settings
+ */
+ public function save() {
+ global $current_section, $wpdb;
+
+ if ( ! $current_section ) {
+
+ $settings = $this->get_settings();
+ SP_Admin_Settings::save_fields( $settings );
+
+ } else {
+
+ $this->save_tax_rates();
+
+ }
+
+ $wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_sp_tax_rates_%') OR `option_name` LIKE ('_transient_timeout_sp_tax_rates_%')" );
+ }
+
+ /**
+ * Output tax rate tables
+ */
+ public function output_tax_rates() {
+ global $sportspress, $current_section, $wpdb;
+
+ $page = ! empty( $_GET['p'] ) ? absint( $_GET['p'] ) : 1;
+ $limit = 100;
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+ $current_class = '';
+
+ foreach( $tax_classes as $class )
+ if ( sanitize_title( $class ) == $current_section )
+ $current_class = $class;
+ ?>
+
+ See here for available alpha-2 country codes.', 'sportspress' ), 'http://en.wikipedia.org/wiki/ISO_3166-1#Current_codes' ); ?>
+
+
+ $value ) {
+
+ // new keys are inserted...
+ if ( $key == 'new' ) {
+
+ foreach ( $value as $new_key => $new_value ) {
+
+ // Sanitize + format
+ $country = strtoupper( sanitize_text_field( $tax_rate_country[ $key ][ $new_key ] ) );
+ $state = strtoupper( sanitize_text_field( $tax_rate_state[ $key ][ $new_key ] ) );
+ $postcode = sanitize_text_field( $tax_rate_postcode[ $key ][ $new_key ] );
+ $city = sanitize_text_field( $tax_rate_city[ $key ][ $new_key ] );
+ $rate = number_format( sanitize_text_field( $tax_rate[ $key ][ $new_key ] ), 4, '.', '' );
+ $name = sanitize_text_field( $tax_rate_name[ $key ][ $new_key ] );
+ $priority = absint( sanitize_text_field( $tax_rate_priority[ $key ][ $new_key ] ) );
+ $compound = isset( $tax_rate_compound[ $key ][ $new_key ] ) ? 1 : 0;
+ $shipping = isset( $tax_rate_shipping[ $key ][ $new_key ] ) ? 1 : 0;
+
+ if ( ! $name )
+ $name = __( 'Tax', 'sportspress' );
+
+ if ( $country == '*' )
+ $country = '';
+
+ if ( $state == '*' )
+ $state = '';
+
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rates",
+ array(
+ 'tax_rate_country' => $country,
+ 'tax_rate_state' => $state,
+ 'tax_rate' => $rate,
+ 'tax_rate_name' => $name,
+ 'tax_rate_priority' => $priority,
+ 'tax_rate_compound' => $compound,
+ 'tax_rate_shipping' => $shipping,
+ 'tax_rate_order' => $i,
+ 'tax_rate_class' => sanitize_title( $current_class )
+ )
+ );
+
+ $tax_rate_id = $wpdb->insert_id;
+
+ if ( ! empty( $postcode ) ) {
+ $postcodes = explode( ';', $postcode );
+ $postcodes = array_map( 'strtoupper', array_map( 'sanitize_text_field', $postcodes ) );
+
+ $postcode_query = array();
+
+ foreach( $postcodes as $postcode )
+ if ( strstr( $postcode, '-' ) ) {
+ $postcode_parts = explode( '-', $postcode );
+
+ if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
+ for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
+ if ( ! $i )
+ continue;
+
+ if ( strlen( $i ) < strlen( $postcode_parts[0] ) )
+ $i = str_pad( $i, strlen( $postcode_parts[0] ), "0", STR_PAD_LEFT );
+
+ $postcode_query[] = "( '" . esc_sql( $i ) . "', $tax_rate_id, 'postcode' )";
+ }
+ }
+ } else {
+ if ( $postcode )
+ $postcode_query[] = "( '" . esc_sql( $postcode ) . "', $tax_rate_id, 'postcode' )";
+ }
+
+ $wpdb->query( "INSERT INTO {$wpdb->prefix}sportspress_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
+ }
+
+ if ( ! empty( $city ) ) {
+ $cities = explode( ';', $city );
+ $cities = array_map( 'strtoupper', array_map( 'sanitize_text_field', $cities ) );
+ foreach( $cities as $city ) {
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
+ }
+
+ $i++;
+ }
+
+ // ...whereas the others are updated
+ } else {
+
+ $tax_rate_id = absint( $key );
+
+ if ( $_POST['remove_tax_rate'][ $key ] == 1 ) {
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d;", $tax_rate_id ) );
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rates WHERE tax_rate_id = %d;", $tax_rate_id ) );
+ continue;
+ }
+
+ // Sanitize + format
+ $country = strtoupper( sanitize_text_field( $tax_rate_country[ $key ] ) );
+ $state = strtoupper( sanitize_text_field( $tax_rate_state[ $key ] ) );
+ $rate = number_format( (double) sanitize_text_field( $tax_rate[ $key ] ), 4, '.', '' );
+ $name = sanitize_text_field( $tax_rate_name[ $key ] );
+ $priority = absint( sanitize_text_field( $tax_rate_priority[ $key ] ) );
+ $compound = isset( $tax_rate_compound[ $key ] ) ? 1 : 0;
+ $shipping = isset( $tax_rate_shipping[ $key ] ) ? 1 : 0;
+
+ if ( ! $name )
+ $name = __( 'Tax', 'sportspress' );
+
+ if ( $country == '*' )
+ $country = '';
+
+ if ( $state == '*' )
+ $state = '';
+
+ $wpdb->update(
+ $wpdb->prefix . "sportspress_tax_rates",
+ array(
+ 'tax_rate_country' => $country,
+ 'tax_rate_state' => $state,
+ 'tax_rate' => $rate,
+ 'tax_rate_name' => $name,
+ 'tax_rate_priority' => $priority,
+ 'tax_rate_compound' => $compound,
+ 'tax_rate_shipping' => $shipping,
+ 'tax_rate_order' => $i,
+ 'tax_rate_class' => sanitize_title( $current_class )
+ ),
+ array(
+ 'tax_rate_id' => $tax_rate_id
+ )
+ );
+
+ if ( isset( $tax_rate_postcode[ $key ] ) ) {
+ // Delete old
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'postcode';", $tax_rate_id ) );
+
+ // Add changed
+ $postcode = sanitize_text_field( $tax_rate_postcode[ $key ] );
+ $postcodes = explode( ';', $postcode );
+ $postcodes = array_map( 'strtoupper', array_map( 'sanitize_text_field', $postcodes ) );
+
+ $postcode_query = array();
+
+ foreach( $postcodes as $postcode )
+ if ( strstr( $postcode, '-' ) ) {
+ $postcode_parts = explode( '-', $postcode );
+
+ if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
+ for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
+ if ( ! $i )
+ continue;
+
+ if ( strlen( $i ) < strlen( $postcode_parts[0] ) )
+ $i = str_pad( $i, strlen( $postcode_parts[0] ), "0", STR_PAD_LEFT );
+
+ $postcode_query[] = "( '" . esc_sql( $i ) . "', $tax_rate_id, 'postcode' )";
+ }
+ }
+ } else {
+ if ( $postcode )
+ $postcode_query[] = "( '" . esc_sql( $postcode ) . "', $tax_rate_id, 'postcode' )";
+ }
+
+ $wpdb->query( "INSERT INTO {$wpdb->prefix}sportspress_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
+
+ }
+
+ if ( isset( $tax_rate_city[ $key ] ) ) {
+ // Delete old
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'city';", $tax_rate_id ) );
+
+ // Add changed
+ $city = sanitize_text_field( $tax_rate_city[ $key ] );
+ $cities = explode( ';', $city );
+ $cities = array_map( 'strtoupper', array_map( 'sanitize_text_field', $cities ) );
+ foreach( $cities as $city ) {
+ if ( $city ) {
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
+ }
+ }
+
+ $i++;
+ }
+ }
+ }
+
+ /**
+ * Output results settings.
+ *
+ * @access public
+ * @return void
+ */
+ public function results_setting() {
+ $main_result = get_option( 'sportspress_main_result', 0 );
+
+ $args = array(
+ 'post_type' => 'sp_result',
+ 'numberposts' => -1,
+ 'posts_per_page' => -1,
+ 'orderby' => 'menu_order',
+ 'order' => 'ASC'
+ );
+ $data = get_posts( $args );
+ ?>
+
+ |
+
+
+
+ |
+
+ id = 'products';
+ $this->label = __( 'Products', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ add_action( 'sportspress_sections_' . $this->id, array( $this, 'output_sections' ) );
+ }
+
+ /**
+ * Get sections
+ *
+ * @return array
+ */
+ public function get_sections() {
+ $sections = array(
+ '' => __( 'Product Options', 'sportspress' ),
+ 'inventory' => __( 'Inventory', 'sportspress' )
+ );
+
+ return $sections;
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ $settings = $this->get_settings( $current_section );
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+
+ /**
+ * Save settings
+ */
+ public function save() {
+ global $current_section;
+
+ $settings = $this->get_settings( $current_section );
+ SP_Admin_Settings::save_fields( $settings );
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings( $current_section = '' ) {
+
+ if ( $current_section == 'inventory' ) {
+
+ return apply_filters('sportspress_inventory_settings', array(
+
+ array( 'title' => __( 'Inventory Options', 'sportspress' ), 'type' => 'title', 'desc' => '', 'id' => 'inventory_options' ),
+
+ array(
+ 'title' => __( 'Manage Stock', 'sportspress' ),
+ 'desc' => __( 'Enable stock management', 'sportspress' ),
+ 'id' => 'sportspress_manage_stock',
+ 'default' => 'yes',
+ 'type' => 'checkbox'
+ ),
+
+ array(
+ 'title' => __( 'Hold Stock (minutes)', 'sportspress' ),
+ 'desc' => __( 'Hold stock (for unpaid orders) for x minutes. When this limit is reached, the pending order will be cancelled. Leave blank to disable.', 'sportspress' ),
+ 'id' => 'sportspress_hold_stock_minutes',
+ 'type' => 'number',
+ 'custom_attributes' => array(
+ 'min' => 0,
+ 'step' => 1
+ ),
+ 'css' => 'width:50px;',
+ 'default' => '60',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Notifications', 'sportspress' ),
+ 'desc' => __( 'Enable low stock notifications', 'sportspress' ),
+ 'id' => 'sportspress_notify_low_stock',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Enable out of stock notifications', 'sportspress' ),
+ 'id' => 'sportspress_notify_no_stock',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Notification Recipient', 'sportspress' ),
+ 'desc' => '',
+ 'id' => 'sportspress_stock_email_recipient',
+ 'type' => 'email',
+ 'default' => get_option( 'admin_email' ),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Low Stock Threshold', 'sportspress' ),
+ 'desc' => '',
+ 'id' => 'sportspress_notify_low_stock_amount',
+ 'css' => 'width:50px;',
+ 'type' => 'number',
+ 'custom_attributes' => array(
+ 'min' => 0,
+ 'step' => 1
+ ),
+ 'default' => '2',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Out Of Stock Threshold', 'sportspress' ),
+ 'desc' => '',
+ 'id' => 'sportspress_notify_no_stock_amount',
+ 'css' => 'width:50px;',
+ 'type' => 'number',
+ 'custom_attributes' => array(
+ 'min' => 0,
+ 'step' => 1
+ ),
+ 'default' => '0',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Out Of Stock Visibility', 'sportspress' ),
+ 'desc' => __( 'Hide out of stock items from the catalog', 'sportspress' ),
+ 'id' => 'sportspress_hide_out_of_stock_items',
+ 'default' => 'no',
+ 'type' => 'checkbox'
+ ),
+
+ array(
+ 'title' => __( 'Stock Display Format', 'sportspress' ),
+ 'desc' => __( 'This controls how stock is displayed on the frontend.', 'sportspress' ),
+ 'id' => 'sportspress_stock_format',
+ 'css' => 'min-width:150px;',
+ 'default' => '',
+ 'type' => 'select',
+ 'options' => array(
+ '' => __( 'Always show stock e.g. "12 in stock"', 'sportspress' ),
+ 'low_amount' => __( 'Only show stock when low e.g. "Only 2 left in stock" vs. "In Stock"', 'sportspress' ),
+ 'no_amount' => __( 'Never show stock amount', 'sportspress' ),
+ ),
+ 'desc_tip' => true,
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'inventory_options'),
+
+ ));
+
+ } else {
+
+ // Get shop page
+ $shop_page_id = sp_get_page_id('shop');
+
+ $base_slug = ($shop_page_id > 0 && get_page( $shop_page_id )) ? get_page_uri( $shop_page_id ) : 'shop';
+
+ $sportspress_prepend_shop_page_to_products_warning = '';
+
+ if ( $shop_page_id > 0 && sizeof(get_pages("child_of=$shop_page_id")) > 0 )
+ $sportspress_prepend_shop_page_to_products_warning = ' ' . __( 'Note: The shop page has children - child pages will not work if you enable this option.', 'sportspress' ) . '';
+
+ return apply_filters( 'sportspress_product_settings', array(
+
+ array( 'title' => __( 'Product Listings', 'sportspress' ), 'type' => 'title','desc' => '', 'id' => 'catalog_options' ),
+
+ array(
+ 'title' => __( 'Product Archive / Shop Page', 'sportspress' ),
+ 'desc' => '
' . sprintf( __( 'The base page can also be used in your product permalinks.', 'sportspress' ), admin_url( 'options-permalink.php' ) ),
+ 'id' => 'sportspress_shop_page_id',
+ 'type' => 'single_select_page',
+ 'default' => '',
+ 'class' => 'chosen_select_nostd',
+ 'css' => 'min-width:300px;',
+ 'desc_tip' => __( 'This sets the base page of your shop - this is where your product archive will be.', 'sportspress' ),
+ ),
+
+ array(
+ 'title' => __( 'Shop Page Display', 'sportspress' ),
+ 'desc' => __( 'This controls what is shown on the product archive.', 'sportspress' ),
+ 'id' => 'sportspress_shop_page_display',
+ 'class' => 'chosen_select',
+ 'css' => 'min-width:300px;',
+ 'default' => '',
+ 'type' => 'select',
+ 'options' => array(
+ '' => __( 'Show products', 'sportspress' ),
+ 'subcategories' => __( 'Show subcategories', 'sportspress' ),
+ 'both' => __( 'Show both', 'sportspress' ),
+ ),
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Default Category Display', 'sportspress' ),
+ 'desc' => __( 'This controls what is shown on category archives.', 'sportspress' ),
+ 'id' => 'sportspress_category_archive_display',
+ 'class' => 'chosen_select',
+ 'css' => 'min-width:300px;',
+ 'default' => '',
+ 'type' => 'select',
+ 'options' => array(
+ '' => __( 'Show products', 'sportspress' ),
+ 'subcategories' => __( 'Show subcategories', 'sportspress' ),
+ 'both' => __( 'Show both', 'sportspress' ),
+ ),
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Default Product Sorting', 'sportspress' ),
+ 'desc' => __( 'This controls the default sort order of the catalog.', 'sportspress' ),
+ 'id' => 'sportspress_default_catalog_orderby',
+ 'class' => 'chosen_select',
+ 'css' => 'min-width:300px;',
+ 'default' => 'title',
+ 'type' => 'select',
+ 'options' => apply_filters('sportspress_default_catalog_orderby_options', array(
+ 'menu_order' => __( 'Default sorting (custom ordering + name)', 'sportspress' ),
+ 'popularity' => __( 'Popularity (sales)', 'sportspress' ),
+ 'rating' => __( 'Average Rating', 'sportspress' ),
+ 'date' => __( 'Sort by most recent', 'sportspress' ),
+ 'price' => __( 'Sort by price (asc)', 'sportspress' ),
+ 'price-desc' => __( 'Sort by price (desc)', 'sportspress' ),
+ )),
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Add to cart', 'sportspress' ),
+ 'desc' => __( 'Redirect to the cart page after successful addition', 'sportspress' ),
+ 'id' => 'sportspress_cart_redirect_after_add',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start'
+ ),
+
+ array(
+ 'desc' => __( 'Enable AJAX add to cart buttons on archives', 'sportspress' ),
+ 'id' => 'sportspress_enable_ajax_add_to_cart',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end'
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'catalog_options' ),
+
+ array( 'title' => __( 'Product Data', 'sportspress' ), 'type' => 'title', 'id' => 'product_data_options' ),
+
+ array(
+ 'title' => __( 'Weight Unit', 'sportspress' ),
+ 'desc' => __( 'This controls what unit you will define weights in.', 'sportspress' ),
+ 'id' => 'sportspress_weight_unit',
+ 'class' => 'chosen_select',
+ 'css' => 'min-width:300px;',
+ 'default' => 'kg',
+ 'type' => 'select',
+ 'options' => array(
+ 'kg' => __( 'kg', 'sportspress' ),
+ 'g' => __( 'g', 'sportspress' ),
+ 'lbs' => __( 'lbs', 'sportspress' ),
+ 'oz' => __( 'oz', 'sportspress' ),
+ ),
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Dimensions Unit', 'sportspress' ),
+ 'desc' => __( 'This controls what unit you will define lengths in.', 'sportspress' ),
+ 'id' => 'sportspress_dimension_unit',
+ 'class' => 'chosen_select',
+ 'css' => 'min-width:300px;',
+ 'default' => 'cm',
+ 'type' => 'select',
+ 'options' => array(
+ 'm' => __( 'm', 'sportspress' ),
+ 'cm' => __( 'cm', 'sportspress' ),
+ 'mm' => __( 'mm', 'sportspress' ),
+ 'in' => __( 'in', 'sportspress' ),
+ 'yd' => __( 'yd', 'sportspress' ),
+ ),
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Product Ratings', 'sportspress' ),
+ 'desc' => __( 'Enable ratings on reviews', 'sportspress' ),
+ 'id' => 'sportspress_enable_review_rating',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start',
+ 'show_if_checked' => 'option',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Ratings are required to leave a review', 'sportspress' ),
+ 'id' => 'sportspress_review_rating_required',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => '',
+ 'show_if_checked' => 'yes',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Show "verified owner" label for customer reviews', 'sportspress' ),
+ 'id' => 'sportspress_review_rating_verification_label',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => '',
+ 'show_if_checked' => 'yes',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Only allow reviews from "verified owners"', 'sportspress' ),
+ 'id' => 'sportspress_review_rating_verification_required',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end',
+ 'show_if_checked' => 'yes',
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'product_data_options' ),
+
+ array( 'title' => __( 'Product Image Sizes', 'sportspress' ), 'type' => 'title','desc' => sprintf(__( 'These settings affect the actual dimensions of images in your catalog - the display on the front-end will still be affected by CSS styles. After changing these settings you may need to regenerate your thumbnails.', 'sportspress' ), 'http://wordpress.org/extend/plugins/regenerate-thumbnails/'), 'id' => 'image_options' ),
+
+ array(
+ 'title' => __( 'Catalog Images', 'sportspress' ),
+ 'desc' => __( 'This size is usually used in product listings', 'sportspress' ),
+ 'id' => 'shop_catalog_image_size',
+ 'css' => '',
+ 'type' => 'image_width',
+ 'default' => array(
+ 'width' => '150',
+ 'height' => '150',
+ 'crop' => true
+ ),
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Single Product Image', 'sportspress' ),
+ 'desc' => __( 'This is the size used by the main image on the product page.', 'sportspress' ),
+ 'id' => 'shop_single_image_size',
+ 'css' => '',
+ 'type' => 'image_width',
+ 'default' => array(
+ 'width' => '300',
+ 'height' => '300',
+ 'crop' => 1
+ ),
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Product Thumbnails', 'sportspress' ),
+ 'desc' => __( 'This size is usually used for the gallery of images on the product page.', 'sportspress' ),
+ 'id' => 'shop_thumbnail_image_size',
+ 'css' => '',
+ 'type' => 'image_width',
+ 'default' => array(
+ 'width' => '90',
+ 'height' => '90',
+ 'crop' => 1
+ ),
+ 'desc_tip' => true,
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'image_options' ),
+
+ array( 'title' => __( 'Downloadable Products', 'sportspress' ), 'type' => 'title', 'id' => 'digital_download_options' ),
+
+ array(
+ 'title' => __( 'File Download Method', 'sportspress' ),
+ 'desc' => __( 'Forcing downloads will keep URLs hidden, but some servers may serve large files unreliably. If supported, X-Accel-Redirect/ X-Sendfile can be used to serve downloads instead (server requires mod_xsendfile).', 'sportspress' ),
+ 'id' => 'sportspress_file_download_method',
+ 'type' => 'select',
+ 'class' => 'chosen_select',
+ 'css' => 'min-width:300px;',
+ 'default' => 'force',
+ 'desc_tip' => true,
+ 'options' => array(
+ 'force' => __( 'Force Downloads', 'sportspress' ),
+ 'xsendfile' => __( 'X-Accel-Redirect/X-Sendfile', 'sportspress' ),
+ 'redirect' => __( 'Redirect only', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Access Restriction', 'sportspress' ),
+ 'desc' => __( 'Downloads require login', 'sportspress' ),
+ 'id' => 'sportspress_downloads_require_login',
+ 'type' => 'checkbox',
+ 'default' => 'no',
+ 'desc_tip' => __( 'This setting does not apply to guest purchases.', 'sportspress' ),
+ 'checkboxgroup' => 'start',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Grant access to downloadable products after payment', 'sportspress' ),
+ 'id' => 'sportspress_downloads_grant_access_after_payment',
+ 'type' => 'checkbox',
+ 'default' => 'yes',
+ 'desc_tip' => __( 'Enable this option to grant access to downloads when orders are "processing", rather than "completed".', 'sportspress' ),
+ 'checkboxgroup' => 'end',
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'digital_download_options' ),
+
+ ));
+ }
+ }
+}
+
+endif;
+
+return new SP_Settings_Products();
\ No newline at end of file
diff --git a/includes/admin/settings/class-sp-settings-shipping.php b/includes/admin/settings/class-sp-settings-shipping.php
new file mode 100644
index 00000000..e4ad3101
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-shipping.php
@@ -0,0 +1,281 @@
+id = 'shipping';
+ $this->label = __( 'Shipping', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_sections_' . $this->id, array( $this, 'output_sections' ) );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_admin_field_shipping_methods', array( $this, 'shipping_methods_setting' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get sections
+ *
+ * @return array
+ */
+ public function get_sections() {
+ $sections = array(
+ '' => __( 'Shipping Options', 'sportspress' )
+ );
+
+ // Load shipping methods so we can show any global options they may have
+ $shipping_methods = SP()->shipping->load_shipping_methods();
+
+ foreach ( $shipping_methods as $method ) {
+
+ if ( ! $method->has_settings() ) continue;
+
+ $title = empty( $method->method_title ) ? ucfirst( $method->id ) : $method->method_title;
+
+ $sections[ strtolower( get_class( $method ) ) ] = esc_html( $title );
+ }
+
+ return $sections;
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ return apply_filters('sportspress_shipping_settings', array(
+
+ array( 'title' => __( 'Shipping Options', 'sportspress' ), 'type' => 'title', 'id' => 'shipping_options' ),
+
+ array(
+ 'title' => __( 'Shipping Calculations', 'sportspress' ),
+ 'desc' => __( 'Enable shipping', 'sportspress' ),
+ 'id' => 'sportspress_calc_shipping',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start'
+ ),
+
+ array(
+ 'desc' => __( 'Enable the shipping calculator on the cart page', 'sportspress' ),
+ 'id' => 'sportspress_enable_shipping_calc',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => '',
+ 'autoload' => false
+ ),
+
+ array(
+ 'desc' => __( 'Hide shipping costs until an address is entered', 'sportspress' ),
+ 'id' => 'sportspress_shipping_cost_requires_address',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end',
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Shipping Display Mode', 'sportspress' ),
+ 'desc' => __( 'This controls how multiple shipping methods are displayed on the frontend.', 'sportspress' ),
+ 'id' => 'sportspress_shipping_method_format',
+ 'default' => '',
+ 'type' => 'radio',
+ 'options' => array(
+ '' => __( 'Display shipping methods with "radio" buttons', 'sportspress' ),
+ 'select' => __( 'Display shipping methods in a dropdown', 'sportspress' ),
+ ),
+ 'desc_tip' => true,
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Shipping Destination', 'sportspress' ),
+ 'desc' => __( 'Ship to billing address by default', 'sportspress' ),
+ 'id' => 'sportspress_ship_to_billing',
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'start',
+ 'autoload' => false,
+ 'show_if_checked' => 'option',
+ ),
+
+ array(
+ 'desc' => __( 'Only ship to the users billing address', 'sportspress' ),
+ 'id' => 'sportspress_ship_to_billing_address_only',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ 'checkboxgroup' => 'end',
+ 'autoload' => false,
+ 'show_if_checked' => 'yes',
+ ),
+
+ array(
+ 'title' => __( 'Restrict shipping to Location(s)', 'sportspress' ),
+ 'desc' => sprintf( __( 'Choose which countries you want to ship to, or choose to ship to all locations you sell to.', 'sportspress' ), admin_url( 'admin.php?page=sp-settings&tab=general' ) ),
+ 'id' => 'sportspress_ship_to_countries',
+ 'default' => '',
+ 'type' => 'select',
+ 'class' => 'chosen_select',
+ 'desc_tip' => false,
+ 'options' => array(
+ '' => __( 'Ship to all countries you sell to', 'sportspress' ),
+ 'all' => __( 'Ship to all countries', 'sportspress' ),
+ 'specific' => __( 'Ship to specific countries only', 'sportspress' )
+ )
+ ),
+
+ array(
+ 'title' => __( 'Specific Countries', 'sportspress' ),
+ 'desc' => '',
+ 'id' => 'sportspress_specific_ship_to_countries',
+ 'css' => '',
+ 'default' => '',
+ 'type' => 'multi_select_countries'
+ ),
+
+ array(
+ 'type' => 'shipping_methods',
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'shipping_options' ),
+
+ )); // End shipping settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ // Load shipping methods so we can show any global options they may have
+ $shipping_methods = SP()->shipping->load_shipping_methods();
+
+ if ( $current_section ) {
+ foreach ( $shipping_methods as $method ) {
+ if ( strtolower( get_class( $method ) ) == strtolower( $current_section ) && $method->has_settings() ) {
+ $method->admin_options();
+ break;
+ }
+ }
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+ /**
+ * Output shipping method settings.
+ *
+ * @access public
+ * @return void
+ */
+ public function shipping_methods_setting() {
+ $default_shipping_method = esc_attr( get_option('sportspress_default_shipping_method') );
+ ?>
+
+ |
+
+
+ |
+
+ get_settings();
+
+ SP_Admin_Settings::save_fields( $settings );
+ SP()->shipping->process_admin_options();
+
+ } elseif ( class_exists( $current_section ) ) {
+
+ $current_section_class = new $current_section();
+
+ do_action( 'sportspress_update_options_' . $this->id . '_' . $current_section_class->id );
+ }
+ }
+}
+
+endif;
+
+return new SP_Settings_Shipping();
diff --git a/includes/admin/settings/class-sp-settings-tax.php b/includes/admin/settings/class-sp-settings-tax.php
new file mode 100644
index 00000000..fd50c87d
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-tax.php
@@ -0,0 +1,735 @@
+id = 'tax';
+ $this->label = __( 'Tax', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_sections_' . $this->id, array( $this, 'output_sections' ) );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get sections
+ *
+ * @return array
+ */
+ public function get_sections() {
+ $sections = array(
+ '' => __( 'Tax Options', 'sportspress' ),
+ 'standard' => __( 'Standard Rates', 'sportspress' )
+ );
+
+ // Get tax classes and display as links
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+
+ if ( $tax_classes )
+ foreach ( $tax_classes as $class )
+ $sections[ sanitize_title( $class ) ] = sprintf( __( '%s Rates', 'sportspress' ), $class );
+
+ return $sections;
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option( 'sportspress_tax_classes' ) ) ) );
+ $classes_options = array();
+ if ( $tax_classes )
+ foreach ( $tax_classes as $class )
+ $classes_options[ sanitize_title( $class ) ] = esc_html( $class );
+
+ return apply_filters('sportspress_tax_settings', array(
+
+ array( 'title' => __( 'Tax Options', 'sportspress' ), 'type' => 'title','desc' => '', 'id' => 'tax_options' ),
+
+ array(
+ 'title' => __( 'Enable Taxes', 'sportspress' ),
+ 'desc' => __( 'Enable taxes and tax calculations', 'sportspress' ),
+ 'id' => 'sportspress_calc_taxes',
+ 'default' => 'no',
+ 'type' => 'checkbox'
+ ),
+
+ array(
+ 'title' => __( 'Prices Entered With Tax', 'sportspress' ),
+ 'id' => 'sportspress_prices_include_tax',
+ 'default' => 'no',
+ 'type' => 'radio',
+ 'desc_tip' => __( 'This option is important as it will affect how you input prices. Changing it will not update existing products.', 'sportspress' ),
+ 'options' => array(
+ 'yes' => __( 'Yes, I will enter prices inclusive of tax', 'sportspress' ),
+ 'no' => __( 'No, I will enter prices exclusive of tax', 'sportspress' )
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Calculate Tax Based On:', 'sportspress' ),
+ 'id' => 'sportspress_tax_based_on',
+ 'desc_tip' => __( 'This option determines which address is used to calculate tax.', 'sportspress' ),
+ 'default' => 'shipping',
+ 'type' => 'select',
+ 'options' => array(
+ 'shipping' => __( 'Customer shipping address', 'sportspress' ),
+ 'billing' => __( 'Customer billing address', 'sportspress' ),
+ 'base' => __( 'Shop base address', 'sportspress' )
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Default Customer Address:', 'sportspress' ),
+ 'id' => 'sportspress_default_customer_address',
+ 'desc_tip' => __( 'This option determines the customers default address (before they input their own).', 'sportspress' ),
+ 'default' => 'base',
+ 'type' => 'select',
+ 'options' => array(
+ '' => __( 'No address', 'sportspress' ),
+ 'base' => __( 'Shop base address', 'sportspress' ),
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Shipping Tax Class:', 'sportspress' ),
+ 'desc' => __( 'Optionally control which tax class shipping gets, or leave it so shipping tax is based on the cart items themselves.', 'sportspress' ),
+ 'id' => 'sportspress_shipping_tax_class',
+ 'css' => 'min-width:150px;',
+ 'default' => 'title',
+ 'type' => 'select',
+ 'options' => array( '' => __( 'Shipping tax class based on cart items', 'sportspress' ), 'standard' => __( 'Standard', 'sportspress' ) ) + $classes_options,
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Rounding', 'sportspress' ),
+ 'desc' => __( 'Round tax at subtotal level, instead of rounding per line', 'sportspress' ),
+ 'id' => 'sportspress_tax_round_at_subtotal',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ ),
+
+ array(
+ 'title' => __( 'Additional Tax Classes', 'sportspress' ),
+ 'desc' => __( 'List additonal tax classes below (1 per line). This is in addition to the default Standard Rate. Tax classes can be assigned to products.', 'sportspress' ),
+ 'id' => 'sportspress_tax_classes',
+ 'css' => 'width:100%; height: 65px;',
+ 'type' => 'textarea',
+ 'default' => sprintf( __( 'Reduced Rate%sZero Rate', 'sportspress' ), PHP_EOL )
+ ),
+
+ array(
+ 'title' => __( 'Display prices in the shop:', 'sportspress' ),
+ 'id' => 'sportspress_tax_display_shop',
+ 'default' => 'excl',
+ 'type' => 'select',
+ 'options' => array(
+ 'incl' => __( 'Including tax', 'sportspress' ),
+ 'excl' => __( 'Excluding tax', 'sportspress' ),
+ )
+ ),
+
+ array(
+ 'title' => __( 'Price display suffix:', 'sportspress' ),
+ 'id' => 'sportspress_price_display_suffix',
+ 'default' => '',
+ 'type' => 'text',
+ 'desc' => __( 'Define text to show after your product prices. This could be, for example, "inc. Vat" to explain your pricing. You can also have prices substituted here using one of the following: {price_including_tax}, {price_excluding_tax}.', 'sportspress' ),
+ ),
+
+ array(
+ 'title' => __( 'Display prices during cart/checkout:', 'sportspress' ),
+ 'id' => 'sportspress_tax_display_cart',
+ 'default' => 'excl',
+ 'type' => 'select',
+ 'options' => array(
+ 'incl' => __( 'Including tax', 'sportspress' ),
+ 'excl' => __( 'Excluding tax', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Display tax totals:', 'sportspress' ),
+ 'id' => 'sportspress_tax_total_display',
+ 'default' => 'itemized',
+ 'type' => 'select',
+ 'options' => array(
+ 'single' => __( 'As a single total', 'sportspress' ),
+ 'itemized' => __( 'Itemized', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'sectionend', 'id' => 'tax_options' ),
+
+ )); // End tax settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+
+ if ( $current_section == 'standard' || in_array( $current_section, array_map( 'sanitize_title', $tax_classes ) ) ) {
+ $this->output_tax_rates();
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+ /**
+ * Save settings
+ */
+ public function save() {
+ global $current_section, $wpdb;
+
+ if ( ! $current_section ) {
+
+ $settings = $this->get_settings();
+ SP_Admin_Settings::save_fields( $settings );
+
+ } else {
+
+ $this->save_tax_rates();
+
+ }
+
+ $wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_sp_tax_rates_%') OR `option_name` LIKE ('_transient_timeout_sp_tax_rates_%')" );
+ }
+
+ /**
+ * Output tax rate tables
+ */
+ public function output_tax_rates() {
+ global $sportspress, $current_section, $wpdb;
+
+ $page = ! empty( $_GET['p'] ) ? absint( $_GET['p'] ) : 1;
+ $limit = 100;
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+ $current_class = '';
+
+ foreach( $tax_classes as $class )
+ if ( sanitize_title( $class ) == $current_section )
+ $current_class = $class;
+ ?>
+
+ See here for available alpha-2 country codes.', 'sportspress' ), 'http://en.wikipedia.org/wiki/ISO_3166-1#Current_codes' ); ?>
+
+
+ $value ) {
+
+ // new keys are inserted...
+ if ( $key == 'new' ) {
+
+ foreach ( $value as $new_key => $new_value ) {
+
+ // Sanitize + format
+ $country = strtoupper( sanitize_text_field( $tax_rate_country[ $key ][ $new_key ] ) );
+ $state = strtoupper( sanitize_text_field( $tax_rate_state[ $key ][ $new_key ] ) );
+ $postcode = sanitize_text_field( $tax_rate_postcode[ $key ][ $new_key ] );
+ $city = sanitize_text_field( $tax_rate_city[ $key ][ $new_key ] );
+ $rate = number_format( sanitize_text_field( $tax_rate[ $key ][ $new_key ] ), 4, '.', '' );
+ $name = sanitize_text_field( $tax_rate_name[ $key ][ $new_key ] );
+ $priority = absint( sanitize_text_field( $tax_rate_priority[ $key ][ $new_key ] ) );
+ $compound = isset( $tax_rate_compound[ $key ][ $new_key ] ) ? 1 : 0;
+ $shipping = isset( $tax_rate_shipping[ $key ][ $new_key ] ) ? 1 : 0;
+
+ if ( ! $name )
+ $name = __( 'Tax', 'sportspress' );
+
+ if ( $country == '*' )
+ $country = '';
+
+ if ( $state == '*' )
+ $state = '';
+
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rates",
+ array(
+ 'tax_rate_country' => $country,
+ 'tax_rate_state' => $state,
+ 'tax_rate' => $rate,
+ 'tax_rate_name' => $name,
+ 'tax_rate_priority' => $priority,
+ 'tax_rate_compound' => $compound,
+ 'tax_rate_shipping' => $shipping,
+ 'tax_rate_order' => $i,
+ 'tax_rate_class' => sanitize_title( $current_class )
+ )
+ );
+
+ $tax_rate_id = $wpdb->insert_id;
+
+ if ( ! empty( $postcode ) ) {
+ $postcodes = explode( ';', $postcode );
+ $postcodes = array_map( 'strtoupper', array_map( 'sanitize_text_field', $postcodes ) );
+
+ $postcode_query = array();
+
+ foreach( $postcodes as $postcode )
+ if ( strstr( $postcode, '-' ) ) {
+ $postcode_parts = explode( '-', $postcode );
+
+ if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
+ for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
+ if ( ! $i )
+ continue;
+
+ if ( strlen( $i ) < strlen( $postcode_parts[0] ) )
+ $i = str_pad( $i, strlen( $postcode_parts[0] ), "0", STR_PAD_LEFT );
+
+ $postcode_query[] = "( '" . esc_sql( $i ) . "', $tax_rate_id, 'postcode' )";
+ }
+ }
+ } else {
+ if ( $postcode )
+ $postcode_query[] = "( '" . esc_sql( $postcode ) . "', $tax_rate_id, 'postcode' )";
+ }
+
+ $wpdb->query( "INSERT INTO {$wpdb->prefix}sportspress_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
+ }
+
+ if ( ! empty( $city ) ) {
+ $cities = explode( ';', $city );
+ $cities = array_map( 'strtoupper', array_map( 'sanitize_text_field', $cities ) );
+ foreach( $cities as $city ) {
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
+ }
+
+ $i++;
+ }
+
+ // ...whereas the others are updated
+ } else {
+
+ $tax_rate_id = absint( $key );
+
+ if ( $_POST['remove_tax_rate'][ $key ] == 1 ) {
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d;", $tax_rate_id ) );
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rates WHERE tax_rate_id = %d;", $tax_rate_id ) );
+ continue;
+ }
+
+ // Sanitize + format
+ $country = strtoupper( sanitize_text_field( $tax_rate_country[ $key ] ) );
+ $state = strtoupper( sanitize_text_field( $tax_rate_state[ $key ] ) );
+ $rate = number_format( (double) sanitize_text_field( $tax_rate[ $key ] ), 4, '.', '' );
+ $name = sanitize_text_field( $tax_rate_name[ $key ] );
+ $priority = absint( sanitize_text_field( $tax_rate_priority[ $key ] ) );
+ $compound = isset( $tax_rate_compound[ $key ] ) ? 1 : 0;
+ $shipping = isset( $tax_rate_shipping[ $key ] ) ? 1 : 0;
+
+ if ( ! $name )
+ $name = __( 'Tax', 'sportspress' );
+
+ if ( $country == '*' )
+ $country = '';
+
+ if ( $state == '*' )
+ $state = '';
+
+ $wpdb->update(
+ $wpdb->prefix . "sportspress_tax_rates",
+ array(
+ 'tax_rate_country' => $country,
+ 'tax_rate_state' => $state,
+ 'tax_rate' => $rate,
+ 'tax_rate_name' => $name,
+ 'tax_rate_priority' => $priority,
+ 'tax_rate_compound' => $compound,
+ 'tax_rate_shipping' => $shipping,
+ 'tax_rate_order' => $i,
+ 'tax_rate_class' => sanitize_title( $current_class )
+ ),
+ array(
+ 'tax_rate_id' => $tax_rate_id
+ )
+ );
+
+ if ( isset( $tax_rate_postcode[ $key ] ) ) {
+ // Delete old
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'postcode';", $tax_rate_id ) );
+
+ // Add changed
+ $postcode = sanitize_text_field( $tax_rate_postcode[ $key ] );
+ $postcodes = explode( ';', $postcode );
+ $postcodes = array_map( 'strtoupper', array_map( 'sanitize_text_field', $postcodes ) );
+
+ $postcode_query = array();
+
+ foreach( $postcodes as $postcode )
+ if ( strstr( $postcode, '-' ) ) {
+ $postcode_parts = explode( '-', $postcode );
+
+ if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
+ for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
+ if ( ! $i )
+ continue;
+
+ if ( strlen( $i ) < strlen( $postcode_parts[0] ) )
+ $i = str_pad( $i, strlen( $postcode_parts[0] ), "0", STR_PAD_LEFT );
+
+ $postcode_query[] = "( '" . esc_sql( $i ) . "', $tax_rate_id, 'postcode' )";
+ }
+ }
+ } else {
+ if ( $postcode )
+ $postcode_query[] = "( '" . esc_sql( $postcode ) . "', $tax_rate_id, 'postcode' )";
+ }
+
+ $wpdb->query( "INSERT INTO {$wpdb->prefix}sportspress_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
+
+ }
+
+ if ( isset( $tax_rate_city[ $key ] ) ) {
+ // Delete old
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'city';", $tax_rate_id ) );
+
+ // Add changed
+ $city = sanitize_text_field( $tax_rate_city[ $key ] );
+ $cities = explode( ';', $city );
+ $cities = array_map( 'strtoupper', array_map( 'sanitize_text_field', $cities ) );
+ foreach( $cities as $city ) {
+ if ( $city ) {
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
+ }
+ }
+
+ $i++;
+ }
+ }
+ }
+
+}
+
+endif;
+
+return new SP_Settings_Tax();
\ No newline at end of file
diff --git a/includes/admin/settings/class-sp-settings-teams.php b/includes/admin/settings/class-sp-settings-teams.php
new file mode 100644
index 00000000..ad1a1d08
--- /dev/null
+++ b/includes/admin/settings/class-sp-settings-teams.php
@@ -0,0 +1,783 @@
+id = 'teams';
+ $this->label = __( 'Teams', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option( 'sportspress_tax_classes' ) ) ) );
+ $classes_options = array();
+ if ( $tax_classes )
+ foreach ( $tax_classes as $class )
+ $classes_options[ sanitize_title( $class ) ] = esc_html( $class );
+
+ return apply_filters('sportspress_event_settings', array(
+
+ array( 'title' => __( 'Team Options', 'sportspress' ), 'type' => 'title','desc' => '', 'id' => 'tax_options' ),
+
+ array(
+ 'title' => __( 'Enable Teams', 'sportspress' ),
+ 'desc' => __( 'Enable taxes and tax calculations', 'sportspress' ),
+ 'id' => 'sportspress_calc_taxes',
+ 'default' => 'no',
+ 'type' => 'checkbox'
+ ),
+
+ array(
+ 'title' => __( 'Prices Entered With Tax', 'sportspress' ),
+ 'id' => 'sportspress_prices_include_tax',
+ 'default' => 'no',
+ 'type' => 'radio',
+ 'options' => array(
+ 'vs' => sprintf( '%s vs %s', __( 'Team', 'sportspress' ), __( 'Team', 'sportspress' ) ),
+ 'v' => sprintf( '%s v %s', __( 'Team', 'sportspress' ), __( 'Team', 'sportspress' ) ),
+ '—' => sprintf( '%s — %s', __( 'Team', 'sportspress' ), __( 'Team', 'sportspress' ) ),
+ '/' => sprintf( '%s / %s', __( 'Team', 'sportspress' ), __( 'Team', 'sportspress' ) )
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Calculate Tax Based On:', 'sportspress' ),
+ 'id' => 'sportspress_tax_based_on',
+ 'desc_tip' => __( 'This option determines which address is used to calculate tax.', 'sportspress' ),
+ 'default' => 'shipping',
+ 'type' => 'select',
+ 'options' => array(
+ 'shipping' => __( 'Customer shipping address', 'sportspress' ),
+ 'billing' => __( 'Customer billing address', 'sportspress' ),
+ 'base' => __( 'Shop base address', 'sportspress' )
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Default Customer Address:', 'sportspress' ),
+ 'id' => 'sportspress_default_customer_address',
+ 'desc_tip' => __( 'This option determines the customers default address (before they input their own).', 'sportspress' ),
+ 'default' => 'base',
+ 'type' => 'select',
+ 'options' => array(
+ '' => __( 'No address', 'sportspress' ),
+ 'base' => __( 'Shop base address', 'sportspress' ),
+ ),
+ ),
+
+ array(
+ 'title' => __( 'Shipping Tax Class:', 'sportspress' ),
+ 'desc' => __( 'Optionally control which tax class shipping gets, or leave it so shipping tax is based on the cart items themselves.', 'sportspress' ),
+ 'id' => 'sportspress_shipping_tax_class',
+ 'css' => 'min-width:150px;',
+ 'default' => 'title',
+ 'type' => 'select',
+ 'options' => array( '' => __( 'Shipping tax class based on cart items', 'sportspress' ), 'standard' => __( 'Standard', 'sportspress' ) ) + $classes_options,
+ 'desc_tip' => true,
+ ),
+
+ array(
+ 'title' => __( 'Rounding', 'sportspress' ),
+ 'desc' => __( 'Round tax at subtotal level, instead of rounding per line', 'sportspress' ),
+ 'id' => 'sportspress_tax_round_at_subtotal',
+ 'default' => 'no',
+ 'type' => 'checkbox',
+ ),
+
+ array(
+ 'title' => __( 'Additional Tax Classes', 'sportspress' ),
+ 'desc' => __( 'List additonal tax classes below (1 per line). This is in addition to the default Standard Rate. Tax classes can be assigned to products.', 'sportspress' ),
+ 'id' => 'sportspress_tax_classes',
+ 'css' => 'width:100%; height: 65px;',
+ 'type' => 'textarea',
+ 'default' => sprintf( __( 'Reduced Rate%sZero Rate', 'sportspress' ), PHP_EOL )
+ ),
+
+ array(
+ 'title' => __( 'Display prices in the shop:', 'sportspress' ),
+ 'id' => 'sportspress_tax_display_shop',
+ 'default' => 'excl',
+ 'type' => 'select',
+ 'options' => array(
+ 'incl' => __( 'Including tax', 'sportspress' ),
+ 'excl' => __( 'Excluding tax', 'sportspress' ),
+ )
+ ),
+
+ array(
+ 'title' => __( 'Price display suffix:', 'sportspress' ),
+ 'id' => 'sportspress_price_display_suffix',
+ 'default' => '',
+ 'type' => 'text',
+ 'desc' => __( 'Define text to show after your product prices. This could be, for example, "inc. Vat" to explain your pricing. You can also have prices substituted here using one of the following: {price_including_tax}, {price_excluding_tax}.', 'sportspress' ),
+ ),
+
+ array(
+ 'title' => __( 'Display prices during cart/checkout:', 'sportspress' ),
+ 'id' => 'sportspress_tax_display_cart',
+ 'default' => 'excl',
+ 'type' => 'select',
+ 'options' => array(
+ 'incl' => __( 'Including tax', 'sportspress' ),
+ 'excl' => __( 'Excluding tax', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array(
+ 'title' => __( 'Display tax totals:', 'sportspress' ),
+ 'id' => 'sportspress_tax_total_display',
+ 'default' => 'itemized',
+ 'type' => 'select',
+ 'options' => array(
+ 'single' => __( 'As a single total', 'sportspress' ),
+ 'itemized' => __( 'Itemized', 'sportspress' ),
+ ),
+ 'autoload' => false
+ ),
+
+ array( 'type' => 'results' ),
+
+ array( 'type' => 'sectionend', 'id' => 'event_options' ),
+
+ )); // End event settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+
+ if ( $current_section == 'standard' || in_array( $current_section, array_map( 'sanitize_title', $tax_classes ) ) ) {
+ $this->output_tax_rates();
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+ /**
+ * Save settings
+ */
+ public function save() {
+ global $current_section, $wpdb;
+
+ if ( ! $current_section ) {
+
+ $settings = $this->get_settings();
+ SP_Admin_Settings::save_fields( $settings );
+
+ } else {
+
+ $this->save_tax_rates();
+
+ }
+
+ $wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_sp_tax_rates_%') OR `option_name` LIKE ('_transient_timeout_sp_tax_rates_%')" );
+ }
+
+ /**
+ * Output tax rate tables
+ */
+ public function output_tax_rates() {
+ global $sportspress, $current_section, $wpdb;
+
+ $page = ! empty( $_GET['p'] ) ? absint( $_GET['p'] ) : 1;
+ $limit = 100;
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+ $current_class = '';
+
+ foreach( $tax_classes as $class )
+ if ( sanitize_title( $class ) == $current_section )
+ $current_class = $class;
+ ?>
+
+ See here for available alpha-2 country codes.', 'sportspress' ), 'http://en.wikipedia.org/wiki/ISO_3166-1#Current_codes' ); ?>
+
+
+ $value ) {
+
+ // new keys are inserted...
+ if ( $key == 'new' ) {
+
+ foreach ( $value as $new_key => $new_value ) {
+
+ // Sanitize + format
+ $country = strtoupper( sanitize_text_field( $tax_rate_country[ $key ][ $new_key ] ) );
+ $state = strtoupper( sanitize_text_field( $tax_rate_state[ $key ][ $new_key ] ) );
+ $postcode = sanitize_text_field( $tax_rate_postcode[ $key ][ $new_key ] );
+ $city = sanitize_text_field( $tax_rate_city[ $key ][ $new_key ] );
+ $rate = number_format( sanitize_text_field( $tax_rate[ $key ][ $new_key ] ), 4, '.', '' );
+ $name = sanitize_text_field( $tax_rate_name[ $key ][ $new_key ] );
+ $priority = absint( sanitize_text_field( $tax_rate_priority[ $key ][ $new_key ] ) );
+ $compound = isset( $tax_rate_compound[ $key ][ $new_key ] ) ? 1 : 0;
+ $shipping = isset( $tax_rate_shipping[ $key ][ $new_key ] ) ? 1 : 0;
+
+ if ( ! $name )
+ $name = __( 'Tax', 'sportspress' );
+
+ if ( $country == '*' )
+ $country = '';
+
+ if ( $state == '*' )
+ $state = '';
+
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rates",
+ array(
+ 'tax_rate_country' => $country,
+ 'tax_rate_state' => $state,
+ 'tax_rate' => $rate,
+ 'tax_rate_name' => $name,
+ 'tax_rate_priority' => $priority,
+ 'tax_rate_compound' => $compound,
+ 'tax_rate_shipping' => $shipping,
+ 'tax_rate_order' => $i,
+ 'tax_rate_class' => sanitize_title( $current_class )
+ )
+ );
+
+ $tax_rate_id = $wpdb->insert_id;
+
+ if ( ! empty( $postcode ) ) {
+ $postcodes = explode( ';', $postcode );
+ $postcodes = array_map( 'strtoupper', array_map( 'sanitize_text_field', $postcodes ) );
+
+ $postcode_query = array();
+
+ foreach( $postcodes as $postcode )
+ if ( strstr( $postcode, '-' ) ) {
+ $postcode_parts = explode( '-', $postcode );
+
+ if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
+ for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
+ if ( ! $i )
+ continue;
+
+ if ( strlen( $i ) < strlen( $postcode_parts[0] ) )
+ $i = str_pad( $i, strlen( $postcode_parts[0] ), "0", STR_PAD_LEFT );
+
+ $postcode_query[] = "( '" . esc_sql( $i ) . "', $tax_rate_id, 'postcode' )";
+ }
+ }
+ } else {
+ if ( $postcode )
+ $postcode_query[] = "( '" . esc_sql( $postcode ) . "', $tax_rate_id, 'postcode' )";
+ }
+
+ $wpdb->query( "INSERT INTO {$wpdb->prefix}sportspress_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
+ }
+
+ if ( ! empty( $city ) ) {
+ $cities = explode( ';', $city );
+ $cities = array_map( 'strtoupper', array_map( 'sanitize_text_field', $cities ) );
+ foreach( $cities as $city ) {
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
+ }
+
+ $i++;
+ }
+
+ // ...whereas the others are updated
+ } else {
+
+ $tax_rate_id = absint( $key );
+
+ if ( $_POST['remove_tax_rate'][ $key ] == 1 ) {
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d;", $tax_rate_id ) );
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rates WHERE tax_rate_id = %d;", $tax_rate_id ) );
+ continue;
+ }
+
+ // Sanitize + format
+ $country = strtoupper( sanitize_text_field( $tax_rate_country[ $key ] ) );
+ $state = strtoupper( sanitize_text_field( $tax_rate_state[ $key ] ) );
+ $rate = number_format( (double) sanitize_text_field( $tax_rate[ $key ] ), 4, '.', '' );
+ $name = sanitize_text_field( $tax_rate_name[ $key ] );
+ $priority = absint( sanitize_text_field( $tax_rate_priority[ $key ] ) );
+ $compound = isset( $tax_rate_compound[ $key ] ) ? 1 : 0;
+ $shipping = isset( $tax_rate_shipping[ $key ] ) ? 1 : 0;
+
+ if ( ! $name )
+ $name = __( 'Tax', 'sportspress' );
+
+ if ( $country == '*' )
+ $country = '';
+
+ if ( $state == '*' )
+ $state = '';
+
+ $wpdb->update(
+ $wpdb->prefix . "sportspress_tax_rates",
+ array(
+ 'tax_rate_country' => $country,
+ 'tax_rate_state' => $state,
+ 'tax_rate' => $rate,
+ 'tax_rate_name' => $name,
+ 'tax_rate_priority' => $priority,
+ 'tax_rate_compound' => $compound,
+ 'tax_rate_shipping' => $shipping,
+ 'tax_rate_order' => $i,
+ 'tax_rate_class' => sanitize_title( $current_class )
+ ),
+ array(
+ 'tax_rate_id' => $tax_rate_id
+ )
+ );
+
+ if ( isset( $tax_rate_postcode[ $key ] ) ) {
+ // Delete old
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'postcode';", $tax_rate_id ) );
+
+ // Add changed
+ $postcode = sanitize_text_field( $tax_rate_postcode[ $key ] );
+ $postcodes = explode( ';', $postcode );
+ $postcodes = array_map( 'strtoupper', array_map( 'sanitize_text_field', $postcodes ) );
+
+ $postcode_query = array();
+
+ foreach( $postcodes as $postcode )
+ if ( strstr( $postcode, '-' ) ) {
+ $postcode_parts = explode( '-', $postcode );
+
+ if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
+ for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
+ if ( ! $i )
+ continue;
+
+ if ( strlen( $i ) < strlen( $postcode_parts[0] ) )
+ $i = str_pad( $i, strlen( $postcode_parts[0] ), "0", STR_PAD_LEFT );
+
+ $postcode_query[] = "( '" . esc_sql( $i ) . "', $tax_rate_id, 'postcode' )";
+ }
+ }
+ } else {
+ if ( $postcode )
+ $postcode_query[] = "( '" . esc_sql( $postcode ) . "', $tax_rate_id, 'postcode' )";
+ }
+
+ $wpdb->query( "INSERT INTO {$wpdb->prefix}sportspress_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
+
+ }
+
+ if ( isset( $tax_rate_city[ $key ] ) ) {
+ // Delete old
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}sportspress_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'city';", $tax_rate_id ) );
+
+ // Add changed
+ $city = sanitize_text_field( $tax_rate_city[ $key ] );
+ $cities = explode( ';', $city );
+ $cities = array_map( 'strtoupper', array_map( 'sanitize_text_field', $cities ) );
+ foreach( $cities as $city ) {
+ if ( $city ) {
+ $wpdb->insert(
+ $wpdb->prefix . "sportspress_tax_rate_locations",
+ array(
+ 'location_code' => $city,
+ 'tax_rate_id' => $tax_rate_id,
+ 'location_type' => 'city',
+ )
+ );
+ }
+ }
+ }
+
+ $i++;
+ }
+ }
+ }
+
+ /**
+ * Output results settings.
+ *
+ * @access public
+ * @return void
+ */
+ public function results_setting() {
+ $main_result = get_option( 'sportspress_main_result', 0 );
+
+ $args = array(
+ 'post_type' => 'sp_result',
+ 'numberposts' => -1,
+ 'posts_per_page' => -1,
+ 'orderby' => 'menu_order',
+ 'order' => 'ASC'
+ );
+ $data = get_posts( $args );
+ ?>
+
+ |
+
+
+
+ |
+
+ id = 'text';
+ $this->label = __( 'Text', 'sportspress' );
+
+ add_filter( 'sportspress_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
+ add_action( 'sportspress_settings_' . $this->id, array( $this, 'output' ) );
+ add_action( 'sportspress_settings_save_' . $this->id, array( $this, 'save' ) );
+ }
+
+ /**
+ * Get settings array
+ *
+ * @return array
+ */
+ public function get_settings() {
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option( 'sportspress_tax_classes' ) ) ) );
+ $classes_options = array();
+ if ( $tax_classes )
+ foreach ( $tax_classes as $class )
+ $classes_options[ sanitize_title( $class ) ] = esc_html( $class );
+
+ $settings = array( array( 'title' => __( 'Text Options', 'sportspress' ), 'type' => 'title','desc' => '', 'id' => 'text_options' ) );
+
+ $this->strings =& SP()->text->strings;
+ foreach ( $this->strings as $string ):
+ $settings[] = array(
+ 'title' => $string,
+ 'id' => 'sportspress_text_' . sanitize_title( $string ),
+ 'default' => '',
+ 'placeholder' => $string,
+ 'type' => 'text',
+ );
+ endforeach;
+
+ $settings[] = array( 'type' => 'sectionend', 'id' => 'text_options' );
+
+ return apply_filters( 'sportspress_event_settings', $settings ); // End text settings
+ }
+
+ /**
+ * Output the settings
+ */
+ public function output() {
+ global $current_section;
+
+ $tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('sportspress_tax_classes' ) ) ) );
+
+ if ( $current_section == 'standard' || in_array( $current_section, array_map( 'sanitize_title', $tax_classes ) ) ) {
+ $this->output_tax_rates();
+ } else {
+ $settings = $this->get_settings();
+
+ SP_Admin_Settings::output_fields( $settings );
+ }
+ }
+
+}
+
+endif;
+
+return new SP_Settings_Text();
\ No newline at end of file
diff --git a/includes/admin/settings/settings.php b/includes/admin/settings/settings.php
index c482f67f..94a9bbae 100644
--- a/includes/admin/settings/settings.php
+++ b/includes/admin/settings/settings.php
@@ -162,12 +162,5 @@ function sportspress_options_validate( $input ) {
}
function sportspress_add_menu_page() {
- add_options_page(
- __( 'SportsPress', 'sportspress' ),
- __( 'SportsPress', 'sportspress' ),
- 'manage_options',
- 'sportspress',
- 'sportspress_options'
- );
}
add_action( 'admin_menu', 'sportspress_add_menu_page' );
diff --git a/includes/admin/views/html-admin-settings.php b/includes/admin/views/html-admin-settings.php
new file mode 100644
index 00000000..8dcda03c
--- /dev/null
+++ b/includes/admin/views/html-admin-settings.php
@@ -0,0 +1,26 @@
+
\ No newline at end of file
diff --git a/includes/class-sp-frontend-scripts.php b/includes/class-sp-frontend-scripts.php
new file mode 100644
index 00000000..c1893d56
--- /dev/null
+++ b/includes/class-sp-frontend-scripts.php
@@ -0,0 +1,219 @@
+ array(
+ 'src' => str_replace( array( 'http:', 'https:' ), '', SP()->plugin_url() ) . '/assets/css/sportspress-layout.css',
+ 'deps' => '',
+ 'version' => SP_VERSION,
+ 'media' => 'all'
+ ),
+ 'sportspress-smallscreen' => array(
+ 'src' => str_replace( array( 'http:', 'https:' ), '', SP()->plugin_url() ) . '/assets/css/sportspress-smallscreen.css',
+ 'deps' => 'sportspress-layout',
+ 'version' => SP_VERSION,
+ 'media' => 'only screen and (max-width: ' . apply_filters( 'sportspress_style_smallscreen_breakpoint', $breakpoint = '768px' ) . ')'
+ ),
+ 'sportspress-general' => array(
+ 'src' => str_replace( array( 'http:', 'https:' ), '', SP()->plugin_url() ) . '/assets/css/sportspress.css',
+ 'deps' => '',
+ 'version' => SP_VERSION,
+ 'media' => 'all'
+ ),
+ ) );
+ }
+
+ /**
+ * Register/queue frontend scripts.
+ *
+ * @access public
+ * @return void
+ */
+ public function load_scripts() {
+ global $post, $wp;
+
+ $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
+ $lightbox_en = get_option( 'sportspress_enable_lightbox' ) == 'yes' ? true : false;
+ $ajax_cart_en = get_option( 'sportspress_enable_ajax_add_to_cart' ) == 'yes' ? true : false;
+ $assets_path = str_replace( array( 'http:', 'https:' ), '', SP()->plugin_url() ) . '/assets/';
+ $frontend_script_path = $assets_path . 'js/frontend/';
+
+ // Register any scripts for later use, or used as dependencies
+ wp_register_script( 'chosen', $assets_path . 'js/chosen/chosen.jquery' . $suffix . '.js', array( 'jquery' ), '1.0.0', true );
+ wp_register_script( 'jquery-blockui', $assets_path . 'js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.60', true );
+ wp_register_script( 'jquery-payment', $assets_path . 'js/jquery-payment/jquery.payment' . $suffix . '.js', array( 'jquery' ), '1.0.2', true );
+ wp_register_script( 'sp-credit-card-form', $assets_path . 'js/frontend/credit-card-form' . $suffix . '.js', array( 'jquery', 'jquery-payment' ), SP_VERSION, true );
+
+ wp_register_script( 'sp-add-to-cart-variation', $frontend_script_path . 'add-to-cart-variation' . $suffix . '.js', array( 'jquery' ), SP_VERSION, true );
+ wp_register_script( 'sp-single-product', $frontend_script_path . 'single-product' . $suffix . '.js', array( 'jquery' ), SP_VERSION, true );
+ wp_register_script( 'sp-country-select', $frontend_script_path . 'country-select' . $suffix . '.js', array( 'jquery' ), SP_VERSION, true );
+ wp_register_script( 'sp-address-i18n', $frontend_script_path . 'address-i18n' . $suffix . '.js', array( 'jquery' ), SP_VERSION, true );
+ wp_register_script( 'jquery-cookie', $assets_path . 'js/jquery-cookie/jquery.cookie' . $suffix . '.js', array( 'jquery' ), '1.3.1', true );
+
+ // Queue frontend scripts conditionally
+ if ( $ajax_cart_en )
+ wp_enqueue_script( 'sp-add-to-cart', $frontend_script_path . 'add-to-cart' . $suffix . '.js', array( 'jquery' ), SP_VERSION, true );
+
+ if ( is_cart() )
+ wp_enqueue_script( 'sp-cart', $frontend_script_path . 'cart' . $suffix . '.js', array( 'jquery', 'sp-country-select' ), SP_VERSION, true );
+
+ if ( is_checkout() ) {
+
+ if ( get_option( 'sportspress_enable_chosen' ) == 'yes' ) {
+ wp_enqueue_script( 'sp-chosen', $frontend_script_path . 'chosen-frontend' . $suffix . '.js', array( 'chosen' ), SP_VERSION, true );
+ wp_enqueue_style( 'sportspress_chosen_styles', $assets_path . 'css/chosen.css' );
+ }
+
+ wp_enqueue_script( 'sp-checkout', $frontend_script_path . 'checkout' . $suffix . '.js', array( 'jquery', 'sportspress', 'sp-country-select', 'sp-address-i18n' ), SP_VERSION, true );
+ }
+
+ if ( is_page( get_option( 'sportspress_myaccount_page_id' ) ) ) {
+ if ( get_option( 'sportspress_enable_chosen' ) == 'yes' ) {
+ wp_enqueue_script( 'sp-chosen', $frontend_script_path . 'chosen-frontend' . $suffix . '.js', array( 'chosen' ), SP_VERSION, true );
+ wp_enqueue_style( 'sportspress_chosen_styles', $assets_path . 'css/chosen.css' );
+ }
+ }
+
+ if ( is_add_payment_method_page() )
+ wp_enqueue_script( 'sp-add-payment-method', $frontend_script_path . 'add-payment-method' . $suffix . '.js', array( 'jquery', 'sportspress' ), SP_VERSION, true );
+
+ if ( $lightbox_en && ( is_product() || ( ! empty( $post->post_content ) && strstr( $post->post_content, '[product_page' ) ) ) ) {
+ wp_enqueue_script( 'prettyPhoto', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array( 'jquery' ), '3.1.5', true );
+ wp_enqueue_script( 'prettyPhoto-init', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js', array( 'jquery' ), SP_VERSION, true );
+ wp_enqueue_style( 'sportspress_prettyPhoto_css', $assets_path . 'css/prettyPhoto.css' );
+ }
+
+ if ( is_product() )
+ wp_enqueue_script( 'sp-single-product' );
+
+ // Global frontend scripts
+ wp_enqueue_script( 'sportspress', $frontend_script_path . 'sportspress' . $suffix . '.js', array( 'jquery', 'jquery-blockui' ), SP_VERSION, true );
+ wp_enqueue_script( 'sp-cart-fragments', $frontend_script_path . 'cart-fragments' . $suffix . '.js', array( 'jquery', 'jquery-cookie' ), SP_VERSION, true );
+
+ // Variables for JS scripts
+ wp_localize_script( 'sportspress', 'sportspress_params', apply_filters( 'sportspress_params', array(
+ 'ajax_url' => SP()->ajax_url(),
+ 'ajax_loader_url' => apply_filters( 'sportspress_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ),
+ ) ) );
+
+ wp_localize_script( 'sp-single-product', 'sp_single_product_params', apply_filters( 'sp_single_product_params', array(
+ 'i18n_required_rating_text' => esc_attr__( 'Please select a rating', 'sportspress' ),
+ 'review_rating_required' => get_option( 'sportspress_review_rating_required' ),
+ ) ) );
+
+ wp_localize_script( 'sp-checkout', 'sp_checkout_params', apply_filters( 'sp_checkout_params', array(
+ 'ajax_url' => SP()->ajax_url(),
+ 'ajax_loader_url' => apply_filters( 'sportspress_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ),
+ 'update_order_review_nonce' => wp_create_nonce( "update-order-review" ),
+ 'apply_coupon_nonce' => wp_create_nonce( "apply-coupon" ),
+ 'option_guest_checkout' => get_option( 'sportspress_enable_guest_checkout' ),
+ 'checkout_url' => add_query_arg( 'action', 'sportspress_checkout', SP()->ajax_url() ),
+ 'is_checkout' => is_page( sp_get_page_id( 'checkout' ) ) && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ? 1 : 0
+ ) ) );
+
+ wp_localize_script( 'sp-address-i18n', 'sp_address_i18n_params', apply_filters( 'sp_address_i18n_params', array(
+ 'locale' => json_encode( SP()->countries->get_country_locale() ),
+ 'locale_fields' => json_encode( SP()->countries->get_country_locale_field_selectors() ),
+ 'i18n_required_text' => esc_attr__( 'required', 'sportspress' ),
+ ) ) );
+
+ wp_localize_script( 'sp-cart', 'sp_cart_params', apply_filters( 'sp_cart_params', array(
+ 'ajax_url' => SP()->ajax_url(),
+ 'ajax_loader_url' => apply_filters( 'sportspress_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ),
+ 'update_shipping_method_nonce' => wp_create_nonce( "update-shipping-method" ),
+ ) ) );
+
+ wp_localize_script( 'sp-cart-fragments', 'sp_cart_fragments_params', apply_filters( 'sp_cart_fragments_params', array(
+ 'ajax_url' => SP()->ajax_url(),
+ 'fragment_name' => apply_filters( 'sportspress_cart_fragment_name', 'sp_fragments' )
+ ) ) );
+
+ wp_localize_script( 'sp-add-to-cart', 'sp_add_to_cart_params', apply_filters( 'sp_add_to_cart_params', array(
+ 'ajax_url' => SP()->ajax_url(),
+ 'ajax_loader_url' => apply_filters( 'sportspress_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ),
+ 'i18n_view_cart' => esc_attr__( 'View Cart', 'sportspress' ),
+ 'cart_url' => get_permalink( sp_get_page_id( 'cart' ) ),
+ 'is_cart' => is_cart(),
+ 'cart_redirect_after_add' => get_option( 'sportspress_cart_redirect_after_add' )
+ ) ) );
+
+ wp_localize_script( 'sp-add-to-cart-variation', 'sp_add_to_cart_variation_params', apply_filters( 'sp_add_to_cart_variation_params', array(
+ 'i18n_no_matching_variations_text' => esc_attr__( 'Sorry, no products matched your selection. Please choose a different combination.', 'sportspress' ),
+ 'i18n_unavailable_text' => esc_attr__( 'Sorry, this product is unavailable. Please choose a different combination.', 'sportspress' ),
+ ) ) );
+
+ wp_localize_script( 'sp-country-select', 'sp_country_select_params', apply_filters( 'sp_country_select_params', array(
+ 'countries' => json_encode( array_merge( SP()->countries->get_allowed_country_states(), SP()->countries->get_shipping_country_states() ) ),
+ 'i18n_select_state_text' => esc_attr__( 'Select an option…', 'sportspress' ),
+ ) ) );
+
+ // CSS Styles
+ $enqueue_styles = $this->get_styles();
+
+ if ( $enqueue_styles )
+ foreach ( $enqueue_styles as $handle => $args )
+ wp_enqueue_style( $handle, $args['src'], $args['deps'], $args['version'], $args['media'] );
+ }
+
+ /**
+ * SP requires jQuery 1.8 since it uses functions like .on() for events and .parseHTML.
+ * If, by the time wp_print_scrips is called, jQuery is outdated (i.e not
+ * using the version in core) we need to deregister it and register the
+ * core version of the file.
+ *
+ * @access public
+ * @return void
+ */
+ public function check_jquery() {
+ global $wp_scripts;
+
+ // Enforce minimum version of jQuery
+ if ( ! empty( $wp_scripts->registered['jquery']->ver ) && ! empty( $wp_scripts->registered['jquery']->src ) && 0 >= version_compare( $wp_scripts->registered['jquery']->ver, '1.8' ) ) {
+ wp_deregister_script( 'jquery' );
+ wp_register_script( 'jquery', '/wp-includes/js/jquery/jquery.js', array(), '1.8' );
+ wp_enqueue_script( 'jquery' );
+ }
+ }
+
+ /**
+ * Provide backwards compat for old constant
+ * @param array $styles
+ * @return array
+ */
+ public function backwards_compat( $styles ) {
+ if ( defined( 'WOOCOMMERCE_USE_CSS' ) ) {
+
+ _deprecated_function( 'WOOCOMMERCE_USE_CSS', '2.1', 'Styles should be removed using wp_deregister_style or the sportspress_enqueue_styles filter rather than the WOOCOMMERCE_USE_CSS constant.' );
+
+ if ( ! WOOCOMMERCE_USE_CSS )
+ return false;
+ }
+
+ return $styles;
+ }
+}
+
+new SP_Frontend_Scripts();
\ No newline at end of file
diff --git a/includes/class-sp-post-types.php b/includes/class-sp-post-types.php
index 9eafe1b6..b9b76172 100644
--- a/includes/class-sp-post-types.php
+++ b/includes/class-sp-post-types.php
@@ -353,9 +353,8 @@ class SP_Post_types {
apply_filters( 'sportspress_register_post_type_event',
array(
'labels' => array(
- 'name' => __( 'Schedule', 'sportspress' ),
+ 'name' => __( 'Events', 'sportspress' ),
'singular_name' => __( 'Event', 'sportspress' ),
- 'all_items' => __( 'Events', 'sportspress' ),
'add_new_item' => __( 'Add New Event', 'sportspress' ),
'edit_item' => __( 'Edit Event', 'sportspress' ),
'new_item' => __( 'New', 'sportspress' ),
@@ -386,7 +385,6 @@ class SP_Post_types {
'labels' => array(
'name' => __( 'Calendars', 'sportspress' ),
'singular_name' => __( 'Calendar', 'sportspress' ),
- 'all_items' => __( 'Calendars', 'sportspress' ),
'add_new_item' => __( 'Add New Calendar', 'sportspress' ),
'edit_item' => __( 'Edit Calendar', 'sportspress' ),
'new_item' => __( 'New', 'sportspress' ),
@@ -417,7 +415,6 @@ class SP_Post_types {
'labels' => array(
'name' => __( 'Teams', 'sportspress' ),
'singular_name' => __( 'Team', 'sportspress' ),
- 'all_items' => __( 'Teams', 'sportspress' ),
'add_new_item' => __( 'Add New Team', 'sportspress' ),
'edit_item' => __( 'Edit Team', 'sportspress' ),
'new_item' => __( 'New', 'sportspress' ),
@@ -448,7 +445,6 @@ class SP_Post_types {
'labels' => array(
'name' => __( 'League Tables', 'sportspress' ),
'singular_name' => __( 'League Table', 'sportspress' ),
- 'all_items' => __( 'League Tables', 'sportspress' ),
'add_new_item' => __( 'Add New League Table', 'sportspress' ),
'edit_item' => __( 'Edit League Table', 'sportspress' ),
'new_item' => __( 'New', 'sportspress' ),
@@ -477,9 +473,8 @@ class SP_Post_types {
apply_filters( 'sportspress_register_post_type_player',
array(
'labels' => array(
- 'name' => __( 'Roster', 'sportspress' ),
+ 'name' => __( 'Players', 'sportspress' ),
'singular_name' => __( 'Player', 'sportspress' ),
- 'all_items' => __( 'Players', 'sportspress' ),
'add_new_item' => __( 'Add New Player', 'sportspress' ),
'edit_item' => __( 'Edit Player', 'sportspress' ),
'new_item' => __( 'New', 'sportspress' ),
@@ -510,7 +505,6 @@ class SP_Post_types {
'labels' => array(
'name' => __( 'Player Lists', 'sportspress' ),
'singular_name' => __( 'Player List', 'sportspress' ),
- 'all_items' => __( 'Player Lists', 'sportspress' ),
'add_new_item' => __( 'Add New Player List', 'sportspress' ),
'edit_item' => __( 'Edit Player List', 'sportspress' ),
'new_item' => __( 'New', 'sportspress' ),
@@ -541,7 +535,6 @@ class SP_Post_types {
'labels' => array(
'name' => __( 'Staff', 'sportspress' ),
'singular_name' => __( 'Staff', 'sportspress' ),
- 'all_items' => __( 'Staff', 'sportspress' ),
'add_new_item' => __( 'Add New Staff', 'sportspress' ),
'edit_item' => __( 'Edit Staff', 'sportspress' ),
'new_item' => __( 'New', 'sportspress' ),
@@ -561,7 +554,7 @@ class SP_Post_types {
'supports' => array( 'title', 'author', 'thumbnail' ),
'has_archive' => true,
'show_in_nav_menus' => true,
- 'show_in_menu' => 'edit.php?post_type=sp_player',
+ 'menu_icon' => 'dashicons-businessman',
)
)
);
diff --git a/includes/class-sp-sports.php b/includes/class-sp-sports.php
index e71da450..665939f3 100644
--- a/includes/class-sp-sports.php
+++ b/includes/class-sp-sports.php
@@ -2264,8 +2264,13 @@ class SP_Sports {
}
public function __get( $key ) {
- if ( 'options' == $key )
- return $this->data;
+ if ( 'options' == $key ):
+ $option = array();
+ foreach ( $this->data as $slug => $data ):
+ $options[ $slug ] = $data['name'];
+ endforeach;
+ return $options;
+ endif;
return ( array_key_exists( $key, $this->data ) ? $this->data[ $key ] : null );
}
diff --git a/sportspress.php b/sportspress.php
index 771e1c65..694475eb 100644
--- a/sportspress.php
+++ b/sportspress.php
@@ -241,7 +241,7 @@ final class SportsPress {
// Admin request actions (deprecating)
include_once( 'admin/hooks/admin-init.php' );
- include_once( 'admin/hooks/admin-menu.php' );
+ //include_once( 'admin/hooks/admin-menu.php' );
//include_once( 'admin/hooks/admin-enqueue-scripts.php' );
include_once( 'admin/hooks/admin-print-styles.php' );
include_once( 'admin/hooks/admin-head.php' );