register_main_settings(); $this->register_zoho_settings(); } protected function register_main_settings() { add_settings_section( self::SETTINGS_SECTION_MAIN, fqp__( 'General Settings' ), function () { echo ''; /* section description */ }, dirname( FQP_PLUGIN_BASE_NAME ) . '/admin/settings.php' ); $langs = FQP::get_lang_list(); foreach ( $langs as $lang ) { $lang_code = esc_html( $lang['code'] ); $lang_title = esc_html( $lang['translated_name'] ); add_settings_field( "fqp-main-thanks-page-{$lang_code}", fqp__( 'Thanks Page URL' ) . " ({$lang_title})", function () use ( $lang_code ) { $value = esc_attr( get_option( "fqp_main_thanks_page_{$lang_code}" ) ); echo ""; }, dirname( FQP_PLUGIN_BASE_NAME ) . '/admin/settings.php', self::SETTINGS_SECTION_MAIN ); register_setting( self::SETTINGS_GROUP, "fqp_main_thanks_page_{$lang_code}", [ $this, 'sanitize_thanks_page_url' ] ); } } public function sanitize_thanks_page_url( $value ) { $value = trim( $value ); if ( ! preg_match( '/(?:http|https):\/\/((?:[\w-]+)(?:\.[\w-]+)+)(?:[\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/', $value ) ) { return ''; } return $value; } public static function get_thanks_url( $lang = null ) { if ( null == $lang ) { $lang = FQP::get_curr_lang(); } return get_option( "fqp_main_thanks_page_{$lang}" ); } protected function register_zoho_settings() { add_settings_section( self::SETTINGS_SECTION_ZOHO, fqp__( 'ZOHO Settings' ), function () { echo ''; /* section description */ }, dirname( FQP_PLUGIN_BASE_NAME ) . '/admin/settings.php' ); add_settings_field( 'fqp-zoho-auth-token', fqp__( 'Authentication Token' ), function () { $value = esc_attr( get_option( 'fqp_zoho_auth_token' ) ); echo ""; }, dirname( FQP_PLUGIN_BASE_NAME ) . '/admin/settings.php', self::SETTINGS_SECTION_ZOHO ); register_setting( self::SETTINGS_GROUP, 'fqp_zoho_auth_token', [ $this, 'sanitize_zoho_auth_token' ] ); } public function sanitize_zoho_auth_token( $value ) { $value = trim( $value ); return $value; } public function validatePrice( $price ) { $error = false; if ( '' == $price ) { $error = fqp__( '%s is required' ); } elseif ( !is_numeric( $price ) ) { $error = fqp__( '%s is in wrong format' ); } elseif ( floatval( $price ) < 0 ) { $error = fqp__( '%s is wrong' ); } return $error; } public function sanitize_prices( $data ) { if ( empty( $data ) ) { return $data; } $errors = []; $data['per_partner_discount'] = $this->sanitize_price( $data['per_partner_discount'] ); $error = $this->validatePrice( $data['per_partner_discount'] ); if ( $error ) { $errors['per_partner_discount'] = sprintf( $error, fqp__( 'Per Partner Discount' ) ); } $entry_types = DB::get_entry_types(); foreach ( $entry_types as $entry_id => $entry ) { if ( 'y' == $entry['hasBacking'] ) { foreach ( $entry['backing'] as $backing_id => $backing ) { $backing_price = $this->sanitize_price( @$data['price'][$entry_id][$backing_id] ); $data['price'][$entry_id][$backing_id] = $backing_price; $error = $this->validatePrice( $backing_price ); if ( $error ) { $key = $entry_id . '-' . $backing_id; $title = $entry['title'] . ' ' . fqp__( 'with' ) . ' ' . $backing['title'] . ' ' . fqp__( 'Price' ); $errors[$key] = sprintf( $error, $title ); } } } else { $entry_price = $this->sanitize_price( @$data['price'][$entry_id] ); $data['price'][$entry_id] = $entry_price; $error = $this->validatePrice( $entry_price ); if ( $error ) { $key = $entry_id; $title = $entry['title'] . ' ' . fqp__( 'Price' ); $errors[$key] = sprintf( $error, $title ); } } } if ( !empty( $errors ) ) { if ( function_exists( 'add_settings_error' ) ) { foreach ( $errors as $key => $error ) { add_settings_error( self::OPTION_PRICES, "invalid_{$key}", $error ); } } set_transient( 'settings_errors', get_settings_errors(), 30 ); set_transient( self::OPTION_PRICES, $data, 30 ); $back_url = add_query_arg( 'settings-updated', 'false', wp_get_referer() ); wp_redirect( $back_url ); exit; } $db_data = get_option( self::OPTION_PRICES, [] ); return self::mergeRecursive( $db_data, $data ); } public function whitelist_options( $options ) { if ( array_key_exists( self::OPTION_GROUP, $options ) ) { foreach ( $options[self::OPTION_GROUP] as $key => $option) { if ( !array_key_exists( $option, $_POST ) ) { unset( $options[self::OPTION_GROUP][$key] ); } } } return $options; } public function sanitize_emails( $data ) { if (empty($data)) { return $data; } $errors = []; $data['emails'] = join( ', ', $this->sanitize_emails_list( $data['emails'] ) ); if ( empty( $data['emails'] ) ) { $errors[] = fqp__( 'Notification Email is required.' ); } $data['subject'] = sanitize_text_field( $data['subject'] ); if ( empty( $data['subject'] ) ) { $errors[] = fqp__( 'Notification Subject is required.' ); } if ( empty( $data['body'] ) ) { $errors[] = fqp__( 'Notification Body is required.' ); } if ( !empty( $errors ) ) { if ( function_exists( 'add_settings_error' ) ) { foreach ( $errors as $key => $error ) { add_settings_error( self::OPTION_EMAILS, "invalid_{$key}", $error ); } } set_transient( 'settings_errors', get_settings_errors(), 30 ); set_transient( self::OPTION_EMAILS, $data, 30 ); $back_url = add_query_arg( 'settings-updated', 'false', wp_get_referer() ); wp_redirect( $back_url ); exit; } $db_data = get_option( self::OPTION_EMAILS, [] ); return self::mergeRecursive( $db_data, $data ); } public static function mergeRecursive($firstArray, $secondArray) { if (is_array($firstArray) && is_array($secondArray)) { foreach ($secondArray as $key => $value) { if (isset($firstArray[$key])) { $firstArray[$key] = self::mergeRecursive($firstArray[$key], $value); } else { $firstArray[$key] = $value; } } } else { $firstArray = $secondArray; } return $firstArray; } public function admin_menu() { add_menu_page( fqp__( 'Fasoon' ), fqp__( 'Fasoon' ), 'manage_options', 'fasoon-quote-price', [ $this, 'price_menu' ], plugins_url( 'img/icon.png', FQP_PLUGIN_BASE_NAME ) ); add_submenu_page( 'fasoon-quote-price', fqp__( 'Submissions' ), fqp__( 'Submissions' ), 'manage_options', dirname( FQP_PLUGIN_BASE_NAME ) . '/admin/submissions.php' ); add_submenu_page( 'fasoon-quote-price', fqp__( 'Pricing' ), fqp__( 'Pricing' ), 'manage_options', dirname( FQP_PLUGIN_BASE_NAME ) . '/admin/prices.php' ); add_submenu_page( 'fasoon-quote-price', fqp__( 'Emails' ), fqp__( 'Emails' ), 'manage_options', dirname( FQP_PLUGIN_BASE_NAME ) . '/admin/emails.php' ); add_submenu_page( 'fasoon-quote-price', fqp__( 'Partners' ), fqp__( 'Partners' ), 'manage_options', 'edit.php?post_type=' . FQP::PARTNER_POST_TYPE ); add_submenu_page( 'fasoon-quote-price', fqp__( 'Settings' ), fqp__( 'Settings' ), 'manage_options', dirname( FQP_PLUGIN_BASE_NAME ) . '/admin/settings.php' ); remove_submenu_page('fasoon-quote-price', 'fasoon-quote-price'); } public function price_menu() { wp_redirect( dirname( FQP_PLUGIN_BASE_NAME ) . '/admin-options.php' ); } public function sanitize_price ( $price ) { return preg_replace( '/[^\.0-9]+/', '', $price ); } public function sanitize_emails_list( $emails ) { $emails = preg_split( '/[\s, ]+/', $emails ); $emails = array_filter( $emails ); foreach ( $emails as &$email ) { $email = sanitize_email( trim( $email ) ); } unset( $email ); $emails = array_filter( $emails ); return $emails; } }