Coloque anuncios entre párrafos de solo texto

21 minutos de lectura

avatar de usuario
Debajyoti Das

Estoy usando el siguiente código para colocar un código de anuncio dentro de mi contenido.

<?php
$content = apply_filters('the_content', $post->post_content);
$content = explode (' ', $content);
$halfway_mark = ceil(count($content) / 2);
$first_half_content = implode(' ', array_slice($content, 0, $halfway_mark));
$second_half_content = implode(' ', array_slice($content, $halfway_mark));
echo $first_half_content.'...';
echo ' YOUR ADS CODE';
echo $second_half_content;
?>

¿Cómo puedo modificar esto para que pueda colocar 2 anuncios al mismo tiempo entre párrafos de solo texto (tanto el <p>...</p> adjuntando el anuncio no debe tener imágenes o videos incrustados).

Quiero evitar jQuery.

Ejemplo de mi caso de uso…
Ejemplo de mi caso de uso

  • Quiero insertar 2 bloques de anuncios en este artículo.
  • Quiero que el primer bloque de anuncios esté después del primer párrafo. Pero cualquier imagen en el primer párrafo debe eliminarse.
  • Para el segundo anuncio, debe colocarse en la segunda mitad del artículo, entre párrafos de solo texto, de modo que un código de anuncio cambie entre una buena cantidad de texto y nunca esté muy cerca de una imagen o video incrustado, etc.
  • Debe haber al menos 2 párrafos entre 2 anuncios.

  • “colocar 3 anuncios igualmente espaciados”, es decir, 3 divs horizontalmente a través?

    – David

    19/09/2014 a las 11:32

  • @David: verticalmente, como 1para 2para AD 3para 4 para ….

    – Debajyoti Das

    19/09/2014 a las 11:35

  • ¿No vas a matar tu sitio con tantos anuncios? Solo tenga cuidado si son anuncios de Google Adsense.

    – Pieter Goosen

    19 de septiembre de 2014 a las 12:08

  • Qué pasa si no hay para sin imagen ni video. No puede haber. de casos de uso. ¿Qué es lo que realmente quieres lograr?

    – nitigyan

    19/09/2014 a las 17:51


  • En sitios ricos en contenido… eso no es posible. Y tenemos un caso de uso en el que el segundo, si no el tercero, debe colocarse al final.

    – Debajyoti Das

    19 de septiembre de 2014 a las 18:12

avatar de usuario
pieter goosen

Aquí está mi enfoque de la pregunta. Perdón por publicar un poco tarde (y perder la recompensa 🙁 ), pero ha sido una semana agitada, así que hice todo en partes.

RESUMEN RÁPIDO

  • No he eliminado los archivos adjuntos en el primer párrafo. Realmente no veo por qué el contenido debe ser objeto de vandalismo por el bien de un anuncio.

  • He realizado muchas comprobaciones en mi código para tratar de asegurarme de que los anuncios solo se inserten entre párrafos de solo texto. Los párrafos de solo texto se consideran párrafos que no contienen etiquetas img, li y ul

  • He documentado cada bloque de código correctamente, para que pueda trabajar fácilmente en cada sección. también he añadido todo bloques de documentos que debe atender, si es necesario

  • he utilizado wptexturize aplicar etiquetas p a the_content. Cada doble salto de línea constituye un párrafo

  • Modifique y use este código como mejor le parezca. Lo he probado, por lo que está libre de errores de mi parte.

Aquí está el código. Espero que esto funcione para usted como se esperaba. *¡PD! Todo esto entra en su functions.php. No es necesario ningún otro código o mods para sus archivos de plantilla

<?php
add_filter( 'the_content', 'so_25888630_ad_between_paragraphs' );

function so_25888630_ad_between_paragraphs($content){
    /**-----------------------------------------------------------------------------
     *
     *  @author       Pieter Goosen <http://stackoverflow.com/users/1908141/pieter-goosen>
     *  @return       Ads in between $content
     *  @link         http://stackoverflow.com/q/25888630/1908141
     * 
     *  Special thanks to the following answers on my questions that helped me to
     *  to achieve this
     *     - http://stackoverflow.com/a/26032282/1908141
     *     - http://stackoverflow.com/a/25988355/1908141
     *     - http://stackoverflow.com/a/26010955/1908141
     *     - http://wordpress.stackexchange.com/a/162787/31545
     *
    *------------------------------------------------------------------------------*/ 
    if( in_the_loop() ){ //Simply make sure that these changes effect the main query only

        /**-----------------------------------------------------------------------------
         *
         *  wptexturize is applied to the $content. This inserts p tags that will help to  
         *  split the text into paragraphs. The text is split into paragraphs after each
         *  closing p tag. Remember, each double break constitutes a paragraph.
         *  
         *  @todo If you really need to delete the attachments in paragraph one, you want
         *        to do it here before you start your foreach loop
         *
        *------------------------------------------------------------------------------*/ 
        $closing_p = '</p>';
        $paragraphs = explode( $closing_p, wptexturize($content) );

        /**-----------------------------------------------------------------------------
         *
         *  The amount of paragraphs is counted to determine add frequency. If there are
         *  less than four paragraphs, only one ad will be placed. If the paragraph count
         *  is more than 4, the text is split into two sections, $first and $second according
         *  to the midpoint of the text. $totals will either contain the full text (if 
         *  paragraph count is less than 4) or an array of the two separate sections of
         *  text
         *
         *  @todo Set paragraph count to suite your needs
         *
        *------------------------------------------------------------------------------*/ 
        $count = count( $paragraphs );
        if( 4 >= $count ) {
            $totals = array( $paragraphs ); 
        }else{
            $midpoint = floor($count / 2);
            $first = array_slice($paragraphs, 0, $midpoint );
            if( $count%2 == 1 ) {
                $second = array_slice( $paragraphs, $midpoint, $midpoint, true );
            }else{
                $second = array_slice( $paragraphs, $midpoint, $midpoint-1, true );
            }
            $totals = array( $first, $second );
        }

        $new_paras = array();   
        foreach ( $totals as $key_total=>$total ) {
            /**-----------------------------------------------------------------------------
             *
             *  This is where all the important stuff happens
             *  The first thing that is done is a work count on every paragraph
             *  Each paragraph is is also checked if the following tags, a, li and ul exists
             *  If any of the above tags are found or the text count is less than 10, 0 is 
             *  returned for this paragraph. ($p will hold these values for later checking)
             *  If none of the above conditions are true, 1 will be returned. 1 will represent
             *  paragraphs that qualify for add insertion, and these will determine where an ad 
             *  will go
             *  returned for this paragraph. ($p will hold these values for later checking)
             *
             *  @todo You can delete or add rules here to your liking
             *
            *------------------------------------------------------------------------------*/ 
            $p = array();
            foreach ( $total as $key_paras=>$paragraph ) {
                $word_count = count(explode(' ', $paragraph));
                if( preg_match( '~<(?:img|ul|li)[ >]~', $paragraph ) || $word_count < 10 ) {  
                    $p[$key_paras] = 0; 
                }else{
                    $p[$key_paras] = 1; 
                }   
            }

            /**-----------------------------------------------------------------------------
             *
             *  Return a position where an add will be inserted
             *  This code checks if there are two adjacent 1's, and then return the second key
             *  The ad will be inserted between these keys
             *  If there are no two adjacent 1's, "no_ad" is returned into array $m
             *  This means that no ad will be inserted in that section
             *
            *------------------------------------------------------------------------------*/ 
            $m = array();
            foreach ( $p as $key=>$value ) {
                if( 1 === $value && array_key_exists( $key-1, $p ) && $p[$key] === $p[$key-1] && !$m){
                    $m[] = $key;
                }elseif( !array_key_exists( $key+1, $p ) && !$m ) {
                    $m[] = 'no-ad';
                }
            } 

            /**-----------------------------------------------------------------------------
             *
             *  Use two different ads, one for each section
             *  Only ad1 is displayed if there is less than 4 paragraphs
             *
             *  @todo Replace "PLACE YOUR ADD NO 1 HERE" with your add or code. Leave p tags
             *  @todo I will try to insert widgets here to make it dynamic
             *
            *------------------------------------------------------------------------------*/ 
            if( $key_total == 0 ){
                $ad = array( 'ad1' => '<p>PLACE YOUR ADD NO 1 HERE</p>' );
            }else{
                $ad = array( 'ad2' => '<p>PLACE YOUR ADD NO 2 HERE</p>' );
            }

            /**-----------------------------------------------------------------------------
             *
             *  This code loops through all the paragraphs and checks each key against $mail
             *  and $key_para
             *  Each paragraph is returned to an array called $new_paras. $new_paras will
             *  hold the new content that will be passed to $content.
             *  If a key matches the value of $m (which holds the array key of the position
             *  where an ad should be inserted) an add is inserted. If $m holds a value of
             *  'no_ad', no ad will be inserted
             *
            *------------------------------------------------------------------------------*/ 
            foreach ( $total as $key_para=>$para ) {
                if( !in_array( 'no_ad', $m ) && $key_para === $m[0] ){
                    $new_paras[key($ad)] = $ad[key($ad)];
                    $new_paras[$key_para] = $para;
                }else{
                    $new_paras[$key_para] = $para;
                }
            }
        }

        /**-----------------------------------------------------------------------------
         *
         *  $content should be a string, not an array. $new_paras is an array, which will
         *  not work. $new_paras are converted to a string with implode, and then passed
         *  to $content which will be our new content
         *
        *------------------------------------------------------------------------------*/ 
        $content =  implode( ' ', $new_paras );
    }
    return $content;
}

EDITAR

De sus comentarios:

  • Debe usar el siguiente código para depurar <pre><?php var_dump($NAME_OF_VARIABLE); ?></pre>. Para su primer número, usaré ?><pre><?php var_dump($paragraphs); ?></pre><?php Justo después de esta línea $paragraphs = explode( $closing_p, wpautop($content) ); para ver exactamente cómo se divide el contenido. Esto le dará una idea de si su contenido se está dividiendo correctamente.

  • También usa ?><pre><?php var_dump($p); ?></pre><?php Justo después de esta línea $p = array(); para inspeccionar qué valor se le da a un párrafo específico. Recuerde, los párrafos con etiquetas img, li y ul deben tener un 0, también párrafos con menos de 10 palabras. El resto debe tener un 1

  • EDITAR -> Se resuelve el problema con los párrafos eliminados. Gracias por señalarme ese defecto. Nunca me di cuenta de esto. He actualizado el código, así que simplemente cópielo y péguelo.

EDITAR 2

Tenga en cuenta que no puede probar su código con la herramienta en línea que está utilizando. Esto no es un fiel reflejo de lo que genera the_content(). La salida que ve usando su herramienta en línea se filtra y marca antes de enviarse a la pantalla como the_content(). Si inspecciona su salida con un navegador como Google Chrome, verá que las etiquetas p se aplican correctamente.

También he cambiado la etiqueta a con la etiqueta de imagen en el código.

  • Dios mío, esto funciona de maravilla. MUCHAS GRACIAS, ya que actualizaré mi sitio con esto. Traté muy duro de fallar esto de muchas maneras, pero fracasé. Código sólido. Todos los requisitos pasaron. 🙂 Mi respeto… Te mereces una recompensa. Lo recordaré y te otorgaré uno cuando tenga más.

    – Debajyoti Das

    28 de septiembre de 2014 a las 12:10


  • Nota: explotando con </p> crea salida sin el </p>. entonces estoy usando $paragraphs = preg_split("/(?=<\/p>)/", $content, null, PREG_SPLIT_DELIM_CAPTURE); que parece funcionar bien.

    – Debajyoti Das

    19 de febrero de 2015 a las 0:15


avatar de usuario
David

con el código de muestra que me diste, esto es lo mejor que puedo hacer, había demasiadas imágenes allí, necesitarías un genio para descubrir la lógica requerida para tus requisitos, pero pruébalo, puede que no esté demasiado lejos apagado. Necesitarás php 5.5 para esto.

un par de puntos a tener en cuenta:

1. identifica los párrafos como si estuvieran envueltos en elementos p, no como en los párrafos visuales.

2. si existen p elementos dentro de otros elementos, también los reconocerá como párrafos. El primer anuncio es un ejemplo de esto. Evite usar p dentro de comillas, listas, etc., no es necesario, use spans, divs para el texto en su lugar.
3. He comentado una línea que llama a una función en __construct, descomente esto para insertar la segunda imagen. Esto realmente funciona bien, pero su contenido tiene muchos elementos p con oraciones divididas en varias p, es poco probable que esto sea un factor en el contenido real.
4. Busca imágenes en el párrafo 1 + párrafo 2 y las elimina.

$content = apply_filters('the_content', get_the_content() ); 

    class adinsert {


    var $content;
    var $paragraphs;    
    var $ad_pos1=2;
    var $ad_pos2;
    var $ad_pos3;
    var $ad= '<h1>ad position here</h1>';

public function __construct($content) {

    if(!$content)
        return $content;

    $this->set_content($content);

    $this->paragrapherize(2);
    $this->paragraph_numbers();
    $this->get_first_pos();
    $this->paragrapherize();
    $this->paragraph_numbers();
    $this->find_images();
    $this->find_ad_pos(); 
    $this->insert_ads();

}


public function echo_content(){
    echo $this->content;
}

private function insert_ads() {

    if($this->ad_pos2 && $this->ad_pos2 != 'end'):
        $posb= $this->ad_pos2;
        $this->content=substr_replace($this->content,$this->ad,$posb ,0);
    else:
        $this->content.= $this->ad;    
    endif;

    //comment the below line to remove last image insertion 
    $this->content.= $this->ad;
}

private function get_first_pos() {

    $i=0;

    foreach($this->paragraphs as $key=>$data):
        if($i==0):

            $length= $data['end']-$data['start'];
            $string= substr($this->content, $data['start'],$length);    
            $newkey= $key+1;
            $lengthb= $this->paragraphs[$newkey]['end']-$this->paragraphs[$newkey]['start'];
            $stringb= substr($this->content, $this->paragraphs[$newkey]['start'],$lengthb);

            $wcount= count(explode(' ', $string));

            if( preg_match('/(<img[^>]+>)/i', $string, $image) ):
                    $newstring=preg_replace('/(<img[^>]+>)/i', '', $string);

                        if($wcount>10):
                            $newstring.=$this->ad;
                            $this->ad_pos1=1;       
                            $this->content=str_replace($string,$newstring,$this->content);
                        endif;
            else:
                        if($wcount>10) :
                            $newstring=$string.$this->ad;
                            echo $newstring;
                            $this->ad_pos1=1;
                            //$this->content=str_replace($string,$newstring,$this->content);
                            $this->content= preg_replace('~'.$string.'~', $newstring, $this->content, 1);
                        endif;
            endif;

            if( preg_match('/(<img[^>]+>)/i', $stringb, $imageb) ):
                        $newstringb=preg_replace('/(<img[^>]+>)/i', '', $stringb);  
                        if($wcount<10) :
                        $newstringb.=$this->ad;
                        $this->ad_pos1=2;
                        $this->content=str_replace($stringb,$newstringb,$this->content);
                        endif;
            else:
                        if($wcount<10) :
                            $newstring=$stringb.$this->ad;
                            $this->ad_pos1=2;
                            $this->content=str_replace($stringb,$newstringb,$this->content);
                        endif;
            endif;

        else:
            break;
        endif;
        $i++;       
    endforeach;
}


private function find_ad_pos() {

    $remainder_images= $this->paragraph_count;
    if($remainder_images < $this->ad_pos1 + 3):
        $this->ad_pos2='end';
    else:   

        foreach($this->paragraphs as $key=>$data):
            $p[]=$key;
        endforeach;

        unset($p[0]);
        unset($p[1]);

        $startpos= $this->ad_pos1 + 2;
        $possible_ad_positions= $remainder_images - $startpos;
    //figure out half way
        if($remainder_images < 3): //use end pos
            $pos1= $startpos;
            $pos1=$this->getclosestkey($pos1, $p);
        else: // dont use end pos
            $pos1=  ($remainder_images/2)-1;
            $pos1= $this->getclosestkey($pos1, $p);
        endif;
        $this->ad_pos2= $this->paragraphs[$pos1]['end'];
    endif;
}


private function getclosestkey($key, $keys) {
    $close= 0;
    foreach($keys as $item): //4>4
        if($close == null || $key - $close > $item - $key ) :
          $close = $item;
        endif;
    endforeach;
    return $close;
}



private function find_images() {

    foreach($this->paragraphs as $item=>$key):
        $length= $key['end']-$key['start'];
        $string= substr($this->content, $key['start'],$length);
        if(strpos($string,'src')!==false && $item !=0 && $item !=1):
            //unset the number, find start in paragraphs array + 1 after
            unset($this->paragraphs[$item]);
            $nextitem= $item+1;
            $previtem= $item-1;
            unset($this->paragraphs[$nextitem]);
            unset($this->paragraphs[$previtem]);
        endif;          
    endforeach;

}





private function paragraph_numbers() {

    $i=1;
    foreach($this->paragraphs as $item):
        $i++;
    endforeach; 
    $this->paragraph_count=$i;
}

private function paragrapherize($limit=0) {

    $current_pos=0;
    $i=0;

    while( strpos($this->content, '<p', $current_pos) !== false ):

    if($limit && $i==$limit)
        break;

    if($i==105) {
        break;
    }
        if($i!=0) {
            $current_pos++; 
        }


        $paragraph[$i]['start']=strpos($this->content, '<p', $current_pos);//1

    //looking for the next time a /p follows a /p so is less than the next position of p

    $nextp= strpos($this->content, '<p', $paragraph[$i]['start']+1); //14 failing on next???
    $nextendp= strpos($this->content, '</p>', $current_pos);//22

    if($nextp>$nextendp)://NO
        $paragraph[$i]['end']=$nextendp;
        if( ($nextendp - $paragraph[$i]['start']) < 80 ):
            unset($paragraph[$i]);
        endif;

        $current_pos= $nextendp;
        $i++;   
    else:   

    $startipos = $nextendp;

        $b=0;                                           
        do {
            if($b==100){
               break;
            }

            $nextp= strpos($this->content, '<p', $startipos); //230
            $nextendp= strpos($this->content, '</p>', $startipos+1);//224


            if($nextp>$nextendp) {

                $paragraph[$i]['end']=$nextendp;
                $current_pos= $nextendp;

                $i++;
            } else {
                $startipos = $nextendp+1;
            }
            $b++;

        } while ($nextp < $nextendp );
    endif;
        endwhile;
        $this->paragraphs= $paragraph;
    }

    public function set_content($content) {
        $this->content= $content;
    }

}

$newcontent= new adinsert($content);

luego, dónde desea generar su contenido

 <?php echo $newcontent->echo_content(); ?>

  • Sí, funcionó… 🙂 1. Pero el tercer anuncio se coloca justo antes de una imagen. eval.in/private/2f5c211b9788c4 2. Y también elimina los bloques div existentes. 3. Debe haber al menos 2 párrafos entre 2 anuncios

    – Debajyoti Das

    19/09/2014 a las 18:23


  • también está eliminando bloques no p existentes como div table etc.

    – Debajyoti Das

    19/09/2014 a las 18:39

  • ¿Puedes pegar el contenido html real en algún lugar para que pueda tener una idea del resultado típico? Está diseñado para usar p como el envoltorio externo, ya que eso es en lo que supuse que consiste cada bloque. También eche un vistazo al bloque if else usando $ad_avail_positions que decide cuándo se colocan los anuncios… ¿cuántos párrafos habría normalmente? Si es un rango muy amplio de variación, la función tiende a inflarse un poco a menos que pueda usar algo simple como si el anuncio en este bloque, coloque el siguiente anuncio a 2 bloques si no hay imagen, o si la imagen, salte al siguiente disponible, ¡etc!

    – David

    19/09/2014 a las 20:00

  • Puedes ver lo que he definido para $content aquí eval.in/private/2f5c211b9788c4 Nota: Las tablas, las listas no se forman dentro del bloque p en html… están fuera. Creo que podemos incluir estas marcas comunes en getElementsByTagName. ¿qué opinas?

    – Debajyoti Das

    19/09/2014 a las 20:53


  • Las etiquetas comunes fuera de

    son

    ,

    ,
      ,
      ,

      – Debajyoti Das

      19/09/2014 a las 20:59

      Esta es una solución. No es completamente programático, pero lo he hecho antes y funcionará. Básicamente, use un “código corto”. El problema de hacerlo de forma totalmente programática es que no hay una buena manera de averiguar si el flujo de un artículo con imágenes en línea, videos, etc. haría que las ubicaciones de los anuncios se vean realmente mal. En su lugar, configure su CMS con un código abreviado para que los editores puedan colocar anuncios en un lugar óptimo en el artículo.

      P.ej

      <p>Bacon ipsum dolor sit amet short ribs tenderloin venison pastrami meatloaf kevin, shoulder meatball landjaeger pork corned beef turkey salami frankfurter jerky. Pork loin bresaola porchetta strip steak meatball t-bone andouille chuck chicken shankle shank tongue. Hamburger flank kevin short ribs. Pork loin landjaeger frankfurter corned beef, fatback salami short loin ground round biltong.</p>
      
      [ad_block]
      
      <p>Pastrami jerky drumstick swine ribeye strip steak pork belly kevin tail rump pancetta capicola. Meatloaf doner porchetta, rump tenderloin t-bone biltong pork belly. Porchetta boudin ham ribeye frankfurter flank short loin, drumstick pork loin filet mignon chuck fatback. Strip steak jowl capicola ham hock turducken biltong ground round filet mignon venison prosciutto chuck pork. Venison ribeye fatback kielbasa, ball tip turducken capicola drumstick sausage pancetta boudin turkey ham strip steak corned beef.</p>
      

      Luego, usando PHP str_replace simplemente puede intercambiar el código abreviado ad_block con su HTML para sus anuncios.

      P.ej

      echo str_replace('[ad_block]', $ad_block_html, $content);
      

      • Completamente de acuerdo… Pero tiene sentido solo para sitios relativamente nuevos. Pesadilla para un sitio ya grande, administrado de forma individual.

        – Debajyoti Das

        19 de septiembre de 2014 a las 11:29

      • Gracias por el tocino… lo siento, no resolví todo el problema. 🙂

        – Leonardo Teo

        19/09/2014 a las 11:31

      avatar de usuario
      Marcello Monkemeyer

      Hice algunos retoques y esto es lo que finalmente obtuve. Siéntase libre de probar y darme algunos comentarios.

      class Advertiser
      {
          /**
           * All advertises to place
           *
           * @access  private
           * @var     array
           */
          private $ads        = array();
      
          /**
           * The position behind the </p> element nearest to the center
           *
           * @access  private
           * @var     int
           */
          private $center     = null;
      
          /**
           * The content to parse
           *
           * @access  private
           * @var     string
           */
          private $content    = null;
      
          /**
           * Constructor method
           *
           * @access  public
           * @param   string  $content    the content to parse (optional)
           * @param   array   $ads        all advertises to place (optional)
           * @return  object              itself as object
           */
          public function __construct ($content = null, $ads = array())
          {
              if (count($ads)) $this->ads = $ads;
              if ($content) $this->setContent($content);
      
              return $this;
          }
      
          /**
           * Calculates and sets the position behind the </p> element nearest to the center
           *
           * @access  public
           * @return  object              the position behind the </p> element nearest to the center
           */
          public function calcCenter ()
          {
              $content = $this->content;
      
              if (!$content) return $this;
      
              $center = ceil(strlen($content)/2);
      
              $rlpos  = strripos(substr($content, 0, $center), '</p>');
              $rrpos  = stripos($content, '</p>', $center);
      
              $this->center = 4 + ($center-$rlpos <= $rrpos-$center ? $rlpos : $rrpos);
      
              return $this;
          }
      
          /**
           * Places the first ad
           *
           * @access  public
           * @param   string  $ad optional; if not specified, take the internally setted ad
           * @return  object      itself as object
           */
          public function placeFirstAd ($ad = null)
          {
              $ad = $ad ? $ad : $this->ads[0];
              $content = $this->content;
      
              if (!$content || !$ad) return $this;
      
              // the position before and after the first paragraph
              $pos1 = strpos($content, '<p');
              $pos2 = strpos($content, '</p>') + 4;
      
              // place ad
              $content = substr($content, 0, $pos2) . $ad . substr($content, $pos2);
      
              // strip images
              $content = substr($content, 0, $pos1) . preg_replace('#<img(?:\s.*?)?/?>#i', '', substr($content, $pos1, $pos2)) . substr($content, $pos2);
      
              $this->content = $content;
      
              return $this;
          }
      
          /**
           * Places the second ad
           *
           * @access  public
           * @param   string  $ad optional; if not specified, take the internally set ad
           * @return  object      itself as object
           */
          public function placeSecondAd ($ad = null)
          {
              $ad = $ad ? $ad : $this->ads[1];
              $content = $this->content;
      
              if (!$content || !$ad) return $this;
      
              $center = $this->center;
      
              // place ad
              $content = substr($content, 0, $center) . $ad . substr($content, $center);
      
              $this->content = $content;
      
              return $this;
          }
      
          /* Getters */
      
          /**
           * Gets the content in it's current state
           *
           * @access  public
           * @return  string  the content in it's current state
           */
          public function getContent ()
          {
              return $this->content;
          }
      
          /* Setters */
      
          /**
           * Sets the content
           *
           * @access  public
           * @param   string  $content    the content to parse
           * @return  object              itself as object
           */
          public function setContent ($content)
          {
              $this->content = $content;
      
              $this->calcCenter();
      
              return $this;
          }
      
          /**
           * Sets the first ad
           *
           * @access  public
           * @param   string  $ad the ad
           * @return  object      itself as object
           */
          public function setFirstAd ($ad)
          {
              if ($ad) $this->ad[0] = $ad;
      
              return $this;
          }
      
          /**
           * Sets the second ad
           *
           * @access  public
           * @param   string  $ad the ad
           * @return  object      itself as object
           */
          public function setSecondAd ($ad)
          {
              if ($ad) $this->ad[1] = $ad;
      
              return $this;
          }
      }
      

      Ejemplo de uso:

      $first_ad   = 'bacon';
      $second_ad  = 'ham';
      
      $content    = apply_filters('the_content', $post->post_content);
      
      $advertiser = new Advertiser($content);
      
      $advertiser->placeFirstAd($first_ad);
      //$advertiser-> placeSecondAd($second_ad);
      
      $advertised_content = $advertiser->getContent();
      

      Puede comentar placeSecondAd() o reemplazarlo con su función de trabajo.

      avatar de usuario
      Amir Fo

      Aquí hay una manera inteligente:

      $content = "<p>A</p><p>B</p><p>C</p><p>D</p>";
      $pos = 2;
      $content = preg_replace('/<p>/', '<helper>', $content, $pos + 1); //<helper>A</p><helper>B</p><helper>C</p><p>D</p>
      $content = preg_replace('/<helper>/', '<p>', $content, $pos);     //<p>A</p><p>B</p><helper>C</p><p>D</p>
      $content = str_replace("<helper>", "<p>ad</p><p>", $content);     //<p>A</p><p>B</p><p>ad</p><p>C</p><p>D</p>
      

      Aquí hay una función completa:

      function insertAd($content, $ad, $pos = 0){
        // $pos = 0 means randomly position in the content
        $count = substr_count($content, "<p>");
        if($count == 0  or $count <= $pos){
          return $content;
        }
        else{
          if($pos == 0){
            $pos = rand (1, $count - 1);
          }
          $content = preg_replace('/<p>/', '<helper>', $content, $pos + 1);
          $content = preg_replace('/<helper>/', '<p>', $content, $pos);
          $content = str_replace('<helper>', $ad . "\n<p>", $content);
          return $content;
        }
      }
      

      Ok, esta es una idea para moverte (posiblemente) en una dirección más cercana a la forma totalmente programática que estás preguntando…

      Use un analizador HTML DOM como http://simplehtmldom.sourceforge.net/ para analizar cada artículo. Con esto, en teoría, debería poder seleccionar todas las etiquetas de párrafo y luego insertar los bloques de anuncios entre los correctos según sus cálculos.

      $html = str_get_html($content);
      $paragraphs_arr = $html->find('p'); //Returns all paragraphs
      $halfway_mark = ceil(count($paragraphs_arr) / 2);
      
      $halfway_paragraph = $paragraphs_arr[$halfway_mark];
      
      // Somewhere here now you just have to figure out how to inject the ad right after the halfway paragraph.
      
      E.g.
      $p_content = $halfway_paragraph->innertext();
      $p_content = $p_content."</p><p><!-- Ad --></p>"; // Force close the tag as we're in the innertext.
      $halfway_paragraph->innertext($p_content);
      

      ¿Eso se acerca un poco más a lo que estás tratando de hacer?

      avatar de usuario
      Anjana

      Usar

       strip_tags('contnet','like <p>');
      

      • En esto responde la pregunta cómo

        – Pieter Goosen

        23 de septiembre de 2014 a las 11:06

      ¿Ha sido útil esta solución?