REBORN - попытка залатать дырки и заставить работать. Трудимся вместе с deepseek
This commit is contained in:
parent
205fb64180
commit
bc1fb7572f
|
|
@ -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 — в следующей итерации
|
||||
|
|
@ -13,11 +13,11 @@ class IndexController extends Controller
|
|||
self::addScript('/js/bootstrap.min.js');
|
||||
self::addScript('/js/leaflet.js');
|
||||
|
||||
self::addScript('https://maps.google.com/maps/api/js?v=3');
|
||||
self::addScript('/js/tile/Google.js');
|
||||
// self::addScript('https://maps.google.com/maps/api/js?v=3');
|
||||
// self::addScript('/js/tile/Google.js');
|
||||
|
||||
self::addScript('https://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU');
|
||||
self::addScript('/js/tile/Yandex.js');
|
||||
// self::addScript('https://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU');
|
||||
// self::addScript('/js/tile/Yandex.js');
|
||||
|
||||
self::addScript('/js/app.js?ver=' . App::getConfig('version'));
|
||||
self::addScript('/js/jquery.cookie.js');
|
||||
|
|
@ -108,34 +108,76 @@ class IndexController extends Controller
|
|||
|
||||
static function actionLogin()
|
||||
{
|
||||
$source = file_get_contents('https://ulogin.ru/token.php?token=' . $_POST['token'] . '&host=' . $_SERVER['HTTP_HOST']);
|
||||
$uLoginUser = json_decode($source, true);
|
||||
$uLoginUser['identity'] = md5($uLoginUser['uid'] . $uLoginUser['network'] . '=P');
|
||||
$email = isset($_POST['email']) ? trim($_POST['email']) : '';
|
||||
$password = isset($_POST['password']) ? $_POST['password'] : '';
|
||||
|
||||
$user = User::model()->getByUID($uLoginUser['identity']);
|
||||
|
||||
if (!$user->id) {
|
||||
$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;
|
||||
}
|
||||
if (!$email || !$password) {
|
||||
$_SESSION['login_error'] = 'Заполните email и пароль.';
|
||||
App::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
|
||||
}
|
||||
|
||||
$target = App::getBasedir().'public/img/avatars/'.$user->id.'.jpg';
|
||||
Image::createAvatar($uLoginUser['photo_big'], $target);
|
||||
$user = User::model()->getByEmail($email);
|
||||
|
||||
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);
|
||||
unset($_SESSION['login_error']);
|
||||
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()
|
||||
{
|
||||
$xml = new SimpleXMLElement('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"/>');
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ class LpController extends Controller
|
|||
|
||||
public function __construct()
|
||||
{
|
||||
App::error404();
|
||||
self::$layout = 'layouts/lp.php';
|
||||
self::addScript('/js/jquery-2.1.0.min.js');
|
||||
self::addScript('/js/jquery-ui-1.10.4.custom.min.js');
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
return Point::model()->getCountByUser($this->id);
|
||||
|
|
|
|||
|
|
@ -70,18 +70,19 @@ function init(lat, lng) {
|
|||
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 © <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 © <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 © <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 © <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 © <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 © <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 © <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 © <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 © <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 © <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 © <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 © <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 15});
|
||||
layers['google'] = new L.Google('HYBRID');
|
||||
layers['yandexMap'] = new L.Yandex();
|
||||
layers['yandex'] = new L.Yandex('hybrid');
|
||||
// layers['google'] = new L.Google('HYBRID');
|
||||
// layers['yandexMap'] = new L.Yandex();
|
||||
// layers['yandex'] = new L.Yandex('hybrid');
|
||||
|
||||
if ($.cookie('mapLayer') && $.cookie('mapLayer') == 'quest') {
|
||||
setLayer('sputnik');
|
||||
if ($.cookie('mapLayer') && ($.cookie('mapLayer') != 'osm' || $.cookie('mapLayer') != 'topo')) {
|
||||
setLayer('osm');
|
||||
}
|
||||
|
||||
setLayer($.cookie('mapLayer') ? $.cookie('mapLayer') : 'sputnik');
|
||||
setLayer($.cookie('mapLayer') ? $.cookie('mapLayer') : 'osm');
|
||||
|
||||
initCategories(); // getPoints внутри
|
||||
|
||||
|
|
|
|||
|
|
@ -27,16 +27,11 @@ if (App::$user) {
|
|||
</div>
|
||||
<div id="box">
|
||||
<span id="boxClose" onclick="closeBox();">×</span>
|
||||
<div id="boxLayers">
|
||||
<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 sputnikLayer">⚫ </span><a onclick="setLayer('sputnik');return false;" class="layers sputnikLayer">OSM-Sputnik</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 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="boxLayers">
|
||||
<h3>Карты</h3>
|
||||
<span class="dot layers osmLayer">⚫ </span><a onclick="setLayer('osm');return false;" class="layers osmLayer">Open Street Map</a><br/>
|
||||
<span class="dot layers topoLayer">⚫ </span><a onclick="setLayer('topo');return false;" class="layers topoLayer">Генштаб от маршруты.ру</a><br/>
|
||||
</div>
|
||||
<div id="boxFilter">
|
||||
<h3>Фильтры и поиск</h3>
|
||||
<span class="input-group">
|
||||
|
|
@ -132,7 +127,7 @@ if (App::$user) {
|
|||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</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) : '' ?>
|
||||
<?= self::renderPartial('modals/categories.php', array('categories' => $categories), true) ?>
|
||||
<?= self::renderPartial('modals/image.php', array(), true) ?>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
<?php if ($scripts): ?>
|
||||
<?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 endif; ?>
|
||||
</html>
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
|
||||
<?php if ($scripts): ?>
|
||||
<?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 endif; ?>
|
||||
</html>
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<?php if ($scripts): ?>
|
||||
<?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 endif; ?>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<?php if ($scripts): ?>
|
||||
<?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 endif; ?>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<?php if ($scripts): ?>
|
||||
<?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 endif; ?>
|
||||
|
||||
|
|
|
|||
|
|
@ -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-dialog">
|
||||
<div class="modal-content">
|
||||
|
|
@ -6,18 +5,30 @@
|
|||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Вход на сайт</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center; padding-bottom: 0;">
|
||||
<p style="text-align: justify; text-indent: 15px;">
|
||||
Для добавления точек, создания коллекции точек в избранном, сохранения маршрутов и использования ряда других функций, необходимо выполнить вход на сайт. Вход осуществляется через учётную запись в любой социальной сети. При этом вам не нужно вводить пароль - всё очень просто!
|
||||
</p>
|
||||
<p style="text-align: justify; text-indent: 15px;">
|
||||
Мы сохраняем только ваше имя, ник и аватарку, не запрашивая лишних данных. Приятных путешествий!
|
||||
</p>
|
||||
<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>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Отмена</button>
|
||||
</div>
|
||||
<form method="post" action="/index/login/">
|
||||
<div class="modal-body" style="padding-bottom: 0;">
|
||||
<p style="text-align: justify; text-indent: 15px;">
|
||||
Для добавления точек, создания коллекции точек в избранном, сохранения маршрутов и использования ряда других функций, необходимо выполнить вход на сайт.
|
||||
</p>
|
||||
<?php if (isset($_SESSION['login_error']) && $_SESSION['login_error']): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($_SESSION['login_error']) ?></div>
|
||||
<?php unset($_SESSION['login_error']); ?>
|
||||
<?php endif; ?>
|
||||
<div class="form-group">
|
||||
<label for="loginEmail">Email</label>
|
||||
<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>
|
||||
|
|
@ -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">×</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>
|
||||
|
|
@ -55,20 +55,7 @@ $oldIndex = $pagesCount+1;
|
|||
<?php else: ?>
|
||||
<br/>
|
||||
<?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/>
|
||||
<?= self::renderPartial('randomPoint.php', array('randomPoint'=>$randomPoint), true)?>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
</div>
|
||||
<div class="col-md-4">
|
||||
<h4 style="text-align: center;">Контакты</h4>
|
||||
Телефон: <a href="tel:+79046106141">+7 (904) 610-6141</a><br/>
|
||||
EMail: info@wikipoints.ru<br/>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
|
|
|
|||
|
|
@ -51,16 +51,6 @@ $oldIndex = $pagesCount+1;
|
|||
}
|
||||
?>
|
||||
<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/>
|
||||
<h3><?= $header ?></h3>
|
||||
|
||||
|
|
@ -104,20 +94,6 @@ $oldIndex = $pagesCount+1;
|
|||
<?php else: ?>
|
||||
<br/>
|
||||
<?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/>
|
||||
<?= self::renderPartial('randomPoint.php', array('randomPoint'=>$randomPoint), true)?>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -45,17 +45,6 @@ if ($pointsAirport && $usersAirport && $pointsAirport->id != $usersAirport->id){
|
|||
<a href="/page/instapoint/id/<?= $point->id ?>">4IG</a>
|
||||
<?php endif; ?>
|
||||
</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/>
|
||||
|
||||
<div class="mainTextBlock">
|
||||
|
|
@ -141,7 +130,7 @@ if ($pointsAirport && $usersAirport && $pointsAirport->id != $usersAirport->id){
|
|||
<?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>
|
||||
<?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; ?>
|
||||
</p>
|
||||
</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>
|
||||
</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; ?>
|
||||
|
||||
<div class="row">
|
||||
|
|
|
|||
|
|
@ -90,4 +90,4 @@ if (App::$user && App::$user->id) {
|
|||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</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) ?>
|
||||
|
|
|
|||
Loading…
Reference in New Issue