I am trying to align contents of two arrays in a tabular format and send an email. But the second column in the table doesn't align as desired. The content of the second column appears as a single row.
I'm attaching output table as well:
#!/usr/bin/perl
use strict;
use warnings;
use MIME::Lite;
use HTML::Entities;
my $msg;
my #Sucess = qw(s1 s2 s3 s4 s5 s6);
my #Failed = qw(f1 f2 f3 f4);
my $html = '<table style="width:600px;margin:0 100px" border="1" BORDERCOLOR="#000000">
<thead><th bgcolor="#9fc0fb">Successful</th><th bgcolor="#9fc0fb">Failed</th></thead>
<tbody>';
$html .= "<tr><td>$_</td>" for #Sucess;
$html .= "<td>$_</td>" for #Failed;
$html .= " </tr>";
$msg = MIME::Lite->new(
from => 'foo#abc.com',
To => 'foo#abc.com',
Subject => 'Status of Update',
Type => 'multipart/related'
);
$msg->attach(
Type => 'text/html',
Data => qq{
<body>
<html>$html</html>
</body>
},
);
MIME::Lite->send ('smtp','xyz.global.abc.com' );
$msg->send;
You need to replace your code that builds up the table with something that works in a logical order. HTML tables need to be defined row by row. You can't process all of the successes and then all of the failures.
I'd replace your middle section of code with something like this:
use List::Util qw[max];
my $max = max($#Sucess, $#Failed);
for (0 .. $max) {
$html .= '<tr><td>';
$html .= $Sucess[$_] // '';
$html .= '</td><td>';
$html .= $Failed[$_] // '';
$html .= "</td></tr>\n";
}
But actually, I would never put raw HTML in a Perl program. Use a templating system instead.
First you loop over each item in #Sucess and for each one you:
Create a new row
Create a cell in that row
$html .= "<tr><td>$_</td>" for #Sucess;
Then you look over each item in #Failed and for each one you:
Create a cell in the last row you created (for the most recent #Sucess)
$html .= "<td>$_</td>" for #Failed;
Finally, you explicitly close the last table row you created:
$html .= " </tr>";
To get the layout you desire (which is distinctly non-tabular) you need to work row by row. You can't deal with all the #Sucess and then all the #Failed.
my #Sucess= qw(s1 s2 s3 s4 s5 s6);
my #Failed= qw(f1 f2 f3 f4);
my $html = "<table>\n";
do {
my $s = shift #Sucess;
my $f = shift #Failed;
$html .= sprintf("<tr> <td> %s </td> <td> %s </td> </tr> \n", map { $_ // '' } $s, $f);
} while ( #Sucess or #Failed );
$html .= "</table>";
print $html;
Related
For example, I have a cgi where I have appended the shell script to a text file lstatus.txt as follows:
use IO::All;
use CGI;
system `bash /opt/apache/cgi-bin/lisa/lisapage3.sh > lstatus.txt`
io('lstatus.txt') > $data
Print << EOF;
<HTML>
<BODY>
<P>$data</P>
</BODY>
</HTML>
The output is as follows: EnterpriseDasboardService is Running. RegistryService is Running.PortalService is Running.VirtualServiceEnvironment is Running.
Now, I tried editing the text file lstatus.txt and the content in it is as follows:
EnterpriseDasboardService is Running > $abs
RegistryService is Running > $pqr
PortalService is Running > $qwe
VirtualServiceEnvironment is Running > $dfg
I have assigned the variables to each line in a text file as mentioned above.
I need each variable to be used in the table tag as follows:
<table>
<th>STATUS</th>
<tr>
<td>$abs</td>
.....
<td>$dfg</td>
</tr>
</table>
I want the output to be displayed in a table which I could not do by using the above changes.
Perhaps you want something like following code bellow
Note: read documentation for system
use strict;
use warnings;
use feature 'say';
use CGI;
my $filename = 'lstatus.txt';
my #arguments = ('/opt/apache/cgi-bin/lisa/lisapage3.sh','>',$filename);
system 'bash', #arguments;
open my $fh, '<', $filename
or die "Couldn't open $filename";
my #data = <$fh>;
close $fh;
chomp #data;
my $table = data2table(\#data);
$html =
"<html>
<head>
<title>Status webpage</title>
</head>
<body>
$table
</body>
</html>
";
say $html;
sub data2table {
my $data = shift;
my $table;
my $space = "\n\t\t";
$table = $space . '<table>';
$table .= $space . "\t<tr><th>STATUS</th></tr>";
$table .= $space . "\t<tr><td>$_</td></tr>" for #{$data};
$table .= $space . '</table>';
return $table;
}
So simply put, I have my PHP code generating a bunch of HTML. I then want to update a database entry like so
$wpdb->update("wp_table",
array( 'content' => $html ),
array( 'id' => 1 ),
array( '%s' ),
array( '%d' )
);
This simply does not work. Nothing in the database changes.
To debug, I placed the exact same code right above with one minor change, and it DOES WORK:
$wpdb->update("wp_sn_cached_popular_display",
array( 'content' => "hello" ),
array( 'id' => 1 ),
array( '%s' ),
array( '%d' )
);
(I swapped out the $html for a direct string.)
I can't even begin to comprehend why, and I've played around with it a lot. I've even done this and it DOES WORK too:
$string = "hello";
$wpdb->update("wp_sn_cached_popular_display",
array( 'content' => $string),
array( 'id' => 1 ),
array( '%s' ),
array( '%d' )
);
It's just the one $html variable is causing this function to not run, or something?
Compiling the $html variable is a bunch of stuff like this:
$html .= '<li>';
$html .= '<div class="upcoming-left">';
$html .= '<time datetime="' . $date . '" class="icon">';
$html .= '<em>' . $date_day.'</em>';
$html .= '<strong>' . $date_month . '</strong>';
$html .= '<span>' . $date_num . '</span>';
$html .= '</time>';
$html .= '</div>';
$html .= '<div class="upcoming-right">';
$html .= '<span class="upcoming-title">' . $upcoming_title . '</span>';
$html .= '<span class="upcoming-desc">' . $upcoming_desc . '</span>';
$html .= '<div class="clear"></div>';
$html .= '</div>';
$html .= '</li>';
//...
Any ideas why this is?
Bonus fun time: This appears to work on my local xampp insall, not the live site.
This could be an issue with table datatypes
https://www.w3schools.com/sql/sql_datatypes.asp
depending on what the table is set to it may not support the string length of your html variable or certain chars in it.
It looks like you concat your .html var multiple times. It's a pretty long string in the end. to test this try to save a very long manually entered string. try with special chars. look at the table structure. This is just some ideas and where my thoughts go.
I have to read a txt file into a HTML table.
There are many fields in it but I only want to read the field that says "value".
Here is my txt file:
one=availability:, timestamp=90754, value=no
two=description:, timestamp=074693, value=not sure
three=Name, timestamp=90761, value=yes
The one, two, three values are my row headers and I want it to display the values underneath.
Is there anyway of doing this using iframe?? PHP is not working for me.
Supposing the value is always the last field and you are reading the file line by line I would use a dirty approach:
$value = explode('value=', $line)[1];
longwinded approach
$headers=[];
$values=[];
$lines = file('./homework.txt', FILE_IGNORE_NEW_LINES);
foreach($lines as $line){
$chunks = explode(',',$line);
foreach($chunks as $index => $chunk){
list($key, $value) = explode('=', trim($chunk));
if(!$index){
$headers[] = $value;
}
if('value' === $key){
$values[] = $value;
}
}
}
echo "<table><thead><tr>";
foreach($headers as $h){
echo "<th>{$h}</th>";
}
echo "</tr></thead><tbody><tr>";
foreach($values as $v){
echo "<td>{$v}</td>";
}
echo "</tr></tbody></table>";
If all rows follow the same pattern you can probably use:
//$textfilestring = "one=availability:, timestamp=90754, value=no
//two=description:, timestamp=074693, value=not sure
//three=Name, timestamp=90761, value=yes";
$textfilestring = file_get_contents("PATH_TO_FILE");
$arraylines = explode("\n", $textfilestring);
for ($i=0;$i<count($arraylines);$i++) {
$arraylines[$i] = explode("value=", $arraylines[$i]);
}
echo "<pre>";
var_dump($arraylines);
echo "</pre>";
echo $arraylines[0][1] . "<br>";
echo $arraylines[1][1] . "<br>";
echo $arraylines[2][1] . "<br>";
$arraylines should be twodimensional with one part beeing
one=availability:, timestamp=90754,
and one beeing
no
Not tested though.
I want to convert my sql data to csv files while clicking on a button. The code fragments I found for sql to CSV conversion were in PHP, and I'm trying to convert it to CakePHP since I'm working in CakePHP.
Here is the PHP code I'm tring to convert:
$result = mysql_query("SHOW COLUMNS FROM ".$table."");
$i = 0;
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_assoc($result)) {
$csv_output .= $row['Field']."; ";
$i++;
}
}
$csv_output .= "\n";
$values = mysql_query("SELECT * FROM ".$table."");
while ($rowr = mysql_fetch_row($values)) {
for ($j=0;$j<$i;$j++) {
$csv_output .= $rowr[$j]."; ";
}
$csv_output .= "\n";
}
$filename = $file."_".date("Y-m-d_H-i",time());
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header( "Content-disposition: filename=".$filename.".csv");
print $csv_output;
SOLUTION
Function in the Controller:
function exporttocsv()
{
$this->set('headers',$this->Result->find('all',array('fields'=>'Result.label')));
$this->set('values',$this->Result->find('all',array('fields'=>'Result.value')));
}
exporttocsv.ctp file:
<?php
foreach($headers as $header):
$csv_output .=$header['Result']['label'].", ";
endforeach;
$csv_output .="\n";
if(!empty($values)){
foreach($values as $value):
$csv_output .=$value['Result']['value'].", ";
endforeach;
$csv_output .="\n";
}
else{
echo "There is no data to export.";
}
$filename = "export_".date("Y-m-d_H-i",time());
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header("Content-disposition: filename=".$filename.".csv");
print $csv_output;
exit;
?>
First of all, you don't do queries and output in the same file in Cake. You query the data as usual in the Controller, $this->set() the result to the view, and in the view you do something like this:
foreach ($results as $result) {
echo join(', ', $result['COLUMNS']);
echo "\n";
}
Outputs something like this:
value, varchar(25), NO, , ,
submitter, int(11), NO, , ,
...
Since Cake automatically wraps a layout around your view, you'll have to set the layout to something different, like 'ajax' (which is simply an empty layout).
deceze is correct about outputting the results from the view file. You'll just need to set some headers so that it appears as a file download on the client side. You can simply put these 2 calls in the top of your view:
header("Content-type:application/vnd.ms-excel");
header("Content-disposition:attachment;filename=\"{$filename}\"" );
If you plan on doing csv downloads in more than one place in your application, I'd recommend this helper:
http://bakery.cakephp.org/articles/view/csv-helper-php5
I use it and it works well.
Trying to pull rows from a table and list them in an ol, however, my code only wants to return the last 2 out of the 3 total rows.
<?php
// Connects to your Database
mysql_connect("mysql.***.com", "***", "***") or die(mysql_error());
mysql_select_db("shpdb") or die(mysql_error());
$data = mysql_query("SELECT * FROM savannah") or die(mysql_error());
$info = mysql_fetch_array( $data );
?>
<h1>Dashboard</h1>
<h3>Manage and view documents.</h3>
<h5>Currently viewing Savannah's list of </h5>
<p><strong>List of patients:</strong></p>
<ol>
<?php
while($info = mysql_fetch_array( $data )) {
// Print out the contents of the entry
Print "<li><b>Name:</b> ".$info['name'] . " <br />";
Print "<b>ID:</b> ".$info['ID']." <br />";
Print "<b>Age:</b> ".$info['age'] ." <br />";
Print "<b>Location:</b> ".$info['location'] ." </li>";
}
Print "</ol>"; ?>
The table "savannah" contains three rows, but like I said above, running this script only returns the last two.
Any ideas? Much appreciated.
You have
$info = mysql_fetch_array( $data );
used once before actual loop. Just remove the line below mysql_query procedure.