/**
	 * check if $page belongs to $category
	 * @param $page Title current page
	 * @param $category String category to check (not a title object!)
	 * @param $parser Parser
	 * @return boolean If $page is a member of $category
	 */
	private static function inCat( Title $page, $category, Parser $parser ) {
		if ( $category === '' ) return false;
		$catTitle = Title::makeTitleSafe(
			NS_CATEGORY,
			$category
		);
		if ( !$catTitle ) return false;
		$catDBkey = $catTitle->getDBkey();

		if ( !isset( $parser->pageInCat_cache ) ) {
			$parser->pageInCat_cache = array();
		} else {
			if ( isset( $parser->pageInCat_cache[$catDBkey] ) ) {
				# been there done that, return cached value
				return $parser->pageInCat_cache[$catDBkey];
			} elseif( isset( $parser->pageInCat_onlyCache ) && $parser->pageInCat_onlyCache ) {
				# All categories have been preloaded into cache, so
				# we must have hit a cat not in page.
				# Mark it so can be checked for correctness later.
				$parser->PageInCat_cache[$catDBkey] = false;
				return false;
			}
		}

		$pageId = $page->getArticleId();
		if ( !$pageId ) {
			// page hasn't yet been saved (preview)
			// add to the cache list so the other hook
			// will warn about incorrect value.
			// Important to do this after checking cache
			// in case categories were pre-loaded during preview.
			$parser->pageInCat_cache[$catDBkey] = false;
			return false;
		}

		if ( !$parser->incrementExpensiveFunctionCount() ) {
			# expensive function limit reached.
			return false;
		}

		if ( self::inCatCheckDb( $pageId, $catDBkey ) ) {
			$parser->pageInCat_cache[$catDBkey] = true;
			return true;
		} /* else if false */

		$parser->pageInCat_cache[$catDBkey] = false;
		return false;
	}
 /**
  * Execute the ParserFunction and throws exceptions if needed
  * 
  * @param array $arguments Array of strings
  * @return string output for parser
  * @throws \MWException Internal errors + user errors
  */
 public function tryExecute($arguments)
 {
     // if the limit has been exceeded, output is an error message
     // an additional warning message is displayed in page edit mode
     if (!$this->parser->incrementExpensiveFunctionCount()) {
         return 'Expensive function count error.';
     }
     // initializes
     $this->declareParameters();
     // tries to set parameters by name
     $arguments_without_name = $this->trySetParametersByName($arguments);
     // tries to set parameters by order
     $this->trySetParametersByOrder($arguments_without_name);
     // check all parameters (required, ...)
     $this->validate();
     // returns the output
     return $this->getOutputForParser();
 }
 /**
  * Returns the sources of any cascading protection acting on a specified page.
  * Pages will not return their own title unless they transclude themselves.
  * This is an expensive parser function and can't be called too many times per page,
  * unless cascading protection sources for the page have already been loaded.
  *
  * @param Parser $parser
  * @param string $title
  *
  * @return string
  * @since 1.23
  */
 public static function cascadingsources($parser, $title = '')
 {
     $titleObject = Title::newFromText($title);
     if (!$titleObject instanceof Title) {
         $titleObject = $parser->mTitle;
     }
     if ($titleObject->areCascadeProtectionSourcesLoaded() || $parser->incrementExpensiveFunctionCount()) {
         $names = [];
         $sources = $titleObject->getCascadeProtectionSources();
         foreach ($sources[0] as $sourceTitle) {
             $names[] = $sourceTitle->getPrefixedText();
         }
         return implode($names, '|');
     }
     return '';
 }