1

背景:

Agameは aに属しround
Aは a にround属しseason
Aは a にseason属し、competition
Acompetitionは所有されていません。

8つのテーブルがあります

名前 => 列

`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`

したがって、最初の 4 つのテーブルはさまざまなパーツをリンクし
、次の 4 つのテーブルはユーザーをそれぞれのパーツにリンクします。

いくつかのダミー データです。読みやすいように 2 番目の ID が変更されたときにテーブルを分割したことに注意してください。

最初の 4 つのテーブル

/--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             |      \---------------------/
\---------------------/ 

次の 4 つの表は、以下のリストで最もよく説明されています

ユーザー:

  • ユーザー 1
    • ゲーム 1 のみにリンク:
      user_game (user_id:1, game_id:1)
    • directゲーム 1にアクセスできます
    • parentラウンド1にアクセスできます
    • parentシーズン 1にアクセスできます
    • parentコンペティション 1にアクセスできます
  • ユーザー 2
    • ラウンド 1 のみにリンク:
      user_round (user_id:2, round_id:1)
    • childゲーム 1、2にアクセスできます
    • directラウンド1にアクセスできます
    • parentシーズン 1にアクセスできます
    • parentコンペティション 1にアクセスできます
  • ユーザー 3
    • ラウンド 1 にリンク:
      user_round (user_id:3, round_id:1)
    • ユーザー 2のすべてのアクセス権を持つ
    • ゲーム 2 にリンク:
      `user_game (user_id:3, game_id:2)。
    • directゲーム 2にアクセスできます
    • ゲーム13にもリンクされています:
      user_game (user_id:3, game_id:13)
    • directゲーム 13にアクセスできます
    • parentラウンド7でアクセス可能
    • parentシーズン3にアクセスできます
    • parentコンペティション 2にアクセスできます

したがって、上記の 3 人のユーザーのアクセス権を取得するときは、これら 3 つの配列で終了したいと考えています。次の点に注意してください
parent_access。direct : ユーザーは、親オブジェクト (オブジェクトに関係なく) に直接アクセス権が付与されているため、フル アクセス権を持っています
direct_access
child access

ユーザー 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
        ),
    )
);

ユーザー 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
        ),
    )
);

ユーザー 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
        )
    )
);
4

2 に答える 2

0

XACMLなどの承認言語を使用して、誰がどの特定のデータにアクセスできるかを表現する必要があります。次に、あなたが「属性」の1つのソースになったテーブル。

XACMLを使用すると、次のようなルールを表現できます。

  • そのユーザーがそのゲームに参加している場合、そのユーザーはゲームを見ることができます
  • そのユーザーがゲームが属するラウンドを表示できる場合、そのユーザーはゲームを表示できます(親子関係)...
于 2013-01-30T15:24:08.657 に答える
0

結果は少し異なりますが、これは私の現在の作業を示すためにここに投稿されており、満足していませんが、それでも答えとして機能します.

したがって、ここに私の現在のコードがあります: 次のような行:$competitions = $this->competitions->disabled(true)->getAll();競合テーブルでクエリを実行し、カスタム オブジェクトを返すため、そこでは少し異なりますが、コードで何をするかを理解できるはずです。

ここで気に入らないのは、18 個の foreach ループがあることです。多くがネストされているため、18 回の foreach ループが再実行されます。誰でもこれを減らす方法を見ることができますか?

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);
}
于 2013-01-30T12:36:44.230 に答える