Is adding attachments to issues (API v2) possible atm?

Issue #61 new
Constantin Kraft created an issue

Title pretty much describes what I want to know.

Comments (14)

  1. Alexandru Guzinschi

    You can, but unfortunately there is no direct support for uploads inside the library for now, so you need to go a level down and do some tinkering yourself.

    <?php
    use Buzz\Message\Form\FormRequest;
    use Buzz\Message\Form\FormUpload;
    
    $api = new \Bitbucket\API\Api();
    $api->getClient()
        ->addListener(
            new \Bitbucket\API\Http\Listener\OAuth2Listener($oauth_params)
        )
        ->setApiVersion('2.0')
        ->delListener('normalize_array') // @see issue #62
    ;
    
    $request = new FormRequest();
    $request->setField('issue_id', $issue_id);
    $request->setField('file', new FormUpload(__DIR__.'/somefile.txt'));
    $request->setHeaders(array(
        'Content-Type' => 'multipart/form-data'
    ));
    
    $api->getClient()->setRequest($request);
    
    $response = $api->getClient()->request(
        sprintf('repositories/%s/%s/issues/%d/attachments', $account_name, $repo_slug, $issue_id),
        array(),
        'POST'
    );
    
    if ($response->isOk()) {
        // it worked
    }
    

    It is kinda verbose (sorry), but it should work.

    When I will find some free time, I will implement all this boilerplate inside the library and expose a simple api to upload files.

  2. Jothikannan Chandramohan

    i am getting following response:

    [content:Buzz\Message\AbstractMessage:private] => {"type": "error", "error": {"message": "Resource not found", "detail": "There is no API hosted at this URL.\n\nFor information about our API's, please refer to the documentation at: https://developer.atlassian.com/bitbucket/api/2/reference/"}}
    
  3. Alexandru Guzinschi

    @Jothikannan Chandramohan Check if your Request hasresource and host parameters populated with correct data.
    You can also post a dump of $request and I will take a look.

  4. Jothikannan Chandramohan

    @Alexandru Guzinschi Please check my request

    Buzz\Message\Form\FormRequest Object ( [fields:Buzz\Message\Form\FormRequest:private] => Array ( [issue_id] => 2 [file] => Buzz\Message\Form\FormUpload Object ( [name:Buzz\Message\Form\FormUpload:private] => [filename:Buzz\Message\Form\FormUpload:private] => [contentType:Buzz\Message\Form\FormUpload:private] => [file:Buzz\Message\Form\FormUpload:private] => /assets/images/@ [headers:Buzz\Message\AbstractMessage:private] => Array ( ) [content:Buzz\Message\AbstractMessage:private] => ) ) [boundary:Buzz\Message\Form\FormRequest:private] => [method:Buzz\Message\Request:private] => POST [resource:Buzz\Message\Request:private] => / [host:Buzz\Message\Request:private] => [protocolVersion:Buzz\Message\Request:private] => 1.1 [headers:Buzz\Message\AbstractMessage:private] => Array ( [0] => Content-Type: multipart/form-data ) [content:Buzz\Message\AbstractMessage:private] => )

  5. Alexandru Guzinschi

    @Jothikannan Chandramohan Please try to add following code snippet before $api->getClient()->setRequest($request); :

    $request->fromUrl(
        sprintf('%s/repositories/%s/%s/issues/%d/attachments', $api->getClient()->getApiBaseUrl(), $account_name, $repo_slug, $issue_id)
    );
    
  6. Jothikannan Chandramohan
    class Bitbucket {
    
            protected $CI;
    
            public function __construct()
            {
                $oauth_params = array(
                      'client_id'         => 'XXXX',
                      'client_secret'     => 'XXXX'
                  );
    
                $this->issue = new Bitbucket\API\Repositories\Issues;
                  $this->issue->getClient()->addListener(
                      new \Bitbucket\API\Http\Listener\OAuth2Listener($oauth_params)
                  );
    
                $this->api = new Bitbucket\API\Api();
                $this->api->getClient()
                    ->addListener(
                        new \Bitbucket\API\Http\Listener\OAuth2Listener($oauth_params)
                    )
                    ->setApiVersion('2.0')
                    ->delListener('normalize_array') // @see issue #62
                ;
            }
    
              public function upload(){
    
                $request = new FormRequest();
                $request->setField('issue_id', 2);
                $request->setField('file', new FormUpload(base_url().'assets/images/meter1.png'));
                $request->setHeaders(array(
                    'Content-Type' => 'multipart/form-data'
                ));
    
                $this->api->getClient()->setRequest($request);
                $response = $this->issue->upload($this->accountname, $this->repo_slug, 2,$request);
    
                if ($response->isOk()) {
                   print_r($response);
                }
    
            }
    
          }
    

    $this->issue->upload have a method with the following

    public function upload($account, $repo, $issue_id,$request, array $options = array()){
    
            return $this->requestPost(
                sprintf('repositories/%s/%s/issues/%d/attachments', $account, $repo,$issue_id),
                $options
            );
        }
    

    This is my complete code for the attachment functionality, please check and let me know if I am doing anything wrong.

  7. Jothikannan Chandramohan

    Now I am getting host and resource in my request, but still in response I am getting the same error

    Buzz\Message\Form\FormRequest Object ( [fields:Buzz\Message\Form\FormRequest:private] => Array ( [issue_id] => 2 [file] => Buzz\Message\Form\FormUpload Object ( [name:Buzz\Message\Form\FormUpload:private] => [filename:Buzz\Message\Form\FormUpload:private] => [contentType:Buzz\Message\Form\FormUpload:private] => [file:Buzz\Message\Form\FormUpload:private] => xxxxx/assets/images/meter1.png [headers:Buzz\Message\AbstractMessage:private] => Array ( ) [content:Buzz\Message\AbstractMessage:private] => ) ) [boundary:Buzz\Message\Form\FormRequest:private] => [method:Buzz\Message\Request:private] => POST [resource:Buzz\Message\Request:private] => /2.0/repositories/xxxxxxx/xxxxxxxxxxxx/issues/2/attachments [host:Buzz\Message\Request:private] => https://api.bitbucket.org [protocolVersion:Buzz\Message\Request:private] => 1.1 [headers:Buzz\Message\AbstractMessage:private] => Array ( [0] => Content-Type: multipart/form-data ) [content:Buzz\Message\AbstractMessage:private] => )
    
  8. Alexandru Guzinschi
    class Bitbucket
    {
        /** @var \Bitbucket\API\Repositories\Issues $issue */
        private $issue;
    
        public function __construct()
        {
            $oauth_params = array(
                'client_id'         => 'XXXX',
                'client_secret'     => 'XXXX'
            );
    
            $this->issue = new \Bitbucket\API\Repositories\Issues;
            $this->issue->getClient()->addListener(
                new \Bitbucket\API\Http\Listener\OAuth2Listener($oauth_params)
            );
    
            $this->issue->getClient()
                ->addListener(
                    new \Bitbucket\API\Http\Listener\OAuth2Listener($oauth_params)
                )
                ->setApiVersion('2.0')
                ->delListener('normalize_array') // @see issue #62
            ;
        }
    
        public function upload($account_name, $repo_slug, $issue_id, $file_path)
        {
            $request = new FormRequest();
            $request->setField('issue_id', $issue_id);
            $request->setField('file', new FormUpload($file_path));
            $request->setHeaders(array(
                'Content-Type' => 'multipart/form-data'
            ));
            $request->fromUrl(
                sprintf(
                    '%s/repositories/%s/%s/issues/%d/attachments',
                    $this->issue->getClient()->getApiBaseUrl(),
                    $account_name,
                    $repo_slug,
                    $issue_id
                )
            );
    
            $this->issue->getClient()->setRequest($request);
    
            return $this->issue->getClient()->request(
                sprintf('repositories/%s/%s/issues/%d/attachments', $account_name, $repo_slug, $issue_id),
                array(),
                'POST'
            );
        }
    }
    $bitbucket = new Bitbucket();
    $result = $bitbucket->upload($account_name, $repo_slug, $issue_id, __DIR__ . '/some-image.png');
    var_dump($result);
    

    Also,

    $this->issue->upload have a method with the following […]

    $this->issue is set in constructor as `Bitbucket\API\Repositories\Issues` , which doesn't have an upload method. This means that you are editing the content of your vendor directory. Stop doing that!

  9. Jothikannan Chandramohan

    I have one more doubt, when i try to print the request I am getting

    "object(Buzz\\Message\\Response)#53 (5) {\n  [\"protocolVersion\":\"Buzz\\Message\\Response\":private]=>\n  NULL\n  [\"statusCode\":\"Buzz\\Message\\Response\":private]=>\n  NULL\n  [\"reasonPhrase\":\"Buzz\\Message\\Response\":private]=>\n  NULL\n  [\"headers\":\"Buzz\\Message\\AbstractMessage\":private]=>\n  array(20) {\n    [0]=>\n    string(20) \"HTTP/1.1 201 Created\"\n    [1]=>\n    string(13) \"Server: nginx\"\n    [2]=>\n    string(19) \"Vary: Authorization\"\n    [3]=>\n    string(38) \"Content-Type: text/html; charset=utf-8\"\n    [4]=>\n    string(174) \"X-OAuth-Scopes: pipeline:variable, webhook, snippet:write, wiki, issue:write, pullrequest:write, repository:delete, repository:admin, project:write, team:write, account:write\"\n    [5]=>\n    string(71) \"Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\"\n    [6]=>\n    string(35) \"Date: Tue, 25 Jun 2019 08:43:54 GMT\"\n    [7]=>\n    string(102) \"Location: https://api.bitbucket.org/2.0/repositories/xxxxxx/xxxxxxxxxxxxxx/issues/2/attachments\"\n    [8]=>\n    string(20) \"X-Served-By: app-161\"\n    [9]=>\n    string(40) \"ETag: \"d41d8cd98f00b204e9800998ecf8427e\"\"\n    [10]=>\n    string(30) \"X-Static-Version: b85ba0a755ed\"\n    [11]=>\n    string(31) \"X-Content-Type-Options: nosniff\"\n    [12]=>\n    string(36) \"X-Accepted-OAuth-Scopes: issue:write\"\n    [13]=>\n    string(25) \"X-Credential-Type: oauth2\"\n    [14]=>\n    string(29) \"X-Render-Time: 0.242187023163\"\n    [15]=>\n    string(22) \"Connection: Keep-Alive\"\n    [16]=>\n    string(20) \"X-Request-Count: 155\"\n    [17]=>\n    string(27) \"X-Frame-Options: SAMEORIGIN\"\n    [18]=>\n    string(23) \"X-Version: b85ba0a755ed\"\n    [19]=>\n    string(17) ...
    

    response seems NULL, how can get the response that the attachment has been uploaded or not, can you please help on that?

  10. Alexandru Guzinschi

    @Jothikannan Chandramohan If the HTTP status code is in 2xx range, it means that the request was successful. In your case, the status code is 201

    See successful responses on MDN for more information.

  11. Log in to comment