Skip to content

Instantly share code, notes, and snippets.

@ezekg
Last active December 22, 2022 08:35
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ezekg/7a839c615f905499ae46 to your computer and use it in GitHub Desktop.
Save ezekg/7a839c615f905499ae46 to your computer and use it in GitHub Desktop.
Import CSV script for WP Store Locator plugin
<?php
/**
* This is a quick and dirty script. This should NEVER be run on a production server.
*
* Include this script at the bottom of your functions.php file, e.g.
*
* ```php
* // Your functions.php file
* // ...
*
* include_once "import-store-locations.php"
* ```
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// Redirect to 404 if script is accessed directly
if ( ! defined("ABSPATH") ) {
header("Location: http://{$_SERVER['HTTP_HOST']}/404");
die;
};
/**
* Show insert posts button in admin backend
*/
add_action("admin_notices", function() {
echo "<div class='updated'>";
echo "<p>";
echo "To insert the store locations into the database, click the button to the right.";
echo "<a class='button button-primary' style='margin:0.25em 1em' href='{$_SERVER["REQUEST_URI"]}&insert_store_locations'>Insert Posts</a>";
echo "</p>";
echo "</div>";
});
/**
* Create and insert posts from CSV files
*/
add_action("admin_init", function() {
global $wpdb, $wpsl_admin;
// I'd recommend replacing this with your own code to make sure
// the post creation _only_ happens when you want it to.
if ( ! isset($_GET["insert_store_locations"]) ) {
return;
}
// Set up custom post type and custom fields. The custom fields are mapped
// to the columns defined within the CSV file. An array of column names
// will be concatenated into a single string on import.
//
// NOTE: Make sure this matches your CSV file's column names EXACTLY, i.e.
// | Name | ShipAddress_Addr2 | ShipAddress_Addr3 | ShipAddress_Addr4 | ShipAddress_City | ShipAddress_State | ShipAddress_PostalCode | Phone | Fax | Email |
// |------|-------------------|-------------------|-------------------|------------------|-------------------|------------------------|-------|-----|-------|
// | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
// | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
// | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
// | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
// | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
$config = [
"post_type" => "wpsl_stores",
"fields" => [
"post_title" => "Name",
"wpsl_address" => "ShipAddress_Addr2",
"wpsl_address2" => ["ShipAddress_Addr3", "ShipAddress_Addr4"],
"wpsl_city" => "ShipAddress_City",
"wpsl_state" => "ShipAddress_State",
"wpsl_zip" => "ShipAddress_PostalCode",
"wpsl_country" => "United States",
"wpsl_lat" => "", // Automatically queried from Google's API if left blank
"wpsl_lng" => "", // ^^^
"wpsl_phone" => "Phone",
"wpsl_fax" => "Fax",
"wpsl_email" => "Email",
"wpsl_url" => "",
],
];
// Get the data from all those CSVs!
$posts = function() {
$data = [];
$errors = [];
// Get array of CSV files (in data/ directory in root of WP install)
$files = glob(ABSPATH . "../data/*.csv");
foreach ( $files as $file ) {
// Attempt to change permissions if not readable
if ( ! is_readable($file) ) {
chmod($file, 0744);
}
// Check if file is writable, then open it in 'read only' mode
if ( is_readable($file) && $_file = fopen($file, "r") ) {
// To sum this part up, all it really does is go row by
// row, column by column, saving all the data
$post = [];
// Get first row in CSV, which is of course the headers
$header = fgetcsv($_file);
while ( $row = fgetcsv($_file) ) {
foreach ( $header as $i => $key ) {
$post[$key] = $row[$i] !== "NULL" ? $row[$i] : null;
}
$data[] = $post;
}
fclose($_file);
} else {
$errors[] = "File '$file' could not be opened. Check the file's permissions to make sure it's readable by your server.";
}
}
if ( ! empty($errors) ) {
// ... do stuff with the errors
}
return $data;
};
// Keep count so that we don't time out
$inserted = 0;
$insert_limit = 25;
// Look through all posts and create post in database
foreach ( $posts() as $post ) {
if ( $inserted > $insert_limit ) break;
// Populate all custom fields with content from post variable
$fields = [];
foreach ( $config["fields"] as $custom_field => $csv_column ) {
if ( is_array($csv_column) ) {
$columns = [];
foreach( $csv_column as $csv_col ) {
if ( is_null($post[$csv_col]) ) continue;
$columns[] = $post[$csv_col];
}
$fields[$custom_field] = implode(" ", $columns);
} else {
if ( array_key_exists($csv_column, $post) ) {
$fields[$custom_field] = $post[$csv_column] ?: "";
} else {
$fields[$custom_field] = $csv_column; // Default value if not in CSV
}
}
}
// If the post exists, skip this post and go to the next onne
if ( get_page_by_title($fields["post_title"], "OBJECT", $config["post_type"]) ) {
continue;
}
// Insert the post into the database
$fields["id"] = wp_insert_post([
"post_title" => $fields["post_title"],
"post_content" => "",
"post_type" => $config["post_type"],
"post_status" => "draft",
]);
// Update post's custom fields
foreach ( $fields as $field => $content ) {
update_field($field, $content, $fields["id"]);
}
// If the address is not null, publish the post (this also fires off a
// request to Google's map API to get lat/lng)
if ( $fields["wpsl_address"] && $fields["wpsl_city"] && $fields["wpsl_zip"] ) {
// Get lat/long
$wpsl_admin->geocode->check_geocode_data($fields["id"], [
"lat" => $fields["wpsl_lat"],
"lng" => $fields["wpsl_lng"],
"address" => $fields["wpsl_address2"],
"city" => $fields["wpsl_city"],
"zip" => $fields["wpsl_zip"],
"country" => $fields["wpsl_country"],
]);
wp_publish_post($fields["id"]);
}
$inserted++;
}
});
@mylesholman
Copy link

Hey mate, I've tried this a few ways but it just simply refreshes the admin screen and nothing seems to happen. Any idea?

@gpit2286
Copy link

@mylesholman I just put some time into digging into this a little bit more. The things I discovered are...

  • As the script reads, the csv files need to be in the ../data directory in relation to the base index script of wordpress.
  • There is a type in the script at line 37. It should read href='{$_SERVER["REQUEST_URI"]}?insert_store_locations'
  • There is an initial limit on the number of stores to include of 25 set at line 135. Not at the top.
  • This also requires the installation of the plug found here for the update_field() call
  • The last problem I ran into was that the check on line 183 requires an address, city, and zip. My stores I was importing only had a address and zip so I gracefully deleted the city check.

Check those things first.

@shivam0214
Copy link

shivam0214 commented Jan 17, 2018

Hey mate, I've tried this a few ways but it just simply refreshes the admin screen and nothing seems to happen. any updates?

@iamchetanp
Copy link

Not working..

@graffxdesign
Copy link

Oh, it is just in the table wp_store_locator very easy to import them now

@aarnoo92
Copy link

Hi, I have changed all the above lines. If I click on the button I get the message 'invalid posttype'.
How can I fix this?

@karamgaby
Copy link

I created this script to export the stores data into a csv file
https://gist.github.com/gk-git/bd64440e798a105c217894b461e5327e

@zeus1921
Copy link

zeus1921 commented Jul 7, 2021

This dosnt work for newest versions but i'v managed to import 500 stores with version 2.2.232 (download it here =) with this script this one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment