initial commit
|
@ -0,0 +1,330 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('incl/const.php');
|
||||
require('class/database.php');
|
||||
require('class/user.php');
|
||||
require('class/access_groups.php');
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$dbconn = $database->getConn();
|
||||
|
||||
$acc_obj = new access_group_Class($dbconn, $_SESSION['user']->id);
|
||||
$rows = $acc_obj->getRows();
|
||||
|
||||
$obj = new user_Class($dbconn, $_SESSION['user']->id);
|
||||
$users = $obj->getRowsArr();
|
||||
// admin is owned by super admin, so we have to add him to list
|
||||
$users[$_SESSION['user']->id] = $_SESSION['user']->name;
|
||||
|
||||
if(!isset($_SESSION['user']) || $_SESSION['user']->accesslevel != 'Admin') {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
|
||||
<head>
|
||||
<?php include("incl/meta.php"); ?>
|
||||
<link href="dist/css/table.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
var actions = `
|
||||
<a class="add" title="Add" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
<a class="edit" title="Edit" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
<a class="delete" title="Delete" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
`;
|
||||
//$("table td:last-child").html();
|
||||
// Append table with add row form on add new button click
|
||||
$(".add-new").click(function() {
|
||||
//var actions = $("table td:last-child").html();
|
||||
$(this).attr("disabled", "disabled");
|
||||
var index = $("table tbody tr:last-child").index();
|
||||
|
||||
var row = '<tr>';
|
||||
|
||||
$("table thead tr th").each(function(k, v) {
|
||||
if($(this).attr('data-editable') == 'false') {
|
||||
|
||||
if($(this).attr('data-action') == 'true') { // last child or actions cell
|
||||
row += '<td>'+actions+'</td>';
|
||||
}
|
||||
else {
|
||||
row += '<td></td>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($(this).attr('data-type') == 'select') {
|
||||
if($(this).attr('data-name') == 'userids') {
|
||||
row += `
|
||||
<td data-type="select" data-value="0">
|
||||
<select name="`+$(this).attr('data-name')+`" multiple>
|
||||
<?PHP foreach($users as $k => $v) { ?>
|
||||
`+
|
||||
`<option value="<?=$k?>"><?='('.$k.')'.$v?></option>`
|
||||
+`
|
||||
<?PHP } ?>
|
||||
</select>
|
||||
</td>
|
||||
`;
|
||||
}
|
||||
}
|
||||
else {
|
||||
row += ' <td> <input type = "text" class = "form-control" name="'+$(this).attr('data-name')+'"> </td>';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
row += '</tr>';
|
||||
|
||||
$("table").append(row);
|
||||
$("table tbody tr").eq(index + 1).find(".add, .edit").toggle();
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Add row on add button click
|
||||
$(document).on("click", ".add", function() {
|
||||
var obj = $(this);
|
||||
var empty = false;
|
||||
var input = $(this).parents("tr").find('input[type="text"], select');
|
||||
input.each(function() {
|
||||
if (!$(this).val()) {
|
||||
$(this).addClass("error");
|
||||
empty = true;
|
||||
} else {
|
||||
$(this).removeClass("error");
|
||||
}
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".error").first().focus();
|
||||
if (!empty) {
|
||||
var data = {};
|
||||
data['save'] = 1;
|
||||
data['id'] = $(this).closest('tr').attr('data-id');
|
||||
|
||||
input.each(function() {
|
||||
if($(this).closest('td').attr('data-type') == 'select') {
|
||||
var val = $(this).find('option:selected').text();
|
||||
$(this).parent("td").attr('data-value', $(this).val());
|
||||
$(this).parent("td").html(val);
|
||||
}
|
||||
else {
|
||||
$(this).parent("td").html($(this).val());
|
||||
}
|
||||
|
||||
data[$(this).attr('name')] = $(this).val();
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/access_groups.php',
|
||||
data: data,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
if(response.id) { // means, new record is added
|
||||
obj.closest('table').find('tr:last-child').attr('data-id', response.id);
|
||||
obj.closest('table').find('tr:last-child td:first-child').text(response.id)
|
||||
}
|
||||
alert(response.message)
|
||||
}
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".add, .edit").toggle();
|
||||
$(".add-new").removeAttr("disabled");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Edit row on edit button click
|
||||
$(document).on("click", ".edit", function() {
|
||||
$(this).parents("tr").find("td:not([data-editable=false])").each(function(k, v) {
|
||||
|
||||
if($(this).closest('table').find('thead tr th').eq(k).attr('data-editable') != 'false') {
|
||||
var name = $(this).closest('table').find('thead tr th').eq(k).attr('data-name');
|
||||
var id = $(this).closest('tr').attr('data-id');
|
||||
|
||||
if($(this).closest('table').find('thead tr th').eq(k).attr('data-type') == 'select') {
|
||||
if(name == 'userids') {
|
||||
$(this).html(`
|
||||
<select name="`+name+`" multiple>
|
||||
<?PHP foreach($users as $k => $v) { ?>
|
||||
<option value="<?=$k?>"><?='('.$k.')'.$v?></option>
|
||||
<?PHP } ?>
|
||||
</select>
|
||||
`);
|
||||
}
|
||||
var val = $(this).attr('data-value').split(',');
|
||||
$(this).find('[name='+name+']').val(val);
|
||||
}
|
||||
else {
|
||||
$(this).html(' <input type = "text" name="'+ name +'" class = "form-control" value = "' + $(this).text() + '" > ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".add, .edit").toggle(); $(".add-new").attr("disabled", "disabled");
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Delete row on delete button click
|
||||
$(document).on("click", ".delete", function() {
|
||||
var obj = $(this);
|
||||
var data = {'delete': true, 'id': obj.parents("tr").attr('data-id')}
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/access_groups.php',
|
||||
data: data,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
if(response.success) { // means, new record is added
|
||||
obj.parents("tr").remove();
|
||||
}
|
||||
|
||||
$(".add-new").removeAttr("disabled");
|
||||
alert(response.message);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div id="main-wrapper" data-layout="vertical" data-navbarbg="skin5" data-sidebartype="full"
|
||||
data-sidebar-position="absolute" data-header-position="absolute" data-boxed-layout="full">
|
||||
|
||||
<?php const MENU_SEL = 'access_groups.php';
|
||||
include("incl/topbar.php");
|
||||
include("incl/sidebar.php");
|
||||
?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
|
||||
<div class="page-breadcrumb" style="padding-left:30px; padding-right: 30px; padding-top:0px; padding-bottom: 0px">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<nav aria-label="breadcrumb">
|
||||
|
||||
</nav>
|
||||
<h1 class="mb-0 fw-bold">Access Groups</h1>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="text-end upgrade-btn">
|
||||
<!--<a href="https://www.wrappixel.com/templates/flexy-bootstrap-admin-template/" class="btn btn-primary text-white"
|
||||
target="_blank">Add New</a>-->
|
||||
|
||||
<button type="button" class="btn btn-primary text-white add-new">
|
||||
<i class="fa fa-plus"></i> Add New </button><br>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-name="id" data-editable='false'>ID</th>
|
||||
<th data-name="name">Name</th>
|
||||
<th data-name="userids" data-type="select">Users</th>
|
||||
<th data-editable='false' data-action='true'>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody> <?php while($row = pg_fetch_object($rows)): ?> <tr data-id="<?=$row->id?>" align="left">
|
||||
<td><?=$row->id?></td>
|
||||
<td><?= $row->name?></td>
|
||||
|
||||
<?php
|
||||
$grp_usrs = $acc_obj->getGroupUsers(array($row->id));
|
||||
$grp_id_usrs = array();
|
||||
foreach($grp_usrs as $id => $name){
|
||||
array_push($grp_id_usrs, '('.$id.')'.$name);
|
||||
}
|
||||
?>
|
||||
<td data-type="select" data-value="<?=implode(',',array_keys($grp_usrs))?>"><?=implode(', ',$grp_id_usrs)?></td>
|
||||
|
||||
<td>
|
||||
<a class="add" title="Add" data-toggle="tooltip"> <i class="material-icons"></i></a>
|
||||
<a class="edit" title="Edit" data-toggle="tooltip"> <i class="material-icons"></i></a>
|
||||
<a class="delete" title="Delete" data-toggle="tooltip"> <i class="material-icons"></i></a>
|
||||
</td>
|
||||
</tr> <?php endwhile; ?> </tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
||||
|
||||
<div class="col-12">
|
||||
|
||||
<div class="col-6">
|
||||
<p> </p>
|
||||
<div id = "repThumbnail" class = "alert alert-warning">
|
||||
<a href = "#" class = "close" data-dismiss = "alert">×</a>
|
||||
<strong>Note:</strong> Username is prefixed with its ID.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type = "text/javascript">
|
||||
$(function(){
|
||||
$(".close").click(function(){
|
||||
$("#repThumbnail").alert();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer text-center">
|
||||
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!--Menu sidebar -->
|
||||
<script src="dist/js/sidebarmenu.js"></script>
|
||||
<!--Custom JavaScript -->
|
||||
<script src="dist/js/custom.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('../incl/const.php');
|
||||
require('../class/database.php');
|
||||
require('../class/access_groups.php');
|
||||
|
||||
$result = ['success' => false, 'message' => 'Error while processing your request!'];
|
||||
|
||||
if(isset($_SESSION['user']) && $_SESSION['user']->accesslevel == 'Admin') {
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$obj = new access_group_Class($database->getConn(), $_SESSION['user']->id);
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
|
||||
if(($id > 0) && !$obj->isOwnedByUs($id)){
|
||||
$result = ['success' => false, 'message' => 'Action not allowed!'];
|
||||
|
||||
}else if(isset($_POST['save'])) {
|
||||
$newId = 0;
|
||||
|
||||
if($id) { // update
|
||||
$obj->update($_POST);
|
||||
}
|
||||
else { // insert
|
||||
$newId = $obj->create($_POST);
|
||||
}
|
||||
|
||||
$result = ['success' => true, 'message' => 'Data Successfully Saved!', 'id' => $newId];
|
||||
|
||||
} else if(isset($_POST['delete']) && ($id != 1)) {
|
||||
|
||||
if($obj->delete($id)){
|
||||
$result = ['success' => true, 'message' => 'Group Successfully Deleted!'];
|
||||
}else{
|
||||
$result = ['success' => false,'message' => 'Failed to delete group!'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
?>
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
require('../incl/const.php');
|
||||
require('../class/database.php');
|
||||
require('../class/user.php');
|
||||
|
||||
session_start();
|
||||
if(isset($_SESSION['user'])) {
|
||||
header("Location: ../../index.php");
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$user_obj = new user_Class($database->getConn(), 0);
|
||||
|
||||
if(isset($_POST['submit'])&&!empty($_POST['submit'])){
|
||||
$row = $user_obj->loginCheck($_POST['pwd'], $_POST['email']);
|
||||
if($row){
|
||||
$_SESSION['user'] = $row;
|
||||
header("Location: ../../index.php");
|
||||
}else{
|
||||
header("Location: ../../login.php?err=".urlencode('Error: Failed to login!'));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('../incl/const.php');
|
||||
require('../class/database.php');
|
||||
require('../class/map.php');
|
||||
require('../class/app.php');
|
||||
|
||||
function unzip_me($zipname){
|
||||
$ext_dir = '/tmp/uploads';
|
||||
if(!is_dir($ext_dir)){
|
||||
mkdir($ext_dir);
|
||||
}
|
||||
|
||||
$zip = new ZipArchive;
|
||||
$res = $zip->open($zipname);
|
||||
if ($res === TRUE) {
|
||||
$zip->extractTo($ext_dir);
|
||||
$zip->close();
|
||||
} else {
|
||||
echo 'Error: Failed to open'.$zipname;
|
||||
}
|
||||
return $ext_dir;
|
||||
}
|
||||
|
||||
function zip2html_dir($upload, $upload_dir){
|
||||
|
||||
$unzip_dir = unzip_me($upload["tmp_name"]);
|
||||
$name = basename($upload["name"]);
|
||||
$name = explode('.', $name)[0];
|
||||
|
||||
|
||||
if(is_file($unzip_dir.'/index.html')){
|
||||
$html_dir = $upload_dir.'/'.$name;
|
||||
rename($unzip_dir, $html_dir);
|
||||
}else if(is_file($unzip_dir.'/'.$name.'/index.html')){
|
||||
$html_dir = $unzip_dir.'/'.$name;
|
||||
}else{
|
||||
echo 'Error: index.html not found';
|
||||
$html_dir = null;
|
||||
}
|
||||
return $html_dir;
|
||||
}
|
||||
|
||||
$result = ['success' => false, 'message' => 'Error while processing your request!'];
|
||||
|
||||
if(isset($_SESSION['user']) && $_SESSION['user']->accesslevel == 'Admin') {
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$obj = new map_Class($database->getConn(), $_SESSION['user']->id);
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
|
||||
if(($id > 0) && !$obj->isOwnedByUs($id)){
|
||||
$result = ['success' => false, 'message' => 'Action not allowed!'];
|
||||
|
||||
}else if(isset($_POST['save'])) {
|
||||
$newId = 0;
|
||||
|
||||
if($id) { // update
|
||||
|
||||
$newId = $obj->update($_POST) ? $id : 0;
|
||||
if($newId > 0){
|
||||
$html_dir = APPS_DIR.'/'.$newId;
|
||||
App::updateDatasources($_POST, $html_dir, DATA_DIR, APPS_DIR);
|
||||
}
|
||||
|
||||
} else if(!empty($_POST['app']) || !empty($_FILES['archive'])){ // insert
|
||||
|
||||
$newId = $obj->create($_POST);
|
||||
|
||||
if(!is_dir(CACHE_DIR.'/'.$newId)){
|
||||
mkdir(CACHE_DIR.'/'.$newId, 0770);
|
||||
}
|
||||
|
||||
if($newId > 0){
|
||||
$upload_dir = App::upload_dir($_SESSION['user']->ftp_user);
|
||||
$html_dir = null;
|
||||
$unzip_dir = null;
|
||||
// html dir can be in /var/www/upload or in /tmp, if its an upload
|
||||
if(isset($_POST['app'])){
|
||||
$html_dir = $upload_dir.'/'.$_POST['app'];
|
||||
}else if(!empty($_FILES["archive"]["tmp_name"])){ // if we have uploaded file
|
||||
$html_dir = zip2html_dir($_FILES["archive"], $upload_dir);
|
||||
}
|
||||
|
||||
if($html_dir){
|
||||
App::installApp($newId, $_POST, $html_dir, DATA_DIR, APPS_DIR); // process map data files
|
||||
if($unzip_dir){
|
||||
App::rrmdir($unzip_dir);
|
||||
}
|
||||
}else{
|
||||
$obj->delete($newId);
|
||||
$newId = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($newId > 0){
|
||||
if(isset($_FILES["image"]) && ($_FILES['image']['size'] < 10485760)){ // if image file and is less than 10 MB
|
||||
$image = null;
|
||||
// scale image to 200x150
|
||||
if($_FILES["image"]["type"] == 'image/png'){
|
||||
$image = imagecreatefrompng($_FILES["image"]["tmp_name"]);
|
||||
}else if($_FILES["image"]["type"] == 'image/jpeg'){
|
||||
$image = imagecreatefromjpeg($_FILES["image"]["tmp_name"]);
|
||||
}
|
||||
|
||||
if($image){
|
||||
$imgResized = imagescale($image , 200, 150);
|
||||
imagepng($imgResized, "../../assets/maps/".$newId.'.png');
|
||||
}
|
||||
}
|
||||
|
||||
$result = ['success' => true, 'message' => 'Map successfully created!', 'id' => $newId];
|
||||
}else{
|
||||
$result = ['success' => false, 'message' => 'Failed to save Map!'];
|
||||
}
|
||||
} else if(isset($_POST['delete'])) {
|
||||
|
||||
$result = $obj->getById($_POST['id']);
|
||||
$row = pg_fetch_assoc($result);
|
||||
pg_free_result($result);
|
||||
|
||||
if($obj->delete(intval($_POST['id']))){
|
||||
|
||||
App::uninstallApp($row['name'], DATA_DIR, APPS_DIR);
|
||||
|
||||
$result = ['success' => true, 'message' => 'Data Successfully Deleted!'];
|
||||
}else{
|
||||
$result = ['success' => false, 'message' => 'Error: Data Not Deleted!'];
|
||||
}
|
||||
|
||||
} else if(isset($_POST['clear'])) {
|
||||
$map_cache_dir = CACHE_DIR.'/'.$_POST['id'];
|
||||
|
||||
if(is_dir($map_cache_dir)){
|
||||
$dir_size = 0;
|
||||
|
||||
$files = scandir($map_cache_dir);
|
||||
foreach($files as $f){
|
||||
if(is_file($map_cache_dir.'/'.$f)){
|
||||
$dir_size += filesize($map_cache_dir.'/'.$f);
|
||||
unlink($map_cache_dir.'/'.$f);
|
||||
}
|
||||
}
|
||||
|
||||
rmdir($map_cache_dir);
|
||||
|
||||
$unit = 'bytes';
|
||||
if($dir_size > (1024*1024)){
|
||||
$dir_size = $dir_size / (1024*1024);
|
||||
$unit = 'Mbytes';
|
||||
} else if($dir_size > 1024){
|
||||
$dir_size = $dir_size / 1024;
|
||||
$unit = 'kbytes';
|
||||
}
|
||||
|
||||
$result = ['success' => true, 'message' => 'Successfully removed '.sprintf("%.2f %s", $dir_size, $unit)];
|
||||
}else{
|
||||
$result = ['success' => false, 'message' => 'Error: No cache!'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
?>
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('../incl/const.php');
|
||||
require('../class/database.php');
|
||||
require('../class/map.php');
|
||||
require('../class/permalink.php');
|
||||
|
||||
$result = ['success' => false, 'message' => 'Error while processing your request!'];
|
||||
|
||||
if(isset($_SESSION['user']) && $_SESSION['user']->accesslevel == 'Admin') {
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$obj = new permalink_Class($database->getConn(), $_SESSION['user']->id);
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] == 'GET'){ // if called from map directly
|
||||
// make a 1 visit permalink, expiring in 1 hour
|
||||
if(!empty($_GET['permalink'])){
|
||||
$row = $obj->getMap($_GET['permalink']);
|
||||
$_POST['map_id'] = $row['map_id'];
|
||||
$_POST['query'] = str_replace('permalink='.$_GET['permalink'].'&', '', $_SERVER['QUERY_STRING']);
|
||||
}else{
|
||||
$_POST['map_id'] = $_GET['id'];
|
||||
$_POST['query'] = $_GET['loc'];
|
||||
}
|
||||
$_POST['description'] = 'Permalink for map '.$_POST['map_id'];
|
||||
$_POST['visits_limit'] = 1;
|
||||
$_POST['expires'] = "1 hour";
|
||||
$_POST['save'] = true;
|
||||
}
|
||||
|
||||
if(($id > 0) && !$obj->isOwnedByUs($id)){
|
||||
$result = ['success' => false, 'message' => 'Action not allowed!'];
|
||||
|
||||
}else if(isset($_POST['save'])) {
|
||||
$newId = 0;
|
||||
|
||||
if(isset($_POST['id'])) { // update
|
||||
if($obj->update($_POST)){
|
||||
$result = ['success' => true, 'message' => 'Permalink Successfully Updated!'];
|
||||
}else{
|
||||
$result = ['success' => false, 'message' => 'Permalink Not Updated!'];
|
||||
}
|
||||
|
||||
} else { // insert
|
||||
|
||||
$map_obj = new map_Class($database->getConn(), $_SESSION['user']->id);
|
||||
$res = $map_obj->getById($_POST['map_id']);
|
||||
$map_row = pg_fetch_assoc($res);
|
||||
|
||||
$hash_data = $_SERVER['HTTP_USER_AGENT'].date('m/d/Y h:i:s a', time());
|
||||
$hash_data .= $_POST['map_id'].$_POST['description'].$_POST['expires'].$_POST['visits_limit'];
|
||||
$_POST['hash'] = hash('md5', $hash_data);
|
||||
|
||||
list($newId,$created,$expires) = $obj->create($_POST);
|
||||
if($newId > 0){
|
||||
|
||||
$perma_url = 'apps/'. $_POST['map_id'].'/index.php?permalink='.$_POST['hash'];
|
||||
|
||||
$result = ['success' => true, 'message' => 'Data Successfully Saved!',
|
||||
'id' => $newId, 'hash' => $_POST['hash'], 'url'=> $perma_url,'created'=>$created, 'expires'=>$expires ];
|
||||
|
||||
}else{
|
||||
$result = ['success' => false, 'message' => 'Data Not Saved!'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else if(isset($_POST['delete'])) {
|
||||
if($obj->delete(intval($_POST['id']))){
|
||||
$result = ['success' => true, 'message' => 'Data Successfully Deleted!'];
|
||||
}else{
|
||||
$result = ['success' => false, 'message' => 'Error: Data Not Deleted!'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
?>
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
require_once('../incl/const.php');
|
||||
require_once('../class/database.php');
|
||||
require_once('../class/user.php');
|
||||
require_once('../class/signup.php');
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\SMTP;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
|
||||
require '../class/PHPMailer/Exception.php';
|
||||
require '../class/PHPMailer/PHPMailer.php';
|
||||
require '../class/PHPMailer/SMTP.php';
|
||||
|
||||
function send_verify_email_smtp($name, $email, $url){
|
||||
try {
|
||||
//Create an instance; passing `true` enables exceptions
|
||||
$mail = new PHPMailer(true);
|
||||
|
||||
//TODO: move this to setup.php
|
||||
$mail->SMTPDebug = SMTP::DEBUG_OFF; //Enable verbose debug output
|
||||
//$mail->SMTPDebug = SMTP::DEBUG_SERVER; //Enable verbose debug output
|
||||
$mail->isSMTP(); //Send using SMTP
|
||||
$mail->Host = SMTP_HOST; //Set the SMTP server to send through
|
||||
$mail->SMTPAuth = true; //Enable SMTP authentication
|
||||
$mail->Username = SMTP_USER; //SMTP username
|
||||
$mail->Password = SMTP_PASS; //SMTP password
|
||||
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; //Enable implicit TLS encryption
|
||||
$mail->Port = SMTP_PORT; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
|
||||
|
||||
//Recipients
|
||||
$mail->setFrom(SMTP_USER, 'Signup Mailer');
|
||||
$mail->addAddress($email, $name); //Add a recipient
|
||||
//$mail->addAddress('ellen@example.com'); //Name is optional
|
||||
$mail->addReplyTo(SMTP_USER, 'Information');
|
||||
//$mail->addCC('cc@example.com');
|
||||
//$mail->addBCC('bcc@example.com');
|
||||
|
||||
//Attachments
|
||||
//$mail->addAttachment('/var/tmp/file.tar.gz'); //Add attachments
|
||||
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); //Optional name
|
||||
|
||||
//Content
|
||||
$mail->isHTML(true); //Set email format to HTML
|
||||
$mail->Subject = 'QatMaps Verification Email ';
|
||||
|
||||
$email_html = file_get_contents('../snippets/verify_email.html');
|
||||
$email_html = str_replace('USER_NAME', $name, $email_html);
|
||||
$email_html = str_replace('VERIFY_URL', $url, $email_html);
|
||||
$mail->Body = $email_html;
|
||||
$mail->AltBody = 'Click to verify your email '.$url;
|
||||
|
||||
$mail->send();
|
||||
return true;
|
||||
|
||||
} catch (Exception $e) {
|
||||
//die("Message could not be sent. Mailer Error: {$mail->ErrorInfo}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function send_verify_email($name, $email, $url){
|
||||
$to = $email;
|
||||
$subject = 'Verification Email for PostGIS Sync';
|
||||
$message = 'Hello '.$name.' here is your verification link for PostGIS Sync <a href="'.$url.'">'.$url.'</a>.';
|
||||
$headers = 'From: noreply@'.$_SERVER['SERVER_NAME'] . "\r\n" .
|
||||
'Reply-To: noreply@'.$_SERVER['SERVER_NAME'] . "\r\n" .
|
||||
'X-Mailer: PHP/' . phpversion();
|
||||
|
||||
mail($to, $subject, $message, $headers);
|
||||
}
|
||||
|
||||
if(isset($_SESSION['user'])) {
|
||||
header("Location: ../../index.php");
|
||||
}
|
||||
|
||||
$loc = '../../signup.php?err='.urlencode('Error: Bad request!');
|
||||
|
||||
if(!empty($_POST['name']) && !empty($_POST['email']) && !empty($_POST['password']) ){
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$obj = new signup_Class($database->getConn());
|
||||
$uobj = new user_Class($database->getConn(), SUPER_ADMIN_ID);
|
||||
|
||||
$urow = $uobj->getByEmail($_POST['email']);
|
||||
if($urow){
|
||||
$loc = '../../signup.php?err='.urlencode('Error: Email is already registered!');
|
||||
}else{
|
||||
|
||||
$_POST['verify'] = hash('sha256', $_POST['name'].$_POST['email'].$_POST['password'].date("D M j G:i:s T Y"));
|
||||
$_POST['password'] = password_hash($_POST['password'], PASSWORD_DEFAULT);
|
||||
|
||||
$newId = $obj->create($_POST);
|
||||
if($newId > 0){
|
||||
|
||||
$verify_url = 'https://'.$_SERVER['SERVER_NAME'].str_replace('signup.php', 'verify.php', $_SERVER['REQUEST_URI'])
|
||||
. '?id='.$newId.'&verify='.urlencode($_POST['verify']);
|
||||
|
||||
if(!send_verify_email_smtp($_POST['name'], $_POST['email'], $verify_url)){
|
||||
$obj->delete($newId);
|
||||
$loc = '../../signup.php?err='.urlencode('Error: Failed to signup!');
|
||||
}else{
|
||||
$loc = '../../login.php?msg='.urlencode('Your verification email has been sent!');
|
||||
}
|
||||
}else{ // error
|
||||
$loc = '../../signup.php?err='.urlencode('Error: Failed to signup!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: '.$loc);
|
||||
?>
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('../incl/const.php');
|
||||
require('../class/database.php');
|
||||
require('../class/user.php');
|
||||
|
||||
$result = ['success' => false, 'message' => 'Error while processing your request!'];
|
||||
|
||||
if(isset($_SESSION['user']) && $_SESSION['user']->accesslevel == 'Admin') {
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$obj = new user_Class($database->getConn(), $_SESSION['user']->id);
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
|
||||
if(($id > 0) && !$obj->isOwnedByUs($id)){
|
||||
$result = ['success' => false, 'message' => 'Action not allowed!'];
|
||||
|
||||
}else if(isset($_POST['save'])) {
|
||||
$newId = 0;
|
||||
|
||||
if($id) { // update
|
||||
$obj->update($_POST);
|
||||
}
|
||||
else { // insert
|
||||
$newId = $obj->create($_POST);
|
||||
}
|
||||
|
||||
$result = ['success' => true, 'message' => 'Data Successfully Saved!', 'id' => $newId];
|
||||
|
||||
} else if(isset($_POST['delete']) && ($id != 1)) {
|
||||
|
||||
$ref_ids = array();
|
||||
$ref_name = null;
|
||||
$tbls = array('map', 'access_groups', 'permalink');
|
||||
|
||||
foreach($tbl as $k){
|
||||
$rows = $database->getAll('public.'.$k, 'owner_id = '.$id);
|
||||
foreach($rows as $row){
|
||||
$ref_ids[] = $row[$k.'_id'];
|
||||
}
|
||||
|
||||
if(count($ref_ids) > 0){
|
||||
$ref_name = $k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(count($ref_ids) > 0){
|
||||
$result = ['success' => false, 'message' => 'Error: Can\'t delete because user owns '.$ref_name.'(s) ' . implode(',', $ref_ids) . '!' ];
|
||||
}else {
|
||||
|
||||
$result = $obj->getById($id);
|
||||
$row = pg_fetch_assoc($result);
|
||||
pg_free_result($result);
|
||||
|
||||
$ret_val = $obj->delete($id);
|
||||
if($ret_val){
|
||||
shell_exec('sudo /usr/local/bin/delete_ftp_user.sh '.$row['ftp_user']);
|
||||
}
|
||||
$result = ['success' => $ret_val, 'message' => 'Data Successfully Deleted!'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
?>
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
require_once('../incl/const.php');
|
||||
require_once('../class/database.php');
|
||||
require_once('../class/signup.php');
|
||||
require_once('../class/user.php');
|
||||
require_once('../class/access_groups.php');
|
||||
|
||||
$loc = '../../signup.php?err='.urlencode('Error: Bad verify request!');
|
||||
|
||||
if( !empty($_GET['id']) && !empty($_GET['verify']) ){
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$obj = new signup_Class($database->getConn());
|
||||
|
||||
$result = $obj->verify($_GET['id'], $_GET['verify']);
|
||||
if(!$result || (pg_num_rows($result) > 0)){
|
||||
|
||||
$row = pg_fetch_assoc($result);
|
||||
pg_free_result($result);
|
||||
|
||||
$row['accesslevel'] = 'Admin';
|
||||
$row['groups'] = [1]; // Default group
|
||||
|
||||
$email_user = explode('@', $row['email'])[0];
|
||||
$row['ftp_user'] = $email_user.$row['id'];
|
||||
|
||||
// create a new user
|
||||
$uobj = new user_Class($database->getConn(), SUPER_ADMIN_ID);
|
||||
$newId = $uobj->create($row, true);
|
||||
if($newId){
|
||||
user_Class::create_ftp_user($row['ftp_user'], $row['email'], $row['password']);
|
||||
|
||||
// create def access group for new admin
|
||||
$def_grp = array('name' => $row['ftp_user'], 'userids' => array($newId));
|
||||
$acc_obj = new access_group_Class($database->getConn(), $newId);
|
||||
$grp_id = $acc_obj->create($def_grp);
|
||||
|
||||
if($grp_id > 0){
|
||||
$row['id'] = $newId;
|
||||
$row['groups'] = array($grp_id);
|
||||
$uobj->update($row);
|
||||
|
||||
$obj->delete($_GET['id']); // remove signup request
|
||||
$loc = '../../login.php?msg='.urlencode('Congratulations '.$row['name'].'. Your verification is successfull !');
|
||||
}else{
|
||||
$loc = '../../signup.php?err='.urlencode('Error: Failed to create group!');
|
||||
}
|
||||
}else{
|
||||
$loc = '../../signup.php?err='.urlencode('Error: Failed to create user!');
|
||||
}
|
||||
|
||||
}else{ // error
|
||||
$loc = '../../signup.php?err='.urlencode('Error: Invalid verify request!');
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: '.$loc);
|
||||
?>
|
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 365 B |
After Width: | Height: | Size: 563 B |
After Width: | Height: | Size: 563 B |
After Width: | Height: | Size: 666 B |
After Width: | Height: | Size: 666 B |
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PHPMailer Exception class.
|
||||
* PHP Version 5.5.
|
||||
*
|
||||
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||
*
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
* @author Brent R. Matzelle (original founder)
|
||||
* @copyright 2012 - 2020 Marcus Bointon
|
||||
* @copyright 2010 - 2012 Jim Jagielski
|
||||
* @copyright 2004 - 2009 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
namespace PHPMailer\PHPMailer;
|
||||
|
||||
/**
|
||||
* PHPMailer exception handler.
|
||||
*
|
||||
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
/**
|
||||
* Prettify error message output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorMessage()
|
||||
{
|
||||
return '<strong>' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "</strong><br />\n";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
class access_group_Class
|
||||
{
|
||||
private $table_name = 'access_groups';
|
||||
private $dbconn = null;
|
||||
private $owner_id = null;
|
||||
|
||||
function __construct($dbconn, $owner_id) {
|
||||
$this->dbconn = $dbconn;
|
||||
$this->owner_id = $owner_id;
|
||||
}
|
||||
|
||||
function create($data)
|
||||
{
|
||||
$sql = "INSERT INTO PUBLIC." .$this->table_name." (name,owner_id) ".
|
||||
"VALUES('".$this->cleanData($data['name'])."',".$this->owner_id.") RETURNING id";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return 0;
|
||||
}
|
||||
|
||||
$row = pg_fetch_object($result);
|
||||
pg_free_result($result);
|
||||
|
||||
if($row) {
|
||||
# insert report access
|
||||
$values = array();
|
||||
foreach($data['userids'] as $user_id){
|
||||
array_push($values, "(".$user_id.",".$row->id.")");
|
||||
}
|
||||
|
||||
$sql = "insert into public.user_access (user_id,access_group_id) values ".implode(',', $values);
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return 0;
|
||||
}
|
||||
pg_free_result($result);
|
||||
|
||||
return $row->id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getRows()
|
||||
{
|
||||
$sql ="select * from public." .$this->table_name;
|
||||
if($this->owner_id != SUPER_ADMIN_ID){
|
||||
$sql .= " WHERE owner_id = ".$this->owner_id;
|
||||
}
|
||||
$sql .= " ORDER BY id DESC";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getRowsArr(){
|
||||
$rv = array();
|
||||
|
||||
$sql = "select id,name from public.".$this->table_name;
|
||||
if($this->owner_id != SUPER_ADMIN_ID){
|
||||
$sql .= " WHERE owner_id = ".$this->owner_id;
|
||||
}
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rv[$row['id']] = $row['name'];
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function getGroupUsers($gids){
|
||||
$rv = array();
|
||||
|
||||
$sql = "select id,name from public.user WHERE id in (select user_id from public.user_access where access_group_id in (".implode(',', $gids)."))";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rv[$row['id']] = $row['name'];
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function getGroupMapGroups($gids){
|
||||
$rv = array();
|
||||
|
||||
$sql = "select id,name from public.map WHERE id in (SELECT map_id from public.map_access where access_group_id IN (".implode(',', $gids)."))";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rv[$row['id']] = $row['name'];
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function getByUserId($user_id){
|
||||
$rv = array();
|
||||
|
||||
$sql ="select id,name from public.access_groups WHERE id in (SELECT access_group_id from public.user_access where user_id='".intval($user_id)."')";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rv[$row['id']] = $row['name'];
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function getGroupById($id){
|
||||
$sql ="select * from public." .$this->table_name . " where id='".intval($id)."'";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getGroupByName($name){
|
||||
$sql ="select * from public." .$this->table_name . " where name='".$name."'";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
$row = pg_fetch_assoc($result);
|
||||
pg_free_result($result);
|
||||
return $row;
|
||||
}
|
||||
|
||||
function delete($id){
|
||||
|
||||
$sql ="delete from public.user_access where access_group_id='".intval($id)."'";
|
||||
if($this->owner_id != SUPER_ADMIN_ID){
|
||||
$sql .= " AND owner_id = ".$this->owner_id;
|
||||
}
|
||||
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(pg_affected_rows($result) >= 0){
|
||||
pg_free_result($result);
|
||||
|
||||
$sql ="delete from public.map_access where access_group_id='".intval($id)."'";
|
||||
if($this->owner_id != SUPER_ADMIN_ID){
|
||||
$sql .= " AND owner_id = ".$this->owner_id;
|
||||
}
|
||||
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(pg_affected_rows($result) >= 0){
|
||||
pg_free_result($result);
|
||||
|
||||
$sql ="delete from public." .$this->table_name . " where id='".intval($id)."'";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
$rv = (pg_affected_rows($result) >= 0);
|
||||
pg_free_result($result);
|
||||
|
||||
return $rv;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function update($data=array()) {
|
||||
$sql = "update public.access_groups set name='".$this->cleanData($data['name'])."' where id = '".intval($data['id'])."' ";
|
||||
$rv = pg_affected_rows(pg_query($this->dbconn, $sql));
|
||||
|
||||
if($rv > 0){
|
||||
|
||||
$sql ="delete from public.user_access where access_group_id='".intval($data['id'])."'";
|
||||
$rv = pg_query($this->dbconn, $sql);
|
||||
|
||||
# insert report access
|
||||
$values = array();
|
||||
|
||||
foreach($data['userids'] as $user_id){
|
||||
array_push($values, "(".$user_id.",".$data['id'].")");
|
||||
}
|
||||
|
||||
$sql = "insert into public.user_access (user_id,access_group_id) values ".implode(',', $values);
|
||||
$ret = pg_query($this->dbconn, $sql);
|
||||
}
|
||||
}
|
||||
|
||||
function isOwnedByUs($id){
|
||||
|
||||
if($this->owner_id == SUPER_ADMIN_ID){ // if Super Admin
|
||||
return true;
|
||||
}
|
||||
|
||||
$sql = "select * from public.".$this->table_name." where id=".$id." and owner_id=".$this->owner_id;
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
$rv = (pg_num_rows($result) > 0);
|
||||
pg_free_result($result);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function cleanData($val)
|
||||
{
|
||||
return pg_escape_string($this->dbconn, $val);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,500 @@
|
|||
<?php
|
||||
|
||||
const TIME_MAP = array('week' => 604800, 'day' => 86400, 'hour' => 3600, 'minute' => 60, 'off' => 0);
|
||||
|
||||
class App {
|
||||
|
||||
public static function rrmdir($dir) {
|
||||
if (is_dir($dir)) {
|
||||
$objects = scandir($dir);
|
||||
foreach ($objects as $object) {
|
||||
if ($object != "." && $object != "..") {
|
||||
if (is_dir($dir. DIRECTORY_SEPARATOR .$object) && !is_link($dir."/".$object))
|
||||
App::rrmdir($dir. DIRECTORY_SEPARATOR .$object);
|
||||
else
|
||||
unlink($dir. DIRECTORY_SEPARATOR .$object);
|
||||
}
|
||||
}
|
||||
rmdir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
public static function find_per($cache_seconds){
|
||||
foreach(TIME_MAP as $per => $val){
|
||||
if($cache_seconds >= $val){
|
||||
return $per;
|
||||
}
|
||||
}
|
||||
return 'off';
|
||||
}
|
||||
|
||||
public static function parseDatasources($html_dir, $lines = null){
|
||||
$ds = array();
|
||||
$ls = array();
|
||||
$use_dt = false;
|
||||
|
||||
if($lines == null){
|
||||
$lines = file($html_dir.'/index.php');
|
||||
}
|
||||
|
||||
foreach ($lines as $i => $line) {
|
||||
if(preg_match('/const SHOW_DATATABLES = (.*);/', $line, $matches)){
|
||||
$use_dt = ($matches[1] == 'true');
|
||||
|
||||
}else if(preg_match('/<script src="data_(file|pg|gs)(\d+)\.php" data\-jfn="(.*)"/', $line, $matches)){
|
||||
$dsi = $matches[2];
|
||||
$v = array('data_type' => $matches[1], 'line' => $line, 'ln' => $i, 'name' => $matches[3], 'json_filename' => $matches[3],
|
||||
'pg_host' => '', 'pg_db' => '', 'pg_user' => '', 'pg_pwd' => '', 'pg_port' => 5432,
|
||||
'gs_host' => '', 'gs_user' => '', 'gs_pwd' => '', 'gs_ws' => '',
|
||||
'pg_cache_per' => 'minutes', 'pg_cache_val' => '',
|
||||
'gs_cache_per' => 'minutes', 'gs_cache_val' => '');
|
||||
|
||||
$content = null;
|
||||
if($matches[1] == 'pg'){
|
||||
$content = file_get_contents($html_dir.'/data_pg'.$matches[2].'.php');
|
||||
if(preg_match('/new Database\("(.*)", "(.*)", "(.*)", "(.*)", (\d+),/', $content, $pg_matches)){
|
||||
$v['pg_host'] = $pg_matches[1];
|
||||
$v['pg_db'] = $pg_matches[2];
|
||||
$v['pg_user'] = $pg_matches[3];
|
||||
$v['pg_pwd'] = $pg_matches[4];
|
||||
$v['pg_port'] = $pg_matches[5];
|
||||
}
|
||||
|
||||
}else if($matches[1] == 'gs'){
|
||||
$content = file_get_contents($html_dir.'/data_gs'.$matches[2].'.php');
|
||||
if(preg_match('/:\/\/(.*):(.*)@(.*)\/geoserver\/.*&typeName=(.*):/', $content, $gs_matches)){
|
||||
$v['gs_host'] = $matches[1];
|
||||
$v['gs_user'] = $matches[2];
|
||||
$v['gs_pwd'] = $matches[3];
|
||||
$v['gs_ws'] = $matches[4];
|
||||
}
|
||||
}
|
||||
|
||||
if($content && preg_match('/\$CACHE_PERIOD = ([0-9]+)/', $content, $matches)) {
|
||||
$cache_seconds = $matches[1];
|
||||
$per = App::find_per($cache_seconds);
|
||||
$v[$v['data_type'].'_cache_val'] = (TIME_MAP[$per] == 0) ? 0 : $cache_seconds / TIME_MAP[$per];
|
||||
$v[$v['data_type'].'_cache_per'] = $per;
|
||||
}
|
||||
|
||||
$ds[$dsi] = $v;
|
||||
|
||||
}else if(preg_match('/<\?php include\("layer_(wms|gs_geo)(\d+)\.php"\); \?>/', $line, $matches)){
|
||||
$lyi = $matches[2];
|
||||
$v = array('layer_type' => $matches[1], 'line' => $line, 'ln' => $i, 'name' => '',
|
||||
'ly_ws' => '', 'ly_layer' => '', 'ly_user' => '', 'ly_pwd' => '',
|
||||
'wms_user' => '', 'wms_pwd' => '', 'wms_url' => '',
|
||||
'gs_geo_host' => '', 'gs_geo_user' => '', 'gs_geo_pwd' => '', 'gs_geo_ws' => '', 'gs_geo_layer' => '',
|
||||
'gs_geo_color' => '', 'gs_geo_opacity' => '', 'gs_geo_fill_color' => '', 'gs_geo_fill_opacity' => '',
|
||||
'gs_geo_cache_per' => 'minutes', 'gs_geo_cache_val' => '');
|
||||
|
||||
$content = file_get_contents($html_dir.'/layer_wms'.$lyi.'.php');
|
||||
|
||||
if(preg_match('/var (.*) = L\.(WMS\.layer|geoJson\()/', $content, $var_matches)){
|
||||
$v['layer_varname'] = $var_matches[1];
|
||||
}
|
||||
|
||||
if(preg_match('/var .* = L\.WMS\.layer\("(.*)", "(.*):(.*)",\s+{/', $content, $matches)){
|
||||
if(str_starts_with($matches[1], 'proxy_wms')){ // if secured through proxy
|
||||
$content = file_get_contents($html_dir.'/'.$matches[1]);
|
||||
if(preg_match('/const BASE_URL = \'http[s]?:\/\/(.*):(.*)@(.*)\';/', $content, $url_matches)){
|
||||
$v['wms_user'] = $url_matches[1];
|
||||
$v['wms_pwd'] = $url_matches[2];
|
||||
$v['wms_url'] = $url_matches[3];
|
||||
}
|
||||
}else{
|
||||
$v['wms_url'] = $matches[1];
|
||||
}
|
||||
$v['wms_ws'] = $matches[2];
|
||||
$v['wms_layer'] = $matches[3];
|
||||
}
|
||||
$v['name'] = $v['wms_ws'].':'.$v['wms_layer'];
|
||||
|
||||
if(is_file($html_dir.'/layer_gs_geo'.$lyi.'.php')){
|
||||
$content = file_get_contents($html_dir.'/layer_gs_geo'.$lyi.'.php');
|
||||
if(preg_match('/:\/\/(.*):(.*)@(.*)\/geoserver\/.*&typeName=(.*):([^&]+)/', $content, $matches)){
|
||||
$v['gs_geo_host'] = $matches[3];
|
||||
$v['gs_geo_user'] = $matches[1];
|
||||
$v['gs_geo_pwd'] = $matches[2];
|
||||
$v['gs_geo_ws'] = $matches[4];
|
||||
$v['gs_geo_layer'] = $matches[5];
|
||||
}
|
||||
|
||||
if(preg_match('/color: "(.*)",/', $content, $matches)){ $v['gs_geo_color'] = $matches[1]; }
|
||||
if(preg_match('/fillColor: "(.*)",/', $content, $matches)){ $v['gs_geo_fill_color'] = $matches[1]; }
|
||||
if(preg_match('/opacity: ([0-9\.]+),/', $content, $matches)){ $v['gs_geo_opacity'] = $matches[1]; }
|
||||
if(preg_match('/fillOpacity: "([0-9\.]+)",/', $content, $matches)){ $v['gs_geo_fill_opacity'] = $matches[1]; }
|
||||
|
||||
if(preg_match('/\$CACHE_PERIOD = ([0-9]+)/', $content, $matches)) {
|
||||
$cache_seconds = $matches[1];
|
||||
$per = App::find_per($cache_seconds);
|
||||
$v['gs_geo_cache_val'] = (TIME_MAP[$per] == 0) ? 0 : $cache_seconds / TIME_MAP[$per];
|
||||
$v['gs_geo_cache_per'] = $per;
|
||||
}
|
||||
}
|
||||
|
||||
$ls[$lyi] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return [$ds, $ls, $use_dt];
|
||||
}
|
||||
|
||||
public static function update_template($src, $dest, $vars){
|
||||
|
||||
$lines = file($src);
|
||||
$fp = fopen($dest, 'w');
|
||||
|
||||
foreach($lines as $ln => $line){
|
||||
foreach($vars as $k => $v){
|
||||
if(str_contains($line, $k)){
|
||||
$line = str_replace($k, $v, $line);
|
||||
}
|
||||
}
|
||||
fwrite($fp, $line);
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
private static function extract_varname($filename){
|
||||
// extract varname from first line of data file
|
||||
$js_fp = fopen($filename, 'r');
|
||||
$line = fread($js_fp, 1024);
|
||||
fclose($js_fp);
|
||||
|
||||
$eq_pos = strpos($line, '=');
|
||||
$js_varname_decl = substr($line, 0, $eq_pos); // var json_neighborhoods_2
|
||||
$js_varname = explode(' ', $js_varname_decl)[1]; // json_neighborhoods_2
|
||||
return $js_varname;
|
||||
}
|
||||
|
||||
public static function updateDatasources($details, $html_dir, $data_dir, $apps_dir){
|
||||
$changes = 0;
|
||||
$js_varnames = array();
|
||||
$lines = file($html_dir.'/index.php');
|
||||
list($fds,$lys,$use_dt) = App::parseDatasources($html_dir, $lines); // file data sources
|
||||
|
||||
$newId = $details['id'];
|
||||
|
||||
foreach($fds as $dsi => $ds) {
|
||||
|
||||
if( empty($details['data_type'.$dsi])){ // if we have datasource from form
|
||||
continue;
|
||||
}
|
||||
|
||||
$json_filename = $ds['json_filename'];
|
||||
|
||||
$js_varname = App::extract_varname($data_dir.'/'.$newId.'/'.$json_filename);
|
||||
if(isset($details['use_datatable'])){
|
||||
array_push($js_varnames, $js_varname);
|
||||
}
|
||||
|
||||
// update fds lines
|
||||
if($details['data_type'.$dsi] == 'file'){
|
||||
|
||||
$vars = ['MAP_ID_VALUE' => $newId,
|
||||
'DATA_FILE' => '../../../data/'.$newId.'/'. $json_filename
|
||||
];
|
||||
App::update_template('../snippets/data_file.php', $html_dir.'/data_file'.$dsi.'.php', $vars);
|
||||
|
||||
$lines[$ds['ln']] = '<script src="data_file'.$dsi.'.php" data-jfn="'.$json_filename.'"></script>'."\n";
|
||||
$changes = $changes + 1;
|
||||
}else{
|
||||
// extract PG table from filename
|
||||
$pg_tbl = null;
|
||||
if(preg_match('/([a-z]+)/', $json_filename, $matches)){
|
||||
$pg_tbl = $matches[1];
|
||||
}
|
||||
|
||||
if($details['data_type'.$dsi] == 'pg'){
|
||||
|
||||
$cache_seconds = TIME_MAP[$details['pg_cache_per'.$dsi]] * intval($details['pg_cache_val'.$dsi]);
|
||||
|
||||
$vars = [ 'MAP_ID_VALUE' => $newId, 'VARNAME' => $js_varname, 'CACHE_PERIOD_SECONDS' => $cache_seconds,
|
||||
'PG_HOST' => $details['pg_host'.$dsi], 'PG_DB' => $details['pg_db'.$dsi],
|
||||
'PG_USER' => $details['pg_user'.$dsi], 'PG_PWD' => $details['pg_pwd'.$dsi],
|
||||
'PG_PORT' => $details['pg_port'.$dsi], 'PG_TBL' => $pg_tbl
|
||||
];
|
||||
App::update_template('../snippets/data_pg.php', $html_dir.'/data_pg'.$dsi.'.php', $vars);
|
||||
$lines[$ds['ln']] = '<script src="data_pg'.$dsi.'.php" data-jfn="'.$json_filename.'"></script>'."\n";
|
||||
$changes = $changes + 1;
|
||||
|
||||
}else if($details['data_type'.$dsi] == 'gs'){
|
||||
|
||||
$cache_seconds = TIME_MAP[$details['gs_cache_per'.$dsi]] * intval($details['gs_cache_val'.$dsi]);
|
||||
|
||||
$proto = 'https://';
|
||||
$url = '';
|
||||
if(0 === strpos($details['gs_host'.$dsi], 'https://')){
|
||||
$url = substr($details['gs_host'.$dsi], 8);
|
||||
}else if(0 === strpos($details['gs_host'.$dsi], 'http://')){
|
||||
$proto = 'http://';
|
||||
$url = substr($details['gs_host'.$dsi], 7);
|
||||
}else{
|
||||
$url = $details['gs_host'.$dsi]; //only hostname, no proto
|
||||
}
|
||||
$gs_layer = $pg_tbl;
|
||||
|
||||
$full_url = $proto.$details['gs_user'.$dsi].":".$details['gs_pwd'.$dsi].'@'.$url. "/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=" . $details['gs_ws'.$dsi] . ":" . $gs_layer . "&maxFeatures=3000&outputFormat=application/json";
|
||||
|
||||
$vars = ['MAP_ID_VALUE' => $newId, 'VARNAME' => $js_varname, 'CACHE_PERIOD_SECONDS' => $cache_seconds,
|
||||
'FULL_URL' => $full_url,
|
||||
];
|
||||
App::update_template('../snippets/data_gs.php', $html_dir.'/data_gs'.$dsi.'.php', $vars);
|
||||
$lines[$ds['ln']] = '<script src="data_gs'.$dsi.'.php" data-jfn="'.$json_filename.'"></script>'."\n";
|
||||
$changes = $changes + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sidebar_included = false;
|
||||
foreach($lys as $lyi => $ly) {
|
||||
|
||||
if( empty($details['layer_type'.$lyi]) ){ // if we have layer from form
|
||||
continue;
|
||||
}
|
||||
|
||||
// update fds lines
|
||||
if($details['layer_type'.$lyi] == 'wms'){
|
||||
|
||||
// update url,ws,layer in WMS file
|
||||
$content = file_get_contents($html_dir.'/layer_wms'.$lyi.'.php');
|
||||
|
||||
if(!empty($details['wms_user'.$lyi])){ // if WMS is secured
|
||||
$wms_url = $details['wms_url'.$lyi];
|
||||
$pos = strpos($wms_url, '://');
|
||||
$auth_url = substr($wms_url, 0, $pos).'://'.$details['wms_user'.$lyi].':'.$details['wms_pwd'.$lyi].'@'.substr($wms_url, $pos + 3);
|
||||
|
||||
$vars = [ 'MAP_ID' => $newId, 'BASE_URL_VALUE' => $auth_url ];
|
||||
App::update_template('../snippets/proxy_wms.php', $html_dir.'/proxy_wms'.$lyi.'.php', $vars);
|
||||
|
||||
$details['wms_url'.$lyi] = 'proxy_wms'.$lyi.'.php';
|
||||
}
|
||||
|
||||
$replacement = ' = L.WMS.layer("'.$details['wms_url'.$lyi].'", "'.$details['wms_ws'.$lyi].':'.$details['wms_layer'.$lyi].'", {';
|
||||
$content = preg_replace('/ = L\.WMS\.layer\("(.*)", "(.*):(.*)",\s+{/', $replacement, $content);
|
||||
file_put_contents($html_dir.'/layer_wms'.$lyi.'.php', $content);
|
||||
|
||||
$lines[$ly['ln']] = '<?php include("layer_wms'.$lyi.'.php"); ?>'."\n";
|
||||
$changes = $changes + 1;
|
||||
|
||||
}else if($details['layer_type'.$lyi] == 'gs_geo'){
|
||||
|
||||
$cache_seconds = TIME_MAP[$details['gs_geo_cache_per'.$lyi]] * intval($details['gs_geo_cache_val'.$lyi]);
|
||||
|
||||
// add layer varname to show up in datatables
|
||||
array_push($js_varnames, $details['layer_varname'.$lyi].'_data');
|
||||
|
||||
$proto = 'https://';
|
||||
$url = '';
|
||||
if(0 === strpos($details['gs_geo_host'.$lyi], 'https://')){
|
||||
$url = substr($details['gs_geo_host'.$lyi], 8);
|
||||
}else if(0 === strpos($details['gs_geo_host'.$lyi], 'http://')){
|
||||
$proto = 'http://';
|
||||
$url = substr($details['gs_geo_host'.$lyi], 7);
|
||||
}else{
|
||||
$url = $details['gs_geo_host'.$lyi]; //only hostname, no proto
|
||||
}
|
||||
|
||||
$full_url = $proto.$details['gs_geo_user'.$lyi].":".$details['gs_geo_pwd'.$lyi].'@'.$url. "/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=" . $details['gs_geo_ws'.$lyi] . ":" . $details['gs_geo_layer'.$lyi] . "&maxFeatures=3000&outputFormat=application/json";
|
||||
|
||||
$vars = ['VARNAME' => $details['layer_varname'.$lyi], 'FULL_URL' => $full_url, 'CACHE_PERIOD_SECONDS' => $cache_seconds, 'MAP_ID_VALUE' => $newId,
|
||||
'STYLE_COLOR' => $details['gs_geo_color'.$lyi], 'STYLE_OPACITY' => $details['gs_geo_opacity'.$lyi],
|
||||
'STYLE_FILL_COLOR' => $details['gs_geo_fill_color'.$lyi], 'STYLE_FILL_OPACITY' => $details['gs_geo_fill_opacity'.$lyi],
|
||||
];
|
||||
|
||||
App::update_template('../snippets/layer_gs_geo.php', $html_dir.'/layer_gs_geo'.$lyi.'.php', $vars);
|
||||
|
||||
$line = '';
|
||||
if(!$sidebar_included){
|
||||
$line = 'map.addControl(new sidebarControl());';
|
||||
$sidebar_included = true; // include sidebar once
|
||||
}
|
||||
$line .= '<?php include("layer_gs_geo'.$lyi.'.php"); ?>'."\n";
|
||||
|
||||
$lines[$ly['ln']] = $line;
|
||||
$changes = $changes + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($details['use_datatable']) != $use_dt){
|
||||
$changes = $changes + 1;
|
||||
}
|
||||
|
||||
// update the file
|
||||
if($changes){
|
||||
$show_dt_updated = false;
|
||||
|
||||
$fp = fopen($html_dir.'/index.php', 'w');
|
||||
foreach($lines as $line){
|
||||
|
||||
if(!$show_dt_updated){
|
||||
if(preg_match('/const SHOW_DATATABLES = /', $line, $matches)){
|
||||
$line = 'const SHOW_DATATABLES = '.(isset($details['use_datatable']) ? 'true' : 'false').';'."\n";
|
||||
|
||||
}else if(preg_match('/const JS_VARNAMES = array\(/', $line, $matches)){
|
||||
$line = 'const JS_VARNAMES = array("'.implode('","', $js_varnames).'");'."\n";
|
||||
$show_dt_updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite($fp, $line);
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
public static function upload_dir($username){
|
||||
$ftp_home = shell_exec('grep "^'.$username.':" /etc/passwd | cut -f6 -d:');
|
||||
$upload_dir = substr($ftp_home, 0, -1);
|
||||
return $upload_dir;
|
||||
}
|
||||
|
||||
public static function copy_r($source, $target){
|
||||
if ( is_dir( $source ) ) {
|
||||
@mkdir( $target );
|
||||
$d = dir( $source );
|
||||
while ( FALSE !== ( $entry = $d->read() ) ) {
|
||||
if ( $entry == '.' || $entry == '..' ) {
|
||||
continue;
|
||||
}
|
||||
$Entry = $source . '/' . $entry;
|
||||
if ( is_dir( $Entry ) ) {
|
||||
App::copy_r( $Entry, $target . '/' . $entry );
|
||||
} else {
|
||||
copy( $Entry, $target . '/' . $entry );
|
||||
}
|
||||
}
|
||||
|
||||
$d->close();
|
||||
}else {
|
||||
copy( $source, $target );
|
||||
}
|
||||
}
|
||||
|
||||
public static function installApp($newId, $details, $html_dir, $data_dir, $apps_dir){
|
||||
|
||||
// move html dir to apps
|
||||
App::copy_r($html_dir, $apps_dir.'/'.$newId);
|
||||
// work in new html dir
|
||||
$html_dir = $apps_dir.'/'.$newId;
|
||||
|
||||
// index.html -> index.php
|
||||
rename($html_dir.'/index.html', $html_dir.'/index.php');
|
||||
|
||||
$auth_lines = file_get_contents('../snippets/index_prefix.php');
|
||||
$auth_lines = str_replace('MAP_ID', $newId, $auth_lines);
|
||||
|
||||
if(isset($details['use_datatable'])){
|
||||
$auth_lines = preg_replace('/const SHOW_DATATABLES = false;/', 'const SHOW_DATATABLES = true;', $auth_lines);
|
||||
}
|
||||
|
||||
//insert our php auth code above <!doctype html> in index.php
|
||||
$content = file_get_contents($html_dir.'/index.php');
|
||||
file_put_contents($html_dir.'/index.php', $auth_lines . $content);
|
||||
|
||||
// data directory outside of /var/www/html to /var/www/data
|
||||
rename($html_dir.'/data', $data_dir.'/'.$newId);
|
||||
|
||||
// Replace sources to data files
|
||||
$lines = file($html_dir.'/index.php');
|
||||
|
||||
$fp = fopen($html_dir.'/index.php', "w");
|
||||
|
||||
$no_exec = '<?php if(empty(DB_HOST)){ die("Error: Can\'t execute!"); } ?>';
|
||||
$di = 0; $li = 0;
|
||||
|
||||
for($i=0; $i < count($lines); $i++){
|
||||
$line = $lines[$i];
|
||||
|
||||
if(preg_match('/src="data\/(.*)"/', $line, $matches)){
|
||||
$json_filename = $matches[1];
|
||||
|
||||
$vars = [ 'MAP_ID_VALUE' => $newId,
|
||||
'DATA_FILE' => '../../../data/'.$newId.'/'. $json_filename ];
|
||||
App::update_template('../snippets/data_file.php', $html_dir.'/data_file'.$di.'.php', $vars);
|
||||
|
||||
$line = '<script src="data_file'.$di.'.php" data-jfn="'.$json_filename.'"></script>'."\n";
|
||||
$di = $di + 1;
|
||||
|
||||
}else if(preg_match('/var (.*) = L\.WMS\.layer\("(.*)", "(.*):(.*)",\s+{/', $line, $matches)){
|
||||
|
||||
if(!empty($details['wms_user'.$li])){ // if WMS is secured
|
||||
$wms_url = $matches[2];
|
||||
$pos = strpos($wms_url, '://');
|
||||
$auth_url = substr($wms_url, 0, $pos).'://'.$details['wms_user'.$li].':'.$details['wms_pwd'.$li].'@'.substr($wms_url, $pos + 3);
|
||||
|
||||
$vars = [ 'MAP_ID' => $newId, 'BASE_URL_VALUE' => $auth_url ];
|
||||
App::update_template('../snippets/proxy_wms.php', $html_dir.'/proxy_wms'.$li.'.php', $vars);
|
||||
|
||||
$line = str_replace($wms_url, 'proxy_wms'.$li.'.php', $line);
|
||||
}
|
||||
|
||||
$wms_content = $line;
|
||||
|
||||
$lb = substr_count($line, '{'); //left brackets
|
||||
$rb = substr_count($line, '}'); //right brackets
|
||||
|
||||
while($lb > $rb){
|
||||
$i++;
|
||||
$line = $lines[$i];
|
||||
$wms_content .= $line;
|
||||
$lb += substr_count($line, '{'); //left brackets
|
||||
$rb += substr_count($line, '}'); //right brackets
|
||||
}
|
||||
|
||||
file_put_contents($html_dir.'/layer_wms'.$li.'.php', $no_exec."\n".$wms_content);
|
||||
$line = 'var '.$matches[1].' = <?php include("layer_wms'.$li.'.php"); ?>'."\n";
|
||||
$li = $li + 1;
|
||||
|
||||
}else if(str_contains($line, 'src="js/leaflet.pattern.js"')){
|
||||
$line .= '<script src="../../assets/dist/js/sidebar_control.js"></script>'."\n";
|
||||
$line .= '<script src="../../assets/dist/js/leaflet.browser.print.min.js"></script>'. "\n";
|
||||
|
||||
}else if(str_contains($line, 'map.attributionControl.setPrefix')){
|
||||
|
||||
$line = file_get_contents('../snippets/datatables_control.php'). "\n".$line;
|
||||
$line = file_get_contents('../snippets/permalink_control.js'). "\n".$line;
|
||||
|
||||
}else if(str_contains($line, '<body>')){
|
||||
$line .= file_get_contents('../snippets/index_header.php');
|
||||
|
||||
}else if(str_contains($line, '</body>')){
|
||||
|
||||
$line = file_get_contents('../snippets/datatables.php')."\n".$line;
|
||||
$line = file_get_contents('../snippets/permalink_modal.html')."\n".$line;
|
||||
|
||||
}else if(str_contains($line, 'width:')){
|
||||
|
||||
if(str_contains($lines[$i-1], '#map {')){
|
||||
$line = 'width: 100%;'."\n";
|
||||
}
|
||||
|
||||
}else if(str_contains($line, 'var measureControl')){
|
||||
$line = '<?php if($loc) {?>map.flyTo([<?=$loc[1]?>, <?=$loc[2]?>], <?=$loc[0]?>);<?php } ?>'. "\n". $line;
|
||||
$line = file_get_contents('../snippets/print_control.js') . "\n" . $line;
|
||||
}
|
||||
|
||||
fwrite($fp, $line);
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
public static function uninstallApp($id, $data_dir, $apps_dir){
|
||||
App::rrmdir($data_dir.'/'.$id);
|
||||
App::rrmdir($apps_dir.'/'.$id);
|
||||
}
|
||||
|
||||
public static function getApps($apps_dir) {
|
||||
$rv = array();
|
||||
$entries = scandir($apps_dir);
|
||||
foreach($entries as $e){
|
||||
if(is_dir($apps_dir.'/'.$e) && !str_starts_with($e, '.')){
|
||||
array_push($rv, $e);
|
||||
}
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
};
|
||||
?>
|
|
@ -0,0 +1,138 @@
|
|||
<?PHP
|
||||
class Database {
|
||||
private $connection;
|
||||
|
||||
function __construct($db_host, $db_name, $db_user, $db_pass, $db_port, $db_schema) {
|
||||
$this->connection = pg_connect("dbname={$db_name} user={$db_user} password={$db_pass} host={$db_host} port={$db_port}");
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
pg_close($this->connection);
|
||||
}
|
||||
|
||||
function modify($str) {
|
||||
return ucwords(str_replace("_", " ", $str));
|
||||
}
|
||||
|
||||
function getConn() {
|
||||
return $this->connection;
|
||||
}
|
||||
function getAll($table, $where = '', $orderby = '') {
|
||||
$orderby = $orderby ? 'ORDER BY '.$orderby : '';
|
||||
$where = $where ? 'WHERE '.$where : '';
|
||||
|
||||
$query = "SELECT * FROM {$table} {$where} {$orderby}";
|
||||
$result = pg_query($this->connection, $query);
|
||||
|
||||
if (!$result) {
|
||||
echo "An error occurred executing the query.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch all rows
|
||||
$rows = array();
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
|
||||
function get($table, $where = '') {
|
||||
if(is_numeric($where)) {
|
||||
$where = "id = ".intval($where);
|
||||
}
|
||||
else if (empty($where)) {
|
||||
$where = "1";
|
||||
}
|
||||
|
||||
$query = "SELECT * FROM {$table} WHERE $where";
|
||||
$result = pg_query($this->connection, $query);
|
||||
|
||||
if (!$result) {
|
||||
echo "An error occurred executing the query.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch one rows
|
||||
$row = pg_fetch_assoc($result);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
|
||||
/* Select Query */
|
||||
function select($query) {
|
||||
$result = pg_query($this->connection, $query);
|
||||
|
||||
if (!$result) {
|
||||
echo "An error occurred executing the query.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch all rows
|
||||
$rows = array();
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
function buildGeoJSON($query){
|
||||
$qc_id = 0; # NOTE: counter needed by qgis2web ?
|
||||
echo '{"type": "FeatureCollection",
|
||||
"features": [';
|
||||
|
||||
$feature = array('type' => 'Feature');
|
||||
|
||||
$result = pg_query($this->connection, $query);
|
||||
if ($result) {
|
||||
$sep = '';
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$feature['geometry'] = json_decode($row['geojson'], true);
|
||||
# Remove geojson and geometry fields from properties
|
||||
unset($row['geojson']);
|
||||
unset($row['geom']);
|
||||
$row['qc_id'] = $qc_id; $qc_id = $qc_id + 1;
|
||||
$feature['properties'] = $row;
|
||||
|
||||
echo $sep."\n".json_encode($feature, JSON_NUMERIC_CHECK);
|
||||
$sep = ',';
|
||||
}
|
||||
pg_free_result($result);
|
||||
}
|
||||
|
||||
echo ']}';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function find_srid($schema, $tbl, $geom){
|
||||
/*$query = "SELECT Find_SRID('".$schema."','".$tbl."','".$geom."')";
|
||||
$result = pg_query($this->connection, $query);
|
||||
|
||||
if (!$result) {
|
||||
echo "An error occurred executing the query.\n";
|
||||
exit;
|
||||
}
|
||||
$row = pg_fetch_assoc($result);
|
||||
pg_free_result($result);
|
||||
|
||||
return $row['find_srid'];*/
|
||||
return 4326;
|
||||
}
|
||||
|
||||
function getGeoJSON($schema, $tbl, $geom){
|
||||
if(!empty($where)){
|
||||
$where = 'WHERE '.$where;
|
||||
}
|
||||
|
||||
$srid = $this->find_srid($schema, $tbl, $geom);
|
||||
|
||||
$query = 'SELECT *, public.ST_AsGeoJSON(public.ST_Transform(('.$tbl.'.'.$geom.'),'.$srid.')) AS geojson FROM "'.$schema.'"."'.$tbl.'"';
|
||||
return $this->buildGeoJSON($query);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
class map_Class
|
||||
{
|
||||
private $table_name = 'map';
|
||||
private $dbconn = null;
|
||||
private $owner_id = null;
|
||||
|
||||
function __construct($dbconn, $owner_id) {
|
||||
$this->dbconn = $dbconn;
|
||||
$this->owner_id = $owner_id;
|
||||
}
|
||||
|
||||
function create($data)
|
||||
{
|
||||
$sql = "INSERT INTO PUBLIC." .$this->table_name."
|
||||
(name,description,owner_id) "."VALUES('".
|
||||
$this->cleanData($data['name'])."','".
|
||||
$this->cleanData($data['description'])."',".$this->owner_id.") RETURNING id";
|
||||
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return 0;
|
||||
}
|
||||
|
||||
$row = pg_fetch_object($result);
|
||||
pg_free_result($result);
|
||||
|
||||
if($row) {
|
||||
# insert into access groups
|
||||
$values = array();
|
||||
foreach($data['accgrps'] as $group_id){
|
||||
array_push($values, "(".$group_id.",".$row->id.")");
|
||||
}
|
||||
|
||||
$sql = "insert into public.map_access (access_group_id,map_id) values ".implode(',', $values);
|
||||
$ret = pg_query($this->dbconn, $sql);
|
||||
|
||||
return $row->id;
|
||||
}
|
||||
return 0;
|
||||
|
||||
//return pg_affected_rows(pg_query($this->dbconn, $sql));
|
||||
}
|
||||
|
||||
function getRows(){
|
||||
$sql ="select * from public." .$this->table_name;
|
||||
if($this->owner_id != SUPER_ADMIN_ID){
|
||||
$sql .= " WHERE owner_id = ".$this->owner_id;
|
||||
}
|
||||
$sql .= " ORDER BY id DESC";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getById($id){
|
||||
$sql ="select * from public." .$this->table_name . " where id='".intval($id)."'";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getBy($k, $v){
|
||||
$sql ="select * from public." .$this->table_name . " where ".$k."='".$v."'";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getAccessGroups($id){
|
||||
$rv = array();
|
||||
|
||||
$sql ="select id,name from public.access_groups WHERE id in (SELECT access_group_id from public.map_access where map_id='".intval($id)."')";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rv[$row['id']] = $row['name'];
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function chainExec($sqls){
|
||||
for($i=0; $i < count($sqls); $i++){
|
||||
$result = pg_query($this->dbconn, $sqls[$i]);
|
||||
if(!$result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$success = (pg_affected_rows($result) >= 0);
|
||||
pg_free_result($result);
|
||||
if(!$success){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function delete($id)
|
||||
{
|
||||
|
||||
$sqls = array(
|
||||
"delete from public.map_access where map_id='".intval($id)."'",
|
||||
"delete from public." .$this->table_name . " where id='".intval($id)."'");
|
||||
return $this->chainExec($sqls);
|
||||
}
|
||||
|
||||
function update($data)
|
||||
{
|
||||
# insert access groups
|
||||
$values = array();
|
||||
foreach($data['accgrps'] as $group_id){
|
||||
array_push($values, "(".$group_id.",".$data['id'].")");
|
||||
}
|
||||
|
||||
$sqls = array(
|
||||
"update public.".$this->table_name." set name='".
|
||||
$this->cleanData($data['name'])."', description='".
|
||||
$this->cleanData($data['description'])."' where id = '".intval($data['id'])."' ",
|
||||
"delete from public.map_access where map_id=".$data['id'],
|
||||
"insert into public.map_access (access_group_id,map_id) values ".implode(',', $values)
|
||||
);
|
||||
return $this->chainExec($sqls);
|
||||
}
|
||||
|
||||
function isOwnedByUs($id){
|
||||
|
||||
if($this->owner_id == SUPER_ADMIN_ID){ // if Super Admin
|
||||
return true;
|
||||
}
|
||||
|
||||
$sql = "select * from public.".$this->table_name." where id=".$id." and owner_id=".$this->owner_id;
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
$rv = (pg_num_rows($result) > 0);
|
||||
pg_free_result($result);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function cleanData($val)
|
||||
{
|
||||
return pg_escape_string($this->dbconn, $val);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
<?php
|
||||
class permalink_Class
|
||||
{
|
||||
private $table_name = 'permalink';
|
||||
private $dbconn = null;
|
||||
private $owner_id = null;
|
||||
|
||||
function __construct($dbconn, $owner_id) {
|
||||
$this->dbconn = $dbconn;
|
||||
$this->owner_id = $owner_id;
|
||||
}
|
||||
|
||||
function getExpires($interval){
|
||||
if(!preg_match("/[a-z]/i", $interval)){ // if its just numbers (ex. 2024-02-20 18:35:07.616773)
|
||||
return ['expires' => $interval]; // it comes from update
|
||||
}
|
||||
|
||||
$sql = "SELECT CURRENT_TIMESTAMP + '".$interval."' as expires";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
|
||||
$row = pg_fetch_assoc($result);
|
||||
return $row;
|
||||
}
|
||||
|
||||
function create($data)
|
||||
{
|
||||
|
||||
$row = $this->getExpires($data['expires']);
|
||||
if($row === false){
|
||||
return [0,0,0];
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO PUBLIC." .$this->table_name."
|
||||
(map_id,description,query,expires,visits_limit,hash,owner_id) "."VALUES('".
|
||||
$this->cleanData($data['map_id'])."','".
|
||||
$this->cleanData($data['description'])."','".
|
||||
$this->cleanData($data['query'])."','".
|
||||
$row['expires']."','".
|
||||
$this->cleanData($data['visits_limit'])."','".
|
||||
$this->cleanData($data['hash'])."',".$this->owner_id.") RETURNING id,created,expires";
|
||||
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return [0,0,0];
|
||||
}
|
||||
|
||||
$row = pg_fetch_object($result);
|
||||
if($row) {
|
||||
return [$row->id,$row->created,$row->expires];
|
||||
}
|
||||
return [0,0,0];
|
||||
}
|
||||
|
||||
function getRows()
|
||||
{
|
||||
$sql ="select * from public." .$this->table_name;
|
||||
if($this->owner_id != SUPER_ADMIN_ID){
|
||||
$sql .= " WHERE owner_id = ".$this->owner_id;
|
||||
}
|
||||
$sql .= " ORDER BY id DESC";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getRowsArr(){
|
||||
$rv = array();
|
||||
|
||||
$sql = "select id,name from public.".$this->table_name;
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rv[$row['id']] = $row['name'];
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function getById($id){
|
||||
$sql ="select * from public." .$this->table_name . " where id='".intval($id)."'";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getByHash($hash){
|
||||
$sql ="select * from public." .$this->table_name . " where hash='".$hash."'";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function deleteByMap($map_id){
|
||||
$sql ="delete from public." .$this->table_name . " where map_id='".intval($map_id)."'";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return 0;
|
||||
}
|
||||
$rv = (pg_affected_rows($result) > 0);
|
||||
pg_free_result($result);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function delete($id){
|
||||
$sql ="delete from public." .$this->table_name . " where id='".intval($id)."'";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return 0;
|
||||
}
|
||||
$rv = (pg_affected_rows($result) > 0);
|
||||
pg_free_result($result);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function update($data) {
|
||||
|
||||
$row = $this->getExpires($data['expires']);
|
||||
if($row === false){
|
||||
return 0;
|
||||
}
|
||||
|
||||
$sql = "update public.".$this->table_name." set description='".
|
||||
$this->cleanData($data['description'])."', query='".
|
||||
$this->cleanData($data['query'])."', expires='".
|
||||
$this->cleanData($data['expires'])."', visits_limit='".
|
||||
$this->cleanData($data['visits_limit'])."' where id = '".intval($data['id'])."' ";
|
||||
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return 0;
|
||||
}
|
||||
return pg_affected_rows($result);
|
||||
}
|
||||
|
||||
function updateVisits($data) {
|
||||
|
||||
$sql = "update public.".$this->table_name." set visits='".
|
||||
$this->cleanData($data['visits'])."' where id = '".intval($data['id'])."' ";
|
||||
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return 0;
|
||||
}
|
||||
return pg_affected_rows($result);
|
||||
}
|
||||
|
||||
function getMap($hash, $countme){
|
||||
$sql = "select * FROM ".$this->table_name." where hash='".$hash."'";
|
||||
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result || (pg_num_rows($result) == 0)){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
$row = pg_fetch_assoc($result);
|
||||
pg_free_result($result);
|
||||
|
||||
if($countme){
|
||||
// update the visited permalink counter
|
||||
$visits = intval($row['visits']) + 1;
|
||||
$limit = intval($row['visits_limit']);
|
||||
|
||||
if($limit != 0){
|
||||
if($visits > $limit){
|
||||
$this->delete($row['id']);
|
||||
return null; //expired by visits
|
||||
}/* NOTE: can't delete, because after last visit, we use permalink in data_{file,pg,gs}.php!
|
||||
else if($visits == $limit){ //last visit
|
||||
$this->delete($row['id']); // delete permalink
|
||||
return $row;
|
||||
}*/
|
||||
}
|
||||
|
||||
$row['visits'] = $visits;
|
||||
$this->updateVisits($row);
|
||||
}
|
||||
|
||||
// check time
|
||||
if (time() >= strtotime($row['expires'])) {
|
||||
$this->delete($row['id']);
|
||||
return null; //expired by time
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
function isOwnedByUs($id){
|
||||
|
||||
if($this->owner_id == SUPER_ADMIN_ID){ // if Super Admin
|
||||
return true;
|
||||
}
|
||||
|
||||
$sql = "select * from public.".$this->table_name." where id=".$id." and owner_id=".$this->owner_id;
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
$rv = (pg_num_rows($result) > 0);
|
||||
pg_free_result($result);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function cleanData($val)
|
||||
{
|
||||
return pg_escape_string($this->dbconn, $val);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
class signup_Class
|
||||
{
|
||||
private $table_name = 'signup';
|
||||
private $dbconn = null;
|
||||
|
||||
function __construct($dbconn) {
|
||||
$this->dbconn = $dbconn;
|
||||
}
|
||||
|
||||
function create($data)
|
||||
{
|
||||
$sql = "INSERT INTO PUBLIC." .$this->table_name."
|
||||
(name,email,password,verify) "."VALUES('".
|
||||
$this->cleanData($data['name'])."','".
|
||||
$this->cleanData($data['email'])."','".
|
||||
$data['password']."','".
|
||||
$this->cleanData($data['verify'])."'".
|
||||
") RETURNING id";
|
||||
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return 0;
|
||||
}
|
||||
|
||||
$row = pg_fetch_object($result);
|
||||
pg_free_result($result);
|
||||
if($row) {
|
||||
return $row->id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getRows(){
|
||||
$sql ="select * from public." .$this->table_name." ORDER BY id DESC";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getById($id){
|
||||
$sql ="select * from public." .$this->table_name . "
|
||||
where id='".intval($id)."'";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function delete($id){
|
||||
$sql ="delete from public." .$this->table_name . " where id='".intval($id)."'";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if($result){
|
||||
$rv = (pg_affected_rows($result) > 0);
|
||||
pg_free_result($result);
|
||||
return $rv;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function verify($id, $verify){
|
||||
$sql ="select * from public.".$this->table_name." where id='".intval($id)."' AND verify='".$verify."'";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function cleanData($val){
|
||||
return pg_escape_string($this->dbconn, $val);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
<?php
|
||||
class user_Class
|
||||
{
|
||||
private $table_name = 'user';
|
||||
private $dbconn = null;
|
||||
private $owner_id = null;
|
||||
|
||||
function __construct($dbconn, $owner_id) {
|
||||
$this->dbconn = $dbconn;
|
||||
$this->owner_id = $owner_id;
|
||||
}
|
||||
|
||||
function create($data, $isHashed = false)
|
||||
{
|
||||
if(!$isHashed){
|
||||
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO PUBLIC." .$this->table_name."
|
||||
(name,email,password,ftp_user,accesslevel,owner_id) "."VALUES('".
|
||||
$this->cleanData($data['name'])."','".
|
||||
$this->cleanData($data['email'])."','".
|
||||
$data['password']."','".
|
||||
$this->cleanData($data['ftp_user'])."','".
|
||||
$this->cleanData($data['accesslevel'])."',".
|
||||
$this->owner_id.") RETURNING id";
|
||||
|
||||
$row = pg_fetch_object(pg_query($this->dbconn, $sql));
|
||||
|
||||
if($row) {
|
||||
|
||||
# insert user groups
|
||||
$values = array();
|
||||
foreach($data['groups'] as $group_id){
|
||||
array_push($values, "(".$row->id.",".$group_id.")");
|
||||
}
|
||||
|
||||
$sql = "insert into public.user_access (user_id,access_group_id) values ".implode(',', $values);
|
||||
$ret = pg_query($this->dbconn, $sql);
|
||||
|
||||
return $row->id;
|
||||
}
|
||||
return 0;
|
||||
|
||||
//return pg_affected_rows(pg_query($this->dbconn, $sql));
|
||||
}
|
||||
|
||||
function getRows()
|
||||
{
|
||||
$sql ="select * from public." .$this->table_name;
|
||||
if($this->owner_id != SUPER_ADMIN_ID){
|
||||
$sql .= " WHERE owner_id = ".$this->owner_id;
|
||||
}
|
||||
$sql .= " ORDER BY id DESC";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function getRowsArr(){
|
||||
$rv = array();
|
||||
$result = $this->getRows();
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$rv[$row['id']] = $row['name'];
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function getById($id){
|
||||
|
||||
$sql ="select * from public." .$this->table_name . "
|
||||
where id='".intval($id)."'";
|
||||
return pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
function loginCheck($pwd, $email){
|
||||
|
||||
$sql ="select * from public.user where email = '".$this->cleanData($email)."'";
|
||||
$result = pg_query($this->dbconn,$sql);
|
||||
$row = pg_fetch_object($result);
|
||||
pg_free_result($result);
|
||||
|
||||
if (password_verify($pwd, $row->password)) {
|
||||
return $row;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getByEmail($email){
|
||||
|
||||
$sql ="select * from public.".$this->table_name." where email='".$email."'";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
|
||||
$row = pg_fetch_object($result);
|
||||
pg_free_result($result);
|
||||
return $row;
|
||||
}
|
||||
|
||||
function delete($id)
|
||||
{
|
||||
$sql ="delete from public.user_access where user_id='".intval($id)."'";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
pg_free_result($result);
|
||||
|
||||
$sql ="delete from public." .$this->table_name . " where id='".intval($id)."'";
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
pg_free_result($result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function update($data=array())
|
||||
{
|
||||
|
||||
$id = intval($data['id']);
|
||||
$row = pg_fetch_object($this->getById($id));
|
||||
|
||||
$sql = "update public.user set name='".
|
||||
$this->cleanData($data['name'])."'";
|
||||
|
||||
if($row->password != $data['password']){ # if password is changed
|
||||
$hashpassword = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
$sql .= ", password='".$hashpassword."'";
|
||||
}
|
||||
|
||||
if(isset($data['ftp_user'])){
|
||||
$sql .= ", ftp_user = '".$this->cleanData($data['ftp_user'])."'";
|
||||
}
|
||||
|
||||
$sql .= ", accesslevel='".$this->cleanData($data['accesslevel']).
|
||||
"' where id = '".$id."'";
|
||||
|
||||
$rv = pg_affected_rows(pg_query($this->dbconn, $sql));
|
||||
|
||||
if($rv > 0){
|
||||
# drop old groups
|
||||
$sql = "delete from public.user_access where user_id=".$data['id'];
|
||||
$ret = pg_query($this->dbconn, $sql);
|
||||
|
||||
# insert user groups
|
||||
$values = array();
|
||||
foreach($data['groups'] as $group_id){
|
||||
array_push($values, "(".$data['id'].",".$group_id.")");
|
||||
}
|
||||
|
||||
$sql = "insert into public.user_access (user_id,access_group_id) values ".implode(',', $values);
|
||||
$ret = pg_query($this->dbconn, $sql);
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function isOwnedByUs($id){
|
||||
|
||||
if($this->owner_id == SUPER_ADMIN_ID){ // if Super Admin
|
||||
return true;
|
||||
}
|
||||
|
||||
$sql = "select * from public.".$this->table_name." where id=".$id." and owner_id=".$this->owner_id;
|
||||
$result = pg_query($this->dbconn, $sql);
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
$rv = (pg_num_rows($result) > 0);
|
||||
pg_free_result($result);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function cleanData($val)
|
||||
{
|
||||
return pg_escape_string($this->dbconn, $val);
|
||||
}
|
||||
|
||||
static public function create_ftp_user($ftp_user, $email, $hashed_pwd){
|
||||
$descriptorspec = array(
|
||||
0 => array("pipe", "r"),
|
||||
1 => array("pipe", "w"),
|
||||
2 => array("pipe", "w")
|
||||
);
|
||||
|
||||
$process = proc_open('sudo /usr/local/bin/create_ftp_user.sh', $descriptorspec, $pipes, null, null);
|
||||
|
||||
if (is_resource($process)) {
|
||||
|
||||
fwrite($pipes[0], $ftp_user."\n".$hashed_pwd."\n");
|
||||
fclose($pipes[0]);
|
||||
|
||||
//echo stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
|
||||
// It is important that you close any pipes before calling proc_close in order to avoid a deadlock
|
||||
$return_value = proc_close($process);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/* plus glyph for showing collapsible panels */
|
||||
.panel-heading .accordion-plus-toggle:before {
|
||||
font-family: FontAwesome;
|
||||
content: "\f068";
|
||||
float: right;
|
||||
color: silver;
|
||||
}
|
||||
|
||||
.panel-heading .accordion-plus-toggle.collapsed:before {
|
||||
content: "\f067";
|
||||
color: silver;
|
||||
}
|
||||
|
||||
/* arrow glyph for showing collapsible panels */
|
||||
.panel-heading .accordion-arrow-toggle:before {
|
||||
font-family: FontAwesome;
|
||||
content: "\f078";
|
||||
float: right;
|
||||
color: silver;
|
||||
}
|
||||
|
||||
.panel-heading .accordion-arrow-toggle.collapsed:before {
|
||||
content: "\f054";
|
||||
color: silver;
|
||||
}
|
||||
|
||||
/* sets the link to the width of the entire panel title */
|
||||
.panel-title > a {
|
||||
display: block;
|
||||
}
|
2
admin/dist/css/icons/material-design-iconic-font/css/materialdesignicons.min.css
vendored
Normal file
BIN
admin/dist/css/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.eot
vendored
Normal file
5520
admin/dist/css/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.svg
vendored
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
admin/dist/css/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.ttf
vendored
Normal file
BIN
admin/dist/css/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.woff
vendored
Normal file
BIN
admin/dist/css/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.woff2
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
.table>thead {
|
||||
background-color: #fff!important;
|
||||
color: #fff;
|
||||
border-style : hidden!important;
|
||||
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
color: #black!important;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 80%;
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
border-collapse:collapse!important;
|
||||
border: none;
|
||||
|
||||
}
|
||||
|
||||
td {
|
||||
border-style : hidden!important;
|
||||
}
|
||||
|
||||
.text-end {
|
||||
text-align: center!important;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: 1px solid #fff;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.secrer {
|
||||
display: block;
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
#main-wrapper[data-layout=horizontal] .left-sidebar[data-sidebarbg=skin6] .sidebar-nav ul, #main-wrapper[data-layout=vertical] .left-sidebar[data-sidebarbg=skin6] .sidebar-nav ul {
|
||||
background: #fff;
|
||||
border-radius:40px;
|
||||
}
|
||||
|
||||
#main-wrapper[data-layout=horizontal] .left-sidebar[data-sidebarbg=skin6], #main-wrapper[data-layout=vertical] .left-sidebar[data-sidebarbg=skin6] {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.sidebar-nav ul .sidebar-item.selected>.sidebar-link {
|
||||
background-color: #666;
|
||||
color: #fff!important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.page-wrapper {
|
||||
background: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.dataTables_wrapper div.dataTables_filter {
|
||||
text-align: right;
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
|
||||
.bg-success {
|
||||
background-color: #41afa5!important;
|
||||
}
|
||||
|
||||
.bg-warning2 {
|
||||
background-color: cornflowerblue!important;
|
||||
}
|
||||
|
||||
|
||||
.bg-info {
|
||||
background-color: #50667f!important;
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
border: none!important;
|
||||
border-radius: inherit;
|
||||
|
||||
}
|
||||
|
||||
.navbar {
|
||||
position: relative;
|
||||
min-height: 50px;
|
||||
margin-bottom: 0px!important;
|
||||
border: 1px solid transparent;
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
body {
|
||||
color: #404E67;
|
||||
background: #fff; /*#F5F7FA;*/
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
width: 100%;
|
||||
margin: 20px auto;
|
||||
background: #fff;
|
||||
padding: 5px;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
|
||||
}
|
||||
|
||||
.table-title {
|
||||
padding-bottom: 10px;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.table-title h2 {
|
||||
margin: 6px 0 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.table-title .add-new {
|
||||
float: right;
|
||||
height: 30px;
|
||||
font-weight: bold;
|
||||
font-size: 10px;
|
||||
text-shadow: none;
|
||||
min-width: 100px;
|
||||
border-radius: 50px;
|
||||
line-height: 13px;
|
||||
}
|
||||
|
||||
.table-title .add-new i {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
table.table {
|
||||
/*table-layout: fixed;*/
|
||||
}
|
||||
|
||||
table.table tr th,
|
||||
table.table tr td {
|
||||
border-color: #e9e9e9;
|
||||
}
|
||||
|
||||
table.table th i {
|
||||
font-size: 10px;
|
||||
margin: 0 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table.table th:last-child {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
table.table td a {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
table.table td a.add {
|
||||
color: #27C46B;
|
||||
}
|
||||
|
||||
table.table td a.edit {
|
||||
color: #FFC107;
|
||||
}
|
||||
|
||||
table.table td a.delete {
|
||||
color: #E34724;
|
||||
}
|
||||
|
||||
table.table td i {
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
table.table td a.add i {
|
||||
font-size: 24px;
|
||||
margin-right: -1px;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
table.table .form-control {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
box-shadow: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
table.table .form-control.error {
|
||||
border-color: #f50000;
|
||||
}
|
||||
|
||||
table.table td .add {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
$(function () {
|
||||
"use strict";
|
||||
|
||||
$(".preloader").fadeOut();
|
||||
// this is for close icon when navigation open in mobile view
|
||||
$(".nav-toggler").on("click", function () {
|
||||
$("#main-wrapper").toggleClass("show-sidebar");
|
||||
});
|
||||
$(".search-box a, .search-box .app-search .srh-btn").on("click", function () {
|
||||
$(".app-search").toggle(200);
|
||||
$(".app-search input").focus();
|
||||
});
|
||||
|
||||
// ==============================================================
|
||||
// Resize all elements
|
||||
// ==============================================================
|
||||
$("body, .page-wrapper").trigger("resize");
|
||||
$(".page-wrapper").delay(20).show();
|
||||
|
||||
//****************************
|
||||
/* This is for the mini-sidebar if width is less then 1170*/
|
||||
//****************************
|
||||
var setsidebartype = function () {
|
||||
var width = window.innerWidth > 0 ? window.innerWidth : this.screen.width;
|
||||
if (width < 1170) {
|
||||
$("#main-wrapper").attr("data-sidebartype", "mini-sidebar");
|
||||
} else {
|
||||
$("#main-wrapper").attr("data-sidebartype", "full");
|
||||
}
|
||||
};
|
||||
$(window).ready(setsidebartype);
|
||||
$(window).on("resize", setsidebartype);
|
||||
});
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Template Name: Admin Template
|
||||
Author: Wrappixel
|
||||
|
||||
File: js
|
||||
*/
|
||||
// ==============================================================
|
||||
// Auto select left navbar
|
||||
// ==============================================================
|
||||
$(function() {
|
||||
"use strict";
|
||||
var url = window.location + "";
|
||||
var path = url.replace(window.location.protocol + "//" + window.location.host + "/", "");
|
||||
var element = $('ul#sidebarnav a').filter(function() {
|
||||
return this.href === url || this.href === path;// || url.href.indexOf(this.href) === 0;
|
||||
});
|
||||
element.parentsUntil(".sidebar-nav").each(function (index)
|
||||
{
|
||||
if($(this).is("li") && $(this).children("a").length !== 0)
|
||||
{
|
||||
$(this).children("a").addClass("active");
|
||||
$(this).parent("ul#sidebarnav").length === 0
|
||||
? $(this).addClass("active")
|
||||
: $(this).addClass("selected");
|
||||
}
|
||||
else if(!$(this).is("ul") && $(this).children("a").length === 0)
|
||||
{
|
||||
$(this).addClass("selected");
|
||||
|
||||
}
|
||||
else if($(this).is("ul")){
|
||||
$(this).addClass('in');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
element.addClass("active");
|
||||
$('#sidebarnav a').on('click', function (e) {
|
||||
|
||||
if (!$(this).hasClass("active")) {
|
||||
// hide any open menus and remove all other classes
|
||||
$("ul", $(this).parents("ul:first")).removeClass("in");
|
||||
$("a", $(this).parents("ul:first")).removeClass("active");
|
||||
|
||||
// open our new menu and add the open class
|
||||
$(this).next("ul").addClass("in");
|
||||
$(this).addClass("active");
|
||||
|
||||
}
|
||||
else if ($(this).hasClass("active")) {
|
||||
$(this).removeClass("active");
|
||||
$(this).parents("ul:first").removeClass("active");
|
||||
$(this).next("ul").removeClass("in");
|
||||
}
|
||||
})
|
||||
$('#sidebarnav >li >a.has-arrow').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,429 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('incl/const.php');
|
||||
require('class/database.php');
|
||||
require('class/map.php');
|
||||
require('class/app.php');
|
||||
require('class/access_groups.php');
|
||||
|
||||
if(!isset($_SESSION['user']) || $_SESSION['user']->accesslevel != 'Admin'){
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
|
||||
$map = ['name' => '','description' => ''];
|
||||
|
||||
$map_acc_ids = array();
|
||||
$use_dt = false;
|
||||
|
||||
if(!empty($_GET['id'])){
|
||||
$map_obj = new map_Class($database->getConn(), $_SESSION['user']->id);
|
||||
|
||||
$result = $map_obj->getById($_GET['id']);
|
||||
if(!$result){
|
||||
$_GET['error'] = 'Error: No such map!';
|
||||
exit;
|
||||
}
|
||||
$map = pg_fetch_assoc($result);
|
||||
pg_free_result($result);
|
||||
|
||||
$map_acc_grps = $map_obj->getAccessGroups($_GET['id']);
|
||||
$map_acc_ids = array_keys($map_acc_grps);
|
||||
|
||||
list($dss,$lys,$use_dt) = App::parseDatasources(APPS_DIR.'/'.$map['id']);
|
||||
|
||||
}else{
|
||||
$upload_dir = App::upload_dir($_SESSION['user']->ftp_user);
|
||||
$app_names = App::getApps($upload_dir);
|
||||
}
|
||||
|
||||
$acc_obj = new access_group_Class($database->getConn(), $_SESSION['user']->id);
|
||||
$acc_grps = $acc_obj->getRowsArr();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
|
||||
<head>
|
||||
<?php include("incl/meta.php"); ?>
|
||||
<link href="dist/css/table.css" rel="stylesheet">
|
||||
<?php if(!empty($_GET['id'])){ ?>
|
||||
<link href="dist/css/accordion.css" rel="stylesheet">
|
||||
<?php } ?>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
$('#map_form').submit(false);
|
||||
<?php
|
||||
if(isset($_GET['id'])){
|
||||
|
||||
foreach($dss as $dsi => $ds) {
|
||||
if($ds['data_type'] == 'gs'){ ?>
|
||||
$('#pg_details<?=$dsi?>').hide();
|
||||
<?php } else if($ds['data_type'] == 'pg'){ ?>
|
||||
$('#gs_details<?=$dsi?>').hide();
|
||||
<?php }else { ?>
|
||||
$('#pg_details<?=$dsi?>').hide();
|
||||
$('#gs_details<?=$dsi?>').hide();
|
||||
<?php }
|
||||
}
|
||||
|
||||
foreach($lys as $lyi => $ly) {
|
||||
if($ly['layer_type'] == 'gs_geo'){ ?>
|
||||
$('#wms_details<?=$lyi?>').hide();
|
||||
<?php }else if($ly['layer_type'] == 'wms'){ ?>
|
||||
$('#gs_geo_details<?=$lyi?>').hide();
|
||||
<?php }
|
||||
}
|
||||
} ?>
|
||||
$('#archive').hide();
|
||||
|
||||
|
||||
$(document).on("click", 'input[name="from_type"]', function() {
|
||||
if($(this).attr('id') == 'from_uploaded'){
|
||||
$('#app').show(); $('#app').prop('disabled', false); $('#app').prop('required',true);
|
||||
$('#archive').hide();$('#archive').prop('disabled', true); $('#archive').prop('required',false);
|
||||
}else{
|
||||
$('#app').hide(); $('#app').prop('disabled', true); $('#app').prop('required',false);
|
||||
$('#archive').show(); $('#archive').prop('disabled', false); $('#archive').prop('required',true);
|
||||
}
|
||||
});
|
||||
|
||||
//// data
|
||||
$(document).on("click", 'input[class="data_files"]', function() {
|
||||
const id = $(this).attr('data-id');
|
||||
let pg = $('#pg_details' + id);
|
||||
let gs = $('#gs_details' + id);
|
||||
|
||||
pg.hide(); pg.children('input').prop('required',false);
|
||||
gs.hide(); gs.children('input').prop('required',false);
|
||||
});
|
||||
|
||||
$(document).on("click", 'input[class="data_pg"]', function() {
|
||||
const id = $(this).attr('data-id');
|
||||
let pg = $('#pg_details' + id);
|
||||
let gs = $('#gs_details' + id);
|
||||
|
||||
pg.show(); pg.children('input').prop('required',true);
|
||||
gs.hide(); gs.children('input').prop('required',false);
|
||||
});
|
||||
|
||||
$(document).on("click", 'input[class="data_gs"]', function() {
|
||||
const id = $(this).attr('data-id');
|
||||
let pg = $('#pg_details' + id);
|
||||
let gs = $('#gs_details' + id);
|
||||
|
||||
pg.hide(); pg.children('input').prop('required',false);
|
||||
gs.show(); gs.children('input').prop('required',true);
|
||||
});
|
||||
|
||||
//// layers
|
||||
$(document).on("click", 'input[class="layer_wms"]', function() {
|
||||
const id = $(this).attr('data-id');
|
||||
let wms = $('#wms_details' + id);
|
||||
let gs = $('#gs_geo_details' + id);
|
||||
|
||||
wms.show(); wms.children('input').prop('required',true);
|
||||
wms.children('input[name^="wms_user"], input[name^="wms_pwd"]').prop('required',false);
|
||||
gs.hide(); gs.children('input').prop('required',false);
|
||||
});
|
||||
|
||||
$(document).on("click", 'input[class="layer_gs_geo"]', function() {
|
||||
const id = $(this).attr('data-id');
|
||||
let wms = $('#wms_details' + id);
|
||||
let gs = $('#gs_geo_details' + id);
|
||||
|
||||
wms.hide(); wms.children('input').prop('required',false);
|
||||
gs.show(); gs.children('input').prop('required',true);
|
||||
});
|
||||
|
||||
// Update/Create connection on submit button click
|
||||
$(document).on("click", "#btn_submit", function() {
|
||||
let obj = $(this);
|
||||
let input = $('#map_form').find('input[type="text"], input[type="password"], select');
|
||||
let empty = false;
|
||||
|
||||
input.each(function() {
|
||||
if (!$(this).prop('disabled') && $(this).prop('required') && !$(this).val()) {
|
||||
$(this).addClass("error");
|
||||
empty = true;
|
||||
} else {
|
||||
$(this).removeClass("error");
|
||||
}
|
||||
});
|
||||
|
||||
if(empty){
|
||||
$('#map_form').find(".error").first().focus();
|
||||
}else{
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/map.php',
|
||||
data: new FormData($('#map_form')[0]),
|
||||
processData: false,
|
||||
contentType: false,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
alert(response.message);
|
||||
if(response.success) {
|
||||
<?php if(isset($_GET['id'])){ ?>
|
||||
window.location.href = 'maps.php'; // redirect to maps.php
|
||||
<?php } else { ?>
|
||||
window.location.href = 'edit_map.php?id=' + response.id; // redirect to step 2 for datasources
|
||||
<?php } ?>
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main-wrapper" data-layout="vertical" data-navbarbg="skin5" data-sidebartype="full"
|
||||
data-sidebar-position="absolute" data-header-position="absolute" data-boxed-layout="full">
|
||||
|
||||
<?php const MENU_SEL = 'maps.php';
|
||||
include("incl/topbar.php");
|
||||
include("incl/sidebar.php");
|
||||
?>
|
||||
<div class="page-wrapper">
|
||||
<div class="page-breadcrumb" style="padding-left:30px; padding-right: 30px; padding-top:0px; padding-bottom: 0px">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<nav aria-label="breadcrumb">
|
||||
</nav>
|
||||
<?php if(isset($_GET['id'])){ ?>
|
||||
<h1 class="mb-0 fw-bold">Update Map <?=$_GET['id']?></h1>
|
||||
<?php } else { ?>
|
||||
<h1 class="mb-0 fw-bold">Add new map</h1>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="text-end upgrade-btn">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<form action="" method="post" enctype="multipart/form-data" id="map_form" style="width: 50%;">
|
||||
<?php if (isset($_GET['error'])) { ?>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<?=$_GET['error']?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if(isset($_GET['id'])){ ?>
|
||||
<input type="hidden" class="form-control" name="id" id="id" value="<?=$_GET['id']?>" />
|
||||
<?php } ?>
|
||||
<input type="hidden" class="form-control" name="save" id="save" value="1" />
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" name="name" id="name" value="<?=$map['name']?>" required/>
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<input type="text" class="form-control" name="description" id="description" value="<?=$map['description']?>" required/>
|
||||
</div>
|
||||
|
||||
<?php if(!isset($_GET['id'])){ ?>
|
||||
<fieldset>
|
||||
<legend>Source</legend>
|
||||
<div class="form-group">
|
||||
|
||||
<input type="radio" id="from_uploaded" name="from_type" value="uploaded" checked>
|
||||
<label for="from_uploaded">Uploads</label>
|
||||
<input type="radio" id="from_zip" name="from_type" value="archive">
|
||||
<label for="from_zip">Archive</label>
|
||||
|
||||
<select class="form-control" name="app" id="app" aria-label="Select app">
|
||||
<?php foreach($app_names as $k){ ?>
|
||||
<option <?php if($k == $map['name']){ ?> selected <?php }?> value="<?=$k?>"><?=$k?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
|
||||
<input type="file" class="form-control" name="archive" id="archive" value="" accept=".zip" disabled/>
|
||||
<p>NOTE: Archive can contains files, or project directory.</p>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php }else {
|
||||
$aci = 0;
|
||||
?>
|
||||
|
||||
<fieldset>
|
||||
<legend>Data</legend>
|
||||
<?php
|
||||
foreach($dss as $dsi => $ds) { ?>
|
||||
<div class="panel-group" id="accordion<?=$aci?>" role="tablist" aria-multiselectable="false">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="heading<?=$aci?>">
|
||||
<h5 class="panel-title">
|
||||
<a role="button" data-toggle="collapse" class="accordion-plus-toggle collapsed" data-parent="#accordion<?=$aci?>" href="#collapse<?=$aci?>" aria-expanded="false" aria-controls="collapse<?=$aci?>"><?=$ds['name']?></a>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="collapse<?=$aci?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading<?=$aci?>">
|
||||
|
||||
<div class="form-group col-sm">
|
||||
<input type="radio" class="data_files" data-id="<?=$dsi?>" name="data_type<?=$dsi?>" value="file" <?php if($ds['data_type'] == 'file'){ ?> checked<?php } ?>> <label for="data_files<?=$dsi?>">Files</label>
|
||||
<input type="radio" class="data_pg" data-id="<?=$dsi?>" name="data_type<?=$dsi?>" value="pg" <?php if($ds['data_type'] == 'pg'){ ?> checked<?php } ?>> <label for="data_pg<?=$dsi?>">Postgres</label>
|
||||
<input type="radio" class="data_gs" data-id="<?=$dsi?>" name="data_type<?=$dsi?>" value="gs" <?php if($ds['data_type'] == 'gs'){ ?> checked<?php } ?>> <label for="data_gs<?=$dsi?>">GeoServer</label>
|
||||
</div>
|
||||
|
||||
<div class="pg_details" id="pg_details<?=$dsi?>">
|
||||
<label for="pg_host<?=$dsi?>" class="form-label">Host</label> <input type="text" class="form-control" name="pg_host<?=$dsi?>" id="pg_host<?=$dsi?>" value="<?=$ds['pg_host']?>"/>
|
||||
<label for="pg_port<?=$dsi?>" class="form-label">Port</label> <input type="text" class="form-control" name="pg_port<?=$dsi?>" id="pg_port<?=$dsi?>" value="<?=$ds['pg_port']?>"/>
|
||||
<label for="pg_db<?=$dsi?>" class="form-label">Database</label> <input type="text" class="form-control" name="pg_db<?=$dsi?>" id="pg_db<?=$dsi?>" value="<?=$ds['pg_db']?>"/>
|
||||
<label for="pg_user<?=$dsi?>" class="form-label">User</label> <input type="text" class="form-control" name="pg_user<?=$dsi?>" id="pg_user<?=$dsi?>" value="<?=$ds['pg_user']?>"/>
|
||||
<label for="pg_pwd<?=$dsi?>" class="form-label">Password</label> <input type="password" class="form-control" name="pg_pwd<?=$dsi?>" id="pg_pwd<?=$dsi?>" value="<?=$ds['pg_pwd']?>"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="pg_cache<?=$dsi?>" class="form-label">Cache</label>
|
||||
<input type="number" name="pg_cache_val<?=$dsi?>" id="pg_cache_val<?=$dsi?>" value="<?=$ds['pg_cache_val']?>"/>
|
||||
<select name="pg_cache_per<?=$dsi?>" id="pg_cache_per<?=$dsi?>">
|
||||
<?php foreach(TIME_MAP as $per => $val) { ?>
|
||||
<option value="<?=$per?>" <?php if($ds['pg_cache_per'] == $per) { ?> selected <?php } ?>><?=$per?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gs_details" id="gs_details<?=$dsi?>">
|
||||
<label for="gs_host<?=$dsi?>" class="form-label">Host</label> <input type="text" class="form-control" name="gs_host<?=$dsi?>" id="gs_host<?=$dsi?>" value="<?=$ds['gs_host']?>"/>
|
||||
<label for="gs_user<?=$dsi?>" class="form-label">User</label> <input type="text" class="form-control" name="gs_user<?=$dsi?>" id="gs_user<?=$dsi?>" value="<?=$ds['gs_user']?>"/>
|
||||
<label for="gs_pwd<?=$dsi?>" class="form-label">Password</label> <input type="password" class="form-control" name="gs_pwd<?=$dsi?>" id="gs_pwd<?=$dsi?>" value="<?=$ds['gs_pwd']?>"/>
|
||||
<label for="gs_ws<?=$dsi?>" class="form-label">Workspace</label><input type="text" class="form-control" name="gs_ws<?=$dsi?>" id="gs_ws<?=$dsi?>" value="<?=$ds['gs_ws']?>"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="gs_cache<?=$dsi?>" class="form-label">Cache</label>
|
||||
<input type="number" name="gs_cache_val<?=$dsi?>" id="gs_cache_val<?=$dsi?>" value="<?=$ds['gs_cache_val']?>"/>
|
||||
<select name="gs_cache_per<?=$dsi?>" id="gs_cache_per<?=$dsi?>">
|
||||
<?php foreach(TIME_MAP as $per => $val) { ?>
|
||||
<option value="<?=$per?>" <?php if($ds['gs_cache_per'] == $per) { ?> selected <?php } ?>><?=$per?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php $aci = $aci + 1;
|
||||
} ?>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Layers</legend>
|
||||
<?php
|
||||
foreach($lys as $lyi => $ly) { ?>
|
||||
<div class="panel-group" id="accordion<?=$aci?>" role="tablist" aria-multiselectable="false">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="heading<?=$aci?>">
|
||||
<h5 class="panel-title">
|
||||
<a role="button" data-toggle="collapse" class="accordion-plus-toggle collapsed" data-parent="#accordion<?=$aci?>" href="#collapse<?=$aci?>" aria-expanded="false" aria-controls="collapse<?=$aci?>"><?=$ly['name']?></a>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="collapse<?=$aci?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading<?=$aci?>">
|
||||
|
||||
<div class="form-group col-sm">
|
||||
<input type="radio" class="layer_wms" data-id="<?=$lyi?>" name="layer_type<?=$lyi?>" value="wms" <?php if($ly['layer_type'] == 'wms'){ ?> checked<?php } ?>> <label for="layer_wms<?=$lyi?>">WMS</label>
|
||||
<input type="radio" class="layer_gs_geo" data-id="<?=$lyi?>" name="layer_type<?=$lyi?>" value="gs_geo" <?php if($ly['layer_type'] == 'gs_geo'){ ?> checked<?php } ?>> <label for="layer_gs_geo<?=$lyi?>">GeoJSON(GS)</label>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="layer_varname<?=$lyi?>" id="layer_varname<?=$lyi?>" value="<?=$ly['layer_varname']?>"/>
|
||||
|
||||
<div class="wms_details" id="wms_details<?=$lyi?>">
|
||||
<label for="wms_url<?=$lyi?>" class="form-label">URL</label> <input type="text" class="form-control" name="wms_url<?=$lyi?>" id="wms_url<?=$lyi?>" value="<?=$ly['wms_url']?>"/>
|
||||
<label for="wms_ws<?=$lyi?>" class="form-label">Workspace</label> <input type="text" class="form-control" name="wms_ws<?=$lyi?>" id="wms_ws<?=$lyi?>" value="<?=$ly['wms_ws']?>"/>
|
||||
<label for="wms_layer<?=$lyi?>" class="form-label">Layer</label> <input type="text" class="form-control" name="wms_layer<?=$lyi?>" id="wms_layer<?=$lyi?>" value="<?=$ly['wms_layer']?>"/>
|
||||
|
||||
<label for="wms_user<?=$lyi?>" class="form-label">User (only for secured connections)</label> <input type="text" class="form-control" name="wms_user<?=$lyi?>" id="wms_user<?=$lyi?>" value="<?=$ly['wms_user']?>"/>
|
||||
<label for="wms_pwd<?=$lyi?>" class="form-label">Password</label> <input type="password" class="form-control" name="wms_pwd<?=$lyi?>" id="wms_pwd<?=$lyi?>" value="<?=$ly['wms_pwd']?>"/>
|
||||
</div>
|
||||
|
||||
<div class="gs_geo_details" id="gs_geo_details<?=$lyi?>">
|
||||
<label for="gs_geo_host<?=$lyi?>" class="form-label">Host</label> <input type="text" class="form-control" name="gs_geo_host<?=$lyi?>" id="gs_geo_host<?=$lyi?>" value="<?=$ly['gs_geo_host']?>"/>
|
||||
<label for="gs_geo_user<?=$lyi?>" class="form-label">User</label> <input type="text" class="form-control" name="gs_geo_user<?=$lyi?>" id="gs_geo_user<?=$lyi?>" value="<?=$ly['gs_geo_user']?>"/>
|
||||
<label for="gs_geo_pwd<?=$lyi?>" class="form-label">Password</label> <input type="password" class="form-control" name="gs_geo_pwd<?=$lyi?>" id="gs_geo_pwd<?=$lyi?>" value="<?=$ly['gs_geo_pwd']?>"/>
|
||||
<label for="gs_geo_ws<?=$lyi?>" class="form-label">Workspace</label> <input type="text" class="form-control" name="gs_geo_ws<?=$lyi?>" id="gs_geo_ws<?=$lyi?>" value="<?=$ly['gs_geo_ws']?>"/>
|
||||
<label for="gs_geo_layer<?=$lyi?>" class="form-label">Layer</label> <input type="text" class="form-control" name="gs_geo_layer<?=$lyi?>" id="gs_geo_layer<?=$lyi?>" value="<?=$ly['gs_geo_layer']?>"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="gs_geo_color<?=$lyi?>" class="form-label">Color</label>
|
||||
<input type="color" class="form-control" name="gs_geo_color<?=$lyi?>" id="gs_geo_color<?=$lyi?>" value="<?=$ly['gs_geo_color']?>"/>
|
||||
<input type="range" class="form-control" name="gs_geo_opacity<?=$lyi?>" id="gs_geo_opacity<?=$lyi?>" value="<?=$ly['gs_geo_opacity']?>" min="0" max="100"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="gs_geo_fillcolor<?=$lyi?>" class="form-label">Fill Color</label>
|
||||
<input type="color" class="form-control" name="gs_geo_fill_color<?=$lyi?>" id="gs_geo_fill_color<?=$lyi?>" value="<?=$ly['gs_geo_fill_color']?>"/>
|
||||
<input type="range" class="form-control" name="gs_geo_fill_opacity<?=$lyi?>" id="gs_geo_fill_opacity<?=$lyi?>" value="<?=$ly['gs_geo_fill_opacity']?>" min="0" max="100"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="gs_geo_cache<?=$lyi?>" class="form-label">Cache</label>
|
||||
<input type="number" name="gs_geo_cache_val<?=$lyi?>" id="gs_geo_cache_val<?=$lyi?>" value="<?=$ly['gs_geo_cache_val']?>"/>
|
||||
<select name="gs_geo_cache_per<?=$lyi?>" id="gs_geo_cache_per<?=$lyi?>">
|
||||
<?php foreach(TIME_MAP as $per => $val) { ?>
|
||||
<option value="<?=$per?>" <?php if($ly['gs_geo_cache_per'] == $per) { ?> selected <?php } ?>><?=$per?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php $aci = $aci + 1;
|
||||
} ?>
|
||||
</fieldset>
|
||||
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<fieldset>
|
||||
<legend>View</legend>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="checkbox" class="form-checkbox" name="use_datatable" id="use_datatable" value="1" <?php if($use_dt) {?> checked <?php } ?>/>
|
||||
<label for="use_datatable" class="form-label">Show DataTable below map</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="image" class="form-label">Preview image (.png, .jpeg formats)</label>
|
||||
<?php if(isset($_GET['id']) && is_file("../assets/maps/".$_GET['id'].".png")){ ?>
|
||||
<img src="../assets/maps/<?=$_GET['id']?>.png" alt="Map Preview" width="200" height="150">
|
||||
<?php } else { ?>
|
||||
<img src="../assets/maps/default.png" alt="Map Preview" width="200" height="150">
|
||||
<?php } ?>
|
||||
<input type="file" class="form-control" name="image" id="image" value="" accept=".png,.jpg,.jpeg"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="accgrps" class="form-label">Access Groups</label>
|
||||
<select class="form-control" name="accgrps[]" id="accgrps" aria-label="Select access groups" multiple required>
|
||||
<?php foreach($acc_grps as $k => $v){?>
|
||||
<option <?php if(in_array($k, $map_acc_ids)){?> selected <?php }?> value="<?=$k?>"><?=$v?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<button type="submit" class="btn btn-primary" id="btn_submit"><?php if(isset($_GET['id'])){ ?>Update<?php } else { ?>Create<?php } ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer text-center">
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="dist/js/sidebarmenu.js"></script>
|
||||
<script src="dist/js/custom.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<title>QGIS2Map App</title>
|
||||
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon.ico">
|
||||
<link href="dist/css/style.min.css" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela+Round|Open+Sans">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||
|
||||
<link href="dist/css/meta.css" rel="stylesheet">
|
|
@ -0,0 +1,28 @@
|
|||
<?php function sidebar_row($page, $icon, $label){ ?>
|
||||
<li class="sidebar-item" <?php if(MENU_SEL == $page){ ?> selected <?php } ?> >
|
||||
<a class="sidebar-link waves-effect waves-dark sidebar-link" href="<?=$page?>" aria-expanded="false">
|
||||
<i class="mdi mdi-<?=$icon?>"></i><span class="hide-menu"><?=$label?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
|
||||
<aside class="left-sidebar toggled" data-sidebarbg="skin6">
|
||||
<div class="scroll-sidebar toggled" style="padding-left:10px">
|
||||
<nav class="sidebar-nav toggled"><br>
|
||||
<ul id="sidebarnav">
|
||||
<?php
|
||||
sidebar_row('index.php', 'view-dashboard', 'Dashboard');
|
||||
|
||||
if($_SESSION['user']->accesslevel == 'Admin') { // only admins have acess to user/group creation
|
||||
sidebar_row('users.php', 'account-settings-variant', 'Users');
|
||||
sidebar_row('access_groups.php', 'account-multiple', 'User Groups');
|
||||
sidebar_row('maps.php', 'map', 'Maps');
|
||||
sidebar_row('permalinks.php', 'map', 'Permalinks');
|
||||
}
|
||||
sidebar_row('../index.php', 'exit-to-app', 'Front End');
|
||||
sidebar_row('../logout.php', 'logout', 'Log Out');
|
||||
?>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</aside>
|
|
@ -0,0 +1,21 @@
|
|||
<header class="topbar" data-navbarbg="skin6">
|
||||
<nav class="navbar top-navbar navbar-expand-md navbar-light" style="background-color:#50667f!important">
|
||||
<div class="navbar-header" data-logobg="skin6">
|
||||
<a class="navbar-brand" href="index.php" style="background-color:#50667f!important">
|
||||
<b class="logo-icon">
|
||||
<img src="assets/images/cited-logo.png" alt="homepage" class="dark-logo" />
|
||||
<img src="assets/images/cited-logo.png" alt="homepage" class="light-logo" />
|
||||
</b>
|
||||
<span class="logo-text">
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="nav-toggler waves-effect waves-light d-block d-md-none" href="javascript:void(0)"><i
|
||||
class="ti-menu ti-close"></i></a>
|
||||
</div>
|
||||
|
||||
|
||||
</nav>
|
||||
</header>
|
||||
<!--<p> </p>-->
|
||||
|
|
@ -0,0 +1,315 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('incl/const.php');
|
||||
require('class/database.php');
|
||||
|
||||
if(!isset($_SESSION['user']) || $_SESSION['user']->accesslevel != 'Admin') {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$dbconn = $database->getConn();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
|
||||
<head>
|
||||
<?php include("incl/meta.php"); ?>
|
||||
<link href="dist/css/table.css" rel="stylesheet">
|
||||
|
||||
<style type="text/css">
|
||||
a {
|
||||
text-decoration:none!important;
|
||||
}
|
||||
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.16), 0 4px 10px rgba(0,0,0,0.23);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main-wrapper" data-layout="vertical" data-navbarbg="skin5" data-sidebartype="full"
|
||||
data-sidebar-position="absolute" data-header-position="absolute" data-boxed-layout="full">
|
||||
|
||||
<?php const MENU_SEL = 'index.php';
|
||||
include("incl/topbar.php");
|
||||
include("incl/sidebar.php");
|
||||
?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
|
||||
<div class="page-breadcrumb" style="padding-left:30px; padding-right: 30px; padding-top:0px; padding-bottom: 0px">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
|
||||
<h1 class="mb-0 fw-bold">Dashboard</h1>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row">
|
||||
<div class="d-flex border-bottom title-part-padding px-0 mb-3 align-items-center">
|
||||
|
||||
</div>
|
||||
<div class="row" style="width:65%">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="col-md-4 col-xl-2 d-flex align-items-stretch">
|
||||
<a
|
||||
href="maps.php"
|
||||
class="card bg-info text-white w-100 card-hover"
|
||||
>
|
||||
<div class="card-header pt-5">
|
||||
<!--begin::Title-->
|
||||
<div class="card-title d-flex flex-column">
|
||||
<!--begin::Amount-->
|
||||
<span class="fs-2hx fw-bold text-white me-2 lh-1 ls-n2"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-map-fill" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.598-.49L10.5.99 5.598.01a.5.5 0 0 0-.196 0l-5 1A.5.5 0 0 0 0 1.5v14a.5.5 0 0 0 .598.49l4.902-.98 4.902.98a.5.5 0 0 0 .196 0l5-1A.5.5 0 0 0 16 14.5zM5 14.09V1.11l.5-.1.5.1v12.98l-.402-.08a.5.5 0 0 0-.196 0zm5 .8V1.91l.402.08a.5.5 0 0 0 .196 0L11 1.91v12.98l-.5.1z"/>
|
||||
</svg>
|
||||
Maps</span>
|
||||
<!--end::Amount-->
|
||||
|
||||
<!--begin::Subtitle-->
|
||||
<span class="text-white opacity-75 pt-1 fw-semibold fs-6"></span>
|
||||
<!--end::Subtitle-->
|
||||
</div>
|
||||
<!--end::Title-->
|
||||
</div>
|
||||
<div class="card-body" style="box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="ri-apple-fill display-6"></span>
|
||||
<div class="ms-auto">
|
||||
<i data-feather="arrow-right" class="fill-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<h4 class="card-title mb-1 text-white">
|
||||
Maps
|
||||
</h4>
|
||||
<h6 class="card-text fw-normal text-white-50">
|
||||
Add and Edit Maps
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xl-2 d-flex align-items-stretch">
|
||||
<a
|
||||
href="users.php"
|
||||
class="card bg-success text-white w-100 card-hover"
|
||||
>
|
||||
<div class="card-header pt-5">
|
||||
<!--begin::Title-->
|
||||
<div class="card-title d-flex flex-column">
|
||||
<!--begin::Amount-->
|
||||
<span class="fs-2hx fw-bold text-white me-2 lh-1 ls-n2"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person-fill" viewBox="0 0 16 16">
|
||||
<path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6"/>
|
||||
</svg> Users</span>
|
||||
<!--end::Amount-->
|
||||
|
||||
<!--begin::Subtitle-->
|
||||
<span class="text-white opacity-75 pt-1 fw-semibold fs-6"></span>
|
||||
<!--end::Subtitle-->
|
||||
</div>
|
||||
<!--end::Title-->
|
||||
</div>
|
||||
<div class="card-body" style="box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="ri-folders-line display-6"></span>
|
||||
<div class="ms-auto">
|
||||
<i data-feather="arrow-right" class="fill-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<h4 class="card-title mb-1 text-white">Manage Users</h4>
|
||||
<h6 class="card-text fw-normal text-white-50">
|
||||
Add and Edit Users
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xl-2 d-flex align-items-stretch">
|
||||
<a
|
||||
href="access_groups.php"
|
||||
class="card bg-warning text-white w-100 card-hover"
|
||||
>
|
||||
|
||||
<div class="card-header pt-5">
|
||||
<!--begin::Title-->
|
||||
<div class="card-title d-flex flex-column">
|
||||
<!--begin::Amount-->
|
||||
<span class="fs-2hx fw-bold text-white me-2 lh-1 ls-n2"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-people-fill" viewBox="0 0 16 16">
|
||||
<path d="M7 14s-1 0-1-1 1-4 5-4 5 3 5 4-1 1-1 1zm4-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6m-5.784 6A2.24 2.24 0 0 1 5 13c0-1.355.68-2.75 1.936-3.72A6.3 6.3 0 0 0 5 9c-4 0-5 3-5 4s1 1 1 1zM4.5 8a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5"/>
|
||||
</svg> User Groups</span>
|
||||
<!--end::Amount-->
|
||||
|
||||
<!--begin::Subtitle-->
|
||||
<span class="text-white opacity-75 pt-1 fw-semibold fs-6"></span>
|
||||
<!--end::Subtitle-->
|
||||
</div>
|
||||
<!--end::Title-->
|
||||
</div>
|
||||
<div class="card-body" style="box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="ri-spam-2-line display-6"></span>
|
||||
<div class="ms-auto">
|
||||
<i data-feather="arrow-right" class="fill-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<h4 class="card-title mb-1 text-white">
|
||||
User Groups
|
||||
</h4>
|
||||
<h6 class="card-text fw-normal text-white-50">
|
||||
Manage User Groups
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="d-flex border-bottom title-part-padding px-0 mb-3 align-items-center">
|
||||
|
||||
</div>
|
||||
<div class="row" style="width:65%">
|
||||
<div class="col-md-4 col-xl-2 d-flex align-items-stretch">
|
||||
<a
|
||||
href="permalinks.php"
|
||||
class="card bg-purple text-white w-100 card-hover"
|
||||
>
|
||||
<div class="card-body" style="box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="ri-apple-fill display-6"></span>
|
||||
<div class="ms-auto">
|
||||
<i data-feather="arrow-right" class="fill-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<h4 class="card-title mb-1 text-white">
|
||||
Permalinks
|
||||
</h4>
|
||||
<h6 class="card-text fw-normal text-white-50">
|
||||
Manage Permalinks
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xl-2 d-flex align-items-stretch">
|
||||
<a
|
||||
href="../index.php"
|
||||
class="card bg-warning2 text-white w-100 card-hover"
|
||||
>
|
||||
<div class="card-body" style="box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="ri-folders-line display-6"></span>
|
||||
<div class="ms-auto">
|
||||
<i data-feather="arrow-right" class="fill-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<h4 class="card-title mb-1 text-white">Front End</h4>
|
||||
<h6 class="card-text fw-normal text-white-50">
|
||||
Client View
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xl-2 d-flex align-items-stretch">
|
||||
<a
|
||||
href="../logout.php"
|
||||
class="card bg-danger text-white w-100 card-hover"
|
||||
>
|
||||
<div class="card-body" style="box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="ri-spam-2-line display-6"></span>
|
||||
<div class="ms-auto">
|
||||
<i data-feather="arrow-right" class="fill-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<h4 class="card-title mb-1 text-white">
|
||||
Log Out
|
||||
</h4>
|
||||
<h6 class="card-text fw-normal text-white-50">
|
||||
Add and Edit Styles
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer text-center">
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="dist/js/sidebarmenu.js"></script>
|
||||
<script src="dist/js/custom.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('incl/const.php');
|
||||
require('class/database.php');
|
||||
require('class/map.php');
|
||||
|
||||
if(!isset($_SESSION['user']) || $_SESSION['user']->accesslevel != 'Admin') {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$dbconn = $database->getConn();
|
||||
|
||||
$maps_obj = new map_Class($dbconn, $_SESSION['user']->id);
|
||||
$rows = $maps_obj->getRows();
|
||||
|
||||
//TODO: get directory names with new maps
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
|
||||
<head>
|
||||
<?php include("incl/meta.php"); ?>
|
||||
<link href="dist/css/table.css" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap4.min.css">
|
||||
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
// Delete row on delete button click
|
||||
$(document).on("click", ".delete", function() {
|
||||
var obj = $(this);
|
||||
var data = {'delete': true, 'id': obj.parents("tr").attr('data-id')}
|
||||
if(confirm('Map will be deleted ?')){
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/map.php',
|
||||
data: data,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
if(response.success) { // means, new record is added
|
||||
obj.parents("tr").remove();
|
||||
}
|
||||
|
||||
$(".add-new").removeAttr("disabled");
|
||||
alert(response.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$(document).on("click", ".clear", function() {
|
||||
var obj = $(this);
|
||||
var data = {'clear': true, 'id': obj.parents("tr").attr('data-id')}
|
||||
if(confirm('Map cache will be deleted ?')){
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/map.php',
|
||||
data: data,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
if(response.success){
|
||||
obj.hide();
|
||||
}
|
||||
alert(response.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
border: none!important;
|
||||
border-radius: inherit;
|
||||
text-decoration: none!important;
|
||||
}
|
||||
.bg-warning {
|
||||
background-color: #50667f!important;
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main-wrapper" data-layout="vertical" data-navbarbg="skin5" data-sidebartype="full"
|
||||
data-sidebar-position="absolute" data-header-position="absolute" data-boxed-layout="full">
|
||||
|
||||
<?php define('MENU_SEL', 'maps.php');
|
||||
include("incl/topbar.php");
|
||||
include("incl/sidebar.php");
|
||||
?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
|
||||
<div class="page-breadcrumb" style="padding-left:30px; padding-right: 30px; padding-top:0px; padding-bottom: 0px">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<nav aria-label="breadcrumb">
|
||||
|
||||
</nav>
|
||||
<h1 class="mb-0 fw-bold">Maps</h1>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="text-end upgrade-btn">
|
||||
<a href="edit_map.php" class="btn btn-primary text-white add-new" role="button" aria-pressed="true">
|
||||
<i class="fa fa-plus"></i> Add New
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<table class="table table-bordered" id="sortTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-name="id" data-editable='false'>ID</th>
|
||||
<th data-name="name">Name</th>
|
||||
<th data-name="description">Description</th>
|
||||
<th data-editable='false' data-action='true'>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody> <?php while($row = pg_fetch_object($rows)): ?> <tr data-id="<?=$row->id?>" align="left">
|
||||
<td><?=$row->id?></td>
|
||||
<td><?=$row->name?></td>
|
||||
<td><?=$row->description?></td>
|
||||
<td>
|
||||
<a href="edit_map.php?id=<?=$row->id?>" class="edit" title="Edit" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
<?php if(is_dir(CACHE_DIR.'/'.$row->id)) { ?>
|
||||
<a class="clear" title="Clear cache" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<a class="delete" title="Delete" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr> <?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer class="footer text-center">
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="dist/js/sidebarmenu.js"></script>
|
||||
<script src="dist/js/custom.js"></script>
|
||||
<script>new DataTable('#sortTable', { paging: false });</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,357 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('incl/const.php');
|
||||
require('class/database.php');
|
||||
require('class/map.php');
|
||||
require('class/permalink.php');
|
||||
require('class/access_groups.php');
|
||||
|
||||
if(!isset($_SESSION['user']) || $_SESSION['user']->accesslevel != 'Admin') {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$dbconn = $database->getConn();
|
||||
|
||||
$tab = 'permalink'; $action = 'permalink';
|
||||
$conn_obj = new permalink_Class($dbconn, $_SESSION['user']->id);
|
||||
$conn_rows = $conn_obj->getRows();
|
||||
|
||||
$maps_obj = new map_Class($dbconn, $_SESSION['user']->id);
|
||||
$map_rows = $maps_obj->getRows();
|
||||
|
||||
$maps = array();
|
||||
while($row = pg_fetch_assoc($map_rows)){
|
||||
$maps[$row['id']] = $row;
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
|
||||
<head>
|
||||
<?php include("incl/meta.php"); ?>
|
||||
<link href="dist/css/table.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap4.min.css">
|
||||
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
td {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active {
|
||||
color: #fff;
|
||||
background-color: #666;
|
||||
border-color: #f1f9ff #f1f9ff #fff;
|
||||
border-top-left-radius: 12px;
|
||||
border-top-right-radius: 12px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
var actions = `
|
||||
<a class="add" title="Add" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
<a class="edit" title="Edit" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
<a class="delete" title="Delete" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
`;
|
||||
//$("table td:last-child").html();
|
||||
// Append table with add row form on add new button click
|
||||
$(".add-new").click(function() {
|
||||
//var actions = $("table td:last-child").html();
|
||||
$(this).attr("disabled", "disabled");
|
||||
var index = $("table tbody tr:last-child").index();
|
||||
|
||||
var row = '<tr>';
|
||||
|
||||
$("table thead tr th").each(function(k, v) {
|
||||
if($(this).attr('data-editable') == 'false') {
|
||||
|
||||
if($(this).attr('data-action') == 'true') { // last child or actions cell
|
||||
row += '<td>'+actions+'</td>';
|
||||
} else {
|
||||
row += '<td></td>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($(this).attr('data-type') == 'select') {
|
||||
if($(this).attr('data-name') == 'map_id') {
|
||||
row += `
|
||||
<td data-type="select" data-value="0">
|
||||
<select name="`+$(this).attr('data-name')+`">
|
||||
<?PHP foreach($maps as $k => $v) { ?>
|
||||
<option value="<?=$k?>"><?=$v['name']?></option>
|
||||
<?PHP } ?>
|
||||
</select>
|
||||
</td>
|
||||
`;
|
||||
}
|
||||
}else{
|
||||
row += ' <td> <input type = "text" class = "form-control" name="'+$(this).attr('data-name')+'"> </td>';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
row += '</tr>';
|
||||
|
||||
$("table").append(row);
|
||||
$("table tbody tr").eq(index + 1).find(".add, .edit").toggle();
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Add row on add button click
|
||||
$(document).on("click", ".add", function() {
|
||||
var obj = $(this);
|
||||
var empty = false;
|
||||
var input = $(this).parents("tr").find('input[type="text"], select');
|
||||
input.each(function() {
|
||||
if (!$(this).val() && ($(this).attr('name') != 'query')) {
|
||||
$(this).addClass("error");
|
||||
empty = true;
|
||||
} else {
|
||||
$(this).removeClass("error");
|
||||
}
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".error").first().focus();
|
||||
if (!empty) {
|
||||
var data = {};
|
||||
data['save'] = 1;
|
||||
data['id'] = $(this).closest('tr').attr('data-id');
|
||||
|
||||
input.each(function() {
|
||||
if($(this).closest('td').attr('data-type') == 'select') {
|
||||
var val = $(this).find('option:selected').text();
|
||||
$(this).parent("td").attr('data-value', $(this).val());
|
||||
$(this).parent("td").html(val);
|
||||
}else {
|
||||
$(this).parent("td").html($(this).val());
|
||||
}
|
||||
|
||||
data[$(this).attr('name')] = $(this).val();
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/permalink.php',
|
||||
data: data,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
if(response.id) { // means, new record is added
|
||||
obj.closest('table').find('tr:last-child').attr('data-id', response.id);
|
||||
obj.closest('table').find('tr:last-child td:first-child').text(response.id)
|
||||
|
||||
obj.closest('table').find('tr:last-child td').eq(3).text(response.created);
|
||||
obj.closest('table').find('tr:last-child td').eq(4).text(response.expires);
|
||||
obj.closest('table').find('tr:last-child td').eq(5).text(0);
|
||||
var perma_link = '<a href="../' + response.url + '">' + response.hash + '</a>';
|
||||
obj.closest('table').find('tr:last-child td').eq(7).html(perma_link);
|
||||
}
|
||||
alert(response.message)
|
||||
}
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".add, .edit").toggle();
|
||||
$(".add-new").removeAttr("disabled");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Edit row on edit button click
|
||||
$(document).on("click", ".edit", function() {
|
||||
$(this).parents("tr").find("td:not([data-editable=false])").each(function(k, v) {
|
||||
|
||||
if($(this).closest('table').find('thead tr th').eq(k).attr('data-editable') != 'false') {
|
||||
var name = $(this).closest('table').find('thead tr th').eq(k).attr('data-name');
|
||||
var id = $(this).closest('tr').attr('data-id');
|
||||
|
||||
|
||||
if($(this).closest('table').find('thead tr th').eq(k).attr('data-type') == 'select') {
|
||||
if(name == 'map_id') {
|
||||
$(this).html(`
|
||||
<select name="`+name+`" multiple>
|
||||
<?PHP foreach($maps as $k => $v) { ?>
|
||||
<option value="<?=$k?>"><?=$v['name']?></option>
|
||||
<?PHP } ?>
|
||||
</select>
|
||||
`);
|
||||
}
|
||||
|
||||
var val = $(this).attr('data-value').split(',');
|
||||
$(this).find('[name='+name+']').val(val);
|
||||
|
||||
} else {
|
||||
var val = $(this).html().replace('<br>', '&');
|
||||
$(this).html(' <input type = "text" name="'+ name +'" class = "form-control" value = "' + val + '" > ');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".add, .edit").toggle(); $(".add-new").attr("disabled", "disabled");
|
||||
});
|
||||
|
||||
|
||||
// Delete row on delete button click
|
||||
$(document).on("click", ".delete", function() {
|
||||
var obj = $(this);
|
||||
var data = {'delete': true, 'id': obj.parents("tr").attr('data-id')}
|
||||
if(confirm('Connection will be deleted ?')){
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/permalink.php',
|
||||
data: data,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
if(response.success) { // means, new record is added
|
||||
obj.parents("tr").remove();
|
||||
}
|
||||
|
||||
alert(response.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
border: none!important;
|
||||
border-radius: inherit;
|
||||
text-decoration: none!important;
|
||||
}
|
||||
.bg-warning {
|
||||
background-color: #50667f!important;
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="main-wrapper" data-layout="vertical" data-navbarbg="skin5" data-sidebartype="full"
|
||||
data-sidebar-position="absolute" data-header-position="absolute" data-boxed-layout="full">
|
||||
|
||||
<?php define('MENU_SEL', 'permalinks.php');
|
||||
include("incl/topbar.php");
|
||||
include("incl/sidebar.php");
|
||||
?>
|
||||
<div class="page-wrapper">
|
||||
<div class="page-breadcrumb" style="padding-left:30px; padding-right: 30px; padding-top:0px; padding-bottom: 0px">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<nav aria-label="breadcrumb">
|
||||
|
||||
</nav>
|
||||
<h1 class="mb-0 fw-bold">Permalinks</h1>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="text-end upgrade-btn">
|
||||
<div class="text-end upgrade-btn">
|
||||
<a class="btn btn-primary text-white add-new" role="button" aria-pressed="true"><i class="fa fa-plus"></i> Add New</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid"><p> </p>
|
||||
<div class="table-responsive">
|
||||
|
||||
<table class="table table-bordered" id="sortTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-name="id" data-editable='false'>ID</th>
|
||||
<th data-name="map_id" data-type="select">Map</th>
|
||||
<th data-name="description">Description</th>
|
||||
<th data-name="query">Query</th>
|
||||
|
||||
<th data-name="created" data-editable='false'>Created</th>
|
||||
<th data-name="expires">Expires</th>
|
||||
|
||||
<th data-name="visits" data-editable='false'>Visits</th>
|
||||
<th data-name="visits_limit" >Limit</th>
|
||||
|
||||
<th data-name="hash" data-editable='false'>Hash</th>
|
||||
<th data-editable='false' data-action='true'>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody> <?php while($row = pg_fetch_object($conn_rows)): ?> <tr data-id="<?=$row->id?>" align="left">
|
||||
<td><?=$row->id?></td>
|
||||
<td data-type="select" data-value="<?=$row->map_id?>"><?=$maps[$row->map_id]['name']?></td>
|
||||
<td><?=$row->description?></td>
|
||||
<td><?=str_replace('&', '</br>', urldecode($row->query))?></td>
|
||||
<td><?=$row->created?></td>
|
||||
<td><?=$row->expires?></td>
|
||||
<td><?=$row->visits?></td>
|
||||
<td><?=$row->visits_limit?></td>
|
||||
<td>
|
||||
<a href="../apps/<?=$row->map_id?>/index.php?permalink=<?=$row->hash?>"><?=$row->hash?></a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a class="add" title="Add" data-toggle="tooltip"><i class="material-icons"></i></a>
|
||||
<a class="edit" title="Edit" data-toggle="tooltip"><i class="material-icons"></i></a>
|
||||
<a class="delete" title="Delete" data-toggle="tooltip"><i class="material-icons"></i></a>
|
||||
</td>
|
||||
</tr> <?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
||||
<p> </p>
|
||||
<div class="col-6" style="width: 50%!important">
|
||||
<p> </p>
|
||||
<div class = "alert alert-success">
|
||||
<a href = "#" class = "close" data-dismiss = "alert">×</a>
|
||||
<strong>Note:</strong> Permalinks will be auto-deleted on when they expire by time or run out of visits. Limit of 0, disables visits limitation.
|
||||
</div>
|
||||
|
||||
<div class = "alert alert-warning">
|
||||
<a href = "#" class = "close" data-dismiss="alert">×</a>
|
||||
<strong>Note:</strong> In expires you can write PostgreSQL TIMESTAMP values, like '1 hour', '1 day'.
|
||||
For more <a href="https://www.postgresql.org/docs/current/functions-datetime.html" target="_blank">see here.</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>new DataTable('#sortTable', { paging: false });</script>
|
||||
<footer class="footer text-center">
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="dist/js/sidebarmenu.js"></script>
|
||||
<script src="dist/js/custom.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('incl/const.php');
|
||||
require('class/user.php');
|
||||
require('class/access_groups.php');
|
||||
require('class/database.php');
|
||||
|
||||
if(!isset($_SESSION['user']) || $_SESSION['user']->accesslevel != 'Admin') {
|
||||
header('Location: ../login.php');
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$dbconn = $database->getConn();
|
||||
|
||||
$acc_obj = new access_group_Class($dbconn, $_SESSION['user']->id);
|
||||
$acc_grp = $acc_obj->getRowsArr();
|
||||
|
||||
if(isset($_POST['submit'])&&!empty($_POST['submit'])){
|
||||
|
||||
$usr_obj = new user_Class($dbconn, $_SESSION['user']->id);
|
||||
$_POST['ftp_user'] = '';
|
||||
if(empty($_POST['groups'])){
|
||||
$_POST['groups'] = array(1); // give new admin Default group for now
|
||||
}
|
||||
|
||||
$newId = $usr_obj->create($_POST);
|
||||
if($newId > 0){
|
||||
|
||||
if($_POST['accesslevel'] == 'Admin'){
|
||||
|
||||
$myuser_result = $usr_obj->getById($newId);
|
||||
$myuser = pg_fetch_assoc($myuser_result);
|
||||
pg_free_result($myuser_result);
|
||||
|
||||
$email_user = explode('@', $_POST['email'])[0];
|
||||
$_POST['ftp_user'] = $email_user.$newId;
|
||||
|
||||
user_Class::create_ftp_user($_POST['ftp_user'], $_POST['email'], $myuser['password']);
|
||||
|
||||
// create def access group for new admin
|
||||
$def_grp = array('name' => $_POST['ftp_user'], 'userids' => array($newId));
|
||||
$acc_obj = new access_group_Class($dbconn, $newId);
|
||||
$grp_id = $acc_obj->create($def_grp);
|
||||
|
||||
if($grp_id > 0){
|
||||
$_POST['id'] = $newId;
|
||||
$_POST['groups'] = array($grp_id);
|
||||
$usr_obj->update($_POST);
|
||||
}
|
||||
}
|
||||
|
||||
header("Location: users.php");
|
||||
}else{
|
||||
echo "Something Went Wrong";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
|
||||
<head>
|
||||
<?php include("incl/meta.php"); ?>
|
||||
<link href="dist/css/table.css" rel="stylesheet">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
|
||||
$(document).on("change", "#accesslevel", function() {
|
||||
var obj = $(this);
|
||||
const acc_level = obj.find('option:selected').text();
|
||||
|
||||
if(acc_level == 'User'){
|
||||
$('#acc_grp_div').show(); $('#acc_grp_div').attr('required', true);
|
||||
}else{
|
||||
$('#acc_grp_div').hide(); $('#acc_grp_div').attr('required', false);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main-wrapper" data-layout="vertical" data-navbarbg="skin5" data-sidebartype="full"
|
||||
data-sidebar-position="absolute" data-header-position="absolute" data-boxed-layout="full">
|
||||
|
||||
<?php define('MENU_SEL', 'registration.php');
|
||||
include("incl/topbar.php");
|
||||
include("incl/sidebar.php");
|
||||
?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
|
||||
<div class="page-breadcrumb" style="padding-left:30px; padding-right: 30px; padding-top:0px; padding-bottom: 0px">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<nav aria-label="breadcrumb">
|
||||
|
||||
</nav>
|
||||
<h1 class="mb-0 fw-bold">Register New User</h1>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="text-end upgrade-btn">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<table class="table table-bordered">
|
||||
|
||||
|
||||
<tbody>
|
||||
|
||||
<form method="post">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" class="form-control" id="name" placeholder="Enter name" name="name" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">Email:</label>
|
||||
<input type="email" class="form-control" id="email" placeholder="Enter email" name="email" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="accesslevel">Access Level:</label>
|
||||
<select name="accesslevel" id="accesslevel">
|
||||
<option value="User">User</option>
|
||||
<?php if($_SESSION['user']->id == SUPER_ADMIN_ID) { // only super admin can create admins ?>
|
||||
<option value="Admin">Admin</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group" id="acc_grp_div">
|
||||
<fieldset>
|
||||
<legend>Access Groups:</legend>
|
||||
<?php
|
||||
foreach($acc_grp as $group_id => $name){ ?>
|
||||
<p>
|
||||
<input type="checkbox" name="groups[]" id="group_<?=$group_id?>" value="<?=$group_id?>"/>
|
||||
<label for="group_<?=$group_id?>" class="form-label"><?=$name?></label>
|
||||
</p>
|
||||
<?php } ?>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="pwd">Password:</label>
|
||||
<input type="password" class="form-control" id="password" placeholder="Enter password" name="password">
|
||||
</div>
|
||||
|
||||
<input type="submit" name="submit" class="btn btn-primary" value="Submit">
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
||||
|
||||
<div class="col-6">
|
||||
<p> </p>
|
||||
<div id = "repThumbnail" class = "alert alert-danger">
|
||||
<a href = "#" class = "close" data-dismiss = "alert">×</a>
|
||||
<strong>Note:</strong> Be sure to set the Access Level for the user.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type = "text/javascript">
|
||||
$(function(){
|
||||
$(".close").click(function(){
|
||||
$("#repThumbnail").alert();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer text-center">
|
||||
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="dist/js/sidebarmenu.js"></script>
|
||||
<script src="dist/js/custom.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,253 @@
|
|||
<?php
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
|
||||
require('class/user.php');
|
||||
|
||||
if(file_exists('incl/const.php')){
|
||||
require('incl/const.php');
|
||||
}
|
||||
|
||||
$msg="";
|
||||
$smtp_keys = ['host', 'user', 'pass', 'port'];
|
||||
|
||||
$host=empty(DB_HOST) ? '' : DB_HOST;
|
||||
$port=empty(DB_PORT) ? '' : DB_PORT;
|
||||
$dbuname=empty(DB_USER) ? '' : DB_USER;
|
||||
$dbpwd=empty(DB_PASS) ? '' : DB_PASS;
|
||||
$dbname=empty(DB_NAME) ? '' : DB_NAME;
|
||||
$apps_dir=empty(APPS_DIR) ? '' : APPS_DIR;
|
||||
$data_dir=empty(DATA_DIR) ? '' : DATA_DIR;
|
||||
$cache_dir=empty(CACHE_DIR) ? '' : CACHE_DIR;
|
||||
|
||||
|
||||
if(isset($_POST['submit'])){
|
||||
$host=$_POST['host'];
|
||||
$port=$_POST['port'];
|
||||
$dbuname=$_POST['dbuname'];
|
||||
$dbpwd=$_POST['dbpwd'];
|
||||
$dbname=$_POST['dbname'];
|
||||
|
||||
$con = pg_connect("dbname=$dbname user=$dbuname password=$dbpwd host=$host port=$port");
|
||||
if(!$con){
|
||||
$msg= pg_last_error($con);
|
||||
}else{
|
||||
|
||||
$file_data = "<?php\n";
|
||||
$file_data .= "const DB_HOST = '$host';\n";
|
||||
$file_data .= "const DB_NAME = '$dbname';\n";
|
||||
$file_data .= "const DB_SCMA = 'public';\n";
|
||||
$file_data .= "const DB_USER = '$dbuname';\n";
|
||||
$file_data .= "const DB_PASS = '$dbpwd';\n";
|
||||
$file_data .= "const DB_PORT = '$port';\n";
|
||||
$file_data .= "const SUPER_ADMIN_ID = 1;\n";
|
||||
$file_data .= "const ACCESS_LEVELS = array('User', 'Admin', 'Devel');\n";
|
||||
$file_data .= "const ADMINISTRATION_ACCESS_LEVELS = array('Admin', 'Devel');\n";
|
||||
$file_data .= "const APPS_DIR = '$apps_dir';\n";
|
||||
$file_data .= "const DATA_DIR = '$data_dir';\n";
|
||||
$file_data .= "const CACHE_DIR = '$cache_dir';\n";
|
||||
|
||||
foreach($smtp_keys as $k){
|
||||
$file_data .= "const SMTP_".strtoupper($k)." = '".$_POST['smtp_'.$k]."';\n";
|
||||
}
|
||||
|
||||
file_put_contents('incl/const.php', $file_data);
|
||||
|
||||
$sql = file_get_contents('setup.sql');
|
||||
$res = pg_query($con, $sql);
|
||||
if(!$res){
|
||||
echo pg_last_error($con);
|
||||
die();
|
||||
}
|
||||
|
||||
$def_user = array('name' => 'John Smith', 'email' => 'admin@admin.com', 'password' => '1234',
|
||||
'accesslevel' => 'Admin', 'ftp_user' => 'admin1', 'owner_id' => 1);
|
||||
$def_grp = array('name' => 'Default', 'owner_id' => 1);
|
||||
$def_usr_grps = array('user_id' => 1, 'access_group_id' => 1);
|
||||
|
||||
$def_user['password'] = password_hash($def_user['password'], PASSWORD_DEFAULT);
|
||||
|
||||
// insert manually
|
||||
if(!pg_insert($con, 'public.user', $def_user) ||
|
||||
!pg_insert($con, 'public.access_groups', $def_grp) ||
|
||||
!pg_insert($con, 'public.user_access', $def_usr_grps) ){
|
||||
die(pg_last_error($con));
|
||||
}
|
||||
|
||||
user_Class::create_ftp_user($def_user['ftp_user'], $def_user['email'], $def_user['password']);
|
||||
|
||||
if(!isset($_POST['allow_signup'])){
|
||||
|
||||
$result = pg_query($con, 'DROP TABLE signup');
|
||||
|
||||
unlink('../signup.php');
|
||||
unlink('class/signup.php');
|
||||
unlink('action/signup.php');
|
||||
unlink('action/verify.php');
|
||||
}
|
||||
|
||||
unlink('setup.sql');
|
||||
unlink('setup.php');
|
||||
|
||||
header('location:index.php');
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>QGIS2Map App Installer</title>
|
||||
<link href="../assets/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
table{width:30% !important; text-align:center; margin:auto; margin-top:70px;}
|
||||
.success{color:green;}
|
||||
.error{color:red;}
|
||||
.frm{width:70% !important; margin:auto; margin-top:100px;}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<main role="main" class="container">
|
||||
<?php
|
||||
if((isset($_GET['step'])) && $_GET['step']==2){
|
||||
?>
|
||||
<div align="center"><p> </p><img src="img/jri-admin-logo.png"></div>
|
||||
|
||||
<form class="frm" method="post">
|
||||
|
||||
<span class="error"><?=$msg?></span>
|
||||
|
||||
<div>
|
||||
<fieldset>
|
||||
<legend>Database</legend>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="Host" required name="host" value="<?=$host?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="number" class="form-control" placeholder="Port Number" required name="port" value="<?=$port?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="Database User Name" required name="dbuname" value="<?=$dbuname?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="Database Password" name="dbpwd" value="<?=$dbpwd?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="Database Name" required name="dbname" value="<?=$dbname?>">
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<fieldset>
|
||||
<legend>SMTP details:</legend>
|
||||
<div class="form-group">
|
||||
<?php foreach($smtp_keys as $k){ ?>
|
||||
<input type="text" class="form-control" placeholder="<?=$k?>" name="smtp_<?=$k?>" value="" required>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<fieldset>
|
||||
<legend>Options</legend>
|
||||
<div class="form-group">
|
||||
<input type="checkbox" class="form-checkbox" placeholder="signup allowed" name="allow_signup" value="1"/>
|
||||
<label for="allow_signup">Allow Sign-Up for Admin accounts</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div align="right">
|
||||
<button type="submit" name="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
}else{
|
||||
?>
|
||||
|
||||
<div align="center"><p> </p>QGIS2Map App Installer</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Requirement</th>
|
||||
<th scope="col">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">PHP Version</th>
|
||||
<td>
|
||||
<?php
|
||||
$is_error="";
|
||||
$php_version=phpversion();
|
||||
if($php_version>5){
|
||||
echo "<span class='success'>".$php_version."</span>";
|
||||
}else{
|
||||
echo "<span class='error'>".$php_version."</span>";
|
||||
$is_error='yes';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Session Working</th>
|
||||
<td>
|
||||
<?php
|
||||
$_SESSION['IS_WORKING']=1;
|
||||
if(!empty($_SESSION['IS_WORKING'])){
|
||||
echo "<span class='success'>Yes</span>";
|
||||
}else{
|
||||
echo "<span class='error'>No</span>";
|
||||
$is_error='yes';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row"><?=$apps_dir?></th>
|
||||
<td>
|
||||
<?php
|
||||
if(is_writeable($apps_dir)){
|
||||
echo "<span class='success'>Writeable</span>";
|
||||
}else{
|
||||
echo "<span class='error'>Not writeable</span>";
|
||||
$is_error='yes';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<?php
|
||||
if($is_error==''){
|
||||
?>
|
||||
<a href="?step=2"><button type="button" class="btn btn-success">Next</button></a>
|
||||
<?php
|
||||
}else{
|
||||
?><button type="button" class="btn btn-danger">Errors</button><br><br>Please fix above error(s) and try again<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
<?php }?>
|
||||
|
||||
</main>
|
||||
|
||||
<script src="https://getbootstrap.com/docs/4.0/dist/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,54 @@
|
|||
CREATE TYPE public.userlevel AS ENUM ('Admin', 'User', 'Devel');
|
||||
|
||||
CREATE TABLE public.user ( id SERIAL PRIMARY KEY,
|
||||
name character varying(250),
|
||||
email character varying(250),
|
||||
password character varying(255),
|
||||
ftp_user character varying(250),
|
||||
accesslevel public.userlevel,
|
||||
owner_id integer NOT NULL REFERENCES public.user(id),
|
||||
UNIQUE(email)
|
||||
);
|
||||
|
||||
CREATE TABLE public.access_groups ( id SERIAL PRIMARY KEY,
|
||||
name character varying(255) NOT NULL,
|
||||
owner_id integer NOT NULL REFERENCES public.user(id)
|
||||
);
|
||||
|
||||
CREATE TABLE public.user_access ( id SERIAL PRIMARY KEY,
|
||||
user_id integer NOT NULL REFERENCES public.user(id),
|
||||
access_group_id integer NOT NULL REFERENCES public.access_groups(id),
|
||||
UNIQUE(user_id, access_group_id)
|
||||
);
|
||||
|
||||
CREATE TABLE public.map ( id SERIAL PRIMARY KEY,
|
||||
name character varying(50) NOT NULL,
|
||||
description character varying(50) NOT NULL,
|
||||
owner_id integer NOT NULL REFERENCES public.user(id)
|
||||
);
|
||||
|
||||
CREATE TABLE public.map_access ( id SERIAL PRIMARY KEY,
|
||||
map_id integer NOT NULL REFERENCES public.map(id),
|
||||
access_group_id integer NOT NULL REFERENCES public.access_groups(id),
|
||||
UNIQUE(map_id, access_group_id)
|
||||
);
|
||||
|
||||
CREATE TABLE public.permalink ( id SERIAL PRIMARY KEY,
|
||||
description character varying(255),
|
||||
query character varying(255),
|
||||
map_id integer NOT NULL REFERENCES public.map(id),
|
||||
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
expires TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + interval '1 hour',
|
||||
visits integer NOT NULL DEFAULT 0,
|
||||
visits_limit integer NOT NULL DEFAULT 1,
|
||||
hash character varying(36) NOT NULL,
|
||||
owner_id integer NOT NULL REFERENCES public.user(id)
|
||||
);
|
||||
|
||||
CREATE TABLE public.signup ( id SERIAL PRIMARY KEY,
|
||||
name character varying(250),
|
||||
email character varying(250),
|
||||
password character varying(250),
|
||||
verify character varying(250),
|
||||
UNIQUE(email)
|
||||
);
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
const MAP_ID = MAP_ID_VALUE;
|
||||
include('../../admin/snippets/index_prefix.php');
|
||||
readfile('DATA_FILE');
|
||||
?>
|
|
@ -0,0 +1,40 @@
|
|||
var VARNAME =
|
||||
<?php
|
||||
const MAP_ID = MAP_ID_VALUE;
|
||||
include('../../admin/snippets/index_prefix.php');
|
||||
|
||||
const CACHE_PERIOD = CACHE_PERIOD_SECONDS;
|
||||
const GS_URL = 'FULL_URL';
|
||||
if(CACHE_PERIOD == 0){
|
||||
readfile(GS_URL);
|
||||
}else {
|
||||
$js_file = CACHE_DIR.'/MAP_ID_VALUE/VARNAME_data.js';
|
||||
if(!is_file($js_file) || (time() - filemtime($js_file)) > CACHE_PERIOD){
|
||||
|
||||
if(!is_dir(CACHE_DIR.'/MAP_ID_VALUE')){
|
||||
mkdir(CACHE_DIR.'/MAP_ID_VALUE');
|
||||
}
|
||||
|
||||
$fin = fopen(GS_URL, 'r');
|
||||
$fout = fopen($js_file, 'w');
|
||||
|
||||
while(($contents = fread($fin, 4096))){
|
||||
fwrite($fout, $contents);
|
||||
}
|
||||
fclose($fin);
|
||||
fclose($fout);
|
||||
}
|
||||
readfile($js_file);
|
||||
}
|
||||
?>
|
||||
;
|
||||
|
||||
{
|
||||
let qc_id = 0;
|
||||
VARNAME.features.forEach(function (feat) { feat.properties["qc_id"] = qc_id; qc_id = qc_id + 1;});
|
||||
|
||||
if(VARNAME.features[0].properties["gid"] === undefined){
|
||||
let gid = 0;
|
||||
VARNAME.features.forEach(function (feat) { feat.properties["gid"] = gid; gid = gid + 1;});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
var VARNAME =
|
||||
<?php
|
||||
const MAP_ID = MAP_ID_VALUE;
|
||||
include('../../admin/snippets/index_prefix.php');
|
||||
|
||||
const CACHE_PERIOD = CACHE_PERIOD_SECONDS;
|
||||
if(CACHE_PERIOD == 0){
|
||||
$proj_db = new Database("PG_HOST", "PG_DB", "PG_USER", "PG_PWD", PG_PORT, "public");
|
||||
$proj_db->getGeoJSON("public", "PG_TBL", "geom");
|
||||
}else {
|
||||
$js_file = CACHE_DIR.'/MAP_ID_VALUE/VARNAME_data.js';
|
||||
if(!is_file($js_file) || (time() - filemtime($js_file)) > CACHE_PERIOD){
|
||||
|
||||
if(!is_dir(CACHE_DIR.'/MAP_ID_VALUE')){
|
||||
mkdir(CACHE_DIR.'/MAP_ID_VALUE');
|
||||
}
|
||||
|
||||
$fout = fopen($js_file, 'w');
|
||||
ob_start(function($buffer) use($fout){
|
||||
fwrite($fout, $buffer);
|
||||
}, 1024); //notice the use of chunk_size == 1
|
||||
|
||||
$proj_db = new Database("PG_HOST", "PG_DB", "PG_USER", "PG_PWD", PG_PORT, "public");
|
||||
$proj_db->getGeoJSON("public", "PG_TBL", "geom");
|
||||
|
||||
ob_end_clean();
|
||||
|
||||
fclose($fout);
|
||||
}
|
||||
readfile($js_file);
|
||||
}
|
||||
?>
|
||||
;
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
if(SHOW_DATATABLES){ ?>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
let lg_ids_i = 0;
|
||||
|
||||
<?php for($i=0; $i < count(JS_VARNAMES); $i++){
|
||||
$varname = JS_VARNAMES[$i]; ?>
|
||||
var columns_<?=$i?> = Object.keys(<?=$varname?>.features[0].properties).map(function(k){
|
||||
return {'title' : k};
|
||||
});
|
||||
|
||||
if (typeof <?=$varname?>_lg_ids !== 'undefined') {
|
||||
columns_<?=$i?>.unshift({'title' : '#'});
|
||||
}
|
||||
|
||||
lg_ids_i = 0;
|
||||
const dataSet_<?=$i?> = <?=$varname?>.features.map(function(e) {
|
||||
var props = Object.keys(e.properties).map(function(k){
|
||||
return e.properties[k];
|
||||
});
|
||||
|
||||
if (typeof <?=$varname?>_lg_ids !== 'undefined') {
|
||||
var t = '<a href="javascript:void(0);" class="fa fa-search" onclick="focusLayer(\'<?=$varname?>_lg\',' + <?=$varname?>_lg_ids[lg_ids_i] + ')"></a>';
|
||||
props.unshift(t);
|
||||
lg_ids_i = lg_ids_i + 1;
|
||||
}
|
||||
|
||||
return props;
|
||||
});
|
||||
|
||||
$('#dataTable<?=$i?>').DataTable({
|
||||
columns: columns_<?=$i?>,
|
||||
deferRender: true,
|
||||
data: dataSet_<?=$i?>
|
||||
});
|
||||
<?php } ?>
|
||||
});
|
||||
</script>
|
||||
<div id='dataTables'>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<?php $first = ' active'; $li_first = 'class="nav-item" role="presentation"';
|
||||
for($i=0; $i < count(JS_VARNAMES); $i++){
|
||||
$varname = JS_VARNAMES[$i]; ?>
|
||||
<li <?=$li_first?>>
|
||||
<button class="nav-link<?=$first?>" href="#tab-table<?=$i?>" data-bs-toggle="tab" data-bs-target="#tab-table<?=$i?>"><?=$varname?></button>
|
||||
</li>
|
||||
<?php $first = ''; $li_first = ''; } ?>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content pt-2">
|
||||
<?php $first = ' show active';
|
||||
for($i=0; $i < count(JS_VARNAMES); $i++){
|
||||
$varname = JS_VARNAMES[$i]; ?>
|
||||
<div class="tab-pane<?=$first?>" id="tab-table<?=$i?>">
|
||||
<table id="dataTable<?=$i?>" class="table table-striped table-bordered" cellspacing="0" width="100%"></table>
|
||||
<p class="mb-0"> <a href="javascript:void(0);" onclick="dataToCSV('<?=$varname?>', <?=$varname?>)">Export to CSV</a> </p>
|
||||
</div>
|
||||
<?php $first = ''; } ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
|
@ -0,0 +1,15 @@
|
|||
<?php if(SHOW_DATATABLES) { ?>
|
||||
var DtControl = L.Control.extend({
|
||||
options: { position: 'topleft' },
|
||||
|
||||
onAdd: function(map) {
|
||||
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control');
|
||||
container.title = 'Hide/Show DataTables';
|
||||
container.innerHTML = `<a href="#" id="dt-link" class="fa fa-table"></a>`;
|
||||
L.DomEvent.disableClickPropagation(container); /* Prevent click events propagation to map */
|
||||
return container;
|
||||
}
|
||||
});
|
||||
map.addControl(new DtControl());
|
||||
map.on('click', unfocusLayer);
|
||||
<?php } ?>
|
|
@ -0,0 +1,136 @@
|
|||
<header>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
||||
<link href="../../assets/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="../../assets/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
|
||||
<div class="navbar navbar-dark bg-dark shadow-sm" style="background-color:#50667f!important">
|
||||
<div class="container">
|
||||
<a href="#" class="navbar-brand d-flex align-items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-text" viewBox="0 0 16 16">
|
||||
<path d="M5.5 7a.5.5 0 0 0 0 1h5a.5.5 0 0 0 0-1h-5zM5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z"/>
|
||||
<path d="M9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0zm0 1v2A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5z"/>
|
||||
</svg> <strong> QatMaps</strong>
|
||||
</a>
|
||||
<?php if((isset($_SESSION['user'])) && ($_SESSION['user']->accesslevel == 'Admin')) { ?>
|
||||
<a href="../../admin/index.php" style="text-decoration:none; color: #fff!important; font-size: 1.25rem; font-weight: 300;">Administration</a>
|
||||
<a href="../../logout.php" style="text-decoration:none; color: #fff!important; font-size: 1.25rem; font-weight: 300;">Log Out</a>
|
||||
<?php } else { ?>
|
||||
<a href="../../index.php" style="text-decoration:none; color: #fff!important; font-size: 1.25rem; font-weight: 300;">Back to Dashboard</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<style>
|
||||
.sidebar {
|
||||
max-width: 300px;
|
||||
background: white;
|
||||
max-height: 400px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
display: none;
|
||||
}
|
||||
.sidebar .close {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
var table_visible = false;
|
||||
|
||||
$(document).ready(function() {
|
||||
$(document).on("click", ".copy", function() {
|
||||
var obj = $(".modal-body");
|
||||
var temp = $("<input>");
|
||||
$("body").append(temp);
|
||||
temp.val(obj.text()).select();
|
||||
temp.focus();
|
||||
document.execCommand("copy");
|
||||
temp.remove();
|
||||
});
|
||||
|
||||
$(document).on("click", "#fg-permalink", function() {
|
||||
//href = /apps/57/index.php#11/41.8036/-87.6407
|
||||
let path = window.location.href.split('/apps/')[1]; // 57/index.php#11/41.8036/-87.6407
|
||||
let loc = path.split('#');
|
||||
let map_id = loc[0].split('/');
|
||||
$.get('../../admin/action/permalink.php?id=' + map_id[0] + '&loc=' + loc[1], function (data){
|
||||
const response = $.parseJSON(data);
|
||||
if(response.success){
|
||||
var url = window.location.origin + '/' + response.url;
|
||||
$('.modal-body').html( '<a href="' + url + '" target="_blank">' + url +'</a>');
|
||||
$('#conn_modal').modal('show');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on("click", "#dt-link", function() {
|
||||
const d = (table_visible) ? 1 : 2;
|
||||
|
||||
$("#map").height($(window).height() / d);
|
||||
map.invalidateSize();
|
||||
table_visible = !table_visible;
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php if(SHOW_DATATABLES) { ?>
|
||||
<script>
|
||||
|
||||
var saved_lg_name = null;
|
||||
var saved_layer_id = null;
|
||||
|
||||
const on_focus_style = {
|
||||
color: "#efefef",
|
||||
fillColor: "#efefef",
|
||||
opacity: 1.0,
|
||||
fillOpacity: 1.0,
|
||||
weight: 1
|
||||
};
|
||||
|
||||
function unfocusLayer(){
|
||||
if(saved_lg_name != null){
|
||||
var lg_name = saved_lg_name;
|
||||
var l = window[lg_name].getLayer(saved_layer_id);
|
||||
|
||||
var lg_style = {
|
||||
color: window[lg_name].options.color,
|
||||
fillColor: window[lg_name].options.fillColor,
|
||||
opacity: window[lg_name].options.opacity,
|
||||
fillOpacity: window[lg_name].options.fillOpacity,
|
||||
weight: window[lg_name].options.weight
|
||||
};
|
||||
|
||||
l.setStyle(lg_style);
|
||||
|
||||
saved_lg_name = null;
|
||||
saved_layer_id = null;
|
||||
}
|
||||
}
|
||||
|
||||
function focusLayer(lg_name, layer_id){
|
||||
var l = window[lg_name].getLayer(layer_id);
|
||||
|
||||
unfocusLayer();
|
||||
saved_lg_name = lg_name;
|
||||
saved_layer_id = layer_id;
|
||||
|
||||
if(l.getLatLng){
|
||||
map.flyTo(l.getLatLng());
|
||||
}else{
|
||||
var bounds = l.getBounds();
|
||||
map.fitBounds(bounds); // Fit the map to the polygon bounds
|
||||
map.panTo(bounds.getCenter()); // Or center on the polygon
|
||||
}
|
||||
l.setStyle(on_focus_style);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="../../assets/dist/js/tbl2CSV.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap4.min.css">
|
||||
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap4.min.js"></script>
|
||||
<?php } ?>
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('../../admin/incl/const.php');
|
||||
require('../../admin/class/database.php');
|
||||
require('../../admin/class/permalink.php');
|
||||
require('../../admin/class/access_groups.php');
|
||||
|
||||
$loc = null;
|
||||
const SHOW_DATATABLES = false;
|
||||
const JS_VARNAMES = array();
|
||||
|
||||
if(isset($_GET['permalink']) || isset($_SESSION['permalink'])){
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$obj = new permalink_Class($database->getConn(), $_SESSION['user']->id);
|
||||
|
||||
if(isset($_GET['permalink'])){ // called from index.php
|
||||
$_SESSION['permalink'] = $_GET['permalink']; // save permalink for data_{file,gs,pg}.php
|
||||
$row = $obj->getMap($_GET['permalink'], 1);
|
||||
}else{
|
||||
$row = $obj->getMap($_SESSION['permalink'], 0);
|
||||
}
|
||||
|
||||
if($row == null){
|
||||
die('Sorry permalink is invalid or expired!');
|
||||
}
|
||||
|
||||
$map_id = $row['map_id'];
|
||||
if($map_id != MAP_ID){
|
||||
die('Sorry permalink is not for this map!');
|
||||
}
|
||||
|
||||
$loc = explode('/', $row['query']); // 11/41.8036/-87.6407
|
||||
}else{
|
||||
|
||||
if(!isset($_SESSION['user'])) {
|
||||
header('Location: ../../login.php');
|
||||
exit;
|
||||
}
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$map_id = MAP_ID;
|
||||
$acc_obj = new access_group_Class($database->getConn(), $_SESSION['user']->id);
|
||||
|
||||
$usr_grps = $acc_obj->getByUserId($_SESSION['user']->id);
|
||||
if(!count($usr_grps)){
|
||||
die('Sorry, no access group!');
|
||||
}
|
||||
|
||||
$usr_grps = $acc_obj->getGroupMapGroups(array_keys($usr_grps));
|
||||
if(!count($usr_grps) || !isset($usr_grps[$map_id])){
|
||||
die('Sorry, access not allowed!');
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,80 @@
|
|||
<?php if(empty(DB_HOST)){ die("Error: Can\'t execute!"); } ?>
|
||||
|
||||
var VARNAME_data_lg = L.layerGroup(null, {
|
||||
color: "STYLE_COLOR",
|
||||
fillColor: "STYLE_FILL_COLOR",
|
||||
opacity: STYLE_OPACITY,
|
||||
fillOpacity: STYLE_FILL_OPACITY,
|
||||
weight: 2
|
||||
});
|
||||
var VARNAME_data_lg_ids = [];
|
||||
const VARNAME_data = <?php
|
||||
|
||||
function fn_VARNAME(){
|
||||
$CACHE_PERIOD = CACHE_PERIOD_SECONDS;
|
||||
$GS_URL = 'FULL_URL';
|
||||
if($CACHE_PERIOD == 0){
|
||||
readfile($GS_URL);
|
||||
}else {
|
||||
$js_file = CACHE_DIR.'/MAP_ID_VALUE/VARNAME_data.js';
|
||||
if(!is_file($js_file) || (time() - filemtime($js_file)) > $CACHE_PERIOD){
|
||||
|
||||
if(!is_dir(CACHE_DIR.'/MAP_ID_VALUE')){
|
||||
mkdir(CACHE_DIR.'/MAP_ID_VALUE');
|
||||
}
|
||||
|
||||
$fin = fopen($GS_URL, 'r');
|
||||
$fout = fopen($js_file, 'w');
|
||||
|
||||
while(($contents = fread($fin, 4096))){
|
||||
fwrite($fout, $contents);
|
||||
}
|
||||
fclose($fin);
|
||||
fclose($fout);
|
||||
}
|
||||
readfile($js_file);
|
||||
}
|
||||
}
|
||||
fn_VARNAME();
|
||||
?>;
|
||||
|
||||
var VARNAME = L.geoJson(VARNAME_data, {
|
||||
style: {
|
||||
color: "STYLE_COLOR",
|
||||
fillColor: "STYLE_FILL_COLOR",
|
||||
opacity: STYLE_OPACITY,
|
||||
fillOpacity: STYLE_FILL_OPACITY,
|
||||
weight: 2
|
||||
},
|
||||
onEachFeature(feature, layer) {
|
||||
|
||||
VARNAME_data_lg.addLayer(layer);
|
||||
VARNAME_data_lg_ids.push(layer._leaflet_id);
|
||||
|
||||
var on_event = 'click';
|
||||
|
||||
layer.on(on_event, function(e) {
|
||||
var properties = feature.properties;
|
||||
|
||||
var html = '<table style="text-align: left; font-size: 100%;">';
|
||||
for (const key in properties) {
|
||||
html += '<tr><th>'+ key +"</th> <td>"+ properties[key] + "</td></tr>";
|
||||
}
|
||||
html += '</table>';
|
||||
|
||||
$('.sidebar .table-container').html(html);
|
||||
$('.sidebar').show();
|
||||
});
|
||||
},
|
||||
|
||||
pointToLayer(feature, latlng) {
|
||||
return L.circleMarker(latlng, {
|
||||
radius: 6,
|
||||
color: "STYLE_COLOR",
|
||||
fillColor: "STYLE_FILL_COLOR",
|
||||
opacity: STYLE_OPACITY,
|
||||
fillOpacity: STYLE_FILL_OPACITY,
|
||||
weight: 2
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
var CustomControlPermalink = L.Control.extend({
|
||||
options: { position: 'topleft'},
|
||||
onAdd: function(map) {
|
||||
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control');
|
||||
container.innerHTML = `<a href="#" id="fg-permalink" class="fa fa-share-alt"></a>`;
|
||||
L.DomEvent.disableClickPropagation(container); // Prevent click events propagation to map
|
||||
return container;
|
||||
}
|
||||
});
|
||||
map.addControl(new CustomControlPermalink());
|
|
@ -0,0 +1,15 @@
|
|||
<div id="conn_modal" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<p>This permalink will be available for 1h and deleted after 1 visit.</p>
|
||||
</div>
|
||||
|
||||
<div class="modal-body" id="modal-body"><p>Permalink URL.</p></div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary copy">Copy</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,19 @@
|
|||
L.control.browserPrint({
|
||||
title: 'Just print me!',
|
||||
documentTitle: 'Map printed using leaflet.browser.print plugin',
|
||||
printLayer: L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> — Map data © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
||||
subdomains: 'abcd',
|
||||
minZoom: 1,
|
||||
maxZoom: 16,
|
||||
ext: 'png'
|
||||
}),
|
||||
closePopupsOnPrint: false,
|
||||
printModes: [
|
||||
L.BrowserPrint.Mode.Landscape(),
|
||||
"Portrait",
|
||||
L.BrowserPrint.Mode.Auto("B4",{title: "Auto"}),
|
||||
L.BrowserPrint.Mode.Custom("B5",{title:"Select area"})
|
||||
],
|
||||
manualMode: false
|
||||
}).addTo(map);
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('../../admin/incl/const.php');
|
||||
require('../../admin/class/database.php');
|
||||
require('../../admin/class/access_groups.php');
|
||||
|
||||
if(!isset($_SESSION['user'])) {
|
||||
header('Location: ../../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
|
||||
$map_id = MAP_ID;
|
||||
$acc_obj = new access_group_Class($database->getConn(), $_SESSION['user']->id);
|
||||
|
||||
$usr_grps = $acc_obj->getByUserId($_SESSION['user']->id);
|
||||
if(!count($usr_grps)){
|
||||
die('Sorry, no access group!');
|
||||
}
|
||||
|
||||
$usr_grps = $acc_obj->getGroupMapGroups(array_keys($usr_grps));
|
||||
if(!count($usr_grps) || !isset($usr_grps[$map_id])){
|
||||
die('Sorry, access not allowed!');
|
||||
}
|
||||
|
||||
// https://shop.chicagotvguides.com/geoserver/wms?service=WMS&request=GetFeatureInfo&version=1.1.1&layers=topp%3Astates&styles=&format=image%2Fpng&transparent=true&continuousWorld=true&tiled=true&info_format=text%2Fhtml&width=1374&height=852&srs=EPSG%3A3857&bbox=-12983287.876406899%2C1633917.916623927%2C-6261721.357121639%2C5801876.194958019&query_layers=topp%3Astates&X=653&Y=285
|
||||
const BASE_URL = 'BASE_URL_VALUE';
|
||||
readfile(BASE_URL.'?'.$_SERVER['QUERY_STRING']);
|
||||
|
||||
/*define("COOKIE_FILE", "/tmp/cookie.txt");
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, BASE_URL.'?'.$_SERVER['QUERY_STRING']);
|
||||
curl_setopt($curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
|
||||
curl_setopt($curl, CURLOPT_USERPWD, "admin:geoserver");
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 0);
|
||||
curl_setopt($curl, CURLOPT_FORBID_REUSE, TRUE);
|
||||
//curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array('Connection: close'));
|
||||
$result = curl_exec($curl);
|
||||
curl_close($curl);*/
|
||||
?>
|
|
@ -0,0 +1,406 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Simple Transactional Email</title>
|
||||
<style>
|
||||
/* -------------------------------------
|
||||
GLOBAL RESETS
|
||||
------------------------------------- */
|
||||
|
||||
/*All the styling goes here*/
|
||||
|
||||
img {
|
||||
border: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f6f6f6;
|
||||
font-family: sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: separate;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
width: 100%; }
|
||||
table td {
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
BODY & CONTAINER
|
||||
------------------------------------- */
|
||||
|
||||
.body {
|
||||
background-color: #f6f6f6;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
|
||||
.container {
|
||||
display: block;
|
||||
margin: 0 auto !important;
|
||||
/* makes it centered */
|
||||
max-width: 580px;
|
||||
padding: 10px;
|
||||
width: 580px;
|
||||
}
|
||||
|
||||
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 580px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
HEADER, FOOTER, MAIN
|
||||
------------------------------------- */
|
||||
.main {
|
||||
background: #ffffff;
|
||||
border-radius: 3px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.content-block {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
clear: both;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
.footer td,
|
||||
.footer p,
|
||||
.footer span,
|
||||
.footer a {
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
TYPOGRAPHY
|
||||
------------------------------------- */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
color: #000000;
|
||||
font-family: sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
margin: 0;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 35px;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
p,
|
||||
ul,
|
||||
ol {
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
p li,
|
||||
ul li,
|
||||
ol li {
|
||||
list-style-position: inside;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #3498db;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
BUTTONS
|
||||
------------------------------------- */
|
||||
.btn {
|
||||
box-sizing: border-box;
|
||||
width: 100%; }
|
||||
.btn > tbody > tr > td {
|
||||
padding-bottom: 15px; }
|
||||
.btn table {
|
||||
width: auto;
|
||||
}
|
||||
.btn table td {
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
.btn a {
|
||||
background-color: #ffffff;
|
||||
border: solid 1px #3498db;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
color: #3498db;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 12px 25px;
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.btn-primary table td {
|
||||
background-color: #3498db;
|
||||
}
|
||||
|
||||
.btn-primary a {
|
||||
background-color: #3498db;
|
||||
border-color: #3498db;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
OTHER STYLES THAT MIGHT BE USEFUL
|
||||
------------------------------------- */
|
||||
.last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.mt0 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.mb0 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.preheader {
|
||||
color: transparent;
|
||||
display: none;
|
||||
height: 0;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
mso-hide: all;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.powered-by a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
border-bottom: 1px solid #f6f6f6;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||
------------------------------------- */
|
||||
@media only screen and (max-width: 620px) {
|
||||
table[class=body] h1 {
|
||||
font-size: 28px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
table[class=body] p,
|
||||
table[class=body] ul,
|
||||
table[class=body] ol,
|
||||
table[class=body] td,
|
||||
table[class=body] span,
|
||||
table[class=body] a {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
table[class=body] .wrapper,
|
||||
table[class=body] .article {
|
||||
padding: 10px !important;
|
||||
}
|
||||
table[class=body] .content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
table[class=body] .container {
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .main {
|
||||
border-left-width: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
table[class=body] .btn table {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .btn a {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .img-responsive {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
PRESERVE THESE STYLES IN THE HEAD
|
||||
------------------------------------- */
|
||||
@media all {
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
.apple-link a {
|
||||
color: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-size: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
#MessageViewBody a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
.btn-primary table td:hover {
|
||||
background-color: #34495e !important;
|
||||
}
|
||||
.btn-primary a:hover {
|
||||
background-color: #34495e !important;
|
||||
border-color: #34495e !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body class="">
|
||||
<span class="preheader">This is preheader text. Some clients will show this text as a preview.</span>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td class="container">
|
||||
<div class="content">
|
||||
|
||||
<!-- START CENTERED WHITE CONTAINER -->
|
||||
<table role="presentation" class="main">
|
||||
|
||||
<!-- START MAIN CONTENT AREA -->
|
||||
<tr>
|
||||
<td class="wrapper">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
<p>Hi USER_NAME,</p>
|
||||
<p>Click below to verify your email address for QatMaps.</p>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td> <a href="VERIFY_URL" target="_blank">Verify Email</a> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Questions? Be sure to read the <a href="https://qatmaps.docs.acugis.com">Docs</a></p>
|
||||
<p>Happy Mapping!.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- END MAIN CONTENT AREA -->
|
||||
</table>
|
||||
<!-- END CENTERED WHITE CONTAINER -->
|
||||
|
||||
<!-- START FOOTER -->
|
||||
<div class="footer">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td class="content-block">
|
||||
<span class="apple-link">AcuGIS</span><br>
|
||||
<span class="apple-link">Cited, Inc. Wilmington, Delaware 19802</span>
|
||||
<br> Don't like these emails? <a href="http://i.imgur.com/CScmqnj.gif">Unsubscribe</a>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content-block powered-by">
|
||||
Powered by <a href="http://htmlemail.io">HTMLemail</a>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- END FOOTER -->
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,318 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('incl/const.php');
|
||||
require('class/database.php');
|
||||
require('class/user.php');
|
||||
require('class/access_groups.php');
|
||||
|
||||
if(!isset($_SESSION['user']) || $_SESSION['user']->accesslevel != 'Admin') {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
$dbconn = $database->getConn();
|
||||
|
||||
$obj = new user_Class($dbconn, $_SESSION['user']->id);
|
||||
$users = $obj->getRows();
|
||||
|
||||
$myuser_result = $obj->getById($_SESSION['user']->id);
|
||||
$myuser = pg_fetch_assoc($myuser_result);
|
||||
pg_free_result($myuser_result);
|
||||
|
||||
$acc_obj = new access_group_Class($dbconn, $_SESSION['user']->id);
|
||||
$acc_grps = $acc_obj->getRowsArr();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
|
||||
<head>
|
||||
<?php include("incl/meta.php"); ?>
|
||||
<link href="dist/css/table.css" rel="stylesheet">
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
// Append table with add row form on add new button click
|
||||
$(".add-new").click(function() {
|
||||
//var actions = $("table td:last-child").html();
|
||||
$(this).attr("disabled", "disabled");
|
||||
var index = $("table tbody tr:last-child").index();
|
||||
|
||||
var row = '<tr>';
|
||||
|
||||
$("table thead tr th").each(function(k, v) {
|
||||
if($(this).attr('data-editable') == 'false') {
|
||||
|
||||
if($(this).attr('data-action') == 'true') { // last child or actions cell
|
||||
row += '<td>'+actions+'</td>';
|
||||
}
|
||||
else {
|
||||
row += '<td></td>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($(this).attr('data-type') == 'select') {
|
||||
if($(this).attr('data-name') == 'groups') {
|
||||
row += `
|
||||
<td data-type="select" data-value="0">
|
||||
<select name="`+$(this).attr('data-name')+`" multiple>
|
||||
<?PHP foreach($acc_grps as $k => $v) { ?>
|
||||
<option value="<?=$k?>"><?=$v?></option>
|
||||
<?PHP } ?>
|
||||
</select>
|
||||
</td>
|
||||
`;
|
||||
}
|
||||
else if($(this).attr('data-name') == 'accesslevel') {
|
||||
row += `
|
||||
<td data-type="select" data-value="0">
|
||||
<select name="`+$(this).attr('data-name')+`">
|
||||
<?PHP foreach(ACCESS_LEVELS as $k) { ?>
|
||||
<option value="<?=$k?>"><?=$k?></option>
|
||||
<?PHP } ?>
|
||||
</select>
|
||||
</td>
|
||||
`;
|
||||
}
|
||||
}
|
||||
else {
|
||||
row += ' <td> <input type = "text" class = "form-control" name="'+$(this).attr('data-name')+'"> </td>';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
row += '</tr>';
|
||||
|
||||
$("table").append(row);
|
||||
$("table tbody tr").eq(index + 1).find(".add, .edit").toggle();
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Add row on add button click
|
||||
$(document).on("click", ".add", function() {
|
||||
var obj = $(this);
|
||||
var empty = false;
|
||||
var input = $(this).parents("tr").find('input[type="text"], select');
|
||||
input.each(function() {
|
||||
if (!$(this).val()) {
|
||||
$(this).addClass("error");
|
||||
empty = true;
|
||||
} else {
|
||||
$(this).removeClass("error");
|
||||
}
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".error").first().focus();
|
||||
if (!empty) {
|
||||
var data = {};
|
||||
data['save'] = 1;
|
||||
data['id'] = $(this).closest('tr').attr('data-id');
|
||||
|
||||
input.each(function() {
|
||||
if($(this).closest('td').attr('data-type') == 'select') {
|
||||
var val = $(this).find('option:selected').text();
|
||||
$(this).parent("td").attr('data-value', $(this).val());
|
||||
$(this).parent("td").html(val);
|
||||
}else {
|
||||
$(this).parent("td").html($(this).val());
|
||||
}
|
||||
|
||||
data[$(this).attr('name')] = $(this).val();
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/user.php',
|
||||
data: data,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
if(response.id) { // means, new record is added
|
||||
obj.closest('table').find('tr:last-child').attr('data-id', response.id);
|
||||
obj.closest('table').find('tr:last-child td:first-child').text(response.id)
|
||||
}
|
||||
alert(response.message)
|
||||
}
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".add, .edit").toggle();
|
||||
$(".add-new").removeAttr("disabled");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Edit row on edit button click
|
||||
$(document).on("click", ".edit", function() {
|
||||
$(this).parents("tr").find("td:not([data-editable=false])").each(function(k, v) {
|
||||
|
||||
if($(this).closest('table').find('thead tr th').eq(k).attr('data-editable') != 'false') {
|
||||
var name = $(this).closest('table').find('thead tr th').eq(k).attr('data-name');
|
||||
var id = $(this).closest('tr').attr('data-id');
|
||||
|
||||
if($(this).closest('table').find('thead tr th').eq(k).attr('data-type') == 'select') {
|
||||
if(name == 'accesslevel') {
|
||||
$(this).html(`
|
||||
<select name="`+name+`">
|
||||
<?PHP foreach(ACCESS_LEVELS as $k) { ?>
|
||||
<option value="<?=$k?>"><?=$k?></option>
|
||||
<?PHP } ?>
|
||||
</select>
|
||||
`);
|
||||
|
||||
var val = $(this).attr('data-value');
|
||||
$(this).find('[name='+name+']').val(val);
|
||||
} else if(name == 'groups') {
|
||||
$(this).html(`
|
||||
<select name="`+name+`" multiple>
|
||||
<?PHP foreach($acc_grps as $k => $v) { ?>
|
||||
<option value="<?=$k?>"><?=$v?></option>
|
||||
<?PHP } ?>
|
||||
</select>
|
||||
`);
|
||||
}
|
||||
|
||||
var val = $(this).attr('data-value').split(',');
|
||||
$(this).find('[name='+name+']').val(val);
|
||||
|
||||
} else {
|
||||
$(this).html(' <input type = "text" name="'+ name +'" class = "form-control" value = "' + $(this).text() + '" > ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$(this).parents("tr").find(".add, .edit").toggle();
|
||||
$(".add-new").attr("disabled", "disabled");
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Delete row on delete button click
|
||||
$(document).on("click", ".delete", function() {
|
||||
var obj = $(this);
|
||||
var data = {'delete': true, 'id': obj.parents("tr").attr('data-id')}
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'action/user.php',
|
||||
data: data,
|
||||
dataType:"json",
|
||||
success: function(response){
|
||||
if(response.success) { // means, new record is added
|
||||
obj.parents("tr").remove();
|
||||
}
|
||||
|
||||
$(".add-new").removeAttr("disabled");
|
||||
alert(response.message);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main-wrapper" data-layout="vertical" data-navbarbg="skin5" data-sidebartype="full"
|
||||
data-sidebar-position="absolute" data-header-position="absolute" data-boxed-layout="full">
|
||||
|
||||
<?php const MENU_SEL = 'users.php';
|
||||
include("incl/topbar.php");
|
||||
include("incl/sidebar.php");
|
||||
?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
|
||||
<div class="page-breadcrumb" style="padding-left:30px; padding-right: 30px; padding-top:0px; padding-bottom: 0px">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<nav aria-label="breadcrumb">
|
||||
|
||||
</nav>
|
||||
<h1 class="mb-0 fw-bold">Users</h1>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="text-end upgrade-btn">
|
||||
|
||||
|
||||
<a href="registration.php" class="btn btn-info btn-md active" role="button" aria-pressed="true">Add User</a>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-name="id" data-editable='false'>ID</th>
|
||||
<th data-name="name">name</th>
|
||||
<th data-name="email" data-editable='false'>Email</th>
|
||||
<th data-name="password">Password</th>
|
||||
<th data-name="ftp_user" data-editable='false'>FTP User</th>
|
||||
<th data-name="accesslevel" data-type="select">Access Level</th>
|
||||
<th data-name="groups" data-type="select">Access Groups</th>
|
||||
<th data-editable='false' data-action='true'>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody> <?php while($user = pg_fetch_object($users)): ?> <tr data-id="<?=$user->id?>" align="left">
|
||||
<td><?=$user->id?> </td>
|
||||
<td><?= $user->name?></td>
|
||||
<td><?= $user->email?></td>
|
||||
<td><?= $user->password?></td>
|
||||
<td><?= $user->ftp_user?></td>
|
||||
<td data-type="select" data-value="<?=$user->accesslevel?>"><?=$user->accesslevel?></td>
|
||||
<?php
|
||||
$usr_acc_grps = $acc_obj->getByUserId($user->id);
|
||||
$grp_ids = implode(',',array_keys($usr_acc_grps));
|
||||
$grp_names = implode(',',array_values($usr_acc_grps));
|
||||
?>
|
||||
<td data-type="select" data-value="<?=$grp_ids?>"><?=$grp_names?></td>
|
||||
<td>
|
||||
<a class="add" title="Add" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
<a class="edit" title="Edit" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
<a class="delete" title="Delete" data-toggle="tooltip">
|
||||
<i class="material-icons"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr> <?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-6" style="width: 50%!important">
|
||||
<div class = "alert alert-success">
|
||||
<a href = "#" class = "close" data-dismiss = "alert">×</a>
|
||||
<strong>Note:</strong> Your personal FTP login username is <b><?=$myuser['ftp_user']?></b>. For password use your login password.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Menu sidebar -->
|
||||
<script src="dist/js/sidebarmenu.js"></script>
|
||||
<!--Custom JavaScript -->
|
||||
<script src="dist/js/custom.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="408" fill="#fff"><path d="M106.342 0c-29.214 0-50.827 25.58-49.86 53.32.927 26.647-.278 61.165-8.966 89.31C38.802 170.862 24.07 188.707 0 191v26c24.069 2.293 38.802 20.138 47.516 48.37 8.688 28.145 9.893 62.663 8.965 89.311C55.515 382.42 77.128 408 106.342 408h299.353c29.214 0 50.827-25.58 49.861-53.319-.928-26.648.277-61.166 8.964-89.311 8.715-28.232 23.411-46.077 47.48-48.37v-26c-24.069-2.293-38.765-20.138-47.48-48.37-8.687-28.145-9.892-62.663-8.964-89.31C456.522 25.58 434.909 0 405.695 0H106.342zm236.559 251.102c0 38.197-28.501 61.355-75.798 61.355h-87.202a2 2 0 01-2-2v-213a2 2 0 012-2h86.74c39.439 0 65.322 21.354 65.322 54.138 0 23.008-17.409 43.61-39.594 47.219v1.203c30.196 3.309 50.532 24.212 50.532 53.085zm-84.58-128.125h-45.91v64.814h38.669c29.888 0 46.373-12.03 46.373-33.535 0-20.151-14.174-31.279-39.132-31.279zm-45.91 90.53v71.431h47.605c31.12 0 47.605-12.482 47.605-35.941 0-23.46-16.947-35.49-49.608-35.49h-45.602z"/></svg>
|
After Width: | Height: | Size: 1007 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="408"><defs><linearGradient id="bs-logo-a" x1="76.079" x2="523.48" y1="10.798" y2="365.945" gradientUnits="userSpaceOnUse"><stop stop-color="#9013fe"/><stop offset="1" stop-color="#6610f2"/></linearGradient><linearGradient id="bs-logo-b" x1="193.508" x2="293.514" y1="109.74" y2="278.872" gradientUnits="userSpaceOnUse"><stop stop-color="#fff"/><stop offset="1" stop-color="#f1e5fc"/></linearGradient><filter xmlns="http://www.w3.org/2000/svg" id="bs-logo-c" width="197" height="249" x="161.901" y="83.457" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/><feOffset dy="4"/><feGaussianBlur stdDeviation="8"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow"/><feBlend in="SourceGraphic" in2="effect1_dropShadow" result="shape"/></filter></defs><path fill="url(#bs-logo-a)" d="M56.481 53.32C55.515 25.58 77.128 0 106.342 0h299.353c29.214 0 50.827 25.58 49.861 53.32-.928 26.647.277 61.165 8.964 89.31 8.715 28.232 23.411 46.077 47.48 48.37v26c-24.069 2.293-38.765 20.138-47.48 48.37-8.687 28.145-9.892 62.663-8.964 89.311.966 27.739-20.647 53.319-49.861 53.319H106.342c-29.214 0-50.827-25.58-49.86-53.319.927-26.648-.278-61.166-8.966-89.311C38.802 237.138 24.07 219.293 0 217v-26c24.069-2.293 38.802-20.138 47.516-48.37 8.688-28.145 9.893-62.663 8.965-89.31z"/><path fill="url(#bs-logo-b)" filter="url(#bs-logo-c)" stroke="#fff" d="M267.103 312.457c47.297 0 75.798-23.158 75.798-61.355 0-28.873-20.336-49.776-50.532-53.085v-1.203c22.185-3.609 39.594-24.211 39.594-47.219 0-32.783-25.882-54.138-65.322-54.138h-88.74v217h89.202zm-54.692-189.48h45.911c24.958 0 39.131 11.128 39.131 31.279 0 21.505-16.484 33.535-46.372 33.535h-38.67v-64.814zm0 161.961v-71.431h45.602c32.661 0 49.608 12.03 49.608 35.49 0 23.459-16.484 35.941-47.605 35.941h-47.605z"/></svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,11 @@
|
|||
var sidebarControl = L.Control.extend({
|
||||
options: { position: 'bottomleft'},
|
||||
onAdd: function (map) {
|
||||
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
|
||||
container.innerHTML = `<div class="sidebar">
|
||||
<a href="#" class="btn btn-sm mt-1 mx-3 close" id="fg-close-it" onclick="$(this).closest('.sidebar').hide()">X</a>
|
||||
<div class="table-container px-3 py-4"></div>
|
||||
</div>`;
|
||||
return container;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,78 @@
|
|||
function tableToCSV(tbl_id, csv_name) {
|
||||
|
||||
// Variable to store the final csv data
|
||||
var csv_data = [];
|
||||
|
||||
//gets table
|
||||
var tbl = document.getElementById(tbl_id);
|
||||
|
||||
//gets rows of table
|
||||
const rows_len = tbl.rows.length;
|
||||
|
||||
// Get each row data
|
||||
for (var i = 0; i < rows_len; i++) {
|
||||
|
||||
//gets cells of current row
|
||||
var cols = tbl.rows.item(i).cells;
|
||||
|
||||
//gets amount of cells of current row
|
||||
var cols_len = cols.length;
|
||||
|
||||
//loops through each cell in current row
|
||||
var csvrow = [];
|
||||
for(var j = 0; j < cols_len; j++){
|
||||
// Get the text data of each cell
|
||||
// of a row and push it to csvrow
|
||||
csvrow.push(cols[j].innerHTML);
|
||||
}
|
||||
|
||||
// Combine each column value with comma
|
||||
csv_data.push(csvrow.join(","));
|
||||
}
|
||||
|
||||
// Combine each row data with new line character
|
||||
csv_data = csv_data.join('\n');
|
||||
|
||||
// Call this function to download csv file
|
||||
downloadCSVFile(csv_name, csv_data);
|
||||
|
||||
}
|
||||
|
||||
function dataToCSV(csv_name, project_data){
|
||||
var csv_hdr = JSON.stringify(Object.keys(project_data.features[0].properties)).replace(/(^\[)|(\]$)/mg, '');
|
||||
var csv_data = project_data.features.map(function (feat){
|
||||
return JSON.stringify(Object.values(feat.properties));
|
||||
}).join('\n')
|
||||
.replace(/(^\[)|(\]$)/mg, '');
|
||||
|
||||
// Call this function to download csv file
|
||||
downloadCSVFile(csv_name, csv_hdr + '\n' + csv_data);
|
||||
}
|
||||
|
||||
function downloadCSVFile(csv_name, csv_data) {
|
||||
|
||||
// Create CSV file object and feed
|
||||
// our csv_data into it
|
||||
CSVFile = new Blob([csv_data], {
|
||||
type: "text/csv"
|
||||
});
|
||||
|
||||
// Create to temporary link to initiate
|
||||
// download process
|
||||
var temp_link = document.createElement('a');
|
||||
|
||||
// Download csv file
|
||||
|
||||
temp_link.download = csv_name + '.csv';
|
||||
var url = window.URL.createObjectURL(CSVFile);
|
||||
temp_link.href = url;
|
||||
|
||||
// This link should not be displayed
|
||||
temp_link.style.display = "none";
|
||||
document.body.appendChild(temp_link);
|
||||
|
||||
// Automatically click the link to
|
||||
// trigger download
|
||||
temp_link.click();
|
||||
document.body.removeChild(temp_link);
|
||||
}
|
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 176 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 84 KiB |
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
session_start();
|
||||
require('admin/incl/const.php');
|
||||
require('admin/class/database.php');
|
||||
require('admin/class/access_groups.php');
|
||||
|
||||
if(!isset($_SESSION['user'])) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$database = new Database(DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_PORT, DB_SCMA);
|
||||
|
||||
$acc_obj = new access_group_Class($database->getConn(), $_SESSION['user']->id);
|
||||
$usr_grps = ($_SESSION['user']->id == SUPER_ADMIN_ID) ? $acc_obj->getRowsArr()
|
||||
: $acc_obj->getByUserId($_SESSION['user']->id);
|
||||
|
||||
$rows = array();
|
||||
if(count($usr_grps)){
|
||||
$usr_grps_keys = array_keys($usr_grps);
|
||||
$usr_map_grps = $acc_obj->getGroupMapGroups($usr_grps_keys);
|
||||
|
||||
if(count($usr_map_grps)){
|
||||
$usr_map_grps_ids = implode(',', array_keys($usr_map_grps));
|
||||
$rows = $database->getAll('map', "id IN (".$usr_map_grps_ids.")", 'id');
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<title>QGIS2Map App</title>
|
||||
|
||||
<link href="assets/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
.bd-placeholder-img {
|
||||
font-size: 1.125rem;
|
||||
text-anchor: middle;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.bd-placeholder-img-lg {
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
box-shadow: 0 0.15rem 0.55rem rgba(0, 0, 0, 0.1);
|
||||
transition: box-shadow 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 0.35rem 0.85rem rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.col {
|
||||
padding-right: calc(var(--bs-gutter-x) * .75);
|
||||
padding-left: calc(var(--bs-gutter-x) * .75);
|
||||
}
|
||||
|
||||
.navbar {
|
||||
position: relative;
|
||||
min-height: 50px;
|
||||
margin-bottom: 0px!important;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
|
||||
<div class="navbar navbar-dark bg-dark shadow-sm" style="background-color:#50667f!important">
|
||||
<div class="container">
|
||||
<a href="#" class="navbar-brand d-flex align-items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-text" viewBox="0 0 16 16">
|
||||
<path d="M5.5 7a.5.5 0 0 0 0 1h5a.5.5 0 0 0 0-1h-5zM5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z"/>
|
||||
<path d="M9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0zm0 1v2A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5z"/>
|
||||
</svg> <strong> QatMaps</strong>
|
||||
</a>
|
||||
|
||||
<?php
|
||||
if(in_array($_SESSION['user']->accesslevel, ADMINISTRATION_ACCESS_LEVELS)){
|
||||
echo '<a href="admin/index.php" style="text-decoration:none; color: #fff!important; font-size: 1.25rem; font-weight: 300;">Administration</a>';
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<a href="logout.php" style="text-decoration:none; color: #fff!important; font-size: 1.25rem; font-weight: 300;">Log Out</a>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<main style="background-color:#edf0f2">
|
||||
|
||||
<section class="py-5 text-left container" style="padding-bottom: 0rem!important;">
|
||||
<div class="row py-lg-5">
|
||||
<div class="col-lg-6 col-md-8 mx-auto" style="margin-left: 5px!important;">
|
||||
<h1 class="fw-light"><?php echo $_SESSION['user']->name;?> Maps
|
||||
|
||||
</h1>
|
||||
<p class="lead text-muted">Maps</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="album py-5 bg-light">
|
||||
<div class="container">
|
||||
|
||||
|
||||
<div class="row row-cols-1 row-cols-md-4 g-4">
|
||||
|
||||
<?php foreach($rows as $row) {
|
||||
$image = file_exists("assets/maps/{$row['id']}.png") ? "assets/maps/{$row['id']}.png" : "assets/maps/default.png"; ?>
|
||||
<div class="col">
|
||||
<a href="apps/<?=$row['id']?>/index.php" style="text-decoration:none; color: #6c757d!important; font-size: 1.25rem; font-weight: 300;">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title" style="font-size: 15px; font-weight: 800;"><?=$row['name']?></h5>
|
||||
</div>
|
||||
<div class="px-3">
|
||||
<div style="height: 150px; width: 100%; background: url('<?=$image?>') no-repeat; background-size: cover; background-position: center center;"></div>
|
||||
</div>
|
||||
<?PHP if($row['description']) { ?>
|
||||
<div class="card-body">
|
||||
<p class="card-text" style="color: #6c757d!important; font-size: 15px; font-weight: 600;"> <?=$row['description']?> </p>
|
||||
</div>
|
||||
<?PHP } ?>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="text-muted py-5">
|
||||
<div class="container">
|
||||
<p class="float-end mb-1">
|
||||
<a href="#" style="text-decoration:none; color: #6c757d!important; font-size: 1.25rem; font-weight: 300;">Back to top</a> </p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="assets/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,68 @@
|
|||
<IfModule mod_ssl.c>
|
||||
<VirtualHost _default_:443>
|
||||
#ServerName example.com
|
||||
#ServerAlias www.example.com
|
||||
ServerAdmin webmaster@localhost
|
||||
|
||||
DocumentRoot /var/www/html
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
|
||||
#SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
|
||||
|
||||
#SSLCACertificatePath /etc/ssl/certs/
|
||||
#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
|
||||
|
||||
#SSLCARevocationPath /etc/apache2/ssl.crl/
|
||||
#SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl
|
||||
|
||||
# Client Authentication (Type):
|
||||
# Client certificate verification type and depth. Types are
|
||||
# none, optional, require and optional_no_ca. Depth is a
|
||||
# number which specifies how deeply to verify the certificate
|
||||
# issuer chain before deciding the certificate is not valid.
|
||||
#SSLVerifyClient require
|
||||
#SSLVerifyDepth 10
|
||||
|
||||
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
|
||||
<FilesMatch "\.php$">
|
||||
SSLOptions +StdEnvVars
|
||||
</FilesMatch>
|
||||
|
||||
<Directory "/">
|
||||
Require all denied
|
||||
</Directory>
|
||||
|
||||
<Directory "/var/www/html/">
|
||||
Require all granted
|
||||
Options -Indexes
|
||||
<LimitExcept GET POST>
|
||||
Deny from all
|
||||
</LimitExcept>
|
||||
</Directory>
|
||||
|
||||
<Directory "/var/www/html/class">
|
||||
Require all denied
|
||||
</Directory>
|
||||
|
||||
<Directory "/var/www/html/admin/class">
|
||||
Require all denied
|
||||
</Directory>
|
||||
|
||||
<Directory "/var/www/html/admin/snippets">
|
||||
Require all denied
|
||||
</Directory>
|
||||
|
||||
|
||||
<FilesMatch "\.(jpe?g|png|gif|js|css|ico)$">
|
||||
ExpiresActive On
|
||||
ExpiresDefault "access plus 1 day"
|
||||
</FilesMatch>
|
||||
|
||||
|
||||
</VirtualHost>
|
||||
</IfModule>
|
|
@ -0,0 +1,80 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
APP_DB='q2w'
|
||||
APP_DB_PASS=$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c32);
|
||||
DATA_DIR='/var/www/data'
|
||||
CACHE_DIR='/var/www/cache'
|
||||
APPS_DIR='/var/www/html/apps'
|
||||
|
||||
if [ ! -d installer ]; then
|
||||
echo "Usage: ./installer/app-installer.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 1. Install packages (assume PG is preinstalled)
|
||||
apt-get -y install apache2 libapache2-mod-php php-{pgsql,zip,gd} proftpd
|
||||
|
||||
# setup apache
|
||||
a2enmod ssl headers expires
|
||||
cp installer/apache2.conf /etc/apache2/sites-available/default-ssl.conf
|
||||
a2ensite default-ssl
|
||||
a2dissite 000-default
|
||||
systemctl reload apache2
|
||||
|
||||
sed -i.save '
|
||||
s/#DefaultRoot~/DefaultRoot ~/
|
||||
s/# RequireValidShelloff/RequireValidShell off/' /etc/proftpd/proftpd.conf
|
||||
systemctl enable proftpd
|
||||
systemctl restart proftpd
|
||||
|
||||
# 2. Create db
|
||||
su postgres <<CMD_EOF
|
||||
createdb ${APP_DB}
|
||||
createuser -sd ${APP_DB}
|
||||
psql -c "alter user ${APP_DB} with password '${APP_DB_PASS}'"
|
||||
psql -c "ALTER DATABASE ${APP_DB} OWNER TO ${APP_DB}"
|
||||
CMD_EOF
|
||||
|
||||
echo "${APP_DB} pass: ${APP_DB_PASS}" >> /root/auth.txt
|
||||
|
||||
mkdir -p "${APPS_DIR}"
|
||||
mkdir -p "${CACHE_DIR}"
|
||||
mkdir -p "${DATA_DIR}"
|
||||
|
||||
chown -R www-data:www-data "${APPS_DIR}"
|
||||
chown -R www-data:www-data "${CACHE_DIR}"
|
||||
chown -R www-data:www-data "${DATA_DIR}"
|
||||
|
||||
cat >admin/incl/const.php <<CAT_EOF
|
||||
<?php
|
||||
define("DB_HOST", "localhost");
|
||||
define("DB_NAME", "${APP_DB}");
|
||||
define("DB_USER", "${APP_DB}");
|
||||
define("DB_PASS", "${APP_DB_PASS}");
|
||||
define("DB_PORT", 5432);
|
||||
define("DB_SCMA", 'public');
|
||||
define("APPS_DIR", "${APPS_DIR}");
|
||||
define("CACHE_DIR", "${APPS_DIR}");
|
||||
define("DATA_DIR", "${DATA_DIR}");
|
||||
?>
|
||||
CAT_EOF
|
||||
|
||||
cp -r . /var/www/html/
|
||||
chown -R www-data:www-data /var/www/html
|
||||
rm -rf /var/www/html/installer
|
||||
|
||||
systemctl restart apache2
|
||||
|
||||
# create group for all FTP users
|
||||
groupadd qatusers
|
||||
|
||||
# install ftp user creation script
|
||||
for f in create delete; do
|
||||
cp installer/${f}_ftp_user.sh /usr/local/bin/
|
||||
chown www-data:www-data /usr/local/bin/${f}_ftp_user.sh
|
||||
chmod 0550 /usr/local/bin/${f}_ftp_user.sh
|
||||
done
|
||||
|
||||
cat >/etc/sudoers.d/q2w <<CAT_EOF
|
||||
www-data ALL = NOPASSWD: /usr/local/bin/create_ftp_user.sh, /usr/local/bin/delete_ftp_user.sh
|
||||
CAT_EOF
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
read FTP_USERNAME
|
||||
read FTP_PASSWORD
|
||||
|
||||
useradd -G qatusers -m -s /usr/sbin/nologin ${FTP_USERNAME}
|
||||
echo -n "${FTP_USERNAME}:${FTP_PASSWORD}" | chpasswd -e
|
||||
|
||||
FTP_HOME=$(grep "^${FTP_USERNAME}:" /etc/passwd | cut -f6 -d:)
|
||||
|
||||
# allow Apache access
|
||||
chown ${FTP_USERNAME}:www-data "${FTP_HOME}"
|
||||
chmod 0755 "${FTP_HOME}"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
FTP_USERNAME="${1}"
|
||||
|
||||
if [ $(groups "${FTP_USERNAME}" | grep -m 1 -c 'qatusers') -gt 0 ]; then
|
||||
userdel -r ${FTP_USERNAME}
|
||||
fi
|
|
@ -0,0 +1,309 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
APP_DB='q2w'
|
||||
APP_DB_PASS=$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c32);
|
||||
DATA_DIR='/var/www/data'
|
||||
CACHE_DIR='/var/www/cache'
|
||||
APPS_DIR='/var/www/html/apps'
|
||||
|
||||
PG_VER='16'
|
||||
PG_PASS=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32);
|
||||
|
||||
HNAME=$(hostname -I | sed -n 1p | cut -f1 -d' ' | tr -d '\n')
|
||||
|
||||
USE_SSL='no'
|
||||
|
||||
declare -x STEPS=('Initializing')
|
||||
declare -x CMDS=('init_installer')
|
||||
|
||||
function install_postgresql(){
|
||||
RELEASE=$(lsb_release -cs)
|
||||
|
||||
#3. Install PostgreSQL
|
||||
echo "deb http://apt.postgresql.org/pub/repos/apt/ ${RELEASE}-pgdg main" > /etc/apt/sources.list.d/pgdg.list
|
||||
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
||||
|
||||
apt-get update -y || true
|
||||
|
||||
apt-get install -y postgresql-${PG_VER} postgresql-client-${PG_VER} postgresql-contrib-${PG_VER} \
|
||||
python3-postgresql postgresql-plperl-${PG_VER} \
|
||||
postgresql-pltcl-${PG_VER} postgresql-${PG_VER}-postgis-3 \
|
||||
odbc-postgresql libpostgresql-jdbc-java
|
||||
if [ ! -f /usr/lib/postgresql/${PG_VER}/bin/postgres ]; then
|
||||
echo "Error: Get PostgreSQL version"; exit 1;
|
||||
fi
|
||||
|
||||
ln -sf /usr/lib/postgresql/${PG_VER}/bin/pg_config /usr/bin
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/main/ /var/lib/postgresql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/backups /var/lib/postgresql
|
||||
|
||||
systemctl start postgresql
|
||||
|
||||
#5. Set postgres Password
|
||||
if [ $(grep -m 1 -c 'pg pass' /root/auth.txt) -eq 0 ]; then
|
||||
sudo -u postgres psql 2>/dev/null -c "alter user postgres with password '${PG_PASS}'"
|
||||
echo "pg pass: ${PG_PASS}" > /root/auth.txt
|
||||
fi
|
||||
|
||||
#4. Add Postgre variables to environment
|
||||
if [ $(grep -m 1 -c 'PGDATA' /etc/environment) -eq 0 ]; then
|
||||
cat >>/etc/environment <<CMD_EOF
|
||||
PGDATA=/var/lib/postgresql/${PG_VER}/main
|
||||
CMD_EOF
|
||||
fi
|
||||
|
||||
#6. Configure ph_hba.conf
|
||||
cat >/etc/postgresql/${PG_VER}/main/pg_hba.conf <<CMD_EOF
|
||||
local all all trust
|
||||
host all all 127.0.0.1 255.255.255.255 trust
|
||||
host all all 0.0.0.0/0 scram-sha-256
|
||||
host all all ::1/128 scram-sha-256
|
||||
hostssl all all 127.0.0.1 255.255.255.255 scram-sha-256
|
||||
hostssl all all 0.0.0.0/0 scram-sha-256
|
||||
hostssl all all ::1/128 scram-sha-256
|
||||
CMD_EOF
|
||||
sed -i.save "s/.*listen_addresses.*/listen_addresses = '*'/" /etc/postgresql/${PG_VER}/main/postgresql.conf
|
||||
sed -i.save "s/.*ssl =.*/ssl = on/" /etc/postgresql/${PG_VER}/main/postgresql.conf
|
||||
|
||||
#10. Create Symlinks for Backward Compatibility from PostgreSQL 9 to PostgreSQL 8
|
||||
#ln -sf /usr/pgsql-9.4/bin/pg_config /usr/bin
|
||||
mkdir -p /var/lib/pgsql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/main /var/lib/pgsql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/backups /var/lib/pgsql
|
||||
|
||||
#create SSL certificates
|
||||
if [ ! -f /var/lib/postgresql/${PG_VER}/main/server.key -o ! -f /var/lib/postgresql/${PG_VER}/main/server.crt ]; then
|
||||
SSL_PASS=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32);
|
||||
if [ $(grep -m 1 -c 'ssl pass' /root/auth.txt) -eq 0 ]; then
|
||||
echo "ssl pass: ${SSL_PASS}" >> /root/auth.txt
|
||||
else
|
||||
sed -i.save "s/ssl pass:.*/ssl pass: ${SSL_PASS}/" /root/auth.txt
|
||||
fi
|
||||
openssl genrsa -des3 -passout pass:${SSL_PASS} -out server.key 2048
|
||||
openssl rsa -in server.key -passin pass:${SSL_PASS} -out server.key
|
||||
|
||||
chmod 400 server.key
|
||||
|
||||
openssl req -new -key server.key -days 3650 -out server.crt -passin pass:${SSL_PASS} -x509 -subj '/C=CA/ST=Frankfurt/L=Frankfurt/O=acuciva-de.com/CN=acuciva-de.com/emailAddress=info@acugis.com'
|
||||
chown postgres.postgres server.key server.crt
|
||||
mv server.key server.crt /var/lib/postgresql/${PG_VER}/main
|
||||
fi
|
||||
|
||||
systemctl restart postgresql
|
||||
}
|
||||
|
||||
function install_webmin(){
|
||||
|
||||
if [ -f "/etc/letsencrypt/live/${HNAME}/cert.pem" ]; then
|
||||
cat /etc/letsencrypt/live/${HNAME}/cert.pem > /etc/webmin/miniserv.pem
|
||||
cat /etc/letsencrypt/live/${HNAME}/privkey.pem >> /etc/webmin/miniserv.pem
|
||||
echo "extracas=/etc/letsencrypt/live/${HNAME}/fullchain.pem" >> /etc/webmin/miniserv.conf
|
||||
fi
|
||||
|
||||
systemctl restart webmin
|
||||
|
||||
echo "deb http://download.webmin.com/download/repository sarge contrib" > /etc/apt/sources.list.d/webmin.list
|
||||
wget --quiet -qO - http://www.webmin.com/jcameron-key.asc | apt-key add -
|
||||
apt-get -y update
|
||||
apt-get -y install webmin
|
||||
}
|
||||
|
||||
function install_proftpd(){
|
||||
apt-get -y install proftpd
|
||||
sed -i.save '
|
||||
s/#DefaultRoot~/DefaultRoot ~/
|
||||
s/# RequireValidShelloff/RequireValidShell off/' /etc/proftpd/proftpd.conf
|
||||
systemctl enable proftpd
|
||||
systemctl restart proftpd
|
||||
|
||||
cat >/etc/sudoers.d/q2w <<CAT_EOF
|
||||
www-data ALL = NOPASSWD: /usr/local/bin/create_ftp_user.sh, /usr/local/bin/delete_ftp_user.sh
|
||||
CAT_EOF
|
||||
}
|
||||
|
||||
function install_qat_application(){
|
||||
# 1. Install packages (assume PG is preinstalled)
|
||||
apt-get -y install apache2 libapache2-mod-php php-{pgsql,zip,gd}
|
||||
|
||||
# setup apache
|
||||
a2enmod ssl headers expires
|
||||
|
||||
cp installer/apache2.conf /etc/apache2/sites-available/default-ssl.conf
|
||||
sed -i.save "s/#ServerName example.com/#ServerName ${HNAME}/" /etc/apache2/sites-available/default-ssl.conf
|
||||
|
||||
a2ensite default-ssl
|
||||
a2dissite 000-default
|
||||
systemctl reload apache2
|
||||
|
||||
# 2. Create db
|
||||
su postgres <<CMD_EOF
|
||||
createdb ${APP_DB}
|
||||
createuser -sd ${APP_DB}
|
||||
psql -c "alter user ${APP_DB} with password '${APP_DB_PASS}'"
|
||||
psql -c "ALTER DATABASE ${APP_DB} OWNER TO ${APP_DB}"
|
||||
CMD_EOF
|
||||
|
||||
echo "${APP_DB} pass: ${APP_DB_PASS}" >> /root/auth.txt
|
||||
|
||||
mkdir -p "${APPS_DIR}"
|
||||
mkdir -p "${CACHE_DIR}"
|
||||
mkdir -p "${DATA_DIR}"
|
||||
|
||||
chown -R www-data:www-data "${APPS_DIR}"
|
||||
chown -R www-data:www-data "${CACHE_DIR}"
|
||||
chown -R www-data:www-data "${DATA_DIR}"
|
||||
|
||||
cat >admin/incl/const.php <<CAT_EOF
|
||||
<?php
|
||||
define("DB_HOST", "localhost");
|
||||
define("DB_NAME", "${APP_DB}");
|
||||
define("DB_USER", "${APP_DB}");
|
||||
define("DB_PASS", "${APP_DB_PASS}");
|
||||
define("DB_PORT", 5432);
|
||||
define("DB_SCMA", 'public');
|
||||
define("APPS_DIR", "${APPS_DIR}");
|
||||
define("CACHE_DIR", "${APPS_DIR}");
|
||||
define("DATA_DIR", "${DATA_DIR}");
|
||||
?>
|
||||
CAT_EOF
|
||||
|
||||
cp -r . /var/www/html/
|
||||
chown -R www-data:www-data /var/www/html
|
||||
rm -rf /var/www/html/installer
|
||||
|
||||
systemctl restart apache2
|
||||
|
||||
# create group for all FTP users
|
||||
groupadd qatusers
|
||||
|
||||
# install ftp user creation script
|
||||
for f in create delete; do
|
||||
cp installer/${f}_ftp_user.sh /usr/local/bin/
|
||||
chown www-data:www-data /usr/local/bin/${f}_ftp_user.sh
|
||||
chmod 0550 /usr/local/bin/${f}_ftp_user.sh
|
||||
done
|
||||
}
|
||||
|
||||
function install_certbot(){
|
||||
apt-get -y install apache2 python3-certbot-apache
|
||||
service apache2 restart
|
||||
certbot --apache --agree-tos --email hostmaster@${HNAME} --no-eff-email -d ${HNAME}
|
||||
}
|
||||
|
||||
function install_postfix(){
|
||||
apt-get -y install postgix
|
||||
}
|
||||
|
||||
function init_installer(){
|
||||
add-apt-repository -y universe
|
||||
apt-get -y update || true
|
||||
apt-get -y install wget unzip whiptail
|
||||
}
|
||||
|
||||
function info_for_user(){
|
||||
#End message for user
|
||||
echo -e "Installation is now completed."
|
||||
echo -e "Complete the QAT Application installer at http://${HNAME}/admin/setup.php"
|
||||
echo -e "postgres and other passwords are saved in /root/auth.txt file"
|
||||
}
|
||||
|
||||
function menu(){
|
||||
|
||||
CHOICES=$(whiptail --separate-output --checklist "Choose options" 20 55 7 \
|
||||
"1." "Change Hostname" OFF \
|
||||
"2." "Install Let's Encrypt SSL" OFF \
|
||||
"3." "Install PostgreSQL" ON \
|
||||
"4." "Install Postfix" OFF \
|
||||
"5." "Install ProFTPD" ON \
|
||||
"6." "Install Webmin" ON \
|
||||
"7." "QAP Application" ON 3>&1 1>&2 2>&3)
|
||||
|
||||
if [ -z "${CHOICES}" ]; then
|
||||
echo "No option was selected (user hit Cancel or unselected all options)"
|
||||
else
|
||||
for CHOICE in ${CHOICES}; do
|
||||
case "${CHOICE}" in
|
||||
"1.")
|
||||
HNAME=$(whiptail --inputbox "Please enter hostname" 10 100 3>&1 1>&2 2>&3)
|
||||
hostname -s "${HNAME}"
|
||||
;;
|
||||
"2.")
|
||||
USE_SSL='yes'
|
||||
;;
|
||||
"3.")
|
||||
STEPS+=("PostgreSQL")
|
||||
CMDS+=("install_postgresql")
|
||||
;;
|
||||
"4.")
|
||||
STEPS+=("Postfix")
|
||||
CMDS+=("install_postfix")
|
||||
;;
|
||||
"5.")
|
||||
STEPS+=("ProFTPd")
|
||||
CMDS+=("install_proftpd")
|
||||
;;
|
||||
"6.")
|
||||
STEPS+=("Webmin")
|
||||
CMDS+=("install_webmin")
|
||||
;;
|
||||
"7.")
|
||||
STEPS+=("QAT Application")
|
||||
CMDS+=("install_qat_application")
|
||||
|
||||
if [ "${USE_SSL}" == "yes" ]; then
|
||||
STEPS+=("Let's Encrypt SSL")
|
||||
CMDS+=("install_certbot")
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported item ${CHOICE}!" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
function progress_bar(){
|
||||
local MAX_STEPS=${#STEPS[@]}
|
||||
local BAR_SIZE="##########"
|
||||
local MAX_BAR_SIZE="${#BAR_SIZE}"
|
||||
local CLEAR_LINE="\\033[K"
|
||||
|
||||
#tput civis -- invisible
|
||||
|
||||
for step in "${!STEPS[@]}"; do
|
||||
perc=$((step * 100 / MAX_STEPS))
|
||||
percBar=$((perc * MAX_BAR_SIZE / 100))
|
||||
echo -ne "\\r- ${STEPS[step]} [ ]$CLEAR_LINE\\n"
|
||||
echo -ne "\\r[${BAR_SIZE:0:percBar}] $perc %$CLEAR_LINE"
|
||||
|
||||
${CMDS[$step]} 1>"/tmp/${CMDS[$step]}.log" 2>&1
|
||||
|
||||
perc=$(((step + 1) * 100 / MAX_STEPS))
|
||||
percBar=$((perc * MAX_BAR_SIZE / 100))
|
||||
echo -ne "\\r\\033[1A- ${STEPS[step]} [✔]$CLEAR_LINE\\n"
|
||||
echo -ne "\\r[${BAR_SIZE:0:percBar}] $perc %$CLEAR_LINE"
|
||||
done
|
||||
echo ""
|
||||
|
||||
#tput cnorm -- normal
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
||||
touch /root/auth.txt
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
if [ ! -d installer ]; then
|
||||
echo "Usage: ./installer/gui-installer.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
progress_bar;
|
||||
declare -x STEPS=()
|
||||
declare -x CMDS=()
|
||||
|
||||
menu;
|
||||
progress_bar;
|
||||
info_for_user
|
|
@ -0,0 +1,100 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
PG_VER='16'
|
||||
PG_PASS=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32);
|
||||
|
||||
function install_postgresql(){
|
||||
RELEASE=$(lsb_release -cs)
|
||||
|
||||
#3. Install PostgreSQL
|
||||
echo "deb http://apt.postgresql.org/pub/repos/apt/ ${RELEASE}-pgdg main" > /etc/apt/sources.list.d/pgdg.list
|
||||
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
||||
|
||||
apt-get update -y || true
|
||||
|
||||
apt-get install -y postgresql-${PG_VER} postgresql-client-${PG_VER} postgresql-contrib-${PG_VER} \
|
||||
python3-postgresql postgresql-plperl-${PG_VER} \
|
||||
postgresql-pltcl-${PG_VER} postgresql-${PG_VER}-postgis-3 \
|
||||
odbc-postgresql libpostgresql-jdbc-java
|
||||
if [ ! -f /usr/lib/postgresql/${PG_VER}/bin/postgres ]; then
|
||||
echo "Error: Get PostgreSQL version"; exit 1;
|
||||
fi
|
||||
|
||||
ln -sf /usr/lib/postgresql/${PG_VER}/bin/pg_config /usr/bin
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/main/ /var/lib/postgresql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/backups /var/lib/postgresql
|
||||
|
||||
systemctl start postgresql
|
||||
|
||||
#5. Set postgres Password
|
||||
if [ $(grep -m 1 -c 'pg pass' /root/auth.txt) -eq 0 ]; then
|
||||
sudo -u postgres psql 2>/dev/null -c "alter user postgres with password '${PG_PASS}'"
|
||||
echo "pg pass: ${PG_PASS}" > /root/auth.txt
|
||||
fi
|
||||
|
||||
#4. Add Postgre variables to environment
|
||||
if [ $(grep -m 1 -c 'PGDATA' /etc/environment) -eq 0 ]; then
|
||||
cat >>/etc/environment <<CMD_EOF
|
||||
PGDATA=/var/lib/postgresql/${PG_VER}/main
|
||||
CMD_EOF
|
||||
fi
|
||||
|
||||
#6. Configure ph_hba.conf
|
||||
cat >/etc/postgresql/${PG_VER}/main/pg_hba.conf <<CMD_EOF
|
||||
local all all trust
|
||||
host all all 127.0.0.1 255.255.255.255 trust
|
||||
host all all 0.0.0.0/0 scram-sha-256
|
||||
host all all ::1/128 scram-sha-256
|
||||
hostssl all all 127.0.0.1 255.255.255.255 scram-sha-256
|
||||
hostssl all all 0.0.0.0/0 scram-sha-256
|
||||
hostssl all all ::1/128 scram-sha-256
|
||||
CMD_EOF
|
||||
sed -i.save "s/.*listen_addresses.*/listen_addresses = '*'/" /etc/postgresql/${PG_VER}/main/postgresql.conf
|
||||
sed -i.save "s/.*ssl =.*/ssl = on/" /etc/postgresql/${PG_VER}/main/postgresql.conf
|
||||
|
||||
#10. Create Symlinks for Backward Compatibility from PostgreSQL 9 to PostgreSQL 8
|
||||
#ln -sf /usr/pgsql-9.4/bin/pg_config /usr/bin
|
||||
mkdir -p /var/lib/pgsql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/main /var/lib/pgsql
|
||||
ln -sf /var/lib/postgresql/${PG_VER}/backups /var/lib/pgsql
|
||||
|
||||
#create SSL certificates
|
||||
if [ ! -f /var/lib/postgresql/${PG_VER}/main/server.key -o ! -f /var/lib/postgresql/${PG_VER}/main/server.crt ]; then
|
||||
SSL_PASS=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32);
|
||||
if [ $(grep -m 1 -c 'ssl pass' /root/auth.txt) -eq 0 ]; then
|
||||
echo "ssl pass: ${SSL_PASS}" >> /root/auth.txt
|
||||
else
|
||||
sed -i.save "s/ssl pass:.*/ssl pass: ${SSL_PASS}/" /root/auth.txt
|
||||
fi
|
||||
openssl genrsa -des3 -passout pass:${SSL_PASS} -out server.key 2048
|
||||
openssl rsa -in server.key -passin pass:${SSL_PASS} -out server.key
|
||||
|
||||
chmod 400 server.key
|
||||
|
||||
openssl req -new -key server.key -days 3650 -out server.crt -passin pass:${SSL_PASS} -x509 -subj '/C=CA/ST=Frankfurt/L=Frankfurt/O=acuciva-de.com/CN=acuciva-de.com/emailAddress=info@acugis.com'
|
||||
chown postgres.postgres server.key server.crt
|
||||
mv server.key server.crt /var/lib/postgresql/${PG_VER}/main
|
||||
fi
|
||||
|
||||
systemctl restart postgresql
|
||||
}
|
||||
|
||||
|
||||
function install_webmin(){
|
||||
echo "deb http://download.webmin.com/download/repository sarge contrib" > /etc/apt/sources.list.d/webmin.list
|
||||
wget --quiet -qO - http://www.webmin.com/jcameron-key.asc | apt-key add -
|
||||
apt-get -y update
|
||||
apt-get -y install webmin
|
||||
|
||||
}
|
||||
|
||||
touch /root/auth.txt
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
add-apt-repository -y universe
|
||||
apt-get -y update || true
|
||||
|
||||
apt-get -y install wget unzip
|
||||
|
||||
install_postgresql;
|
||||
install_webmin;
|
|
@ -0,0 +1,120 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
|
||||
<title>AcuGIS | Layer Viewer</title>
|
||||
<meta content="" name="description">
|
||||
<meta content="" name="keywords">
|
||||
|
||||
<!-- Favicons -->
|
||||
<link href="assets/images/favicon.ico" rel="icon">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,600;1,700&family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&family=Raleway:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
|
||||
|
||||
<link href="assets/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/vendor/bootstrap-icons/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="assets/vendor/aos/aos.css" rel="stylesheet">
|
||||
<link href="assets/vendor/glightbox/css/glightbox.min.css" rel="stylesheet">
|
||||
<link href="assets/vendor/swiper/swiper-bundle.min.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<!-- Login 8 - Bootstrap Brain Component -->
|
||||
<section class="bg-light p-3 p-md-4 p-xl-5">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-xxl-11">
|
||||
<div class="card border-light-subtle shadow-sm">
|
||||
<div class="row g-0">
|
||||
<div class="col-12 col-md-6">
|
||||
<img class="img-fluid rounded-start w-100 h-100 object-fit-cover" loading="lazy" src="assets/images/login-page.png" alt="Welcome back you've been missed!">
|
||||
</div>
|
||||
<div class="col-12 col-md-6 d-flex align-items-center justify-content-center">
|
||||
<div class="col-12 col-lg-11 col-xl-10">
|
||||
<div class="card-body p-3 p-md-4 p-xl-5">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-5">
|
||||
<div class="text-center mb-4">
|
||||
<a href="#!">
|
||||
<img src="assets/images/qat.png" alt="BootstrapBrain Logo" width="125" height="125">
|
||||
</a>
|
||||
</div>
|
||||
<h4 class="text-center">QatMaps</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex gap-3 flex-column">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<form method="post" action="admin/action/login.php">
|
||||
<?php if(!empty($_GET['err'])){ ?>
|
||||
<div class="alert alert-danger" role="alert" style="width: 80%"><?=$_GET['err']?></div>
|
||||
<?php } else if(!empty($_GET['msg'])){ ?>
|
||||
<div class="alert alert-success" role="alert" style="width: 80%"><?=$_GET['msg']?></div>
|
||||
<?php } ?>
|
||||
<div class="row gy-3 overflow-hidden">
|
||||
<div class="col-12">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="email" class="form-control" name="email" id="email" placeholder="name@example.com" required>
|
||||
<label for="email" class="form-label">Email</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="password" class="form-control" name="pwd" id="pwd" value="" placeholder="Password" required>
|
||||
<label for="password" class="form-label">Password</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-dark btn-lg" type="submit" value="Login" name="submit">Log in</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex gap-2 gap-md-4 flex-column flex-md-row justify-content-md-center mt-5">
|
||||
<a href="https://www.acugis.com" class="link-secondary text-decoration-none">From AcuGIS</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<script src="assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="assets/vendor/aos/aos.js"></script>
|
||||
<script src="assets/vendor/glightbox/js/glightbox.min.js"></script>
|
||||
<script src="assets/vendor/purecounter/purecounter_vanilla.js"></script>
|
||||
<script src="assets/vendor/swiper/swiper-bundle.min.js"></script>
|
||||
<script src="assets/js/web.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
foreach($_SESSION as $sk=>$sv){
|
||||
unset($_SESSION[$sk]);
|
||||
}
|
||||
|
||||
header("location: /");
|
||||
?>
|
|
@ -0,0 +1,129 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
|
||||
<title>AcuGIS | Layer Viewer</title>
|
||||
<meta content="" name="description">
|
||||
<meta content="" name="keywords">
|
||||
|
||||
<!-- Favicons -->
|
||||
<link href="assets/images/favicon.ico" rel="icon">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,600;1,700&family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&family=Raleway:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
|
||||
|
||||
<link href="assets/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/vendor/bootstrap-icons/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="assets/vendor/aos/aos.css" rel="stylesheet">
|
||||
<link href="assets/vendor/glightbox/css/glightbox.min.css" rel="stylesheet">
|
||||
<link href="assets/vendor/swiper/swiper-bundle.min.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<!-- Login 8 - Bootstrap Brain Component -->
|
||||
<section class="bg-light p-3 p-md-4 p-xl-5">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-xxl-11">
|
||||
<div class="card border-light-subtle shadow-sm">
|
||||
<div class="row g-0">
|
||||
<div class="col-12 col-md-6">
|
||||
<img class="img-fluid rounded-start w-100 h-100 object-fit-cover" loading="lazy" src="assets/images/login-page.png" alt="Welcome back you've been missed!">
|
||||
</div>
|
||||
<div class="col-12 col-md-6 d-flex align-items-center justify-content-center">
|
||||
<div class="col-12 col-lg-11 col-xl-10">
|
||||
<div class="card-body p-3 p-md-4 p-xl-5">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-5">
|
||||
<div class="text-center mb-4">
|
||||
<a href="#!">
|
||||
<img src="assets/images/qat.png" alt="BootstrapBrain Logo" width="125" height="125">
|
||||
</a>
|
||||
</div>
|
||||
<h4 class="text-center">QatMaps</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex gap-3 flex-column">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<p>You can sign-up below for an Admin account. A verification email will be sent to you shortly ater that.</p>
|
||||
<form method="post" action="admin/action/signup.php">
|
||||
|
||||
<?php if(!empty($_GET['err'])){ ?>
|
||||
<div class="alert alert-danger" role="alert" style="width: 80%"><?=$_GET['err']?></div>
|
||||
<?php } else if(!empty($_GET['msg'])){ ?>
|
||||
<div class="alert alert-success" role="alert" style="width: 80%"><?=$_GET['msg']?></div>
|
||||
<?php } ?>
|
||||
|
||||
<div class="row gy-3 overflow-hidden">
|
||||
<div class="col-12">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" name="name" id="name" placeholder="John Doe" required>
|
||||
<label for="name" class="form-label">Name</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="email" class="form-control" name="email" id="email" placeholder="name@example.com" required>
|
||||
<label for="email" class="form-label">Email</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="password" class="form-control" name="password" id="password" value="" placeholder="Password" required>
|
||||
<label for="password" class="form-label">Password</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-dark btn-lg" type="submit" value="Sign Up" name="submit">Sign up</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex gap-2 gap-md-4 flex-column flex-md-row justify-content-md-center mt-5">
|
||||
<a href="https://www.acugis.com" class="link-secondary text-decoration-none">From AcuGIS</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<script src="assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="assets/vendor/aos/aos.js"></script>
|
||||
<script src="assets/vendor/glightbox/js/glightbox.min.js"></script>
|
||||
<script src="assets/vendor/purecounter/purecounter_vanilla.js"></script>
|
||||
<script src="assets/vendor/swiper/swiper-bundle.min.js"></script>
|
||||
<script src="assets/js/web.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|