PHP - String Concatenation - By loop - php

Here is my code,
if ($_SESSION["crossfit"]=="Y") { if ($_SESSION["tr_duration1"]==1) { $dr1="1 Month"; } else {
if ($_SESSION["tr_duration1"]==12) { $dr1="1 Year"; } else
{ $dr1=$_SESSION["tr_duration1"] . ' Months'; }} $c1='Crossfit - ' . $dr1;}
if ($_SESSION["muaythai"]=="Y") { if ($_SESSION["tr_duration2"]==1) { $dr2="1 Month"; } else {
if ($_SESSION["tr_duration2"]==12) { $dr2="1 Year"; } else
{ $dr2=$_SESSION["tr_duration2"] . ' Months'; }} $c2=', Muaythai - ' . $dr2;}
if ($_SESSION["mma"]=="Y") { if ($_SESSION["tr_duration3"]==1) { $dr3="1 Month"; } else {
if ($_SESSION["tr_duration1"]==12) { $dr3="1 Year"; } else
{ $dr3=$_SESSION["tr_duration3"] . ' Months'; }} $c3=', MMA - ' . $dr3;}
if ($_SESSION["gymnastics"]=="Y") { if ($_SESSION["tr_duration4"]==1) { $dr4="1 Month"; } else {
if ($_SESSION["tr_duration4"]==12) { $dr4="1 Year"; } else
{ $dr4=$_SESSION["tr_duration4"] . ' Months'; }} $c4=', Gymnastics - ' . $dr4;}
$for = $c1 . $c2 . $c3 . $c4 . '.';
At least one of the programs will be 'Y' or all of them.
What I want is that $c1 $c2 $c3 $c4 come out separated by ',' and ends with '.' so it becomes readable.
My problem is if I put
$for = $c1 . $c2 . $c3 . $c4 . '.'; and the ',' with $c1 and select programs 2 and 3
I get
$for = , Muaythai - 3 Months, MMA - 12 Months.
of course I want,
$for = Muaythai - 3 Months, MMA - 12 Months.
If I put ',' in the $for directly and remove from $c1 if 2nd and 3rd programs are selected
$for = $c1 . ',' . $c2 . ',' . $c3 . ',' . $c4 . '.'
I get
$for = ,Muaythai - 3 Months, MMA - 12 Months,.
I want
$for = Muaythai - 3 Months, MMA - 12 Months.
I have also tried putting nesting so many isset's but haven't succeeded.
I have also tried by making a 'for' loop but ended up with more syntax errors than output errors
It works fine only if I select only the first program or all the 4 programs.

Try something like this:
$tmp = array($c1,$c2,$c3,$c4);
$filtered = array_filter($tmp);
$for = implode(",", $filtered).".";
This will strip out any $c_ variables that aren't populated, and separate them with commas.
EDIT: I have reivewed your code, and would like to suggest this optimised version:
$keys = array("Crossfit","Muaythai","MMA","Gymnastics");
$result = array();
foreach($keys as $i=>$name) {
if( $_SESSION[strtolower($name)] == "Y") {
$duration = $_SESSION['tr_duration'.($i+1)];
switch($duration) {
case 1: $dur = "1 Month"; break;
case 12: $dur = "1 Year"; break;
default: $dur = $duration." Months";
}
$result[] = $name." - ".$dur;
}
}
if( !$result) $for = "Nothing selected!";
else $for = implode(", ",$result).".";
If you need help understand what's going on here, feel free to ask!

you can do it using single variable and concate values to it.
try like this:
for = "";
if ($_SESSION["crossfit"] == "Y") {
if ($_SESSION["tr_duration1"] == 1) {
$dr1 = "1 Month";
} else {
if ($_SESSION["tr_duration1"] == 12) {
$dr1 = "1 Year";
} else {
$dr1 = $_SESSION["tr_duration1"] . ' Months';
}
}
$for .= 'Crossfit - ' . $dr1;
}
if ($_SESSION["muaythai"] == "Y") {
if ($_SESSION["tr_duration2"] == 1) {
$dr2 = "1 Month";
} else {
if ($_SESSION["tr_duration2"] == 12) {
$dr2 = "1 Year";
} else {
$dr2 = $_SESSION["tr_duration2"] . ' Months';
}
}
$for .= empty($for) ? 'Muaythai - ' . $dr2 : ', Muaythai - ' . $dr2;
}
if ($_SESSION["mma"] == "Y") {
if ($_SESSION["tr_duration3"] == 1) {
$dr3 = "1 Month";
} else {
if ($_SESSION["tr_duration1"] == 12) {
$dr3 = "1 Year";
} else {
$dr3 = $_SESSION["tr_duration3"] . ' Months';
}
}
$for .= empty($for) ? 'MMA - ' . $dr3 : ', MMA - ' . $dr3;
}
if ($_SESSION["gymnastics"] == "Y") {
if ($_SESSION["tr_duration4"] == 1) {
$dr4 = "1 Month";
} else {
if ($_SESSION["tr_duration4"] == 12) {
$dr4 = "1 Year";
} else {
$dr4 = $_SESSION["tr_duration4"] . ' Months';
}
}
$for .= empty($for) ? 'Gymnastics - ' . $dr4 : ', Gymnastics - ' . $dr4;
$c4 = ', Gymnastics - ' . $dr4;
}
you should use switch case instead of many if else.

Related

Showing color from ternary operator

I am trying to show a color if my ternary operator comes back as true and another one if it comes back as false. The operator is working but one thing is off. The code inside of the double quotes shows instead of the actual color itself. Anyone know how to fix this ?
$msg .= ($row['opened'] == '0') ? "background-color: #DDEDFF;" : "background-color: #000000;";
EDIT!!! - These are the only times my $msg variable shows up
public function getLatestMessage ($userLoggedIn, $user2) {
$query = $this->con->prepare('SELECT body, user_to, opened, date FROM messages WHERE
user_to = ? AND user_from = ? OR user_to = ? AND user_from = ? ORDER BY id DESC LIMIT 1');
$query->bind_param("ssss", $userLoggedIn, $user2, $user2, $userLoggedIn);
$query->execute();
$query_result = $query->get_result();
$msg = ""; //to hold the message data
if ($row = $query_result->fetch_assoc()) { //don't need a while here because we've limited the query to one record
//Timeframe
$date_time_now = date("Y-m-d H:i:s");
$start_date = new DateTime($row['date']); //Time of post
$end_date = new DateTime($date_time_now); //Current time
$interval = $start_date->diff($end_date); //Difference between dates
if($interval->y >= 1) {
if($interval->y == 1)
$time_message = $interval->y . "yr"; //1 year ago
else
$time_message = $interval->y . "yrs"; //1+ year ago
}
else if ($interval-> m >= 1) {
if($interval->d == 0) {
$days = " ago";
}
else if($interval->d == 1) {
$days = $interval->d . "d";
}
else {
$days = $interval->d . "d";
}
if($interval->m == 1) {
$time_message = $interval->m . "month";
}
else {
$time_message = $interval->m . "months";
}
}
else if($interval->d >= 1) {
if($interval->d == 1) {
$time_message = "Yesterday";
}
else {
$time_message = $interval->d . "d ";
}
}
else if($interval->h >= 1) {
if($interval->h == 1) {
$time_message = $interval->h . "hr";
}
else {
$time_message = $interval->h . "hrs";
}
}
else if($interval->i >= 1) {
if($interval->i == 1) {
$time_message = $interval->i . "m";
}
else {
$time_message = $interval->i . "m";
}
}
else {
if($interval->s < 30) {
$time_message = "Just now";
}
else {
$time_message = $interval->s . " seconds ago";
}
}
$msg .= ($row['user_to'] == $userLoggedIn) ? "They said: " : "You said: ";
$msg .= ' ';
$msg .= $body = $row['body'];
$msg .= ' ';
$msg .= $time_message ;
$msg .= ' ';
$msg .= ($row['opened'] == '0') ? "background-color: #DDEDFF;" : "background-color: #000000;";
}
return $msg;
}
Your code is doing exactly what you are telling it: outputting a string that says "background-color: ... ".
How would the browser know you want to style the text with that color instead of presenting those words to the user?
You need to instead specify for the browser that this is a style you are giving it.
Instead of
$msg .= ($row['opened'] == '0') ? "background-color: #DDEDFF;" : "background-color: #000000;";
try something like:
$color = $row['opened'] == '0' ? "#DDEDFF" : "#000000";
$msg .= "<span style='background-color:$color'>THE TEXT YOU WANT TO COLORIZE</span>";
COMPLETE EXAMPLE
<?php
function getLatestMessage($opened) {
$color = $opened ? "#DDEDFF" : "#000000";
$msg = "<span style='background-color:$color'>THE TEXT YOU WANT TO COLORIZE</span>";
return $msg;
}
echo getLatestMessage(true);
echo getLatestMessage(false);
?>

PHP: Set table cell background based on result

I'm trying to generate colours based on output of a csv (originally formatted ping).
I can get the values no problem,but the if, ifelse, else doesn't seem to be working.
if($min > 0.499 && $min <= 1) {$tcolor = $yellow;} elseif($min >= 1.0) {$tcolor = $red; } else { $tcolor = $white;}
if($avg > 0.499 && $avg <= 1) {$tcolor = $yellow;} elseif($avg >= 1.0) {$tcolor = $red; } else { $tcolor = $white;}
if($max > 0.499 && $max <= 1) {$tcolor = $yellow;} elseif($max >= 1.0) {$tcolor = $red; } else { $tcolor = $white;}
if($mdev > 0.499 && $mdev <= 1) {$tcolor = $yellow;} elseif($mdev >= 1) {$tcolor = $red; } else { $tcolor = $white;}
echo "<tr><td>$ip</td><td bgcolor=\"$tcolor\">$min<br>$tcolor</td><td bgcolor=\"$tcolor\">$avg<br>$tcolor</td><td bgcolor=\"$tcolor\">$max<br>$tcolor</td><td bgcolor=\"$tcolor\">$mdev</td></tr>";
Edit: As many asked about the colour code already, I have it above the code listed as
$yellow = "#FFFF66";
$red = "#FF0000";
$white = "#FFFFFF";
And the number I see the overlap, but I've also tried with 0.999 with the same result.
It sounds like you got it solved, but you should look at using functions like so, so you don't have to repeat if statements like you did.
<?php
function setCellColor($value){
$color = '#FFFFFF';
if($value >= 0.5 && $value <= 1){
$color = '#FFFF00';
} else if($value > 1) {
$color = '#FF0000';
}
return ' style="background: ' . $color . '" ';
}
echo '<tr><td>' . $ip . '</td><td ' . setCellColor($min) . '>' . $min . '</td><td ' . setCellColor($avg) . '>' . $avg . '</td><td ' . setCellColor($max) . '>' . $max . '</td><td ' . setCellColor($mdev) . '>' . $mdev . '</td></tr>';
?>
Check this out:
function build_td_with_style($value) {
switch (true) {
case $value > 0.5 && $value <= 1 :
$class = 'yellow';
break;
case $value > 1 :
$class = 'red';
break;
default :
$class = 'white';
}
return "<td class='{$class}'>{$value}</td>";
}
$tds = implode('', array_map("build_td_with_style", [$min, $avg, $max, $mdev]));
echo "<tr><td>{$ip}</td>{$tds}</tr>";
style.css :
.yellow {
background-color: yellow;
}
.red {
background-color: red;
}
.white {
background-color: white;
}

How To Change Numbers Based On Results

I have a follow up question on something I got help with here the other day (No Table Three Column Category Layout).
The script is as follows:
$res = mysql_query($query);
$system->check_mysql($res, $query, __LINE__, __FILE__);
$parent_node = mysql_fetch_assoc($res);
$id = (isset($parent_node['cat_id'])) ? $parent_node['cat_id'] : $id;
$catalist = '';
if ($parent_node['left_id'] != 1)
{
$children = $catscontrol->get_children_list($parent_node['left_id'], $parent_node['right_id']);
$childarray = array($id);
foreach ($children as $k => $v)
{
$childarray[] = $v['cat_id'];
}
$catalist = '(';
$catalist .= implode(',', $childarray);
$catalist .= ')';
$all_items = false;
}
$NOW = time();
/*
specified category number
look into table - and if we don't have such category - redirect to full list
*/
$query = "SELECT * FROM " . $DBPrefix . "categories WHERE cat_id = " . $id;
$result = mysql_query($query);
$system->check_mysql($result, $query, __LINE__, __FILE__);
$category = mysql_fetch_assoc($result);
if (mysql_num_rows($result) == 0)
{
// redirect to global categories list
header ('location: browse.php?id=0');
exit;
}
else
{
// Retrieve the translated category name
$par_id = $category['parent_id'];
$TPL_categories_string = '';
$crumbs = $catscontrol->get_bread_crumbs($category['left_id'], $category['right_id']);
for ($i = 0; $i < count($crumbs); $i++)
{
if ($crumbs[$i]['cat_id'] > 0)
{
if ($i > 0)
{
$TPL_categories_string .= ' > ';
}
$TPL_categories_string .= '' . $category_names[$crumbs[$i]['cat_id']] . '';
}
}
// get list of subcategories of this category
$subcat_count = 0;
$query = "SELECT * FROM " . $DBPrefix . "categories WHERE parent_id = " . $id . " ORDER BY cat_name";
$result = mysql_query($query);
$system->check_mysql($result, $query, __LINE__, __FILE__);
$need_to_continue = 1;
$cycle = 1;
$column = 1;
$TPL_main_value = '';
while ($row = mysql_fetch_array($result))
{
++$subcat_count;
if ($cycle == 1)
{
$TPL_main_value .= '<div class="col'.$column.'"><ul>' . "\n";
}
$sub_counter = $row['sub_counter'];
$cat_counter = $row['counter'];
if ($sub_counter != 0)
{
$count_string = ' (' . $sub_counter . ')';
}
else
{
if ($cat_counter != 0)
{
$count_string = ' (' . $cat_counter . ')';
}
else
{
$count_string = '';
}
}
if ($row['cat_colour'] != '')
{
$BG = 'bgcolor=' . $row['cat_colour'];
}
else
{
$BG = '';
}
// Retrieve the translated category name
$row['cat_name'] = $category_names[$row['cat_id']];
$catimage = (!empty($row['cat_image'])) ? '<img src="' . $row['cat_image'] . '" border=0>' : '';
$TPL_main_value .= "\t" . '<li>' . $catimage . '' . $row['cat_name'] . $count_string . '</li>' . "\n";
++$cycle;
if ($cycle == 7) // <---- here
{
$cycle = 1;
$TPL_main_value .= '</ul></div>' . "\n";
++$column;
}
}
if ($cycle >= 2 && $cycle <= 6) // <---- here minus 1
{
while ($cycle < 7) // <---- and here
{
$TPL_main_value .= ' <p> </p>' . "\n";
++$cycle;
}
$TPL_main_value .= '</ul></div>'.$number.'
' . "\n";
}
I was needing to divide the resulting links into three columns to fit my html layout.
We accomplished this by changing the numbers in the code marked with "// <---- here".
Because the amount of links returned could be different each time, I am trying to figure out how to change those numbers on the fly. I tried using
$number_a = mysql_num_rows($result);
$number_b = $number_a / 3;
$number_b = ceil($number_b);
$number_c = $number_b - 1;
and then replacing the numbers with $number_b or $number_c but that doesn't work. Any ideas?
As mentioned before, you can use the mod (%) function to do that.
Basically what it does is to get the remainder after division. So, if you say 11 % 3, you will get 2 since that is the remainder after division. You can then make use of this to check when a number is divisible by 3 (the remainder will be zero), and insert an end </div> in your code.
Here is a simplified example on how to use it to insert a newline after every 3 columns:
$cycle = 1;
$arr = range (1, 20);
$len = sizeof ($arr);
for ( ; $cycle <= $len; $cycle++)
{
echo "{$arr[$cycle - 1]} ";
if ($cycle % 3 == 0)
{
echo "\n";
}
}
echo "\n\n";

Wrong calendar displaying after server crash

Few days ago server crashed and was down for few hours, after server become available, my calendar started to display wrong data. It had to show me current month and 5 next(half a year in total). Server data is correct. Any ideas whats wrong with calendar? Does mysql server time can make my calendar show wrong data?
if (!isset($_MONTH))
$_MONTH = 6;
if (isset($_POST['subscribe_month']))
$_MONTH = $class->_dig($_POST['subscribe_month']);
$sql = mysql_query("SELECT d.header, d.id FROM " . $class->_cfg['pfx'] . "workshops as w
LEFT JOIN " . $class->_cfg['pfx'] . "workshops_date as wd ON wd.cid=w.id
LEFT JOIN " . $class->_cfg['pfx'] . "dictionary as d ON d.id=wd.city
WHERE w.public='1' and wd.public='1' and wd.date_end>='" . date("Y-m-d") . "' a
nd wd.predprosomtr='0' " . $where . " ORDER BY d.rang");
$CityList = array();
while ($_sql = mysql_fetch_assoc($sql)) {
$CityList[$_sql['id']] = $_sql['header'];
}
if ($Fcity && $Fcity != 0)
$where.=" and d.id=" . $Fcity . "";
elseif ($_POST['city'] && $class->_dig($_POST['city']) > 0)
$where.=" and d.id=" . $class->_dig($_POST['city']) . "";
if ($CitySearch != 0)
$where.=" and wd.city=" . $CitySearch . " ";
$sql = mysql_query("SELECT w.header, w.direction, w.subheader, wd.colsmonth, wd.is_new, wd.public_date_finish, wd.p_date_finish, w.aliaslink, wd.aliaslink as wd_aliaslink, w.direction, wd.city, wd.date_start, d.header as city_name, wd.date_end, wd.cid, wd.id as wd_id, w.id as w_id FROM " . $class->_cfg['pfx'] . "workshops as w
LEFT JOIN " . $class->_cfg['pfx'] . "workshops_date as wd ON wd.cid=w.id
LEFT JOIN " . $class->_cfg['pfx'] . "dictionary as d ON d.id=wd.city
WHERE w.public='1' and wd.public='1' and wd.date_end>='" . date("Y-m-d") . "' and w.direction<>'' and wd.predprosomtr='0' " . $where . " ORDER BY wd.date_start, wd.city");
//$output.=$where;
$month = 12;
$year = date("Y");
while ($_sql = mysql_fetch_assoc($sql)) {
$view = true;
if ($_sql['public_date_finish'] == '1' && $_sql['p_date_finish'] < date("Y-m-d"))
$view = false;
if ($view) {
$arWorkshops[$_sql['w_id']] = $_sql;
if (!isset($arWorkshopsCity[$_sql['cid']][$_sql['city']]) && $_sql['city'] > 0)
$arWorkshopsCity[$_sql['cid']][$_sql['city']] = $_sql['city'];
if (isset($arWorkshopsDate[$_sql['cid']]['count']))
$arWorkshopsDate[$_sql['cid']]['count'] = $arWorkshopsDate[$_sql['cid']]['count'] + 1;
else
$arWorkshopsDate[$_sql['cid']]['count'] = 1;
$direct = explode('#', $_sql['direction']);
for ($i = 0; $i < count($direct); $i++) {
if (trim($direct[$i]) != '') {
$arDirectionList[$direct[$i]] = $direct[$i];
}
}
//$arDirectionList[$_sql['direction']]=$_sql['direction'];
if (!isset($arWorkshopsDate[$_sql['cid']][ceil($class->convert_date($_sql['date_start'], '.', "month"))]))
$arWorkshopsDate[$_sql['cid']][ceil($class->convert_date($_sql['date_start'], '.', "month"))] = $_sql;
if ($class->convert_date($_sql['date_start'], '.', "month") < $month && $class->convert_date($_sql['date_start'], '.', "year") == $year) {
$month = $class->convert_date($_sql['date_start'], '.', "month");
$year = $class->convert_date($_sql['date_start'], '.', "year");
}
//if($class->convert_date($_sql['date_start'], '.', "year")==(date("Y")+1))$year=$class->convert_date($_sql['date_start'], '.', "year");
//$output.=$_sql['header']."-".$_sql['date_start']."-".$_sql['wd_id']."<br>";
}
}
//var_dump($arWorkshopsDate[185]);
$output.='<table class="table"><tr><th width="60"> </th><th class="first" style="width:auto">Название</th>';
if ($_MONTH == 12)
$w = "5%"; else
$w = "9%";
for ($i = $month; $i < ($month + $_MONTH); $i++) {
if ($year == date("Y"))
$m = $i;else
$m++;
if ($m <= 12 && $year == date("Y")) {
$output.='<th class="month" style="width:' . $w . '">' . $class->convert_date($m, '.', "myear") . ' <span>' . $year . '</span></th>';
} else {
if ($m > 12) {
$m = 1;
$year = $year + 1;
}
$output.='<th class="month" style="width:' . $w . '">' . $class->convert_date($m, '.', "myear") . ' <span>' . $year . '</span></th>';
}
}
$output.=' <th style="width:10%">';
if ($typeblock == 'webinars')
$output.='Формат';
else
$output.='Город';
$output.='</th></tr>';
if (isset($arWorkshops)) {
//foreach($arWorkshops as $LO=>$listOrd){
foreach ($arWorkshops as $k => $value) {
if (!$direction || $direction == 0)
$direction2 = $class->_direction($value['direction']);
else
$direction2 = $direction;
foreach ($arWorkshopsCity[$k] as $LO => $listOrd) {
$output2 = "";
$link_date = "";
$pt = 0;
$m_nth = ceil($month);
$is_new_class = '';
for ($i = ceil($month); $i < ($month + $_MONTH); $i++) {
if ($m_nth > 12)
$m_nth = 1;
if (isset($arWorkshopsDate[$k][$m_nth]) && $arWorkshopsDate[$k][$m_nth]['city'] == $LO) {
$pt++;
if ($pt == 1)
$city_name = $arWorkshopsDate[$k][$m_nth]['city_name'];
//if(isset($_TYPE) && $_TYPE!=0)$output.='<td class="date"><a href="/'.$typeblock.'/'.$value['aliaslink'].'/'.$arWorkshopsDate[$k][$i]['wd_aliaslink'].'/">';
//else
if (($arWorkshopsDate[$k][$m_nth]['is_new'] == '1') || ($arWorkshopsDate[$k][$m_nth + 1]['is_new'] == '1')) {
$is_new_class = " it_is_new";
} else {
$is_new_class = '';
}
$output2.='<td class="date"><a href="/' . $typeblock . '/' . $arDictionaryID[$direction2]['aliaslink'] . '/' . $value['aliaslink'] . '/' . $arWorkshopsDate[$k][$m_nth]['wd_aliaslink'] . '/">';
$link_date = '/' . $typeblock . '/' . $arDictionaryID[$direction2]['aliaslink'] . '/' . $value['aliaslink'] . '/' . $arWorkshopsDate[$k][$m_nth]['wd_aliaslink'] . '/';
if ($arWorkshopsDate[$k][$m_nth]['colsmonth'] > 0)
$output2.=$class->convert_date($arWorkshopsDate[$k][$m_nth]['date_start'], '.', "day_month") . "</a><br />" . $arWorkshopsDate[$k][$m_nth]['colsmonth'] . " мес.";
elseif ($arWorkshopsDate[$k][$m_nth]['date_start'] == $arWorkshopsDate[$k][$m_nth]['date_end'])
$output2.=$class->convert_date($arWorkshopsDate[$k][$m_nth]['date_start'], '.', "day_month") . "</a>";
else
$output2.=$class->convert_date($arWorkshopsDate[$k][$m_nth]['date_start'], '.', "day_month") . "<br />-" . $class->convert_date($arWorkshopsDate[$k][$m_nth]['date_end'], '.', "day_month") . "</a>";
$output2.='</td>';
}else {
$output2.='<td></td>';
}
$m_nth++;
}
if (($arWorkshopsDate[$k][$m_nth]['is_new'] == '1')) {
$is_new_class = " it_is_new";
}
$output.='<tr><td class="' . $is_new_class . '"> </td><td>';
//if(isset($_TYPE) && $_TYPE!=0)$output.='<strong>'.$value['header'].'</strong>';
//else
if ($pt == 1 && $arWorkshopsDate[$k]['count'] == 1)
$link = $link_date;
else
$link = '/' . $typeblock . '/' . $arDictionaryID[$direction2]['aliaslink'] . '/' . $value['aliaslink'] . '/';
$output.='<a href="' . $link . '"><strong>' . $value['header'] . '</strong>';
if (trim($value['subheader']) != '')
$output.=': ' . $value['subheader'] . '';
$output.='</a>';
$output.='</td>';
$output.=$output2;
$output.=' <td class="city">' . $city_name . '</td></tr>';
}
}
//}
}
$output.='</table>';
?>
Issue solved. By default some "good" coder made it show only from 12th month in $month = 12;
I just changed it to $month = date("m"); And this solved my issue

How to write this statement using PHP & CodeIgniter

I'm trying to figure out how to write a statement in my first CI app (and only second PHP app ever) and I'm stuck.
I have a junction table that holds book_id and user_id from their respective tables. I want to find out who has read a book and echo that back out, but I need the formatting to make sense. Here is the query:
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
And here's my logic for one person
// Get my user info
$user = $this->ion_auth->get_user();
// Tell me who has read it.
$this->db->select('user_id');
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
// If only one person has read it
if ($readQuery->num_rows() == 1) {
$readResult = $readQuery->row();
// And if that person was me...
if ($readResult->user_id == $user->id) {
$message = 'You have read this.';
// If it was someone else...
} else {
$reader = $this->ion_auth->get_user($readResult->user_id);
$message = "$reader->first_name $reader->last_name has read this";
}
// If two people have read it
}
So I'm good if only one person has read it. But when two people have read it, I want it to say "Name One and Name Two have read this." if the logged in person hasn't read it. If they're one of the two people, it should say "You and Name Two have read this".
And so on for 3-5. If 3-5 people have read it, the options would be "Name One, Name Two, and Name Three have read this" or "You, Name Two, and Name Three have read this." up to five people
And if it's 6 or more, it should just say the names of two of them, IE "You, Name Two, and 5 other people have read this."
I considered doing a conditional for each instance and then pushing all of the users to an array. Then I could use in_array() to see if the logged-in user has read it and try to report back, but I'm just having some trouble working up the logic.
Is there an easier way?
Thanks much in advance,
Marcus
I'd say use a switch statement with ranges. You'll have to do a bit of acrobatics to handle the issue of including "You" or not. The code below is untested but give you the general idea.
$message = "";
$readers = array();
$me_included = 0; // Counter increment if you're included in the reader list
$this->db->select('user_id');
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
foreach ($readQuery->result() as $row) {
if ($row->user_id == $user->id) {
$message = "You";
$me_included = 1;
} else {
$readers[] = $this->ion_auth->get_user($row->user_id);
}
}
$reader_count = $sizeof($readers) + $me_included;
switch(TRUE)
{
// One reader, not you
case( ($reader_count == 1) && ($me_included == 0) ):
$message .= $readers[0]->first_name . " " . $readers[0]->last_name . " has read this.";
break;
// Only you
case( ($reader_count == 1) && ($me_included == 1) ):
$message .= " have read this.";
break;
// Two readers
case( ($reader_count == 2) ):
for ($i = 0; $i <= sizeof($readers); $i++) {
if ($i == sizeof($readers)) {
$message .= " and ";
}
$message .= $readers[i]->first_name . " " . $readers[i]->last_name;
}
$message .= " have read this.";
break;
case( ($reader_count > 3) && ($reader_count < 6) ):
if ($me_included) {
$message .= ", ";
}
for ($i = 0; $i <= sizeof($readers); $i++) {
if ($i == sizeof($readers)) {
$message .= " and ";
}
$message .= $readers[i]->first_name . " " . $readers[i]->last_name;
if ($i != sizeof($readers)) {
$message .= ", ";
} else {
$message .= " have read this.";
}
}
break;
case( ($reader_count > 6) ):
if ($me_included) {
$message .= ", " . $readers[0]->first_name . " " . $readers[0]->last_name . " and " . ($reader_count - 2) . " others have read this.";
} else {
for ($i = 0; $i <= 1; $i++) {
$message .= $readers[0]->first_name . " " . $readers[0]->last_name . ", " . $readers[1]->first_name . " " . $readers[1]->last_name . " and " . ($reader_count - 2) . " others have read this.";
}
break;
}
$users = array();
while($row)
{
if(currentuser)
{
array_unshift($users,'You')
}
else
{
$users[] = row[name]
}
}
$count = $max = count($users);
if($max >= 6)
{
$max = 2;
}
$str = '';
for($i=0;$i<$max;$i++)
{
$str .= ($str == '' ? '' : ($i == $count-1 && $count < 6 ? ' And ' : ', ') ) . $users[$i];
}
if($count >= 6)
{
$str .= ' and '.$count-2.' others'
}
This should help you along. It's pretty much pseudo-code but the logic is there to achieve what you want (I believe). You'd obviously want to not fetch all the rows if you are just showing a number of users but that can easily be accomplished.
There are actually a couple places we can optimize this.
1) In the initial query do a JOIN with the user table so we don't have to query again multiple times just for each name:
$readers = $this->db->select('id', 'first_name', 'last_name')->from('books_users')->join('users', 'books_users.id =users.id', 'left')->where('book_id' => $isbn);
2) Additionally, we can avoid iterating over the entire (potentially large) result set just to see if you read it, by doing a separate query:
$you_read = $this->db->get_where('books_users', array('book_id' => $isbn, 'user_id' => $user->id));
Just for the sake of completeness, here is the final code I used. Hopefully it will be of use to someone.
// Find out who has read this book
// Get the users
$current_user = $this->ion_auth->get_user();
$users = $this->ion_auth->get_users();
// Get the readers
$this->db->select('user_id');
$query = $this->db->get_where('books_users', array('book_id' => $isbn));
// If there were results
$readers = array();
if ($query->num_rows() > 0) {
foreach ($users as $user) {
if ($current_user->id == $user->id) {
array_unshift($readers, 'You');
} else {
$readers[] = $user->first_name . ' ' . $user->last_name;
}
$count = $max = count($readers);
if ($max >= 6) {
$max = 2;
}
$message = '';
for ($i = 0; $i < $max; $i++) {
$message .= ($message == '' ? '' : ($i == ($count - 1) && ($count < 6) ? ' and ' : ', ')) . $readers[$i];
}
if ($count >= 6) {
$message .= ' and ' . ($count - 2) . ' others';
}
$message .= ($count == 1 && !$current_user->id ? ' has ' : ' have ') . 'read this.';
}
} else {
$message = 'Be the first to read this.';
}

Categories