Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
vendor
/
hashids
/
hashids
:
AssignsRoles.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?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'); } }