/**
  * Fetches the requested pages markup, cleans it and returns a DOMDocument.
  * @param array $aParams Needs the 'article-id' or 'title' key to be set and valid.
  * @return array 
  */
 public static function getPage($aParams)
 {
     wfRunHooks('BSUEModulePDFbeforeGetPage', array(&$aParams));
     $oBookmarksDOM = new DOMDocument();
     $oBookmarksDOM->loadXML('<bookmarks></bookmarks>');
     $oTitle = null;
     if (isset($aParams['article-id'])) {
         $oTitle = Title::newFromID($aParams['article-id']);
     }
     if ($oTitle == null) {
         //HINT: This is probably the wrong place for urldecode(); Should be
         //done by caller. I.e. BookExportModulePDF
         $oTitle = Title::newFromText(urldecode($aParams['title']));
     }
     $oPCP = new BsPageContentProvider();
     $oPageDOM = $oPCP->getDOMDocumentContentFor($oTitle, $aParams + array('follow-redirects' => true));
     // TODO RBV (06.12.11 17:09): Follow Redirect... setting or default?
     //Collect Metadata
     $aData = self::collectData($oTitle, $oPageDOM, $aParams);
     //Cleanup DOM
     self::cleanUpDOM($oTitle, $oPageDOM, $aParams);
     $oBookmarkNode = BsUniversalExportHelper::getBookmarkElementForPageDOM($oPageDOM);
     //HINT: http://www.mm-newmedia.de/blog/2010/05/wrong-document-error-wtf/
     $oBookmarksDOM->documentElement->appendChild($oBookmarksDOM->importNode($oBookmarkNode, true));
     $oDOMXPath = new DOMXPath($oPageDOM);
     $oFirstHeading = $oDOMXPath->query("//*[contains(@class, 'firstHeading')]")->item(0);
     $oBodyContent = $oDOMXPath->query("//*[contains(@class, 'bodyContent')]")->item(0);
     // TODO RBV (01.02.12 11:28): What if no TOC?
     $oTOCULElement = $oDOMXPath->query("//*[contains(@class, 'toc')]//ul")->item(0);
     if (isset($aParams['display-title'])) {
         $oBookmarkNode->setAttribute('name', $aParams['display-title']);
         $oFirstHeading->nodeValue = $aParams['display-title'];
         $aData['meta']['title'] = $aParams['display-title'];
     }
     $aPage = array('resources' => $aData['resources'], 'dom' => $oPageDOM, 'firstheading-element' => $oFirstHeading, 'bodycontent-element' => $oBodyContent, 'toc-ul-element' => $oTOCULElement, 'bookmarks-dom' => $oBookmarksDOM, 'bookmark-element' => $oBookmarkNode, 'meta' => $aData['meta']);
     wfRunHooks('BSUEModulePDFgetPage', array($oTitle, &$aPage, &$aParams, $oDOMXPath));
     return $aPage;
 }
 /**
  * Dispatched from execute();
  */
 private function processParameter($sParameter)
 {
     try {
         $this->oRequestedTitle = Title::newFromText($sParameter);
         /*if( !$this->oRequestedTitle->exists() && $this->oRequestedTitle->getNamespace() != NS_SPECIAL ) { //!$this->mRequestedTitle->isSpecialPage() does not work in MW 1.13
         			throw new Exception( 'error-requested-title-does-not-exist' );
         		}*/
         //Get relevant page props
         $dbr = wfGetDB(DB_SLAVE);
         $res = $dbr->selectField('page_props', 'pp_value', array('pp_propname' => 'bs-universalexport-params', 'pp_page' => $this->oRequestedTitle->getArticleID()));
         if ($res != false) {
             $res = FormatJson::decode($res, true);
             if (is_array($res)) {
                 $this->aParams = array_merge($this->aParams, $res);
             }
         }
         BsUniversalExportHelper::getParamsFromQueryString($this->aParams);
         //Title::userCan always returns false on special pages (exept for createaccount action)
         if ($this->oRequestedTitle->getNamespace() === NS_SPECIAL) {
             if ($this->getUser()->isAllowed('universalexport-export') !== true) {
                 throw new Exception('bs-universalexport-error-permission');
             }
         } elseif ($this->oRequestedTitle->userCan('universalexport-export') === false) {
             throw new Exception('bs-universalexport-error-permission');
         }
         // TODO RBV (24.01.11 17:37): array_intersect(), may be better?
         $aCategoryNames = BsUniversalExportHelper::getCategoriesForTitle($this->oRequestedTitle);
         foreach ($aCategoryNames as $sCategoryName) {
             if (in_array($sCategoryName, $this->aCategoryBlacklist)) {
                 throw new Exception('bs-universalexport-error-requested-title-in-category-blacklist');
             }
         }
         BsUniversalExportHelper::checkPermissionForTitle($this->oRequestedTitle, $this->aParams);
         //Throws Exception
         $sModuleKey = $this->aParams['module'];
         if (!isset($this->aModules[$sModuleKey]) || !$this->aModules[$sModuleKey] instanceof BsUniversalExportModule) {
             throw new Exception('bs-universalexport-error-requested-export-module-not-found');
         }
         $oExportModule = $this->aModules[$sModuleKey];
         $aFile = $oExportModule->createExportFile($this);
         $this->returnFile($aFile);
     } catch (Exception $oException) {
         //Display Exception-Message and Stacktrace
         $this->oOutputPage->setPageTitle(wfMessage('bs-universalexport-page-title-on-error')->text());
         $oExceptionView = new ViewException($oException);
         $this->oOutputPage->addHtml($oExceptionView->execute());
     }
 }