A bite of bits

Have a seat and enjoy the madewithlove team's development stories.

Happy birthday, wp-cli

It has been a year since I made the first commit on what is now known as the wp-cli project. The progress the project made in one year is amazing and thanks to that, wp-cli’s usage has become widespread and an increasing number of companies have started to use it in their production environments.
Read the rest of this entry »

WP-CLI: WordPress Command Line Tools

Have you ever tried to automate WordPress upgrade tasks or deployments? I did, it was a big pain.

Sometimes I would find myself updating WordPress options on 54 different blogs trough the admin interface. Completely tired of it I created a little tool to automate these kind of things trough the command line interface (like every self respecting developer would do). The wp-cli project was born. 

Read the rest of this entry »

Handling WordPress uploads anywhere

We are currently working on a WordPress project where visitors need to be able to upload images for a competition. Their data is stored as a custom post type but we wondered how we’d store their image uploads? We can’t upload them trough regular php and add a meta to the post linking to the image, but what about WordPress’s different image sizes and media management?

The solution turns out to be really easy if we use the WordPress function media_handle_upload. It works with the normal $_FILES array, resizes your image, and gives back the attachment id.

Read the rest of this entry »

The real wpmu_delete_user

// @todo Merge with wp_delete_user() ?

Like they suggest in their comment the wpmu_delete_user function is not ready yet. When deleting a user, WordPress does not allow you to reassign the user’s content to another user. My rewrite below is a merge with the wp_delete_user that lets you do so.

function wpmu_delete_user($id, $reassign) {
    global $wpdb;

    $id = (int) $id;

    do_action( 'wpmu_delete_user', $id );

    $blogs = get_blogs_of_user( $id );

    if ( ! empty( $blogs ) ) {
        foreach ( $blogs as $blog ) {
            switch_to_blog( $blog->userblog_id );
            remove_user_from_blog( $id, $blog->userblog_id );

            if ( 'novalue' === $reassign || null === $reassign ) {
                $post_ids = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id) );

                if ( $post_ids ) {
                    foreach ( $post_ids as $post_id )
                        wp_delete_post($post_id);
                }

                // Clean links
                $link_ids = $wpdb->get_col( $wpdb->prepare("SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id) );

                if ( $link_ids ) {
                    foreach ( $link_ids as $link_id )
                        wp_delete_link($link_id);
                }
            } else {
                $reassign = (int) $reassign;
                $wpdb->update( $wpdb->posts, array('post_author' => $reassign), array('post_author' => $id) );
                $wpdb->update( $wpdb->links, array('link_owner' => $reassign), array('link_owner' => $id) );
            }

            restore_current_blog();
        }
    }

    // FINALLY, delete user
    $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d", $id) );
    $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->users WHERE ID = %d", $id) );

    clean_user_cache( $id );

    // allow for commit transaction
    do_action( 'deleted_user', $id );

    return true;
}

I think it would be even better to use the wp_delete_user function in this function instead of just copying the code, by doing that the hooks would be triggered for each blog which would allow each’s plugins to do their thing.