1

I was searching for a way to enable/use a workflow for uploaded files (in my case pictures). Users with specific roles/capabilities should be able to upload files that are connected to a post. The post also has an custom field that holds an array used as gallery in the post view.

What I want is:
1. User uploads file
2. Attachment post is generated via media_handle_upload
3. Attachment gets "pending" post_status
4. Id is added to array
5. Admin only needs to change post_status and picture is visible

In this case it would be easy to show only attachments with post_status != "pending". As far as I see this is not possible with Wordpress.

My two solutions at the moment would be:
1. Let admin add the file to the array when picture is okay
2. Use a meta field for the attachment post to get a workflow

Is there a Worpress way I'm not seeing at the moment or should I use one of my two solustions?

I'm using Wordpress 4.9.8

  • You shouldn't need a post meta field, the post status does that job just fine. But if you did need a field, a taxonomy would be 1000x faster than a post meta field, especially since you're going to be filtering, and you should never search for posts based on what their meta contains, it's a performance and scaling nightmare – Tom J Nowell Oct 9 '18 at 13:40
  • @TomJNowell Maybe I misunderstand the post status field in my context. I thought that attachment post types always have "inherit". The reference for the function get_post_status says that you will get the id of parent post and not the attachment itself. That lead me to the conclusion that changing the post status of an attachment is not the right approach. And thanks for pointing out using a taxonomy instead of a custom field. – Michael N. Oct 9 '18 at 14:08
  • You can give it a different post status, after all they're still posts. inherit is not an attachment specific thing, it's a general thing. A page would behave the same way if it was given a status of inherit. The post status is not the problem, it's building the UI and filtering things – Tom J Nowell Oct 9 '18 at 14:10
  • Ok that makes sense and would be the best option. One last question, When the post type is other than inherit, get_post_status would return the status of the attachment or still the parent posts? – Michael N. Oct 9 '18 at 14:16
  • 1
    Thank you very much. When I'm finished with the code I will post my solution here. Maybe it is helping future readers – Michael N. Oct 9 '18 at 18:29
0

Here is how I realized a simple media workflow. Security checking and sanitizing is up to everyone.

Based on Wordpress version: 4.9.8

Create Attachment Post | Handle Media

if (!empty($_FILES) && isset($_POST['postid'])) {
  media_handle_upload("attachments", $_POST['postid']);
}

Post status pending is not possible for attachments when using media_handle_upload. For this case a filter needs to be used. This Filter should be added before using media_handle_upload.

add_filter('wp_insert_attachment_data', 'SetAttachmentStatusPending', '99');

function SetAttachmentStatusPending($data) {
  if ($data['post_type'] == 'attachment') {
    $data['post_status'] = 'pending';
  }

  return $data;
}

Now the attachment post is added with pending post_status.

Show pending posts in media library

Worpress Media Library shows only posts with private or inherit post_status. To show posts with pending status we can hook in

add_action('pre_get_posts', array($this, 'QueryAddPendingMedia'));

function QueryAddPendingMedia($query)
{
  // Change query only for admin media page
  if (!is_admin() || get_current_screen()->base !== 'upload') {
    return;
  }

  $arr = explode(',', $query->query["post_status"]);
  $arr[] = 'pending';
  $query->set('post_status', implode(',', $arr));
}

Actions and Bulk Actions

To complete the workflow we need something to publish pending media. To do this we can add (bulk) actions to the media library.

Add Bulk Action

add_filter('bulk_actions-upload', 'BulkActionPublish');

function BulkActionPublish($bulk_actions)
{
  $bulk_actions['publish'] = __('Publish');

  return $bulk_actions;
}

Add Row Action

To add a link to the row actions this code is useful

add_filter('media_row_actions', 'AddMediaPublishLink', 10, 3);

function AddMediaPublishLink(array $actions, WP_Post $post, bool $detached)
{
  if ($post->post_status === 'pending') {
    $link = wp_nonce_url(add_query_arg(array('act' => 'publish', 'itm' => $post->ID), 'upload.php'), 'publish_media_nonce');
    $actions['publish'] = sprintf('<a href="%s">%s</a>', $link, __("Publish"));
  }

  return $actions;
}

Handle Actions

add_action('load-upload.php', 'RowActionPublishHandle');
add_filter('handle_bulk_actions-upload', 'BulkActionPublishHandler', 10, 3);

function BulkActionPublishHandler($redirect_to, $doaction, $post_ids)
{
  if ($doaction !== 'publish') {
    return $redirect_to;
  }

  foreach ($post_ids as $post_id) {
    wp_update_post(array(
      'ID' => $post_id,
      'post_status' => 'publish'
    ));
  }

  return $redirect_to;
}

function RowActionPublishHandle()
{
  // Handle publishing only for admin media page
  if (!is_admin() || get_current_screen()->base !== 'upload') {
    return;
  }

  if (isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'publish_media_nonce')) {
    if (isset($_GET['act']) && $_GET['act'] === 'publish') {
      wp_update_post(array(
        'ID' => $_GET['itm'],
        'post_status' => 'publish'
      ));
    }
  }
}

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.