%s

', wp_lostpassword_url( get_permalink() ), __( 'Forgot your password?', 'advanced-classifieds-and-directory-pro' ) ); $form .= sprintf( '

%s

', wp_registration_url(), __( 'Create an account', 'advanced-classifieds-and-directory-pro' ) ); return $form; } /* * Whether the current user has a specific capability. * * @since 1.0.0 * * @param string $capability Capability name. * @param int $post_id Optional. ID of the specific object to check against if `$capability` is a "meta" cap. * @return bool True if the current user has the capability, false if not. */ function acadp_current_user_can( $capability, $post_id = 0 ) { $user_id = get_current_user_id(); // If editing, deleting, or reading a listing, get the post and post type object. if( 'edit_acadp_listing' == $capability || 'delete_acadp_listing' == $capability || 'read_acadp_listing' == $capability ) { $post = get_post( $post_id ); $post_type = get_post_type_object( $post->post_type ); // If editing a listing, assign the required capability. if( 'edit_acadp_listing' == $capability ) { if( $user_id == $post->post_author ) { $capability = 'edit_acadp_listings'; } else { $capability = 'edit_others_acadp_listings'; } } // If deleting a listing, assign the required capability. else if( 'delete_acadp_listing' == $capability ) { if( $user_id == $post->post_author ) { $capability = 'delete_acadp_listings'; } else { $capability = 'delete_others_acadp_listings'; } } // If reading a private listing, assign the required capability. else if( 'read_listing' == $capability ) { if( 'private' != $post->post_status ) { $capability = 'read'; } else if( $user_id == $post->post_author ) { $capability = 'read'; } else { $capability = 'read_private_acadp_listings'; } } } return current_user_can( $capability ); } /* * Inserts a new key/value after the key in the array. * * @since 1.0.0 * * @param string $key The key to insert after. * @param array $array An array to insert in to. * @param array $new_array An array to insert. * @return The new array if the key exists, FALSE otherwise. */ function acadp_array_insert_after( $key, $array, $new_array ) { if( array_key_exists( $key, $array ) ) { $new = array(); foreach( $array as $k => $value ) { $new[ $k ] = $value; if( $k === $key ) { foreach( $new_array as $new_key => $new_value ) { $new[ $new_key ] = $new_value; } } } return $new; } return $array; } /** * Calculate listing expiry date. * * @since 1.0.0 * * @param int $post_id Post ID. * @param string $start_date Date from which the expiry date must be caluclated. * @return string $date Expiry date. */ function acadp_listing_expiry_date( $post_id, $start_date = NULL ) { // Get number of days to add $general_settings = get_option( 'acadp_general_settings' ); $days = apply_filters( 'acadp_listing_duration', $general_settings['listing_duration'], $post_id ); if( $days <= 0 ) $days = 999; if( $start_date == NULL ) { // Current time $start_date = current_time( 'mysql' ); } // Calculate new date $date = new DateTime( $start_date ); $date->add( new DateInterval( "P{$days}D" ) ); // return return $date->format( 'Y-m-d H:i:s' ); } /** * Parse MySQL date format. * * @since 1.0.0 * * @param string $date MySQL date string. * @return array $date Array of date values. */ function acadp_parse_mysql_date_format( $date ) { $date = preg_split( '([^0-9])', $date ); return array( 'year' => $date[0], 'month' => $date[1], 'day' => $date[2], 'hour' => $date[3], 'min' => $date[4], 'sec' => $date[5] ); } /** * Convert to MySQL date format (Y-m-d H:i:s). * * @since 1.0.0 * * @param array $date Array of date values. * @return string $date Formatted date string. */ function acadp_mysql_date_format( $date ) { $defaults = array( 'year' => 0, 'month' => 0, 'day' => 0, 'hour' => 0, 'min' => 0, 'sec' => 0 ); $date = array_merge( $defaults, $date ); $year = (int) $date['year']; $year = str_pad( $year, 4, '0', STR_PAD_RIGHT ); $month = (int) $date['month']; $month = max( 1, min( 12, $month ) ); $day = (int) $date['day']; $day = max( 1, min( 31, $day ) ); $hour = (int) $date['hour']; $hour = max( 1, min( 24, $hour ) ); $min = (int) $date['min']; $min = max( 0, min( 59, $min ) ); $sec = (int) $date['sec']; $sec = max( 0, min( 59, $sec ) ); return sprintf( '%04d-%02d-%02d %02d:%02d:%02d', $year, $month, $day, $hour, $min, $sec ); } /** * Get payment statuses. * * @since 1.0.0 * * @return array $statuses A list of available payment status. */ function acadp_get_payment_statuses() { $statuses = array( 'created' => __( "Created", 'advanced-classifieds-and-directory-pro' ), 'pending' => __( "Pending", 'advanced-classifieds-and-directory-pro' ), 'completed' => __( "Completed", 'advanced-classifieds-and-directory-pro' ), 'failed' => __( "Failed", 'advanced-classifieds-and-directory-pro' ), 'cancelled' => __( "Cancelled", 'advanced-classifieds-and-directory-pro' ), 'refunded' => __( "Refunded", 'advanced-classifieds-and-directory-pro' ) ); return apply_filters( 'acadp_payment_statuses', $statuses ); } /** * Get bulk actions. * * @since 1.0.0 * * @return array $actions A list of payment history page bulk actions. */ function acadp_get_payment_bulk_actions() { $actions = array( 'set_to_created' => __( "Set to Created", 'advanced-classifieds-and-directory-pro' ), 'set_to_pending' => __( "Set to Pending", 'advanced-classifieds-and-directory-pro' ), 'set_to_completed' => __( "Set to Completed", 'advanced-classifieds-and-directory-pro' ), 'set_to_failed' => __( "Set to Failed", 'advanced-classifieds-and-directory-pro' ), 'set_to_cancelled' => __( "Set to Cancelled", 'advanced-classifieds-and-directory-pro' ), 'set_to_refunded' => __( "Set to Refunded", 'advanced-classifieds-and-directory-pro' ) ); return apply_filters( 'acadp_payment_bulk_actions', $actions ); } /** * Sanitize Amount * * Returns a sanitized amount by stripping out thousands separators. * * @since 1.0.0 * * @param string $amount Price amount to format. * @return string $amount Newly sanitized amount. */ function acadp_sanitize_amount( $amount ) { $is_negative = false; $currency_settings = get_option( 'acadp_currency_settings' ); $currency = ! empty( $currency_settings[ 'currency' ] ) ? $currency_settings[ 'currency' ] : 'USD'; $thousands_sep = ! empty( $currency_settings[ 'thousands_separator' ] ) ? $currency_settings[ 'thousands_separator' ] : ','; $decimal_sep = ! empty( $currency_settings[ 'decimal_separator' ] ) ? $currency_settings[ 'decimal_separator' ] : '.'; // Sanitize the amount if( $decimal_sep == ',' && false !== ( $found = strpos( $amount, $decimal_sep ) ) ) { if( ( $thousands_sep == '.' || $thousands_sep == ' ' ) && false !== ( $found = strpos( $amount, $thousands_sep ) ) ) { $amount = str_replace( $thousands_sep, '', $amount ); } else if( empty( $thousands_sep ) && false !== ( $found = strpos( $amount, '.' ) ) ) { $amount = str_replace( '.', '', $amount ); } $amount = str_replace( $decimal_sep, '.', $amount ); } else if( $thousands_sep == ',' && false !== ( $found = strpos( $amount, $thousands_sep ) ) ) { $amount = str_replace( $thousands_sep, '', $amount ); } if( $amount < 0 ) { $is_negative = true; } $amount = preg_replace( '/[^0-9\.]/', '', $amount ); $decimals = acadp_currency_decimal_count( 2, $currency ); $amount = number_format( (double) $amount, $decimals, '.', '' ); if( $is_negative ) { $amount *= -1; } return apply_filters( 'acadp_sanitize_amount', $amount ); } /** * Returns a nicely formatted amount. * * @since 1.0.0 * * @param string $amount Price amount to format * @param string $decimals Whether or not to use decimals. Useful when set to false for non-currency numbers. * @return string $amount Newly formatted amount or Price Not Available */ function acadp_format_amount( $amount, $decimals = true ) { $currency_settings = get_option( 'acadp_currency_settings' ); $currency = ! empty( $currency_settings[ 'currency' ] ) ? $currency_settings[ 'currency' ] : 'USD'; $thousands_sep = ! empty( $currency_settings[ 'thousands_separator' ] ) ? $currency_settings[ 'thousands_separator' ] : ','; $decimal_sep = ! empty( $currency_settings[ 'decimal_separator' ] ) ? $currency_settings[ 'decimal_separator' ] : '.'; // Format the amount if( $decimal_sep == ',' && false !== ( $sep_found = strpos( $amount, $decimal_sep ) ) ) { $whole = substr( $amount, 0, $sep_found ); $part = substr( $amount, $sep_found + 1, ( strlen( $amount ) - 1 ) ); $amount = $whole . '.' . $part; } // Strip , from the amount (if set as the thousands separator) if( $thousands_sep == ',' && false !== ( $found = strpos( $amount, $thousands_sep ) ) ) { $amount = str_replace( ',', '', $amount ); } // Strip ' ' from the amount (if set as the thousands separator) if( $thousands_sep == ' ' && false !== ( $found = strpos( $amount, $thousands_sep ) ) ) { $amount = str_replace( ' ', '', $amount ); } if( empty( $amount ) ) { $amount = 0; } if( $decimals ) { $decimals = acadp_currency_decimal_count( 2, $currency ); } else { $decimals = 0; } $formatted = number_format( $amount, $decimals, $decimal_sep, $thousands_sep ); return apply_filters( 'acadp_format_amount', $formatted, $amount, $decimals, $decimal_sep, $thousands_sep ); } /** * Set the number of decimal places per currency * * @since 1.0.0 * * @param int $decimals Number of decimal places. * @param string $currency Payment currency. * @return int $decimals */ function acadp_currency_decimal_count( $decimals = 2, $currency = 'USD' ) { switch( $currency ) { case 'RIAL' : case 'JPY' : case 'TWD' : case 'HUF' : $decimals = 0; break; } return apply_filters( 'acadp_currency_decimal_count', $decimals, $currency ); } /** * Get currencies. * * @since 1.0.0 * * @return array $currencies A list of the available currencies. */ function acadp_get_currencies() { $currencies = array( 'USD' => __( 'US Dollars ($)', 'advanced-classifieds-and-directory-pro' ), 'EUR' => __( 'Euros (€)', 'advanced-classifieds-and-directory-pro' ), 'GBP' => __( 'Pounds Sterling (£)', 'advanced-classifieds-and-directory-pro' ), 'AUD' => __( 'Australian Dollars ($)', 'advanced-classifieds-and-directory-pro' ), 'BRL' => __( 'Brazilian Real (R$)', 'advanced-classifieds-and-directory-pro' ), 'CAD' => __( 'Canadian Dollars ($)', 'advanced-classifieds-and-directory-pro' ), 'CZK' => __( 'Czech Koruna', 'advanced-classifieds-and-directory-pro' ), 'DKK' => __( 'Danish Krone', 'advanced-classifieds-and-directory-pro' ), 'HKD' => __( 'Hong Kong Dollar ($)', 'advanced-classifieds-and-directory-pro' ), 'HUF' => __( 'Hungarian Forint', 'advanced-classifieds-and-directory-pro' ), 'ILS' => __( 'Israeli Shekel (₪)', 'advanced-classifieds-and-directory-pro' ), 'JPY' => __( 'Japanese Yen (¥)', 'advanced-classifieds-and-directory-pro' ), 'MYR' => __( 'Malaysian Ringgits', 'advanced-classifieds-and-directory-pro' ), 'MXN' => __( 'Mexican Peso ($)', 'advanced-classifieds-and-directory-pro' ), 'NZD' => __( 'New Zealand Dollar ($)', 'advanced-classifieds-and-directory-pro' ), 'NOK' => __( 'Norwegian Krone', 'advanced-classifieds-and-directory-pro' ), 'PHP' => __( 'Philippine Pesos', 'advanced-classifieds-and-directory-pro' ), 'PLN' => __( 'Polish Zloty', 'advanced-classifieds-and-directory-pro' ), 'SGD' => __( 'Singapore Dollar ($)', 'advanced-classifieds-and-directory-pro' ), 'SEK' => __( 'Swedish Krona', 'advanced-classifieds-and-directory-pro' ), 'CHF' => __( 'Swiss Franc', 'advanced-classifieds-and-directory-pro' ), 'TWD' => __( 'Taiwan New Dollars', 'advanced-classifieds-and-directory-pro' ), 'THB' => __( 'Thai Baht (฿)', 'advanced-classifieds-and-directory-pro' ), 'INR' => __( 'Indian Rupee (₹)', 'advanced-classifieds-and-directory-pro' ), 'TRY' => __( 'Turkish Lira (₺)', 'advanced-classifieds-and-directory-pro' ), 'RIAL' => __( 'Iranian Rial (﷼)', 'advanced-classifieds-and-directory-pro' ), 'RUB' => __( 'Russian Rubles', 'advanced-classifieds-and-directory-pro' ) ); return apply_filters( 'acadp_currencies', $currencies ); } /** * Get the directory's set currency * * @since 1.0.0 * @return string The currency code. */ function acadp_get_currency() { $currency_settings = get_option( 'acadp_currency_settings' ); $currency = ! empty( $currency_settings[ 'currency' ] ) ? $currency_settings[ 'currency' ] : 'USD'; return strtoupper( $currency ); } /** * Given a currency determine the symbol to use. If no currency given, site default is used. * If no symbol is determine, the currency string is returned. * * @since 1.0.0 * * @param string $currency The currency string. * @return string The symbol to use for the currency. */ function acadp_currency_symbol( $currency = '' ) { switch( $currency ) { case "GBP" : $symbol = '£'; break; case "BRL" : $symbol = 'R$'; break; case "EUR" : $symbol = '€'; break; case "USD" : case "AUD" : case "NZD" : case "CAD" : case "HKD" : case "MXN" : case "SGD" : $symbol = '$'; break; case "JPY" : $symbol = '¥'; break; default : $symbol = $currency; break; } return apply_filters( 'acadp_currency_symbol', $symbol, $currency ); } /** * Formats the currency display. * * @since 1.0.0 * * @param string $price Paid Amount. * @return array $currency Currencies displayed correctly. */ function acadp_currency_filter( $price = '' ) { $currency_settings = get_option( 'acadp_currency_settings' ); $currency = ! empty( $currency_settings[ 'currency' ] ) ? $currency_settings[ 'currency' ] : 'USD'; $position = $currency_settings['position']; $negative = $price < 0; if( $negative ) { $price = substr( $price, 1 ); // Remove proceeding "-" - } $symbol = acadp_currency_symbol( $currency ); if( $position == 'before' ) { switch( $currency ) { case "GBP" : case "BRL" : case "EUR" : case "USD" : case "AUD" : case "CAD" : case "HKD" : case "MXN" : case "NZD" : case "SGD" : case "JPY" : $formatted = $symbol . $price; break; default : $formatted = $currency . ' ' . $price; break; } $formatted = apply_filters( 'acadp_' . strtolower( $currency ) . '_currency_filter_before', $formatted, $currency, $price ); } else { switch( $currency ) { case "GBP" : case "BRL" : case "EUR" : case "USD" : case "AUD" : case "CAD" : case "HKD" : case "MXN" : case "SGD" : case "JPY" : $formatted = $price . $symbol; break; default : $formatted = $price . ' ' . $currency; break; } $formatted = apply_filters( 'acadp_' . strtolower( $currency ) . '_currency_filter_after', $formatted, $currency, $price ); } if( $negative ) { // Prepend the mins sign before the currency sign $formatted = '-' . $formatted; } return $formatted; } /** * Get the view(layout) name the listings should be displayed. * * @since 1.0.0 * * @return string $view Grid or List. */ function acadp_get_listings_current_view_name() { $listings_settings = get_option( 'acadp_listings_settings' ); return isset( $_GET['view'] ) ? sanitize_text_field( $_GET['view'] ) : $listings_settings['default_view']; } /** * Get the highest priority ACADP template file that exists. * * @since 1.0.0 * * @param string $name The name of the specialized template. * @param string $widget Name of the Widget(only if applicable). * @return string The ACADP template file. */ function acadp_get_template( $name, $widget = '' ) { $template_file = ''; if( '' !== $widget ) { if( ! $template_file = locate_template( "acadp_templates/widgets/$widget/$name" ) ) { $template_file = ACADP_PLUGIN_DIR . "widgets/$widget/views/$name"; } } else { if( ! $template_file = locate_template( "acadp_templates/$name" ) ) { $template_file = ACADP_PLUGIN_DIR . "public/partials/$name"; } } return apply_filters( 'acadp_get_template', $template_file, $name, $widget ); } /** * List ACADP categories. * * @since 1.0.0 * * @param array $settings Settings args. * @return string HTML code that contain categories list. */ function acadp_list_categories( $settings ) { if( $settings['depth'] <= 0 ) { return; } $args = array( 'orderby' => $settings['orderby'], 'order' => $settings['order'], 'hide_empty' => ! empty( $settings['hide_empty'] ) ? 1 : 0, 'parent' => $settings['term_id'], 'hierarchical' => false ); $terms = get_terms( 'acadp_categories', $args ); $html = ''; if( count( $terms ) > 0 ) { --$settings['depth']; $html .= ''; } return $html; } /** * Get total listings count. * * @since 1.0.0 * * @param int $term_id Custom Taxonomy term ID. * @return int Listings count. */ function acadp_get_listings_count_by_category( $term_id ) { $args = array( 'fields' =>'ids', 'posts_per_page' => -1, 'post_type' => 'acadp_listings', 'post_status' => 'publish', 'tax_query' => array( array( 'taxonomy' => 'acadp_categories', 'field' => 'term_id', 'terms' => $term_id ) ) ); return count( get_posts( $args ) ); } /** * List ACADP locations. * * @since 1.0.0 * * @param array $settings Settings args. * @return string HTML code that contain locations list. */ function acadp_list_locations( $settings ) { if( $settings['depth'] <= 0 ) { return; } $args = array( 'orderby' => $settings['orderby'], 'order' => $settings['order'], 'hide_empty' => ! empty( $settings['hide_empty'] ) ? 1 : 0, 'parent' => $settings['term_id'], 'hierarchical' => false ); $terms = get_terms( 'acadp_locations', $args ); $html = ''; if( count( $terms ) > 0 ) { --$settings['depth']; $html .= ''; } return $html; } /** * Get total listings count. * * @since 1.0.0 * * @param int $term_id Custom Taxonomy term ID. * @return int Listings count. */ function acadp_get_listings_count_by_location( $term_id ) { $args = array( 'fields' =>'ids', 'posts_per_page' => -1, 'post_type' => 'acadp_listings', 'post_status' => 'publish', 'tax_query' => array( array( 'taxonomy' => 'acadp_locations', 'field' => 'term_id', 'terms' => $term_id ) ) ); return count( get_posts( $args ) ); } /** * Insert/Update listing views count. * * @since 1.0.0 * * @param int $post_id Post ID. */ function acadp_set_listing_views( $post_id ) { $user_ip = $_SERVER['REMOTE_ADDR']; // retrieve the current IP address of the visitor $key = $user_ip . '_acadp_' . $post_id; // combine post ID & IP to form unique key $value = array( $user_ip, $post_id ); // store post ID & IP as separate values (see note) $visited = get_transient( $key ); // get transient and store in variable // check to see if the Post ID/IP ($key) address is currently stored as a transient if( false === ( $visited ) ) { // store the unique key, Post ID & IP address for 12 hours if it does not exist set_transient( $key, $value, 60*60*12 ); // now run post views function $count_key = 'views'; $count = get_post_meta($post_id, $count_key, true); if( '' == $count ) { $count = 0; delete_post_meta( $post_id, $count_key ); add_post_meta( $post_id, $count_key, '0' ); } else { $count++; update_post_meta( $post_id, $count_key, $count ); } } } /** * Get orderby list. * * @since 1.0.0 * * @return array $options A list of the orderby options. */ function acadp_get_orderby_options() { $general_settings = get_option( 'acadp_general_settings' ); $options = array( 'title-asc' => __( "A to Z ( title )", 'advanced-classifieds-and-directory-pro' ), 'title-desc' => __( "Z to A ( title )", 'advanced-classifieds-and-directory-pro' ), 'date-desc' => __( "Recently added ( latest )", 'advanced-classifieds-and-directory-pro' ), 'date-asc' => __( "Date added ( oldest )", 'advanced-classifieds-and-directory-pro' ), 'price-asc' => __( "Price ( low to high )", 'advanced-classifieds-and-directory-pro' ), 'price-desc' => __( "Price ( high to low )", 'advanced-classifieds-and-directory-pro' ), 'views-desc' => __( "Most viewed", 'advanced-classifieds-and-directory-pro' ), 'views-asc' => __( "Less viewed", 'advanced-classifieds-and-directory-pro' ) ); if( empty( $general_settings['has_price'] ) ) { unset( $options['price-asc'] ); unset( $options['price-desc'] ); } return $options; } /** * Get total listings count of the current user. * * @since 1.0.0 * * @return int Total listings count. */ function acadp_get_user_total_listings() { global $wpdb; $where = get_posts_by_author_sql( 'acadp_listings', true, get_current_user_id(), false ); $count = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->posts $where" ); return $count; } /** * Get active listings count of the current user. * * @since 1.0.0 * * @return int Active listings count. */ function acadp_get_user_total_active_listings() { global $wpdb; $where = get_posts_by_author_sql( 'acadp_listings', true, get_current_user_id(), true ); $count = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->posts $where" ); return $count; } /** * Parse the video URL and determine it's valid embeddable URL for usage. * * @since 1.0.0 * * @param string $url YouTube / Vimeo URL. * @return array An array of video metadata if found. */ function acadp_parse_videos( $url ) { $embeddable_url = ''; // Check for YouTube $is_youtube = preg_match( '/youtu\.be/i', $url ) || preg_match( '/youtube\.com\/watch/i', $url ); if( $is_youtube ) { $pattern = '/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/'; preg_match( $pattern, $url, $matches ); if( count( $matches ) && strlen( $matches[7] ) == 11 ) { $embeddable_url = 'https://www.youtube.com/embed/'.$matches[7]; } } // Check for Vimeo $is_vimeo = preg_match( '/vimeo\.com/i', $url ); if( $is_vimeo ) { $pattern = '/\/\/(www\.)?vimeo.com\/(\d+)($|\/)/'; preg_match( $pattern, $url, $matches ); if( count( $matches ) ) { $embeddable_url = 'https://player.vimeo.com/video/'.$matches[2]; } } // Return return $embeddable_url; } /** * Retrieve paginated link for listing pages. * * @since 1.0.0 * * @param int $numpages The total amount of pages. * @param int $pagerange How many numbers to either side of current page. * @param int $paged The current page number. */ function acadp_pagination( $numpages = '', $pagerange = '', $paged = '' ) { if( empty( $pagerange ) ) { $pagerange = 2; } /** * This first part of our function is a fallback * for custom pagination inside a regular loop that * uses the global $paged and global $wp_query variables. * * It's good because we can now override default pagination * in our theme, and use this function in default quries * and custom queries. */ global $paged; if( empty( $paged ) ) { $paged = 1; } if( $numpages == '' ) { global $wp_query; $numpages = $wp_query->max_num_pages; if( ! $numpages ) { $numpages = 1; } } /** * We construct the pagination arguments to enter into our paginate_links * function. */ $arr_params = array( 'order', 'view' ); $base = acadp_remove_query_arg( $arr_params, get_pagenum_link( 1 ) ) . '%_%'; if( ! get_option('permalink_structure') || isset( $_GET['q'] ) ) { $prefix = strpos( $base, '?' ) ? '&' : '?'; $format = $prefix.'paged=%#%'; } else { $prefix = ( '/' == substr( $base, -1 ) ) ? '' : '/'; $format = $prefix.'page/%#%'; } $pagination_args = array( 'base' => $base, 'format' => $format, 'total' => $numpages, 'current' => $paged, 'show_all' => false, 'end_size' => 1, 'mid_size' => $pagerange, 'prev_next' => true, 'prev_text' => __( '«' ), 'next_text' => __( '»' ), 'type' => 'array', 'add_args' => false, 'add_fragment' => '' ); $paginate_links = paginate_links( $pagination_args ); if( $paginate_links ) { echo "
"; echo "
"; printf( __( "Page %d of %d", 'advanced-classifieds-and-directory-pro' ), $paged, $numpages ); echo "
"; echo ""; echo "
"; } } /** * Removes an item or list from the query string. * * @since 1.0.0 * * @param string|array $key Query key or keys to remove. * @param bool|string $query Optional. When false uses the $_SERVER value. Default false. * @return string New URL query string. */ function acadp_remove_query_arg( $key, $query = false ) { if( is_array( $key ) ) { // removing multiple keys foreach( $key as $k ) { $query = str_replace( '#038;', '&', $query ); $query = add_query_arg( $k, false, $query ); } return $query; } return add_query_arg( $key, false, $query ); } /** * Verify the captcha answer. * * @since 1.0.0 * * @param string $form ACADP Form Name. * @return bool True if not a bot, false if bot. */ function acadp_is_human( $form ) { $recaptcha_settings = get_option( 'acadp_recaptcha_settings' ); $has_captcha = false; if( isset( $recaptcha_settings['forms'] ) && '' !== $recaptcha_settings['site_key'] && '' !== $recaptcha_settings['secret_key'] ) { if( in_array( $form, $recaptcha_settings['forms'] ) ) { $has_captcha = true; } } if( $has_captcha ) { $response = isset( $_POST['g-recaptcha-response'] ) ? esc_attr( $_POST['g-recaptcha-response'] ) : ''; if( '' !== $response ) { // make a GET request to the Google reCAPTCHA Server $request = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=' . $recaptcha_settings['secret_key'] . '&response=' . $response . '&remoteip=' . $_SERVER["REMOTE_ADDR"] ); // get the request response body $response_body = wp_remote_retrieve_body( $request ); $result = json_decode( $response_body, true ); // return true or false, based on users input return ( true == $result['success'] ) ? true : false; } else { return false; } } return true; } /** * Get payment gateways. * * @since 1.0.0 * * @return array $gateways A list of the available gateways. */ function acadp_get_payment_gateways() { $gateways = apply_filters( 'acadp_payment_gateways', array( 'offline' => __( 'Offline Payment', 'advanced-classifieds-and-directory-pro' ) ) ); return $gateways; } /** * Update Order details. Send emails to site and listing owners * when order completed. * * @since 1.0.0 * * $param array $order Order details. */ function acadp_order_completed( $order ) { // update order details update_post_meta( $order['id'], 'payment_status', 'completed' ); update_post_meta( $order['id'], 'transaction_id', $order['transaction_id'] ); // If the order has featured $featured = get_post_meta( $order['id'], 'featured', true ); if( isset( $featured ) ) { $post_id = get_post_meta( $order['id'], 'listing_id', true ); update_post_meta( $post_id, 'featured', 1 ); } // Hook for developers do_action( 'acadp_order_completed', $order['id'] ); // send emails acadp_email_listing_owner_order_completed( $order['id'] ); acadp_email_admin_payment_received( $order['id'] ); }