Parsing Text File into Variables with PHP - php

Need some help with parsing a text file into PHP. The file is generated by a PHP script, so I don't have control over the content formatting. The text file looks like this:
7/4/2013-7/4/2013 Best Legs in a Kilt To start the summer
off with a bang, the Playhouse has teamed up with the folks at The
Festival. kilt.jpg 1,1,0,
-
7/8/2013-7/23/2013 Hot Legs Yes, folks, it's all platform
shoes, leisure suits, and crazy hair-do's. hotstuff.jpg
1,1,0,
-
The code that I have thus far is:
$content = file_get_contents('DC_PictureCalendar/admin/database/cal2data.txt');
list($date, $showname, $summary, $image, $notneeded, $notneeded2) = explode("\n", $content);
echo 'Show Name' . $showname . '<br/>';
This only gets me the first show title, I need to grab all of them. I'm sure a For loop would do it, but not sure how to do it based on the contents of the file. All I need is the 2nd line (show title) and the 4th line (image). Any help? Thanks in advance.

If you are reading the entire file into an array anyway, then just use file() which will read each line into an array.
$content = file('DC_PictureCalendar/admin/database/cal2data.txt', FILE_IGNORE_NEW_LINES);
You can then filter all the lines you don't want like this
$content = array_diff($content, array('1,1,0', '-'));
You can then break into chunks of 4 lines each (i.e. one item per entry)
$content_chunked = array_chunk($content, 4);
This would give you an array like
Array(
0 => Array(
0 => '7/4/2013-7/4/2013',
1 => 'Best Legs in a Kilt',
2 => 'To start the summer off with a bang, the Playhouse has teamed up with the folks at The Festival.',
3 => 'kilt.jpg'
),
1 => Array(
0 => '7/8/2013-7/23/2013',
1 => 'Hot Legs',
2 => 'Yes, folks, it's all platform shoes, leisure suits, and crazy hair-do's.',
3 => 'hotstuff.jpg'
) ... etc.
)
I would then map this array into a useful array of objects with property names that are meaningful to you:
$items = array_map(function($array)) {
$item = new StdClass;
$item->date = $array[0];
$item->showname = $array[1];
$item->summary = $array[2];
$item->image = $array[3];
return $item;
}, $content_chunked);
That would leave you with an array of objects like:
Array(
0 => stdClass(
'date' => '7/4/2013-7/4/2013',
'showname' => 'Best Legs in a Kilt',
'summary' => 'To start the summer off with a bang, the Playhouse has teamed up with the folks at The Festival.',
'image' => 'kilt.jpg'
),
1 => stdClass(
'date' => '7/8/2013-7/23/2013',
'showname' => 'Hot Legs',
'summary' => 'Yes, folks, it's all platform shoes, leisure suits, and crazy hair-do's.',
'image' => 'hotstuff.jpg'
) ... etc.
)

Related

CodeIgniter - foreach loop

TL;DR
I'm trying to loop all the rows and output it with html. When I'm looping it, I get an array with the properties and values of a single row which is also the last row, when I do not loop it, I get 2 arrays (each array is a row) within an array. For some reason it doesn't loop it and display all the rows as it should, how do I fix this?
I'm trying to make a loop of sections and the articles within them, where as each article has a parent section.
In the database, there are 5 sections and 2 articles, article #1 has section #1 as it's parent and article #2 has section #2 as it's parent.
When print it as an array without looping it, I get the following array;
Array
(
[0] => Array
(
[s_id] => 1
[s_name] => News
[s_slug] => news
[s_visibility] => 1
[s_type] => 1
[s_status] => 1
[s_permission] => 0
[s_external] => 0
[s_location] => news
[s_color] => 1
[s_homepage] => 1
[a_id] => 1
[a_section] => 1
[a_title] => Ted Cruz’s ‘Secret’ Skill That No President Has Likely Had Since Thomas Jefferson
[a_description] => Apparently Cruz, whose famed 2013 marathon filibuster speech over defunding Obamacare jumped across a range of topics, has an uncanny capability to remember things he hears verbatim.
[a_content] => Apparently Cruz, whose famed 2013 marathon filibuster speech over defunding Obamacare jumped across a range of topics, has an uncanny capability to remember things he hears verbatim.
[a_views] => 0
[a_visibility] => 1
[a_date] => 17.11.2015
[a_author] => 1632422528
[a_category] => 1
[a_slug] =>
)
[1] => Array
(
[s_id] => 2
[s_name] => VOD
[s_slug] => vod
[s_visibility] => 1
[s_type] => 2
[s_status] => 1
[s_permission] => 0
[s_external] => 0
[s_location] => vod
[s_color] => 2
[s_homepage] => 1
[a_id] => 2
[a_section] => 2
[a_title] => GTA V PC Edition Released
[a_description] => Wondering where the score is? Our GTA Online review will remain scoreless, as a score does not properly reflect its continuously changing nature. Here's how and why we decided to do it this way.
[a_content] => Wondering where the score is? Our GTA Online review will remain scoreless, as a score does not properly reflect its continuously changing nature. Here's how and why we decided to do it this way.
[a_views] => 0
[a_visibility] => 1
[a_date] => 19.11.2015
[a_author] => 1632422528
[a_category] => 1
[a_slug] =>
)
)
But when I run it into a foreach loop, it outputs only a single array which is the later one (1).
I'm using CodeIgniter 3, the loop is inside a library called "Global_functions",
The model is "Functions_model".
Global_functions (only the related function, not the entire class because it contains other unrelated functions):
public function get_homepage_sections()
{
$getHomeData = $this->CI->functions_model->get_homepage_data();
foreach ($getHomeData as $get_sections)
{
switch ($get_sections['s_color'])
{
case 1:
$sectionColor = "blue";
break;
case 2:
$sectionColor = "purple";
break;
case 3:
$sectionColor = "orange";
break;
case 4:
$sectionColor = "green";
break;
default:
$sectionColor = "";
break;
}
$outputData = '
<li>
<div><h2 class="category ' . $sectionColor . '">' . $get_sections['s_name'] . '</h2></div>';
$outputData .= '
</li>';
}
return $get_sections;
}
Functions_model;
public function get_homepage_data()
{
$selected_columns = array(
'sections.s_id',
'sections.s_name',
'sections.s_slug',
'sections.s_visibility',
'sections.s_type',
'sections.s_status',
'sections.s_permission',
'sections.s_external',
'sections.s_location',
'sections.s_color',
'sections.s_homepage',
'articles.a_id',
'articles.a_section',
'articles.a_title',
'articles.a_description',
'articles.a_content',
'articles.a_views',
'articles.a_visibility',
'articles.a_date',
'articles.a_author',
'articles.a_category',
'articles.a_slug'
);
$query = $this->db->select( $selected_columns )
->from( config_item('sections') . ', ' . config_item('articles') )
//->join( config_item('articles'), 'articles.a_section = sections.s_id' )
->where( 'articles.a_section = sections.s_id' )
//->or_where( 'user_email', $user_string )
->get();
if ( $query->num_rows() >= 1 )
{
return $query->result_array();
}
}
Being called from the controller as follows (homepageSection);
public function index()
{
/* if ($this->require_role('admin')) {
echo $this->load->view('examples/page_header', '', TRUE);
echo '<p>You are logged in!</p>';
echo $this->load->view('examples/page_footer', '', TRUE);
}*/
// return $isAutoRememberMe;
//extra_for_auth();
// Call a function of the model
$data['getGlobalMessage'] = $this->global_functions->get_global_message();
$data['userOptions'] = $this->global_functions->extra_for_auth();
$data['homepageSection'] = $this->global_functions->get_homepage_sections();
//print_r ($data);
$this->parser->parse('template/header', $data);
$this->parser->parse('sections/homepage', $data);
$this->load->view('template/footer');
}
section/homepage file contains the call {homepageSection}, as you can see the parser is called and parses the file rather than loading it with view().
I think there is an error in get_home_sections()
instead of:
return $get_sections;
you should:
return $getHomeData
you are returning the last item from the array, that looks like the problem you stated.
Another point i see a little bit confusing is the var you are cummulating html.
$outputData is being reset in each loop, and you are not doing nothing with it. It's a good idea to initialize it at the begining of the funcion as empty string
$outputData = '';
and in the loop you should do an additive assingment with .=

Converting PHP array manipulation to Ruby hashes

I've written this script to be run in PHP, and am trying to convert it to Ruby.
Code:
$cases = array();
foreach($results as $result)
{
if(!array_key_exists($result['id'], $cases))
$cases[$result['id']] = array($result);
else
$cases[$result['id']][] = $result;
}
foreach($cases as $key => $case)
{
foreach($case as $payment)
{
if(count($case) > 1)
{
$cases[$key]['total'] += ($payment['p1'] > $payment['p2']) ? $payment['p1'] : $payment['p2'];
} else {
$cases[$key]['total'] = ($payment['p1'] > $payment['p2']) ? $payment['p1'] : $payment['p2'];
}
}
}
In Ruby, I have the results as an array returned by MySQL (using mysql2 gem). Using the loop below, it prints every row. How can I check if the key exists when it does not provide keys?
What's the best way to implement this code in Ruby? How can I add a hash onto a hash in Ruby similar to adding an array onto an array in PHP.
results.each(:as => :array) do |row|
puts row.inspect
end
More explanation:
PHP Structure
Array(
0 => Array(
Array(
[id] => 'random id',
[p1] => 534,
[p2] => 105
),
Array(
[id] => 'random id',
[p1] => 335,
[p2] => 425
)
),
1 => Array(
Array(
[id] => 'random id',
[p1] => 259,
[p2] => 124
)
)
)
And i'm trying to iterate over each array inside the first, and if p1 > p2, add p1 to the total key on that array. i.e., the 0 index would look like this:
0 => Array(
'total' => 959,
Array(
[id] => 'random id',
[p1] => 534,
[p2] => 105
),
Array(
[id] => 'random id',
[p1] => 335,
[p2] => 425
)
)
Are you trying to group by result['id']? I believe that "translating" your PHP code to ruby will look something like this:
cases = {}
results.each do |result|
if cases[result['id']]
cases[result['id']] << result
else
cases[result['id']] = [result]
end
end
Another way to get the same result is to use group_by:
cases = results.group_by { |result| result['id'] }
The second part "translated" to ruby will look something like this:
cases.each do |key, c|
c.each do |payment|
if c.count > 1
c['total'] += (payment['p1'] > payment['p2']) ? payment['p1'] : payment['p2']
else
c['total'] = (payment['p1'] > payment['p2']) ? payment['p1'] : payment['p2']
end
end
end
(this will actually not work in ruby, since an array cannot have an arbitrary key like 'total' - it accepts only numbers in its brackets. You will have to modify this code to hold the totals in a different structure)
Again, a more idiomatic way of summing up the max between 'p1' and 'p2' of each payment in each case might look more like this:
totals = cases.values.map do |c|
c.inject(0) { |sum, payment| sum + [payment['p1'], payment['p2']].max }
end

PHPExcel Background Color Logic

I have a very confusing issue with PHPExcel. I have 800 students. I'm generated a spreadsheet which lists how much praise (on a daily basis for the current month) that the student has has.
For instance, it may look like this:
+---------------+-----+-----+-----+-----+
| Student Name | 1st | 2nd | 3rd | 4th | ...
+---------------+-----+-----+-----+-----+
| Test Student | 2 | 0 | 3 | 7 |
+---------------+-----+-----+-----+-----+
I want to change the background color of the cells which are greater (or equal to) 5. I use a loop to loop over the students, and days. This is my code:
for($d=1; $d<=$daysInCMonth; $d++)
{
$phpExcel
->getSheetByName('Monthly Leaderboard')
->setCellValue($alphabetArray[($d+7)] . ($recordCount+5), $record['monthlyReport'][$MonthlyReportKeys[($d-1)]]);
if($record['monthlyReport'][$MonthlyReportKeys[($d-1)]]>=5)
{
$cellId = $alphabetArray[($d+7)] . ($recordCount+5);
$phpExcel
->getSheetByName('Monthly Leaderboard')
->getStyle($cellId)
->applyFromArray(
array('fill' => array('type' => PHPExcel_Style_Fill::FILL_SOLID,'color' => array('rgb' => '000000'))
));
}
}
To help understand the code, the initial for loop loops through from 1 up until the number of days in the current month (IE 30 for June). It then sets cells value as the number of points for each given day.
This all works perfectly. Now, the if condition will catch cells which have a value of greater (or equal to) 5.
The code $alphabetArray[($d+7)] . ($recordCount+5) grabs the current cell ID in the iteration. I know this works fine as well, because if I echo it to the screen, the first output is T5 which is a cell greater than 5.
If I implicitly specify T5 as the cell to color, it works fine. However, if I try to use the value of $cellId to dynamically color all cells for my condition, none of the cells are colored.
I know the cell ID is 100% correct, I know the coloring statement is correct (as it does color cells if I refer to them specifically). It just doesn't want to play dynamically.
Any ideas?
Thanks
Phil
This is quite an old question now, but I found it after having the same problem. After digging into the code I found something that does work. So thought I would add it in here for any future finder.
For conditional coloring of the background the method of just setting the color of the fill doesn't seem to work. e.g.
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'color' => array(
'rgb' => 'FFC7CE'
),
)
The above works perfectly well when applied directly to a cell, but when used in a conditional styling. If just does nothing. However if you change it to
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'startcolor' => array(
'rgb' => 'FFC7CE'
),
'endcolor' => array(
'rgb' => 'FFC7CE'
),
)
The background colors as expected. It looks like the conditional coloring of a background needs the start and end colors specified.
$headerStyle = array(
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'00B4F2'),
),
'font' => array(
'bold' => true,
)
);
$borderStyle = array('borders' =>
array('outline' =>
array('style' => PHPExcel_Style_Border::BORDER_THICK,
'color' => array('argb' => '000000'), ),),);
//HEADER COLOR
$objPHPExcel->getActiveSheet()->getStyle('A1:'.'V1')->applyFromArray($headerStyle);
//SET ALIGN OF TEXT
$objPHPExcel->getActiveSheet()->getStyle('A1:V1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$objPHPExcel->getActiveSheet()->getStyle('B2:V'.$row)->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP);
//BORDER TO CELL
$objPHPExcel->getActiveSheet()->getStyle('A1:'.'V1')->applyFromArray($borderStyle);
$borderColumn = (intval($column) -1 );
$objPHPExcel->getActiveSheet()->getStyle('A1:'.'V'.$borderColumn)->applyFromArray($borderStyle);

Using supplier with largest margin using PHP logic

I have the following values from a database call that I want to apply some logic to. I thought I could originally use PHP's max however this doesn't appear to be the case.
I have three suppliers of a product. They might not all stock the item I am displaying, and they all offer a different margin, on a product by product basis though, so that is why I can't just say generally supplier 1 is better than supplier 2 etc.
$supplier1Live = 1
$supplier2Live = 1
$supplier3Live = 0
$marginSupplier1 = 20
$marginSupplier2 = 40
$martinSupplier3 = 50
In this example I would want to use Supplier 2 as they stock the product supplier2Live = 1 and also have the better margin than the other supplier who stocks the product (supplier1)
My mind however is drawing a complete blank in how to code this?
I thought I could add it to an array giving:
$array = array(
"supplier1" => array(
"live" => 1,
"margin" => 20
),
"supplier2" => array(
"live" => 1,
"margin" => 40
),
"supplier3" => array(
"live" => 0,
"margin" => 50
)
);
And run something on that, but not sure what to.
Filter the array using array_filter (filter by live==1), and then find the maximum out of the resultant array (maximum on the "margin" value)
Like this, if I understand correctly
$array = array(
"supplier1" => array(
"live" => 1,
"margin" => 20
),
"supplier2" => array(
"live" => 1,
"margin" => 40
),
"supplier3" => array(
"live" => 0,
"margin" => 50
)
);
$res = array_filter($array,function($v){return $v["live"];});
$supplier = array_reduce($res, function($a, $b){
return $a["margin"]>$b["margin"]?$a:$b;
});
print_r($supplier);
Try something like this:
$best_supplier = null;
$best_supplier_margin = null;
foreach($array as $name => $supplier) {
if($supplier['live']) {
if($supplier['margin'] > $best_supplier_margin || is_null($best_supplier_margin)) {
$best_supplier = $name;
$best_supplier_margin = $supplier['margin'];
}
}
}
if(is_null($best_supplier)) throw new Exception('No suppliers are live!');
echo $best_supplier;
So you basically want to find the max of supplierXLive * marginSupplierX?
You can also implement a custom compare function and provide it to PHPs usort() function

how to replace text in a mysql database content array

im trying to get rid of unneccesary text in my database content.My code looks like this:
if(mysql_num_rows($result))
$items[] = array();
while($row = mysql_fetch_assoc($result)) {
$items[] = array('id' => $row['id'], 'cat' => $row['cat'], 'type' => $row['type'], 'name' => $row['name'], 'sub_title' => $row['sub_title'], 'display_date' => $row['display_date'], 'slug' => $row['slug'], 'ticket_url' => $row['ticket_url'], 'status' => $row['status'], 'content' => $row['content'], 'display_until' => $row['display_until'], 'photo' => $row['photo'], 'thumb' => $row['thumb']);
$removals = array('\n','\r','\t','<\/div>\r\n');
$spaces = "";
$parsedText = str_replace($removals, $spaces, $items);
}
echo json_encode(array('events'=>$items));
And the content then displays like this:
{"events":[[],{"id":"66","cat":"9","type":"2","name":"Oileán - A Celebration of the Blasket Islands","sub_title":"National Folk Theatre","display_date":"Tues 4th - Thurs 6th May at 8.30pm","slug":"This production celebrates life on the Blasket Islands in times past, exploring the way of life of the islanders and their spirit of survival. Oileán captures the essence of this island community, their traditions and customs, their wealth of song and story, their love of life and their strong kinship with one another. ","ticket_url":"","status":"1","content":"
\r\n\tPresented by the members of the National Folk Theatre of Ireland</strong>, this production celebrates and explores Blasket Island living while also challenging our own notions of identity as contemporary islanders. </div>\r\n
\r\n\t </div>\r\n
\r\n\tPremiered in 2003, Oileán</strong></em> marked the 50th</sup> anniversary of the departure of the Blasket Islanders to the mainland. The Great Blasket Island, located off the coast of West Kerry still retains an almost mystical significance for many, both from Ireland and abroad. The way of life of the islanders and their spirit of survival is framed in this production, which captures the essence of this island community, their traditions and customs, their wealth of song and story, their love of life and their strong kinship with one another. </div>\r\n
\r\n\t </div>\r\n
\r\n\tOileán</i></b> is delivered in the unique Siamsa style through the medium of dance, mime, music and song.</div>\r\n
\r\n\t </div>\r\n
\r\n\t
\r\n\t\t </div>\r\n\t
\r\n\t\tPlease note that due to the popularity of performances by the National Folk Theatre</strong>, some productions may be sold out well in advance and tickets may not be available on-line. However, we often have returns and tickets may be available nearer to the day of a performance</strong>. Please contact us directly by phone on: +353 (0)66 7123055.</em></div>\r\n\t
\r\n\t\t </div>\r\n\t
\r\n\t\t </div>\r\n</div>\r\n","display_until":"20100504","photo":"1269869378-oilean_side.jpg","thumb":"1269869378-oilean_thumb.jpg"},
The above display is the first item in the DB.
Im trying the replace all the \r , \n , etc in the above content?How can i go about this?Is what i have allready on the right track?
2 things
if(mysql_num_rows($result))
$items = array(); // not $items[], that would set the first item as an array
while($row = mysql_fetch_assoc($result)) {
$removals = array("\n","\r","\t","<\/div>\r\n");
$spaces = "";
$items[] = array(
'id' => $row['id'],
'cat' => $row['cat'],
'type' => $row['type'],
'name' => $row['name'],
'sub_title' => $row['sub_title'],
'display_date' => $row['display_date'],
'slug' => $row['slug'],
'ticket_url' => $row['ticket_url'],
'status' => $row['status'],
// replace the content here
// youll want to use preg_replace though otherwise youll end up with multiple </div>'s
'content' => str_replace( $removals, $spaces, $row['content'] ),
'display_until' => $row['display_until'],
'photo' => $row['photo'],
'thumb' => $row['thumb']
);
}
echo json_encode(array('events'=>$items));

Categories