Skip to content

Commit 65f4e98

Browse files
committed
Merge remote-tracking branch 'upstream/master' into replace_rest_with_graphql_for_theme_level_support
2 parents 8c755c5 + a7ff629 commit 65f4e98

File tree

7 files changed

+101
-26
lines changed

7 files changed

+101
-26
lines changed

ignore-by-php-version.neon.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use PHPStan\DependencyInjection\NeonAdapter;
66

7-
$adapter = new NeonAdapter();
7+
$adapter = new NeonAdapter([]);
88

99
$config = [];
1010

src/Http/Middleware/Billable.php

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use Illuminate\Support\Facades\Redirect;
99
use Osiset\ShopifyApp\Contracts\ShopModel as IShopModel;
1010
use Osiset\ShopifyApp\Util;
11-
use RuntimeException;
1211

1312
/**
1413
* Responsible for ensuring the shop is being billed.
@@ -19,35 +18,47 @@ class Billable
1918
* Checks if a shop has paid for access.
2019
*
2120
* @param Request $request The request object.
22-
* @param Closure $next The next action.
21+
* @param Closure $next The next action.
2322
*
24-
*@throws Exception
23+
* @throws Exception
2524
*
2625
* @return mixed
2726
*/
2827
public function handle(Request $request, Closure $next)
2928
{
30-
if (!Util::isMPAApplication()) {
31-
throw new RuntimeException('You cannot use Billable middleware with SPA mode');
29+
if (Util::getShopifyConfig('billing_enabled') !== true) {
30+
return $next($request);
3231
}
3332

34-
if (Util::getShopifyConfig('billing_enabled') === true) {
35-
/** @var $shop IShopModel */
36-
$shop = auth()->user();
37-
if (!$shop->plan && !$shop->isFreemium() && !$shop->isGrandfathered()) {
38-
// They're not grandfathered in, and there is no charge or charge was declined... redirect to billing
39-
return Redirect::route(
40-
Util::getShopifyConfig('route_names.billing'),
41-
array_merge($request->input(), [
42-
'shop' => $shop->getDomain()->toNative(),
43-
'host' => $request->get('host'),
44-
'locale' => $request->get('locale'),
45-
])
46-
);
47-
}
33+
// Proceed if we are on SPA mode & it's a non ajax request
34+
if (!Util::isMPAApplication() && ! $request->ajax()) {
35+
return $next($request);
4836
}
4937

50-
// Move on, everything's fine
51-
return $next($request);
38+
/** @var $shop IShopModel */
39+
$shop = auth()->user();
40+
41+
// if shop has plan or is on freemium or is grandfathered then move on with request
42+
if (! $shop || $shop->plan || $shop->isFreemium() || $shop->isGrandfathered()) {
43+
return $next($request);
44+
}
45+
46+
$args = [
47+
Util::getShopifyConfig('route_names.billing'),
48+
array_merge($request->input(), [
49+
'shop' => $shop->getDomain()->toNative(),
50+
'host' => $request->get('host'),
51+
'locale' => $request->get('locale'),
52+
]),
53+
];
54+
55+
if ($request->ajax()) {
56+
return response()->json(
57+
['forceRedirectUrl' => route(...$args)],
58+
402
59+
);
60+
}
61+
62+
return Redirect::route(...$args);
5263
}
5364
}

src/Objects/Values/SessionToken.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ protected function verifyExpiration(): void
398398

399399
protected function determineTokenSource(array $body): int
400400
{
401-
if (!isset($body['iss']) && !isset($body['sid'])) {
401+
if (!isset($body['sid'])) {
402402
return SessionTokenSource::CHECKOUT_EXTENSION;
403403
}
404404

src/Traits/WebhookController.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,20 @@ public function handle(string $type, Request $request): ResponseResponse
3232
$jobClass = $config[$type]['class'];
3333
}
3434

35-
$jobClass::dispatch(
35+
$dispatch = $jobClass::dispatch(
3636
$request->header('x-shopify-shop-domain'),
3737
$jobData
38-
)->onConnection(Util::getShopifyConfig('job_connections')['webhooks'])
39-
->onQueue(Util::getShopifyConfig('job_queues')['webhooks']);
38+
);
39+
40+
$connection = Util::getShopifyConfig('job_connections')['webhooks'] ?? null;
41+
if ($connection) {
42+
$dispatch->onConnection($connection);
43+
}
44+
45+
$queue = Util::getShopifyConfig('job_queues')['webhooks'] ?? null;
46+
if ($queue) {
47+
$dispatch->onQueue($queue);
48+
}
4049

4150
return Response::make('', ResponseResponse::HTTP_CREATED);
4251
}

src/resources/views/auth/fullpage_redirect.blade.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
<meta charset="utf-8">
55
<base target="_top">
66
<meta name="shopify-api-key" content="{{ \Osiset\ShopifyApp\Util::getShopifyConfig('api_key', $shopDomain ?? Auth::user()->name ) }}"/>
7+
@if(request()->header('sec-fetch-dest') === 'iframe')
8+
<script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script>
9+
@endif
710

811
<title>Redirecting...</title>
912

tests/Http/Middleware/BillableTest.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Osiset\ShopifyApp\Test\Http\Middleware;
44

55
use Illuminate\Auth\AuthManager;
6+
use Illuminate\Http\Request;
67
use Osiset\ShopifyApp\Http\Middleware\Billable as BillableMiddleware;
78
use Osiset\ShopifyApp\Storage\Models\Charge;
89
use Osiset\ShopifyApp\Storage\Models\Plan;
@@ -100,4 +101,49 @@ public function testDisabledBillingShouldPassOn(): void
100101

101102
$this->assertTrue($result[0]);
102103
}
104+
105+
public function testNoNativeAppBridgeAndNoAjaxRequest(): void
106+
{
107+
$plan = factory(Util::getShopifyConfig('models.plan', Plan::class))->states('type_recurring')->create();
108+
$shop = factory($this->model)->create(['plan_id' => $plan->getId()->toNative()]);
109+
110+
factory(Util::getShopifyConfig('models.charge', Charge::class))->states('type_recurring')->create(
111+
[
112+
'plan_id' => $plan->getId()->toNative(),
113+
'user_id' => $shop->getId()->toNative(),
114+
]
115+
);
116+
117+
$this->auth->login($shop);
118+
$this->app['config']->set('shopify-app.billing_enabled', true);
119+
$this->app['config']->set('shopify-app.frontend_engine', 'REACT');
120+
121+
$request = Request::create('/test', 'GET');
122+
123+
$this->assertFalse($request->ajax());
124+
125+
$result = $this->runMiddleware(BillableMiddleware::class, $request);
126+
127+
$this->assertTrue($result[0]);
128+
}
129+
130+
public function testAjaxRequest(): void
131+
{
132+
$shop = factory($this->model)->create();
133+
134+
$this->auth->login($shop);
135+
$this->app['config']->set('shopify-app.billing_enabled', true);
136+
$this->app['config']->set('shopify-app.frontend_engine', 'REACT');
137+
138+
$request = Request::create('/test', 'GET');
139+
$request->headers->set('X-Requested-With', 'XMLHttpRequest');
140+
141+
$this->assertTrue($request->ajax());
142+
143+
$response = $this->runMiddleware(BillableMiddleware::class, $request);
144+
145+
$this->assertFalse($response[0]);
146+
$this->assertEquals(402, $response[1]->getStatusCode());
147+
$this->assertArrayHasKey('forceRedirectUrl', $response[1]->getData(true));
148+
}
103149
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"asset": {
3+
"key": "sections/no-schema.liquid",
4+
"value": "<!-- Invalid schema -->"
5+
}
6+
}

0 commit comments

Comments
 (0)