WordPress/PHP - Refining an if/else statement - php

I am looking at adding an if/else statement, showing different HTML as required. My question is how I could possibly refine this code? Is there a more refined way of presenting this code?
<?php if ('Images' == get_post_meta($post->ID, 'project_type', true)) { ?>
<h1>Images</h1>
<div class="images">...</div>
<? } elseif ('Slideshow' == get_post_meta($post->ID, 'project_type', true)) { ?>
<h1>Slideshow</h1>
<div class="slideshow">...</div>
<? } elseif ('Video' == get_post_meta($post->ID, 'project_type', true)) { ?>
<h1>Video</h1>
<div class="video">...</div>
<? } elseif ('Audio' == get_post_meta($post->ID, 'project_type', true)) { ?>
<h1>Audio</h1>
<div class="audio">...</div>
<?php } ?>

<?php
// Only call the function once (performance)
$post_id = get_post_meta($post->ID, "project_type", true);
// Use a whitelist to validate
$whitelist = array("Images", "Slideshow", "Video", "Audio");
// Check if given post ID is valid
if (in_array($post_id, $whitelist) === true) { ?>
<h1><?= $post_id ?></h1>
<div class="<?= strtolower($post_id) ?>">...</div>
<?php } ?>
Yes, this approach doesn't take into account what might be happening within your <div> element. As this isn't part of your question. If there is a lot going on I'd propose an object oriented approach. Another bad approach would be a switch statement.
<?php
switch (get_post_meta($post->ID, "project_type", true)) {
case "Images": ?>
<h1>Images</h1>
<div class="images">...</div>
<?php break;
case "Slideshow": ?>
<!-- Same story again ... -->
<?php break;
} // End switch
With OOP we can create something like the following:
<?php
namespace Stackoverflow;
abstract class MyBaseTemplate {
protected $title;
protected $class;
protected $content;
public function __toString() {
return "<h1>{$this->title}</h1><div class='{$this->class}'>{$this->content}</div>";
}
}
class Images extends MyBaseTemplate {
public function __construct() {
$this->title = "Images";
$this->class = "images";
$this->content = "...";
}
}
class Slideshow extends MyBaseTemplate {
// Init
}
// In the other file instead of if/else and switch
$post_id = get_post_meta($post->ID, "project_type", true);
$class = "\\Stackoverflow\\{$post_id}";
if (class_exists($class) === true) {
echo new $class();
}

Sometimes it can be cleaner to put all that markup in echo statements, but only if it is simple markup and the result is actually more readable than mixing in the php statements as above. Example:
<?php
if (...) {
echo "<h1>Images</h1>"
echo "<div class=\"images\">...</div>"
} else if(...) {
echo "<h1>...</h1>"
}
?>

Fleshgrinder is right, you could make this better by only using get_post_meta one time.
If the contents of the html is different for each of these, I would probably use a switch rather than else/elseif/etc...
$project_type = get_post_meta($post->ID, 'project_type', true);
switch ( $project_type ) {
case 'Images':
echo '<h1>Images</h1>';
echo '<div class="images">...</div>';
break;
case 'Slideshow':
echo '<h1>Slideshow</h1>';
echo '<div class="slideshow">...</div>';
break;
case 'Video':
echo '<h1>Video</h1>';
echo '<div class="video">...</div>';
break;
case 'Audio':
echo '<h1>Audio</h1>';
echo '<div class="audio">...</div>';
break;
}

Related

Warning: Illegal string offset 'enabled' in

We are trying to break up a form into several pages using jQuery steps. The error points to the form that we're trying to create. Call to the form initially looks like this:
$enable_paid_submission = houzez_option('enable_paid_submission');
$user_pack_id = get_the_author_meta( 'package_id' , $userID );
$remaining_listings = 0;
if( is_page_template( 'submit_property_test.php' ) ) {
if( $enable_paid_submission == 'membership' && $remaining_listings != -1 && $remaining_listings < 1 ) {
print '<div class="user_package_status"><h4>'.esc_html__('HTMLhere.','houzez' ).'</h4></div>';
<?php
$layout = houzez_option('property_form_sections');
$layout = $layout['enabled'];
if ($layout): foreach ($layout as $key=>$value) {
switch($key) {
case 'features':
get_template_part( 'features' );
break;
case 'location':
get_template_part( 'location' );
break;
case 'multi-units':
get_template_part('multi-units');
break;
}
}
endif;
?>
We would like to break the three sections of the form (features, location and multi-units) into three different pages. We added jQuery steps and it now looks like the following:
<script>
$(function ()
{
$("#wizard").steps({
headerTag: "h2",
bodyTag: "section",
transitionEffect: "fade"
});
});
</script>
<div id="wizard">
<h2>Features</h2>
<section>
<?php
$layout = houzez_option('property_form_sections');
$layout = $layout['enabled'];
if ($layout): foreach ($layout as $key=>$value) {
switch($key) {
case 'description-price':
get_template_part('features');
break;
}
}
endif;
?>
<h2>Location</h2>
<section>
<?php
$layout = houzez_option('property_form_sections');
$layout = $layout['enabled'];
if ($layout): foreach ($layout as $key=>$value) {
switch($key) {
case 'description-price':
get_template_part('location');
break;
}
}
endif;
?>
</section>
<h2>Multi-units</h2>
<section>
<?php
$layout = houzez_option('property_form_sections');
$layout = $layout['enabled'];
if ($layout): foreach ($layout as $key=>$value) {
switch($key) {
case 'description-price':
get_template_part('multi-units');
break;
}
}
endif;
?>
</section>
It was running okay in the first few hours. Now it is returning the error.
It looks like you are expecting the the function call to houzez_option() to return an array. It would seem from the error that you are getting that it is not. Without seeing what the houzez_option() code looks like it is impossible to tell you why it is not.
You could still improve your code some by having it check specifically for what you expect to be returned from your function.
$layout = isset( $layout['enabled'] ) ? $layout['enabled'] : '';
if ( is_array( $layout ) ): foreach ($layout as $key=>$value) {
switch($key) {
case 'description-price':
get_template_part('features');
break;
}
}
else:
echo 'Unable to retrieve options';
endif;
This will prevent the error and alert you that it isn't working on the frontend. You could also make the message clearer for the enduser. I was just providing a generic example.

foreach statement echo once if nested foreach is empty?

OK I have a foreach statement searching for a keyword across 3 multisite blogs in wordpress like so:
<?php
foreach ( $blogs as $blog ):
switch_to_blog($blog['blog_id']);
$search = new WP_Query($query_string);
if ($search->found_posts>0) {
foreach ( $search->posts as $post ) {
echo "POST CONTEN";
}
}elseif ($search->found_posts===0) {
# code...
$notfound = true;
}
endforeach;
if ($notfound) {
# code...
echo "POST NOT FOUND";
}
This works fine if there are no posts using the keyword across all thre blogs it echos the POST NOT FOUND but if there is a post on blog 1 but not on blog 2 or 3 it still echos POST NOT FOUND why?
Chris
//********UPDATE***********************************/
<?php
$searchfor = get_search_query(); // Get the search query for display in a headline
$query_string=esc_attr($query_string); // Escaping search queries to eliminate potential MySQL-injections
$blogs = get_blog_list( 0,'all' );
$notfound = true;
foreach ( $blogs as $blog ):
switch_to_blog($blog['blog_id']);
$search = new WP_Query($query_string);
if ($search->found_posts>0) {
$notfound = false;
}
if($notfound){
?>
<div class="post">
<h2><?php _e('Ingen resultater'); ?></h2>
<p><?php _e('Beklager, vi fant ingen innlegg som samsvarer med ditt søk: ' . get_search_query()); ?></p>
</div>
<?php
}else{
foreach ( $search->posts as $post ) {
echo "content";
}
}
endforeach;
?>
Your logic is backwards. You should start with a "nothing found" condition, and change it to false when something is found:
$not_found = true;
while ...
if ($search->found_posts != 0) {
$not_found = false;
}
}
if ($not_found) {
echo 'nothing found'; // $not_found is true
} else {
echo 'found something'; // $not_found is false
}
Sorry about the formatting. Just copied your code here. Do the opposite of what your doing, look at the variable $found here.
<?php
$found = false;
foreach ( $blogs as $blog ):
switch_to_blog($blog['blog_id']);
$search = new WP_Query($query_string);
if ($search->found_posts>0) {
foreach ( $search->posts as $post ) {
echo "POST CONTEN";
}
$found = true;
}elseif ($search->found_posts===0) {
# code...
}
endforeach;
if ($found == false) {
# code...
echo "POST NOT FOUND";
}

Multiple IDs in PHP call in WordPress

** I apologize for being unclear - I meant I want "Summit Sponsors" to display once regardless of how many IDs are used. Just for it to be hidden if no IDs are used. Thanks **
I was wondering if anyone knew a clean way to use multiple custom fields in an IF statement.
At the moment I have it spaced out, so each custom field "SponsorHeading#" has it's own if/else statement:
<?php
if(get_post_meta($post_id, 'SponsorHeading1', true)) {
echo '<h2>Summit Sponsors </h2>';
}
else {
echo '';
}
if(get_post_meta($post_id, 'SponsorHeading2', true)) {
echo '<h2>Summit Sponsors </h2>';
}
else {
echo '';
}
?>
and so on for 3 more custom fields. I'd like to have something cleaner like:
<?php
if(get_post_meta($post_id, 'SponsorHeading1', true)) || if(get_post_meta($post_id, 'SponsorHeading2', true)) || if(get_post_meta($post_id, 'SponsorHeading3', true)) {
echo '<h2>Summit Sponsors </h2>';
}
else {
echo '';
}
?>
or something along those lines to clean it up but nothing I've tried has worked.
Any suggestions?
Not 100% sure on if there is a more efficient way to manage this within WordPress’s logic itself, but the simplest solution I can conceive of using the example you give is to put all of the ids into an array & have logic to loop through them like so:
<?php
$fields = array('SponsorHeading1', 'SponsorHeading2', 'SponsorHeading3');
foreach($fields as $field_value) {
if(get_post_meta($post_id, $field_value, true)) {
echo '<h2>Summit Sponsors </h2>';
}
else {
echo '';
}
}
?>
EDIT: Addressing the user edits to the question. So how about this? We loop through the fields, and the value of $has_value changes to TRUE if at least one of the fields is returned by get_post_meta(). And if $has_value is TRUE then act on it:
<?php
$fields = array('SponsorHeading1', 'SponsorHeading2', 'SponsorHeading3');
$has_value = FALSE;
foreach($fields as $field_value) {
if(get_post_meta($post_id, $field_value, true)) {
$has_value = TRUE;
}
}
if ($has_value) {
echo '<h2>Summit Sponsors </h2>';
}
else {
echo '';
}
?>

error returning information using php

I am steps away from finishing this project, I seem to have a problem with my logic in my fetchMessage() function, I am passing in the session_id however I am getting nothing returned here is my function code
function fetchMessages($session)
{
$get = ("SELECT * FROM chatRoom WHERE session_id = '$session'");
$hold = mysql_query($get, $con);
if($hold)
{
return mysql_fetch_array($hold);
}
}
the code calling this function is
<?php
include 'core/conection.php';
include 'function.php';
if(isset($_POST['method']) === true && empty($_POST['method']) === false)
{
$method = trim($_POST['method']);
$session = trim($_POST['session']);
if($method === 'fetch')
{
$messages = fetchMessages($session);
if(empty($messages) === true)
{
echo 'A representative will be with you shortly';
echo '<br />';
echo $session;
}else
{
foreach($messages as $message)
{
$ts = $message['timestamp'];
?>
<div class = "message">
<?php echo date('n-j-Y h:i:s a', $ts); ?>
<?php echo $message['username']; ?>
says:<p><?php echo nl2br($message['message']); ?></p>
</div>
<?php
}
}
}
}
?>
I know it is making it at least this far because at this line
if(empty($messages) === true)
{
echo 'A representative will be with you shortly';
echo '<br />';
echo $session;
}
it displays the correct session_id i have a fealing it is either my fetchMessages function that is wrong or the html code to display the results that is wrong.

How to get $var outside the function without using global php?

Need small help here. Was reading how bad it is to add global var within function and call it outside but having small issue getting the vars outside. Global helped but I want to be safe also since I am handling some files here
my loop is this
<?php
require_once('functions.php');
?>
<?php
foreach( $files as $key=> $file ){
global $download_link;
get_file_info($key,$file);
?>
<span><?php echo $file->name ?></span>
<?php } ?>
PART of my function.php / is about 150 lines long but this is main snipp
function get_file_info($key,$file){
global $download_link;
$access = explode(",",$file->access);
$permission = in_array(1,$access);
if($permission){
$download_link = 'ok to download';
}else{
$download_link = 'canot download';
}
}
beside the link var I also have few others like date , counter etc but they are all bound by some condition.
I tried to do
return $link; at the end of the function instead using global but getting undefined variable error;
SO base question here is , how to get the download_link var outside the function without using global ?
You can do this a lot easier by modifying your File class
class File {
# ...
function get_url() {
return in_array(1, explode(',', $this->access))
? $this->url # return the file's url
: "/path/to/subscribe" # return a default path for non-access
;
}
}
Your HTML would use it as follows
<?php
foreach ($files as $file) {
echo 'Download this '.$file->name.'';
}
Since you just use get_file_info to set $download_link, why not just return $permission and define $download_link outside the function?
<?php
function get_file_info($key,$file){
$access = explode(",",$file->access);
$permission = in_array(1,$access);
return $permission;
}
foreach( $files as $key=> $file ){
$download_link = 'canot download';
if(get_file_info($key,$file)) {
download_link = 'ok to download';
}
echo '<span>'. $file->name . '</span>';
}
?>
You may change your loop like this:
<?php
require_once('functions.php');
?>
<?php
foreach( $files as $key=> $file ){
$download_link = get_file_info($key,$file);
?>
<span><?php echo $file->name ?></span>
<?php } ?>
And your function code:
function get_file_info($key,$file){
$access = explode(",",$file->access);
$permission = in_array(1,$access);
if($permission){
return 'ok to download';
}
else {
return 'canot download';
}
}

Categories