PHP. Баннерная система. Часть - 3

Создание Панели управления баннерной системой.

Ранее мы создали основной функционал, который возвращает банеры и позволяет управлять или.
Теперь мы реализуем простейшую панель управления.
Пароль будем хранить в коде, но в рабочей системе так не делайте.
Начнем сразу с кода и по ходу дела буду коментировать код.
создадим файл cp.php

<?php
//Панель управления банерами
//Запускаем сесссию для унификации пользователя
session_start();
//Создадим некий токен который будет ключом доступа, его можно
//генерировать 1 на сутки, но это все как плюшки
$key='sid123';

$access=$_SESSION['key'];

//Получим действие которое от нас требует пользователь
$action=$_POST['action'];
if($action==''){
    if($access==$key)$action='init';
    else
    $action='login';
}
//Если действи отсутствует и клю не соответствует то идем ан авторизацию
//Иначе пользователь залогинен и хочет перейти к постройке интерфейса панели управлени

$user='admin';
$pass='admin';
//НАстройки подключения к серверу
$cfg['host']    =    'localhost';    //сервер
$cfg['base']    =    'banners';        //база данных
$cfg['user']    =    'root';            //пользователь
$cfg['pass']    =    '';                //пароль
$cfg['table']    =    'banners';        //таблица для банеров, если отсутствует будет создана


//Действие, если не авторезирован то в авторизацию
if($action=='auth'){
    $l=$_POST['login'];
    $p=$_POST['password'];
    if(($l==$user)&&($p==$pass)){
        $_SESSION['key']=$key;
        $action='init';
    }
    else{
        $action='login';
    }
}
//Если пользователь решил выйти из системы, разлогинем его
if($action=='logout'){
    $_SESSION['key']=null;
    $action='login';
};
//Если авторизация - то строим интерфейс где можно ввесли логин и пароль
if($action=='login'){
     print "
    Login:<input type='text' id='cplogin' name='cplogin'>
    Password:<input type='text' id='cppassword' name='cppassword'>
    <input type=submit id='cp_login' value='logIn'>
    ";
    exit();
}; //login

//Подключение к серверу
$dsn = "mysql:host={$cfg['host']};dbname={$cfg['base']};charset=utf8";
$opt = array(
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$pdo = new PDO($dsn, $cfg['user'], $cfg['pass'], $opt);
$pdo->query('SET NAMES utf8');

//Построение интерфейса панели управления
if($action=='init'){
    $sql="select id,caption,url,imgname,click,limitclick,views,limitviews,dateexpired,enable from {$cfg['table']}";
    $query=$pdo->prepare($sql);
    $query->execute();
    print "<hr>
            <table id='tbl_cpBanners'>
            <tr>
                <td>Код</td>
                <td>Название</td>
                <td>Картинка</td>
                <td style='width:50px;'>Кликов</td>
                <td style='width:50px;'>Лимит кликов</td>
                <td style='width:50px;'>Просмотров</td>
                <td style='width:50px;'>Лимит просмотров</td>
                <td style='width:100px;'>Дата отключения</td>
                <td style='width:50px;'>Вкл/Выкл</td>
           
            </tr>
            ";
//тут заполним таблицу всеми банерами которые у нас есть
    while ($row=$query->fetch()){
        if($row['dateexpired']!=''){
            list($yyyy,$mm,$dd)=explode("-",$row['dateexpired']);
            $date="{$dd}-{$mm}-{$yyyy}";
        } else {
            $date="Без даты окончания";
        }
        if($row['imgname']=='')$row['imgname']='nophoto.png';
        $state=($row['enable']=='1')?"banner/images/on.png":"banner/images/off.png";
        print "
                <tr class='trEdit' data-id='{$row['id']}'>
                <td data-type='int' data-edit='false'>{$row['id']}</td>
                <td data-type='char' data-edit='true'>{$row['caption']}</label></td>
                <td data-type='pic' data-edit='true'>
                <img src='./banner/data/{$row['imgname']}'>
                </td>
                <td data-type='int' data-edit='true'>{$row['click']}</td>
                <td data-type='int' data-edit='true'>{$row['limitclick']}</td>
                <td data-type='int' data-edit='true'>{$row['views']}</td>
                <td data-type='int' data-edit='true'>{$row['limitviews']}</td>
                <td data-type='int' data-edit='true'>{$date}</td>
                <td data-type='flag' data-edit='true'><img src='{$state}'></td>
                </tr>
                ";
    };    
    print "</table>";
    print "<hr>
            <input type='button' id='cp_addBanner' value='Append Banner'>&nbsp;|&nbsp;
            <input type='button' id='cp_logout' value='LogOut'> ";
};
//Если пользователь требует от нас редактирование , то строим интерфейс окна редактирования
if($action=='edit'){
    $id=$_POST['id'];
    $sql="select id,caption,url,imgname,click,limitclick,views,limitviews,dateexpired,enable from {$cfg['table']} where id={$id}";
    $query=$pdo->prepare($sql);
    $query->execute();
    $row=$query->fetch();
    $state=($row['enable']=='1')?"banner/images/on.png":"banner/images/off.png";
    if($row['dateexpired']!=''){
        list($yyyy,$mm,$dd)=explode("-",$row['dateexpired']);
        $date="{$dd}-{$mm}-{$yyyy}";
    } else {
        $date="";
    }
    if($row['imgname']=='')$row['imgname']='nophoto.png';
    print "
            <div style='position:relative;z-index:9999; width:800px; height:auto; background-color:#fff;margin:0 auto; top:10%;padding:5px;border-radius:8px;'>
            <table id='tblEditBanner' data-id='{$row['id']}'>
                <tr>
                    <td>Название</td><td><input type='text' style='width:90%;' id='cp_Caption' value='{$row['caption']}'></td>
                </tr>
                <tr>
                    <td>URL</td><td><input type='text' style='width:90%;' id='cp_url' value='{$row['url']}'></td>
                </tr>
               
                <tr>
                    <td>Изображение<input type='button' value='Сменить банер'  id='btn_add_file'></td>
                    <td id='b_cpImage'><img src='banner/data/{$row['imgname']}' id='img_target'></td>
                </tr>
                <tr>
                    <td>Лимит кликов</td><td><input type='text' class='num' value='{$row['limitclick']}' id='cp_textLimitclick'><input type='button' value='Установить'id='cp_setLimitclick' style='display:none;'> указать -1 для отключения контроля</td>
                </tr>
                <tr>
                    <td>Лимит показов</td><td><input type='text' class='num' value='{$row['limitviews']}' id='cp_textLimitviews'><input type='button' value='Установить'id='cp_setLimitviews' style='display:none;'> указать -1 для отключения контроля</td>
                </tr>
                <tr>
                    <td>Дата истечения</td><td><input type='text' value='{$date}' readonly id='cp_dateExpired'><input type='button' value='Убрать' id='cp_btnClearDate'>
                    </td>
                </tr>   
                <tr>
                    <td>Вкл/Выкл</td><td><img src='{$state}' id='cp_btnEnable'></td>
                </tr>                                                           
            </table>
            <hr>
            <input type='checkbox' id='cp_chkDeleteBanner'>Удалить банеры
            <input type='button' value='Точно?' id='cp_btnDeleteBanner' style='display:none;'>
           
            <input type='button' style='float:right;' value='Закрыть' id='cp_btnCancel'>
            </div>
           
            ";
    //Нужна форма для hide upload file
    print "
        <div id='divupload' style='display:none;'>
        <form id='frmupload' method='post' action='banner/cp.php' enctype='multipart/form-data'>
            <input type=hidden name='id' value='{$row['id']}'/>
            <input type=hidden name='action' value='update_image'/>
            <input type='file' id='updfile' name='upfile'/>
        </form>
        </div>";
};

//Пришла команда обновить изображение
if($action=='update_image'){
    if($_FILES['file']['name']!=''){
        //имя для винды
        $newname=iconv('utf-8','windows-1251',$_FILES['file']['name']);
        $old_ext=mb_strtolower(substr(strrchr($newname, '.'), 1));
        $r_newname = md5(microtime()).'.'.$old_ext;
        //$newname=$_FILES['file']['name'];
        //путь сохранения файла
        $uploaddir='data/'.$r_newname;
        $ext=mb_strtolower(substr(strrchr($uploaddir, '.'), 1));
        //путь в базу данных
        $inbd=$r_newname; //
        //Проверим поля перед занесением в базу данных
        $pos=strpos(" jpeg, jpg, png, gif, bmp", $ext);
        $id=$_POST['id'];
        $caption=$_FILES['upfile']['name'];//имя файла
        if($pos>0)
        {
            if(move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir)){
                //Удалить ранее существовавший файл
                $sql="select imgname from {$cfg['table']} where id={$id}";
                $query=$pdo->prepare($sql);
                $query->execute();
                $row=$query->fetch();
                $fname='./data/'.$row['imgname'];
                if(file_exists($fname)){
                    @unlink($fname);
                    //    print_r(error_get_last());
                    //    print $fname;   
                   
                }
                else {
                    print "Файла {$fname} не существует";
                    die();
                }
               
                $sql="update {$cfg['table']} set imgname='{$inbd}' where id={$id}";
                $pdo->query($sql);
               
                header('Content-Type: text/html; charset=utf-8');
                print "banner/data/{$r_newname}";//Веренем новое изображение для подстановки
            }else{
                $msg='Подозрительная активность! Возможна атака с помощью файловой загрузки!';
            }
        } else{
            $msg="Документ должен быть в одном из форматов: ...";
        }
    }
   
}

//Команда изменить состояние
if($action=='ch_state'){
    $id=$_POST['id'];
    $sql="SELECT enable from {$cfg['table']} where id={$id}";
    $query=$pdo->prepare($sql);
    $query->execute();
    $row=$query->fetch();
    $state=$row['enable'];
    $ch_state=($state=='1')?'0':'1';
    $sql="UPDATE {$cfg['table']} SET enable='{$ch_state}' WHERE id={$id}";
    $pdo->query($sql);
    print $ch_state=='1'?"banner/images/on.png":"banner/images/off.png";
}

//Команда очистить поле даты истечения
if($action=='clear_date'){
    $id=$_POST['id'];
    $sql="UPDATE {$cfg['table']} SET dateexpired=NULL WHERE id={$id}";
    $pdo->query($sql);
}

//Команда установки даты истечения срока баннера
if($action=='set_date'){
    $id=$_POST['id'];
    $date=$_POST['date'];
    list($dd,$mm,$yyyy)=explode("-",$date);
    $date="{$yyyy}-{$mm}-{$dd}";
   
    $sql="UPDATE {$cfg['table']} SET dateexpired='{$date}' WHERE id={$id}";
    $pdo->query($sql);
}
//Команда установки лимитов на показ
if($action=='set_limitviews'){
    $id=$_POST['id'];
    $limit=$_POST['val'];

    $sql="UPDATE {$cfg['table']} SET limitviews='{$limit}' WHERE id={$id}";
    $pdo->query($sql);
}
//Команда установки лимитов на клики
if($action=='set_limitclick'){
    $id=$_POST['id'];
    $limit=$_POST['val'];

    $sql="UPDATE {$cfg['table']} SET limitclick='{$limit}' WHERE id={$id}";
    $pdo->query($sql);
}
//Команда установки названия баннера
if($action=='set_caption'){
    $id=$_POST['id'];
    $caption=$_POST['caption'];
   
    $sql="UPDATE {$cfg['table']} SET caption=:capt WHERE id={$id}";
    $st=$pdo->prepare($sql);
    $st->execute(array(':capt'=>$caption));
    //$pdo->query($sql);
}
//Команда установки URL для перехода по банеру
if($action=='set_url'){
    $id=$_POST['id'];
    $url=$_POST['url'];

    $sql="UPDATE {$cfg['table']} SET url=:u WHERE id={$id}";
    $st=$pdo->prepare($sql);
    $st->execute(array(':u'=>$url));
}
//Удаление баннера
if($action=='delete_banner'){
    $id=$_POST['id'];

    $sql="DELETE FROM {$cfg['table']} WHERE id={$id}";
    $pdo->query($sql);
    }

//Команда добавления баннера   
if($action=='append_banner'){
        $sql="INSERT INTO {$cfg['table']}(id,caption) VALUES(null,'Пустая запись');";
        $pdo->query($sql);
        $id=$pdo->lastInsertId();
        $sql="select id,caption,url,imgname,click,limitclick,views,limitviews,dateexpired,enable from {$cfg['table']} where id={$id}";
        $query=$pdo->prepare($sql);
        $query->execute();
        $row=$query->fetch();
        if($row['dateexpired']!=''){
            list($yyyy,$mm,$dd)=explode("-",$row['dateexpired']);
            $date="{$dd}-{$mm}-{$yyyy}";
        } else {
            $date="Без даты окончания";
        }
        if($row['imgname']=='')$row['imgname']='nophoto.png';
        $state=($row['enable']=='1')?"banner/images/on.png":"banner/images/off.png";
        print "    <tr class='trEdit' data-id='{$row['id']}'>
                <td data-type='int' data-edit='false'>{$row['id']}</td>
                <td data-type='char' data-edit='true'>{$row['caption']}</label></td>
                <td data-type='pic' data-edit='true'>
                <img src='./banner/data/{$row['imgname']}'>
                </td>
                <td data-type='int' data-edit='true'>{$row['click']}</td>
                <td data-type='int' data-edit='true'>{$row['limitclick']}</td>
                <td data-type='int' data-edit='true'>{$row['views']}</td>
                <td data-type='int' data-edit='true'>{$row['limitviews']}</td>
                <td data-type='int' data-edit='true'>{$date}</td>
                <td data-type='flag' data-edit='true'><img src='{$state}'></td>
                </tr>";
    }   
   
//Отключение от базы данных
$pdo=null;
?>

собственно тут происходит обрабоотка команд которые будут поступать от интерфейса пользователя, который тут же строится. Но этого мало, надо написать обработчики которые будут посылать нам все эти команды, за это будет отвечать Java Script
По этому делаем файл java.js и подключим его для работы скриптов.

var id_tr;
$(document).ready(function(){
$(document).on('click','#cp_login',function(e){
        var login=$("#cplogin").val();
        var pass=$("#cppassword").val();
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"auth","login":login,"password":pass},async:true,
            success:function(data){   
                if(data==''){
                    $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"login"},async:true,
                        success:function(data){
                            $("cp_banner").html(data);
                            },error:function(xhr,str){}});
                }
                if(data!='')$("#cp_banner").html(data);   
            },error:function(xhr,str){}});

    });

    $(document).on('click','#cp_btnCancel',function(e){
        $("#bFade").remove();
        location.reload(true);
    });
   
    $(document).on('click','#cp_btnEnable',function(e){
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"ch_state","id":id_tr},async:true,
            success:function(data){
                $("#cp_btnEnable").attr('src',data);
            },
            error:function(xhr,str){}
            });
    });
   
   
    $(document).on('click','#cp_btnClearDate',function(e){
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"clear_date","id":id_tr},async:true,
            success:function(data){
                $("#cp_dateExpired").val('');
            },
            error:function(xhr,str){}
            });
    });
   
   
    $(document).on('click','#cp_chkDeleteBanner',function(e){
        if($(this).prop("checked")){
            $("#cp_btnDeleteBanner").show();
        }
        else{
            $("#cp_btnDeleteBanner").hide();
        }
    });
   
    $(document).on('click','#cp_btnDeleteBanner',function(e){
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"delete_banner","id":id_tr},async:true,
            success:function(data){
                location.reload(true);
            },
            error:function(xhr,str){}
            });
    });
   
   
    $(document).on('keyup','#cp_textLimitviews',function(e){
        var obj=$('#cp_setLimitviews').css('display');
        if(obj=='none'){
            $('#cp_setLimitviews').show();
        }
    });
   
   
    $(document).on('keyup','#cp_Caption',function(e){
        var data=$(this).val();
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"set_caption","id":id_tr,"caption":data},async:true,
            success:function(data){
                //пох
            },
            error:function(xhr,str){}
            });
    });
   
    $(document).on('keyup','#cp_url',function(e){
        var data=$(this).val();
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"set_url","id":id_tr,"url":data},async:true,
            success:function(data){
                //пох 2
            },
            error:function(xhr,str){}
            });
    });
   
    $(document).on('keyup','#cp_textLimitclick',function(e){
        var obj=$('#cp_setLimitclick').css('display');
        if(obj=='none'){
            $('#cp_setLimitclick').show();
        }
    });
   
    $(document).on('click','#cp_setLimitviews',function(e){       
        var lim=$("#cp_textLimitviews").val();
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"set_limitviews","id":id_tr,"val":lim},async:true,
            success:function(data){
                $("#cp_setLimitviews").hide();   
            },
            error:function(xhr,str){}
            });
    });

   
    $(document).on('click','#cp_setLimitclick',function(e){       
        var lim=$("#cp_textLimitclick").val();
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"set_limitclick","id":id_tr,"val":lim},async:true,
            success:function(data){
                $("#cp_setLimitclick").hide();   
            },
            error:function(xhr,str){}
            });
    });

   
    $(document).on('click','#cp_addBanner',function(e){       
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"append_banner"},async:true,
            success:function(data){
                $('#tbl_cpBanners > tbody > tr:last').after(data);
                //alert('add');
            },
            error:function(xhr,str){}
            });
    });


   
    $(document).on('click','#tbl_cpBanners tr',function(e){
        id_tr=$(this).attr('data-id');
        //alert(id_tr);
        var doc_height=$(document).height()-4;
        var doc_width=$(document).width()-4;
        //Делаем запрос на форму редактирования, строим форму
        //alert("h:"+doc_height+"  w:"+doc_width);
        if(!$("#bFade").length) {
              $('body').append("<div id='bFade' style='display:block; position:fixed;left:0;top:0;z-index:9998;height:"+doc_height+"px;width:"+doc_width+"px;background-color:rgba(0,0,0,0.9);'>&nbsp;</div>");
            }
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"edit","id":id_tr},async:true,
            success:function(data){
                $("#bFade").empty().append(data);
                $("#cp_dateExpired").datepicker({ dateFormat: 'dd-mm-yy',
                    onSelect:function(){
                        var dt=$('#cp_dateExpired').val();
                        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"set_date","id":id_tr,"date":dt},async:true,
                            success:function(data){
                                //$("#cp_dateExpired").val('');
                            },
                            error:function(xhr,str){}
                            });
                    }});
                  $("#btn_add_file").upload({
                        name: 'file',
                        method: 'post',
                        action: 'banner/cp.php',
                        enctype: 'multipart/form-data',
                        autoSubmit: true,
                        params:{
                            action:'update_image',
                            id:id_tr
                        },
                        onSubmit: function() {
                        },
                        onSelect: function() {
                        },
                        onComplete: function(data) {
                            $("#img_target").attr('src',data);
                            //$("#b_cpImage").empty();
                           
                        }
                      });
                 
                  $("#tblEditBanner .num").keydown(function(event) {
                        // Разрешаем нажатие клавиш backspace, del, tab и esc
                        if ( event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 109 ||
                             // Разрешаем выделение: Ctrl+A
                            (event.keyCode == 65 && event.ctrlKey === true) ||
                             // Разрешаем клавиши навигации: home, end, left, right
                            (event.keyCode >= 35 && event.keyCode <= 39)) {
                                 return;
                        }
                        else {
                            // Запрещаем всё, кроме клавиш цифр на основной клавиатуре, а также Num-клавиатуре
                            if ((event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105 )) {
                                event.preventDefault();
                            } 
                        }
                    });
                 
            },
            error:function(xhr,str){}
            });
    });

    $(document).on('click','#cp_logout',function(e){
        $.ajax({type:'POST',url:'banner/cp.php',data:{"action":"logout"},async:true,
            success:function(data){
                $("cp_banner").html(data);
                location.reload();
                },error:function(xhr,str){}});
    });

});

Ну собственно описывать все я не буду, но смысл такой, тут jQuery обработка событий на элементы интерфейса.

весь код рабочей банерки можно взять тут для изучения 
для просмотра работы банерной системы переходим
как пример http://localhost/banners/
а для вызова панели управления переходим http://localhost/banners/banner_cp.php
 

Комментариев нет:

Отправить комментарий