i have made a script that returns me an array with several lines like :
DATA:VALUE:VALUE_MAX
I need to fill a table with those value like :
NAME | Status
--------------------------
DATA | OK/minor/warning...
.... | .........
.... | .........
with VALUE and VALUE_MAX i calculate the percent wich give me the status.
here is my code for print the table :
my #i = my_status();
print <<END;
<div class="container">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
END
my $inc = 0;
while (#i) {
my #temp = split /:/, #i[$inc];
my $name = $temp[0];
my $percent = ($temp[1] * $temp[2] / 100);
my $status = undef;
if ($percent <= 24 ) {
print "<tr class='info'>";
$status = "Critical !";
}
elsif ($percent <= 49 ) {
print "<tr class='danger'>";
$status = "Danger !";
}
elsif ($percent <= 74 ) {
print "<tr class='warning'>";
$status = "Warning";
}
elsif ($percent <= 99 ) {
print "<tr class='active'>";
$status = "Minor";
}
elsif ($percent == 100 ) {
print "<tr class='success'>";
$status = "OK";
}
print "<td>$name</td>";
print "<td>$status</td>";
print "</tr>";
$inc++;
}
print <<END;
</tbody>
</table>
</div>
END
My script "my_status" is a bit long to execute, it's full of server request...
but the thing is, on the HTML page, everything is a mess, i get wrong value, and an endless loop who print only "Critical !" in status colomns
what is wrong with my script ?
You are not iterating #i in your while loop. Your line
while (#i) {
means that it will stay in the loop as long as #i is true. Because that's an array, that means that as long as there are items in #i, it will stay in the loop.
You do not remove anything from #i inside of the loop. There are no shift or pop commands, and you also do not overwrite #i. So it will stay indefinitely. You've got yourself an infinite loop.
What you want instead is probably a foreach loop. Then you also don't need $inc. It will put each element inside of #i into $elem and run the loop.
foreach my $elem (#i) {
my #temp = split /:/, $elem;
my $name = $temp[0];
my $percent = ( $temp[1] * $temp[2] / 100 );
my $status = undef;
if ( $percent <= 24 ) {
print "<tr class='info'>";
$status = "Critical !";
}
elsif ( $percent <= 49 ) {
print "<tr class='danger'>";
$status = "Danger !";
}
elsif ( $percent <= 74 ) {
print "<tr class='warning'>";
$status = "Warning";
}
elsif ( $percent <= 99 ) {
print "<tr class='active'>";
$status = "Minor";
}
elsif ( $percent == 100 ) {
print "<tr class='success'>";
$status = "OK";
}
print "<td>$name</td>";
print "<td>$status</td>";
print "</tr>";
}
You can read up on loops in perlsyn starting from for loops.
Related
need help to accelerate the run of below perl code. 4 to 6hours should be fine. faster is better :)
csv file is about 14m to 14.5m rows, and aorund 1100 to 1500columns; 62gig
what it does:
do a count (like a countif in excel)
get the percent (based on 14m rows)
get the rank based on count
My current code:
use List::MoreUtils qw(uniq);
$x="Room_reserve";
$in = "D:\\package properties\\${x}.csv";
$out = "D:\\package properties\\output\\${x}_output.csv";
open($fh, '<', $in) or die "Could not open file '$file' $!";
#data = <$fh>;
close($fh);
%counts;
#columns;
$first = 1;
#counter
foreach $dat (#data) {
chomp($dat);
#rows = split(',',$dat);
if ($first == 1) {
$first = 0;
next;
}
else {
$count = 1;
foreach $i (0..$#rows) {
if ( exists($columns[$i]{$rows[$i]}) ) {
$columns[$i]{$rows[$i]}++;
}
else {
$columns[$i]{$rows[$i]} = int($count);
}
}
}
}
#output
$first = 1;
open($fh, '>', $out) or die "Could not open file '$file' $!";
foreach $dat (#data) {
chomp($dat);
#rows = split(',',$dat);
foreach $i (0..$#rows) {
if ($i > 6) {
#for modifying name
if ( $first == 1 ) {
$line = join( ",", "Rank_$rows[$i]", "Percent_$rows[$i]",
"Count_$rows[$i]", $rows[$i]);
print $fh "$line,";
if ( $i == $#rows ) {
$first = 0;
}
}
else {
#dat_val = reverse sort { $a <=> $b } values %{$columns[$i]};
%ranks = {};
$rank_cnt = 0;
foreach $val (#dat_val) {
if ( ! exists($ranks{$val}) ) {
$rank_cnt++;
}
$ranks{$val} = $rank_cnt;
}
$rank = $ranks{$columns[$i]{$rows[$i]}};
$cnt = $columns[$i]{$rows[$i]};
$ave = ($cnt / 14000000) * 100;
$line = join( ",", $rank, $ave, $cnt, $rows[$i]);
print $fh "$line,";
}
}
else {
print $fh "$rows[$i],";
}
}
print $fh "\n";
}
close($fh);
thanks in advance.
my table
Col
_1
_2
_3
_4
_5
_6
Col2
Col3
Col
Col5
FALSE
1
2
3
4
5
6
6
6
1
4
FALSE
1
2
3
4
5
6
6
6
1
4
FALSE
1
2
3
4
5
7
6
6
1
3
edited to show sample table and correct $x
##Sample output
Col
_1
_2
_3
_4
_5
_6
Col2
rank_Col2
percent_rank_Col2
count_Col2
Col3
rank_Col3
percent_rank_Col3
count_Col3
Col
rank_Col
percent_rank_Col
count_Col
Col5
rank_Col5
percent_rank_Col5
count_Col5
FALSE
1
2
3
4
5
6
9
2
0.33
1
6
1
0.67
2
1
1
0.67
2
11
1
0.33
1
FALSE
1
2
3
4
5
6
6
1
0.67
2
6
1
0.67
2
2
2
0.33
1
4
1
0.33
1
FALSE
1
2
3
4
5
7
6
1
0.67
2
4
2
0.33
1
1
1
0.67
2
3
1
0.33
1
Presume you have this file:
% ls -lh file
-rw-r--r-- 1 dawg wheel 57G Jul 24 13:15 file
% time wc -l file
14000000 file
wc -l file 29.24s user 7.27s system 99% cpu 36.508 total
% awk -F, 'FNR==1{print $NF; exit}' file
1099
So we have a 57GB file with 14,000,000 line by 1099 col csv with random numbers.
It only takes 20 to 30 SECONDS to read the entire file in a line-by-line fashion.
How long in Perl?
% time perl -lnE '' file
perl -lnE '' file 5.70s user 9.67s system 99% cpu 15.381 total
So only 15 seconds in Perl line by line. How long to 'gulp' it?
% time perl -0777 -lnE '' file
perl -0777 -lnE '' file 12.13s user 23.86s system 98% cpu 36.688 total
But that is on THIS computer which has 255GB of RAM...
It took this Python script approximately 23 minutes to write that file:
total=0
cols=1100
with open('/tmp/file', 'w') as f_out:
for cnt in range(14_000_000):
line=','.join(f'{x}' for x in range(cols))
total+=cols
f_out.write(f'{cnt},{total},{line}\n')
The issue with your Perl script is you are gulping the whole file (with #data = <$fh>;) and the OS maybe is running out of RAM. It is likely swapping and this is very slow. (How much RAM do you have?)
Rewrite the script to do it line by line. You should be able to do your entire analysis in less than 1 hour.
Can you try the following script? It precomputes the ranks instead of recalculating them for each row. It also avoids saving the first 7 columns in #columns since they appear not to be used for anything.
use feature qw(say);
use strict;
use warnings;
{
my $x="Room_reserve";
my $in = "D:\\package properties\\${x}.csv";
my $out = "D:\\package properties\\output\\${x}_output.csv";
my $min_col = 7;
my ($data1, $data2) = read_input_file($in, $min_col);
my $columns = create_counter($data2);
my $ranks = create_ranks( $columns);
write_output($data1, $data2, $columns, $ranks, $min_col, $out);
}
sub create_counter {
my ($data) = #_;
print "Creating counter..";
my #columns;
my $first = 1;
for my $row (#$data) {
if ( $first ) {
$first = 0; next; # skip header
}
for my $i (0..$#$row) {
$columns[$i]{$row->[$i]}++;
}
}
say "done.";
return \#columns;
}
sub create_ranks {
my ( $columns ) = #_;
print "Creating ranks..";
my #ranks;
for my $col (#$columns) {
# sort the column values according to highest frequency.
my #freqs = sort { $b <=> $a } values %$col;
my $idx = 1;
my %ranks = map {$_ => $idx++} #freqs;
push #ranks, \%ranks;
}
say "done.";
return \#ranks;
}
sub read_input_file {
my ($in, $min_col) = #_;
print "Reading input file $in ..";
open(my $fh, '<', $in) or die "Could not open file '$in' $!";
my #data1;
my #data2;
while( my $line = <$fh> ) {
chomp $line;
my #fields = split(',', $line);
next if #fields == 0;
die "Unexpected column count at line $.\n" if #fields < $min_col;
push #data1, [#fields[0..($min_col-1)]];
push #data2, [#fields[$min_col..$#fields]];
}
say " $. lines.";
close($fh);
return \#data1, \#data2;
}
sub write_output {
my ($data1, $data2, $columns, $ranks, $min_col, $out) = #_;
say "Saving output file $out..";
open(my $fh, '>', $out) or die "Could not open file '$out': $!";
for my $i (0..$#$data1) {
my $row1 = $data1->[$i];
my $row2 = $data2->[$i];
if ($i == 0) {
print $fh join ",", #$row1;
print $fh ",";
for my $j (0..$#$row2) {
print $fh join ",", $row2->[$j],
"Rank_" . $row2->[$j],
"Percent_". $row2->[$j],
"Count_" . $row2->[$j];
print $fh "," if $j < $#$row2;
}
print $fh "\n";
next;
}
print $fh join ",", #$row1;
print $fh ",";
for my $j (0..$#$row2) {
my $cnt = $columns->[$j]{$row2->[$j]};
my $rank = $ranks->[$j]{$cnt};
my $ave = ($cnt / 14000000) * 100;
print $fh join ",", $row2->[$j], $rank, $ave, $cnt;
print $fh "," if $j < $#$row2;
}
print $fh "\n";
}
close $fh;
say "Done.";
}
Is there any function that will give me the name of passed time with two dates in mysql? for example, after i've wrote a post then the page redirects me to the post page it must say " posted 4 seconds before", and afte five minutes later it will say posted 5 minutes before". If the time bigger than 60 minutes it will say xx hours before ...
15 days later it must say 2 weeks ago.
Something like wordpress meta info.
Same as time on my nick name at to right bottom of this post
I suggest you to write this on scripting side. If you are using PHP you can use the following code block to convert unixtime to relative phrase.
function relative_date($date)
{
$diff = time() - $date;
if ($diff < 0) {
return "just now";
} else {
$app = "ago";
}
$t_diff = $diff;
$days = floor($diff / 3600 / 24);
$diff = $diff - ( $days * 3600 * 24 );
$hours = floor($diff / 3600);
$diff = $diff - ( $hours * 3600 );
$minutes = floor($diff / 60);
$diff = $diff - ( $minutes * 60 );
$seconds = $diff;
if ($t_diff > 60 * 60 * 24) {
$str = ( $days . ' days' );
} else if ($t_diff > 60) {
$str = ( $hours ? "{$hours} hours" : "" ) . ( $minutes ? " $minutes minutes" : "" );
} else {
$str = ( $seconds ) . " seconds";
}
$str = $str . " $app";
return $str;
}
This is what I want
function formatDateDiff($start, $end=null) {
if(!($start instanceof DateTime)) {
$start = new DateTime($start);
}
if($end === null) {
$end = new DateTime();
}
if(!($end instanceof DateTime)) {
$end = new DateTime($start);
}
$interval = $end->diff($start);
$doPlural = function($nb,$str){
if ($nb > 1) {
switch ($str) {
case 'Yıl':
case 'Ay':
case 'Gün':
return $str.'e';
case 'Saat':
case 'Dakika':
case 'Saniye':
return $str.'n';
}
} else
return $str;
}; // adds plurals
$format = array();
if($interval->y !== 0) {
$format[] = "%y ".$doPlural($interval->y, "Yıl");
}
if($interval->m !== 0) {
$format[] = "%m ".$doPlural($interval->m, "Ay");
}
if($interval->d !== 0) {
$format[] = "%d ".$doPlural($interval->d, "Gün");
}
if($interval->h !== 0) {
$format[] = "%h ".$doPlural($interval->h, "Saat");
}
if($interval->i !== 0) {
$format[] = "%i ".$doPlural($interval->i, "Dakika");
}
if($interval->s !== 0) {
$format[] = "%s ".$doPlural($interval->s, "Saniye");
}
if(count($format)==0 || (count($format)==1 && $interval->s !== 0)) {
return "Az Önce";
}
// We use the two biggest parts
if(count($format) > 1) {
$format = array_shift($format).", ".array_shift($format);
} else {
$format = array_pop($format);
}
// Prepend 'since ' or whatever you like
return $interval->format($format);
}
Reference Address: https://www.php.net/manual/en/dateinterval.format.php
Thank you so much for your reply.
I have a simple form for update image name into mysql database, but unfortunately it always throw the error SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens. The code seems OK, but I don't know it cannot update the database. Any help is appreciated.
Here is the image name and the SQL that I have printed out.
Array
(
[0] => 20141027103534_0.jpg
[1] => 20141027103534_1.jpg
[2] =>
[3] =>
[4] =>
[5] => 20141027103534_5.jpg
[6] => 20141027103534_6.jpg
[7] =>
[8] =>
[9] =>
)
UPDATE `image`
SET
`propertyPictureCate1` = :propertyPictureCate1,
`propertyPictureCate2` = :propertyPictureCate2,
`propertyPictureCate3` = :propertyPictureCate3,
`propertyPictureCate4` = :propertyPictureCate4,
`propertyPictureCate5` = :propertyPictureCate5,
`memo1` = :memo1,
`memo2` = :memo2,
`memo3` = :memo3,
`memo4` = :memo4,
`memo5` = :memo5,
`spotPictureCate1` = :spotPictureCate1,
`spotPictureCate2` = :spotPictureCate2,
`spotPictureCate3` = :spotPictureCate3,
`spotPictureCate4` = :spotPictureCate4,
`spotPictureCate5` = :spotPictureCate5,
`spotName1` = :spotName1,
`spotName2` = :spotName2,
`spotName3` = :spotName3,
`spotName4` = :spotName4,
`spotName5` = :spotName5,
`distance1` = :distance1,
`distance2` = :distance2,
`distance3` = :distance3,
`distance4` = :distance4,
`distance5` = :distance5,
`img1` = :img1,
`img2` = :img2,
`img6` = :img6,
`img7` = :img7
WHERE `buildingID` = :buildingID
the image name within bindParam that I tested to print out.
img1 20141027103534_0.jpg
img2 20141027103534_1.jpg
img6 20141027103534_5.jpg
img7 20141027103534_6.jpg
and below is my code for above result
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$file_name = [];
for ($i = 0; $i < count($_FILES['file']['tmp_name']); $i++) {
if($_FILES['file']['error'][$i] != 4) {
$validextensions = array("jpeg", "jpg", "png","gif");
$ext = explode('.', basename($_FILES['file']['name'][$i]));
$file_extension = end($ext);
$file_name[$i] = date("Ymdhis") . "_". $i . "." . $ext[count($ext) - 1];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/".PROJ_DIR."/uploads/" . date("Ymdhis") . "_". $i . "." . $ext[count($ext) - 1];
move_uploaded_file($_FILES['file']['tmp_name'][$i], $target_path);
} else {
$file_name[$i] = "";
}
}
try {
$sql = "
UPDATE `image`
SET
`propertyPictureCate1` = :propertyPictureCate1,
`propertyPictureCate2` = :propertyPictureCate2,
`propertyPictureCate3` = :propertyPictureCate3,
`propertyPictureCate4` = :propertyPictureCate4,
`propertyPictureCate5` = :propertyPictureCate5,
`memo1` = :memo1,
`memo2` = :memo2,
`memo3` = :memo3,
`memo4` = :memo4,
`memo5` = :memo5,
`spotPictureCate1` = :spotPictureCate1,
`spotPictureCate2` = :spotPictureCate2,
`spotPictureCate3` = :spotPictureCate3,
`spotPictureCate4` = :spotPictureCate4,
`spotPictureCate5` = :spotPictureCate5,
`spotName1` = :spotName1,
`spotName2` = :spotName2,
`spotName3` = :spotName3,
`spotName4` = :spotName4,
`spotName5` = :spotName5,
`distance1` = :distance1,
`distance2` = :distance2,
`distance3` = :distance3,
`distance4` = :distance4,
`distance5` = :distance5".
$s1 = (($file_name[0] != "") ? ",\n`img1` = :img1" : NULL).
$s2 = (($file_name[1] != "") ? ",\n`img2` = :img2" : NULL).
$s3 = (($file_name[2] != "") ? ",\n`img3` = :img3" : NULL).
$s4 = (($file_name[3] != "") ? ",\n`img4` = :img4" : NULL).
$s5 = (($file_name[4] != "") ? ",\n`img5` = :img5" : NULL).
$s6 = (($file_name[5] != "") ? ",\n`img6` = :img6" : NULL).
$s7 = (($file_name[6] != "") ? ",\n`img7` = :img7" : NULL).
$s8 = (($file_name[7] != "") ? ",\n`img8` = :img8" : NULL).
$s9 = (($file_name[8] != "") ? ",\n`img9` = :img9" : NULL).
$s10 = (($file_name[9] != "") ? ",\n`img10` = :img10" : NULL).
" \nWHERE `buildingID` = :buildingID
";
echo '<pre>';
print_r($file_name);
echo '</pre>';
echo '<pre>';
print_r($sql);
echo '</pre>';
$stmt = $con->prepare($sql);
$stmt->bindParam(":propertyPictureCate1",$_POST['propertyPictureCate1']);
$stmt->bindParam(":propertyPictureCate2",$_POST['propertyPictureCate2']);
$stmt->bindParam(":propertyPictureCate3",$_POST['propertyPictureCate3']);
$stmt->bindParam(":propertyPictureCate4",$_POST['propertyPictureCate4']);
$stmt->bindParam(":propertyPictureCate5",$_POST['propertyPictureCate5']);
$stmt->bindParam(":memo1",$_POST['memo1']);
$stmt->bindParam(":memo2",$_POST['memo2']);
$stmt->bindParam(":memo3",$_POST['memo3']);
$stmt->bindParam(":memo4",$_POST['memo4']);
$stmt->bindParam(":memo5",$_POST['memo5']);
$stmt->bindParam(":spotPictureCate1",$_POST['spotPictureCate1']);
$stmt->bindParam(":spotPictureCate2",$_POST['spotPictureCate2']);
$stmt->bindParam(":spotPictureCate3",$_POST['spotPictureCate3']);
$stmt->bindParam(":spotPictureCate4",$_POST['spotPictureCate4']);
$stmt->bindParam(":spotPictureCate5",$_POST['spotPictureCate5']);
$stmt->bindParam(":spotName1",$_POST['spotName1']);
$stmt->bindParam(":spotName2",$_POST['spotName2']);
$stmt->bindParam(":spotName3",$_POST['spotName3']);
$stmt->bindParam(":spotName4",$_POST['spotName4']);
$stmt->bindParam(":spotName5",$_POST['spotName5']);
$stmt->bindParam(":buildingID",$_POST['buildingID']);
if($file_name[0] !== ""){
echo 'img1 '.$file_name[0].'<br>';
$stmt->bindParam(":img1", $file_name[0]);
}
if($file_name[1] !== ""){
echo 'img2 '.$file_name[1].'<br>';
$stmt->bindParam(":img2", $file_name[1]);
}
if($file_name[2] !== ""){
echo 'img3 '.$file_name[2].'<br>';
$stmt->bindParam(":img3", $file_name[2]);
}
if($file_name[3] !== ""){
echo 'img4 '.$file_name[3].'<br>';
$stmt->bindParam(":img4", $file_name[3]);
}
if($file_name[4] !== ""){
echo 'img5 '.$file_name[4].'<br>';
$stmt->bindParam(":img5", $file_name[4]);
}
if($file_name[5] !== ""){
echo 'img6 '.$file_name[5].'<br>';
$stmt->bindParam(":img6", $file_name[5]);
}
if($file_name[6] !== ""){
echo 'img7 '.$file_name[6].'<br>';
$stmt->bindParam(":img7", $file_name[6]);
}
if($file_name[7] !== ""){
echo 'img8 '.$file_name[7].'<br>';
$stmt->bindParam(":img8", $file_name[7]);
}
if($file_name[8] !== ""){
echo 'img9 '.$file_name[8].'<br>';
$stmt->bindParam(":img9", $file_name[8]);
}
if($file_name[9] !== ""){
echo 'img10 '.$file_name[9].'<br>';
$stmt->bindParam(":img10", $file_name[9]);
}
//$stmt->debugDumpParams();
$stmt->execute();
$con = null;
} catch(PDOException $e) {
echo $e->getMessage();
}
}
You forgot to bind distance parameters to your statement.
Before calling $stmt->execute(), you should either add these lines for binding to $stmt
$stmt->bindParam(":distance1",$_POST['distance1']);
$stmt->bindParam(":distance2",$_POST['distance2']);
$stmt->bindParam(":distance3",$_POST['distance3']);
$stmt->bindParam(":distance4",$_POST['distance4']);
$stmt->bindParam(":distance5",$_POST['distance5']);
or remove these lines from you $sql string variable
`distance1` = :distance1,
`distance2` = :distance2,
`distance3` = :distance3,
`distance4` = :distance4,
`distance5` = :distance5
I want to list all records in one custom taxonomy start with only A or B. Below code is to list all record with all letters.
Here is the code to list all record with one custom taxonomy with all letters in groups. Example,
A
Aajkacatch (0)
Aajkiitem (0)
Aamzie (0)
Aaneri (0)
Aaramshop (0)
Abaaya (0)
B
B.LAB (0)
Baby-Republic (0)
Babyoye (45)
Bank-Bazaar (1)
<?php
// Template Name: Store Template
// get all the stores
$stores = get_terms(APP_TAX_STORE, array('hide_empty' => 0, 'child_of' => 0, 'pad_counts' => 0, 'app_pad_counts' => 1));
// get ids of all hidden stores
$hidden_stores = clpr_hidden_stores();
$list = '';
$groups = array();
if ($stores && is_array($stores) ) {
// unset child stores
foreach($stores as $key => $value)
if($value->parent != 0)
unset($stores[$key]);
foreach($stores as $store)
$groups[mb_strtoupper(mb_substr($store->name, 0, 1))][] = $store;
if (!empty($groups)) :
foreach($groups as $letter => $stores) {
$old_list = $list;
$letter_items = false;
$list .= "\n\t" . '<h2 class="stores">' . apply_filters( 'the_title', $letter ) . '</h2>';
$list .= "\n\t" . '<ul class="stores">';
foreach($stores as $store) {
if (!in_array($store->term_id, $hidden_stores)) {
$list .= "\n\t\t" . '<li>' . apply_filters('the_title', $store->name). ' (' . intval($store->count) . ')</li>';
$letter_items = true;
}
}
$list .= "\n\t" . '</ul>';
if(!$letter_items)
$list = $old_list;
}
endif;
} else {
$list .= "\n\t" . '<p>' . __('Sorry, but no stores were found.', 'appthemes') .'</p>';
}
?>
While it wouldn't be the most efficient way, you could easily just check the first letter of the store name.
change:
if (!in_array($store->term_id, $hidden_stores)) {
to:
if (!in_array($store->term_id, $hidden_stores) ) {
$first_letter = substr( $store->name, 0, 1 );
if ( $first_letter == 'A' || && $first_letter == 'B' )
That would ensure you're only listing A and B items.
Based on : Getting a modified preorder tree traversal model (nested set) into a <ul>
I have following table :
id name lft rgt level
1 company 1 22 0
75 Developer 26 31 1
76 Tester 24 27 1
77 Analyst 22 23 1
78 under developer 27 30 2
79 under tster 25 26 2
And following query/code for fetching nested records:
function getstructureInformation() {
$treeArr = array();
$tree = array();
$sql = "SELECT node.name, node.id, node.unit_id,
node.description,node.lft,node.rgt,node.level,
(COUNT(parent.name) - 1) AS depth
FROM tablename AS node
CROSS JOIN tablename AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft";
$query = $this->db->query($sql);
$data = $query->result();
foreach ($data as $datap) {
$treeArr['id'] = $datap->id;
$treeArr['unit_id'] = $datap->unit_id;
$treeArr['lft'] = $datap->lft;
$treeArr['rgt'] = $datap->rgt;
$treeArr['level'] = $datap->level;
$treeArr['name'] = $datap->name;
$treeArr['depth'] = $datap->depth;
$treeArr['description'] = $datap->description;
$tree[] = $treeArr;
}
return $tree;
}
Here the PHP code for displaying it into the view page:
$result = '';
$currDepth = -1; // -1 to get the outer <ul>
while (!empty($tree)) {
$currNode = array_shift($tree);
if ($currNode['depth'] > $currDepth) {
echo '<ul>';
}
if ($currNode['depth'] < $currDepth) {
$result .= str_repeat('</ul>', $currDepth - $currNode['depth']);
}
echo '<li>' . $currNode['name'] . '</li>';
$currDepth = $currNode['depth'];
if (empty($tree)) {
echo str_repeat('</ul>', $currDepth + 1);
}
}
But its not displaying properly like:
It displaying output as:
001 : Company Name
3 : Analyst
2 : Tester
33 : under tster
1 : Developer
44 : under developer
The desired output is like:
001 : Company Name
3 : Analyst
2 : Tester
33 : under tster
1 : Developer
44 : under developer
Is there any solution?
This should work :
function printTree ($tree) {
$last_level = -1;
foreach ($tree as $v) {
$diff = $v['level'] - $last_level;
if ($diff == 0) {
echo '<li>' .$v['name']. '</li>';
}
elseif ($diff > 0) {
for ($i = 0; $i < $diff; $i++)
echo '<ul>';
echo '<li>' .$v['name']. '</li>' ;
}
else {
for ($i = 0; $i > $diff; $i--)
echo '</ul>';
echo '<li>' .$v['name']. '</li>' ;
}
$last_level = $v['level'];
}
}
But with this function, you won't have the depth printed.
Tested and working with
$tree = array (
array (
'name' => 'Line',
'level' => 0
),
array (
'name' => 'Line',
'level' => 1
),
array (
'name' => 'Line',
'level' => 2
),
array (
'name' => 'Line',
'level' => 1
)
);
printTree ($tree);