Tracking number of clicks on a link - php - php

I have made a tracking website in php which tracks number of clicks on a specific link - for affiliate links tracking. what I am doing is:
When a user clicks a link provided by my website, he goes to my website which after recording its ip address redirects the user to another address mapped to the link user clicked. A counter increments the number of click after validating ip.
The problem I am facing is that when i compare the number of clicks in my website and that of facebook results, my result is many times more. I don't know what is the cause of that.
My results:
Facebook results:
My question is that why is there a difference? if facebook has some additional checks does someone know what they are? or are they private? or facebook just reduces the number of clicks?
Help would be really appreciated. I am stuck here.
Here is my code to check the visitors ip and increment the click counter:
<?php
require_once "dbdata.php";
if(isset($_GET['linkid']) && !empty($_GET['linkid'])){
$id = $_GET['linkid']; //getting link id to fetch data from database
$ip = $_SERVER['REMOTE_ADDR']; // getting visitors ip address
//database connection
#$db = new mysqli(hostname,username,password,dbname) or die(json_encode(array("status"=>"Can not connect (Database Connection Error)")));
//getting data from table
$query = "select * from links_shared where id = $id ;";
$result_link = $db -> query($query) or die(json_encode(array("status"=>"Error Fetching previous income data")));
$row_link = $result_link-> fetch_assoc();
$link = $row_link['orignal']; //the link to be redirect the user to
header("Location:".$link); //redirected
if($row_link['status'] == "live"){ //status of link should be live
$array_ip = explode(",", $row_link['ip']); //comma sepearted string of ips to array
if(!in_array($ip, $array_ip)){ //check if ip is not already present
$query = "select * from links_deleted where url = '$link' ;"; //getting block list
$result_del = $db -> query($query) or die(json_encode(array("status"=>"Can not select deleted")));
if($result_del -> num_rows <1){ //check if link not in block list
$concat = ",".$ip;
echo $query = "update links_shared set clicks = (clicks + 1), ip = concat(ip,'$concat') where id= $id; ";
$result_update = $db -> query($query) or die(json_encode(array("status"=>"can not update clicks")));
}
}
}
}
?>

Either facebook is invalidating clicks that your script accepts (eg: untrusted IPs, repeated IPs, automatic bot detection...) or more simply facebook only sees clicks from its platform but your script receives all clicks from everywhere.
Of course there could also be a problem with your script itself, but since you don't show it, I can't address that.

Related

My poll has a 'back button' loophole

Have had a couple questions answered very nicely here and I've got some more trouble someone can probably help with:
I have SQL database that holds a poll question answer and a user IP address. Here is my (now working!) PHP code:
// check to see if user has already voted
$current_user = $_SERVER['REMOTE_ADDR'];
$select_query = "SELECT * FROM w_poll_counter WHERE user_IP = '" . $current_user ."';";
$result = mysql_query($select_query);
if($result)
{
$row = mysql_fetch_array($result);
$user_from_db = $row['user_IP'];
if($current_user === $user_from_db)
{
//user already voted - show results page
header("Location: scripts/show_results.php");
exit();
}
}
The code works great, except there's one problem... After a user votes and sees the results page, they can click the browser's 'back' button and then simply vote again, since the code to check their IP address doesn't run in that instance.
What do I need to do to fix this issue?
Thanks!
Check if the user has already voted before executing your update statement.
Also you should take better care, your script is very vulnerable to sql injections. https://stackoverflow.com/a/60496/3595565
I can show you this example of an implementation via pdo:
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8;', 'dbUser', 'dbPassword');
$stmtCheck = $pdo->prepare("SELECT * FROM w_poll_counter WHERE user_IP = ?");
$stmtCheck->execute(array($_SERVER['REMOTE_ADDR']));
$result = $stmtCheck->fetchAll(PDO::FETCH_ASSOC);
if(count($result) === 0){
//update
}

php not working when user click in BACK bottom in browser

I have a problem and I don't know if anyone has a solution...
I have an online.php script that gets user ip and data and write it on mysql:
$browser = $_SERVER['HTTP_USER_AGENT'];
$root = $_SERVER['DOCUMENT_ROOT'];
include_once ("$root/config.php");
$ip = $_SERVER['REMOTE_ADDR'];
...
$sb4154 = $on124->num_rows;
if ($sb4154 == 0) {
$url=#$_SERVER['HTTP_REFERER'];
$ihghg = $mysqli_link->prepare("INSERT INTO online (ip, hora, browser) VALUES (?,now(),?)");
$ihghg->bind_param('ss', $ip, $browser);
$ihghg->execute();
$ihghg->close();
}
else {
$ihghg = $mysqli_link->prepare("UPDATE online SET `hora` = now() WHERE `ip` = ? LIMIT 1");
$ihghg->bind_param('s', $ip);
$ihghg->execute();
$ihghg->close();
}
it is basically that. (I use ... to sum up).
My php, when you click in a link it opens the image:
<a href="image.jpg">
So the user needs to click back in the browser to see more pictures. The problem is here, when user click back, this include online.php script not work, the UPDATE time not set the hour.
Why it is not working when user click back in browser?

How does your sql query on the sub-page determine which menu was used to navigate to the page?

Admin can see two menu.
Manage - Retrieve query depends on User location. This menu provide for all users.
Admin Menu - No restrict on query. This menu provide only for Admin.
Above two menu using same Page, but query dynamically choose depends on User.
I tried passing value through URL like url.com?admin=1 . If Admin parameter is set query will not have any restriction. Otherwise Restrict by Location.
But my problem is while I click and navigate from one to another page and perform some form action , In these case, URL parameter automatically unset even Admin. So query will be restrict by location even Admin.
So any one help me to solve this problem.
<?php
$LoginEmpID = $_SESSION["EmployeeLoggedIN"];
//find out location for display room id and discription (Ex.Salem Employee only can give salem's rooms)
$employeeLocation = sprintf("SELECT Location FROM Employee where Emp_ID = %s", GetSQLValueString($LoginEmpID, "int"));
$Recordset_employeeLocation = mysql_query($employeeLocation) or die(mysql_error());
$row_Recordset_employeeLocation = mysql_fetch_array($Recordset_employeeLocation);
$str_Emp_location = $row_Recordset_employeeLocation['Location'];
//DropDown For Room Information
$query_Recordset1_room_number = sprintf("SELECT room_id, role_description,location_id FROM hrms_m_rooms where location_id = %s",GetSQLValueString($str_Emp_location, "text"));
if(isset($_GET['admin']))
{
//DropDown For Room Information
$query_Recordset1_room_number = sprintf("SELECT room_id, role_description,location_id FROM hrms_m_rooms where location_id = %s",GetSQLValueString($str_Emp_location, "text"));
}
$Recordset1_room_number = mysql_query($query_Recordset1_room_number) or die(mysql_error());
$row_Recordset1_room_number = mysql_fetch_array($Recordset1_room_number);
$totalRows_Recordset1_room_number = mysql_num_rows($Recordset1_room_number);
$current_loaction = $row_Recordset1_room_number['location_id'];
//Dropdown lookupid
$query_Recordset1_resource_type = "SELECT lookup_id, lookup_description FROM hrms_general_master WHERE lookup_type = 'RESOURCE_TYPE'";
$Recordset1_resource_type = mysql_query($query_Recordset1_resource_type) or die(mysql_error());
$row_Recordset1_resource_type = mysql_fetch_assoc($Recordset1_resource_type);
$totalRows_Recordset1_resource_type = mysql_num_rows($Recordset1_resource_type);
?>
The first thing I would suggest is switching from mysql to mysqli or even better using mysql-pdo.
I hope placing a url parameter of ?Admin=1 is only for testing/debugging purposes. This is a HUGE security leak since anyone can log in then manually set their ?Admin=25 to ?Admin=1 and access your admin area.
I would suggest creating a field for permission levels in your DB if you haven't done so already.
Then using session_start(); as #Saty commented at the top of your page and creating a session for admin on your login page like this...
$loginStrGroup = $row['permission'];
$_SESSION['UserGroup'] = $loginStrGroup;
Then remove your url parameter ?Admin=1
Finally change if(isset($_GET['admin'])) to if(isset($_SESSION['UserGroup']) && ($_SESSION['UserGroup'] == 'Admin'))
Make sure to put that on every page you need the "Admin" to be able to see the admin menu.
ADDED CODE:
If the Manage menu and Admin menu both point to the same page, but what is displayed to the user depends on which menu they used, then I would only show one menu depending upon whether they were Admin or not.
if(isset($_SESSION['UserGroup']) && ($_SESSION['UserGroup'] == 'Admin')) {
--- show admin menu ---
} else {
--- show manager menu ---
}

Write to a php file via wordpress

I've built a web page that is able to send text messages to employees at the company where I work. With new employees being added and removed on a constant basis, I want to integrate this app with wordpress where the employees can be managed without editing the code.
Each post would contain the user's name and phone number. The name would be pulled in on the webpage as an option for the user to contact. When the form is submitted, it would go to a php form that runs an if/else to find the employee and match that employee with their phone number like so:
//Who the text message is to, Establish their phone #
if($employee == 'brad'):
$text_to[] = '+15555555555';
elseif ($employee == 'mary'):
$text_to[] = '+15555555555';
elseif ($employee == 'tom'):
$text_to[] = '+15555555555';
elseif ($employee == 'bill'):
$text_to[] = '+15555555555';
elseif ($employee == 'joe'):
endif;
I want to be able to not only pull these names from wordpress via a loop to display onto my page, but also to be able to add or remove the new entries, along with their phone number, to this php contact form.
I know how to loop through the wordpress posts to display the names on the page. I want to know if it's possible to also use this data to modify this contact form, and if so, how to set this up. Each time someone edits the wordpress entry for Joe, the PHP form gets this update so that when Joe is sent a message, it finds his phone number and sends him the message.
Any help is greatly appreciated. I should also note that I'm using Twilio to send the texts messages.
The use of a DMBS works well, but is not the only solution.
include 'users.inc'; // flat file creating array $userList
which could be an array( ofArrays ) for complex structures
[assume $userList = array($user => $phone, ...); ]
then foreach( $userList as $user => $phone ) { // process($user, $phone); }
Kudos for trying to solve a simple problem yourself. It's obvious that you are new to the idea of databases, and quite frankly, you're doing this the wrong way.
Let's talk about how your initial approach can be improved:
Each post would contain the user's name and phone number.
Perhaps instead of posts, we have one database table to store employee information.
You'll find tons of information on databases and how to use them with your wordpress account with a simple google search.
I want to be able to not only pull these names from wordpress via a loop to display onto my page, but also to be able to add or remove the new entries, along with their phone number, to this php contact form.
Again, if you had a database to store employee information, this is basic.
For example, an employees database table may have the following columns:
id
name
phone
created_at
updated_at
Since PHP has built in functions for communicating with a MYSQL database (which is most likely what WordPress is already using), you can do things like:
Get all employee data
SELECT * FROM employees
Get a certain employee's data
SELECT * FROM employees WHERE name = '$name'
$name is a variable that can be set via POST request from a WordPress form
Update a certain employee's data
UPDATE employees SET phone = '+15555555555' WHERE name = '$name'
Remove a certain employee's data
DELETE FROM employees WHERE id = 5
You are also able to do things like:
SELECT * FROM employees WHERE created_at > '3/1/2015'
Which will return all employees that were added after 3/1/15.
So everything that you all suggested was helpful. I may have not been as clear as I could have that I really needed the creation/editing/deletion of entries to be done via wordpress posts. I was able to set it up like this by doing the following:
//pull variables from html form input. Employee variables are post ID's that I will then be able to use to retrieve the post_content which contains their phone numbers
$employee1 = $_POST['employeeName1'];
$employee2 = $_POST['employeeName2'];
$employee3 = $_POST['employeeName3'];
$customMsg = $_POST["textMessage"];
//Create array from above variables and exclude any that lack post data
$employees = array($employee1, $employee2, $employee3);
$setEmployeeIDs = array();
foreach ($employees as $employee) {
if (!empty($employee)) {
$setEmployeeIDs[] = $employee;
}
}
$servername = "xxxx";
$username = "xxxx";
$password = "xxxx";
$dbname = "xxxx";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
//Get array of Phone Numbers connected to each ID and add to array
$sql = "SELECT * FROM wp_posts WHERE ID IN (".implode(',',$setEmployeeIDs).")";
$result = $conn->query($sql);
$phoneNumbers = array();
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$phoneNumbers[] = $row["post_content"] ;
}
} else {
echo "0 results";
}
$conn->close();
So to sum it up, I used wordpress to publish/edit/delete that data as posts, then sent the ID's selected from the webpage to the php form, and then was able to retrieve the phone numbers from the SQL database using Raphael's direction.

Display dynamic PHP content based on IP address

In my MySQL database you login via the game and then type your username in on the site and see your stats. This is my information snippet from my API.
elseif ($_GET['task'] == 'login') {
$get_user = $_GET['user'];
$get_db = 'engine';
$result = mysql_query("SELECT * FROM $get_db WHERE name = '" . mysql_real_escape_string($get_user) . "'", $link);
while($data = mysql_fetch_array($result)) {
echo '{"task":"login","password":"'; echo $data['hash'];
echo '","lastip":"'; echo $data['lastip'];
echo '","timestamp":"'; echo $data['logindate'];
echo '"}';
}
}
I am trying to add a line of text under the search textbox on the homepage that will pop up if your IP recently logged into a server. It'll say "Hey, aren't you username?"
What type of code would be required to do this? I would need to call upon their IP, and search the database for all users who have authenticated with it, and then make sure to display the latest one based on their timestamp.
You can use both $_SERVER['REMOTE_ADDR'] and $_SERVER['HTTP_X_FORWARDED_FOR'] to get the public IP and sometimes (with the second case) the private IP.
By the way, notice that old mysql_*() functions are deprecated as of PHP 5.5. You should use the mysqli or PDO_MySQL extensions.
$_SERVER['REMOTE_ADDR'] will give you the IP address of the person viewing the page.
From there you just need to compare it to the lastip field in your query.
$userIP = $_SERVER['REMOTE_ADDR'];
$query = "SELECT * FROM ".$get_db." WHERE lastip = ".$userIP." ORDER BY logindate DESC LIMIT 1";
Or something along those lines.
You could use the $_SERVER['REMOTE_ADDR'], which contains the IP of the viewer.
Then you could run
SELECT name FROM 'users' where users.known_ips LIKE '%$ip%' AND users.loggedin = 0 ORDER BY lastlogin DESC LIMIT 1;
('%' represents 0 or more characters. It's a wildcard.) And then you could use
mysqli_stmt_bind_results($ipquery,$name);
mysqli_stmt_fetch($ipquery);
# Now $name = first username found
This method will get their name if they have ever used that computer to log in.

Categories