File "AssignsRoles.php"
Full Path: /home/pulsehostuk9/public_html/invoicer.pulsehost.co.uk/vendor/lavary/AssignsRoles.php
File size: 4.11 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace Silber\Bouncer\Conductors;
use Illuminate\Support\Collection;
use Silber\Bouncer\Database\Models;
use Silber\Bouncer\Helpers;
class AssignsRoles
{
/**
* The roles to be assigned.
*
* @var array
*/
protected $roles;
/**
* Constructor.
*
* @param \Illuminate\Support\Collection|\Silber\Bouncer\Database\Role|string $roles
*/
public function __construct($roles)
{
$this->roles = Helpers::toArray($roles);
}
/**
* Assign the roles to the given authority.
*
* @param \Illuminate\Database\Eloquent\Model|array|int $authority
* @return bool
*/
public function to($authority)
{
$authorities = is_array($authority) ? $authority : [$authority];
$roles = Models::role()->findOrCreateRoles($this->roles);
foreach (Helpers::mapAuthorityByClass($authorities) as $class => $ids) {
$this->assignRoles($roles, $class, new Collection($ids));
}
return true;
}
/**
* Assign the given roles to the given authorities.
*
* @param string $authorityClass
* @return void
*/
protected function assignRoles(Collection $roles, $authorityClass, Collection $authorityIds)
{
$roleIds = $roles->map(function ($model) {
return $model->getKey();
});
$morphType = (new $authorityClass)->getMorphClass();
$records = $this->buildAttachRecords($roleIds, $morphType, $authorityIds);
$existing = $this->getExistingAttachRecords($roleIds, $morphType, $authorityIds);
$this->createMissingAssignRecords($records, $existing);
}
/**
* Get the pivot table records for the roles already assigned.
*
* @param \Illuminate\Support\Collection $roleIds
* @param string $morphType
* @param \Illuminate\Support\Collection $authorityIds
* @return \Illuminate\Support\Collection
*/
protected function getExistingAttachRecords($roleIds, $morphType, $authorityIds)
{
$query = $this->newPivotTableQuery()
->whereIn('role_id', $roleIds->all())
->whereIn('entity_id', $authorityIds->all())
->where('entity_type', $morphType);
Models::scope()->applyToRelationQuery($query, $query->from);
return new Collection($query->get());
}
/**
* Build the raw attach records for the assigned roles pivot table.
*
* @param \Illuminate\Support\Collection $roleIds
* @param string $morphType
* @param \Illuminate\Support\Collection $authorityIds
* @return \Illuminate\Support\Collection
*/
protected function buildAttachRecords($roleIds, $morphType, $authorityIds)
{
return $roleIds
->crossJoin($authorityIds)
->mapSpread(function ($roleId, $authorityId) use ($morphType) {
return Models::scope()->getAttachAttributes() + [
'role_id' => $roleId,
'entity_id' => $authorityId,
'entity_type' => $morphType,
];
});
}
/**
* Save the non-existing attach records in the DB.
*
* @return void
*/
protected function createMissingAssignRecords(Collection $records, Collection $existing)
{
$existing = $existing->keyBy(function ($record) {
return $this->getAttachRecordHash((array) $record);
});
$records = $records->reject(function ($record) use ($existing) {
return $existing->has($this->getAttachRecordHash($record));
});
$this->newPivotTableQuery()->insert($records->all());
}
/**
* Get a string identifying the given attach record.
*
* @return string
*/
protected function getAttachRecordHash(array $record)
{
return $record['role_id'].$record['entity_id'].$record['entity_type'];
}
/**
* Get a query builder instance for the assigned roles pivot table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function newPivotTableQuery()
{
return Models::query('assigned_roles');
}
}