connectors
object
%Connector
/phlo/resources/connectors/Connector.phlo
const
Connector :: section
line 10
Defines a section within a Connector, allowing for the organization of related components and functionalities.
voidconst
Connector :: api
line 11
Defines a connector for API interactions, allowing seamless communication between different services.
voidmethod
%Connector -> __construct (?array $config = null)
line 13
Initializes a Connector instance with optional configuration settings. If no configuration is provided, it attempts to load credentials from a predefined section.
if ($config === null){
$section = static::section
$creds = $section ? %creds->{$section} : null
$config = $creds ? (array)$creds->toArray : []
}
$this->config = $config
$this->timeout = 15
$this->retries = 0static
Connector :: make (?array $config = null):static
line 24
Creates a new instance of the Connector class using the provided configuration.
new static($config)method
%Connector -> base
line 26
Accesses the base API for the Connector, allowing interaction with its core functionalities.
static::apimethod
%Connector -> headers
line 27
This property retrieves the headers associated with the Connector.
[]static
Connector :: fields
line 29
Connector::$fields is a static property that holds an array of field definitions for the Connector class.
[]method
%Connector -> configured (...$keys):bool
line 31
Checks if all specified keys are configured in the Connector's configuration. Returns true if all keys are present, otherwise returns false.
foreach ($keys AS $key){
if (($this->config[$key] ?? void) === void) return false
}
return truemethod
%Connector -> missing (...$keys):?obj
line 38
Checks if the specified credentials are configured and returns null if they are; otherwise, it triggers a failure indicating which credentials are missing.
return $this->configured(...$keys) ? null : static::fail(static::section.' credentials not configured ('.implode(', ', $keys).')')static
Connector :: bearer ($token):string
line 42
The Connector::$bearer property holds the authorization header value formatted with a Bearer token for API requests.
'Authorization: Bearer '.$tokenstatic
Connector :: basic ($user, $pass):string
line 43
Generates a Basic Authorization header by encoding the provided username and password in base64 format.
'Authorization: Basic '.base64_encode($user.colon.$pass)static
Connector :: build (string $method, string $url, ?array $query = null, array $headers = [], mixed $json = null, mixed $form = null):array
line 45
Constructs an HTTP request configuration including method, URL, headers, and body based on provided parameters.
if ($query) $url .= (str_contains($url, qm) ? '&' : qm).http_build_query($query)
$body = null
if ($json !== null){
$body = is_string($json) ? $json : json_encode($json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
$headers[] = 'Content-Type: application/json'
}
elseif ($form !== null){
$body = is_string($form) ? $form : http_build_query($form)
$headers[] = 'Content-Type: application/x-www-form-urlencoded'
}
$headers[] = 'Accept: application/json'
return ['method' => strtoupper($method), 'url' => $url, 'headers' => $headers, 'body' => $body]static
Connector :: ok ($data, int $status = 200):obj
line 60
The Connector::$ok property holds an object with a boolean 'ok' value, a 'status', and 'data' attributes.
obj(ok: true, status: $status, data: $data)static
Connector :: fail ($error, int $status = 0):obj
line 61
The Connector::$fail property represents a failure state, containing an object with 'ok' set to false, along with the 'status' and 'error' details.
obj(ok: false, status: $status, error: $error)static
Connector :: errorMessage ($data, string $raw, int $status):string
line 63
Connector::$errorMessage retrieves the error message from a given data object, checking various properties for a string representation of the error, and defaults to a formatted HTTP status message if no error is found.
if (is_object($data)){
if (isset($data->error->message)) return (string)$data->error->message
if (isset($data->error) && is_string($data->error)) return $data->error
if (isset($data->message)) return (string)$data->message
if (isset($data->errors)){
$errors = $data->errors
if (is_string($errors)) return $errors
if (is_array($errors)) return is_string($errors[0] ?? null) ? $errors[0] : json_encode($errors)
if (is_object($errors)) return json_encode($errors)
}
}
return $raw !== void ? $raw : 'HTTP '.$statusstatic
Connector :: parse ($raw, int $status = 200):obj
line 78
Parses a raw input string into a JSON object, returning a success response or an error message based on the HTTP status code.
$raw = (string)$raw
$data = $raw === void ? null : json_decode($raw)
if ($status < 200 || $status >= 300) return static::fail(static::errorMessage($data, $raw, $status), $status)
return obj(ok: true, status: $status, data: $data ?? $raw)static
Connector :: retryable ($method, int $status):bool
line 85
in_array($method, ['GET', 'HEAD', 'QUERY']) && ($status === 429 || $status >= 500)static
Connector :: backoff (int $attempt, $response):int
line 87
The Connector::$backoff property calculates the backoff time in microseconds based on the 'retry-after' header from the response, with a maximum limit of 30 seconds or a default value multiplied by the attempt count.
$after = (int)($response->headers['retry-after'] ?? 0)
return $after > 0 ? min($after, 30) * 1000000 : 200000 * $attemptmethod
%Connector -> dispatch (array $req):obj
line 92
$method = $req['method']
$body = $req['body']
$attempt = 0
$response = null
while (true){
try {
if ($method === 'GET') $raw = HTTP($req['url'], $req['headers'], cookies: false, timeout: $this->timeout, response: $response)
elseif ($method === 'DELETE') $raw = HTTP($req['url'], $req['headers'], DELETE: true, cookies: false, timeout: $this->timeout, response: $response)
elseif ($method === 'PUT') $raw = HTTP($req['url'], $req['headers'], PUT: $body ?? void, cookies: false, timeout: $this->timeout, response: $response)
elseif ($method === 'PATCH') $raw = HTTP($req['url'], $req['headers'], PATCH: $body ?? void, cookies: false, timeout: $this->timeout, response: $response)
elseif ($method === 'QUERY') $raw = HTTP($req['url'], $req['headers'], QUERY: $body ?? void, cookies: false, timeout: $this->timeout, response: $response)
else $raw = HTTP($req['url'], $req['headers'], POST: $body ?? void, cookies: false, timeout: $this->timeout, response: $response)
}
catch (\Throwable $e){
return static::fail($e->getMessage(), 0)
}
$status = $response->status ?? 0
if (($status >= 200 && $status < 300) || !static::retryable($method, $status) || $attempt >= $this->retries) break
usleep(static::backoff(++$attempt, $response))
}
$result = static::parse($raw, $status)
$result->headers = $response->headers ?? []
return $resultmethod
%Connector -> request (string $method, string $url, ?array $query = null, array $headers = [], mixed $json = null, mixed $form = null):obj
line 118
Sends an HTTP request using the specified method, URL, query parameters, headers, and optional JSON or form data.
if (!str_starts_with($url, 'http')) $url = rtrim((string)$this->base, slash).slash.ltrim($url, slash)
$headers = array_merge((array)$this->headers, $headers)
return $this->dispatch(static::build($method, $url, $query, $headers, $json, $form))method
%Connector -> get (string $url, ?array $query = null, array $headers = []):obj
line 124
Sends a GET request to the specified URL with optional query parameters and headers.
$this->request('GET', $url, query: $query, headers: $headers)method
%Connector -> post (string $url, mixed $json = null, array $headers = []):obj
line 125
Sends a POST request to the specified URL with optional JSON data and headers.
$this->request('POST', $url, headers: $headers, json: $json)method
%Connector -> put (string $url, mixed $json = null, array $headers = []):obj
line 126
Sends a PUT request to the specified URL with optional JSON data and headers.
$this->request('PUT', $url, headers: $headers, json: $json)method
%Connector -> patch (string $url, mixed $json = null, array $headers = []):obj
line 127
Sends a PATCH request to the specified URL with optional JSON data and headers.
$this->request('PATCH', $url, headers: $headers, json: $json)method
%Connector -> query (string $url, mixed $json = null, array $headers = []):obj
line 128
$this->request('QUERY', $url, headers: $headers, json: $json)method
%Connector -> del (string $url, array $headers = []):obj
line 129
Sends a DELETE request to the specified URL with optional headers.
$this->request('DELETE', $url, headers: $headers)method
%Connector -> form (string $url, array $fields, array $headers = []):obj
line 130
Sends a POST request to the specified URL with the given form fields and headers.
$this->request('POST', $url, headers: $headers, form: $fields)method
%Connector -> paginate (string $url, callable $extract, ?array $query = null, string $param = 'page', int $start = 1, int $max = 0):array
line 132
Fetches paginated data from a specified URL, extracting items using a provided callable and accumulating them until a maximum count is reached or no more data is available.
$items = []
$page = $start
while (true){
$res = $this->get($url, ($query ?? []) + [$param => $page])
if (!$res->ok) break
$batch = $extract($res->data)
if (!$batch) break
foreach ($batch AS $item) $items[] = $item
if ($max && count($items) >= $max) break
$page++
}
return $itemsobject
%EBoekhouden
/phlo/resources/connectors/finance/EBoekhouden.phlo
const
EBoekhouden :: section
line 11
'EBoekhouden'const
EBoekhouden :: api
line 12
'https://api.e-boekhouden.nl/v1'prop
%EBoekhouden -> sessionToken
line 14
voidmethod
%EBoekhouden -> headers
line 16
$this->sessionToken !== void ? ['Authorization: '.$this->sessionToken] : []static
EBoekhouden :: fields
line 18
arr(
section: 'EBoekhouden',
config: arr(source: 'Source label shown in the e-Boekhouden audit trail (optional)'),
secret: arr(api_token: 'API token (Beheer > Instellingen > API)'),
)method
%EBoekhouden -> session:obj
line 25
if ($m = $this->missing('api_token')) return $m
if ($this->sessionToken !== void) return static::ok($this->sessionToken)
$res = $this->post('session', ['accessToken' => trim((string)$this->config['api_token']), 'source' => (string)($this->config['source'] ?? 'Phlo')])
if (!$res->ok) return $res
$token = (string)($res->data->token ?? void)
if ($token === void) return static::fail('e-Boekhouden session token missing in response', $res->status)
$this->sessionToken = $token
return static::ok($token)method
%EBoekhouden -> guard:?obj
line 36
$res = $this->session
return $res->ok ? null : $resmethod
%EBoekhouden -> relations (array $query = []):obj
line 41
if ($m = $this->guard) return $m
return $this->get('relation', $query)method
%EBoekhouden -> createRelation (array $relation):obj
line 46
if ($m = $this->guard) return $m
return $this->post('relation', $relation)method
%EBoekhouden -> invoices (array $query = []):obj
line 51
if ($m = $this->guard) return $m
return $this->get('invoice', $query)method
%EBoekhouden -> createInvoice (array $invoice):obj
line 56
if ($m = $this->guard) return $m
return $this->post('invoice', $invoice)object
%ExactOnline
/phlo/resources/connectors/finance/ExactOnline.phlo
const
ExactOnline :: section
line 11
Defines a section within the ExactOnline resource, allowing for structured data management.
'ExactOnline'const
ExactOnline :: tokenUrl
line 12
Returns the URL for obtaining an OAuth2 token from ExactOnline.
'https://start.exactonline.nl/api/oauth2/token'method
%ExactOnline -> base
line 14
Constructs the base URL for the ExactOnline API using the specified division from the configuration.
'https://start.exactonline.nl/api/v1/'.($this->config['division'] ?? void)static
ExactOnline :: fields
line 16
Defines the fields required for integrating with ExactOnline, including configuration for OAuth credentials and scopes.
arr(
section: 'ExactOnline',
config: arr(division: 'Division (administration) number'),
secret: arr(
client_id: 'OAuth client ID',
client_secret: 'OAuth client secret',
refresh_token: 'OAuth refresh token (managed and rotated after first authorization)',
),
scopes: 'OAuth2 authorization code flow; token endpoint refreshes automatically',
)method
%ExactOnline -> guard
line 27
Checks for the presence of required parameters 'division', 'client_id', 'client_secret', and 'refresh_token'.
$this->missing('division', 'client_id', 'client_secret', 'refresh_token')method
%ExactOnline -> invoices (array $query = []):obj
line 29
Retrieves a list of sales invoices from ExactOnline based on the provided query parameters.
if ($m = $this->guard) return $m
return $this->get('salesinvoice/SalesInvoices', $query)method
%ExactOnline -> accounts (array $query = []):obj
line 34
Retrieves account information from ExactOnline using the specified query parameters.
if ($m = $this->guard) return $m
return $this->get('crm/Accounts', $query)method
%ExactOnline -> createInvoice (array $invoice):obj
line 39
Creates a new invoice in ExactOnline using the provided invoice data.
if ($m = $this->guard) return $m
return $this->post('salesinvoice/SalesInvoices', $invoice)object
%GoogleCalendar
/phlo/resources/connectors/cloud/GoogleCalendar.phlo
const
GoogleCalendar :: section
line 11
Defines a section within a Google Calendar resource, allowing for the organization of events and details.
'Google'const
GoogleCalendar :: tokenUrl
line 12
This is the URL endpoint used to obtain an access token from Google Calendar's OAuth 2.0 authorization server.
'https://oauth2.googleapis.com/token'method
%GoogleCalendar -> base
line 14
This defines the base URL for accessing the Google Calendar API version 3.
'https://www.googleapis.com/calendar/v3'static
GoogleCalendar :: fields
line 16
GoogleCalendar::$fields provides configuration details for accessing Google Calendar, including OAuth credentials and required scopes.
arr(
section: 'Google',
secret: arr(
client_id: 'OAuth client ID',
client_secret: 'OAuth client secret',
refresh_token: 'OAuth refresh token (scopes: calendar, spreadsheets)',
),
scopes: 'https://www.googleapis.com/auth/calendar, https://www.googleapis.com/auth/spreadsheets',
)method
%GoogleCalendar -> guard
line 26
Checks for the presence of required credentials: client_id, client_secret, and refresh_token.
$this->missing('client_id', 'client_secret', 'refresh_token')method
%GoogleCalendar -> events (string $calendarId = 'primary', array $query = []):obj
line 28
Retrieves events from a specified Google Calendar using the provided calendar ID and optional query parameters.
if ($m = $this->guard) return $m
return $this->get('calendars/'.rawurlencode($calendarId).'/events', $query)method
%GoogleCalendar -> createEvent (array $event, string $calendarId = 'primary'):obj
line 33
Creates a new event in the specified Google Calendar using the provided event details.
if ($m = $this->guard) return $m
return $this->post('calendars/'.rawurlencode($calendarId).'/events', $event)object
%GoogleSheets
/phlo/resources/connectors/cloud/GoogleSheets.phlo
const
GoogleSheets :: section
line 11
Defines a section for organizing data within a Google Sheets resource.
'Google'const
GoogleSheets :: tokenUrl
line 12
This is the URL endpoint for obtaining OAuth 2.0 tokens from Google Sheets.
'https://oauth2.googleapis.com/token'method
%GoogleSheets -> base
line 14
This item represents a base URL for accessing the Google Sheets API, specifically the endpoint for interacting with spreadsheets.
'https://sheets.googleapis.com/v4/spreadsheets'static
GoogleSheets :: fields
line 16
Defines the configuration fields for Google Sheets integration, including OAuth credentials and required scopes.
arr(
section: 'Google',
secret: arr(
client_id: 'OAuth client ID',
client_secret: 'OAuth client secret',
refresh_token: 'OAuth refresh token (scopes: calendar, spreadsheets)',
),
scopes: 'https://www.googleapis.com/auth/spreadsheets',
)method
%GoogleSheets -> guard
line 26
Checks for the presence of required credentials: client_id, client_secret, and refresh_token.
$this->missing('client_id', 'client_secret', 'refresh_token')method
%GoogleSheets -> values ($spreadsheetId, string $range):obj
line 28
Retrieves the values from a specified range in a Google Sheets spreadsheet identified by the given spreadsheet ID.
if ($m = $this->guard) return $m
return $this->get($spreadsheetId.'/values/'.rawurlencode($range))method
%GoogleSheets -> append ($spreadsheetId, string $range, array $rows, string $valueInputOption = 'USER_ENTERED'):obj
line 33
Appends rows of data to a specified range in a Google Sheets spreadsheet, using the provided value input option.
if ($m = $this->guard) return $m
return $this->post($spreadsheetId.'/values/'.rawurlencode($range).':append?valueInputOption='.$valueInputOption, ['values' => $rows])object
%Lightspeed
/phlo/resources/connectors/shops/Lightspeed.phlo
const
Lightspeed :: section
line 11
Defines a section in a Lightspeed application, allowing for the organization and management of content within that section.
'Lightspeed'method
%Lightspeed -> base
line 13
Lightspeed->base constructs the base URL for accessing the Lightspeed API, incorporating the cluster ID from the configuration if available.
'https://api.lightspeedapp.com/API/V3/Account/'.($this->config['cluster_id'] ?? void)method
%Lightspeed -> headers
line 15
This method retrieves the headers required for Lightspeed API authentication using the provided API key and secret from the configuration.
[static::basic($this->config['api_key'] ?? void, $this->config['api_secret'] ?? void)]static
Lightspeed :: fields
line 17
Lightspeed::$fields defines the configuration fields required for connecting to the Lightspeed API, including cluster ID, language, API key, API secret, and access scopes.
arr(
section: 'Lightspeed',
config: arr(
cluster_id: 'Account / cluster ID',
language: 'Language (optional, default nl)',
),
secret: arr(
api_key: 'API key',
api_secret: 'API secret',
),
scopes: 'Customer read/write, Sale read',
)method
%Lightspeed -> customers (array $query = []):obj
line 30
Retrieves customer data from the Lightspeed API using the provided query parameters.
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
return $this->get('Customer.json', $query)method
%Lightspeed -> findCustomer ($participant):obj
line 35
Finds a customer by their email or phone number, depending on the format of the provided participant identifier.
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
$field = str_contains((string)$participant, '@') ? 'Email' : 'Phone'
return $this->get('Customer.json', [$field => $participant, 'limit' => 1])method
%Lightspeed -> customer ($id):obj
line 41
Retrieves customer information from the Lightspeed API using the specified customer ID.
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
return $this->get('Customer/'.$id.'.json')method
%Lightspeed -> sales (array $query = []):obj
line 46
Retrieves sales data from the API using the provided query parameters, ensuring that required credentials are present.
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
return $this->get('Sale.json', $query)method
%Lightspeed -> createCustomer (array $customer):obj
line 51
Creates a new customer by sending the provided customer data to the Lightspeed API, ensuring that required parameters are present.
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
return $this->post('Customer.json', $customer)object
%MessageBird
/phlo/resources/connectors/chat/MessageBird.phlo
const
MessageBird :: section
line 11
Defines a section for MessageBird within the Phlo application.
'MessageBird'method
%MessageBird -> base
line 13
This defines the base URL for the MessageBird API, which is used for sending and receiving messages.
'https://rest.messagebird.com'method
%MessageBird -> headers
line 15
This retrieves the headers required for authenticating requests to the MessageBird API using the provided access key.
['Authorization: AccessKey '.($this->config['access_key'] ?? void)]static
MessageBird :: fields
line 17
Defines the fields for the MessageBird configuration, including the originator and access key.
arr(
section: 'MessageBird',
config: arr(originator: 'Originator (sender number or name)'),
secret: arr(access_key: 'Access key'),
)static
MessageBird :: errorMessage ($data, string $raw, int $status):string
line 23
Retrieves the error message from the MessageBird API response, if available; otherwise, it falls back to the parent class's error message method.
if (is_object($data) && isset($data->errors[0]->description)) return (string)$data->errors[0]->description
return parent::errorMessage($data, $raw, $status)method
%MessageBird -> sms ($to, $body, array $extra = []):obj
line 28
Sends an SMS message to the specified recipient(s) using the MessageBird API, requiring an access key and originator configuration.
if ($m = $this->missing('access_key', 'originator')) return $m
$recipients = is_array($to) ? $to : [$to]
return $this->post('messages', ['originator' => $this->config['originator'], 'recipients' => $recipients, 'body' => $body] + $extra)object
%MicrosoftGraph
/phlo/resources/connectors/cloud/MicrosoftGraph.phlo
const
MicrosoftGraph :: section
line 11
This function interacts with the Microsoft Graph API to manage sections within a resource.
'Microsoft'method
%MicrosoftGraph -> base
line 13
This defines the base URL for accessing the Microsoft Graph API, allowing interaction with Microsoft services and resources.
'https://graph.microsoft.com/v1.0'method
%MicrosoftGraph -> headers
line 15
This item retrieves the headers required for authentication with Microsoft Graph using a bearer token.
[static::bearer((string)$this->token)]static
MicrosoftGraph :: fields
line 17
Defines the configuration fields required to connect to Microsoft Graph, including tenant ID, client ID, mailbox, client secret, and application permissions.
arr(
section: 'Microsoft',
config: arr(
tenant_id: 'Azure AD tenant ID',
client_id: 'App registration client ID',
mailbox: 'Default mailbox / user UPN for calendar and mail (optional)',
),
secret: arr(client_secret: 'App registration client secret'),
scopes: 'Application permissions: User.Read.All, Calendars.ReadWrite, Mail.Send',
)prop
%MicrosoftGraph -> token
line 28
Retrieves an access token from Microsoft Graph using the fetchToken method.
$this->fetchToken()method
%MicrosoftGraph -> fetchToken
line 30
Fetches an OAuth2 token from Microsoft Graph using client credentials, caching the token for future use if APCu is available.
$tenant = $this->config['tenant_id'] ?? void
$id = $this->config['client_id'] ?? void
$secret = $this->config['client_secret'] ?? void
if ($tenant === void || $id === void || $secret === void) return void
$key = 'phlo:graph:'.$tenant.colon.$id
if (function_exists('apcu_fetch')){
$cached = apcu_fetch($key)
if ($cached) return $cached
}
$res = $this->dispatch(static::build('POST', 'https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/token', null, [], null, ['grant_type' => 'client_credentials', 'client_id' => $id, 'client_secret' => $secret, 'scope' => 'https://graph.microsoft.com/.default']))
if (!$res->ok) return void
$token = $res->data->access_token ?? void
$expires = (int)($res->data->expires_in ?? 3600)
if ($token !== void && function_exists('apcu_store')) apcu_store($key, $token, max(60, $expires - 60))
return $tokenmethod
%MicrosoftGraph -> mailbox ($user = null)
line 48
Retrieves the mailbox associated with a specified user, or defaults to a configured mailbox if no user is provided.
$user ?? ($this->config['mailbox'] ?? void)method
%MicrosoftGraph -> users (array $query = []):obj
line 50
Retrieves a list of users from Microsoft Graph based on the provided query parameters.
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
return $this->get('users', $query)method
%MicrosoftGraph -> user ($id):obj
line 55
Fetches user information from Microsoft Graph using the specified user ID.
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
return $this->get('users/'.rawurlencode((string)$id))method
%MicrosoftGraph -> events ($user = null, array $query = []):obj
line 60
Fetches events from a specified user's Microsoft mailbox using the Microsoft Graph API.
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
$mailbox = $this->mailbox($user)
if ($mailbox === void) return static::fail('Microsoft mailbox required')
return $this->get('users/'.rawurlencode((string)$mailbox).'/events', $query)method
%MicrosoftGraph -> sendMail ($message, $user = null, bool $save = true):obj
line 67
Sends an email message using the Microsoft Graph API, optionally specifying a user and whether to save the message to the Sent Items folder.
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
$mailbox = $this->mailbox($user)
if ($mailbox === void) return static::fail('Microsoft mailbox required')
return $this->post('users/'.rawurlencode((string)$mailbox).'/sendMail', ['message' => $message, 'saveToSentItems' => $save])method
%MicrosoftGraph -> createEvent (array $event, $user = null):obj
line 74
Creates a new event in the specified user's Microsoft calendar using the provided event details.
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
$mailbox = $this->mailbox($user)
if ($mailbox === void) return static::fail('Microsoft mailbox required')
return $this->post('users/'.rawurlencode((string)$mailbox).'/events', $event)object
%Moneybird
/phlo/resources/connectors/finance/Moneybird.phlo
const
Moneybird :: section
line 11
Defines a section within the Moneybird integration for organizing related functionalities.
'Moneybird'method
%Moneybird -> base
line 13
This retrieves the base URL for the Moneybird API, incorporating the administration ID from the configuration if available.
'https://moneybird.com/api/v2/'.($this->config['administration_id'] ?? void)method
%Moneybird -> headers
line 15
Returns the headers required for authentication with the Moneybird API, using a bearer token derived from the access token in the configuration.
[static::bearer($this->config['access_token'] ?? void)]static
Moneybird :: fields
line 17
Defines the fields for the Moneybird integration, including the administration ID and a personal access token for accessing contacts and invoices.
arr(
section: 'Moneybird',
config: arr(administration_id: 'Administration ID'),
secret: arr(access_token: 'Personal access token with read/write for contacts and invoices'),
)method
%Moneybird -> contacts (array $query = []):obj
line 23
Retrieves a list of contacts from Moneybird based on the provided query parameters.
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->get('contacts.json', $query)method
%Moneybird -> findContact ($query):obj
line 28
Finds a contact in Moneybird based on the provided query, returning the first result found.
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->get('contacts.json', ['query' => $query, 'per_page' => 1])method
%Moneybird -> contact ($id):obj
line 33
Retrieves the contact information associated with the specified ID from Moneybird, requiring an administration ID and access token.
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->get('contacts/'.$id.'.json')method
%Moneybird -> invoices (array $query = []):obj
line 38
Fetches invoices from Moneybird based on the provided query parameters, requiring an 'administration_id' and 'access_token'.
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->get('sales_invoices.json', $query)method
%Moneybird -> createContact (array $contact):obj
line 43
Creates a new contact in Moneybird using the provided contact details. It requires an administration ID and access token to function properly.
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->post('contacts.json', ['contact' => $contact])method
%Moneybird -> createInvoice (array $invoice):obj
line 48
Creates a new invoice in Moneybird using the provided invoice data.
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->post('sales_invoices.json', ['sales_invoice' => $invoice])object
%OAuthConnector
/phlo/resources/connectors/OAuthConnector.phlo
const
OAuthConnector :: tokenUrl
line 11
Specifies the URL for obtaining an OAuth token.
voidmethod
%OAuthConnector -> oauthKey
line 13
Retrieves the OAuth key for the current section in the OAuthConnector.
static::sectionprop
%OAuthConnector -> token
line 15
Retrieves the OAuth token using the provided credentials and refresh token from the TokenStore.
TokenStore::access($this->oauthKey, static::tokenUrl, $this->config['client_id'] ?? void, $this->config['client_secret'] ?? void, ['refresh_token' => $this->config['refresh_token'] ?? null])method
%OAuthConnector -> headers
line 17
Returns the headers required for OAuth authentication, including a bearer token derived from the instance's token.
[static::bearer((string)$this->token)]method
%OAuthConnector -> authed
line 19
Checks if the OAuth token is authenticated by verifying that it is not void.
(string)$this->token !== voidobject
%Resend
/phlo/resources/connectors/chat/Resend.phlo
const
Resend :: section
line 11
Resend::section allows you to define a section in a Resend resource for organizing related content.
'Resend'method
%Resend -> base
line 13
Sets the base URL for the Resend API.
'https://api.resend.com'method
%Resend -> headers
line 15
Sets the headers for the Resend request using the provided API key from the configuration.
[static::bearer($this->config['api_key'] ?? void)]static
Resend :: fields
line 17
Defines the fields for the Resend configuration, including the default sender email and the API key.
arr(
section: 'Resend',
config: arr(from_email: 'Default sender, e.g. "App <noreply@yourdomain.com>"'),
secret: arr(api_key: 'API key (re_...)'),
)method
%Resend -> send ($to, $subject, $html = void, array $extra = []):obj
line 23
Sends an email to the specified recipient(s) with the given subject and optional HTML content, using the configured sender email address.
if ($m = $this->missing('api_key', 'from_email')) return $m
$email = ['from' => $this->config['from_email'], 'to' => is_array($to) ? $to : [$to], 'subject' => $subject]
if ($html !== void) $email['html'] = $html
return $this->post('emails', $email + $extra)object
%Shopify
/phlo/resources/connectors/shops/Shopify.phlo
const
Shopify :: section
line 11
Defines a section in a Shopify theme, allowing for customizable content and layout within the store.
'Shopify'method
%Shopify -> base
line 13
Constructs the base URL for the Shopify API using the shop domain and API version from the configuration.
'https://'.($this->config['shop_domain'] ?? void).'/admin/api/'.($this->config['api_version'] ?? '2024-01')method
%Shopify -> headers
line 15
This retrieves the headers required for Shopify API authentication, including the access token from the configuration.
['X-Shopify-Access-Token: '.($this->config['access_token'] ?? void)]static
Shopify :: fields
line 17
Defines the configuration fields for integrating with Shopify, including shop domain, API version, access token, and required scopes.
arr(
section: 'Shopify',
config: arr(
shop_domain: 'Shop domain, e.g. your-store.myshopify.com',
api_version: 'Admin API version (optional, default 2024-01)',
),
secret: arr(access_token: 'Admin API access token (shpat_...)'),
scopes: 'read_customers, read_orders, read_products, write_draft_orders, write_inventory',
)method
%Shopify -> customers (array $query = []):obj
line 27
Fetches a list of customers from Shopify using the provided query parameters.
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('customers.json', $query)method
%Shopify -> searchCustomers ($query, int $limit = 10):obj
line 32
Searches for customers in Shopify based on a query string and an optional limit on the number of results returned.
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('customers/search.json', ['query' => $query, 'limit' => $limit])method
%Shopify -> customer ($id):obj
line 37
Retrieves customer information from Shopify using the specified customer ID.
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('customers/'.$id.'.json')method
%Shopify -> orders (array $query = []):obj
line 42
Fetches a list of orders from Shopify based on the provided query parameters.
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('orders.json', $query)method
%Shopify -> products (array $query = []):obj
line 47
Fetches a list of products from Shopify using the provided query parameters.
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('products.json', $query)method
%Shopify -> createDraftOrder (array $order):obj
line 52
Creates a draft order in Shopify using the provided order details.
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->post('draft_orders.json', ['draft_order' => $order])method
%Shopify -> createProduct (array $product):obj
line 57
Creates a new product in Shopify using the provided product details.
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->post('products.json', ['product' => $product])method
%Shopify -> setInventory ($inventoryItemId, $locationId, int $available):obj
line 62
Sets the available inventory level for a specific inventory item at a given location in Shopify.
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->post('inventory_levels/set.json', ['inventory_item_id' => $inventoryItemId, 'location_id' => $locationId, 'available' => $available])object
%Slack
/phlo/resources/connectors/chat/Slack.phlo
const
Slack :: section
line 11
Creates a section block in a Slack message, allowing for the inclusion of text and other elements.
'Slack'const
Slack :: api
line 12
This item provides access to the Slack API, allowing integration with Slack services and functionalities.
'https://slack.com/api'method
%Slack -> headers
line 14
Returns the headers required for authentication when making requests to the Slack API using a bearer token.
[static::bearer($this->config['bot_token'] ?? void)]static
Slack :: fields
line 16
Defines the configuration fields for integrating with Slack, including the bot token, signing secret, and required scopes.
arr(
section: 'Slack',
secret: arr(
bot_token: 'Bot user OAuth token (xoxb-...)',
signing_secret: 'Signing secret for inbound webhook verification (optional)',
),
scopes: 'chat:write, channels:history, channels:read',
)method
%Slack -> result (obj $res):obj
line 25
Processes the result from a Slack API call, returning the response if successful or a failure message if an error occurred.
if (!$res->ok) return $res
$data = $res->data
if (is_object($data) && ($data->ok ?? null) === false) return static::fail($data->error ?? 'Slack API error', $res->status)
return $resmethod
%Slack -> send ($channel, $text, array $extra = []):obj
line 32
Sends a message to a specified Slack channel using the Slack API. It requires a configured bot token and accepts additional parameters through an array.
if (!$this->configured('bot_token')) return static::fail('Slack bot_token not configured')
return $this->result($this->post('chat.postMessage', ['channel' => $channel, 'text' => $text] + $extra))method
%Slack -> history ($channel, int $limit = 20):obj
line 37
Fetches the message history from a specified Slack channel, with an optional limit on the number of messages returned.
if (!$this->configured('bot_token')) return static::fail('Slack bot_token not configured')
return $this->result($this->get('conversations.history', ['channel' => $channel, 'limit' => $limit]))method
%Slack -> channels (int $limit = 100, string $types = 'public_channel'):obj
line 42
Retrieves a list of channels from Slack, with optional parameters to limit the number of channels and specify the types of channels to return.
if (!$this->configured('bot_token')) return static::fail('Slack bot_token not configured')
return $this->result($this->get('conversations.list', ['limit' => $limit, 'types' => $types]))object
%Telegram
/phlo/resources/connectors/chat/Telegram.phlo
const
Telegram :: section
line 11
Defines a section within a Telegram resource, allowing for organized grouping of related content.
'Telegram'method
%Telegram -> base
line 13
Constructs the base URL for the Telegram Bot API using the provided bot token from the configuration.
'https://api.telegram.org/bot'.($this->config['bot_token'] ?? void)static
Telegram :: fields
line 15
Defines the fields related to Telegram configuration, including the bot token and optional webhook secret for verification.
arr(
section: 'Telegram',
secret: arr(
bot_token: 'Bot token from BotFather',
webhook_secret: 'Webhook secret token for inbound verification (optional)',
),
help: 'Create a bot via BotFather and store its token. The chat_id is the recipient or chat to message.',
)method
%Telegram -> result (obj $res):obj
line 24
Processes the result from a Telegram API response, returning the response if successful or a failure message if an error is detected.
if (!$res->ok) return $res
$data = $res->data
if (is_object($data) && ($data->ok ?? null) === false) return static::fail($data->description ?? 'Telegram API error', $res->status)
return $resmethod
%Telegram -> send ($chatId, $text, array $extra = []):obj
line 31
Sends a message to a specified Telegram chat using the provided chat ID and text, with optional extra parameters.
if ($m = $this->missing('bot_token')) return $m
return $this->result($this->post('sendMessage', ['chat_id' => $chatId, 'text' => $text] + $extra))method
%Telegram -> photo ($chatId, $photo, $caption = void, array $extra = []):obj
line 36
Sends a photo to a specified Telegram chat with an optional caption and additional parameters.
if ($m = $this->missing('bot_token')) return $m
$payload = ['chat_id' => $chatId, 'photo' => $photo]
if ($caption !== void) $payload['caption'] = $caption
return $this->result($this->post('sendPhoto', $payload + $extra))method
%Telegram -> document ($chatId, $document, $caption = void, array $extra = []):obj
line 43
Sends a document to a specified chat on Telegram, optionally including a caption and additional parameters.
if ($m = $this->missing('bot_token')) return $m
$payload = ['chat_id' => $chatId, 'document' => $document]
if ($caption !== void) $payload['caption'] = $caption
return $this->result($this->post('sendDocument', $payload + $extra))method
%Telegram -> updates (int $offset = 0, int $limit = 100):obj
line 50
Retrieves updates from the Telegram bot API, allowing for pagination through the 'offset' and 'limit' parameters.
if ($m = $this->missing('bot_token')) return $m
return $this->result($this->get('getUpdates', ['offset' => $offset, 'limit' => $limit]))object
%TokenStore
/phlo/resources/connectors/TokenStore.phlo
static
TokenStore :: path ($key):string
line 10
The TokenStore::$path property defines the file path for storing token data, formatted as a JSON file based on a sanitized version of the provided key.
data.'tokens/'.preg_replace('/[^a-z0-9_.-]+/i', us, (string)$key).'.json'static
TokenStore :: read ($key):array
line 12
Reads a token from the TokenStore by its key, returning an array of tokens if the file exists and is accessible.
$file = static::path($key)
if (!is_file($file)) return []
@chmod(data.'tokens', 0700)
@chmod($file, 0600)
return (array)json_read($file, true)static
TokenStore :: write ($key, array $token):void
line 20
This method writes a token to a specified file in a secure directory, ensuring the directory and file have appropriate permissions.
$dir = data.'tokens'
is_dir($dir) || mkdir($dir, 0700, true)
@chmod($dir, 0700)
$file = static::path($key)
json_write($file, $token)
@chmod($file, 0600)static
TokenStore :: valid (array $token):bool
line 29
Checks if the access token is valid by ensuring it exists and has not expired, allowing for a 30-second buffer before expiration.
($token['access_token'] ?? void) !== void && (int)($token['expires_at'] ?? 0) > time() + 30static
TokenStore :: store ($res, $refresh):array
line 31
Stores the access token, refresh token, and expiration time for authentication purposes.
$token = [
'access_token' => $res['access_token'],
'refresh_token' => $res['refresh_token'] ?? $refresh,
'expires_at' => time() + (int)($res['expires_in'] ?? 3600),
]
return $tokenstatic
TokenStore :: lock ($key)
line 42
TokenStore::$lock manages a file-based locking mechanism for token storage, ensuring exclusive access to the token file during operations.
$dir = data.'tokens'
is_dir($dir) || mkdir($dir, 0700, true)
$lock = @fopen(static::path($key).'.lock', 'c')
if (!$lock || !flock($lock, LOCK_EX)){
$lock && fclose($lock)
return null
}
return $lockstatic
TokenStore :: access ($key, $tokenUrl, $clientId, $clientSecret, array $seed = []):?string
line 53
Retrieves the access token from the TokenStore, refreshing it if necessary using the refresh token.
$token = static::read($key)
if (static::valid($token)) return $token['access_token']
$lock = static::lock($key)
if (!$lock) return null
try {
$token = static::read($key)
if (!($token['refresh_token'] ?? null) && ($seed['refresh_token'] ?? null)){
$token = ['refresh_token' => $seed['refresh_token']]
static::write($key, $token)
}
if (static::valid($token)) return $token['access_token']
$refresh = $token['refresh_token'] ?? null
if (!$refresh || !$tokenUrl || !$clientId) return null
$res = OAuth2::refresh($tokenUrl, $clientId, $clientSecret, $refresh)
if (!($res['access_token'] ?? null)) return null
$token = static::store($res, $refresh)
static::write($key, $token)
return $token['access_token']
} finally {
flock($lock, LOCK_UN)
fclose($lock)
}object
%Twilio
/phlo/resources/connectors/chat/Twilio.phlo
const
Twilio :: section
line 11
Defines a section for Twilio integration within a Phlo application.
'Twilio'method
%Twilio -> base
line 13
Constructs the base URL for accessing the Twilio API using the account SID from the configuration.
'https://api.twilio.com/2010-04-01/Accounts/'.($this->config['account_sid'] ?? void)method
%Twilio -> headers
line 15
Retrieves the headers required for Twilio API requests using the provided account SID and auth token from the configuration.
[static::basic($this->config['account_sid'] ?? void, $this->config['auth_token'] ?? void)]static
Twilio :: fields
line 17
Defines the fields for configuring Twilio integration, including account SID, sender number, and optional messaging service SID, along with the authentication token.
arr(
section: 'Twilio',
config: arr(
account_sid: 'Account SID (ACxxxx)',
from_number: 'Sender number in E.164, e.g. +31600000000 (use this or messaging_service_sid)',
messaging_service_sid: 'Messaging Service SID (optional alternative to from_number)',
),
secret: arr(auth_token: 'Auth token'),
)method
%Twilio -> sms ($to, $body, array $extra = []):obj
line 27
Sends an SMS message using Twilio's API, requiring either a from_number or messaging_service_sid from the configuration.
if ($m = $this->missing('account_sid', 'auth_token')) return $m
$from = $this->config['from_number'] ?? void
$service = $this->config['messaging_service_sid'] ?? void
if ($from === void && $service === void) return static::fail('Twilio from_number or messaging_service_sid required')
$fields = ['To' => $to, 'Body' => $body] + $extra
if ($service !== void) $fields['MessagingServiceSid'] = $service
else $fields['From'] = $from
return $this->form('Messages.json', $fields)method
%Twilio -> message ($sid):obj
line 38
Retrieves a message from Twilio using the specified message SID.
if ($m = $this->missing('account_sid', 'auth_token')) return $m
return $this->get('Messages/'.$sid.'.json')