Skip to content

Installation v16.x.x

Luke Walsh edited this page Dec 18, 2022 · 1 revision

For v16.x.x


First off, the best way is to use Composer to grab the code:

composer require osiset/laravel-shopify

Note: You must install a laravel project first. Learn how to install Laravel with the official documentation.

Providers & Facades

With Laravel's auto-discover feature, this is handled for you on install.

Configuration

Package

php artisan vendor:publish --tag=shopify-config

You're now able to access config in config/shopify-app.php.

Essentially you will need to fill in the app_name, api_key, api_secret, and api_scopes to generate a working app. Items like webhooks and scripttags are completely optional depending on your app requirements. As well, anything to do with billing is also optional, and is disabled by default.

Its recommended you use an env file for the configuration.


Shopify App

In your app's settings on your Shopify Partner dashboard, you need to set the callback URL to be:

https://(your-domain).com/

And the redirect_uri to be:

https://(your-domain).com/authenticate

The callback URL will point to the home route, while the redirect_uri will point to the authentication route.

Routing

This package expects a route named home to exist. By default, the package has this route defined which shows a simple welcome page. To enable it, you will need to open routes/web.php and comment out the default Laravel route for /.

Optionally, to make your own, edit routes/web.php and modify the default route to use the auth.shop middleware with the home and login named, example:

Route::get('/', function () {
    return view('welcome');
})->middleware(['auth.shopify'])->name('home');

//This will redirect user to login page.
Route::get('/login', function () {
    if (Auth::user()) {
        return redirect()->route('home');
    }
    return view('login');
})->name('login');

Next, modify resources/views/welcome.blade.php to extend this packages' layout for Shopify AppBridge abilities, example:

@extends('shopify-app::layouts.default')

@section('content')
    <!-- You are: (shop domain name) -->
    <p>You are: {{ Auth::user()->name }}</p>
@endsection

@section('scripts')
    @parent

    <script type="text/javascript">
        var AppBridge = window['app-bridge'];
        var actions = AppBridge.actions;
        var TitleBar = actions.TitleBar;
        var Button = actions.Button;
        var Redirect = actions.Redirect;
        var titleBarOptions = {
            title: 'Welcome',
        };
        var myTitleBar = TitleBar.create(app, titleBarOptions);
    </script>
@endsection

Next, Create a login.blade.php with a form. Input with name="shop" to get the .myshopify.com domain of a store and a submit button which will submit the form to home route of your app.

Example:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Shopify App — Installation</title>

  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <style>
*{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body{padding:2.5em 0;color:#212b37;font-family:-apple-system,BlinkMacSystemFont,San Francisco,Roboto,Segoe UI,Helvetica Neue,sans-serif}.container{width:100%;text-align:center;margin-left:auto;margin-right:auto}@media screen and (min-width:510px){.container{width:510px}}.title{font-size:1.5em;margin:2em auto;display:flex;align-items:center;justify-content:center;word-break:break-all}.subtitle{font-size:.8em;font-weight:500;color:#64737f;line-height:2em}.error{line-height:1em;padding:.5em;color:red}input.marketing-input{width:100%;height:52px;padding:0 15px;box-shadow:0 0 0 1px #ddd;border:0;border-radius:5px;background-color:#fff;font-size:1em;margin-bottom:15px}input.marketing-input:focus{color:#000;outline:0;box-shadow:0 0 0 2px #5e6ebf}button.marketing-button{display:inline-block;width:100%;padding:1.0625em 1.875em;background-color:#5e6ebf;color:#fff;font-weight:700;font-size:1em;text-align:center;outline:0;border:0 solid transparent;border-radius:5px;cursor:pointer}button.marketing-button:hover{background:linear-gradient(to bottom,#5c6ac4,#4959bd);border-color:#3f4eae}button.marketing-button:focus{box-shadow:0 0 .1875em .1875em rgba(94,110,191,.5);background-color:#223274;color:#fff}
  </style>
</head>
<body>

  <main class="container" role="main">
    <h3 class="title">
    {{ env('SHOPIFY_APP_NAME','Shopify App') }}


    </h3>
    <p class="subtitle">
      <label for="shop">Enter your shop domain to log in or install this app.</label>
    </p>

    <form action="{{ route('home') }}" accept-charset="UTF-8">
        
      <input id="shop" name="shop" type="text" autofocus="autofocus" placeholder="example.myshopify.com" class="marketing-input">
      <button type="submit" class="marketing-button">Install</button>
</form> 
 </main>

</body>
</html>

You're also welcome to incorporate Polaris as normal.


Middlewares

Middlewares are handled by the provider of this package for you.


Models

You will need to modify your Laravel user model. Normally located in app/User.php or app/Models/User.php.

Open the file, add after the namespace:

use Osiset\ShopifyApp\Contracts\ShopModel as IShopModel;
use Osiset\ShopifyApp\Traits\ShopModel;

Next, modify the class line to become:

class User extends Authenticatable implements IShopModel

Next, inside the class, add:

use ShopModel;

A completed example:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Osiset\ShopifyApp\Contracts\ShopModel as IShopModel;
use Osiset\ShopifyApp\Traits\ShopModel;

class User extends Authenticatable implements IShopModel
{
    use Notifiable;
    use ShopModel;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

Jobs

Recommendations

By default Laravel uses the sync driver to process jobs. These jobs run immediately and synchronously (blocking).

This package uses jobs to install webhooks, scripttags, and an option after-install hook if any are defined in the configuration. If you do not have any after-install hooks, scripttags, or webhooks to install on the shop, you may skip this section.

If you do however, you can leave the sync driver as default. But, it may impact load times for the customer accessing the app. Its recommended to setup Redis or database as your default driver in config/queue.php so jobs can run in the background and not affect the frontend performance. See Laravel's docs on setting up queue drivers.

For more information on creating webhooks, see Creating Webhooks of this wiki or After Authentication Job.

ScriptTags Job

First, you need to get permission for write script tags to storefront. Add write_script_tags to api_scopes (or in SHOPIFY_API_SCOPES env variable) in config/shopify-app.php like the following:

'api_scopes' => env('SHOPIFY_API_SCOPES', 'read_products,write_products,write_script_tags'),

Second, add script tag values to scripttags in config/shopify-app.php:

'scripttags' => [
    [
        'src' => env('SHOPIFY_SCRIPTTAG_1_SRC', 'https://some-app.com/some-controller/js-method-response'),
        'event' => env('SHOPIFY_SCRIPTTAG_1_EVENT', 'onload'),
        'display_scope' => env('SHOPIFY_SCRIPTTAG_1_DISPLAY_SCOPE', 'online_store')
    ]
],

If you want to add local javascript file, you can do like the following:

'scripttags' => [
    [
        'src' => env('SHOPIFY_SCRIPTTAG_1_SRC', env('APP_URL') . '/scripttags/dummy.js'),
        'event' => env('SHOPIFY_SCRIPTTAG_1_EVENT', 'onload'),
        'display_scope' => env('SHOPIFY_SCRIPTTAG_1_DISPLAY_SCOPE', 'online_store')
    ]
],

dummy.js should be in public/scripttags directory.

Uninstalled Job (recommended)

There is a default job provided which soft deletes the shop, and its charges (if any) for you. You're able to install this job directly or extend it.

To install, first run:

php artisan vendor:publish --tag=shopify-jobs a job will be placed in App/Jobs/AppUninstalledJob.

Next, edit config/shopify-app.php to enable the job:

    'webhooks' => [
        [
            'topic' => env('SHOPIFY_WEBHOOK_1_TOPIC', 'app/uninstalled'),
            'address' => env('SHOPIFY_WEBHOOK_1_ADDRESS', 'https://(your-domain).com/webhook/app-uninstalled')
        ],
    ],

Use your environment file to replace the values, such as the domain, but set the topic to app/uninstalled and the path as /webhook/app-uninstalled will allow the webhook manager to do the heavy lifting for you.


Migrations

Automatic

By default, running php artisan migrate is enough. If you'd like to edit or review the migrations before running migrate, see Manual below.

Manual

Set env SHOPIFY_MANUAL_MIGRATIONS=1 or edit config/shopify-app.php, then run:

php artisan vendor:publish --tag=shopify-migrations

This will publish the migrations to your app's migration folder. When you're satisfied, run php artisan migrate to commit the changes.


AppBridge & Legacy

By default Appbridge is enabled, the embeddable mode for Shopify Apps. If you wish to disable this, set SHOPIFY_APPBRIDGE_ENABLED=0 for your environment variable. This will enabled legacy mode and skip any AppBridge modes.

Please note, X-Frame-Options header must be removed for AppBridge to function. This package attempts to remove this header through the responses in Laravel, but this does not work for all cases. For Nginx, and Laravel Forge, you must specifically comment-out or remove the line below from the Nginx configuration:

add_header X-Frame-Options "SAMEORIGIN";

The Nginx configuration is found in Laravel Forge at the very bottom of the page for the site in question: Files->Edit Nginx Configuration