|
- <?php
-
- /**
- * Plugin Name: Xero
- * Plugin URI: https://procomhost.com
- * Description: Xero Integration for Hair on the move created by Patrick
- * Version: 1.0
- * Author: Lena, Patrick
- * Author URI: http://github.com/
- */
-
- namespace Biukop;
- require_once(dirname(__FILE__) . '/vendor/autoload.php');
- require_once (ABSPATH . 'wp-includes/pluggable.php');
- require_once('storage.php');
-
- use Carbon_Fields\Container;
- use Carbon_Fields\Field;
-
- class Xero {
-
- 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']
- ];
- public $storage;
- public $config;
- public $apiInstance;
- public $xeroTenantId;
-
- public function __construct() {
- add_action( 'after_setup_theme', array($this,'boot_carbon' ));
- 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_action('init', array($this, "xero_init"));
- add_action('plugins_loaded', array($this, load_storage));
- // $this->xero_init();
- $this->storage = new StorageClass();
- }
-
- public function xero_init() {
- $this->provider = new \League\OAuth2\Client\Provider\GenericProvider([
- 'clientId' => '85B4A7B8AF35442CBB9943799B402FE1',
- 'clientSecret' => 'bNSYPDdBTGNMVF7kB56iOLhEmqQTlsitwH6cc4kQy83XW3iO',
- 'redirectUri' => 'https://procomhost.com/?xero_callback',
- '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'
- ]);
- }
-
- 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 Xero </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();
- }
- }
- }
-
- function refresh_token() {
- $this->storage->read_value();
- $this->xeroTenantId = (string)$this->storage->getSession()['tenant_id'];
-
- if ($this->storage->getHasExpired()) {
- $provider = new \League\OAuth2\Client\Provider\GenericProvider([
- 'clientId' => '85B4A7B8AF35442CBB9943799B402FE1',
- 'clientSecret' => 'bNSYPDdBTGNMVF7kB56iOLhEmqQTlsitwH6cc4kQy83XW3iO',
- 'redirectUri' => 'https://procomhost.com/test/xero-php-oauth2-starter/callback.php',
- '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'
- ]);
-
- try {
- $newAccessToken = $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"] );
- }
-
- if ( $this->apiInstance == null ){
- $this->config = \XeroAPI\XeroPHP\Configuration::getDefaultConfiguration()->setAccessToken( (string)$this->storage->getSession()['token'] );
- $this->apiInstance = new \XeroAPI\XeroPHP\Api\AccountingApi(
- new \GuzzleHttp\Client(),
- $this->config
- );
- }
- }
-
- public function xero_org_name() {
- ini_set('display_errors', 'On');
- $this->refresh_token();
-
- $apiResponse = $this->apiInstance->getOrganisations($this->xeroTenantId);
- $message = 'Organisation Name: <b> ' . $apiResponse->getOrganisations()[0]->getName() . "</b> ";
- return $message;
- }
-
- public function xero_org_contacts() {
- ini_set('display_errors', 'On');
- $this->refresh_token();
-
- $apiResponse = $this->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');
- $this->refresh_token();
-
- $apiResponse = $this->apiInstance->getInvoices($this->xeroTenantId);
- $invoices = $apiResponse->getInvoices();
-
- $message = "<table> ";
- $message .= "<tr> <td> # </td>
- <td> invoice id</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;
- }
-
- }
-
-
-
- $b = new Xero();
|