REBORN - попытка залатать дырки и заставить работать. Трудимся вместе с deepseek

This commit is contained in:
Krivchikov Dmitry 2026-06-29 11:05:47 +03:00
parent 205fb64180
commit bc1fb7572f
20 changed files with 387 additions and 129 deletions

204
PLAN.md Normal file
View File

@ -0,0 +1,204 @@
# План работ: wikipoints.ru
## Статус
- Бэкап БД: есть (`poi.sql`, 18 таблиц, 868 строк)
- Google Maps API key: **просрочен** (`AIzaSyDuWmguxO35oV9WGc6D8xUPvQBaUS4kt78`)
- SMS.ru / Alarmer: ключи устарели, но не критично
- uLogin: **выпилить**, заменить на вход по email + пароль
- Подтверждение email: через **Resend** (добавить колонки `email`, `password`, `emailConfirmed`)
---
## 1. База данных
### 1.1 Импортировать `poi.sql`
```sql
mysql -u root -p poi < poi.sql
```
### 1.2 Расширить таблицу `users`
```sql
ALTER TABLE users
ADD COLUMN `email` varchar(255) DEFAULT NULL AFTER `uid`,
ADD COLUMN `password` varchar(255) DEFAULT NULL AFTER `email`,
ADD COLUMN `emailConfirmed` tinyint(1) NOT NULL DEFAULT 0 AFTER `password`,
ADD COLUMN `confirmToken` varchar(64) DEFAULT NULL AFTER `emailConfirmed`,
ADD UNIQUE KEY `email` (`email`);
```
Старым пользователям (через uLogin) проставить `emailConfirmed = 1` — они не могут войти по паролю, но не теряют доступ. Новые регистрируются только через email+пароль.
---
## 2. Авторизация (выпил uLogin)
### 2.1 Новый контроллер `AuthController` или методы в `IndexController`
**actionRegister** — регистрация:
- Поля: email, пароль (2 раза), ник
- Валидация: email уникальный, пароль ≥ 6 символов
- Хеш пароля: `password_hash($pass, PASSWORD_BCRYPT)`
- Генерация `confirmToken = bin2hex(random_bytes(32))`
- Отправка письма через Resend с ссылкой `/auth/confirm?token=...`
- После успеха: флеш-сообщение «Проверьте почту»
**actionLogin** — вход (заменить старый ulogin):
- Форма: email + пароль
- Поиск пользователя по email, проверка `password_verify()`
- Если `emailConfirmed = 0` — «Подтвердите email»
- Успех: `App::userLogin($user)`, редирект
**actionLogout** — без изменений (уже работает)
**actionConfirm** — подтверждение email:
- Проверить `confirmToken`, проставить `emailConfirmed = 1`, очистить токен
- Автоматический вход, редирект на главную
**actionForgot** — восстановление пароля:
- Форма email → поиск пользователя → Resend c токеном сброса
- Новая колонка `resetToken` (или переиспользовать `confirmToken`)
**actionReset** — сброс пароля:
- Проверить токен, показать форму нового пароля
### 2.2 Модель `User` — добавить методы
```php
function getByEmail($email) { ... }
static function hashPassword($pass) { return password_hash($pass, PASSWORD_BCRYPT); }
function verifyPassword($pass) { return password_verify($pass, $this->password); }
```
### 2.3 Файлы для удаления/изменения
| Файл | Действие |
|------|----------|
| `views/modals/login.php` | Переписать целиком: убрать uLogin, вставить форму email+пароль + ссылку на регистрацию |
| `controllers/IndexController.php` (actionLogin) | Удалить ulogin-код, заменить на email/пароль |
| `views/layouts/*.php` (скрипт ulogin) | Убрать проверку `strpos($script, 'ulogin')` |
| `public/js/app.js` | Проверить и убрать ulogin-вызовы |
### 2.4 Шаблоны
- `views/modals/register.php` — новый
- `views/modals/login.php` — переписать
- `views/auth/confirm.php` — новый
- `views/auth/forgot.php` — новый
- `views/auth/reset.php` — новый
---
## 3. Уведомления через Resend
### 3.1 Установка (без composer — вручную)
Скачать и положить в `classes/`:
- `classes/Resend.php` — простой класс-обёртка для Resend API (POST https://api.resend.com/emails)
- API-ключ через config.php: `'resendKey' => 're_...'`
### 3.2 Отправка писем
- Регистрация: подтверждение email (HTML-шаблон)
- Восстановление пароля
- (Опционально) уведомления о новых точках/комментариях
---
## 4. Google Maps API ключ
### 4.1 Файлы для замены
| Файл | Строка |
|------|--------|
| `controllers/JsonController.php:384,506` | `AIzaSyDuWmguxO35oV9WGc6D8xUPvQBaUS4kt78` → новый ключ |
### 4.2 Вынести в config
Добавить в `config.php`:
```php
'googleMapsKey' => 'НОВЫЙ_КЛЮЧ',
```
В коде:
```php
$key = App::getConfig('googleMapsKey');
```
---
## 5. Конфигурация
### 5.1 `config.php` — изменения
```php
return array(
'title' => '...',
'description' => '...',
'DB' => array(
'host' => 'localhost',
'user' => 'poi',
'password' => '...',
'dbname' => 'poi',
),
'images' => [...],
'version' => trim(file_get_contents(...)),
'metrika' => false, // отключить, ключей нет
'ganalytics' => false, // отключить
'disableSMS' => true, // SMS.ru не работает
'alarmerKey' => '', // не используется
'protocol' => 'http', // пока http
'googleMapsKey' => '...', // новый ключ
'resendKey' => 're_...', // ключ Resend
);
```
---
## 6. PHP-совместимость (минимальные правки)
| Проблема | Правка |
|----------|--------|
| `__autoload()` | Пока работает в PHP 7.4/8.x (deprecated, но не fatal). Совместимость не сломана |
| `die;``die();` | Косметика, не блокирует |
| PHP4-конструкторы | Проверить `Model.php` и `Controller.php` — если `Class() { parent::Class(); }` — заменить на `__construct()` |
| `mysql_*` | Уже нет, везде PDO |
После всех правок проверить:
```bash
php -l app.php
php -l controllers/*.php
php -l models/*.php
php -l classes/*.php
```
---
## 7. Порядок выполнения
```
1. config_template.php → скопировать, настроить БД, ключи
2. Импортировать poi.sql, выполнить ALTER TABLE users
3. Добавить класс Resend
4. Расширить модель User (email, password, getByEmail)
5. Создать AuthController (register, login, logout, confirm, forgot, reset)
6. Переписать views/modals/login.php (форма email+pass)
7. Создать views/modals/register.php
8. Создать шаблоны confirm/forgot/reset
9. Заменить Google Maps ключ в JsonController
10. Вычистить uLogin из layouts
11. Обновить config.php (resendKey, googleMapsKey, disableSMS, metrika/ganalytics)
12. Проверить php -l
13. Проверить в браузере
```
---
## Не делаем (осознанно)
- SQL-инъекции глобально — править только критичные места
- XSS-защита — не трогаем legacy
- Миграции — не пишем, всё через sql-файл
- Тесты — не пишем
- Composer — не добавляем
- CSRF — не добавляем
- Спрятать пароль БД в .env — в следующей итерации

View File

@ -13,11 +13,11 @@ class IndexController extends Controller
self::addScript('/js/bootstrap.min.js'); self::addScript('/js/bootstrap.min.js');
self::addScript('/js/leaflet.js'); self::addScript('/js/leaflet.js');
self::addScript('https://maps.google.com/maps/api/js?v=3'); // self::addScript('https://maps.google.com/maps/api/js?v=3');
self::addScript('/js/tile/Google.js'); // self::addScript('/js/tile/Google.js');
self::addScript('https://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU'); // self::addScript('https://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU');
self::addScript('/js/tile/Yandex.js'); // self::addScript('/js/tile/Yandex.js');
self::addScript('/js/app.js?ver=' . App::getConfig('version')); self::addScript('/js/app.js?ver=' . App::getConfig('version'));
self::addScript('/js/jquery.cookie.js'); self::addScript('/js/jquery.cookie.js');
@ -108,34 +108,76 @@ class IndexController extends Controller
static function actionLogin() static function actionLogin()
{ {
$source = file_get_contents('https://ulogin.ru/token.php?token=' . $_POST['token'] . '&host=' . $_SERVER['HTTP_HOST']); $email = isset($_POST['email']) ? trim($_POST['email']) : '';
$uLoginUser = json_decode($source, true); $password = isset($_POST['password']) ? $_POST['password'] : '';
$uLoginUser['identity'] = md5($uLoginUser['uid'] . $uLoginUser['network'] . '=P');
$user = User::model()->getByUID($uLoginUser['identity']); if (!$email || !$password) {
$_SESSION['login_error'] = 'Заполните email и пароль.';
if (!$user->id) { App::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
$user = $user->add(array(
'uid' => $uLoginUser['identity'],
'nick' => $uLoginUser['nickname'],
'name' => $uLoginUser['first_name'],
'profile' => $uLoginUser['profile'],
'network' => $uLoginUser['network'],
'photo' => $uLoginUser['photo_big'],
));
if (!$user) {
return false;
}
} }
$target = App::getBasedir().'public/img/avatars/'.$user->id.'.jpg'; $user = User::model()->getByEmail($email);
Image::createAvatar($uLoginUser['photo_big'], $target);
if (!$user || !$user->id || !$user->verifyPassword($password)) {
$_SESSION['login_error'] = 'Неверный email или пароль.';
App::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
}
if (!$user->emailConfirmed) {
$_SESSION['login_error'] = 'Email не подтверждён. Проверьте почту.';
App::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
}
App::userLogin($user); App::userLogin($user);
unset($_SESSION['login_error']);
App::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/'); App::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
} }
static function actionRegister()
{
$email = isset($_POST['email']) ? trim($_POST['email']) : '';
$nick = isset($_POST['nick']) ? trim($_POST['nick']) : '';
$password = isset($_POST['password']) ? $_POST['password'] : '';
$password2 = isset($_POST['password2']) ? $_POST['password2'] : '';
$error = '';
if (!$email || !$nick || !$password) {
$error = 'Заполните все поля.';
} elseif ($password !== $password2) {
$error = 'Пароли не совпадают.';
} elseif (strlen($password) < 6) {
$error = 'Пароль должен быть не менее 6 символов.';
} elseif (User::model()->getByEmail($email)) {
$error = 'Этот email уже зарегистрирован.';
}
if ($error) {
$_SESSION['register_error'] = $error;
App::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
}
$user = User::model()->add(array(
'uid' => md5($email . time()),
'email' => $email,
'nick' => $nick,
'name' => $nick,
'password' => User::hashPassword($password),
'profile' => '',
'network' => 'email',
'photo' => '',
'emailConfirmed' => 0,
'confirmToken' => bin2hex(random_bytes(32)),
));
if (!$user) {
$_SESSION['register_error'] = 'Ошибка регистрации. Попробуйте позже.';
App::redirect('/');
}
$_SESSION['register_success'] = 'Регистрация прошла успешно! Подтвердите email, перейдя по ссылке в письме.';
App::redirect('/');
}
static function actionSitemap() static function actionSitemap()
{ {
$xml = new SimpleXMLElement('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"/>'); $xml = new SimpleXMLElement('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"/>');

View File

@ -10,6 +10,7 @@ class LpController extends Controller
public function __construct() public function __construct()
{ {
App::error404();
self::$layout = 'layouts/lp.php'; self::$layout = 'layouts/lp.php';
self::addScript('/js/jquery-2.1.0.min.js'); self::addScript('/js/jquery-2.1.0.min.js');
self::addScript('/js/jquery-ui-1.10.4.custom.min.js'); self::addScript('/js/jquery-ui-1.10.4.custom.min.js');

View File

@ -28,6 +28,31 @@ class User extends Model
} }
} }
function getByEmail($email)
{
$res = App::DB()->query('SELECT `id` FROM `' . $this->_tableName_ . '` WHERE `email` = ' . App::DB()->quote($email));
if ($res) {
$res = $res->fetch(PDO::FETCH_ASSOC);
if ($res) {
return $this->getByPK((int) $res['id']);
}
}
return false;
}
static function hashPassword($password)
{
return password_hash($password, PASSWORD_BCRYPT);
}
function verifyPassword($password)
{
if (!$this->password) {
return false;
}
return password_verify($password, $this->password);
}
function getPointsCount() function getPointsCount()
{ {
return Point::model()->getCountByUser($this->id); return Point::model()->getCountByUser($this->id);

View File

@ -70,18 +70,19 @@ function init(lat, lng) {
L.control.scale({imperial: false}).addTo(myMap); L.control.scale({imperial: false}).addTo(myMap);
// layers['quest'] = L.tileLayer('https://otile1-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com" target="_blank">Mapbox</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18}); // layers['quest'] = L.tileLayer('https://otile1-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com" target="_blank">Mapbox</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18});
layers['sputnik'] = L.tileLayer('https://{s}.sputnik.wikipoints.ru/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://sputnik.ru" target="_blank">Sputnik</a>, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18}); // layers['sputnik'] = L.tileLayer('https://{s}.sputnik.wikipoints.ru/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://sputnik.ru" target="_blank">Sputnik</a>, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18});
// layers['sputnik'] = L.tileLayer('https://{s}.tilessputnik.ru/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://sputnik.ru" target="_blank">Sputnik</a>, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18});
layers['osm'] = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18}); layers['osm'] = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18});
layers['topo'] = L.tileLayer('https://topo.wikipoints.ru/?z={z}&x={x}&y={y}&ver=0216', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a>, Imagery © <a href="http://www.marshruty.ru/" target="_blank">Маршруты.ру</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 15}); layers['topo'] = L.tileLayer('https://topo.wikipoints.ru/?z={z}&x={x}&y={y}&ver=0216', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a>, Imagery © <a href="http://www.marshruty.ru/" target="_blank">Маршруты.ру</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 15});
layers['google'] = new L.Google('HYBRID'); // layers['google'] = new L.Google('HYBRID');
layers['yandexMap'] = new L.Yandex(); // layers['yandexMap'] = new L.Yandex();
layers['yandex'] = new L.Yandex('hybrid'); // layers['yandex'] = new L.Yandex('hybrid');
if ($.cookie('mapLayer') && $.cookie('mapLayer') == 'quest') { if ($.cookie('mapLayer') && ($.cookie('mapLayer') != 'osm' || $.cookie('mapLayer') != 'topo')) {
setLayer('sputnik'); setLayer('osm');
} }
setLayer($.cookie('mapLayer') ? $.cookie('mapLayer') : 'sputnik'); setLayer($.cookie('mapLayer') ? $.cookie('mapLayer') : 'osm');
initCategories(); // getPoints внутри initCategories(); // getPoints внутри

0
update.sh Executable file → Normal file
View File

View File

@ -1 +1 @@
abcde 205fb

View File

@ -27,16 +27,11 @@ if (App::$user) {
</div> </div>
<div id="box"> <div id="box">
<span id="boxClose" onclick="closeBox();">&times;</span> <span id="boxClose" onclick="closeBox();">&times;</span>
<div id="boxLayers"> <div id="boxLayers">
<h3>Карты</h3> <h3>Карты</h3>
<!-- <span class="dot layers questLayer"> </span><a onclick="setLayer('quest');return false;" class="layers questLayer">map Quest</a><br/>--> <span class="dot layers osmLayer"> </span><a onclick="setLayer('osm');return false;" class="layers osmLayer">Open Street Map</a><br/>
<span class="dot layers sputnikLayer"> </span><a onclick="setLayer('sputnik');return false;" class="layers sputnikLayer">OSM-Sputnik</a><br/> <span class="dot layers topoLayer"> </span><a onclick="setLayer('topo');return false;" class="layers topoLayer">Генштаб от маршруты.ру</a><br/>
<span class="dot layers osmLayer"> </span><a onclick="setLayer('osm');return false;" class="layers osmLayer">Open Street Map</a><br/> </div>
<span class="dot layers topoLayer"> </span><a onclick="setLayer('topo');return false;" class="layers topoLayer">Генштаб от маршруты.ру</a><br/>
<span class="dot layers googleLayer"> </span><a onclick="setLayer('google');return false;" class="layers googleLayer">Google maps</a><br/>
<span class="dot layers yandexLayer"> </span><a onclick="setLayer('yandex');return false;" class="layers yandexLayer">Яндекс.Карты</a><br/>
<span class="dot layers yandexMapLayer"> </span><a onclick="setLayer('yandexMap');return false;" class="layers yandexMapLayer">Яндекс.Карты (схема)</a><br/>
</div>
<div id="boxFilter"> <div id="boxFilter">
<h3>Фильтры и поиск</h3> <h3>Фильтры и поиск</h3>
<span class="input-group"> <span class="input-group">
@ -132,7 +127,7 @@ if (App::$user) {
<?php endif; ?> <?php endif; ?>
<?php endif; ?> <?php endif; ?>
</div> </div>
<?= App::$user ? '' : self::renderPartial('modals/login.php', null, true) ?> <?= App::$user ? '' : self::renderPartial('modals/login.php', null, true) . self::renderPartial('modals/register.php', null, true) ?>
<?= App::$user ? self::renderPartial('modals/addPoint.php', array('categories' => Category::model()->getCategoriesForChoise()), true) : '' ?> <?= App::$user ? self::renderPartial('modals/addPoint.php', array('categories' => Category::model()->getCategoriesForChoise()), true) : '' ?>
<?= self::renderPartial('modals/categories.php', array('categories' => $categories), true) ?> <?= self::renderPartial('modals/categories.php', array('categories' => $categories), true) ?>
<?= self::renderPartial('modals/image.php', array(), true) ?> <?= self::renderPartial('modals/image.php', array(), true) ?>

View File

@ -49,7 +49,7 @@
<?php if ($scripts): ?> <?php if ($scripts): ?>
<?php foreach ($scripts as $script): ?> <?php foreach ($scripts as $script): ?>
<script src="<?= $script ?>" <?= (strpos($script, 'ulogin') !== FALSE) ? 'async':'' ?> type="text/javascript"></script> <script src="<?= $script ?>" type="text/javascript"></script>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>
</html> </html>

View File

@ -60,7 +60,7 @@
<?php if ($scripts): ?> <?php if ($scripts): ?>
<?php foreach ($scripts as $script): ?> <?php foreach ($scripts as $script): ?>
<script src="<?= $script ?>" <?= (strpos($script, 'ulogin') !== FALSE) ? 'async':'' ?> type="text/javascript"></script> <script src="<?= $script ?>" type="text/javascript"></script>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>
</html> </html>

View File

@ -13,7 +13,7 @@
<?php if ($scripts): ?> <?php if ($scripts): ?>
<?php foreach ($scripts as $script): ?> <?php foreach ($scripts as $script): ?>
<script src="<?= $script ?>" <?= (strpos($script, 'ulogin') !== FALSE) ? 'async':'' ?> type="text/javascript"></script> <script src="<?= $script ?>" type="text/javascript"></script>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>

View File

@ -14,7 +14,7 @@
<?php if ($scripts): ?> <?php if ($scripts): ?>
<?php foreach ($scripts as $script): ?> <?php foreach ($scripts as $script): ?>
<script src="<?= $script ?>" <?= (strpos($script, 'ulogin') !== FALSE) ? 'async':'' ?> type="text/javascript"></script> <script src="<?= $script ?>" type="text/javascript"></script>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>

View File

@ -19,7 +19,7 @@
<?php if ($scripts): ?> <?php if ($scripts): ?>
<?php foreach ($scripts as $script): ?> <?php foreach ($scripts as $script): ?>
<script src="<?= $script ?>" <?= (strpos($script, 'ulogin') !== FALSE) ? 'async':'' ?> type="text/javascript"></script> <script src="<?= $script ?>" type="text/javascript"></script>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>

View File

@ -1,4 +1,3 @@
<script src="//ulogin.ru/js/ulogin.js" async type="text/javascript"></script>
<div class="modal fade" id="loginModal" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;"> <div class="modal fade" id="loginModal" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
@ -6,18 +5,30 @@
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Вход на сайт</h4> <h4 class="modal-title">Вход на сайт</h4>
</div> </div>
<div class="modal-body" style="text-align: center; padding-bottom: 0;"> <form method="post" action="/index/login/">
<p style="text-align: justify; text-indent: 15px;"> <div class="modal-body" style="padding-bottom: 0;">
Для добавления точек, создания коллекции точек в избранном, сохранения маршрутов и использования ряда других функций, необходимо выполнить вход на сайт. Вход осуществляется через учётную запись в любой социальной сети. При этом вам не нужно вводить пароль - всё очень просто! <p style="text-align: justify; text-indent: 15px;">
</p> Для добавления точек, создания коллекции точек в избранном, сохранения маршрутов и использования ряда других функций, необходимо выполнить вход на сайт.
<p style="text-align: justify; text-indent: 15px;"> </p>
Мы сохраняем только ваше имя, ник и аватарку, не запрашивая лишних данных. Приятных путешествий! <?php if (isset($_SESSION['login_error']) && $_SESSION['login_error']): ?>
</p> <div class="alert alert-danger"><?= htmlspecialchars($_SESSION['login_error']) ?></div>
<div style="display: inline-block;" id="uLogin" data-ulogin="display=panel;fields=first_name,nickname,photo_big;providers=twitter,mailru,vkontakte,google,yandex,facebook,instagram;hidden=odnoklassniki,livejournal,openid,foursquare,tumblr;redirect_uri=<?= App::getConfig('protocol', 'https') ?>%3A%2F%2F<?= $_SERVER['HTTP_HOST'] ?>%2Findex%2Flogin"></div> <?php unset($_SESSION['login_error']); ?>
</div> <?php endif; ?>
<div class="modal-footer"> <div class="form-group">
<button type="button" class="btn btn-default" data-dismiss="modal">Отмена</button> <label for="loginEmail">Email</label>
</div> <input type="email" class="form-control" id="loginEmail" name="email" placeholder="email@example.com" required>
</div>
<div class="form-group">
<label for="loginPassword">Пароль</label>
<input type="password" class="form-control" id="loginPassword" name="password" placeholder="Пароль" required>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success">Войти</button>
<button type="button" class="btn btn-link" onclick="$('#loginModal').modal('hide');$('#registerModal').modal('show');">Регистрация</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Отмена</button>
</div>
</form>
</div> </div>
</div> </div>
</div> </div>

43
views/modals/register.php Normal file
View File

@ -0,0 +1,43 @@
<div class="modal fade" id="registerModal" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Регистрация</h4>
</div>
<form method="post" action="/index/register/">
<div class="modal-body" style="padding-bottom: 0;">
<?php if (isset($_SESSION['register_error']) && $_SESSION['register_error']): ?>
<div class="alert alert-danger"><?= htmlspecialchars($_SESSION['register_error']) ?></div>
<?php unset($_SESSION['register_error']); ?>
<?php endif; ?>
<?php if (isset($_SESSION['register_success']) && $_SESSION['register_success']): ?>
<div class="alert alert-success"><?= htmlspecialchars($_SESSION['register_success']) ?></div>
<?php unset($_SESSION['register_success']); ?>
<?php endif; ?>
<div class="form-group">
<label for="regEmail">Email</label>
<input type="email" class="form-control" id="regEmail" name="email" placeholder="email@example.com" required>
</div>
<div class="form-group">
<label for="regNick">Имя (ник)</label>
<input type="text" class="form-control" id="regNick" name="nick" placeholder="Ваше имя" required>
</div>
<div class="form-group">
<label for="regPassword">Пароль</label>
<input type="password" class="form-control" id="regPassword" name="password" placeholder="Минимум 6 символов" minlength="6" required>
</div>
<div class="form-group">
<label for="regPassword2">Повторите пароль</label>
<input type="password" class="form-control" id="regPassword2" name="password2" placeholder="Повторите пароль" minlength="6" required>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success">Зарегистрироваться</button>
<button type="button" class="btn btn-link" onclick="$('#registerModal').modal('hide');$('#loginModal').modal('show');">Уже есть аккаунт? Войти</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Отмена</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -55,20 +55,7 @@ $oldIndex = $pagesCount+1;
<?php else: ?> <?php else: ?>
<br/> <br/>
<?php endif; ?> <?php endif; ?>
<div class="row">
<div class="col-md-12" style="text-align: center;">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Point - DOWN -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-0069680015252793"
data-ad-slot="4972494746"
data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
<hr/> <hr/>
<?= self::renderPartial('randomPoint.php', array('randomPoint'=>$randomPoint), true)?> <?= self::renderPartial('randomPoint.php', array('randomPoint'=>$randomPoint), true)?>
</div> </div>

View File

@ -7,7 +7,6 @@
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h4 style="text-align: center;">Контакты</h4> <h4 style="text-align: center;">Контакты</h4>
Телефон: <a href="tel:+79046106141">+7 (904) 610-6141</a><br/>
EMail: info&#64;wikipoints.ru<br/> EMail: info&#64;wikipoints.ru<br/>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">

View File

@ -51,16 +51,6 @@ $oldIndex = $pagesCount+1;
} }
?> ?>
<br/><br/> <br/><br/>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Point-TOP -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-0069680015252793"
data-ad-slot="2373587563"
data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<br/> <br/>
<h3><?= $header ?></h3> <h3><?= $header ?></h3>
@ -104,20 +94,6 @@ $oldIndex = $pagesCount+1;
<?php else: ?> <?php else: ?>
<br/> <br/>
<?php endif; ?> <?php endif; ?>
<div class="row">
<div class="col-md-12" style="text-align: center;">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Point - DOWN -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-0069680015252793"
data-ad-slot="4972494746"
data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
<hr/> <hr/>
<?= self::renderPartial('randomPoint.php', array('randomPoint'=>$randomPoint), true)?> <?= self::renderPartial('randomPoint.php', array('randomPoint'=>$randomPoint), true)?>
</div> </div>

View File

@ -45,17 +45,6 @@ if ($pointsAirport && $usersAirport && $pointsAirport->id != $usersAirport->id){
<a href="/page/instapoint/id/<?= $point->id ?>">4IG</a> <a href="/page/instapoint/id/<?= $point->id ?>">4IG</a>
<?php endif; ?> <?php endif; ?>
</div> </div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Point-TOP -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-0069680015252793"
data-ad-slot="2373587563"
data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<br/> <br/>
<div class="mainTextBlock"> <div class="mainTextBlock">
@ -141,7 +130,7 @@ if ($pointsAirport && $usersAirport && $pointsAirport->id != $usersAirport->id){
<?php endif; ?> <?php endif; ?>
<nobr>[ <span class="glyphicon glyphicon-user"></span> <a href="/user/<?= $point->authorUser->id ?>"><?= $point->authorUser->nick ?></a> - <span class="glyphicon glyphicon-pencil" title="<?= date('d-m-Y H:i', $point->date) ?>"></span> <?= $point->authorUser->getPointsCount() ?> ]</nobr> <nobr>[ <span class="glyphicon glyphicon-user"></span> <a href="/user/<?= $point->authorUser->id ?>"><?= $point->authorUser->nick ?></a> - <span class="glyphicon glyphicon-pencil" title="<?= date('d-m-Y H:i', $point->date) ?>"></span> <?= $point->authorUser->getPointsCount() ?> ]</nobr>
<?php if (App::$user && App::$user->isAdmin == 1): ?> <?php if (App::$user && App::$user->isAdmin == 1): ?>
<nobr>[ <span class="glyphicon glyphicon-new-window"></span> <a href="<?= $point->source ?>" target="_blank">источник: <?= $point->source ?></a> ]</nobr> <nobr>[ <span class="glyphicon glyphicon-new-window"></span> <a href="<?= $point->source ?>" target="_blank">источник: <?= mb_substr($point->source, 0, 40) ?></a> ]</nobr>
<?php endif; ?> <?php endif; ?>
</p> </p>
</div> </div>
@ -237,21 +226,6 @@ if ($pointsAirport && $usersAirport && $pointsAirport->id != $usersAirport->id){
<script charset="utf-8" src="//www.travelpayouts.com/widgets/394e02eacac3a5c9b000360787c2d5d2.js?v=727" async></script> <script charset="utf-8" src="//www.travelpayouts.com/widgets/394e02eacac3a5c9b000360787c2d5d2.js?v=727" async></script>
</div> </div>
</div> </div>
<?php else: ?>
<div class="row hideOnPrint">
<div class="col-md-12" style="text-align: center;">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Point - DOWN -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-0069680015252793"
data-ad-slot="4972494746"
data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
<?php endif; ?> <?php endif; ?>
<div class="row"> <div class="row">

View File

@ -90,4 +90,4 @@ if (App::$user && App::$user->id) {
</div><!--/.nav-collapse --> </div><!--/.nav-collapse -->
</div> </div>
</nav> </nav>
<?= App::$user ? '' : self::renderPartial('modals/login.php', null, true) ?> <?= App::$user ? '' : self::renderPartial('modals/login.php', null, true) . self::renderPartial('modals/register.php', null, true) ?>