Some background:
A game
belongs to a round
,
A round
belongs to a season
,
A season
belongs to a competition
A competition
is unowned.
We have eight tables
name => columns
`games` => `id`, `round_id`,
`rounds` => `id`, `season_id`,
`seasons` => `id`, `competition_id`,
`competitions` => `id`,
----
`user_game` => `user_id`, `game_id`,
`user_round` => `user_id`, `round_id`,
`user_season` => `user_id`, `season_id`,
`user_competition` => `user_id`, `competition_id`
So, the first four tables link the different parts together,
the second four tables link a user to the respective part.
Some dummy data, note I've split the tables when the second id changes for easy reading.
First four tables
/--GAMES--------------\ /--ROUNDS-------------\
| id | round_id | | id | season_id |
| 1 | 1 | | 1 | 1 |
| 2 | 1 | | 2 | 1 |
|----|----------------| | 3 | 1 |
| 3 | 2 | |----|----------------|
| 4 | 2 | | 4 | 2 |
|----|----------------| | 5 | 2 |
| 5 | 3 | | 6 | 2 |
| 6 | 3 | |----|----------------|
|----|----------------| | 7 | 3 |
| 7 | 4 | | 8 | 3 |
| 8 | 4 | | 9 | 3 |
|----|----------------| |----|----------------|
| 9 | 5 | | 10 | 4 |
| 10 | 5 | \---------------------/
|----|----------------|
| 11 | 6 | /--SEASONS------------\
| 12 | 6 | | id | competition_id |
|----|----------------| | 1 | 1 |
| 13 | 7 | | 2 | 1 |
| 14 | 7 | |----|----------------|
|----|----------------| | 3 | 2 |
| 15 | 8 | | 4 | 2 |
| 16 | 8 | \---------------------/
|----|----------------|
| 17 | 9 | /--COMPETITIONS-------\
| 18 | 9 | | id |
|----|----------------| | 1 |
| 19 | 10 | | 2 |
| 20 | 10 | \---------------------/
\---------------------/
The next four tables are best explained in the list below
Users:
user_game (user_id:1, game_id:1)
direct
access on game 1 parent
access on round 1 parent
access on season 1 parent
access on competition 1 user_round (user_id:2, round_id:1)
child
access on games 1,2 direct
access on round 1 parent
access on season 1 parent
access on competition 1 user_round (user_id:3, round_id:1)
direct
access on game 2 user_game (user_id:3, game_id:13)
direct
access on game 13 parent
access on round 7 parent
access on season 3 parent
access on competition 2 So, when fetching access for the three users above I want to end up with these three arrays, Noting that:
parent_access
: User has partial access as has access to a child object (regardless of what object)
direct_access
: User has full access as has been granted directly
child access
: User has full access as a parent object (regardless of what object) has been granted direct access
User 1
$user1 = array(
'games' => array(
[1] => array(
'id' => 1,
'parent_access' => false,
'direct_access' => true,
'child_access' => false
)
),
'rounds' => array(
[1] => array(
'id' => 1,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
)
),
'seasons' => array(
[1] => array(
'id' => 1,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
),
),
'competitions' => array(
[1] => array(
'id' => 1,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
),
)
);
User 2
$user2 = array(
'games' => array(
[1] => array(
'id' => 1,
'parent_access' => false,
'direct_access' => false,
'child_access' => true
),
[2] => array(
'id' => 2,
'parent_access' => false,
'direct_access' => false,
'child_access' => true
)
),
'rounds' => array(
[1] => array(
'id' => 1,
'parent_access' => false,
'direct_access' => true,
'child_access' => false
)
),
'seasons' => array(
[1] => array(
'id' => 1,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
),
),
'competitions' => array(
[1] => array(
'id' => 1,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
),
)
);
User 3
$user3 = array(
'games' => array(
[1] => array(
'id' => 1,
'parent_access' => false,
'direct_access' => false,
'child_access' => true
),
[2] => array(
'id' => 2,
'parent_access' => false,
'direct_access' => true,
'child_access' => true
),
[13] => array(
'id' => 13,
'parent_access' => false,
'direct_access' => true,
'child_access' => false
)
),
'rounds' => array(
[1] => array(
'id' => 1,
'parent_access' => false,
'direct_access' => true,
'child_access' => false
),
[7] => array(
'id' => 7,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
)
),
'seasons' => array(
[1] => array(
'id' => 1,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
),
[3] => array(
'id' => 3,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
)
),
'competitions' => array(
[1] => array(
'id' => 1,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
),
[2] => array(
'id' => 2,
'parent_access' => true,
'direct_access' => false,
'child_access' => false
)
)
);
A bit different of an outcome, but this is posted here to show my current working, and it still does work as an answer, albeit one I am not happy with.
So, here is my current code: lines like: $competitions = $this->competitions->disabled(true)->getAll();
run the query on the competitions table and return a custom object, so things are a bit different there, but you should be able to work out what it does by the code.
What U don't like about this here is that we have 18 foreach loops! many nested so that's 18 re-running foreach loops! Can anyone see a way to reduce this?
public function access($user_id, $action = 'none')
{
$access = array(
'competitions' => array()
);
/* COMPETITIONS */
$competitions = $this->competitions->disabled(true)->getAll();
foreach ($competitions as $competition) {
$access['competitions'][$competition->data('id')] = array(
//'item' => $competition,
'type' => 'competition',
'id' => $competition->data('id'),
'child_access' => false,
'direct_access' => false,
'parent_access' => false,
'seasons' => array()
);
/* SEASONS */
$seasons = $competition->seasons(true);
foreach ($seasons as $season) {
$access['competitions'][$competition->data('id')]['seasons'][$season->data('id')] = array(
//'item' => $season,
'type' => 'season',
'id' => $season->data('id'),
'child_access' => false,
'direct_access' => false,
'parent_access' => false,
'rounds' => array()
);
/* ROUNDS */
$rounds = $season->rounds(true);
foreach ($rounds as $round) {
$access['competitions'][$competition->data('id')]['seasons'][$season->data('id')]['rounds'][$round->data('id')] = array(
//'item' => $round,
'type' => 'round',
'id' => $round->data('id'),
'child_access' => false,
'direct_access' => false,
'parent_access' => false,
'games' => array()
);
/* GAMES */
$games = $round->games(true);
foreach ($games as $game) {
//dump('$access["competitions"]['.$competition->data('id').']["seasons"]['.$season->data('id').']["rounds"]['.$round->data('id').']["games"]['.$game->data('id').']');
$access['competitions'][$competition->data('id')]['seasons'][$season->data('id')]['rounds'][$round->data('id')]['games'][$game->data('id')] = array(
//'item' => $game,
'type' => 'game',
'id' => $game->data('id'),
'child_access' => false,
'direct_access' => false,
'parent_access' => false
);
}
}
}
}
/* CHECK COMPETITIONS */
$competitions = $this->db->select('competition_id')->from('user_competition')->where('user_id', $user_id)->get();
foreach ($competitions->result() as $id) {
$id = $id->competition_id;
$access['competitions'][$id]['direct_access'] = true;
/* SEASONS */
foreach ($access['competitions'][$id]['seasons'] as &$season) {
$season['child_access'] = true;
/* ROUNDS */
foreach ($season['rounds'] as &$round) {
$round['child_access'] = true;
/* GAMES */
foreach ($round['games'] as &$game) {
$game['child_access'] = true;
unset($game);
}
unset($round);
}
unset($season);
}
}
/* CHECK SEASONS */
$seasons = $this->db->select('season_id')->from('user_season')->where('user_id', $user_id)->get();
foreach ($seasons->result() as $id) {
$id = $id->season_id;
$competition_id = $this->seasons->disabled(true)->get($id)->data('competition id');
$competition = $access['competitions'][$competition_id];
$competition['parent_access'] = true;
$season = $competition['seasons'][$id];
$season['direct_access'] = true;
/* ROUNDS */
foreach ($season['rounds'] as &$round) {
$round['child_access'] = true;
/* GAMES */
foreach ($round['games'] as &$game) {
$game['child_access'] = true;
unset($game);
}
unset($round);
}
}
/* CHECK ROUNDS */
$rounds = $this->db->select('round_id')->from('user_round')->where('user_id', $user_id)->get();
foreach ($rounds->result() as $id) {
$id = $id->round_id;
$round_obj = $this->rounds->disabled(true)->get($id);
$season_obj = $round_obj->season();
$competition_id = $season_obj->data('competition id');
$access['competitions'][$competition_id]['parent_access'] = true;
$access['competitions'][$competition_id]['seasons'][$season_obj->data('id')]['parent_access'] = true;
$access['competitions'][$competition_id]['seasons'][$season_obj->data('id')]['rounds'][$id]['direct_access'] = true;
/* GAMES */
foreach ($access['competitions'][$competition_id]['seasons'][$season_obj->data('id')]['rounds'][$id]['games'] as &$game) {
$game['child_access'] = true;
unset($game);
}
}
/* CHECK GAMES */
$games = $this->db->select('game_id')->from('user_game')->where('user_id', $user_id)->get();
foreach ($games->result() as $id) {
$id = $id->game_id;
$game_obj = $this->games->disabled(true)->get($id);
$round_obj = $game_obj->round();
$season_obj = $round_obj->season();
$competition_id = $season_obj->data('competition id');
$access['competitions'][$competition_id]['parent_access'] = true;
$access['competitions'][$competition_id]['seasons'][$season_obj->data('id')]['parent_access'] = true;
$access['competitions'][$competition_id]['seasons'][$season_obj->data('id')]['rounds'][$round_obj->data('id')]['parent_access'] = true;
$access['competitions'][$competition_id]['seasons'][$season_obj->data('id')]['rounds'][$round_obj->data('id')]['games'][$id]['direct_access'] = true;
}
if ($action == 'trim') {
foreach ($access['competitions'] as $k => &$competition) {
if ($competition['child_access'] === false &&
$competition['direct_access'] === false &&
$competition['parent_access'] === false
) {
unset($access['competitions'][$k]);
continue;
}
foreach ($competition['seasons'] as $k1 => &$season) {
if ($season['child_access'] === false &&
$season['direct_access'] === false &&
$season['parent_access'] === false
) {
unset($competition['seasons'][$k1]);
continue;
}
foreach ($season['rounds'] as $k2 => &$round) {
if ($round['child_access'] === false &&
$round['direct_access'] === false &&
$round['parent_access'] === false
) {
unset($season['rounds'][$k2]);
continue;
}
foreach ($round['games'] as $k3 => $game) {
if ($game['child_access'] === false &&
$game['direct_access'] === false &&
$game['parent_access'] === false
) {
unset($round['games'][$k3]);
continue;
}
}
}
}
}
}
dump($access);
}
You need to use an authorization language such as XACML to express who can access which particular data. Then, the tables you have become one source of "attributes".
With XACML you can express rules such as:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.