Рейтинг@Mail.ru
 

Шаг 9

Панель администрирования

Ну какая уважающая себя гостевая книга без модерации?
Снабдим её админкой. Тем более почти всё для этого уже готово.

Скопируем все что у нас есть в другой файл, назовем admin.php
Бытует мнение, что админки нужно маскировать экзотическими именами, но это дело на любителя. Если поставить нормальную защиту, то эта операция и не понадобится вовсе. Вот и сама защита
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php


///////////////////////////////////////////////////////////////// 
//                       SEQURYTI 
//                        ЗАЩИТА 
/////////////////////////////////////////////////////////////////
/**  
* Logins and passwords for an input in the administrator-panel  
* Логины и пароли для входа в админ-панель (может быть несколько)   
*/   
    
$admins = array(
                    
// логин   => пароль
                      
'root'   => 'root'
                      
'admin'  => 'admin',  
                    );

     
 
// Если переменная из окошка аутентификации пуста 
    
if(empty($_SERVER['PHP_AUTH_USER']))     
    {
       
// значит выдаем юзеру это окошко, что бы заполнил                
        
header ('WWW-Authenticate: Basic realm="Admin Page"');     
        
header ('HTTP/1.0 401 Unauthorized');     
        exit();     
    }   
 
// Устанавливаем ключ входа 
    
$key false
 
// Сверем данные аутентификации  с полученными от юзера      
    if(isset(
$admins[$_SERVER['PHP_AUTH_USER']]) &&  $_SERVER['PHP_AUTH_PW'] === $admins[$_SERVER['PHP_AUTH_USER']])    
        
$key true;// Если пара совпала, переустанавливаем ключ

 // Если ключ не переустановлен, значит ничего не совпало. 
    if(empty($key))      
    {              
        header ('WWW-Authenticate: Basic realm="Admin Page"');        
        
header ('HTTP/1.0 401 Unauthorized');      
        exit();      
    } 



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

Защита готова. Не смотря на кажущуюся простоту, это достаточно надежная защита. Теперь дополним её, чтобы получилась сама админка.

Так как мы считаем не этичным править чужой текст, не будем делать такую возможность, ограничимся удалением неугодных постов. Для этого выведем их, снабдив чекбоксами.
Метод POST дает возможность передавать данные массивом. Чтобы было понятнее, как это, сделаем небольшой тест:
1
2
3
4
5
6
7
8
9
10
11
12
<pre>
<?php
    print_r
($_POST);
?>
</pre>
<form action="" method="post">
<input type="checkbox" name="delete[]" value="1" /><br />
<input type="checkbox" name="delete[]" value="2" /><br />
<input type="checkbox" name="delete[]" value="3" /><br />
<input name="" type="submit" />
</form>


Это похоже на радиокнопку - у группы так же одно имя, а значения передаются в массив. Разница в том, что отмечать можно несколько чекбоксов одновременно.
1
2
3
4
5
6
7
8
9
10
11
Array
(
    [delete] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)

Воспользуемся этим и присвоим им уникальные номера, благо мы озаботились автоинкрементным идентификатором.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<?php



/**    
* The guest book  (the administration panel)  
* Гостевая книга  (панель администрирования)  
* @author IT studio IRBIS-team    
* @copyright © 2009 IRBIS-team    
*/    
/////////////////////////////////////////////////////////    
/**    
* We establish the charset and level of errors    
* Устанавливаем кодировку и уровень ошибок    
*/    
    
header("Content-Type: text/html; charset=utf-8");    
    
error_reporting(E_ALL);  
       
/////////////////////////////////////////////////////////////  
//                        ADJUSTMENT  
//                        НАСТРОЙКИ  
/////////////////////////////////////////////////////////////   
/**      
* Quantity of posts on page   
* Количество постов на странице    
*/  
   
define('NUM_POSTS'3);  
     
/**   
* Logins and passwords for an input in the administrator-panel   
* Логины и пароли для входа в админ-панель   
*/    
    
$admins = array(   
                      
'root'   => 'root',  
                      
'admin'  => 'admin',   
                    );     
     
     
/////////////////////////////////////////////////////////////////   
//                       SEQURYTI   
//                        ЗАЩИТА   
/////////////////////////////////////////////////////////////////       

    
if(empty($_SERVER['PHP_AUTH_USER']))       
    {       
        
header ('WWW-Authenticate: Basic realm="Admin Page"');       
        
header ('HTTP/1.0 401 Unauthorized');       
        exit();       
    }     

    
$key false;   
    
    if(isset(
$admins[$_SERVER['PHP_AUTH_USER']]) &&  $_SERVER['PHP_AUTH_PW'] === $admins[$_SERVER['PHP_AUTH_USER']])    
        
$key true;
    

   if(!
$key)       
       exit(
'Нету раздавать.');     
     
           
     
/////////////////////////////////////////////////////////////  
//                       FUNCTIONS  
//                        ФУНКЦИИ  
/////////////////////////////////////////////////////////////      
/**      
* Function of reading of a directory     
* Функция чтения директории 
* @param string      
* @return array     
*/  
    
function dirScan($dir)  
    {   
        static 
$files;  
          
            if(empty(
$files))  
            {  
                
$files scandir($dir);  
                
$files array_diff($files, array('.''..'));  
            }  
   
        
$files count($files)?$files:array('1');  
                  
        return 
$files;  
    }  
      
/**      
* Function of generation of the menu of paginal navigation     
* Функция генерации меню постраничной навигации  
* @param string   
* @return string     
*/      
    
function pageMenu($page)   
    {       
        
$files dirScan('data');  
        
natsort($files);  

        
$menu ' | '
          
        foreach(
$files as $num)   
            if(
$page == $num)  
                
$menu .= '<strong>'$num  .'</strong> | ';  
            else  
                
$menu .= '<a href="?page='$num .'">'$num .'</a> | ';       

        return 
$menu;   
    }     
   
/**      
* Replacement function bb-tags and smilies      
* Функция замены bb-тегов и смайликов   
* @param string   
* @return string     
*/  
    
function bbTags($text)  
    {     
        
$bb = array( 
                    
'[B]',  
                    
'[/B]',  
                    
'[I]',  
                    
'[/I]',  
                    
'[S]',  
                    
'[/S]',  
                    
'[U]',  
                    
'[/U]',  
                    
'[:)]',  
                    
'[:(]',  
                    
'[;)]',  
                    
'[:D]'  
                   
);   

        
$tag = array( 
                     
'<b>',  
                     
'</b>',  
                     
'<i>',  
                     
'</i>',  
                     
'<s>',  
                     
'</s>',  
                     
'<u>',  
                     
'</u>',   
                     
'<img src="smiles/1.gif" />',  
                     
'<img src="smiles/2.gif" />',   
                     
'<img src="smiles/3.gif" />',  
                     
'<img src="smiles/4.gif" />'  
                
);  
                  
        return 
str_ireplace($bb$tag$text);              
    }  
      
          
/////////////////////////////////////////////////////////////////  
//                        VARIABLES  
//                        ПЕРЕМЕННЫЕ  
/////////////////////////////////////////////////////////////////  
      
    
$page   = !empty($_GET['page']) ? $_GET['page'] : 1;       
    
$delete = !empty($_POST['delete']) ? $_POST['delete'] : array();     
    
$posts  = array();  

        
/////////////////////////////////////////////////////////////////  
//                        SCRIPT  
//                        СКРИПТ  
/////////////////////////////////////////////////////////////////  
      
    
if(!empty($_POST['ok']))    
    {    
               
        if(
count($delete) > 0)    
        {    
            
$posts unserialize(file_get_contents('data/'$page));   
                          
            for(
$i 0$i count($delete); ++$i)  
            {   
                
$posts[$delete[$i]]['name'] = '';  
                
$posts[$delete[$i]]['mess'] = 'Удалено модератором';                  
            }   
               
            
file_put_contents('data/'$pageserialize($posts));    

            
header('location: http://'$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);    
            exit();    
        }    
    }    
    else    
        
$info[] = 'Напишите что нибудь';   
           
/////////////////////////////////////////////////////////////////  
//                        VIEW  
//                    ОТОБРАЖЕНИЕ  
/////////////////////////////////////////////////////////////////  

?>    
<form action="" method="post">      
<div style="padding-left:50px">  
<?php echo pageMenu($page); ?>  
</div>  
<?php  

    
if(file_exists('data/'$page))  
    {      
          
        
$posts unserialize(file_get_contents('data/'$page));  

        foreach(
$posts as $id => $post)  
        {  
            
$date $post['date'];          
            
$name htmlspecialchars($post['name']);  
            
$mess nl2br(bbTags(htmlspecialchars($post['mess'])));                  
?>          
<div style="border:1px solid; width:70%; background-color:#66FFFF; min-height:100px; margin:5px; padding:5px">

<!-- Присвоим уникальные значения чекбоксам -->
  
<input type="checkbox" name="delete[]" value="<?php echo $id?>" />          
<?php echo $date?> / <strong><?php echo $name?></strong>  
<hr width="30%" align="left" />  
<?php echo $mess?>  
</div>  
<?php  
         
}   
    }  
?>  
<div style="padding-left:50px">  
<?php echo pageMenu($page); ?>  
</div>  

<input name="ok" type="submit" value="Удалить" onclick="return confirm('Подумай!')"/>    
</form>


Ну а дальше все просто как три копейки. В цикле пробегаемся по массиву постов, и меняем неугодные сообщения на грозную оплеуху модератора.
Немного подробнее с этого места. Если сейчас заглянуть внутрь массива, который находится в файле,
1
2
3
4
5
6
7
<pre>
<?php
    $posts 
unserialize(file_get_contents('1')); 
    
print_r($posts);
?>
</pre>

можно увидеть такую картину Репина:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Array
(
    [1] => Array
        (
            [date] => 22-04-2010
            [name] => twin
            [mess] => Как то так [;)]
        )

    [2] => Array
        (
            [date] => 22-04-2010
            [name] => user
            [mess] => Да ну?
        )
)

Соответственно, чтобы добраться до нужного элемента, нам нужно построить такую конструкцию:
1
2
3
4
5
6
7
<?php


    $posts 
unserialize(file_get_contents('1')); 

    echo 
$posts[1]['mess'];
где 1 - номер поста. А он у нас находится в value чекбокса, а значит в переменной $delete.

И теперь, если совместить первое со вторым, то получится такое изобретение:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

/////////////////////////////////////////////////////////////////  
//                        SCRIPT  
//                        СКРИПТ  
/////////////////////////////////////////////////////////////////  
      
    
if(!empty($_POST['ok']))    
    {    
               
        if(
count($delete) > 0)    
        {    
            
$posts unserialize(file_get_contents('data/'$page));   
             
// Проходим циклом по массиву постов             
            
for($i 0$i count($delete); ++$i)  
            {   
                
// Когда номер поста совпадет со значением отмеченного чекбокса,
                // заменяем его внутренности
                
$posts[$delete[$i]]['name'] = '';  
                
$posts[$delete[$i]]['mess'] = 'Удалено модератором';                  
            }   
               
            
file_put_contents('data/'$pageserialize($posts));    

            
header('location: http://'$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);    
            exit();    
        }    
    }    
    else    
        
$info[] = 'Напишите что нибудь'
При желании можно и совсем удалить совпавший элемент, но мы будем надеяться, что много не нагадят. А то нарушится порядок следования.

Всё. Теперь нужно набрать в открывшемся окне логин - пароль, который предварительно указать в настройках и смело бороться с флудерами и матершинниками.