Skip to content

Commit

Permalink
Fixed conflicts.
Browse files Browse the repository at this point in the history
  • Loading branch information
Phil Sturgeon committed Feb 1, 2014
2 parents d383b0c + 74d8beb commit a12c5cd
Show file tree
Hide file tree
Showing 22 changed files with 373 additions and 55 deletions.
23 changes: 21 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
## 0.5.0
## 0.7.0 (2014-02-01)

Features:

- Added Cursor, as a different approach to paginating large data sets
- Switched from PSR-0 to PSR-4

## 0.6.0 (2013-12-27)

Features:

- Adds a `PaginatorInterface`, with a `IlluminatePaginatorAdapter` to let Fractal be framework agnostic

## 0.5.1 (2013-12-13)

Bugs:

- Fixed PHP 5.3 support. Short array syntax will be the death of me

## 0.5.0 (2013-12-13)

Features:

Expand All @@ -8,4 +27,4 @@ Features:

Features:

- Allow $defaultEmbed to be enabled in a transformer, to always embed without requesting.
- Allow $defaultEmbed to be enabled in a transformer, to always embed without requesting
2 changes: 1 addition & 1 deletion Guardfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ guard 'phpunit2', :tests_path => 'tests', :cli => '--colors' do
watch(%r{^.+Test\.php$})

# Watch library files and run their tests
watch(%r{^src/League/Fractal/(.+)\.php}) { |m| "tests/League/Fractal/Test/#{m[1]}Test.php" }
watch(%r{^src/(.+)\.php}) { |m| "tests/#{m[1]}Test.php" }
end
101 changes: 67 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Fractal

[![Build Status](https://travis-ci.org/php-loep/fractal.png?branch=master)](https://travis-ci.org/php-loep/fractal)
[![Coverage Status](https://coveralls.io/repos/php-loep/fractal/badge.png)](https://coveralls.io/r/php-loep/fractal)
[![Build Status](https://travis-ci.org/thephpleague/fractal.png?branch=master)](https://travis-ci.org/thephpleague/fractal)
[![Coverage Status](https://coveralls.io/repos/thephpleague/fractal/badge.png)](https://coveralls.io/r/thephpleague/fractal)
[![Total Downloads](https://poser.pugx.org/league/fractal/downloads.png)](https://packagist.org/packages/league/fractal)
[![Latest Stable Version](https://poser.pugx.org/league/fractal/v/stable.png)](https://packagist.org/packages/league/fractal)

When building an API it is common for people to just grab stuff from the database and pass it
to `json_encode()`. This might be passable for "trivial" API's but if they are in use by the public,
When building an API it is common for people to just grab stuff from the database and pass it
to `json_encode()`. This might be passable for "trivial" API's but if they are in use by the public,
or used by an iPhone application then this will quickly lead to inconsistent output.

This package aims to do a few simple things:
Expand All @@ -15,12 +15,12 @@ This package aims to do a few simple things:
* Avoid db schema changes changing your output
* Allow for simple, flexible and controllable embedding of data, avoiding infinite loops

This package is compliant with [PSR-0][], [PSR-1][], and [PSR-2][]. If you
This package is compliant with [PSR-1][], [PSR-2][] and [PSR-4][]. If you
notice compliance oversights, please send a patch via pull request.

[PSR-0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
[PSR-1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
[PSR-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
[PSR-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md


## Install
Expand All @@ -30,7 +30,7 @@ Via Composer
``` json
{
"require": {
"league/fractal": "0.6.*"
"league/fractal": "0.7.*"
}
}
```
Expand All @@ -54,13 +54,13 @@ In your controllers you can then create "resources", of which there are three ty
* **League\Fractal\Resource\Item** - A singular resource, probably one entry in a data store
* **League\Fractal\Resource\Collection** - A collection of resources

The `Item` and `Collection` constructors will take any kind of data you wish to send it
as the first argument, and then a "transformer" as the second argument. This can be callable or a string
containing a fully-qualified class name.
The `Item` and `Collection` constructors will take any kind of data you wish to send it
as the first argument, and then a "transformer" as the second argument. This can be callable or a string
containing a fully-qualified class name.

The transformer will the raw data passed back into it, so if you pass an instance of `BookModel` into an
`ItemResource` then you can expect this instance to be `BookModel`. If you passed an array or a collection
(an object implementing [ArrayIterator][]) of `BookModel` instances then this transform method will be run
The transformer will the raw data passed back into it, so if you pass an instance of `BookModel` into an
`ItemResource` then you can expect this instance to be `BookModel`. If you passed an array or a collection
(an object implementing [ArrayIterator][]) of `BookModel` instances then this transform method will be run
on each of those instances.

``` php
Expand All @@ -76,7 +76,7 @@ $resource = new Fractal\Resource\Collection($books, function(BookModel $book) {
```

If you want to reuse your transformers (recommended) then create classes somewhere and pass in the name.
Assuming you use an autoloader of course. These classes must extend `League\Fractal\TransformerAbstract` and
Assuming you use an autoloader of course. These classes must extend `League\Fractal\TransformerAbstract` and
contain a transform method, much like the callback example: `public function transform(Foo $foo)`.

``` php
Expand All @@ -89,11 +89,11 @@ $resource = new Fractal\Resource\Collection($books, new BookTransformer);

### Embedding Data

Your transformer at this point is mainly just giving you a method to handle array conversion from
you data source (or whatever your model is returning) to a simple array. Embedding data in an
intelligent way can be tricky as data can have all sorts of relationships. Many developers try to
find a perfect balance between not making too many HTTP requests and not downloading more data than
they need to, so flexibility is also important.
Your transformer at this point is mainly just giving you a method to handle array conversion from
you data source (or whatever your model is returning) to a simple array. Embedding data in an
intelligent way can be tricky as data can have all sorts of relationships. Many developers try to
find a perfect balance between not making too many HTTP requests and not downloading more data than
they need to, so flexibility is also important.

Sticking with the book example, the `BookTransformer` might contain an optional embed for an author.

Expand Down Expand Up @@ -142,19 +142,19 @@ class BookTransformer extends TransformerAbstract
}
```

So if a client application were to call the URL `/books?embed=author` then they would see author data in the
response. These can be nested with dot notation, as far as you like.
So if a client application were to call the URL `/books?embed=author` then they would see author data in the
response. These can be nested with dot notation, as far as you like.

**E.g:** `/books?embed=author,publishers,publishers.somethingelse`

This example happens to be using the lazy-loading functionality of an ORM for `$book->author`, but there is no
reason that eager-loading could not also be used by inspecting the `$_GET['embed']` list of requested scopes. This
This example happens to be using the lazy-loading functionality of an ORM for `$book->author`, but there is no
reason that eager-loading could not also be used by inspecting the `$_GET['embed']` list of requested scopes. This
would just be a translation array, turning scopes into eager-loading requirements.

### Outputting Processed Data

When ready to output this data, you must convert the "resource" back into data. Calling
`$fractal->createData();` with a resource argument will run the transformers (any any
When ready to output this data, you must convert the "resource" back into data. Calling
`$fractal->createData();` with a resource argument will run the transformers (any any
nested transformer calls) and convert everything to an array for you to output:

``` php
Expand All @@ -165,26 +165,26 @@ $data = $fractal->createData($resource)->toArray();
$json = $fractal->createData($resource)->toJson();
```

If you want to use something other than JSON then you'll need to think that one up yourself. If
you're using horribly complicated XML for example, then you will probably need to create some
If you want to use something other than JSON then you'll need to think that one up yourself. If
you're using horribly complicated XML for example, then you will probably need to create some
specific view files, which negates the purpose of using this system entirely. Auto-generated XML,
YAML or anything similar could easily be set up in a switch, just check against the `Accept` header.

### Pagination

When working with a large data set it obviously makes sense to offer pagination options to the endpoint,
When working with a large data set it obviously makes sense to offer pagination options to the endpoint,
otherwise that data can get very slow. To avoid writing your own pagination output into every endpoint you
can utilize the the `League\Fractal\Resource\Collection::setPaginator()` method.

The paginator passed to `setPaginator()` must implement `League\Fractal\Pagination\PaginatorInterface`
The paginator passed to `setPaginator()` must implement `League\Fractal\Pagination\PaginatorInterface`
and it's specified methods.

Fractal currently only ships with an adapter for Laravel's `illuminate/pagination` package as
Fractal currently only ships with an adapter for Laravel's `illuminate/pagination` package as
`League\Fractal\Pagination\IlluminatePaginatorAdapter`.

[Laravel Pagination]: http://laravel.com/docs/pagination

Inside of Laravel 4, using the Eloquent or Query Builder method `paginate()`, the following syntax is
Inside of Laravel 4, using the Eloquent or Query Builder method `paginate()`, the following syntax is
possible:

``` php
Expand All @@ -200,6 +200,39 @@ $resource = new Collection($books, new BookTransformer);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
```

[ArrayIterator]: http://php.net/ArrayIterator

### Navigate collections with cursors

When we have large sets of data and running a `SELECT COUNT(*) FROM whatever` isn't really an option, we need a proper
way of fetching results. One of the approches is to use cursors that will indicate to your backend where to start
fetching results. You can set a new cursor on your collections using the
`League\Fractal\Resource\Collection::setCursor()` method.

The cursor must implement `League\Fractal\Cursor\CursorInterface` and it's specified methods.

Fractal currently ships with a very basic adapter, `League\Fractal\Cursor\Cursor`. It's really easy to use:

```php
use Acme\Model\Book;
use Acme\Transformer\BookTransformer;
use League\Fractal\Cursor\Cursor;
use League\Fractal\Resource\Collection;

$books = new Book;

if ($current = Input::get('cursor', false)) {
$books = $books->where('id', '>', $current);
}

$books = $books->take(5)->get();

$cursor = new Cursor($current, $books->last()->id, $books->count());

$resource = new Collection($books, new BookTransformer);
$resource->setCursor($cursor);
```

## TODO

This is still in concept stage, and these issues are left to explore:
Expand All @@ -217,15 +250,15 @@ $ phpunit

## Contributing

Please see [CONTRIBUTING](https://github.com/php-loep/fractal/blob/master/CONTRIBUTING.md) for details.
Please see [CONTRIBUTING](https://github.com/thephpleague/fractal/blob/master/CONTRIBUTING.md) for details.


## Credits

- [Phil Sturgeon](https://github.com/philsturgeon)
- [All Contributors](https://github.com/php-loep/fractal/contributors)
- [All Contributors](https://github.com/thephpleague/fractal/contributors)


## License

The MIT License (MIT). Please see [License File](https://github.com/php-loep/fractal/blob/master/LICENSE) for more information.
The MIT License (MIT). Please see [License File](https://github.com/thephpleague/fractal/blob/master/LICENSE) for more information.
13 changes: 6 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"api",
"json"
],
"homepage": "https://github.com/php-loep/fractal",
"homepage": "https://github.com/thephpleague/fractal",
"license": "MIT",
"authors": [
{
Expand All @@ -17,18 +17,17 @@
}
],
"require-dev": {
"illuminate/pagination": "~4.0",
"illuminate/pagination": "~4.1",
"league/phpunit-coverage-listener": "~1.1",
"mockery/mockery": "dev-master@dev",
"silex/silex": "~1.1"
"mockery/mockery": "dev-master@dev"
},
"suggest": {
"illuminate/pagination": "~4.0"
},
"autoload": {
"psr-0": {
"League": ["src", "tests"],
"Silex\\Provider": "src"
"psr-4": {
"League\\Fractal\\": "src",
"League\\Fractal\\Tests\\": "tests"
}
}
}
7 changes: 3 additions & 4 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" bootstrap="tests/Bootstrap.php">
<testsuites>
<testsuite name="Fractal Test Suite">
<testsuite name="League Fractal Test Suite">
<directory suffix="Test.php">tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/Silex</directory>
<directory suffix=".php">src/League</directory>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
Expand All @@ -28,7 +27,7 @@
<string>League\Fractal</string>
</element>
<element key="repo_token">
<string>SWXV74M3EDTakDezlQvrc12eH4ODwk0bV</string>
<string>LbVGh7Vb9CIJNLDWgIfi7N0d6B5JnvLfk</string>
</element>
<element key="target_url">
<string>https://coveralls.io/api/v1/jobs</string>
Expand Down

0 comments on commit a12c5cd

Please sign in to comment.