wikipoints/controllers/JsonController.php

649 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
class JsonController extends Controller
{
/**
* Точки
*/
static function actionPoints()
{
if (App::$user && App::$user->isAdmin == 1) {
$points = Point::model()->getAll(array('where' => '`status` != "del"'));
} else {
$minEditDate = isset($_GET['time']) ? (int) $_GET['time'] : 0;
if (!isset($_GET['bounds']) || !isset($_GET['bounds'][0]) || !isset($_GET['bounds'][1]) || !isset($_GET['bounds'][2]) || !isset($_GET['bounds'][3])) {
$points = Point::model()->getAllPublished(false, $minEditDate);
} else {
$_GET['bounds'][0] = floatval($_GET['bounds'][0]);
$_GET['bounds'][1] = floatval($_GET['bounds'][1]);
$_GET['bounds'][2] = floatval($_GET['bounds'][2]);
$_GET['bounds'][3] = floatval($_GET['bounds'][3]);
$points = Point::model()->getAllPublished($_GET['bounds'], $minEditDate);
}
}
$categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));
$result = array();
foreach ($points as $point) {
$tempPoint['id'] = $point->id;
$tempPoint['name'] = $point->name;
$tempPoint['lat'] = $point->lat;
$tempPoint['lng'] = $point->lng;
$tempPoint['categoryId'] = $point->categoryId;
$tempPoint['status'] = $point->status;
$result[] = $tempPoint;
}
self::renderPartial('json.php', array(
'data' => $result,
));
}
/**
* Точка
*/
static function actionPoint()
{
$id = (int) App::getParam('id');
if ($id) {
$point = Point::model()->getByPK($id);
$point->descriptionHtml = Markdown::liteProcessing($point->description);
$point->descriptionHtml = nl2br($point->descriptionHtml);
$point->descriptionHtml = Helper::replaceLinks($point->descriptionHtml, 'js');
$point->name = htmlspecialchars($point->name);
$imgs = $point->photos;
$photosCount = 1;
if ($point->img == '' && !empty($imgs)) {
$img = array_shift($imgs);
$point->img = $img->name;
}
$imgs = $point->photos;
if (!empty($imgs)) {
$tmp = array();
$photosCount = count($imgs);
foreach ($imgs as $img) {
$tmp[] = $img->name;
}
$point->images = $tmp;
}
$extraParams = $point->getExtraParams();
if (!empty($extraParams)) {
$tmp = array();
foreach ($extraParams as $extraParam) {
$tmp[] = array($extraParam->name, $extraParam->value);
}
$point->extraParams = $tmp;
}
$categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));
$point->categoryIcon = $categories[$point->categoryId]['icon'];
$point->categoryName = $categories[$point->categoryId]['name'];
$point->photosCount = $photosCount;
$point->inFavorites = Favorite::model()->checkIsMy($id);
$point->iLike = Like::model()->checkIsMy($id);
self::renderPartial('json.php', $point->getValues());
} else {
App::error404();
}
}
/**
* Категории
*/
static function actionCategories()
{
$categories = Category::model()->getAll(array('order' => 'ord DESC', 'asArray' => true, 'noKeys' => true));
$categories[] = array(
"id" => "0",
"name" => "Все точки",
"icon" => "/ico/all.png",
"ord" => "0"
);
$categories = array_reverse($categories);
self::renderPartial('json.php', array(
'data' => $categories,
));
}
/**
* Добавление точки
*/
static function actionAddPoint()
{
$logName = isset($_POST['id']) && $_POST['id'] ? 'point_'.intval($_POST['id']) : 'point_0_NEW';
App::log('points/'.$logName, array(
'user' => App::$user ? App::$user->getValues() : NULL,
'POST' => $_POST,
));
$errors = array();
if (!App::$user) {
$errors[8] = 'Вы не авторизованы! Пожалуйста, войдите.';
}
if (isset($_POST['id']) && $_POST['id'] && App::$user->isAdmin == 0) {
$point = new Point();
$id = (int) $_POST['id'];
$point = $point->getByPK($id);
if ($point->author != App::$user->id || $point->status == Point::statusPublished) {
$errors[9] = 'Редактирование точек достурно только администратору или автору!';
}
}
$photos = $images = array();
if (empty($errors) && !App::$request['ajax'] && isset($_POST['id']) && (int) $_POST['id']) {
$id = (int) $_POST['id'];
$uploaddir = App::getBasedir().'public/photos/';
if (isset($_FILES) && !empty($_FILES)) {
foreach ($_FILES['photos']['name'] as $key => $fileName) {
$temp = pathinfo($_FILES['photos']['name'][$key]);
$extension = strtolower($temp['extension']) ? strtolower($temp['extension']) : 'jpg';
$photo = $id . strtolower('_' . substr(md5($fileName . time()), 0, 5) . '.' . $extension);
if (move_uploaded_file($_FILES['photos']['tmp_name'][$key], $uploaddir . $photo)) {
$photos[] = $photo;
}
}
}
if (isset($_POST['imgs']) && !empty($_POST['imgs'])) {
foreach ($_POST['imgs'] as $key => $img) {
if (mb_strpos($img, '://') !== false) {
$temp = pathinfo($img);
$extension = strtolower($temp['extension']) ? strtolower($temp['extension']) : 'jpg';
$photo = $id . strtolower('_' . substr(md5($img . time()), 0, 5) . '.' . $extension);
if (file_put_contents($uploaddir . $photo, file_get_contents($img))) {
PhotoLinks::addLink($photo, $img);
$images[] = $photo;
}
} else {
$images[] = $img;
}
}
}
$resPhotos = array();
$ordering = $_POST['ordering'];
foreach ($ordering as $order) {
$resPhotos[] = $order == 'FILE' ? array_shift($photos) : array_shift($images);
}
if (!empty($resPhotos)) {
App::DB()->query('DELETE FROM `poi`.`photos` WHERE `pointId` = ' . $id . ';');
$P = new Photo();
foreach ($resPhotos as $key => $photo) {
$P->add(array(
'pointId' => $id,
'name' => $photo,
'ord' => $key,
));
Image::createAllSizes($photo);
if ($ordering[$key] == 'FILE') {
PhotoLinks::addLink($photo, $_POST['photoLinks'][$key]);
}
}
$point = Point::model()->getByPK($id);
$point->img = '';
$point->save();
}
ExtraParams::model()->delByPoint($id);
$params = isset($_POST['extraParamNames']) ? $_POST['extraParamNames'] : NULL;
$values = isset($_POST['extraParamValues']) ? $_POST['extraParamValues'] : NULL;
if ($params && $values) {
foreach ($params as $paramIndex => $param) {
$paramName = $param;
$paramValue = isset($values[$paramIndex]) ? $values[$paramIndex] : NULL;
if ($paramName && $paramValue) {
ExtraParams::model()->add(array(
'pointId' => $point->id,
'name' => strip_tags($paramName),
'value' => strip_tags($paramValue),
));
}
}
}
App::redirect('/?point=' . $id);
}
if (isset($_POST['name'])) {
$_POST['name'] = strip_tags($_POST['name']);
}
if (isset($_POST['description'])) {
$_POST['description'] = strip_tags($_POST['description']);
}
if (!( isset($_POST['name']) && $_POST['name'] && strlen($_POST['name']) >= 5 )) {
$errors[1] = 'Неверное название точки';
}
if (!( isset($_POST['img']) && (int) $_POST['img'])) {
$errors[2] = 'Плохая ссылка на изображение';
}
$discriptionLimit = (App::$user && App::$user->isAdmin) ? 20 : 500;
if (!( isset($_POST['description']) && $_POST['description'] && strlen($_POST['description']) > $discriptionLimit )) {
$errors[3] = 'Слишком короткое описание';
}
if (!( isset($_POST['categoryId']) && $_POST['categoryId'] )) {
$errors[4] = 'Не задана категория точки';
}
if (!( isset($_POST['source']) )) {
$errors[5] = 'Не передано поле источкика информации. Допускается пустое значение.';
}
if (!( isset($_POST['lat']) && $_POST['lat'] )) {
$errors[6] = 'Ошибочное значение широты';
}
if (!( isset($_POST['lng']) && $_POST['lng'] )) {
$errors[7] = 'Ошибочное значение долготы';
}
if (!empty($errors)) {
header("HTTP/1.0 400 Bad Request");
header('Content-Type: application/json');
print json_encode($errors);
return false;
}
if (App::$request['ajax']) {
$point = new Point();
unset($_POST['img']);
if (isset($_POST['id']) && $_POST['id']) {
// Редактирование существующей точки
$id = (int) $_POST['id'];
$_POST['dateEdit'] = time();
$_POST['status'] = (App::$user && App::$user->isAdmin == 1) ? Point::getStatusByString($_POST['status']) : Point::statusModeration;
$point = $point->getByPK($id);
// Публикация ранее неопубликованной точки
if ($point->status == Point::statusModeration AND Point::getStatusByString($_POST['status']) == Point::statusPublished) {
Notifications::model()->add(array(
'userId' => $point->author,
'objectId' => $id,
'type' => Notifications::typePointConfirmed,
'date' => time(),
));
$_POST['ord'] = time();
}
if (Point::getStatusByString($_POST['status']) == Point::statusDel) {
Notifications::model()->add(array(
'userId' => $point->author,
'objectId' => $id,
'type' => Notifications::typePointDeleted,
'date' => time(),
));
$_POST['ord'] = time();
}
$point->setValues($_POST);
$point->save();
} else {
$_POST['author'] = App::$user->id;
$_POST['date'] = time();
$_POST['dateEdit'] = time();
$_POST['status'] = (App::$user && App::$user->isAdmin == 1) ? Point::getStatusByString($_POST['status']) : Point::statusModeration;
$_POST['ord'] = (App::$user && App::$user->isAdmin == 1) ? time() : 0;
$point->add($_POST);
if (!$point->id) {
header("HTTP/1.0 500 Internal Server Error");
die('Error 500 - Internal Server Error');
}
// SMS::send('#' . $point->id . ' ' . $point->name . ' :: ' . App::$user->nick);
Alarmer::send('Новая точка #' . $point->id . ' "' . $point->name . '" от ' . App::$user->nick . ' https://wikipoints.ru/?point=' . $point->id);
}
self::renderPartial('json.php', array(
'data' => $point->id
));
}
}
static function actionSaveRoute()
{
if (!(isset($_POST['name']) && $_POST['name'] && isset($_POST['points']) && $_POST['points'])) {
App::error404('Неправильное значение!');
}
$request = array(
'author' => App::$user->id,
'date' => time(),
'name' => $_POST['name'],
'points' => json_encode($_POST['points']),
);
$route = Route::model()->add($request);
self::renderPartial('json.php', $route->id);
}
static function actionRoute()
{
$id = (int) App::getParam('id');
if ($id) {
$route = Route::model()->getByPK($id);
self::renderPartial('json.php', $route->points);
} else {
App::error404();
}
}
static function actionDeleteRoute()
{
$id = (int) App::getParam('id');
if ($id && App::$user) {
$route = Route::model()->getByPK($id);
if ($route->author == App::$user->id) {
$route->delete($id);
}
self::renderPartial('json.php', true);
} else {
App::error404();
}
}
static function actionGeoCoding()
{
// ====== GOOGLE ============
$lat = $lng = FALSE;
$search = isset($_GET['search']) ? $_GET['search'] : '';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://maps.googleapis.com/maps/api/geocode/json?language=ru&key=AIzaSyDuWmguxO35oV9WGc6D8xUPvQBaUS4kt78&address=' . urlencode($search));
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_REFERER, "http://wikipoints.ru");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$out = curl_exec($ch);
if (!empty($out)) {
$obj = json_decode($out);
if ((string) $obj->status == 'OK') {
$count = count($obj->results);
if ($count > 0) {
$index = 0;
$name = (string) $obj->results[$index]->formatted_address;
$lat = (string) $obj->results[$index]->geometry->location->lat;
$lng = (string) $obj->results[$index]->geometry->location->lng;
$coords = array();
$coords['lat'] = $lat;
$coords['lng'] = $lng;
self::renderPartial('json.php', $coords);
die;
}
}
}
curl_close($ch);
// ========== YANDEX =============
$address = isset($_GET['search']) ? $_GET['search'] : '';
$res = @file_get_contents('http://geocode-maps.yandex.ru/1.x/?format=json&geocode=' . urlencode($address));
$res = json_decode($res, true);
if (isset($res['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos'])) {
$point = explode(' ', $res['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos']);
} else if (isset($res['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['Point']['pos'])) {
$point = explode(' ', $res['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['Point']['pos']);
} else {
$point = array(0, 0);
}
$coords = array();
$coords['lat'] = $point[1];
$coords['lng'] = $point[0];
self::renderPartial('json.php', $coords);
}
static function actionAddRemoveFavorites()
{
$id = (int) App::getParam('id');
if (!$id || !App::$user) {
App::error404();
}
self::renderPartial('json.php', Helper::boolval(Favorite::addRemove($id)));
}
static function actionAddRemoveLike()
{
$id = (int) App::getParam('id');
if (!$id || !App::$user) {
App::error404();
}
self::renderPartial('json.php', Helper::boolval(Like::addRemove($id)));
}
static function actionSearch()
{
$search = isset($_GET['query']) ? $_GET['query'] : '';
$results = array();
if ($search) {
App::log('searchQueries', $search);
// ====== POINTS ============
$points = Point::model()->searchByString($search);
if (!empty($points)) {
foreach ($points as $point) {
$results[] = array('value' => $point->name, 'data' => '/?point=' . $point->id);
}
}
if (count($results) < 10 && strlen($search) > 5) {
// ====== YANDEX ============
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://geocode-maps.yandex.ru/1.x/?geocode=' . urlencode($search));
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$out = null;
$out = curl_exec($ch);
if (!empty($out)) {
$obj = simplexml_load_string($out);
if (isset($obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found)) {
$count = (int) $obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found;
if ($count > 0) {
for ($index = 0; $index < $count && $index < 5 && count($results) < 25; $index++) {
$name = (string) $obj->GeoObjectCollection->featureMember[$index]->GeoObject->name;
$coords = explode(' ', (string) $obj->GeoObjectCollection->featureMember[$index]->GeoObject->Point->pos);
$lat = $coords[1];
$lng = $coords[0];
$results[] = array('value' => $name, 'data' => "/?lat=$lat&lng=$lng&zoom=13&marker=true");
}
} else if (isset($obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->Point)) {
$coords = explode(' ', (string) $obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->Point->pos);
$lat = $coords[1];
$lng = $coords[0];
$name = "Координаты N°" . $lat . ' E°' . $lng;
$results[] = array('value' => $name, 'data' => "/?lat=$lat&lng=$lng&zoom=13&marker=true");
}
}
}
curl_close($ch);
}
if (count($results) < 10 && strlen($search) > 5) {
// ====== GOOGLE ============
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://maps.googleapis.com/maps/api/geocode/json?language=ru&key=AIzaSyDuWmguxO35oV9WGc6D8xUPvQBaUS4kt78&address=' . urlencode($search));
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_REFERER, "http://wikipoints.ru");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$out = null;
$out = curl_exec($ch);
if (!empty($out)) {
$obj = json_decode($out);
if ((string) $obj->status == 'OK') {
$count = count($obj->results);
if ($count > 0) {
for ($index = 0; $index < $count && $index < 5 && count($results) < 25; $index++) {
$name = (string) $obj->results[$index]->formatted_address;
$lat = (string) $obj->results[$index]->geometry->location->lat;
$lng = (string) $obj->results[$index]->geometry->location->lng;
$results[] = array('value' => $name, 'data' => "/?lat=$lat&lng=$lng&zoom=13&marker=true");
}
}
}
}
curl_close($ch);
}
}
self::renderPartial('json.php', array('query' => $search, 'suggestions' => $results));
}
/**
* Article / K.O. =)
*/
static function actionArticle()
{
$id = (int) App::getParam('id');
if ($id) {
$article = Article::model()->getByPK($id);
if (!$article) {
die;
}
self::renderPartial('modals/article.php', array(
'title' => $article->title,
'text' => $article->html,
));
}
}
static function actionPointagreement()
{
$article = Article::model()->getByPK(4);
if (!$article) {
die;
}
self::renderPartial('modals/pointAgreement.php', array(
'title' => $article->title,
'text' => $article->html,
));
}
static function actionGetmyartphotos()
{
if (!App::$user) {
App::error404();
}
self::renderPartial('json.php', array(
'data' => ArticlePhotos::model()->getAll(
array(
'where' => '`owner` = ' . (int) App::$user->id,
'order' => '`id` DESC',
'asArray' => true,
'noKeys' => true
)
)
));
}
static function actionTrack()
{
$id = intval(App::getParam('id'));
if (!$id) {
App::error404();
}
$trip = Trips::model()->getByPK($id);
if ($trip->isEmpty() || ($trip->status != Trips::STATUS_PUBLIC && $trip->owner != App::$user->id)) {
App::error404();
}
$res = array(
'name' => $trip->name,
'time' => $trip->createdAt,
);
$resWayPoints = array();
$resTracks = array();
$resLatlngs = array();
$wayPoints = WayPoints::model()->getAll(array('where' => '`tripId` = ?'), array($trip->id));
if ($wayPoints) {
foreach ($wayPoints as $block) {
$resWayPoints[] = array(
'lat' => floatval($block->lat),
'lng' => floatval($block->lng),
'time' => strtotime($block->createdAt),
'name' => (string) $block->name,
'description' => nl2br($block->description),
);
}
}
$tracks = Tracks::model()->getAll(array('where' => '`tripId` = ?'), array($trip->id));
if ($tracks) {
foreach ($tracks as $track) {
$resLatlngs = array();
$trackPoints = TrackPoints::model()->getAll(array('where' => '`trackId` = ?'), array($track->id));
if ($trackPoints) {
foreach ($trackPoints as $trackPoint) {
$resLatlngs[] = array(
'lat' => $trackPoint->lat,
'lng' => $trackPoint->lng,
);
}
}
$resTracks[] = array(
'name' => (string) $track->name,
'length' => 0,
'latlngs' => $resLatlngs,
);
}
}
$res['wayPoints'] = $resWayPoints;
$res['tracks'] = $resTracks;
self::renderPartial('json.php', $res);
}
}