Exemplo n.º 1
0
 /**
  * This method handles embedded content protection.
  * Must be set onto ArticleSaveComplete hook AFTER articleSaveComplete_SaveSD
  * in order to handle newly created page SDs.
  */
 public static function articleSaveComplete_SaveEmbedded(&$article, &$user, $text)
 {
     // Flag to prevent recursion
     static $InsideSaveEmbedded;
     if ($InsideSaveEmbedded) {
         return true;
     }
     $InsideSaveEmbedded = true;
     global $wgRequest, $wgOut, $haclgContLang, $wgUser;
     $isACL = $article->getTitle()->getNamespace() == HACL_NS_ACL;
     if ($isACL) {
         $articleSD = IACLDefinition::newFromTitle($article->getTitle(), false);
         if (!$articleSD || $articleSD['pe_type'] != IACL::PE_PAGE) {
             // This is not a page SD, do nothing.
             return true;
         }
     } else {
         // FIXME possibly use the category SD for category pages
         //       the problem here is that in ACL editor two different SDs
         //       may be created and queried for embedded content:
         //       for category article and for category itself
         $articleSD = IACLDefinition::getSDForPE(IACL::PE_PAGE, $article->getId());
         if (!$articleSD) {
             return true;
         }
     }
     // Handle embedded content protection
     $errors = array();
     foreach ($wgRequest->getValues() as $k => $v) {
         if (substr($k, 0, 7) == 'sd_emb_' && $v) {
             $wgRequest->setVal($k, false);
             // clear value to handle embedded content only one time
             $emb_pe_id = intval(substr($k, 7));
             $emb_title = Title::newFromId($emb_pe_id);
             list($req_sd_type, $req_sd_id, $emb_sd_revid) = explode('-', $v, 3);
             if ($emb_title) {
                 $emb_sd_title = Title::newFromText(IACLDefinition::nameOfSD(IACL::PE_PAGE, $emb_title));
                 $emb_sd_article = new WikiPage($emb_sd_title);
             }
             // Check for errors:
             if (!$emb_title || !$emb_title->getArticleId() || !$emb_sd_title->userCan('edit')) {
                 // Embedded content deleted || Manage access denied
                 $errors[] = array($emb_title, 'canedit');
             } elseif ($req_sd_type && $req_sd_id && "{$req_sd_type}-{$req_sd_id}" != $articleSD['key']) {
                 // Invalid SD requested for protection
                 $errors[] = array($emb_title, 'invalidsd');
             } elseif (!$emb_sd_revid && $emb_sd_title->exists() || $emb_sd_revid && $emb_sd_title->getLatestRevId() != $emb_sd_revid) {
                 // Mid-air collision: SD created/changed by someone in the meantime
                 $errors[] = array($emb_title, 'midair');
             } else {
                 // Save embedded element SD
                 $emb_sd_article->doEdit('{{#predefined right: ' . $articleSD['def_title'] . '}}', wfMsg('hacl_comment_protect_embedded', '' . $articleSD['def_title']), EDIT_FORCE_BOT);
             }
         }
     }
     // Display errors to the user, if any
     // This is safe to do as we are definitely in interactive non-batch edit mode
     if ($errors) {
         foreach ($errors as &$e) {
             $e = "[[:" . $e[0]->getPrefixedText() . "]] (" . wfMsg('hacl_embedded_error_' . $e[1]) . ")";
         }
         $wgOut->setTitle(Title::newFromText('Special:IntraACL'));
         $wgOut->addWikiText(wfMsgNoTrans('hacl_embedded_not_saved', implode(", ", $errors), $article->getTitle()->getPrefixedText()));
         $wgOut->setPageTitle(wfMsg('hacl_embedded_not_saved_title'));
         $wgOut->output();
         // FIXME terminate MediaWiki more correctly
         wfGetDB(DB_MASTER)->commit();
         exit;
     }
     // Clear flag and continue hook processing
     $InsideSaveEmbedded = false;
     return true;
 }