I have a textarea where I can enter the content:
<textarea name="content" placeholder="Content"></textarea>
The type of the content column in the DB is Text.
So I could add text there and then insert that text to the DB:
$stmt = $conn->prepare('INSERT INTO content VALUES(?)');
$stmt->execute( [$content] );
Then I show that content some where on my website:
$stmt = $conn->prepare('SELECT content FROM posts');
$stmt->execute();
$results = $stmt->fetchAll();
foreach( $results as $result ){
echo '<div>'. $result .'</div>';
}
But that content is then showed as a plain text, So if I entered:
$content = "This content contains a URL http://example.com";
I get: This content contains a URL http://example.com, So the link is not shown as a link, But a plain text.
Also if I added an image:
$content = "http://example.com/images/img.jpg";
Or a video:
$content = "http://example.com/images/video.mp4";
Or a video from Youtube.
So what should I do?
Should I use PHP or Javascript to check if the content contains a URL/image/video, Then add the related html elements to that URL?
I would not recommend using an editor like CKEditor just to wrap some URLs in markup, as others have shockingly suggested. That is a very lazy and expensive (not necessarily price but size of files and number of requests) way of solving a simple task.
The following solution is untested and the regex patterns were taken from external sources, so I unfortunately can't guarantee their correctness. Try it yourself and test, test, test.
EXAMPLE
// your string
$content = "This is the content https://example.com/images/image1.jpg";
// find all URLs in $content and add matches to $matches array
$regex = "#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#";
preg_match_all($regex, $content, $matches);
// loop through $matches array
foreach ($matches as $match) {
// check each item in array and use regex to determine type
if (preg_match('/\.(jpg|jpeg|png|gif)(?:[\?\#].*)?$/i', $match)) {
$markup = '<img src="'.$match.'">';
} else {
$markup = ''.$match.'';
}
// now replace the $match'ed URL in $content with the right $markup
str_replace($match, $markup, $content);
}
DOCS
preg_match_all: http://php.net/manual/en/function.preg-match-all.php
preg_match: http://php.net/manual/en/function.preg-match.php
str_replace: http://php.net/manual/en/function.str-replace.php
Related
I'm a 'newbie' on stackoverflow but it is a source that I keep coming to regularly for tips.
I've picked up some code from the simple.html file accompanying the jsPDF auto-table plug-in but as it doesn't appear to pick up data from a php generated table.
I am trying to get the data into a format that can be transformed into a nice pdf report - 'with all the trimmings' - ie; page-breaks, headers on each page, alternate row-colours etc.
I've tried to get the data into a form that can be used by the jsPDF autotable but I'm going wrong in that it is just going through the array and keeping the last record and printing that in pdf format. Code shown below.
<button onclick="generate()">Generate pdf</button>
<script src="/js//jspdf.debug.js"></script>
<script src="/js/jspdf.plugin.autotable.js"></script>
<?php
$link = mysqli_connect('localhost','user','password','database');
if(!$link)
{
echo 'Database Error: ' . mysqli_connect_error() ;
exit;
}
$results=array();
$sql_staff = "SELECT staff_id, staff_firstname, staff_lastname, staff_username, staff_chargerate, staff_lastlogin FROM tblstaff ORDER BY staff_lastname ASC, staff_firstname ASC ";
$result_staff = mysqli_query($link,$sql_staff);
while($row = mysqli_fetch_array($result_staff)){
$results[0] = $row['staff_id'];
$results[1] = $row['staff_firstname'] . " " . $row['staff_lastname'];
$results[2] = $row['staff_username'];
$results[3] = $row['staff_chargerate'];
$results[4] = $row['staff_lastlogin'];
echo json_encode($results);
$data = json_encode($results);
}
?>
<script>
function generate() {
var head = [["ID", "Staff Name", "Username", "Charge-rate", "Last Log-in"]];
var body = [
<?echo $data;?>
];
var doc = new jsPDF();
doc.autoTable({head: head, body: body});
doc.output("dataurlnewwindow");
}
</script>
I think that the problem lays around the line $data = json_encode($results); but I don't know enough about either PHP or Javascript to determine how the code needs to be altered to produce a full PDF report. Can anyone assist please?
Your issue is probably related to overwriting the values in the $results array which means you will get one item instead of an array of items. You probably want something like this:
$results = array();
while($row = mysqli_fetch_array($result_staff)){
$dataRow = array();
array_push($dataRow, $row['staff_id']);
array_push($dataRow, $row['staff_firstname'] . " " . $row['staff_lastname']);
// etc
array_push($results, $dataRow);
}
$data = json_encode($results);
I want to ask advice from you guys since I have a problem of showing html tags within table structure.
Actually, I want to show is "link".
To be clear I will explain you more details.
I am making auto generated table structure view with the help of javascript and jquery that shows data from database and want to show these data as table structure which also include the link that allows user to edit the data. That's it.
See the below image:
As you can see, links are showing as normal characters.
So anyone who knows the answer please advice me.
Below is the code:
//php
$sql = "SELECT * FROM v_category";
$dbaction = new db_action($sql,'G');
$result = $dbaction->db_process();
$dataRows = "Category Name|Remark|Edit|";
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$ctgr_id = $row["ctgr_id"];
$ctgr_name = $row["ctgr_name"];
$remark = $row["remk"];
$link = "<a href='?cv=ms-category&mode=2&id=$ctgr_id'>link</a>";
$dataRows = $dataRows . "**row**" . $ctgr_name . "|";
$dataRows = $dataRows . $remark . "|";
$dataRows = $dataRows . $link;
}
} else {
echo "0 results";
}
echo '<div id="draw-grid" class="tbl-responsive" style="overflow-x:auto;"><script>DrawTable("draw-grid","'.$dataRows.'");</script></div>';
//javascript
function DrawTable(Container,dataRows)
{
dataRows = dataRows.split(ROW_SPLITTER);
var tTable=$('<table>');
//draw the table header
tTable.append(drawHeader(dataRows[0]));
//draw the table body
tTable.append(drawBody(dataRows));
//add table to wrapper container first and then add into the parent container
$('<div>').append(tTable)
.appendTo($('#'+Container));
return;
}
function drawHeader(headerRow)
{
var headerRowColumns = headerRow.split("|");
var tblRow=$('<tr>');
headerRowColumns.forEach(function(element,index) {
$('<th>')
.text(element)
.appendTo(tblRow);
});
return $('<thead>').append(tblRow);
}
function drawBody(objRows)
{
var tBody=$('<tbody>');
objRows.forEach(
function(objRow,index)
{
if(index!=0)
{
tBody.append(drawBodyRow(objRow,index));
}
});
return tBody;
}
function drawBodyRow(bodyRow,rowIndex)
{
var bodyRowColumns = bodyRow.split("|");
var tRow=$('<tr>');
bodyRowColumns.forEach(function(element,columnIndex)
{
$('<td>').text(element).appendTo(tRow);
});
return tRow;
}
$('<td>').text(element).appendTo(tRow);
In this line and others like it, you're setting the inner text of the matched elements to be a value.
This is actually a good thing in almost all cases. You don't want to be interjecting arbitrary HTML into a context where a text value is intended. Otherwise, you open up yourself to potential security issues, or at least, invalid HTML.
What you should be doing instead, if you really intend to inject HTML, is to append those elements to this one.
Your code has other problems too...
$link = "<a href='?cv=ms-category&mode=2&id=$ctgr_id'>link</a>";
In this line, you're interpolating arbitrary data into a URL and into HTML, with nothing being escaped. Use http_build_query() to escape the data for the query string. Then, be sure to use htmlspecialchars() for any arbitrary data injected into HTML to ensure it's escaped for that context.
Im trying to change the_title() for my wordpress website page, however it changes all the text and I only what to change 'ORDER' to 'QUOTE' and leave the order number '#3344'. Could anyone help me with my if statement.
<?php
// Changeing Order title to quote
$page_id = get_the_ID();
if($page_id == '49')
{
$original_title = get_the_title();
$new_title = str_replace("ORDER","QUOTE","ORDER");
echo $new_title;
}
else {
the_title();
}
?>
Please have a close look at the docs. However - you have to use the wp_title() function:
Example code:
wp_title( string $sep = '»', bool $display = true, string $seplocation = '' )
Parameters:
$sep (string) (Optional) default is '»'. How to separate the various items within the page title.
$display (bool) (Optional) Whether to display or retrieve title.
(string) (Optional) Direction to display title, 'right'.
I'm pretty sure wp_title will do the job right :)
Some more information you can find here: !! hit me !!
I have a feature, where users can post thoughts and users can add comments to each thought The way it works is that, when the comments link is clicked, all comments associated with that thought_id will be loaded.
Here is the structure of my user_comments table:
id
body_of_msg
comment_posted_by
comment_posted_to
post_id (which is the id of a thought from the `user_thoughts` table)
Consider the following data:
user_thoughts table (1 row):
id: 184
thought: "hello, this is a thought from anderson."
Assume I have two rows in the user_comments table:
id: 1
body_of_msg: Comment assigned to thought_id of 184
comment_posted_by: conor
comment_posted_to: anderson
post_id: 184
id: 2
body_of_msg: Another comment assigned to thought_id of 184
comment_posted_by: alice
comment_posted_to: anderson
post_id: 184
Problem: At the moment, when I click the comments link, only one of the comments is being shown (the latest comment is being shown, so in this case, Alice's comment).
Here is the code:
<?php
// Get the comments attached to a users post...
$get_comm = mysqli_query ($connect, "SELECT * FROM user_comments WHERE post_id='$thought_id' ORDER BY post_id DESC");
$num_of_comments = mysqli_num_rows($get_comm); // get number of comments for each post by post_id
// if there are comments for the post, get its content
if ($num_of_comments !=0 || $num_of_comments == 0){
while( $comment = mysqli_fetch_assoc ($get_comm)){
$comment_body = $comment['body_of_msg'];
$comment_posted_to = $comment['comment_posted_to'];
$comment_posted_by = $comment['comment_posted_by'];
$removed = $comment['comment_removed'];
}
echo "";
/** There are other divs and content echo'd here**/
////////////////////////////////////////////
// this is where each comment is displayed
echo "
<div id='toggleComment$thought_id' class='new_comment' style='display:none;'>
<br/><b><a href = 'profile_page/$comment_posted_by'> $comment_posted_by said</a></b>: $comment_body "; ?><?php
if ($comment_posted_by == $username){
echo "<a id='remove_comment' href = '/inc/remove_comment.php'> Delete </a>";
} echo "
</div>";
/////////////////////////////////////////////
}
?>
Where $thought_id comes from:
$count = mysqli_query ($connect, "SELECT * FROM user_thoughts");
while ($row = mysqli_fetch_assoc($get_thoughts_from_db)) {
$thought_id = $row['id'];
}
What I think:
This could just be me struggling to find a solution, but, could it be that each comment is overlapping the other? My comment feature involved comments dynamically appearing below the thought, so I have utilized Javascript, to achieve this. Just thinking the block may be getting replaced by a new comment?
What I have tried:
while( $comment = mysqli_fetch_assoc ($get_comm)){
$comment_body = $comment['body_of_msg'];
$comment_posted_to = $comment['comment_posted_to'];
$comment_posted_by = $comment['comment_posted_by'];
$removed = $comment['comment_removed'];
// this is where each comment is displayed
echo "
<div id='toggleComment$thought_id' class='new_comment' style='display:none;'>
<br/><b><a href = 'profile_page/$comment_posted_by'> $comment_posted_by said</a></b>: $comment_body "; ?><?php
if ($comment_posted_by == $username){
echo "<a id='remove_comment' href = '/inc/remove_comment.php'> Delete </a>";
} echo "
</div>";
}
}
This still only shows one comment, when there are two to be shown.
Why don't you use ajax? I had done a site web that use comments (like stackoverflow) and I used a lot ajax for that. Of course, all the creations of html elements will be done in js and what you will return from php will be only json (containing the content of comments and its info).
This will help you also to load new comments without refreshing the page (setInterval).
For the answer, I have find three things that are strange, the first one is
if ($num_of_comments !=0 || $num_of_comments == 0){
which will be always true. The second thing is the fact that the echo is outside the while bloc (this probably the cause of having one comment echoed). The last thing is display none that you put in the style of the html element. So what I suggest you is to make the echo in the while block or to make an array of comments and make an iterator. After that, try to use the inspector tool of your browser to see if the code source returned contain only one comment or more. This will help you to see if the php works or not.
I'm trying to get a quantity value from external link, but I can't see this value until particular colour or size is selected (selection on that website works using JavaScript void(0) ).
Is it possible to trigger a link somehow and get the value after? Any suggestions?
However I know how to get a static value from url, see below:
$url = 'http://www.website.com/page.html';
$content = file_get_contents($url);
$first_step = explode( '<span id="quantity">' , $content );
$second_step = explode("</span>" , $first_step[1] );
echo $second_step[0];
Maybe solution, you can to split the process into two parts :
get all elements with regexp
preg_match_all('/<span [^>]+>/i',$content , $match);
print_r($match);
search attrs array of the result
$spans = array();
foreach( $match as $tag)
{
preg_match_all('/(id)=("[^"]*")/i',$tag, $spans[$tag]);
}
print_r($spans);