I’m trying to change a category permission via API, but returning error 400.
I created this function with the php api.
And calling on my script:
$r = $api->editCategoryPermissions(641, array(‘admins’ => 1));
But returning error 400.
Can anyone help me?
1 Like
Probably call with something more like:
$r = $api->editCategoryPermissions(641, array(
array('group_name' => 'admins', 'permission_type' => 1)
));
1 Like
OK, this will likely be due to array handling for parameters in PHP:
Change the function to:
function editCategoryPermissions( $categoryId, $permissions, $username = 'system' ) {
$params = array();
foreach ( $permissions as $group => $permission ) {
$params['permissions[' . $group . ']'] = $permission;
}
if ( empty( $params ) ) {
// @todo consider throwing an exception here
// sending empty parameters is most likely bad
}
return $this->_putRequest( '/categories/' . $categoryId, $params, $username );
}
And call as you did before:
$r = $api->editCategoryPermissions( 641, array( 'admins' => 1 ) );
2 Likes
Thanks @DeanMarkTaylor, but still throwing 400
What does the body text of the 400 error say?
What does the implementation of _putRequest
look like?
Nothing
stdClass Object ( [http_code] => 400 [apiresult] => )
private function _putRequest($reqString, $paramArray, $apiUser = 'system')
{
return $this->_putpostRequest($reqString, $paramArray, $apiUser, true);
}
private function _putpostRequest($reqString, $paramArray, $apiUser = 'system', $putMethod = false)
{
$ch = curl_init();
$url = sprintf(
'%s://%s%s?api_key=%s&api_username=%s',
$this->_protocol,
$this->_dcHostname,
$reqString,
$this->_apiKey,
$apiUser
);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($paramArray));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ($putMethod) {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
}
$body = curl_exec($ch);
$rc = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$resObj = new \stdClass();
$resObj->http_code = $rc;
$resObj->apiresult = json_decode($body);
return $resObj;
}
Personally I always:
- get the existing properties for the category from Discourse first
- reduce the result properties down to a known whitelist of properties
- add the permissions
- then make the
PUT
request
It might be that one or more of the of the properties is required.
The category permissions editor built into Discourse follows a similar process, however it knows exactly what should be sent back without needing a whitelist.
Filtering by a whitelist could be risky if other properties are added (by a new version of Discourse, a plugin, or custom fields), I haven’t checked the Discourse code to see if it removes the property if not set.
3 Likes