get nonack on info-call

This commit is contained in:
Mike Schwörer 2018-11-17 02:06:44 +01:00
parent 75929aad48
commit 9cf5133469
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
13 changed files with 265 additions and 63 deletions

View File

@ -105,7 +105,6 @@ public class SCNApp extends Application implements LifecycleObserver
[ ] - test notification channels [ ] - test notification channels
[ ] - startup time [ ] - startup time
[ ] - Delete single message (swipe right) [ ] - Delete single message (swipe right)
[ ] - Query non-ack-ed messages in app
[ ] - periodically get non-ack (option - even when not in-app) [ ] - periodically get non-ack (option - even when not in-app)
[ ] - publish (+ HN post ?) [ ] - publish (+ HN post ?)

View File

@ -3,15 +3,19 @@ package com.blackforestbytes.simplecloudnotifier.model;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
import com.blackforestbytes.simplecloudnotifier.view.MessageAdapter; import com.blackforestbytes.simplecloudnotifier.view.MessageAdapter;
import com.blackforestbytes.simplecloudnotifier.SCNApp; import com.blackforestbytes.simplecloudnotifier.SCNApp;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class CMessageList public class CMessageList
{ {
public ArrayList<CMessage> Messages; public ArrayList<CMessage> Messages;
public Set<String> AllAcks;
private ArrayList<WeakReference<MessageAdapter>> _listener = new ArrayList<>(); private ArrayList<WeakReference<MessageAdapter>> _listener = new ArrayList<>();
@ -29,6 +33,7 @@ public class CMessageList
private CMessageList() private CMessageList()
{ {
Messages = new ArrayList<>(); Messages = new ArrayList<>();
AllAcks = new HashSet<>();
SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("CMessageList", Context.MODE_PRIVATE); SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("CMessageList", Context.MODE_PRIVATE);
int count = sharedPref.getInt("message_count", 0); int count = sharedPref.getInt("message_count", 0);
@ -42,6 +47,8 @@ public class CMessageList
Messages.add(new CMessage(scnid, time, title, content, prio)); Messages.add(new CMessage(scnid, time, title, content, prio));
} }
AllAcks = sharedPref.getStringSet("acks", new HashSet<>());
} }
public CMessage add(final long scnid, final long time, final String title, final String content, final PriorityEnum pe) public CMessage add(final long scnid, final long time, final String title, final String content, final PriorityEnum pe)
@ -56,6 +63,7 @@ public class CMessageList
SharedPreferences.Editor e = sharedPref.edit(); SharedPreferences.Editor e = sharedPref.edit();
Messages.add(msg); Messages.add(msg);
AllAcks.add(Long.toHexString(msg.SCN_ID));
while (Messages.size()>SCNSettings.inst().LocalCacheSize) Messages.remove(0); while (Messages.size()>SCNSettings.inst().LocalCacheSize) Messages.remove(0);
@ -66,6 +74,8 @@ public class CMessageList
e.putInt( "message["+count+"].priority", pe.ID); e.putInt( "message["+count+"].priority", pe.ID);
e.putLong( "message["+count+"].scnid", scnid); e.putLong( "message["+count+"].scnid", scnid);
e.putStringSet("acks", AllAcks);
e.apply(); e.apply();
for (WeakReference<MessageAdapter> ref : _listener) for (WeakReference<MessageAdapter> ref : _listener)
@ -81,6 +91,7 @@ public class CMessageList
if (!run) if (!run)
{ {
Messages.add(new CMessage(scnid, time, title, content, pe)); Messages.add(new CMessage(scnid, time, title, content, pe));
AllAcks.add(Long.toHexString(msg.SCN_ID));
fullSave(); fullSave();
} }
@ -119,6 +130,8 @@ public class CMessageList
e.putLong( "message["+i+"].scnid", Messages.get(i).SCN_ID); e.putLong( "message["+i+"].scnid", Messages.get(i).SCN_ID);
} }
e.putStringSet("acks", AllAcks);
e.apply(); e.apply();
} }
@ -151,4 +164,9 @@ public class CMessageList
if (_listener.get(i).get() == null) _listener.remove(i); if (_listener.get(i).get() == null) _listener.remove(i);
} }
} }
public boolean isAck(long id)
{
return AllAcks.contains(Long.toHexString(id));
}
} }

View File

@ -167,7 +167,7 @@ public class SCNSettings
{ {
fcm_token_local = token; fcm_token_local = token;
save(); save();
if (!fcm_token_local.equals(fcm_token_server)) ServerCommunication.update(user_id, user_key, fcm_token_local, loader); if (!fcm_token_local.equals(fcm_token_server)) ServerCommunication.updateFCMToken(user_id, user_key, fcm_token_local, loader);
} }
else else
{ {
@ -199,7 +199,7 @@ public class SCNSettings
{ {
if (!isConnected()) return; if (!isConnected()) return;
ServerCommunication.update(user_id, user_key, loader); ServerCommunication.resetSecret(user_id, user_key, loader);
} }
// refresh account data // refresh account data

View File

@ -5,7 +5,9 @@ import android.view.View;
import com.blackforestbytes.simplecloudnotifier.SCNApp; import com.blackforestbytes.simplecloudnotifier.SCNApp;
import com.blackforestbytes.simplecloudnotifier.lib.string.Str; import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
import com.blackforestbytes.simplecloudnotifier.service.FBMService;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONTokener; import org.json.JSONTokener;
@ -94,12 +96,12 @@ public class ServerCommunication
} }
} }
public static void update(int id, String key, String token, View loader) public static void updateFCMToken(int id, String key, String token, View loader)
{ {
try try
{ {
Request request = new Request.Builder() Request request = new Request.Builder()
.url(BASE_URL + "update.php?user_id="+id+"&user_key="+key+"&fcm_token="+token) .url(BASE_URL + "updateFCMToken.php?user_id="+id+"&user_key="+key+"&fcm_token="+token)
.build(); .build();
client.newCall(request).enqueue(new Callback() client.newCall(request).enqueue(new Callback()
@ -160,12 +162,12 @@ public class ServerCommunication
} }
} }
public static void update(int id, String key, View loader) public static void resetSecret(int id, String key, View loader)
{ {
try try
{ {
Request request = new Request.Builder() Request request = new Request.Builder()
.url(BASE_URL + "update.php?user_id=" + id + "&user_key=" + key) .url(BASE_URL + "updateFCMToken.php?user_id=" + id + "&user_key=" + key)
.build(); .build();
client.newCall(request).enqueue(new Callback() { client.newCall(request).enqueue(new Callback() {
@ -280,6 +282,12 @@ public class ServerCommunication
SCNSettings.inst().save(); SCNSettings.inst().save();
SCNApp.refreshAccountTab(); SCNApp.refreshAccountTab();
if (json_int(json, "unack_count")>0)
{
ServerCommunication.requery(id, key, loader);
}
} catch (Exception e) { } catch (Exception e) {
Log.e("SC:info", e.toString()); Log.e("SC:info", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
@ -298,6 +306,89 @@ public class ServerCommunication
} }
} }
public static void requery(int id, String key, View loader)
{
try
{
Request request = new Request.Builder()
.url(BASE_URL + "requery.php?user_id=" + id + "&user_key=" + key)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("SC:requery", e.toString());
SCNApp.showToast("Communication with server failed", 4000);
SCNApp.runOnUiThread(() -> {
if (loader != null) loader.setVisibility(View.GONE);
});
}
@Override
public void onResponse(Call call, Response response) {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful())
throw new IOException("Unexpected code " + response);
if (responseBody == null) throw new IOException("No response");
String r = responseBody.string();
Log.d("Server::Response", r);
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
if (!json_bool(json, "success"))
{
SCNApp.showToast(json_str(json, "message"), 4000);
return;
}
int count = json_int(json, "count");
JSONArray arr = json.getJSONArray("data");
for (int i = 0; i < count; i++)
{
JSONObject o = arr.getJSONObject(0);
long time = json_lng(o, "timestamp");
String title = json_str(o, "title");
String content = json_str(o, "body");
PriorityEnum prio = PriorityEnum.parseAPI(json_int(o, "priority"));
long scn_id = json_lng(o, "scn_msg_id");
FBMService.recieveData(time, title, content, prio, scn_id, true);
}
SCNSettings.inst().user_id = json_int(json, "user_id");
SCNSettings.inst().quota_curr = json_int(json, "quota");
SCNSettings.inst().quota_max = json_int(json, "quota_max");
SCNSettings.inst().promode_server = json_bool(json, "is_pro");
if (!json_bool(json, "fcm_token_set")) SCNSettings.inst().fcm_token_server = "";
SCNSettings.inst().save();
SCNApp.refreshAccountTab();
if (json_int(json, "unack_count")>0)
{
ServerCommunication.requery(id, key, loader);
}
} catch (Exception e) {
Log.e("SC:info", e.toString());
SCNApp.showToast("Communication with server failed", 4000);
} finally {
SCNApp.runOnUiThread(() -> {
if (loader != null) loader.setVisibility(View.GONE);
});
}
}
});
}
catch (Exception e)
{
Log.e("SC:requery", e.toString());
SCNApp.showToast("Communication with server failed", 4000);
}
}
public static void upgrade(int id, String key, View loader, boolean pro, String pro_token) public static void upgrade(int id, String key, View loader, boolean pro, String pro_token)
{ {
try try
@ -370,8 +461,24 @@ public class ServerCommunication
} }
@Override @Override
public void onResponse(Call call, Response response) { public void onResponse(Call call, Response response)
// ???? {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful())
throw new IOException("Unexpected code " + response);
if (responseBody == null) throw new IOException("No response");
String r = responseBody.string();
Log.d("Server::Response", r);
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
if (!json_bool(json, "success")) SCNApp.showToast(json_str(json, "message"), 4000);
} catch (Exception e) {
Log.e("SC:ack", e.toString());
SCNApp.showToast("Communication with server failed", 4000);
}
} }
}); });
} }
@ -396,6 +503,11 @@ public class ServerCommunication
return o.getInt(key); return o.getInt(key);
} }
private static long json_lng(JSONObject o, String key) throws JSONException
{
return o.getLong(key);
}
private static String json_str(JSONObject o, String key) throws JSONException private static String json_str(JSONObject o, String key) throws JSONException
{ {
return o.getString(key); return o.getString(key);

View File

@ -39,8 +39,26 @@ public class FBMService extends FirebaseMessagingService
PriorityEnum prio = PriorityEnum.parseAPI(remoteMessage.getData().get("priority")); PriorityEnum prio = PriorityEnum.parseAPI(remoteMessage.getData().get("priority"));
long scn_id = Long.parseLong(remoteMessage.getData().get("scn_msg_id")); long scn_id = Long.parseLong(remoteMessage.getData().get("scn_msg_id"));
recieveData(time, title, content, prio, scn_id, false);
}
catch (Exception e)
{
Log.e("FB:Err", e.toString());
SCNApp.showToast("Recieved invalid message from server", Toast.LENGTH_LONG);
}
}
public static void recieveData(long time, String title, String content, PriorityEnum prio, long scn_id, boolean alwaysAck)
{
CMessage msg = CMessageList.inst().add(scn_id, time, title, content, prio); CMessage msg = CMessageList.inst().add(scn_id, time, title, content, prio);
if (CMessageList.inst().isAck(scn_id))
{
Log.w("FB::MessageReceived", "Recieved ack-ed message: " + scn_id);
if (alwaysAck) ServerCommunication.ack(SCNSettings.inst().user_id, SCNSettings.inst().user_key, msg);
return;
}
if (SCNApp.isBackground()) if (SCNApp.isBackground())
{ {
NotificationService.inst().showBackground(msg); NotificationService.inst().showBackground(msg);
@ -52,10 +70,4 @@ public class FBMService extends FirebaseMessagingService
ServerCommunication.ack(SCNSettings.inst().user_id, SCNSettings.inst().user_key, msg); ServerCommunication.ack(SCNSettings.inst().user_id, SCNSettings.inst().user_key, msg);
} }
catch (Exception e)
{
Log.e("FB:Err", e.toString());
SCNApp.showToast("Recieved invalid message from server", Toast.LENGTH_LONG);
}
}
} }

View File

@ -37,11 +37,10 @@ if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>301, 'messag
$stmt = $pdo->prepare('UPDATE messages SET ack=1 WHERE scn_message_id=:smid AND sender_user_id=:uid'); $stmt = $pdo->prepare('UPDATE messages SET ack=1 WHERE scn_message_id=:smid AND sender_user_id=:uid');
$stmt->execute(['smid' => $scn_msg_id, 'uid' => $user_id]); $stmt->execute(['smid' => $scn_msg_id, 'uid' => $user_id]);
echo json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'prev_ack' => $datas[0]['ack'], 'prev_ack' => $datas[0]['ack'],
'new_ack' => 1, 'new_ack' => 1,
'message' => 'ok' 'message' => 'ok'
]); ]);
return 0;

View File

@ -26,19 +26,26 @@ if ($data === null) die(json_encode(['success' => false, 'errid'=>202, 'message'
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'errid'=>203, 'message' => 'UserID not found'])); if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'errid'=>203, 'message' => 'UserID not found']));
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'errid'=>204, 'message' => 'Authentification failed'])); if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'errid'=>204, 'message' => 'Authentification failed']));
$stmt = $pdo->prepare('SELECT COUNT(*) FROM messages WHERE ack=0 AND sender_user_id=:uid');
$stmt->execute(['uid' => $user_id]);
$nack_count = $stmt->fetch(PDO::FETCH_NUM);
$quota = $data['quota_today']; $quota = $data['quota_today'];
$is_pro = $data['is_pro']; $is_pro = $data['is_pro'];
if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $quota=0; if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $quota=0;
echo json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'message' => 'ok',
'user_id' => $user_id, 'user_id' => $user_id,
'quota' => $quota, 'quota' => $quota,
'quota_max' => Statics::quota_max($is_pro), 'quota_max' => Statics::quota_max($is_pro),
'is_pro' => $is_pro, 'is_pro' => $is_pro,
'fcm_token_set' => ($data['fcm_token'] != null), 'fcm_token_set' => ($data['fcm_token'] != null),
'message' => 'ok' 'unack_count' => $nack_count,
]); ]);
return 0;

View File

@ -217,10 +217,15 @@ function refreshVerifyToken()
return $obj['access_token']; return $obj['access_token'];
} }
/**
* @param int $http_code
* @param array $message
*/
function api_return($http_code, $message) function api_return($http_code, $message)
{ {
http_response_code($http_code); http_response_code($http_code);
echo $message; header('Content-Type: application/json');
echo json_encode($message);
die(); die();
} }

View File

@ -38,7 +38,7 @@ $stmt->execute(['uid' => $user_id, 'ft' => $fcm_token]);
$pdo->commit(); $pdo->commit();
echo json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'user_id' => $user_id, 'user_id' => $user_id,
@ -48,5 +48,3 @@ echo json_encode(
'is_pro' => $ispro, 'is_pro' => $ispro,
'message' => 'New user registered' 'message' => 'New user registered'
]); ]);
return 0;

56
web/api/requery.php Normal file
View File

@ -0,0 +1,56 @@
<?php
include_once 'model.php';
$INPUT = array_merge($_GET, $_POST);
if (!isset($INPUT['user_id'])) die(json_encode(['success' => false, 'errid'=>101, 'message' => 'Missing parameter [[user_id]]']));
if (!isset($INPUT['user_key'])) die(json_encode(['success' => false, 'errid'=>102, 'message' => 'Missing parameter [[user_key]]']));
$user_id = $INPUT['user_id'];
$user_key = $INPUT['user_key'];
//----------------------
$pdo = getDatabase();
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, is_pro, quota_day, fcm_token FROM users WHERE user_id = :uid LIMIT 1');
$stmt->execute(['uid' => $user_id]);
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>201, 'message' => 'User not found']));
$data = $datas[0];
if ($data === null) die(json_encode(['success' => false, 'errid'=>202, 'message' => 'User not found']));
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'errid'=>203, 'message' => 'UserID not found']));
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'errid'=>204, 'message' => 'Authentification failed']));
//-------------------
$stmt = $pdo->prepare('SELECT * FROM messages WHERE ack=0 AND sender_user_id=:uid ORDER BY `timestamp` DESC LIMIT 16');
$stmt->execute(['uid' => $user_id]);
$nonacks_sql = $stmt->fetchAll(PDO::FETCH_ASSOC);
$nonacks = [];
foreach ($nonacks_sql as $nack)
{
$nonacks []=
[
'title' => $nack['title'],
'body' => $nack['content'],
'priority' => $nack['priority'],
'timestamp' => $nack['timestamp'],
'usr_msg_id' => $nack['usr_message_id'],
'scn_msg_id' => $nack['scn_message_id'],
];
}
api_return(200,
[
'success' => true,
'message' => 'ok',
'count' => count($nonacks),
'data' => $nonacks,
]);

View File

@ -39,7 +39,7 @@ if ($fcm_token === null)
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), user_key=:at WHERE user_id = :uid'); $stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), user_key=:at WHERE user_id = :uid');
$stmt->execute(['uid' => $user_id, 'at' => $new_userkey]); $stmt->execute(['uid' => $user_id, 'at' => $new_userkey]);
echo json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'user_id' => $user_id, 'user_id' => $user_id,
@ -49,7 +49,6 @@ if ($fcm_token === null)
'is_pro' => $is_pro, 'is_pro' => $is_pro,
'message' => 'user updated' 'message' => 'user updated'
]); ]);
return 0;
} }
else else
{ {
@ -61,7 +60,7 @@ else
$stmt = $pdo->prepare('UPDATE users SET fcm_token=NULL WHERE user_id <> :uid AND fcm_token=:ft'); $stmt = $pdo->prepare('UPDATE users SET fcm_token=NULL WHERE user_id <> :uid AND fcm_token=:ft');
$stmt->execute(['uid' => $user_id, 'ft' => $fcm_token]); $stmt->execute(['uid' => $user_id, 'ft' => $fcm_token]);
echo json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'user_id' => $user_id, 'user_id' => $user_id,
@ -71,5 +70,4 @@ else
'is_pro' => $is_pro, 'is_pro' => $is_pro,
'message' => 'user updated' 'message' => 'user updated'
]); ]);
return 0;
} }

View File

@ -45,7 +45,7 @@ if ($ispro)
$stmt = $pdo->prepare('UPDATE users SET is_pro=0, pro_token=NULL WHERE user_id <> :uid AND pro_token = :ptk'); $stmt = $pdo->prepare('UPDATE users SET is_pro=0, pro_token=NULL WHERE user_id <> :uid AND pro_token = :ptk');
$stmt->execute(['uid' => $user_id, 'ptk' => $pro_token]); $stmt->execute(['uid' => $user_id, 'ptk' => $pro_token]);
echo json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'user_id' => $user_id, 'user_id' => $user_id,
@ -54,7 +54,6 @@ if ($ispro)
'is_pro' => true, 'is_pro' => true,
'message' => 'user updated' 'message' => 'user updated'
]); ]);
return 0;
} }
else else
{ {
@ -63,7 +62,7 @@ else
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), is_pro=0, pro_token=NULL WHERE user_id = :uid'); $stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), is_pro=0, pro_token=NULL WHERE user_id = :uid');
$stmt->execute(['uid' => $user_id]); $stmt->execute(['uid' => $user_id]);
echo json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'user_id' => $user_id, 'user_id' => $user_id,
@ -72,5 +71,4 @@ else
'is_pro' => false, 'is_pro' => false,
'message' => 'user updated' 'message' => 'user updated'
]); ]);
return 0;
} }

View File

@ -1,6 +1,6 @@
<?php <?php
include_once 'model.php'; include_once 'api/model.php';
try try
{ {
@ -9,13 +9,13 @@ try
//sleep(1); //sleep(1);
//------------------------------------------------------------------ //------------------------------------------------------------------
if ($_SERVER['REQUEST_METHOD'] !== 'POST') api_return(400, json_encode(['success' => false, 'error' => ERR::REQ_METHOD, 'errhighlight' => -1, 'message' => 'Invalid request method (must be POST)'])); if ($_SERVER['REQUEST_METHOD'] !== 'POST') api_return(400, ['success' => false, 'error' => ERR::REQ_METHOD, 'errhighlight' => -1, 'message' => 'Invalid request method (must be POST)']);
$INPUT = array_merge($_GET, $_POST); $INPUT = array_merge($_GET, $_POST);
if (!isset($INPUT['user_id'])) api_return(400, json_encode(['success' => false, 'error' => ERR::MISSING_UID, 'errhighlight' => 101, 'message' => 'Missing parameter [[user_id]]'])); if (!isset($INPUT['user_id'])) api_return(400, ['success' => false, 'error' => ERR::MISSING_UID, 'errhighlight' => 101, 'message' => 'Missing parameter [[user_id]]']);
if (!isset($INPUT['user_key'])) api_return(400, json_encode(['success' => false, 'error' => ERR::MISSING_TOK, 'errhighlight' => 102, 'message' => 'Missing parameter [[user_token]]'])); if (!isset($INPUT['user_key'])) api_return(400, ['success' => false, 'error' => ERR::MISSING_TOK, 'errhighlight' => 102, 'message' => 'Missing parameter [[user_token]]']);
if (!isset($INPUT['title'])) api_return(400, json_encode(['success' => false, 'error' => ERR::MISSING_TITLE, 'errhighlight' => 103, 'message' => 'Missing parameter [[title]]'])); if (!isset($INPUT['title'])) api_return(400, ['success' => false, 'error' => ERR::MISSING_TITLE, 'errhighlight' => 103, 'message' => 'Missing parameter [[title]]']);
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -29,12 +29,12 @@ try
//------------------------------------------------------------------ //------------------------------------------------------------------
if ($priority !== '0' && $priority !== '1' && $priority !== '2') api_return(400, json_encode(['success' => false, 'error' => ERR::INVALID_PRIO, 'errhighlight' => 105, 'message' => 'Invalid priority'])); if ($priority !== '0' && $priority !== '1' && $priority !== '2') api_return(400, ['success' => false, 'error' => ERR::INVALID_PRIO, 'errhighlight' => 105, 'message' => 'Invalid priority']);
if (strlen(trim($message)) == 0) api_return(400, json_encode(['success' => false, 'error' => ERR::NO_TITLE, 'errhighlight' => 103, 'message' => 'No title specified'])); if (strlen(trim($message)) == 0) api_return(400, ['success' => false, 'error' => ERR::NO_TITLE, 'errhighlight' => 103, 'message' => 'No title specified']);
if (strlen($message) > 120) api_return(400, json_encode(['success' => false, 'error' => ERR::TITLE_TOO_LONG, 'errhighlight' => 103, 'message' => 'Title too long (120 characters)'])); if (strlen($message) > 120) api_return(400, ['success' => false, 'error' => ERR::TITLE_TOO_LONG, 'errhighlight' => 103, 'message' => 'Title too long (120 characters)']);
if (strlen($content) > 10000) api_return(400, json_encode(['success' => false, 'error' => ERR::CONTENT_TOO_LONG, 'errhighlight' => 104, 'message' => 'Content too long (10000 characters)'])); if (strlen($content) > 10000) api_return(400, ['success' => false, 'error' => ERR::CONTENT_TOO_LONG, 'errhighlight' => 104, 'message' => 'Content too long (10000 characters)']);
if ($usrmsgid != null && strlen($usrmsgid) > 64) api_return(400, json_encode(['success' => false, 'error' => ERR::USR_MSG_ID_TOO_LONG, 'errhighlight' => -1, 'message' => 'MessageID too long (64 characters)'])); if ($usrmsgid != null && strlen($usrmsgid) > 64) api_return(400, ['success' => false, 'error' => ERR::USR_MSG_ID_TOO_LONG, 'errhighlight' => -1, 'message' => 'MessageID too long (64 characters)']);
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -47,19 +47,19 @@ try
if (count($datas)<=0) die(json_encode(['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'User not found'])); if (count($datas)<=0) die(json_encode(['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'User not found']));
$data = $datas[0]; $data = $datas[0];
if ($data === null) api_return(401, json_encode(['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'User not found'])); if ($data === null) api_return(401, ['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'User not found']);
if ($data['user_id'] !== (int)$user_id) api_return(401, json_encode(['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'UserID not found'])); if ($data['user_id'] !== (int)$user_id) api_return(401, ['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'UserID not found']);
if ($data['user_key'] !== $user_key) api_return(401, json_encode(['success' => false, 'error' => ERR::USER_AUTH_FAILED, 'errhighlight' => 102, 'message' => 'Authentification failed'])); if ($data['user_key'] !== $user_key) api_return(401, ['success' => false, 'error' => ERR::USER_AUTH_FAILED, 'errhighlight' => 102, 'message' => 'Authentification failed']);
$fcm = $data['fcm_token']; $fcm = $data['fcm_token'];
$new_quota = $data['quota_today'] + 1; $new_quota = $data['quota_today'] + 1;
if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $new_quota=1; if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $new_quota=1;
if ($new_quota > Statics::quota_max($data['is_pro'])) api_return(403, json_encode(['success' => false, 'error' => ERR::QUOTA_REACHED, 'errhighlight' => -1, 'message' => 'Daily quota reached ('.Statics::quota_max($data['is_pro']).')'])); if ($new_quota > Statics::quota_max($data['is_pro'])) api_return(403, ['success' => false, 'error' => ERR::QUOTA_REACHED, 'errhighlight' => -1, 'message' => 'Daily quota reached ('.Statics::quota_max($data['is_pro']).')']);
if ($fcm == null || $fcm == '' || $fcm == false) if ($fcm == null || $fcm == '' || $fcm == false)
{ {
api_return(412, json_encode(['success' => false, 'error' => ERR::NO_DEVICE_LINKED, 'errhighlight' => -1, 'message' => 'No device linked with this account'])); api_return(412, ['success' => false, 'error' => ERR::NO_DEVICE_LINKED, 'errhighlight' => -1, 'message' => 'No device linked with this account']);
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -71,7 +71,7 @@ try
if (count($stmt->fetchAll(PDO::FETCH_ASSOC))>0) if (count($stmt->fetchAll(PDO::FETCH_ASSOC))>0)
{ {
api_return(200, json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'message' => 'Message already sent', 'message' => 'Message already sent',
@ -81,7 +81,7 @@ try
'quota' => $data['quota_today'], 'quota' => $data['quota_today'],
'is_pro' => $data['is_pro'], 'is_pro' => $data['is_pro'],
'quota_max' => Statics::quota_max($data['is_pro']), 'quota_max' => Statics::quota_max($data['is_pro']),
])); ]);
} }
} }
@ -138,14 +138,14 @@ try
{ {
reportError("FCM communication failed (success_1 <> true)\n\n".$httpresult); reportError("FCM communication failed (success_1 <> true)\n\n".$httpresult);
$pdo->rollBack(); $pdo->rollBack();
api_return(500, json_encode(['success' => false, 'error' => ERR::FIREBASE_COM_ERRORED, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'])); api_return(500, ['success' => false, 'error' => ERR::FIREBASE_COM_ERRORED, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.']);
} }
} }
catch (Exception $e) catch (Exception $e)
{ {
reportError("FCM communication failed", $e); reportError("FCM communication failed", $e);
$pdo->rollBack(); $pdo->rollBack();
api_return(500, json_encode(['success' => false, 'error' => ERR::FIREBASE_COM_FAILED, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'."\n\n".'Exception: ' . $e->getMessage()])); api_return(500, ['success' => false, 'error' => ERR::FIREBASE_COM_FAILED, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'."\n\n".'Exception: ' . $e->getMessage()]);
} }
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), messages_sent=messages_sent+1, quota_today=:q, quota_day=NOW() WHERE user_id = :uid'); $stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), messages_sent=messages_sent+1, quota_today=:q, quota_day=NOW() WHERE user_id = :uid');
@ -156,7 +156,7 @@ try
$pdo->commit(); $pdo->commit();
api_return(200, json_encode( api_return(200,
[ [
'success' => true, 'success' => true,
'error' => ERR::NO_ERROR, 'error' => ERR::NO_ERROR,
@ -169,11 +169,11 @@ try
'is_pro' => $data['is_pro'], 'is_pro' => $data['is_pro'],
'quota_max' => Statics::quota_max($data['is_pro']), 'quota_max' => Statics::quota_max($data['is_pro']),
'scn_msg_id' => $scn_msg_id, 'scn_msg_id' => $scn_msg_id,
])); ]);
} }
catch (Exception $mex) catch (Exception $mex)
{ {
reportError("Root try-catch triggered", $mex); reportError("Root try-catch triggered", $mex);
if ($pdo->inTransaction()) $pdo->rollBack(); if ($pdo->inTransaction()) $pdo->rollBack();
api_return(500, json_encode(['success' => false, 'error' => ERR::INTERNAL_EXCEPTION, 'errhighlight' => -1, 'message' => 'PHP script threw exception.'."\n\n".'Exception: ' . $e->getMessage()])); api_return(500, ['success' => false, 'error' => ERR::INTERNAL_EXCEPTION, 'errhighlight' => -1, 'message' => 'PHP script threw exception.'."\n\n".'Exception: ' . $e->getMessage()]);
} }