bedita / php-sdk
BEdita PHP SDK
Installs: 76 375
Dependents: 1
Suggesters: 0
Security: 0
Stars: 4
Watchers: 6
Forks: 2
Open Issues: 4
Requires
- php: >=8.3
- monolog/monolog: ^2
- php-http/guzzle7-adapter: ^1.0
- woohoolabs/yang: ^3.0
Requires (Dev)
- cakephp/cakephp-codesniffer: ^3.0
- josegonzalez/dotenv: 2.*
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.0
- psy/psysh: @stable
- vimeo/psalm: ^5.18
README
BEdita PHP Official PHP SDK
Prerequisites
- PHP >= 8.3
- Composer
Install
To install the latest version of this library, run the command below:
composer require bedita/php-sdk
Basic Usage
Init BEditaClient
Instantiate BEditaClient with API url and API key. This will usually be done via factory methods like ApiclientProvider::getApiClient() that will read from environment variables and/or configuration files.
$apiUrl = 'http://your-api-url'; $apiKey = 'your-api-key'; /** @var \BEdita\SDK\BEditaClient $client */ $client = new BEditaClient($apiUrl, $apiKey);
Init Logger for custom log
You can activate a detailed request/response log to file of API calls using initLogger()
method.
This will be also usually performed by factory methods like ApiclientProvider::getApiClient().
$client->initLogger(['log_file' => '/path/to/file/name.log']);
Request Headers
Some headers are handled as default in API calls:
Accept
asapplication/vnd.api+json
to use JSON-API formatContent-Type
asapplication/json
when a request body is setAuthorization
withBearer {token}
if a JWT token has been setX-Api-Key
with the key passed to contructor
Upon every API call you can add new headers or overwrite defaults in the $header
array argument (see below).
Authenticate and tokens
To retrieve or set JWT tokens you can:
- use
authenticate(string $username, string $password)
method to perform a classic username/password authentication - use
setupTokens()
to set JWT tokens, retrieved from previousauthenticate
or other methods, for subsequent calls
$response = (array)$client->authenticate('my-username', 'my-password'); if (!empty($response['meta'])) { $client->setupTokens($response['meta']); }
On every subsequent API call JWT token will be used in Authentication
header and expired token response will also be handled via refresh token automatically by the SDK.
Direct API calls and utility methods
In order to use BEdita 4 API you have generally two options:
- use direct API calls invoking POST/GET/PATCH/DELETE HTTP methods using correspondent
get()
/post()
/patch()
/delete()
methods making sure that path, query string, body and headers are correctly populated; - use the utility methods explained below like
save
,addRelated
and others to simplify settings and obtain a clearer code.
Read objects and resources
You can use getObjects(string $type = 'objects', ?array $query = null, ?array $headers = null)
to retrieve a list of objects by type, getObject(int|string $id, string $type = 'objects', ?array $query = null, ?array $headers = null)
to get a single object by unique identifier and type.
Examples:
// get documents $response = (array)$client->getObjects('documents'); // argument passed is a string $type // get documents using a filter $query = [ 'filter' => ['parent' => 'some-parent-id'], ]; $response = (array)$client->getObjects('documents', $query); // arguments passed are string $type and array $query // get documents using a filter and more query options // include: including related data by relations "has_media" and "part_of" // lang: the desired lang (if translation is available) $query = [ 'filter' => ['parent' => 'some-parent-id'], 'include' => 'has_media,part_of', 'lang' => 'en', ]; $response = (array)$client->getObjects('documents', $query); // arguments passed are string $type and array $query
// get document 17823 $response = (array)$client->getObject(17823, 'documents'); // arguments passed are int|string $id, string $type // get document 17823, english version, including related data by relations "has_media" and "part_of" $query = [ 'lang' => 'en', 'include' => 'has_media,part_of', ]; $response = (array)$client->getObject(17823, 'documents', ['lang' => 'en_EN']); // arguments passed are int|string $id, string $type and array $query // get folder website-footer $response = (array)$client->getObject('website-footer', 'folders'); // arguments passed are int|string $id, string $type
You can also use get(string $path, ?array $query = null, ?array $headers = null)
to make an explicit GET API call, specifying the complete request path.
This is the correct way to call special endpoints like /home
or /status
for instance (GET calls that are not used to retrieve objects o resources).
// get API status $response = (array)$client->get('/status'); // argument passed is string $path // get API home info $response = (array)$client->get('/home'); // argument passed is string $path // get a list of documents $query = [ 'filter' => ['parent' => 'some-parent-id'], ]; $response = (array)$client->get('/documents', $query); // arguments passed are string $path and array $query // get a stream by id $response = (array)$client->get('/streams/the-stream-id'); // argument passed is string $path
When you need to get relationships related data, you can you getRelated(int|string $id, string $type, string $relation, ?array $query = null, ?array $headers = null)
.
// get subfolders for a folder with ID 888 $query = [ 'filter' => ['type' => 'folders'], ]; $subfolders = $client->getRelated(888, 'folders', 'children', $query); // arguments passed are int|string $id, string $type, string $relation, array $query // get children (all types) inside a folder with unique name 'my-folder-uname' $children = $client->getRelated('my-folder-uname', 'folders', 'children'); // arguments passed are int|string $id, string $type, string $relation
Save objects and resources
You can use save(string $type, array $data, ?array $headers = null)
method: this is the standard method to use to create or update objects or resources in BEdita 4.
Please note that the payload is made of object attributes, without the need to specify a data.attribute
section that you must use when dealing with direct POST o PATCH API calls.
Example:
// save a new document $data = [ 'title' => 'My new doc', 'status' => 'on', ]; $response = (array)$client->save('documents', $data); // arguments passed are string $type, array $data // retrocompatibility version with saveObject, deprecated $response = (array)$client->saveObject('documents', $data); // arguments passed are string $type, array $data // save an existing document $data = [ 'id' => 999, 'title' => 'My new doc, changed title', ]; $response = (array)$client->save('documents', $data); // arguments passed are string $type, array $data // retrocompatibility version with saveObject, deprecated $response = (array)$client->saveObject('documents', $data); // arguments passed are string $type, array $data
save
and saveObject
use internally patch(string $path, mixed $body, ?array $headers = null)
(when saving an existing object) or post(string $path, mixed $body, ?array $headers = null)
(when saving a new object).
If you like to use them directly:
// save a new document $data = [ 'type' => 'documents', 'attributes' => [ 'title' => 'My doc', 'status' => 'on', ], ]; $response = (array)$client->post('/documents', $data); // arguments passed are string $path, array $data // save an existing document $data = [ 'type' => 'documents', 'attributes' => [ 'title' => 'My doc', 'status' => 'on', ], ]; $response = (array)$client->post('/documents/999', $data); // arguments passed are string $path, array $data
Delete and restore data
Soft delete
Soft delete puts object into the trashcan.
You can trash an object with delete(string $path, mixed $body = null, ?array $headers = null)
or deleteObject(int|string $id, string $type)
.
// delete document by ID 99999 $response = $client->delete('/documents/99999'); // argument passed is string $path // delete document by ID 99999 and type documents $response = $client->deleteObject(99999, 'documents'); // arguments passed are string|int $id, string $type // delete multiple $response = $client->deleteObjects([999991, 999992, 999993], 'documents');
Restore data
Data in trashcan can be restored with restoreObject(int|string $id, string $type)
.
// restore document 99999 $response = $client->restoreObject(99999, 'documents'); // arguments passed are string|int $id, string $type // restore multiple $response = $client->restoreObjects([999991, 999992, 999993], 'documents');
Hard delete
Hard delete removes object from trashcan.
You can remove an object from trashcan with remove(int|string $id)
.
// delete document by ID 99999 $response = $client->deleteObject(99999, 'documents'); // arguments passed are string|int $id, string $type // permanently remove documents 99999 $response = $client->remove(99999); // argument passed is string|int $id // permanently remove multiple $response = $client->removeObjects([999991, 999992, 999993]);
Working with relations
Add related objects
You can add related objects using addRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null)
.
// save a document and add related objects, in this example a "see_also" relation between documents and documents is involved $document = $client->save('documents', ['title' => 'My new doc']); $relatedData = [ [ 'id' => 9999, // another doc id 'type' => 'documents', ], ]; $client->addRelated($document['data']['id'], 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData
Replace related objects
replaceRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null)
is handy to replace related objects.
// replace related objects, in this example a "see_also" relation between document 8888 and document 9999 $relatedData = [ [ 'id' => 9999, 'type' => 'documents', ], ]; $client->replaceRelated(8888, 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData
Note: internally addRelated
uses post
and replaceRelated
uses patch
. Both will call /:type/:id/relationships/:relation
Remove related objects
Related objects can be removed using removeRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null)
.
// remove related data, in this example a "see_also" relation between document 8888 and document 9999 $relatedData = [ [ 'id' => 9999, 'type' => 'documents', ], ]; $client->removeRelated(8888, 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData
Upload
The easiest way to create a new media object with file upload is to call a POST with file content as body.
Example of image upload:
$content = file_get_contents('/path/to/image.png'); $response = $client->post('/images/upload/image.png', $content, ['Content-type' => 'image/png'] );
A new object of type images
will be created having image.png
file as related stream resource.
If you need instead to handle more low level actions via streams read the paragraphs below.
Upload streams
Use upload(string $filename, string $filepath, ?array $headers = null)
to perform a POST /streams/upload/:filename
and create a new stream with your file.
// upload the image /home/gustavo/sample.jpg $response = $client->upload('sample.jpg', '/home/gustavo/sample.jpg');
Note: if you don't pass $headers
argument, the function uses mime_content_type($filepath)
.
// upload the image /home/gustavo/sample.jpg, passing content type $response = $client->upload('sample.jpg', '/home/gustavo/sample.jpg', ['Content-type' => 'image/jpeg']);
Create media from stream
You create a media object from a stream with createMediaFromStream(string $streamId, string $type, array $body)
. This basically makes 3 calls:
POST /:type
with$body
as payload, create media objectPATCH /streams/:stream_id/relationships/object
modify stream adding relation to mediaGET /:type/:id
get media data
// upload an audio file $filepath = '/home/gustavo/sample.mp3'; $filename = basename($filepath); $headers = ['Content-type' => 'audio/mpeg']; $response = $client->upload($filename, $filepath, $headers); // create media from stream $streamId = Hash::get($response, 'data.id'); $body = [ 'data' => [ 'type' => 'audios', 'attributes' => [ 'title' => $filename, 'status' => 'on', ], ], ]; $response = $client->createMediaFromStream($id, $type, $body);
Thumbnails
Media thumbnails can be retrived using thumbs(int|null $id, $query = [])
.
Usage:
// get thumbnail for media 123 => GET /media/thumbs/123 $client->thumbs(123); // get thumbnail for media 123 with a preset => GET /media/thumbs/123&preset=glide $client->thumbs(123, ['preset' => 'glide']); // get thumbnail for multiple media => GET /media/thumbs?ids=123,124,125 $client->thumbs(null, ['ids' => '123,124,125']); // get thumbnail for multiple media with a preset => GET /media/thumbs?ids=123,124,125&preset=async $client->thumbs(null, ['ids' => '123,124,125', 'preset' => 'async']); // get thumbnail media 123 with specific options (these options could be not available... just set in preset(s)) => GET /media/thumbs/123/options[w]=100&options[h]=80&options[fm]=jpg $client->thumbs(123, ['options' => ['w' => 100, 'h' => 80, 'fm' => 'jpg']]);
Schema
You can get the JSON SCHEMA of a resource or object with schema(string $type)
.
// get schema of users => GET /model/schema/users $schema = $client->schema('users');
Get info of a relation (data, params) and get left/right object types using relationData(string $name)
.
// get relation data of relation see_also => GET /model/relations/see_also $schema = $client->relationData('see_also');