Update MySQL Value Through Img Src Variable Including jQuery - mysql

Thank-you to all who have helped me over the last few days.. Unfortunately I was working so I couldn't get back to you. I have included some code into what I thought would work, but for some reason the below code will not update in my SQL Database. I will provide the code and it's output if someone could please copy the code and see why it's not working... It's really doing my head in! Haha!
(The connection to the MySQL db + table is working fine).
// admin.php
<a href="#" id="chngeHref" /><img src="<?php echo "image.php?url=" . $row[2]; ?>?tid=<?php echo $row[0]; ?>&opn=<?php echo $row[1]; ?>" id="chnge" /></a>
// image.php?url=image.jpg?tid=3&opn=1
I was advised to do it this way to make it easier for me to pass the variables (tid and opn) through the process.
// update.php
$tid = $_GET['tid'];
$opn = $_GET['opn'];
if ($opn == "0") { $opn = "1"; } elseif ($opn == "1") { $opn = "0"; }
mysql_query("UPDATE catalogue SET opn = $opn WHERE tid = $tid ; ");
mysql_close();
// it's just a simple script to change a variable from 1 to 0 or 0 to 1 where tid = a specific number...
I have my jQuery stuff all tucked away in a lovely little file, because there is alot of it...
// navigate.js
$.extend({
getUrlVars: function() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; });
return vars;
}
});
$("#chngeHref").click(function() {
var tid = $.getUrlVars()['tid'];
var opn = $.getUrlVars()['opn'];
$.ajax({
type: "POST",
url: "update.php",
data: "tid="+ tid +"& opn="+ opn,
success: function(){
$('#chnge').fadeTo('slow',0.4);
}
});
});
The .extend code i found on the net which finds the parameter and value of all those in the address line. I THINK this is where my issue might be, because the top code is never actually sending it to the address bar, it's being sent through jQuery to the update.php file.
I can only say thank-you soooo much in advance to anyone who can assist in this.
Phillip.

There are a few issues here bsides the SQL Injection vulnerability Nathan mentions, namely you're POSTing, so you need to use $_POST rather than $_GET to retrieve your variables. Also you have an extra space in the data block, this:
data: "tid="+ tid +"& opn="+ opn,
should be:
data: "tid="+ tid +"&opn="+ opn,
or a bit cleaner using object notation (so it also gets properly encoded):
data { tid: tid, opn: opn },
For the SQL Injection issue, instead of this:
mysql_query("UPDATE catalogue SET opn = $opn WHERE tid = $tid ; ");
At the very least escape the values, like this:
$tid = mysql_real_escape_string($_POST['tid']);
$opn = mysql_real_escape_string($_POST['opn']);
Or, go the parameterized query route, which is what I'd prefer.

Related

how do I change ${....} to black instead of red when I use it within '<div> .......... </div>' in google app script [duplicate]

I know in PHP we can do something like this:
$hello = "foo";
$my_string = "I pity the $hello";
Output: "I pity the foo"
I was wondering if this same thing is possible in JavaScript as well. Using variables inside strings without using concatenation — it looks more concise and elegant to write.
You can take advantage of Template Literals and use this syntax:
`String text ${expression}`
Template literals are enclosed by the back-tick (` `) (grave accent) instead of double or single quotes.
This feature has been introduced in ES2015 (ES6).
Example
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b}.`);
// "Fifteen is 15.
How neat is that?
Bonus:
It also allows for multi-line strings in javascript without escaping, which is great for templates:
return `
<div class="${foo}">
...
</div>
`;
Browser support:
As this syntax is not supported by older browsers (mostly Internet Explorer), you may want to use Babel/Webpack to transpile your code into ES5 to ensure it will run everywhere.
Side note:
Starting from IE8+ you can use basic string formatting inside console.log:
console.log('%s is %d.', 'Fifteen', 15);
// Fifteen is 15.
Prior to Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, nope, that was not possible in javascript. You would have to resort to:
var hello = "foo";
var my_string = "I pity the " + hello;
Prior to Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, no. Although you could try sprintf for JavaScript to get halfway there:
var hello = "foo";
var my_string = sprintf("I pity the %s", hello);
well you could do this, but it's not esp general
'I pity the $fool'.replace('$fool', 'fool')
You could easily write a function that does this intelligently if you really needed to
Complete and ready to be used answer for <ES6:
var Strings = {
create : (function() {
var regexp = /{([^{]+)}/g;
return function(str, o) {
return str.replace(regexp, function(ignore, key){
return (key = o[key]) == null ? '' : key;
});
}
})()
};
Call as
Strings.create("My firstname is {first}, my last name is {last}", {first:'Neo', last:'Andersson'});
To attach it to String.prototype:
String.prototype.create = function(o) {
return Strings.create(this, o);
}
Then use as :
"My firstname is ${first}".create({first:'Neo'});
If you are on >ES6 then you can also do:
let first = 'Neo';
`My firstname is ${first}`;
2022 update: Just use the ES6 Template Literals feature. It's fully supported in practically every browser you'll encounter these days. If you are still targeting browsers like IE11 and lower .. well, my heart goes out to you. The below solution I came up with 5 years ago will still work for you. Also, email me if you want a job that doesn't involve catering to old browsers 👍.
You can use this javascript function to do this sort of templating. No need to include an entire library.
function createStringFromTemplate(template, variables) {
return template.replace(new RegExp("\{([^\{]+)\}", "g"), function(_unused, varName){
return variables[varName];
});
}
createStringFromTemplate(
"I would like to receive email updates from {list_name} {var1} {var2} {var3}.",
{
list_name : "this store",
var1 : "FOO",
var2 : "BAR",
var3 : "BAZ"
}
);
Output: "I would like to receive email updates from this store FOO BAR BAZ."
Using a function as an argument to the String.replace() function was part of the ECMAScript v3 spec. See this SO answer for more details.
If you like to write CoffeeScript you could do:
hello = "foo"
my_string = "I pity the #{hello}"
CoffeeScript actually IS javascript, but with a much better syntax.
For an overview of CoffeeScript check this beginner's guide.
I would use the back-tick ``.
let name1 = 'Geoffrey';
let msg1 = `Hello ${name1}`;
console.log(msg1); // 'Hello Geoffrey'
But if you don't know name1 when you create msg1.
For exemple if msg1 came from an API.
You can use :
let name2 = 'Geoffrey';
let msg2 = 'Hello ${name2}';
console.log(msg2); // 'Hello ${name2}'
const regexp = /\${([^{]+)}/g;
let result = msg2.replace(regexp, function(ignore, key){
return eval(key);
});
console.log(result); // 'Hello Geoffrey'
It will replace ${name2} with his value.
I wrote this npm package stringinject https://www.npmjs.com/package/stringinject which allows you to do the following
var string = stringInject("this is a {0} string for {1}", ["test", "stringInject"]);
which will replace the {0} and {1} with the array items and return the following string
"this is a test string for stringInject"
or you could replace placeholders with object keys and values like so:
var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });
"My username is tjcafferkey on Github"
If you're trying to do interpolation for microtemplating, I like Mustache.js for that purpose.
Don't see any external libraries mentioned here, but Lodash has _.template(),
https://lodash.com/docs/4.17.10#template
If you're already making use of the library it's worth checking out, and if you're not making use of Lodash you can always cherry pick methods from npm npm install lodash.template so you can cut down overhead.
Simplest form -
var compiled = _.template('hello <%= user %>!');
compiled({ 'user': 'fred' });
// => 'hello fred!'
There are a bunch of configuration options also -
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
var compiled = _.template('hello {{ user }}!');
compiled({ 'user': 'mustache' });
// => 'hello mustache!'
I found custom delimiters most interesting.
Simply use:
var util = require('util');
var value = 15;
var s = util.format("The variable value is: %s", value)
Create a method similar to String.format() of Java
StringJoin=(s, r=[])=>{
r.map((v,i)=>{
s = s.replace('%'+(i+1),v)
})
return s
}
use
console.log(StringJoin('I can %1 a %2',['create','method'])) //output: 'I can create a method'
Peace quote of 2020:
Console.WriteLine("I {0} JavaScript!", ">:D<");
console.log(`I ${'>:D<'} C#`)
Maybe
wrt=(s, arr=[])=>{
arr.map((v,i)=>{s = s.replace(/\?/,v);});
return s;
};
a='first var';
b='secondvar';
tr=wrt('<tr><td>?<td></td>?</td><tr>',[a,b]);
console.log(tr);
//or use tr in html(tr), append(tr) so on and so forth
// Use ? with care in s
String.prototype.interpole = function () {
var c=0, txt=this;
while (txt.search(/{var}/g) > 0){
txt = txt.replace(/{var}/, arguments[c]);
c++;
}
return txt;
}
Uso:
var hello = "foo";
var my_string = "I pity the {var}".interpole(hello);
//resultado "I pity the foo"
var hello = "foo";
var my_string ="I pity the";
console.log(my_string, hello)

SQL SELECT query excluding an array of id's for infinite scroll [duplicate]

I have followed help located in this topic: Using infinite scroll w/ a MySQL Database
And have gotten close to getting this working properly. I have a page that is displayed in blocks using jquery masonry, in which the blocks are populated by data from a mysql database. When I scroll to the end of the page I successfully get the loading.gif image but immediately after the image it says "No more posts to show." which is what it should say if that were true. I am only calling in 5 posts initially out of about 10-15, so the rest of the posts should load when I reach the bottom of the page but I get the message that is supposed to come up when there really aren't any more posts.
Here is my javascript:
var loading = false;
$(window).scroll(function(){
if($(window).scrollTop() == $(document).height() - $(window).height()) {
var h = $('.blockContainer').height();
var st = $(window).scrollTop();
var trigger = h - 250;
if((st >= 0.2*h) && (!loading) && (h > 500)){
loading = true;
$('div#ajaxLoader').html('<img src="images/loading.gif" name="HireStarts Loading" title="HireStarts Loading" />');
$('div#ajaxLoader').show();
$.ajax({
url: "blocks.php?lastid=" + $(".masonryBlock:last").attr("id"),
success: function(html){
if(html){
$(".blockContainer").append(html);
$('div#ajaxLoader').hide();
}else{
$('div#ajaxLoader').html('<center><b>No more posts to show.</b></center>');
}
}
});
}
}
});
Here is the php on the page the blocks are actually on. This page initially posts 5 items from the database. The javascript grabs the last posted id and sends that via ajax to the blocks.php script, which then uses the last posted id to grab the rest of the items from the database.
$allPosts = $link->query("/*qc=on*/SELECT * FROM all_posts ORDER BY post_id DESC LIMIT 5");
while($allRows = mysqli_fetch_assoc($allPosts)) {
$postID = $link->real_escape_string(intval($allRows['post_id']));
$isBlog = $link->real_escape_string(intval($allRows['blog']));
$isJob = $link->real_escape_string(intval($allRows['job']));
$isVid = $link->real_escape_string(intval($allRows['video']));
$itemID = $link->real_escape_string(intval($allRows['item_id']));
if($isBlog === '1') {
$query = "SELECT * FROM blogs WHERE blog_id = '".$itemID."' ORDER BY blog_id DESC";
$result = $link->query($query);
while($blogRow = mysqli_fetch_assoc($result)) {
$blogID = $link->real_escape_string($blogRow['blog_id']);
$blogTitle = $link->real_escape_string(html_entity_decode($blogRow['blog_title']));
$blogDate = $blogRow['pub_date'];
$blogPhoto = $link->real_escape_string($blogRow['image']);
$blogAuthor = $link->real_escape_string($blowRow['author']);
$blogContent = $link->real_escape_string($blogRow['content']);
//clean up the text
$blogTitle = stripslashes($blogTitle);
$blogContent = html_entity_decode(stripslashes(truncate($blogContent, 150)));
echo "<div class='masonryBlock' id='".$postID."'>";
echo "<a href='post.php?id=".$blogID."'>";
echo "<div class='imgholder'><img src='uploads/blogs/photos/".$blogPhoto."'></div>";
echo "<strong>".$blogTitle."</strong>";
echo "<p>".$blogContent."</p>";
echo "</a>";
echo "</div>";
}
}
Here is the php from the blocks.php script that the AJAX calls:
//if there is a query in the URL
if(isset($_GET['lastid'])) {
//get the starting ID from the URL
$startID = $link->real_escape_string(intval($_GET['lastid']));
//make the query, querying 25 fields per run
$result = $link->query("SELECT * FROM all_posts ORDER BY post_id DESC LIMIT '".$startID."', 25");
$html = '';
//put the table rows into variables
while($allRows = mysqli_fetch_assoc($result)) {
$postID = $link->real_escape_string(intval($allRows['post_id']));
$isBlog = $link->real_escape_string(intval($allRows['blog']));
$isJob = $link->real_escape_string(intval($allRows['job']));
$isVid = $link->real_escape_string(intval($allRows['video']));
$itemID = $link->real_escape_string(intval($allRows['item_id']));
//if the entry is a blog
if($isBlog === '1') {
$query = "SELECT * FROM blogs WHERE blog_id = '".$itemID."' ORDER BY blog_id DESC";
$result = $link->query($query);
while($blogRow = mysqli_fetch_assoc($result)) {
$blogID = $link->real_escape_string($blogRow['blog_id']);
$blogTitle = $link->real_escape_string(html_entity_decode($blogRow['blog_title']));
$blogDate = $blogRow['pub_date'];
$blogPhoto = $link->real_escape_string($blogRow['image']);
$blogAuthor = $link->real_escape_string($blowRow['author']);
$blogContent = $link->real_escape_string($blogRow['content']);
$blogTitle = stripslashes($blogTitle);
$blogContent = html_entity_decode(stripslashes(truncate($blogContent, 150)));
$html .="<div class='masonryBlock' id='".$postID."'>
<a href='post.php?id=".$blogID."'>
<div class='imgholder'><img src='uploads/blogs/photos/".$blogPhoto."'></div>
<strong>".$blogTitle."</strong>
<p>".$blogContent."</p>
</a></div>";
}
}
echo $html;
}
I have tried using the jquery infinite-scroll plugin, but it seemed much more difficult to do it that way. I don't know what the issue is here. I have added alerts and did testing and the javascript script is fully processing, so it must be with blocks.php right?
EDIT: I have made a temporary fix to this issue by changing the sql query to SELECT * FROM all_posts WHERE post_id < '".$startID."' ORDER BY post_id DESC LIMIT 15
The blocks are now loading via ajax, however they are only loading one block at a time. The ajax is sending a request for every single block and they are fading in one after another, is it possible to make them all fade in at once with jquery masonry?
I seen your code in another answer, and I would recommend using the LIMIT functionality in MySql instead of offsetting the values. Example:
SELECT * FROM all_posts ORDER BY post_id DESC LIMIT '".(((int)$page)*5)."',5
This will just take a page number in the AJAX request and get the offset automatically. It's one consistent query, and works independent of the last results on the page. Send something like page=1 or page=2 in your jQuery code. This can be done a couple different ways.
First, count the number of elements constructed on the page and divide by the number on the page. This will yield a page number.
Second, you can use jQuery and bind the current page number to the body:
$(body).data('page', 1)
Increment it by one each page load.
Doing this is really the better way to go, because it uses one query for all of the operations, and doesn't require a whole lot of information about the data already on the page.
Only thing to note is that this logic requires the first page request to be 0, not 1. This is because 1*5 will evaluate to 5, skipping the first 5 rows. If its 0, it will evaluate to 0*5 and skip the first 0 rows (since 0*5 is 0).
Let me know any questions you have!
Have you tried doing any debugging?
If you are not already using, I would recommend getting the firebug plugin.
Does the ajax call return empty? If it does, try echoing the sql and verify that is the correct statement and that all the variables contain the expected information. A lot of things could fail considering there's a lot of communication happening between client, server and db.
In response to your comment, you are adding the html in this piece of code:
if(html){
$(".blockContainer").append(html);
$('div#ajaxLoader').hide();
}
I would do a console.log(html) and console.log($(".blockContainer").length) before the if statement.

How to get the name of a course's teacher

Could you help me create a query that shows the teacher(s) of a course
Example:
Title of course: Course 1
Teacher: James Anderson
I have this query:
SELECT DISTINCT ldm_user.id,
ldm_user.firstname,
ldm_user.lastname,
ldm_course.shortname,
ldm_course.fullname,
ldm_role.id as role_id,
ldm_role_assignments.id
FROM ldm_course,ldm_user,ldm_role,ldm_context,ldm_role_assignments
WHERE ldm_course.fullname = "i-ONS001 Taller de Lectura y Redacción IV" and ldm_role_assignments.id = 4
But this is not returning the name of the teacher as expected.
This one is a little old, but I had to spend some time trying to figure it out and thought I would share what I came up with.
The basic PHP below will get the list of users enrolled in the course, comb through them and find any with the "editingteacher" role.
$moodle_site = 'YOUR_MOODLE_URL';
$moodle_token = 'YOUR_MOODLE_TOKEN';
$courseid = 7; // Enter the Moodle course ID you want to find the teacher for
$restformat = 'json';
$params = '';
$functionname = 'core_enrol_get_enrolled_users'; // Make sure function is enabled in Moodle
$serverurl = $moodle_site . '/webservice/rest/server.php' . '?wstoken=' . $moodle_token . '&wsfunction=' . $functionname . '&courseid='.$courseid;
$curl = new curl;
$restformat = ($restformat == 'json') ? '&moodlewsrestformat=' . $restformat : '';
$resp = $curl->post($serverurl . $restformat, $params);
$get_result = json_decode($resp, true);
if (!empty($resp)) {
foreach ($get_result as $array_level1) {
foreach ($array_level1["roles"] as $array_level2) {
if ($array_level2["shortname"]=='editingteacher') {
echo 'Teacher ID: '.$array_level1["id"].'<br>';
echo 'Teacher Name: '.$array_level1["firstname"].' '.$array_level1["lastname"].'<br>';
echo 'Teacher Email: '.$array_level1["email"].'<br>';
}
}
}
} else {
echo 'No users were returned.<br>';
}
Your question is incomplete, because the exact query will vary depending on your version of Moodle, whether you're using SQL or MySQL, and also we can't give you a comprehensive answer without knowing your table structures.
However, in Moodle 2.x you can use an API query (PHP) which looks something like this:
$role = $DB->get_record('role', array('shortname' => 'editingteacher'));
$context = get_context_instance(CONTEXT_COURSE, $courseid);
$teachers = get_role_users($role->id, $context);
and then doing a return $teachers; or echo $teachers; to output said results.
Like I said, without knowing your exact system details I can't give you an accurate response and a functioning query so take that with a pinch of salt; you might need to play around with it to get it to work.
Ref: https://moodle.org/mod/forum/discuss.php?d=115636

Laravel: Querying based on Input. If input is empty, get all

I have a calendar (FullCalendar) where the user can filter down results based on a few params (Tutor Secondary Tutor, Lesson, Location). When the user makes a change to the query it hits the following code.
The issue I am having is the 'OR'. What I really want is an IF input is null then get all.
If User { Get all lessons where lead_tutor_id = 1 and secondary_tutors_id = 1 }
If User and Location { Get lessons where the user is as above, but have location_id = 3 }
etc, etc.
So, is there a way I can fall back to get ALL the results IF only one or two filters are set?
$current_events = Calendar::Where(function($query) use ($start_time, $end_time, $tutor, $location, $lesson)
{
$query->whereBetween('date_from', [$start_time, $end_time])->orderBy('date_from')
->whereRaw('lead_tutor_id = ?
OR secondary_tutors_id = ?
OR location_id = ?
OR lesson_id = ?',
[
$tutor, // Input get() for user
$tutor, // Input get() for user
$location, // Input get() for location
$lesson, // Input get() for lesson
]
);
})->with('lessons', 'leadtutor', 'secondarytutor')->get();
I've been playing with Query Scopes, but this seems to fail if passing a NULL value through to it.
Any help is very much appreciated. Thanks in advance.
You can build the query on forehand, store it in a variable and use it once its build.
$query = isset($var) ? $var : '';
$query .= isset($othervar) ? $othervar : '';
whereBetween(*)->orderBy(*)->whereRaw($query)
Only thing you need to keep in mind is to insert the 'OR's in the right place . So have like a check for wether it is the first thing to be inserted or not, if not then put 'OR' in front of it.
Hope that is enough info to help you.
After the advice from Saint Genius, I have got this working:
$built_query = [];
isset($lead_tutor) ? $built_query['lead_tutor'] = 'lead_tutor_id = ' . $lead_tutor . ' ' : null;
isset($secondary_tutor) ? $built_query['secondary_tutor'] = 'secondary_tutors_id = ' . $secondary_tutor . ' ' : null;
isset($location_id) ? $built_query['location'] = 'location_id = ' . $location_id : null;
isset($lesson_id) ? $built_query['lesson'] = 'lesson_id = ' . $lesson_id : null;
// Flatten the array so we can create a query and add the word ADD in between each element.
$built_query = implode(" AND ", $built_query);
// Run the query
$current_events = Calendar::whereBetween('date_from', [$start_time, $end_time])->orderBy('date_from')->whereRaw($built_query)->with('lessons', 'leadtutor', 'secondarytutor')->get();

PHP + MySQL profiler

You know how vBulletin has a sql profiler when in debug mode? How would I go about building one for my own web application? It's built in procedural PHP.
Thanks.
http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html
The above link links how you can get al the sql profile information after any query.
Best way to implement it is to create a database class and have it have a "profile" flag to turn on logging of queries and the appropriate information as shown int he link above.
Example:
Class dbthing{
var $profile = false;
function __construct($profile = false){
if($profile){
$this->query('set profiling=1');
$this->profile = true;
}
...
}
function query($sql, $profile_this == false){
...
if($this->profile && !$profile_this)
$this->query("select sum(duration) as qtime from information_schema.profiling where query_id=1", true);
... // store the timing here
}
}
I use a database connection wrapper that I can place a profiling wrapper arround. This way I can discard the wrapper, or change it, without changing my base connector class.
class dbcon {
function query( $q ) {}
}
class profiled_dbcon()
{
private $dbcon;
private $thresh;
function __construct( dbcon $d, $thresh=false )
{
$this->dbcon = $d;
$this->thresh = $thresh;
}
function queury( $q )
{
$begin = microtime( true );
$result = this->dbcon->query();
$end = microtime( true );
if( $this->thresh && ($end - $begin) >= $this->thresh ) error_log( ... );
return $result;
}
}
For profiling with a 10 second threshold:
$dbc = new profiled_dbcon( new dbcon(), 10 );
I have it use error_log() what the times were. I would not log query performance back to the database server, that affects the database server performance. You'd rather have your web-heads absorb that impact.
Though late, Open PHP MyProfiler would help you achieve this, and you can extract functional sections from the code for your usage.