/** * Generates a target name from the given target name formula * * This parses the formula and replaces <unique number> tags * * @param type $targetNameFormula * * @throws MWException * @return type */ protected function generateTargetName($targetNameFormula) { $targetName = $targetNameFormula; // prepend a super-page, if one was specified if ($this->getRequest()->getCheck('super_page')) { $targetName = $this->getRequest()->getVal('super_page') . '/' . $targetName; } // prepend a namespace, if one was specified if ($this->getRequest()->getCheck('namespace')) { $targetName = $this->getRequest()->getVal('namespace') . ':' . $targetName; } // replace "unique number" tag with one that won't get erased by the next line $targetName = preg_replace('/<unique number(.*)>/', '{num\\1}', $targetName, 1); // if any formula stuff is still in the name after the parsing, just remove it // FIXME: This is wrong. If anything is still left, something should have been present in the form and wasn't. An error should be raised. //$targetName = StringUtils::delimiterReplace( '<', '>', '', $targetName ); // replace spaces back with underlines, in case a magic word or parser // function name contains underlines - hopefully this won't cause // problems of its own $targetName = str_replace(' ', '_', $targetName); // now run the parser on it global $wgParser; $targetName = $wgParser->transformMsg($targetName, ParserOptions::newFromUser(null)); $titleNumber = ''; $isRandom = false; $randomNumHasPadding = false; $randomNumDigits = 6; if (preg_match('/{num.*}/', $targetName, $matches) && strpos($targetName, '{num') !== false) { // Random number if (preg_match('/{num;random(;(0)?([1-9][0-9]*))?}/', $targetName, $matches)) { $isRandom = true; $randomNumHasPadding = array_key_exists(2, $matches); $randomNumDigits = array_key_exists(3, $matches) ? $matches[3] : $randomNumDigits; $titleNumber = SFUtils::makeRandomNumber($randomNumDigits, $randomNumHasPadding); } else { if (preg_match('/{num.*start[_]*=[_]*([^;]*).*}/', $targetName, $matches)) { // get unique number start value // from target name; if it's not // there, or it's not a positive // number, start it out as blank if (count($matches) == 2 && is_numeric($matches[1]) && $matches[1] >= 0) { // the "start" value" $titleNumber = $matches[1]; } } else { if (preg_match('/^(_?{num.*}?)*$/', $targetName, $matches)) { // the target name contains only underscores and number fields, // i.e. would result in an empty title without the number set $titleNumber = '1'; } else { $titleNumber = ''; } } } // set target title $targetTitle = Title::newFromText(preg_replace('/{num.*}/', $titleNumber, $targetName)); // if the specified target title is invalid, give up if (!$targetTitle instanceof Title) { throw new MWException(wfMessage('sf_autoedit_invalidtargetspecified', trim(preg_replace('/<unique number(.*)>/', $titleNumber, $targetNameFormula)))->parse()); } // If title exists already, cycle through numbers for // this tag until we find one that gives a nonexistent // page title. // We cannot use $targetTitle->exists(); it does not use // Title::GAID_FOR_UPDATE, which is needed to get // correct data from cache; use // $targetTitle->getArticleID() instead. $numAttemptsAtTitle = 0; while ($targetTitle->getArticleID(Title::GAID_FOR_UPDATE) !== 0) { $numAttemptsAtTitle++; if ($isRandom) { // If the set of pages is "crowded" // already, go one digit higher. if ($numAttemptsAtTitle > 20) { $randomNumDigits++; } $titleNumber = SFUtils::makeRandomNumber($randomNumDigits, $randomNumHasPadding); } elseif ($titleNumber == "") { $titleNumber = 2; } else { $titleNumber = str_pad($titleNumber + 1, strlen($titleNumber), '0', STR_PAD_LEFT); } $targetTitle = Title::newFromText(preg_replace('/{num.*}/', $titleNumber, $targetName)); } $targetName = $targetTitle->getPrefixedText(); } return $targetName; }