Why output control doesn't catch sql? - php

I wrote a code which is changing headings h1 to h2 if it's not first heading of that type. It works, but only when I'm using just PHP. If I want to use it on website, which one is using database to output content, that code doesn't work.
I'm using ob_start() before <html> and ob_get_contents() + ob_end_clean() + rest of my code after </html>, so I think that has to be something wrong "catching" content from database, but I'm not sure. I tried to use that code on a website based on WordPress.
My code (I know it isn't probably the best solution, but it works when I'm using it on any website without CMS):
<!DOCTYPE html>
<?php
ob_start();
?>
<html>
<head>
<title>random page</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-5">
<h1>afdsfdassfdfdsa</h1>
</div>
</div>
</div>
<h1>sadffsadf afdsfdsa afsdfs?</h1>
<h1 class="superclass">random text?</h1>
<div>
<p>some ending content</p>
</div>
</body>
</html>
<?php
$bufferContent = ob_get_contents();
ob_end_clean();
$matchedContent = '';
$endContent = '';
$modifiedContent = '';
$firstHeadingBoolean = true;
$h1Pattern = array();
$h1Pattern[0] = '%<h1(.*?)>%';
$h1Pattern[1] = '%</h1>%';
$h1Replacement = array();
$h1Replacement[0] = '<h2$1>';
$h1Replacement[1] = '</h2>';
if(preg_match_all('%((.|\n)*?)(<h1.*?>.*?</h1>)%', $bufferContent, $contentMatches)){
foreach($contentMatches[0] as $matches) {
$matchedContent .= $matches;
}
$endContent = str_replace($matchedContent, '', $bufferContent);
foreach ($contentMatches[0] as $matches) {
if(!$firstHeadingBoolean){
$firstHeadingBoolean = false;
} else {
$matches = preg_replace($h1Pattern, $h1Replacement, $matches);
}
$modifiedContent .= $matches;
}
echo $modifiedContent;
echo $endContent;
} else {
echo $bufferContent;
}
?>
EDIT: I tried to use solutions from there but nothing has changed: WordPress filter to modify final html output
Now, after some testing, I can see it's not working because preg_match_all doesn't work correctly. Anyone has an idea what is wrong with that preg_match_all? I tested that regex pattern inside that in regex101 and on my localhost and everything worked fine. I don't understand, why isn't it working here?

Ok, so that wasn't problem with sql but with regex. To solve that problem I used code like that:
<?php
ob_start();
?>
<!-- html code -->
<?php
$bufferContent = ob_get_contents();
ob_end_clean();
$bufferContent = preg_split("%(?=<h1)%",$bufferContent);
$i = 0;
$h1Pattern = array();
$h1Pattern[0] = '%<h1(.*?)>%';
$h1Pattern[1] = '%</h1>%';
$h1Replacement = array();
$h1Replacement[0] = '<h2$1>';
$h1Replacement[1] = '</h2>';
foreach($bufferContent as $bufferElement){
if(preg_match("%<h1%", $bufferElement)){
if($i > 0){
echo preg_replace($h1Pattern, $h1Replacement, $bufferElement);
} else {
echo $bufferElement;
$i++;
}
} else {
echo $bufferElement;
}
}
?>

Related

scraping a web page for all headings and contents in php

I have looked around the web on how to scrape all headings (h1 to h6) with content. Like this <h2>Some Heading</h2>, <h4>Some Heading</h4>. I have even looked at file_get_html() which PHP does not recognize. The code I have written so far lets you see the content but with out the h1 tags. I am new to this so if anyone can help me I would appreciate it. Here is my code I have now:
<html>
<head>
<title></title>
</head>
<body>
<?php
$theurl = "http://www.msn.com";
if(!($contents=file_get_contents($theurl)))
{
echo 'Could not open URL';
exit;
}else{
echo "The $theurl is open <br />";
}
$pattern = "/<h[1-6]>(.*?)<\/h[1-6]>/si";
$found = preg_match_all($pattern,$contents,$matches);
if(is_array($matches) && count($matches) >= 1){
echo "Scraping $theurl<br />";
for($i = 1; $i <= $found - 1; $i++){
echo $matches[0][$i];
}
}else{
echo "No heading found";
}
?>
</body>
</html>

Is it possible to check if a subArea contains blocks in Concrete5?

Is there a way to check if a subArea contains blocks before outputting markup when using the Area Splitter add-on?
Have been trying stuff like this but don't understand how to make it work sorry:
<?php
defined('C5_EXECUTE') or die("Access Denied.");
$c = Page::getCurrentPage();
$this->controller->setArea($this->area);
?>
<div class="box">
<? if (($this->controller->subArea()->getTotalBlocksInArea($c) != 0) || ($c->isEditMode())) : ?>
<div class="box-header">
<?php $this->controller->subArea(); ?>
</div>
<? endif; ?>
<? if (($this->controller->subArea()->getTotalBlocksInArea($c) != 0) || ($c->isEditMode())) : ?>
<div class="box-footer">
<?php $this->controller->subArea(); ?>
</div>
<? endif; ?>
</div>
Any pointers in the right direction would be much appreciated.
Cheers
Ben
Not sure about the "area splitter" addon... I believe that's a really old thing that has been supplanted by the native "Area Layouts" in the core (which were added way back in 5.4 I believe).
If you're talking about the native "area layouts" functionality, though, then I have some code in the free Page List Teasers addon that does this:
$aHandle = 'Main'; //<--CHANGE THIS ACCORDINGLY
$c = Page::getCurrentPage();
//Get blocks inside "Area Layouts"...
$layout_blocks = array();
$area = new Area($aHandle);
$layouts = $area->getAreaLayouts($c); //returns empty array if no layouts
foreach ($layouts as $layout) {
$maxCell = $layout->getMaxCellNumber();
for ($i=1; $i<=$maxCell; $i++) {
$cellAreaHandle = $layout->getCellAreaHandle($i);
$cellBlocks = $c->getBlocks($cellAreaHandle);
$layout_blocks = array_merge($layout_blocks, $cellBlocks);
}
}
//Get non-area-layout blocks...
$nonlayout_blocks = $c->getBlocks($aHandle); //Returns blocks in the order they're on the page
//Combine the two sets of blocks
$blocks = array_merge($layout_blocks, $nonlayout_blocks);
Hopefully you can take that code and modify it to achieve what you want (e.g calling count() on the layout_blocks array or the combined array, depending on which you want).

PHP omit an include from specific page

I have a PHP site that includes a header (menu nav and logo).
I have a section in my site that I would like to include a DIFFERENT header
I am struggling with this. Any help would be appreciated!
Here is my code:
<div id="wrapper">
<? include('inc/header.inc.php'); ?>
<? require('process/build_page.php'); ?>
<? require('inc/footer.inc.php'); ?>
</div>
I want to include the following header on a specific section called "my-association"
<? include('inc/header_ma.inc.php'); ?>
The process/build_page code looks like this:
<?
global $full_uri;
class BuildPage
{
function BuildPage()
{
global $full_uri;
if($full_uri)
{
$this->build_path();
}
else
{
exit();
}
}
function build_path()
{
global $full_uri;
$uri_array = explode("/", $full_uri); # make uri into an array divided by /
$clean_uri = array_filter($uri_array); # remove empty elements
unset($clean_uri[1]); # remove base part of uri
$clean_uri = array_values($clean_uri); #reset array key to start with 0
# if array is empty the homepage is being requested
if(empty($clean_uri)){
$clean_uri[0] = 'home';
}
# build uri to point to include file
$new_path = "content/";
$new_path .= implode("/", $clean_uri);
$new_path .= ".inc.php";
$this->build($new_path);
}
function build($path)
{
$output = "";
$output .= $this->get_include_contents($path);
echo $output;
}
function get_include_contents($filename)
{
if (is_file($filename))
{
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}
function print_array($data)
{
echo "<pre>";
print_r($data);
echo "</pre>";
die();
}
};
$buildpage = new BuildPage();
?>
Please advise!
Thanks
Please let me know if I've missed something but wouldn't this do the trick?
<div id="wrapper">
<?
$change_header = array('/special_page_1','/special_page_2','/special_page_3');
if(in_array($full_uri,$change_header))
include('inc/header_ma.inc.php');
else
include('inc/header.inc.php');
?>
<? require('process/build_page.php'); ?>
<? require('inc/footer.inc.php'); ?>
</div>

PHP jQuery Post - returns too much HTML

I have a problem when using jQuery Post, the PHP returns all the HTML of the page up to the newly created HTML, rather then just the HTML that is output by the PHP.
As an example say the php outputs: '<div>Some Content</div>'
Then the jQuery Post returns: '<html><head>...all the head content...</head><body>...other content...<div>Some Content</div>'
Here's the jQuery (link to full code: http://pastebin.com/U7R8PqX1):
jQuery("form[ID^=product_form]").submit(function() {
var current_url = js_data.current_url;
form_values = jQuery(this).serialize();
jQuery.post(current_url+"?ajax=true", form_values, function(returned_data) {
jQuery('div.shopping-cart').html(returned_data);
}
});
return false;
});
And here's the PHP (version 5.3.6 - link to full code: http://pastebin.com/zjSUUbmL):
function output_cart()
{
ob_start();
echo $this->output_cart_html();
$output = ob_get_contents();
ob_end_clean();
echo $output;
exit();
}
function output_cart_html() {
if (!isset($_SESSION['cart_items']))
{
$output = '<div class="cart_content faded">BASKET - Empty</div>';
return $output;
} else {
$total_items = 0;
$total_items = 0;
$items_in_cart = $_SESSION['cart_items'];
// work out total price and total items
foreach ($items_in_cart as $item_in_cart) {
$total_items += $item_in_cart['quantity'];
$total_price += floatval($item_in_cart['updated_price']*$item_in_cart['quantity']);
}
$template_url = get_bloginfo('template_directory');
$output = '';
$output_price = $dp_shopping_cart_settings['dp_currency_symbol'].number_format($total_price,2);
if($total_items == 1){ $item_text = ' Item'; } else { $item_text = ' Items'; }
$output .= $total_items . $item_text;
$output .= ' <span class="bullet"></span> Total '.$output_price;
// empty cart btn
$output .= '<form action="" method="post" class="empty_cart">
<input type="hidden" name="ajax_action" value="empty_cart" />
<span class="emptycart"> <img src="'.$template_url.'/images/empty.png" width="9" height="9" title="Empty Your Items" alt="Empty Your Items" />Empty Your Cart</span>
</form>';
// check out btn
$output .= ' <span class="bullet"></span> <span class="gocheckout">'.$this->output_checkout_link().' </span>';
return $output;
}
}
You need to check if the form has been posted yet with the PHP. To do this, just check if the 'ajax' parameter is there, or send another $_GET variable if you wish (by adding &anotherparementer=1 to the end of the jQuery post URL). Example:
<?php
if(isset($_GET['ajax'])) {
//your PHP code here that submits the form, i.e. the functions that you have, etc.
}
else {
?>
<html>
<head>
head content here...
</head>
<body>
body content here...
</body>
</html>
<?php
}
?>
I hope this helps.
Ok it turns out my problem was with the way Wordpress processes AJAX requests. The plugin I was building on top of was using AJAX but didn't have these issues (I'm not sure why maybe because they were using eval), so I hadn't realised there was a correct way of using AJAX with Wordpress. Here's a bunch of information if anyone else has similar problems:
http://codex.wordpress.org/AJAX_in_Plugins
http://byronyasgur.wordpress.com/2011/06/27/frontend-forward-facing-ajax-in-wordpress/
(this one really helped me out, a very simple example that I was able to adapt)
-- sorry I couldn't post more links because I'm too new on this site, but check out the links at the bottom of the first link above, especially the '5 Tips'.
As I'm using classes I instantiated the class from the index file of my plugin with this:
if ($_POST['action'] === 'action_name') {
$class_obj = new \namespace_name\class();
add_action('wp_ajax_action_name', array($class_obj, 'method_name'));
add_action('wp_ajax_nopriv_action_name', array($class_obj, 'method_name'));
}

Access a PHP array from JavaScript

I have the following code where I declare a PHP array variable and inside a function, I put some data into the array. I also display buttons mapped to each index of the array that will show the data in the PHP array for that index number.
When testing on a browser, I don't get the right answer. I checked the page source, it had code like data_array = ["<?php echo implode ('',Array); ?>"]; instead of the text from the Array.
What am I doing wrong and what should I do to get the correct output? (BTW, I tried to execute the same without declaring the function and it seemed to work, but I need a function for my work and can't take that approach).
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
<html lang="en">
<head>
<title>Example</title>
<?php
$giant_says = array();
function display() {
global $giant_says;
$giant_says[] = "<a href='http://www.google.com'>Google</a>";
$giant_says[] = "Yahoo!";
$giant_says[] = "Bing";
echo "<div id='content'>";
echo $giant_says[0];
echo "</div><br><br>";
$i = 0;
while($i < count($giant_says)) {
echo "<input type='button' value='".$i."' onClick=\"addtext(".$i.");return false;\"";
$i += 1;
}
}
?>
<script type="text/javascript">
function addtext(index) {
giantSays = ["<?php echo implode ('","', $giant_says); ?>"];
document.getElementById('content').innerHTML = giantSays[index];
}
</script>
</head>
<body>
<?php
display();
?>
</body>
</html>
You have the order wrong, which is causing the implode() to compress an empty array. I also suggest using json_encode() instead of implode(). It exists for this type of thing - updated example below:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
<html lang="en">
<head>
<title>Example</title>
<?php
$giant_says = array();
function display(&$giant_says) {
// Calculate the array (referenced)
$giant_says[] = "<a href='http://www.google.com'>Google</a>";
$giant_says[] = "Yahoo!";
$giant_says[] = "Bing";
// Return the HTML, to display later
ob_start();
echo "<div id='content'>";
echo $giant_says[0];
echo "</div><br><br>";
$i = 0;
while($i < count($giant_says)) {
echo "<input type='button' value='".$i."' onClick=\"addtext(".$i.");return false;\">";
$i += 1;
}
$Return = ob_get_contents();
ob_end_clean();
return $Return;
}
$Display = display($giant_says);
?>
<script type="text/javascript">
function addtext(index) {
giantSays = <?php echo json_encode($giant_says); ?>;
document.getElementById('content').innerHTML = giantSays[index];
}
</script>
</head>
<body>
<?php
echo $Display;
?>
</body>
</html>
You're trying to implode the $giant_says array before you've filled it (you're calling display() after the implode when the call needs to happen before).
The problem is that you call the display method, that fills the content after the html part with the javascript is sended.
the html code is "like" making an "echo 'html'" from your php. Your html is already processed but the display method is not called. call the method before the html code.
Example:
<?php
$giant_says = array();
$giant_says[] = "<a href='http://www.google.com'>Google</a>";
$giant_says[] = "Yahoo!";
$giant_says[] = "Bing";
function display() {
global $giant_says;
echo '<div id="content">'.$giant_says[0]."</div><br><br>";
$i = 0;
while($i < count($giant_says)) {
echo "<input type='button' value='".$i."' onClick=\"addtext(".$i.");\" />";
$i += 1;
}
}
?>
<html>
<head>
<title>Example</title>
<script type="text/javascript">
function addtext(index) {
giantSays = ["<?php echo implode ('","', $giant_says); ?>"];
document.getElementById('content').innerHTML = giantSays[index];
return false;
}
</script>
</head>
<body>
<?php display(); ?>
</body>
</html>

Categories