I have a wordpress site that contains hundreds of company profiles. Each company has an address that is geocoded when someone visits their profile. At present that's the only way the address get's geocoded, so if no one visits the page then the address doesn't get geocoded.
That also creates another problem, it geocodes the address every time someone visits the page!
I need to come up with a way that will trigger the geocoding once for each company BUT without having to visit the page.
Is there any way this can be done?
UPDATE:
This is the script that is triggered when you visit a company profile (i.e the geocoding). So for 300 companies you would need to visit all 300 pages for all of them to be geocoded!
<?php
require("database.php");
// Opens a connection to a MySQL server
$con = mysql_connect("localhost", $username, $password);
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("medicom_wp", $con);
$company = get_field('company_name');
$address = get_field('address');
$city = get_field('city');
$post_code = get_field('post_code');
$sql = sprintf("select count('x') as cnt from markers where `name` = '%s'", mysql_real_escape_string($company));
$row_dup = mysql_fetch_assoc(mysql_query($sql,$con));
if ($row_dup['cnt'] == 0) {
mysql_query("INSERT INTO markers (`name`, `address`, `lat`, `lng`, `type`) VALUES ('".$company."', '".$address.", ".$city.", ".$post_code."', '0.0', '0.0', '')");
}
wp_reset_query();
define("MAPS_HOST", "maps.google.com");
define("KEY", "");
// Opens a connection to a MySQL server
$connection = mysql_connect("localhost", $username, $password);
if (!$connection) {
die("Not connected : " . mysql_error());
}
// Set the active MySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
die("Can\'t use db : " . mysql_error());
}
// Select all the rows in the markers table
$query = "SELECT * FROM markers WHERE 1";
$result = mysql_query($query);
if (!$result) {
die("Invalid query: " . mysql_error());
}
// Initialize delay in geocode speed
$delay = 0;
$base_url = "http://" . MAPS_HOST . "/maps/geo?output=xml" . "&key=" . KEY;
// Iterate through the rows, geocoding each address
while ($row = #mysql_fetch_assoc($result)) {
$geocode_pending = true;
while ($geocode_pending) {
$address = $row["address"];
$id = $row["id"];
$request_url = $base_url . "&q=" . urlencode($address);
$xml = simplexml_load_file($request_url) or die("url not loading");
$status = $xml->Response->Status->code;
if (strcmp($status, "200") == 0) {
// Successful geocode
$geocode_pending = false;
$coordinates = $xml->Response->Placemark->Point->coordinates;
$coordinatesSplit = split(",", $coordinates);
// Format: Longitude, Latitude, Altitude
$lat = $coordinatesSplit[1];
$lng = $coordinatesSplit[0];
$query = sprintf("UPDATE markers " .
" SET lat = '%s', lng = '%s' " .
" WHERE id = '%s' LIMIT 1;",
mysql_real_escape_string($lat),
mysql_real_escape_string($lng),
mysql_real_escape_string($id));
$update_result = mysql_query($query);
if (!$update_result) {
die("Invalid query: " . mysql_error());
}
} else if (strcmp($status, "620") == 0) {
// sent geocodes too fast
$delay += 1000;
} else {
// failure to geocode
$geocode_pending = false;
echo "Address " . $address . " failed to geocoded. ";
echo "Received status " . $status . "
\n";
}
usleep($delay);
}
}
?>
Assuming you are doing the geocoding on the server, then to solve the problem of looking up the data each time, just cache the result.
Your logic will then look something like:
if geocode in database
get data from database
else
get data from geocode lookup
store data in database
return data
If you really want to avoid doing it on demand (i.e. not even the first time), then do what I have in "else" there when you save a page.
Related
I am attempting to loop through a set of records containing IPs for users. I am using the freegeoip.net API service for geolocation. Inside of the users table, I've stored IPs from users of the application and now I'm interested in updating all records individually by making a call to the API, having it return JSON content that I fetch with file_get_contents and then input into 2 fields based on the key (i.e. city, region_name AKA state).
Example of sample data being returned from API: http://freegeoip.net/json/
I have essentially 3 columns: [ip], [city], [state]
I have the IP data populated.
Below is the beginning of my PHP code which is a modification of my SELECT methods. Now I need to execute UPDATE queries individually. Inside of the file_get_contents is the API URL for freegeoip.
<?php
$con=mysqli_connect("localhost","user","password","database");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM user_log");
while($row = mysqli_fetch_array($result)) {
$pageContent = file_get_contents('http://freegeoip.net/json/' . $row['ip']);
$parsedJson = json_decode($pageContent);
echo "<br />The IP is: " . $row['ip'];
echo "<br />The Location is: " . $parsedJson;
}
mysqli_close($con);
?>
Question: How would I modify this code to loop through each MySQL record (based on IP column) and update the relevant fields data (city and state) received from my API?
Loop through your IPs
Fetch the geo location
Update the record
$result = mysqli_query($con,"SELECT DISTINCT(`ip`) AS ip FROM user_log");
while($row = mysqli_fetch_array($result)) {
$pageContent = file_get_contents('http://freegeoip.net/json/' . $row['ip']);
$parsedJson = json_decode($pageContent, true);
echo "<br />The IP is: " . $row['ip'];
echo "<br />The Location is: " . $parsedJson['city'];
$strDbQuery = "UPDATE user_log SET city = ?, state = ? WHERE ip = ?";
$objUpdate = mysqli_prepare($con, $strDbQuery);
if($objUpdate) {
mysqli_stmt_bind_param($objUpdate, 'sss', $parsedJson['city'], $parsedJson['region_name'], $row['ip']);
mysqli_stmt_execute($objUpdate);
} else {
echo "Cannot update for ip ". $row['ip'] . PHP_EOL;
}
}
mysqli_close($con);
<?php
$con = mysqli_connect("localhost","user","password","database");
/* check connection */
if ($con->connect_errno) {
die("Connect failed: " . $con->connect_error);
}
$result = $con->query("SELECT * FROM `user_log`");
while($row = $result->fetch_array()) {
$pageContent = file_get_contents('http://freegeoip.net/json/' . $row['ip']);
$parsedJson = json_decode($pageContent);
$stmt = $con->prepare("UPDATE `user_log` SET `city` = ?, `region_name` = ? WHERE `ip` = ?");
$stmt->bind_param("sss", $parsedJson['city'], $parsedJson['region_name'], $row['ip']);
$stmt->execute();
}
?>
I've built a website using Wordpress.
I have a template that has the following code, it is geocoding an address and saving the result into a new database.
I then have another template that reads all the lat/lng's from the new database and plots hundreds of markers on a Google map.
The problem is that the geocoding only happens when someone visits the page. This creates a couple of problems - 1) It geocodes EVERY time someone visits the page. 2) It ONLY geocodes when someone visits the page!
Is there a way to run this code ONCE when Wordpress publishes/updates the page?
This section grabs the company info from Wordpress and inserts it into the database:
$company = get_field('company_name');
$address = get_field('address');
$city = get_field('city');
$post_code = get_field('post_code');
$sql = sprintf("select count('x') as cnt from markers where `name` = '%s'", mysql_real_escape_string($company));
$row_dup = mysql_fetch_assoc(mysql_query($sql,$con));
if ($row_dup['cnt'] == 0) {
mysql_query("INSERT INTO markers (`name`, `address`, `lat`, `lng`, `type`) VALUES ('".$company."', '".$address.", ".$city.", ".$post_code."', '0.0', '0.0', '')");
}
wp_reset_query();
Here's the full code:
<?php
require("database.php");
// Opens a connection to a MySQL server
$con = mysql_connect("localhost", $username, $password);
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("medicom_wp", $con);
$company = get_field('company_name');
$address = get_field('address');
$city = get_field('city');
$post_code = get_field('post_code');
$sql = sprintf("select count('x') as cnt from markers where `name` = '%s'", mysql_real_escape_string($company));
$row_dup = mysql_fetch_assoc(mysql_query($sql,$con));
if ($row_dup['cnt'] == 0) {
mysql_query("INSERT INTO markers (`name`, `address`, `lat`, `lng`, `type`) VALUES ('".$company."', '".$address.", ".$city.", ".$post_code."', '0.0', '0.0', '')");
}
wp_reset_query();
define("MAPS_HOST", "maps.google.com");
define("KEY", "");
// Opens a connection to a MySQL server
$connection = mysql_connect("localhost", $username, $password);
if (!$connection) {
die("Not connected : " . mysql_error());
}
// Set the active MySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
die("Can\'t use db : " . mysql_error());
}
// Select all the rows in the markers table
$query = "SELECT * FROM markers WHERE 1";
$result = mysql_query($query);
if (!$result) {
die("Invalid query: " . mysql_error());
}
// Initialize delay in geocode speed
$delay = 0;
$base_url = "http://" . MAPS_HOST . "/maps/geo?output=xml" . "&key=" . KEY;
// Iterate through the rows, geocoding each address
while ($row = #mysql_fetch_assoc($result)) {
$geocode_pending = true;
while ($geocode_pending) {
$address = $row["address"];
$id = $row["id"];
$request_url = $base_url . "&q=" . urlencode($address);
$xml = simplexml_load_file($request_url) or die("url not loading");
$status = $xml->Response->Status->code;
if (strcmp($status, "200") == 0) {
// Successful geocode
$geocode_pending = false;
$coordinates = $xml->Response->Placemark->Point->coordinates;
$coordinatesSplit = split(",", $coordinates);
// Format: Longitude, Latitude, Altitude
$lat = $coordinatesSplit[1];
$lng = $coordinatesSplit[0];
$query = sprintf("UPDATE markers " .
" SET lat = '%s', lng = '%s' " .
" WHERE id = '%s' LIMIT 1;",
mysql_real_escape_string($lat),
mysql_real_escape_string($lng),
mysql_real_escape_string($id));
$update_result = mysql_query($query);
if (!$update_result) {
die("Invalid query: " . mysql_error());
}
} else if (strcmp($status, "620") == 0) {
// sent geocodes too fast
$delay += 1000;
} else {
// failure to geocode
$geocode_pending = false;
echo "Address " . $address . " failed to geocoded. ";
echo "Received status " . $status . "
\n";
}
usleep($delay);
}
}
?>
In general:
In a plugin (or in the file functions.php located in your theme) you have the following code:
add_action('publish_post', function($post_id) {
// Here you have some code that finds out the geocode data
// then you attach it to this post as a meta value
update_post_meta($post_id, 'my_geocode', $geo_data);
});
Then in your template file (single.php) you will have somehting like:
$geo_data = get_post_meta($post->ID, 'my_geocode', true);
if( $geo_data ) {
get_template_part('geocode');
}
Or if you want to keep your template files clean you can add action "the_content"
in the file functions.php located in the theme directory (or in your plugin file)
add_action('the_content', function() {
if( is_singular() ) {
global $post;
$geo_data = get_post_meta($post->ID, 'my_geocode', true);
if( $geo_data ) {
get_template_part('geocode');
}
}
});
Do a google search like "wordpress add_action". Wordpress lets you "listen" to different events taking place within wordpress. In your case I think you can use the action named "update_post".
I really don't know what i'm doing wrong. I want to count the rows in my query. My id's started from 1 to ... step 1, so the biggest number is the last record. I only want to let the script run on the last record of de DB. So here is my code.
public function saveLongLan()
{
define("MAPS_HOST", "maps.google.com");
define("KEY", "MYKEY");
$link = mysql_connect('localhost', 'root', 'root');
if (!$link) {
die('Not connected : ' . mysql_error());
}
// Set the active MySQL database
$db_selected = mysql_select_db('Foodsquare', $link);
if (!$db_selected)
{
die("Can\'t use db : " . mysql_error());
}
$query = "SELECT * FROM tblPlaces WHERE 1";
$result = mysql_query($query);
$row_cnt = mysqli_num_rows($result);
if (!$result)
{
die("Invalid query: " . mysql_error());
}
$delay = 0;
$base_url = "http://" . MAPS_HOST . "/maps/geo?output=xml" . "&key=" . KEY;
while ($row = #mysql_fetch_assoc($result))
{
$geocode_pending = true;
while ($geocode_pending)
{
$address = $row["Street"];
$id = $row["Id"];
$request_url = $base_url . "&q=" . urlencode($address);
$xml = simplexml_load_file($request_url) or die("url not loading");
$status = $xml->Response->Status->code;
if (strcmp($status, "200") == 0)
{
// Successful geocode
$geocode_pending = false;
$coordinates = $xml->Response->Placemark->Point->coordinates;
//explode functie breekt een string af vanaf een bepaald teken en stopt hem dan in een array
$coordinatesSplit = explode(',', $coordinates);
// formaat: Longitude, Latitude, Altitude
$lat = $coordinatesSplit[1];//getal = plaats in array
$lng = $coordinatesSplit[0];
$query = sprintf("UPDATE tblPlaces " .
" SET lat = '%s', lng = '%s' " .
" WHERE id = '". $row_cnt . "' LIMIT 1;",
mysql_real_escape_string($lat),
mysql_real_escape_string($lng),
mysql_real_escape_string($id));
$update_result = mysql_query($query);
if (!$update_result)
{
die("Invalid query: " . mysql_error());
}
} else if (strcmp($status, "620") == 0)
{
// sent geocodes too fast
$delay += 100000;
}
else
{
// failure to geocode
$geocode_pending = false;
echo "Address " . $address . " failed to geocoded. ";
echo "Received status " . $status . " \n";
}
usleep($delay);
}
}
}
your query is incorrect $query = "SELECT * FROM tblPlaces WHERE 1";
you should specify the column name after where clause for comparison with a value for example: WHERE column_name = 1 or something like that.
You're using mysqli_num_rows($result) but you aren't using MySQLi.
Change:
$row_cnt = mysqli_num_rows($result);
To:
$row_cnt = mysql_num_rows($result);
And you should be good to go.
I'm writing a quiz program using PHP and a bit of Javascript. The questions can be answered correctly when IE or Chrome is used but Firefox refreshes the page and increments the session variable.
Here's a code snippet:
if(isset($_GET['answer1']))
{
if($_GET['answer'] == $_GET['answer1'])
{
include 'config.php';
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db($db, $con);
$userId = $_SESSION['userId'];
$wordNow = $_SESSION['word'];
$sql3 = "SELECT * FROM userAccomplishments Where UserId = '$userId' AND
word = '$wordNow'";
$result3 = mysql_query($sql3);
if (mysql_num_rows($result3) == 0) {
$sql4 = "SELECT wordId from allwords WHERE word = '$wordNow'";
$result = mysql_query($sql4);
if (!$result) {
echo "Could not successfully run query ($sql) from DB: " . mysql_error();
exit;
}
if (mysql_num_rows($result) == 0) {
echo "No rows found, nothing to print so am exiting from random number";
exit;
}
while ($row = mysql_fetch_assoc($result)) {
$wordId = $row["wordId"];
// echo $row["word"] . " " ."<BR>" ;
}
list($usec, $sec) = explode(' ', microtime());
$script_end = (float) $sec + (float) $usec;
$elapsed_time = (float)($script_end - $script_start);
$elapsed_time = $_GET['formvar'];
$sql2 = "INSERT INTO userAccomplishments (UserId, word, TimeTaken, wordId)
VALUES ('$userId', '$wordNow', '$elapsed_time', '$wordId')";
echo 'You got '. $wordNow . ' in ' .$elapsed_time . ' seconds. <BR><BR>';
$result = mysql_query($sql2);
}
$_SESSION['views'] = $_SESSION['views'] + 1;
}
else
{
$_SESSION['views'] = $_SESSION['views'] + 1;
echo 'Keep studying <BR>';
}
}
else
{
$_SESSION['views'] = 1;
}
Doesn't look like you're calling session_start(). Make sure you call it to get your session in gear! Woo! Yeah!
I have a table, "jos_ezrealty" that has address, city, state fields and declat & declong for latitude and longitude. I need to adapt the code below (provided by google - http://code.google.com/apis/maps/articles/phpsqlgeocode.html) to work with my table. All of my address fields are filled, and half of my lat & long fields are filled. I want to use the code below to fill in the missing lat & long information (don't worry about geocoding request limits, as I only have 300 properties and this code only fills in the missing ones)
Thanks -
<?php
require("phpsqlgeocode_dbinfo.php");
define("MAPS_HOST", "maps.google.com");
define("KEY", "abcdefg");
// Opens a connection to a MySQL server
$connection = mysql_connect("localhost", $username, $password);
if (!$connection) {
die("Not connected : " . mysql_error());
}
// Set the active MySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
die("Can\'t use db : " . mysql_error());
}
// Select all the rows in the markers table
$query = "SELECT * FROM markers WHERE 1";
$result = mysql_query($query);
if (!$result) {
die("Invalid query: " . mysql_error());
}
// Initialize delay in geocode speed
$delay = 0;
$base_url = "http://" . MAPS_HOST . "/maps/geo?output=xml" . "&key=" . KEY;
// Iterate through the rows, geocoding each address
while ($row = #mysql_fetch_assoc($result)) {
$geocode_pending = true;
while ($geocode_pending) {
$address = $row["address"];
$id = $row["id"];
$request_url = $base_url . "&q=" . urlencode($address);
$xml = simplexml_load_file($request_url) or die("url not loading");
$status = $xml->Response->Status->code;
if (strcmp($status, "200") == 0) {
// Successful geocode
$geocode_pending = false;
$coordinates = $xml->Response->Placemark->Point->coordinates;
$coordinatesSplit = split(",", $coordinates);
// Format: Longitude, Latitude, Altitude
$lat = $coordinatesSplit[1];
$lng = $coordinatesSplit[0];
$query = sprintf("UPDATE markers " .
" SET lat = '%s', lng = '%s' " .
" WHERE id = '%s' LIMIT 1;",
mysql_real_escape_string($lat),
mysql_real_escape_string($lng),
mysql_real_escape_string($id));
$update_result = mysql_query($query);
if (!$update_result) {
die("Invalid query: " . mysql_error());
}
} else if (strcmp($status, "620") == 0) {
// sent geocodes too fast
$delay += 100000;
} else {
// failure to geocode
$geocode_pending = false;
echo "Address " . $address . " failed to geocoded. ";
echo "Received status " . $status . "
\n";
}
usleep($delay);
}
}
?>
If I understood correctly you need to adapt your database schema into the code example provided by google.
If that is the case then if your database follows the google example i.e.
CREATE TABLE `markers` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 60 ) NOT NULL ,
`address` VARCHAR( 80 ) NOT NULL ,
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
`type` VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;
You only have to rename your table to markers or change and change the $database value at the phpsqlgeocode_dbinfo.php or change the queries to select your table.
Otherwise please specify your problem.