I have cURL function which make calls to api based on ID which I provide and return data in array. So far everything works perfectly. What I want and can't figure out is this:
I have foreach which display in table all orders lie
#foreach($orders as $order)
$order->address
$order->time_created
$order->price
... etc
#endforeach
Is it possible to put this cURL inside the foreach and add on each row based on $order->order_id to show some more data from the array?
So something like this
#foreach($orders as $order)
$order->address
$order->time_created
$order->price
... etc
$url = get_curl_content_tx("http://example.com/".$order->order_id);
$data = json_decode($url,true);
#foreach ( $data as $moreData )
#if ( $moreData['data'] == $order->time_created )
// show something
#else
// show other thing
#endif
#endforeach
#endforeach
My problem is that I can't figure how to loop the url so I can get all orders_id i.e.
$url = get_curl_content_tx("http://example.com/1");
$url = get_curl_content_tx("http://example.com/2");
$url = get_curl_content_tx("http://example.com/3");
$url = get_curl_content_tx("http://example.com/4");
$url = get_curl_content_tx("http://example.com/5");
$url = get_curl_content_tx("http://example.com/6");
So then I can perform my if/else block. Framework which I use is Laravel 4.2.
Hope it is clear enough what I want to accomplish. If is not I will try to clear things..
EDIT: Example what it should be:
<table>
<thead>
<tr>
<th class="text-center">#</th>
<th class="text-center">Date Created</th>
<th class="text-center">Name</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<th>$url = get_curl_content_tx("http://example.com/1")</th>
<th>Product 1</th>
</tr>
<tr>
<th>2</th>
<th>$url = get_curl_content_tx("http://example.com/2")</th>
<th>Product 2</th>
</tr>
</tbody>
</table>
You can use laravel's unique method for collections to remove duplicate order id's before iterating them.
$collection = collect([
['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
]);
$unique = $collection->unique('brand');
$unique->values()->all();
Or you can use PHP method as well. How to remove duplicate values from a multi-dimensional array in PHP
I have manage to do it and will post it as answer. So since I already had ID's of the product I've made it like this directly in the blade. Maybe there is a room for improvements but for now at least it is working.
This is short version without echoes in conditions
<td class="text-center">
<?php
$url=get_curl_content_tx("http://example.com/". $order->order_id);
$arr = json_decode($url, true);
if (is_array($arr['data']) || is_object($arr['data'])) {
foreach($arr['data'] as $data ) {
$match = false;
if ($data['amount'] == $order->amount) {
$match = $data;
break;
}
}
if($match !== false ) {
if( .. ) {
// do something
}
else {
// do something else
}
}
else { }
}
?>
</td>
Related
Sorry for such a long post. I request to read till the end to understand what I am trying to accomplish and what my roadblock is!
I have a table like this
<html>
<body>
<table class="searchTable" cellspacing="0" cellpadding="5" style="width: 100%;">
<tbody>
<tr>
<th>Book</th>
<th>Model Name</th>
<th>Description</th>
<th>Category</th>
</tr>
<tr>
<td>
<a onclick="getFullData( '', 'K0072', 'B20' );" href="">K0072</a>
</td>
<td>B20</td>
<td>K0072 Description</td>
<td>K0072 Category</td>
</tr>
<tr>
<td>
<a onclick="getFullData( '', 'K0074', 'B2004' );" href="">K0072</a>
</td>
<td>B2004</td>
<td>K0074 Description</td>
<td>K0074 Category</td>
</tr>
<tr>
<td>
<a onclick="getFullData( '', 'K0081', 'B2005' );" href="">K0072</a>
</td>
<td>B2005</td>
<td>K0081 Description</td>
<td>K0081 Category</td>
</tr>
</tbody>
</table>
</body>
</html>
Please note, I am fetching the data from another website using cURL POST method. Which means, I have no control over the HTML.
I am able to generate the following array from the above HTML using DOMDocument.
array (size=3)
0 =>
array (size=4)
0 => string 'K0072' (length=5)
1 => string 'B20' (length=3)
2 => string 'K0072 Description' (length=17)
3 => string 'K0072 Category' (length=14)
1 =>
array (size=4)
0 => string 'K0074' (length=5)
1 => string 'B2004' (length=5)
2 => string 'K0074 Description' (length=17)
3 => string 'K0074 Category' (length=14)
2 =>
array (size=4)
0 => string 'K0081' (length=5)
1 => string 'B2005' (length=5)
2 => string 'K0081 Description' (length=17)
3 => string 'K0081 Category' (length=14)
This is my code:
$doc = new DOMDocument();
$doc->loadHTML( getHtml() );
$doc->preserveWhiteSpace = false;
$doc->encoding = 'UTF-8';
$tables = $doc->getElementsByTagName( 'table' );
$dataArray = array();
$count = 0;
foreach( $tables as $table ) {
if ( $table->getAttribute( 'class' ) !== 'searchTable' ) {
continue;
}
// $header = $doc->getElementsByTagName( 'th' );
// $rows = $doc->getElementsByTagName( 'tr' );
$data = $doc->getElementsByTagName( 'td' );
$tempArray = array();
foreach ( $data as $td ) {
$value = trim( $td->textContent );
$tempArray[$count] = $value;
$count++;
if( 0 !== $count && $count % 4 === 0 ) {
array_push( $dataArray, $tempArray );
$tempArray = array();
$count = 0;
}
}
}
var_dump( $dataArray );
die();
The problem is I am not able to extract the argument values of getFullData method for each record. Because, I need to build URLs based on the arguments, for example: https://pi.php?part=K0072&m=B20.
<tr>
<td>
<a onclick="getFullData( '', 'K0072', 'B20' );" href="">K0072</a>
</td>
...
</tr>
I had seen somehere (can't remember now! :( ) that DOXPath could be used to find DOM elements by using element attribute, like here I probably may use the onlick attribute.
But the problem is, the source document has other anchors as well which are calling differnt methods. This means there would be unnecessary records in PHP for filtering.
Is there a way that allows me to extract only those anchors which are calling the getFullData method? Also how would I extract the argument values?
End of day, the final array has to look like this:
array (size=3)
0 =>
array (size=5)
0 => string 'K0072' (length=5)
1 => string 'B20' (length=3)
2 => string 'K0072 Description' (length=17)
3 => string 'K0072 Category' (length=14)
4 => string 'https://pi.php?part=K0072&m=B20'
1 =>
array (size=5)
0 => string 'K0074' (length=5)
1 => string 'B2004' (length=5)
2 => string 'K0074 Description' (length=17)
3 => string 'K0074 Category' (length=14)
4 => string 'https://pi.php?part=K0074&m=B2004'
2 =>
array (size=5)
0 => string 'K0081' (length=5)
1 => string 'B2005' (length=5)
2 => string 'K0081 Description' (length=17)
3 => string 'K0081 Category' (length=14)
4 => string 'https://pi.php?part=K0081&m=B2005'
Any suggestion?
UPDATE:
Thank you Chris Hass for driving me to some direction. Taking the idea, I just tried this and got some potential results!
$ancs = $xPath->query( "//a[#onclick]" );
foreach( $ancs as $a ) {
var_dump ( $a->getAttribute( 'onclick' ) );
}
I'm not going to rewrite everything for you, but this should hopefully get you the gist. I'm completely skipping XPath stuff, some people really like it, and the selectors allow you to make more concise rules, but I think simple is often the best for starters.
As noted in my comment, I'm grabbing each individual tr first, sanity checking the contents and trying to continue as much as possible. For the onclick I'm parsing as RegEx, removing the function wrappers, and then parsing it as CSV since that is what it basically is.
Here's an online sample of this, too.
$html = <<<'TAG'
<html>
<body>
<table class="searchTable" cellspacing="0" cellpadding="5" style="width: 100%;">
<tbody>
<tr>
<th>Book</th>
<th>Model Name</th>
<th>Description</th>
<th>Category</th>
</tr>
<tr>
<td>
<a onclick="getFullData( '', 'K0074', 'B2004' );" href="">K0072</a>
</td>
<td>B2004</td>
<td>K0074 Description</td>
<td>K0074 Category</td>
</tr>
</tbody>
</table>
</body>
</html>
TAG;
$doc = new DOMDocument();
$doc->loadHTML($html);
$tables = $doc->getElementsByTagName('table');
foreach ($tables as $table) {
if ($table->getAttribute('class') !== 'searchTable') {
continue;
}
$rows = $table->getElementsByTagName('tr');
foreach ($rows as $row) {
$cells = $row->getElementsByTagName('td');
// Sanity check that we have four rows or skip it
if (4 !== count($cells)) {
continue;
}
// Sanity check that the first cell has a link inside it
$firstCellLinks = $cells[0]->getElementsByTagName('a');
if (1 !== count($firstCellLinks)) {
continue;
}
// Make sure the first link has an onclick attribute
if (!$firstCellLinks[0]->hasAttribute('onclick')) {
continue;
}
// Finally, get the contents of the cell. This can be simplified to a one-line but
// I've expanded it to be more obvious.
$firstCellLinkOnClick = $firstCellLinks[0]->attributes['onclick']->value;
$firstCellLinkOnClickParamsAsString = preg_replace('/getFullData\(([^)]+)\);/', '$1', $firstCellLinkOnClick);
$firstCellLinkOnClickParamsAsArray = str_getcsv($firstCellLinkOnClickParamsAsString, ',', "'");
print_r($firstCellLinkOnClickParamsAsArray);
/*
Array
(
[0] =>
[1] => K0074
[2] => B2004
)
*/
}
}
Try something like this, using xpath:
$dom = new DOMDocument();
$dom->loadXML($html);
$xpath = new DOMXPath($dom);
$dataArray = array();
$link='https://pi.php?part=K0072&m=';
$targets = $xpath->query("//tr[.//a]");
foreach ($targets as $tr)
{
$count = 0;
$tempArray = array();
foreach ($xpath->query('.//td',$tr) as $target) {
$tempArray[$count] = trim($target->textContent);
$count++;
}
$anc = $xpath->query('.//td',$tr)[1]->nodeValue;
$tempArray[$count] = $link.$anc;
array_push( $dataArray, $tempArray );
};
var_dump( $dataArray );
I have obtained the following data through Mysql.
idx item_name parent_id
44 'A' -1
46 'B' -1
47 'C' 44
48 'D' 44
49 'E' 44
50 'F' 46
51 'G' 47
52 'H' 47
53 'I' 48
I want to draw a table using this data.
I've searched for information, but it's very difficult.
Is there anyone who can help me?
Example
<table>
<thead>
<tr>
<th>item1</th>
<th>item2</th>
<th>item3</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="4">A</td>
<td rowspan="2">C</td>
<td>G</td>
<td>-</td>
</tr>
<tr>
<td>H</td>
<td>-</td>
</tr>
<tr>
<td>D</td>
<td>I</td>
<td>-</td>
</tr>
<tr>
<td>E</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>B</td>
<td>F</td>
<td>-</td>
<td>-</td>
</tr>
</tbody>
Is there a PHP library related to this?
=========================================
The values in the database consist of a passenger structure. (Parent ID Existence)
I want to make this data into a table using PHP.
"Rowspan" will be used to accommodate the number of children.
However, this method of HTML coding is very difficult.
I need a library or a related example code.
Here you go, the code that I made to solve your problem.
It is not perfect but I hope you got the idea.
Your problem cannot be solved by a simple array loop, because your data is not a simple table but a tree. Therefore, using recursive loop to walk through the data is one of the solutions.
<?php
// the data, should be obtained from your database
// to simplify the code, I made them into an array of objects
$rows[] = (object) array( 'idx' => 44, 'name' => 'A', 'pid' => -1 );
$rows[] = (object) array( 'idx' => 46, 'name' => 'B', 'pid' => -1 );
$rows[] = (object) array( 'idx' => 47, 'name' => 'C', 'pid' => 44 );
$rows[] = (object) array( 'idx' => 48, 'name' => 'D', 'pid' => 44 );
$rows[] = (object) array( 'idx' => 49, 'name' => 'E', 'pid' => 44 );
$rows[] = (object) array( 'idx' => 50, 'name' => 'F', 'pid' => 46 );
$rows[] = (object) array( 'idx' => 51, 'name' => 'G', 'pid' => 47 );
$rows[] = (object) array( 'idx' => 52, 'name' => 'H', 'pid' => 47 );
$rows[] = (object) array( 'idx' => 53, 'name' => 'I', 'pid' => 48 );
// Build Tree
foreach($rows as $r) {
$r->child = [];
foreach($rows as $c) {
if($r->idx == $c->idx) continue;
if($c->pid == $r->idx)
$r->child[] = $c;
}
}
// recursive walk through the trees to set maxLevel and nodeLevel
function cLeaves($node, $level, &$maxLevel) {
$count = 0;
if(count($node->child) == 0) {
$node->span = 1;
$node->level = $level;
$maxLevel = $maxLevel < $level ? $level : $maxLevel;
return 1;
} else {
$node->level = $level;
$level++;
foreach($node->child as $c) {
$count += cLeaves($c, $level, $maxLevel);
}
$node->span = $count;
return $count;
}
}
// recursive walk through the trees to draw table
function drawTable($cnode, $maxLevel) {
echo '<td rowspan="'.$cnode->span.'">'.$cnode->name.'</td>';
if(count($cnode->child) == 0) {
if($cnode->level < $maxLevel) {
for($i = $cnode->level; $i<$maxLevel; $i++)
echo '<td>-</td>';
}
echo '<td>-</td>'; // for the value column
echo '</tr>';
return;
}
foreach($cnode->child as $c) {
drawTable($c, $maxLevel);
}
}
// update the data structure
$maxLevel = 0;
foreach($rows as $r) {
if($r->pid == -1) {
$level = 0;
$r->span = cLeaves($r, $level, $maxLevel);
$r->level = $level;
}
}
echo '<table border="1">';
echo '<tr>';
// draw table's title row
for($i = 0; $i <= $maxLevel; $i++) {
echo '<td>item'.($i+1).'</td>';
if($i == $maxLevel) echo '<td>value</td>';
}
echo '</tr>';
// draw tree on table format
foreach($rows as $r) {
if($r->pid == -1) {
echo '<tr>';
drawTable($r, $maxLevel);
}
}
echo '</table>';
?>
If you run the code, the result would be something like below:
What I still remember from PHP is, you can use for loop and put one of these rows into the php <tag>. Then use your SELECT query to get each tuple from MySql into each tuple's cells in this tag:
<tr>
<td> Cell value using Sql Select statement</td>
<td> Cell value using Sql Select statement</td>
<td> Cell value using Sql Select statement</td>
</tr>
You can do this process n of times depend on the No. Of rows you want to insert into the table.
Then, close your **PHP <tag>.
you can use mysqli_fetch_assoc to fetch your data from the database and run a loop to format it using html table:
<table border=1>
<thead>
<tr>
<th>idx</th>
<th>item_name</th>
<th>parent_id</th>
</tr>
</thead>
<tbody>
<?php
$con = mysqli_connect("localhost", "root", "", "yourdatabase");
$table = mysqli_query($con, "SELECT idx, item_name, parent_id FROM mytable");
while ($record = mysqli_fetch_assoc($table)) {
echo "<tr>";
echo "<td>" . $record["idx"] . "</td>";
echo "<td>" . $record["item_name"] . "</td>";
echo "<td>" . $record["parent_id"] . "</td>";
echo "</tr>";
}
?>
</tbody>
If you want to use a library, you can check codeigniter (PHP framework)'s table helper.
https://codeigniter.com/userguide3/libraries/table.html
$this->table->generate($table);
Good day. I'm now trying to create detail that come from my sql table.
Here is My PHP:-
public function export()
{
$query = $this->input->cookie("cookie_invent_query");
$data['header'] = $this->modelmodel->showdata($query);
foreach($data['header'] as $header){
$data['detail'][] = $this->modelmodel->showdata("select * from DeliveryOrderDetail
where deliveryordertransno = '".$header->TransactionNo."' ");
}
echo "<pre>"; print_r($data['detail']);
$this->load->view("do_mutasi/export",$data);
}
with my script above i get tis in print_r()
result from $data['header']
Array
(
[0] => stdClass Object
(
[FinalReleaseStatus] => 1
[DeliveryOrderDate] => 2016-12-21 17:25:18.487
[TransactionNo] => DO-DL-K-LFKG-11
[DocumentNo] => DOZZ-DL-K-LFKG-6
[ToCustomerCode] => AFF004
[CategoryCode] => ZZ
[ETADate] => 2016-12-21 17:25:18.487
)
)
result from $data['detail']
Array
(
[0] => Array
(
[0] => stdClass Object
(
[TransactionNo] => DOD-DL-K-LFKG-9
[LineNo] => 1000
[ItemCode] => FA00000111
[DeliveryOrderTransNo] => DO-DL-K-LFKG-11
[ExtraRemark] => 0
[ExtraRemark2] => 0
[Quantity] => 3.00000000000000000000
[UOMCode] => PCS
[CreatedDate] => 2016-12-21 17:26:25.063
[CreatedBy] => boby
[ModifiedDate] => 2016-12-21 17:26:25.063
[ModifiedBy] =>
)
)
)
then after i send it to my view and this what i can do for now
<?php foreach($header as $hdr) { ?>
Header
<table class="table">
<thead>
<tr>
<th>Trnsaction No</th>
<th>Document No</th>
<th>To Customer</th>
<th>Delivery Order Date</th>
</tr>
</thead>
<tbody>
<td><?=$hdr->TransactionNo;?></td>
<td><?=$hdr->DocumentNo;?></td>
<td><?=$hdr->ToCustomerCode;?></td>
<td><?=$hdr->DeliveryOrderDate;?></td>
</tbody>
</table>
Detail
<table>
<thead>
<tr>
<th>Transaction No</th>
<th>Item Code</th>
<th>Quntity</th>
<th>Uom Code</th>
</tr>
</thead>
<tbody>
<?php
foreach($detail as $rsltdt =>$key) { ?>
<tr>
<td><?=$rsltdt['TransactionNo'];?></td>
<td><?=$rsltdt['ItemCode'];?></td>
<td><?=$rsltdt['Quantity'];?></td>
<td><?=$rsltdt['UOMCode'];?></td>
</tr>
<?php } ?>
</tbody>
</table>
<?php } ?>
Asyou can see. I loop the detail inside the header loop. Because in some records there are multiple detail. I loop the header because i want to show it multiple records not just one record
here is the result so far
I can't show detail. So my question is. How can i show the detail depends on header.
[TransactionNo] = [DeliveryOrderTransNo]
Check once:-
foreach($detail as $rsltdt) {
foreach ($rsltdt as $rsl){ ?>
<tr>
<td><?=$rsl->TransactionNo;?></td>
<td><?=$rsl->ItemCode;?></td>
<td><?=$rsl->Quantity;?></td>
<td><?=$rsl->UOMCode;?></td>
</tr>
<?php } } ?>
It is better to put all details in its corresponding header :
public function export()
{
$query = $this->input->cookie("cookie_invent_query");
$data['header'] = $this->modelmodel->showdata($query);
foreach($data['header'] as $header){
$data['header']['details'] = $this->modelmodel->showdata("select * from DeliveryOrderDetail
where deliveryordertransno = '".$header->TransactionNo."' ");
}
}
then you can simply write the second loop :
foreach($hdr['details'] as $rsltdt) { ?>
<tr>
<td><?=$rsltdt->TransactionNo;?></td>
<td><?=$rsltdt->ItemCode;?></td>
<td><?=$rsltdt->Quantity;?></td>
<td><?=$rsltdt->UOMCode;?></td>
</tr>
<?php } ?>
You don't need to nest the details array anymore :
put:
$data['header']['details'] = $this->modelmodel->showdata("select * f....
instead of:
$data['header']['details'][] = $this->modelmodel->showdata("select * f....
I made a report of the databases created in a server, showing some row counters results from similar tables on those databases, using a table named Host to change the database configuration..Now I'm trying to add a simple search form in the same view to show only the macthed results. But I having problems with pagination.
In the HostController:
<?php
class HostsController extends AppController {
public $paginate = array('limit' => 1); //just as a test
function index() {
$conditions = array();
if(!empty($_GET['host_name'])){
$asd=($_GET['host_name']);
$asd=strtoupper($asd);
$conditions = array(
'OR' => array(
'upper(Host.client_name) LIKE' => "%$asd%",
'upper(Host.contact_name) LIKE' => "%$asd%",
'upper(Host.contac_email) LIKE' => "%$asd%"));
}
$hosts = $this->Host->find('all', array('conditions'=>$conditions));
foreach ($hosts as $key => $host) {
App::import('model','Product');
$this->Product = new Product;
$this->Product->changeDataSource($host['Host']['db_name']);
if($this->changeDbSource($host['Host']['db_name'])) {
$count = $this->Product->query('SELECT count(id) as "Product__count" from products');
$hosts[$key]['Host']['count_products']= $count[0]['Product']['count'];
$options = array(
'conditions' => array(),
'order' => array(
'Product.created DESC'));
$product = $this->Product->find('first', $options);
$hosts[$key]['Host']['last_product'] = $product['Product'];
}
App::import('model','Sale');
$this->Sale = new Sale;
$this->Sale->changeDataSource($host['Host']['db_name']);
if($this->changeDbSource($host['Host']['db_name'])) {
$count = $this->Sale->query('SELECT count(id) as "Sale__count" from sales');
$hosts[$key]['Host']['count_sales']= $count[0]['Sale']['count'];
$options = array(
'conditions' => array(),
'order' => array(
'Sale.created DESC'));
$sale = $this->Sale->find('first', $options);
$hosts[$key]['Host']['last_sale'] = $sale['Sale'];
} }
$this->set(compact('hosts'));
$this->paginate ();}///<<<< Here is the problem?>
In the view:
<form method="GET" >
<input id="clientNameSearch" type="text" name="host_name"
value="<?php echo !empty($_GET['host_name']) ?
$_GET['host_name']:"";?>" placeholder="Client, Contact or email of the contact" >
<input type="submit" value="Search">
</form>
In the app controller(with a database config per row in hosts table):
function changeDbSource($database = 'default') {
$db = ConnectionManager::getInstance();
$connected = $db->getDataSource($database);
if($connected->isConnected()) {return true;} else {return false;}}
So, using just $this->paginate (); give me the WHOLE LIST of host table (or the search result) and doesnt paginate, only the leyend of the button result of
echo $this->Paginator->counter(array('format' => __());
in the view seems to work
I've been trying some variations on paginate() arguments, using conditions, definig a custom paginate() and others options suggested here with no positive result, probably because I'm new on this.
According to the documentation, I shoud be able to use:
<?php
if (!empty($_GET['host_name'])){
$asd=($_GET['host_name']);
$asd=strtoupper($asd);
$this->paginate = array(
'conditions' => array(
'OR' => array(
'upper(Host.client_name) LIKE' => "%$asd%",
'upper(Host.contact_name) LIKE' => "%$asd%",
'upper(Host.contac_email) LIKE' => "%$asd%")
),'limit' => 2);}//just a test
if(empty($_GET['host_name'])) {$this->paginate();}?>
Still, no results.
So, if anyone know how to make it work or any suggestion, I'm all ears.
Thanks in advance(sorry for the poor english and coding).
Solution:?
Since there was no anwsers..here is what I got:
I just put the next code before the foreach loops
if (!empty($_GET['host_name'])){
$getvar=($_GET['host_name']);
$getvar=strtoupper($getvar);
$this->paginate = array(
'conditions' => array(
'OR' => array(
'upper(Host.client_name) LIKE' => "%$getvar%",
'upper(Host.contact_name) LIKE' => "%$getvar%",
'upper(Host.contac_email) LIKE' => "%$getvar%",
'upper(Host.company_ruc) LIKE' => "%$getvar%")
),
'limit' =>2);}
$hosts=$this->paginate ();
And in the Index.php:
<?php
$args = $_GET;
unset($args['url']);
$paginator->options(
array(
'url' => $this->passedArgs + array('?'=>$args)
)
);?>
It shows what I need, in the way I need, but the sort option apparenly doesnt work..I guess I wont use it
Add the search form in your view:
echo $this->Form->create('Host');
echo $this->Form->text('keywords');
echo $this->Form->submit('Search');
echo $this->Form->end();
Add the search form method in your controller:
$settings = array();
// Simple search method
if(! empty($this->request->data['Host']['keywords'])){
$keywords = explode(' ',$this->request->data['Host']['keywords']);
foreach($keywords as $key=>$keyword){
$settings['conditions']['OR'][] = array('Host.foo Like' => '%'.$keyword.'%');
$settings['conditions']['OR'][] = array('Host.bar Like' => '%'.$keyword.'%');
}
}
$this->paginate = $settings;
$this->set('hosts', $this->Paginator->paginate('Host'));
(Replace Host.foo and Host.bar with the columns you want to search in your hosts table - you can add more if you need to).
The standard Cake paginator will work for you in your index view:
<table>
<thead>
<tr>
<th><?php echo $this->Paginator->sort('name'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($hosts as $host): ?>
<tr>
<td><?php echo h($host['Host']['name']); ?> </td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
Remember the Paginator->sort('heading') must match the name of the column in your table, if you want a different title to show on your page you can use the second - title - argument i.e. Paginator->sort('column_name', 'Title to Display');
Should get you rolling.
I'm looking to modify a table on a page to include merged rows.
Here is the php code that deals with the output from a mysql db:
######## PRINT OUT TABLE WITH YEARS AND OFFICES PLUS NAMES IN CELLS ########
for ($y = $year_max; $y >=$year_min; $y--){
echo '<tr><th>'.$y.'</th>';
for ($i = 0; $i<count($offices_used); $i++){
if (isset($data[$y][$offices_used[$i]])){
echo '<td>'.$data[$y][$offices_used[$i]].'</td>';
} // END IF
else {
echo '<td></td>';
} // END ELSE
} echo '</tr>';
} // END FOR
The table further below is generated from a multidimensional array such as immediately below;
array (
[2013] => Array
(
[President] => John Mills
[Internal VP] => Virgil Bagdonas
[External VP] => Reid Gilmore
[Treasurer] => Todd Heino
[Secretary] => Eric Holmquist
[Newsletter] => Art Bodwell
[Webmaster] => Dave Eaton
[Photographer] => Rick Angus
[Video Librarian] => Mike Peters
[Store Manager] => Kevin Nee
)
[2012] => Array
(
[President] => Dave Eaton
[Internal VP] => Jim Metcalf
[External VP] => Reid Gilmore
[Treasurer] => Mike Peters
[Secretary] => Eric Holmquist
[Newsletter] => Art Bodwell
[Webmaster] => Dave Eaton
[Photographer] => Peter Wilcox
[Video Librarian] => Ray Asselin
[Store Manager] => Joe Giroux
)
[2011] => Array
(
[President] => Charlie Croteau
[Internal VP] => Reid Gilmore
[External VP] => Rick Angus
[Treasurer] => Mike Peters
[Secretary] => Eric Holmquist
[Newsletter] => Ron Rocheleau
[Webmaster] => Dave Eaton
[Photographer] => Peter Wilcox
[Video Librarian] => Ray Asselin
[Book Librarian] => Roger Boisvert
[Store Manager] => Mike Smith
)
...etc
My php code NOW generates this table from mysql db:
<tr>
<th>Year</th>
<th>President</th>
<th>Internal VP</th>
<th>External VP</th>
<th>Treasurer</th>
<th>Secretary</th>
<th>Webmaster</th>
<th>Newsletter</th>
<th>Photographer</th>
<th>Video Librarian</th>
<th>Book Librarian</th>
<th>Store Manager</th>
</tr>
<tr>
<th>2013</th>
<td>John Mills</td>
<td>Virgil Bagdonas</td>
<td>Reid Gilmore</td>
<td>Todd Heino</td>
<td>Eric Holmquist</td>
<td>Dave Eaton</td>
<td>Art Bodwell</td>
<td>Rick Angus</td>
<td>Mike Peters</td>
<td></td>
<td>Kevin Nee</td>
</tr>
<tr>
<th>2012</th>
<td>Dave Eaton</td>
<td>Jim Metcalf</td>
<td>Reid Gilmore</td>
<td>Mike Peters</td>
<td>Eric Holmquist</td>
<td>Dave Eaton</td>
<td>Art Bodwell</td>
<td>Peter Wilcox</td>
<td>Ray Asselin</td>
<td></td>
<td>Joe Giroux</td>
</tr>
<tr>
<th>2011</th>
<td>Charlie Croteau</td>
<td>Reid Gilmore</td>
<td>Rick Angus</td>
<td>Mike Peters</td>
<td>Eric Holmquist</td>
<td>Dave Eaton</td>
<td>Ron Rocheleau</td>
<td>Peter Wilcox</td>
<td>Ray Asselin</td>
<td>Roger Boisvert</td>
<td>Mike Smith</td>
</tr>
But I WOULD LIKE to modify the array handling output to get the following:
<tr>
<th>Year</th>
<th>President</th>
<th>Internal VP</th>
<th>External VP</th>
<th>Treasurer</th>
<th>Secretary</th>
<th>Webmaster</th>
<th>Newsletter</th>
<th>Photographer</th>
<th>Video Librarian</th>
<th>Book Librarian</th>
<th>Store Manager</th>
</tr>
<tr>
<th>2013</th>
<td>John Mills</td>
<td>Virgil Bagdonas</td>
<td rowspan= "3">Reid Gilmore</td>
<td>Todd Heino</td>
<td rowspan="3">Eric Holmquist</td>
<td rowspan="9">Dave Eaton</td>
<td rowspan="2">Art Bodwell</td>
<td>Rick Angus</td>
<td>Mike Peters</td>
<td></td>
<td>Kevin Nee</td>
</tr>
<tr>
<th>2012</th>
<td>Dave Eaton</td>
<td>Jim Metcalf</td>
<td rowspan="2">Mike Peters</td>
<td>Peter Wilcox</td>
<td rowspan="3">Ray Asselin</td>
<td></td>
<td>Joe Giroux</td>
</tr>
<tr>
<th>2011</th>
<td>Charlie Croteau</td>
<td>Rick Angus</td>
<td>Ron Rocheleau</td>
<td>Peter Wilcox</td>
<td>Roger Boisvert</td>
<td>Mike Smith</td>
</tr>
Any leads on how to add a flag or counter to accomplish this is welcome. Thanks!
try this hope to work.(because I have not run it but think should work).
CODE for colspan:
for ($y = $year_max; $y >=$year_min; $y--){
echo '<tr><th>'.$y.'</th>';
$lastVal='';
$buf=array();
for ($i = 0; $i<count($offices_used); $i++){
(!isset($data[$y][$offices_used[$i]])?($data[$y][$offices_used[$i]]=''):'');// Im not sure that is really needed
if($lastVal==$data[$y][$offices_used[$i]]){
$buf[count($buf)-1]['rep']++;
}else{
$lastVal=$data[$y][$offices_used[$i]];
$buf[]=array('data'=>$lastVal,'rep'=>1);
}
foreach($buf as $arr){
echo '<td'.($arr['rep']>1?' colspan="'.$arr['rep'].'"':'') . '>'.$arr['data'].'</td>';
}
} echo '</tr>';
} // END FOR
NOTICE: error of code corrected
CODE for rowspan:(I think it can be down easier than this. bur I have tried to be good).
$buf=array();
for ($i = 0; $i<count($offices_used); $i++){// this loop makes fill $buf
$lastVal='';
for ($y = $year_max; $y >=$year_min; $y--){
(!isset($data[$y][$offices_used[$i]])?($data[$y][$offices_used[$i]]=''):'');// Im not sure that is really needed
if($lastVal==$data[$y][$offices_used[$i]]){
$buf[$i][count($buf[$i])-1]['rep']++;
}else{
$lastVal=$data[$y][$offices_used[$i]];
$buf[$i][$year_max-$y]=array('data'=>$lastVal,'rep'=>1);
}
}
}
$mtemp=$year_max;
foreach($buf as $row){
echo '<tr><th>'.$mtemp.'</th>';
foreach($row as $rec){
echo '<td'.($rec['rep']>1?' rowspan="'.$rec['rep'].'"':'') . '>'.$rec['data'].'</td>';
}
$mtemp--;
echo '</tr>';
}
really hope to work.
NOTICE: corrected
Solved by using:
############################################################################
######## PRINT OUT TABLE WITH YEARS AND OFFICES PLUS NAMES IN CELLS ########
for ($y = $year_max; $y >=$year_min; $y--){ // Loop through years
echo '<tr><th>'.$y.'</th>';
for ($i = 0; $i<count($offices_used); $i++){
if (isset($data[$y][$offices_used[$i]])){
$rowz =1;
if(!($data[$y][$offices_used[$i]] == $data[($y+1)][$offices_used[$i]])){
while ($data[$y][$offices_used[$i]] == $data[($y-$rowz)][$offices_used[$i]]) $rowz ++;
echo '<td rowspan = "'.$rowz.'">'.$data[$y][$offices_used[$i]].'</td>';
}
} // END IF
else {
echo '<td align = "center"> - </td>';
} // END ELSE
} echo '</tr>'; // End row of current year
} // END FOR Loop through years
echo '</table>';
See http://jsfiddle.net/eaton9999/8gMVK/ for resultant output page.
Thanks again to imsiso and other who helped!
I wrote a library a few days ago that can handle this stuff..
Have a look at https://github.com/donquixote/cellbrush
The benefit of the library is that you don't need to think about the order of cells in html, and which cells need to be skipped due to rowspan or colspan. Instead, you can just "paint" a cell anywhere in the grid, with whichever rowspan or colspan you want. And instead of specifying a number for rowspan or colspan, you simply specify the first and last row and column names of the rospan/colspan region.
E.g.
$table->td(['2011', '2013'], 'Secretary', 'Eric Holmquist');
Below is some code that creates the table you were asking for, with the help of this library. You still need some logic to calculate the intervals, but at least you don't need to worry about the integrity of the table html.
(This question is quite old, but there might still be people running into it from Google. So I hope it might be useful.)
<?php
require_once __DIR__ . '/vendor/autoload.php';
$data = array(
'2013' => array(
'President' => 'John Mills',
'Internal VP' => 'Virgil Bagdonas',
'External VP' => 'Reid Gilmore',
'Treasurer' => 'Todd Heino',
'Secretary' => 'Eric Holmquist',
'Newsletter' => 'Art Bodwell',
'Webmaster' => 'Dave Eaton',
'Photographer' => 'Rick Angus',
'Video Librarian' => 'Mike Peters',
'Store Manager' => 'Kevin Nee',
),
'2012' => array(
'President' => 'Dave Eaton',
'Internal VP' => 'Jim Metcalf',
'External VP' => 'Reid Gilmore',
'Treasurer' => 'Mike Peters',
'Secretary' => 'Eric Holmquist',
'Newsletter' => 'Art Bodwell',
'Webmaster' => 'Dave Eaton',
'Photographer' => 'Peter Wilcox',
'Video Librarian' => 'Ray Asselin',
'Store Manager' => 'Joe Giroux',
),
'2011' => array(
'President' => 'Charlie Croteau',
'Internal VP' => 'Reid Gilmore',
'External VP' => 'Rick Angus',
'Treasurer' => 'Mike Peters',
'Secretary' => 'Eric Holmquist',
'Newsletter' => 'Ron Rocheleau',
'Webmaster' => 'Dave Eaton',
'Photographer' => 'Peter Wilcox',
'Video Librarian' => 'Ray Asselin',
'Book Librarian' => 'Roger Boisvert',
'Store Manager' => 'Mike Smith',
),
);
// Collect positions to build table columns.
$positions = [];
foreach ($data as $year => $yearData) {
foreach ($yearData as $position => $person) {
$positions[$position] = TRUE;
}
}
$positions = array_keys($positions);
// Define table columns.
$table = (new \Donquixote\Cellbrush\Table())
->addColName('year')
->addColNames($positions)
;
// Create thead section.
$headRow = $table->thead()->addRow('head');
$headRow->th('year', 'Year');
foreach ($positions as $position) {
$headRow->th($position, $position);
}
// Create table rows with labels based on year.
$years = array_keys($data);
$table->addRowNames($years);
foreach ($years as $year) {
$table->th($year, 'year', $year);
}
// Fill table cells in each column.
foreach ($positions as $position) {
$periodPerson = NULL;
$periodFirstYear = NULL;
$periodLastYear = NULL;
$column = $table->colHandle($position);
foreach ($years as $year) {
$person = isset($data[$year][$position])
? $data[$year][$position]
: '-';
if (!isset($periodFirstYear)) {
// First year.
$periodFirstYear = $year;
}
elseif ($person !== $periodPerson) {
// Add a table cell with rowspan.
$column->td([$periodFirstYear, $periodLastYear], $periodPerson);
$periodFirstYear = $year;
}
$periodPerson = $person;
$periodLastYear = $year;
}
if (isset($periodFirstYear)) {
// Add a table cell with rowspan.
$column->td([$periodFirstYear, $periodLastYear], $periodPerson);
}
}
print $table->render();