Simple dom parser results in multiple pages - php

I have parsed a page to get the titles, and sometimes the parsed titles are more than 11. My designed template contain max 11 titles. My question is how to replicate the template () for the rest of the titles (from 12 -> n). I have to replicate the template somehow for the rest of results, but I don't know exactly how.
Bellow is my template, witch is displaying all the results.
<?php
include('parse/simple_html_dom.php');
$url = 'link-to-url';
$html = file_get_html($url);
$headlines = array();
$i = 0;
?>
<div class="pf w0 h0">
<div class="w0 h0">
<div class="header-pagina">
<svg role="img" class="header37"><use xlink:href="#header-hp"></use></svg>
</div>
<div class="page-wrapper">
<?php
foreach($html->find('.cmsmasters_row[1] .cmsmasters_toggle_title') as $title) {
$i++;
echo '<div class="agenda-curs">';
echo '<div class="agenda-tab"><span class="modul-tab-text color1" contenteditable="true">Modulul '.$i.'</span></div>';
echo '<div class="agenda-text" contenteditable="true">'.$headlines[] = $title->plaintext.'</div >';
echo '</div>';
}
$head = implode("", $headlines);
?>
</div>
<svg role="img" class="footer35"><use xlink:href="#footer35"></use></svg>
</div>
</div>

I don't know what you are using $head = implode("", $headlines); for in your script but you will be able to glean the data that you want from $headlines or headline_batch below.
Separating your processing from your printing will make your code easier to read and maintain. I could write the script to use less loops, but I am favoring readability over efficiency.
<?php
include('parse/simple_html_dom.php');
$url = 'link-to-url';
$html = file_get_html($url);
$headlines = array();
$counter = 0;
foreach($html->find('.cmsmasters_row[1] .cmsmasters_toggle_title') as $title) {
$headlines[++$counter] = $title->plaintext;
}
// no more processing, just printing
foreach (array_chunk($headlines, 10, true) as $headline_batch) {
?>
<div class="pf w0 h0">
<div class="w0 h0">
<div class="header-pagina">
<svg role="img" class="header37"><use xlink:href="#header-hp"></use></svg>
</div>
<?php
foreach ($headline_batch as $counter => $title) {
echo '<div class="agenda-curs">
<div class="agenda-tab"><span class="modul-tab-text color1" contenteditable="true">Modulul ' . $counter . '</span></div>
<div class="agenda-text" contenteditable="true">' . $title . '</div >
</div>';
}
?>
</div>
<svg role="img" class="footer35"><use xlink:href="#footer35"></use></svg>
</div>
</div>
<?php
}
?>
Using array_chunk($headlines, 10, true) will spare you having to use a modulus condition in your loop to check if a new group should be started. The true parameter retains the $counter values after splitting into groups.

Related

Dynamically building bootstrap row, 3 per row

I am not sure the best way to go about this, on a site i'm building (using bootstrap) i want to have 3 cards per row using the grid system like:
HTML:
<div class="container">
<div class="row">
<div class="col-sm">
One of three columns
</div>
<div class="col-sm">
One of three columns
</div>
<div class="col-sm">
One of three columns
</div>
</div>
</div>
Which is no problem normally, but i'm building it (or trying to) dynamically:
PHP:
<main>
<br /><br /><br />
<?php
$pages = array_slice(scandir($_SERVER['DOCUMENT_ROOT']), 2);
$mixed = shuffle($pages);
$count = 0;
echo '<div class="container"><div class="row">';
foreach($pages as $page)
{
$count++;
if (strpos($page, '.php') !== false && $page != 'index.php') {
$html = file_get_contents($page);
$code = explode("|", extractXvideos($html));
?>
<div class="col-md-4">
<div class="card" style="width: 18rem;">
<img src="<?= $code[3]; ?>" class="card-img-top" alt="<?= $code[0]; ?>">
<div class="card-body">
<p class="card-text"><?= substr($code[0], 0, 25); ?> ...</p>
</div>
</div>
</div>
<?php
if ($count == 18) {
// The reason only 15 is showing is because we ignore ".", ".." & "index.php".
break;
}
}
}
echo '</div></div>';
?>
</main>
For this project i'm scanning .php pages on the server, then trying to lay them out 3 per row, so after every row of 3 i need to start a new row echo '<div class="container"><div class="row">'; from what i can see, i do not know the best way to go about this, any help would be appreciated.
main
<?php
$pages = array_slice(scandir($_SERVER['DOCUMENT_ROOT']), 2);
$mixed = shuffle($pages);
$count = 0;
$output = '';
foreach($pages as $page) {
$count++;
if (strpos($page, '.php') !== false && $page != 'index.php') {
$html = file_get_contents($page);
$code = explode("|", extractXvideos($html));
$output .= '<div class="container">';
$output .= '<div class="row">';
$output .= '<div class="col">Column</div>';
$output .= '<div class="col">Column</div>';
$output .= '<div class="col">Column</div>';
$output .= '</div>
$output .= '</div>';
}
}
echo $output;
?>
main
try this template and apply your conditions.

WP-JSON - Multi-endpoint - Re-occuring Foreach Error

I'm currently trying to build out a multi-endpoint system for WP-JSON between 4 websites, and most of the time it's fine, however sometimes when my page performs the process, it will throw back an error for the Foreach cycle, saying 'Warning: Invalid argument supplied for foreach() in ...'
I've tried alternative methods of merging the arrays before retrieving the body using wp_remote_retrieve_body but there's no such luck. I've looked up various google solutions on multiple-endpoints using php but nothing i've found seems to do an effective job
<?php
function limit_text($text, $limit) {
if (str_word_count($text, 0) > $limit) {
$words = str_word_count($text, 2);
$pos = array_keys($words);
$text = substr($text, 0, $pos[$limit]) . '...';
}
return $text;
}
/* BASE DETAILS FOR SEARCH*/
$b_url = get_site_url(); // Base URL
$posts_merged;
$args = array(
'sslverify' => false
);
if($_GET['search'] or !empty($_GET['search'])){
$filter_query = '?search='.$_GET['search'];
}else{
$filter_query = '';
}
$post_url_collective = array(
$b_url.'/wp-json/wp/v2/posts'.$filter_query, // Main Site
$b_url.'/db/wp-json/wp/v2/posts'.$filter_query, // DB Site
$b_url.'/dc/wp-json/wp/v2/posts'.$filter_query, // DC Site
$b_url.'/fw/wp-json/wp/v2/posts'.$filter_query // FW Site
);
$post_response = wp_remote_get($post_url_collective[0], $args);
$post_response = wp_remote_retrieve_body($post_response);
$post_response = json_decode($post_response);
$post_response_two = wp_remote_get($post_url_collective[1], $args);
$post_response_two = wp_remote_retrieve_body($post_response_two);
$post_response_two = json_decode($post_response_two);
$post_response_three = wp_remote_get($post_url_collective[2], $args);
$post_response_three = wp_remote_retrieve_body($post_response_three);
$post_response_three = json_decode($post_response_three);
$post_response_four = wp_remote_get($post_url_collective[3], $args);
$post_response_four = wp_remote_retrieve_body($post_response_four);
$post_response_four = json_decode($post_response_four);
$posts_merged = array_merge( $post_response, $post_response_two, $post_response_three, $post_response_four );
?>
<div class="container multi-search-wrap">
<div class="row" style="margin-bottom: 0px">
<div class="col sm12 m12 l12">
<form class="multi-search-form" method="GET">
<div class="row" style="margin-bottom: 0px">
<div class="col sm8 m9 l10">
<input type="text" name="search" value="<?php echo ( isset( $_GET['search'] ) ? $_GET['search'] : '' ); ?>" placeholder="Search for..."/>
</div>
<div class="col sm4 m3 l2">
<input type="submit" value="Search" />
</div>
</div>
</form>
</div>
</div>
<div class="row" style="background: #eeeeee;padding: 10px;font-size: 12px;margin:0px 0px 20px 0px">
<div class="col sm12 m12 l12">
We've found <strong><?php echo count($posts_merged);?></strong> results for <?php echo $_GET['search'];?>...
</div>
</div>
<div class="row">
<?php
// Post Loop
foreach($posts_merged as $get_post) {
$image_url = $b_url.'/wp-json/wp/v2/media/'.$get_post->featured_media;
$image_response = wp_remote_get($image_url, $args);
$image_response = json_decode($image_response['body']);
//echo'<pre>';print_r($image_response);echo'</pre>';
echo '<div class="col sm12 m6 l6 multi-search-post">';
echo '<div class="row">';
echo '<div class="col sm12 m3 l4 multi-search-post">';
if(!empty($image_response->media_details->sizes->thumbnail->source_url)){
echo '<img class="img_'.$get_post->id.'" src="'.$image_response->media_details->sizes->thumbnail->source_url.'" width="auto"><br>';
}else{
echo '<img class="img_'.$get_post->id.'" src="'.get_template_directory_uri().'/images/post-placeholder.jpg" width="auto"><br>';
}
echo '</div>';
echo '<div class="col sm12 m9 l8 multi-search-post">';
echo '<a href="'.$get_post->link.'">';
echo '<h3>'.$get_post->title->rendered.'</h3>';
echo '</a>';
echo '<p>'.limit_text($get_post->excerpt->rendered, 30).'</p>';
echo '</div>';
echo '</div>';
echo '</div>';
}
?>
</div>
</div>
I would like to improve the load speed of the queries but the most important part is ridding this occassional Foreach error.
Any help would be greatly appreciated

Group items by 3 in for each loop

I have an array of items and want to loop through them but instead of grouping them inside of a div I would like to group them by css Class.
I dont want to do div grouping because of mobile views there might be 4 or more in line and the breaks css class will change as the screen size changes or will be moved to absolute positioning removing the break all together and forming a grid.
I can create the breaks every 3 items but the class assign im struggling with.
Any help would be appreciated.
I would like to create the below layout in a PHP foreach loop.
ex.
<div class="listing">
<div class="group_1">item1</div>
<div class="group_1">item2</div>
<div class="group_1">item3</div>
<div class="break_1"></div>
<div class="group_2">item4</div>
<div class="group_2">item5</div>
<div class="group_2">item6</div>
<div class="break_2"></div>
<div class="group_3">item7</div>
<div class="group_3">item8</div>
<div class="group_3">item9</div>
<div class="break_3"></div>
<div class="group_4">item10</div>
<div class="group_4">item11</div>
<div class="group_4">item12</div>
<div class="break_4"></div>
</div>
Not very sure if it is what you are looking, anyway, given a basic array like this:
$arr=array(1,2,3,4,5,6,7,8,9,10,11,12);
you can loop it and have the code you expect this way:
$group_num=1;
echo "<div class='listing'>";
foreach ($arr as $key=>$item) {
echo "<div class='group_$group_num'>$item</div>";
if ($key%3==0) {
echo "<div class='break'></div>";
$group_num++;
}
}
echo "</div>";
Results:
<div class='listing'>
<div class='group_1'>1</div>
<div class='group_1'>2</div>
<div class='group_1'>3</div>
<div class='break'></div>
<div class='group_2'>4</div>
<div class='group_2'>5</div>
<div class='group_2'>6</div>
<div class='break'></div>
<div class='group_3'>7</div>
<div class='group_3'>8</div>
<div class='group_3'>9</div>
<div class='break'></div>
<div class='group_4'>10</div>
<div class='group_4'>11</div>
<div class='group_4'>12</div>
<div class='break'></div>
if we have array of items as :
$items = ['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7', 'item8'];
$result = '';
foreach($items as $index => $item) {
$groupNumber = intval(floor($index/3)) + 1;
$result .= "<div class='group_$groupNumber'>$item</div>";
}
echo $result;
and this is a sample output
Thanks to the help of Giacomo Pittalis and Hassan Ali Salem I have managed to solve this in a bit of a crude way.
<?php
$items = ['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7', 'item8', 'item9', 'item10'];
$i = 0;
$len = count($items);
foreach ($items as $item) {
$mod = intval(floor($i / 3) + 1);
echo '<div class="' . 'group_' . $mod . '">' . $items[$i] . '</div>';
if (($i % 3 == 2)) { ?>
<div class="content_holder hidden" id="group_<?php echo $mod; ?>"></div>
<?php }
if ($i == $len - 1) { ?>
<div class="content_holder hidden" id="group_<?php echo $mod; ?>"></div>
<?php }
$i++;
}
?>

Items per slide responsive

I've made a logo slider using Bootstrap (basically as seen here http://jsfiddle.net/juddlyon/Q2TYv/10/).
Within each slide there are 4 logos. I want to make this responsive, where on smaller screens it only shows 2 logos per slide. I'm not sure what the best way is to do this.
I can double the grid-4 width to 50% with media queries but then it will still show 4 per slide, in a 2x2 grid.
Another way is to duplicate the entire slide and hide and show the correct one, but this seems like a rather inefficient appreach.
So really I need to reduce the number of logos per slide as it is loaded.. but how?
I'm using WP and Advanced Custom Fields to populate the slider. Simplified code below:
PHP:
<?php
$firstslide = 0;
$slide = 0;
$repeater = get_field('clients', $clients);
$order = array();
foreach( $repeater as $i => $row ) {
$order[ $i ] = $row['name'];
}
array_multisort($order, SORT_ASC, $repeater);
if($repeater):
foreach($repeater as $i => $row):
if ($firstslide == 0) {
$class = "item active";
} else {
$class = "item";
};
if ($slide == 0) {
echo '<div class="' . $class . '">';
};
?>
<div class="grid-4">
<img src="<?php echo $row['logo']; ?>">
</div>
<?php
if ($slide == 4) {
echo '</div>';
$slide = 0;
} else {
$slide++;
}
$firstslide++;
endforeach;
wp_reset_postdata();
endif;
?>
This would results in something like:
<div class="item active">
<div class="grid-4"><img src="logo1.jpg"></div>
<div class="grid-4"><img src="logo2.jpg"></div>
<div class="grid-4"><img src="logo3.jpg"></div>
<div class="grid-4"><img src="logo4.jpg"></div>
</div>
<div class="item">
<div class="grid-4"><img src="logo5.jpg"></div>
<div class="grid-4"><img src="logo6.jpg"></div>
<div class="grid-4"><img src="logo7.jpg"></div>
<div class="grid-4"><img src="logo8.jpg"></div>
</div>
<div class="item">
<div class="grid-4"><img src="logo9.jpg"></div>
<div class="grid-4"><img src="logo10.jpg"></div>
<div class="grid-4"><img src="logo11.jpg"></div>
<div class="grid-4"><img src="logo12.jpg"></div>
</div>
Very simplified CSS for the grid:
.grid-4 {
width: 25%;
}
After more searching, it looks like Slick is a solution that will just take care this.
jsfiddle.net/BishopBarber/ufnjkjy4/1/

responsive image and text alignment

I have a site that uses three col-md-4 as a class.
This is the code:
echo '<div class="head6 panel-heading">Local Business Listing</div>
<div class="panel-body">
';
$funcs->viewSurvey();
$array4 = $funcs->viewSurvey();
$searchengine = $array4['searchengine'];
$sum = $array4['sum'];
$searches = explode(',', $searchengine);
$searchesa = array("Google","Yahoo","Bing");
$check = '<img src="images/checked.png" height="40px" width="40px">';
$uncheck = '<img src="images/unchecked.png" height="40px" width="40px">';
foreach ($searchesa as $key_a => $val_c) {
$found = false;
echo '<div class="col-sm-4">';
foreach ($searches as $key_b => $val_d) {
if ($val_c == $val_d) {
echo ''.$check.'<h3 class="head6">'. $val_c.'</h3>' ;
$found = true;
}
}
if (!$found){
echo ''.$uncheck.'<h3 class="head6">'. $val_c.'</h3>' ;
}
echo '</div>';
}
echo '
</div>';
When the screen is smaller it appears like this
how can I place it in single line still even in a mobile display?
You can use col-xs-4 for single line still even in a mobile display.
Try This.. Change div class panel-body to this panel-body col-md-4 col-xs-4
<div class="panel-body col-md-4 col-xs-4">
</div>
Hope this could you help you.

Categories