Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
27pchrisl committed Dec 19, 2021
1 parent b569904 commit adab974
Show file tree
Hide file tree
Showing 429 changed files with 34,301 additions and 2,835 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Documentation
on:
push:
branches:
- 3.x
- 4.x
jobs:
docs:
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [ 7.3, 7.4, 8.0 ]
php: [ 7.3, 7.4, 8.0, 8.1 ]
laravel: [ 8 ]
dependency-version: [ prefer-stable ]

Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
php-version: 8.1
extensions: simplexml, dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick
tools: composer:v2
coverage: xdebug
Expand Down
1,481 changes: 892 additions & 589 deletions composer.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/getting-started/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ As we're just starting out we'll use the existing service provider at `app/Provi
Open this file and add the following to the `boot()` method.

```php
\Lodata::discoverEloquentModel(\App\Models\User::class)
\Lodata::discover(\App\Models\User::class)
```

You can now access [`http://127.0.0.1:8000/odata/Users`](http://127.0.0.1:8000/odata/Users) and see the users in your database.
Expand Down
1 change: 1 addition & 0 deletions doc/introduction/compliance.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Lodata supports many sections of the OData specification, these are the major ar
* The [$search](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#_Toc31358956) system query option
* The [$value](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#_Toc31358940) path segment
* The [$filter](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#_Toc31358948) system query option, with all expressions, functions, operators, and supports query parameter aliases
* The [$index](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_PositionalInserts) system query option
* [Asynchronous requests](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_AsynchronousRequests) using Laravel jobs, with monitoring, cancellation and callbacks
* [Batch requests](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_BatchRequests) in both multipart and JSON formats, including entity back-references and asynchronous batch requests
* [Deep insert](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_CreateRelatedEntitiesWhenCreatinganE) support at any depth
Expand Down
2 changes: 1 addition & 1 deletion doc/introduction/reporting-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ When reporting an issue please include any configuration of entity sets or opera
Ideally to reproduce an issue you can generate a test case. Lodata uses [snapshot tests](https://github.com/spatie/phpunit-snapshot-assertions)
extensively to capture the entire output of the API.

Many examples exist in the test folder, for example [https://github.com/flat3/lodata/blob/develop/tests/Unit/Eloquent/EloquentTest.php](https://github.com/flat3/lodata/blob/develop/tests/Unit/Eloquent/EloquentTest.php)
Many examples exist in the test folder, for example [https://github.com/flat3/lodata/blob/main/tests/Unit/Eloquent/EloquentTest.php](https://github.com/flat3/lodata/blob/main/tests/Unit/Eloquent/EloquentTest.php)

Test cases that generate snapshots can use the provided assertions and the `Request` object to generate and configure a request.

Expand Down
46 changes: 38 additions & 8 deletions doc/making-requests/querying-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ scenarios for these query options.

## $filter

The $filter system query option allows clients to filter a collection of resources that are addressed by a request URL.
The `$filter` system query option allows clients to filter a collection of resources that are addressed by a request URL.
The expression specified with `$filter` is evaluated for each resource in the collection, and only items where the
expression evaluates to true are included in the response.

Expand Down Expand Up @@ -45,7 +45,7 @@ GET http://localhost:8000/odata/People?$filter=FirstName eq 'Scott'

## $orderby

The $orderby system query option allows clients to request resources in either ascending order using asc or descending
The `$orderby` system query option allows clients to request resources in either ascending order using asc or descending
order using desc. If asc or desc not specified, then the resources will be ordered in ascending order. The request
below orders People on property LastName in descending order.

Expand Down Expand Up @@ -87,8 +87,8 @@ GET http://localhost:8000/odata/People?$orderby=LastName

## $top and $skip

The $top system query option requests the number of items in the queried collection to be included in the result.
The $skip query option requests the number of items in the queried collection that are to be skipped and not included
The `$top` system query option requests the number of items in the queried collection to be included in the result.
The `$skip` query option requests the number of items in the queried collection that are to be skipped and not included
in the result.
The request below returns the first two people of the People entity set.

Expand Down Expand Up @@ -157,7 +157,7 @@ GET http://localhost:8000/odata/People?$skip=1

## $count

The $count system query option allows clients to request a count of the matching resources included with the
The `$count` system query option allows clients to request a count of the matching resources included with the
resources in the response.
The request below returns the total number of people in the collection.

Expand Down Expand Up @@ -200,7 +200,7 @@ GET http://localhost:8000/odata/People?$count=true

## $expand

The $expand system query option specifies the related resources to be included in line with retrieved resources.
The `$expand` system query option specifies the related resources to be included in line with retrieved resources.
The request below returns people with navigation property Passengers of a Flight

<code-group>
Expand Down Expand Up @@ -275,7 +275,7 @@ GET http://localhost:8000/odata/flights?$expand=passengers

## $select

The $select system query option allows the clients to requests a limited set of properties for each entity or
The `$select` system query option allows the clients to requests a limited set of properties for each entity or
complex type. The request below returns origin and destination of all flights:

<code-group>
Expand Down Expand Up @@ -310,7 +310,7 @@ GET http://localhost:8000/odata/flights?$select=origin,destination

## $search

The $search system query option restricts the result to include only those entities matching the specified search
The `$search` system query option restricts the result to include only those entities matching the specified search
expression. The definition of what it means to match is dependent upon the implementation. The request below gets all
airports that have 'fo' or 'lh' in their code.

Expand Down Expand Up @@ -342,6 +342,36 @@ GET http://localhost:8000/odata/flights?$search=fo OR lh
</code-block>
</code-group>

## $index

The value of the `$index` system query option is the zero-based ordinal position where an
item is to be inserted. This option is supported on entity sets that can be numerically indexed.

The ordinal positions of items within the collection greater than or equal to the inserted
position are increased by one. A negative ordinal number indexes from the end of the collection, with -1 representing
an insert as the last item in the collection.

<code-group>
<code-block title="Request">
```uri
POST http://localhost:8000/odata/examples?$index=1
{
"name": "Zeta"
}
```
</code-block>

<code-block title="Response">
```json
{
"@context": "http://localhost/odata/$metadata#examples/$entity",
"name": "Zeta",
"id": 1
}
```
</code-block>
</code-group>

## Lambda Operators

OData defines two operators `any` and `all` that evaluate a Boolean expression on a collection.
Expand Down
2 changes: 1 addition & 1 deletion doc/modelling/drivers/database.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ types discovered by the entity set.
Almost all the available `$filter` capabilities are mapped into SQL expressions, supporting all the same database
backends that Laravel does.

This driver supports `$search` by passing the provided search term into `field LIKE %param%` requests.
This driver supports `$search` by passing the provided search term into `field LIKE %param%` requests.
136 changes: 126 additions & 10 deletions doc/modelling/drivers/eloquent.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,59 @@
# Eloquent

Lodata can 'discover' Eloquent models, and the relationships between the models.
Lodata can 'discover' Eloquent models, the relationships between the models, and expose methods as operations on the
models.

::: tip
The Eloquent driver extends the SQL driver, so the same `$filter` capabilities exist in both.
:::

Discovery is
## Data model

Discovery of the data model is
performed first using [DBAL](https://www.doctrine-project.org/projects/doctrine-dbal/en/2.12/index.html) to
introspect the database table, then [Eloquent casts](https://laravel.com/docs/8.x/eloquent-mutators#custom-casts)
are used for further type specification. During requests, the Eloquent model getter/setter functions are used
to refer to the properties, so any additional field processing being performed by the model will be preserved.

To discover a model the `Lodata` facade that exists in the root namespace can be used. For example to discover
two models:
To discover a model the `Lodata` facade can be used. For example to discover the `Flight` model:

```php
class LodataServiceProvider extends ServiceProvider
{
public function boot()
{
\Lodata::discoverEloquentModel(\App\Models\Flight::class);
\Lodata::discoverEloquentModel(\App\Models\Passenger::class);
\Lodata::discover(\App\Models\Flight::class);
}
}
```

If model `Flight` has a method `passengers` that returns a [relationship](https://laravel.com/docs/8.x/eloquent-relationships)
to `Passenger` such as hasOne, hasMany, hasManyThrough, this can be discovered by Lodata as a navigation property on the `Flights` entity set.
## Relationships

If model `Flight` has a method `passengers` that returns a
[relationship](https://laravel.com/docs/8.x/eloquent-relationships) to `Passenger` such as hasOne, hasMany,
hasManyThrough, this can be discovered by Lodata as a navigation property on the `Flights` entity set. This method
can be tagged using an attribute that will be picked up during discovery.

::: tip
The same as Laravel itself, Lodata typically refers to 'entity types' in the singular form and 'entity sets' in
the plural form. An entity set and its related entity set must both be defined through discovery before a
relationship can be created.
the plural form.
:::

```php
use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
#[LodataRelationship]
public function passengers()
{
return $this->hasMany(Passenger::class);
}
}
```

Alternatively for PHP versions that do not support attributes:

```php
\Lodata::getEntitySet('Flights')
->discoverRelationship('passengers')
Expand All @@ -48,3 +67,100 @@ also be used in `$expand` requests.

If Lodata is able to determine the relationship cardinality it will be represented in the service metadata
document.

## Operations

Lodata can also expose model methods as operations. The method will be called on the specific instance of the entity
referenced in the URL.

<code-group>
<code-block title="Code">
```php
use Carbon\Carbon;
use Flat3\Lodata\Attributes\LodataFunction;

class Person extends Model {
#[LodataFunction]
public function age(): float {
return Carbon::parse($this->birthdate)->age;
}
}

class LodataServiceProvider extends ServiceProvider
{
public function boot()
{
Lodata::discover(Person::class);
}
}
```
</code-block>

<code-block title="Request">
```
http://localhost:8000/odata/Person(1)/age()
```
</code-block>

<code-block title="Result">
```json
{
"@context": "http://localhost:8000/odata/$metadata#Edm.Double",
"value": 52.2
}
```
</code-block>
</code-group>

## Repository

Some Laravel applications implement a [repository](https://www.twilio.com/blog/repository-pattern-in-laravel-application)
pattern for handling data access. Lodata can support this technique if the repository implements the
`RepositoryInterface` so that it can retrieve the correct model class name using the `getClass` method. For
invocation Lodata will pass the model instance as the bound parameter.

<code-group>
<code-block title="Code">
```php
use Flat3\Lodata\Attributes\LodataFunction;
use Flat3\Lodata\Interfaces\RepositoryInterface;

class Repository implements RepositoryInterface
{
public function getClass(): string
{
return Airport::class;
}

#[LodataFunction (bind: "airport")]
public function code(Airport $airport, ?string $suffix): string
{
return $airport->code.($suffix ?: '');
}
}

class LodataServiceProvider extends ServiceProvider
{
public function boot()
{
Lodata::discover(Repository::class);
}
}
```
</code-block>

<code-block title="Request">
```
http://localhost:8000/odata/Airports(1)/code(suffix='abc')
```
</code-block>

<code-block title="Result">
```json
{
"@context": "http://localhost:8000/odata/$metadata#Edm.String",
"value": "lhrabc"
}
```
</code-block>
</code-group>
Loading

0 comments on commit adab974

Please sign in to comment.