Download the PHP package mekras/jira-client without Composer
On this page you can find all versions of the php package mekras/jira-client. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download mekras/jira-client
More information about mekras/jira-client
Files in mekras/jira-client
Package jira-client
Short Description Jira REST API client with comfortable wrappers for most commonly used API instances like issues, custom fields, components and so on.
License GPL-3.0-only
Homepage https://github.com/mekras/jira-client
Informations about the package jira-client
Changes from original Badoo Jira client
- PSR-18 HTTP client support
- PSR-16 cache support
PSR-18 HTTP client support
You can use any PSR-18 compatible HTTP client instead of builtin cURL-based. This can be useful for testing.
PSR-16 cache support
You can use any PSR-16 compatible cache to reduce number of HTTP requests.
Original README
- Introduction
- Quick start
- Install
- Initialize the client
- Create new issue
- Get existing issue
- Update existing issue
- Delete exiting issue
- Documentation
- Client and ClientRaw
- \Badoo\Jira\Issue class
- Custom fields
- Issue changelog
- Other instances
- Advanced topics
- Managing API requests
- Extending \Badoo\Jira\Issue
- Writing new CustomField base class
Introduction
This is Badoo JIRA REST Client. It contains a bunch of wrapper classes for most common API objects: Issues, Components and so on.
This makes code easier to write because of autocompletion your IDE will provide you.
You can also generate lots of classes for custom fields to get the documentation for your own JIRA installation right in PHP code.
Quick start
Install
Initialize the client
Create new issue
Get the issue
Update the issue
Delete the issue
Documentation
NOTE: all examples in this documentation related to any interaction with JIRA consider you configured 'global' client object.
Read Configure the client section above to know how to do that.
Client and ClientRaw
The client to JIRA API is split into two parts:
The simplest interface to API: \Badoo\Jira\REST\ClientRaw
It can request API and parse responses.
Throws an \Badoo\Jira\REST\Exception
for API errors or parsed response data when everything went OK.
That's all, it has no other complex logic inside: you decide what URI to request, which type of HTTP request to send (GET, POST, etc.) and what parameters to send.
Consider ClientRaw as a smart wrapper for PHP curl.
Structured client \Badoo\Jira\REST\Client
It is split into several sections, one for each prefix of API methods: e.g. /issue, /field, /project and so on. Each section has bindings to the most popular API methods with parameters it accepts.
The idea is free you from remembering URIs and HTTP request types for common actions. It enables your IDE to give you a hint about available API methods and the options you can provide to each.
Some of sections also cache API responses and have special 'synthetic' methods for most common actions. For example,
you can't get info on particular field by its ID using only API. You have also search through the response.
But with \Badoo\Jira\REST\Client
you can do this
When you can't find something in structured client, you still can access Raw client inside it to do everything you need:
The structured client also has a 'global' client object. This object can be accessed via instance() static method:
Under the hood is 'new \Badoo\Jira\REST\Client()', but ::instance() will always return you the same object for all calls to method.
Almost all wrapper classes inside \Badoo\Jira
library require a configured API client to work.
It is always received as the last parameter of any static method or constructor of wrapper and it always defaults to
'global' client when the value was not provided.
Once you configured the global client you don't need to give API client to all wrappers you initialize. They will get it by themselves.
NOTE: all following examples in documentation, related to any interaction with JIRA, consider you configured 'global' client object. That is why we don't pass initialized JIRA API Client to all Issue, CustomField and other objects.
The only reason we left the way to provide API client to all wrappers as a parameter is to enable you to interact with several JIRA installations from one piece of code. For example, if you want to work with your staging and production instances at the same time:
\Badoo\Jira\Issue class
Getting \Badoo\Jira\Issue instances
To get an issue object you can create it providing only an issue key.
This is equivalent to:
If you want, you can instantiate another API client and provide it to \Badoo\Jira\Issue
constructor.
This might be useful when you have several JIRA instances and want to work with them from single piece of code.
Look at Client and ClientRaw section of documentation to see how to configure instance of API client.
Updating the issue
\Badoo\Jira\Issue
object accumulates changes for fields in internal properties. This means, none of changes you did with
your $Issue object will be applied to real JIRA issue until you call ->save(). This allows you to update issue
in compact way, putting several field changes into a single API request. $Issue object will also continue to return old
field values until you send changes to JIRA with ->save().
Checking if we can edit the field
Not all fields can be changed even if you have them displayed in fields list.
This can be caused by project permissions or issue edit screen configuration. To check if current user can update
field through API, use ->isEditable();
Initializing \Badoo\Jira\Issue object on partial fields data
You also can create \Badoo\Jira\Issue
object on data that contains only some fields. For example, you store in your DB
some issues info for your own reasons: key, summary, and description. You can create \Badoo\Jira\Issue
object on this
data without breaking the object logic: it still will load data from API when you need it.
Custom fields
You can generate a custom field with special generator stored in this repositroy.
For more information follow CFGenerator
subdirectory and open README.md file.
You will find both quickstart and detailed documentation on generator there.
In this section we consider you already created a class for regular custom field, available out of the box in JIRA: 'Checkboxes', 'Number Field', 'Radio Buttons', 'Select List (single choice)' and so on.
Let's consider you created custom field class (or classes) inside \Example\CustomField
namespace.
Field value: get, check, set
Several custom fields on single issue
When you need to work with several custom fields of the same issue, it is a better practice to use single $Issue object for it:
Issue changelog
Changelog of issue has the following structure:
There is a special \Badoo\Jira\History
class designed to work with this data.
It uses its own wrappers for each piece of information from changelog:
Getting issue's history of changes
If you already have an issue object to work with, just use ->getHistory()
method:
When you have none, just create an object using static method:
History class has some useful methods to help you solve most common tasks:
- track field changes,
- calculate time in statuses,
- get last change of issue,
- get last change of specific issue field,
- ...and so on
Discover it's methods using your IDE autocompletion, they might be useful!
Other instances of the Badoo JIRA API Client
Most of the wrapper classes, e.g. User, Status, Priority and so on, have ability to transparently load data from API on demand.
As for CustomFields and Issue objects, you have 2 ways of initialization: with static methods (e.g. ::get()
)
and regular constructor:
Most of them have shorthand static methods:
Names of this methods have similar structure. For convenience we decided to follow next convention:
- ::search() static methods are about multi-criteria search of instances.
This is applicable, e.g. for
\Badoo\Jira\Issue::search()
where you use complex JQL queries and\Badoo\Jira\User::search()
where JIRA looks through several user attributes trying to find you a user. - ::get() static methods are about getting a single object by its ID with immediate request to API inside method.
This allows you to control where exactly you will get the
\Badoo\Jira\REST\Exception
on API errors if you need it. -
::by
() static methods provide you with single or multiple objects identified by some single criteria.Example:
- \Badoo\Jira\User::byEmail() gives you a JIRA User by its email
- \Badoo\Jira\Version::byName() gives you a JIRA Version by its name.
-
::for
() static methods look for all items somehow related to Instance.Example:
\Badoo\Jira\CustomField::forIssue()
gives you a custom field object related to an issue\Badoo\Jira\Version::forProject()
gives you all versions created in specific project
-
::fromStdClass() method is used by all wrapper classes for initialization on data from API. If you got some information from API with specific request using, say,
\Badoo\Jira\REST\ClientRaw
, you still can operate with typed objects instead of raw \stdClass' onesExample:
The classes who work as active records and know not only how to load data from API, but also how to set it, use
the same behaviour as \Badoo\Jira\Issue
uses: they accumulate changes within object and push them to API only on
->save()
method call.
Advanced topics
Managing API requests
Once $Issue object is created with 'new' instruction - it has only issue key and client inside. It will load data only when you try to get some field for the first time:
When $Issue object loads data from API by himself, it does not select the fields to load.
This increases API response time and loads lots of data which is not required 'right now' for getting issue's summary,
but \Badoo\Jira\Issue has no idea how many additional ->get
We compared the time it takes the JIRA to load the data and send it to the client (see examples/measure-load-time.php). It may vary from installation to installation, but almost always (as far as we know - always) the 'get all fields' request will be more effective than 3 'get single field' requests and frequently it will be more effective than 2 ones.
You can make it do the API call immediately after new instance creation by using one of class' static methods:
The only thing \Badoo\Jira\Issue
manages inside is 'expand'. JIRA API allows you to request various portions of
information for issue, controlled by 'expand' parameter.
E.g. in most cases you don't need rendered HTML code of fields, or issue changelog.
This data will not be loaded by \Badoo\Jira\Issue
by default when you call ->get
When you need an issue history, \Badoo\Jira\Issue
object has to request API once again to get it.
It will also provide object with updated fields information and you will get updated summary, description and so on
if they changed since the last call to API.
In most cases, when you work with a single issue, you don't need to bother yourself with this internal logic
of \Badoo\Jira\Issue
class, but understanding is required to manage API requests in an effective way when you
start to work with lots of issues at the same time:
you can choose several ways of Issue objects initialization and this will
have different side effects on API requests amount and effectiveness.
For example, if you know you need only summary and description for lots of issues, you can request only them. This will dramatically reduce the time of API response:
Issue history can be quite hard to load for JIRA. It affects API response time significantly,
especially when you have long changelogs.
This is the thing you also can optimize by telling \Badoo\Jira\Issue
what do you need:
Unfortunately, you can't use both $fields and $expand parameters at the same time.
This is because of internal logic of \Badoo\Jira\Issue
cache, that will be broken by such combination.
We will fix this issue in the future if it show up itself as problematic.
Managing API requests with custom fields
You can instantiate a custom field object in several ways. As for \Badoo\Jira\Issue
instantiation,
they differ in API requests required for initialization and values update.
In both examples CustomField object we creted has \Badoo\Jira\Issue object under the hood. The difference reveals when you start to work with several custom fields of one issue.
Initialization with static method ::forIssue()
will always create new \Badoo\Jira\Issue object under the hood.
This means that fields:
will have different \Badoo\Jira\Issue
objects, even though they are refer to the single JIRA issue.
All custom fields use \Badoo\Jira\Issue
as instrument to manage their values:
they load data through it and edit themselves using interface Issue provides.
When you call $CustomField->setValue()
, it actually is simillar to $Issue->edit(<custom field id>, <new field value>);
.
That means you are able to 'stack' several custom field changes in one $Issue object to send updates to API only once, making interaction with API more optimal.
Managing API requests with other classes
Other classes, like Status, Priority and User, have special ::get
static method which duplicates a regular constructor
but has effect on requests to API.
Extending \Badoo\Jira\Issue
\Badoo\Jira\Issue
is about abstract JIRA instance. It has no idea about custom fields you oftenly use, statuses you
frequently transition to, and so on. It is much more convenient to have your own shortcuts for actions you do often
To do this, we recomment to craete you own Issue class to extend \Badoo\Jira\Issue
functionality with your own methods.
For example, you might want to easily close issue with one call, setting resolution to some special value. Here is the receipt:
You would probably want to extend \Badoo\Jira\Issue\CreateRequest
to return your Issue object instead of
original one:
Methods to use in child class
Here is just a piece of code with examples. They are much more informative than lost of words.
Writing your own custom field base class
All custom fields should be inherited from \Badoo\Jira\Issue\CustomFields\CustomField
class or one of its children
The simplest examples of custom field base classes are \Badoo\Jira\CustomFields\TextField
and
\Badoo\Jira\CustomFields\NumberField
.
There are some additional special methods you should know about:
$this->getOriginalObject()
- gets field value as it is provided by JIRA API.$this->dropCache()
- drops internal object cache, e.g. drops cached field value.
getOriginalObject()
method requests bound Issue object for current field value.
It caches value inside current object, it is safe to call it multiple times in a row.
This will not cause several API requests.
We expect you to always use this method instead of $this->Issue->getFieldValue()
when you write your own
wrapper inherited directly from \Badoo\Jira\Issue\CustomFields\CustomField
.
dropCache()
method is intended to drop all data about field value cached internally in object. If you plan to use
internal properties in your custom class, don't forget to redefine dropCache()
method so
it clears values of your fields.
dropCache()
method is called by bound Issue object once it loads data from API. This is a way to notify all
existing bound custom field objects that field value might have been updated.
All versions of jira-client with dependencies
ext-json Version *
ext-curl Version *
psr/log Version ^1.0
symfony/yaml Version ^4.2|^5.0
league/climate Version ^3.5
psr/http-client Version ^1.0
psr/http-factory Version ^1.0
psr/simple-cache Version ^1.0