Hi im try to use a class to insert adsense blocks after x numbers of paragraph etc.
its works with regular text, but dont works with adsense codes.
the full code is HERE
<?php
namespace keesiemeijer\Insert_Content;
function insert_content( $content, $insert_content = '', $args = array() ) {
$args = array_merge( get_defaults(), (array) $args );
if ( empty( $insert_content ) ) {
return $content;
}
// Validate arguments
$args['parent_element_id'] = trim( (string) $args['parent_element_id'] );
$args['insert_element'] = trim( (string) $args['insert_element'] );
$args['insert_element'] = $args['insert_element'] ? $args['insert_element'] : 'p';
$args['insert_after_p'] = abs( intval( $args['insert_after_p'] ) );
$parent_element = false;
// Content wrapped in the parent HTML element (to be inserted).
$insert_content = "<{$args['insert_element']}>{$insert_content}</{$args['insert_element']}>";
$nodes = new \DOMDocument();
// Load the HTML nodes from the content.
#$nodes->loadHTML( $content );
if ( $args['parent_element_id'] ) {
$parent_element = $nodes->getElementById( $args['parent_element_id'] );
if ( !$parent_element ) {
// Parent element not found.
return $content;
}
// Get all paragraphs from the parent element.
$p = $parent_element->getElementsByTagName( 'p' );
} else {
// Get all paragraphs from the content.
$p = $nodes->getElementsByTagName( 'p' );
}
$insert_nodes = new \DOMDocument();
#$insert_nodes->loadHTML( $insert_content );
$insert_element = $insert_nodes->getElementsByTagName( $args['insert_element'] )->item( 0 );
if ( !$insert_element ) {
return $content;
}
// Get paragraph indexes
$nodelist = get_node_indexes( $p, $args );
// Check if paragraphs are found.
if ( !empty( $nodelist ) ) {
$insert_index = get_item_index( $nodelist, $args );
if ( false === $insert_index ) {
return $content;
}
// Insert content after this (paragraph) node.
$insert_node = $p->item( $insert_index );
// Insert the nodes
insert_content_element( $nodes, $insert_node, $insert_element );
$html = get_HTML( $nodes );
if ( $html ) {
$content = $html;
}
} else {
// No paragraphs found.
if ( (bool) $args['insert_if_no_p'] ) {
if ( $parent_element ) {
// Insert content after parent element.
insert_content_element( $nodes, $parent_element, $insert_element );
$html = get_HTML( $nodes );
if ( $html ) {
$content = $html;
}
} else {
// Add insert content after the content/
$content .= $insert_content;
}
}
}
return $content;
}
/**
* Get default arguments.
*
* #return array Array with default arguments.
*/
function get_defaults() {
return array(
'parent_element_id' => '',
'insert_element' => 'p',
'insert_after_p' => '',
'insert_if_no_p' => true,
'top_level_p_only' => true,
);
}
function get_node_indexes( $nodes, $args ) {
$args = array_merge( get_defaults(), (array) $args );
$nodelist = array();
$length = isset( $nodes->length ) ? $nodes->length : 0;
$parent_id = trim( $args['parent_element_id'] );
for ( $i = 0; $i < $length; ++$i ) {
$nodelist[ $i ] = $i;
$parent = false;
$node = $nodes->item( $i );
if ( $parent_id ) {
if ( $node->parentNode->hasAttribute( 'id' ) ) {
$parent_id_attr = $node->parentNode->getAttribute( 'id' );
$parent = ( $parent_id === $parent_id_attr );
}
} else {
$parent = ( 'body' === $node->parentNode->nodeName );
}
if ( (bool) $args['top_level_p_only'] && !$parent ) {
// Remove nested paragraphs from the list.
unset( $nodelist[ $i ] );
}
}
return array_values( $nodelist );
}
function get_item_index( $nodelist, $args ) {
if ( empty( $nodelist ) ) {
return false;
}
$args = array_merge( get_defaults(), (array) $args );
$count = count( $nodelist );
$insert_index = abs( intval( $args['insert_after_p'] ) );
end( $nodelist );
$last = key( $nodelist );
reset( $nodelist );
if ( !$insert_index ) {
if ( 1 < $count ) {
// More than one paragraph found.
// Get middle position to insert the HTML.
$insert_index = $nodelist[ floor( $count / 2 ) -1 ];
} else {
// One paragraph
$insert_index = $last;
}
} else {
// start counting at 0.
--$insert_index;
--$count;
if ( $insert_index > $count ) {
if ( (bool) $args['insert_if_no_p'] ) {
// insert after last paragraph.
$insert_index = $last;
} else {
return false;
}
}
}
return $nodelist[ $insert_index ];
}
/**
* Insert an element (and it's child elements) in the content.
*
* #param object $nodes DOMNodeList instance containing all nodes.
* #param object $insert_node DOMElement object to insert nodes after
* #param object $insert DOMElement object to insert
* #return void
*/
function insert_content_element( $nodes, $insert_node, $insert_element ) {
$next_sibling = isset( $insert_node->nextSibling ) ? $insert_node->nextSibling : false;
if ( $next_sibling ) {
// get sibling element (exluding text nodes and whitespace).
$next_sibling = nextElementSibling( $insert_node );
}
if ( $next_sibling ) {
// Insert before next sibling.
$next_sibling->parentNode->insertBefore( $nodes->importNode( $insert_element, true ), $next_sibling );
} else {
// Insert as child of parent element.
$insert_node->parentNode->appendChild( $nodes->importNode( $insert_element, true ) );
}
}
function nextElementSibling( $node ) {
while ( $node && ( $node = $node->nextSibling ) ) {
if ( $node instanceof \DOMElement ) {
break;
}
}
return $node;
}
function get_HTML( $nodes ) {
$body_node = $nodes->getElementsByTagName( 'body' )->item( 0 );
if ( $body_node ) {
// Convert nodes from the body element to a string containing HTML.
$content = $nodes->saveHTML( $body_node );
// Remove first body element only.
$replace_count = 1;
return str_replace( array( '<body>', '</body>' ) , array( '', '' ), $content, $replace_count );
}
return '';
}
to call the function
$args = array(
'insert_after_p' => 3, // Insert after the second paragraph
);
echo keesiemeijer\Insert_Content\insert_content($content, $insert_content, $args );
Related
I want to use a shortcode to show determinate content depending on a date given, I have this code on function.php on WP:
add_shortcode( 'stime', 'stime_f' );
function stime_f( $atts, $content = '' ) {
$a = shortcode_atts( [
'type' => false,
], $atts );
$output = '';
if ( $a['type'] ) {
$a['type'] = array_map( 'trim', str_getcsv( $a['type'], ',' ) );
}
foreach ($a as $value){
$list0 = $value[0];
$list1 = $value[1];
}
$tm = strtotime($list1);
if ( time() < $tm ) {
$list = "SOON";
return $list;
}
$list = $list0;
return $list;
}
So I used when publish:
[stime type="http://site1.com
http://site2.com,2020-12-05"]
And works, when it's not the date give result: SOON
otherwise result:
http://site1.com
http://site2.com
Results are fine, but I want to use:
[stime type="SITE1
SITE2,2020-12-05"]
I suppose it's for quotes on href and target, there are some way to make it possible?
Thanks
You can use enclosing shortcodes for this.
Below is the updated code:
add_shortcode( 'stime', 'stime_f' );
function stime_f( $atts, $content ) {
if ( $content ) {
$a = array_map( 'trim', str_getcsv( $content, ',' ) );
$list0 = $a[0];
$list1 = $a[1];
$tm = strtotime($list1);
if ( time() < $tm ) {
$list = "SOON";
return $list;
}
$list = $list0;
return $list;
} else {
return '';
}
}
Then use shortcode like this:
[stime] SITE1
SITE2,2020-12-05 [/stime]
I am using MediaWiki in combination with Joomla. As I want to add icons to some links I need to connect both. I know that this is possible through putting the img tag inside the a tag.
BUT the problem is that some links are generated throgh a function called makeListItem that MediaWiki uses for more than just these links. Now my question is, can I somehow connect the img to the a without putting it inside the a tag?
This calls the function to create the elements:
<?php $this->renderNavigation( 'PERSONAL' ); ?>
The actual function (shortened):
foreach ( $personalTools as $key => $item ) {
?>
<div class="searchbox" style="clear:both;">
<img src="<?php echo $icon[$key] ?>" alt="p-Icons" class="iconnav"/>
<?php
echo $this->makeListItem( $key, $item );
?>
</div>
<?php
}
?>
The src of the image is defined in a array that is declared just above the foreach.
Thanks in advance
You have to modify your makeListItem() function (BaseTemplate class).
function makeListItem( $key, $item, $options = array() ) {
if ( isset( $item['links'] ) ) {
$links = array();
foreach ( $item['links'] as $linkKey => $link ) {
$links[] = $this->makeLink( $linkKey, $link, $options );
}
$html = implode( ' ', $links );
} else {
$link = $item;
// These keys are used by makeListItem and shouldn't be passed on to the link
foreach ( array( 'id', 'class', 'active', 'tag', 'itemtitle' ) as $k ) {
unset( $link[$k] );
}
if ( isset( $item['id'] ) && !isset( $item['single-id'] ) ) {
// The id goes on the <li> not on the <a> for single links
// but makeSidebarLink still needs to know what id to use when
// generating tooltips and accesskeys.
$link['single-id'] = $item['id'];
}
$html = $this->makeLink( $key, $link, $options );
}
$attrs = array();
foreach ( array( 'id', 'class' ) as $attr ) {
if ( isset( $item[$attr] ) ) {
$attrs[$attr] = $item[$attr];
}
}
if ( isset( $item['active'] ) && $item['active'] ) {
if ( !isset( $attrs['class'] ) ) {
$attrs['class'] = '';
}
$attrs['class'] .= ' active';
$attrs['class'] = trim( $attrs['class'] );
}
if ( isset( $item['itemtitle'] ) ) {
$attrs['title'] = $item['itemtitle'];
}
return Html::rawElement( isset( $options['tag'] ) ? $options['tag'] : 'li', $attrs, $html );
}
I have the following code:
$data = file_get_contents('http://www.robotevents.com/robot-competitions/vex-robotics-competition?limit=all');
echo "Downloaded";
$dom = new domDocument;
#$dom->loadHTML($data);
$dom->preserveWhiteSpace = false;
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(2)->getElementsByTagName('tr');
foreach ($rows as $row) {
$cols = $row->getElementsByTagName('td');
for ($i = 0; $i < $cols->length; $i++) {
echo $cols->item($i)->nodeValue . "\n";
}
}
The final field has an Link which I need to store the URL of. Also, The script outputs characters such as "Â". Does anyone know how to do/fix these things?
I would recommend not using DOM to parse HTML, as it has problems with invalid HTML. INstead use regular expression
I use this class:
<?php
/**
* Class to return HTML elements from a HTML document
* #version 0.3.1
*/
class HTMLQuery
{
protected $selfClosingTags = array( 'area', 'base', 'br', 'hr', 'img', 'input', 'link', 'meta', 'param' );
private $html;
function __construct( $html = false )
{
if( $html !== false )
$this->load( $html );
}
/**
* Load a HTML string
*/
public function load( $html )
{
$this->html = $html;
}
/**
* Returns elements from the HTML
*/
public function getElements( $element, $attribute_match = false, $value_match = false )
{
if( in_array( $element, $this->selfClosingTags ) )
preg_match_all( "/<$element *(.*)*\/>/isU", $this->html, $matches );
else
preg_match_all( "/<$element(.*)>(.*)<\/$element>/isU", $this->html, $matches );
if( $matches )
{
#Create an array of matched elements with attributes and content
foreach( $matches[0] as $key => $el )
{
$current_el = array( 'name' => $element );
$attributes = $this->parseAttributes( $matches[1][$key] );
if( $attributes )
$current_el['attributes'] = $attributes;
if( $matches[2][$key] )
$current_el['content'] = $matches[2][$key];
$elements[] = $current_el;
}
#Return only elements with a specific attribute and or value if specified
if( $attribute_match != false && $elements )
{
foreach( $elements as $el_key => $current_el )
{
if( $current_el['attributes'] )
{
foreach( $current_el['attributes'] as $att_name => $att_value )
{
$keep = false;
if( $att_name == $attribute_match )
{
$keep = true;
if( $value_match == false )
break;
}
if( $value_match && ( $att_value == $value_match ) )
{
$keep = true;
break;
}
elseif( $value_match && ( $att_value != $value_match ) )
$keep = false;
}
if( $keep == false )
unset( $elements[$el_key] );
}
else
unset( $elements[$el_key] );
}
}
}
if( $elements )
return array_values( $elements );
else
return array();
}
/**
* Return an associateive array of all the form inputs
*/
public function getFormValues()
{
$inputs = $this->getElements( 'input' );
$textareas = $this->getElements( 'textarea' );
$buttons = $this->getElements( 'button' );
$elements = array_merge( $inputs, $textareas, $buttons );
if( $elements )
{
foreach( $elements as $current_el )
{
$attribute_name = mb_strtolower( $current_el['attributes']['name'] );
if( in_array( $current_el['name'], array( 'input', 'button' ) ) )
{
if( isset( $current_el['attributes']['name'] ) && isset( $current_el['attributes']['value'] ) )
$form_values[$attribute_name] = $current_el['attributes']['value'];
}
else
{
if( isset( $current_el['attributes']['name'] ) && isset( $current_el['content'] ) )
$form_values[$attribute_name] = $current_el['content'];
}
}
}
return $form_values;
}
/**
* Parses attributes into an array
*/
private function parseAttributes( $str )
{
$str = trim( rtrim( trim( $str ), '/' ) );
if( $str )
{
preg_match_all( "/([^ =]+)\s*=\s*[\"'“”]{0,1}([^\"'“”]*)[\"'“”]{0,1}/i", $str, $matches );
if( $matches[1] )
{
foreach( $matches[1] as $key => $att )
{
$attribute_name = mb_strtolower( $att );
$attributes[$attribute_name] = $matches[2][$key];
}
}
}
return $attributes;
}
}
?>
Usage is:
$c = new HTMLQuery();
$x = $c->getElements( 'tr' );
print_r( $x );
Ok so basically I am reading through this piece of source code and do not understand the purpose of a specific area.
class URL_Processor
{
private static $urlPath;
private static $urlBits = array();
/*
Gets data from the current URL
#return Void
*/
public function getURLData()
{
$urldata = (isset($_GET['page'])) ? $_GET['page'] : '' ;
self::$urlPath = $urldata;
if( $urldata == '' )
{
self::$urlBits[] = 'home';
self::$urlPath = 'home';
}
else
{
$data = explode( '/', $urldata );
while ( !empty( $data ) && strlen( reset( $data ) ) === 0 )
{
array_shift( $data );
}
while ( !empty( $data ) && strlen( end( $data ) ) === 0)
{
array_pop($data);
}
self::$urlBits = $this->array_trim( $data );
}
}
private function array_trim( $array )
{
while ( ! empty( $array ) && strlen( reset( $array ) ) === 0)
{
array_shift( $array );
}
while ( !empty( $array ) && strlen( end( $array ) ) === 0)
{
array_pop( $array );
}
return $array;
}
}
So basically from my understanding the two while loops with 'array_shift' in the getURLData method empty out the array but according to my logic the second while loop wont even be able to empty anything out because the first while loop already did.
Then the last line of the method getURLData
self::$urlBits = $this->array_trim( $data );
does the same thing but how if the passed in argument is empty already?
Very confused!!!
The first while loop removes all leading elements in the array where their string length is zero, the second one does the same with trailing elements. reset($array) will point to the first, end($array) to the last element.
Why he mushes it through a second time? I don't know.
i am importing the products with advance data flow profile and facing the weird problem while saving the category as i am passing the category name to my function as
Parent Category/Child category
The / sign between categories automatically create and assign the product to child category
it is working as expected but in my case the Parent Category name is renaming somehow i have checked that i am passing the right name to the function...
e.g. Semipreciuos gem stone beads/Stone type is saving as Semipreciuos gem stone bead/Stone type
The last s word is missing from the name
protected function _addCategories($categories,$desc='',$discountable,$store) {
$rootId = $store->getRootCategoryId ();
if (! $rootId) {
return array();
}
$rootPath = '1/' . $rootId;
if (empty ( $this->_categoryCache [$store->getId ()] )) {
$collection = Mage::getModel ( 'catalog/category' )->getCollection ()->setStore($store)->addAttributeToSelect ( 'name' );
$collection->getSelect ()->where ( "path like '" . $rootPath . "/%'" );
foreach ( $collection as $cat ) {
$pathArr = explode ( '/', $cat->getPath () );
$namePath = '';
for($i = 2, $l = sizeof ( $pathArr ); $i < $l; $i ++) {
$name = $collection->getItemById ( $pathArr [$i] )->getName ();
$namePath .= (empty ( $namePath ) ? '' : '/') . trim ( $name );
}
$cat->setNamePath ( $namePath );
}
$cache = array();
foreach ( $collection as $cat ) {
$cache [strtolower ( $cat->getNamePath () )] = $cat;
$cat->unsNamePath ();
}
$this->_categoryCache [$store->getId ()] = $cache;
}
$cache = & $this->_categoryCache [$store->getId ()];
$catIds = array();
foreach ( explode ( ',', $categories ) as $categoryPathStr ) {
$categoryPathStr = preg_replace ( '#s*/s*#', '/', trim ( $categoryPathStr ) );
if (! empty ( $cache [$categoryPathStr] )) {
$catIds [] = $cache [$categoryPathStr]->getId ();
continue;
}
$path = $rootPath;
$namePath = '';
foreach ( explode ( '/', $categoryPathStr ) as $catName ) {
$namePath .= (empty ( $namePath ) ? '' : '/') . strtolower ( $catName );
if (empty ( $cache [$namePath] )) {
$cat = Mage::getModel('catalog/category')->setStoreId($store->getId())->setPath ( $path )->setName ( $catName )->// comment out the following line if new categories should stay inactive
setIsActive(1)->setDescription($desc)->setData('discountable',$discountable)->save();
$cache [$namePath] = $cat;
}
$catId = $cache [$namePath]->getId ();
$path .= '/' . $catId;
}
##Assigning product to child category
/*$parentId = null;
$currentcat = Mage::getModel("catalog/category")->load($catId);
$parentId = $currentcat->getParentId();
if($parentId){
$catIds[] = $parentId;
}
*/
if ($catId) {
$catIds [] = $catId;
}
}
return join ( ',', $catIds );
}
Above is my category function for creating categories... any one has any idea what is going on..
It is not related to Magento, but rather to PHP & regular expression.
$categoryPathStr = preg_replace ( '#s*/s*#', '/', trim ( $categoryPathStr ) );
That line replaces "s*/s*" with "/", which is why you have your last s removed. I see no real reason for that preg_replace (?), so just remove that line, or replace it with
$categoryPathStr = trim ( $categoryPathStr );
so that leading/ending white spaces get removed.