I would to know how I can display the result from a soql child to parent request.
$query = "SELECT FirstName, LastName, (select Retreat_Booking__c.Retreat__c from Retreat_Bookings__r)FROM Contact"
$response = $mySforceConnection->query($query);
$queryResult = new QueryResult($response);
while($queryResult->current()->FirstName!='' || $queryResult->current()->LastName!='')
{
echo $queryResult->current()->FirstName." ".$queryResult->current()->LastName." ".$queryResult->current()->Retreat__c." <BR/>";
$queryResult->next();
}
The request works and display "FirstName" and "LastName" but not "Retreat__c".
I know the result in the 2nd select is a json and I tried many things, but nothing works.
Query should be like below
$query = "SELECT FirstName, LastName, (select Retreat_Booking__r.Retreat__c from Retreat_Bookings__c)FROM Contact";
That is,
Retreat_Booking__r.Retreat__c instead of Retreat_Booking__c.Retreat__c
and
from Retreat_Bookings__c instead of Retreat_Bookings__r
After FROM there should be the custom object name which is (extension is __c) Retreat_Bookings__c and retrieving data from a reference objects field, you should use __r extension and thus Retreat_Booking__r.Retreat__c
Update
For your 2nd question, you can try
$query = "SELECT FirstName, LastName, (select Retreat_Booking__r.Retreat__c from Retreat_Bookings__c) AS rb FROM Contact"
and then
while($queryResult->current()->FirstName!='' || `$queryResult->current()->LastName!='')
{
echo $queryResult->current()->FirstName." ".$queryResult->current()->LastName." ".$queryResult->current()->rb.Retreat__c" <BR/>";
$queryResult->next();
}`
Related
I have a problem here. I have a drop-down list with a users and when I click on any user, it shows a clients which are assigned to it.
Now I've added Unassigned clients selection into the drop-down top to show which clients are unassigned. I've added it with a array_unshift() command, but now in some existing users (not all of it) it's not showing any clients, but these are assigned in the database.
When I remove array_unshift, the clients shows properly, but then there are no extra selection.
I'm thinking that there are something wrong with the array_unshift(), but not sure..
Here is my select function:
public static function getUsers()
{
$query = self::find()
->select(['id', "CONCAT(name, ' ', surname, ' (', email, ')') as name"]);
$users = ArrayHelper::map($query->asArray()->all(), 'id', 'name');
array_unshift($users, 'Test'));
return $users;
}
From PHP docs:
All numerical array keys will be modified to start counting from zero while literal keys won't be changed.
Use +:
public static function getUnmappedUsersList()
{
$query = self::find()
->select(['id', "CONCAT(name, ' ', surname, ' (', email, ')') as name"]);
return [Yii::t('app', 'ADMIN_PANEL_MIGRATE_UNASSIGNED_CLIENTS')]
+ ArrayHelper::map($query->asArray()->all(), 'id', 'name');
}
Using PDO I have built a succinct object for retrieving rows from a database as a PHP object with the first column value being the name and the second column value being the desired value.
$sql = "SELECT * FROM `site`"; $site = array();
foreach($sodb->query($sql) as $sitefield){
$site[$sitefield['name']] = $sitefield['value'];
}
I now want to apply it to a function with 2 parameters, the first containing the table and the second containing any where clauses to then produce the same result.
function select($table,$condition){
$sql = "SELECT * FROM `$table`";
if($condition){
$sql .= " WHERE $condition";
}
foreach($sodb->query($sql) as $field){
return $table[$field['name']] = $field['value'];
}
}
The idea that this could be called something like this:
<?php select("options","class = 'apples'");?>
and then be used on page in the same format as the first method.
<?php echo $option['green'];?>
Giving me the value of the column named value that is in the same row as the value called 'green' in the column named field.
The problem of course is that the function will not return the foreach data like that. That is that this bit:
foreach($sodb->query($sql) as $field){
return $table[$field['name']] = $field['value'];
}
cannot return data like that.
Is there a way to make it?
Well, this:
$sql = "SELECT * FROM `site`"; $site = array();
foreach($sodb->query($sql) as $sitefield){
$site[$sitefield['name']] = $sitefield['value'];
}
Can easily become this:
$sql = "SELECT * FROM `site`";
$site = array();
foreach( $sodb->query($sql) as $row )
{
$site[] = $row;
}
print_r($site);
// or, where 0 is the index you want, etc.
echo $site[0]['name'];
So, you should be able to get a map of all of your columns into the multidimensional array $site.
Also, don't forget to sanitize your inputs before you dump them right into that query. One of the benefits of PDO is using placeholders to protect yourself from malicious users.
I'm looking to sort the results of a query in the controller, "after" it is returned from the model, here is what im trying:
$query = $this->user->get_all_users();
foreach($query as $user){
// dynamically according to my projects' logic
// assigns a grade to each user
$user->grade = assign_a_grade_to_user()
}
what im looking to do is , the results in $query should be sorted according to the grade a student has , and then pass that sorted $query to my view to print
any suggestions or idea to get this ?
NOTE : no issues if we use another temporary variables or data structures like we can store the sorted results in some other variable too
This should do:
function cmp( $a, $b )
{
if( $a->grade== $b->grade){ return 0 ; }
return ($a->grade< $b->grade) ? -1 : 1;
}
$sortedArray=usort($query ,'cmp');
So your code should look like:
$query = $this->user->get_all_users();
foreach($query as $user){
// assigns a grade to each user
$user->grade = assign_a_grade_to_user()
}
$sortedArray=usort($query ,'cmp');
$data['users']=$query;
$this->load->view('home',$data);
I'm using the following code. The code works, but I want to change it so that it uses bindparam
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$stqid=array();
for ($i=0; $i<$array_count; $i++){
$stqid[$i][0]=$lastInsertValue;
$stqid[$i][1]=$qid[$i][0];
$stqid[$i][2]=$qid[$i][1];
}
$values = array();
foreach ($stqid as $rowValues) {
foreach ($rowValues as $key => $rowValue) {
$rowValues[$key] = $rowValues[$key];
}
$values[] = "(" . implode(', ', $rowValues) . ")";
}
$count = $dbh->exec("INSERT INTO qresults(instance, qid, result) VALUES ".implode (', ', $values));
$dbh = null;
}
catch(PDOException $e){
echo $e->getMessage();
}
I replaced the following
$count = $dbh->exec("INSERT INTO qresults(instance, qid, result) VALUES ".implode (', ', $values));
with
$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:an_array)";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':an_array', implode(',', $values),PDO::PARAM_STR);
$stmt->execute();
but the insert doesn't work anymore (I didn't get any error messages though).
QUESTION: What am I doing wrong? How can I rewrite the code to use bindParam?
You're trying to create a statement and bind a param.
Statement are great because it potentially nullify any kind of SQL injection. And it does it by removing the concept of a query being only seen as a string. The SQL query is seen as a string with a parameter list and an the associated data as binded variables.
So the query is not only text, but text + data.
I mean:
This simple query:
SELECT * FROM A WHERE val="$param"
It is not safe because the query is only viewed as a string. And if $param is not checked, it is a SQLi hole.
But when create a statement, your query becomes:
SELECT * FROM A WHERE val=:param
Then you use bindparam to specify the value a :param. Which mean the value is not appended to the query string, but the query is already parsed and the data is provided.
In your case, you bind to the param :array an imploded array (I assume "data1", "data2", etc..). Which is only one parameter with the value as a string ( "data1, data2, data3..." ), so it will only result in one insert and not multiple insertions.
You can change your statement generation by generating a query with enough parameters to handle your array
$sql = "INSERT INTO qresults (instance, qid, result) VALUES ( :val0, :val1, :val2, ...)";
Then loop on your array and call the bindparam method for each parameters.
$count = 0;
foreach($values as $val)
{
$stmt->bindParam(":val$count", $val,PDO::PARAM_STR);
$count++;
}
This will work.
Edit: This solution show how it works for a one dimensional array, but can be easily extended to your problem by tweaking the statement query generation and modify the bindparam loop.
Your statement should looks like:
$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:val0, :val1, :val2) , (:val3, :val4, :val5), ...";
You just have to count the number of element in your base array.
I decided that I wanted a search field on my website, the thing is I don't really have any knowledge about search algorithms. The search box works like you can enter any number of names(username, firstname, lastname) or emails separating each by a space. So I came up with the following using codeigniter's active record class (it's very simple):
$emails = FALSE;
$names = FALSE;
foreach($search_array as $value){
if(valid_email($value)){
$emails[] = $value;
} else{
$names[] = $value;
}
}
if($emails){
$this->db->where_in('email', $emails);
if($names){
$this->db->or_where_in('username', $names);
$this->db->or_where_in('firstname', $names);
$this->db->or_where_in('lastname', $names);
}
} else{
if($names){
$this->db->where_in('username', $names);
$this->db->or_where_in('firstname', $names);
$this->db->or_where_in('lastname', $names);
}
}
$this->db->select('id, username, firstname, lastname');
$query = $this->db->get('users');
if($query->num_rows() > 0){
return $query->result();
}
return FALSE;
What this code does is running a bunch of where statements and then simply sending it all back.
Perhaps I could clean up the if-statements and how the email works, but that's not the point. This code works perfectly (at least with a very small database :P) but I want it to do more:
Right now you need to enter the correct name or email to get any good result. If your almost right it would be nice to get some suggestions but that I probably can figure that out by myself doing some LIKE.
I want to sort the whole result array, and here is where I'm stumbling. Since both the email and the username is unique I want a search to display using the following priorities:
Email
Username
Firstname + Lastname
Firstname
Lastname
Well for the time being I don't really care about for example Email+username+firstname+lastname since I believe that would be way to overwhelming :P
I did found this topic Search query, 'order by' priority but since I don't know which is what in my search it didn't really help me but perhaps I could use something similar?
Anyway you guys know a way to solve the priority problem? Have I perhaps missed some major functions that could help? And what will happen when my database goes big? ;)
Thanks for all help!
You can do:
ORDER BY email != 'value',
username != 'value',
firstname != 'value' AND lastname != 'value',
firstname != 'value',
lastname != 'value'
If the expression is false (meaning they are the same) then it's equal to 0 and will sort higher than an expression that is true (meaning they are different) which equals 1 and sorts after a 0.
If you find the != confusing then this is the same thing:
ORDER BY email = 'value' DESC,
username = 'value' DESC,
firstname = 'value' AND lastname = 'value' DESC,
firstname = 'value' DESC,
lastname = 'value' DESC