Creating Html Element from multidimensional Array - php

Not sure how will i able to explain this, but here we go
I have an array as below:
$arr = array(
array('id' => 1,
'content' => '<h1>This is a simple Content</h1>',
'vars' => null,
'path' => 'holders/row.php',
'sub-page' => array(
'id' => 2,
'content' => '<h1>Sample Body Here</h1>',
'vars' => '{"title":"Sample Title Here"}',
'path' => 'holders/box.php',
'sub-page' => array(
'id' => 3,
'vars' => '{"title":"Sample Title NUmber 3 Here"}',
'content' => '<h1>Again Sample Body Here</h1>',
'path' => 'holders/box.php'
)
)
)
);
What i am looking for is
array should go to the deepest sub-page and json_decode the vars key and extract as variables and include the file.
Once this is done, the output is passed to the parent's content key and parse it again
This is basically for creating dynamic content
the holders/row.php contains:
<div class="row">
<?= $content; ?>
</div>
and holders/box.php contains:
<div class="box lite">
<div class="box-title">
<h4><?= $title; ?></h4>
<div class="tools">
<a href="javascript:;" class="collapse">
<i class="fa fa-chevron-up"></i>
</a>
</div>
</div>
<div class="box-body">
<?= $content; ?>
</div>
</div>
and the desired output is:
<div class="row">
<div class="box lite">
<div class="box-title">
<h4>Sample Title Here</h4>
<div class="tools">
<a href="javascript:;" class="collapse">
<i class="fa fa-chevron-up"></i>
</a>
</div>
</div>
<div class="box-body">
<h1>Again Sample Body Here</h1>
<div class="box lite">
<div class="box-title">
<h4>Sample Title NUmber 3 Here</h4>
<div class="tools">
<a href="javascript:;" class="collapse">
<i class="fa fa-chevron-up"></i>
</a>
</div>
</div>
<div class="box-body">
<h1>Again Sample Body Here</h1>
</div>
</div>
</div>
</div>
</div>
What have i tried so far
I am trying to loop around the array as below:
foreach ($arr as &$page) {
if (isset($page[$keyToParse])) {
$subMenu = $page[$keyToParse];
unset($page[$keyToParse]);
$page['content'] = $page['content'] . $this->parsePage($keyToParse, $subMenu);
return $page['content'];
} else {
$params = strlen($page['vars']) > 0 ? json_decode($page['vars'], true) : [];
$elementPath = $page['path'];
$params = array_merge($params, array('content' => $page['content']));
$page['content'] = callback(function () use ($params, $elementPath) {
extract($params);
include($elementPath);
});
return $page['content'];
}
and the function callback is as:
function callback($userfunc)
{
ob_start();
$userfunc();
$return = ob_get_contents();
ob_end_clean();
return $return;
}
Please help as i am stuck for a long time now

All you should have to do is something like this.
function renderNode($node){
ob_start();
if (isset($node["sub-page"]) && $node["sub-page"]){
$node["content"] = renderNode($node["sub-page"]);
}
extract($node);
include ($node["path"]);
return ob_get_clean();
}
and then invoke it like:
echo renderNode($arr[0]);

Related

Grabbing specific elements inside DIV from external page

I need to scrap the following elements inside each one of these div's class="product-grid-item" (page contains several of them), but in fact I have no clue how to do it... so, I need help not to pull my hair out.
1 - The link and image inside the div: class="product-element-top2;
<a href="https://...this_link" class="product-image-link"> (just need the link)
<img width="300" height="300" src="https://...this_image_url... (just need this image URL)
2 - The title inside the h3 tag as follows;
<h3 class="wd-entities-title"><a href="https://...linkhere">The title goes here (just the title)
3 - Last but not least, I need to grab tha price inside this;
<span class="price"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">€</span>20,00</bdi></span></span> (just the "€20.00")
Here's the full HTML:
<div class="product-grid-item" data-loop="1">
<div class="product-element-top">
<a href="https://...linkhere" class="product-image-link">
<img width="300" height="300" src="https://image-goes-here.jpg" class="attachment-woocommerce_thumbnail size-woocommerce_thumbnail"> </a>
<div class="top-information wd-fill">
<h3 class="wd-entities-title">The title goes here</h3>
<span class="price"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">€</span>20,00</bdi></span></span>
<div class="wd-add-btn wd-add-btn-replace woodmart-add-btn">
<span>Options</span></div>
</div>
<div class="wd-buttons wd-pos-r-t color-scheme-light woodmart-buttons">
<div class="wd-compare-btn product-compare-button wd-action-btn wd-style-icon wd-compare-icon">
Buy
</div>
<div class="quick-view wd-action-btn wd-style-icon wd-quick-view-icon wd-quick-view-btn">
quick view
</div>
<div class="wd-wishlist-btn wd-action-btn wd-style-icon wd-wishlist-icon woodmart-wishlist-btn">
<a class="" href="https://linkhere/wishlist/" data-key="dcf36756534755" data-product-id="387654" data-added-text="See Wishlist">Wishlist</a>
</div>
</div>
<div class="quick-shop-wrapper wd-fill wd-scroll">
<div class="quick-shop-close wd-action-btn wd-style-text wd-cross-icon">Close</div>
<div class="quick-shop-form wd-scroll-content">
</div>
</div>
</div>
</div>
One of my clumsy attempts:
$html = file_get_contents("https://url-here.goetohere");
$DOM = new DOMDocument();
$DOM->loadHTML($html);
$finder = new DomXPath($DOM);
$classname = 'product-grid-item';
$classname = 'product-element-top2';
$classname = 'product-element-top2';
$classname = 'wd-entities-title';
$classname = 'price';
$nodes = $finder->query("//*[contains(#class, '$classname')]");
foreach ($nodes as $node) {
echo 'here »» ' . htmlentities($node->nodeValue) . '<br>';
}
Assuming that the HTML is being fetched correctly prior to attempting any DOM processing then it is fairly straightforward to construct some basic XPath expressions to find the indicated content.
As per the comment page contains several of them there are 2 product-grid-item divs as you'll note in the output.
$html='
<div class="product-grid-item" data-loop="1">
<div class="product-element-top">
<a href="https://...linkhere" class="product-image-link">
<img width="300" height="300" src="https://image-goes-here.jpg" class="attachment-woocommerce_thumbnail size-woocommerce_thumbnail">
</a>
<div class="top-information wd-fill">
<h3 class="wd-entities-title">
The title goes here
</h3>
<span class="price">
<span class="woocommerce-Price-amount amount">
<bdi>
<span class="woocommerce-Price-currencySymbol">€</span>20,00
</bdi>
</span>
</span>
<div class="wd-add-btn wd-add-btn-replace woodmart-add-btn">
<a href="https://...linkhere" data-quantity="1" class="button product_type_variable add_to_cart_button add-to-cart-loop">
<span>Options</span>
</a>
</div>
</div>
<div class="wd-buttons wd-pos-r-t color-scheme-light woodmart-buttons">
<div class="wd-compare-btn product-compare-button wd-action-btn wd-style-icon wd-compare-icon">
Buy
</div>
<div class="quick-view wd-action-btn wd-style-icon wd-quick-view-icon wd-quick-view-btn">
quick view
</div>
<div class="wd-wishlist-btn wd-action-btn wd-style-icon wd-wishlist-icon woodmart-wishlist-btn">
<a class="" href="https://linkhere/wishlist/" data-key="dcf36756534755" data-product-id="387654" data-added-text="See Wishlist">Wishlist</a>
</div>
</div>
<div class="quick-shop-wrapper wd-fill wd-scroll">
<div class="quick-shop-close wd-action-btn wd-style-text wd-cross-icon">
Close
</div>
<div class="quick-shop-form wd-scroll-content"></div>
</div>
</div>
</div>
<div class="product-grid-item" data-loop="1">
<div class="product-element-top">
<a href="https://www.example.com/banana" class="product-image-link">
<img width="300" height="300" src="https://www.example.com/kittykat.jpg" class="attachment-woocommerce_thumbnail size-woocommerce_thumbnail">
</a>
<div class="top-information wd-fill">
<h3 class="wd-entities-title">
Oh look, another title!
</h3>
<span class="price">
<span class="woocommerce-Price-amount amount">
<bdi>
<span class="woocommerce-Price-currencySymbol">€</span>540,00
</bdi>
</span>
</span>
<div class="wd-add-btn wd-add-btn-replace woodmart-add-btn">
<a href="https://www.example.com/gorilla" data-quantity="1" class="button product_type_variable add_to_cart_button add-to-cart-loop">
<span>Options</span>
</a>
</div>
</div>
<div class="wd-buttons wd-pos-r-t color-scheme-light woodmart-buttons">
<div class="wd-compare-btn product-compare-button wd-action-btn wd-style-icon wd-compare-icon">
Buy
</div>
<div class="quick-view wd-action-btn wd-style-icon wd-quick-view-icon wd-quick-view-btn">
quick view
</div>
<div class="wd-wishlist-btn wd-action-btn wd-style-icon wd-wishlist-icon woodmart-wishlist-btn">
<a class="" href="https://www.example.com/wishlist/" data-key="dcf36756534755" data-product-id="387654" data-added-text="See Wishlist">Wishlist</a>
</div>
</div>
<div class="quick-shop-wrapper wd-fill wd-scroll">
<div class="quick-shop-close wd-action-btn wd-style-text wd-cross-icon">
Close
</div>
<div class="quick-shop-form wd-scroll-content"></div>
</div>
</div>
</div>';
To process the downloaded HTML
# set the libxml parameters and create new DOMDocument/XPath objects.
libxml_use_internal_errors( true );
$dom=new DOMDocument;
$dom->validateOnParse=false;
$dom->strictErrorChecking=false;
$dom->recover=true;
$dom->loadHTML( $html );
libxml_clear_errors();
$xp=new DOMXPath( $dom );
# some basic XPath expressions
$exprs=(object)array(
'product-link' => '//a[#class="product-image-link"]',
'product-img-src' => '//a[#class="product-image-link"]/img',
'h3-title-text' => '//h3[#class="wd-entities-title"]',
'price' => '//span[#class="price"]/span/bdi'
);
# find the keys (for convenience) to be used below
$keys=array_keys( get_object_vars( $exprs ) );
# store results here
$res=array();
# loop through all patterns and issue XPath query.
foreach( $exprs as $key => $expr ){
# add key to output and set as an array.
$res[ $key ]=[];
$col=$xp->query( $expr );
# find the data if the query succeeds
if( $col && $col->length > 0 ){
foreach( $col as $node ){
switch( $key ){
case $keys[0]:$res[$key][]=$node->getAttribute('href');break;
case $keys[1]:$res[$key][]=$node->getAttribute('src');break;
case $keys[2]:$res[$key][]=trim($node->textContent);break;
case $keys[3]:$res[$key][]=trim($node->textContent);break;
}
}
}
}
# show the result or do really interesting things with the data
printf('<pre>%s</pre>',print_r($res,true));
Which yields:
Array
(
[product-link] => Array
(
[0] => https://...linkhere
[1] => https://www.example.com/banana
)
[product-img-src] => Array
(
[0] => https://image-goes-here.jpg
[1] => https://www.example.com/kittykat.jpg
)
[h3-title-text] => Array
(
[0] => The title goes here
[1] => Oh look, another title!
)
[price] => Array
(
[0] => â¬20,00
[1] => â¬540,00
)
)

How to echo these foreach arrays properly?

Working on a project, am pretty new to PHP and don't know how to do this in a better way.
$item_thumbnails = array(
"https://brkcdn.com/v2/images/shop/thumbnails/f7dd8e95-551f-5e1f-92f1-2ea6c29e61ca.png",
"https://brkcdn.com/v2/images/shop/thumbnails/9fd1ea9d-cfd0-525a-963f-0c3438c5dc34.png"
);
$item_names = array(
"brick-luke's Fedora",
"Golden Bok"
);
$item_urls = array(
"https://www.brick-hill.com/shop/20/",
"https://www.brick-hill.com/shop/10267/"
);
$item_values = array(
"30.000",
"100.000"
);
$item_demands = array(
"High",
"Low"
);
foreach ($item_urls as $key => $item_url) {
foreach ($item_thumbnails as $key => $item_thumbnail) {}
foreach ($item_names as $key => $item_name) {}
foreach ($item_values as $key => $item_value) {}
foreach ($item_demands as $key => $item_demand) {}
echo ('
<div class="card">
<a class="image" href="'.$item_url.'">
<img src="'.$item_thumbnail.'" onerror="this.onerror=null;this.src="'.$storageUrl.'/error.png"">
</a>
<div class="content">
<a class="header">'.$item_name.'</a>
<div class="ui divider"></div>
Value: <div class="ui right floated red horizontal label">'.$item_value.'</div>
<div class="ui divider"></div>
Demand: <div class="ui right floated green horizontal label">'.$item_demand.'</div>
</div>
</div>
');
}
It only shows the latest item in the array on all tabs (if there are more).
How to fix this? Help is appreciated.
Something like this should work:
$item_thumbnails = array(
"https://brkcdn.com/v2/images/shop/thumbnails/f7dd8e95-551f-5e1f-92f1-2ea6c29e61ca.png",
"https://brkcdn.com/v2/images/shop/thumbnails/9fd1ea9d-cfd0-525a-963f-0c3438c5dc34.png"
);
$item_names = array(
"brick-luke's Fedora",
"Golden Bok"
);
$item_urls = array(
"https://www.brick-hill.com/shop/20/",
"https://www.brick-hill.com/shop/10267/"
);
$item_values = array(
"30.000",
"100.000"
);
$item_demands = array(
"High",
"Low"
);
// iterate over one array and get values from
// other arrays under the same key `$key`
foreach ($item_urls as $key => $item_url) {
echo ('
<div class="card">
<a class="image" href="'.$item_url.'">
<img src="' . $item_thumbnails[$key] . '" onerror="this.onerror=null;this.src="'.$storageUrl.'/error.png"">
</a>
<div class="content">
<a class="header">' . $item_names[$key] . '</a>
<div class="ui divider"></div>
Value: <div class="ui right floated red horizontal label">' . $item_values[$key] . '</div>
<div class="ui divider"></div>
Demand: <div class="ui right floated green horizontal label">' . $item_demands[$key] . '</div>
</div>
</div>
');
}
First of all you should improve your array structure.
$items = array(
[
"thumbnail" => "https://brkcdn.com/v2/images/shop/thumbnails/f7dd8e95-551f-5e1f-92f1-2ea6c29e61ca.png"
"name" => "brick-luke's Fedora",
"url" => "https://www.brick-hill.com/shop/20/",
"value" => "30.000",
"demand" => "High"
],
[
"thumbnail" => "https://brkcdn.com/v2/images/shop/thumbnails/9fd1ea9d-cfd0-525a-963f-0c3438c5dc34.png",
"name" => "Golden Bok",
"url" => "https://www.brick-hill.com/shop/10267/",
"value" => "100.000",
"demand" => "Low"
]
);
After that you can foreach $items variable and take data from it. See below:
<?php
foreach ($items as $item) {
?>
<div class="card">
<a class="image" href="<?php echo $item['url']; ?>">
<img src="<?php echo $item['thumbnail']; ?>" onerror="this.onerror=null;this.src=<?php echo $storageUrl; ?>/error.png">
</a>
<div class="content">
<a class="header"><?php echo $item['name']; ?></a>
<div class="ui divider"></div>
Value: <div class="ui right floated red horizontal label"><?php echo $item['value']; ?></div>
<div class="ui divider"></div>
Demand: <div class="ui right floated green horizontal label"><?php echo $item['demand']; ?></div>
</div>
</div>
<?php
}
?>
Enjoy!

Pass array to view in Codeigniter

I have a breadcrumb that i send to my view pages, but the part that have an array not load, just static code.
I think the problem it's in variable inside array, because i have another breadcrumbs with same problem, the static is loaded.
Example breadcrumb that I want: Home -> Product -> "Tshirt name"
Controller:
$itensBreadCrumb["itensBreadCrumb"] = array(
"Home" => "home",
"Produtos" => "produtos", // after this don't load in view.
strtolower($produto->nome) => ""
);
$dataProdutos['produto'] = $produto;
$dataProdutos['estoques'] = $this->produtos_model->retornaEstoqueProduto($produto[0]->id);
$dataProdutos['breadcrumb'] = $this->load->view("breadcrumb", $itensBreadCrumb, TRUE);
Breadcrumb structure View:
<div class="breadcrumb">
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<?php foreach ($itensBreadCrumb as $item => $link) {
if(!empty($link)){
?>
<?=$item?>
<?php }else{ ?>
<span class="item-bread"><?=$item?></span>
<?php
}
} ?>
</div>
</div>
</div>
How i'm calling breadcrumb in pages.
<?= $breadcrumb ?>

Div tags in a foreach loop in PHP

I'm wondering what is the best practice to embed tags in a foreach loop?
I have an associative array which has one entry with the following keys:
$portfolio = [
'title' => '',
'technology' => '',
'description' => '',
'link' => '',
];
What I am trying to do is echo the div tag with the specific elements inside, but each div tag is then duplicated:
<div class="container">
<div class="row">
<div class="col-md-6 col-lg-4"><div class="card">\n<div class="car img
top"></div>
</div>
</div><div class="col-md-6 col-lg-4"><div class="card"><div class="car
img top"></div>
</div>
</div><div class="col-md-6 col-lg-4"><div class="card"><div class="car
img top"></div>
</div>
</div><div class="col-md-6 col-lg-4"><div class="card"><div class="car
img top"></div>
</div>
</div> </div><!-- row end -->
</div><!-- container end -->
My foreach loop is:
I have commented some out, as I'm in the process of debugging as when the page is loaded a white page appears, which the error is within the commented out code, which I will fix.
foreach($portfolio as $value){
echo '<div class="col-md-6 col-lg-4">' . '\n';
echo '<div class="card">' . '\n';
echo '<div class="car img top">';
//echo "<img src='img/" . "$value['image']'" . ">";
//echo "</div>";
//echo "<div class='card-body'>";
// echo "<div class='card-body'>";
// echo "<h3 class'card-title'><a class='text-secondary' href='#'>See Project</a></h3>";
// echo "<h6 class='card-subtitle mb-2 text-muted'>$value['description']</h6>";
echo "</div>". "\n";
echo "</div>" . "\n";
echo "</div>";
}
Any help would be appreciated, but I think my best aim is to do a multidimensional array?
Thanks,
James
If your problem is only a formatting and legibility one, try to use this syntax instead.
<?php foreach($portfolio as $value):?>
<div class="col-md-6 col-lg-4">
<div class="card">
<div class="car img top">
<img src="img/<?php echo $value['image'];?>" />
</div>";
<div class="card-body">
<div class="card-body">
<h3 class='card-title'>
<a class='text-secondary' href='<?php echo $value['link']?>'>
<?php echo $value['title']?>
</a>
</h3>
<h6 class='card-subtitle mb-2 text-muted'><?php echo $value['description']?></h6>
</div>
</div>
</div>
</div>
<?php endforeach;?>
Notice that you had mistakes on your quotes and you had forgotten the closing div tag. This format makes it easier to read and catch mistakes.
Note in my example, I assume that your $portfolio variable is a multi-dimensional array as such:
$portfolio = [
[
'title' => '',
'technology' => '',
'description' => '',
'link' => ''
],
[
'title' => '',
'technology' => '',
'description' => '',
'link' => ''
],
// etc
];

Automatically Update Bootstrap Layout With PHP

I'm trying to generate a layout with php and jQuery which lists certain profiles and organizes them in a certain way.
Specifically, I have an array of program titles and I'd like to list all of the program titles on the page as headers with two program titles per row. Then, I have an array of names which each contain an array of program names. I'd like to list all of the users that have a certain program in their array underneath the relevant program title. Additionally, the names start off hidden and each program title has a button underneath it which hides and shows tutors. I've created this layout using Bootstrap here:
<?php
include ('objects.php');
function tutorCreator($tutorName, $boxNum, $spanClass){
include ('objects.php');
echo "<div class='" . $spanClass . " tutorBox" . $boxNum . "'>";
}
?>
<div class="row-fluid">
<span class="programHeader span5">DreamWeaver</span>
<span class="programHeader offset1 span5">GIMP</span>
</div>
<div class="row-fluid">
<span class="span2 showTutors">Show tutors</span>
<span class="span2 offset4 showTutors">Show tutors</span>
</div>
<div class="row-fluid">
<?php
tutorCreator('Kevin Marks', '1', "span4");
tutorCreator('Kevin Marks','2', "span4 offset2");
?>
</div>
<div class="row-fluid">
<?php
tutorCreator('Helen Larson', "1", "span4");
tutorCreator('Helen Larson','2', "span4 offset2");
?>
</div>
<div class="row-fluid">
<span class="programHeader span5">Google Analytics</span>
<span class="programHeader offset1 span5">HootSuite</span>
</div>
<div class="row-fluid">
<span class="span2 showTutors">Show tutors</span>
<span class="span2 offset4 showTutors">Show tutors</span>
</div>
<div class="row-fluid">
<?php
tutorCreator('Ken Gato', '3', "span4");
tutorCreator('Julien Mans', '4', "span4 offset2");
?>
</div>
<div class="row-fluid">
<?php
tutorCreator('Ommed Kosh', '3', "span4");
?>
</div>
The classes added to the tutor names are for the purpose of being shown when the appropriate "show tutors" button is listed and to help with the layout.
The objects.php file contains the arrays with the list of tutors and the list of programs. This layout works fine. However, I'm trying to change the php code so that this layout is automatically updated each time I add a program or a tutor to the arrays in objects.php. I've been trying to figure it out for a few days and I just can't get an automatically updated layout which works well. I realize this is probably too broad a question but I've hit a road block so any help would really be appreciated. You can see a fuller version of the current layout here: http://www.tutorgrams.com/tutors. Thanks for any help.
Here is the objects.php file (with some tutors and programs removed for brevity):
<?php
$programs = array();
$programs['DreamWeaver'] = array(
'name' => 'DreamWeaver');
$programs['GIMP'] = array(
'name' => 'GIMP');
$programs['Google Analytics'] = array(
'name' => 'Google Analytics');
$programs['HootSuite'] = array(
'name' => 'HootSuite');
$tutors['Helen Larson'] = array(
'name' => 'Helen Larson',
'programs' => array('DreamWeaver', 'GIMP')
);
$tutors['Kevin Marks'] = array(
'name' => 'Kevin Marks',
'programs' => array('DreamWeaver', 'GIMP')
);
$tutors['Ommed Kosh'] = array(
'name' => 'Ommed Kosh',
'programs' => array('Google Analytics')
);
$tutors['Julien Mans'] = array(
'name' => 'Julien Mans',
'programs' => array('HootSuite')
);
$tutors['Ken Gato'] = array(
'name' => 'Ken Gato',
'programs' => array('Google Analytics')
);
?>
How does this look?
<?php
$numProgs = count($programs);
$progs = array_keys($programs);
$i = 0; ?>
<?php while($i < $numProgs): ?>
<div class="row-fluid">
<span class="programHeader span5"><?php echo $progs[$i]; ?></span>
<span class="programHeader offset1 span5"><?php echo $progs[$i + 1]; ?></span>
</div>
<div class="row-fluid">
<span class="span2 showTutors">Show tutors</span>
<span class="span2 offset4 showTutors">Show tutors</span>
</div>
<div class="row-fluid">
<?php foreach($tutors as $name => $data) {
$tutProgs = $data['programs'];
if(in_array($progs[$i], $tutProgs)) {
tutorCreator($name, $i, "span4");
}
} ?>
</div>
<div class="row-fluid">
<?php
foreach($tutors as $name => $data) {
$tutProgs = $data['programs'];
if(in_array($progs[$i + 1], $tutProgs)) {
tutorCreator($name, $i + 1, "span4 offset2");
}
}
?>
</div>
<?php $i += 2; ?>
<?php endwhile; ?>
It could probably be optimised a little but it seems to do the trick for me. The only thing is I don't have your themes so It might not look right yet.

Categories