0

I am currently following a tutorial by Steven Slack on s2webpress.com on how to add an Author Image upload field to a user Profile page. I've managed to get most of it working, except for the part that allows me to use the WP 3.5 media manager system.

The jQuery snippet that I'm trying to add is inside this code:

/**
 * Adds additional user fields
 * more info: http://justintadlock.com/archives/2009/09/10/adding-and-using-custom-user-profile-fields
 */

function bck_authorimagefield( $user ) { ?>

    <h3><?php _e( 'Author Image', 'textdomain' ); ?></h3>

    <table class="form-table">

        <tr>
            <th><label for="user_meta_image"><?php _e( 'The author profile picture', 'textdomain' ); ?></label></th>
            <td>
                <!-- Outputs the image after save -->
                <img src="<?php echo esc_url( get_the_author_meta( 'user_meta_image', $user->ID ) ); ?>" style="width:150px;"><br />
                <!-- Outputs the text field and displays the URL of the image retrieved by the media uploader -->
                <input type="text" name="user_meta_image" id="user_meta_image" value="<?php echo esc_url_raw( get_the_author_meta( 'user_meta_image', $user->ID ) ); ?>" class="regular-text" />
                <!-- Outputs the save button -->
                <input type='button' class="additional-user-image button-primary" value="<?php _e( 'Upload Image', 'textdomain' ); ?>" id="uploadimage"/><br />
                <span class="description"><?php _e( 'Upload an additional image for your user profile.', 'textdomain' ); ?></span>
            </td>
        </tr>

    </table><!-- end form-table -->
<?php } // bck_authorimagefield

add_action( 'show_user_profile', 'bck_authorimagefield' );
add_action( 'edit_user_profile', 'bck_authorimagefield' );

/**
* Saves additional user fields to the database
*/
function bck_saveauthorimagefield( $user_id ) {

    // only saves if the current user can edit user profiles
    if ( !current_user_can( 'edit_user', $user_id ) )
        return false;

    update_usermeta( $user_id, 'user_meta_image', $_POST['user_meta_image'] );
}

add_action( 'personal_options_update', 'bck_saveauthorimagefield' );
add_action( 'edit_user_profile_update', 'bck_saveauthorimagefield' );


/*
 * Adapted from: http://mikejolley.com/2012/12/using-the-new-wordpress-3-5-media-uploader-in-plugins/
 */
jQuery(document).ready(function($){
// Uploading files
var file_frame;

  $('.additional-user-image').on('click', function( event ){

    event.preventDefault();

    // If the media frame already exists, reopen it.
    if ( file_frame ) {
      file_frame.open();
      return;
    }

    // Create the media frame.
    file_frame = wp.media.frames.file_frame = wp.media({
      title: $( this ).data( 'uploader_title' ),
      button: {
        text: $( this ).data( 'uploader_button_text' ),
      },
      multiple: false  // Set to true to allow multiple files to be selected
    });

    // When an image is selected, run a callback.
    file_frame.on( 'select', function() {
      // We set multiple to false so only get one image from the uploader
      attachment = file_frame.state().get('selection').first().toJSON();

      // Do something with attachment.id and/or attachment.url here
    });

    // Finally, open the modal
    file_frame.open();
  });

});
/**
 * Return an ID of an attachment by searching the database with the file URL.
 *
 * First checks to see if the $url is pointing to a file that exists in
 * the wp-content directory. If so, then we search the database for a
 * partial match consisting of the remaining path AFTER the wp-content
 * directory. Finally, if a match is found the attachment ID will be
 * returned.
 *
 * http://frankiejarrett.com/get-an-attachment-id-by-url-in-wordpress/
 *
 * @return {int} $attachment
 */
function bck_getattachmentimagebyurl( $url ) {

    // Split the $url into two parts with the wp-content directory as the separator.
    $parse_url  = explode( parse_url( WP_CONTENT_URL, PHP_URL_PATH ), $url );

    // Get the host of the current site and the host of the $url, ignoring www.
    $this_host = str_ireplace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) );
    $file_host = str_ireplace( 'www.', '', parse_url( $url, PHP_URL_HOST ) );

    // Return nothing if there aren't any $url parts or if the current host and $url host do not match.
    if ( !isset( $parse_url[1] ) || empty( $parse_url[1] ) || ( $this_host != $file_host ) ) {
        return;
    }

    // Now we're going to quickly search the DB for any attachment GUID with a partial path match.
    // Example: /uploads/2013/05/test-image.jpg
    global $wpdb;

    $prefix     = $wpdb->prefix;
    $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM " . $prefix . "posts WHERE guid RLIKE %s;", $parse_url[1] ) );

    // Returns null if no attachment is found.
    return $attachment[0];
}

/*
 * Retrieve the appropriate image size
 */
function bck_getadditionalusermetathumb() {

    $attachment_url = esc_url( get_the_author_meta( 'user_meta_image', $post->post_author ) );

    // grabs the id from the URL using Frankie Jarretts function
    $attachment_id = bck_getattachmentimagebyurl( $attachment_url );

    // retrieve the thumbnail size of our image
    $image_thumb = wp_get_attachment_image_src( $attachment_id, 'thumbnail' );

    // return the image thumbnail
    return $image_thumb[0];

}

function bck_displayauthorimage() {
// retrieve our additional author meta info
$user_meta_image = esc_attr( get_the_author_meta( 'user_meta_image', $post->post_author ) );

    // make sure the field is set
    if ( isset( $user_meta_image ) && $user_meta_image ) {

        // only display if function exists
        if ( function_exists( 'bck_getadditionalusermetathumb' ) ) ?>
            <img alt="author photo" src="<?php echo bck_getadditionalusermetathumb(); ?>" class="author-photo" />

    <?php }      

}

However, when I try to activate the plugin that this author image code is contained in, I get the following error:

Parse error: syntax error, unexpected '$', expecting '&' or variable (T_VARIABLE) in [the file's base URL]/authorimage.php on line 154

Line 154 is the first line of that jQuery snippet that I added above. I removed that snippet from the plugin altogether, and just left everything else, and it worked up to the point that no dialog box appeared when I press Upload Image on the User Profile page.

Am I missing something here? I thought PHP could have jQuery in it, so long as it started with: jQuery(document).ready(function($){ ....

  • Looks like you're embedding your jQuery in authorimage.php, show the rest of the file. The error is PHP generated, and much probably just a syntax error, a missing comma, bracket or brace, something like that: stackoverflow.com/… – brasofilo Oct 12 '13 at 4:06
  • Hi brasofilo, I've combed through the code and couldn't find any syntax errors, though it's possible that I've missed something! I've pasted the full code here:pastebin.com/R0v6cW1h - the jQuery starts on line 50 – tristanojbacon Oct 14 '13 at 17:02
2

Yes, PHP can have JavaScript (and CSS and HTML) in it, but you must tell: "here ends PHP -> other language -> here starts PHP", like so:

<?php
echo '<div id="hide-me">something</div>';
?>
<script>
// some JS to hide the div
</script>
<?php
echo 'another thing';

On the other hand, your code will not work because you're dumping the JS in the middle of nowhere. It's not clear if you're doing a plugin (which you should) or using it on the theme. In themes, sometimes, you're allowed to do that, but it's not the case here.

You need to add that JS code as a separate file and use:

add_action( 'admin_enqueue_scripts', 'profile_script_wpse_117593' );

function profile_script_wpse_117593( $hook_suffix ) 
{
    if ( 'profile.php' == $hook_suffix ) 
    {
        // URL TO USE IN A PLUGIN: plugins_url( '/js/script.js', __FILE__ );
        wp_enqueue_script( 
             'my-script' // Handle
            , get_stylesheet_directory_uri() . '/js/script.js' // Theme URL
            , array( 'jquery' ) // Dependencies
            , false // Version
            , true // In footer
        );
    }
}

Or we can be lazy and print it directly in the profile page footer:

add_action( 'admin_footer-profile.php', 'dump_script_wpse_117593' );

function dump_script_wpse_117593()
{
    ?>
        <script type="text/javascript">
        jQuery(document).ready(function ($){
            alert('in!');
        });
        </script>
    <?php
}

Note that's important to target our screen, so as not to enqueue the script all over the admin area.

  • Thanks for that brasofilo, I'll try out the 2nd one. This is in a plugin, not in the theme's functions.php file – tristanojbacon Oct 26 '13 at 22:32
  • I placed it in it's own JS file, and used the second block of code you recommended. However, I get this error when I click the Add Image button on the profile page: Uncaught TypeError: Cannot read property 'frames' of undefined, on line 16, which is the line with file_frame = wp.media.frames.file_frame = wp.media({ - any thoughts on what the issue could be? My jQuery/Javascript experience is pretty minimal... – tristanojbacon Oct 26 '13 at 22:38
0

This is definitely meant to be used like a plugin as mentioned above. The jquery is supposed to be put into an appropriate script file in a plugin. I will update the article and mention that the code is not supposed to be drop in and use code.

It should be used as a demonstration of methods only.

  • Thanks Steven. I am in fact writing this in a plugin, not in the functions.php file – tristanojbacon Oct 26 '13 at 22:32

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.