Passed
Push — serialization-refactor ( 7d0248...e27dea )
by Alex
02:50
created

CollectionSerializer::getIncludedRecords()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
namespace Huntie\JsonApi\Serializers;
4
5
use Illuminate\Pagination\LengthAwarePaginator;
6
7
class CollectionSerializer extends JsonApiSerializer
8
{
9
    /**
10
     * The collection of records to transform.
11
     *
12
     * @var \Illuminate\Support\Collection|LengthAwarePaginator
13
     */
14
    protected $records;
15
16
    /**
17
     * The subset of attributes to return for each record.
18
     *
19
     * @var array
20
     */
21
    protected $fields;
22
23
    /**
24
     * The relationships to load and include.
25
     *
26
     * @var array
27
     */
28
    protected $include;
29
30
    /**
31
     * Create a new JSON API collection serializer.
32
     *
33
     * @param Collection|LengthAwarePaginator $records The collection of records to serialize
34
     * @param array|null                      $fields  Subset of fields to return
35
     * @param array|null                      $include Relations to include
36
     */
37
    public function __construct($records, array $fields = [], array $include = [])
38
    {
39
        parent::__construct();
40
41
        $this->records = $records;
0 ignored issues
show
Documentation Bug introduced by
It seems like $records can also be of type object<Huntie\JsonApi\Serializers\Collection>. However, the property $records is declared as type object<Illuminate\Suppor...n\LengthAwarePaginator>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
42
        $this->fields = array_unique($fields);
43
        $this->include = array_unique($include);
44
    }
45
46
    /**
47
     * Return a collection of JSON API resource objects for the record set.
48
     *
49
     * @return \Illuminate\Support\Collection
50
     */
51
    public function toResourceCollection()
52
    {
53
        if ($records instanceof LengthAwarePaginator) {
0 ignored issues
show
Bug introduced by
The variable $records does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
54
            $this->addPaginationLinks();
55
        }
56
57
        return $this->records->map(function ($record) {
0 ignored issues
show
Bug introduced by
The method map does only exist in Illuminate\Support\Collection, but not in Illuminate\Pagination\LengthAwarePaginator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
58
            return (new ResourceSerializer($record, $this->fields, $this->include))->toResourceObject();
59
        });
60
    }
61
62
    /**
63
     * Return a collection of JSON API resource objects for each included
64
     * relationship.
65
     *
66
     * @return \Illuminate\Support\Collection
67
     */
68
    public function getIncludedRecords()
69
    {
70
        return $this->records->map(function ($record) {
0 ignored issues
show
Bug introduced by
The method map does only exist in Illuminate\Support\Collection, but not in Illuminate\Pagination\LengthAwarePaginator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
71
            return (new ResourceSerializer($record, $this->fields, $this->include))->getIncludedRecords();
72
        })->flatten(1);
73
    }
74
75
    /**
76
     * Return primary data for the JSON API document.
77
     *
78
     * @return array
79
     */
80
    protected function getPrimaryData()
81
    {
82
        return $this->toResourceCollection()->toArray();
83
    }
84
85
    /**
86
     * Return any secondary included resource data.
87
     *
88
     * @return array
89
     */
90
    protected function getIncludedData()
91
    {
92
        return $this->getIncludedRecords()->toArray();
93
    }
94
95
    /**
96
     * Add pagination links and meta information to the main document.
97
     */
98
    protected function addPaginationLinks()
99
    {
100
        $this->addLinks([
101
            'first' => $this->records->url(1),
0 ignored issues
show
Bug introduced by
The method url does only exist in Illuminate\Pagination\LengthAwarePaginator, but not in Illuminate\Support\Collection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
102
            'last' => $this->records->url($this->records->lastPage()),
0 ignored issues
show
Bug introduced by
The method lastPage does only exist in Illuminate\Pagination\LengthAwarePaginator, but not in Illuminate\Support\Collection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
103
            'prev' => $this->records->previousPageUrl(),
0 ignored issues
show
Bug introduced by
The method previousPageUrl does only exist in Illuminate\Pagination\LengthAwarePaginator, but not in Illuminate\Support\Collection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
104
            'next' => $this->records->nextPageUrl(),
0 ignored issues
show
Bug introduced by
The method nextPageUrl does only exist in Illuminate\Pagination\LengthAwarePaginator, but not in Illuminate\Support\Collection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
105
        ]);
106
107
        $this->addMeta('total', $this->records->total());
0 ignored issues
show
Bug introduced by
The method total does only exist in Illuminate\Pagination\LengthAwarePaginator, but not in Illuminate\Support\Collection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
108
    }
109
}
110