0

trying to use the REST API that comes with the flagging module on Drupal 8.

I've enabled and secured the endpoint that comes with the module: /entity/flagging: POST

I'm nearly there, but following examples from earlier releases don't seem to work; What I'm trying to achieve is adding a flag for one user (1) for one content item (34). I got this far on the POST:

{
"entity_id":[{"target_id":34}],
"flag_id": "my_flag",
"uid": [{"target_id": 1 }],
"flag_action": "flag"
}

But I get this error:

InvalidArgumentException: Field flag_action is unknown.

Without the flag_action argument though I get:

{"message":"You are not authorized to create this flagging entity of bundle my flag."}

I'm not sure how I can not be authorised i'm sending credentials of the sys admin (using basic_auth).

Anybody know how I can add or remove a single flag from an entity using the Rest API? thanks!

1 Answer 1

2

I tried to create a flag, however, I had the same results.

To solve this, I have created a module.

note: to make tests I installed the "Flag Bookmark" module. file test_api.info.yml.

    name: Test API
    type: module
    description: Custom RESTful API module with GET/POST/PUT/DELETE etc.. method examples.
    author: Minnur Yunusov
    core: 8.x

file test_api.routing.yml.

# Test API endpoints

  test_api.get:
  path: 'my-api/get.json'
  defaults: { _controller: '\Drupal\test_api\Controller\TestAPIController::get_example' }
  methods:  [GET]
  requirements:
    _access: 'TRUE'

test_api.put:
  path: 'my-api/put.json'
  defaults: { _controller: '\Drupal\test_api\Controller\TestAPIController::put_example' }
  methods:  [PUT]
  requirements:
    _access: 'TRUE'

test_api.post:
  path: 'my-api/post.json'
  defaults: { _controller: '\Drupal\test_api\Controller\TestAPIController::post_example' }
  methods:  [POST]
  requirements:
    _access: 'TRUE'

test_api.delete:
  path: 'my-api/delete.json'
  defaults: { _controller: '\Drupal\test_api\Controller\TestAPIController::delete_example' }
  methods:  [DELETE]
  requirements:
    _access: 'TRUE'

we create the following directories and file TestAPIController.php src/Controller/TestAPIController.php

<?php

/**
 * @file
 * Contains \Drupal\test_api\Controller\TestAPIController.
 */

namespace Drupal\test_api\Controller;

use Drupal\Core\Controller\ControllerBase;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Drupal\user\Entity\User;

/**
 * Controller routines for test_api routes.
 */
class TestAPIController extends ControllerBase {

  /**
   * Callback for `my-api/get.json` API method.
   */
  public function get_example( Request $request ) {

    $response['data'] = 'Some test data to return';
    $response['method'] = 'GET';

    return new JsonResponse( $response );
  }

  /**
   * Callback for `my-api/put.json` API method.
   */
  public function put_example( Request $request ) {

    $response['data'] = 'Some test data to return';
    $response['method'] = 'PUT';

    return new JsonResponse( $response );
  }

  /**
   * Callback for `my-api/post.json` API method.
   */
  public function post_example( Request $request ) {

    // This condition checks the `Content-type` and makes sure to 
    // decode JSON string from the request body into array.
    if ( 0 === strpos( $request->headers->get( 'Content-Type' ), 'application/json' ) ) {
      $data = json_decode( $request->getContent(), TRUE );
      $request->request->replace( is_array( $data ) ? $data : [] );
    }


    //get value json
    $flag_id= $data["flag_id"];
    $entity_type= $data["entity_type"];
    $entity_id = $data["entity_id"];
    $uid= $data["uid"];
    $created = REQUEST_TIME;

    //get user   
    $user= User::load($uid);

    //get field uuid
    $user_uuid= $user->get('uuid')->value;

    //add entity_id to the field field uuid (unique value);
    $user_uuid= $user_uuid.'-'.$data["entity_id"];

    $fields=array(
      'flag_id' => $flag_id,
      'uuid' =>$user_uuid, //unique value
      'entity_type' =>$entity_type,
      'entity_id' => $entity_id,
      'uid' =>$uid,
      'global' =>0,
      'created' => $created
    );


    if ($data["flag_action"]=='flag') {

        //verify if exists record
        $sql="select * from {flagging} where entity_type ='$entity_type' and entity_id=$entity_id and flag_id='$flag_id' and uid=$uid ";    
        //execute query
        $connection = \Drupal::database();
        $result = $connection->query($sql);
        $result=$result->fetchAll();

        //if not exists record, create flag
        if (count($result)>0) {
          $response['¿Flag exists?'] = 'true';
        }
        else {


              $resultado= db_insert('flagging')
              ->fields($fields)
              ->execute();  

              $response['newflag'] = $resultado;

        }


        $response['data'] = $data;


    }


    else if ($data["flag_action"]=='unflag') {

        //verify if exits record
        $sql="select * from {flagging} where entity_type ='$entity_type' and entity_id=$entity_id and flag_id='$flag_id' and uid=$uid ";    
        //execute query
        $connection = \Drupal::database();
        $result = $connection->query($sql);
        $result=$result->fetchAll();

        //if exists record, delete flag
        if (count($result)>0) {

          $num_deleted = db_delete('flagging')
          ->condition('entity_type', $entity_type)
          ->condition('entity_id', $entity_id)
          ->condition('flag_id', $flag_id)
          ->condition('uid', $uid)
          ->execute();



          $response['¿Delete flag?'] = 'true';
        }
        else {

          $response['¿Flag exists?'] = 'false';

        }


        $response['data'] = $data;


    }










    /*

    //send json example
    //change "bookmark"  by "my_flag"


    {
      "entity_id":31,
      "entity_type":"node",
      "flag_id": "bookmark", 
      "uid": 1,
      "flag_action": "flag"
    }

    */



    return new JsonResponse( $response );
  }

  /**
   * Callback for `my-api/delete.json` API method.
   */
  public function delete_example( Request $request ) {

    $response['data'] = 'Some test data to return';
    $response['method'] = 'DELETE';

    return new JsonResponse( $response );
  }

}

Note: in the tests change "bookmark" by "my_flag"

test: url: http://jeremiselxi.260mb.net/drupal8/my-api/post.json method:post; headers: Content-type: application/json X-CSRF-Token: token()

note: this token is obtained through the GET method to the url localhost/session/token

create flag

{
  "entity_id":34,
  "entity_type":"node",
  "flag_id": "bookmark", 
  "uid": 1,
  "flag_action": "flag"
}

result:

200 OK

Headers
{
  "newflag": "22",
  "data": {
    "entity_id": 34,
    "entity_type": "node",
    "flag_id": "bookmark",
    "uid": 1,
    "flag_action": "flag"
  }
}

note: If the flag does not exist, then create the flag

"newflag": "22"

else

"¿Flag exists?": "true"

create unflag

{
  "entity_id":34,
  "entity_type":"node",
  "flag_id": "bookmark", 
  "uid": 1,
  "flag_action": "unflag"
}

result:

200 OK

Headers
{
  "¿Delete flag?": "true",
  "data": {
    "entity_id": 34,
    "entity_type": "node",
    "flag_id": "bookmark",
    "uid": 1,
    "flag_action": "unflag"
  }
}

note: If the flag exists, then delete the flag

"¿Delete flag?": "true"

else

"¿Flag exists?": "false",
5
  • Did it work for you? Commented Feb 21, 2019 at 4:19
  • Yes, it worked very well for me. This is the code that I used. Commented Feb 21, 2019 at 4:26
  • Awesome. I have tried and it worked! Commented Feb 21, 2019 at 4:37
  • Excellent .... Any concerns or doubts, I'm here Commented Feb 21, 2019 at 4:39
  • @JHONATANDAVIDFERNANDEZROSA This is stunnig. This saved me !! Thanks a lot.. I think Drupal has to fix post flagging only adminster permission.
    – Rifas Ali
    Commented Jul 7, 2021 at 8:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.