Entity collections
All results from Small Swoole Entity Manager inherit from EntityCollection class.
You can extend this class in order to implement specific methods for your entities.
The collection has the behaviour of an array but is also an object.
See Small Collection package for all functionalities.
Use it as an array
Collection are iterables and support most of array functionnalities :
<?php
$collection = new Collection(['a', 'b', 'c', 'd', 'e']);
foreach ($collection as $key => $value) {
echo $value;
}
$result = $collection[3];
Use it as an object
You can set a value for a specific key :
<?php
$collection = new \Small\Collection\Collection\Collection();
$key = 101;
$value = 'test';
$collection->set($key, $value);
And use it :
EntityCollection methods
persist
You can perform persist on all entities in collection :
<?php
$collection = $userManager->findBy(['type' => 'customer']);
$collection->map(function (int $key, UserEntity $user) {
$user->addPoints(rand(1, 10));
});
$collection->persist();
delete
You can perform deletion of all entities of collection from database :
Extending EntityCollection
Extending EntityCollection allow you to create methods specific for a given group of entity.
First create collection :
<?php
/* File : EntityCollection/UserEntityCollection.php */
namespace MyApp\EntityCollection;
use Small\SwooleEntityManager\Entity\EntityCollection;
class UserEntityCollection extends EntityCollection
{
public function getChilds: self
{
return $this->filterByCallback(fn($key, $user) => $user->getAge() < 18);
}
}
And tag your entity :
<?php
/* File : Entity/UserEntity.php */
namespace MyApp\Entity;
use Small\SwooleEntityManager\Entity\AbstractEntity;
use Small\SwooleEntityManager\Entity\Attribute\PrimaryKey;
use Small\SwooleEntityManager\Entity\Attribute\Field;
use Small\SwooleEntityManager\Entity\Attribute\Collection;
use Small\SwooleEntityManager\Entity\Enum\FieldValueType;
use MyApp\EntityCollection\UserEntityCollection;
#[Collection(UserEntityCollection::class)]
class UserEntity extends AbstractEntity
{
#[PrimaryKey]
public ?int $id = null;
#[Field(
type: FieldValueType::string,
)]
public ?string $username = null;
}
You can now use your collection methods on results :
Basic methods
Generic methods
You can create an empty collection :
Or fill it with an array at initialization :
Set a key
<?php
$collection = new \Small\Collection\Collection\Collection(['map', 'drive', 'country']);
$collection->set($key, $value);
Merge another collection
You can merge a collection with another
<?php
$collection = new \Small\Collection\Collection\Collection(['map', 'drive', 'country']);
$collectionBis = new \Small\Collection\Collection\Collection(['map1', 'drive2', 'country3']);
$newCollection = $collection->merge($collectionBis);
Or with an array
<?php
$collection = new \Small\Collection\Collection\Collection(['map', 'drive', 'country']);
$newCollection = $collection->merge(['map1', 'drive2', 'country3']);
And it is possible to act on the source collection
<?php
$collection = new \Small\Collection\Collection\Collection(['map', 'drive', 'country']);
$collection->merge(['map1', 'drive2', 'country3'], true);
Fusion by keys
You can fusion two collection on one on key based comparison
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$collectionBis = new \Small\Collection\Collection\Collection([
0 => 'map1',
1 => 'drive2',
2 => 'country3'
]);
$newCollection = $collection->fusionByKey($collectionBis);
Result :
It is possible to act on the source collection
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$collectionBis = new \Small\Collection\Collection\Collection([
0 => 'map1',
1 => 'drive2',
2 => 'country3'
]);
$collection->fusionByKey($collectionBis, true);
Intersect collections
You can intersect two collections
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$collectionBis = new \Small\Collection\Collection\Collection([
0 => 'map1',
1 => 'drive',
2 => 'country'
]);
$newCollection = $collection->intersect($collectionBis);
Result
It is possible to act on the source collection
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$collectionBis = new \Small\Collection\Collection\Collection([
0 => 'map1',
1 => 'drive',
2 => 'country'
]);
$collection->intersect($collectionBis, true);
Intersect by keys
You can intersect two collections on key based comparison
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$collectionBis = new \Small\Collection\Collection\Collection([
0 => 'map1',
1 => 'drive',
2 => 'country'
]);
$newCollection = $collection->intersectByKey($collectionBis);
Result
It is possible to act on the source collection
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$collectionBis = new \Small\Collection\Collection\Collection([
0 => 'map1',
1 => 'drive',
2 => 'country'
]);
$collection->intersectByKey($collectionBis, true);
Values
You can get a collection of values with keys reinitialisation
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$values = $collection->values();
Result
Convert collection to array
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$array = $collection->toArray();
The process is recursive :
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country',
4 => new \Small\Collection\Collection\Collection([1, 2, 3, 4]);
]);
$array = $collection->toArray(false);
Result
Filter by keys
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$array = $collection->filterByKeys([2, 3]);
Result
Filter by values
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$array = $collection->filterByValues(["map", "drive"]);
Result
Filter by callback
<?php
$collection = new \Small\Collection\Collection\Collection([
1 => 'map',
2 => 'drive',
3 => 'country'
]);
$array = $collection->filterByCallback(function (int|string $key, mixed $value): bool {
if ($key >= 3) {
return true;
}
return false;
});
Result
Sort by keys
<?php
$collection = new \Small\Collection\Collection\Collection([
2 => 'map',
1 => 'drive',
3 => 'country'
]);
$array = $collection->sortByKey();
Result
Sort by values
<?php
$collection = new \Small\Collection\Collection\Collection([
2 => 'map',
1 => 'drive',
3 => 'country'
]);
$array = $collection->sortByKey();
Result
Sort by callback
<?php
$collection = new \Small\Collection\Collection\Collection([
2 => 'map',
1 => 'drive',
3 => 'country'
]);
$array = $collection->sortByCallback(function (mixed $a, mixed $b): int {
if ($a < $b) {
return -1;
} else if ($a > $b) {
return 1;
}
return 0;
});
Result
Fill collection with a value
Result
Get first value
<?php
$collection = new \Small\Collection\Collection\Collection(['a', 'b', 'c']);
// echo 'a'
echo $collection->first();
Get last value
<?php
$collection = new \Small\Collection\Collection\Collection(['a', 'b', 'c']);
// echo 'c'
echo $collection->last();
Get first key
<?php
$collection = new \Small\Collection\Collection\Collection(['a', 'b', 'c']);
// echo 0
echo $collection->firstKey();
Get last key
<?php
$collection = new \Small\Collection\Collection\Collection(['a', 'b', 'c']);
// echo 2
echo $collection->firstKey();
Push a value
Adding d char to the end of collection
<?php
$collection = new \Small\Collection\Collection\Collection(['a', 'b', 'c']);
$collection->push('d');
Result
Pop a value
<?php
$collection = new \Small\Collection\Collection\Collection(['a', 'b', 'c']);
$value = $collection->pop();
Result $value : "c"
Array after pop :
Map a callback to collection
<?php
$collection = new \Small\Collection\Collection\Collection([0, 1, 2]);
$result = $collection->map(function (int|string $key, mixed $value) {
return $value + 1;
});
Result
Remove keys
Same that values method but apply to $this
Selector
You can select arrays like it was a database table.
You can create use selector to request data in a collection :
<?php
$selector = new Small\Collection\Selector\CollectionSelector(
(new ValuesToRecords(
new Collection([1, 2, 3])
))->transform()
)->where()
->firstCondition(
new Condition(
new ConditionElement(ConditionElementType::var, '*'),
ConditionOperator::equal,
new ConditionElement(ConditionElementType::const, 2),
)
)->orCondition(
new Condition(
new ConditionElement(ConditionElementType::var, '*'),
ConditionOperator::equal,
new ConditionElement(ConditionElementType::const, 3),
)
)
)->execute()
;
Here, the result will be a Small\Collection\Record\RecordCollection :
Bracket
It is possible to use bracket :
<?php
$selector = new Small\Collection\Selector\CollectionSelector(
(new \Small\Collection\Record\ToRecordTransformer\CollectionsToRecords(
new Collection([
['test1' => 'a', 'test2' => 'b'],
['test1' => 'a', 'test2' => 'c'],
['test1' => 'c', 'test2' => 'b'],
['test1' => 'd', 'test2' => 'b'],
])
))->transform()
)->where()
->firstCondition(
new Condition(
new ConditionElement(ConditionElementType::var, 'test1'),
ConditionOperator::equal,
new ConditionElement(ConditionElementType::const, 'a'),
)
)->andBracket()
->firstCondition(
new Condition(
new ConditionElement(ConditionElementType::var, 'test2'),
ConditionOperator::equal,
new ConditionElement(ConditionElementType::const, 'b'),
)
)->orCondition(
new Condition(
new ConditionElement(ConditionElementType::var, 'test2'),
ConditionOperator::equal,
new ConditionElement(ConditionElementType::const, 'c'),
)
)
)->execute()
;
Here, the result will be a Small\Collection\Record\RecordCollection :
Comparators
<?php
ConditionOperator::equal
ConditionOperator::inferior
ConditionOperator::superior
ConditionOperator::inferiorOrEqual
ConditionOperator::superiorOrEqual
ConditionOperator::notEqual
ConditionOperator::like // joker char _ and joker string *
ConditionOperator::notLike // joker char _ and joker string *
ConditionOperator::matchRegex
ConditionOperator::notMatchRegex
ConditionOperator::isNull
ConditionOperator::isNotNull
ConditionOperator::exists
ConditionOperator::notExists
ConditionOperator::in
ConditionOperator::notIn
For example :
<?php
$selector = new Small\Collection\Selector\CollectionSelector(
(new \Small\Collection\Record\ToRecordTransformer\CollectionsToRecords(
new Collection([
['test1' => 'a', 'test2' => 'b'],
['test1' => 'a', 'test2' => 'c'],
['test1' => 'c', 'test2' => 'b'],
['test1' => 'd', 'test2' => 'b'],
])
))->transform()
)->where()
->firstCondition(
new Condition(
new ConditionElement(ConditionElementType::var, 'test1'),
ConditionOperator::equal,
new ConditionElement(ConditionElementType::const, 'a'),
)
)->andCondition(
new Condition(
new ConditionElement(ConditionElementType::var, 'test2'),
ConditionOperator::in,
new ConditionElement(ConditionElementType::const, ['b', 'c']),
)
)->execute()
;
Here, the result will be a Small\Collection\Record\RecordCollection :