Skip to content

Commit

Permalink
Merge pull request #53 from AuroraWebSoftware/polymorphic-update-orga…
Browse files Browse the repository at this point in the history
…nization-node

Polymorphic update organization node
  • Loading branch information
emreakay authored Oct 3, 2023
2 parents f84a806 + 3d34b99 commit e24f656
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 61 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@
}
}
},
"minimum-stability": "dev",
"minimum-stability": "stable",
"prefer-stable": true
}
2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ includes:

parameters:
reportUnmatchedIgnoredErrors: false
level: 6
level: 7
paths:
- src
- config
Expand Down
5 changes: 4 additions & 1 deletion src/AAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ public function organizationNodes(bool $includeRootNode = false, ?string $modelT
$rootNode = OrganizationNode::find($organizationNodeId);
throw_unless($rootNode, new InvalidOrganizationNodeException());
$rootNodeChar = $includeRootNode ? '' : '/';

/**
* @phpstan-ignore-next-line
*/
$query->orWhere('path', 'like', $rootNode->path.$rootNodeChar.'%');
}
})
Expand All @@ -208,6 +210,7 @@ public function organizationNode(int $nodeId, ?string $modelType = null): Organi
return $organizationNode;
}
}

/*
if ($organizationNodes->contains(fn($node, $key) => $node->id == $nodeId)) {
return OrganizationNode::findOrFail($nodeId)->first();
Expand Down
3 changes: 2 additions & 1 deletion src/Models/OrganizationNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* @method static Builder|OrganizationNode query()
* @method static Builder|OrganizationNode whereCreatedAt($value)
* @method static Builder|OrganizationNode whereId($value)
* @method static Builder|OrganizationNode where($value)
* @method static Builder|OrganizationNode whereModelId($value)
* @method static Builder|OrganizationNode whereModelType($value)
* @method static Builder|OrganizationNode whereName($value)
Expand All @@ -39,7 +40,7 @@
* @method static Builder|OrganizationNode wherePath($value)
* @method static Builder|OrganizationNode whereUpdatedAt($value)
* @method static OrganizationNode find($value)
* @mixin \Eloquent
* @mixin OrganizationNode
*/
class OrganizationNode extends Model
{
Expand Down
2 changes: 1 addition & 1 deletion src/Models/Role.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* @property Carbon|null $updated_at
* @property int|null $organization_scope_id
*
* @method static find($role_id) : Role
* @method static Role find($role_id)
*/
class Role extends Model
{
Expand Down
8 changes: 5 additions & 3 deletions src/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace AuroraWebSoftware\AAuth\Models;

use AuroraWebSoftware\AAuth\Contracts\AAuthUserContract;
use Eloquent;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
Expand All @@ -23,8 +23,6 @@
* @property string|null $remember_token
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @mixin Eloquent
*
* @property-read \Illuminate\Database\Eloquent\Collection|Role[] $roles
* @property-read int|null $roles_count
* @property-read \Illuminate\Database\Eloquent\Collection|Role[] $organizational_roles
Expand Down Expand Up @@ -88,6 +86,10 @@ public function rolesWithOrganizationNodes(): Collection

foreach ($rolesWithOrganizationNodes as $rolesWithOrganizationNode) {
$role = Role::find($rolesWithOrganizationNode->role_id);
/**
* @var Role $role
* @phpstan-ignore-next-line
*/
$role->organizationNode = OrganizationNode::find($rolesWithOrganizationNode->organization_node_id);

$rolesCollection->push($role);
Expand Down
108 changes: 60 additions & 48 deletions src/Services/OrganizationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use AuroraWebSoftware\AAuth\Http\Requests\StoreOrganizationNodeRequest;
use AuroraWebSoftware\AAuth\Http\Requests\StoreOrganizationScopeRequest;
use AuroraWebSoftware\AAuth\Http\Requests\UpdateOrganizationNodeRequest;
use AuroraWebSoftware\AAuth\Http\Requests\UpdateOrganizationScopeRequest;
use AuroraWebSoftware\AAuth\Models\OrganizationNode;
use AuroraWebSoftware\AAuth\Models\OrganizationScope;
Expand All @@ -22,8 +21,8 @@ class OrganizationService
/**
* Creates an org. scope with given array
*
* @param array $organizationScope
* @param bool $withValidation
* @param array $organizationScope
* @param bool $withValidation
* @return OrganizationScope
*
* @throws ValidationException
Expand All @@ -45,9 +44,9 @@ public function createOrganizationScope(array $organizationScope, bool $withVali
/**
* Updates a Perm.
*
* @param array $organizationScope
* @param int $id
* @param bool $withValidation
* @param array $organizationScope
* @param int $id
* @param bool $withValidation
* @return ?OrganizationScope
*
* @throws ValidationException
Expand All @@ -71,7 +70,7 @@ public function updateOrganizationScope(array $organizationScope, int $id, bool
/**
* deletes perm.
*
* @param int $id
* @param int $id
* @return bool|null
*/
public function deleteOrganizationScope(int $id): ?bool
Expand All @@ -82,8 +81,8 @@ public function deleteOrganizationScope(int $id): ?bool
/**
* Creates an org. node with given array
*
* @param array $organizationNode
* @param bool $withValidation
* @param array $organizationNode
* @param bool $withValidation
* @return OrganizationNode
*
* @throws ValidationException
Expand All @@ -103,19 +102,19 @@ public function createOrganizationNode(array $organizationNode, bool $withValida
$parentPath = $this->getPath($organizationNode['parent_id'] ?? null);

// add temp path before determine actual path
$organizationNode['path'] = $parentPath.'/?';
$organizationNode['path'] = $parentPath . '/?';
$organizationNode = OrganizationNode::create($organizationNode);

// todo , can be add inside model's created event
$organizationNode->path = $parentPath.$organizationNode->id;
$organizationNode->path = $parentPath . $organizationNode->id;
$organizationNode->save();

return $organizationNode;
}

/**
* @param Model $model
* @param int $parentOrganizationId
* @param Model $model
* @param int $parentOrganizationId
* @return OrganizationNode|null
*/
public function createOrganizationNodeForModel(Model $model, int $parentOrganizationId): ?OrganizationNode
Expand All @@ -124,7 +123,8 @@ public function createOrganizationNodeForModel(Model $model, int $parentOrganiza
}

/**
* @param int|null $organizationNodeId
* Return path with trailing slash (/)
* @param int|null $organizationNodeId
* @return string|null
*/
public function getPath(?int $organizationNodeId): ?string
Expand All @@ -133,65 +133,77 @@ public function getPath(?int $organizationNodeId): ?string
return '';
}

return OrganizationNode::find($organizationNodeId)?->path.'/';
return OrganizationNode::find($organizationNodeId)?->path . '/';
}

/**
* @param int $organizationNodeId
* @param int $organizationNodeId
*/
public function calculatePath(int $organizationNodeId): void
{
// todo
}

/**
* @param array $organizationNode
* @param int $id
* @param bool $withValidation
* @return OrganizationNode|false
*
* @throws ValidationException
* Updates organization node recursively using breadth first method
* @param OrganizationNode $node
* @param bool|null $withDBTransaction
* @return void
*/
public function updateOrganizationNode(array $organizationNode, int $id, bool $withValidation = true): OrganizationNode|bool
public function updateNodePathsRecursively(OrganizationNode $node, ?bool $withDBTransaction = true): void
{
if ($withValidation) {
$validator = Validator::make($organizationNode, UpdateOrganizationNodeRequest::$rules);
if ($withDBTransaction) {
DB::beginTransaction();
}

if ($validator->fails()) {
$message = implode(' , ', $validator->getMessageBag()->all());
try {
$node->path = $this->getPath($node->parent_id) . $node->id;
$node->save();

throw new ValidationException($validator, new Response($message, Response::HTTP_UNPROCESSABLE_ENTITY));
}
}
$subNodes = OrganizationNode::whereParentId($node->id)->get();

$organizationNodeModel = OrganizationNode::find($id);
foreach ($subNodes as $subNode) {
$this->updateNodePathsRecursively($subNode, false);
}

$organizationNodeModel->path = $this->getPath($organizationNodeModel->parent_id).$organizationNodeModel->id;
} catch (\Exception $exception) {
DB::rollback();
}

return $organizationNodeModel->update($organizationNode) ? $organizationNodeModel : false;
if ($withDBTransaction) {
DB::commit();
}
}

/**
* @param int $id
* @return bool
* deletes organization nodes using depth first search
* @param OrganizationNode $node
* @param bool|null $withDBTransaction
* @return void
*/
public function deleteOrganizationNode(int $id): bool
public function deleteOrganizationNodesRecursively(OrganizationNode $node, ?bool $withDBTransaction = true): void
{
// todo
// tamamen yeniden yazılacak.
/*
$rolePermissionService = new \App\Services\RolePermissionService();
if ($withDBTransaction) {
DB::beginTransaction();
}

try {
//
$subNodes = OrganizationNode::whereParentId($node->id)->get();

$PivotTable = DB::table('user_role_organization_node')
->where('organization_node_id', $id)
->get();
foreach ($subNodes as $subNode) {
$this->deleteOrganizationNodesRecursively($subNode, false);
}

$node->delete();

} catch (\Exception $exception) {
DB::rollback();
}

foreach ($PivotTable as $pivotrow) {
$rolePermissionService->detachOrganizationRoleFromUser($pivotrow->user_id, $pivotrow->role_id, $pivotrow->organization_node_id);
if ($withDBTransaction) {
DB::commit();
}

return OrganizationNode::find($id)->delete();
*/
return false;
}
}
59 changes: 58 additions & 1 deletion src/Traits/AAuthOrganizationNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,64 @@ public static function createWithAAuthOrganizationNode(array $modelCreateData, i
return $createdModel;
}

public function deleteWithAAuthOrganizationNode(int $modelId)
/**
* @throws Throwable
*/
public static function updateWithAAuthOrganizationNode(int $modelId, int $nodeId, array $modelUpdateData, int $parentOrganizationNodeId, int $organizationScopeId)
{

$organizationService = new OrganizationService();

$parentOrganizationNode = OrganizationNode::find($parentOrganizationNodeId);

throw_if($parentOrganizationNode == null, new InvalidOrganizationNodeException());

$organizationScope = OrganizationScope::find($organizationScopeId);

throw_if($organizationScope == null, new InvalidOrganizationScopeException());


$modelInfo = self::find($modelId);

$updatedModel = $modelInfo->update($modelUpdateData);



$OrgNodeUpdateData = [
'name' => $modelInfo->getModelName(),
'organization_scope_id' => $organizationScope->id,
'parent_id' => $parentOrganizationNode->id,
'model_type' => self::getModelType(),
'model_id' => $modelId,
];
$updateON = $organizationService->updateOrganizationNodesRecursively($OrgNodeUpdateData, $nodeId);

return $updatedModel;
}

/**
* @param int $modelId
* @return bool
* @throws Throwable
*/
public static function deleteWithAAuthOrganizationNode(int $modelId)
{

$organizationService = new OrganizationService();

$organizationNode = OrganizationNode::where('model_id', $modelId)->first();


throw_if($organizationNode == null, new InvalidOrganizationNodeException());


$modelInfo = self::findOrFail($modelId);

$deleteModel = $modelInfo->delete($modelInfo);


$deleteON = $organizationService->deleteOrganizationNodesRecursively($organizationNode->id);

return true;
}
}
29 changes: 25 additions & 4 deletions tests/Unit/OrganizationServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,34 @@
$createdCount = OrganizationNode::whereName($data['name'])->count();
$this->assertEquals(1, $createdCount);



$this->service->updateNodePathsRecursively($createdON);
$updatedCount = OrganizationNode::whereName($data['name'])->count();
$this->assertEquals(1, $updatedCount);
});

test('can testing delete of an OrganizationNode ', function () {
$os = OrganizationScope::first();

$data = [
'name' => 'Updated Org Node 2',
'name' => 'Updated Org Node 1',
'organization_scope_id' => $os->id,
'parent_id' => 1,
];

$updatedON = $this->service->updateOrganizationNode($data, $createdON->id);
$updatedCount = OrganizationNode::whereName($data['name'])->count();
$this->assertEquals(1, $updatedCount);
$createdON = $this->service->createOrganizationNode($data);

$this->assertEquals($createdON->name, $data['name']);

$createdCount = OrganizationNode::whereName($data['name'])->count();
$this->assertEquals(1, $createdCount);


$deletedON = $this->service->deleteOrganizationNodesRecursively($createdON);
$this->assertEquals($deletedON, null);

$deletedONCount = OrganizationNode::where('id', $createdON->id)->count();
$this->assertEquals(0, $deletedONCount);

});

0 comments on commit e24f656

Please sign in to comment.