Git Product home page Git Product logo

basic-shopify-api's People

Contributors

atastycookie avatar darrynten avatar gnikyt avatar hugoheneault avatar jaffacake avatar jason-engage avatar jedimdan avatar lucasmichot avatar pagameba avatar roberttolton avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

basic-shopify-api's Issues

Change Connection Timeout?

Hi, where would you update the guzzle 'connect_timeout' => X value in the code?

I think at the moment its set to a large default number...

Throttling

thanks for the wonderful library!

Wondering how you are handling throttling. Are you doing that in your controllers? It's not built into the library, correct?

Thanks.

GraphQL Mutations

Hello.
The example you provided on how to create mutations (collectionCreate) works without any issues. The problem is I can't get the mutation publishablePublish to work. I'm trying the following:
$result = $this->GetGraphQLAccess()->graph( 'mutation publishablePublish($id: ID!, $input: [PublicationInput!]!) { publishablePublish(id: $id, input: $input) { publishable { availablePublicationCount publicationCount publishedOnPublication(publicationId: ' . $channelid . ') } userErrors { field message } } } ', ['id' => $productid, 'input' => ['publicationId' => $channelid]])

For some reason, when I print the response, it returns an empty request, like this:

["body"]=> object(stdClass)#20 (1) { ["publishablePublish"]=> NULL } ["errors"]=> bool(true)

Writing the same query in the Shopify GraphiQL App does actually work. I'm doing this query to publish all products in all available channels. Thanks in advance.

The errors of the shopify gateway is not displayed properly.

After reset api returns, there is no display of the correct error message.

$shop=ShopifyApp:shop();
$product = [
"title" =>'test',
"vendor" => 'abc',

            "options"=>[
						{
						  'name':'color_name'
						},
						{
						  'name':'size_name'
						}
						],
            "images" => [
                [
                    "src" =>'http://www.google.com/logo.jpg'
                ]
                
            ]
        ];

$result=$shop->api()->rest('POST','/admin/api/2019-07/products.json',['product'=>$product]);
$errors = $result->errors;
echo $errors;

The errors message not show.

if print_r($errors) the will show :

"message": "Allowed memory size of 2147483648 bytes exhausted (tried to allocate 1071648768 bytes)",
"exception": "Symfony\Component\Debug\Exception\FatalErrorException",

private api webhook

im wondering how do I verify webhook for private api? and since webhook are you using header POST, your example is not working

GET /admin/oauth/access_scopes.json - 404 ERROR

Array
(
    [errors] => [API] Invalid API key or access token (unrecognized login or wrong password)
    [status] => 401
)

Even when Token is correct. Same api call works with same token in postman.

At first i realised that, **Basic-Shopify-API** is adding version to this endpoint, while this endpoint do not support versioning.
I created a PR to fix this, Please check.

Now, 404 error is fixed but instead i am getting 401 error. Which is very weird.

Delete request params are being ignored

Hello!

Not very familiar with git :/ but would like to report that delete request's params are being ignored.

I believe line 718 in the api should something along the lines of:

$guzzleParams[strtoupper($type) === 'GET' || strtoupper($type) === 'DELETE' ? 'query' : 'json'] = $params;

originally its

$guzzleParams[strtoupper($type) === 'GET' ? 'query' : 'json'] = $params;

Thank you for an awesome solution!

Response body is empty

After using withPath() method from class GuzzleHttp\Psr7\Uri for generating uri to API request, response return empty body.

For example i try to call this API request from laravel-shopify package:
ShopifyApp::shop()->api()->request('GET', 'admin/themes/33141915714/assets.json?asset[key]=layout/theme.liquid&theme_id=33141915714')

In postman its return me asset object correctly. From laravel-shopify package, its return empty object to me. I try to find out a reason and it was because of withPath() method, which is called from rest() method in BasicShopifyAPI class.
Param which are pasting to withPath() method, in this case admin/themes/33141915714/assets.json?asset[key]=layout/theme.liquid&theme_id=33141915714, are replace by admin/themes/33141915714/assets.json%3Fasset%5Bkey%5D=layout/theme.liquid&theme_id=33141915714 because of rawurlencode() function inside of GuzzleHttp\Psr7\Uri class. Some characters are replaced by %3F or %5B, etc.

Final uri, in this case https://store.myshopify.com/admin/themes/33141915714/assets.json%3Fasset%5Bkey%5D=layout/theme.liquid&theme_id=33141915714, return empty body.

Rest & Graph return type incorrect in docblock

Hey, I noticed that in the documentation & in the code that you return an object back from the rest() & graph() functions. However, your docblock states that it returns an array instead.

This is breaking my coding standards checks and I've had to add in another casting into my code.

Could you update the docblock return type?

Thanks!

Newly created shops do not allow GET params to be sent as JSON.

Shops that are newly created no longer use JSON GET parameters. Requests result in a 400 error.

I am not sure which shops are affected but my older demo store from 2014 is unaffected and all demo stores created under the affiliate program after December, 1st 2017 have been affected in my experience.

The solution to this issue is to check if a request is GET and then to place the parameters on the url.

error example:

$request = $api->request('GET', '/admin/products.json', ['page' => $page, 'limit' => $limit]);

laravel-shopify-error

solution example:

$request = $api->request('GET', '/admin/products.json?page=' . $page . '&limit=' . $limit);

laravel-shopify-solution

GraphQL Examples

Thank you for the GraphQL update a few months back. I've actually had some time to play around with this, as it's my first experience with GraphQL. In a previous issue, you gave an example to pull some basic data, which works perfectly.

Can we get just a few more basic examples using mutations for example? I'm struggling to get one simple query working with Basic-Shopify-API throwing an error at me, Undefined property: stdClass::$extensions.

Any help is much appreciated.

Return value of Osiset\BasicShopifyAPI::jsonDecode() must be an instance of stdClass, null returned

Catch this in my Sentry logs, sometimes Shopify seems to return null.
Maybe can we add something to catch the null in $this->jsonDecode($body);

Symfony\Component\Debug\Exception\FatalThrowableError: Return value of Osiset\BasicShopifyAPI::jsonDecode() must be an instance of stdClass, null returned
#19 /vendor/osiset/basic-shopify-api/src/Osiset/BasicShopifyAPI.php(1004): Osiset\BasicShopifyAPI::jsonDecode
#18 /vendor/osiset/basic-shopify-api/src/Osiset/BasicShopifyAPI.php(832): Osiset\BasicShopifyAPI::Osiset\{closure}
#17 /vendor/osiset/basic-shopify-api/src/Osiset/BasicShopifyAPI.php(868): Osiset\BasicShopifyAPI::rest

Add error key to error response

Currently you only check for the error key: $body = property_exists($body, 'errors') ? $body->errors : null;

I think it definitely makes sense to add a check for the error key as well. This is the case e.g. when creating fulfillments with missing data: "error":"location_id must be specified when creating fulfillments."

This my workaroud for now:

if ($body !== null) {
    if (property_exists($body, 'errors'))
    {
        $body = $body->errors;
    }
    elseif (property_exists($body, 'error'))
    {
        $body = $body->error;
    }
    else
    {
        $body = null;
    }
}

GraphQL Rate Limitting

I am using this package with a month,
I found a little bit missing functionality for GraphQL of Rate Limitting.
As you have covered RateLimiting for REST API, and it works without throwing any error.
I was trying to implement it for my GraphQL calls, but it's not that easy as i have thought, can you please implement Rate Limitting for GraphQL? It will be real great update.

I am trying to implement this functionality on myself. I will need current Query Cost and Available Cost to add sleep time before making GraphQL request, but I am not able to calculate my current Query Cost, I can retrieve Available Cost from apiCallLimits, if we can calculate query cost before making request than might we can implement Rate Limitting functionality for GraphQL.

REST call doesn't add version number.

Based on the docs to create the Fulfillment here, I used the following code using this package.

$api = new BasicShopifyAPI();
$api->setVersion('2019-07'); // "YYYY-MM" or "unstable"
$api->setShop('your shop here');
$api->setAccessToken('your token here');

// Now run your requests...
$data = [
     'fulfillment'=>[
         //  ....
     ]
];
$api->rest('POST','/admin/api/orders/'.$orderId.'/fulfillments.json',$data);

The above call doesn't seem to add the set version info to the URI before sending the request to Shopify. i had to manually append the version segment to the URI.

API Rate Limiting

I'm finding that whatever settings I enter into $this->api->enableRateLimiting(750, 500); doesn't seem to be working, or I'm misunderstanding something. To test it, I've created a function:

public function testDelay() {
    for ($i = 1; $i <= 5; $i++) {
        $job = new DelayTest($i, new DateTime('now'));
        $this->dispatch($job);
    }
    echo "\n";
}

The job being executed reaches out to Shopify and pulls an index on orders from another controller. Here's the Job:

class DelayTest implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $iteration;
    private $then;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(int $iteration, DateTime $then)
    {
        $this->iteration = $iteration;
        $this->then = $then;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $now = new DateTime('now');
        $getCtrl = new GetController();
        $orders = $getCtrl->orders('1', (string)$this->iteration, '10', 'any', 'any', 'any');
        $orders = \json_decode($orders);
        echo $this->iteration . '| order id: ' . $orders[0]->id . " then: " . $this->then->format('H:i:s:v') . ", now: " . $now->format('H:i:s:v') . "\n";
    }
}

The output of the above gives me this:

1| order id: 1874921488420 then: 06:51:16:114, now: 06:51:16:118
2| order id: 1874915131428 then: 06:51:16:652, now: 06:51:16:653
3| order id: 1874907103268 then: 06:51:17:121, now: 06:51:17:122
4| order id: 1874894946340 then: 06:51:17:642, now: 06:51:17:643
5| order id: 1874877317156 then: 06:51:18:095, now: 06:51:18:096

What confuses me is that the now: timestamp isn't being incremented by 750ms. Am I approaching this correctly?

"access_scopes" gets no token attached

Expected Behavior

When requesting to get the current token access_scopes
I would like to get them properly

Current Behavior

Currently I get a 401 response, thats because we are not adding the access token to the request.

Steps to Reproduce

  1. do a GET request to /admin/oauth/access_scopes
  2. you will get 401

I looked a the code and saw the below method inside BasicShopifyAPI.php
We are not adding the token for the "access_scopes" path

Any reason for that?

    protected function isAuthableRequest(string $uri)
    {
        return preg_match('/\/admin\/oauth\/(authorize|access_token|access_scopes)/', $uri) === 0;
    }

Thanks!

Improvements

  1. Will add a setSession shortcut which will allow for passing of shop domain and shop token. Simply a quicker and less verbose method

  2. Will add a withSession which will be similar to setSession however it will accept a closure to do work.

Example:

// Do stuff for shop1
$api->withSession('shop1.myshopify.com', 'abc', function() {
    // $this will reference a new instance of BasicShopifyAPI automatically injected
    $request = $this->request('GET', '/admin/shop.json');
    print $request->body->shop->name; // Shop 1
});

// Do stuff for shop2
$api->withSession('shop2.myshopify.com', 'abc', function() {
    $request = $this->request('GET', '/admin/shop.json');
    print $request->body->shop->name; // Shop 2
});

Each will be isolated instances.

Will try to code this in next week! As well as fix the open issue.

id ad bigint

Thanks for the awesome API!

I was using it to download products, and I noticed that it is converting the id to float.

It seems that Shopify is using bigint for id's

https://twitter.com/tobi/status/294449853319233536

But json_decode turns that to float.

http://php.net/manual/en/function.json-decode.php

Bitmask of JSON decode options. Currently there are two supported options. The first is JSON_BIGINT_AS_STRING that allows casting big integers to string instead of floats which is the default. The second option is JSON_OBJECT_AS_ARRAY that has the same effect as setting assoc to TRUE.

One solution is to json_decode as:

$array = json_decode($json, true, 512, JSON_BIGINT_AS_STRING)

Not sure if that would affect anything else.

Thanks!

Webhooks not registering on shopify

I can't seem to get the webhooks registering for my embedded shopify app using this package but everything else works great!

I am using laravel 5.8 and the latest "ohmybrew/laravel-shopify": "^9.1"

I have gone into the OhMyBrew\ShopifyApp\Services\WebhookManager and logged if they are being created and indeed they are. When I try to trigger the event on shopify's end there is no request at my app. I have also tried a get request to see the registered webhooks.json and it is empty.

Currently I am able to make a webhook in the notifications admin area on the store but this is not a great solution since it is not scalable and requires a new api token for authentication.

I need help figuring out why these aren't registering even though it looks like everything is working as it should.

Here are a couple of screenshots to show you the above description:

Screen Shot 2019-08-30 at 5 30 38 PM

Screen Shot 2019-08-30 at 5 31 23 PM

Screen Shot 2019-08-30 at 5 35 28 PM

Thanks for your time

GraphQL Support

Although in beta, I will add support for it.

At a glance, this will involve making an abstract class for the base, with an interface; then, creating a new class for the graphQL which extends the base; then, modifying the original class to extend the base.

The GraphQL functions pretty similar. High level its just a different endpoint, and different limits to grab (costs).

Will be investigating this in a new branch. There should be no breaking changes for this.

Restricting DB data to only the connected shop/user

I'm a Laravel newbie and maybe I missed it somewhere here, but how is everyone managing queries for each shop so that they only have access to their own data? Currently I'm passing a shop ID condition in to all my queries. Is there something built in that passes the shop ID or other authenticated ID to the model?

General search is suggesting that I extend the model to include the shop ID so I don't have to added it to every query. I'm still trying to figure out how to do this. However it seems like a package that is designed to handle multiple shops would have this already, so I think I'm missing something.

HTTP response code was 503

Just got this error today:

Invalid response object from API:  (HTTP response code was 503) {"userId":6,"exception":"[object] (ShippingEasy_ApiError(code: 0): Invalid response object from API:  (HTTP response code was 503) at /var/www/xxx/vendor/maverickslab/shipping-easy/src/shipping_easy-php/lib/ShippingEasy/ApiRequestor.php:52)

Required parameter missing or invalid on Variant Put Request

Hi,

Probably me being really stupid. I can connect but every time I try to update the price I get Required parameter missing or invalid on Variant Put Request - Not sure what I am missing?

The code I am running is below. The variant ID is correct. Apologies in advance if this is the wrong place for this.

$api = new BasicShopifyAPI(true); // true sets it to private
$api->setVersion('2019-10'); // "YYYY-MM" or "unstable"
$api->setShop( $shopify_url );
$api->setApiKey( $api_key );
$api->setApiPassword( $api_pwd );
$response = $api->rest( 
    'PUT', 
    '/admin/variants/__VARIANT_ID__.json',
    ['id'=>__VARIANT_ID__,'price'=>'69.99'], 
);

Ta in advance

Querying with Danish characters in SKU returns no results

Using Danish characters in an sku query (æøåÆØÅ) results in no hits.
If the same query phrase is used in GraphiQL or Insomnia, the result is positive as expected.

Query:
{ products(first: 1, query: "sku:GR-GREGARTEØ-0100") { edges { node { id } } } }

Result:
{"response":{},"body":{"products":{"edges":[]}},"errors":false,"timestamps":[null,1585393004.7812]}

If same query is run in GraphiQL or Insomnia this is the result:
{
"data": {
"products": {
"edges": [
{
"node": {
"id": "gid://shopify/Product/9628048583"
}
}
]
}
},
"extensions": {
"cost": {
"requestedQueryCost": 3,
"actualQueryCost": 3,
"throttleStatus": {
"maximumAvailable": 1000.0,
"currentlyAvailable": 997,
"restoreRate": 50.0
}
}
}
}

And I really cant figure out why?

Memory size exhaust

Expected behavior:
Return error: Invalid token

What happens:
Symfony\Component\Debug\Exception\FatalErrorException Allowed memory size of 134217728 bytes exhausted (tried to allocate 60821504 bytes)

Step to reproduce:

  • Install Basic Shopify API

  • Call REST function with wrong token:

       $api = new BasicShopifyAPI();
       $api->setVersion('2019-10')
       $api->setShop('xxxx.myshopify.com');
       $api->setAccessToken($token); 
       $resul = $api->rest('get','admin/shop.json');
    

Dependencies:

    "ohmybrew/basic-shopify-api": "^6.1",
    "php": "^7.2",
    "laravel/framework": "^6.2",

extractLinkHeader not always extracting the desired link

Hi,

I found very useful the new functionality about parsing the "Link" header to the "link" property, for pagination purposes.
This functionality works perfect for the first page, because we have the "page_info" string in the "link" property.
The problem comes in the second page, where the "Link" header returns two links:

<https://xxxx.myshopify.com/admin/api/2019-10/products.json?limit=3&page_info=eyJkaXJlY3Rpb24iOiJwcmV2IiwibGFzdF9pZCI6MjM5ODQxNjg5NjA3NywibGFzdF92YWx1ZSI6IlNpbGxhIGRlIHJ1ZWRhcyBhIHBlZGFsZXMifQ>; rel="previous", 
<https://xxxx.myshopify.com/admin/api/2019-10/products.json?limit=3&page_info=eyJkaXJlY3Rpb24iOiJuZXh0IiwibGFzdF9pZCI6MjQ2NzI4MzEwNzkxNywibGFzdF92YWx1ZSI6IlRlc3Qgbm90IHB1Ymxpc2hlZCJ9>; rel="next"

The regex in the "extractHeaderLink" will always take the page_info from the first link, and forget about the second one.
This is not good if you are expecting the "link" parameter to loop over a big collection in Shopify API, because you are getting in an infinite loop in page 1, page 2, page 1, page 2. This is because the "previous" page link, always appear in first place in the header (except in page 1, where there is only a "next" page link).

My proposal, is to have both "previous" and "next" properties in BasicShopifyAPI class, along with the "link", which takes the correct "page_info" link for the previous page and for the next one respectively.

Thanks!

Serialization of 'Closure' is not allowed in laravel job queue.

Hi, i have created a job to handle large product data. I have using laraveljob queue to handle product data but i am getting "Serialization of 'Closure' is not allowed " error due to to client configuration i.e $api = new BasicShopifyAPI(); .

I know we need to serialize this $api = new BasicShopifyAPI(); but i don't know how i can do this.
Laravel queue job class not allow this configuration. Can you please help me ,how we can handle this in the laravel job queue ?

Redirects not handled with private access

Using private access, redirects (Location header) in Shopify do not include private credentials.

So when accessing discount lookup for example, it will redirect to a login page.

This is now fixed in master with #900bc0b.

It also includes an error handler for CLIENT errors only (400 types).

Tests need to be adjusted and written to account for this now... will update.

Feature request - retry n times with backoff rate settings for api failures

Great library! I'd like to make a feature request for a retry option.

  • $api->setIntervalSeconds(n)

    • Defaults to 1
    • Where n is a positive integer representing seconds between retries
  • $api->setMaxAttempts(n)

    • Defaults to 2
    • Where n is the number of times to retry a failed API call before throwing an exception.
  • $api->setBackOffRate(n)

    • Default to 2 seconds.
    • Where n is the positive integer representing the multiplier by which the retry interval increases during each attempt.

AWS does this, e.g., with Step Functions: https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html

Signatures do not expire

The verifyRequest method does not check the freshness of the signature, which means the signatures are still valid after expiration on Shopify.

It should be possible to configure an expiration and check the timestamp at L524.

Api GetUser

I have set
SHOPIFY_API_GRANT_MODE=per-user in my .env
and when I call $shop->api() I see the access_token.

But when I call $shop->api()->getUser() it returns null. What am I missing?

Unsure how to use setLogger

Hi,

I'm not sure how to use $api->setLogger function so it will write into Laravel log files.
I'm trying to get the errors->exception from the rest response and I see that the api class already logs it so I tried to use setLogger however I don't see it created the file.

Most likely, I set it up incorrectly.

This is my code:

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('shopify');
        $logger->pushHandler(new StreamHandler(storage_path('logs/flagged-order.log'), Logger::WARNING));
        $this->shop->api()->setLogger($logger);

Here's the api response:

{#6643 ▼
  +"response": Response {#6640 ▼
    -reasonPhrase: "Bad Request"
    -statusCode: 400
    -headers: array:29 [▶]
    -headerNames: array:29 [▶]
    -protocol: "1.1"
    -stream: Stream {#6638 ▶}
  }
  +"errors": {#6634 ▼
    +"status": 400
    +"body": {#261 ▼
      +"errors": {#6637 ▼
        +"page_info": "Invalid value."
      }
    }
    +"exception": ClientException {#6641 ▶}
  }
  +"body": ""
  +"timestamps": array:2 [▶]

Please help. Thanks :)

Help for newbie

Hi, I have installed composer and install this library with that.
After I have installed also psr/log as first composer command didn't it.

C:\Users\Fernando>composer require ohmybrew/basic-shopify-api
Using version ^5.4 for ohmybrew/basic-shopify-api
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 6 installs, 0 updates, 0 removals
  - Installing guzzlehttp/promises (v1.3.1): Downloading (100%)
  - Installing ralouphie/getallheaders (3.0.3): Downloading (100%)
  - Installing psr/http-message (1.0.1): Downloading (100%)
  - Installing guzzlehttp/psr7 (1.6.1): Downloading (100%)
  - Installing guzzlehttp/guzzle (6.3.3): Downloading (100%)
  - Installing ohmybrew/basic-shopify-api (v5.4.0): Downloading (100%)
guzzlehttp/psr7 suggests installing zendframework/zend-httphandlerrunner (Emit P
SR-7 responses)
guzzlehttp/guzzle suggests installing psr/log (Required for using the Log middle
ware)
Writing lock file
Generating autoload files

C:\Users\Fernando>composer require psr/log
Using version ^1.1 for psr/log
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing psr/log (1.1.0): Downloading (100%)
Writing lock file
Generating autoload files

After that I have move vendor folder to my project (I have done compose in a virtual machine) in XAMPP portable.

With this php file:

<?php
require __DIR__ . "/../vendor/autoload.php"; 
use OhMyBrew\BasicShopifyAPI;
$api = new OhMyBrew\BasicShopifyAPI(true);
$api->setVersion('2019-10'); // "YYYY-MM" or "unstable"
$api->setShop('YYYYY.myshopify.com');
$api->setApiPassword('XXXXX');
.....

I get this error:

Fatal error: Uncaught Error: Class 'OhMyBrew\BasicShopifyAPI' not found in D:\xampp\htdocs\app\customers.php:15 Stack trace: #0 {main} thrown in D:\\xampp\htdocs\app\customers.php on line 4

Could any body help me?
Is there any way to install this library without composer?
What am I doing wrong ?

Thanks

Documentation Error

Just noticed an error in the 'Errors' section of the documentation, that currently states:

$call = $api->rest('GET', '/admin/non-existant-route-or-object.json');

if ($call->errors) {
  echo "Oops! {$call->errors->status} error";
  print_r($call->errors->body);

  // Original exception can be accessed via `$call->errors->exception`
  // Example, if response body was `{"error": "Not found"}`...
  /// then: `$call->errors->body->error` would return "Not Found"
}

However, errors is a boolean and trying to access $call->errors->exception results in "Trying to get property 'exception' of non-object"

Trying to get property 'errors' of non-object

Following the readme I'm given the error in the title. I'm trying to access the API using a private app.

$api = new BasicShopifyAPI(true);
$api->setVersion('2019-04'); // "YYYY-MM" or "unstable"
$api->setShop('...');
$api->setApiKey('...');
$api->setApiPassword('...');
$api->setApiSecret('...');
$result = $api->rest('GET', 'orders.json');
return $result;
development.ERROR: Trying to get property 'errors' of non-object {"userId":1,"exception":"[object] (ErrorException(code: 0): Trying to get property 'errors' of non-object at /mnt/d/work/app/vendor/ohmybrew/basic-shopify-api/src/OhMyBrew/BasicShopifyAPI.php:776)
[stacktrace]
#0 /mnt/d/work/app/vendor/ohmybrew/basic-shopify-api/src/OhMyBrew/BasicShopifyAPI.php(776): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Trying to get p...', '/mnt/d/work/eco...', 776, Array)
#1 /mnt/d/work/app/vendor/ohmybrew/basic-shopify-api/src/OhMyBrew/BasicShopifyAPI.php(791): OhMyBrew\\BasicShopifyAPI->OhMyBrew\\{closure}(Object(GuzzleHttp\\Exception\\ClientException))
#2 /mnt/d/work/app/app/Http/Controllers/ShopifyController.php(233): OhMyBrew\\BasicShopifyAPI->rest('GET', 'orders.json')
#3 [internal function]: App\\Http\\Controllers\\ShopifyController->getById(Object(Illuminate\\Http\\Request), '1', '1825670823972')
#4 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): call_user_func_array(Array, Array)
#5 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction('getById', Array)
#6 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(219): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\ShopifyController), 'getById')
#7 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(176): Illuminate\\Routing\\Route->runController()
#8 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(680): Illuminate\\Routing\\Route->run()
#9 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#10 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#11 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#12 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#13 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(43): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#14 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Auth\\Middleware\\Authenticate->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'api')
#15 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#16 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(58): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#17 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure), 60, '1')
#18 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#19 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#20 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#21 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(657): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#22 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(623): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#23 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(612): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#24 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#25 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#26 /mnt/d/work/app/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#27 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#28 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#29 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#30 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#31 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#32 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#33 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#34 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#35 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#36 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#37 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#38 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#39 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#40 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#41 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#42 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#43 /mnt/d/work/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#44 /mnt/d/work/app/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#45 {main}
"} 

Not clear in README that params do not only apply to url params only.

$api->rest(string $type, string $path, array $params = null);

This is minor, but it wasn't as easy to understand as it could be that when the type is something other then GET that params will be converted to JSON as the payload. Documentation only refers to "the path", which in my opinion points to the query string params on a GET.

params refers to an array of params you wish to pass to the path, examples: ['handle' => 'cool-coat']

My suggestion would be to make it a little more clear how the type and the params operate for GET, POST, PUT, DELETE, etc.

  • params refers to an array of params you wish to pass to the path, examples ['handle' => 'cool-coat']. When the type will perform an update such as a PUT params will be converted to JSON as the payload.

Webhook in Private App

Hi @ohmybrew

I used this package for a Private App.
So, how can I use the webhook in a private app? It will auto verify the webhook call or I have to verify manually?

Async with GraphQL

I see rest has async, what about GraphQL? Is anything prohibitive to implementing this?

extractLinkHeader fails when underscore is present in page link

I got an invalid value error from Shopify on page_info.

Looking into the raw request I can see that the parsed next link does not match the link in the raw request.

Direct from the link header:
<https://domain.myshopify.com/admin/api/2019-10/products.json?limit=100&page_info=eyJkaXJlY3Rpb24iOiJwcmV2IiwibGFzdF9pZCI6NDI3NDE1NjQzNzYzOSwibGFzdF92YWx1ZSI6IkJ5IE5vcmQgLSBEZWxsaW5nIGxpbm5lZHVrIC0gMiBzdG9ybGVrYXIgb2NoIDMgZsOkcmdlciJ9>; rel="previous", <https://domain.myshopify.com/admin/api/2019-10/products.json?limit=100&page_info=eyJkaXJlY3Rpb24iOiJuZXh0IiwibGFzdF9pZCI6MjAxMjc3MjA0MDc2NywibGFzdF92YWx1ZSI6IkNobG_DqSAtIExvdmUgU3RvcnkgRURQIDMwIG1sIn0>; rel="next"

Parsed links:
"next": "eyJkaXJlY3Rpb24iOiJuZXh0IiwibGFzdF9pZCI6MjAxMjc3MjA0MDc2NywibGFzdF92YWx1ZSI6IkNobG" "previous": "eyJkaXJlY3Rpb24iOiJwcmV2IiwibGFzdF9pZCI6NDI3NDE1NjQzNzYzOSwibGFzdF92YWx1ZSI6IkJ5IE5vcmQgLSBEZWxsaW5nIGxpbm5lZHVrIC0gMiBzdG9ybGVrYXIgb2NoIDMgZsOkcmdlciJ9"

The issue seems to be the underscore in the link and can be fixed by adding _ to the regex.

$regex = '/<.*page_info=([a-z0-9\-_]+).*>; rel="?{type}"?/i';

https://github.com/ohmybrew/Basic-Shopify-API/blob/master/src/OhMyBrew/BasicShopifyAPI.php#L1113

GraphQL call does not work properly

Using the sample code
$call = $api->graph('{ shop { products(first:1) { edges { node { handle, id } } } } }');
You receive the response

Instead if you use
$call = $api->graph('{ shop { products(last:1) { edges { node { handle, id } } } } }');
I receive nothing

Even if I try to make a query
$call = $api->graph('{ shop { products(query:"tag:foo") { edges { node { handle, id } } } } }');
I receive nothing

Call to a member function getBody() on null

Just recieved this error this morning

[2019-12-10 08:32:28] production.ERROR: Call to a member function getBody() on null {"userId":9,"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function getBody() on null at /var/www/web-app/vendor/ohmybrew/basic-shopify-api/src/OhMyBrew/BasicShopifyAPI.php:772)
[stacktrace]
#0 /var/www/web-app/vendor/ohmybrew/basic-shopify-api/src/OhMyBrew/BasicShopifyAPI.php(803): OhMyBrew\\BasicShopifyAPI->OhMyBrew\\{closure}(Object(GuzzleHttp\\Exception\\ConnectException))
#1 /var/www/web-app/app/Http/Controllers/Shopify/GetController.php(229): OhMyBrew\\BasicShopifyAPI->rest('GET', '/admin/products...', Array)
#2 /var/www/web-app/app/Http/Controllers/Shopify/GetController.php(221): App\\Http\\Controllers\\Shopify\\GetController->getOrderProductsByIds(Array)
#3 /var/www/web-app/app/Http/Controllers/ShippingEasyController.php(107): App\\Http\\Controllers\\Shopify\\GetController->getOrderProducts(Array, 1)
#4 /var/www/web-app/app/Http/Controllers/CarrierController.php(61): App\\Http\\Controllers\\ShippingEasyController->getByNumber(Object(App\\Store), '656373')
#5 [internal function]: App\\Http\\Controllers\\CarrierController->getByNumber(Object(Illuminate\\Http\\Request), '1', '656373')
#6 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): call_user_func_array(Array, Array)
#7 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction('getByNumber', Array)
#8 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(219): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\CarrierController), 'getByNumber')
#9 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(176): Illuminate\\Routing\\Route->runController()
#10 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(680): Illuminate\\Routing\\Route->run()
#11 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#12 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#13 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#14 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#15 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(43): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#16 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Auth\\Middleware\\Authenticate->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'api')
#17 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#18 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(58): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#19 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure), 60, '1')
#20 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#21 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#22 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#23 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(657): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#24 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(623): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#25 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(612): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#26 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#27 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#28 /var/www/web-app/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#29 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#30 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#31 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#32 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#33 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#34 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#35 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#36 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#37 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#38 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#39 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#40 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#41 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#42 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#43 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#44 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#45 /var/www/web-app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#46 /var/www/web-app/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#47 {main}
"}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.