Giter Club home page Giter Club logo

laravel-airtable's Introduction

Laravel SDK for Airtable

Latest Stable Version Code Style Action Status - Pint PHPStan Tests Quality Score Total Downloads

A simple approach to interacting with Airtables.

Installation

You can install the package via composer:

composer require tapp/laravel-airtable

Publish the config file:

php artisan vendor:publish --provider="Tapp\Airtable\AirtableServiceProvider"

Define airtables account information in .env:

AIRTABLE_KEY=
AIRTABLE_BASE=
AIRTABLE_TABLE=
AIRTABLE_TYPECAST=false 
  • AIRTABLE_KEY Airtable is requiring personal access tokens for Authorization starting in 2024. A token can be created here: https://airtable.com/create/tokens. If you are upgrading from an API key to access token, simply replace the value previously held in this environment variable with your new token.
  • AIRTABLE_BASE can be found here: https://airtable.com/api, select base then copy from URL: https://airtable.com/[Base Is Here]/api/docs#curl/introduction
  • AIRTABLE_TABLE can be found in the docs for the appropriate base, this is not case senstive. IE: tasks
  • AIRTABLE_TYPECAST set this to true to allow automatic casting.

Example Config

If you need to support multiple tables, add them to the tables config in the config/airtable.php If your table is on a different base than the one set in the env, add that as well.

...
    'tables' => [

        'default' => [
            'name' => env('AIRTABLE_TABLE', 'Main'),
            'base' => 'base_id',
        ],

        'companies' => [
            'name' => env('AIRTABLE_COMPANY_TABLE', 'Companies'),
            'base' => 'base_id',
        ],
        ...
    ],
...

Usage

Import the facade in your class.

use Airtable;

Get records from that table

  • This will only return the first 100 records due to Airtable page size limiation
Airtable::table('tasks')->get();

Get all records from that table.

  • This will get all records by sending multiple requests until all record are fetched.
  • Optional Parameter which is the delay between requests in microseconds as API is limited to 5 requests per second per base, defaults to 0.2 second.
Airtable::table('tasks')->all();
Airtable::table('tasks')->all(500000); // 0.5 seconds

Get one record from the default table.

Airtable::find('id_string');

Filter records

  • First argument is the column name
  • Second argument is the operator or the value if you want to use equal '=' as an operator.
  • Third argument is the value of the filter
Airtable::where('id', '5')->get();
Airtable::where('id', '>', '5')->get();

Filter records by formula

  • When using where is not enough you may need to pass in raw filter values.
  • Airtable reference
Airtable::table('tasks')->filterByFormula('OR({id} = "abc", {id} = "def", {id} = "ghi")')->get();

Sorting records

  • First argument is the column name
  • Second argument is the sort direction: asc (default) or desc
Airtable::orderBy('id')->get();
Airtable::orderBy('created_at', 'desc')->get();

You can sort by multiple fields by calling orderBy more than once (a single call with array syntax is not supported):

Airtable::orderBy('id')->orderBy('created_at', 'desc')->get();

Set other API Parameters

Airtable::addParam('returnFieldsByFieldId', true); // one param at a time
Airtable::params(['returnFieldsByFieldId' => true, 'view' => 'My View']) // multiple params at once

Create

  • Insert a record
Airtable::create(['name' => 'myName']);

First or Create

  • First argument will be used for finding existing
  • Second argument is additional data to save if no results are found and we are creating (will not be saved used if item already exists)
Airtable::firstOrCreate(['name' => 'myName'], ['field' => 'myField']);

Update or Create

  • First argument will be used to find existing
  • Second argument is additional data to save when we create or update
Airtable::updateOrCreate(['name' => 'myName'], ['field' => 'myField']);

Airtable::table('companies')->firstOrCreate(['Company Name' => $team->name]);

Update

  • First argument will be the id
  • Second argument is the whole record including the updated fields

Note: Update is destructive and clear all unspecified cell values if you did not provide a value for them. use PATCH up update specified fields

Airtable::table('companies')->update('rec5N7fr8GhDtdNxx', [ 'name' => 'Google', 'country' => 'US']);

Patch

  • First argument will be the id
  • Second argument is the field you would like to update
Airtable::table('companies')->patch('rec5N7fr8GhDtdNxx', ['country' => 'US']);

Mass Update or Patch

  • Array of data to be updated or patched
Airtable::table('companies')->patch([
    [
        'id' => 'rec5N7fr8GhDtdNxx',
        'fields' => ['country' => 'US']
    ],
    [
        'id' => 'rec8BhDt4fs2',
        'fields' => ['country' => 'UK']
    ],
    ...
]);

Destroy

  • Destroy a record
Airtable::table('companies')->destroy('rec5N7fr8GhDtdNxx');

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Laravel Package Boilerplate

This package was generated using the Laravel Package Boilerplate.

laravel-airtable's People

Contributors

albalooshi avatar andreia avatar asugai avatar cassolmedia avatar chriship avatar dsferruzza avatar gabrieltakacs avatar gustavosobrinho01 avatar johnwesely avatar jokosusilo avatar kevnk avatar laravel-shift avatar mo7amed-3bdalla7 avatar scottgrayson avatar scrutinizer-auto-fixer avatar swilla avatar synchro avatar yassinebourakba 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-airtable's Issues

Date search/match syntax?

I have not been able to figure out how to perform a search using an exact match for a date field, e.g.

Airtable::findOrCreate(['Date' => Carbon::now()->format('Y-m-d')], [ ... ]);

will not match on a existing record with a Date value of today. I've been working around this by using searches for values within a date range, but that's pretty clunky:

        $existingRecords = Airtable::where('Date', '>=', $dayBefore->format('Y-m-d'))
            ->where('Date', '<=', $dayAfter->format('Y-m-d'))

Maybe I'm just getting the syntax wrong? Or is this a limitation of the API?

Laravel 7 support

It seems i cant install it on Laravel 7 clean installation.

 Problem 1
    - Installation request for tapp/laravel-airtable ^0.10.0 -> satisfiable by tapp/laravel-airtable[0.10].
    - Conclusion: remove laravel/framework v7.6.2
    - Conclusion: don't install laravel/framework v7.6.2
    - tapp/laravel-airtable 0.10 requires illuminate/support 5.7.* || 5.8.* || 6.* -> satisfiable by illuminate/support[5.7.17, 5.7.18, 5.7.19, 5.7.x-dev, 5.8.x-dev, 6.x-dev, v5.7.0, v5.7.1, v5.7.10, v5.7.11, v5.7.15, v5.7.2, v5.7.20, v5.7.21, v5.7.22, v5.7.23, v5.7.26, v5.7.27, v5.7.28, v5.7.3, v5.7.4, v5.7.5, v5.7.6, v5.7.7, v5.7.8, v5.7.9, v5.8.0, v5.8.11, v5.8.12, v5.8.14, v5.8.15, v5.8.17, v5.8.18, v5.8.19, v5.8.2, v5.8.20, v5.8.22, v5.8.24, v5.8.27, v5.8.28, v5.8.29, v5.8.3, v5.8.30, v5.8.31, v5.8.32, v5.8.33, v5.8.34, v5.8.35, v5.8.36, v5.8.4, v5.8.8, v5.8.9, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4, v6.1.0, v6.10.0, v6.11.0, v6.12.0, v6.13.0, v6.13.1, v6.14.0, v6.15.0, v6.15.1, v6.16.0, v6.17.0, v6.17.1, v6.18.0, v6.18.1, v6.18.2, v6.18.3, v6.18.4, v6.18.5, v6.18.6, v6.18.7, v6.18.8, v6.2.0, v6.3.0, v6.4.1, v6.5.0, v6.5.1, v6.5.2, v6.6.0, v6.6.1, v6.6.2, v6.7.0, v6.8.0].

Multiple where clauses

The package doesn't support the use of multiple where clauses.

  1. The following piece of code shouldn't rise an exception:
Airtable::table('products')
   ->where('name', 'product_name')
   ->where('category', 'product_category')
   ->get();

The where function in Airtbale class should return $this.

  1. When i use addFilter functions instead of where the generated url in getEndpointUrl is wrong, it doesn't correctly support multiple filters:
Airtable::table('products')
   ->where('name', 'product_name')
   ->addFilter('category', '=', 'product_category')
   ->get();

I wanted to make a PR, fixed this simple but useful issue in a branch but couldn't push it

Can't get this to work

I've followed the installation instructions provided in the readme but when I try to access Airtable in a controller I get this error:

Class 'App\Http\Controllers\Airtable' not found

I've tried use Tapp\Airtable; and it's not finding that either.

I can confirm that airtable.php is in the app/config directory and that I have the right stuff in the .env file.

Types don't match

$this->client = $client ?? $this->buildClient($access_token);

In the construct the parameter $client is asking for Http object, but $this->client by default will receive a PendingRequest.

If it's provided with a new Http client will explode.

Has an example in the function get() of the same class,
return $this->decodeResponse($this->client->get($url));

Http object isn't accessible this way.

Table is not configured.

Error Code
Table [Gesamtportfolio] is not configured.

.env
AIRTABLE_TABLE=Gesamtportfolio

Controller
return Airtable::table('Gesamtportfolio')->get();

Screenshot attached from airtable, where you can see the table name
vFGCFQL

What am i doing wrong?

Better Examples

I have the request for pulling in all the information from a table working.

How would you go about filtering this information? I am not totally understanding the example provided because it seems like too few arguments to get the information from the table. For example Airtable::find('id_string'); how would I write syntax to find a name in a table called employees?

Add support for sort / orderBy

This is a feature request.

The AirTable API supports sorting via a sort parameter on GET requests. The param uses the format:

[{field: "Name", direction: "desc"}]

and it may contain multiple sort entries. To follow the Eloquent-style interface that's been used on this package, I guess it should be called orderBy. I'd really like this to be accessible through this package

View support?

anyway to fetch data through certain view? rather then whole table.

Changed for Personal access tokens and doesn't work

Hello,
I changed for Personal access tokens, after that my app doesn't work. I've tried everyting.
Code:
` public function show() {
$reservations = Airtable::table('zamowienia')->get();

    dd($reservations);
    $data = [
        'category_name' => 'dashboard',
        'page_name' => 'test-app',
        'has_scrollspy' => 0,
        'scrollspy_offset' => '',
        'reservations' => $reservations,
    ];
    // $pageName = 'analytics';
    return view('test-app')->with($data);
}`

Error:
Illuminate\Support\Collection {#1252 ▼ #items: array:1 [▼ "error" => array:2 [▼ "type" => "AUTHENTICATION_REQUIRED" "message" => "Authentication required" ] ] }

Any ideas?

> 100 Records

I'd like to get all records from my table, but I only get the first 100 when I do

$results = Airtable::table('default')->get();

How do you recommend I get all records? Thanks

[Feature] Ability to typecast on demand

Hi,

Thanks for your work.

For most of my calls, I don't want to create new select options automatically.

However, I'd like to do it for one. It could be great to not have to enable the options for all calls, and to allow passing directly the arguments to the calls.

Ex: Airtable::create(['name' => 'myName'], ['typecast' => true]);

Happy to do the PR if you're ok with that.
Mathieu

Implement the ability to use field filters on GET

Fields
(array of strings)
optional

Only data for fields whose names are in this list will be included in the result. If you don't need every field, you can use this parameter to reduce the amount of data transferred.

For example, to only return data from Name and Listings, send these two query parameters:

fields%5B%5D=Name&fields%5B%5D=Listings
Note: %5B%5D may be omitted when specifying multiple fields, but must always be included when specifying only a single field.

Find by LIKE

Hey!

Firstly, thank you! Works very well in my application.

Would you think implements a where function to acceps like operators?
$data = AirTable::table('table')->where('columnName','LIKE','%partOfText%')->get()

Sounds good ? Let me know if you need help it.

Best!

Table Names Cannot Contain "."

I have tables where their names are domain names and I think due to the way config values are grabbed, that fails because the dot in ".com" is interpreted as a new nested object key.

I've renamed my tables to not have periods, so this is just a note to you.

[Feature Request] Update to PHP 8

I'm using the latest PHP: 8.0.2 and get this error when trying to install.

Package tapp/laravel-airtable has a PHP requirement incompatible with your PHP version

Any chance this package could be updated to PHP 8?

Thank You

Multiple base connection

Is there a way of having multiple base connection like :
'base' => [
'base1' => env('AIRTABLE_BASEID1'),
'base2' => env('AIRTABLE_BASEID2'),
...
],

And so, directly from this previous connection, picking table name like this :
Airtable::table('TableName')->get();

Bc if i have like 5 base with 20 tables in each i would have to hard write 100 table connection in airtable.php like this :
'tables' => [
'Table1FromBase1' => [
'name' => 'Table1_name',
'base' => 'baseid1'
],
... (x100)
],

Or am i missing something ?

Non-static method Tapp\Airtable\Airtable::table()

ErrorException
Non-static method Tapp\Airtable\Airtable::table() should not be called statically

I have configured following your documentation and I get this error.

$products = Airtable::table('Products')->get();

Version Laravel 8 / php 8.0

[New feature] PatchOrCreate - to create or update (without destructing)

Airtable::table('default')->updateOrCreate(['Email' => '[email protected]'], ['Address' => 'Calle 13']);
is very useful to check if some record exists to update it, and if not create it.

The problem is that it deletes the rest of the column values, so Is not convenient in some scenarios.

To work around this I do need to find the Airtable id using ->where() method and use the patch method.

Would be appreciated a PatchOrCreate method

Support for Laravel 8

I am trying to use it in Laravel 8 and it would be great if you could support it. And even lowering the guzzlehttp version to ~6.0 is not fixing it as 7.0.1 is the minimum requirement for Laravel 8.

The requested package guzzlehttp/guzzle (locked at 7.0.1, required as ~6.0) is satisfiable by guzzlehttp/guzzle[7.0.1] but these conflict with your requirements or minimum-stability.

Too few arguments to function Tapp\Airtable\AirtableManager::table(), 0 passed

In running the code Airtable::find($record_id) I get the output error

ArgumentCountError:
Too few arguments to function Tapp\Airtable\AirtableManager::table(), 0 passed in /var/www/vendor/tapp/laravel-airtable/src/AirtableManager.php on line 149 and exactly 1 expected

at /var/www/vendor/tapp/laravel-airtable/src/AirtableManager.php:42
at Tapp\Airtable\AirtableManager->table()
(/var/www/vendor/tapp/laravel-airtable/src/AirtableManager.php:149)
at Tapp\Airtable\AirtableManager->__call('find', array('reclPuLCImaRag12o'))
(/var/www/vendor/illuminate/support/Facades/Facade.php:261)
at Illuminate\Support\Facades\Facade::__callStatic('find', array('reclPuLCImaRag12o'))

Do I need to pass in the table name? As I can confirm that env('AIRTABLE_TABLE') has been defined

Bug: AirtableApiClient.php's addFilter() should escape quotes in filter target $value

If I run a basic field search using a string that contains quotes:

Airtable::where('Story', 'He said "no"')->get();

I receive an error:

{
    "error": {
        "type": "INVALID_FILTER_BY_FORMULA",
        "message": "The formula for filtering records is invalid: Invalid formula. Please check your formula text."
    }
}

I think this is because addFilter() in AirtableApiClient.php is passing the string value through to Airtable without escaping the quotes, confusing the filter:

$this->filters[] = "{{$column}}{$operation}\"{$value}\"";

[2024-05-20 17:01:29] local.DEBUG: Filters: Array
(
    [0] => {Story}="He said "no""
)

If I escape the quotes in my text, it works.

Airtable::where('Story', 'He said \"no\"')->get();

[2024-05-20 17:02:01] local.DEBUG: Filters: Array
(
    [0] => {Story}="He said \"no\""
)

(There may be a better way to handle this more broadly in constructing API queries than just escaping quotes, but that's as far as I got.)

Tests won't run on PHP 8

The test suite can't be run on PHP 8 because of dependencies on old versions of PHPUnit, Laravel, and orchestra that are not PHP 8 compatible.

Issue when AirtableManager tries to create a AirtableApiClient

HI!

I tried to update a project that uses this lib from v1.0 to v1.2.
When running my code, I get the following error:

 Tapp\Airtable\Api\AirtableApiClient::__construct(): Argument #4 ($client) must be of type ?Illuminate\Support\Facades\Http, string given, called in vendor/tapp/laravel-airtable/src/AirtableManager.php on line 124

Reading the related code shows indeed an error:

The error points out a type error because the fourth parameter was removed, which created a shift.
The commit that introduced the issue is here: eb6aac5#diff-62e27cda4cce08967fff7c195aadf69244cdf9d7fa61fa322443478f81da5f4fL24

Could you have a look please?

Lumen

Can this be used with lumen?

Table not configured?

Hey @swilla,

first of all thanks for the package. I'm quite new to Laravel but i have used the Airtable API already. So I thought I'll give it a try even though the documentation is a bit sparse at the moment.

Unfortunately I'm having a hard time getting started.

        $test = Airtable::table('Customers')->get();
        ddd($test);

Here's a simple thing I'm trying. Base ID and Key are in the config. I'm getting an error complaining about the Customers table not being configured. I was already confused why you would configure a table, I did configure one though but that didn't change anything.

I'm also not sure why your inline documentation in config.php points to API doc information about tables. Usually the API takes the name of the table so I'm not sure what information about tables I should pull from the API docs.

Sidenote: I'm quite sure my data (API Key, Basekey) is correct as I'm using the same from a pythong script using https://github.com/gtalarico/airtable-python-wrapper

Maybe you can help me get started - I'm sure I'm just missing something.

Thank you

Non-static method Tapp\Airtable\Airtable::table() should not be called statically

Hi

Ran into this error:

Non-static method Tapp\Airtable\Airtable::table() should not be called statically.

 $test =  Airtable::table('table_name')->get();
      dd($test);

composer.json

    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.2",
        "ext-json": "*",
        "calebporzio/sushi": "^2.0",
        "doctrine/dbal": "^2.10",
        "facade/ignition": "^1.14",
        "fideloper/proxy": "^4.0",
        "fruitcake/laravel-cors": "^1.0",
        "intervention/image": "^2.5",
        "itsjavi/bootstrap-colorpicker": "^3.0",
        "laravel/cashier": "^9.3",
        "laravel/framework": "^6.0",
        "laravel/socialite": "^4.1",
        "laravel/tinker": "^1.0",
        "league/flysystem-aws-s3-v3": "^1.0",
        "mews/purifier": "^3.1",
        "ramsey/uuid": "^3.9",
        "sentry/sentry-laravel": "1.6.1",
        "spatie/crawler": "^4.4",
        "spatie/laravel-cookie-consent": "^2.6",
        "spatie/laravel-cors": "^1.6",
        "spatie/laravel-sitemap": "^5.2",
        "symfony/dom-crawler": "^4.3",
        "symfony/translation": "4.3.8",
        "tapp/laravel-airtable": "^0.10.0",
        "tymon/jwt-auth": "1.0.0-rc.5"
    },
    "require-dev": {
        "beyondcode/laravel-dump-server": "^1.0",
        "filp/whoops": "^2.0",
        "fzaninotto/faker": "^1.4",
        "mockery/mockery": "^1.0",
        "nunomaduro/collision": "^2.0",
        "phpunit/phpunit": "^7.0"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true,
        "platform": {
            "php": "7.2"
        }
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }
}

Everything is set up as per docs, it seems that the facade is not registering correctly?

Issue with fetching all records

Description

When using getAllPages() method in AirtableApiClient class, the returned records don't match the preset filters.

How to reproduce the issue

When making a query with filters such as :

Airtable::where('id', '>', '5')->all();

If and only if the count of records that satisfy the where clause are superior to the pageSize (100 by default), in other words if there is an offset for paginated result, the reponse will carry all records in Airtable not only those with id > 5.

[URGENT ACTION REQUIRED] StyleCI Payment Details

StyleCI is migrating to a new payment system, and you must re-enter your payment information as soon as possible to continue using the StyleCI Annual Startup plan. Please re-enter your payment details on the StyleCI account settings page, or directly by clicking here.

Using multiple bases

Just wondering how to configure for using multiple bases. I see in AirtableManager line 113 there is:

$base = $this->app['config']['airtable.base'];

Does this suggests that this library will only ever work with a single base, or have I misunderstood how to specify different bases?

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.