jqGrid integrated toolbar search not working - php

I am trying to get the integrated search toolbars working on my page, however I am not having any luck. The regular search function is working for me, but whenever I type anything into the integrated toolbars, it returns 0 results.
Here is my jquery:
$("#parts_table").jqGrid({
url:'testparts2.php',
datatype: "json",
colNames:['Part ID','Name', 'Description', 'Weight'],
colModel:[
{name:'part_ID',index:'part_ID', search: true, stype:'text', width:55},
{name:'part_name',index:'part_name', width:90},
{name:'part_desc',index:'part_desc', width:100},
{name:'part_weight',index:'part_weight', width:80, align:"right"},
],
rowNum:30,
rowList:[10,20,30],
pager: '#pager2',
sortname: 'part_ID',
viewrecords: true,
sortorder: "asc",
caption:"Parts in Database",
width: '800',
height: '300',
});
$("#parts_table").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});
$("#parts_table").jqGrid('filterToolbar',{stringResult: false,searchOnEnter : false, defaultSearch: 'cn', ignoreCase: true});
and here is my PHP code:
<?php
include "begin.php";
$page = $_REQUEST['page']; // get the requested page
$limit = $_REQUEST['rows']; // get how many rows we want to have into the grid
$sidx = $_REQUEST['sidx']; // get index row - i.e. user click to sort
$sord = $_REQUEST['sord']; // get the direction
if(!$sidx) $sidx =1;
//array to translate the search type
$ops = array(
'eq'=>'=', //equal
'ne'=>'<>',//not equal
'lt'=>'<', //less than
'le'=>'<=',//less than or equal
'gt'=>'>', //greater than
'ge'=>'>=',//greater than or equal
'bw'=>'LIKE', //begins with
'bn'=>'NOT LIKE', //doesn't begin with
'in'=>'LIKE', //is in
'ni'=>'NOT LIKE', //is not in
'ew'=>'LIKE', //ends with
'en'=>'NOT LIKE', //doesn't end with
'cn'=>'LIKE', // contains
'nc'=>'NOT LIKE' //doesn't contain
);
function getWhereClause($col, $oper, $val){
global $ops;
if($oper == 'bw' || $oper == 'bn') $val .= '%';
if($oper == 'ew' || $oper == 'en' ) $val = '%'.$val;
if($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') $val = '%'.$val.'%';
return " WHERE $col {$ops[$oper]} '$val' ";
}
$where = ""; //if there is no search request sent by jqgrid, $where should be empty
$searchField = isset($_GET['searchField']) ? $_GET['searchField'] : false;
$searchOper = isset($_GET['searchOper']) ? $_GET['searchOper']: false;
$searchString = isset($_GET['searchString']) ? $_GET['searchString'] : false;
if ($_GET['_search'] == 'true') {
$where = getWhereClause($searchField,$searchOper,$searchString);
}
$totalrows = isset($_REQUEST['totalrows']) ? $_REQUEST['totalrows']: false;
if($totalrows) {
$limit = $totalrows;
}
$result = mysql_query("SELECT COUNT(*) AS count FROM parts");
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count >0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages) $page=$total_pages;
if ($limit<0) $limit = 0;
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
if ($start<0) $start = 0;
$SQL = "SELECT * FROM parts ".$where." ORDER BY $sidx $sord LIMIT $start , $limit";
$result = mysql_query( $SQL ) or die("Couldn't execute query.".mysql_error());
$response->page = $page;
$response->total = $total_pages;
$response->records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$response->rows[$i]['part_ID']=$row[part_ID];
$response->rows[$i]['cell']=array($row[part_ID],$row[part_name],$row[part_desc],$row[part_weight]);
$i++;
}
echo json_encode($response);
?>
It took me hours of searching to find a PHP example that worked for regular searching (see above), however it doesn't seem to work for the toolbar searching. Can anyone help? Thanks
edit: Here is code from jqGrid's demo folder for using this search, but it appears to be full of errors and I have no idea how to use it for my case. I don't need to specify data type for the searches (they are all varchars, so strings will work fine)..so I think that I can strip out the switch/case part for value conversion. I think I just need to change my original code to use $_REQUEST['filters'] and a foreach loop to build the query, but I'm not that great with PHP so any help is appreciated.
demo code:
$wh = "";
$searchOn = Strip($_REQUEST['_search']);
if($searchOn=='true') {
$searchstr = Strip($_REQUEST['filters']);
$wh= constructWhere($searchstr);
//echo $wh;
}
function constructWhere($s){
$qwery = "";
//['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
$qopers = array(
'eq'=>" = ",
'ne'=>" <> ",
'lt'=>" < ",
'le'=>" <= ",
'gt'=>" > ",
'ge'=>" >= ",
'bw'=>" LIKE ",
'bn'=>" NOT LIKE ",
'in'=>" IN ",
'ni'=>" NOT IN ",
'ew'=>" LIKE ",
'en'=>" NOT LIKE ",
'cn'=>" LIKE " ,
'nc'=>" NOT LIKE " );
if ($s) {
$jsona = json_decode($s,true);
if(is_array($jsona)){
$gopr = $jsona['groupOp'];
$rules = $jsona['rules'];
$i =0;
foreach($rules as $key=>$val) {
$field = $val['field'];
$op = $val['op'];
$v = $val['data'];
if($v && $op) {
$i++;
// ToSql in this case is absolutley needed
$v = ToSql($field,$op,$v);
if ($i == 1) $qwery = " AND ";
else $qwery .= " " .$gopr." ";
switch ($op) {
// in need other thing
case 'in' :
case 'ni' :
$qwery .= $field.$qopers[$op]." (".$v.")";
break;
default:
$qwery .= $field.$qopers[$op].$v;
}
}
}
}
}
return $qwery;
}
function ToSql ($field, $oper, $val) {
// we need here more advanced checking using the type of the field - i.e. integer, string, float
switch ($field) {
case 'id':
return intval($val);
break;
case 'amount':
case 'tax':
case 'total':
return floatval($val);
break;
default :
//mysql_real_escape_string is better
if($oper=='bw' || $oper=='bn') return "'" . addslashes($val) . "%'";
else if ($oper=='ew' || $oper=='en') return "'%" . addcslashes($val) . "'";
else if ($oper=='cn' || $oper=='nc') return "'%" . addslashes($val) . "%'";
else return "'" . addslashes($val) . "'";
}
}
$result = mysql_query("SELECT COUNT(*) AS count FROM invheader a, clients b WHERE a.client_id=b.client_id".$wh);
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count >0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages) $page=$total_pages;
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
if ($start<0) $start = 0;
$SQL = "SELECT a.id, a.invdate, b.name, a.amount,a.tax,a.total,a.note FROM invheader a, clients b WHERE a.client_id=b.client_id".$wh." ORDER BY ".$sidx." ".$sord. " LIMIT ".$start." , ".$limit;
$result = mysql_query( $SQL ) or die("Could not execute query.".mysql_error());
$responce->page = $page;
$responce->total = $total_pages;
$responce->records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$responce->rows[$i]['id']=$row[id];
$responce->rows[$i]['cell']=array($row[id],$row[invdate],$row[name],$row[amount],$row[tax],$row[total],$row[note]);
$i++;
}
//echo $json->encode($responce); // coment if php 5
echo json_encode($responce);

I actually just had this same problem myself yesterday. You are correct, you need to bring in the filters using $_REQUEST['filters'] and then break it up so that you can use each piece.
First, you are going to need to set stringResult: true in your jQuery file where you initialize the FilterToolbar.
Here is the code that PHP will use to bring in, and break up the filters object:
// Gets the 'filters' object from JSON
$filterResultsJSON = json_decode($_REQUEST['filters']);
// Converts the 'filters' object into a workable Array
$filterArray = get_object_vars($filterResultsJSON);
Now that you have $filterArray containing the contents of the filters object, you can now break up the rules object which is contained inside. Basically, there is another array inside the $filterArray which contains the search details if the user tries performing this search across multiple columns in their table - it's called rules.
Here is how I break up the rules object and perform a SELECT query based on the user's input:
// Begin the select statement by selecting cols from tbl
$sql = 'select '.implode(',',$crudColumns).' from '.$crudTableName;
// Init counter to 0
$counter = 0;
// Loop through the $filterArray until we process each 'rule' array inside
while($counter < count($filterArray['rules']))
{
// Convert the each 'rules' object into a workable Array
$filterRules = get_object_vars($filterArray['rules'][$counter]);
// If this is the first pass, start with the WHERE clause
if($counter == 0){
$sql .= ' WHERE ' . $filterRules['field'] . ' LIKE "%' . $filterRules['data'] . '%"';
}
// If this is the second or > pass, use AND
else {
$sql .= ' AND ' . $filterRules['field'] . ' LIKE "%' . $filterRules['data'] . '%"';
}
$counter++;
}
// Finish off the select statement
$sql .= ' ORDER BY ' . $postConfig['sortColumn'] . ' ' . $postConfig['sortOrder'];
$sql .= ' LIMIT '.$intStart.','.$intLimit;
/* run the query */
$result = mysql_query( $sql )
I'm sure you'll have questions, so feel free to ask if you do!

Related

PHP experience system // simple

As a begginer in php programming language i'm playing with the code, working on localhost and i did some little projects.Now i am trying to do an experience system as simple as i can, i am stuck at this part and i don't know what i am doing wrong.Some suggestions?
What i am doing wrong?
The code.
function update_user_xp($user_id, $xp_ammount){
global $db;
$params = array('user_id' => $user_id);
$users = $db->rawQuery("SELECT * FROM users_xp WHERE user_id = ?", $params);
$data = array(
'user_xp_amount' => $xp_ammount + $users[0]['user_xp_amount'],
'user_id' => $user_id
);
$db->where ('user_id', $data['user_id']);
if ($db->update ('users_xp', $data)){
$xpReceived = 'You have received '.$xp_ammount.' points of experience! Have a total of '.$data['user_xp_amount'].' points of experience.';
} else {
$xpReceived = $db->getLastError();
}
return $xpReceived;
}
//update_user_xp(4, 10); // user_id: 4, update with 10 points
function get_user_xp ($user_id){
global $db;
$params = array('user_id' => $user_id);
$user = $db->rawQueryOne ('SELECT * FROM users_xp WHERE user_id=?', $params);
$xp = $user['user_xp_amount'];
return $xp;
}
function xp_need () {
global $db;
$xpBarNeed = $db->rawQuery("SELECT `level`, `expneeded` FROM `experience_level`");
foreach ($xpBarNeed as $key => $value) {
$output[] = $value;
}
return $output;
}
$xpn = xp_need();
$userXP = get_user_xp(4);
for($i = 0; $i < count($xpn); $i++){
if($xpn[$i]['expneeded'] == $userXP)
{
//This part is working well
print 'You are level <b>' . $xpn[$i]['level'].'</b>';
} else {
if ($userXP > $xpn[$i]['expneeded'] && $userXP >= $xpn[$i]['expneeded'])
{
//This is the part that doesn t work,
$diffEXP = $xpn[$i]['expneeded'] -= $userXP;
print 'You need more exp '. $diffEXP.'</br>';
}
}
}
This is how i am seeing in the page.
https://prnt.sc/u7z18u
Please note that my solution is not the best or say a well-optimized solution at the time of writing. I will try to optimize it in the near future. For the time being, you can use this:
<?php
$xpn = xp_need();
$userXP = get_user_xp(4);
$level = 0;
$nextExp = 0;
for ($i = count($xpn) - 1;$i >= 0;$i--)
{
if ($userXP >= $xpn[$i]['expneeded'])
{
$level = $xpn[$i]['level'];
$nextExp = $xpn[$i + 1]['expneeded'];
break;
}
}
$expNeeded = $nextExp - $userXP;
$percentage = round(($userXP/$nextExp) * 100);
echo "Current level: " . $level;
echo "<br/>Exp needed for the next level (" . ($level + 1) . "): " . $expNeeded;
echo "<br/>Exp achieved percentage for the next level: " . $percentage;
?>

PHP Random Name instead of sequence

I have a basic URL shortener script but I am having an issue. Each time I enter a new url to shorten the script just adds the next letter to the database (i.e. http://www.both.com/a then http://www.both.com/b then http://www.both.com/c etc). The problem is I don't want to people to be able to view those links by simply going in sequential order. How can I make it so each new url has a random 6 digit alpha and numerical name created? Also, I wanted to make the alpha both random upper and lower case.
<?php
require 'config.php';
header('Content-Type: text/plain;charset=UTF-8');
$url = isset($_GET['url']) ? urldecode(trim($_GET['url'])) : '';
if (in_array($url, array('', 'about:blank', 'undefined', 'http://localhost/'))) {
die('Enter a URL.');
}
if (strpos($url, SHORT_URL) === 0) {
die($url);
}
function nextLetter(&$str) {
$str = ('z' == $str ? 'a' : ++$str);
}
function getNextShortURL($s) {
$a = str_split($s);
$c = count($a);
if (preg_match('/^z*$/', $s)) { // string consists entirely of `z`
return str_repeat('a', $c + 1);
}
while ('z' == $a[--$c]) {
nextLetter($a[$c]);
}
nextLetter($a[$c]);
return implode($a);
}
$db = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE);
$db->set_charset('utf8mb4');
$url = $db->real_escape_string($url);
$result = $db->query('SELECT slug FROM redirect WHERE url = "' . $url . '" LIMIT 1');
if ($result && $result->num_rows > 0) { // If there’s already a short URL for this URL
die(SHORT_URL . $result->fetch_object()->slug);
} else {
$result = $db->query('SELECT slug, url FROM redirect ORDER BY date DESC, slug DESC LIMIT 1');
if ($result && $result->num_rows > 0) {
$slug = getNextShortURL($result->fetch_object()->slug);
if ($db->query('INSERT INTO redirect (slug, url, date, hits) VALUES ("' . $slug . '", "' . $url . '", NOW(), 0)')) {
header('HTTP/1.1 201 Created');
echo SHORT_URL . $slug;
$db->query('OPTIMIZE TABLE `redirect`');
}
}
}
?>
try something like this :
function generateString($length) {
$alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$alphabetLength = strlen($alphabet);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $alphabet[rand(0, $alphabetLength - 1)];
}
return $randomString;
}
$short = generateRandomString(6);

How can I get more than one GET parameter by using switch/case in php?

I'm pretty new to programming and currently working on a video game database thingy. I'm stuck at a point at which I want to filter my entries with the "GET" method. It all works fine until I want to search after multiple parameters for the main issue is to go through my switch/case statement multiple times. So here's the code:
$columnName = NULL;
$searchValue = NULL;
switch ($_GET) {
case isset($_GET['name']):
$columnName = "games.name";
$searchValue = $_GET['name'];
break;
case isset($_GET['developer']):
$columnName = "developer.name";
$searchValue = $_GET['developer'];
break;
case isset($_GET['device']):
$columnName = "devices.name";
$searchValue = $_GET['device'];
break;
case isset($_GET['company']):
$columnName = "company.name";
$searchValue = $_GET['company'];
break;
case isset($_GET['medium']):
$columnName = "medium.name";
$searchValue = $_GET['medium'];
break;
default:
break;
}
if ($columnName !== null && $searchValue !== null) {
$selectStatement .= " WHERE " . $columnName . " LIKE '%" . $searchValue . "%'";
}
The variable $selectStatement is the selection statement for my database entries, but i thought it would not be helpful to post it in it's entirety.
Thanks in advance.
EDIT:
I'm surprised that I got so many answers after just a few minutes, thank you so much!
But I tried every single of your answers and none is really working for me. For example, if I search for two parameters now, it only recognizes the last one.
In this example
http://localhost/index.php?developer=ubisoft&medium=disc
it only shows me the medium, but not the developer...
switch is not ideal to use for your case.
you can have an IF ELSE condition
if ( isset($_GET['name']) ){
$columnName = "games.name";
$searchValue = $_GET['name'];
}
elseif( isset($_GET['developer']) ) {
$columnName = "developer.name";
$searchValue = $_GET['developer'];
}
elseif(){
}
and so on....
Another way is you can have an array to map your parameter to column name.
$_GET['type'] --> this can be your name, developer, medium, device, company...
$_GET['value'] --> your value for name or developer or medium....
$mapping = [
'name' => 'games.name',
'developer' => 'developer.name',
'device' => 'device.name',
'medium' => 'medium.name'
];
$columnName = $mapping[$_GET['type']];
$searchValue = $_GET['value'];
$selectStatement .= " WHERE " . $columnName . " LIKE '%" . $searchValue . "%'";
You should use if statement for multiple conditions or do not use break statement (not recommended)
Working demo with static GET values: https://eval.in/868873
if ($_GET) {
if( isset($_GET['name']))
{
$columnName[] = "games.name";
$searchValue[] = $_GET['name'];
}
if( isset($_GET['developer']))
{
$columnName[] = "developer.name";
$searchValue[] = $_GET['developer'];
}
if( isset($_GET['device']))
{
$columnName[] = "devices.name";
$searchValue[] = $_GET['device'];
}
if( isset($_GET['company']))
{
$columnName[] = "company.name";
$searchValue[] = $_GET['company'];
}
if( isset($_GET['medium']))
{
$columnName[] = "medium.name";
$searchValue[] = $_GET['medium'];
}
}
Loop through columnName
$selectStatement = '';
if ($columnName !== null && $searchValue !== null) {
$length = count($columnName);
for ($i=0; $i < $length; $i++) {
if ($i == 0)
$selectStatement .= " WHERE " . $columnName[$i] . " LIKE '%" . $searchValue[$i] . "%'";
else
$selectStatement .= " AND " . $columnName[$i] . " LIKE '%" . $searchValue[$i] . "%'";
}
}
echo $selectStatement;
for ?developer=ubisoft&medium=disc
Output:
WHERE developer.name LIKE '%ubisoft%' AND medium.name LIKE '%disc%'
why do you use switch/case statement? It is suitable for searching one occurence of element in your elements set. Just use if statement. It would look like following:
$columns = array();
if(isset($_GET["column1"])) {
$columns []= $_GET["column1"];
}
if(isset($_GET["column2"])) {
$columns []= $_GET["column2"];
}
$columnsString = implode(",", $columns);
// You will get string like "column1,column2"
// And you can make the same thing with your WHERE statements

Warning: Missing argument 2 for feed::getLikes(), called in [...]on line 1497 and defined in [...] on line 3117

There are errors in the lines I mentioned, but I could not figure out what it is.
There is something illogical in this line, but I did not see.
I mentioned the line is a range of places.
Line: 1497
'.(($this->getLikes()) ? '<div class="sidebar-list">'.$LNG['likes'].': <strong>'.$this->getLikes().' '.$LNG['messages'].'</strong></div>' : '').'
Line: 3117
function getLikes($start, $type) {
global $LNG;
// Type 0: Return the likes count
// Type 1: Return the liked posts
if($type) {
if($start == 0) {
$start = '';
} else {
$start = 'AND `likes`.`id` < \''.$this->db->real_escape_string($start).'\'';
}
$query = sprintf("SELECT
`likes`.`id` as `like_id`, `likes`.`post` as `like_post`, `likes`.`by` as `like_by`, `likes`.`time` as `time`,
`messages`.`id` as `id`, `messages`.`message` as `message`, `messages`.`type` as `type`, `messages`.`value` as `value`,
`users`.`username` as `username`, `users`.`first_name` as `first_name`, `users`.`last_name` as `last_name`, `users`.`image` as `image`
FROM `likes`,`messages`,`users` WHERE `likes`.`by` = '%s' AND `likes`.`post` = `messages`.`id` AND `messages`.`uid` = `users`.`idu` AND `messages`.`public` = 1 %s ORDER BY `likes`.`time` DESC LIMIT %s", $this->profile_data['idu'], $start, ($this->per_page + 1));
$getLikes = $this->db->query($query);
// Declare the rows array
$rows = array();
while($row = $getLikes->fetch_assoc()) {
// Store the result into the array
$rows[] = $row;
}
// Decide whether the load more will be shown or not
if(array_key_exists($this->per_page, $rows)) {
$loadmore = 1;
// Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
array_pop($rows);
}
// Start the output
foreach($rows as $value) {
$time = $value['time']; $b = '';
if($this->time == '0') {
$time = date("c", strtotime($value['time']));
} elseif($this->time == '2') {
$time = $this->ago(strtotime($value['time']));
} elseif($this->time == '3') {
$date = strtotime($value['time']);
$time = date('Y-m-d', $date);
$b = '-standard';
}
$output .= '<div class="message-container"><div class="message-content"><div class="message-inner">
'.realName($this->profile_data['username'], $this->profile_data['first_name'], $this->profile_data['last_name']).' '.sprintf($LNG['x_liked_y_post'], '<div class="like_btn like_btn_extended" style="float: none;"><img src="'.$this->url.'/thumb.php?src='.$value['image'].'&w=25&h=25&t=a" /></div>'.realName($value['username'], $value['first_name'], $value['last_name']).'', $this->url.'/index.php?a=post&m='.$value['like_post']).' - <span class="timeago'.$b.'" title="'.$time.'" style="float: none;">'.$time.'</span>
'.((!empty($value['message'])) ? '<div class="like_text_snippet">'.($this->parseMessage(substr($value['message'], 0, 60))).'...</div>' : '').'</div></div></div>';
}
// Display the load more button
if($loadmore) {
$output .= '<div class="message-container" id="more_messages">
<div class="load_more"><a onclick="loadLikes('.$value['like_id'].', \''.$this->profile_data['idu'].'\', \''.$this->profile_data['username'].'\')">'.$LNG['view_more_messages'].'</a></div>
</div>';
}
return $output;
} else {
$query = $this->db->query(sprintf("SELECT count(`likes`.`id`) FROM `likes`,`messages` WHERE `likes`.`by` = '%s' AND `likes`.`post` = `messages`.`id` AND `messages`.`public` = '1'", $this->profile_data['idu']));
// Store the array results
$result = $query->fetch_array();
// Return the likes value
return $result[0];
}
}
The message is clear enough. In definition of function you have:
getLikes($start, $type)
so you need to always pass 2 parameters to the function
Instead of
'.(($this->getLikes()) ? '<div class="sidebar-list">'.$LNG['likes'].': <strong>'.$this->getLikes().' '.$LNG['messages'].'</strong></div>' : '').'
you should have something like that:
'.(($this->getLikes($something1, $something2)) ? '<div class="sidebar-list">'.$LNG['likes'].': <strong>'.$this->getLikes($something1, $something2).' '.$LNG['messages'].'</strong></div>' : '').'

Add a number after a string, if it already exists

I'm working on a script that checks if the url already exists in the database, and if yes adds an additional -1 or -2 etc etc at the end. I found this script
But it 'd need to to check it again after adding-1. Since it may be already existing. How can I do that? I tired i this way
$query = mysql_query("SELECT * FROM posts WHERE url='$url'");
while ( $query ) {
$result = mysql_fetch_assoc($query);
$url = $result['url'];
$urlnew = $result['url'];
$oldurl = $url;
$first = 1;
$separator = '-';
while ( $urlnew == $url ) {
$url = preg_match('/(.+)'.$separator.'([0-9]+)$/', $urlnew, $match);
$urlnew = isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $url.$separator.$first;
$first++;
}
$url = $urlnew;
}
The new code above works just fine. But it checks only once. How can I make it to check untill it dose not exists in the DB?
tried adding a new sql query at the bottom after $url -$urlnew but it only breaks the function.
EDIT
Here's the correct script :D
$query = mysql_query("SELECT * FROM posts WHERE url LIKE '%".$url."%'");
if ( $query ) {
while ( $result = mysql_fetch_assoc($query) ) {
$url = $result['url'];
$urlnew = $result['url'];
$first = 1;
$separator = '-';
while ( $urlnew == $url ) {
preg_match('/(.+)'.$separator.'([0-9]+)$/', $urlnew, $match);
$urlnew = isset($match[2]) ? $match[1].$separator.($match[2] + 1) :$url.$separator.$first;
$first++;
}
}
}
$url = $urlnew;
Your code is likely vulnerable to SQL Injection. You should consider using PDO or MySQLi instead.
Here's an example of how you could do so:
$url = 'www.example.com';
$i = 0;
$max_duplicates = 100;
$query = $pdo->prepare('SELECT COUNT(id) count FROM urls WHERE url=?');
while ($i++ < $max_duplicates) {
$result = $query->execute($url);
if (!$result->fetch(PDO::FETCH_OBJ)->count)
break;
if ($i == 1) {
$url = $url . '-1';
} else {
$n = $i > 10 ? 2 : 1;
$url = substr($url, -$n) . $i;
}
}
Here's what I used for my needs
function checkLink($link, $counter=1){
global $connect;
$newLink = $link;
do{
$checkLink = mysqli_query($connect, "SELECT id FROM table WHERE link = '$newLink'");
if(mysqli_num_rows($checkLink) > 0){
$newLink = $link.'-'.$counter;
$counter++;
} else {
break;
}
} while(1);
return $newLink;
}
$link = 'www.example.com';
$uniquelink = checkLink($link);

Categories