1

Ive got the following code for a WordPRess plugin that essentially add two custom inputs on each page/post edit screen. The values are then saved and output in the header of the frontend page.

The code works fine if it is located inside a .php file and dropped straight into 'wp-content/plugins'. However, if I put it in its own folder inside plugins eg 'wp-content/plugins/myplugin' the input fields are not saved when saving the post/page via the edit screen. Additionally nothing it output to the frontend pages html head section.

It seems like this is an abandoned project so Ive been unable to work with the original developer to work out a solution. However, it would certainly seem that by something in the code needs to be updated to reflect that the code is placed insicde a plugin folder.

Heres the code.....

<?php


$clinical_post_types = array();
//add all post types
$post_types = get_post_types(); 
foreach ( $post_types as $post_type ) {
 $clinical_post_types[] = $post_type;
 //echo 'POST TYPES: ' .$post_type;
}

// Meta box
// -----------------------------------------------------------------
// Add the language metabox on every registered custom post type
function clinical_add_language_metaboxe() {
 global $clinical_post_types;
foreach ($clinical_post_types as $post_type) {
 add_meta_box('clinical_meta_box', __('Search Engine Optimization', 'clinical'), 'clinical_meta_custom_box', $post_type, 'normal', 'default');
 }
}

// The Post's meta fields Metabox
function clinical_meta_custom_box() {
 global $post;
 echo '<input type="hidden" name="clinicalmeta_noncename" '
 . 'id="clinicalmeta_noncename" value="'
 . wp_create_nonce( plugin_basename(__FILE__) ) . '/seo_fields.php" />';
 // Get the meta fields data if its already been entered
 $meta_title = get_post_meta($post->ID, '_clinical_meta_title', true);
 $meta_description = get_post_meta($post->ID, '_clinical_meta_description', true);
 // Echo out the field
 $html = '<p><label for="clinical_meta_title"><strong>'. __('Title', 'clinical') .'</strong></label></p>';
 $html .= '<p><input type="text" class="regular-text" name="_clinical_meta_title" id="clinical_meta_title" value="'. $meta_title .'" /></p>';
 $html .= '<p><label for="clinical_meta_description"><strong>'. __('Description', 'clinical') .'</strong></label></p>';
 $html .= '<p><textarea class="large-text" name="_clinical_meta_description" id="clinical_meta_description">'. $meta_description .'</textarea></p>';
 echo $html;
}

// Save the metabox data
function clinical_save_post_meta($post_id, $post) {
 global $clinical_post_types;
 $key_title = '_clinical_meta_title';
 $key_description = '_clinical_meta_description';
 // if we're not in a clinical-enabled post type, skip.
if (in_array($post->post_type, $clinical_post_types)) 
 return $post;
// verify this came from our screen and with proper authorization,
// because save_post can be triggered at other times
if ((empty($_POST[$key_title]) && empty($_POST[$key_description])) || empty($_POST['clinicalmeta_noncename']) || !wp_verify_nonce($_POST['clinicalmeta_noncename'],   plugin_basename(__FILE__).'/seo_fields.php')
|| !current_user_can('edit_post', $post->ID)
) {
return $post->ID;
}
// OK, we're authenticated: we need to find and save the data
$title = $_POST[$key_title];
$description = $_POST[$key_description];
// set the post's meta title:
$updated_title = update_post_meta($post->ID, $key_title, $title);
$updated_description = update_post_meta($post->ID, $key_description, $description);
// Delete if blank:
if (!$title) delete_post_meta($post->ID, $key_title);
if (!$description) delete_post_meta($post->ID, $key_description);
}

// Filters
function clinical_wp_title_filter($title) {
 global $post;
 $seo_title = get_post_meta($post->ID, '_clinical_meta_title', true);
 if (!empty($seo_title)) 
  return $seo_title;
 return $title;
}

function clinical_wp_head_action() {
 global $post;
 $seo_description = get_post_meta($post->ID, '_clinical_meta_description', true);
 if (!empty($seo_description)) {
  echo '<!-- Clinical CMS SEO -->
  <meta name="description" content="'. esc_attr($seo_description) .'" />
  <!-- END Clinical CMS  SEO -->';
 }
}

// Helpers
// Filters and Hooks
add_action('admin_init', 'clinical_add_language_metaboxe');
add_action('save_post', 'clinical_save_post_meta', 1, 2);
add_filter('wp_title', 'clinical_wp_title_filter');
add_action('wp_head', 'clinical_wp_head_action');
  • does the file contain a valid plugin header? – Milo Jul 17 '15 at 17:10
  • Yes, I just removed that for simplicity. Also, as mentioned this works fine when run directly from the plugins folder. Its only when place in its own folder (eg 'wp-content/plugins/myplugin/') that the info fails to save. – Phill Healey Jul 18 '15 at 20:37
  • Maybe it's a nonce issue? – Milo Jul 18 '15 at 21:55
  • That was something I was considering but I don't understand why it would be.... Any pointers would be appreciated. – Phill Healey Jul 19 '15 at 17:30
  • @Milo I forgot to tag you in my reply... – Phill Healey Jul 25 '15 at 18:55
3
+25

Here is the fixed and modified code which was having the nonce action issue.

<?php
/*
Plugin Name: Test Plugin
Plugin URI: Test
Description: Test
Author: Test
Version: 007
Author URI:
*/

// add all post types
$clinical_post_types = array();
$post_types          = get_post_types();
foreach ( $post_types as $post_type ) {
    $clinical_post_types[] = $post_type;
}

// Meta box
// Add the language metabox on every registered custom post type
function clinical_add_language_metaboxe() {
    global $clinical_post_types;
    foreach ( $clinical_post_types as $post_type ) {
        add_meta_box( 'clinical_meta_box', __( 'Search Engine Optimization', 'clinical' ), 'clinical_meta_custom_box', $post_type, 'normal', 'default' );
    }
}

// The Post's meta fields Metabox
function clinical_meta_custom_box() {
    global $post;

    // Get the meta fields data if its already been entered
    $meta_title       = get_post_meta( $post->ID, '_clinical_meta_title', true );
    $meta_description = get_post_meta( $post->ID, '_clinical_meta_description', true );

    echo '<input type="hidden" name="clinicalmeta_noncename" id="clinicalmeta_noncename" value="' . wp_create_nonce( "clinicalmeta_nonce_action" ) . '" />';

    // Echo out the field
    $html = '<p><label for="clinical_meta_title"><strong>' . __( 'Title', 'clinical' ) . '</strong></label></p>';
    $html .= '<p><input type="text" class="regular-text" name="_clinical_meta_title" id="clinical_meta_title" value="' . $meta_title . '" /></p>';
    $html .= '<p><label for="clinical_meta_description"><strong>' . __( 'Description', 'clinical' ) . '</strong></label></p>';
    $html .= '<p><textarea class="large-text" name="_clinical_meta_description" id="clinical_meta_description">' . $meta_description . '</textarea></p>';
    echo $html;
}

// Save the metabox data
function clinical_save_post_meta( $post_id, $post ) {
    global $clinical_post_types;

    $key_title       = '_clinical_meta_title';
    $key_description = '_clinical_meta_description';

    // if we're not in a clinical-enabled post type, skip.
    if ( in_array( $post->post_type, $clinical_post_types ) ) {
        // return $post;
    }
    // verify this came from our screen and with proper authorization,
    // because save_post can be triggered at other times
    if ( ( empty( $_POST[ $key_title ] ) && empty( $_POST[ $key_description ] ) ) || empty( $_POST['clinicalmeta_noncename'] ) || ( ! wp_verify_nonce( $_POST['clinicalmeta_noncename'], "clinicalmeta_nonce_action" ) ) || ( ! current_user_can( 'edit_post', $post->ID ) ) ) {
        return $post->ID;
    }
    // OK, we're authenticated: we need to find and save the data
    $title       = $_POST[ $key_title ];
    $description = $_POST[ $key_description ];

    // set the post's meta title:
    $updated_title       = update_post_meta( $post->ID, $key_title, $title );
    $updated_description = update_post_meta( $post->ID, $key_description, $description );
    // Delete if blank:
    if ( empty( $title ) ) {
        delete_post_meta( $post->ID, $key_title );
    }
    if ( empty( $description ) ) {
        delete_post_meta( $post->ID, $key_description );
    }
}

// Filters
function clinical_wp_title_filter( $title ) {
    global $post;
    $seo_title = get_post_meta( $post->ID, '_clinical_meta_title', true );
    if ( ! empty( $seo_title ) ) {
        return $seo_title;
    }

    return $title;
}

function clinical_wp_head_action() {
    global $post;
    $seo_description = get_post_meta( $post->ID, '_clinical_meta_description', true );
    if ( ! empty( $seo_description ) ) {
        echo '<!-- Clinical CMS SEO --> <meta name="description" content="' . esc_attr( $seo_description ) . '" /> <!-- END Clinical CMS  SEO -->';
    }
}

// Helpers
// Filters and Hooks
add_action( 'admin_init', 'clinical_add_language_metaboxe' );
add_action( 'save_post', 'clinical_save_post_meta', 1, 2 );
add_filter( 'wp_title', 'clinical_wp_title_filter' );
add_action( 'wp_head', 'clinical_wp_head_action' );
  • Nope, that doesn't work either. – Phill Healey Jul 27 '15 at 20:14
  • I updated the code with commenting out a line. Can you please try with the updated code once more ? Also, does it through any errors ? – Subharanjan Jul 28 '15 at 2:28
1

This is an issue with the creation of the nonce.

wp_create_nonce( plugin_basename(__FILE__) ) . '/seo_fields.php" />

should probably be

wp_create_nonce( plugin_basename(__FILE__) . '/seo_fields.php' ) . '" />

because otherwise

!wp_verify_nonce($_POST['clinicalmeta_noncename'],   plugin_basename(__FILE__).'/seo_fields.php')

would not check for the same action.

See: https://codex.wordpress.org/Function_Reference/wp_verify_nonce#Parameters

drops mic

  • 2
    Why is it that most problems are due to tiny little foolish errors? Your answer sounds very probable. I'll check it out tomorrow and then let you know. Thanks. – Phill Healey Jul 28 '15 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.