Check NULL value using PhpActiveRecord - php

According to the documentation here (http://www.phpactiverecord.org/projects/main/wiki/Finders)
There is a way to find records in the database like so below.
# fetch all lousy romance novels which are cheap
Book::all(array('conditions' => array('genre = ? AND price < ?', 'Romance', 15.00)));
# sql => SELECT * FROM `books` WHERE genre = 'Romance' AND price < 15.00
This however will not work if any of the values are NULL. This is simply because NULL is not any value so it does not have anything to compare from. This I understand, but what I can't figure out in the documentation is how to actually check using that format if the value is null or not.
In SQL you could simply say WHERE value is null, or not null, but with PHPActiveRecord condition array string I'm not sure...
The reason I want to do it with the condition string and array is I have code setup which automatically creates those conditions, I'll post the code below.
function create_find_options($fields,$operators,$values,$sortfields,$sortdirections,$limit,$offset,$logic){
$conditionstring = '';
$fieldcount = count($fields);
$i=0;
for($k=0;$k<count($logic)-1;$k++){
$conditionstring.="(";//add starting parenthesis for every known logic.
}
for($i=0;$i<$fieldcount;$i++){
$conditionstring.=$fields[$i];
switch($operators[$i]){
case "equals":
$conditionstring.=" = ?";
break;
case "greaterthan":
$conditionstring.=" > ?";
break;
case "lessthan":
$conditionstring.=" < ?";
break;
case "notequals":
$conditionstring.=" != ?";
break;
case "contains":
$conditionstring.=" LIKE ?";
break;
}
if($i!=$fieldcount-1 && $fieldcount>=2){
if($i>0){
$conditionstring.=")";//first condition does not get ending parenthesis.
}
$conditionstring.=" ".$logic[$i]." ";//AND or OR
}
}
//$conditionstring = substr($conditionstring,0,strlen($conditionstring)-5);
//die($conditionstring);
$options = array('conditions' => array($conditionstring));
$i=0;
for($i=0;$i<$fieldcount;$i++){
if($operators[$i]=="contains"){ //exception for contains because it needs the percentage symbols around the value.
$options['conditions'][] = "%".$values[$i]."%";
}else{
$options['conditions'][] = $values[$i];
}
}
//Add any sorts now.
$i=0;
$sortcount = count($sortfields);
$orderstring = '';
for($i=0;$i<$sortcount;$i++){
$orderstring.= $sortfields[$i]." ".$sortdirections[$i].",";
}
$orderstring = rtrim($orderstring,",");//remove trailing comma
$options['order'] = $orderstring;//sets order rules.
//Add any limits now.
if(isset($limit)){
$options['limit'] = $limit;
}
if(isset($offset)){
$options['offset'] = $offset;
}
return $options;
}
So my function will automatically create the condition string needed, but it fails on NULL for the reason I described above. I think I need to add some extra conditions in here that if I detect NULL how to handle it better, but I'm not sure how to do that or if that's possible with PHPActiveRecord?

Well after spending ... all day, I have found a solution. I suppose it might have been common sense but it was not in the documentation so I had to guess.
Apparently you can simply say 'is null' in the condition string like regular SQL and it will work...
That said I updated my function to the following and this generate a complete options array with the conditions ready to go that will work even with null values.
Hopefully this is useful to someone! In my situation I wanted 0 to be the same as null, so you can adjust accordingly for your situation.
function create_find_options($fields,$operators,$values,$sortfields,$sortdirections,$limit,$offset,$logic){
$conditionstring = '';
$fieldcount = count($fields);
$i=0;
for($k=0;$k<count($logic)-1;$k++){
$conditionstring.="(";//add starting parenthesis for every known logic.
}
for($i=0;$i<$fieldcount;$i++){
$conditionstring.=$fields[$i];
$nullFound = false;
if($values[$i]=='0'){
$nullFound = true;
}
switch($operators[$i]){
case "equals":
if($nullFound==true){
$conditionstring.=" is null OR ".$fields[$i].' = 0';
}else{
$conditionstring.=" = ?";
}
break;
case "greaterthan":
$conditionstring.=" > ?";
break;
case "lessthan":
$conditionstring.=" < ?";
break;
case "notequals":
if($nullFound==true){
$conditionstring.=" is not null OR ".$fields[$i].' != 0';
}else{
$conditionstring.=" != ? OR ".$fields[$i].' is null';
}
break;
case "contains":
$conditionstring.=" LIKE ?";
break;
}
if($i!=$fieldcount-1 && $fieldcount>=2){
if($i>0){
$conditionstring.=")";//first condition does not get ending parenthesis.
}
$conditionstring.=" ".$logic[$i]." ";//AND or OR
}
}
//$conditionstring = substr($conditionstring,0,strlen($conditionstring)-5);
//die($conditionstring);
$options = array('conditions' => array($conditionstring));
$i=0;
for($i=0;$i<$fieldcount;$i++){
if($values[$i]!="0"){
if($operators[$i]=="contains"){ //exception for contains because it needs the percentage symbols around the value.
$options['conditions'][] = "%".$values[$i]."%";
}else{
$options['conditions'][] = $values[$i];
}
}
}
//Add any sorts now.
$i=0;
$sortcount = count($sortfields);
$orderstring = '';
for($i=0;$i<$sortcount;$i++){
$orderstring.= $sortfields[$i]." ".$sortdirections[$i].",";
}
$orderstring = rtrim($orderstring,",");//remove trailing comma
$options['order'] = $orderstring;//sets order rules.
//Add any limits now.
if(isset($limit)){
$options['limit'] = $limit;
}
if(isset($offset)){
$options['offset'] = $offset;
}
//die(print_r($options));
return $options;
}

Related

If condition A execute 1 OR if condition B execute 2 return not as expected

status stored has value 'LET, SALE, LET/SALE'
My php code does not return as expected, I wish if ($input['status'] = "SALE") will return 'SALE, LET/SALE' but it return only LET/SALE
I have tried to amend the code many ways, but can't work probably
if (!empty($input['status']))
{
{
if ($input['status'] = "SALE");
{
if (is_null($where))
{
$where = "WHERE";
}
else {
$where = "AND";
}
$query .= " $where status LIKE '%".$input['status']."%' AND `selling` <=
{$input['max_price']}";
}
}
{
if ($input['status'] = "LET");
{
if (is_null($where))
{
$where = "WHERE";
}
else {
$where = "AND";
}
$query .= " $where status LIKE '%".$input['status']."%' AND `rental` <=
{$input['max_price']}";
}
}
}
I wish to query property LET or SALE at condition max_price. Lets say if query SALE with max 100,000 return results shall include SALE, LET/SALE with max_price less than 100,000
You are assigning a value in your "if" statement. Use == (is equal to) instead of = (equals). What's happening is that it reassigns the value each time and stays at the last choice, which was LET/SALE
Change to:
if ($input['status'] == "SALE");
and do that for all of your "ifs"

How can i check if user changed post value?

I have a form for users to give reputations to people.
I'm trying to check if user changed select value to cheat by giving more points
Here is my system:
There is a select box where users can choose how many reputation to give to the user, I'm using the following code to check if user changed the values by inspecting the element:
// Validate post
if(trim($_POST["reputationToGive"]) === 1){
$added = 1;
} elseif(trim($_POST["reputationToGive"]) === 2){
$added = 2;
} elseif(trim($_POST["reputationToGive"]) === 3){
$added = 3;
} else {
// fallback event
}
Code I'm using for select box:
<option value='1'>Give 1 reputation</option>
But somehow, it always triggers the fallback event.
Looking for corrections, have a great day!
I guess the === gives you the problem.
I don't know how you wrote the selectbox. But my geuss is that you get strings back and compare it to integers. Also trim will convert it to string.
I also suggest using a switch for this.
$value = (int) trim($_POST["reputationToGive"]);
$added = 0;
switch ( $value ) {
case 1:
case 2:
case 3:
$added = $value;
break;
default:
// fallback event
break;
}
If you want to be sure the answer is not changed in the post. You could use totally different values in the form that you will translate to the right value in the script.
$value = trim($_POST["reputationToGive"]);
$added = 0;
switch ( $value ) {
case 'AD3ZY':
$added = 1;
break;
case 'B&7X1':
$added = 2;
break;
case 'Px!29':
$added = 3;
break;
default:
// fallback event
break;
}

WHMCS - Catch SQL errors

I am using WHMCS for managing the members of my website, and I am facing a problem with my sql queries.
Here is the logic of the code :
while(!$boolean && tries<10){
... CODE...
if($count==0)
{
$table = "name_of_table";
$value = array("field"=>"value", ...);
$newid = insert_query($table,$values);
$boolean = true;
break;
}
tries++;
}
if($boolean){
$table = "other_table";
$value = array("field"=>"value", ...);
$newid = insert_query($table,$values);
}
The problem is that the second query does not run.
I did a few verifications : the programs goes into the if(boolean) condition, but the insert_query inside of it returns the id.... of the previous query (the one in the loop) !
Does anyone have an idea of what is happening here ?

If Else Echo JSON array check

I have a JSON array that I am pulling values from per $vars. Within the JSON data are going to be some key words that I am looking for. I have a single if else that looks like:
(demonstration purposes)
if( $FullName == $Data[$c]['manager'] $FullName == $Data[$c]['leader'] || $FullName == $Data[$c]['helper']) {
$cheapLabor = 'NO';
} else {
$cheapLabor = 'YES';
}
That works great however, now I want to define more specifically some if else points on status points which would represent their employement status. Each Emp Status is based on a group.
I would need it to check from the top of the food chain, then go downward to check if status = x. If it does then $cheapLabor = 'y'; else $cheapLabor = 'z';
I tried doing it, but I can't seem to get it to work. Here is what I am working with:
$repData = json_decode($json, TRUE);
$c = 0;
$var = $repData[$c]['column'];
if($FullName == $repData[$c]['ceo']) {
$groups = '[13]';
} else {
$groups = '[5]';
}
if($FullName == $repData[$c]['director']) {
$groups = '[10]';
} else {
$groups = '[5]';
}
if($FullName == $repData[$c]['regional']) {
$groups = '[9]';
} else {
$groups = '[5]';
}
if($FullName == $repData[$c]['project_manager']) {
$groups = '[8]';
} else {
$groups = '[]';
}
if($FullName == $repData[$c]['team_leader']) {
$groups = '[6]';
} else {
$groups = '[5]';
}
if($FullName == $repData[$c]['rae']) {
$groups = '[5]';
} else {
$staus = '[5]';
}
Shomz Answer partial working...
$groups = '[4]'; // new hire group default, to be overwritten if a user has the correct title within Table.
$roleGroups = array(
'regional' => '[7]',
'team_leader' => '[6]',
'RAE' => '[5]'
);
foreach ($roleGroups as $role => $groups) { // go through all the Position Titles
if ($FullName == $repData[$c][$role]) { // see if there's a match
$repGroup = $groups; // if so, assign the group
}
}
It sets team_leader and regional correctly but anything else just sets it as regional group.
Just realized that its actually rewriting the value.
Your code is overwriting $groups in every if-statement. You probably want to rewrite that in a switch/case statement with a default value being [5].
Let's say the first if is true, so $FullName == $repData[$c]['ceo'] is true and $groups becomes [13]. In the next line, there are two choices:
either a person is a director (AND a CEO, but it doesn't matter, see why below)
or a person is not a director (could be a CEO)
In both cases, $groups will either get a value of [10] or [5], meaning that no matter what happened inside the statement above, this statement will overwrite it. Thus, only your last if statement is able to produce results you might expect.
"Only one group per role"
In that case a simple switch/case statement will work:
switch($FullName){
case ($repData[$c]['ceo']):
$groups = '[13]';
break;
case ($repData[$c]['director']):
$groups = '[10]';
break;
// etc... for other roles
default:
$groups = '[5]';
break;
}
Or you can go even simpler and use an associative array to combine roles with group numbers. For example:
$roleGroups = array('ceo' => '[13]', 'director' => '[15]', etc);
Then simply see if there's a match:
$groups = '[5]'; // default, to be overwritten if a role is found below
foreach ($roleGroups as $role => $group) { // go through all the groups
if ($FullName == $repData[$c][$role]) { // see if there's a match
$groups = $group; // if so, assign the group
}
}
Hope this makes sense. Either way, $groups will have the number of the role if role is found, 5 otherwise.

How to simplify multiple switch in PHP?

is it possible to simplify this code? I am trying to put all cases in a switch but always d break in the first case and i need all echo's in the html. What is possible? Thank you!
$resultservices = mysqli_query($connecDB,"SELECT * FROM clients WHERE id_client = $id_client");
while($rowservice = mysqli_fetch_array($resultservices)){
$php = (int)$rowservice['php'];
$java = (int)$rowservice['java'];
$ruby = (int)$rowservice['ruby'];
$node = (int)$rowservice['node'];
}
// Values can be "1" or "0". Example: php:1, java:1, ruby:0, node:1
switch ($php) {
case 0: break;
case 1: echo "<li>php</li>"; break;
}
switch ($java) {
case 0: break;
case 1: echo "<li>java</li>"; break;
}
switch ($ruby) {
case 0: break;
case 1: echo "<li>ruby</li>"; break;
}
switch ($node) {
case 0: break;
case 1: echo "<li>node</li>"; break;
}
While I'm not sure what you're trying to do, how about:
$resultservices = mysqli_query($connecDB,"SELECT * FROM clients WHERE id_client = $id_client");
while($rowservice = mysqli_fetch_array($resultservices)){
$service[1] = (int)$rowservice['1'];
$service[2] = (int)$rowservice['1'];
$service[3] = (int)$rowservice['0'];
$service[4] = (int)$rowservice['1'];
}
foreach ($service as $k=>$v) {
if ($v) {
echo "<li>service".$k."</li>";
}
}
[edit] I see we've got some new variables.
while($rowservice = mysqli_fetch_array($resultservices)){
$service['php'] = (int)$rowservice['php'];
$service['java'] = (int)$rowservice['java'];
$service['ruby'] = (int)$rowservice['ruby'];
$service['node'] = (int)$rowservice['node'];
}
foreach ($service as $k=>$v) {
if ($v) {
echo "<li>".$k."</li>";
}
}
Although really, all you're doing is outputting the last row of your MySQL, so you could also do
$resultservices = mysqli_query($connecDB,"SELECT * FROM clients WHERE id_client = '".mysqli_real_escape_string($connecDB, $id_client)."' ORDER BY id DESC LIMIT 1");
while($rowservice = mysqli_fetch_array($resultservices)){
if ($rowservice['php']) {
echo "<li>php</li>"
}
if ($rowservice['java']) {
echo "<li>java</li>"
}
if ($rowservice['ruby']) {
echo "<li>ruby</li>"
}
if ($rowservice['node']) {
echo "<li>node</li>"
}
}
Given that 3 of your four service values are going to have the SAME value, you could eliminate 2 of the switches and end up with the same results:
$service01 = (int)$rowservice['1'];
$service02 = (int)$rowservice['1']; // identical to service01
$service03 = (int)$rowservice['0'];
$service04 = (int)$rowservice['1']; // identical to service01
meaning you could have:
switch($service01) {
case 0: break;
case 1: echo "<li>service01, 02, and 04</li>"; break;
}
And then, assuming these values will never be anything but true/false 0/1 values, you could eliminate the switches entirely and go with a conventional if:
if ($service01) {
echo "service 01, 02 and 04";
}

Categories