skip same dates in foreach loop - php

this is a text file content which will be chatting database
you:2016-05-02 11:41:53 Hi
Muhammad:2016-05-02 11:42:41 Hi
you:2016-05-02 11:43:33 How are you ?
Muhammad:2016-05-02 14:44:56 I'm fine!
this is the code to loop to get content
<?php
$chat = file("members/cdn/1/chats/9188.txt");
foreach($chat as $line){
$name = strchr($line,":",true);
$message = explode(' ', substr(strchr($line,":"),1), 3);
if(some thing){
?>
<div>
<!-- here i want to skip the same dates -->
<?=$message[0];?>
</div>
<?php
}
?>
<div class="container">
<div class="arrow">
<div class="outer"></div>
<div class="inner"></div>
</div>
<div class="message-body">
<p><?=$message[2];?></p>
<p class="message_time"><?=date("g:i a", strtotime($message[1]));?></p>
</div>
</div>
<div class="spacer"></div>
<?php
}
?>
I want the date of the message appear one time above of messages in the same date

Simply remember that date you last used and then compare it to the one in $message[0]
<?php
$lastDate = NULL;
$chat = file("members/cdn/1/chats/9188.txt");
foreach($chat as $line) :
$name = strchr($line,":",true);
$message = explode(' ', substr(strchr($line,":"),1), 3);
if($lastDate != $message[0]) :
$lastDate = $message[0];
?>
<div><?=$message[0];?></div>
<?php
endif;
?>
<div class="container">
<div class="arrow">
<div class="outer"></div>
<div class="inner"></div>
</div>
<div class="message-body">
<p><?=$message[2];?></p>
<p class="message_time"><?=date("g:i a", strtotime($message[1]));?></p>
</div>
</div>
<div class="spacer"></div>
<?php
endforeach;
?>

Try this:
$prevDate[] = array();
foreach($chat as $line){
$name = strchr($line,":",true);
$message = explode(' ', substr(strchr($line,":"),1), 3);
if(some thing){
?>
<div>
<!-- here i want to skip the same dates -->
<?php
if(!in_array($message[0],$prevDate)) { // check if date exist in array - means displayed previously or not
echo $message[0];
$prevDate = $message[0]; // store date in array so that next time you can check whether it has been already displayed or not
}
?>
</div>
<?php
}
?>
<div class="container">
<div class="arrow">
<div class="outer"></div>
<div class="inner"></div>
</div>
<div class="message-body">
<p><?=$message[2];?></p>
<p class="message_time"><?=date("g:i a", strtotime($message[1]));?></p>
</div>
</div>
<div class="spacer"></div>
<?php
}

First, you can use list assignment to get the components split out into separate vars:
list($user,$date,$time,$message) = explode(' ', substr(strchr($line,":"),1), 4);
Then you can use a simple comparison to see if the date is new:
if ($date != $last_date) {
$last_date = $date;
?><div><?=$date?></div><?php
}
You should declare $last_date before the loop, but you can leave its value undefined.

Related

After 500 results displayed from DB html/css loses formatting

I have a page that runs off a local webserver that is uses SQLite as its database. As its used local I am not worried about listing all results on one page as they load super fast. I am having an issue with it though as after 500 results are displayed from SQLite3 the formatting goes all wonky and starts stacking them on top of each other. Everything before that is fine. Its written in php. Info was entered into the database using htmlspecialchars so I dont believe that is the issue. The code that builds each record in the loop is
$list = '';
while($row = $results->fetchArray()) {
$id = $row["id"];
$MovieTitle = $row["MovieTitle"];
$MovieYear = $row["MovieDate"];
$MovieRes = $row["MovieRes"];
$FileName = $row["FileName"];
$Summary = $row["Summary"];
$Genres = $row["Genres"];
$PictureLocation = $row["PictureLocation"];
$Rating = $row["Rating"];
$ReleaseDate = $row["ReleaseDate"];
$list .= '<div class="box">
<div class="movie">
<div class="movie-image"><span class="play"><span class="name">'.$MovieTitle.'</span></span><img src="'.$ThumbnailPic.'" alt=""></div>
<div class="rating">
<p>RATING: '.$Rating.'</p>
<div class="stars">
<div class="'.$StarGraphic.'"></div>
</div>
<span class="comments"></span></div>
</div>';
}
and i just echo them them in the html as such
<html>
<body>
<div id="main">
<br>
<?php echo $list; ?>
</div>
</body>
</html>
Your HTML is wrong, you did not close <div class="box"> and <span class="play"> tags properly.
Correct HTML is:
<div class="box">
<div class="movie">
<div class="movie-image">
<span class="play">
<a href="movielist.php?movie='.$FileName.'">
<span class="name">'.$MovieTitle.'</span>
<img src="'.$ThumbnailPic.'" alt="">
</a>
</span>
</div>
<div class="rating">
<p>
RATING: '.$Rating.'
</p>
<div class="stars">
<div class="'.$StarGraphic.'"></div>
</div>
<span class="comments"></span>
</div>
</div>
</div>
Aso, you can have some tags or quotes in your database records. So you have to use escaping your variables before output http://php.net/manual/en/function.htmlspecialchars.php
Something like this:
$list = '';
while($row = $results->fetchArray()) {
$id = htmlspecialchars($row["id"]);
$MovieTitle = htmlspecialchars($row["MovieTitle"]);
$MovieYear = htmlspecialchars($row["MovieDate"]);
$MovieRes = htmlspecialchars($row["MovieRes"]);
$FileName = htmlspecialchars($row["FileName"]);
$Summary = htmlspecialchars($row["Summary"]);
$Genres = htmlspecialchars($row["Genres"]);
$PictureLocation = htmlspecialchars($row["PictureLocation"]);
$Rating = htmlspecialchars($row["Rating"]);
$ReleaseDate = htmlspecialchars($row["ReleaseDate"]);
$list .= '<div class="box">
<div class="movie">
<div class="movie-image"><span class="play"><span class="name">'.$MovieTitle.'</span></span><img src="'.$ThumbnailPic.'" alt=""></div>
<div class="rating">
<p>RATING: '.$Rating.'</p>
<div class="stars">
<div class="'.$StarGraphic.'"></div>
</div>
<span class="comments"></span></div>
</div>';
}

Re-order Show Feed XML

I have the following code which displays a theatre show feed on my website, coming from an external ticketing company.
<!-- PULL IN SHOW FEED -->
<div class="container">
<div class="col-md-12 whats-on-feed">
<!-- PULL IN SHOW FEED -->
<div class="container">
<div class="col-md-12 whats-on-feed">
<?php
$xml = simplexml_load_file('https://tickets.leicesterymca.co.uk/feed/shows');
if(isset($wp_query->query_vars['month'])) {
$month = $wp_query->query_vars['month'];
$fromDate = date("Y"). '-'. $month;
$shows = $xml->xpath("//*[contains(ActiveFrom,'$fromDate')]");
}else if(isset($wp_query->query_vars['genre'])) {
$genre = str_replace("-", " ", $wp_query->query_vars['genre']);
if($genre != 'all'){
$shows = $xml->xpath("//*[Genres/Genre/#Name='$genre']");
}else{
$shows = $xml;
}
}else{
$shows = $xml;
}
?>
<div class="block-grid-xs-1 block-grid-sm-2 block-grid-md-3 block-grid-lg-4 show-list">
<?php
$i = 1;
foreach ($shows as $Show) {
$activeFrom=date_create($Show->ActiveFrom);
$activeTo=date_create($Show->ActiveTo);
if(strlen($Show->ShowId) > 0){
?>
<div>
<div class="box">
<div class="caption">
<h3><?php echo $Show->Name ?></h3>
<p><?php echo $activeFrom->format('D d M Y'); ?></p>
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<a href='/show?showid=<?php echo $Show->ShowId ?>' class='btn btn-success btn-sm btn-clear-white'>More Info</a>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<a href='/buy?showid=<?php echo $Show->ShowId ?>' class='btn btn-success btn-sm btn-clear-white'>Buy Tickets</a>
</div>
</div>
</div>
<div class='image-holder' style='background-image: url("<?php echo $Show->SmallImageUrl ?>");' /></div>
</div>
</div>
<?php $i++; }} ?>
</div>
</div>
This is coming from an XML feed that the ticketing company outputs from their system.
Currently they are displaying in order of show ID, I think this is the default, but I need them to display in order of date - The data node in the xml feed for date is: ActiveFrom.
I have seen this solution:
<xsl:sort select="ActiveFrom" order="ascending" />
But I don't really know if A: it's the correct approach, or B: Where I would add it in relation to my code? Can anyone help?
You can try this code
$xml = 'https://tickets.leicesterymca.co.uk/feed/shows';
$data = simplexml_load_file($xml);
$encode = json_encode($data);
$decode = json_decode($encode, true);
$show = $decode['Show'];
//function to sort by array value
function date_compare($a, $b) {
$t1 = strtotime($a['ActiveFrom']);
$t2 = strtotime($b['ActiveFrom']);
return $t1 - $t2;
}
usort($show, 'date_compare');
//test active from value
foreach ($show as $time) {
echo $time['ActiveFrom'].'<br>';
}
//echo '<pre>'.print_r($show, true).'</pre>';
Edited
<?php
$xml = 'https://tickets.leicesterymca.co.uk/feed/shows';
$data = simplexml_load_file($xml);
$encode = json_encode($data);
$decode = json_decode($encode);
$results = $decode->Show;
//function to sort by object (not array)
function date_compare($a, $b) {
$t1 = strtotime($a->ActiveFrom);
$t2 = strtotime($b->ActiveFrom);
return $t2 - $t1; // reverse it to check it works or not $t2 - t1
}
usort($results , 'date_compare');
if(isset($wp_query->query_vars['month'])) {
$month = $wp_query->query_vars['month'];
$fromDate = date("Y"). '-'. $month;
$shows = $xml->xpath("//*[contains(ActiveFrom,'$fromDate')]");
}
else if(isset($wp_query->query_vars['genre'])) {
$genre = str_replace("-", " ", $wp_query->query_vars['genre']);
if($genre != 'all'){
$shows = $xml->xpath("//*[Genres/Genre/#Name='$genre']");
}else{
$shows = $results;
}
}
else {
$shows = $results;
}
?>
<!--next-->
<?php
$i = 1;
foreach ($results as $Show) {
$activeFrom = date_create($Show->ActiveFrom);
$activeTo = date_create($Show->ActiveTo);
if(strlen($Show->ShowId) > 0){
?>
<div>
<div class="box">
<div class="caption">
<h3><?php echo $Show->Name ?></h3>
<p><?php echo $activeFrom->format('D d M Y'); ?></p>
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<a href='/show?showid=<?php echo $Show->ShowId ?>' class='btn btn-success btn-sm btn-clear-white'>More Info</a>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<a href='/buy?showid=<?php echo $Show->ShowId ?>' class='btn btn-success btn-sm btn-clear-white'>Buy Tickets</a>
</div>
</div>
</div>
<div class='image-holder' style='background-image: url("<?php echo $Show->SmallImageUrl ?>");' /></div>
</div>
</div>
<?php $i++; }} ?>
</div>
</div>

Assign looped records to single variable using php

I need to get all looped records to single variable. I tried this but i got final records of loop. How do i get all records. Can you please solve this. Here i added my code,
$text = '';
$sql = mysql_query("SELECT * FROM table WHERE column_name = 'column_value'");
while($row = mysql_fetch_array($sql)){
$text = '<li><div class="row">
<div class="col-md-12 post">
<div class="row">
<div class="col-md-12">
<h5>
<strong>'.$row['field2'].'</strong></h4>
</div>
</div>
<div class="row post-content">
<div class="col-md-12">
<p style="margin-bottom:0px">
';
$text.= substr($row['field3'],0,150);
$text.= '...</p>
<a class="pull-right" href="'.$row['field2'].'.php">>> Read more</a>
</div>
</div>
</div>
</div></li>';
}
you are not concating your $text variable
$text = '';
while() { ...
$text .= '<li>...'; // you missed this dot
}
echo $text;

Trying to get property of non-object in Codeigniter?

My controller code just generate ten copies of the same data. And I put the data in an array of array.Controller Code Below:
for($i=0;$i < $this->per_page;$i++)
{
$temp['title'] = "test";
$temp['link'] = "localhost/cib/index.php";
$temp['month'] = '4';
$temp['day'] = '21';
$temp['authorlink'] = "localhost/cib/index.php/author";
$temp['author'] = "Charles";
$temp['content'] = "tetestersafaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
$results[] = $temp;
}
$data['main_content'] = 'report_list';
$data['posts'] = $results;
$this->load->view('include/templates', $data);
And I show the data generated by controller in the view page report_list, the code of report_list is
<div id="bg_top">
</div>
<div class = "container" id="content">
<div class="row-fluid">
<div class="span9" id="content_left">
<h2>解题报告列表</h2>
<link href="<?php echo base_url('assets/css/style.css') ?>" rel="stylesheet">
<?php if(!empty($posts) && is_array($posts)):?>
<?php foreach($posts as $post):?>
<div class="entry">
<h2 class="entrytitle"><?php echo anchor($post->link, $post->title)?><span></span></h2>
<div class="entrymeta1">
<div class="meta-date">
<span class="meta-month"><?php echo $post->month?></span>
<span class="meta-day"><?php echo $post->day?></span>
</div>
<span class="meta-author"><?php echo anchor($post->authorlink, $post->author)?></span>
<span class="meta-category"></span>
<span class="meta-comment"></span>
<div class="clear"></div>
</div><!-- [entrymeta1] -->
<div class="entrybody">
<p><?php echo $post->content;?><?php echo anchor($post->link, '阅读全文')?></p>
</div>
<div class="entrymeta3">
</div>
</div><!-- [entry] -->
<?php endforeach;?>
<?php endif;?>
</div>
<div class="span3">
<?php echo "hello world2";?>
</div>
</div>
</div>
The question is where am wrong? why is there errors "Trying to get property of non-object"?
I tried to print the data in the controller, it works quite well.
foreach($results as $post)
{
foreach($post as $key=>$value)
{
echo $key.':'.$value;
echo '<br/>';
}
}
You need to print the variables in the view file in array style like this:
<?php echo anchor($post['link'], $post['title'])?>
Still you can always print the array to view the structure:
<?php echo "<pre>";print_r($posts);echo "</pre>";
My assumption is that
You are expecting $posts as array of objects. But in $posts in some loaction there is no object with property month, day etc. So just before the for loop you should look the type of $posts by
var_dump($posts)
This will give you the clear picture about your error
Change all the variables $post->link to array $post['link']
$post->month
$post->day
every fields that are using in template.

PHP dynamic alphabetical list with headers

So what I am trying to produce is something like this:
Except, I do not want duplicates, when there is more than one sign, it becomes duplicated as well as re creating the "C" list view header. My SQL query is creating a column known as first_char which is holding the first character of one of the other columns.......below is my code:
<?php foreach ($data as $name=>$signs): ?>
<!-- If name is not empty, create the header -->
<?php if (isset($name) && !empty($signs)): ?>
<div data-role='collapsible-set' data-theme='d'>
<h2>Username: <strong id="headerName"><?=$name?></strong></h2>
<?php endif; ?>
<?php endforeach; ?>
<!-- for every sign, take the first char and create a list view -->
<?php foreach ($signs as $char):
$current_char = '';
if ($char['first_char'] != $current_char){
$current_char = $char['first_char'];
echo '<ul data-role="listview" data-dividertheme="d" style="margin-top: 0;"><li data-role="list-divider">'.$current_char.'</li></ul><br>';
}
foreach ($signs as $sign):
if($current_char == $sign['first_char'] and !empty($signs)):
?>
<div data-role='collapsible' data-collapsed='true' data-icon='arrow-l'>
<h3><?=$sign['sign_name']?></h3>
<div class='ui-grid-a'>
<div class="ui-block-a">
<div class="ui-bar ui-bar-d" style="height:25px;">
<strong>Last Seen:</strong><strong id="text"><?=$sign['last_connected']?></strong>
</div>
</div>
<div class="ui-block-a">
<div class="ui-bar ui-bar-d" style="height:25px;">
<strong>Resolution:</strong><strong id="text"><?=$sign['resolution_x'].'x'.$sign['resolution_y']?></strong>
</div>
</div>
<div class="ui-block-a">
<div class="ui-bar ui-bar-d" style="height:25px;">
<strong>Group Name:</strong><strong id="text"><?=$sign['group_name']?></strong>
</div>
</div>
<div class="ui-block-a">
<div class="ui-bar ui-bar-d" style="height:25px;">
<strong>Sign Number:</strong><strong id="text"><?=$sign['sign_id']?></strong>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php endforeach; ?>
<?php endforeach; ?>
Thanks in advance
This fixes the previous error and gets rid of the duplication. $current_char needed to be outside the foreach loop, and removed the 2nd foreach.
<?php $current_char = '';?>
<?php foreach ($signs as $sign):?>
<?php
if ($sign['first_char'] != $current_char){
$current_char = $sign['first_char'];
echo '<ul data-role="listview" data-dividertheme="b" style="margin-top: 0;padding-top: 3px;"><li data-role="list-divider">'.$current_char.'</li></ul><br>';
}
?>
The query used above for SQL was this:
SELECT
user.username,
groups.group_id, groups.group_name,
sign.last_connected, sign.sign_id, sign.sign_name, sign.resolution_x, sign.resolution_y, LEFT(sign.sign_name, 1) AS first_char
FROM
user
LEFT JOIN(
groups, sign
)ON(
user.user_id = groups.userID AND
groups.group_id = sign.groupID
)
WHERE
username = ? AND
UPPER(sign.sign_name) BETWEEN "A" AND "Z"
OR sign.sign_name BETWEEN "0" AND "9" ORDER BY sign.sign_name

Categories