Skip to content

Commit 02c1312

Browse files
committed
Initial import from project
0 parents  commit 02c1312

File tree

8 files changed

+266
-0
lines changed

8 files changed

+266
-0
lines changed

README.md

Whitespace-only changes.

_config/extensions.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: silverstripe-xero#extensions
3+
---
4+
SilverStripe\SiteConfig\SiteConfig:
5+
extensions:
6+
- FullscreenInteractive\SilverStripeXero\XeroSiteConfigExtension

_config/routes.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: silverstripe-xero#routes
3+
---
4+
SilverStripe\Control\Director:
5+
rules:
6+
'connectXero//$Action/$ID': 'FullscreenInteractive\SilverStripeXero\XeroController'

composer.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "fullscreeninteractive/silverstripe-xero",
3+
"description": "",
4+
"type": "silverstripe-vendormodule",
5+
"keywords": [
6+
"silverstripe",
7+
"xero"
8+
],
9+
"homepage": "https://github.com/fullscreeninteractive/silverstripe-xero",
10+
"license": "BSD-3-Clause",
11+
"authors": [
12+
{
13+
"name": "Will Rossiter",
14+
"email": "[email protected]"
15+
}
16+
],
17+
"require": {
18+
"silverstripe/framework": "^4",
19+
"calcinai/xero-php": "^2.3"
20+
},
21+
"require-dev": {
22+
"phpunit/phpunit": "^5.7",
23+
"squizlabs/php_codesniffer": "^3"
24+
},
25+
"replace": {
26+
"silverstripe/googlesitemaps": "*"
27+
},
28+
"extra": {
29+
"branch-alias": {
30+
"dev-master": "1.x-dev"
31+
}
32+
},
33+
"autoload": {
34+
"psr-4": {
35+
"FullscreenInteractive\\SilverStripeXero\\": "src/"
36+
}
37+
},
38+
"prefer-stable": true,
39+
"minimum-stability": "dev"
40+
}

src/DebugInvoice.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
use FullscreenInteractive\SilverStripeXero\XeroFactory;
4+
use SilverStripe\Dev\BuildTask;
5+
use SilverStripe\Security\Permission;
6+
use XeroPHP\Models\Accounting\Invoice;
7+
8+
class DebugInvoice extends BuildTask
9+
{
10+
public function run($request)
11+
{
12+
$invoiceId = $request->getVar('invoiceId');
13+
14+
if (Permission::check('ADMIN')) {
15+
$xero = XeroFactory::singleton()->getApplication();
16+
17+
print_r($xero->loadByGUID(Invoice::class, $invoiceId));
18+
}
19+
}
20+
}

src/XeroController.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace FullscreenInteractive\SilverStripeXero;
4+
5+
use SilverStripe\Control\Controller;
6+
use SilverStripe\Control\Director;
7+
use SilverStripe\Security\Permission;
8+
use SilverStripe\SiteConfig\SiteConfig;
9+
10+
class XeroController extends Controller
11+
{
12+
public function index()
13+
{
14+
$url = self::join_links(Director::absoluteBaseURL() . 'xero');
15+
16+
$provider = XeroFactory::singleton()->getProvider();
17+
18+
if (!isset($_GET['code'])) {
19+
// If we don't have an authorization code then get one
20+
$authUrl = $provider->getAuthorizationUrl([
21+
'scope' => 'openid offline_access email profile accounting.contacts accounting.transactions'
22+
]);
23+
24+
$_SESSION['oauth2state'] = $provider->getState();
25+
header('Location: ' . $authUrl);
26+
exit;
27+
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
28+
unset($_SESSION['oauth2state']);
29+
30+
exit('Invalid state');
31+
} else {
32+
$token = $provider->getAccessToken('authorization_code', [
33+
'code' => $_GET['code']
34+
]);
35+
36+
if (!Permission::check('ADMIN')) {
37+
return $this->httpError(401);
38+
}
39+
40+
$obj = SiteConfig::current_site_config();
41+
$obj->XeroAccessToken = $token->getToken();
42+
43+
$refresh = $token->getRefreshToken();
44+
45+
if ($refresh) {
46+
$obj->XeroRefreshToken = $refresh;
47+
}
48+
49+
$obj->write();
50+
$tenants = $provider->getTenants($token);
51+
52+
foreach ($tenants as $tenant) {
53+
$id = $tenant->id;
54+
55+
$obj->XeroTenantId = $id;
56+
$obj->write();
57+
58+
return $this->redirect('admin/settings/?doneGlobal=1');
59+
}
60+
}
61+
}
62+
}

src/XeroFactory.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace FullscreenInteractive\SilverStripeXero;
4+
5+
use SilverStripe\Control\Controller;
6+
use SilverStripe\Control\Director;
7+
use SilverStripe\Core\Environment;
8+
use SilverStripe\Core\Injector\Injectable;
9+
use SilverStripe\SiteConfig\SiteConfig;
10+
11+
class XeroFactory
12+
{
13+
use Injectable;
14+
15+
/**
16+
* @var \XeroPHP\Application
17+
*/
18+
protected $application;
19+
20+
/**
21+
* Setup
22+
*/
23+
public function setupApplication()
24+
{
25+
$provider = $this->getProvider();
26+
$config = SiteConfig::current_site_config();
27+
28+
$newAccessToken = $provider->getAccessToken('refresh_token', [
29+
'refresh_token' => $config->XeroRefreshToken
30+
]);
31+
32+
$config->XeroAccessToken = $newAccessToken->getToken();
33+
34+
$refresh = $newAccessToken->getRefreshToken();
35+
36+
if ($refresh) {
37+
$config->XeroRefreshToken = $refresh;
38+
}
39+
40+
$config->write();
41+
}
42+
43+
/**
44+
* @return \XeroPHP\Application
45+
*/
46+
public function getApplication()
47+
{
48+
if (!$this->application) {
49+
$this->setupApplication();
50+
}
51+
52+
return $this->application;
53+
}
54+
55+
/**
56+
* @return \Calcinai\OAuth2\Client\Provider\Xero
57+
*/
58+
public function getProvider()
59+
{
60+
return new \Calcinai\OAuth2\Client\Provider\Xero([
61+
'clientId' => Environment::getEnv('XERO_CLIENT_ID'),
62+
'clientSecret' => Environment::getEnv('XERO_CLIENT_SECRET'),
63+
'redirectUri' => $this->getRedirectUri()
64+
]);
65+
}
66+
67+
/**
68+
* @return string
69+
*/
70+
public function getRedirectUri()
71+
{
72+
return Controller::join_links(
73+
Director::absoluteBaseURL(),
74+
'connectXero'
75+
);
76+
}
77+
}

src/XeroSiteConfigExtension.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace FullscreenInteractive\SilverStripeXero;
4+
5+
use SilverStripe\Core\Environment;
6+
use SilverStripe\Forms\DropdownField;
7+
use SilverStripe\Forms\FieldList;
8+
use SilverStripe\Forms\ReadonlyField;
9+
use SilverStripe\ORM\DataExtension;
10+
use SilverStripe\Security\Permission;
11+
12+
class XeroSiteConfigExtension extends DataExtension
13+
{
14+
private static $db = [
15+
'XeroTenantId' => 'Varchar(200)',
16+
'XeroAccessToken' => 'Varchar(200)',
17+
'XeroRefreshToken' => 'Varchar(200)'
18+
];
19+
20+
public function updateCMSFields(FieldList $fields)
21+
{
22+
if (!Permission::check('ADMIN')) {
23+
return;
24+
}
25+
26+
if (!Environment::getEnv('XERO_CLIENT_ID') || !Environment::getEnv('XERO_CLIENT_SECRET')) {
27+
return;
28+
}
29+
30+
$fields->addFieldsToTab('Root.Xero', [
31+
ReadonlyField::create('XeroAccessToken', 'Access token')
32+
->setDescription(sprintf(
33+
'<a href="%s">Link to a xero account</a>',
34+
XeroFactory::singleton()->getRedirectUri()
35+
))
36+
]);
37+
38+
if ($this->owner->XeroAccessToken) {
39+
$provider = XeroFactory::singleton()->getProvider();
40+
$tenants = [];
41+
42+
foreach ($provider->getTenants($this->owner->XeroAccessToken) as $tenant) {
43+
$tenants[$tenant->id] = $tenant->name;
44+
}
45+
46+
$fields->addFieldsToTab('Root.Xero', [
47+
DropdownField::create(
48+
'XeroTenantId',
49+
'XeroTenantId',
50+
$tenants
51+
)
52+
]);
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)