2

I am currently working on a Wordpress site, one of the tasks was to create custom post location post types which I was able to do. I then used a filter I wrote in functions.php to include a separate locations.php file I wrote to be displayed on my location post types pages. See filter below:

add_filter('the_content', 'prepend_location_data' );
function prepend_location_data( $content ){
    if( is_singular('location')){

        $html=include("locations.php");
    return $content . $html;
    }
    return $content;
}

I was able to then use the ACF plugin to add custom fields to my locations posts and display them using ACF functions on my locations.php page. My next task is to add some sort of widget or menu to the top of all the pages to display a particular phone number based on the users IP. I was able to write a php function within the locations.php file I made that gets the user's IP, uses the IP to get the city of the IP and then if that city is equal to a city included in one of the city custom field I created it will return the phone number for that city. See functions below:

<?php
function get_the_user_ip() {
    if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
    //Checks if IP is from shared internet
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
    //Checks if IP is passed from proxy
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } 
    else {
    //Most trustworthy source of IP address
    $ip = $_SERVER['REMOTE_ADDR'];
    }
    //Uses ipinfo.io to find location information based on IP address
    $details = json_decode(file_get_contents("https://ipinfo.io/{$ip}"));

    //Returns city value from the details array
    $city=$details->city;

    return apply_filters('wpb_get_ip', $city );
    }


function display_phone(){
    $cityField=get_field('city');
    $phoneField=get_field('phone_number');
    //Assigns the return value of get_the_user_ip to a variable
    $userCity=get_the_user_ip();
    if($userCity==$cityField){
        return ($phoneField);
    }
}

add_shortcode('show_phone', 'display_phone');
?>

The problem is the shortcode will only work on the locations pages. I realize I somehow have to pass the return value of the display_phone function back to the functions.php file or maybe just do all this logic within the functions.php to begin with. Does anyone have any suggestions about things to try or where to look? Can I use ACF functions within my functions.php? Should I use a Javascript function to do this? Any advice is appreciated.

Phone number would display here at the top right of the menu

I also have tried the following modifications to the display_phone function to no avail.

function display_phone(){
    global $post;
    $current_id = $post->ID;
    $cityField=get_field('city', $post->ID);
    $phoneField=get_field('phone_number');
    //Assigns the return value of get_the_user_ip to a variable
    $userCity=get_the_user_ip();
    if($userCity==$cityField){
        return ($phoneField);
}
}

next modification to display_phone function:

function display_phone(){
    global $post;
    $current_id = $post->ID;
    $cityField=get_field('city', $current_id);
    $phoneField=get_field('phone_number');
    //Assigns the return value of get_the_user_ip to a variable
    $userCity=get_the_user_ip();
    if($userCity==$cityField){
        return ($phoneField);
}
}

UPDATE: Ok so after thinking about this a bit more i'm thinking I need to write a function that will loop through all of the city and phone number fields of the location post types to see if they match with the city returned by the get_the_user_ip function. Obviously the display phone function will have to be modified to do this and i'm thinking I will have to take both functions out of locations.php and maybe perform this logic within the header.php file. Does anyone have any experience doing something similar or any advice on how to do this? I'm not really sure how to loop through the field data of my location post types unless i'm actually doing the logic within a post. I realize this could be solved by using a hard-coded array of cities and phone numbers but I am trying to avoid that and make use of the ACF plugin instead.

UPDATE: So I took the logic out of the locations.php page and moved it to the end of the functions.php file. Right now it is printing the correct phone number at the top of every page on load but only for a second. So it looks like the next step in the process is to get this number assigned to a variable and passed through a function somehow so that I can then assign to a shortcode and use throughout my site.

<?php 

function get_the_user_ip() {
    if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
    //Checks if IP is from shared internet
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
    //Checks if IP is passed from proxy
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } 
    else {
    //Most trustworthy source of IP address
    $ip = $_SERVER['REMOTE_ADDR'];
    }
    //Uses ipinfo.io to find location information based on IP address
    $details = json_decode(file_get_contents("https://ipinfo.io/{$ip}"));

    //Returns city value from the details array
    $city=$details->city;

    return apply_filters('wpb_get_ip', $city );
    }


$posts = get_posts(array(
    'posts_per_page'    => -1,
    'post_type'         => 'location'
));
$userCity=get_the_user_ip();
if( $posts ): 



     foreach( $posts as $post ): 

        $cityField=get_field('city');
        //echo "$cityField";        
        $phoneField=get_field('phone_number');
        //echo "$phoneField";
         if($userCity==$cityField){
             echo ($phoneField);
         }

     endforeach;


    wp_reset_postdata(); 

 endif; 


?>
Blaise
  • 137
  • 11
  • I'm not sure I understand what you're trying to do here, but you could just add `` somewhere in your theme's header.php file (see [do_shortcode()](https://developer.wordpress.org/reference/functions/do_shortcode/) for more details). – cabrerahector Oct 04 '18 at 16:33
  • @cabrerahector basically I am trying to have a different phone number display to the user on the top menu based on their location, as the company has multiple branches. Thanks for the suggestion. I am going through the header.php file now. I will let you know if it works. – Blaise Oct 04 '18 at 16:50
  • You're comparing the IP address to the value of `get_field('city');`, but those fields are only added to the locations posts, so it makes sense that there is no value to compare against when you're on other pages. – johnnyd23 Oct 04 '18 at 17:16
  • @johnnyd23 Is there a way to run the the functions I wrote in a different area or pull them into the functions.php file somehow so that I can display the return value site-wide? – Blaise Oct 04 '18 at 17:29
  • What would you be comparing the IP address to on a site-wide basis? – johnnyd23 Oct 04 '18 at 17:29
  • @johnnyd23 well I would like to compare them to the city fields. I guess a better question would be how can I export these fields to an area outside of the locations posts? From reading the ACF documentation I should be able to loop through the custom "city" fields outside of the locations posts. I'm just not exactly clear on where or how to do this. I would prefer not to hard-code an array of cities and phone numbers anywhere. – Blaise Oct 04 '18 at 17:45
  • For global data you would be better off using ACF option pages: https://www.advancedcustomfields.com/add-ons/options-page/ (also don't forget to add `"autoload"=>true` if possible) – René Oct 05 '18 at 14:40
  • @René I appreciate the advice I will go ahead and add that now. – Blaise Oct 05 '18 at 16:11

2 Answers2

0

I think you need to provide the page ID as well otherwise how will WordPress know which locations phone number to use? So

get_field('city');

will become

get_field('city', $post->ID);

You can get the current pages ID by using the below in your display_phone function:

global $post;
$current_id = $post->ID;

UPDATE:

Looks like you're good to go. Like you said all you need to do is create a shortcode to call it.

function rusty_showphone() {
  $posts = get_posts(array(
    'posts_per_page'    => -1,
    'post_type'         => 'location'
  ));
  $userCity=get_the_user_ip();
  if( $posts ): 
    foreach( $posts as $post ): 
        $cityField=get_field('city');        
        $phoneField=get_field('phone_number');
         if($userCity==$cityField){
             return $phoneField;
         }
     endforeach;
     wp_reset_postdata(); 
   endif; 
  }
add_shortcode('showphone', 'rusty_showphone');
RustyBadRobot
  • 556
  • 3
  • 16
  • That makes sense and doing what you said doesn't break my function but it still will only display on the location page I am located at. The shortcode will just display as [show_city] on the main page for instance, instead of actually displaying the phone number as it should. Basically the shortcode will only work in location posts. – Blaise Oct 04 '18 at 17:10
  • I tried that but for some reason the phone number still doesn't show site wide. The short code works in any of the locations posts though. Which seems strange because when I print it instead of return it, the phone number appears on every page for a second so I know it has to be accessible somehow. – Blaise Oct 08 '18 at 18:05
0

So I found a solution. If anyone has any suggestions about how I could do any better that would be great.

First I made a new file within my wordpress child theme called phone-display.php see below:

<?php 

function get_the_user_ip() {
    if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
    //Checks if IP is from shared internet
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
    //Checks if IP is passed from proxy
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } 
    else {
    //Most trustworthy source of IP address
    $ip = $_SERVER['REMOTE_ADDR'];
    }
    //Uses ipinfo.io to find location information based on IP address
    $details = json_decode(file_get_contents("https://ipinfo.io/{$ip}"));

    //Returns city value from the details array
    $city=$details->city;

    return apply_filters('wpb_get_ip', $city );
    }


$posts = get_posts(array(
    'posts_per_page'    => -1,
    'post_type'         => 'location'
));
$userCity=get_the_user_ip();
if( $posts ): 



     foreach( $posts as $post ): 

        $cityField=get_field('city');
        //echo "$cityField";        
        $phoneField=get_field('phone_number');
        //echo "$phoneField";
         if($userCity==$cityField){
             echo ($phoneField);
         }

     endforeach;


    wp_reset_postdata(); 

 endif; 


?>

Then I added this custom div element where I wanted the phone number to be displayed.

<div id="phone"></div>

Then I added this JavaScript code to the bottom of my footer.php file.

<script>document.getElementById("phone").innerHTML = '<?php include("phone-display.php"); ?>';</script>
Blaise
  • 137
  • 11