WordPress - Adding Page/Post Attachment Feature to the Media Edit Screen - wordpress

Is there a way to add the page attachment feature to the edit media screen? So if I add/edit a media item, I can also attach/re-attach it to a page.
Here's the code I have so far:
function my_post_submitbox_misc_actions( $id ){
$post = get_post( $id );
if( $post->post_parent > 0 ) {
if( get_post( $post->post_parent ) ) {
$title = _draft_or_post_title( $post->post_parent );
}
?>
<div class="misc-pub-section misc-pub-attachment">
Attached to: <strong><?php echo $title ?></strong>
(<a class="hide-if-no-js" onclick="findPosts.open( ''media[]'', '<?php echo $post->ID ?>' );return false;" href="#the-list"><?php _e( 'Re-Attach' ); ?></a>)
</div>
<?php
} else { ?>
<?php _e( '(Unattached)' ); ?><br />
<a class="hide-if-no-js" onclick="findPosts.open( 'media[]', '<?php echo $post->ID ?>' );return false;" href="#the-list"><?php _e( 'Attach' ); ?></a>
<?php
}
}
add_action( 'attachment_submitbox_misc_actions', 'my_post_submitbox_misc_actions' );
And here's my call to the database:
global $wpdb;
$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment'", $parent_id ) );
if ( isset( $attached ) ) {
$location = 'upload.php';
if ( $referer = wp_get_referer() ) {
if ( false !== strpos( $referer, 'upload.php' ) )
$location = $referer;
}
$location = add_query_arg( array( 'attached' => $attached ) , $location );
wp_redirect( $location );
}

I've use these combined functions, in my functions.php file, to add a link in the media library (upload.php in admin area) for each media item in the table to attach/re-attach that item to anything.
// Functions to allow one to re-attach an image to a post
function upload_columns( $columns ) {
// Unset( $columns['parent'] );
$columns['better_parent'] = 'Re-Attach';
return $columns;
}
add_filter( 'manage_upload_columns', 'upload_columns' );
function media_custom_columns( $column_name, $id ) {
$post = get_post($id);
if( $column_name != 'better_parent' )
return;
if( $post->post_parent > 0 ) {
if( get_post( $post->post_parent ) ) {
$title = _draft_or_post_title( $post->post_parent );
}
?>
<strong><?php echo $title ?></strong>, <?php echo get_the_time( __( 'Y/m/d' )); ?>
<br />
<a class="hide-if-no-js" onclick="findPosts.open( 'media[]', '<?php echo $post->ID ?>' );return false;" href="#the-list"><?php _e( 'Re-Attach' ); ?></a>
<?php
}else {
?>
<?php _e( '(Unattached)' ); ?><br />
<a class="hide-if-no-js" onclick="findPosts.open( 'media[]', '<?php echo $post->ID ?>' );return false;" href="#the-list"><?php _e( 'Attach' ); ?></a>
<?php
}
}
add_action( 'manage_media_custom_column', 'media_custom_columns', 10, 2 );
I know this doesn't put the option where you are describing, but it's a start in the right direction.
UPDATE:
Note that I'll leave the above code in case someone wants to have the re-attach option in their library table.
As for your question... Here is the code, explanation to follow:
function my_post_submitbox_misc_actions( $id ) {
global $pagenow, $typenow;
// We only want to run the code on a specific page
if( $pagenow != 'post.php' || $typenow != 'attachment' ) {
return;
}
$post = get_post( $id );
if( $post->post_parent > 0 ) {
if( get_post( $post->post_parent ) ) {
$title = _draft_or_post_title( $post->post_parent );
}
?>
<div class="misc-pub-section misc-pub-attachment">
Attached to: <strong><?php echo $title ?></strong>
( <a class="hide-if-no-js" onclick="findPosts.open('action','find_posts');return false;" href="#"><?php _e( 'Re-Attach' ); ?></a> )
</div>
<?php
} else {
_e( '(Unattached)' ); ?><br />
<a class="hide-if-no-js" onclick="findPosts.open('action','find_posts');return false;" href="#"><?php _e( 'Attach' ); ?></a>
<?php
}
}
add_action( 'attachment_submitbox_misc_actions', 'my_post_submitbox_misc_actions' );
// Function to call the find_posts_div pop up OUTSIDE the post form
function my_post_submitbox_misc_form() {
global $pagenow, $typenow;
// We only want to run the code on a specific page
if( $pagenow != 'post.php' || $typenow != 'attachment' ) {
return;
}
// Enqueue our scripts
wp_enqueue_style('thickbox');
wp_enqueue_script('thickbox'); // needed for find posts div
wp_enqueue_script('media');
wp_enqueue_script('wp-ajax-response');
?>
<form name="plugin_form" id="plugin_form" method="post" action="/wp-content/themes/<?php echo get_template() . '/test.php'; ?>">
<?php
wp_nonce_field('plugin_nonce');
find_posts_div();
?>
</form>
<?php
}
add_filter('admin_footer','my_post_submitbox_misc_form');
BREAKDOWN
The first function is very similar to what you already have in your code above. I believe the only change I made was to add the check to make sure we only run this code on the edit attachment page. You might need to tweak this, as I tested it, but not fully.
I also changed the way we call findPosts.open(). We now pass a variable called 'action' and set it's value to 'find_posts' so we can check for it later...
So the first function simply shows the post the attachment is already attached to, and lets you re-assign it if desired... or shows you an option to just attach it. The re-attach and attach are just links that, when clicked, launch findPosts.open() which looks for a hidden div/inputs on the page... we haven't created those yet.
The second function is the key... first, you do need to enqueue scripts and one style. The import piece of code here is the find_posts_div() call. This is what makes the magic happen, but all this does is creates hidden divs and form fields in a pop-up, just waiting to be called (our anchors in the first function). This NEEDS TO BE in a separate function so that we can use add_filter to call the function OUTSIDE OF the post form.
At first I tried to have it all together in one function. The browser strips out our <form> tag because we are attempting to place a form inside another form (the post form), and that's a no no. So by calling it in the admin_footer, we load the code outside the form.
Wrapping the find_posts_div() in a form allows us to submit the results of that form to where ever we want, to do whatever we want with it. In our case, we create a new page (test.php) and submit the results there, so we can do what we need.
So far, the test.php page is as follows:
<?php
echo '<pre>';print_r($_POST);echo '</pre>';
die();
?>
This will show you all the values of $_POST... feel free to add more hidden values and what not, but the 'found_post_id' value is the post id from the selected value from the pop up. Then you can check out lines 103 - 141 of upload.php to find code to do the actual re-attach. There might be a hook or something better, but I didn't have time to look.
Hope this helps!

So after a little help from Daniel and some research, I was finally able to make it work! Here's how my code looks now:
function spd_submitbox_misc_actions( $id ) {
global $pagenow, $typenow;
// We only want to run the code on a specific page
if( $pagenow != 'post.php' || $typenow != 'attachment' ) {
return;
}
$post = get_post( $id );
if( $post->post_parent > 0 ) {
if( get_post( $post->post_parent ) ) {
$title = _draft_or_post_title( $post->post_parent );
}
?>
<div class="misc-pub-section misc-pub-attachment">
Attached to: <strong><?php echo $title ?></strong>
<a class="hide-if-no-js" onclick="findPosts.open('action','find_posts');return false;" href="#"><?php _e( ' (Re-Attach) ' ); ?></a>
</div>
<?php
} else { ?>
<div class="misc-pub-section misc-pub-attachment">
Attached to: (Unattached) <a class="hide-if-no-js" onclick="findPosts.open('action','find_posts');return false;" href="#"><?php _e( 'Attach' ); ?></a>
</div>
<?php
}
}
add_action( 'attachment_submitbox_misc_actions', 'spd_submitbox_misc_actions' );
// Function to call the find_posts_div pop up OUTSIDE the post form
function spd_post_submitbox_misc_form() {
global $pagenow, $typenow;
// We only want to run on edit media page
if( $pagenow != 'post.php' || $typenow != 'attachment' )
return;
// Enqueue our scripts
wp_enqueue_style('thickbox');
wp_enqueue_script('thickbox'); // needed for find posts div
wp_enqueue_script('media');
wp_enqueue_script('wp-ajax-response');
$send_to = get_template_directory_uri() . '/inc/spdfunctions/spd_post_actions.php';
?>
<form name="attach-to-post" method="post" action="<?php echo $send_to; ?>">
<?php find_posts_div(); ?>
<input type="hidden" name="attach-to-post" value="attach" />
<input type="hidden" name="attachment-id" value="<?php the_ID(); ?>" />
</form>
<?php
}
add_filter('admin_footer','spd_post_submitbox_misc_form');
Then to process the submission:
if ( $_REQUEST['action'] && isset( $_POST['attach-to-post'] ) ) {
$location = $_SERVER['DOCUMENT_ROOT'];
include( $location . '/wp-load.php' );
$parent_id = $_POST['found_post_id'];
$attach_id = (int) $_POST['attachment-id'];
$attached = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( %d )", $parent_id, $attach_id ) );
//redirect back to edit media screen
if ( isset( $attached ) ) {
$referer = wp_get_referer();
$location = add_query_arg( array( 'attached' => $attached ) , $referer );
wp_redirect( $location );
}
}
Thanks again, Daniel, for all your help. It was very much appreciated!

Related

Adding custom checkbox to WooCommerce product variation options

I've added a custom field to variable products in the WC admin. Using the action:
action_woocommerce_variation_options_pricing
But it's displaying in the wrong location. I'd ideally like the checkbox to display in the options section above. But i can't find the action to move it there.
I've spent ages looking through the WC docs, but can't find the correct action. Does anyone know the correct way for me to move the checkbox to this location?
You can use the woocommerce_variation_options action hook, to add a custom checkbox to the WooCommerce product variation options.
(Copied from: views/html-variation-admin.php, line 188)
<?php do_action( 'woocommerce_variation_options', $loop, $variation_data, $variation ); ?>
So you get:
// Add checkbox
function action_woocommerce_variation_options( $loop, $variation_data, $variation ) {
$is_checked = get_post_meta( $variation->ID, '_mycheckbox', true );
if ( $is_checked == 'yes' ) {
$is_checked = 'checked';
} else {
$is_checked = '';
}
?>
<label class="tips" data-tip="<?php esc_attr_e( 'This is my data tip', 'woocommerce' ); ?>">
<?php esc_html_e( 'Checkbox:', 'woocommerce' ); ?>
<input type="checkbox" class="checkbox variable_checkbox" name="_mycheckbox[<?php echo esc_attr( $loop ); ?>]"<?php echo $is_checked; ?>/>
</label>
<?php
}
add_action( 'woocommerce_variation_options', 'action_woocommerce_variation_options', 10, 3);
// Save checkbox
function action_woocommerce_save_product_variation( $variation_id, $i ) {
if ( ! empty( $_POST['_mycheckbox'] ) && ! empty( $_POST['_mycheckbox'][$i] ) ) {
update_post_meta( $variation_id, '_mycheckbox', 'yes' );
} else {
update_post_meta( $variation_id, '_mycheckbox', 'no' );
}
}
add_action( 'woocommerce_save_product_variation', 'action_woocommerce_save_product_variation', 10, 2 );

How to display custom meta box value in single post in wordpress?

I am trying to make custom meta box and display it's value in single post,but code doesn't display value in single post.The value is stored in post at admin side,i want to display that value as front end side as well.Right now i am using twenty seventeen theme.i am using this code for custom meta box in function.php file:
add_action( 'add_meta_boxes', 'm_param_meta_box_add' );
function m_param_meta_box_add() {
add_meta_box( 'm_param_post', 'Box Title', 'm_param_post_meta_box_cb', 'post', 'normal', 'high' );
}
function m_param_post_meta_box_cb( $post )
{
$values = get_post_custom( $post->ID );
if ( isset( $values['m_meta_description'] ) ) {
$m_meta_description_text = esc_attr( $values['m_meta_description'][0] );
}
wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );
?>
<table class="form-table">
<tr valign="top">
<th scope="row"><label for="m_meta_description">Post Description</label></th>
<td><textarea rows="3" cols="50" name="m_meta_description"><?php echo $m_meta_description_text; ?></textarea></td>
</tr>
</table>
<?php
} // close m_param_post_meta_box_cb function
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $post_id )
{
// Bail if we're doing an auto save
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// if our nonce isn't there, or we can't verify it, bail
if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) ) return;
// Make sure your data is set before trying to save it
if( isset( $_POST['m_meta_description'] ) ) {
update_post_meta( $post_id, 'm_meta_description', wp_kses( $_POST['m_meta_description']) );
}
}
add_action('wp_head', 'add_to_wp_head');
function add_to_wp_head( )
{
if (is_single())
{
global $post;
$m_meta_description = get_post_meta($post->ID, 'm_meta_description', true);
echo '<meta name="description" content="' . $m_meta_description . '"/>';
}
}
The code that i am trying in single.php is look like:
<?php
add_action('wp_head', 'add_to_wp_head');
function add_to_wp_head( )
{
if (is_single())
{
global $post;
$m_meta_description = get_post_meta($post->ID, 'm_meta_description', true);
echo '<meta name="description" content="' . $m_meta_description . '"/>';
}
}
?>
Try to insert below code in your "template-parts/post/content" file
<?php
$m_meta_description = get_post_meta($post->ID, 'm_meta_description', true);
echo 'meta box value: ' . $m_meta_description;
?>
$meta = get_post_meta($post->ID,'meta-box-text', true);
if($meta != '') {
echo $meta;
}else {
echo "Can't Display The Content";
}
Use this code.
Here meta-box-text is the name attribute.
Don't forget to insert this code in loop
Another way:
$meta_print_value=get_post_meta(get_the_ID(),'meta-box-text',true);
echo($meta_print_value);

display value of custom field in woocommerce content-product.php

I want to display the value of a custom-field in the content-product.php in woocommerce. I did like this, but the output is only the word "array".
where is my mistake?
Thanks a lot!
rabox
<?php if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
global $product;
// Ensure visibility
if ( empty( $product ) || ! $product->is_visible() ) {
return;
}
?>
<li <?php post_class(); ?>>
<span class="product_additional_info"><?php echo get_post_meta($post-
>ID, ‚additional-info‘, true); ?></span>
I found a piece of code that works here https://wordpress.stackexchange.com/questions/179451/unable-to-display-custom-fields-on-woocommerce-product-pages
It goes like that:
<?php
$custom_fields = get_post_custom($post->ID);
$my_custom_field = $custom_fields["Name of your Field"];
foreach ( $my_custom_field as $key => $value ) {
echo "<strong>$key: </strong> $value <br />";
}
?>
Would be interesting to know why I cannot use the "wordpress-way" of using custom fields.
Woocommerce content-product.php uses global $product; so you can get the product id with $product->get_id()
Now, you can get the value of custom field by passing the product id and custom field name in get_post_meta();
Example: get_post_meta( $product->get_id(), '_your_custom_field', true );

Unable to Save Rev Slider in custom mets box

I'm in the process of creating a custom meta box for pages. One of the primary functions of this metabox is to be able to call in a Revolution Slider. At this point I am able to create a dropdown that displays all available revsliders created but I am not able to save them and call them. Below is my code, perhaps someone can tell me what I am doing wrong.
function simplex_page_theme ($post) {
$values = get_post_custom($post->ID);
$revslider = isset( $values['revslider'] ) ? esc_attr( $values['revslider'][0] ) : ”;
wp_nonce_field( 'simp_meta_box', 'simplex_meta_box_nonce' );
?>
<tr valign="top">
<td>
<?php $revslider = new RevSlider();
$arrSliders = $revslider->getArrSliders();
if( empty( $arrSliders ) ) : ?>
<div style="background-color:#FFFFE0; border:1px solid #E6DB55; padding:0 0.8em; margin:0;">
<p style="font-weight:bold; margin:7px 0;"><?php printf( __('No sliders found! Please create a new slider from the %1$sRevolution Slider%2$s page.'), '', '' ); ?></p>
</div>
<?php else : ?>
<label for="current_rev_slider"><?php esc_html_e('Choose a Revolution Slider:'); ?></label><br />
<select name="rev_slider_shortcode" id="current_rev_slider">
<option value=""<?php echo (get_option('revslider') == '') ? ' selected="selected"' : ''; ?>><?php esc_html_e('--Select Slider--'); ?></option>
<option value="<?php echo $revslider->getShortcode(); ?>"><?php echo $revslider->getTitle(); ?></option>
<?php foreach( $arrSliders as $revslider ): ?>
<?php endforeach; ?>
</select><br />
<em><?php printf( __('To create additional sliders or to configure the existing ones please refer to the %1$sRevolution Slider%2$s page.'), '<a title="'.esc_html__('Go to Revolution Slider page').'" href="admin.php?page=revslider">', '</a>' ); ?></em><br />
<div class="clear"></div>
<?php endif; ?>
</td>
</tr>
<?php }
// Saves the Custom Metabozes
add_action( 'save_post', 'simplex_meta_box_save' );
function simplex_meta_box_save( $post_id ){
// Bail if we're doing an auto save
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// if our nonce isn't there, or we can't verify it, bail
if( !isset( $_POST['simplex_meta_box_nonce'] ) || !wp_verify_nonce( $_POST['simplex_meta_box_nonce'], 'simp_meta_box' ) ) return;
// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) ) return;
// now we can actually save the data
$htmallowed = array(
'a' => array( // on allow a tags
'href' => array() // and those anchors can only have href attribute
)
);
// Make sure your data is set before trying to save it
if( isset( $_POST['revslider'] ) )
update_post_meta( $post_id, 'revslider', esc_attr( $_POST['revslider'] ) );
}
Have a look at this tutorial about creating and saving meta boxes. It should point you in the right direction. http://www.smashingmagazine.com/2011/10/04/create-custom-post-meta-boxes-wordpress/

Add vote system to custom content type in wordpress

I have a custom theme for an online shop (http://themeforest.net/item/mayashop-a-flexible-responsive-ecommerce-theme/2189918) that comes with multiple content types (besides the default post type) and I need to add some kind of vote system to one of this non-default content types ( specifically to the product content type so users can vote the products they like of my shop).
Is there any plugin that provides this funcionality?
Thanks
There are a lot of plugins that do this , you can just google them up,
But if you want to know how it can be easily (and primitivly) done with the help of custom fields , then here you go :
add_action( 'wp_ajax_nopriv_o99__action', 'o99__ajax_cb' );
add_action( 'wp_ajax_o99__action', 'o99__ajax_cb' );
// this fanction is the ajax callback.
function o99__ajax_cb(){
// Verify the nonce to make sure the request is ours and legael...
if( !isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'o99__nonce' ) ) die( '-1' );
$post_id = isset( $_REQUEST['post_id'] ) ? absint( $_REQUEST['post_id'] ) : 0;
if( ! $post_id ) die( '-1' );
$counter = get_post_meta( $post_id, 'o99_good_post', true );
$counter = absint( $counter );
$cookie = 'o99_post_vote' .$post_id;
if( $counter){
if (!isset($_COOKIE[$cookie]) ) {
$counter++;
}
else {$counter=$counter;}
}
else{
$counter = mt_rand(20,150);
}
update_post_meta( $post_id, 'o99_good_post', $counter ); //hidden field
echo $counter;
die();
}
function o99__good_bad(){
global $post;
// send a simple cookie
$cookie = 'o99_post_vote' .$post_id;
$count = get_post_meta( $post->ID, 'o99_good_post', true ); //hidden field
if (!$count ){
$count = '0';
}
$icon = '<img src="';
$icon .= get_bloginfo('template_url') ; // better using get_stylesheet_uri() now
if (!isset($_COOKIE[$cookie]) ) {
$icon .= '/images/dl-star16.png"/>'; // set up your icons according to case
}
else {
$icon .= '/images/dl-v16.png"/>';
}
?>
<span id="o99__click" title="Click Here to Vote this Post up"><?php echo $icon; ?> click here to vote up
This post was voted <span id="o99__count"><?php echo strip_tags( $count );?>
</span> times</span>
<?php
}
// just injecting the JS into head --
add_action( 'wp_head', 'o99__head' );
function o99__head()
{
if( ! is_singular() ) return;
$post_id = get_queried_object_id();
?>
<script type="text/javascript">
var o99__data = {
action: 'o99__action',
post_id: '<?php echo absint( $post_id ); ?>',
nonce: '<?php echo wp_create_nonce( 'o99__nonce' ); ?>',
}
jQuery(document).ready(function(){
jQuery( '#o99__click' ).click(function(){
jQuery.get(
'<?php echo site_url( 'wp-admin/admin-ajax.php' ); ?>',
o99__data,
function( data ){
if(jQuery.cookie('o99_post_vote<?php echo absint( $post_id ); ?>') != null) {
alert( 'You can only vote once per post!' );
};
if(jQuery.cookie('o99_post_vote<?php echo absint( $post_id ); ?>') == null) {
if( '-1' != data )
{
jQuery( 'span#o99__count' ).html( data );
jQuery.cookie('o99_post_vote<?php echo absint( $post_id ); ?>', 'voted', { expires: 7 });
alert( 'your vote was accepted!' );
};
}
}
);
});
});
</script>
<?php
}
?>
This is a very old function that was hacked a long time ago, it should still work, but maybe need a bit of polish ..
Edit I
some examples of more complex plugins :
http://wordpress.org/extend/plugins/post-ratings/
http://wordpress.org/extend/plugins/post-ratings/screenshots/
http://wordpress.org/extend/plugins/gd-star-rating/
and if you will search the codex you will find much more ..
Those listed above support custom post types .

Resources