/** * @covers \Airship\array_multi_diff() */ public function testArrayMultiDiff() { $old = [1 => ['read' => true, 'write' => true, 'execute' => true], 2 => ['read' => true, 'write' => false, 'execute' => true], 3 => ['read' => false, 'write' => false, 'execute' => false]]; $new_1 = [1 => ['read' => true, 'write' => true, 'execute' => true], 3 => ['read' => true, 'write' => false, 'execute' => false]]; $new_2 = [1 => ['read' => true, 'write' => true, 'execute' => true], 2 => ['read' => true, 'write' => false, 'execute' => true], 3 => ['read' => false, 'write' => false, 'execute' => false], 4 => ['read' => true, 'write' => false, 'execute' => false]]; $this->assertSame([1 => [], 3 => ['read' => true]], \Airship\array_multi_diff($new_1, $old)); $this->assertSame([4 => ['read' => true, 'write' => false, 'execute' => false], 1 => [], 2 => [], 3 => []], \Airship\array_multi_diff($new_2, $old)); $this->assertSame([2 => ['read' => true, 'write' => false, 'execute' => true], 1 => [], 3 => ['read' => false]], \Airship\array_multi_diff($old, $new_1)); $this->assertSame([1 => [], 2 => [], 3 => []], \Airship\array_multi_diff($old, $new_2)); }
/** * Saves a permission context. This affects the context itself as well as * the whitelist. * * @param string $cabin Which Cabin? * @param int $contextId Which context? * @param array $post POST data * @return bool */ public function saveContext(string $cabin, int $contextId, array $post) : bool { $actions = $this->getActionNames($cabin); $actionIds = \array_flip($actions); $post['group_perms'] = $this->permBoolean($post['group_perms'] ?? [], $actions); $post['user_perms'] = $this->permBoolean($post['user_perms'] ?? [], $actions); $groupPerms = $this->getGroupRulesForContextSave($actions, $contextId); $userPerms = $this->getUserRulesForContextSave($actions, $contextId); // Sort then diff group permissions: \ksort($groupPerms); \ksort($post['group_perms']); $groupInsert = \Airship\array_multi_diff($post['group_perms'], $groupPerms); $groupDelete = \Airship\array_multi_diff($groupPerms, $post['group_perms']); // Sort then diff user permissions: \ksort($userPerms); \ksort($post['user_perms']); $userInsert = \Airship\array_multi_diff($post['user_perms'], $userPerms); $userDelete = \Airship\array_multi_diff($userPerms, $post['user_perms']); $this->db->beginTransaction(); // Update the locator $this->db->update('airship_perm_contexts', ['locator' => $post['context']], ['cabin' => $cabin, 'contextid' => $contextId]); // Insert then delete rules based on the changes made: // Insert new group rules: foreach ($groupInsert as $group => $inserts) { foreach ($inserts as $lbl => $val) { if ($val) { $this->db->insert('airship_perm_rules', ['context' => $contextId, 'groupid' => $group, 'action' => $actionIds[$lbl]]); } } } // Delete old group rules: foreach ($groupDelete as $group => $deletes) { foreach ($deletes as $lbl => $val) { if ($val) { $this->db->delete('airship_perm_rules', ['context' => $contextId, 'groupid' => $group, 'action' => $actionIds[$lbl]]); } } } // Insert new user rules: foreach ($userInsert as $user => $inserts) { foreach ($inserts as $lbl => $val) { if ($val) { $this->db->insert('airship_perm_rules', ['context' => $contextId, 'userid' => $user, 'action' => $actionIds[$lbl]]); } } } // Delete old user rules: foreach ($userDelete as $user => $deletes) { foreach ($deletes as $lbl => $val) { if ($val) { $this->db->delete('airship_perm_rules', ['context' => $contextId, 'userid' => $user, 'action' => $actionIds[$lbl]]); } } } return $this->db->commit(); }