Update a WP database table from multiple tables - mysql

I am using the WP Google Maps app. This allows map marker data to be entered on the back-end and displayed on maps on the front-end.
I am trying to adapt this so that an Author can create a post, and the data from the post populates the WP Google Maps table so that it appears on the map. In other words, enabling non-admin users to create map markers with additional fields.
The main information for WP Google Maps is stored in a table called wp_wpgmza. I have tried to write an SQL trigger that updates this table with data from wp_posts and wp_postmeta each time a new post is made but I can't crack it. Something about pulling from the two tables and the structure of wp_postmeta
Any suggestions on another way around this problem?
Thanks D

In WordPress, hooks and filters are often used to accomplish most things like that.
You can easily use the following hooks that call your function before saving/inserting a post:
do_action('save_post', $post_ID, $post);
do_action('wp_insert_post', $post_ID, $post);
Here's a sample usage:
function my_function($post_ID, $post) {
}
add_action('save_post', 'my_function', 2);
Inside my_function you could use $wpdb->insert to enter the data to the table.
function my_function($post_ID, $post) {
global $wpdb;
$table = $wpdb->prefix . 'wpgmza';
$data = array(
'column1' => 'value1',
'column2' => 'value2'
);
$wpdb->insert($table , $data);
}
add_action('save_post', 'my_function', 2);
Alternatively, you can use function_exists() and a function used by the plugin itself to insert to the map table.
function my_function($post_ID, $post) {
if (function_exists('some_google_map_app_function')) {
some_google_map_app_function();
}
}
add_action('save_post', 'my_function', 2);
Note: $post_ID, $post are parameters you can use to take a peak into the post data and/or pass along to that google maps function or insert to the table.
Useful Resources:
https://codex.wordpress.org/Function_Reference/add_action
https://codex.wordpress.org/Plugin_API/Action_Reference/save_post

Related

Woocommerce: How to update meta attribute value of all products programmatically

I have a meta attribute on my products that can be accessed like this:
get_post_meta( $product_id, '_disable_shipping', true );
I need to update _disable_shipping attribute of all products on MySQL or programmatically. Is there a simple way of doing it? I want to change all values to yes for all my products.
You can use the following MYSQL query , wp_postmeta depends on your wordpress database prefix
UPDATE `wp_postmeta` SET `meta_value` = 'yes' WHERE `meta_key` = '_disable_shipping'
You can create a plugin and put a function in it which runs through your products and updates every products meta value. If you don't know how you create a plugin, here is a tutorial for this: https://www.smashingmagazine.com/2011/09/how-to-create-a-wordpress-plugin/ It is done in minutes.
Please make sure you have a backup of your database before doing bulk actions to update your products.
The function could look something like this:
function disable_shipping_once(){
$products = get_posts(array('post_type' => 'product', 'numberposts' => -1) );
foreach($products as $product) :
$product_ID = $product->ID;
$meta_value = get_post_meta($product_ID, '_disable_shipping',true);
if($meta_value == "no") :
update_post_meta($product_ID, '_disable_shipping-include', 'yes' );
endif;
endforeach;
}
If you activate your plugin, this function will run. After that, you can deactivate it again.
This code should be pretty save, because it only updates post meta, if the value is "no", so there should not be any unintended updates of the posts.
Maybe there also is a plugin for bulk editing your products. This is the first I found which seems to be doing the job, haven't tested it yet: https://wordpress.org/plugins/custom-field-bulk-editor/

How to modify the output of a view in Drupal 7.x using a module

I want to modify the query that is running to create a table in a view but am having a hard time, so to keep it simple I am using a plain view that just lists users in a table and am trying to modify the query to make the table have two columns. I have been looking at the documentation for Drupal queries, trying to find tutorials, and looking at blog posts on how others modified queries in Drupal and Views, but so far none have worked or shown how to do something as simple as this, or I've tried to create simple query statements following what they did with no outcome.
I've mainly been trying to use hook_views_pre_execute() but have also tried . This is what my code looks like at the moment:
<?php
/**
* Implements hook_views_query_alter().
*/
// This function is called right before the execute process.
function my_module_views_pre_execute(&$view) {
if ($view->name == 'page' && $view->current_display == 'page') { //checks name of the view and what type it is
drupal_set_message("I can make changes to the view here.."); //diagnostic information, shows we can make changes to that view
$query =db_select('node','n')//select base table, alias is n.
->fields('n',array('nid', 'title', 'created', 'uid')); //adding fields nid, title, created, uid.
dpm($query->execute()->fetchAll()); // diagnostic information, shows whats being returned by the query
$query->execute()->fetchAll();
$view->build_info['query'] = $query;
}
}
I am able to create a message on the view with drupal_set_message("I can make changes to the view here..");, and in the Views settings tab I enabled 'Show the SQL query' and the output of that is the query from my module/code (it doesn't match the table created by Views).
So why doesn't it affect the table output at all? How do I modify what query is being run to display the view (which is apparently different from the 'Show the SQL query' output)?
I have taken example only for nid here I can provide you just an Idea for alter the views output.
/**
*
* #param type $view
* #param type $query
* Implements hook_views_query_alter(). This function is Used when we need to Alter the query before executing the query.
*/
function mymodule_views_query_alter(&$view, &$query) {
if ($view->name == 'VIEW_NAME' && $view->current_display == 'PAGE_NAME') {
drupal_set_message("I can make changes to the view here.."); //diagnostic information, shows we can make changes to that view
$query =db_select('node','n')//select base table, alias is n.
->fields('n',array('nid', 'title', 'created', 'uid')); //adding fields nid, title, created, uid.
dpm($query->execute()->fetchAll()); // diagnostic information, shows whats being returned by the query
$result = $query->execute()->fetchAll();
$nids = array();
foreach ($result as $value) {
$nids[] = $value->nid;
}
$view->query->where[1]['conditions'][] = array('field' => "node.nid", "value" => $nids, "operator" => "IN");
}
}
hook_views_pre_execute() is too late in the query build processs so I think you should use hook_views_query_alter().
Thanks

Cakephp 3: Modifying Results from the database

In my database there is a content table and when fetching data from this table I would like to append field url to the results, which is based on slug field which is contained in the table. Anyway, I have seen a way to do this in the previous versions of cakephp using behavior for the model of this table and then modifying results in afterFind callback in the behavior class. But in version 3 there is no afterFind callback, and they recommend using mapReduce() method instead in the manual, but this method is poorly explained in the manual and I cant figure out how to achieve this using mapReduce().
After little bit of research I realized that the best way to append the url field field to find results is using formatResults method, So this is what I did in my finders:
$query->formatResults(function (\Cake\Datasource\ResultSetInterface $results) {
return $results->map(function ($row) {
$row['url'] = array(
'controller' => 'content',
'action' => 'view',
$row['slug'],
$row['content_type']['alias']
);
return $row;
});
});

Minimising Database Queries in Wordpress when using Advanced Custom Fields

I'm working on a page which lists staff members for a large company and trying to minimise the number of times I'm forced to query the database as it gets quite complex and slow.
'person' is a custom post type (there are about 300 people)
'date_accredited' is a date field added via Advanced Custom Fields plugin.
Only accredited staff will have a 'date_accredited'.
I need to list every 'person' BUT, with ALL accredited staff listed first (so about 20 accredited staff come at the top).
At the moment, I am doing a call to WP_Query like:
$args = array(
'posts_per_page' => -1,
'post_type' => 'people',
'no_found_rows' => true,
'meta_key' => 'date_accredited'
);
$people = new WP_Query($args);
After that I'm doing:
while($people->have_posts()): $people->the_post();
$my_post_meta = get_post_meta($post->ID, 'date_accredited', true);
if (!empty($my_post_meta)) {
array_push($accredited, $post);
} else {
array_push($notAccredited, $post);
}
endwhile;
Leaving us with two arrays of 'person' objects. My thinking here was that I would be able to do something like the following to get the list I want:
foreach($accredited as $person):
personTile($person);
endforeach;
foreach($notAccredited as $person):
personTile($person);
endforeach;
I'm trying to avoid re-querying the database.
The personTile(); function was supposed to output various info and HTML (the_post_thumbnail() and various Advanced Custom Fields fields), but what I'm realising now is that none of this is included in the post objects I get from WP_Query(), so I'm forced to use things like:
get_the_post_thumbnail($person->ID)
get_permalink($person->ID)
get_field('date_accredited', $person->ID)
All of these cost another DB Query (each!), and worse still since they are in a loop each one happens around 300 times.
Is there any way to get the permalink, thumbnail and ACF fields to be included in the original DB Query? Would I need to resort to a custom MySQL Query???
Any other suggestions welcome!

How to convert zipcode to longitude and latitude?

I want to find the longitude and latitude of place with a the help to a zipcode.
Can anyone tell me how to do that?
An example in actionscript what be very much helpful for me. Because i am making a project in Flex.
Regards
Zee
Do you have access to a long/lat database? if not, i believe you can use the google maps API to do that lookup.
Oh .. I just noticed Chris' answer. I am not familiar with geonames. You might also want to get familiar with "http://freegeographytools.com/" which has a ton of geocoding, gps, etc. resources for a whole range of projects.
Ahhh ... I just visited Eric's blog post. That is excellent! I will definitely hook up with google for more details in a future project.
If you are looking for on demand geocoding, use Google. They provide a simple pox web service version.
I wrote a blog about this a while back. Check out this link for step by step instructions for using this simple geocoding.
Cheers,
Eric
I got my solve you can also
function getLatLong($code) {
$mapsApiKey = 'ABQIAAAAsV7S85DtCo0H9T4zv19FoRTdT40ApbWAnDYRE0-JyP5I6Ha9-xT9G5hCQO5UtOKSH5M3qhp5OXiWaA';
$query = "http://maps.google.co.uk/maps/geo?q=".urlencode($code)."&output=json&key=".$mapsApiKey;
$data = file_get_contents($query);
// if data returned
if($data) {
// convert into readable format
$data = json_decode($data);
$long = $data->Placemark[0]->Point->coordinates[0];
$lat = $data->Placemark[0]->Point->coordinates[1];
return array('Latitude'=>$lat, 'Longitude'=>$long);
} else {
return false;
}
}
There are several places to get zip code databases, in several formats. Load it into your favorite RDBMS, and query away.
Alternatively, you can use someone else's web service to look up the value for you. Other answers have posted possible web services; also, geocoder.us appears to have support for ZIP code lookup now as well.
There is now a better solution for this using the most recent Google Maps API (v3). The following is a slightly modified example from multiple sources. I have to give most of the credit to them. It's PHP, using cURL to retrieve the data from Google, but you could also use Ajax.
function address_lookup($string){
$string = str_replace (" ", "+", urlencode($string));
$details_url = "http://maps.googleapis.com/maps/api/geocode/json?address=".$string."&sensor=false";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $details_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
// If Status Code is ZERO_RESULTS, OVER_QUERY_LIMIT, REQUEST_DENIED or INVALID_REQUEST
if ($response['status'] != 'OK') {
return null;
}
$geometry = $response['results'][0]['geometry']['location'];
$array = array(
'lat' => $geometry['lat'],
'lng' => $geometry['lng'],
'state' => $response['results'][0]['address_components'][3]['short_name'],
'address' => $response['results'][0]['formatted_address']
);
return $array;
}
$zip= '01742';
$array = address_lookup($zip);
print_r($array);
The easiest way out is using GoogleMap Api. Say you have a zipcode in a varible $zipcode.
$latlongUrl = 'http://maps.googleapis.com/maps/api/geocode/json?components=postal_code:'.$zipcode;
$data = file_get_contents($latlongUrl); // you will get string data
$data = (json_decode($data)); // convert it into object with json_decode
$location = ($data->results[0]->geometry->location); // get location object
$location is the object with Latitude and Longitude value.