| Server IP : 104.129.129.72 / Your IP : 216.73.216.229 Web Server : LiteSpeed System : Linux 123answers 5.15.0-143-generic #153-Ubuntu SMP Fri Jun 13 19:10:45 UTC 2025 x86_64 User : answe8064 ( 1002) PHP Version : 8.2.28 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/123answers.ca/public_html/regina/wp-content/plugins/ccsu-google-scraper/ |
Upload File : |
<?php
/*
Plugin Name: Automated Lead Importer
Description: Automated Lead Importer
Author: Offline Sharks
Version: 2.97
*/
if (!defined('ABSPATH')) exit;
define('_GPI_PLUGIN_PATH', str_replace('\\', '/', trailingslashit(dirname(__FILE__))));
define('_GPI_PLUGIN_URL', str_replace('\\', '/', trailingslashit(plugins_url('', __FILE__))));
// define('_GPI_PLUGIN_AUTO_UPDATE_URL', 'http' . is_ssl() ? 's' : '' . '://www.offlinesharks.com/ccsu-google-scraper-update/ver');
// define('_GPI_PLUGIN_AUTO_UPDATE_FILE', 'http' . is_ssl() ? 's' : '' . '://www.offlinesharks.com/ccsu-google-scraper-update/ccsu-google-scraper.zip');
// define('_GPI_PLUGIN_AUTO_UPDATE_URL', 'http://www.offlinesharks.com/ccsu-google-scraper-update/ver');
// define('_GPI_PLUGIN_AUTO_UPDATE_FILE', 'http://www.offlinesharks.com/ccsu-google-scraper-update/ccsu-google-scraper.zip');
define('_GPI_PLUGIN_AUTO_UPDATE_URL', 'http://www.themepluginupdate.sharkdevserver.com/api/plugins/ccsu-google-scraper-update/ver');
define('_GPI_PLUGIN_AUTO_UPDATE_FILE', 'http://www.themepluginupdate.sharkdevserver.com/api/plugins/ccsu-google-scraper-update/ccsu-google-scraper.zip');
define('_GPI_PLUGIN_CURR_VER', 2.96);
class GooglePlacesImporter
{
# initialize plugin
public function __construct() {
add_action('add_meta_boxes', 'GooglePlacesImporter::add_meta_boxes');
add_action('save_post', 'GooglePlacesImporter::save_meta_boxes');
add_action('admin_menu', 'GooglePlacesImporter::admin_menu');
add_filter('custom_menu_order', 'GooglePlacesImporter::custom_menu_order', 99999);
add_filter('admin_head', 'GooglePlacesImporter::admin_head');
// if (is_admin()) {
// GooglePlacesImporter::maybe_check_for_updates();
// GooglePlacesImporter::maybe_install_counter_tbl();
// add_action('init', 'GooglePlacesImporter::maybe_check_for_updates');
// add_action('init', 'GooglePlacesImporter::maybe_install_counter_tbl');
// if (get_option('gpi_plugin_needs_update') == 1) {
// if (!function_exists('download_url')) {
// require_once(ABSPATH . 'wp-includes/pluggable.php');
// require_once(ABSPATH . 'wp-admin/includes/file.php');
// }
// WP_Filesystem();
// $dpfile = download_url(_GPI_PLUGIN_AUTO_UPDATE_FILE, $timeout = 300);
// if (!is_wp_error($dpfile)) {
// $newfile = ABSPATH . 'ccsu-google-scraper.zip';
// copy($dpfile, $newfile);
// unlink($dpfile);
// $to = ABSPATH . 'wp-content/plugins/';
// if (class_exists('ZipArchive', false)) {
// $result = _unzip_file_ziparchive($newfile, $to, $needed_dirs);
// } else {
// $result = _unzip_file_pclzip($newfile, $to, $needed_dirs);
// }
// delete_transient('gpi_plugin_auto_update_url_content');
// update_option('gpi_plugin_needs_update', 0);
// unlink($newfile);
// }
// }
// }
}
# maybe install counter tbl
public static function maybe_install_counter_tbl() {
global $wpdb;
$table_name = $wpdb->prefix . 'gapi_counter';
$charset_collate = $wpdb->get_charset_collate();
if ($wpdb->get_var("SHOW TABLES LIKE '{$table_name}'") != $table_name) {
$sql = "CREATE TABLE {$table_name} (
id mediumint(9) NOT NULL AUTO_INCREMENT,
date datetime DEFAULT '0000-00-00' NOT NULL,
counter INTEGER NOT NULL,
PRIMARY KEY (id)
) {$charset_collate};";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
}
# increment api counter
public static function increment_counter() {
global $wpdb;
$table_name = $wpdb->prefix . 'gapi_counter';
$now = date('Y-m-d 00:00:00');
$id = $wpdb->get_var("SELECT id FROM {$table_name} WHERE date = '{$now}'");
if ($id == null) {
$wpdb->query("INSERT INTO {$table_name} (`id`, `date`, `counter`) VALUES (NULL, '{$now}', '1');");
} else {
$wpdb->query("UPDATE {$table_name} SET counter = counter + 1 WHERE id = {$id}");
}
}
# get api counter
public static function get_counter($date) {
global $wpdb;
$table_name = $wpdb->prefix . 'gapi_counter';
$v = $wpdb->get_var("SELECT counter FROM {$table_name} WHERE date = '{$date}'");
return empty($v) ? 0 : $v;
}
# maybe check for updates
public static function maybe_check_for_updates() {
$gpi_plugin_auto_update_url_content = get_transient('gpi_plugin_auto_update_url_content');
if (empty($gpi_plugin_auto_update_url_content)) {
$get = wp_remote_get(_GPI_PLUGIN_AUTO_UPDATE_URL);
if (!is_wp_error($get) && is_array($get)) {
set_transient('gpi_plugin_auto_update_url_content', $get['body'], DAY_IN_SECONDS / 4);
$gpi_plugin_auto_update_url_content = $get['body'];
}
}
if ((float) $gpi_plugin_auto_update_url_content > (float) _GPI_PLUGIN_CURR_VER) {
update_option('gpi_plugin_needs_update', 1);
}
}
# get plugin option
public static function get_plugin_option($o) {
$gpi_plugin_global_settings = get_option('gpi_plugin_global_settings');
$gpi_plugin_global_settings = $gpi_plugin_global_settings === false ? array() : $gpi_plugin_global_settings;
return isset($gpi_plugin_global_settings[ $o ]) ? $gpi_plugin_global_settings[ $o ] : null;
}
# get places
public static function get_places($attrs) {
if (!class_exists('GooglePlaces')) require_once('google-places-api/GooglePlaces.php');
if (!class_exists('GooglePlacesClient')) require_once('google-places-api/GooglePlacesClient.php');
$attrs['radius'] = 50000;
$attrs['rpp'] = 60;
$attrs['keyword'] = str_replace(' ', '+', $attrs['keyword']);
$google_places = new joshtronic\GooglePlaces( GooglePlacesImporter::get_plugin_option('api_key') );
$current_overall_results = 0;
$get_another_page = false;
$r = array();
$google_places->location = array($attrs['lat'], $attrs['lng']);
if ($attrs['rank_by'] == 'distance') {
$google_places->rankby = 'distance';
$google_places->types = 'point_of_interest';
} else {
$google_places->rankby = 'prominence';
$google_places->radius = $attrs['radius'];
}
$google_places->keyword = $attrs['keyword']; # keyword, name or types
if (isset($attrs['npt']) && !empty($attrs['npt'])) $google_places->pagetoken = $attrs['npt'];
$results = $google_places->nearbySearch();
$current_overall_results = $current_overall_results + 20;
$r[] = $results;
if ($results['status'] != 'OK' && $results['status'] != 'ZERO_RESULTS') {
echo '<script>alert("' . esc_attr($results['error_message']) . '");</script>';
return array();
} else {
GooglePlacesImporter::increment_counter();
for ($current_overall_results; $current_overall_results < $attrs['rpp']; $current_overall_results = $current_overall_results + 20) {
$last_result = end($r);
if (isset($last_result['next_page_token']) && !empty($last_result['next_page_token'])) {
$google_places->pagetoken = $last_result['next_page_token'];
$r[] = $google_places->nearbySearch();
GooglePlacesImporter::increment_counter();
}
}
$out = array();
$out['results'] = array();
foreach ($r as $_r) {
foreach ($_r['results'] as $__r) {
$out['results'][] = $__r;
}
$out['next_page_token'] = $_r['next_page_token'];
}
return $out;
}
}
# custom menu order
static function custom_menu_order($menu_order) {
global $submenu;
$submenu['edit.php?post_type=listings'][] = $submenu['ccsu-google-scraper/admin-settings-page.php'][2];
unset($submenu['ccsu-google-scraper/admin-settings-page.php'][2]);
$submenu['ccsu-google-scraper/admin-settings-page.php'][0][0] = $submenu['ccsu-google-scraper/admin-settings-page.php'][0][3] = 'Settings';
}
# get google places types
public static function get_types() {
return array(
'*',
'accounting',
'airport',
'amusement_park',
'aquarium',
'art_gallery',
'atm',
'bakery',
'bank',
'bar',
'beauty_salon',
'bicycle_store',
'book_store',
'bowling_alley',
'bus_station',
'cafe',
'campground',
'car_dealer',
'car_rental',
'car_repair',
'car_wash',
'casino',
'cemetery',
'church',
'city_hall',
'clothing_store',
'convenience_store',
'courthouse',
'dentist',
'department_store',
'doctor',
'electrician',
'electronics_store',
'embassy',
'fire_station',
'florist',
'funeral_home',
'furniture_store',
'gas_station',
'gym',
'hair_care',
'hardware_store',
'hindu_temple',
'home_goods_store',
'hospital',
'insurance_agency',
'jewelry_store',
'laundry',
'lawyer',
'library',
'liquor_store',
'local_government_office',
'locksmith',
'lodging',
'meal_delivery',
'meal_takeaway',
'mosque',
'movie_rental',
'movie_theater',
'moving_company',
'museum',
'night_club',
'painter',
'park',
'parking',
'pet_store',
'pharmacy',
'physiotherapist',
'plumber',
'police',
'post_office',
'real_estate_agency',
'restaurant',
'roofing_contractor',
'rv_park',
'school',
'shoe_store',
'shopping_mall',
'spa',
'stadium',
'storage',
'store',
'subway_station',
'supermarket',
'synagogue',
'taxi_stand',
'train_station',
'transit_station',
'travel_agency',
'veterinary_care',
'zoo',
);
}
# parse to readable string
public static function to_readable_str($str) {
$str = str_replace('_', ' ', $str);
$str = ucwords($str);
return $str;
}
# render google place admin row
public static function render_google_place_admin_row($listing) {
global $wpdb;
$post_id = $wpdb->get_var("SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = 'place_id' AND meta_value = '{$listing['place_id']}' LIMIT 1");
$post_exists_in_wp = !empty($post_id) && is_numeric($post_id) && $post_id > 0;
if ($post_exists_in_wp) {
$post_status = get_post_status($post_id);
$post_exists_in_wp = $post_status == 'publish';
}
?>
<tr id="post-<?php echo($listing['place_id']) ?>" class="iedit category-self level-0 post-<?php echo($listing['place_id']) ?> type-page status-publish hentry <?php echo($post_exists_in_wp ? 'existsInWP' : '') ?>" data-place_id="<?php echo($listing['place_id']) ?>" data-reference="<?php echo($listing['reference']) ?>">
<th scope="row" class="check-column">
<label class="screen-reader-text" for="cb-select-<?php echo($listing['place_id']) ?>">Select</label>
<input id="cb-select-<?php echo($listing['place_id']) ?>" type="checkbox" name="post[]" value="<?php echo($listing['place_id']) ?>">
<!--
<div class="locked-indicator">
<span class="locked-indicator-icon" aria-hidden="true"></span>
<span class="screen-reader-text">Locked</span>
</div>
-->
</th>
<td class="title column-title has-row-actions column-primary page-title" data-colname="Title">
<strong><?php echo($listing['name']) ?></strong>
<div class="row-actions">
<span class="importa"><a href="#" class="import">Import</a><!-- | --></span>
<span class="updatea"><a href="#" class="update">Update</a><!-- | --></span>
</td>
<td class="date column-address" data-colname="Address"><?php echo(ucwords($listing['vicinity'])) ?></td>
<td class="category column-category" data-colname="Category">
<?php
$out = '';
foreach ($listing['types'] as $t) {
if (!empty($out)) $out .= ', ';
$out .= $t;
}
$out = GooglePlacesImporter::to_readable_str($out);
echo($out);
?>
</td>
<!--
<td class="date column-phoneno" data-colname="Phone No"><?php echo(ucwords($listing['international_phone_number'])) ?></td>
<td class="date column-website" data-colname="Website"><a href="<?php echo($listing['website']) ?>"><?php echo($listing['website']) ?></a></td>
-->
</tr>
<?php
}
# add menu link
public static function admin_menu() {
add_menu_page(
'Automated Lead Importer',
'Automated Lead Importer',
'manage_options',
_GPI_PLUGIN_PATH . 'admin-settings-page.php',
'',
'dashicons-admin-site',
14119210.1212
);
add_submenu_page(_GPI_PLUGIN_PATH . 'admin-settings-page.php', 'Find & Import', 'Find & Import', 'manage_options', _GPI_PLUGIN_PATH . 'admin-import-page.php');
add_submenu_page(_GPI_PLUGIN_PATH . 'admin-settings-page.php', 'CSV Export', 'CSV Export', 'manage_options', _GPI_PLUGIN_PATH . 'gpi-csv-export.php');
add_submenu_page(_GPI_PLUGIN_PATH . 'admin-settings-page.php', 'Terms of Service', 'Terms of Service', 'manage_options', 'https://offlinesharks.com/software-terms-of-service/');
}
# add admin settings page
public static function admin_settings_page() {
wp_enqueue_media();
$admin_settings_page = array(
'General' => array(
array(
'name' => 'API Key (main / back-end)',
'key' => 'api_key',
'desc' => 'If a single unrestricted key is used, this key will be used for all (front-end / back-end) requests. If you\'re using mutliple (restricted) keys, this key will be used for back-end requests only.',
'type' => PostMetaManagerField2Type2::Textbox,
),
array(
'name' => 'API Key (optional / front-end)',
'key' => 'api_key_front_end',
'type' => PostMetaManagerField2Type2::Textbox,
),
array(
'name' => 'Import',
'key' => 'import_listings_to_custom_categories',
'type' => PostMetaManagerField2Type2::Checkbox,
'custom_vars' => array(
'label' => 'Import listings to custom categories'
)
),
)
);
if (isset($_POST['save_plugin_global_settings']) && $_POST['save_plugin_global_settings'] == 1) {
update_option('gpi_plugin_global_settings', $_POST['gpi_plugin_global_settings']);
?>
<div id="setting-error-settings_updated" class="updated settings-error notice is-dismissible">
<p><strong>Settings updated.</strong></p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button></div>
<?php
}
$gpi_plugin_global_settings = get_option('gpi_plugin_global_settings');
$gpi_plugin_global_settings = $gpi_plugin_global_settings === false ? array() : $gpi_plugin_global_settings;
$pmm = new PostMetaManager2('gpi_plugin_global_settings', $gpi_plugin_global_settings);
?><div class="wrap"><?php
?><div id="icon-options-general" class="icon32"><br></div><?php
?><form method="POST"><?php
?><h1>Automated Lead Importer - Settings</h1><?php
?><br /><?php
?>
<ol class="ccsuList">
<li>Enable "Maps JavaScript API" (<a href="https://console.developers.google.com/apis/dashboard">https://console.developers.google.com/apis/dashboard</a>)</li>
<li>Enable "Places API" (<a href="https://console.developers.google.com/apis/dashboard">https://console.developers.google.com/apis/dashboard</a>)</li>
<li>Enable "Google Maps Geocoding API" (<a href="https://console.developers.google.com/apis/dashboard">https://console.developers.google.com/apis/dashboard</a>)</li>
<li>Enable "API Billing" (<a href="https://console.developers.google.com/apis/dashboard">https://console.developers.google.com/apis/dashboard</a>)<br /><small>Note: Each listing uses 3 requests per call, if you were to add 1000 listings to your site - that would be around ~$17)</small></li>
<li>Generate API key (<a href="https://support.google.com/googleapi/answer/6158862">https://support.google.com/googleapi/answer/6158862</a>)</li>
<ul>
<li>If you don't put any restrictions on the API key, <strong>this is enough - <u>skip to step #6</u></strong></li>
<li>However - if you want to restrict the API key, you'll then need separate keys for the front-end requests vs. back-end requests</li>
<li>Repeat step 5 and generate anoter key (again, you need to do this <strong>only if you want to restrict them</strong>)</li>
<li>Restrict your first key (<strong>API Key (main / back-end)</strong>) via IP address restriction (enter your server IP, save the IP, save the changes on this page) - <a href="<?php echo(_GPI_PLUGIN_URL) ?>images/back-end-key-restriction.png" target="_blank" rel="noreferrer noopener">image</a></li>
<li>Restrict your second key (<strong>API Key (optional / front-end)</strong>) via HTTP referrer restriction (enter your domain name followed by a <strong>/*</strong> (eg. <strong>domain.com/*</strong>), save the domain, save the changes on this page) - <a href="<?php echo(_GPI_PLUGIN_URL) ?>images/front-end-key-restriction.png" target="_blank" rel="noreferrer noopener">image</a></li>
</ul>
<li>Paste the API key(s) below & save</li>
<li>Start importing</li>
</ol>
<style type="text/css">
.ccsuList ul { margin-left: 20px; }
.firstChild { width: 20% !important; }
</style>
<?php
?><br /><?php
?><div class="PMMRootWrp"><?php
$pmm->output($admin_settings_page, false);
?></div><?php
?><div class="clear"></div><?php
?><p class="submit">
<input type="submit" class="button button-primary" value="Save" />
</p><?php
?><p><a href="https://offlinesharks.com/software-terms-of-service/" style="float: right;">Terms Of Service</a></p><?php
?><input type="hidden" name="save_plugin_global_settings" value="1" /><?php
?></form><?php
}
# add admin import page
public static function admin_import_page() {
wp_enqueue_media();
$_types = GooglePlacesImporter::get_types();
$types = array();
foreach ($_types as $_t) {
$types[ GooglePlacesImporter::to_readable_str($_t) ] = $_t;
}
$radius = array();
for ($i = 1000; $i <= 25000; $i = $i + 1000) {
$radius[ $i ] = $i;
}
$admin_import_page = array(
'General' => array(
array(
'name' => 'Keyword',
'key' => 'keyword',
'type' => PostMetaManagerField2Type2::Textbox,
),
array(
'name' => 'Address',
'key' => 'address',
'type' => PostMetaManagerField2Type2::GMapAddress,
),
array(
'name' => 'Rank by',
'key' => 'rank_by',
'desc' => '<ul><li><strong>prominence</strong> - This option sorts results based on their importance. Ranking will favor prominent places within the specified area. Prominence can be affected by a place\'s ranking in Google\'s index, global popularity, and other factors.</li><li><strong>distance</strong> - This option biases search results in ascending order by their distance from the specified location. When distance is specified, one or more of keyword, name, or type is required.</li></ul>',
'type' => PostMetaManagerField2Type2::DropDown,
'custom_vars' => array(
'items' => array('prominence' => 'prominence', 'distance' => 'distance')
)
),
// array(
// 'name' => 'Radius',
// 'key' => 'radius',
// 'desc' => '(in meters)',
// 'type' => PostMetaManagerField2Type2::DropDown,
// 'custom_vars' => array(
// 'items' => $radius
// )
// ),
// array(
// 'name' => 'Type',
// 'key' => 'type',
// 'type' => PostMetaManagerField2Type2::DropDown,
// 'custom_vars' => array(
// 'items' => $types
// )
// ),
// array(
// 'name' => 'Results Per Page',
// 'key' => 'results_per_page',
// 'desc' => '(more results per page = decreased API performance)',
// 'type' => PostMetaManagerField2Type2::DropDown,
// 'custom_vars' => array(
// 'items' => array('20' => '20', '40' => '40', '60' => '60')
// )
// ),
array(
'type' => PostMetaManagerField2Type2::Delimiter,
),
array(
'name' => '',
'key' => 'button_search',
'type' => PostMetaManagerField2Type2::Button,
'custom_vars' => array(
'label' => 'Search'
)
),
array(
'type' => PostMetaManagerField2Type2::Delimiter,
),
)
);
$gpi_plugin_global_settings = get_option('gpi_plugin_global_settings');
$gpi_plugin_global_settings = $gpi_plugin_global_settings === false ? array() : $gpi_plugin_global_settings;
$pmm = new PostMetaManager2('gpi_plugin_global_settings', $gpi_plugin_global_settings);
if(isset($gpi_plugin_global_settings['import_listings_to_custom_categories'])){
$import_listings_to_custom_categories = $gpi_plugin_global_settings['import_listings_to_custom_categories'] == 'pmmf_checked';
}else{
$import_listings_to_custom_categories = false;
}
// $cats = get_terms('category', array('hide_empty' => false));
$cats = get_terms('listing-categories', array('hide_empty' => false));
?><div class="wrap"><?php
?><div id="icon-options-general" class="icon32"><br></div><?php
?><form method="POST"><?php
?><h1>Automated Lead Importer - Import</h1><?php
?><br /><?php
?><div class="PMMRootWrp"><?php
$pmm->output($admin_import_page, false);
?></div><?php
?>
<div class="apiCallsToday">API calls today: <span><?php echo(GooglePlacesImporter::get_counter(date('Y-m-d'))) ?></span></div>
<div class="PMMRoot2Wrp">
<table class="PMMRoot2" style="border-collapse: collapse; width: 80%; margin: 0 auto;">
<tr>
<td style="width: 10%; text-align: right; padding-right: 10px" class="firstChild">
</td>
<td class="secondChild">
<input type="button" name="gpi_plugin_global_settings[button_new_search]" id="gpi_plugin_global_settings[button_new_search]" value="New Search" class="button button-primary" />
</td>
</tr>
<tr>
<td colspan="2" class="delimiter">
<br />
<hr />
<br />
</td>
</tr>
</table>
</div>
<?php
?><div class="clear"></div><?php
?></form><?php
?>
<div class="results">
<table class="wp-list-table widefat fixed striped pages">
<thead>
<tr>
<td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text" for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
<th scope="col" id="title" class="manage-column column-title column-primary">Title</th>
<th scope="col" id="address" class="manage-column column-address">Address</th>
<th scope="col" id="category" class="manage-column column-category">Category</th>
<!--
<th scope="col" id="phoneno" class="manage-column column-phoneno">Phone No</th>
<th scope="col" id="website" class="manage-column column-website">Website</th>
-->
</tr>
</thead>
<tbody id="the-list">
</tbody>
<tfoot>
<tr>
<td class="manage-column column-cb check-column"><label class="screen-reader-text" for="cb-select-all-2">Select All</label><input id="cb-select-all-2" type="checkbox"></td>
<th scope="col" class="manage-column column-title column-primary ">Title</th>
<th scope="col" class="manage-column column-address">Address</th>
<th scope="col" class="manage-column column-category">Category</th>
<!--
<th scope="col" class="manage-column column-phoneno">Phone No</th>
<th scope="col" class="manage-column column-website">Website</th>
-->
</tr>
</tfoot>
</table>
<div class="tablenav bottom">
<div class="alignleft actions bulkactions">
<label for="bulk-action-selector-bottom" class="screen-reader-text">Select bulk action</label>
<select name="action2" id="bulk-action-selector-bottom">
<option value="-1">Bulk Actions</option>
<option value="import">Import / Update</option>
</select>
<input type="submit" id="doaction2" class="button action" value="Apply">
</div>
<div class="alignleft actions">
</div>
<div class="tablenav-pages">
<a class="prev-page" href="#"><span class="screen-reader-text">Prev page</span><span aria-hidden="true">‹</span></a>
<a class="next-page" href="#"><span class="screen-reader-text">Next page</span><span aria-hidden="true">›</span></a>
</div>
<br class="clear">
</div>
</div>
<?php
?></div><?php
?>
<div class="loader">
<div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div>
</div>
<div class="catPopup">
<div class="catWrp">
<h2>Import listing(s) to existing cats:</h2>
<select multiple="multiple" name="cats[]" class="nongpl">
</select>
<h2>Import listing(s) to predefined GPlaces cats:</h2>
<select multiple="multiple" name="gpl_cats[]" class="gpl">
</select>
<h2>Insert custom cat:</h2>
<input type="text" name="ccat" class="ccat" />
<input type="button" name="insert_custom_cat" id="insert_custom_cat" value="Insert" class="button button-primary" />
<br /><br /><hr />
<i>CTRL or CMD (⌘) + mouse click to select multiple</i>
<input type="button" name="insert_with_custom_cats" id="insert_with_custom_cats" value="Import" class="button button-primary" />
<input type="button" name="cancel_with_custom_cats" id="cancel_with_custom_cats" value="Cancel" class="button button-primary" />
</div>
</div>
<style type="text/css">
.catPopup,
.loader{position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;background:rgba(0,0,0,.25)}
.lds-ellipsis{display:inline-block;width:64px;height:64px;position:absolute;top:50%;left:50%;margin:-32px 0 0 -32px}
.lds-ellipsis div{position:absolute;top:27px;width:11px;height:11px;border-radius:50%;background:#fff;animation-timing-function:cubic-bezier(0,1,1,0)}
.lds-ellipsis div:nth-child(1){left:6px;animation:lds-ellipsis1 .6s infinite}
.lds-ellipsis div:nth-child(2){left:6px;animation:lds-ellipsis2 .6s infinite}
.lds-ellipsis div:nth-child(3){left:26px;animation:lds-ellipsis2 .6s infinite}
.lds-ellipsis div:nth-child(4){left:45px;animation:lds-ellipsis3 .6s infinite}
@keyframes lds-ellipsis1{0%{transform:scale(0)}100%{transform:scale(1)}}
@keyframes lds-ellipsis3{0%{transform:scale(1)}100%{transform:scale(0)}}
@keyframes lds-ellipsis2{0%{transform:translate(0,0)}100%{transform:translate(19px,0)}}
.catPopup,
.PMMRoot2Wrp,
.loader,
.results { display: none; }
.row-actions .update,
.existsInWP .row-actions .import { display: none; }
.existsInWP .row-actions .update { display: inline; }
.existsInWP td > strong:after { content: " (imported)"; color: #999; }
.PMMRoot2 .src.kw { margin-top: 30px; }
.PMMRoot2 .src { margin: 10px 0; font-size: 16px; font-weight: 600; }
.apiCallsToday { position: fixed; top: 40px; right: 10px; border: 1px solid #000; padding: 5px; background-color: #eee; }
.catPopup .catWrp { background: #f1f1f1; border: 1px solid #aaa; box-shadow: inset 0 1px 2px rgba(0,0,0,.07); width: 400px; height: 520px; position: absolute; top: 50%; left: 50%; margin: -260px 0 0 -200px; box-sizing: border-box; padding: 10px 20px; }
.catPopup .catWrp h2 { margin: 0 0 10px 0; }
.catPopup .catWrp select { width: 100%; height: 200px; margin-bottom: 15px; }
.catPopup .catWrp select.gpl { height: 100px; }
.catPopup .catWrp input[type=button] { float: right; margin-left: 10px; }
.catPopup .catWrp .ccat { float: left; width: 80%; }
.catPopup .catWrp i { float: left; font-size: 10px; margin-top: 5px; }
</style>
<?php
?>
<script type="text/javascript">
GPI_LOADING = false;
NEXT_PAGE_TOKEN = null;
CURRENT_TOKENS = [];
CURRENT_PG = 1;
CATS = <?php echo(json_encode($cats)) ?>;
if (typeof(CATS.errors) === "object") CATS = [];
ILTCC = <?php echo($import_listings_to_custom_categories ? 'true' : 'false') ?>;
ILTCC_DATA = null;
$ = jQuery;
function serializePlace ($place)
{
return { place_id: $place.attr("data-place_id"), reference: $place.attr("data-reference") };
};
function setCatPopupCats (preselect)
{
var $select = $(".catPopup .nongpl");
$select.find("*").remove();
for (c in CATS)
{
var cat = CATS[c],
p = preselect == cat.name ? "selected='selected'" : "";
$select.append("<option value='" + cat.term_id + "' " + p + ">" + cat.name + "</option>");
}
/* ... */
$select = $(".catPopup .gpl");
$select.find("*").remove();
var gplCatsFinal = [];
for (d in ILTCC_DATA)
{
var data = ILTCC_DATA[d],
gplCats = $(".iedit[data-place_id=" + data.place_id + "] [data-colname=Category]").text();
gplCats = gplCats.split(",");
for (g in gplCats)
{
var c = gplCats[g];
c = $.trim(c);
if (!$.isInArray(c, gplCatsFinal))
{
gplCatsFinal.push(c);
}
}
}
for (gplc in gplCatsFinal)
{
var cat = gplCatsFinal[gplc];
$select.append("<option value=''>" + cat + "</option>");
}
};
jQuery(function ($)
{
$.isInArray = function(item, array) { return !!~$.inArray(item, array); };
var click_cnt = 0;
$("#gpi_plugin_global_settings\\[button_search\\]").on("click", function (e, custom)
{
e.preventDefault();
if (GPI_LOADING) return;
GPI_LOADING = true;
var $this = $(this),
$keyword = $("#gpi_plugin_global_settings\\[keyword\\]"),
$address = $("#gpi_plugin_global_settings\\[address\\]"),
$rank_by = $("#gpi_plugin_global_settings\\[rank_by\\]"),
$lat = $("#gpi_plugin_global_settings\\[address\\]_lat"),
$lng = $("#gpi_plugin_global_settings\\[address\\]_lng"),
$radius = $("#gpi_plugin_global_settings\\[radius\\]"),
$type = $("#gpi_plugin_global_settings\\[type\\]"),
$rpp = $("#gpi_plugin_global_settings\\[results_per_page\\]"),
$theList = $("#the-list");
if (!!!$address.val().length)
{
alert("Address field can't be empty!");
GPI_LOADING = false;
return;
}
$(".loader").fadeIn("fast");
if (!!!$lat.val().length || !!!$lng.val().length)
{
geocoder = new google.maps.Geocoder();
var address = $address.val();
geocoder.geocode( { "address" : address }, function (results, status)
{
if (results != null)
{
var l = gmapsFixLocation(results[0].geometry);
$lat.val(l.lat);
$lng.val(l.lng);
/*
if (typeof(results[0].geometry.location.lat) === "function")
{
$lat.val(results[0].geometry.location.lat());
$lng.val(results[0].geometry.location.lng());
}
*/
/*
if (typeof(results[0].geometry.viewport.f) === "undefined")
{
$lat.val(results[0].geometry.viewport.la.j);
$lng.val(results[0].geometry.viewport.ea.j);
}
else if (typeof(results[0].geometry.viewport.ea) === "undefined")
{
$lat.val(results[0].geometry.viewport.l.j);
$lng.val(results[0].geometry.viewport.j.j);
}
else
{
$lat.val(results[0].geometry.viewport.f.b);
$lng.val(results[0].geometry.viewport.b.f);
}
*/
}
console.log("click_cnt",click_cnt);
if(click_cnt < 15){
GPI_LOADING = false;
$("#gpi_plugin_global_settings\\[button_search\\]").trigger("click");
click_cnt++;
}
});
return;
}
if (typeof(custom) == "undefined")
{
CURRENT_PG = 1;
}
else
{
if (custom == "next") CURRENT_PG++;
if (custom == "prev") CURRENT_PG--;
}
$.post(
"<?php echo(trailingslashit(get_site_url())) ?>?gpi=1",
{ keyword: $keyword.val(), address: $address.val(), rank_by: $rank_by.val(), lat: $lat.val(), lng: $lng.val(), radius: $radius.val(), type: $type.val(), rpp: $rpp.val(), npt: NEXT_PAGE_TOKEN },
function (resp)
{
$(".PMMRoot2Wrp").slideDown("slow");
$(".PMMRootWrp").slideUp("slow", function ()
{
$(".loader").fadeOut("fast", function ()
{
GPI_LOADING = false;
});
});
if (resp == null || !!!resp.length) {
/* ... */
} else {
NEXT_PAGE_TOKEN = null;
$theList.find(" > *").remove();
$(".PMMRoot2 .secondChild").find(".src, #import_selected").remove();
$theList.append(resp);
$(".results").slideDown("slow");
if (NEXT_PAGE_TOKEN == null)
{
$(".next-page").hide(0);
}
else
{
$(".next-page").show(0);
}
if (CURRENT_PG <= 1)
{
$(".prev-page").hide(0);
}
else
{
$(".prev-page").show(0);
}
$(".PMMRoot2 .secondChild").append("<input type='button' name='import_selected' id='import_selected' value='Import Selected Items' class='button button-primary' />");
$(".PMMRoot2 .secondChild").append("<div class='src kw'>Keyword: " + $keyword.val() + "</div>");
$(".PMMRoot2 .secondChild").append("<div class='src addr'>Location: " + $address.val() + "</div>");
$(".PMMRoot2 .secondChild").append("<div class='src rank'>Rank By: " + $rank_by.val() + "</div>");
}
}
);
});
$("#gpi_plugin_global_settings\\[button_new_search\\]").on("click", function (e)
{
e.preventDefault();
if (GPI_LOADING) return;
GPI_LOADING = true;
$(".loader").fadeIn("fast");
$(".PMMRootWrp").slideDown("slow");
$(".results").slideUp("slow");
NEXT_PAGE_TOKEN = null;
CURRENT_TOKENS = [];
$("#gpi_plugin_global_settings\\[keyword\\]").val("");
$("#gpi_plugin_global_settings\\[address\\]").val("");
$("#gpi_plugin_global_settings\\[rank_by\\]").val("prominence");
$("#gpi_plugin_global_settings\\[address\\]_lat").val("");
$("#gpi_plugin_global_settings\\[address\\]_lng").val("");
$("#gpi_plugin_global_settings\\[radius\\]").val(1000);
/* $type = $("#gpi_plugin_global_settings\\[type\\]").val(""); */
$("#gpi_plugin_global_settings\\[results_per_page\\]").val(20);
$(".PMMRoot2Wrp").slideUp("slow", function ()
{
$(".loader").fadeOut("fast", function ()
{
GPI_LOADING = false;
});
});
});
$(".next-page").on("click", function (e)
{
e.preventDefault();
if (NEXT_PAGE_TOKEN == null)
{
/* ALERT ERROR */
}
else
{
$("#gpi_plugin_global_settings\\[button_search\\]").trigger("click", ["next"]);
}
});
$(".prev-page").on("click", function (e)
{
e.preventDefault();
if (CURRENT_TOKENS.length > 1)
{
var newCurrPg = CURRENT_PG - 3;
if (newCurrPg >= 0) NEXT_PAGE_TOKEN = CURRENT_TOKENS[ newCurrPg ];
else NEXT_PAGE_TOKEN = null;
}
else
{
NEXT_PAGE_TOKEN = null;
}
if (NEXT_PAGE_TOKEN == null)
{
$("#gpi_plugin_global_settings\\[button_search\\]").trigger("click");
}
else
{
$("#gpi_plugin_global_settings\\[button_search\\]").trigger("click", ["prev"]);
}
});
$(document).on("click", "#import_selected", function (e)
{
e.preventDefault();
var data = [];
$("#the-list input[type=checkbox]:checked").each(function ()
{
data.push( serializePlace( $(this).parents(".hentry").first() ) );
});
if (data.length == 0)
{
alert("Please tick the checkboxes next to the items you want to import.");
return;
}
if (ILTCC)
{
ILTCC_DATA = data;
setCatPopupCats();
$(".catPopup").fadeIn("fast");
return;
}
$(".loader").fadeIn("fast");
if (GPI_LOADING) return;
GPI_LOADING = true;
$.post(
"<?php echo(trailingslashit(get_site_url())) ?>?gpi-import=1",
{ data: data },
function (resp)
{
for (d in data) $(".hentry[data-place_id=" + data[d].place_id + "]").addClass("existsInWP");
$("#the-list input[type=checkbox]:checked").removeAttr("checked");
$(".apiCallsToday span").text(resp);
$(".loader").fadeOut("fast");
GPI_LOADING = false;
}
);
});
$(document).on("click", "#the-list .import, #the-list .update", function (e)
{
e.preventDefault();
var $this = $(this),
$place = $this.parents(".hentry").first(),
data = [ serializePlace($place) ];
if (ILTCC)
{
ILTCC_DATA = data;
setCatPopupCats();
$(".catPopup").fadeIn("fast");
return;
}
$(".loader").fadeIn("fast");
$.post(
"<?php echo(trailingslashit(get_site_url())) ?>?gpi-import=1",
{ data: data },
function (resp)
{
for (d in data) $(".hentry[data-place_id=" + data[d].place_id + "]").addClass("existsInWP");
$("#the-list input[type=checkbox]:checked").removeAttr("checked");
$(".apiCallsToday span").text(resp);
$(".loader").fadeOut("fast");
}
);
});
$("#doaction2").off("click");
$("#doaction2").on("click", function (e)
{
e.preventDefault();
var action = $("[name=action2]").val();
if (action == "import")
{
var data = [];
$("#the-list input[type=checkbox]:checked").each(function ()
{
data.push( serializePlace( $(this).parents(".hentry").first() ) );
});
if (data.length == 0)
{
alert("Please tick the checkboxes next to the items you want to import.");
return;
}
if (ILTCC)
{
ILTCC_DATA = data;
setCatPopupCats();
$(".catPopup").fadeIn("fast");
return;
}
$(".loader").fadeIn("fast");
if (GPI_LOADING) return;
GPI_LOADING = true;
$.post(
"<?php echo(trailingslashit(get_site_url())) ?>?gpi-import=1",
{ data: data },
function (resp)
{
for (d in data) $(".hentry[data-place_id=" + data[d].place_id + "]").addClass("existsInWP");
$("#the-list input[type=checkbox]:checked").removeAttr("checked");
$(".apiCallsToday span").text(resp);
$(".loader").fadeOut("fast");
GPI_LOADING = false;
}
);
}
});
$(".catPopup #cancel_with_custom_cats").on("click", function (e)
{
e.preventDefault();
$(".catPopup").fadeOut("fast");
});
$(".catPopup #insert_with_custom_cats").on("click", function (e)
{
e.preventDefault();
var data = ILTCC_DATA,
cc = [];
$(".catPopup").fadeOut("fast");
$(".loader").fadeIn("fast");
$(".catPopup select :selected").each(function ()
{
cc.push( $(this).text() );
});
if (GPI_LOADING) return;
GPI_LOADING = true;
$.post(
"<?php echo(trailingslashit(get_site_url())) ?>?gpi-import=1",
{ data: data, insert_to_custom_cats: 1, custom_cats: cc },
function (resp)
{
for (d in data) $(".hentry[data-place_id=" + data[d].place_id + "]").addClass("existsInWP");
$("#the-list input[type=checkbox]:checked").removeAttr("checked");
$(".apiCallsToday span").text(resp);
$(".loader").fadeOut("fast");
GPI_LOADING = false;
ILTCC_DATA = null;
}
);
});
$(".catPopup #insert_custom_cat").on("click", function (e)
{
e.preventDefault();
var $ccat = $(".ccat"),
catName = $ccat.val();
if (!!!catName.length) alert("Category field can't be empty!");
CATS.push({ term_id: -1, name: catName });
$ccat.val("");
setCatPopupCats(catName);
});
});
</script>
<?php
}
public static function import() {
global $wpdb;
$page_ids = get_all_page_ids();
global $pricing_page, $choices_array1;
$choices_array1 = array();
$ex_optin = array('draft');
foreach($page_ids as $page){
$pricing_page = get_the_title($page);
if(get_page_template_slug($page) == "pricing.php"){
$premium_field = array();
$pricing_page = $page ;
if(!empty(get_post_meta($page, 'pricing',true))):
$my_field = array();
$pricing_tbl_cnt = get_post_meta($page,'pricing',true);
if(!empty($pricing_tbl_cnt)):
for ($i=0; $i < $pricing_tbl_cnt; $i++) {
$title_slug = 'pricing_'.$i.'_title';
$price_title = get_post_meta($page,$title_slug,true);
$a = strtolower($price_title);
$choices_array1[] = sanitize_title($a);
array_push($ex_optin,$a);
}
endif;
endif;
}
}
if(empty($choices_array1)){
array_push($choices_array1,'free','premium');
}
if (!class_exists('GooglePlaces')) require_once('google-places-api/GooglePlaces.php');
if (!class_exists('GooglePlacesClient')) require_once('google-places-api/GooglePlacesClient.php');
$api_key = GooglePlacesImporter::get_plugin_option('api_key');
$google_places = new joshtronic\GooglePlaces($api_key);
remove_action('save_post', 'set_featured_image_from_fa');
if (isset($_POST['data']) && !empty($_POST['data']) && is_array($_POST['data'])) {
$insert_to_custom_cats = isset($_POST['insert_to_custom_cats']);
$custom_cats = $insert_to_custom_cats ? $_POST['custom_cats'] : array();
/*$attachment_id = $wpdb->get_var("SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = '_gpi_placeholder_image' AND meta_value = '1' LIMIT 1");
if (empty($attachment_id)) {
$image_path = _GPI_PLUGIN_PATH . 'images/Listing-Placeholder.png';
$filetype = wp_check_filetype(basename($image_path), null);
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename($image_path),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename($image_path) ),
'post_content' => '',
'post_status' => 'inherit'
);
$dest_file = $wp_upload_dir['path'] . '/' . basename($image_path);
copy($image_path, $dest_file);
$attachment_id = wp_insert_attachment($attachment, $dest_file);
if (!function_exists('wp_generate_attachment_metadata')) require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata($attachment_id, $dest_file);
wp_update_attachment_metadata($attachment_id, $attach_data);
update_post_meta($attachment_id, '_gpi_placeholder_image', 1);
}*/
foreach ($_POST['data'] as $data) {
$google_places->reference = $data['reference'];
$details = $google_places->details();
GooglePlacesImporter::increment_counter();
$categories = array();
if ($insert_to_custom_cats) {
if (!empty($custom_cats)) {
foreach ($custom_cats as $category_name) {
$term = term_exists($category_name, 'listing-categories');
// $term = term_exists($category_name, 'category');
if (0 !== $term && null !== $term) {
/* ... */
} else {
$term = wp_insert_term($category_name, 'listing-categories');
// $term = wp_insert_term($category_name, 'category');
}
// $categories[] = array(
// 'name' => $category_name,
// 'id' => $term->term_id
// );
if (is_array($term)) {
$categories[] = $term['term_id'];
} else if (is_object($term)) {
$categories[] = $term->term_id;
}
}
}
} else {
foreach ($details['result']['types'] as $t) {
$category_name = GooglePlacesImporter::to_readable_str($t);
$term = term_exists($category_name, 'listing-categories');
// $term = term_exists($category_name, 'category');
if (0 !== $term && null !== $term) {
/* ... */
} else {
$term = wp_insert_term($category_name, 'listing-categories');
// $term = wp_insert_term($category_name, 'category');
}
// $categories[] = array(
// 'name' => $category_name,
// 'id' => $term->term_id
// );
if (is_array($term)) {
$categories[] = $term['term_id'];
} else if (is_object($term)) {
$categories[] = $term->term_id;
}
}
}
$post_id = $wpdb->get_var("SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = 'place_id' AND meta_value = '{$data['place_id']}' LIMIT 1");
$p = array(
'post_title' => wp_strip_all_tags($details['result']['name']),
'post_content' => '',
// 'post_type' => $_SERVER['HTTP_HOST'] == 'localhost' ? 'post' : 'listings',
'post_type' => 'listings',
// 'post_type' => 'post',
'post_status' => 'publish',
'post_author' => get_current_user_id(),
// 'post_category' => $categories
);
if (!empty($post_id)) $p['ID'] = $post_id;
$post_id = wp_insert_post($p);
update_post_meta($post_id, 'place_id', $data['place_id']);
update_post_meta($post_id, 'reference', $data['reference']);
# update_post_meta($post_id, 'formatted_address', $details['result']['formatted_address']);
// update_post_meta($post_id, 'formatted_phone_number', $details['result']['formatted_phone_number']);
update_post_meta($post_id, 'phone', $details['result']['international_phone_number']);
update_post_meta($post_id, 'website', $details['result']['website']);
//update_post_meta($post_id, 'listing_type', 'free');
update_post_meta($post_id, 'listing_type', $choices_array1[0]);
# update_post_meta($post_id, 'lat', $details['result']['geometry']['location']['lat']);
# update_post_meta($post_id, 'lng', $details['result']['geometry']['location']['lng']);
update_post_meta($post_id, 'address', array(
'address' => $details['result']['formatted_address'],
'lat' => $details['result']['geometry']['location']['lat'],
'lng' => $details['result']['geometry']['location']['lng'],
));
update_post_meta($post_id, 'category', get_term($categories[0], 'listing-categories'));
update_post_meta($post_id, 'g_rating', $details['result']['rating']);
update_post_meta($post_id, 'g_review_no', @count(isset($details['result']['reviews']) && !empty($details['result']['reviews']) ? $details['result']['reviews'] : array()));
try {
$useragent = 'Opera/9.80 (J2ME/MIDP; Opera Mini/4.2.14912/870; U; id) Presto/2.4.15';
$ch = curl_init('');
$query = urlencode($details['result']['name']);
curl_setopt ($ch, CURLOPT_URL, "https://www.google.com/search?q={$query}&oq={$query}&aqs=chrome..69i57j69i60l3.438j0j7&sourceid=chrome&ie=UTF-8&hl=en_us");
curl_setopt ($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$output = curl_exec($ch);
curl_close($ch);
$output = explode('reviews<', $output);
$output = $output[0];
$pos = strrpos($output, '>');
$output = $pos === false ? $output : substr($output, $pos + 1);
$output = trim($output);
if (is_numeric($output)) {
update_post_meta($post_id, 'g_review_no', $output);
}
} catch (Exception $e) {
}
wp_set_post_terms($post_id, $categories, 'listing-categories', false);
/*if (function_exists('get_field') && get_field('s_default_featured_image', 'option')) {
$image_path = get_field('s_default_featured_image', 'option');
$listing_dimg = attachment_url_to_postid($image_path);
update_post_meta($post_id, 'featured_image', $listing_dimg);
set_post_thumbnail($post_id, $listing_dimg);
} else {
update_post_meta($post_id, 'featured_image', $attachment_id);
set_post_thumbnail($post_id, $attachment_id);
}*/
if (isset($details['result']['photos']) && is_array($details['result']['photos']) && !empty($details['result']['photos'])) {
$photo = $details['result']['photos'][0];
$max_width = 1000;
$photo_url = "https://maps.googleapis.com/maps/api/place/photo?maxwidth={$max_width}&photoreference={$photo['photo_reference']}&key={$api_key}";
$local_photo_basename = sanitize_title(wp_strip_all_tags($details['result']['name'])) . '-' . substr(md5(rand()), 0, 7) . '.jpg';
$filetype = wp_check_filetype($local_photo_basename, null);
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . $local_photo_basename,
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', $local_photo_basename ),
'post_content' => '',
'post_status' => 'inherit'
);
$dest_file = $wp_upload_dir['path'] . '/' . $local_photo_basename;
copy($photo_url, $dest_file);
$photo_attachment_id = wp_insert_attachment($attachment, $dest_file);
if (!function_exists('wp_generate_attachment_metadata')) require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata($photo_attachment_id, $dest_file);
wp_update_attachment_metadata($photo_attachment_id, $attach_data);
update_post_meta($post_id, 'featured_image', $photo_attachment_id);
set_post_thumbnail($post_id, $photo_attachment_id);
}
}
}
die("" . GooglePlacesImporter::get_counter(date('Y-m-d')) . "");
}
# add meta boxes
public static function add_meta_boxes() {
add_meta_box('gpi_meta_box', 'Automated Lead Importer', 'GooglePlacesImporter::gpi_meta_box', 'listings', 'side', 'high');
// add_meta_box('gpi_meta_box', 'Automated Lead Importer', 'GooglePlacesImporter::gpi_meta_box', 'post', 'side', 'high');
}
public static function gpi_meta_box($post) {
$place_id = get_post_meta($post->ID, 'place_id', true);
$reference = get_post_meta($post->ID, 'reference', true);
$g_rating = get_post_meta($post->ID, 'g_rating', true);
$g_review_no = get_post_meta($post->ID, 'g_review_no', true);
if (!empty($place_id)) {
?>
<center><a href="#" id="gpi_update">Update</a></center>
<script type="text/javascript">
jQuery(function ($)
{
$("#gpi_update").on("click", function (e)
{
e.preventDefault();
$.post(
"<?php echo(trailingslashit(get_site_url())) ?>?gpi-import=1",
{ data: [{ place_id: "<?php echo($place_id) ?>", reference: "<?php echo($reference) ?>" }] },
function (resp)
{
location.reload(true);
}
);
});
});
</script>
<hr />
<?php
} else {
?>
<!--
<style type="text/css">
#gpi_meta_box { display: none !important; }
</style>
-->
<?php
}
?>
Rating (1.0-5.0):<br />
<input type="text" name="g_rating" value="<?php echo(esc_attr($g_rating)) ?>" style="width: 100%;" />
<br />
Review #:<br />
<input type="text" name="g_review_no" value="<?php echo(esc_attr($g_review_no)) ?>" style="width: 100%;" />
<?php
}
public static function save_meta_boxes($post_id) {
$post_type = get_post_type($post_id);
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
if ($_POST['post_type'] == 'listings') {
if (!current_user_can('edit_page', $post_id))
return;
}
$g_rating = $_POST['g_rating'];
if (is_numeric($g_rating) && $g_rating >= 1.0 && $g_rating <= 5.0) {
/* ... */
} else {
$g_rating = '';
}
$g_rating = PostMetaManagerHelper2::sanitize_meta_for_db_input($g_rating);
update_post_meta($post_id, 'g_rating', $g_rating);
$g_review_no = $_POST['g_review_no'];
if (is_numeric($g_review_no) && $g_rating >= 1.0) {
/* ... */
} else {
$g_review_no = '';
}
$g_review_no = PostMetaManagerHelper2::sanitize_meta_for_db_input($g_review_no);
update_post_meta($post_id, 'g_review_no', $g_review_no);
}
public static function admin_head() {
?>
<script type="text/javascript">
jQuery(function ($)
{
$("a[href=ccsu-google-scraper\\/gpi-csv-export\\.php]").on("click", function (e)
{
e.preventDefault();
window.location.href = "<?php echo(trailingslashit(get_site_url())) ?>?gpi-csv-export=1";
});
$("a[href*=offlinesharks\\.com\\/software-terms-of-service]").attr("target", "_blank");
});
</script>
<?php
}
public static function ajax() {
$places = GooglePlacesImporter::get_places($_POST);
foreach ($places['results'] as $listing) GooglePlacesImporter::render_google_place_admin_row($listing);
echo '<script>';
if (isset($places['next_page_token']) && !empty($places['next_page_token'])) {
echo 'if (jQuery.inArray("' . $places['next_page_token'] . '", CURRENT_TOKENS) == -1) { CURRENT_TOKENS.push("' . $places['next_page_token'] . '"); }';
echo 'NEXT_PAGE_TOKEN = "' . $places['next_page_token'] . '";';
} else {
echo 'NEXT_PAGE_TOKEN = null;';
}
echo 'jQuery(".apiCallsToday span").text("' . GooglePlacesImporter::get_counter(date('Y-m-d')) . '");';
echo '</script>';
exit;
}
public static function listing_csv_export() {
// Send headers immediately to start streaming
$filename = "listing_csv_export.csv";
header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment;filename={$filename}");
header("Content-Transfer-Encoding: binary");
// Open output stream directly
$df = fopen('php://output', 'w');
// Define CSV headers
$headers = [
'Company Name', 'Phone', 'Email', 'Website',
'Address', 'Street Address', 'City', 'State', 'Postal Code',
'Country', 'Business Tags', 'Profile Image', 'Cover Image', 'Facebook', 'Twitter', 'Instagram', 'Linked In',
'Tiktok', 'Business Type', 'Business Description',
'additional_details', 'URL', 'images', 'video_url', 'extra_links', 'schedules_days',
'exp_date', 'g_place_id', 'g_reference','lat', 'lng'
];
fputcsv($df, $headers);
// Batch processing parameters
$per_page = 100; // Adjust based on server capacity
$page = 1;
do {
$args = [
'post_type' => 'listings',
'post_status' => 'publish',
'posts_per_page' => $per_page,
'paged' => $page,
'orderby' => 'date',
'order' => 'DESC',
'no_found_rows' => true, // Skip counting total rows for pagination
'update_post_meta_cache' => false,
'update_post_term_cache' => false
];
$query = new WP_Query($args);
if (!$query->have_posts()) break;
foreach ($query->posts as $p) {
// Retrieve necessary post meta
$place_id = get_post_meta($p->ID, 'place_id', true);
$reference = get_post_meta($p->ID, 'reference', true);
$phone = get_post_meta($p->ID, 'phone', true);
$website = get_post_meta($p->ID, 'website', true);
$listing_type = get_post_meta($p->ID, 'listing_type', true);
$address = get_post_meta($p->ID, 'address', true); // Already unserialized
// Start processing the raw address string
$raw_address = $address['address'] ?? '';
// 1. Extract the ZIP code (5-digit) and remove it from the address.
$zip = '';
if (preg_match('/\b\d{5}\b/', $raw_address, $matches)) {
$zip = $matches[0];
$address_temp = str_replace($zip, '', $raw_address);
} else {
$address_temp = $raw_address;
}
// 2. Normalize the country.
// Look for known country variations and convert them to 'US'
$country = '';
$known_countries = ['USA', 'United States', 'United States of America', 'America'];
foreach ($known_countries as $ctry) {
if (stripos($address_temp, $ctry) !== false) {
$country = 'US';
// Remove the country text from the address
$address_temp = str_ireplace($ctry, '', $address_temp);
break;
}
}
// 3. Clean up the remaining address string
$address_temp = preg_replace('/,+/', ',', $address_temp); // replace multiple commas with one
$address_temp = trim($address_temp, " ,");
// 4. Split the address by commas and determine street, city, and state
$parts = array_map('trim', explode(',', $address_temp));
$street = '';
$city = '';
$state = '';
if (count($parts) > 1) {
// Assume the last part holds the state info.
$statePart = array_pop($parts);
// Remove any non-letter characters.
$statePartClean = preg_replace('/[^a-zA-Z ]/', '', $statePart);
$statePartClean = trim($statePartClean);
// If already a 2-letter abbreviation, use it.
if (strlen($statePartClean) == 2) {
$state = strtoupper($statePartClean);
} else {
// Otherwise, map full state names to abbreviations.
$states = [
'Alabama' => 'AL',
'Alaska' => 'AK',
'Arizona' => 'AZ',
'Arkansas' => 'AR',
'California' => 'CA',
'Colorado' => 'CO',
'Connecticut' => 'CT',
'Delaware' => 'DE',
'Florida' => 'FL',
'Georgia' => 'GA',
'Hawaii' => 'HI',
'Idaho' => 'ID',
'Illinois' => 'IL',
'Indiana' => 'IN',
'Iowa' => 'IA',
'Kansas' => 'KS',
'Kentucky' => 'KY',
'Louisiana' => 'LA',
'Maine' => 'ME',
'Maryland' => 'MD',
'Massachusetts' => 'MA',
'Michigan' => 'MI',
'Minnesota' => 'MN',
'Mississippi' => 'MS',
'Missouri' => 'MO',
'Montana' => 'MT',
'Nebraska' => 'NE',
'Nevada' => 'NV',
'New Hampshire' => 'NH',
'New Jersey' => 'NJ',
'New Mexico' => 'NM',
'New York' => 'NY',
'North Carolina' => 'NC',
'North Dakota' => 'ND',
'Ohio' => 'OH',
'Oklahoma' => 'OK',
'Oregon' => 'OR',
'Pennsylvania' => 'PA',
'Rhode Island' => 'RI',
'South Carolina' => 'SC',
'South Dakota' => 'SD',
'Tennessee' => 'TN',
'Texas' => 'TX',
'Utah' => 'UT',
'Vermont' => 'VT',
'Virginia' => 'VA',
'Washington' => 'WA',
'West Virginia' => 'WV',
'Wisconsin' => 'WI',
'Wyoming' => 'WY'
];
foreach ($states as $name => $abbr) {
if (strcasecmp($statePartClean, $name) === 0) {
$state = $abbr;
break;
}
}
}
// The next part (if available) is assumed to be the city.
if (count($parts) > 0) {
$city = array_pop($parts);
}
// All remaining parts form the street address.
$street = implode(', ', $parts);
} else {
// Fallback: if the address doesn't contain commas, treat the whole thing as the street.
$street = $raw_address;
}
// Get additional ACF fields
$acf_fields = get_fields($p->ID);
// Process categories
$listing_categories = [];
$terms = get_the_terms($p->ID, 'listing-categories');
if (is_array($terms)) {
$listing_categories = wp_list_pluck($terms, 'name');
}
// Process schedules
$schedules_days = $acf_fields['schedules_days'] ?? [];
$formatted_schedule = [];
foreach ($schedules_days as $item) {
if (!empty($item['single_schedule_day']) && !empty($item['business_hour_from']) && !empty($item['business_hour_to'])) {
$formatted_schedule[] = "{$item['single_schedule_day']} {$item['business_hour_from']} - {$item['business_hour_to']}";
}
}
// Process media
$featured_image_url = get_the_post_thumbnail_url($p->ID, 'full');
$image_urls = [];
foreach ($acf_fields['images'] ?? [] as $image) {
$image_urls[] = $image['url'] ?? '';
}
// Process video URL
$video_src = '';
if (!empty($acf_fields['video'])) {
preg_match('/src="(.+?)"/', $acf_fields['video'], $matches);
$video_src = $matches[1] ?? '';
}
fputcsv($df, [
'Company Name' => $p->post_title,
'Phone' => $phone,
'Email' => $acf_fields['email_address'] ?? '',
'Website' => $website,
'Address' => $raw_address,
'Street Address' => $street,
'City' => $city,
'State' => $state,
'Postal Code' => $zip,
'Country' => $country,
'Business Tags' => implode(',', $listing_categories),
'Profile Image' => !empty($acf_fields['logo']) ? $acf_fields['logo'] : $featured_image_url,
'Cover Image' => $featured_image_url,
'Facebook' => $acf_fields['facebook_link'] ?? '',
'Twitter' => $acf_fields['twitter_link'] ?? '',
'Instagram' => $acf_fields['instagram_link'] ?? '',
'Linked In' => $acf_fields['linkedin_link'] ?? '',
'Tiktok' => $acf_fields['tiktok_link'] ?? '',
'Business Type' => $listing_type,
'Business Description' => $acf_fields['content'] ?? '',
'additional_details' => $acf_fields['additional_details'] ?? '',
'URL' => get_permalink($p->ID),
'images' => implode(',', $image_urls),
'video_url' => $video_src,
'extra_links' => $acf_fields['extra_links'] ?? '',
'schedules_days' => implode(', ', $formatted_schedule),
'exp_date' => $acf_fields['exp_date'] ?? '',
'g_place_id' => $place_id,
'g_reference' => $reference,
'lat' => $address['lat'] ?? '',
'lng' => $address['lng'] ?? '',
]);
// Free memory for large variables.
unset($acf_fields, $terms, $schedules_days, $image_urls);
}
wp_reset_postdata();
$page++;
} while (true);
fclose($df);
exit;
}
public static function get_between($content, $start, $end){
$r = explode($start, $content);
if (isset($r[1])){
$r = explode($end, $r[1]);
return $r[0];
}
return '';
}
}
if (isset($_GET['gpi']) && !empty($_GET['gpi']) && $_GET['gpi'] == 1) add_action('init', 'GooglePlacesImporter::ajax');
if (isset($_GET['gpi-import']) && !empty($_GET['gpi-import']) && $_GET['gpi-import'] == 1) add_action('init', 'GooglePlacesImporter::import');
if (isset($_GET['gpi-csv-export']) && !empty($_GET['gpi-csv-export']) && $_GET['gpi-csv-export'] == 1) add_action('init', 'GooglePlacesImporter::listing_csv_export');
function _gapi_init() {
if (!class_exists('PostMetaManagerField2')) require_once('post-meta-manager-api/index.php');
$gpi = new GooglePlacesImporter();
// GooglePlacesImporter::increment_counter();
}
add_action('init', '_gapi_init');
// In your admin-menu.php or similar admin file
// Hook into the admin_menu action to register the submenu.
add_action( 'admin_menu', 'listing_categories_export' );
/**
* Register a new submenu item for CSV Categories Export under Listings.
*/
function listing_categories_export() {
add_submenu_page(
'edit.php?post_type=listings', // Parent slug (Listings menu)
'CSV Categories Export', // Page title
'CSV Categories Export', // Menu title
'manage_options', // Capability
'csv-categories-export', // Menu slug
'listing_categories_export_main' // Callback function
);
}
/**
* Callback function that gets called when the submenu is accessed.
*/
function listing_categories_export_main() {
// Check if the current user has proper permissions.
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'You do not have sufficient permissions to access this page.' );
}
// You can either include the export file or call the function directly.
// For example, if you have a separate file, you might do:
// include_once plugin_dir_path( __FILE__ ) . 'gpi-csv-categories-export.php';
// Otherwise, call the export function directly:
listing_categories_csv_export();
}
/**
* Function to generate and output the CSV for listing categories.
*/
function listing_categories_csv_export() {
// Clean (erase) any previous output buffers to prevent unwanted content.
if (ob_get_length()) {
ob_clean();
}
// Set CSV headers so the browser knows it's a CSV file download.
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=categories_export.csv');
header("Pragma: no-cache");
header("Expires: 0");
// Open output stream.
$output = fopen('php://output', 'w');
if (false === $output) {
wp_die('Could not open output stream.');
}
// Write the CSV header row.
$csv_headers = ['Name'];
fputcsv($output, $csv_headers);
// Retrieve all listing categories (including empty ones).
$categories = get_terms([
'taxonomy' => 'listing-categories',
'hide_empty' => false,
]);
// Loop through each category and write a CSV row.
if ( ! is_wp_error($categories) && ! empty($categories) ) {
foreach ( $categories as $cat ) {
// Use strip_tags() in case any HTML is present in the term fields.
fputcsv($output, [
strip_tags($cat->name)
]);
}
}
// Close the output stream.
fclose($output);
// Terminate execution immediately to prevent any extra output.
exit;
}