final
Этот коммит содержится в:
родитель
b6f7196aa5
Коммит
ef07700d53
71
README.md
71
README.md
@ -1,6 +1,9 @@
|
||||
PTEST
|
||||
=====
|
||||
|
||||
Рабочая версия скрипта развернута здесь:
|
||||
<http://ptest.i2g.ru/>
|
||||
|
||||
Задание
|
||||
-------
|
||||
|
||||
@ -32,17 +35,71 @@ PTEST
|
||||
Развертывание
|
||||
-------------
|
||||
|
||||
Скачать архив <https://mygit.i2g.ru/ptest/snapshot/ptest-master.zip>
|
||||
|
||||
Настроить любимый веб-сервер на папку `public`.
|
||||
|
||||
Мой конфиг для nginx
|
||||
|
||||
|
||||
```
|
||||
server {
|
||||
server_name ptest.i2g.ru;
|
||||
root /mnt/160/sites/ptest.i2g/public;
|
||||
|
||||
location / {
|
||||
try_files $uri /index.php?$query_string;
|
||||
}
|
||||
location ~ ^/index\.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
|
||||
include fastcgi_params;
|
||||
fastcgi_param HTTP_PROXY "";
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_intercept_errors on;
|
||||
# PHP 5 socket location.
|
||||
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||
}
|
||||
|
||||
location = /favicon.ico {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location = /robots.txt {
|
||||
allow all;
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
###MySQL/MariaDB
|
||||
|
||||
1. Импортировать `dump.sql` в базу данных.
|
||||
2. Установить параметры в файле `src/start.php`
|
||||
|
||||
### Composer
|
||||
|
||||
Чтобы скрипт заработал нужно создать автозарузчик классов при помощи
|
||||
[Composer](https://getcomposer.org/download/ "Загрузка пакетного менеджера для PHP-библиотек Composer")
|
||||
|
||||
```
|
||||
composer install
|
||||
```
|
||||
|
||||
Впринципе после этого приложение должно заработать.
|
||||
|
||||
### По желанию
|
||||
|
||||
Для генерации CSS, js и прочей рутины я использую Grunt.
|
||||
Чтобы его установить нужны следующие команды
|
||||
|
||||
```
|
||||
cd grunt
|
||||
npm install
|
||||
cd css
|
||||
git clone https://github.com/IgorVBelousov/ShortCSS.git
|
||||
cd grunt
|
||||
npm install
|
||||
cd css
|
||||
git clone https://github.com/IgorVBelousov/ShortCSS.git
|
||||
git clone https://mygit.i2g.ru/normalize/
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
14
dump.sql
14
dump.sql
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
@ -102,7 +102,7 @@ class App {
|
||||
}
|
||||
|
||||
/**
|
||||
* Запуск маршрутов
|
||||
* Запуск приложения
|
||||
*/
|
||||
public function run(){
|
||||
foreach ( $this->route_table as $route_array ) {
|
||||
|
@ -24,6 +24,9 @@ class Model {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Сохраниние объекта
|
||||
*/
|
||||
public function save() {
|
||||
$operation = "INSERT INTO ";
|
||||
$suffix = "";
|
||||
@ -56,6 +59,13 @@ class Model {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск первого вхождения по условию
|
||||
*
|
||||
* @param string $condition SQL-строка, которая будет идти после WHERE
|
||||
*
|
||||
* @return bool|object false или объект
|
||||
*/
|
||||
static public function findFirst( $condition ) {
|
||||
global $app;
|
||||
$child_model_name = get_called_class();
|
||||
@ -74,6 +84,13 @@ class Model {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск объектов по условию
|
||||
*
|
||||
* @param string $condition SQL-строка, которая будет идти после WHERE
|
||||
*
|
||||
* @return array|bool false или массив объектов
|
||||
*/
|
||||
static public function find( $condition ) {
|
||||
global $app;
|
||||
$child_model_name = get_called_class();
|
||||
@ -98,6 +115,11 @@ class Model {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение количества записей в таблице
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count() {
|
||||
$child_model_name = get_called_class();
|
||||
$model = new $child_model_name;
|
||||
|
@ -104,6 +104,21 @@ a
|
||||
-m 26 0
|
||||
-lh 24
|
||||
|
||||
.add-link
|
||||
-d inline-block
|
||||
-fl right
|
||||
|
||||
&__a
|
||||
-br 1 solid $link_color_border imp
|
||||
-p 7 14
|
||||
b-radius 3
|
||||
|
||||
&:visited
|
||||
-c $link_color
|
||||
|
||||
&:hover
|
||||
-br 1 solid $link_hover_color_border imp
|
||||
|
||||
.sort
|
||||
-d table-row
|
||||
+media('max-width:424px')
|
||||
@ -212,6 +227,7 @@ article
|
||||
-h (120/2)
|
||||
clear both
|
||||
-d block
|
||||
-mb 6
|
||||
|
||||
form
|
||||
-w 320
|
||||
@ -246,6 +262,17 @@ form
|
||||
&:focus
|
||||
-brb 2 solid $link_hover_color_border
|
||||
|
||||
&__submit
|
||||
-c $link_color
|
||||
-br 1 solid $link_color_border
|
||||
-p 7 14
|
||||
b-radius 3
|
||||
-bgc white
|
||||
|
||||
&:hover
|
||||
-c $link_hover_color
|
||||
-br 1 solid $link_hover_color_border
|
||||
|
||||
.i-user
|
||||
sprite_sprite(sprite_account)
|
||||
-mb -6
|
||||
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
@ -271,6 +271,26 @@ a.to-front:visited:hover {
|
||||
margin: 26px 0;
|
||||
line-height: 24px;
|
||||
}
|
||||
.add-link {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
.add-link__a {
|
||||
border: 1px solid rgba(0,99,255,0.3) !important;
|
||||
padding: 7px 14px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-khtml-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.add-link__a:visited {
|
||||
color: #0063ff;
|
||||
}
|
||||
.add-link__a:hover {
|
||||
border: 1px solid rgba(255,71,93,0.24) !important;
|
||||
}
|
||||
.sort {
|
||||
display: table-row;
|
||||
}
|
||||
@ -355,6 +375,7 @@ article+article {
|
||||
height: 60px;
|
||||
clear: both;
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
form {
|
||||
width: 320px;
|
||||
@ -390,6 +411,22 @@ form {
|
||||
.form-element__textarea:focus {
|
||||
border-bottom: 2px solid rgba(255,71,93,0.24);
|
||||
}
|
||||
.form-element__submit {
|
||||
color: #0063ff;
|
||||
border: 1px solid rgba(0,99,255,0.3);
|
||||
padding: 7px 14px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-khtml-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
background-color: #fff;
|
||||
}
|
||||
.form-element__submit:hover {
|
||||
color: #ff475d;
|
||||
border: 1px solid rgba(255,71,93,0.24);
|
||||
}
|
||||
.i-user {
|
||||
background-image: url("/image/sprite.png");
|
||||
background-size: 56px 56px;
|
||||
|
@ -29,16 +29,20 @@ class AdModel extends Model{
|
||||
protected $table_pdate;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* Получить id
|
||||
*
|
||||
* @return integer|null
|
||||
*/
|
||||
public function getId() {
|
||||
return (int) $this->table_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $username
|
||||
* Установить имя пользователя
|
||||
*
|
||||
* @return bool|string
|
||||
* @param string $username имя пользавтеля
|
||||
*
|
||||
* @return bool|string true в случае успеха. иначе сообщение с разъяснениями
|
||||
*/
|
||||
public function setUserName( $username ) {
|
||||
if ( preg_match( '/[a-z,\d]{3,}/i', $username ) ) {
|
||||
@ -49,14 +53,21 @@ class AdModel extends Model{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить имя пользователя
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUserName(){
|
||||
return $this->table_username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $email
|
||||
* Установка e-mail
|
||||
*
|
||||
* @return bool|string
|
||||
* @param string $email
|
||||
*
|
||||
* @return bool|string true в случае успеха. иначе сообщение с разъяснениями
|
||||
*/
|
||||
public function setEmail( $email ) {
|
||||
if ( preg_match('/.+@.+\..+/i', $email ) ) {
|
||||
@ -68,6 +79,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить e-mail
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getEmail() {
|
||||
@ -75,9 +88,11 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $homepage
|
||||
* Установка домашней страницы
|
||||
*
|
||||
* @return bool|string
|
||||
* @param string $homepage URL
|
||||
*
|
||||
* @return bool|string true в случае успеха. иначе сообщение с разъяснениями
|
||||
*/
|
||||
public function setHomepage( $homepage ) {
|
||||
if ( preg_match('|https?://.*\..*|i', $homepage ) ) {
|
||||
@ -89,6 +104,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение домашней страницы
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getHomepage() {
|
||||
@ -96,6 +113,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка IP адреса
|
||||
*
|
||||
* @param mixed $ip
|
||||
*/
|
||||
public function setIp( $ip ) {
|
||||
@ -103,6 +122,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение IP адреса
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIp() {
|
||||
@ -110,6 +131,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка данных User-Agent
|
||||
*
|
||||
* @param mixed $browser
|
||||
*/
|
||||
public function setBrowser( $browser ) {
|
||||
@ -117,6 +140,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение данных User-Agent
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBrowser() {
|
||||
@ -124,6 +149,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка текста
|
||||
*
|
||||
* @param mixed $text
|
||||
*/
|
||||
public function setText( $text ) {
|
||||
@ -131,6 +158,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение текста
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getText() {
|
||||
@ -138,6 +167,8 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка даты
|
||||
*
|
||||
* @param mixed $date
|
||||
*/
|
||||
public function setDate( $date ) {
|
||||
@ -145,20 +176,28 @@ class AdModel extends Model{
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение даты
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDate() {
|
||||
return $this->table_pdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение количества страниц
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countPages() {
|
||||
return ceil($this->count()/25);
|
||||
return (int) ceil($this->count()/25);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page_number
|
||||
* @param string $sort_by
|
||||
* @param string $order
|
||||
* Получение массива объектов для вывода на страницах
|
||||
*
|
||||
* @param integer $page_number номер страницы
|
||||
* @param string $sort_by сортировка по столбцу
|
||||
* @param string $order сортировка по возрастанию или убыванию
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
@ -11,10 +11,22 @@ namespace PTEST\M;
|
||||
|
||||
class CAPTCHAModel {
|
||||
|
||||
/**
|
||||
* Проверка даных капчи
|
||||
*
|
||||
* @param string $code
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function verify( $code ) {
|
||||
return strtoupper( $code ) == $_SESSION['CAPTCHA'] ? true : "Неверный код с картинки";
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерирование изображения
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getImage() {
|
||||
global $app;
|
||||
$letters = 'ABDEFABDEFGKLMNPRSTWXYZ482GKLMNABDEFGKLMNPRSTWXYZ482PRSTWXYZ482'; // алфавит
|
||||
|
@ -40,6 +40,7 @@ if ($this->sort_by == 'mail') {
|
||||
}
|
||||
?>
|
||||
<h1 class="page-title"><?php echo $this->page_title ?></h1>
|
||||
<div class="add-link"><a href="/new/" class="add-link__a">Добавить объявление</a></div>
|
||||
<div class="sort">
|
||||
<div class="sort__cell">Сортировка:</div>
|
||||
<div class="sort__cell"><a href="<?php echo $one_href ?>"><?php echo $one_arr ?>Дата</a></div>
|
||||
|
@ -30,8 +30,9 @@ ob_start();
|
||||
<textarea class="form-element__textarea" name="text" id="" cols="30" rows="10" placeholder="Текст объявления" tabindex="5"><?php echo ($this->post_data->text)?$this->post_data->text:'';?></textarea>
|
||||
<div class="form-element__error"><?php echo ($this->errors->text)?$this->errors->text:''; ?></div>
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Отправить">
|
||||
<div class="form-element">
|
||||
<input type="submit" value="Отправить" class="form-element__submit">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</article>
|
||||
|
@ -37,7 +37,6 @@ $app->setRoute( '|^/(?<column>mail)/(?<order>asc)/(page/(?<id>\d+)/)?$|', 'Index
|
||||
$app->setRoute( '|^/(?<column>mail)/(?<order>desc)/(page/(?<id>\d+)/)?$|', 'Index', 'sort');
|
||||
$app->setRoute( '|^/full/(?<id>\d+)/$|', 'Index', 'full');
|
||||
$app->setRoute( '|^/new/$|', 'Index', 'new');
|
||||
$app->setRoute( '|^/view_table/((?<id>\d+)/)*$|', 'Index', 'table');
|
||||
$app->setRoute( '/^.*$/', 'error404' );
|
||||
|
||||
$app->run();
|
Загрузка…
Ссылка в новой задаче
Block a user