phplaraveltransformer-modelthephpleaguethephpleague-fractal

Using parseincludes in Laravel5 Fractal


Struggling using parseIncludes in https://github.com/thephpleague/fractal.

I have two tables, Property and Weeks. Each property has many weeks. Using Fractal I can return my property item with a collection of weeks. What I want to do is use parseIncludes, so that the return of weeks is optional.

PropertyTransformer.php

<?php
namespace App\Transformer;

use App\Models\Property;
use League\Fractal\TransformerAbstract;


class PropertyTransformer extends TransformerAbstract
{

    protected $availableIncludes = [
        'week'
    ];

    public function transform(Property $property)
    {
        return [
            'id'                => (int) $property['PropertyID'],
            'PropertyName'      => $property['PropertyName'],
            'ExactBeds'         => (int) $property['ExactBeds'],
            'weeks'             => $property->week
        ];
    }

    /**
     * Include Week
     *
     * @return League\Fractal\ItemResource
     */
    public function includeWeek( Property $property )
    {
        $week = $property->week;

        return $this->item($week, new WeekTransformer);
    }
}

WeekTransformer.php

<?php
namespace App\Transformer;

use App\Models\Week;
use League\Fractal;

class WeekTransformer extends Fractal\TransformerAbstract
{


    public function transform(Week $week)
    {
        return [
            'Week'          => $week['week'],
            'Available'     => $week['available'],
            'Price'         => (int) $week['price'],

        ];
    }

}

My PropertyController.php

<?php namespace App\Http\Controllers\Api\v1;

use App\Http\Requests;
use App\Models\Week;
use Illuminate\Support\Facades\Response;

use App\Models\Property;

use League\Fractal;
use League\Fractal\Manager;
use League\Fractal\Resource\Collection as Collection;
use League\Fractal\Resource\Item as Item;

use App\Transformer\PropertyTransformer;


class PropertyController extends \App\Http\Controllers\Controller {

public function show($id)
{
    $property = Property::with('bedroom')->with('week')->find($id);

    $fractal = new Fractal\Manager();

    if (isset($_GET['include'])) {
        $fractal->parseIncludes($_GET['include']);
    }

    $resource = new Fractal\Resource\Item($property, new PropertyTransformer);
    //$resource = new Fractal\Resource\Collection($properies, new PropertyTransformer);

    return $fractal->createData( $resource )->parseIncludes('weeks')->toJson();

}

I get the following error on the parseIncludes:-

Method 'parseIncludes' not found in class \League\Fractal\Scope

I'm following the guide here on transformers - http://fractal.thephpleague.com/transformers/

I think I am going wrong somewhere here where it says:-

These includes will be available but can never be requested unless the Manager::parseIncludes() method is called:

<?php
use League\Fractal;

$fractal = new Fractal\Manager();

if (isset($_GET['include'])) {
    $fractal->parseIncludes($_GET['include']);
}

If I remove the parseIncludes, I don't get an error, I also get my property data with my collection of weeks, but ?include=week doesn't work to optionally get it.


Solution

  • Your problem is in this line:
    return $fractal->createData( $resource )->parseIncludes('weeks')->toJson();

    createData() returns \League\Fractal\Scope and it has no parseInlcudes method.

    You've already called parseIncludes here:

    if (isset($_GET['include'])) {
        $fractal->parseIncludes($_GET['include']);
    }
    

    So just remove the second call to it in the return statement:
    return $fractal->createData($resource)->toJson();