Гостевая книга


В этом разделе будет показан простейший пример разработки гостевой книги с использованием ABC-framework.

Первым этапом нужно установить фреймворк и наметить структуру приложения. В директории App/ обозначим классы контроллера, модели и отображения для гостевой книги.

App\Controllers\GuestController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 

namespace ABC\App\Controllers;

use 
ABC\Abc\Core\Base;

/** 
 * Контроллер
 * 
 */   
class GuestController extends Base

    public function 
actionIndex()
    {

    }  
}



App\Models\GuestModel.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 

namespace ABC\App\Models;

use 
ABC\Abc;

/** 
 * Модель
 * 
 */   
class GuestModel
{
    public function 
getTapeContent()
    {

    }
}




App\Views\GuestView.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 

namespace ABC\App\Views;

use 
ABC\Abc\Core\Base;

/** 
 * Вид
 * 
 */ 
class GuestView extends Base
{
    public function 
createTape()
    {  

    }
}




Еще потребуются два шаблона. Главный (макет), где разместим ссылку на гостевую книгу:

www\theme\tpl\index.tpl
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
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="/theme/css/style.css" type="text/css" />
<title>ABC-framework</title>
</head>
<body>
<div style="text-align:center">
<img src="/theme/img/logo.png" />
</div>
<div class="wrapper">
<div class="sidebar">
<a href="/">Главная</a><br />
<a href="{createUrl('/guest')}">Гостевая книга</a>
</div>
<div class="content">
<!--// content -->
<!--// content end -->
</div>
<div class="clear"></div>
</div>
</body>
</html>



И сам шаблон гостевой книги:

www\theme\tpl\guest.tpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
<div class="guest">
<!--// guest_row -->
<div class="guest_row">
{$date}<br />
{$author}<br />
{$text}<br />
<br />
</div>
<!--// guest_row end -->
<!--// no_posts -->
<h2>Комментариев нет</h2>
<!--// no_posts end -->
</div>




Для красоты можно добавить немного стилей:

www\theme\css\style.css
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
 
.wrapper {
padding:10px;
}
 
.sidebar {
padding-left:50px;
float:left;
}
 
.content {
padding-left:50px;
float:left;
}
 
.guest {
padding:10px;
border:1px dotted;
}
 
.guest .guest_row {
border:1px solid;
margin:3px;
padding:5px;
width:800px;
}
 
.guest .paginator {
text-align:center;
padding:10px;
}
 
.guest .paginator span {
margin:1px;
background-color: #CCFFFF;
padding:3px 6px 3px 6px;
border:1px #0000FF dotted;
}
 
.guest .paginator .active {
background-color: #95E4FF;
color:red;
font-weight:bold;
}
 
.clear {
clear:both;
}




Также потребуется база данных abc_example и в ней такая таблица:
1
2
3
4
5
6
7
8
9

CREATE TABLE IF NOT EXISTS `abc_guest` (
`id` int( 5 ) NOT NULL AUTO_INCREMENT ,
`author` varchar( 20 ) NOT NULL ,
`date` datetime NOT NULL ,
`text` text NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET = utf8 AUTO_INCREMENT =1;



На этом подготовительные работы можно считать законченными.

Теперь конкретика. Сначала в контроллере нужно вызвать слой отображения:

App\Controllers\GuestController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 

namespace ABC\App\Controllers;

use 
ABC\Abc\Core\Base;

/** 
 * Контроллер
 * 
 */   
class GuestController extends Base

    public function 
actionIndex()
    {
        
$this->view->createTape();
    }  
}




Реализация логики отображения (используется встроенный шаблонизатор):

App\Views\GuestView.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
<?php 

namespace ABC\App\Views;

use 
ABC\Abc\Core\Base;

/** 
 * Вид
 * 
 */ 
class GuestView extends Base
{
    public function 
createTape()
    {  
        
$this->selectTpl('guest');
        
$tape $this->model->getTapeContent();
        
        if (!empty(
$tape)) {

            foreach (
$tape as $post) {
                
$this->tpl->assignHtml($post);
                
$this->tpl->setBlock('guest_row');
            }

        } else {
            
$this->tpl->setBlock('no_posts');
        }
        
        
$this->tpl->extendsTpl('content');  
        
$this->render(); 
    }
}




На данном этапе приложение можно запустить. Результатом должна быть надпись «Комментариев нет».

Для того чтобы они появились, нужно сделать две вещи.

1. Добавить записи в таблицу базы данных.
2. Реализовать модель гостевой книги.

Записи можно добавить следующим запросом:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
INSERT INTO `abc_guest` ( `id` , `author` , `date` , `text` )
VALUES (
NULL , 'author1', '2016-01-01 00:00:00',
'съешь же ещё этих мягких французских булок, да выпей чаю
съешь же ещё этих мягких французских булок, да выпей чаю
съешь же ещё этих мягких французских булок, да выпей чаю
съешь же ещё этих мягких французских булок, да выпей чаю'
),(
NULL , 'author2', '2016-01-01 00:00:00', 'У попа была собака, он её любил,
Она съела кусок мяса, он её убил,
В землю закопал,
Надпись написал:

"У попа была собака, он её любил,
Она съела кусок мяса, он её убил,
В землю закопал,
Надпись написал:

"У попа была собака, он её любил,
Она съела кусок мяса, он её убил,
В землю закопал,
Надпись написал:'
)




Этот запрос желательно повторить несколько раз, чтобы было побольше записей.

И теперь набросок модели:

App\Models\GuestModel.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php 

namespace ABC\App\Models;

use 
ABC\Abc;

/** 
 * Модель
 * 
 */   
class GuestModel
{
    public function 
getTapeContent()
    {
        
$pdo Abc::sharedService('Pdo');
        
        
$sql "SELECT * FROM `"$pdo->prefix ."guest`
                ORDER BY `id` ASC"
;
                
        return 
$pdo->query($sql)->fetchAll();  
    }
}




А для того чтобы активировать сервис PDO, нужно прописать секцию конфигурации:

www\configs\local.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php     

    
return [  
                
'debug' => [   
                                
'bugsnare'         => true,  
                                
'language'         => 'Ru',  
                ], 
                  
                
'pdo' => ['dsn'    => 'mysql:dbname=abc_example;host=localhost'
                          
'opt'    => [], 
                          
'user'   => 'root',  
                          
'pass'   => '',  
                          
'prefix' => 'abc_',  
                          
'debug'  =>  true// Режим дебаггинга  
                
], 
    ];  




Скелет гостевой книги готов, информация выведена в браузер. Теперь нужно немного привести это в подобающий вид. И снабдить постраничной навигацией.

Сейчас весь текст отображается в одну строку. Можно, конечно же, воспользоваться функцией nl2br(), однако фреймворк позволяет сделать это более эффективно. Заодно снабдим скрипт возможностью использовать BB-теги. Сделать это можно, воспользовавшись сервисом BB.

App\Views\GuestView.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
38
39
<?php 

namespace ABC\App\Views;

use 
ABC\Abc;
use 
ABC\Abc\Core\Base;

/** 
 * Вид
 * 
 */ 
class GuestView extends Base
{
    public function 
createTape()
    {  
        
$this->selectTpl('guest');
        
$tape $this->model->getTapeContent();
        
        if (!empty(
$tape)) {
         
            
$bb Abc::newService('BB');        
         
            foreach (
$tape as $post) {
                
$this->tpl->assign('date'$post['date']);
                
$this->tpl->assignHtml('author'$post['author']);
                
$text $bb->convert($post['text']);
                
$this->tpl->assign('text'$text);
                
$this->tpl->setBlock('guest_row');
            }
            
        } else {
            
$this->tpl->setBlock('no_posts');
        }
        
        
$this->tpl->extendsTpl('content');  
        
$this->render(); 
    }
}




Проверить работу конвертора можно следующим запросом:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
INSERT INTO `abc_guest` (
`id` ,
`author` ,
`date` ,
`text`
)
VALUES (
NULL ,
'test',
'2016-01-01',
'[b]Жирный[/b]
[color=red]Красный[/color=red]
[size=4]Большой[/size=4]
[:)]'
);





Следующим этапом снабдим гостевую книгу постраничной навигацией.
Сделать это можно с помощью сервиса "Paginator"

App\models\GuestModel.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
38
<?php   

namespace ABC\App\Models;

use 
ABC\Abc;

/** 
 * Модель
 * 
 */   
class GuestModel
{
    public function 
getTapeContent()
    {
        
$num iniGET('num');  
        
$amount 5;     
     
        
$pdo Abc::sharedService('Pdo');  
     
        
$cnt $pdo->query("SELECT COUNT(`id`) AS `cnt`  
                            FROM `"
$pdo->prefix ."guest`"  
                          
)->fetchColumn();
     
        
$pgn Abc::newService('Paginator');  
        
$pgn->setNums($num$amount);       
        
$limit  $pgn->getLimit();  
        
$offset $pgn->getOffset($cnt); 
        
$menu   $pgn->createMenu();        
     
        
$tape $pdo->query("SELECT * FROM `"$pdo->prefix ."guest`  
                             ORDER BY `id` ASC   
                            LIMIT "
$limit " OFFSET "$offset 
                      
)->fetchAll();  
     
        return [
'tape' => $tape'menu' => $menu];  
    }
}




Теперь модель возвращает массив, в котором есть результат лимитированного запроса и меню постраничной навигации. А значит нужно немного переделать логику отображения:

App\Views\GuestView.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
38
39
40
41
42
<?php 

namespace ABC\App\Views;

use 
ABC\Abc;
use 
ABC\Abc\Core\Base;

/** 
 * Вид
 * 
 */ 
class GuestView extends Base
{
    public function 
createTape()
    {  
        
$this->selectTpl('guest');
        
$result $this->model->getTapeContent();
        
        if (!empty(
$result['tape'])) {
         
            
$bb Abc::newService('BB');        
         
            foreach (
$result['tape'] as $post) {
                
$this->tpl->assign('date'$post['date']);
                
$this->tpl->assignHtml('author'$post['author']);
                
$text $bb->convert($post['text']);
                
$this->tpl->assign('text'$text);
                
$this->tpl->setBlock('guest_row');
            }
            
            
$this->tpl->assign('pag_menu'$result['menu']);
            
$this->tpl->setBlock('pag_menu');    
            
        } else {
            
$this->tpl->setBlock('no_posts');
        }
        
        
$this->tpl->extendsTpl('content');  
        
$this->render(); 
    }
}




И, соответственно, шаблон гостевой книги:

www\theme\tpl\guest.tpl
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
 
<div class="guest">
<!--// pag_menu -->
<div class="paginator">
{$pag_menu}
</div>
<!--// pag_menu end -->
<!--// guest_row -->
<div class="guest_row">
{$date}<br />
<strong>{$author}</strong><br />
{$text}<br />
<br />
</div>
<!--// guest_row end -->
<!--// no_posts -->
<h2>Комментариев нет</h2>
<!--// no_posts end -->
<!--// pag_menu -->
<div class="paginator">
{$pag_menu}
</div>
<!--// pag_menu end -->
</div>



Ну и последний штрих. Количество постов на странице у нас регулируется в модели. А по-хорошему должно в конфигурационном файле. Добавим туда настройку:

www\configs\local.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php     

    
return [  
                
'debug' => [   
                                
'bugsnare'         => true,  
                                
'language'         => 'Ru',  
                ], 
                  
                
'guest_book' => [  
                                   
'amount' => 10// Количество сообщений на странице 
                
],      
                  
                
'pdo' => ['dsn'    => 'mysql:dbname=abc_example;host=localhost'
                          
'opt'    => [], 
                          
'user'   => 'root',  
                          
'pass'   => '',  
                          
'prefix' => 'abc_',  
                          
'debug'  =>  true,   
                ], 
    ]; 




А в модели исправим 16-ю строку:

App\models\GuestModel.php
14
15
16
17
18


        $amount 
Abc::getConfig('guest_book')['amount']; // Теперь из конфиги  




Ну вот и всё, гостевая книга в части отображения готова.