function getSQL()
 {
     return AltMethodAdder::getSql();
 }
 /**
  * Insert ad codes, and other random bits of html, into the body of the article
  */
 static function postProcess($body, $opts = array())
 {
     global $wgWikiHowSections, $wgTitle, $wgUser;
     $ads = $wgUser->isAnon() && !@$opts['no-ads'];
     $parts = preg_split("@(<h2.*</h2>)@im", $body, 0, PREG_SPLIT_DELIM_CAPTURE);
     $reverse_msgs = array();
     $no_third_ad = false;
     $isRecipe = Microdata::showRecipeTags() && Microdata::showhRecipeTags();
     foreach ($wgWikiHowSections as $section) {
         $reverse_msgs[wfMessage($section)->text()] = $section;
     }
     $charcount = strlen($body);
     $body = "";
     for ($i = 0; $i < sizeof($parts); $i++) {
         if ($i == 0) {
             if ($body == "") {
                 // if there is no alt tag for the intro image, so it to be the title of the page
                 preg_match("@<img.*mwimage101[^>]*>@", $parts[$i], $matches);
                 if ($wgTitle && sizeof($matches) > 0) {
                     $m = $matches[0];
                     $newm = str_replace('alt=""', 'alt="' . htmlspecialchars($wgTitle->getText()) . '"', $m);
                     if ($m != $newm) {
                         $parts[$i] = str_replace($m, $newm, $parts[$i]);
                     }
                     //add microdata
                     if ($isRecipe) {
                         $parts[$i] = preg_replace('/mwimage101"/', 'mwimage101 photo"', $parts[$i], 1);
                     } else {
                         $parts[$i] = preg_replace('/mwimage101"/', 'mwimage101" itemprop="image"', $parts[$i], 1);
                     }
                     $img_itemprop_done = true;
                 } else {
                     $img_itemprop_done = false;
                 }
                 // add microdata
                 if ($isRecipe) {
                     $parts[$i] = preg_replace('/\\<p\\>/', '<p class="summary">', $parts[$i], 1);
                 } else {
                     $parts[$i] = preg_replace('/\\<p\\>/', '<p itemprop="description">', $parts[$i], 1);
                 }
                 // done alt test
                 $anchorPos = stripos($parts[$i], "<a name=");
                 if ($anchorPos > 0 && $ads) {
                     $content = substr($parts[$i], 0, $anchorPos);
                     $count = preg_match_all('@</p>@', $parts[$i], $matches);
                     if ($count == 1) {
                         // this intro only has one paragraph tag
                         $class = 'low';
                     } else {
                         $endVar = "<p><br /></p>\n<p>";
                         $end = substr($content, -1 * strlen($endVar));
                         if ($end == $endVar) {
                             $class = 'high';
                             //this intro has two paragraphs at the end, move ads higher
                         } else {
                             $class = 'mid';
                             //this intro has no extra paragraphs at the end.
                         }
                     }
                     if (stripos($parts[$i], "mwimg") != false) {
                         $body = "<div class='article_inner editable'>" . $content . "<div class='ad_image " . $class . "'>" . wikihowAds::getAdUnitPlaceholder('intro') . "</div>" . substr($parts[$i], $anchorPos) . "</div>\n";
                     } else {
                         $body = "<div class='article_inner editable'>" . $content . "<div class='ad_noimage " . $class . "'>" . wikihowAds::getAdUnitPlaceholder('intro') . "</div>" . substr($parts[$i], $anchorPos) . "</div>\n";
                     }
                 } elseif ($anchorPos == 0 && $ads) {
                     $body = "<div class='article_inner editable'>{$parts[$i]}" . wikihowAds::getAdUnitPlaceholder('intro') . "</div>\n";
                 } else {
                     $body = "<div class='article_inner editable'>{$parts[$i]}</div>\n";
                 }
             }
             continue;
         }
         if (stripos($parts[$i], "<h2") === 0 && $i < sizeof($parts) - 1) {
             // MWUP aaron changed this from <span> to <span because we now no longer wrap
             // the section name in a normal span, but a span with class and id
             preg_match("@<span.*</span>@", $parts[$i], $matches);
             $rev = "";
             if (sizeof($matches) > 0) {
                 $h2 = trim(strip_tags($matches[0]));
                 $rev = isset($reverse_msgs[$h2]) ? $reverse_msgs[$h2] : "";
             }
             $body .= $parts[$i];
             $i++;
             if ($rev == "steps") {
                 if (Microdata::showRecipeTags()) {
                     if (Microdata::showhRecipeTags()) {
                         $recipe_tag = " instructions'";
                     } else {
                         $recipe_tag = "' itemprop='recipeInstructions'";
                     }
                 } else {
                     $recipe_tag = "'";
                 }
                 $body .= "\n<div id=\"steps\" class='editable{$recipe_tag}>{$parts[$i]}</div>\n";
             } elseif ($rev != "") {
                 $body .= "\n<div id=\"{$rev}\" class='article_inner editable'>{$parts[$i]}</div>\n";
             } else {
                 $body .= "\n<div class='article_inner editable'>{$parts[$i]}</div>\n";
             }
         } else {
             $body .= $parts[$i];
         }
     }
     $punct = "!\\.\\?\\:";
     # valid ways of ending a sentence for bolding
     $i = strpos($body, '<div id="steps"');
     if ($i !== false) {
         $j = strpos($body, '<div id=', $i + 5);
         //find the position of the next div. Starting after the '<div ' (5 characters)
         $sub = "sd_";
         //want to skip over the samples section if they're there
         while ($j !== false && $sub == "sd_") {
             $sub = substr($body, $j + 9, 3);
             //find the id of the next div section 9=strlen(<div id="), 3=strlen(sd_)
             $j = strpos($body, '<div id=', $j + 12);
             //find the position of the next div. Starting after the '<div id="sd_' (12 characters)
         }
     }
     if ($j === false) {
         $j = strlen($body);
     }
     if ($j !== false && $i !== false) {
         $steps = substr($body, $i, $j - $i);
         $parts = preg_split("@(<[/]?ul>|<[/]?ol>|<[/]?li>)@im", $steps, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
         $numsteps = preg_match_all('/<li>/m', $steps, $matches);
         $level = 0;
         $steps = "";
         $upper_tag = "";
         // for the redesign we need some extra formatting for the OL, etc
         $levelstack = array();
         $tagstack = array();
         $current_tag = "";
         $current_li = 1;
         $donefirst = false;
         // used for ads to tell when we've put the ad after the first step
         $bImgFound = false;
         $the_last_picture = '';
         $final_pic = array();
         $alt_link = array();
         // Limit steps to 400 or it will timeout
         if ($numsteps < 400) {
             while ($p = array_shift($parts)) {
                 switch (strtolower($p)) {
                     case "<ol>":
                         $level++;
                         if ($level == 1) {
                             $p = '<ol class="steps_list_2">';
                             $upper_tag = "ol";
                         } else {
                             $p = "&nbsp;{$p}";
                         }
                         if ($current_tag != "") {
                             $tagstack[] = $current_tag;
                         }
                         $current_tag = "ol";
                         $levelstack[] = $current_li;
                         $current_li = 1;
                         break;
                     case "<ul>":
                         if ($current_tag != "") {
                             $tagstack[] = $current_tag;
                         }
                         $current_tag = "ul";
                         $levelstack[] = $current_li;
                         $level++;
                         break;
                     case "</ol>":
                     case "</ul>":
                         $level--;
                         if ($level == 0) {
                             $upper_tag = "";
                         }
                         $current_tag = array_pop($tagstack);
                         $current_li = array_pop($levelstack);
                         break;
                     case "<li>":
                         $closecount = 0;
                         if ($level == 1 && $upper_tag == "ol") {
                             $li_number = $current_li++;
                             $p = '<li><div class="step_num">' . $li_number . '</div>';
                             # this is where things get interesting. Want to make first sentence bold!
                             # but we need to handle cases where there are tags in the first sentence
                             # split based on HTML tags
                             $next = array_shift($parts);
                             $htmlparts = preg_split("@(<[^>]*>)@im", $next, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
                             $dummy = 0;
                             $incaption = false;
                             $apply_b = false;
                             $the_big_step = $next;
                             while ($x = array_shift($htmlparts)) {
                                 # if it's a tag, just append it and keep going
                                 if (preg_match("@(<[^>]*>)@im", $x)) {
                                     //tag
                                     $p .= $x;
                                     if ($x == "<span class='caption'>") {
                                         $incaption = true;
                                     } elseif ($x == "</span>" && $incaption) {
                                         $incaption = false;
                                     }
                                     continue;
                                 }
                                 # put the closing </b> in if we hit the end of the sentence
                                 if (!$incaption) {
                                     if (!$apply_b && trim($x) != "") {
                                         $p .= "<b class='whb'>";
                                         $apply_b = true;
                                     }
                                     if ($apply_b) {
                                         $x = preg_replace("@([{$punct}])@im", "</b>\$1", $x, 1, $closecount);
                                     }
                                 }
                                 $p .= $x;
                                 if ($closecount > 0) {
                                     break;
                                 }
                                 $dummy++;
                             }
                             # get anything left over
                             $p .= implode("", $htmlparts);
                             //microdata the final image if we haven't already tagged the intro img
                             if (!$img_itemprop_done && $numsteps == $li_number) {
                                 $p = preg_replace('/mwimage101"/', 'mwimage101" itemprop="image"', $p, 1);
                             }
                             if ($closecount == 0) {
                                 $p .= "</b>";
                             }
                             // close the bold tag if we didn't already
                             if ($level == 1 && $current_li == 2 && $ads && !$donefirst) {
                                 $p .= wikihowAds::getAdUnitPlaceholder(0);
                                 $donefirst = true;
                             }
                         } elseif ($current_tag == "ol") {
                             //$p = '<li><div class="step_num">'. $current_li++ . '</div>';
                         }
                         break;
                     case "</li>":
                         $p = "<div class='clearall'></div>{$p}";
                         //changed BR to DIV b/c IE doesn't work with the BR clear tag
                         break;
                 }
                 // switch
                 $steps .= $p;
             }
             // while
         } else {
             $steps = substr($body, $i, $j - $i);
             $steps = "<div id='steps_notmunged'>\n" . $steps . "\n</div>\n";
         }
         // we have to put the final_li in the last OL LI step, so reverse the walk of the tokens
         $parts = preg_split("@(<[/]?ul>|<[/]?ol>|<[/]?li>)@im", $steps, 0, PREG_SPLIT_DELIM_CAPTURE);
         $parts = array_reverse($parts);
         $steps = "";
         $level = 0;
         $gotit = false;
         $donelast = false;
         $insertedAlt = false;
         foreach ($parts as $p) {
             $lp = strtolower($p);
             if ($lp == "</ol>") {
                 $level++;
                 $gotit = false;
                 if (class_exists("AltMethodAdder") && $wgTitle && $wgUser && $wgUser->isAnon() && !$insertedAlt) {
                     $p = $p . AltMethodAdder::getCTA($wgTitle);
                     $insertedAlt = true;
                 }
             } elseif ($lp == "</ul>") {
                 $level++;
             } elseif (strpos($lp, "<li") !== false && $level == 1 && !$gotit) {
                 /// last OL step list f****r
                 $p = preg_replace("@<li[^>]*>@i", '<li class="steps_li final_li">', $p);
                 $gotit = true;
             } elseif (strpos($lp, "<ul") !== false) {
                 $level--;
             } elseif (strpos($lp, "<ol") !== false) {
                 $level--;
             } elseif ($lp == "</li>" && !$donelast) {
                 // ads after the last step
                 if ($ads) {
                     if (substr($body, $j) == "") {
                         $p = "<script>missing_last_ads = true;</script>" . wikihowAds::getAdUnitPlaceholder(1) . $p;
                         $no_third_ad = true;
                     } else {
                         $p = wikihowAds::getAdUnitPlaceholder(1) . $p;
                     }
                 }
                 $donelast = true;
             }
             $steps = $p . $steps;
         }
         $body = substr($body, 0, $i) . $steps . substr($body, $j);
     }
     // if numsteps == 400?
     //recipe prep time test
     if (class_exists('Microdata') && $wgTitle) {
         Microdata::insertPrepTimeTest($wgTitle->getDBkey(), $body);
     }
     /// ads below tips, walk the sections and put them after the tips
     if ($ads) {
         $foundtips = false;
         $anchorTag = "";
         foreach ($wgWikiHowSections as $s) {
             $isAtEnd = false;
             if ($s == "ingredients" || $s == "steps") {
                 continue;
             }
             // we skip these two top sections
             $i = strpos($body, '<div id="' . $s . '"');
             if ($i !== false) {
                 $j = strpos($body, '<h2>', $i + strlen($s));
             } else {
                 continue;
                 // we didnt' find this section
             }
             if ($j === false) {
                 $j = strlen($body);
                 // go to the end
                 $isAtEnd = true;
             }
             if ($j !== false && $i !== false) {
                 $section = substr($body, $i, $j - $i);
                 if ($s == "video") {
                     // special case for video
                     $newsection = "<div id='video' itemprop='video'><center>{$section}</center></div>";
                     $body = str_replace($section, $newsection, $body);
                     continue;
                 } elseif ($s == "tips") {
                     //tip ad is now at the bottom of the tips section
                     //need to account for the possibility of no sections below this and therefor
                     //no anchor tag
                     if ($isAtEnd) {
                         $anchorTag = "<p></p>";
                     }
                     $body = str_replace($section, $section . $anchorTag . wikihowAds::getAdUnitPlaceholder('2a'), $body);
                     $foundtips = true;
                     break;
                 } else {
                     $foundtips = true;
                     if ($isAtEnd) {
                         $anchorTag = "<p></p>";
                     }
                     $body = str_replace($section, $section . $anchorTag . wikihowAds::getAdUnitPlaceholder(2), $body);
                     break;
                 }
             }
         }
         if (!$foundtips && !$no_third_ad) {
             //must be the video section
             //need to put in the empty <p> tag since all the other sections have them for the anchor tags.
             $body .= "<p class='video_spacing'></p>" . wikihowAds::getAdUnitPlaceholder(2);
         }
     }
     return $body;
 }