How to add 2 parameters in a ternary condition - PHP? - php

In yang config I a have some parameter like:
$application_promo_shipping = true;
$application_promo_engrave = false;
I make PHP code with a ternary condition like this:
<p class="mx-auto nav-link-promo <?= ($this->config->item('application_promo_shipping')?:"d-none")?>">Free Shipping</p>
<p class="mx-auto nav-link-promo <?= ($this->config->item('application_promo_engrave')?:"d-none")?>">Free engrave</p>
If the value is true the "d-none" class is hide so the only text show is Free shipping
But how can I make like that with 2 parameters, if shipping and engrave is true I want to call a paragraph like this:
FREE ENGRAVE & FREE shipping
Because with the code now, I have a lot of space between 1 paragraph to another paragraph if I change the value to true in 2 parameters.

To your main question here ...
You CAN use multiple operators in one ternary condition and it will look like this:
$output = ($var1 === true && ($var2 == 2 || $var3 == 3)) ? 'if true' : 'if false';
BUT i wouldn't recommend it in your case simply because your ternary condition would be one mega-long line very hardly understanable to other programmers. So, ... how would i solve it?
Just rename your configuration values to something more understandable and shorter :), then you can do your ternary operation and the code will look good.
Approach no. 1:
<?php
$messages = [
0 => 'Free Shipping',
1 => 'Free engrave',
2 => 'FREE ENGRAVE & FREE shipping'
];
$shipping = $this->config->item('application_promo_shipping');
$engrave = $this->config->item('application_promo_engrave');
$message_key = ($shipping && $engrave) ? 2 : (($engrave) ? 1 : 0);
?>
<p class="mx-auto nav-link-promo"><?php echo $messages[$message_key]; ?></p>
Approach no. 2: (not recommended)
<?php
$shipping = $this->config->item('application_promo_shipping');
$engrave = $this->config->item('application_promo_engrave');
?>
<p class="mx-auto nav-link-promo <?php echo ($shipping) ? '' : 'd-none'; ?>">Free Shipping</p>
<p class="mx-auto nav-link-promo <?php echo ($engrave) ? '' : 'd-none'; ?>">Free engrave</p>
<p class="mx-auto nav-link-promo <?php echo ($shipping && $engrave) ? '' : 'd-none'; ?>">FREE ENGRAVE & FREE shipping</p>

One way of going about it is creating the output based on the two variables and store it in a variable that is an array. If the length is at least 1 or higher, print the paragraph and implode() the values with the deliminator &. This way, the paragraph doesn't even get rendered in HTML if both conditions are false.
Using shorter code by ternary operators can be useful - but in this case, it can probably be better to not render the output at all if the condition is true by using a normal if statement.
$output = [];
if ($this->config->item('application_promo_shipping')) {
$output[] = "Free shipping";
}
if ($this->config->item('application_promo_engrave')) {
$output[] = "Free engraving";
}
if (count($output)) {
?>
<p class="mx-auto nav-link-promo"><?php echo implode(" & ", $output); ?></p>
<?php
}
If you're hell-bent on using a ternary and using the d-none class, you can do that as well with the same condition (but you will still need the first two if blocks to declare the values of $output).
<p class="mx-auto nav-link-promo <?= count($output) ?: 'd-none'; ?>"><?= implode(" & ", $output); ?></p>

I tend to use a much simpler approach in order to make my code readable to other developers. Nothing worse than having to decipher code where someone has tried to be unnecessarily clever.
I would do something like this:
if (application_promo_shipping AND !application_promo_engrave) {
echo '<p class="mx-auto nav-link-promo">Free Shipping</p>';
}
if (application_promo_engrave AND !application_promo_shipping) {
echo '<p class="mx-auto nav-link-promo">Free Engraving</p>';
}
if (application_promo_engrave AND application_promo_shipping) {
echo '<p class="mx-auto nav-link-promo">Free Engraving</p> & <p class="mx-auto nav-link-promo">Free Shipping</p>';
}

Related

PHP: Determine Text Colour based on value

I've stored values in an array and I want to apply conditional formatting to the output when I access them.
I want the text of the values, less than or equal to 10, displayed in red or, greater than 10, displayed in green.
For example, below, I would like the resultant value of 5 to be displayed in red.
I'm a newbie to this but would assume I would need the help of CSS to achieve this.
Any advice would be appreciated.
<?php
$total_sql=array();
$total_sql[]=5;
$total_sql[]=10;
$total_sql[]=15;
$total_sql[]=20;
print($total_sql[0]);
?>
<?php
$total_sql=array();
$total_sql[]=5;
$total_sql[]=10;
$total_sql[]=15;
$total_sql[]=20;
print($total_sql[0]);
?>
foreach($total_sql as $item)
{
if($item >10)
{
echo '<p class="green">'.$item.'</p>';
} else {
echo '<p class="red">'.$item.'</p>';
}
.red{color:red;}
.green{color:green}
One liner:
echo '<div style="color: '.(($score == '5') ? 'red' : 'black').';">'.$score.'</div>';
Comparison operator could be:
$score == 'x'
> 'y'
>= 'z'
etc...
I've used an inline style here, but you can use class= too.

PHP: Simplify multiple || operator statements into one? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
php if statement with multiple conditions
I have this code:
if(x==1 || x==2 || x==3 || x==4 )
Is there anyway to simply it shorter? For example:
if(x==1||2||3||4 )
Meaning for the statement to be true if X= 1,2,3 OR 4?
Thank you in advance.
Edit: (Thanks for all the replies, here is some clarification)
I have a while loop but only want specific database entries to be called. My code is current
<?php while(the_repeater_field('team_members','options') && get_sub_field('member_sort') == 1 : ?>
<div class="one_fourth">
<img src="<?php the_sub_field('image'); ?>" alt="" />
<p>
<?php the_sub_field('info'); ?>
<br />
<?php the_sub_field('email'); ?>
</p>
</div>
<?php endwhile; ?>
Right now it works perfectly with == 1 , but I also want to show 2,3,4 as well. I am just not sure how I should've put the code to execute 1||2||3||4
Update 2:
Okay so I used the following code, but I am guessing I am going about it the wrong way. The following code only showed the record that was equal to 1.. but not the records equal to 2,3,4... I am guess because the while loop is only running once since the statement becomes true instantly.
<?php while(the_repeater_field('team_members','options') && in_array(get_sub_field('member_sort'),array(1,2,3,4))): ?>
<div class="one_fourth">
<img src="<?php the_sub_field('image'); ?>" alt="" />
<p>
<?php the_sub_field('info'); ?>
<br />
<?php the_sub_field('email'); ?>
</p>
</div>
<?php endwhile; ?>
if (in_array($x, array(1,2,3,4))
or, even:
if (in_array($x, range(1, 4)))
OK, this question has evolved quite a bit but I think the problem is now that you want to loop over all values but only do stuff on certain conditions. You can use the continue statement to abort the current iteration and move on to the next immediately.
<?php while (the_repeater_field('team_members','options')) : ?>
<?php if (!in_array(get_sub_field('member_sort'), array(1,2,3,4))) continue; ?>
... do stuff
<?php endwhile; ?>
If you are using PHP 5.4+, you could do this:
if (in_array($x, [1,2,3,4]))
Otherwise, it's:
if (in_array($x, array(1,2,3,4)))
It depends on how many you have, and on whether there may be other conditions, but either a switch:
switch(x) {
case 1:
case 2:
case 3:
case 4:
break;
default:
// Do stuff
}
Or an array, especially for many items:
if(!in_array(x, array(1, 2, 3, 4)) {
// Do stuff
}
There is no way. Only by using arrays.

Echo with Shorthand If not behaving properly

I'm programming in PHP, I'm using a 'shorthand if' to echo some HTML code on to the page, but it is behaving in odd ways.
echo '<div id="filter_bar">
<ul>';
echo '<li>Trending</li>' : '>Trending</a></li>';
echo '<li>Most Picked</li>' : '>Most Picked</a></li>';
echo '<li>Newest</li>' : '>Newest</a></li>';
echo '</ul></div>';
The resulting code that I get as a result is this
class="filter_selected">Trending</a></li> class="filter_selected">Most Picked</a></li> class="filter_selected">Newest</a></li>
As you can see, the opening list tags are not showing... but they do if I replace the first period '.' on each line with a ',' comma.
So this works, with the commas
Should I be using a comma here? Everywhere online sheems to show a period '.'
The reason is:
echo '<li>' . true ? 'aaa' : 'bbb'; will give you aaa,
because it is same with '<li>1' ? 'aaa' : 'bbb'
And you should do like this:
echo '<li>' . (true ? 'aaa' : 'bbb');
Maybe you can make your life a bit easier:
echo '<div id="filter_bar"><ul>',
'<li>' : '>', 'Trending</li>',
'<li>' : '>', 'Most Picked</li>',
'<li>' : '>', 'Newest</li>',
'</ul></div>';
Which will use commas (no need to repeat echo that much) and you don't need to repeat strings that much if you only want to insert the class attribute.
Then you made use of parenthesis where they were not needed (see Operator Precedence Docs) but at the place where those are needed, you didn't use them (the last case).
Additionally it's better to fill those values to variables upfront, so you can debug stuff easier (and you don't mix $_GET with output, so to prevent mixing output logic with input variables).
That done you could have learned that your issue is not within the echo but just the expression you've formulated with the ternary operator.
$class_trending = $_GET['select'] == "trending" ? ' class="filter_selected"' : '';
$class_most_picked = $_GET['select'] == "most_picked" ? ' class="filter_selected"' : '';
$class_newest = ($_GET['select'] == "newest") || empty($_GET['select']) ? ' class="filter_selected"' : '';
echo '<div id="filter_bar"><ul>',
'<li><a href="?select=trending"', $class_trending, '>Trending</a></li>',
'<li><a href="?select=most_picked"', $class_most_picked, '>Most Picked</a></li>',
'<li><a href="?select=newest"',$class_newest , '>Newest</a></li>',
'</ul></div>';
dunno your problem but this code looks an ugly mess for me.
I'd make it this way:
in the PHP code I'd prepare variables first.
$sections = array(
'newest' => 'Newest',
'trending' => 'Trending',
'most_picked' => 'Most Picked',
);
if (empty($_GET['select']) OR !$choice = array_search($sections,$_GET['select'])) {
$choice = 'newest';
}
and then in the template run smooth and short loop:
<div id="filter_bar">
<ul>
<? foreach ($sections as $sect => $name): ?>
<li>
<a href="?select=<?=$sect?><? if ($choice == $sect) ?>" class="filter_selected"<? endif ?>><?=$name?></a>
</li>
<? endforeach ?>
</ul>
</div>
One possible solution is
echo "<li><a href='?select=newest'";
echo ($_GET['select'] == "newest" || empty($_GET['select'])) ? ' class="filter_selected">Newest</a></li>' : '>Newest</a></li>';
Change your parentheses to the following:
echo '<div id="filter_bar">
<ul>';
echo '<li>Trending</li>' : '>Trending</a></li>');
echo '<li>Most Picked</li>' : '>Most Picked</a></li>');
echo '<li>Newest</li>' : '>Newest</a></li>');
echo '</ul></div>';
If you do not do this, PHP does not know what exactly your condition is. Also have a look at operator precendence as this explains why it works using commas.
By the way: The ?: is called ternary operator.

php if-statement based on integers is not displaying results?

I'm using the following preg_match:
preg_match( '!<div class="thumblock ">(.*)</div>!si' , wp_gdsr_render_article_thumbs(0, false, "", 0, "", false) , $n );
$thumbs_string = strip_tags( $n[1] );
To extract the number between the span tags:
<div class="thumblock ">
<span class="rating-result">
<div id="gdsr_thumb_text_12_a" class="gdt-size-20 voted inactive gdthumbtext">+1</div>
</span>
<div class="ratingtext ">
<div class="raterclear"></div>
</div>
(in the example above, result is a string: "+1")
So I tried converting it into an integer with this:
$thumbs_number = (int)$thumbs_string;
which is used in this function:
function get_rating_class($thumbs_number) {
if ($thumbs_number < 0) return ' bad';
if ($thumbs_number < 2) return ' average';
if ($thumbs_number < 4) return ' good';
return ' excellent';
}
function rating_class($thumbs_number) {
echo get_rating_class($thumbs_number);
}
to output a div class:
<div class="topic-like-count<?php rating_class($thumbs_number); ?>">
I even did var_dump():
<h2><?php var_dump($thumbs_string); ?></h2>
<h2><?php var_dump($thumbs_number); ?></h2>
and the results were:
string(2) "+1" and int(1) respectively (I directly copy/pasted them here).
But no div class is being output.
Any suggestion to fix this?
EDIT:
The class is indeed being output in the HTML source, but it isn't having any effect (and my stylesheet is not being cached). I have another version of the function which doesn't add an extra div around the span tags, and that one works but unfortunately I need that div.
If the class name is being displayed in the HTML then the PHP code is fine. The stylesheet is likely the problem.
Sure.. add an echo before the call to rating_class($thumbs_number);:
<div class="topic-like-count<?php echo rating_class($thumbs_number); ?>">
Why are you using an extra function that's only used to echo? The following should work just fine.
<div class="topic-like-count<?=get_rating_class($thumbs_number);?>">

Is it a bad practice to have too many nested PHP if-statements?

Right now, I have something like this:
<?php if ( ! is_front_page() ) : ?>
<?php if ( $count >= 1 ) : ?>
<?php if ( $count == 1 ) : ?>
<h2 class="dark-title"><?php _e( 'Top Reply (Latest)' ); ?></h2>
<?php else : ?>
<h2 class="dark-title"><?php _e( 'Top Replies (Latest)' ); ?></h2>
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
There are 3 nested if-statements I would like to know if this is a bad practice. If it is, how can I clean this code?
It is if the conditions are very simple and their are no else cases.
Also, opening useless <?php processing instructions and using the uncommon endif form instead of braces are definitely not encouraged. Instead, write:
<?php
if (!is_front_page() && ($count >= 1)) {
echo '<h2 class="dark-title">';
echo _e(($count==1) ? 'Top Reply (Latest)' : 'Top Replies (Latest)');
echo '</h2>';
}
?>
...if you need
more than 3 levels of indentation, you're screwed...
- Linus Torvalds
It's fine what you've done. In general your firstmost care should be whether your code is readable, not how many levels of nesting you use.
It is certainly a bad idea to repeat markup. If you want to change something, add a class for example, you have to do it in two places.
In some cases, when you just want to assign a value based on a condition, you can use the ternary operator (condition ? iftrue : iffalse), just never nest it.
<?php if ( ! is_front_page() && $count >= 1 ) : ?>
<h2 class="dark-title">
<?php _e( $count == 1 ? 'Top Reply (Latest)' : 'Top Replies (Latest)' ); ?>
</h2>
<?php endif; ?>
It's fairly common. If you want to clean up the code, refactor stuff into separate functions/methods. In your specific case you could also get rid of one nesting by doing if($count == 1) and then elseif($count > 1).

Categories