I'm trying to write a plugin which edits the content of a published post. I've tried using this:
function edit( $post_ID ) {
$content = "Hello. This is a test.";
$post_info = get_post($post_ID);
$post_info->post_content = "$content";
wp_update_post( $post_info );
}
add_action('publish_post', 'edit');
Although that's not working. It enters a loop (because it's being published again) and only ends when it times out. Would there be another way to do this?
I think you have to have a static variable in the function that tracks whether the function has been called. Also, wp_update_post takes an array rather than an object -- at least that's the way I do it.
function edit( $post_ID ) {
static $plugin_has_updated = false;
if ($plugin_has_updated) return;
$plugin_has_updated = true;
$content = "Hello. This is a test.";
$post_arr = array("ID"=>$post_ID, "post_content"=>$content);
wp_update_post( $post_arr );
}
add_action('publish_post', 'edit');
Related
I am trying to build a plugin where I need to take inputs from users from a form and create a shortcode with some of the user inputs. I have created a separate page for the adding form. there I am trying to process the input data and save on a custom table in WordPress DB. The problem I am facing is that, After saving the data in my custom table, I want to create a shortcode with some of the inputs but the add_shortcode method with its callback function is not working. I am new to Wordpress so I am not sure where I am going wrong.
I have tried a lot of ways but at the end was left with scratching my head. I have tried first saving everything. Then on the plugin main file. Tried to retrieve data from DB and create shortcode there. But no result
if (isset($_POST['sc_add_submit'])) {
$name = sanitize_text_field($_POST['sc_name']);
$shortcode = sanitize_text_field($_POST['shortcode']);
$content = sanitize_text_field($_POST['content']);
$short_desc = sanitize_text_field($_POST['short_desc']);
$errors = [];
$msgs = [];
global $wpdb;
$wpdb->insert('wp_sc_content', array(
'sc_name' => $name,
'shortcode' => 'sc_'.$shortcode,
'content' => $content,
'short_desc' => $short_desc,
));
$sc_lastInsert_id = $wpdb->insert_id;
if (!empty($sc_lastInsert_id)) {
$msgs[] = "Shortcode inserted succesfully";
function sc_register_shortcode()
{
return $content;
}
add_shortcode($shortcode, 'sc_register_shortcode');
} else {
$errors[] = "DB insert failed";
}
}
I just need to register the shortcode each time the form is submitted. So that the user paste the shortcode and it returns the content wherever he wants.
So, your shortcodes are "added" as soon as the form is submitted. When you navigate to other pages or reload the screen, the add_shortcode() is not triggering anymore!
What you need to do is to query your shortcodes from the database and hook it to something like init, so it's always loaded.
Let me write the code for you-
<?php
add_action( 'init', 'wpse_54302608_add_shortocodes' );
function wpse_54302608_add_shortocodes() {
global $wpdb;
$table = 'wp_sc_content'; // hopefully $wpdb->prefix . 'sc_content';
$query = "SELECT * FROM {$table}";
$results = $wpdb->get_results( $query );
foreach ( $results as $row ) {
$fn = function() use ( $row ) {
return $row->content;
};
add_shortcode( $row->shortcode, $fn );
}
}
Not tested. But should work.
I try to take some data from one custom field to another in the save_post hook. First I tried the save_post_{post-type} hook, but update_post_meta is not saving anything. I then tried only save_post and it is working...
Strangely the save_post_{post-type} hook is fired, because it gives me some output when I dump the $_Request (for example). Only the update_post_meta isn't working. (And I tried this right before update_post_meta and after to make sure the google maps coordinate thingy is working, and they are, cause I also am able to dump them.)
add_action('save_post_listing', 'geocode_address', 999999);
function geocode_address($post_id) {
global $api_key;
$custom_fields = get_post_meta($post_id, '', true);
if(!empty($custom_fields["wpcf-geo_map"][0])) {
$resp = wp_remote_get( "https://maps.google.com/maps/api/geocode/json?key=".$api_key."&address=".urlencode($custom_fields["wpcf-geo_map"][0])."&sensor=false" );
if ( 200 == $resp['response']['code'] ) {
$body = $resp['body'];
$data = json_decode($body);
if($data->status=="OK"){
$latitude = $data->results[0]->geometry->location->lat;
$longitude = $data->results[0]->geometry->location->lng;
update_post_meta($post_id, "wpcf-latitude", $latitude);
update_post_meta($post_id, "wpcf-longitude", $longitude);
}
}
}
}
I have created a system for a WordPress site using fake pages, and some plugins like More Types (for custom post types), Advanced Custom Fields, and More Taxonomies. The site have a post type for bands and releases.
Everything works very well on frontend, and if a user wanna read about a band, he clicks the menu and ends up at /band/[bandname]. If he wanna read about a release he ends up at /band/[bandname]/releases/[releasename].
As I said, everything works fine in frontend. But when I create a release in backend I'm having a hard time to add the /band/[bandname] part to the permalink for the post type releases. I tried with /band/%band%/releases/, but %band% will be written literally, as it doesn't know where to get the band name from. Any ideas?
I tried to use this code. Band is a post object input in the releases submit form.
add_filter('post_type_link', 'custom_permalinks', 10, 3);
function custom_permalinks($permalink, $post, $leavename)
{
$post_id = get_post_meta($_POST['band'], 'bands', true);
if($post->post_type != 'utgivelse' || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft')))
return $permalink;
$var1 = get_post_meta($post_id, 'bands', true);
$var1 = sanitize_title($var1);
$permalink = str_replace('%band%', $var1, $permalink);
return $permalink;
}
You could do it like this:
<?php
add_filter('rewrite_rules_array','customRewriteRules');
add_filter('query_vars','customRewriteVars');
// Remember to flush_rules() when adding rules
add_filter('init','flushRules');
function flushRules(){
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
// Adding a new rule
function customRewriteRules($rules)
{
$newrules = array();
$newrules['bands-page/([^/]+)/([^/]+)/?'] = 'index.php?pagename=bands-page&customvar1=$matches[1]&customvar2=$matches[2]';
$newrules['bands-page/([^/]+)/?'] = 'index.php?pagename=bands-page&customvar1=$matches[1]'; // pagename could be band/
$finalrules = $newrules + $rules;
return $finalrules;
}
function customRewriteVars($vars)
{
array_push($vars, 'customvar1', 'customvar2');
return $vars;
}
You can pass as many as query vars as you want, and then use that var ($_GET['customvar1']) to do a custom loop or something like that.
By doing some small tweaks, I got it working good. I added the following permalink rule to my releasestype: /band/%band%/releases/
Then I created this to replace variable %band% in permalink:
add_filter('post_type_link', 'custom_permalinks', 10, 3);
function custom_permalinks($permalink, $post, $leavename)
{
$post_id = $post->ID;
if($post->post_type != 'utgivelse' || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft')))
return $permalink;
$var1 = get_the_title(get_post_meta($post_id, 'band', true));
$var1 = sanitize_title($var1);
$permalink = str_replace('%band%', $var1, $permalink);
return $permalink;
}
I am using the FeedWordPress plugin http://wordpress.org/extend/plugins/feedwordpress/ to pull posts from one site to another.
I have written a filter that after some help from Stack users successfully scans the $content and extracts the image URL into $new_content
define('FWPASTOPC_AUTHOR_NAME', 'radgeek');
add_filter(
/*hook=*/ 'syndicated_item_content',
/*function=*/ 'fwp_add_source_to_content',
/*order=*/ 10,
/*arguments=*/ 2
);
function fwp_add_source_to_content ($content, $post) {
// Use SyndicatedPost::author() to get author
// data in a convenient array
$content = $post->content();
// Authored by someone else
if( preg_match( '/<img[^>]+src\s*=\s*["\']?([^"\' ]+)[^>]*>/', $content, $matches ) ) {
$new_content .= 'URL IS '.$matches[0].'';
return $new_content;
}
else
{
}
}
What I wanted to do now was save this URL into a custom field instead of just returning it. Has anyone achieved anything similar?
So as I understand it, the plugin grabs content from external RSS feeds and creates them as posts in your website.
If this is the case, using your filter you should be able to grab the post ID within the $post variable.
So all you need is the add_post_meta() function to add a custom field to the specific post.
So including your code above it should look something like:
define('FWPASTOPC_AUTHOR_NAME', 'radgeek');
add_filter(
/*hook=*/ 'syndicated_item_content',
/*function=*/ 'fwp_add_source_to_content',
/*order=*/ 10,
/*arguments=*/ 2
);
function fwp_add_source_to_content ($content, $post) {
// Use SyndicatedPost::author() to get author
// data in a convenient array
$content = $post->content();
// Authored by someone else
if( preg_match( '/<img[^>]+src\s*=\s*["\']?([^"\' ]+)[^>]*>/', $content, $matches ) ) {
$new_content .= 'URL IS '.$matches[0].'';
//Add custom field with author info to post
add_post_meta($post->ID, 'post_author', $new_content);
return $new_content;
}
}
I'm developing a plugin and one of the issues I am running into is that I cannot get the post id within a function assigned to the admin_init hook.
I tried a few different methods; but, they all seem to use the $wp_query.
Below is a simple version the code I am using. I implemented the code like this just now and ran it by viewing the "post edit" page
add_action('admin_init','do_optional_featured_article');
function do_optional_featured_article()
{
global $wp_query;
echo "<pre>";
print_r($wp_query);
echo "</pre>";
die();
}
$wp_query is a mostly empty array, notably, the post member is empty
-- EDIT --
I got some advice over at wordpress.stackexchange and added in this function:
function get_admin_post()
{
if( isset($_GET['post']) )
{
$post_id = absint($_GET['post']); // Always sanitize
$post = get_post( $post_id ); // Post Object, like in the Theme loop
return $post;
}
elseif( isset($_POST['post_ID']) )
{
$post_id = absint($_POST['post_ID']); // Always sanitize
$post = get_post( $post_id ); // Post Object, like in the Theme loop
return $post;
}
else
{
return false;
}
}
I think this answer will help. It states that the earliest action you can hook into, to get the global $post/$posts variables is the wp action. In the action hook reference on the codex, you can see that the wp action executes a bit after admin_init, which is why you can't retrieve any posts there, I think.
So, that should work:
add_action('wp','do_optional_featured_article');