Gå til innhold

System for brukernivåer i PHP+MySQL


Anbefalte innlegg

Jeg skal lage et forholdsvis banalt "admin"-system i en nettside. Det er i prinsippet kun to nivåer, men problemet kommer utover siden en administrator kan ha flere lag med administratorer under seg igjen, og disse skal kun kunne se innhold fra sine brukere og under-administratorer i flere nivåer. For å illustrere litt, se:

 

Admin ID 1
 Bruker ID 2 -> eid av admin 1
 Bruker ID 3 -> eid av admin 1
 Admin ID 4 -> eid av admin 1
Bruker ID 5 -> eid av admin 4
Bruker ID 6 -> eid av admin 4
Admin ID 7 -> eid av admin 4
  Bruker ID 8 -> eid av admin 7
  Etc.

 

Det viktige her er:

 

Admin 1 skal kunne se alt fra alle bruker og admins.

Brukere skal KUN se sine egne records.

Underadmins skal kunne se alle records fra seg selv, og alle records fra alle brukere og admins under dem selv.

 

Godt mulig dette bare er et spørsmål om databasedesign, men for en sjelden gangs skyld klarer jeg bare ikke pakke hodet mitt rundt hvordan jeg skal løse dette.

 

Det jeg har prøvd hittil er helt banalt å bare opprette et felt i brukerdatabasen som heter "owned_by" og IDen til administratoren som opprettet brukeren. I spørringen sier jeg da:

 

For bruker:
SELECT * FROM db WHERE user_id='$user_id'
For admin:
SELECT * FROM db WHERE user_id='$user_id' AND owned_by='$user_id'

 

For "superbruker" (admin 1) har jeg bare hardkodet en spørring knyttet opp til user_id 1 som velger alt uten kriterier. Problemet med dette systemet, er at det bare virker ett nivå nedover for admins. Admin 4 vil da se ID 5, 6 og 7, mens brukeren med ID 8, eid av ID 7 ikke vil bli vist.

Endret av Feh
Lenke til kommentar
Videoannonse
Annonse

For å lage en trestruktur må du på hver bruker i databasen legge til hvem som eier "han".

Eksempel på struktur:

id, username, parent

 

der "parent" skal ha samme referanse som id til eieren.

1, Admin, 0

2, Mod1, 1

3, Mod2, 1

4, User1, 2

5, User2, 2

6, User3, 3

7, User4, 2

 

Jeg har brukt sqlite i mitt eksempel, slik at du bare kan unzippe filen. Dette er rekursiv kode og kan kjøre litt sent hvis det er snakk om store mengder data, men du kan legge til ubegrenset med nivå.

// Koble til sqlite filen med PDO
$db = 'sqlite:users.sqlite';
$dbh = new PDO($db);
$dbh->setAttribute( PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION);

 

// Sjekker om denne raden har en eier
function has_children($rows,$id) {
 foreach ($rows as $row) {
if ($row['parent'] == $id)
  return true;
 }
 return false;
}
// Henter alle felter som har $parent som eier.
// Antar at $rows kommer fra en database,
// med associative array.
/* array(
array('id'=>'1', 'username'=>'Admin', 'parent'=>'0')
array('id'=>'2', 'username'=>'Mod1', 'parent'=>'1')
//osv
);
*/
function build_menu($rows,$parent=0)
{
 $result = "";
 foreach ($rows as $row){
if ($row['parent'] == $parent){
  $result.= "{$row["username"]} <br>";
  if (has_children($rows,$row['id']))
	$result.= build_menu($rows,$row['id']);
}
 }
 return $result;
}

Til slutt spørringen:

$menu = $dbh->query("SELECT id, username, parent FROM users")->fetchAll(PDO::FETCH_ASSOC);

 

HTML

<form action="" method="get">
<select id="level" name="userid" onchange="this.form.submit()">
<option value="0" selected>Select User</option>
<?php
foreach($menu as $row)
{
 print("<option value=\"". $row["id"] ."\">". $row["username"] ."</option>\n");
}
?>
</select>
</form>
<div>
<?php
print("<b>Selected users ". $getId ." children</b><br>");
echo build_menu($menu, $getId);
?>
</div>

 

Legger ved en fil med kode og database som du kan kikke på.

test.zip

Endret av roysland84
  • Liker 1
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...