I forbindelse med mit arbejde i WordPress for Musalaha, fik vi behov for at vise det nyeste nyhedsbrev på forsiden.

Lad os finde PDF filerne

En løsning var at oprette en side, og så importere denne side på forsiden via min forbedrede side inkludering. Dette er ikke en optimal løsning da skribenten på Musalaha så både skal uploade nyhedsbrevet, indsætte det på siden med vores nyhedsbreve, og huske at opdatere siden indeholdende det seneste nyhedsbrev. I stedet ønskede vi at automatisere denne proces, det gælder trods alt om at give skribenterne så få muligheder for at lave fejl som muligt

Efter at have søgt vidt og bredt efter et plugin, der kunne hjælpe mig med opgaven, endte jeg hos Stray Bits hvor Chris Cummings havde siddet med samme problematik. Min løsning er baseret meget på hans arbejde, men dog med nogle modefikationer for at kunne bruge koden mere bredt i fremtiden, der er jo ingen grund til at låse sig selv fast fra begyndelsen.

function squazz_get_PDF($targetword, $limit = '-1') {
   // Setup what we are searching for
   $args = array(
      'post_type' => 'attachment',
      'post_mime_type' => 'application/pdf',
      'numberposts' => -1,
      'post_status' => null,
      'post_parent' => null,
      'orderby' => 'post_date',
      'order' => 'DESC'
   );
 
   // Get the initial results
   $attachments = get_posts($args);
   // If there are results, sort them
   if ($attachments) {
      $i = 1;
      foreach ($attachments as $post) {
         // Get the post title 
         $title = $post->post_title;
         // Only show results matching our keyword
         if (stripos($title,$targetword) !== false) {
            $files[$i]['ID'] = $post->ID;
            $files[$i]['title'] = $title;
            ...
            if($i == $limit) { break; }
            ++$i;
         }
      }
   } else {
      _e('Nothing to see here', 'SquazzFunctions')
   }
   return $files;
}

Med vores funktion kan vi nu vælge hvilket nøgle ord vi vil søge efter, og hvor mange resultater vi ønsker at få.

Næsten i mål

Med ovenstående løsning fik jeg hvad jeg ønskede, næsten i hvert fald. Funktionen søger efter PDF filer hvis titel indeholder vores keyword. I vores tilfælde skulle vi kun bruge ét dokument, det seneste, som er på engelsk. Og netop her opstår problematikken: “… på englesk“. Arbejdsrutinen omkring upload af vores nyhedsbreve er som oftest den at vi først uploader det engelske nyhedsbrev, så det tyske og så det franske. Hvilket også betyder at jeg i første forsøg fik præsenteret det franske nyhedsbrev da jeg kørte min funktion. Én løsning er at fortælle alle skribenterne at de skal uploade det engelske nyhedsbrev til sidst, men hele grunden til at vi lavede denne funktion var jo at vi ønskede at minimere mængden af ting vore skribenter skulle huske på.

Det vores funktion har brug for, er en opgradering. Ud over at vælge hvad vi vil søge efter, og hvor mange resultater vi ønsker at modtage, vil vi også kunne vælge hvilke ting vi ikke ønsker at få med i resultaterne. Dette viste sig at være nemmere sagt end gjort.

Heldigvis har vi på Musalaha en arbejdsrutine hvor nyhedsbreve navngives “newsletter-*LANGUAGE*-*YEAR*”, dette er vigtig information da vi så “bare” skal fortælle vores mini PDF-søgemaskine hvilke ting vi ikke ønsker at blive præsenteret for. PHP tilbyder os finde strenge ved hjælpe af strpos(), desværre tilbyder PHP os ikke at søge efter et array af strenge i samme streng. Heldigvis for mig er der andre der har haft dette problem, og som så mange gange før kunne StackOwerflow hjælpe mig videre med en super god løsning. For at skabe overblik har vi koden herunder:

function strposa($haystack, $needle, $offset=0) {
   if(!is_array($needle)) $needle = array($needle);
   foreach($needle as $query) {
      // stop on first true result
      if(strpos($haystack, $query, $offset) !== false) return true; 
   }
   return false;
}

Note: strpos() er case-sensitive, brug stripos() hvis du leder efter en case-insensitive løsning.

Med min nye funktion, som kan søge efter flere keywords i en streng, har jeg nu det perfekte våben i kampen mod uønskede fraser i titlen på vores nyhedsbrev. Vi tilføjer et nyt parameter til vores funktion, nogle få linjer i koden af funktionen, så er vi faktisk klar til at frasortere alle de elementer vi ikke ønsker at se.

function squazz_get_PDF($targetword, $limit = '-1', $remove = array()) {
   ...
   if ($attachments) {
      ...
         if (stripos($title,$targetword) !== false) {
            if(!strposa($title,$remove)) {
               ...
            }
         }
      }
   }
   ...
}

Den endelige funktion kan ses herunder i sin fulde form:

function squazz_get_PDF($targetword, $limit = '-1', $remove = array()) {
   // Setup what we are searching for
   $args = array(
      'post_type' => 'attachment',
      'post_mime_type' => 'application/pdf',
      'numberposts' => -1,
      'post_status' => null,
      'post_parent' => null,
      'orderby' => 'post_date',
      'order' => 'DESC'
   );
 
   // Get the initial results
   $attachments = get_posts($args);
   // If there are results, sort them
   if ($attachments) {
      $i = 1;
      foreach ($attachments as $post) {
         // Get the post title 
         $title = $post->post_title;
         // Only show results matching our keyword
         if (stripos($title,$targetword) !== false) {
            if(!strposa($title,$remove)) {
               $files[$i]['ID'] = $post->ID;
               $files[$i]['title'] = $title;
               ...
               if($i == $limit) { break; }
               ++$i;
            }
         }
      }
   } else {
      _e('Nothing to see here', 'SquazzFunctions')
   }
   return $files;
}