Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Ключ
 
 автор: Лена   (23.09.2009 в 22:12)   письмо автору
1.1 Кб
 
 

В базе - четыре таблицы - модули, разрешения, группы пользователей и операции, которые следует реализовать над модулями. Все операции одинаковые. Структуру таблиц прикрепила.
На странице все это будет выглядеть вот так:
_________________________________________
Модуль1 |public | auth | admin
view | | |
edit | V
delete |
_________________________________________
Модуль2 | | |
view |
edit |
delete |
_________________________________________

Например, модуль1 можно редактировать только админу(я поставила там галочку - на самом деле там будет чекбокс).
Вопрос 1. В таблице permission какой лучше ключ сделать? в смысле, какое поле?
Вопрос 2. Что передавать в value чекбокса ,чтобы узнать, что чекбокс отмечен?

  Ответить  
 
 автор: Trianon   (23.09.2009 в 22:14)   письмо автору
 
   для: Лена   (23.09.2009 в 22:12)
 

CREATE TABLE `groups` (
  `id_group` int(11) NOT NULL auto_increment,
  `type_group` tinytext NOT NULL,
  `descr` text,
  PRIMARY KEY  (`id_group`)
) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=utf8 
  PACK_KEYS=0 
  COMMENT='таблица определяет группы польз?' 
  AUTO_INCREMENT=25 ;

CREATE TABLE `modules` (
  `mod_id` int(32) NOT NULL auto_increment,
  `mod_pid` tinyint(4) default '0',
  `block_id` int(11) default '0',
  `mod_name` mediumtext,
  `mod_path` varchar(255) default NULL,
  `descr` mediumtext,
  `visib` tinyint(5) NOT NULL default '0',
  `show_sitemap` enum('yes','no') NOT NULL default 'yes',
  PRIMARY KEY  (`mod_id`),
  FULLTEXT KEY `mod_name` (`mod_name`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 PACK_KEYS=0 AUTO_INCREMENT=4 ;

CREATE TABLE `operations` (
  `op_id` int(11) NOT NULL,
  `op_name` text NOT NULL,
  PRIMARY KEY  (`op_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `permission` (
  `id_group` int(11) default NULL,
  `mod_id` int(11) default NULL,
  `op_id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

  Ответить  
 
 автор: Trianon   (23.09.2009 в 22:19)   письмо автору
 
   для: Trianon   (23.09.2009 в 22:14)
 

1. Составной. Возможно, не один.
2. Важнее, какое name. Тоже составное. К примеру, name="act[$mod-$grp-$op]"
А можно name="act[$mod-$grp][]" value=$op попробовать. Хотя не уверен, что с ним будет проще.

  Ответить  
 
 автор: Лена   (24.09.2009 в 22:19)   письмо автору
 
   для: Trianon   (23.09.2009 в 22:19)
 

Ключ сделала таким - PRIMARY KEY (`id_group`,`mod_id`,`op_id`)
Сейчас не получается обозначить отмеченный чекбокс. То, что пока не нужно, выбросила:
permission.php - обработчик формы

<?php
if(isset($_POST['Perm'])){
print 
'<pre>';
print_r($_POST['act']);
print 
'</pre>';
}

if(!isset(
$_POST['Perm'])){
include(
"permission_form.php");
}
?>


permission_form.php

<?php
//готовим переменные для шаблона $groups,$mod,$op(это выбросила)

$q "SELECT * FROM permission";
    
$result mysql_query($q);
    if(!
$result) exit("Error in $q: "mysql_error());

while(
$row mysql_fetch_assoc($result)){
$all $row['id_group'] . "-" $row['mod_id'] . "-" $row['op_id'];
    foreach(
$_POST['act'] as $key=>$value){
        if(
$key == $all){
        
$check 'checked';
        }else{
        
$check ''; }
    }
}
//отправляем переменные в шаблон
$smarty->assign('checked',$check);
$nbsp str_repeat("&nbsp;"20);
$smarty->assign('nbsp',$nbsp);

$smarty->assign('groups',$groups);
$smarty->assign('mod',$mod);
$smarty->assign('op',$op);
$smarty->display('permission.tpl');
?>


шаблон - 'permission.tpl'

<table width=100% border='1px'>
<tr>
    <td>№</td>
    <td>Название модуля</td>
    {* названия групп пользователей *}
    {foreach from = $groups item = gr}
        <td>{$gr.type_group}</td>
    {/foreach}
</tr>
<form action='permission.php' method='post'>
{* названия модулей *}
{foreach from=$mod item=one key=keys}
<tr>
    <td>{$keys}</td>
    <td colspan = 4>{$one.mod_name}</td>
</tr>
    {* название операций *}
    {foreach from=$op item=p}
<tr>
<td></td>
<td>{$nbsp}{$p.op_name}</td>
        {* группы *}
           {foreach from = $groups item = gr}
            {*название чекбокса - группа+модуль+операция *}
    <td><input type="checkbox" name="act[{$gr.id_group}-{$one.mod_id}-{$p.op_id}]"                     

value="1" {$checked}></td>
        {/foreach}
</tr>
    {/foreach}
{/foreach}
<tr>
    <td colspan=5><input type='submit' value='Установить разрешения' name = 'Perm'></td>
</tr>
</form>
</table>

Не пойму, почему отмеченные чекбоксы после нажатия кнопки становятся неотмеченными.

  Ответить  
 
 автор: Trianon   (24.09.2009 в 22:24)   письмо автору
 
   для: Лена   (24.09.2009 в 22:19)
 

//отправляем переменные в шаблон

Вот на этом месте можно сделать var_dump($check); и всё станет ясно.

  Ответить  
 
 автор: Лена   (25.09.2009 в 13:29)   письмо автору
 
   для: Trianon   (24.09.2009 в 22:24)
 

Не выходит.
обработчик(кусок, что поменяла):

<?php
$sql 
"SELECT g.type_group gt, g.id_group gi, m.mod_name mn, m.mod_id mi, o.op_name opn, o.op_id oi, (l.op_id IS 

NOT NULL) chk
FROM (
modules m
JOIN groups g
JOIN operations o)
LEFT JOIN permission l ON l.mod_id = m.mod_id
AND l.id_group = g.id_group
AND l.op_id = o.op_id
LIMIT 0 , 30"
;
$result mysql_query($sql);
if(!
$result) exit("Error in $sql: "mysql_error());
for(
$i=0;$row mysql_fetch_assoc($result);$i++){
    if(
$i!=$row['mi']){
    
$i =$row['mi'];
    
$mod[$i] = $row['mn'];
    }
    if(
$i!=$row['gi']){
    
$i =$row['gi'];
    
$groups[$i] = $row['gt'];
    }
    if(
$i!=$row['oi']){
    
$i =$row['oi'];
    
$op[$i] = $row['opn'];
    }

foreach(
$_POST['cat'] as $cat){
if(
$cat == && $cat == $row['chk'][$i]) $checked 'cheked';
else  
$checked '';
}

}
?>


Шаблон:

<table width=100% border='1px'>
<tr>
    <td>№</td>
    <td>Название модуля</td>
    {* названия групп пользователей *}
    {foreach from = $groups item = gr}
        <td>{$gr}</td>
    {/foreach}
</tr>
<form action='permission.php' method='post'>
{* названия модулей *}
{foreach from=$mod item=one key=keys}
<tr>
    <td>{$keys}</td>
    <td colspan = 4>{$one}</td>
</tr>
    {* название операций *}
    {foreach from=$op item=p key = opk}
<tr>
<td></td>
<td>{$nbsp}{$p}</td>
        {* группы *}
           {foreach from = $groups item = gr key = grkey}
            {*название чекбокса - группа+модуль+операция *}
    <td><input type="checkbox" name="act[{$grkey}-{$keys}-{$opk}]"                     value="1" {$checked}></td>
        {/foreach}
</tr>
    {/foreach}
{/foreach}
<tr>
    <td colspan=5><input type='submit' value='Установить разрешения' name = 'Perm'></td>
</tr>
</form>
</table>



var_dump($checked); дает NULL

  Ответить  
 
 автор: Trianon   (25.09.2009 в 16:36)   письмо автору
 
   для: Лена   (25.09.2009 в 13:29)
 

если Вы хотите структурировать элементы в порядок
модули(операции(группы(элементы)))
то нужно соответствующим образом
а) задать сортировку в запросе, которая бы сгруппировала (не в смысле gropup by , а в смысле - разместила бы рядом) строки согласно структуре.
б) определить php-код, который результат этого запрос расхлебает.


Первый, очевидно, будет ORDER BY модуль, группа, операция
Что до второго, то тут надо определиться, в массиве какого вида смарти ожидает данные.

  Ответить  
 
 автор: Лена   (25.09.2009 в 22:22)   письмо автору
 
   для: Trianon   (25.09.2009 в 16:36)
 

Сделала, ошибки поняла, осталось обработчик формы сделать.
Я так понимаю, если чекбокс отмечен - в таблицу связки permission вставляем строку, если убрали чекбокс - удалили строку.
Вот что получилось:

<?php
//запрос к базе уже был выше
//вывод результата запроса
while($row mysql_fetch_assoc($result)){
$mod $row['mn'];
$gt $row['gt'];
$opn $row['opn'];
$arr[$mod][$gt][$opn] = $row['chk'];
}


$nbsp str_repeat("&nbsp;"20);
$smarty->assign('nbsp',$nbsp);
$smarty->assign('arr',$arr);
$smarty->display('permission.tpl');
?>

шаблон:

<table width=100% border='1px'>
{foreach from = $arr item = ar key = keys first = true name = mod}
{*  шапка таблицы - только для первого цикла*}
{if $smarty.foreach.mod.first}
<tr>
    <td>№</td>
    <td>Название модуля</td>
    {* названия групп пользователей *}

{foreach from = $ar item = gr key = kgr}    
<td>{$kgr}</td>
    {/foreach}
</tr>
{/if}

<form action='permission.php' method='post'>
{* названия модулей *}
<tr>
    <td>{$number}</td>
    <td colspan = 4>{$keys}</td>
</tr>
    {* название операций *}
    {foreach from= $gr item=op key = opk}
<tr>
<td></td>
<td>{$nbsp}{$opk}</td>
        {* название группы *}
           {foreach from = $ar item = gr key = kgr}
            {*чекбокс*}
    <td><input type="checkbox" name="act[{$keys}-{$kgr}-{$opk}]" value="1" {if $op == 1}checked{/if}></td>
        {/foreach}
</tr>
    {/foreach}

{/foreach}
<tr>
    <td colspan=5><input type='submit' value='Установить разрешения' name = 'Perm'></td>
</tr>
</form>
</table>

  Ответить  
 
 автор: Trianon   (26.09.2009 в 12:40)   письмо автору
 
   для: Лена   (25.09.2009 в 22:22)
 

>осталось обработчик формы сделать.
... который обходился бы возможно меньшим числом запросов...

Тоже задачка не самая примитивная.

  Ответить  
 
 автор: Лена   (27.09.2009 в 14:04)   письмо автору
 
   для: Trianon   (26.09.2009 в 12:40)
 

Cделала две страницы - на одной модули+доступ к ним разных групп. На другой - операции с модулями, предполагается, что доступ к этой странице только у админов и т.д.
Изменила массив, в результате получился такой -
$arr[$mod][$id_mod][$gt][$id_gt] = $c[$i];
модуль-id модуля-группа-id группы = столбец, который показывает, выбран ли чекбокс.
В шаблоне чекбоксы выглядят так:
<td><input type="checkbox" name="act[{$kgr}-{$kgrmr}]" value="1" {if $grmr == 1}checked{/if}></td>
в названии - id модуля+id группы и здесь $grmr это $c[$i]
Все в одном массиве, все раскладывается, только циклов много.
В обрабочике, когда приходят post-параметры(после защиты от иньекции):

<?php
//очистить таблицу
$sql2 "TRUNCATE TABLE permission"
$result2 mysql_query($sql2);
    if(!
$result2) exit("Error in $sql2: "mysql_error());

foreach(
$_POST['act'] as $k=>$v){
$chunk explode("-",$k);
//присвоить значения выбранных чекбоксов
$q "INSERT INTO permission(id_group,mod_id) VALUES('$chunk[1]','$chunk[0]')";
$res2 mysql_query($q);
    if(!
$res2) exit("Error in $q: "mysql_error());

}
?>


Спасибо.

  Ответить  
 
 автор: Trianon   (27.09.2009 в 16:21)   письмо автору
 
   для: Лена   (27.09.2009 в 14:04)
 

Дорого и сердито.

сердито стирать всю таблицу... а если кто-то обратится между запросами?
дорого заносить элементы по одной строке на запрос.

Может есть смысл переделать таблицу, добавив поле активен/неактивен? Ну и суррогатный ключ докучи...

  Ответить  
 
 автор: Лена   (27.09.2009 в 18:25)   письмо автору
 
   для: Trianon   (27.09.2009 в 16:21)
 

То есть, вы предлагаете такую структуру?

CREATE TABLE `permission` (
  `id_group` int(11) NOT NULL default '0',
  `mod_id` int(11) NOT NULL default '0',
  `my_check` int(11) NOT NULL,
  `choos` int(11) NOT NULL auto_increment,
  PRIMARY KEY  (`choos`),
  UNIQUE KEY `id_group` (`id_group`,`mod_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

суррогатный ключ здесь choos, поле для отмеченного чекбокса - my_check. Тогда в названии чекбокса надо передавать значение суррогатного ключа.

  Ответить  
 
 автор: Trianon   (27.09.2009 в 19:13)   письмо автору
 
   для: Лена   (27.09.2009 в 18:25)
 

да , как-то так.
Запрос , формирующий чекбоксы , тоже несколько упрощается при этом. Поскольку отсутствие записей ловить не нужно.

пропустил момент, когда число связываемых факторов сократилось с трех до двух, но не суть важно.

  Ответить  
 
 автор: Лена   (29.09.2009 в 11:41)   письмо автору
 
   для: Trianon   (27.09.2009 в 19:13)
 

Пробовала вчера делать, чтобы ввести еще одно поле, которое покажет выбранный чекбокс, что-то с ним не получается, где-то я ошибку пропускаю, поэтому отказалась.
Решила пойти путем более простым.
Цикл в обработчике немного поменяла, чтобы использовать многострочный INSERT

<?php
foreach($_POST['act'] as $k=>$v){ 
$chunk explode("-",$k);
$id_group[]= "(" $chunk[1] . ',' .  $chunk[0] . ")";
}
$id implode(","$id_group);

//присвоить значения выбранных чекбоксов 
$q "INSERT INTO permission(id_group,mod_id) VALUES" $id
$res2 mysql_query($q); 
    if(!
$res2) exit("Error in $q: "mysql_error()); 
?>

А вот от TRUNCATE я уже никак избавиться не могу, потому как у меня два поля с id'ами - составной уникальный ключ, обновить до нуля я их не могу, вот и приходится все вырезать.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования