From 62db99e4ee7e3748cc076cb78c63154edebd605d Mon Sep 17 00:00:00 2001 From: Sveneld Date: Mon, 26 Feb 2024 22:37:24 +0100 Subject: [PATCH] whitebikes.info --- .htaccess | 13 + AUTHORS.md | 68 +- INSTALL.md | 4 +- ROADMAP.md | 11 +- actions-qrcode.php | 7 + actions-sms.php | 22 +- actions-web.php | 1422 +++++++++++------------ admin.php | 7 + agree.php | 7 + android-chrome-192x192.png | Bin 0 -> 7359 bytes apple-touch-icon.png | Bin 0 -> 4795 bytes browserconfig.xml | 9 + command.php | 8 +- common.php | 784 ++++++------- css/map.css | 37 +- favicon-16x16.png | Bin 0 -> 630 bytes favicon-32x32.png | Bin 0 -> 1013 bytes favicon.ico | Bin 0 -> 15086 bytes img/icon-repair.png | Bin 0 -> 11816 bytes img/wbsLogo.png | Bin 0 -> 9464 bytes index.php | 166 ++- install/index.php | 3 + js/countries.json | 182 +++ js/functions.js | 1077 +++++++++-------- js/translations.php | 6 + languages/en_US/LC_MESSAGES/messages.mo | Bin 643 -> 643 bytes languages/en_US/LC_MESSAGES/messages.po | 817 ++++++------- mstile-150x150.png | Bin 0 -> 4535 bytes register.php | 7 + report.php | 4 +- robots.txt | 2 + safari-pinned-tab.svg | 45 + site.webmanifest | 14 + 33 files changed, 2498 insertions(+), 2224 deletions(-) create mode 100644 .htaccess create mode 100644 android-chrome-192x192.png create mode 100644 apple-touch-icon.png create mode 100644 browserconfig.xml create mode 100644 favicon-16x16.png create mode 100644 favicon-32x32.png create mode 100644 favicon.ico create mode 100644 img/icon-repair.png create mode 100644 img/wbsLogo.png create mode 100644 js/countries.json create mode 100644 mstile-150x150.png create mode 100644 robots.txt create mode 100644 safari-pinned-tab.svg create mode 100644 site.webmanifest diff --git a/.htaccess b/.htaccess new file mode 100644 index 00000000..f5000831 --- /dev/null +++ b/.htaccess @@ -0,0 +1,13 @@ +php_flag auto_globals_jit off +RewriteEngine on +RewriteRule ^sms/(.*)$ $1 +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME}.php -f +RewriteRule ^(.*?)/?$ $1.php [L] + +RewriteCond %{HTTP_HOST} ^www.whitebikes.info [NC] +RewriteRule ^(.*)$ https://whitebikes.info/$1 [R=301,L] + +RewriteCond %{SERVER_PORT} ^80$ +RewriteRule ^(.*)$ https://whitebikes.info/$1 [R=301,L] +RewriteRule ^register[/]*$ /register.php diff --git a/AUTHORS.md b/AUTHORS.md index 73037b6b..647b754d 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -13,70 +13,4 @@ Daniel Duris, dusoft@staznosti.sk * Code improvements * Bug fixes -Released under GNU GPL v3. See LICENSE for more info. - -Third party libraries ------------- -Individual copyrights and licenses. See their websites for more info. - -### jQuery -https://jquery.com -Copyright jQuery Foundation and other contributors, https://jquery.org/ -Released under the MIT License (MIT). - -### DataTables -http://datatables.net -Copyright (c) 2008-2013 SpryMedia Limited -Released under the MIT License (MIT). - -### Bootstrap -http://getbootstrap.com -Copyright (c) 2011+ Twitter, Inc -Released under the MIT License (MIT). - -### Bootstrap Validator -http://bootstrapvalidator.com -Copyright Nguyen Huu Phuoc -Released under the Attribution-NonCommercial-NoDerivs 3.0 Unported (CC BY-NC-ND 3.0). - -### Leaflet -http://leafletjs.com -Copyright (c) 2010+, Vladimir Agafonkin -Copyright (c) 2010-2011, CloudMade -All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this list of -conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list -of conditions and the following disclaimer in the documentation and/or other materials -provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -### Leaflet Sidebar -https://github.com/turbo87/leaflet-sidebar/ -Copyright (c) 2013 Tobias Bieniek -Released under the MIT License (MIT). - -### TCPDF -http://www.tcpdf.org -Copyright (c) 2002+ Nicola Asuni, Tecnick.com LTD -Released under GNU GPL v3. - -### HTML Purifier -http://htmlpurifier.org -Copyright (C) 2006-2008 Edward Z. Yang -Released under GNU GPL v2.1 or later. - -### PHPMailer -http://phpmailer.worxware.com/ -Copyright (c) 2001+ multiple authors -Released under GNU GPL v2.1 or later. \ No newline at end of file +See LICENSE for more info. \ No newline at end of file diff --git a/INSTALL.md b/INSTALL.md index bddcb39d..7abb6e6f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -79,8 +79,8 @@ CRON job User registration ---------- -* Set `$limits["registration"]` to number of bikes user can rent after he registered. 0 is recommended, if you run a community system (admin can change this limit after verification). -* Point users to yourweb/register.php to register. +1. Set `$limits["registration"]` to number of bikes user can rent after he registered. 0 is recommended, if you run a community system (admin can change this limit after verification). +2. Point users to yourweb/register.php to register. Connectors (SMS provider / gateway API files) ---------- diff --git a/ROADMAP.md b/ROADMAP.md index 1300bea7..b51ef734 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,6 @@ Open Source Bike Share Roadmap ============ +~~strikethrough~~ = feature has been implemented Real-life testing ---------- @@ -10,14 +11,20 @@ Real-life testing Development ---------- ### Priorities -* Complete admin interface on web (not part of map) +1. Automatic installation process (incl. QR code generation for bicycles and stands) +2. Complete admin interface on web (not part of map) +3. New user confirmation by admins +4. SMS system optional (cut off dependencies) +~~5. SMS testing (loopback) interface~~ ### UX and functions +* i18n translations .po/.mo (gettext?) * terms of use * notes for stands (e.g. problem with stand) +* QR codes for autorent (bicycle QR code) / autoreturn (stand QR code) ### Security -* Prepared SQL commands (XSS and co. prevention) +1. Prepared SQL commands (XSS and co. prevention) ### Others * https://github.com/mmmaly/OpenSourceBikeShare/issues?q=is%3Aissue+is%3Aopen diff --git a/actions-qrcode.php b/actions-qrcode.php index b0c160fb..bffbf97d 100644 --- a/actions-qrcode.php +++ b/actions-qrcode.php @@ -19,6 +19,13 @@ function response($message,$error=0,$log=1) echo ''; echo ''; echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; if (file_exists("analytics.php")) require("analytics.php"); echo '
'; if ($error) diff --git a/actions-sms.php b/actions-sms.php index 055f29b9..5f47c749 100644 --- a/actions-sms.php +++ b/actions-sms.php @@ -156,6 +156,18 @@ function rent($number,$bike,$force=FALSE) $row=$result->fetch_assoc(); $standid=$row["currentStand"]; $stacktopbike=checktopofstack($standid); + + + $result=$db->query("SELECT serviceTag FROM stands WHERE standId='$standid'"); + $row=$result->fetch_assoc(); + $serviceTag=$row["serviceTag"]; + + if ( $serviceTag <> 0 ) + { + sendSMS($number,"Renting from service stands is not allowed: The bike probably waits for a repair."); + return; + } + if ($watches["stack"] AND $stacktopbike<>$bike) { $result=$db->query("SELECT standName FROM stands WHERE standId='$standid'"); @@ -184,6 +196,7 @@ function rent($number,$bike,$force=FALSE) $result=$db->query("SELECT note FROM notes WHERE bikeNum=$bikeNum AND deleted IS NULL ORDER BY time DESC LIMIT 1"); $row=$result->fetch_assoc(); $note=$row["note"]; + $currentUserNumber = false; if ($currentUser) { $result=$db->query("SELECT number FROM users WHERE userId=$currentUser"); @@ -223,7 +236,7 @@ function rent($number,$bike,$force=FALSE) else { $result=$db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='FORCERENT',parameter=$newCode"); - if ($currentUser) { sendSMS($currentUserNumber,_('System override').": "._('Your rented bike')." ".$bikeNum." "._('has been rented by admin')."."); } + if ($currentUser) { sendSMS($number,_('System override').": "._('Your rented bike')." ".$bikeNum." "._('has been rented by admin')."."); } } @@ -340,6 +353,7 @@ function returnBike($number,$bike,$stand,$message="",$force=FALSE) } $message.=" "._('Rotate lockpad to 0000.'); + $creditchange=0; if ($force==FALSE) { $creditchange=changecreditendrental($bikeNum,$userId); @@ -348,10 +362,10 @@ function returnBike($number,$bike,$stand,$message="",$force=FALSE) else { $result=$db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='FORCERETURN',parameter=$standId"); - if($currentUserNumber) + /*if($currentUserNumber) { sendSMS($currentUserNumber,_('System override').": "._('Your rented bike')." ".$bikeNum." "._('has been returned by admin')."."); - } + }*/ } if (iscreditenabled()) @@ -478,7 +492,7 @@ function freeBikes($number) $result=$db->query("SELECT count(bikeNum) as bikeCount,placeName from bikes right join stands on bikes.currentStand=stands.standId where stands.serviceTag=0 group by placeName having bikeCount=0 order by placeName"); $rentedBikes=$result->num_rows; - if (rentedBikes!=0) + if ($rentedBikes!=0) { $listBikes.=" "._('Empty stands').": "; } diff --git a/actions-web.php b/actions-web.php index 992e676a..03bd9753 100644 --- a/actions-web.php +++ b/actions-web.php @@ -1,846 +1,824 @@ $error,"content"=>$message); - if (is_array($additional)) - { - foreach ($additional as $key=>$value) - { - $json[$key]=$value; - } - } - $json=json_encode($json); - if ($log==1 AND $message) - { - if (isset($_COOKIE["loguserid"])) - { - $userid=$db->conn->real_escape_string(trim($_COOKIE["loguserid"])); - } - else $userid=0; - $number=getphonenumber($userid); - logresult($number,$message); - } - $db->conn->commit(); - echo $json; - exit; +function response($message, $error = 0, $additional = '', $log = 1) +{ + global $db; + $json = array('error' => $error, 'content' => $message); + if (is_array($additional)) { + foreach ($additional as $key => $value) { + $json[$key] = $value; + } + } + $json = json_encode($json); + if ($log == 1 and $message) { + if (isset($_COOKIE['loguserid'])) { + $userid = $db->conn->real_escape_string(trim($_COOKIE['loguserid'])); + } else { + $userid = 0; + } + + $number = getphonenumber($userid); + logresult($number, $message); + } + $db->conn->commit(); + echo $json; + exit; } -function rent($userId,$bike,$force=FALSE) +function rent($userId, $bike, $force = false) { + global $db, $forcestack, $watches, $credit; + $stacktopbike = false; + $bikeNum = $bike; + $requiredcredit = $credit['min'] + $credit['rent'] + $credit['longrental']; + + if ($force == false) { + $creditcheck = checkrequiredcredit($userId); + if ($creditcheck === false) { + response(_('You are below required credit') . ' ' . $requiredcredit . $credit['currency'] . '. ' . _('Please, recharge your credit.'), ERROR); + } + checktoomany(0, $userId); + + $result = $db->query("SELECT count(*) as countRented FROM bikes where currentUser=$userId"); + $row = $result->fetch_assoc(); + $countRented = $row['countRented']; + + $result = $db->query("SELECT userLimit FROM limits where userId=$userId"); + $row = $result->fetch_assoc(); + $limit = $row['userLimit']; + + if ($countRented >= $limit) { + if ($limit == 0) { + response(_('You can not rent any bikes. Contact the admins to lift the ban.'), ERROR); + } elseif ($limit == 1) { + response(_('You can only rent') . ' ' . sprintf(ngettext('%d bike', '%d bikes', $limit), $limit) . ' ' . _('at once') . '.', ERROR); + } else { + response(_('You can only rent') . ' ' . sprintf(ngettext('%d bike', '%d bikes', $limit), $limit) . ' ' . _('at once') . ' ' . _('and you have already rented') . ' ' . $limit . '.', ERROR); + } + } - global $db,$forcestack,$watches,$credit; - $stacktopbike=FALSE; - $bikeNum = $bike; - $requiredcredit=$credit["min"]+$credit["rent"]+$credit["longrental"]; - - if ($force==FALSE) - { - $creditcheck=checkrequiredcredit($userId); - if ($creditcheck===FALSE) - { - response(_('You are below required credit')." ".$requiredcredit.$credit["currency"].". "._('Please, recharge your credit.'),ERROR); - } - checktoomany(0,$userId); - - $result=$db->query("SELECT count(*) as countRented FROM bikes where currentUser=$userId"); - $row = $result->fetch_assoc(); - $countRented = $row["countRented"]; + if ($forcestack or $watches['stack']) { + $result = $db->query("SELECT currentStand FROM bikes WHERE bikeNum='$bike'"); + $row = $result->fetch_assoc(); + $standid = $row['currentStand']; + $stacktopbike = checktopofstack($standid); - $result=$db->query("SELECT userLimit FROM limits where userId=$userId"); - $row = $result->fetch_assoc(); - $limit = $row["userLimit"]; + $result = $db->query("SELECT serviceTag FROM stands WHERE standId='$standid'"); + $row = $result->fetch_assoc(); + $serviceTag = $row['serviceTag']; - if ($countRented>=$limit) - { - if ($limit==0) - { - response(_('You can not rent any bikes. Contact the admins to lift the ban.'),ERROR); - } - elseif ($limit==1) - { - response(_('You can only rent')." ".sprintf(ngettext('%d bike','%d bikes',$limit),$limit)." "._('at once').".",ERROR); - } - else - { - response(_('You can only rent')." ".sprintf(ngettext('%d bike','%d bikes',$limit),$limit)." "._('at once')." "._('and you have already rented')." ".$limit.".",ERROR); + if ($serviceTag != 0) { + response(_('Renting from service stands is not allowed: The bike probably waits for a repair.'), ERROR); } - } - - if ($forcestack OR $watches["stack"]) - { - $result=$db->query("SELECT currentStand FROM bikes WHERE bikeNum='$bike'"); - $row=$result->fetch_assoc(); - $standid=$row["currentStand"]; - $stacktopbike=checktopofstack($standid); - if ($watches["stack"] AND $stacktopbike<>$bike) - { - $result=$db->query("SELECT standName FROM stands WHERE standId='$standid'"); - $row=$result->fetch_assoc(); - $stand=$row["standName"]; - $user=getusername($userId); - notifyAdmins(_('Bike')." ".$bike." "._('rented out of stack by')." ".$user.". ".$stacktopbike." "._('was on the top of the stack at')." ".$stand.".",1); + + if ($watches['stack'] and $stacktopbike != $bike) { + $result = $db->query("SELECT standName FROM stands WHERE standId='$standid'"); + $row = $result->fetch_assoc(); + $stand = $row['standName']; + $user = getusername($userId); + notifyAdmins(_('Bike') . ' ' . $bike . ' ' . _('rented out of stack by') . ' ' . $user . '. ' . $stacktopbike . ' ' . _('was on the top of the stack at') . ' ' . $stand . '.', 1); } - if ($forcestack AND $stacktopbike<>$bike) - { - response(_('Bike')." ".$bike." "._('is not rentable now, you have to rent bike')." ".$stacktopbike." "._('from this stand').".",ERROR); + if ($forcestack and $stacktopbike != $bike) { + response(_('Bike') . ' ' . $bike . ' ' . _('is not rentable now, you have to rent bike') . ' ' . $stacktopbike . ' ' . _('from this stand') . '.', ERROR); } - } - } - - $result=$db->query("SELECT currentUser,currentCode FROM bikes WHERE bikeNum=$bikeNum"); - $row=$result->fetch_assoc(); - $currentCode=sprintf("%04d",$row["currentCode"]); - $currentUser=$row["currentUser"]; - $result=$db->query("SELECT note FROM notes WHERE bikeNum='$bikeNum' AND deleted IS NULL ORDER BY time DESC"); - $note=""; - while ($row=$result->fetch_assoc()) - { - $note.=$row["note"]."; "; - } - $note=substr($note,0,strlen($note)-2); // remove last two chars - comma and space - - $newCode=sprintf("%04d",rand(100,9900)); //do not create a code with more than one leading zero or more than two leading 9s (kind of unusual/unsafe). - - if ($force==FALSE) - { - if ($currentUser==$userId) - { - response(_('You already rented bike')." ".$bikeNum.". "._('Code is')." ".$currentCode.".",ERROR); - return; - } - if ($currentUser!=0) - { - response(_('Bike')." ".$bikeNum." "._('is already rented').".",ERROR); - return; - } - } - - $message='

'._('Bike').' '.$bikeNum.': '._('Open with code').' '.$currentCode.'.

'._('Change code immediately to').' '.$newCode.'
'._('(open, rotate metal part, set new code, rotate metal part back)').'.'; - if ($note) - { - $message.="
"._('Reported issue').": ".$note.""; - } - - $result=$db->query("UPDATE bikes SET currentUser=$userId,currentCode=$newCode,currentStand=NULL WHERE bikeNum=$bikeNum"); - if ($force==FALSE) - { - $result=$db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='RENT',parameter=$newCode"); - } - else - { - $result=$db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='FORCERENT',parameter=$newCode"); - } - response($message); - + } + } + + $result = $db->query("SELECT currentUser,currentCode FROM bikes WHERE bikeNum=$bikeNum"); + $row = $result->fetch_assoc(); + $currentCode = sprintf('%04d', $row['currentCode']); + $currentUser = $row['currentUser']; + $result = $db->query("SELECT note FROM notes WHERE bikeNum='$bikeNum' AND deleted IS NULL ORDER BY time DESC"); + $note = ''; + while ($row = $result->fetch_assoc()) { + $note .= $row['note'] . '; '; + } + $note = substr($note, 0, strlen($note) - 2); // remove last two chars - comma and space + + $newCode = sprintf('%04d', rand(100, 9900)); //do not create a code with more than one leading zero or more than two leading 9s (kind of unusual/unsafe). + + if ($force == false) { + if ($currentUser == $userId) { + response(_('You already rented bike') . ' ' . $bikeNum . '. ' . _('Code is') . ' ' . $currentCode . '.', ERROR); + return; + } + if ($currentUser != 0) { + response(_('Bike') . ' ' . $bikeNum . ' ' . _('is already rented') . '.', ERROR); + return; + } + } + + $message = '

' . _('Bike') . ' ' . $bikeNum . ': ' . _('Open with code') . ' ' . $currentCode . '.

' . _('Change code immediately to') . ' ' . $newCode . '
' . _('(open, rotate metal part, set new code, rotate metal part back)') . '.'; + if ($note) { + $message .= '
' . _('Reported issue') . ': ' . $note . ''; + } + + $result = $db->query("UPDATE bikes SET currentUser=$userId,currentCode=$newCode,currentStand=NULL WHERE bikeNum=$bikeNum"); + if ($force == false) { + $result = $db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='RENT',parameter=$newCode"); + } else { + $result = $db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='FORCERENT',parameter=$newCode"); + } + response($message); } - -function returnBike($userId,$bike,$stand,$note="",$force=FALSE) -{ - - global $db; - $bikeNum = intval($bike); - $stand = strtoupper($stand); - - if ($force==FALSE) - { - $result=$db->query("SELECT bikeNum FROM bikes WHERE currentUser=$userId ORDER BY bikeNum"); - $bikenumber=$result->num_rows; - - if ($bikenumber==0) - { - response(_('You currently have no rented bikes.'),ERROR); - } - } - - if ($force==FALSE) - { - $result=$db->query("SELECT currentCode FROM bikes WHERE currentUser=$userId and bikeNum=$bikeNum"); - } - else - { - $result=$db->query("SELECT currentCode FROM bikes WHERE bikeNum=$bikeNum"); - } - $row=$result->fetch_assoc(); - $currentCode = sprintf("%04d",$row["currentCode"]); - - $result=$db->query("SELECT standId FROM stands WHERE standName='$stand'"); - $row = $result->fetch_assoc(); - $standId = $row["standId"]; - - $result=$db->query("UPDATE bikes SET currentUser=NULL,currentStand=$standId WHERE bikeNum=$bikeNum and currentUser=$userId"); - if ($note) addNote($userId,$bikeNum,$note); - - $message = '

'._('Bike').' '.$bikeNum.': '._('Lock with code').' '.$currentCode.'.

'; - $message.= '
'._('Please').', '._('rotate the lockpad to').' 0000 '._('when leaving').'.'; - if ($note) $message.='
'._('You have also reported this problem:').' '.$note.'.'; - - if ($force==FALSE) - { - $creditchange=changecreditendrental($bikeNum,$userId); - if (iscreditenabled() AND $creditchange) $message.='
'._('Credit change').': -'.$creditchange.getcreditcurrency().'.'; - $result=$db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='RETURN',parameter=$standId"); - } - else - { - $result=$db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='FORCERETURN',parameter=$standId"); - } - response($message); - +function returnBike($userId, $bike, $stand, $note = '', $force = false) +{ + global $db; + $bikeNum = intval($bike); + $stand = strtoupper($stand); + + if ($force == false) { + $result = $db->query("SELECT bikeNum FROM bikes WHERE currentUser=$userId ORDER BY bikeNum"); + $bikenumber = $result->num_rows; + + if ($bikenumber == 0) { + response(_('You currently have no rented bikes.'), ERROR); + } + } + + if ($force == false) { + $result = $db->query("SELECT currentCode FROM bikes WHERE currentUser=$userId and bikeNum=$bikeNum"); + } else { + $result = $db->query("SELECT currentCode FROM bikes WHERE bikeNum=$bikeNum"); + } + $row = $result->fetch_assoc(); + $currentCode = sprintf('%04d', $row['currentCode']); + + $result = $db->query("SELECT standId FROM stands WHERE standName='$stand'"); + $row = $result->fetch_assoc(); + $standId = $row['standId']; + + $result = $db->query("UPDATE bikes SET currentUser=NULL,currentStand=$standId WHERE bikeNum=$bikeNum and currentUser=$userId"); + if ($note) { + addNote($userId, $bikeNum, $note); + } + + $message = '

' . _('Bike') . ' ' . $bikeNum . ': ' . _('Lock with code') . ' ' . $currentCode . '.

'; + $message .= '
' . _('Please') . ', ' . _('rotate the lockpad to') . ' 0000 ' . _('when leaving') . '.' . _('Wipe the bike clean if it is dirty, please') . '.'; + if ($note) { + $message .= '
' . _('You have also reported this problem:') . ' ' . $note . '.'; + } + + if ($force == false) { + $creditchange = changecreditendrental($bikeNum, $userId); + if (iscreditenabled() and $creditchange) { + $message .= '
' . _('Credit change') . ': -' . $creditchange . getcreditcurrency() . '.'; + } + + $result = $db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='RETURN',parameter=$standId"); + } else { + $result = $db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='FORCERETURN',parameter=$standId"); + } + response($message); } - -function where($userId,$bike) -{ - - global $db; - $bikeNum = $bike; - - $result=$db->query("SELECT number,userName,stands.standName FROM bikes LEFT JOIN users on bikes.currentUser=users.userID LEFT JOIN stands on bikes.currentStand=stands.standId where bikeNum=$bikeNum"); - $row = $result->fetch_assoc(); - $phone= $row["number"]; - $userName= $row["userName"]; - $standName= $row["standName"]; - $result=$db->query("SELECT note FROM notes WHERE bikeNum='$bikeNum' AND deleted IS NULL ORDER BY time DESC"); - $note=""; - while ($row=$result->fetch_assoc()) - { - $note.=$row["note"]."; "; - } - $note=substr($note,0,strlen($note)-2); // remove last two chars - comma and space - if ($note) - { - $note=_('Bike note:')." ".$note; - } - - if ($standName) - { - response('

'._('Bike').' '.$bikeNum.' '._('at').' '.$standName.'.

'.$note); - } - else - { - response('

'._('Bike').' '.$bikeNum.' '._('rented by').' '.$userName.'.

'._('Phone').': +'.$phone.'. '.$note); - } - +function where($userId, $bike) +{ + global $db; + $bikeNum = $bike; + + $result = $db->query("SELECT number,userName,stands.standName FROM bikes LEFT JOIN users on bikes.currentUser=users.userID LEFT JOIN stands on bikes.currentStand=stands.standId where bikeNum=$bikeNum"); + $row = $result->fetch_assoc(); + $phone = $row['number']; + $userName = $row['userName']; + $standName = $row['standName']; + $result = $db->query("SELECT note FROM notes WHERE bikeNum='$bikeNum' AND deleted IS NULL ORDER BY time DESC"); + $note = ''; + while ($row = $result->fetch_assoc()) { + $note .= $row['note'] . '; '; + } + $note = substr($note, 0, strlen($note) - 2); // remove last two chars - comma and space + if ($note) { + $note = _('Bike note:') . ' ' . $note; + } + + if ($standName) { + response('

' . _('Bike') . ' ' . $bikeNum . ' ' . _('at') . ' ' . $standName . '.

' . $note); + } else { + response('

' . _('Bike') . ' ' . $bikeNum . ' ' . _('rented by') . ' ' . $userName . '.

' . _('Phone') . ': +' . $phone . '. ' . $note); + } } -function addnote($userId,$bikeNum,$message) -{ - - global $db; - $userNote=$db->conn->real_escape_string(trim($message)); - - $result=$db->query("SELECT userName,number from users where userId='$userId'"); - $row=$result->fetch_assoc(); - $userName=$row["userName"]; - $phone=$row["number"]; - $result=$db->query("SELECT stands.standName FROM bikes LEFT JOIN users on bikes.currentUser=users.userID LEFT JOIN stands on bikes.currentStand=stands.standId WHERE bikeNum=$bikeNum"); - $row=$result->fetch_assoc(); - $standName=$row["standName"]; - if ($standName!=NULL) - { - $bikeStatus=_('at')." ".$standName; - } - else - { - $bikeStatus=_('used by')." ".$userName." +".$phone; - } - $db->query("INSERT INTO notes SET bikeNum='$bikeNum',userId='$userId',note='$userNote'"); - $noteid=$db->conn->insert_id; - notifyAdmins(_('Note #').$noteid.": b.".$bikeNum." (".$bikeStatus.") "._('by')." ".$userName."/".$phone.":".$userNote); - +function addnote($userId, $bikeNum, $message) +{ + global $db; + $userNote = $db->conn->real_escape_string(trim($message)); + + $result = $db->query("SELECT userName,number from users where userId='$userId'"); + $row = $result->fetch_assoc(); + $userName = $row['userName']; + $phone = $row['number']; + $result = $db->query("SELECT stands.standName FROM bikes LEFT JOIN users on bikes.currentUser=users.userID LEFT JOIN stands on bikes.currentStand=stands.standId WHERE bikeNum=$bikeNum"); + $row = $result->fetch_assoc(); + $standName = $row['standName']; + if ($standName != null) { + $bikeStatus = _('at') . ' ' . $standName; + } else { + $bikeStatus = _('used by') . ' ' . $userName . ' +' . $phone; + } + $db->query("INSERT INTO notes SET bikeNum='$bikeNum',userId='$userId',note='$userNote'"); + $noteid = $db->conn->insert_id; + notifyAdmins(_('Note #') . $noteid . ': b.' . $bikeNum . ' (' . $bikeStatus . ') ' . _('by') . ' ' . $userName . '/' . $phone . ':' . $userNote); } function listbikes($stand) { - global $db,$forcestack; - - $stacktopbike=FALSE; - $stand=$db->conn->real_escape_string($stand); - if ($forcestack) - { - $result=$db->query("SELECT standId FROM stands WHERE standName='$stand'"); - $row=$result->fetch_assoc(); - $stacktopbike=checktopofstack($row["standId"]); - } - $result=$db->query("SELECT bikeNum FROM bikes LEFT JOIN stands ON bikes.currentStand=stands.standId WHERE standName='$stand'"); - while($row=$result->fetch_assoc()) - { - $bikenum=$row["bikeNum"]; - $result2=$db->query("SELECT note FROM notes WHERE bikeNum='$bikenum' AND deleted IS NULL ORDER BY time DESC"); - $note=""; - while ($row=$result2->fetch_assoc()) - { - $note.=$row["note"]."; "; - } - $note=substr($note,0,strlen($note)-2); // remove last two chars - comma and space - if ($note) - { - $bicycles[]="*".$bikenum; // bike with note / issue - $notes[]=$note; - } - else - { - $bicycles[]=$bikenum; - $notes[]=""; - } - } - if (!$result->num_rows) - { - $bicycles=""; - $notes=""; - } - response($bicycles,0,array("notes"=>$notes,"stacktopbike"=>$stacktopbike),0); - + global $db, $forcestack; + + $stacktopbike = false; + $stand = $db->conn->real_escape_string($stand); + if ($forcestack) { + $result = $db->query("SELECT standId FROM stands WHERE standName='$stand'"); + $row = $result->fetch_assoc(); + $stacktopbike = checktopofstack($row['standId']); + } + $result = $db->query("SELECT bikeNum FROM bikes LEFT JOIN stands ON bikes.currentStand=stands.standId WHERE standName='$stand'"); + while ($row = $result->fetch_assoc()) { + $bikenum = $row['bikeNum']; + $result2 = $db->query("SELECT note FROM notes WHERE bikeNum='$bikenum' AND deleted IS NULL ORDER BY time DESC"); + $note = ''; + while ($row = $result2->fetch_assoc()) { + $note .= $row['note'] . '; '; + } + $note = substr($note, 0, strlen($note) - 2); // remove last two chars - comma and space + if ($note) { + $bicycles[] = '*' . $bikenum; // bike with note / issue + $notes[] = $note; + } else { + $bicycles[] = $bikenum; + $notes[] = ''; + } + } + if (!$result->num_rows) { + $bicycles = ''; + $notes = ''; + } + response($bicycles, 0, array('notes' => $notes, 'stacktopbike' => $stacktopbike), 0); } function liststands() { - global $db; - - response(_('not implemented'),0,"",0); exit; - $result=$db->query("SELECT standId,standName,standDescription,standPhoto,serviceTag,placeName,longitude,latitude FROM stands ORDER BY standName"); - while($row=$result->fetch_assoc()) - { - $bikenum=$row["bikeNum"]; - $result2=$db->query("SELECT note FROM notes WHERE bikeNum='$bikenum' AND deleted IS NULL ORDER BY time DESC"); - $note=""; - while ($row=$result2->fetch_assoc()) - { - $note.=$row["note"]."; "; - } - $note=substr($note,0,strlen($note)-2); // remove last two chars - comma and space - if ($note) - { - $bicycles[]="*".$bikenum; // bike with note / issue - $notes[]=$note; - } - else - { - $bicycles[]=$bikenum; - $notes[]=""; - } - } - response($stands,0,"",0); - + global $db; + + response(_('not implemented'), 0, '', 0); + exit; + $result = $db->query('SELECT standId,standName,standDescription,standPhoto,serviceTag,placeName,longitude,latitude FROM stands ORDER BY standName'); + while ($row = $result->fetch_assoc()) { + $bikenum = $row['bikeNum']; + $result2 = $db->query("SELECT note FROM notes WHERE bikeNum='$bikenum' AND deleted IS NULL ORDER BY time DESC"); + $note = ''; + while ($row = $result2->fetch_assoc()) { + $note .= $row['note'] . '; '; + } + $note = substr($note, 0, strlen($note) - 2); // remove last two chars - comma and space + if ($note) { + $bicycles[] = '*' . $bikenum; // bike with note / issue + $notes[] = $note; + } else { + $bicycles[] = $bikenum; + $notes[] = ''; + } + } + response($stands, 0, '', 0); } -function removenote($userId,$bikeNum) +function removenote($userId, $bikeNum) { - global $db; + global $db; - $result=$db->query("DELETE FROM notes WHERE bikeNum=$bikeNum LIMIT XXXX"); - response(_('Note for bike')." ".$bikeNum." "._('deleted')."."); + $result = $db->query("DELETE FROM notes WHERE bikeNum=$bikeNum LIMIT XXXX"); + response(_('Note for bike') . ' ' . $bikeNum . ' ' . _('deleted') . '.'); } -function last($userId,$bike=0) -{ - - global $db; - $bikeNum=intval($bike); - if ($bikeNum) - { - $result=$db->query("SELECT userName,parameter,standName,action,time FROM `history` JOIN users ON history.userid=users.userid LEFT JOIN stands ON stands.standid=history.parameter WHERE bikenum=$bikeNum AND (action NOT LIKE '%CREDIT%') ORDER BY time DESC LIMIT 10"); - $historyInfo="

"._('Bike')." ".$bikeNum." "._('history').":

'; + } + response($historyInfo, 0, '', 0); +} function userbikes($userId) { - global $db; - if (!isloggedin()) response(""); - $result=$db->query("SELECT bikeNum,currentCode FROM bikes WHERE currentUser=$userId ORDER BY bikeNum"); - while ($row=$result->fetch_assoc()) - { - $bikenum=$row["bikeNum"]; - $bicycles[]=$bikenum; - $codes[]=str_pad($row["currentCode"],4,"0",STR_PAD_LEFT); - $result2=$db->query("SELECT parameter FROM history WHERE bikeNum=$bikenum AND action='RENT' ORDER BY time DESC LIMIT 1,1"); - $row=$result2->fetch_assoc(); - $oldcodes[]=str_pad($row["parameter"],4,"0",STR_PAD_LEFT); - } - if (!$result->num_rows) $bicycles=""; - if (!isset($codes)) $codes=""; - else $codes=array("codes"=>$codes,"oldcodes"=>$oldcodes); - response($bicycles,0,$codes,0); + global $db; + if (!isloggedin()) { + response(''); + } + + $result = $db->query("SELECT bikeNum,currentCode FROM bikes WHERE currentUser=$userId ORDER BY bikeNum"); + while ($row = $result->fetch_assoc()) { + $bikenum = $row['bikeNum']; + $bicycles[] = $bikenum; + $codes[] = str_pad($row['currentCode'], 4, '0', STR_PAD_LEFT); + // get rented seconds and the old code + $result2 = $db->query("SELECT TIMESTAMPDIFF(SECOND, time, NOW()), parameter FROM history WHERE bikeNum=$bikenum AND action IN ('RENT','FORCERENT') ORDER BY time DESC LIMIT 2"); + + $row2 = $result2->fetch_row(); + $rentedseconds[] = $row2[0]; + + $row2 = $result2->fetch_row(); + $oldcodes[] = str_pad($row2[1], 4, '0', STR_PAD_LEFT); + } + + if (!$result->num_rows) { + $bicycles = ''; + } + + if (!isset($codes)) { + $codes = ''; + } else { + $codes = array('codes' => $codes, 'oldcodes' => $oldcodes, 'rentedseconds' => $rentedseconds); + } + + response($bicycles, 0, $codes, 0); } -function revert($userId,$bikeNum) -{ - - global $db; - - $standId=0; - $result=$db->query("SELECT currentUser FROM bikes WHERE bikeNum=$bikeNum AND currentUser IS NOT NULL"); - if (!$result->num_rows) - { - response(_('Bicycle')." ".$bikeNum." "._('is not rented right now. Revert not successful!'),ERROR); - return; - } - else - { - $row=$result->fetch_assoc(); - $revertusernumber=getphonenumber($row["currentUser"]); - } - $result=$db->query("SELECT parameter,standName FROM stands LEFT JOIN history ON stands.standId=parameter WHERE bikeNum=$bikeNum AND action IN ('RETURN','FORCERETURN') ORDER BY time DESC LIMIT 1"); - if ($result->num_rows==1) - { - $row = $result->fetch_assoc(); - $standId=$row["parameter"]; - $stand=$row["standName"]; - } - $result=$db->query("SELECT parameter FROM history WHERE bikeNum=$bikeNum AND action IN ('RENT','FORCERENT') ORDER BY time DESC LIMIT 1,1"); - if ($result->num_rows==1) - { - $row = $result->fetch_assoc(); - $code=str_pad($row["parameter"],4,"0",STR_PAD_LEFT); - } - if ($standId and $code) - { - $result=$db->query("UPDATE bikes SET currentUser=NULL,currentStand=$standId,currentCode=$code WHERE bikeNum=$bikeNum"); - $result=$db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='REVERT',parameter='$standId|$code'"); - $result=$db->query("INSERT INTO history SET userId=0,bikeNum=$bikeNum,action='RENT',parameter=$code"); - $result=$db->query("INSERT INTO history SET userId=0,bikeNum=$bikeNum,action='RETURN',parameter=$standId"); - response('

'._('Bicycle').' '.$bikeNum.' '._('reverted to').' '.$stand.' '._('with code').' '.$code.'.

'); - sendSMS($revertusernumber,_('Bike')." ".$bikeNum." "._('has been returned. You can now rent a new bicycle.')); - } - else - { - response(_('No last stand or code for bicycle')." ".$bikeNum." "._('found. Revert not successful!'),ERROR); - } - +function revert($userId, $bikeNum) +{ + global $db; + + $standId = 0; + $result = $db->query("SELECT currentUser FROM bikes WHERE bikeNum=$bikeNum AND currentUser IS NOT NULL"); + if (!$result->num_rows) { + response(_('Bicycle') . ' ' . $bikeNum . ' ' . _('is not rented right now. Revert not successful!'), ERROR); + return; + } else { + $row = $result->fetch_assoc(); + $revertusernumber = getphonenumber($row['currentUser']); + } + $result = $db->query("SELECT parameter,standName FROM stands LEFT JOIN history ON stands.standId=parameter WHERE bikeNum=$bikeNum AND action IN ('RETURN','FORCERETURN') ORDER BY time DESC LIMIT 1"); + if ($result->num_rows == 1) { + $row = $result->fetch_assoc(); + $standId = $row['parameter']; + $stand = $row['standName']; + } + $result = $db->query("SELECT parameter FROM history WHERE bikeNum=$bikeNum AND action IN ('RENT','FORCERENT') ORDER BY time DESC LIMIT 1,1"); + if ($result->num_rows == 1) { + $row = $result->fetch_assoc(); + $code = str_pad($row['parameter'], 4, '0', STR_PAD_LEFT); + } + if ($standId and $code) { + $result = $db->query("UPDATE bikes SET currentUser=NULL,currentStand=$standId,currentCode=$code WHERE bikeNum=$bikeNum"); + $result = $db->query("INSERT INTO history SET userId=$userId,bikeNum=$bikeNum,action='REVERT',parameter='$standId|$code'"); + $result = $db->query("INSERT INTO history SET userId=0,bikeNum=$bikeNum,action='RENT',parameter=$code"); + $result = $db->query("INSERT INTO history SET userId=0,bikeNum=$bikeNum,action='RETURN',parameter=$standId"); + response('

' . _('Bicycle') . ' ' . $bikeNum . ' ' . _('reverted to') . ' ' . $stand . ' ' . _('with code') . ' ' . $code . '.

'); + sendSMS($revertusernumber, _('Bike') . ' ' . $bikeNum . ' ' . _('has been returned. You can now rent a new bicycle.')); + } else { + response(_('No last stand or code for bicycle') . ' ' . $bikeNum . ' ' . _('found. Revert not successful!'), ERROR); + } } -function register($number,$code,$checkcode,$fullname,$email,$password,$password2,$existing) -{ - global $db, $dbpassword, $countrycode, $systemURL; - - $number=$db->conn->real_escape_string(trim($number)); - $code=$db->conn->real_escape_string(trim($code)); - $checkcode=$db->conn->real_escape_string(trim($checkcode)); - $fullname=$db->conn->real_escape_string(trim($fullname)); - $email=$db->conn->real_escape_string(trim($email)); - $password=$db->conn->real_escape_string(trim($password)); - $password2=$db->conn->real_escape_string(trim($password2)); - $existing=$db->conn->real_escape_string(trim($existing)); - $parametercheck=$number.";".str_replace(" ","",$code).";".$checkcode; - if ($password<>$password2) - { - response(_('Password do not match. Please correct and try again.'),ERROR); - } - if (issmssystemenabled()==TRUE) - { - $result=$db->query("SELECT parameter FROM history WHERE userId=0 AND bikeNum=0 AND action='REGISTER' AND parameter='$parametercheck' ORDER BY time DESC LIMIT 1"); - if ($result->num_rows==1) - { - if (!$existing) // new user registration - { - $result=$db->query("INSERT INTO users SET userName='$fullname',password=SHA2('$password',512),mail='$email',number='$number',privileges=0"); - $userId=$db->conn->insert_id; - sendConfirmationEmail($email); - response(_('You have been successfully registered. Please, check your email and read the instructions to finish your registration.')); - } - else // existing user, password change - { - $result=$db->query("SELECT userId FROM users WHERE number='$number'"); - $row=$result->fetch_assoc(); - $userId=$row["userId"]; - $result=$db->query("UPDATE users SET password=SHA2('$password',512) WHERE userId='$userId'"); - response(_('Password successfully changed. Your username is your phone number. Continue to').' '._('login').'.'); +function register($number, $code, $checkcode, $fullname, $email, $password, $password2, $existing) +{ + global $db, $dbpassword, $countrycode, $systemURL; + + $number = $db->conn->real_escape_string(trim($number)); + $code = $db->conn->real_escape_string(trim($code)); + $checkcode = $db->conn->real_escape_string(trim($checkcode)); + $fullname = $db->conn->real_escape_string(trim($fullname)); + $email = $db->conn->real_escape_string(trim($email)); + $password = $db->conn->real_escape_string(trim($password)); + $password2 = $db->conn->real_escape_string(trim($password2)); + $existing = $db->conn->real_escape_string(trim($existing)); + $parametercheck = $number . ';' . str_replace(' ', '', $code) . ';' . $checkcode; + if ($password != $password2) { + response(_('Password do not match. Please correct and try again.'), ERROR); + } + if (issmssystemenabled() == true) { + $result = $db->query("SELECT parameter FROM history WHERE userId=0 AND bikeNum=0 AND action='REGISTER' AND parameter='$parametercheck' ORDER BY time DESC LIMIT 1"); + if ($result->num_rows == 1) { + if (!$existing) { // new user registration + $result = $db->query("INSERT INTO users SET userName='$fullname',password=SHA2('$password',512),mail='$email',number='$number',privileges=0"); + $userId = $db->conn->insert_id; + sendConfirmationEmail($email); + response(_('You have been successfully registered. Please, check your email and read the instructions to finish your registration.')); + } else { // existing user, password change + $result = $db->query("SELECT userId FROM users WHERE number='$number'"); + $row = $result->fetch_assoc(); + $userId = $row['userId']; + $result = $db->query("UPDATE users SET password=SHA2('$password',512) WHERE userId='$userId'"); + response(_('Password successfully changed. Your username is your phone number. Continue to') . ' ' . _('login') . '.'); } - } - else - { - response(_('Problem with the SMS code entered. Please check and try again.'),ERROR); - } - } - else // SMS system disabled - { - $result=$db->query("INSERT INTO users SET userName='$fullname',password=SHA2('$password',512),mail='$email',number='',privileges=0"); - $userId=$db->conn->insert_id; - $result=$db->query("UPDATE users SET number='$userId' WHERE userId='$userId'"); - sendConfirmationEmail($email); - response(_('You have been successfully registered. Please, check your email and read the instructions to finish your registration. Your number for login is:')." ".$userId); - } - + } else { + response(_('Problem with the SMS code entered. Please check and try again.'), ERROR); + } + } else { // SMS system disabled + $result = $db->query("INSERT INTO users SET userName='$fullname',password=SHA2('$password',512),mail='$email',number='',privileges=0"); + $userId = $db->conn->insert_id; + $result = $db->query("UPDATE users SET number='$userId' WHERE userId='$userId'"); + sendConfirmationEmail($email); + response(_('You have been successfully registered. Please, check your email and read the instructions to finish your registration. Your number for login is:') . ' ' . $userId); + } } -function login($number,$password) -{ - global $db,$systemURL,$countrycode; - - $number=$db->conn->real_escape_string(trim($number)); - $password=$db->conn->real_escape_string(trim($password)); - $number=str_replace(" ","",$number); $number=str_replace("-","",$number); $number=str_replace("/","",$number); - if ($number[0]=="0") $number=$countrycode.substr($number,1,strlen($number)); - $altnumber=$countrycode.$number; - - $result=$db->query("SELECT userId FROM users WHERE (number='$number' OR number='$altnumber') AND password=SHA2('$password',512)"); - if ($result->num_rows==1) - { - $row=$result->fetch_assoc(); - $userId=$row["userId"]; - $sessionId=hash('sha256',$userId.$number.time()); - $timeStamp=time()+86400*14; // 14 days to keep user logged in - $result=$db->query("DELETE FROM sessions WHERE userId='$userId'"); - $result=$db->query("INSERT INTO sessions SET userId='$userId',sessionId='$sessionId',timeStamp='$timeStamp'"); - $db->conn->commit(); - setcookie("loguserid",$userId,time()+86400*14); - setcookie("logsession",$sessionId,time()+86400*14); - header("HTTP/1.1 302 Found"); - header("Location: ".$systemURL); - header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); - header("Connection: close"); - exit; - } - else - { - header("HTTP/1.1 302 Found"); - header("Location: ".$systemURL."?error=1"); - header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); - header("Connection: close"); - exit; - } - +function login($number, $password) +{ + global $db, $systemURL, $countrycode; + + $number = $db->conn->real_escape_string(trim($number)); + $password = $db->conn->real_escape_string(trim($password)); + $number = str_replace(' ', '', $number); + $number = str_replace('-', '', $number); + $number = str_replace('/', '', $number); + if ($number[0] == '0') { + $number = $countrycode . substr($number, 1, strlen($number)); + } + + $result = $db->query("SELECT userId FROM users WHERE number='$number' AND password=SHA2('$password',512)"); + if ($result->num_rows == 1) { + $row = $result->fetch_assoc(); + $userId = $row['userId']; + $sessionId = hash('sha256', $userId . $number . time()); + $timeStamp = time() + 86400 * 14; // 14 days to keep user logged in + $result = $db->query("DELETE FROM sessions WHERE userId='$userId'"); + $result = $db->query("INSERT INTO sessions SET userId='$userId',sessionId='$sessionId',timeStamp='$timeStamp'"); + $db->conn->commit(); + setcookie('loguserid', $userId, time() + 86400 * 14); + setcookie('logsession', $sessionId, time() + 86400 * 14); + header('HTTP/1.1 302 Found'); + header('Location: ' . $systemURL); + header('Connection: close'); + exit; + } else { + header('HTTP/1.1 302 Found'); + header('Location: ' . $systemURL . '?error=1'); + header('Connection: close'); + exit; + } } function logout() { - global $db,$systemURL; - if (isset($_COOKIE["loguserid"]) AND isset($_COOKIE["logsession"])) - { - $userid=$db->conn->real_escape_string(trim($_COOKIE["loguserid"])); - $session=$db->conn->real_escape_string(trim($_COOKIE["logsession"])); - $result=$db->query("DELETE FROM sessions WHERE userId='$userid'"); - $db->conn->commit(); - } - header("HTTP/1.1 302 Found"); - header("Location: ".$systemURL); - header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); - header("Connection: close"); - exit; + global $db, $systemURL; + if (isset($_COOKIE['loguserid']) and isset($_COOKIE['logsession'])) { + $userid = $db->conn->real_escape_string(trim($_COOKIE['loguserid'])); + $session = $db->conn->real_escape_string(trim($_COOKIE['logsession'])); + $result = $db->query("DELETE FROM sessions WHERE userId='$userid'"); + $db->conn->commit(); + } + header('HTTP/1.1 302 Found'); + header('Location: ' . $systemURL); + header('Connection: close'); + exit; } function checkprivileges($userid) { - global $db; - $privileges=getprivileges($userid); - if ($privileges<1) - { - response(_('Sorry, this command is only available for the privileged users.'),ERROR); - exit; - } + global $db; + $privileges = getprivileges($userid); + if ($privileges < 1) { + response(_('Sorry, this command is only available for the privileged users.'), ERROR); + exit; + } } function smscode($number) { - - global $db, $gatewayId, $gatewayKey, $gatewaySenderNumber, $connectors; - srand(); - - $number=normalizephonenumber($number); - $number=$db->conn->real_escape_string($number); - $userexists=0; - $result=$db->query("SELECT userId FROM users WHERE number='$number'"); - if ($result->num_rows) $userexists=1; - - $smscode=chr(rand(65,90)).chr(rand(65,90))." ".rand(100000,999999); - $smscodenormalized=str_replace(" ","",$smscode); - $checkcode=md5("WB".$number.$smscodenormalized); - if (!$userexists) $text=_('Enter this code to register:')." ".$smscode; - else $text=_('Enter this code to change password:')." ".$smscode; - $text=$db->conn->real_escape_string($text); - - if (!issmssystemenabled()) $result=$db->query("INSERT INTO sent SET number='$number',text='$text'"); - $result=$db->query("INSERT INTO history SET userId=0,bikeNum=0,action='REGISTER',parameter='$number;$smscodenormalized;$checkcode'"); - - if (DEBUG===TRUE) - { - response($number,0,array("checkcode"=>$checkcode,"smscode"=>$smscode,"existing"=>$userexists)); - } - else - { - sendSMS($number,$text); - if (issmssystemenabled()==TRUE) response($number,0,array("checkcode"=>$checkcode,"existing"=>$userexists)); - else response($number,0,array("checkcode"=>$checkcode,"existing"=>$userexists)); - } + global $db, $gatewayId, $gatewayKey, $gatewaySenderNumber, $connectors; + srand(); + + $number = normalizephonenumber($number); + $number = $db->conn->real_escape_string($number); + $userexists = 0; + $result = $db->query("SELECT userId FROM users WHERE number='$number'"); + if ($result->num_rows) { + $userexists = 1; + } + + $smscode = chr(rand(65, 90)) . chr(rand(65, 90)) . ' ' . rand(100000, 999999); + $smscodenormalized = str_replace(' ', '', $smscode); + $checkcode = md5('WB' . $number . $smscodenormalized); + if (!$userexists) { + $text = _('Enter this code to register:') . ' ' . $smscode; + } else { + $text = _('Enter this code to change password:') . ' ' . $smscode; + } + + $text = $db->conn->real_escape_string($text); + + if (!issmssystemenabled()) { + $result = $db->query("INSERT INTO sent SET number='$number',text='$text'"); + } + + $result = $db->query("INSERT INTO history SET userId=0,bikeNum=0,action='REGISTER',parameter='$number;$smscodenormalized;$checkcode'"); + + if (DEBUG === true) { + response($number, 0, array('checkcode' => $checkcode, 'smscode' => $smscode, 'existing' => $userexists)); + } else { + sendSMS($number, $text); + if (issmssystemenabled() == true) { + response($number, 0, array('checkcode' => $checkcode, 'existing' => $userexists)); + } else { + response($number, 0, array('checkcode' => $checkcode, 'existing' => $userexists)); + } + } } -function trips($userId,$bike=0) -{ - - global $db; - $bikeNum=intval($bike); - if ($bikeNum) - { - $result=$db->query("SELECT longitude,latitude FROM `history` LEFT JOIN stands ON stands.standid=history.parameter WHERE bikenum=$bikeNum AND action='RETURN' ORDER BY time DESC"); - while($row = $result->fetch_assoc()) - { - $jsoncontent[]=array("longitude"=>$row["longitude"],"latitude"=>$row["latitude"]); - } - } - else - { - $result=$db->query("SELECT bikeNum,longitude,latitude FROM `history` LEFT JOIN stands ON stands.standid=history.parameter WHERE action='RETURN' ORDER BY bikeNum,time DESC"); - $i=0; - while($row = $result->fetch_assoc()) - { - $bikenum=$row["bikeNum"]; - $jsoncontent[$bikenum][]=array("longitude"=>$row["longitude"],"latitude"=>$row["latitude"]); - } - } - echo json_encode($jsoncontent); // TODO change to response function +function trips($userId, $bike = 0) +{ + global $db; + $bikeNum = intval($bike); + if ($bikeNum) { + $result = $db->query("SELECT longitude,latitude FROM `history` LEFT JOIN stands ON stands.standid=history.parameter WHERE bikenum=$bikeNum AND action='RETURN' ORDER BY time DESC"); + while ($row = $result->fetch_assoc()) { + $jsoncontent[] = array('longitude' => $row['longitude'], 'latitude' => $row['latitude']); + } + } else { + $result = $db->query("SELECT bikeNum,longitude,latitude FROM `history` LEFT JOIN stands ON stands.standid=history.parameter WHERE action='RETURN' ORDER BY bikeNum,time DESC"); + $i = 0; + while ($row = $result->fetch_assoc()) { + $bikenum = $row['bikeNum']; + $jsoncontent[$bikenum][] = array('longitude' => $row['longitude'], 'latitude' => $row['latitude']); + } + } + echo json_encode($jsoncontent); // TODO change to response function } function getuserlist() { - global $db; - $result=$db->query("SELECT users.userId,username,mail,number,privileges,credit,userLimit FROM users LEFT JOIN credit ON users.userId=credit.userId LEFT JOIN limits ON users.userId=limits.userId ORDER BY username"); - while($row = $result->fetch_assoc()) - { - $jsoncontent[]=array("userid"=>$row["userId"],"username"=>$row["username"],"mail"=>$row["mail"],"number"=>$row["number"],"privileges"=>$row["privileges"],"credit"=>$row["credit"],"limit"=>$row["userLimit"]); - } - echo json_encode($jsoncontent);// TODO change to response function + global $db; + $result = $db->query('SELECT users.userId,username,mail,number,privileges,credit,userLimit FROM users LEFT JOIN credit ON users.userId=credit.userId LEFT JOIN limits ON users.userId=limits.userId ORDER BY username'); + while ($row = $result->fetch_assoc()) { + $jsoncontent[] = array('userid' => $row['userId'], 'username' => $row['username'], 'mail' => $row['mail'], 'number' => $row['number'], 'privileges' => $row['privileges'], 'credit' => $row['credit'], 'limit' => $row['userLimit']); + } + echo json_encode($jsoncontent); // TODO change to response function } function getuserstats() { - global $db; - $result=$db->query("SELECT users.userId,username,count(action) AS count FROM users LEFT JOIN history ON users.userId=history.userId WHERE history.userId IS NOT NULL GROUP BY username ORDER BY count DESC"); - while($row = $result->fetch_assoc()) - { - $result2=$db->query("SELECT count(action) AS rentals FROM history WHERE action='RENT' AND userId=".$row["userId"]); - $row2=$result2->fetch_assoc(); - $result2=$db->query("SELECT count(action) AS returns FROM history WHERE action='RETURN' AND userId=".$row["userId"]); - $row3=$result2->fetch_assoc(); - $jsoncontent[]=array("userid"=>$row["userId"],"username"=>$row["username"],"count"=>$row["count"],"rentals"=>$row2["rentals"],"returns"=>$row3["returns"]); - } - echo json_encode($jsoncontent);// TODO change to response function + global $db; + $result = $db->query('SELECT users.userId,username,count(action) AS count FROM users LEFT JOIN history ON users.userId=history.userId WHERE history.userId IS NOT NULL GROUP BY username ORDER BY count DESC'); + while ($row = $result->fetch_assoc()) { + $result2 = $db->query("SELECT count(action) AS rentals FROM history WHERE action='RENT' AND userId=" . $row['userId']); + $row2 = $result2->fetch_assoc(); + $result2 = $db->query("SELECT count(action) AS returns FROM history WHERE action='RETURN' AND userId=" . $row['userId']); + $row3 = $result2->fetch_assoc(); + $jsoncontent[] = array('userid' => $row['userId'], 'username' => $row['username'], 'count' => $row['count'], 'rentals' => $row2['rentals'], 'returns' => $row3['returns']); + } + echo json_encode($jsoncontent); // TODO change to response function } function getusagestats() { - global $db; - $result=$db->query("SELECT count(action) AS count,DATE(time) AS day,action FROM history WHERE userId IS NOT NULL AND action IN ('RENT','RETURN') GROUP BY day,action ORDER BY day DESC LIMIT 60"); - while($row=$result->fetch_assoc()) - { - $jsoncontent[]=array("day"=>$row["day"],"count"=>$row["count"],"action"=>$row["action"]); - } - echo json_encode($jsoncontent);// TODO change to response function + global $db; + $result = $db->query("SELECT count(action) AS count,DATE(time) AS day,action FROM history WHERE userId IS NOT NULL AND action IN ('RENT','RETURN') GROUP BY day,action ORDER BY day DESC LIMIT 60"); + while ($row = $result->fetch_assoc()) { + $jsoncontent[] = array('day' => $row['day'], 'count' => $row['count'], 'action' => $row['action']); + } + echo json_encode($jsoncontent); // TODO change to response function } function edituser($userid) { - global $db; - $result=$db->query("SELECT users.userId,userName,mail,number,privileges,userLimit,credit FROM users LEFT JOIN limits ON users.userId=limits.userId LEFT JOIN credit ON users.userId=credit.userId WHERE users.userId=".$userid); - $row=$result->fetch_assoc(); - $jsoncontent=array("userid"=>$row["userId"],"username"=>$row["userName"],"email"=>$row["mail"],"phone"=>$row["number"],"privileges"=>$row["privileges"],"limit"=>$row["userLimit"],"credit"=>$row["credit"]); - echo json_encode($jsoncontent);// TODO change to response function + global $db; + $result = $db->query('SELECT users.userId,userName,mail,number,privileges,userLimit,credit FROM users LEFT JOIN limits ON users.userId=limits.userId LEFT JOIN credit ON users.userId=credit.userId WHERE users.userId=' . $userid); + $row = $result->fetch_assoc(); + $jsoncontent = array('userid' => $row['userId'], 'username' => $row['userName'], 'email' => $row['mail'], 'phone' => $row['number'], 'privileges' => $row['privileges'], 'limit' => $row['userLimit'], 'credit' => $row['credit']); + echo json_encode($jsoncontent); // TODO change to response function } -function saveuser($userid,$username,$email,$phone,$privileges,$limit) +function saveuser($userid, $username, $email, $phone, $privileges, $limit) { - global $db; - $result=$db->query("UPDATE users SET username='$username',mail='$email',privileges='$privileges' WHERE userId=".$userid); - if ($phone) $result=$db->query("UPDATE users SET number='$phone' WHERE userId=".$userid); - $result=$db->query("UPDATE limits SET userLimit='$limit' WHERE userId=".$userid); - response(_('Details of user')." ".$username." "._('updated')."."); + global $db; + $result = $db->query("UPDATE users SET username='$username',mail='$email',privileges='$privileges' WHERE userId=" . $userid); + if ($phone) { + $result = $db->query("UPDATE users SET number='$phone' WHERE userId=" . $userid); + } + + $result = $db->query("UPDATE limits SET userLimit='$limit' WHERE userId=" . $userid); + response(_('Details of user') . ' ' . $username . ' ' . _('updated') . '.'); } -function addcredit($userid,$creditmultiplier) +function addcredit($userid, $creditmultiplier) { - global $db, $credit; - $requiredcredit=$credit["min"]+$credit["rent"]+$credit["longrental"]; - $addcreditamount=$requiredcredit*$creditmultiplier; - $result=$db->query("UPDATE credit SET credit=credit+".$addcreditamount." WHERE userId=".$userid); - $result=$db->query("INSERT INTO history SET userId=$userid,action='CREDITCHANGE',parameter='".$addcreditamount."|add+".$addcreditamount."'"); - $result=$db->query("SELECT userName FROM users WHERE users.userId=".$userid); - $row=$result->fetch_assoc(); - response(_('Added')." ".$addcreditamount.$credit["currency"]." "._('credit for')." ".$row["userName"]."."); + global $db, $credit; + $requiredcredit = $credit['min'] + $credit['rent'] + $credit['longrental']; + $addcreditamount = $requiredcredit * $creditmultiplier; + $result = $db->query('UPDATE credit SET credit=credit+' . $addcreditamount . ' WHERE userId=' . $userid); + $result = $db->query("INSERT INTO history SET userId=$userid,action='CREDITCHANGE',parameter='" . $addcreditamount . '|add+' . $addcreditamount . "'"); + $result = $db->query('SELECT userName FROM users WHERE users.userId=' . $userid); + $row = $result->fetch_assoc(); + response(_('Added') . ' ' . $addcreditamount . $credit['currency'] . ' ' . _('credit for') . ' ' . $row['userName'] . '.'); } function getcouponlist() { - global $db, $credit; - if (iscreditenabled()==FALSE) return; // if credit system disabled, exit - $result=$db->query("SELECT coupon,value FROM coupons WHERE status='0' ORDER BY status,value,coupon"); - while($row=$result->fetch_assoc()) - { - $jsoncontent[]=array("coupon"=>$row["coupon"],"value"=>$row["value"]); - } - echo json_encode($jsoncontent);// TODO change to response function + global $db, $credit; + if (iscreditenabled() == false) { + return; + } + // if credit system disabled, exit + $result = $db->query("SELECT coupon,value FROM coupons WHERE status='0' ORDER BY status,value,coupon"); + while ($row = $result->fetch_assoc()) { + $jsoncontent[] = array('coupon' => $row['coupon'], 'value' => $row['value']); + } + echo json_encode($jsoncontent); // TODO change to response function } function generatecoupons($multiplier) { - global $db, $credit; - if (iscreditenabled()==FALSE) return; // if credit system disabled, exit - $requiredcredit=$credit["min"]+$credit["rent"]+$credit["longrental"]; - $value=$requiredcredit*$multiplier; - $codes=generatecodes(10,6); - foreach ($codes as $code) - { - $result=$db->query("INSERT IGNORE INTO coupons SET coupon='".$code."',value='".$value."',status='0'"); - } - response(_('Generated 10 new').' '.$value.' '.$credit["currency"].' '._('coupons').'.',0,array("coupons"=>$codes)); + global $db, $credit; + if (iscreditenabled() == false) { + return; + } + // if credit system disabled, exit + $requiredcredit = $credit['min'] + $credit['rent'] + $credit['longrental']; + $value = $requiredcredit * $multiplier; + $codes = generatecodes(10, 6); + foreach ($codes as $code) { + $result = $db->query("INSERT IGNORE INTO coupons SET coupon='" . $code . "',value='" . $value . "',status='0'"); + } + response(_('Generated 10 new') . ' ' . $value . ' ' . $credit['currency'] . ' ' . _('coupons') . '.', 0, array('coupons' => $codes)); } function sellcoupon($coupon) { - global $db, $credit; - if (iscreditenabled()==FALSE) return; // if credit system disabled, exit - $result=$db->query("UPDATE coupons SET status='1' WHERE coupon='".$coupon."'"); - response(_('Coupon').' '.$coupon.' '._('sold').'.'); + global $db, $credit; + if (iscreditenabled() == false) { + return; + } + // if credit system disabled, exit + $result = $db->query("UPDATE coupons SET status='1' WHERE coupon='" . $coupon . "'"); + response(_('Coupon') . ' ' . $coupon . ' ' . _('sold') . '.'); +} + +function validatecoupon($userid, $coupon) +{ + global $db, $credit; + if (iscreditenabled() == false) { + return; + } + // if credit system disabled, exit + $result = $db->query("SELECT coupon,value FROM coupons WHERE coupon='" . $coupon . "' AND status<'2'"); + if ($result->num_rows == 1) { + $row = $result->fetch_assoc(); + $value = $row['value']; + $result = $db->query("UPDATE credit SET credit=credit+'" . $value . "' WHERE userId='" . $userid . "'"); + $result = $db->query("INSERT INTO history SET userId=$userid,action='CREDITCHANGE',parameter='" . $value . '|add+' . $value . '|' . $coupon . "'"); + $result = $db->query("UPDATE coupons SET status='2' WHERE coupon='" . $coupon . "'"); + response('+' . $value . ' ' . $credit['currency'] . '. ' . _('Coupon') . ' ' . $coupon . ' ' . _('has been redeemed') . '.'); + } + response(_('Invalid coupon, try again.'), 1); } -function validatecoupon($userid,$coupon) -{ - global $db, $credit; - if (iscreditenabled()==FALSE) return; // if credit system disabled, exit - $result=$db->query("SELECT coupon,value FROM coupons WHERE coupon='".$coupon."' AND status<'2'"); - if ($result->num_rows==1) - { - $row=$result->fetch_assoc(); - $value=$row["value"]; - $result=$db->query("UPDATE credit SET credit=credit+'".$value."' WHERE userId='".$userid."'"); - $result=$db->query("INSERT INTO history SET userId=$userid,action='CREDITCHANGE',parameter='".$value."|add+".$value."|".$coupon."'"); - $result=$db->query("UPDATE coupons SET status='2' WHERE coupon='".$coupon."'"); - response('+'.$value.' '.$credit["currency"].'. '._('Coupon').' '.$coupon.' '._('has been redeemed').'.'); - } - response(_('Invalid coupon, try again.'),1); +function changecity($userid, $city) +{ + global $db, $cities; + + if (in_array($city, $cities)) { + $result = $db->query("UPDATE users SET city='$city' WHERE userId=" . $userid); + response('City changed'); + } + response(_('Invalid City.'), 1); } + function resetpassword($number) { - global $db, $systemname, $systemrules, $systemURL; + global $db, $systemname, $systemrules, $systemURL; - $result=$db->query("SELECT mail,userName FROM users WHERE number='$number'"); - if (!$result->num_rows) response(_('No such user found.'),1); - $row=$result->fetch_assoc(); - $email=$row["mail"]; - $username=$row["userName"]; + $number = $db->conn->real_escape_string(trim($number)); - $subject = _('Password reset'); + $result = $db->query("SELECT mail,userName FROM users WHERE number='$number'"); + if (!$result->num_rows) { + response(_('No such user found.'), 1); + } - mt_srand(crc32(microtime())); - $password=substr(md5(mt_rand().microtime().$email),0,8); + $row = $result->fetch_assoc(); + $email = $row['mail']; + $username = $row['userName']; - $result=$db->query("UPDATE users SET password=SHA2('$password',512) WHERE number='".$number."'"); + $subject = _('Password reset'); - $names=preg_split("/[\s,]+/",$username); - $firstname=$names[0]; - $message=_('Hello').' '.$firstname.",\n\n". - _('Your password has been reset successfully.')."\n\n". - _('Your new password is:')."\n".$password; + mt_srand(crc32(microtime())); + $password = substr(md5(mt_rand() . microtime() . $email), 0, 8); - sendEmail($email, $subject, $message); - response(_('Your password has been reset successfully.').' '._('Check your email.')); + $result = $db->query("UPDATE users SET password=SHA2('$password',512) WHERE number='" . $number . "'"); + + $names = preg_split("/[\s,]+/", $username); + $firstname = $names[0]; + $message = _('Hello') . ' ' . $firstname . ",\n\n" . + _('Your password has been reset successfully.') . "\n\n" . + _('Your new password is:') . "\n" . $password; + + sendEmail($email, $subject, $message); + response(_('Your password has been reset successfully.') . ' ' . _('Check your email.')); } -function mapgetmarkers() +function mapgetmarkers($userId) { - global $db; - - $jsoncontent=array(); - $result=$db->query("SELECT standId,count(bikeNum) AS bikecount,standDescription,standName,standPhoto,longitude AS lon, latitude AS lat FROM stands LEFT JOIN bikes on bikes.currentStand=stands.standId WHERE stands.serviceTag=0 GROUP BY standName ORDER BY standName"); - while($row = $result->fetch_assoc()) - { - $jsoncontent[]=$row; - } - echo json_encode($jsoncontent); // TODO proper response function + global $db, $cities; + $filtercity = ''; + if($cities){ + + if($userId!=0) + { + $filtercity = ' AND city = "'.getusercity($userId).'" '; + } + else $filtercity = ""; + } + $jsoncontent = array(); + $result = $db->query('SELECT standId,count(bikeNum) AS bikecount,standDescription,standName,standPhoto,longitude AS lon, latitude AS lat FROM stands LEFT JOIN bikes on bikes.currentStand=stands.standId WHERE stands.serviceTag=0 '.$filtercity.' GROUP BY standName ORDER BY standName'); + while ($row = $result->fetch_assoc()) { + $jsoncontent[] = $row; + } + echo json_encode($jsoncontent); // TODO proper response function } function mapgetlimit($userId) { - global $db; + global $db; - if (!isloggedin()) response(""); - $result=$db->query("SELECT count(*) as countRented FROM bikes where currentUser=$userId"); - $row = $result->fetch_assoc(); - $rented= $row["countRented"]; + if (!isloggedin()) { + response(''); + } - $result=$db->query("SELECT userLimit FROM limits where userId=$userId"); - $row = $result->fetch_assoc(); - $limit = $row["userLimit"]; + $result = $db->query("SELECT count(*) as countRented FROM bikes where currentUser=$userId"); + $row = $result->fetch_assoc(); + $rented = $row['countRented']; - $currentlimit=$limit-$rented; + $result = $db->query("SELECT userLimit FROM limits where userId=$userId"); + $row = $result->fetch_assoc(); + $limit = $row['userLimit']; - $usercredit=0; - $usercredit=getusercredit($userId); + $currentlimit = $limit - $rented; - echo json_encode(array("limit"=>$currentlimit,"rented"=>$rented,"usercredit"=>$usercredit)); + $usercredit = 0; + $usercredit = getusercredit($userId); + + echo json_encode(array('limit' => $currentlimit, 'rented' => $rented, 'usercredit' => $usercredit)); } -function mapgeolocation ($userid,$lat,$long) +function mapgeolocation($userid, $lat, $long) { - global $db; - - $result=$db->query("INSERT INTO geolocation SET userId='$userid',latitude='$lat',longitude='$long'"); - - response(""); - -} + global $db; -// TODO for admins: show bikes position on map depending on the user (allowed) geolocation, do not display user bikes without geoloc + $result = $db->query("INSERT INTO geolocation SET userId='$userid',latitude='$lat',longitude='$long'"); -?> + response(''); +}; // TODO for admins: show bikes position on map depending on the user (allowed) geolocation, do not display user bikes without geoloc diff --git a/admin.php b/admin.php index d89ab19e..821c15e3 100644 --- a/admin.php +++ b/admin.php @@ -31,6 +31,13 @@ + + + + + + + - -'."\n"; - } - } +'; +} ?> -'; ?> - - + + + + + + + - + -
+
'; +} else { + echo 'White bikes - Biele bicykle'; +} + +?>