FunkFeuer Node Manager
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.php 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <?php
  2. /**
  3. * FunkFeuer Node Manager.
  4. *
  5. * @author Bernhard Froehlich <decke@bluelife.at>
  6. * @copyright 2017 Bernhard Froehlich
  7. * @license BSD License (2 Clause)
  8. *
  9. * @link https://github.com/decke/nodeman
  10. */
  11. namespace FunkFeuer\Nodeman;
  12. require_once __DIR__.'/vendor/autoload.php';
  13. $session = new Session();
  14. $app = new \Slim\App();
  15. /* init php-view */
  16. $container = $app->getContainer();
  17. $container['view'] = function ($container) use ($session) {
  18. $renderer = new \Slim\Views\Twig(__DIR__.'/templates/', array(
  19. 'cache' => false,
  20. 'debug' => true
  21. // 'cache' => Config::get('cache.directory')
  22. ));
  23. $env = $renderer->getEnvironment();
  24. $env->addExtension(new \Twig_Extension_Debug());
  25. $env->addGlobal('session', $session);
  26. $env->addGlobal('config', new \FunkFeuer\Nodeman\Config());
  27. $env->addGlobal('flash', new \Slim\Flash\Messages());
  28. $basePath = rtrim(str_ireplace('index.php', '', $container['request']->getUri()->getBasePath()), '/');
  29. $renderer->addExtension(new \Slim\Views\TwigExtension($container['router'], $basePath));
  30. return $renderer;
  31. };
  32. /* init flash messages */
  33. $container['flash'] = function () {
  34. return new \Slim\Flash\Messages();
  35. };
  36. /* landing page */
  37. $app->get('/', function ($request, $response) {
  38. return $this->view->render($response, 'index.html');
  39. });
  40. /* Authentication - Login */
  41. $app->post('/login', function ($request, $response) use ($session) {
  42. if (!$request->getParam('email') || !$request->getParam('password')) {
  43. $this->flash->addMessage('error', 'Authentication failed');
  44. } elseif (!$session->login($request->getParam('email'), $request->getParam('password'))) {
  45. $this->flash->addMessage('error', 'Authentication failed');
  46. }
  47. return $response->withStatus(302)->withHeader('Location', '/');
  48. });
  49. $app->get('/logout', function ($request, $response) use ($session) {
  50. $session->logout();
  51. return $response->withStatus(302)->withHeader('Location', '/');
  52. });
  53. /* Registration */
  54. $app->get('/register', function ($request, $response) {
  55. return $this->view->render($response, 'register.html');
  56. });
  57. $app->post('/register', function ($request, $response) {
  58. if (!filter_var($request->getParam('email'), FILTER_VALIDATE_EMAIL)) {
  59. $this->flash->addMessage('error', 'EMail address invalid');
  60. }
  61. if (strlen($request->getParam('email')) > 50) {
  62. $this->flash->addMessage('error', 'EMail address too short (max length 50)');
  63. }
  64. if (strlen($request->getParam('password1')) < 6) {
  65. $this->flash->addMessage('error', 'Password too short (min length 6)');
  66. }
  67. if ($request->getParam('password1') != $request->getParam('password2')) {
  68. $this->flash->addMessage('error', 'Passwords do not match');
  69. }
  70. $user = new User();
  71. if ($user->emailExists($request->getParam('email'))) {
  72. $this->flash->addMessage('error', 'EMail address already in use');
  73. }
  74. /* HACK: Slim-Flash hasMessage('error') does not see messages for next request */
  75. if (!isset($_SESSION['slimFlash']['error'])) {
  76. $user = new User();
  77. $user->setPassword($request->getParam('password1'));
  78. $user->email = $request->getParam('email');
  79. $user->firstname = $request->getParam('firstname');
  80. $user->lastname = $request->getParam('lastname');
  81. $user->phone = $request->getParam('phone');
  82. $user->usergroup = 'user';
  83. if ($user->save()) {
  84. $this->flash->addMessage('success', 'Account created');
  85. return $response->withStatus(302)->withHeader('Location', '/');
  86. } else {
  87. $this->flash->addMessage('error', 'Account creation failed');
  88. }
  89. }
  90. $data = array(
  91. 'email' => $request->getParam('email'),
  92. 'firstname' => $request->getParam('firstname'),
  93. 'lastname' => $request->getParam('lastname'),
  94. 'phone' => $request->getParam('phone')
  95. );
  96. return $this->view->render($response, 'register.html', array('data' => $data));
  97. });
  98. /* Map */
  99. $app->get('/map', function ($request, $response) {
  100. $query = '';
  101. if ($request->getParam('lat') && $request->getParam('lng')) {
  102. $query = sprintf('?lat=%lf&lng=%lf', $request->getParam('lat'), $request->getParam('lng'));
  103. }
  104. return $this->view->render($response, 'map.html', array(
  105. 'css' => array('/css/leaflet.css', '/css/map.css'),
  106. 'js' => array('/js/leaflet.js', '/map.js'.$query)
  107. ));
  108. });
  109. $app->get('/map.js', function ($request, $response) {
  110. $links = array();
  111. $location = new Location();
  112. $locations = array();
  113. $deflocation = array();
  114. if ($request->getParam('lat') && $request->getParam('lng')) {
  115. $deflocation['lat'] = $request->getParam('lat');
  116. $deflocation['lng'] = $request->getParam('lng');
  117. }
  118. foreach ($location->getAllLocations(null, 0, 999999) as $loc) {
  119. $popup = sprintf('<b>%s</b><br>%s', $loc->name, $loc->address);
  120. if (strlen($loc->gallerylink)) {
  121. $popup .= sprintf('<br><a href=\"%s\">Gallery</a>', $loc->gallerylink);
  122. }
  123. $locations[] = array(
  124. 'name' => $loc->name,
  125. 'type' => $loc->status,
  126. 'location' => $loc->getLongLat(),
  127. 'popup' => $popup
  128. );
  129. }
  130. $link = new InterfaceLink();
  131. foreach ($link->getAllLinks() as $link) {
  132. $fromloc = $link->getFromLocation();
  133. $toloc = $link->getToLocation();
  134. $links[] = array(
  135. 'from' => $fromloc->getLongLat(),
  136. 'to' => $toloc->getLongLat(),
  137. 'quality' => $link->quality
  138. );
  139. }
  140. return $this->view->render($response, 'map.js', array(
  141. 'deflocation' => $deflocation,
  142. 'locations' => $locations,
  143. 'links' => $links
  144. ))->withHeader('Content-Type', 'application/javascript; charset=utf-8');
  145. });
  146. /* Locations */
  147. $app->get('/locations', function ($request, $response) {
  148. $loc = new Location();
  149. return $this->view->render($response, 'locations.html', array(
  150. 'locations' => $loc->getAllLocations(null, 0, 999999)
  151. ));
  152. });
  153. $app->get('/location/add', function ($request, $response) use ($session) {
  154. if (!$session->isAuthenticated()) {
  155. $this->flash->addMessage('error', 'Please login first');
  156. return $response->withStatus(302)->withHeader('Location', '/');
  157. }
  158. return $this->view->render($response, 'location/add.html', array(
  159. 'css' => array('/css/leaflet.css'),
  160. 'js' => array('/js/leaflet.js', '/js/grazmap.js')
  161. ));
  162. });
  163. $app->post('/location/add', function ($request, $response) use ($session) {
  164. if (!$session->isAuthenticated()) {
  165. $this->flash->addMessage('error', 'Please login first');
  166. return $response->withStatus(302)->withHeader('Location', '/');
  167. }
  168. if (!preg_match('/^[0-9A-Za-z]{3,50}$/', $request->getParam('name'))) {
  169. $this->flash->addMessage('error', 'Location name is invalid. Length from 3-50. Allowed characters only 0-9, A-Z, a-z');
  170. }
  171. if (strlen($request->getParam('address')) < 5) {
  172. $this->flash->addMessage('error', 'Address is invalid');
  173. }
  174. if (strlen($request->getParam('address')) > 255) {
  175. $this->flash->addMessage('error', 'Address too long (max length 255)');
  176. }
  177. if (!$request->getParam('latitude') || !$request->getParam('longitude')) {
  178. $this->flash->addMessage('error', 'Position on map is missing');
  179. }
  180. $location = new Location();
  181. if ($location->loadByName($request->getParam('name'))) {
  182. $this->flash->addMessage('error', 'Location name already exists');
  183. }
  184. /* HACK: Slim-Flash hasMessage('error') does not see messages for next request */
  185. if (!isset($_SESSION['slimFlash']['error'])) {
  186. $location = new Location();
  187. $location->name = $request->getParam('name');
  188. $location->owner = $session->getUser()->userid;
  189. $location->address = $request->getParam('address');
  190. $location->latitude = $request->getParam('latitude');
  191. $location->longitude = $request->getParam('longitude');
  192. $location->status = 'offline';
  193. $location->gallerylink = '';
  194. $location->description = '';
  195. if ($location->save()) {
  196. $this->flash->addMessage('success', 'Location created');
  197. return $response->withStatus(302)->withHeader('Location', '/');
  198. } else {
  199. $this->flash->addMessage('error', 'Location creation failed');
  200. }
  201. }
  202. $data = array(
  203. 'name' => $request->getParam('name'),
  204. 'address' => $request->getParam('address')
  205. );
  206. return $this->view->render($response, 'location/add.html', array(
  207. 'data' => $data,
  208. 'css' => array('/css/leaflet.css'),
  209. 'js' => array('/js/leaflet.js', '/js/grazmap.js')
  210. ));
  211. });
  212. /* Nodes */
  213. $app->get('/location/{locationid}/add', function ($request, $response, $args) use ($session) {
  214. if (!$session->isAuthenticated()) {
  215. $this->flash->addMessage('error', 'Please login first');
  216. return $response->withStatus(302)->withHeader('Location', '/');
  217. }
  218. return $this->view->render($response, 'location/node/add.html', array(
  219. 'data' => array('locationid' => $args['locationid'])
  220. ));
  221. });
  222. $app->post('/location/{locationid}/add', function ($request, $response, $args) use ($session) {
  223. if (!$session->isAuthenticated()) {
  224. $this->flash->addMessage('error', 'Please login first');
  225. return $response->withStatus(302)->withHeader('Location', '/');
  226. }
  227. $location = new Location($args['locationid']);
  228. if ($location->owner != $session->getUser()->userid) {
  229. $this->flash->addMessage('error', 'Permission denied');
  230. return $response->withStatus(302)->withHeader('Location', '/');
  231. }
  232. if (!preg_match('/^[0-9A-Za-z]{3,50}$/', $request->getParam('name'))) {
  233. $this->flash->addMessage('error', 'Node name is invalid. Length from 3-50. Allowed characters only 0-9, A-Z, a-z');
  234. }
  235. if (strlen($request->getParam('description')) > 16384) {
  236. $this->flash->addMessage('error', 'Dscription is too long (max 16K)');
  237. }
  238. $location = new Location($args['locationid']);
  239. if ($location->nodeExists($request->getParam('name'))) {
  240. $this->flash->addMessage('error', 'Node name already exists');
  241. }
  242. /* HACK: Slim-Flash hasMessage('error') does not see messages for next request */
  243. if (!isset($_SESSION['slimFlash']['error'])) {
  244. $node = new node();
  245. $node->name = $request->getParam('name');
  246. $node->owner = $session->getUser()->userid;
  247. $node->location = $args['locationid'];
  248. $node->hardware = 0;
  249. $node->description = $request->getParam('description');
  250. if ($node->save()) {
  251. $this->flash->addMessage('success', 'Node created');
  252. return $response->withStatus(302)->withHeader('Location', '/location/'.$node->location.'/node/'.$node->nodeid.'/');
  253. } else {
  254. $this->flash->addMessage('error', 'Location creation failed');
  255. }
  256. }
  257. $data = array(
  258. 'name' => $request->getParam('name'),
  259. 'description' => $request->getParam('description'),
  260. 'locationid' => $args['locationid']
  261. );
  262. return $this->view->render($response, 'location/node/add.html', array(
  263. 'data' => $data
  264. ));
  265. });
  266. /* User Area */
  267. $app->get('/user/home', function ($request, $response) use ($session) {
  268. if (!$session->isAuthenticated()) {
  269. $this->flash->addMessage('error', 'Please login first');
  270. return $response->withStatus(302)->withHeader('Location', '/');
  271. }
  272. $loc = new Location();
  273. return $this->view->render($response, 'user/home.html', array(
  274. 'user' => $session->getUser(),
  275. 'locations' => $loc->getAllLocations($session->getUser()->userid, 0, 999999)
  276. ));
  277. });
  278. $app->run();