i was doing long polling , but it can see in my network chrome my long polling in status pending that means is waiting for new data and changes the database , but when I try to insert one item to my database then , but when I try to insert one value show keep that long polling in real time i cant see real time updatings .. how can I fix it?
pusher controller codeigiter
public function pusher() {
header('Content-Type: application/json');
$user_id = $this->session->log['id'];
set_time_limit(0);
while (true) {
$firstCall = false;
if (isset($_GET['timestamp'])) {
$last_ajax_call = $_GET['timestamp'];
} else {
$last_ajax_call = time();
$firstCall = true;
}
clearstatcache();
$notificationsCount = $this->notification->checkForNotifications($last_ajax_call, $user_id);
$newData = (int) $notificationsCount > 0 ? true : false;
$notifications = [];
if ($newData) {
$dataSet = $this->notification->getNotifications($user_id, $last_ajax_call);
foreach($dataSet as $data) {
$notifications[] = $data;
$finalNotificationTime = $data['timestamp'];
}
$result = array('notifications' => $notifications, 'timestamp' => $finalNotificationTime);
$json = json_encode($result);
echo $json;
break;
} else {
if ($firstCall) {
$dataSet = $this->notification->getUnreadNotifications($user_id);
foreach($dataSet as $data) {
$notifications[] = $data;
}
$result = array('notifications' => $notifications, 'timestamp' => $last_ajax_call);
$json = json_encode($result);
echo $json;
break;
}
sleep(1);
session_write_close();
continue;
}
}
exit();
}
ajax
function check_notifications(timestamp) {
var queryString = {
'timestamp': timestamp
};
$.ajax({
type: 'GET',
url: URL_GET_NOTIFICATION,
data: queryString,
success: function (data) {
// put result data into "obj"
for (var i in data.notifications) {
notify(data.notifications[i].message, data.notifications[i].type, data.notifications[i].timestamp);
}
check_notifications(data.timestamp);
}
});
}
check_notifications();
Related
I use Yii2-advanced-app(2.0.15) and i need to do the logon operation with OTP.
With the cell number and password, everything is correct and the cookie is correct but when I use an opt, no value is created for the cookie.
My ajax code:
$("#m-sendCode__form-submit").click(function() {
$(this).attr('disabled','true');
let mobile = $('#mobile').val();
let csrfToken = $('meta[name="csrf-token"]').attr("content");
let rememberMe = $("#remember2").prop('checked');
// console.log(rememberMe);
$.ajax({
url: '/loginbysms',
method: 'POST',
data: {
_csrfFrontend: csrfToken,
phone: phone,
rememberMe: rememberMe
},
timeout: 6000
})
.done(function(data) {
let response = JSON.parse(data);
// console.log(data);
if (response.sent === 1){
$.ajax({
url: '/loginbysms',
method: 'POST',
data: {
_csrfFrontend: csrfToken,
verify: verify,
// rememberMe: rememberMe
},
})
.done(function(data) {
let s = JSON.parse(data);
if (s.status === 1){
window.location.href = '/';
}
});
}
})
.fail(function(error)){
console.log(error);
});
});
And my controller is:
public function actionLoginbysms()
{
$dataAjax = Yii::$app->request->post();
$session = Yii::$app->session;
if(isset($dataAjax)) {
if (isset($dataAjax['phone']) && !empty($dataAjax['phone'])) {
$phone = $dataAjax['phone'];
$user = User::findByPhone2($phone);
$sendSMS = new SendSMS();
if ($sendSMS->SendSMS($user->user_otp, $phone)) {
echo json_encode(['sent' => 1]);
exit;
} else {
echo json_encode(['sent' => 0]);
exit;
}
}
if(isset($dataAjax['verify]) && !empty($dataAjax['verfy'])){
$authorizedUser = User::findByOtp($session-
>get('user_phone'), $dataAjax['verify']);
if (isset($authorizedUser) && !empty($authorizedUser)) {
Yii::$app->user->login($authorizedUser, 3600 * 24 *
30)
echo json_encode(['status' => 1]);
exit;
}
}
}
}
When everything is true and the code is sent correctly by the user, the user enters the home page correctly but no value for the cookie is saved.
Please tell me the mistake.
The controller should be changed as follows:
public function actionLoginbysms()
{
$dataAjax = Yii::$app->request->post();
$session = Yii::$app->session;
if(Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
if (isset($dataAjax['phone']) && !empty($dataAjax['phone'])) {
$mobile = $dataAjax['phone'];
$user = User::findByPhone2($phone);
if ($user) {
unset($dataAjax['phone']);
$numbers = range(10000, 99999);
shuffle($numbers);
$session->set('user_phone', $phone);
if (isset($dataAjax['rememberMe']) && !empty($dataAjax['rememberMe'])
&& ($dataAjax['rememberMe'] == true)) {
$session->set('rememberMe', 'yes');
unset($dataAjax['rememberMe']);
}
$user->user_otp = $numbers[0];
$user->save();
try {
$sendSMS = new SendSMS();
$sendSMS->SendSMS($user->user_otp, $phone);
} catch (\Throwable $e) {
return [
'sent' => 0
];
}
return [
'sent' => 1
];
} else {
return ['user_not_found' => 1];
}
}
else if (isset($dataAjax['verify']) && !empty($dataAjax['verify'])) {
if ($session->isActive && $session->has('user_phone')) {
$authorizedUser = User::findByOtp($session->get('user_phone'), $dataAjax['verify']);
if (isset($authorizedUser) && !empty($authorizedUser)) {
unset($dataAjax['verify']);
$session->remove('user_phone');
$authorizedUser->user_otp = '';
$authorizedUser->save();
if(Yii::$app->user->login($authorizedUser, 3600 * 24 * 30)) {
return ['authenticationSuccess' => 1];
}
}
}
return ['authenticationSuccess' => 0];
}
}
}
As #rob006 said, we should not use exit.
With the help of Yii::#app->response->format = Response::FORMAT_JSON, everything works fine
This is the output I get from ajax request to php pdo:
[{"sys_id":"1","task":"qwe","task_date":"11\/30\/2017 8:49 PM","task_person":"qwe","task_status":"0"},{"sys_id":"2","task":"asd","task_date":"11\/30\/2017 9:54 PM","task_person":"asd","task_status":"0"}]null
As shown there is an excess null value which I cant figure out where it is coming from my code is:
function selecttask(action) {
$.ajax({
type: 'POST',
url: '../include/demo.php',
dataType: "json",
data: {
action: action
},
success: function(data) {
}
}).done(function(data) {
});
}
selecttask("selectall");
My demo.php is:
<?php
include_once("crud.php");
//include_once("../config/config.php");
//$con = new connect_pdo();
$crud = new Crud();
$action = $_POST['action'];
$data = $_POST['data'];
switch (strtolower($action)):
case("selectall"):
$table = "list_tbl";
$selectall = $crud->selectall($table);
echo json_encode($selectall, JSON_UNESCAPED_UNICODE);
break;
case("add"):
$table = "list_tbl";
$insert = $crud->insert($table,$data);
echo json_encode($insert, JSON_UNESCAPED_UNICODE);
break;
endswitch;
?>
Then crud is:
<?php
include_once("../config/config.php");
class Crud extends connect_pdo {
public $_con;
function __construct() {
parent::__construct();
$this->_con = $this->dbh();
}
public function selectall($table_name) {
$queryselectall = "Select * from {$table_name}";
$selectall = $this->_con->prepare($queryselectall);
if ($selectall->execute()) {
if ($selectall->rowCount() > 0) {
$result = $selectall->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($result, JSON_UNESCAPED_UNICODE);
}else{
echo array('error'=> TRUE, 'message'=> 'No result found.');
}
}
}
public function insert($table_name, $res) {
parse_str($res, $data);
$limit = count($data);
$ctr = 0;
$columns = "";
$values = "";
foreach ($data as $key => $value) {
$ctr++;
$columns.= "{$key}";
$values .= ":{$key}";
if ($ctr < $limit) {
$columns.= ",";
$values .= ",";
}
}
$query = "INSERT INTO {$table_name} ({$columns})VALUES({$values})";
try {
$create = $this->_con->prepare($query);
foreach ($data as $key => $value) {
$keys = ":{$key}";
$create->bindValue($keys, $value, PDO::PARAM_STR);
}
if ($create->execute()) {
$lastinserted_id = $this->_con->lastInsertId();
echo array('error' => FALSE, 'message' => 'Data added successfully.', 'lastinserted_id' => $lastinserted_id, 'query' => $query);
} else {
echo array('error' => TRUE, 'message' => 'Execution failed, please contact system support!');
}
} catch (Exception $ex) {
echo array('error' => TRUE, 'message' => $ex);
}
}
}
?>
From the above code I cant determine where the null is coming from.
Did I miss something that is why null is coming as result of ajax request
Probably a better architecture for your Crud class to handle DB interactions by running the queries and returning the results as an array (or throwing an exception if anything exceptional happens). Then your demo.php script can just get the array from the Crud class method and handle the output (json encoding, response output).
I'm trying to develop a Php Photo Gallery only for my personal use and I put a Php System Rating using a modified script that I found on the web... all works fine except for one thing, I cannot stop users from posting several votes in the same day! I'd like that users vote the photos (several photos as well) but voting one time in the same day (one vote for each photo)... I post here the script that I have modified.
ratings.php:
<?php
$rating = new ratings($_POST['widget_id']);
isset($_POST['fetch']) ? $rating->get_ratings() : $rating->vote();
class ratings {
var $data_file = './ratings.data.txt';
private $widget_id;
private $data = array();
function __construct($wid) {
$this->widget_id = $wid;
$all = file_get_contents($this->data_file);
if ($all) {
$this->data = unserialize($all);
}
}
public function get_ratings() {
if ($this->data[$this->widget_id]) {
echo json_encode($this->data[$this->widget_id]);
} else {
$data['widget_id'] = $this->widget_id;
$data['number_votes'] = 0;
$data['total_points'] = 0;
$data['dec_avg'] = 0;
$data['whole_avg'] = 0;
echo json_encode($data);
}
}
public function vote() {
# Get the value of the vote
preg_match('/star_([1-5]{1})/', $_POST['clicked_on'], $match);
$vote = $match[1];
$ID = $this->widget_id;
# Update the record if it exists
if ($this->data[$ID]) {
$this->data[$ID]['number_votes'] += 1;
$this->data[$ID]['total_points'] += $vote;
} else { # Create a new one if it doesn't
$this->data[$ID]['number_votes'] = 1;
$this->data[$ID]['total_points'] = $vote;
}
$this->data[$ID]['dec_avg'] = round($this->data[$ID]['total_points'] / $this->data[$ID]['number_votes'], 1);
$this->data[$ID]['whole_avg'] = round($this->data[$ID]['dec_avg']);
file_put_contents($this->data_file, serialize($this->data));
$this->get_ratings();
}
# ---
# end class
}
?>
ratings.js:
$(document).ready(function() {
$('.rate_widget').each(function(i) {
var widget = this;
var out_data = {
widget_id : $(widget).attr('id'),
fetch: 1
};
$.post(
'ratings/ratings.php',
out_data,
function(INFO) {
$(widget).data('fsr', INFO);
set_votes(widget);
},
'json'
);
});
$('.ratings_stars').hover(
function() {
$(this).prevAll().andSelf().addClass('ratings_over');
$(this).nextAll().removeClass('ratings_vote');
},
function() {
$(this).prevAll().andSelf().removeClass('ratings_over');
set_votes($(this).parent());
}
);
$('.ratings_stars').bind('click', function() {
var star = this;
var widget = $(this).parent();
var clicked_data = {
clicked_on : $(star).attr('class'),
widget_id : $(star).parent().attr('id')
};
$.post(
'ratings/ratings.php',
clicked_data,
function(INFO) {
widget.data('fsr', INFO);
set_votes(widget);
},
'json'
);
});
});
function set_votes(widget) {
var avg = $(widget).data('fsr').whole_avg;
var votes = $(widget).data('fsr').number_votes;
var exact = $(widget).data('fsr').dec_avg;
window.console && console.log('and now in set_votes, it thinks the fsr is ' + $(widget).data('fsr').number_votes);
$(widget).find('.star_' + avg).prevAll().andSelf().addClass('ratings_vote');
$(widget).find('.star_' + avg).nextAll().removeClass('ratings_vote');
$(widget).find('.total_votes').text( votes + ' votes (' + exact + ' rating)' );
}
I tried to implement IP mechanism in ratings.php as below without lucky
<?php
$rating = new ratings($_POST['widget_id']);
isset($_POST['fetch']) ? $rating->get_ratings() : $rating->vote();
class ratings {
var $data_file = './ratings.data.txt';
private $widget_id;
private $data = array();
function __construct($wid) {
$this->widget_id = $wid;
$all = file_get_contents($this->data_file);
if ($all) {
$this->data = unserialize($all);
}
}
public function get_ratings() {
if ($this->data[$this->widget_id]) {
echo json_encode($this->data[$this->widget_id]);
} else {
$data['widget_id'] = $this->widget_id;
$data['number_votes'] = 0;
$data['total_points'] = 0;
$data['dec_avg'] = 0;
$data['whole_avg'] = 0;
echo json_encode($data);
}
}
public function vote() {
# Get the value of the vote
preg_match('/star_([1-5]{1})/', $_POST['clicked_on'], $match);
$vote = $match[1];
$ID = $this->widget_id;
# Update the record if it exists
if ($this->data[$ID]) {
$this->data[$ID]['number_votes'] += 1;
$this->data[$ID]['total_points'] += $vote;
$this->data[$ID]['remote_ip'] = $_SERVER['REMOTE_ADDR'];
} else { # Create a new one if it doesn't
$this->data[$ID]['number_votes'] = 1;
$this->data[$ID]['total_points'] = $vote;
$this->data[$ID]['remote_ip'] = $_SERVER['REMOTE_ADDR'];
}
if ($this->data[$ID]['remote_ip'] != $_SERVER['REMOTE_ADDR']) {
$this->data[$ID]['dec_avg'] = round($this->data[$ID]['total_points'] / $this->data[$ID]['number_votes'], 1);
$this->data[$ID]['whole_avg'] = round($this->data[$ID]['dec_avg']);
file_put_contents($this->data_file, serialize($this->data));
$this->get_ratings();
}
}
# ---
# end class
}
?>
The simplest way is to notify in a data table who vote and which day.
For example : Toto vote on 2014-07-04, so he can't vote twice today.
In data table user you add a colum date to notify the last day of vote.
You can use cookies but it's very very ugly !
I have created a javascript file that contains js to trigger an event onchange of a drop down list. The JS is below:
// /public/js/custom.js
jQuery(function($) {
$("#parent").change(function(event){
event.preventDefault();
var parentID = $('#parent').val();
var id = $('#id').val();
$.post("/menu/GetMenuChildren", {pID: parentID, thisID: id },
function(data){
if(data.response === true){
var $el = $("#Position");
$el.empty(); // remove old options
$.each(data.newOptions, function(key, value) {
$el.append($("<option></option>")
.attr("value", value).text(key));
});
} else {
// print error message
alert("something went wrong in Post");
}
}, 'json');
alert("After Post");
});
});
In my Controller.php I have an function GetMenuChildrenAction as shown below:
public function GetMenuChildrenAction()
{
$request = $this->getRequest();
$response = $this->getResponse();
if ($request->isPost())
{
$post_data = $request->getPost();
$parent_id = $post_data['pID'];
$id = $post_data['thisID'];
//$this->form->get('Position')->SetOptionValues(
$newOptions = $this->getMenuTable()->GetPositionsByID($parent_id, $id);
if(isset($newOptions))
{
$response->setContent(\Zend\Json\Json::encode(array('response' => true, 'newOptions' => $newOptions)));
}
else
{
$response->setContent(\Zend\Json\Json::encode(array('response' => false)));
}
}
return $response;
}
In the MenuTable.php there is a Method GetPositionsByID as shown below:
public function GetPositionsByID($parentID, $id)
{
if($parentID == 0)
{
$menu = $this->getMenu($this->id);
$parentID = $menu->parent_id;
}
if(isset($parentID))
{
$sql = "Select ID,Label from Menu Where parent_ID = " . $parentID . " and id > 1 and id <> " . $id . " Order by Position,Label";
try
{
$statement = $this->adapter->query($sql);
}
catch(Exception $e) {
console.log('Caught exception: ', $e->getMessage(), "\n");
}
$res = $statement->execute();
$rows = array();
$i = 0;
foreach ($res as $row) {
$i = $i + 1;
$rows[$i] = array (
$i => $row['Label']
);
}
return $rows;
}
return array();
}
It all seems to be hooked up correctly, when I debug the code, I get the this line:
$statement = $this->adapter->query($sql);
and then nothing happens. If I replace all the code in the GetPositionsByID method, and simply return an array like the following:
return array('1' => 'one', '2' => 'two');
it works great, however i want to get the data from the DB. Does anyone know why the execute would fail on this line?
$statement = $this->adapter->query($sql);
Thanks in advance
The issue was that the adapter was null.
I have a function A which loads the data from db if the user has liked the image. I have another function B which loads the count for the total number of likes for the image. Both these functions return response using JSON.
If I call them individually, everything works fine, but if I call function B in function A, I get no JSON response and nothing happens although firebug does show two JSON arrays being outputted.
What is wrong with the code?
Function A:
public function loadLikes() {
//sql query
try
{
$query = $this->_db->prepare($sql);
$params = array(':imageid' => $imageid, ':author' => $author);
$query->execute($params);
//calling function B
$this->countLikes($imageid);
if ($query->rowCount() > 0) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
if ($row['like'] == '1') {
$response = json_encode(array('like' => true));
echo $response;
return TRUE;
}
elseif ($row['like'] == '2') {
$response = json_encode(array('unlike' => true));
echo $response;
return TRUE;
}
else {
$error = "Invalid";
$response = json_encode(array('like' => false, 'text' => $error));
echo $response;
return FALSE;
}
}
}
else {
$response = json_encode(array('unlike' => true));
echo $response;
return FALSE;
}
}
catch(PDOException $ex)
{
echo json_encode(array('like' => false, 'text' => $ex));
return FALSE;
}
}
Function B:
public function countLikes($i) {
//sql query
try
{
$query = $this->_db->prepare($sql);
$params = array(':imageid' => $i);
$query->execute($params);
if ($query->rowCount() > 0) {
$count = $query->fetchColumn();
$response = json_encode(array('count' => $count));
echo $response;
return TRUE;
}
}
catch(PDOException $ex)
{
return FALSE;
}
}
jQuery:
$.ajax({
type: "POST",
url: url,
data: postData,
dataType: "json",
success: function(data){
$(".count-like").show(600).text(data.count);
if(data.like) {
$("a#alike").attr('class', 'starred');
}
else if (data.unlike) {
$("a#alike").attr('class', 'unlike');
}
else {
alert(data.text);
}
}
});
If you invoke both functions, then each will output a JSON array. This will result in a HTTP response with following content:
{"like":1}{"count":2}
Both arrays would be valid separately. But if concatenated like this, it's no longer valid JSON.
Instead of outputting the json serialization with echo you should collect it in a temporary variable, merge the two arrays, and then output the combined array with a single:
echo json_encode(array_merge($countArray, $likeArray));
Example adaptions of your code
Function B should become:
public function countLikes($i) {
//sql query
try
{
$query = $this->_db->prepare($sql);
$params = array(':imageid' => $i);
$query->execute($params);
if ($query->rowCount() > 0) {
$count = $query->fetchColumn();
/* JUST RETURN HERE */
return (array('count' => $count));
}
}
catch(PDOException $ex)
{
/* INSTEAD OF FALSE use an empty array,
which is interpreted as false in boolean context*/
return array();
}
}
Then when you call the function:
//calling function B
$countArray = $this->countLikes($imageid);
This will always be an array. Which you then can use in the output code:
$response = json_encode(array('like' => true) + $countArray);
(It's still inadvisable to have an echo right there. But too much code, too little context to propose a nicer rewrite. And if it works, ..)