Collection

The collection provides convenient and unified access to multi-results sets, predominantly returned by builder functions.

All collections also serve as iterators, allowing for looping over them as if they were PHP arrays.

Example

// builder->get() returns a collection
$users = builder::table('users')
    ->where('status', 1)
    ->get();

$count = $users->count();

echo "$count users found";

// You can loop over them
foreach ($users as $user) {
    echo $user->name;
}

Instantiating

$records = $DB->get_records('users');

// Pass any array
$users = new collection($records);

// There's also a shortcut method in case you need a fluent way of creating it
$user_ids = collection::new($records)->pluck('id');

// You can also start from an empty collection and add items later
$users = new collection();
foreach ($records as $record) {
    $users->append($record);
}

Functions

append()

Use this to add new elements to the collection.

$items = [
	[
        'id' => 1,
        'name' => 'Jack'
    ], [
        'id' => 2,
        'name' => 'Jill'
    ]
];

$col = new collection($items);
$col->append([
    'id' => 3,
    'name' => 'Jane'
]);

If you want to specify a key pass it as the second parameter.

$items = [...];

$col = new collection($items);
$col->append(
    [
        'id' => 3,
        'name' => 'Jane'
    ],
    3
);

keys()

Returns the keys of the items

$items = [
    1 => [
        'id' => 1,
        'name' => 'Jack'
    ], 
    2 => [
        'id' => 2,
        'name' => 'Jill'
    ]
];

$col = new collection($items);

print_r($col->keys());

/* prints

Array(
    1,
    2
)

count()

You can call this to get the amount of items in the collection. Alternatively you can also use count($collection) as it implements the Countable interface.

$col = new collection([...]);

echo $col->count();
echo count($col);

map()

This is the equivalent to array_map(). Pass a Callable which accepts the current item and return an item.

It will return a new collection with the modified items. It won't affect the original collection. Use transform() if you want to modify the original collection.

$col = new collection([...]);

// Pass a Closure
$new_col = $col->map(function ($item) {
    // do something with the item
    $new_item = ...;
    return $new_item;
);

map_to()

Accepts either a Callable or a class name. If you supply a Callable it calls it for each item and will use the returned value for it (see map()). If you supply a class name it will create a new instance of the given class for each item and passes the item as the constructor argument.

It will return a new collection with the modified items. It won't affect the original collection. Use transform_to() if you want to modify the original collection.

$col = new collection([...]);

// Pass a Closure
$new_col = $col->map_to(function ($item) {
    // do something with the item
    $new_item = ...;
    return $new_item;
);

// Pass a class name
$new_col = $col->map_to(my_custom_item::class);

transform()

This is the equivalent of map() except that it does not return a new collection but will change the items in the collection it's called on.

transform_to()

This is the equivalent of map_to() except that it does not return a new collection but will change the items in the collection it's called on.

pluck()

Plucks is an equivalent to array_column and returns all values of a given key.

$items = [
	[
        'id' => 1,
        'name' => 'Jack'
    ], [
        'id' => 2,
        'name' => 'Jill'
    ]
];

$col = new collection($items);

print_r($col->pluck('id'));

/* prints

Array(
   1, 
   2
)

*/

first()

Returns the first item of the collection.

$items = [
	[
        'id' => 1,
        'name' => 'Jack'
    ], [
        'id' => 2,
        'name' => 'Jill'
    ]
];

$col = new collection($items);

print_r($col->first());

/* prints

Array(
    [
        'id' => 1,
        'name' => 'Jack'
    ]
)

*/

all()

Returns all items in the collection. It accepts a boolean argument $with_keys (defaulting to false).

$items = [
    1 => [
        'id' => 1,
        'name' => 'Jack'
    ], 
    2 => [
        'id' => 2,
        'name' => 'Jill'
    ]
];

$col = new collection($items);

print_r($col->all());

/* prints

Array(
    [
        'id' => 1,
        'name' => 'Jack'
    ],
    [
        'id' => 2,
        'name' => 'Jill'
    ]
)

*/

print_r($col->all(true));

/* prints

Array(
[
    1 => [
        'id' => 1,
        'name' => 'Jack'
    ],
    2 => [
        'id' => 2,
        'name' => 'Jill'
    ]
]
)

*/

item()

Returns a single item identified by key.

$items = [
    1 => [
        'id' => 1,
        'name' => 'Jack'
    ], 
    2 => [
        'id' => 2,
        'name' => 'Jill'
    ]
];

$col = new collection($items);

print_r($col->item(2));

/* prints

Array(
    [
        'id' => 2,
        'name' => 'Jill'
    ]
)

*/

to_array()

Converts all items to an array of arrays if possible. Tries to either cast the items or calls to_array() function on the items if it has it.

$item1 = new stdClass();
$item1->id = 1;
$item1->name = 'Jack';

$item1 = new stdClass();
$item1->id = 2;
$item1->name = 'Jill';

$items = [$item1, $item2];

$col = new collection($items);

print_r($col->to_array(2));

/* prints

Array(
    [ 
        'id' => 1, 
        'name' => 'Jack' 
    ],
    [
        'id' => 2,
        'name' => 'Jill'
    ]
)

*/

JsonSerializable

You can convert a collection to JSON by calling json_encode on it. Internally it will encode the results of to_array() to JSON.

$items = [
    1 => [
        'id' => 1,
        'name' => 'Jack'
    ], 
    2 => [
        'id' => 2,
        'name' => 'Jill'
    ]
];

$col = new collection($items);

echo(json_encode($col));

/* prints

[{"id":1,"name":"Jack"},{"id":2,"name":"Jill"}]

*/