Explorar el Código

xero oauth2 has been successfully skeletoned with init_wp () working for sync_pay_item().

master
sp hace 4 años
padre
commit
95873d9875
Se han modificado 3 ficheros con 1497 adiciones y 0 borrados
  1. +712
    -0
      XeroOauth2.php
  2. +7
    -0
      composer.json
  3. +778
    -0
      composer.lock

+ 712
- 0
XeroOauth2.php Ver fichero

@@ -0,0 +1,712 @@
<?php

/* xero integration oauth 2 */

/* required by XeroOauth1 in 2021 */

namespace Biukop;
require_once(dirname(__FILE__) . '/vendor/autoload.php');
// require_once(ABSPATH . 'wp-includes/pluggable.php');
require_once(dirname(__FILE__) . '/Storage.php');

use \Carbon_Fields\Container;
use \Carbon_Fields\Field;
use \Carbon_Fields\Carbon_Fields;
use phpDocumentor\Reflection\DocBlock\Tags\Method;

class XeroOAuth2
{
private $office; // parent
private $clientID = '83CC79EEC6A54B4E8C2CA7AD61D1BF69';
private $clientSecret = 'axgKF-Ri60D89conDFhqZsi1wu7uLdQFGvMpino9nI-nfO3f';
private $clientContactGroupID="48646f3d-cf5e-4fea-8c8b-5812bd540e1b";

public $provider;
public $options = [
'scope' => ['openid email profile offline_access assets projects accounting.settings accounting.transactions accounting.contacts accounting.journals.read accounting.reports.read accounting.attachments payroll.employees payroll.payruns payroll.payslip payroll.timesheets payroll.settings files'],
'scope1' => [
'openid',
'email',
'profile',
'offline_access',
'assets',
'projects',
'accounting.settings',
'accounting.transactions',
'accounting.contacts',
'accounting.journals.read',
'accounting.reports.read',
'accounting.attachments',
'payroll.employees',
'payroll.payruns',
'payroll.payslip',
'payroll.timesheets',
'payroll.settings'
]
];
public $storage;
public $config;
public $apiAccountingInstance; //accounting instance
public $apiPayrollInstance; // payroll au instance
public $xeroTenantId;


public function __construct($office)
{
$this->office = $office;
add_action('init', array($this, 'init_wp'));
add_action('after_setup_theme', array($this, 'boot_carbon'));
// add_action('init', array('Carbon_Fields\\Carbon_Fields', 'boot'));
add_action( 'plugins_loaded', array( '\\Carbon_Fields\\Carbon_Fields', 'boot' ) );
add_action('carbon_fields_register_fields', array($this, 'build_settings_page'));
add_action('carbon_fields_container_activated', array($this, 'field_activated'));
add_action('parse_request', array($this, 'xero_callback'));

add_shortcode('xero_org_name', array($this, 'xero_org_name'));
add_shortcode('xero_org_contacts', array($this, 'xero_org_contacts'));
add_shortcode('xero_org_invoices', array($this, 'xero_org_invoices'));
add_shortcode('xero_org_pay_items', array($this, 'xero_org_pay_items'));
add_shortcode('xero_org_employees', array($this, 'xero_org_employees'));
add_shortcode('xero_org_clients', array($this, 'xero_org_clients'));
add_shortcode('xero_org_payroll_calendar', array($this, 'xero_org_payroll_calendar'));



add_action('init', array($this, "xero_init"));
add_action('plugins_loaded', array($this, "load_storage"));
// $this->xero_init();
$this->storage = new StorageClass();
}

public function __call($method, $args) {
if ( method_exists($this->XeroOauth1, $method) ) {
syslog(LOG_INFO,"Calling $method");
$this->XeroOauth1->$method($args);
} else {
error_log("$method is not defined" );
}
}

public function xero_init()
{
$this->provider = $this->create_provider();

}

private function create_provider() {
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => $this->clientID,
'clientSecret' => $this->clientSecret,
'redirectUri' => $this->getRedirectURL(),
'urlAuthorize' => 'https://login.xero.com/identity/connect/authorize',
'urlAccessToken' => 'https://identity.xero.com/connect/token',
'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Organisation'
]);
return $provider;
}

public function load_storage()
{
//$this->storage->read_value();
}

public function boot_carbon()
{
\Carbon_Fields\Carbon_Fields::boot();
}


function build_settings_page()
{
Container::make('theme_options', __('Xero Integration'))
->set_page_parent('options-general.php')
->add_fields(array(
Field::make('text', 'xero_oauth2state', 'Xero Oauth2 State')
->set_attribute('maxLength', 2048)
->set_attribute('readOnly', true)
->set_default_value($this->storage->getOauth2State()),
Field::make('text', 'xero_token', 'Xero Token')
->set_attribute('maxLength', 2048)
->set_attribute('readOnly', true)
->set_default_value($this->storage->getSession()['token']),
Field::make('text', 'xero_refresh_token', 'RefreshToken')
->set_attribute('readOnly', true)
->set_default_value($this->storage->getSession()['refresh_token']),
Field::make('text', 'xero_id_token', 'ID Token')
->set_attribute('readOnly', true)
->set_default_value($this->storage->getSession()['id_token']),
Field::make('text', 'xero_tenant_id', 'Tenant ID')
->set_attribute('readOnly', true)
->set_default_value($this->storage->getSession()['tenant_id']),
Field::make('text', 'xero_expires', 'Expires')
->set_attribute('readOnly', true)
->set_default_value($this->storage->getSession()['expires']),
Field::make('text', 'xero_expires_human', 'Expires')
->set_attribute('readOnly', true)
->set_default_value($this->storage->getSession()['expires_human']),

Field::make('html', 'crb_information_text')
->set_html('<h1>Connect/Reconnect</h2><p>if the above field is empty,
or the expire date looks suspicous, please reconnect to XeroOauth1 </p>
<form action="/">
<input type="hidden" name="xero_reauth" value="1" />
<input type="submit" class="button button-primary button-large" value="Xero Connect" />
</form>')
));

$this->storage->read_value();
}


function field_activated()
{
$this->storage->read_value();
$xeroTenantId = (string)$this->storage->getSession()['tenant_id'];
if ($xeroTenantId == "") {
$this->startAuthorization();
} else {
$this->refresh_token();
}
}

public function startAuthorization()
{
// This returns the authorizeUrl with necessary parameters applied (e.g. state).
$authorizationUrl = $this->provider->getAuthorizationUrl($this->options);

// Save the state generated for you and store it to the session.
// For security, on callback we compare the saved state with the one returned to ensure they match.
$this->storage->setOauth2State($this->provider->getState());

// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit();
}


function xero_callback()
{
if (isset($_GET['xero_reauth'])) {
$this->startAuthorization();
return;
}
if (!isset($_GET['xero_callback'])) {
return;
}
// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {
echo "Something went wrong, no authorization code found";
exit("Something went wrong, no authorization code found");

// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $this->storage->getOauth2State())) {
echo "Invalid State";
$this->storage->setOauth2State("");
exit('Invalid state');
} else {

try {
// Try to get an access token using the authorization code grant.
$accessToken = $this->provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);

$config = \XeroAPI\XeroPHP\Configuration::getDefaultConfiguration()->setAccessToken((string)$accessToken->getToken());
$identityInstance = new \XeroAPI\XeroPHP\Api\IdentityApi(
new \GuzzleHttp\Client(),
$config
);

$result = $identityInstance->getConnections();

// Save my tokens, expiration tenant_id
$this->storage->setToken(
$accessToken->getToken(),
$accessToken->getExpires(),
$result[0]->getTenantId(),
$accessToken->getRefreshToken(),
$accessToken->getValues()["id_token"]
);

// related to $this->build_settings_page
$url = "/wp-admin/options-general.php?page=crb_carbon_fields_container_xero_integration.php";
header('Location: ' . $url);
exit();

} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
echo "Xero Callback failed";
exit();
}
}
}

private function getRedirectURL() {
return get_site_url() . "/?xero_callback";
}

function refresh_token($enforced=false)
{
$this->storage->read_value();
$this->xeroTenantId = (string)$this->storage->getSession()['tenant_id'];

if ($this->storage->getHasExpired() || $enforced) {
$this->provider = $this->create_provider();

try {
$newAccessToken = $this->provider->getAccessToken('refresh_token', [
'refresh_token' => $this->storage->getRefreshToken()
]);

} catch (\Exception $e) {
$this->startAuthorization();
return;
}

// Save my token, expiration and refresh token
$this->storage->setToken(
$newAccessToken->getToken(),
$newAccessToken->getExpires(),
$this->xeroTenantId,
$newAccessToken->getRefreshToken(),
$newAccessToken->getValues()["id_token"]);
}
}

private function get_accounting_instance() {
$this->refresh_token();
if ($this->apiAccountingInstance == null) {
$this->config = \XeroAPI\XeroPHP\Configuration::getDefaultConfiguration()->setAccessToken(
(string)$this->storage->getSession()['token']);
$this->apiAccountingInstance = new \XeroAPI\XeroPHP\Api\AccountingApi(
new \GuzzleHttp\Client(),
$this->config
);
}
return $this->apiAccountingInstance;
}

private function get_payroll_au_instance() {
$this->refresh_token();
if ($this->apiPayrollInstance == null) {
$this->config = \XeroAPI\XeroPHP\Configuration::getDefaultConfiguration()->setAccessToken(
(string)$this->storage->getSession()['token']);
$this->config->setDebug(true);
$this->config->setDebugFile("/home/acaresydneycom/public_html/wp-content/plugins/ts/debug.log");
$this->apiPayrollInstance = new \XeroAPI\XeroPHP\Api\PayrollAuApi(
new \GuzzleHttp\Client(),
$this->config
);
}
return $this->apiPayrollInstance;
}

public function xero_org_name()
{
ini_set('display_errors', 'On');
$apiInstance = $this->get_accounting_instance();
$apiResponse = $apiInstance->getOrganisations($this->xeroTenantId);
return 'Organisation Name: <b> ' . $apiResponse->getOrganisations()[0]->getName() . "</b> ";
}

public function xero_org_contacts()
{
ini_set('display_errors', 'On');
$apiInstance = $this->get_accounting_instance();

$apiResponse = $apiInstance->getContacts($this->xeroTenantId);
$contacts = $apiResponse->getContacts();
$message = "<table> ";
$message .= "<tr> <td> # </td>
<td> unique-id </td>
<td> name </td>
<td> Supplier </td>
<td> Customer </td>
<td> Group </td>
<td> Status </td> </tr> ";
$count = 1;
foreach ($contacts as $c) {

$group = "";
foreach ($c->getContactGroups() as $g) {
$group .= $g->getName() . " - " . $g->getStatus() . "<br>";
}

$message .= "<tr> <td>" . $count++ . "</td> " .
"<td> " . $c->getContactId() . "</td> " .
"<td> " . $c->getName() . "</td> " .
"<td> " . ($c->getIsSupplier() ? "yes" : " - ") . "</td> " .
"<td> " . ($c->getIsCustomer() ? "yes" : " - ") . "</td> " .
"<td> " . $group . "</td> " .
"<td> " . $c->getContactStatus() . "</td> " .
"</tr>";
}
$message .= "</table>";
return $message;

}

public function xero_org_invoices() {
ini_set('display_errors', 'On');
$apiInstance = $this->get_accounting_instance();

$apiResponse = $apiInstance->getInvoices($this->xeroTenantId);
$invoices = $apiResponse->getInvoices();

$message = "<table> ";
$message .= "<tr> <td> # </td>
<td> invoice num</td>
<td> date </td>
<td> contact </td>
<td> amount </td>
<td> Type </td>
<td> Status </td> </tr> ";
$count = 1;

foreach ( $invoices as $c) {
$strDate = "";
$d = $c->getDate();
if ( $d != null) {
$da = $c->getDateAsDate();
$strDate = $da->format("Y-m-d");
} else {
$strDate = $d;
}

$message .= "<tr> <td>" . $count ++ . "</td> " .
"<td> " . $c->getInvoiceNumber() . "</td> " .
"<td> " . $strDate . "</td> " .
"<td> " . $c->getContact()->getName() . "</td> " .
"<td> " . $c->getTotal() . "</td> " .
"<td> " . $c->getType() . "</td> " .
"<td> " . $c->getStatus() . "</td> " .
"</tr>";
}
$message .= "</table>";
return $message;

}

public function xero_org_pay_items(){
ini_set('display_errors', 'On');
$api = $this->get_payroll_au_instance();

$xeroTenantId = $this->xeroTenantId;
//$xeroTenantId = "e23fd416-3b66-43e9-b908-97fbefa24eb8"; // demo company;
//$xeroTenantId = "4e2521ae-83e6-4895-aa90-b20aa0825ce1"; // Acaresydney ;

$ifModifiedSince = null;
$where = null; // "Status==\"ACTIVE\"";
$order = null; // "EmailAddress%20DESC";
$page = 1;
// $result = null;
try {
$result = $api->getPayItems ($xeroTenantId, $ifModifiedSince, $where, $order, $page);
$rates = $result->getPayItems()->getEarningsRates();
$message = "<table> ";
$message .= "<tr> <td> # </td>
<td> Name </td>
<td> EarningsType </td>
<td> RateType </td>
<td> AccountCode </td>
<td> Multiplier </td>
<td> IsExemptFromTax </td>
<td> IsExemptFromSuper </td>
<td> AccrueLeave </td>
<td> IsReportableAsW1 </td>
<td> UpdatedDateUTC </td>
<td> CurrentRecord </td> </tr> ";
$count = 1;

foreach ( $rates as $r) {
$message .= "<tr> <td>" . $r->getEarningsRateId() . "</td> " .
"<td> " . $r->getName() . "</td> " .
"<td> " . $r->getEarningsType() . "</td> " .
"<td> " . $r->getRateType() . "</td> " .
"<td> " . $r->getAccountCode() . "</td> " .
"<td> " . $r->getTypeOfUnits() . "</td> " .
"<td> " . $r->getRatePerUnit() . "</td> " .
"<td> " . $r->getIsExemptFromTax() . "</td> " .
"<td> " . $r->getIsExemptFromSuper() . "</td> " .
"<td> " . $r->getIsReportableAsW1() . "</td> " .
"<td> " . $r->getUpdatedDateUtc() . "</td> " .
"<td> " . $r->getCurrentRecord() . "</td> " .
"</tr>";
}
$message .= "</table>";
return $message;
} catch (\Exception $e) {
echo 'Exception when calling PayrollAuApi->getPayItems: ', $e->getMessage(), PHP_EOL;
return;
}
}

public function xero_org_employees(){
ini_set('display_errors', 'On');
$api = $this->get_payroll_au_instance();

$xeroTenantId = $this->xeroTenantId;
//$xeroTenantId = "e23fd416-3b66-43e9-b908-97fbefa24eb8"; // demo company;
//$xeroTenantId = "4e2521ae-83e6-4895-aa90-b20aa0825ce1"; // Acaresydney ;

$ifModifiedSince = date("M d Y H:i:s", strtotime("-30 days"));
$where = "Status==\"ACTIVE\"";
$order = null; // "EmailAddress%20DESC";
$page = 1;
// $result = null;
try {
$result = $api->getEmployees($xeroTenantId,$ifModifiedSince,$where,$order,$page);
$employees = $result->getEmployees();
$message = "<table> ";
$message .= "<tr> <td> # </td>
<td> First </td>
<td> Last </td>
<td> Status </td>
<td> Email </td>
<td> DOB </td>
<td> Gender </td>
<td> Phone </td>
<td> Mobile </td>
<td> Start </td>
<td> Group </td>
</tr> ";
$count = 1;
foreach ($employees as $r){

$message .= "<tr> <td>" . $count . "</td> " .
"<td> " . $r->getFirstName() . "</td> " .
"<td> " . $r->getLastName() . "</td> " .
"<td> " . $r->getStatus() . "</td> " .
"<td> " . $r->getEmail() . "</td> " .
"<td> " . $r->getDateOfBirthAsDate()->format("M d Y") . "</td> " .
"<td> " . $r->getGender() . "</td> " .
"<td> " . $r->getPhone() . "</td> " .
"<td> " . $r->getMobile() . "</td> " .
"<td> " . $r->getStartDateAsDate()->format("M d Y") . "</td> " .
"<td> " . $r->getEmployeeGroupName() . "</td> " .
"</tr>";
$count ++;
}
$message .= "</table>";
return $message;
} catch (\Exception $e) {
echo 'Exception when calling PayrollAuApi->getPayItems: ', $e->getMessage(), PHP_EOL;
return;
}
}

public function xero_org_clients(){
ini_set('display_errors', 'On');
try {
$contacts = $this->getClients();
$message = "<table> ";
$message .= "<tr> <td> # </td>
<td> Name </td>
<td> Last </td>
<td> Status </td>
<td> Email </td>
<td> AccountNumber </td>
<td> Addresses </td>
</tr> ";
$count = 1;
foreach ($contacts as $r){

$message .= "<tr> <td>" . $count . " - ". $r->getContactID() . "</td> " .
"<td> " . $r->getFirstName() . "</td> " .
"<td> " . $r->getLastName() . "</td> " .
"<td> " . $r->getContactStatus() . "</td> " .
"<td> " . $r->getEmailAddress() . "</td> " .
"<td> " . $r->getAccountNumber() . "</td> " .
"<td> " . $r->getAddresses() . "</td> " .
"</tr>";
$count ++;
}
$message .= "</table>";
return $message;
} catch (\Exception $e) {
echo 'Exception when calling PayrollAuApi->getPayContacts: ', $e->getMessage(), PHP_EOL;
return;
}
}


public function xero_org_payroll_calendar()
{
// update_option('bts_pay_roll_calendar_last_sync', time());
try {
$result = $this->get_payroll_calendar();
$pc = $result->getPayrollCalendars()[0];
$start = $pc->getStartDateAsDate()->format('Y-m-d');
$finish = new \DateTime($start);
$finish = $finish->modify("+13 days")->format('Y-m-d');
$paydate = $pc->getPaymentDateAsDate()->format('Y-m-d');
$calendar["start"] = $start;
$calendar["finish"] = $finish;
$calendar["paydate"] = $paydate;

return print_r ($calendar);
}catch (\Exception $e) {
echo 'Exception when calling PayrollAuApi->getPayrollCalendar: ', $e->getMessage(), PHP_EOL;
}
//update_option('bts_pay_roll_calendar', $calendar);
}

//
//TS implementation
//

/* sync xero to wp options */
public function init_wp(){
try{
error_log("init_wp is empty");
$this->sync_pay_item();
// $this->add_new_client();
// $this->add_new_employee();
// $this->sync_payroll_calendar();
}catch(\Exception $e){

}
}

private function sync_pay_item() {
if ($this->too_close_to_sync_payitem()){
//return;
}

$api = $this->get_payroll_au_instance();
$xeroTenantId = $this->xeroTenantId;
$page = 1;
try {
$result = $api->getPayItems($xeroTenantId, $ifModifiedSince, $where, $order, $page);



foreach ($result->getPayItems()->getEarningsRates() as $e){
// "EarningsRateID": "34e17d08-237a-4ae2-8115-375d1ff8a9ed",
// "Name": "Overtime Hours (exempt from super)",
// "EarningsType": "OVERTIMEEARNINGS",
// "RateType": "MULTIPLE",
// "AccountCode": "477",
// "Multiplier": 1.5,
// "IsExemptFromTax": true,
// "IsExemptFromSuper": true,
// "AccrueLeave": false,
// "IsReportableAsW1": true,
// "UpdatedDateUTC": "2019-03-16T13:18:19+00:00",
// "CurrentRecord": false
if ($e->getCurrentRecord() == "true"){
$payitem_options[]= array(
'EarningsRateID' => $e->getEarningsRateID(),
'Name'=> $e->getName(),
'EarningsType'=> $e->getEarningstype(),
'RatePerUnit' => $e->getRatePerUnit(),
'RateType' => $e->getRateType(),
'AccountCode' => $e->getAccountCode(),
"Multiplier"=> $e->getMultiplier(),
"IsExemptFromTax" => $e->getIsExemptFromTax(),
"IsExemptFromSuper"=> $e->getIsExemptFromSuper(),
"AccrueLeave" => $e->getAccrueLeave(),
"TypeOfUnits" => $e->getTypeOfUnits(),
"CurrentRecord"=> $e->getCurrentRecord(),
);
}
}
update_option('bts_payitem_earnings_rate', $payitem_options);
update_option('bts_payitem_last_sync', time());


} catch (Exception $e) {
echo 'Exception when calling PayrollAuApi->getPayItems: ', $e->getMessage(), PHP_EOL;
}
}

public function sync_users($mininterval, $employeeonly, $clientsonly){
echo "not implemented "; //TODO;
}

public function sync_payroll_calendar() {

}

private function too_close_to_sync_payitem(){
$lastsync = get_option('bts_payitem_last_sync', 0);
$now = time();
$diff = $now - (int) $lastsync;
return $diff < $this->minimum_sync_interval_in_seconds; //default 10 minutes
}

private function sync_payitem(){


}


private function too_close_to_add_employee(){
$lastsync = get_option('bts_add_employee_last_sync', 0);
$now = time();
$diff = $now - (int) $lastsync;
return $diff < 1.5 * $this->minimum_sync_interval_in_seconds; //default 1.1 * 10 minutes
}
private function too_close_to_add_client(){
$lastsync = get_option('bts_add_client_last_sync', 0);
$now = time();
$diff = $now - (int) $lastsync;
return $diff < 2.0 * $this->minimum_sync_interval_in_seconds; //default 1.2 * 10 minutes
}
private function too_close_to_sync_payroll_calendar(){
$lastsync = get_option('bts_pay_roll_calendar_last_sync', 0);
$now = time();
$diff = $now - (int) $lastsync;
return $diff < 3.0 * $this->minimum_sync_interval_in_seconds; //default 1.3 * 10 minutes
}






public function getClients($contact_group_id = null) {
if ( $contact_group_id == null ){
$contact_group_id = $this->clientContactGroupID;
}
$apiAcc = $this->get_accounting_instance();
$result = $apiAcc->getContactGroup($this->xeroTenantId, $contact_group_id);
$cg = $result->getContactGroups();
$allClients = $cg[0]->getContacts();

$ifModifiedSince = new \DateTime();
$recent = new \DateInterval("P30D");
$ifModifiedSince->sub($recent);


$allContacts = $apiAcc->getContacts($this->xeroTenantId, $ifModifiedSince);
$ret = [];
foreach ( $allContacts as $ac ) {
//search from within the group
$found = false;
$id = $ac->getContactID();
foreach ($allClients as $client) {
$clientID = $client->getContactID();
if ( $clientID == $id ) {
$found = true;
break;
}
}

if ( $found ) {
$ret[] = $ac;
}

}
return $ret;
}

public function get_payroll_calendar()
{
$id = "33dc7df5-3060-4d76-b4da-57c20685d77d"; //fortnightly
$api = $this->get_payroll_au_instance();

$pc = $api->getPayrollCalendar($this->xeroTenantId, $id);
return $pc;
}

}

+ 7
- 0
composer.json Ver fichero

@@ -0,0 +1,7 @@
{
"require": {
"xeroapi/xero-php-oauth2": "2.8.1",
"htmlburger/carbon-fields": "^3.3",
"guzzlehttp/psr7": "1.8.2"
}
}

+ 778
- 0
composer.lock Ver fichero

@@ -0,0 +1,778 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "fd8f5e90c9c2ce1e1f6b11421a29aa4a",
"packages": [
{
"name": "firebase/php-jwt",
"version": "v5.4.0",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
"reference": "d2113d9b2e0e349796e72d2a63cf9319100382d2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/d2113d9b2e0e349796e72d2a63cf9319100382d2",
"reference": "d2113d9b2e0e349796e72d2a63cf9319100382d2",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": ">=4.8 <=9"
},
"suggest": {
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
},
"type": "library",
"autoload": {
"psr-4": {
"Firebase\\JWT\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Neuman Vong",
"email": "neuman+pear@twilio.com",
"role": "Developer"
},
{
"name": "Anant Narayanan",
"email": "anant@php.net",
"role": "Developer"
}
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
"keywords": [
"jwt",
"php"
],
"support": {
"issues": "https://github.com/firebase/php-jwt/issues",
"source": "https://github.com/firebase/php-jwt/tree/v5.4.0"
},
"time": "2021-06-23T19:00:23+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "7.3.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "7008573787b430c1c1f650e3722d9bba59967628"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628",
"reference": "7008573787b430c1c1f650e3722d9bba59967628",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.4",
"guzzlehttp/psr7": "^1.7 || ^2.0",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0"
},
"provide": {
"psr/http-client-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"ext-curl": "*",
"php-http/client-integration-tests": "^3.0",
"phpunit/phpunit": "^8.5.5 || ^9.3.5",
"psr/log": "^1.1"
},
"suggest": {
"ext-curl": "Required for CURL handler support",
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "7.3-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://sagikazarmark.hu"
}
],
"description": "Guzzle is a PHP HTTP client library",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"psr-18",
"psr-7",
"rest",
"web service"
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.3.0"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://github.com/alexeyshockov",
"type": "github"
},
{
"url": "https://github.com/gmponos",
"type": "github"
}
],
"time": "2021-03-23T11:33:13+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d",
"reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d",
"shasum": ""
},
"require": {
"php": ">=5.5"
},
"require-dev": {
"symfony/phpunit-bridge": "^4.4 || ^5.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/1.4.1"
},
"time": "2021-03-07T09:25:29+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "dc960a912984efb74d0a90222870c72c87f10c91"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91",
"reference": "dc960a912984efb74d0a90222870c72c87f10c91",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.7-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Schultze",
"homepage": "https://github.com/Tobion"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
"uri",
"url"
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/1.8.2"
},
"time": "2021-04-26T09:17:50+00:00"
},
{
"name": "htmlburger/carbon-fields",
"version": "v3.3.2",
"source": {
"type": "git",
"url": "https://github.com/htmlburger/carbon-fields.git",
"reference": "dd5663e14c6db365323b688dbae1cfbeaf14bee7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/htmlburger/carbon-fields/zipball/dd5663e14c6db365323b688dbae1cfbeaf14bee7",
"reference": "dd5663e14c6db365323b688dbae1cfbeaf14bee7",
"shasum": ""
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"mockery/mockery": "^0.9.7",
"phpunit/phpunit": "~4.8"
},
"type": "library",
"autoload": {
"psr-4": {
"Carbon_Fields\\": "core/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-only"
],
"authors": [
{
"name": "htmlBurger",
"email": "wordpress@htmlburger.com",
"homepage": "https://htmlburger.com/",
"role": "Developer"
},
{
"name": "Miroslav Mitev",
"email": "mmitev.2create@gmail.com",
"role": "Developer"
},
{
"name": "Atanas Angelov",
"email": "atanas.angelov.dev@gmail.com",
"role": "Developer"
},
{
"name": "Georgi Stoyanov",
"email": "stoyanov.gs@gmail.com",
"role": "Developer"
},
{
"name": "Plamen Kostadinov",
"email": "pkostadinov.2create@gmail.com",
"homepage": "http://plasmen.info/",
"role": "Developer"
},
{
"name": "Stanimir Panchev",
"email": "Stan4omir@gmail.com",
"role": "Developer"
},
{
"name": "Marin Atanasov",
"email": "contact@marinatanasov.com",
"homepage": "http://marinatanasov.com/",
"role": "Developer"
},
{
"name": "Siyan Panayotov",
"homepage": "http://siyanpanayotov.com/",
"role": "Developer"
},
{
"name": "Peter Petrov",
"email": "peter.petrov89@gmail.com",
"role": "Developer"
},
{
"name": "Stanimir Stoyanov",
"email": "stanimir.k.stoyanov@gmail.com",
"role": "Developer"
},
{
"name": "Kaloyan Ivanov",
"email": "kaloyanxivanov@gmail.com",
"homepage": "http://vilepixels.com/",
"role": "Developer"
},
{
"name": "Georgi Popov",
"homepage": "http://magadanski.com/",
"role": "Developer"
},
{
"name": "German Velchev",
"email": "germozy@gmail.com",
"role": "Developer"
},
{
"name": "Rashko Petrov",
"email": "brutalenemy666@gmail.com",
"homepage": "http://errorfactory.com/",
"role": "Developer"
},
{
"name": "Alexander Panayotov",
"email": "alexander.panayotov@gmail.com",
"homepage": "http://alexanderpanayotov.com/",
"role": "Developer"
},
{
"name": "Viktor Vasilev",
"email": "liberalcho@gmail.com",
"role": "Developer"
},
{
"name": "Georgi Georgiev",
"email": "george.georgiev96@gmail.com",
"role": "Developer"
},
{
"name": "Atanas Vasilev",
"email": "atanasvasilev91@gmail.com",
"role": "Developer"
}
],
"description": "WordPress developer-friendly custom fields for post types, taxonomy terms, users, comments, widgets, options and more.",
"homepage": "http://carbonfields.net/",
"support": {
"docs": "http://carbonfields.net/docs/",
"email": "wordpress@htmlburger.com",
"issues": "https://github.com/htmlburger/carbon-fields/issues",
"source": "https://github.com/htmlburger/carbon-fields"
},
"time": "2021-04-22T13:24:34+00:00"
},
{
"name": "league/oauth2-client",
"version": "2.6.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/oauth2-client.git",
"reference": "badb01e62383430706433191b82506b6df24ad98"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/badb01e62383430706433191b82506b6df24ad98",
"reference": "badb01e62383430706433191b82506b6df24ad98",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.0 || ^7.0",
"paragonie/random_compat": "^1 || ^2 || ^9.99",
"php": "^5.6 || ^7.0 || ^8.0"
},
"require-dev": {
"mockery/mockery": "^1.3",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpunit/phpunit": "^5.7 || ^6.0 || ^9.3",
"squizlabs/php_codesniffer": "^2.3 || ^3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-2.x": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"League\\OAuth2\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alex Bilbie",
"email": "hello@alexbilbie.com",
"homepage": "http://www.alexbilbie.com",
"role": "Developer"
},
{
"name": "Woody Gilk",
"homepage": "https://github.com/shadowhand",
"role": "Contributor"
}
],
"description": "OAuth 2.0 Client Library",
"keywords": [
"Authentication",
"SSO",
"authorization",
"identity",
"idp",
"oauth",
"oauth2",
"single sign on"
],
"support": {
"issues": "https://github.com/thephpleague/oauth2-client/issues",
"source": "https://github.com/thephpleague/oauth2-client/tree/2.6.0"
},
"time": "2020-10-28T02:03:40+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v9.99.100",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
"shasum": ""
},
"require": {
"php": ">= 7"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*",
"vimeo/psalm": "^1"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"polyfill",
"pseudorandom",
"random"
],
"support": {
"email": "info@paragonie.com",
"issues": "https://github.com/paragonie/random_compat/issues",
"source": "https://github.com/paragonie/random_compat"
},
"time": "2020-10-15T08:29:30+00:00"
},
{
"name": "psr/http-client",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-client.git",
"reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
"reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
"psr/http-message": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP clients",
"homepage": "https://github.com/php-fig/http-client",
"keywords": [
"http",
"http-client",
"psr",
"psr-18"
],
"support": {
"source": "https://github.com/php-fig/http-client/tree/master"
},
"time": "2020-06-29T06:28:15+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/master"
},
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"support": {
"issues": "https://github.com/ralouphie/getallheaders/issues",
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
},
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "xeroapi/xero-php-oauth2",
"version": "2.8.1",
"source": {
"type": "git",
"url": "https://github.com/XeroAPI/xero-php-oauth2.git",
"reference": "cdf5dbeddff46d25212be596ff474c8bcf7351da"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/XeroAPI/xero-php-oauth2/zipball/cdf5dbeddff46d25212be596ff474c8bcf7351da",
"reference": "cdf5dbeddff46d25212be596ff474c8bcf7351da",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"firebase/php-jwt": "^5.0",
"guzzlehttp/guzzle": "^6.2 | ^7.0",
"guzzlehttp/psr7": "^1.8",
"league/oauth2-client": "^2.5.0",
"php": ">=5.6"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~2.12",
"phpunit/phpunit": "^4.8",
"squizlabs/php_codesniffer": "~2.6"
},
"type": "library",
"autoload": {
"psr-4": {
"XeroAPI\\XeroPHP\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Xero API Team",
"homepage": "https://developer.xero.com"
}
],
"description": "Xero official PHP SDK for oAuth2 generated with OpenAPI spec 3",
"homepage": "https://github.com/xeroapi/xero-php-oauth2",
"keywords": [
"api",
"openapispec",
"php",
"rest",
"sdk",
"xero"
],
"support": {
"issues": "https://github.com/XeroAPI/xero-php-oauth2/issues",
"source": "https://github.com/XeroAPI/xero-php-oauth2/tree/2.8.1"
},
"time": "2021-08-09T22:52:00+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.1.0"
}

Cargando…
Cancelar
Guardar