NOTICE: We've Moved to a Ticket System for Support

As of August 31, 2017 (12am EST) our support forums will be retired (read-only), and we will be moving to a support ticket system.ย  This will allow us to better organize and answer support requests, and provide a more personalized experience as we assist our customers.

For the time being, we will leave our forums open for reading and learning while we work on creating a more robust Knowledge Base for everyone to use.

If you are a WC Vendors Pro customer please open a support ticket here. 

If you are a WC Vendors user please open a support ticket on the Wordpress.org forums.

The information on this forum is outdated and in most instances no longer relevant. Please be sure to check our documentation for the most up to date information.

https://docs.wcvendors.com/

Thank you to all of our customers!

 

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #63728
    Henrik Milo
    Participant

    Hi,

    Is it possible for Vendor to specify location address on service? I would like Vendor able to specify online and/or an address for locations. This I can then use for filters and map presentations.

    #64257
    Chris Johnson
    Participant

    Ok here we go… I wont provide support on this code so you will have to mess with it till you get it to work.

    To add a geolocation field to Products/Store settings:

    Get yourself a copy of Advanced Custom Fields and create a field group with the geolocation field in it. Set a location rule of:

    Current User Role = Vendor AND Current User = Viewing Front End

    If you want to geocode the product too then add an additional location rule of:

    Post Type = Product

    *****************************
    * Initialize ACF Google Map *
    *****************************

    Add the following to your functions.php:

    /**
     * ACF Google Map API Key
     *
     * Needed to initialize ACF Map field
     */
    function my_acf_init() {
      
      $mapapikey = 'your_google_map_api_key_here';
        
        acf_update_setting('google_api_key', $mapapikey);
    }
    
    add_action('acf/init', 'my_acf_init');

    Now if all you are wanting to do is to be able to filter based on geolocation and you do not want to display a map on the product itself, you are done. Go get you a copy of Facetwp and use their proximity facet with their google map addon and you are set. If you do want to display a map say in the product itself in its own tab continue on below:

    *****************************
    * Enqueue ACF Google Map JS *
    *****************************

    Add the following to your functions.php:

    /**
     * Enqueue ACF Map JS
     */
    function my_theme_add_scripts() {
      if ( is_woocommerce() ) {
    // 
     $mapapikey = 'your_google_map_api_key_here';
     $mapurl = "https://maps.googleapis.com/maps/api/js?key=$mapapikey";
     wp_enqueue_script( 'google-map', $mapurl, array(), '3', true );
     wp_enqueue_script( 'google-map-init', get_stylesheet_directory_uri() . '/library/js/yourmap.js', array('google-map', 'jquery'), '1.5', true );
    	}
      } 
    add_action( 'wp_enqueue_scripts', 'my_theme_add_scripts' );

    Create the following directory structure in your child theme root folder:

    /library/js/

    Create a javascript file called yourmap.js and store it in the above directory with the following contents:

    (function($) {
     
    /*
    *  render_map
    *
    *  This function will render a Google Map onto the selected jQuery element
    *
    *  @type function
    *  @date 8/11/2013
    *  @since 4.3.0
    *
    *  @param $el (jQuery element)
    *  @return n/a
    */
     
    function render_map( $el ) {
     
     // var
     var $markers = $el.find('.marker');
     
     // vars
     var args = {
     scrollwheel:  false,
     zoom : 10,
     center : new google.maps.LatLng(0, 0),
     mapTypeId : google.maps.MapTypeId.ROADMAP
     };
     
     // create map          
     var map = new google.maps.Map( $el[0], args);
     
     // add a markers reference
     map.markers = [];
     
     // add markers
     $markers.each(function(){
     
         add_marker( $(this), map );
     
     });
    
     // center map
     center_map( map );
     
    }
    
     
    /*
    *  add_marker
    *
    *  This function will add a marker to the selected Google Map
    *
    *  @type function
    *  @date 8/11/2013
    *  @since 4.3.0
    *
    *  @param $marker (jQuery element)
    *  @param map (Google Map object)
    *  @return n/a
    */
     
    function add_marker( $marker, map ) {
     
     // var
     var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
    
     // create marker
     var marker = new google.maps.Marker({
     position : latlng,
     map : map
     });
     
     // add to array
     map.markers.push( marker );
     
     // if marker contains HTML, add it to an infoWindow
     if( $marker.html() )
     {
     // create info window
    
     var infowindow = new google.maps.InfoWindow({
     content : $marker.html()
     });
     
     // show info window when marker is clicked
     google.maps.event.addListener(marker, 'click', function() {
     
     infowindow.open( map, marker );
     
     });
     }
     
       // Event that closes the Info Window with a click on the map
      google.maps.event.addListener(map, 'click', function() {
        infowindow.close();
      });
    
    }
     
    /*
    *  center_map
    *
    *  This function will center the map, showing all markers attached to this map
    *
    *  @type function
    *  @date 8/11/2013
    *  @since 4.3.0
    *
    *  @param map (Google Map object)
    *  @return n/a
    */
     
    function center_map( map ) {
     
     // vars
     var bounds = new google.maps.LatLngBounds();
     
     // loop through all markers and create bounds
     $.each( map.markers, function( i, marker ){
     
     var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
     
     bounds.extend( latlng );
     
     });
     
     // only 1 marker?
     if( map.markers.length == 1 )
     {
     // set center of map
         map.setCenter( bounds.getCenter() );
         map.setZoom( 10 );
     }
     else
     {
     // fit to bounds
     map.fitBounds( bounds );
     }
    
         $(document).on('click', '.delivery_area_tab a', function() {
            google.maps.event.trigger(map, 'resize');
            map.setCenter( bounds.getCenter() );
            map.setZoom( 10 );
        });
    
     
    }
     
    /*
    *  document ready
    *
    *  This function will render each map when the document is ready (page has loaded)
    *
    *  @type function
    *  @date 8/11/2013
    *  @since 5.0.0
    *
    *  @param n/a
    *  @return n/a
    */
     
    $(document).ready(function(){
     
     $('.acf-map').each(function(){
     
     render_map( $(this) );
     
     });
     
    });
     
    })(jQuery);

    Add the following to your function.php file to render the map in a new tab on the single product page:

    add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
    function woo_new_product_tab( $tabs ) {
    	
    	// Adds the new tab
    	
    	$tabs['delivery_area'] = array(
    		'title' 	=> __( 'Delivery Area', 'woocommerce' ),
    		'priority' 	=> 50,
    		'callback' 	=> 'woo_new_product_tab_content'
    	);
    
    	return $tabs;
    
    }
    function woo_new_product_tab_content() {
    
    	// The new tab content
    
    $location = get_field('delivery_location');
      
      echo '< div>';
      echo '< h3>';
      echo 'Delivery Area</h3>';
      echo '< hr>';
      echo '< div class="acf-map">';
      echo '< div class="marker" data-lat="' . $location['lat'] . '" data-lng="' . $location['lng'] . '">';
      echo '< div id="iw-container">';
      echo '< div class="iw-title">';
      echo 'Title';
      echo '</div>';
      echo '< div>';
      echo '< h3';
      echo '< span>Something here</span>';
      echo '</h3>';
      echo '< div>';
      echo '<a class="button" href="#">Button</a>';
      echo '</div>';
      echo '</div>';
      echo '</div>';
      echo '</div>';
      echo '</div>';
      echo '</div>';
    	
    } 

    If you want to display the geolocate field on the WC Pro frontend store setting form to do the following (this allows you to filter on vendor location if you want):

    *****************************
    * Front End Store Settings: *
    *****************************

    Grab the field group ID from the URL when you are in it from the admin panel of ACF:

    wp-admin/post.php?post=161&action=edit

    Add this to your functions.php substituting 'fields_group' => 161, the value of 161 with whatever your field group ID is:

    /* - Courtesy of Ben Lumley - https://www.wcvendors.com/help/topic/howto-add-acf-fields-to-frontend-shop-edit/
     * 
     * This will display + save any custom fields applicable to the vendor_shop in question. Second one displays the fields, you can adjust the action itโ€™s attached to in order  * to move the fields (see templates/dashboard/store-settings.php in the pro plugin for possible actions). You could also split and display different fields in different  * places โ€“ see the docs for acf_form, you can select single/groups of fields.
     * http://www.advancedcustomfields.com/resources/acf_form/
     * Also possible via acf_form to alter the markup a bit to make it fit your theme.
     *
     * This code is not supported by WC Vendors, use at your own risk and at your own discretion.
    */
    
    add_action('wcvendors_settings_after_shop_name', 'wcv_save_acf_fields');
    function wcv_save_acf_fields() {
    	acf_form_head();
    }
    
    add_action('wcvendors_settings_after_seller_info', 'wcv_add_acf_fields');
    function wcv_add_acf_fields() {
    	acf_form( array(
    	  	'fields_group' => 161,  //  Change this to whatever yours is
    		'form' => false,
    		'return' => false,
    		'post_id' => WCVendors_Pro_Vendor_Controller::get_vendor_store_id( get_current_user_id() )
    	) );
    }
    
    // if you have media upload fields (file/image), they won't work, and further, the existing branding uploaders for icon etc break.
    // this is because acf alters the uploader init to pass a post_id, and vendor users don't have 'edit_post' capabilities, assume you guys are handling this somewhere else
    // this snippet adds a filter in so that if we are trying to 'edit_post' on our own published vendor store, it will be allowed - restoring media upload.
    
    add_filter('user_has_cap', 'wcv_vendor_has_cap', 4, 99);
    function wcv_vendor_has_cap($allcaps, $caps, $args, $user) {
    	if ($args[0] == 'edit_post') {
    	$post = get_post($args[2]);
    	if ($post->post_type == 'vendor_store' && $post->post_author == $user->ID) {
    		$allcaps['edit_published_posts'] = true;
    		}
    	}
    	return $allcaps;
    }
    
    //Filter all ACF values.
    
    function my_kses_post( $value ) {
    	
    	// is array
    	if( is_array($value) ) {
    	
    		return array_map('my_kses_post', $value);
    	
    	}
    	
    	
    	// return
    	return wp_kses_post( $value );
    
    }
    
    add_filter('acf/update_value', 'my_kses_post', 10, 1);
    #64260
    Chris Johnson
    Participant

    In the echo lines above remove the leading space before all of the opening element tags. For some reason I have to do that else the forum parses that info out.

    #64319
    Henrik Milo
    Participant

    Hi Chris,

    Thanks a lot for the inputs! – I will try and play with it ๐Ÿ™‚

    – Any roadmap plans on getting location handling in the booking integration? (just to align and evaluate what solutions I go for and setup)

    BR

Viewing 4 posts - 1 through 4 (of 4 total)
  • The forum ‘WooCommerce Bookings Integration’ is closed to new topics and replies.