admin管理员组

文章数量:1332873

I'm using the WP-JSON API to import all my posts from my live site to my development site. It's working fine for posts, categories and authors, but when I upload my images, the API treats the files as having been uploaded that day (so for example, as we're in June 2020, the files all go to wp-content/uploads/2020/06), which results in broken image links. How can I upload files as if they're uploaded on the same date as the source file?

Here's what I have so far (where $MEDIA is a response from my production server to /wp-json/wp/v2/media to list all my media files):

# Loop through the JSON response (encoding as base64, so each object is on a seperate line)
for media in $(printf %s "$MEDIA" | jq -r ".[] | @base64")
do
  media_body=$(printf %s "$media" | base64 -D)
  # Get URL and destination path
  source_url=$(printf %s "$media_body" | jq .source_url | tr -d '"')
  destination_path=$(printf %s "$media_body" | jq .media_details.file | tr -d '"')

  filename=$(basename "$destination_path")

  # Download media file to tmp directory
  curl -s "$source_url" > "/tmp/$filename"

  # Upload the media file to my dev server (store the response as a variable so we can get the ID)
  response=$(curl --request POST "http://localhost/wp-json/wp/v2/media/" \
    -u admin:admin \
    -s \
    --header "cache-control: no-cache" \
    --header "content-disposition: attachment; filename=$filename" \
    --data-binary "@/tmp/$filename" \
    --location)

  id=$(printf %s "$response" | jq -r ". | .id")
  body=$(printf %s "$media_body" | jq -r ". | {date: .date, date_gmt: .date_gmt, slug: .slug, status: \"publish\", title: .title.rendered}")

  # This outputs body eg {"date": "2020-05-27T12:12:53", "date_gmt": "2020-05-27T12:12:53", "slug": "cropped-shortcut-icon-png", "status": "publish", "title": "cropped-shortcut-icon.png" }

  # Update the image's metadata
  curl --location --request POST "http://localhost/wp-json/wp/v2/media/$id" \
    -u admin:admin \
    -s -o /dev/null \
    --header 'Content-Type: application/json' \
    --data-raw "$body"
done

I'm using the WP-JSON API to import all my posts from my live site to my development site. It's working fine for posts, categories and authors, but when I upload my images, the API treats the files as having been uploaded that day (so for example, as we're in June 2020, the files all go to wp-content/uploads/2020/06), which results in broken image links. How can I upload files as if they're uploaded on the same date as the source file?

Here's what I have so far (where $MEDIA is a response from my production server to /wp-json/wp/v2/media to list all my media files):

# Loop through the JSON response (encoding as base64, so each object is on a seperate line)
for media in $(printf %s "$MEDIA" | jq -r ".[] | @base64")
do
  media_body=$(printf %s "$media" | base64 -D)
  # Get URL and destination path
  source_url=$(printf %s "$media_body" | jq .source_url | tr -d '"')
  destination_path=$(printf %s "$media_body" | jq .media_details.file | tr -d '"')

  filename=$(basename "$destination_path")

  # Download media file to tmp directory
  curl -s "$source_url" > "/tmp/$filename"

  # Upload the media file to my dev server (store the response as a variable so we can get the ID)
  response=$(curl --request POST "http://localhost/wp-json/wp/v2/media/" \
    -u admin:admin \
    -s \
    --header "cache-control: no-cache" \
    --header "content-disposition: attachment; filename=$filename" \
    --data-binary "@/tmp/$filename" \
    --location)

  id=$(printf %s "$response" | jq -r ". | .id")
  body=$(printf %s "$media_body" | jq -r ". | {date: .date, date_gmt: .date_gmt, slug: .slug, status: \"publish\", title: .title.rendered}")

  # This outputs body eg {"date": "2020-05-27T12:12:53", "date_gmt": "2020-05-27T12:12:53", "slug": "cropped-shortcut-icon-png", "status": "publish", "title": "cropped-shortcut-icon.png" }

  # Update the image's metadata
  curl --location --request POST "http://localhost/wp-json/wp/v2/media/$id" \
    -u admin:admin \
    -s -o /dev/null \
    --header 'Content-Type: application/json' \
    --data-raw "$body"
done
Share Improve this question edited Jun 30, 2020 at 10:02 Pezholio asked Jun 30, 2020 at 9:44 PezholioPezholio 1013 bronze badges 8
  • According to the API docs you can update the date as you're doing using a POST to /media/$id. So you're doing it but it's not working? It would be very helpful to see what the body variable looks like before you send it, maybe something goes wrong in the line where you create this variable. EDIT: looks like maybe you're suppressing the output from curl too, have you checked that that second curl command runs successfully and what the output from it says? Maybe there's an error response from the WP API – mozboz Commented Jun 30, 2020 at 9:59
  • @mozboz I've updated the code with an example of what the JSON looks like – Pezholio Commented Jun 30, 2020 at 10:02
  • And what does the output from the second curl look like? any errors? or does it come back 200? – mozboz Commented Jun 30, 2020 at 10:11
  • Yep, it comes back 200, and the response returns the right data, but the file is still in wp-content/uploads/2020/06 – Pezholio Commented Jun 30, 2020 at 10:15
  • Oh, sorry maybe I misunderstood the question - you can change the metadata ok, but the file just ends up in the wrong directory? – mozboz Commented Jun 30, 2020 at 10:40
 |  Show 3 more comments

1 Answer 1

Reset to default 1

Don't think this is possible, however will do a bit more research.

Since the functionality to expose this isn't exposed by the server, you need to do something on the server side to enable this to happen. As you're doing everything through a client-side script it wouldn't be too hard to write a little plugin on the server side which you could call with your script:

  • Send it a media ID, and a destination path (i.e. the original URL)
  • It recevies that, changes the file location and then updates the media item path

You'd call it with e.g.:

curl POST "http://localhost/wp-json/wp/v2/movemymedia"

json: { mediaID: 1234, oldPath: "06/2018" }

or whatever.

Seems like a bit of work but would keep things neat in your existing structure.

Personally I prefer to do things like this on the server because the server knows all its local setup and could e.g. move files around easily. Maybe you want to consider flipping your script to work server side pulling the content instead of client side pushing it.

本文标签: rest apiUploading a media item with the wpjson API to a specific path