Prevent the same url occuring - php

I have tried to get a cleaner URL by adding a .htaccess file to my directory. However I have stumbled upon a small problem which I haven't been able to figure out yet how to solve. I provide an opportunity for my members to post content on my website. When posting the content, the title is saved and modified to be used to get a cleaner URL. For example
/dir/post.php?id=362 with the title [Hello friends] becomes ->
/dir/Hello-friends
My problem is how can I prevent that the same URL gets produced over and over again. I want that the following URLs with the same title, to get something added to it, like a number. For example
/dir/Hello-friends (The first post)
/dir/Hello-friends-2 (The second post, but here a number is added).
This is my php code
$conn = new mysqli($servername, $username, $password, $dbname);
if (mysqli_connect_error()) {
die("Database connection failed: " . mysqli_connect_error());
}
function php_slug($string)
{
$slug = preg_replace('/[^a-z0-9-]+/', '-', trim(strtolower($string)));
return $slug;
}
$title = mysqli_real_escape_string($conn,$title1);
$text1 = mysqli_real_escape_string($conn,$text0);
$text2 = mysqli_real_escape_string($conn,$text00);
$text3 = mysqli_real_escape_string($conn,$text000);
$text4 = mysqli_real_escape_string($conn,$text0000);
$text5 = mysqli_real_escape_string($conn,$text00000);
$text6 = mysqli_real_escape_string($conn,$text000000);
$pid = $_POST['pid'];
$post_title = $title;
$post_title = htmlentities($title);
$sql_titel = "SELECT post_title FROM posts WHERE title = '$title'";
$result_titel = mysqli_query($con, $sql_titel);
$resultsFound = mysqli_num_rows($result_titel);
if ($resultsFound > 0) {
$resultsFound++;
$post_title .= '-'.$resultsFound;
}
$sql = "INSERT INTO posts (title, text1, text2, text3, text4, text5, text6, post_title, pid)
VALUES ('$title', '$text1', '$text2', '$text3', '$text4', '$text5', '$text6', '".php_slug($post_title)."', '$pid')";
if ($conn->query($sql) === TRUE) {
echo "<script>alert('controlling post...!')</script>";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
}

If you want to add a random number:
if($_POST['submit']) {
$post_title = $title;
$post_title = htmlentities($title);
$sql_titel = "SELECT post_title FROM posts WHERE post_title = '$post_title'";
$result_titel = mysqli_query($con, $sql_titel);
if(mysqli_num_rows($result_titel) > 0) {
$post_title = $post_title . '-' . mt_rand(1, 1000);
}
}

A simple extension to your code is to use the number of rows returned, like this:
if($_POST['submit']) {
$post_title = htmlentities($title);
// !!! You should use parameterized queries here !!!
$sql_titel = "SELECT post_title FROM posts WHERE title = '$title'";
$result_titel = mysqli_query($con, $sql_titel);
// Using the number of rows returned as our collision ID:
$sameNameID = mysqli_num_rows($result_titel);
if ($sameNameID > 0) {
// Bump it up by 1 (so we essentially get 0,2,3,4,5..):
$sameNameID++;
// Add it to the post title:
$post_title .= '-'.$sameNameID;
}
}
Importantly, notice that it's checking the title field rather than post_title.
Also be aware that you're probably vulnerable to SQL injection. I.e. a random person on the internet could do whatever they want to your database. htmlentities does not protect you from injection. You should use PDO instead.
But having said that, you might want to take inspiration from websites like StackOverflow itself, where a number (the article ID) is always present in the URL.
In StackOverflow's case, it's the ID which actually routes the request - this makes it possible to change the question (or title, in your case) later. For example, all of these link to this question:
https://stackoverflow.com/questions/41537052/
https://stackoverflow.com/questions/41537052/prevent-the-same-url-occuring
https://stackoverflow.com/questions/41537052/prevent-the-same-url-occuring-renamed

Related

How to dynamically display links in web pages using PHP

Good day # all.
I've this code snippet which's aim is to display the Exam this user is qualified to take based on the courses registered for. It would display the Exam Name, Date Available, Passing Grade and either Take Exam link if he/she hasn't written or View Result if he/she has written previously.
/*Connection String */
global $con;
$user_id = $_SESSION['user_id']; //user id
$courses = parse_course($user_id); //parse course gets the list of registered courses (Course Codes) in an array
foreach ($courses as $list)
{
$written = false;
$list = parse_course_id($list); //parse_course_id gets the id for each course
$ers = mysqli_query($con, "Select * from exams where course_id = '$list'");
while ($erows = mysqli_fetch_assoc($ers)) {
$trs = mysqli_query($con, "Select * from result_data where user_id = '$user_id'");
while ($trows = mysqli_fetch_assoc($trs)) {
if ($trows['user_id'] == $user_id && $trows['exam_id'] == $erows['exam_id'])
$written = true;
else
$written = false;
}
if($written)
{
echo "<tr><td>".$erows['exam_name']."</td><td>".$erows['exam_from']." To ".$erows['exam_to']."</td><td>".$erows['passing_grade']."%</td><td>".'View Result '."</td></tr>";
$written = false;
}
else
{
echo "<tr><td>".$erows['exam_name']."</td><td>".$erows['exam_from']." To ".$erows['exam_to']."</td><td>".$erows['passing_grade']."%</td><td>".'Take Exam '."</td></tr>";
$written = false;
}
}
}
But It only displays one View Result entry even if I've taken more than one exam. It shows the recent entry. Please what am I missing?
Untested, but here's how I would do it.
I've assumed $user_id is an integer. I'm a bit worried about it being used in SQL without any sanitization. I can't guarantee anything else you're doing is secure either because I can't see your other code. Please read: http://php.net/manual/en/security.database.sql-injection.php
(Oh I see someone already commented on that - don't take it lightly!)
Anyway, my approach would be to collect the user's written exam IDs into an array first. Then loop through the available exams and check each exam id to see if it's in the array we made earlier.
I wouldn't bother looking into the join advice unless you find this is performing poorly. In many systems it would be common to have 3 functions in this situation, one that generates $users_written_exam_ids ones that pulls up something like $all_available_exams and then this code which compares the two. But because people are seeing both queries here together there is a strong temptation to optimize it, which is cool but you probably just want it to work :)
<?php
global $con;
// Get the user id. Pass through intval() so no SQL injection is possible.
$user_id = intval($_SESSION['user_id']);
// Parse course gets the list of registered courses (Course Codes) in an array
$courses = parse_course($user_id);
foreach ($courses as $list)
{
// Gets the id for each course
$list = parse_course_id($list);
$users_written_exam_ids = array();
$trs = mysqli_query($con, "SELECT exam_id FROM result_data WHERE user_id = '$user_id'");
while ($trows = mysqli_fetch_assoc($trs))
{
$users_written_exam_ids[] = $trows['exam_id'];
}
$ers = mysqli_query($con, "SELECT * FROM exams WHERE course_id = '$list'");
while ($erows = mysqli_fetch_assoc($ers)) {
echo '<tr><td>' . $erows['exam_name'] . '</td><td>' . $erows['exam_from']
. ' To ' . $erows['exam_to'] . '</td><td>' . $erows['passing_grade']
. '%</td><td>';
if (in_array($erows['exam_id'], $users_written_exam_ids))
{
echo 'View Result';
}
else
{
echo 'Take Exam';
}
echo '</td></tr>';
}
}

GET ID after submitting form

Im trying to get the ID when I insert a SQL, I've tried to get the last. I've tried to echo out the ID in the hidden html form but without any success
As you see I've $sql that inserts INTO log_create, but from that I need to receive the ID which is created, it need to be echoed
$id = $db->real_escape_string(trim($_POST['id']));
$name2 = preg_replace('/\s+/', '', $name);
$game = $db->real_escape_string(trim($_POST['game']));
$info = $db->real_escape_string(trim($_POST['info']));
$mobname = $db->real_escape_string(trim($_POST['mobname']));
$sql = "INSERT INTO log_create(`id`, `name`, name2, game, monster, info)VALUES('$id', '$name', '$name2', '$game', '$mobname', '$info')";
if($result=$db->query($sql))
{
$log = $db->query("SELECT itemname FROM `log_mitem` WHERE mobname = '".$mobname."' AND game = '".$game."'") or die($db->error);
if($log1 = $log->fetch_object());
{
while($loco = $log->fetch_object())
{
$item = "$loco->itemname";
$logss = "INSERT INTO log_drops(`item`, `mobname`, `game`, `log_id`, `log_name`)VALUES('$item', '$mobname', '$game', '$id', '$name')";
if($result1 = $db->query($logss));
}
}
echo '<p>';
echo 'Your droplog has been created! Check your droplog category to start hunting!';
echo '</p>';
} else { echo 'Something went wrong!';
}
Thismay help you, maybe?
Good luck! :-)
EDIT: My bad, I should have said what was that, instead of linking directly.
It's the mysqli::$insert_id variable.
It stores the last ID created by the last used "INSERT" sentence.
...
if($result=$db->query($sql))
{
echo "New ID: "+$db->insert_id+"<br />";
...
Or wherever you want to use it.
Make sure to store it before inserting anything else, or it'll be replaced.

Create titles in MYSQL from h1 tags of post (WordPress)

I imported a site to Wordpress that has no titles associated to posts. Each post does have h1 tags...
Can anyone tell me the best way to go into MYSQL and write some script to auto generate the titles of each post based on the h1 tags of each???
When final I need to be able to see these titles in the post section of the WordPress dashboard.
Below Is the code based on your responses Andrew. I created a file called createtiles.php and included it in my rrot directory. Not sure whats going on but when i look at my Post section in WordPress dashboard I still see (No Title).
<?php
$link = mysql_connect('localhost', 'user', 'pass');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
$all_posts = mysql_connect("SELECT * FROM wp_posts");
while ($item = mysql_fetch_assoc($all_posts))
{ $pid = $item['post_id'];
$new_title = substr($item['post_content'],0,70);
mysql_query("UPDATE wp_posts SET post_title='".$new_title."'");
}
mysql_close($link);
?>
(Some of my post only have h1 tags with no other content. )
Well, just a quick rough draft without doing much of any of the work for you.
$title = mysql_fetch_assoc(mysql_query("SELECT post_content, post_title, post_id FROM wp_posts");
foreach($title as $final_title) {
$post_id = $final_title['post_id'];
$post_content = $final_title['post_content'];
$final_content = '<h1>'.$final_title['post_title'].'</h1><br /><br />'.$post_content;
$q = mysql_query("UPDATE wp_posts SET post_content='".$final_content."'");
}
And that's all she wrote. I didn't do much of the work for you, but it definitely is the way to go. Vote Up.
Please do not pay attention to my other answer. It is backwards to what you want.
You need to use http://us2.php.net/substr method to grab a certain amount of characters from your title. I would grab that first 26 letters from your post and then update the titles.
What you need to do is something like this.
$all_posts = mysql_query("SELECT * FROM wp_posts");
while ($item = mysql_fetch_assoc($all_posts)) {
$pid = $item['post_id'];
$new_title = substr($item['post_content'],0,26);
mysql_query("UPDATE wp_posts SET post_title='".$new_title."'");
}
Now that's all she wrote. ;)

Show blob file(text + img) in website. From phpbb database

I have a phpbb forum and I want to show the latest 3 post in my website. I can connect to the DB and retrieve what I want but not img from post. Post content is stored as Blob, when I do a post looks like:
"Hello this is a test post.
[img]http://www.petfinder.com/wp-content/uploads/2012/11/101418789-cat-panleukopenia-fact-sheet-632x475.jpg[/img]
End of the file."
In the forum you can see the text and the image. But when I show the post in my website it looks like:
(Hello this is a test post. [img:3vv18at0]http://www.petfinder.com/wp-content/uploads/2012/11/101418789-cat-panleukopenia-fact-sheet-632x475.jpg[/img:3vv18at0]End of the file.)
Show the entery post as text, I would like to see the post as in the forum, text and images in their places.
This is the code I am using:
<?php
$conexion = mysql_connect("localhost","MYUSER","MYPASS");
$nPost = "0,3";
//DB a la que me conecto
mysql_select_db("DATABASE", $conexion) OR die("No se puede establecer la conexión a MySQL");
$consulta1 = "SELECT * FROM phpbb_topics WHERE forum_id = '4' ORDER BY topic_id DESC LIMIT $nPost";
$resultado1 = mysql_query($consulta1);
$consulta2 = "SELECT * FROM phpbb_posts WHERE forum_id = '4' ORDER BY topic_id DESC LIMIT $nPost";
$resultado2 = mysql_query($consulta2);
while ($row = mysql_fetch_array($resultado1)) {
$datosPost = mysql_fetch_array($resultado2);
$id = "$row[topic_id]";
$titulo = "$row[topic_title]";
$respuestas = "$row[topic_replies]";
$by = "$row[topic_first_poster_name]";
$text = "$datosPost[post_text]";
///////////////////EDIT AND WORKING//////////////////
$b = preg_replace('#\[img:(.*?)\](.*?)\[/img:(.*?)\]#s', '<br><img src="$2"/><br> ', $text);
$c = preg_replace('#\((.*?)\)#s', '$1', $b);
$text = $c;
////////////////////////THANKS TO damienkeitel//////////////
echo"<a href='http://www.compraclientes.com/foro/viewtopic.php?f=4&t=$id'><div class='postEntry'><div class='postHeader'><div class='postTitle'>$titulo</div><div class='postOwner'>(By $by)</div> <div class='postReplies'>($respuestas Respuestas)</div></div><div class='postText'>($text)</div></div></a>";
}
mysql_close($conexion);
?>
Thank you very much
$a = "(Hello this is a test post. [img:3vv18at0]http://www.petfinder.com/wp-content/uploads/2012/11/101418789-cat-panleukopenia-fact-sheet-632x475.jpg[/img:3vv18at0]End of the file.)";
$b = preg_replace('#\[img:(.*?)\](.*?)\[/img:(.*?)\]#s', '<br><img src="$2"/><br> ', $a);
$c = preg_replace('#\((.*?)\)#s', '$1', $b);
echo $c;
http://www.damienkeitel.com/pr.php <-- demo
I believe one of my previous answers, slightly modified, can provide you with information you need.
Display the 5 most recent posts on an external page
The short answer to your question is this chunk of code. This will clean up various aspects of your data.
$topic_title = $posts_row['topic_title'];
$post_author = get_username_string('full', $posts_row['poster_id'], $posts_row['username'], $posts_row['user_colour']);
$post_date = $user->format_date($posts_row['post_time']);
$post_link = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "p=" . $posts_row['post_id'] . "#p" . $posts_row['post_id']);
$post_text = nl2br($posts_row['post_text']);
$bbcode = new bbcode(base64_encode($bbcode_bitfield));
$bbcode->bbcode_second_pass($post_text, $posts_row['bbcode_uid'], $posts_row['bbcode_bitfield']);
$post_text = smiley_text($post_text);
As I mention in the previous answer, that code is based on Example 4 the PHPBB Wiki.

table updates empty spaces when user do not enter anything to the textbox

i am doing a project where one may update the name, position, department and tag of the employee.
But as i do my project, it wont update, i know there is something wrong with my code. would you guys mind checking it.
my php page has an index.php which is the main menu, if you click the employee name in the list, a pop up window will appear. that pop up is for updating.
my php code (it now updating) but errors found:
<?php
$con=mysql_connect('localhost','root','pss') or die(mysql_error());
mysql_select_db('intra',$con);
if(isset($_POST['submitted']))
{
$sql = "SELECT * FROM gpl_employees_list where emp_id='".$_POST['eid']."'";
$result = mysql_query($sql) or die (mysql_error());
if(!$result || mysql_num_rows($result) <= 0)
{
return false;
}
$qry = "UPDATE gpl_employees_list SET emp_nme = '".$_POST['ename']."', emp_pos = '".$_POST['pos']."', emp_dep = '".$_POST['dep']."', emp_tag = '".$_POST['tag']."' WHERE emp_id = '".$_POST['eid']."' ";
mysql_query($qry) or die (mysql_error());
?><script>window.close();</script><?php
}
?>
*NOTE : this is now updating, but if a user leaves one of the textboxes empty, it updates the table with empty spaces as well and that is my problem now. how do i avoid that? i mean if a user leaves one textbox empty,the data with empty values must still contain its old value,but how to do that with this code? thanks for those who will help
MisaChan
You use $_POST for 'name/pos/dep/tag' and $_GET for 'emp' so you're probably not getting the values.
Change the GETs to POST - that should do it.
Since you're updating, I'd recommend using POST over GET.
GET is more appropriate for searching.
Also, you can put all your update queries into one update query.
Like so.
$name = $_POST['name'];
$pos = $_POST['pos'];
$dep = $_POST['dep'];
$tag = $_POST['tag'];
$emp = $_POST['emp'];
$qry_start = "UPDATE gpl_employees_list SET ";
$where = " WHERE emp_id = $emp";
$fields = "";
$updates = "";
if($name){
$updates .= " `emp_name` = $name,";
}
if($pos){
$updates .= " `emp_pos` = $pos,";
}
if($dep){
$updates .= " `emp_dep` = $dep,";
}
if($tag){
$updates .= " `emp_tag` = $tag,";
}
$updates = substr($updates, 0, -1); //To get rid of the trailing comma.
$qry = $qry_start . $updates . $where;
this is what i used to keep it working :) i hope this could be a source for others as well :)
$col['emp_nme'] = (trim($_POST['ename']))?trim($_POST['ename']):false;
$col['emp_pos'] = (trim($_POST['pos']))?trim($_POST['pos']):false;
$col['emp_dep'] = (trim($_POST['dep']))?trim($_POST['dep']):false;
$col['emp_tag'] = (trim($_POST['tag']))?trim($_POST['tag']):false;
// add a val in $col[] with key=column name for each corresponding $_POST val
$queryString ="UPDATE `gpl_employees_list` SET ";
foreach($col as $key => $val){
if($val){
$queryString .="`".$key."`='".$val."',";
}
}
$queryString = substr($queryString ,0 ,strlen($queryString) - 1 )." WHERE emp_id = '".$_POST['eid']."'";
mysql_query($queryString);
After making changes to an SQL database, remember to commit those changes, otherwise they'll be ignored.

Categories