• Resolved fermenator

    (@fermenator)


    I am writing some code to add a [content control] to each Place so that the email and phone number in the place.content.raw is hidden unless the user is logged in. I have the powershell working, and can see that json body is updating content.raw to add the [content control] markup. I then try to do an Invoke-RestMethod to post the updated Place back. The POST seems to work, but the Place isn’t actually being updated. I am not sure why it isn’t working. I am not able to capture any meaning full output from the POST.

Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Author Paolo

    (@paoltaia)

    Hi,

    WordPress REST API requires authorization to update the post data. In GeoDirectory we have added some basic authorization facilities with use of consumer_key & consumer_secret. These keys can be retrieved from GeoDirectory > Settings > API > Keys. Consumer_key & consumer_secret can be used in two ways. By header Authorization: ‘headers’ => array( ‘Authorization’ => ‘Basic ‘ . base64_encode( $CONSUMER_KEY . ‘:’ . $CONSUMER_SECRET ) ) By passing consumer_key & consumer_secret directly as a request parameters &consumer_key=CONSUMER_KEY&consumer_secret=CONSUMER_SECRET

    Let us know how it goes.

    Thanks

    Thread Starter fermenator

    (@fermenator)

    I tried appending to the URI, but that doesn’t seem to work either. I think I might not be sending the right information. What I do is pull the full “place” from the API to manipulate the raw json. I am marking up things like emails and phone numbers to add a content filter so that only members who are logged in can see the “private” data. I can tell from my script that the json is getting updated, but when I attempt a POST back through the API I am not seeing the updates. I am attempting to POST the entire json body. If I just want to update the content, would I just need to send that element by itself?

    Thread Starter fermenator

    (@fermenator)

    I tried using the header method too, but it doesn’t seem to work either. I don’t get an error message.

    Thread Starter fermenator

    (@fermenator)

    I have tried adding $key to $uri, but that doesn't work either.  I stripped out the identifying pieces of the code, but the nuts and bolts of what I am trying to do is below.  If I can get this to work, where we see an email or phone pattern in the text of the content I'll add a [content_control] to hide the values unless the user is logged in (has an valid account).  I have added some breaks in there to keep it from running against all records while troubleshooting.
    
    $userID = 'xxxxxx'
    $userPassword = 'xxxxxx'
    $Bytes = [System.Text.Encoding]::utf8.GetBytes("$($userID):$($userPassword)")
    $encodedAuth = [Convert]::ToBase64String($Bytes)
    $header = @{Authorization = "Basic $($encodedAuth)" }
    
    $userID2 = 'yyyyy'
    $userPassword2 = 'yyyyyy'
    $Bytes = [System.Text.Encoding]::utf8.GetBytes("$($userID2):$($userPassword2)")
    $encodedAuth = [Convert]::ToBase64String($Bytes)
    $header2 = @{Authorization = "Basic $($encodedAuth)" }
    
    $email_regex = '([a-zA-Z0-9_-.]+)@([a-zA-Z0-9_-.]+).([a-zA-Z]{2,5})'
    $not_email_regex = '(content_control status="logged_in"[a-zA-Z0-9_-.]+)@([a-zA-Z0-9_-.]+).([a-zA-Z]{2,5})'
    $phone_regex = '([1-9][0-9][0-9]-[1-9][0-9][0-9]-[0-9][0-9][0-9][0-9])'
    $not_phone_regex = '(content_control status="logged_in"[1-9][0-9][0-9]-[1-9][0-9][0-9]-[0-9][0-9][0-9][0-9])'
    
    $places = Invoke-RestMethod -method get -uri https://mysite.com/wp-json/geodir/v2/places -headers $header
    
    foreach ($place in $places){
    $jsonPlace = $place | ConvertTo-Json
    $email = ($place.content.raw | Select-String $email_regex -AllMatches).Matches
    $not_email = ($place.content.raw | Select-String $not_email_regex -AllMatches).Matches
    if ($email -and ! $not_email) {
    $place.content.raw = $place.content.raw.replace($email,'[content_control status="logged_in"]$email[/content_control]').replace('$email',$email)
    $place.content.rendered = $place.content.rendered.replace($email,'[content_control status="logged_in"]$email[/content_control]').replace('$email',$email)
    }
    $phone = ($place.content.raw | Select-String $phone_regex -AllMatches).Matches
    $not_phone = ($place.content.raw | Select-String $not_phone_regex -AllMatches).Matches
    if ($phone -and ! $not_phone) {
    $place.content.raw = $place.content.raw.replace($phone,'[content_control status="logged_in"]$phone[/content_control]').replace('$phone',$phone)
    $place.content.rendered = $place.content.rendered.replace($phone,'[content_control status="logged_in"]$phone[/content_control]').replace('$phone',$phone)
    }
    $place_id = $place.id
    $jsonPlace = $place | ConvertTo-Json
    $key = "consumer_key=yyyyyy&consumer_secret=yyyyyyy".ToUpper()
    $uri = "https://mysite.com/wp-json/geodir/v2/places/$place_id"
    $result = Invoke-RestMethod -method POST -uri $uri -headers $header2 -body $jsonPlace
    write-output $header2
    break
    }
    
    break
    Plugin Author Stiofan

    (@stiofansisland)

    Below is an post update example:

    $api_base_url 		= 'http://MYSITE.com/wp-json/geodir/v2/places/'; // CHANGE API ENDPOINT.
    $consumer_key 		= 'ck_xxx'; // CHANGE CONSUMER KEY
    $consumer_secret 	= 'cs_yyy'; // CHANGE CONSUMER SECRET
    
    // Request fields.
    $request_params = array(
    	'title' => 'The London Eye',
    	'content' => 'The Coca-Cola London Eye, the Millennium Wheel or simply just the London Eye is a cantilevered observation wheel on the South Bank of the River Thames in London.',
    	'status' => 'publish',
    	'package_id' => '1',
    	'post_tags' => 'Thames,South Bank',
    	'post_category' => array(
    		4,
    		10
    	),
    	'street' => 'Riverside Building, County Hall, Westminster Bridge Road',
    	'country' => 'United Kingdom',
    	'region' => 'Greater London',
    	'city' => 'London',
    	'zip' => 'SE1 7PB',
    	'latitude' => '51.503324',
    	'longitude' => '-0.119543',
    	'neighbourhood' => 'South Bank',
    	'mapview' => 'ROADMAP',
    	'mapzoom' => '8',
    	'phone' => '+1 111 111 1111',
    	'email' => '[email protected]',
    	'website' => 'https://www.londoneye.com',
    	'facebook' => 'https://en-gb.facebook.com/OfficialLondonEye',
    	'twitter' => 'https://twitter.com/TheLondonEye',
    	'job_type' => 'Freelance',
    	'property_features' => array(
    		'Gas Central Heating',
    		'Double Glazing'
    	),
    	'special_offers' => 'Hire your own Private Capsule from only £450',
    	'business_hours' => '["Mo 10:00-22:00","Tu 10:00-22:00","We 10:00-22:00","Th 10:00-20:00","Fr 10:00-20:00"],["UTC":"0"]',
    	'post_images' => 'https://www.londoneye.com/media/s2xes0bt/we-re-good-to-go-london-eye.jpg::https://www.londoneye.com/media/joqmuyuq/herohomepage1920x1080.jpg||hero home page|hero home caption',
    	'logo' => array(
    		'https://www.londoneye.com/media/zn5p2sok/lastminute-com_london_eye_logo_stg05_380x138px.png'
    	)
    );
    
    $raw_response = wp_remote_post( $api_base_url, array(
    	'headers' => array(
    		'Authorization' => 'Basic ' . base64_encode( $consumer_key . ':' . $consumer_secret )
    	),
    	'body' => $request_params
    ) );
    Thread Starter fermenator

    (@fermenator)

    I’ll have to translate this into powershell, but I’ll give it a whirl. I suspect the issue is that I am pulling the place out using the API, and using it as a json object. What you have is an array, so what I am trying to do may not work.

    I did turn on some debugging, and can see that it is complaining about the post_category and member_type.

    {“code”:”rest_invalid_param”,”message”:”Invalid parameter(s): post_category,
    member_type”,”data”:{“status”:400,”params”:{“post_category”:”post_category[0] is not of type
    integer.”,”member_type”:”member_type is not one of Individual,
    Business.”},”details”:{“post_category”:{“code”:”rest_invalid_param”,”message”:”post_category[0] is not of type
    integer.”,”data”:null},”member_type”:{“code”:”rest_invalid_param”,”message”:”member_type is not one of Individual,
    Business.”,”data”:null}}}}

    Thread Starter fermenator

    (@fermenator)

    Looking at the raw json for $place, can see it is set to

        "post_category": [
            {
                "id": 389,
                "name": "Individual Member",
                "slug": "individual-member"
            }
        ],
    
    And member_type is:
    
    		"member_type": {
    			"raw": "Individual",
    			"rendered": "Individual"
    		},
    
    It is almost certainly an issue in attempting to send the body as json.
    Thread Starter fermenator

    (@fermenator)

    As I really only want to update the content field, perhaps I need to just build the array as you showed me. What I need to know is the minimal set of array elements I need to define. I can pull the fields out of the json to set the elements of the array, and then post the array as the body back through the API. Can you tell me the minimal set of elements I need to set?

    Thread Starter fermenator

    (@fermenator)

    I got past the issue. The issue was I was not actually getting the JSON object, but instead a string. My loop wasn’t working as expected because of that. I am now able to POST the update, and it works. I am now hitting an occasional issue when the post_category is more than one value.

    Plugin Author Stiofan

    (@stiofansisland)

    If all you are updating is the content field then you don’t need our API, you can use the WP default API.

    FYI, we also hook into the stantard wp_post update functions, so in most cases you can just throw GD params at those functions to update them, such as “phone” or “email”.

    Stiofan

Viewing 10 replies - 1 through 10 (of 10 total)

The topic ‘Powershell API Post’ is closed to new replies.