Converts a node to an XPath query

@param VariableSet $variableSet
@param FactVariableBinding $factVariableBinding
@return string
357015
public function toQuery( $variableSet, $factVariableBinding )
	{
		$result = parent::toQuery( $variableSet, $factVariableBinding );
		$query = "(" . implode( " or ", $result ) . ")";
		if ( $this->complement )
		{
			$query = "not{$query}";
		}
		return $query;
	}
221510
public static function getDimensionsInContext( $variableSet, $context )
	{
		$result = array();

		if ( isset( $context['segment'] ) )
		{
			$result = array_merge( $result, FactValues::processSegmentForExplicitDimensions( $variableSet, $context['segment'] ) );
			$result = array_merge( $result, FactValues::processSegmentForTypedDimensions( $variableSet, $context['segment'] ) );
		}

		if ( isset( $context['scenario'] ) )
		{
			$result = array_merge( $result, FactValues::processSegmentForExplicitDimensions( $variableSet, $context['scenario'] ) );
			$result = array_merge( $result, FactValues::processSegmentForTypedDimensions( $variableSet, $context['scenario'] ) );
		}

		$entity = $context['entity'];

		if ( isset( $entity['segment'] ) )
		{
			$result = array_merge( $result, FactValues::processSegmentForExplicitDimensions( $variableSet, $entity['segment'] ) );
			$result = array_merge( $result, FactValues::processSegmentForTypedDimensions( $variableSet, $entity['segment'] ) );
		}

		if ( isset( $entity['scenario'] ) )
		{
			$result = array_merge( $result, FactValues::processSegmentForExplicitDimensions( $variableSet, $entity['scenario'] ) );
			$result = array_merge( $result, FactValues::processSegmentForTypedDimensions( $variableSet, $entity['scenario'] ) );
		}

		return $result;
	}
474120
public static function getDimensionsInContextRef( $variableSet, $contextRef )
	{
		if ( ! $contextRef ) return array();
		$context = $variableSet->xbrlInstance->getContext( $contextRef );
		if ( ! $context ) return array();
		return FactValues::getDimensionsInContext( $variableSet, $context );
	}
685077
public function xpath($query, DOMNode $contextNode = null)
    {
        return $this->getXpath()->query($query, $contextNode);
    }
711012
public function Filter( $facts, $variableSet )
	{
		// If the filter is being used in a boolean filter or there is a qname expresssion then return the input facts
		if ( $this->inBoolean || $this->qnameExpressions ) return $facts;

		if ( ! $this->qnames ) return $facts;

		$matched = array();
		$notMatched = array();
		foreach ( $facts as /** @var XPathNavigator $fact */ $fact )
		{
			$clark = "{{$fact->getNamespaceURI()}}{$fact->getLocalName()}";

			if ( in_array( $clark, $this->qnames ) )
			{
				$matched[] = $fact->CloneInstance();
			}
			else
			{
				$notMatched[] = $fact->CloneInstance();
			}
		}

		return DocumentOrderNodeIterator::fromItemset( $this->complement ? $notMatched : $matched );
	}
1197653
private function validateFilters( $taxonomy, $arcRole, &$variable, $variableSet )
	{
		// Find all filter arcs related to this variable
		$variableFilterArcs = $taxonomy->getGenericArc( $arcRole, $variable->extendedLinkRoleUri, $variable->label, $variable->path, null, $variable->linkbase );

		if ( ! $variableFilterArcs ) return true;

		// Find the filter resources
		$filterResources = array();

		// BMS 2018-06-29 Changed this function so the arc for loop is on the outside so it can take advantage of indexing of the resource collections
		// $result = $taxonomy->getGenericResource( 'filter', null, function( $roleUri, $linkbase, $variableSetName, $index, $resource ) use( &$filterResources, $variableFilterArcs )
		// {
		// 	foreach ( $variableFilterArcs as $arcIndex => $variableFilterArc )
		// 	{
		// 		if ( $roleUri == $variableFilterArc['toRoleUri'] )
		// 		if ( $variableSetName == $variableFilterArc['label'] )
		// 		{
		// 			$resource['linkbase'] = $linkbase;
		// 			if ( $variableFilterArc['attributes'] )
		// 			{
		// 				foreach ( $variableFilterArc['attributes'] as $name => $attribute )
		// 				{
		// 					// BMS 2018-04-09 Test candidates changed.
		// 					$value = $attribute['type'] == "xs:boolean"
		// 						? (bool)$attribute['value']
		// 						: $attribute['value'];
		// 					$resource[ $name ] = $value;
		// 				}
		// 			}
		// 			$filterResources[ $variableSetName ][] = $resource;
		// 		}
		// 	}
		// 	return true;
		// } );

		foreach ( $variableFilterArcs as $arcIndex => $variableFilterArc )
		{
			if ( $variable->path == $variableFilterArc['frompath'] )
			$result = $taxonomy->getGenericResource( 'filter', null, function( $roleUri, $linkbase, $variableSetName, $index, $resource ) use( &$filterResources, $variableFilterArc )
			{
				// Don't believe this is necessary as $variableSetName is $variableFilterArc['label']
				// if ( $variableSetName = $variableFilterArc['label'] )
				if ( $resource['path'] != $variableFilterArc['topath'] /* || $linkbase != $variableFilterArc['linkbase'] */ ) return true;

				$resource['linkbase'] = $linkbase;
				if ( $variableFilterArc['attributes'] )
				{
					foreach ( $variableFilterArc['attributes'] as $name => $attribute )
					{
						// BMS 2018-04-09 Test candidates changed.
						$value = $attribute['type'] == "xs:boolean"
							? (bool)$attribute['value']
							: $attribute['value'];
						$resource[ $name ] = $value;
					}
				}
				$filterResources[ $variableSetName ][] = $resource;

				return true;
			}, $variableFilterArc['toRoleUri'], $variableFilterArc['to'], $variableFilterArc['tolinkbase'] );
		}

		foreach ( $filterResources as $variableFilterLabel => $filterResourceSet )
		{
			foreach ( $filterResourceSet as $filterResource )
			{
				// if ( $variable->path != $filterResource['path'] ) continue;

				// If this is a group filter make sure the arc is not covering
				if ( $arcRole == XBRL_Constants::$arcRoleVariableSetFilter )
				{
					if ( isset( $filterResource['cover'] ) && $filterResource['cover'] )
					{
						$this->log->formula_validation( "Filter", "Group filters MUST not cover",
							array(
								'filter type' => $filterResource['filterType'],
								'label' => $filterResource['label'],
								'error' => 'lyquidity:variableSetFilterCovered',
							)
						);
					}
				}

				// Create the filter instance
				$filterClassName = '\\XBRL\\Formulas\\Resources\\' .
					Formulas::$formulaElements[ $filterResource['filterType'] ]['part'] .
					( isset( Formulas::$formulaElements[ $filterResource['filterType'] ]['className'] )
						? Formulas::$formulaElements[ $filterResource['filterType'] ]['className']
						: ucfirst( $filterResource['filterType'] )
					);

				if ( is_null( $filterClassName ) )
				{
					$this->log->formula_validation( "Filter", "Invalid filter type",
						array(
							'Filter type' => $resource['filterType'],
						)
					);
					return false;
				}

				if ( $variableSet->aspectModel == "non-dimensional" &&
					 in_array( $filterResource['filterType'], array( 'explicitDimension', 'typedDimension' ) )
				)
				{
					$this->log->formula_validation( "Filter", "Dimension filters not allowed when using the non-dimensional aspect model",
						array(
							'aspect model' => $variableSet->aspectModel,
							'filter type' => $filterResource['filterType'],
							'label' => $filterResource['label'],
							'error' => 'xbrlve:filterAspectModelMismatch',
						)
					);
				}
				else if ( $variableSet->aspectModel == "dimensional" &&
					      in_array( $filterResource['filterType'], array( 'scenario', 'segment' ) )
				)
				{
					$this->log->formula_validation( "Filter", "Non-dimensional filters not allowed when using the dimensional aspect model",
						array(
							'aspect model' => $variableSet->aspectModel,
							'filter type' => $filterResource['filterType'],
							'label' => $filterResource['label'],
							'error' => 'xbrlve:filterAspectModelMismatch',
						)
					);
				}

				/** @var \XBRL\Formulas\Resources\Filters\Filter $filter */
				$filter = $filterClassName::fromArray( $filterResource );

				if ( ! $filter->validate( $variableSet, $this->nsMgr ) )
				{
					return false;
				}

				// If this is a group filter then make sure the filter does not reference any
				if ( $arcRole == XBRL_Constants::$arcRoleVariableSetFilter )
				{
					// There should be no variable refs
					$refs = $filter->getVariableRefs();
					if ( $refs )
					{
						foreach ( $refs as $refQName )
						{
							if ( isset( $variableSet->variablesByQName[ $refQName->clarkNotation() ] ) )
							{
								$this->log->formula_validation( "Group Filter", "Variable references are not allowed from group filters",
									array(
										'reference' => $refQName->clarkNotation(),
										'filter' => $filter->label,
										'variable set' => $variableSet->label,
										'error' => 'xbrlve:factVariableReferenceNotAllowed',
									)
								);
							}
						}
					}
				}

				$variable->addFilter( $filter );
			}
		}

		return true;

		// // Return applying any filters
		// return $arcRole == XBRL_Constants::$arcRoleVariableSetFilter
		// 	? true
		// 	: $this->validateAspectCovers( $taxonomy, $variable );
	}
346962
def xpathVariableLookupNS(self, name, ns_uri):
        
        ret = libxml2mod.xmlXPathVariableLookupNS(self._o, name, ns_uri)
        if ret is None:raise xpathError('xmlXPathVariableLookupNS() failed')
        return xpathObjectRet(ret)
1298705
private function validatePreconditions( $taxonomy, $variableSet )
	{
		$preconditionArcs = $taxonomy->getGenericArc( XBRL_Constants::$arcRoleVariableSetPrecondition, $variableSet->extendedLinkRoleUri, $variableSet->label, $variableSet->path, null, $variableSet->linkbase );
		if ( $preconditionArcs )
		{
			$element = "precondition";
			$preconditionClassName = '\\XBRL\\Formulas\\Resources\\' .
				Formulas::$formulaElements[ $element ]['part'] .
				( isset( Formulas::$formulaElements[ $element ]['className'] )
					? Formulas::$formulaElements[ $element ]['className']
					: ucfirst( $element )
				);

			$preconditionResources = array();
			// BMS 2018-06-29 Modified this loop to put the arcs on the outside so it can take advantage of the indexes on the resources collection
			// $taxonomy->getGenericResource( 'variable', $element, function( $roleUri, $linkbase, $variableSetName, $index, $resource ) use( $preconditionArcs, &$preconditionResources )
			// {
			// 	foreach ( $preconditionArcs as $preconditionArc )
			// 	{
			// 		if ( $roleUri == $preconditionArc['toRoleUri'] )
			// 		if ( $variableSetName == $preconditionArc['label'] )
			// 		{
			// 			$resource['linkbase'] = $linkbase;
			// 			$resource['linkRoleUri'] = $roleUri;
			// 			$preconditionResources[] = $resource;
			// 		}
			// 	}
			// 	return true;
			// } );

			foreach ( $preconditionArcs as $preconditionArc )
			{
				if ( $variableSet->path != $preconditionArc['frompath'] ) continue;
				$taxonomy->getGenericResource( 'variable', $element, function( $roleUri, $linkbase, $variableSetName, $index, $resource ) use( $preconditionArc, &$preconditionResources )
				{
					// This test is probably redundant because I believe $variableSetName is the same as $variableSetArc['label']
					// if ( $variableSetName == $preconditionArc['label'] )
					if ( $resource['path'] == $preconditionArc['topath'] /* || $linkbase == $preconditionArc['linkbase'] */ )
					{
						$resource['linkbase'] = $linkbase;
						$resource['linkRoleUri'] = $roleUri;
						$preconditionResources[] = $resource;
					}

					return true;
				}, $preconditionArc['toRoleUri'], $preconditionArc['to'], $preconditionArc['tolinkbase'] );
			}

			if ( ! $preconditionResources )
			{
				$this->log->formula_validation( "Precondition", "The source precondition for formula resource cannot be located",
					array(
						'formula' => $variableSet->label,
					)
				);

				return false;
			}

			foreach ( $preconditionResources as $preconditionResource )
			{
				/** @var Precondition $precondition */
				$precondition = $preconditionClassName::fromArray( $preconditionResource );
				$precondition->extendedLinkRoleUri = $preconditionResource['linkRoleUri'];
				if ( ! $precondition->validate( $variableSet, $this->nsMgr ) )
				{
					return false;
				}

				$variableSet->preconditions[ "{$precondition->extendedLinkRoleUri}#{$precondition->label}" ] = $precondition;
			}
		}

		return true;
	}
826585
public function toQuery( $variableSet, $factVariableBinding )
	{
		$clauses = array();

		// Include the qnames if being called as part of a boolean filter or there are qname expressions
		if ( $this->inBoolean || $this->qnameExpressions )
		foreach ( $this->qnames as $clark )
		{
			$qname = qname( $clark );
			$clauses[] = "(fn:node-name(.) eq fn:QName('{$qname->namespaceURI}','{$qname->localName}'))";
		}

		foreach ( $this->qnameExpressions as $qnameExpression )
		{
			$clauses[] = "(fn:node-name(.) eq $qnameExpression)";
		}

		if ( ! $clauses )
		{
			return null;
		}

		$query = implode( " or ", $clauses );
		return count( $clauses ) > 1 ? "($query)" : $query;
	}
561864
private function ExtractVariables(\DOMDocument $document, $namespace = "")
    {
        $xpath = new DOMXPath($document);

        $entries = $xpath->evaluate(
            "//compound[@kind='file'] | //compound[@kind='namespace']", 
            $document
        );

        for($i = 0; $i < $entries->length; $i++)
        {
            $kind = $entries->item($i)->getAttribute("kind");
            $refid = $entries->item($i)->getAttribute("refid");
            $name = $entries->item($i)->childNodes->item(0)->nodeValue;

            if($kind == "namespace")
                $namespace = str_replace("::", "\\", $name);
            else
                $namespace = "\\";

            $file_doc = new DOMDocument();
            $file_doc->load($this->definitions_path . "/$refid.xml");

            $file_xpath = new DOMXPath($file_doc);

            $file_members = $file_xpath->evaluate(
                "//memberdef[@kind='variable']", 
                $file_doc
            );

            for($member = 0; $member < $file_members->length; $member++)
            {
                $location = str_replace(
                    $this->headers_path, 
                    "", 
                    str_replace(
                        "\\", 
                        "/", 
                        $file_xpath->evaluate(
                            "location", 
                            $file_members->item($member)
                        )->item(0)->getAttribute("file")
                    )
                );

                $global_variable_name = $file_xpath->evaluate(
                    "name", 
                    $file_members->item($member)
                )->item(0)->nodeValue;
                
                $global_variable_type = $file_xpath->evaluate(
                    "type", 
                    $file_members->item($member)
                )->item(0)->nodeValue;
                
                $global_variable_description = $file_xpath->evaluate(
                    "briefdescription", 
                    $file_members->item($member)
                )->item(0)->nodeValue;

                $variable = new \Peg\Lib\Definitions\Element\GlobalVariable(
                    $global_variable_name, 
                    str_replace(
                        array(" *", " &"), 
                        array("*", "&"), 
                        $global_variable_type
                    ),
                    $global_variable_description
                );
                
                $this->symbols->AddGlobalVar($variable, $location, $namespace);
            }
        }
    }
114820
public function toSQL($parseBindings = true) {
        $sql = $this->sql;
        if ($parseBindings && !empty($this->bindings)) {
            $sql = $this->xpdo->parseBindings($sql, $this->bindings);
        }
        return $sql;
    }
565319
private XpathPayloadVariableExtractor getXpathVariableExtractor() {
        if (xpathExtractor == null) {
            xpathExtractor = new XpathPayloadVariableExtractor();

            getAction().getVariableExtractors().add(xpathExtractor);
        }

        return xpathExtractor;
    }
332503
public function toQuery( $variableSet, $factVariableBinding )
	{
		$expressions = array();

		// Include the qnames if being called as part of a boolean filter or there are qname expressions
		if ( $this->inBoolean || $this->qnameExpressions )
		foreach ( $this->qnames as $qname )
		{
			$name = qname( $qname );
			$expressions[] = "(fn:node-name(..) eq fn:QName('{$name->namespaceURI}','{$name->localName}'))";
		}

		foreach ( $this->qnameExpressions as $qnameExpression )
		{
			$expressions[] = "(fn:node-name(..) eq {$qnameExpression})";
		}

		return implode( " or ", $expressions );
	}
8159
public function getVariableProperty($variableId, $property)
    {
        list($itemUri, $propertyName) = $this->extractResultVariableProperty($variableId);
        $response =  $this->unserializeVariableValue(
            $this->getPersistence()->hGet(
                self::PREFIX_CALL_ID.$itemUri,
                $propertyName
            )
        );
        $variable = unserialize($response[0]->variable);

        $getter = 'get'.ucfirst($property);
        if (method_exists($variable, $getter)) {
            return $variable->$getter();
        }

        return '';
    }
712884
public function getValue( $variableSet, $evaluationResult, $log )
	{
		$sourceFact = $this->getSourceFact( $variableSet, $evaluationResult, $log );
		if ( ! $sourceFact )
		{
			$log->formula_validation( "Concept aspect rule", "No valid concept can be located",
				array(
					'source' => $this->qname
									? (string)(new QName( $this->qname['originalPrefix'], $this->qname['namespace'], $this->qname['name']) )
									: $this->qnameExpression,
					'error' => 'xbrlfe:missingConceptRule'
				)
			);
			return null;
		}

		return $sourceFact;
	}
1204220
private function evaluate( $variableSet )
	{
		if ( ! $this->canEvaluate ) return;
		if ( isset( $variableSet->evaluated ) ) return true;

		// Process the variables in hierarchy order
		// $variableSet->parameters =& $this->parameterQnames;
		$variableSet->nsMgr = $this->nsMgr;
		$variableSet->xbrlInstance = $this->instances[ $this->instanceQName->clarkNotation() ];
		if ( $variableSet->evaluate() )
		{
			// If the variable set is a formula then add a facts container
			if ( $variableSet instanceof Formula )
			{
				if ( is_null( $this->formulaFactsContainer ) ) $this->formulaFactsContainer = new GeneratedFacts();
				$variableSet->factsContainer = $this->formulaFactsContainer;
			}

			$variableSet->ProcessEvaluationResult( $this->log );

			// If the variable set is a formula recover the facts container
			if ( $variableSet instanceof Formula )
			{
				// This is probably redundant because the container instance will be passed to the variable set by reference
				$this->formulaFactsContainer = $variableSet->factsContainer;
			}
		}

		$variableSet->evaluated = true;

		return true;
	}
44984
public function getAspectsCovered( $variableSet, $factVariableBinding )
	{
		// Unusually, this implementation will updat the binding directly
		$covered = array();

		if ( isset( $this->aspects['all'] ) )
		{
			$covered = is_null( $factVariableBinding )
				? array_values( Formula::$aspectCoversMap )
				: $factVariableBinding->aspectsDefined;

			$pos = array_search( ASPECT_DIMENSIONS, $covered );
			if ( $pos !== false )
			{
				unset( $covered[ $pos ] );
			}
			if ( $factVariableBinding )
			{
				$covered = array_unique( array_merge( $covered, array_diff( $covered, $factVariableBinding->aspectsCovered ) ) );
			}
		}
		else
		{
			$covered = array_keys( $this->aspects );
			if ( in_array( ASPECT_DIMENSIONS, $covered ) )
			{
				$pos = array_search( ASPECT_DIMENSIONS, $covered );
				if ( $pos !== false )
				{
					unset( $covered[ $pos ] );
				}

				if ( $factVariableBinding )
				{
					$dimensions = array_diff( $factVariableBinding->aspectsDefined, array_values( Formula::$aspectCoversMap ) );
					$covered = array_merge( $covered, $dimensions );
				}
			}
			else
			{
				if ( isset( $this->dimensions['qname'] ) )
				foreach( $this->dimensions['qname'] as $includedKey => $dimension )
				{
					if ( in_array( $dimension, $covered ) ) continue;
					$covered[] = $dimension;
				}

				if ( isset( $this->dimensions['qnameExpression'] ) )
				foreach( $this->dimensions['qnameExpression'] as $includedKey => $dimensionExpression )
				{
					try
					{
						$dimension = CoreFuncs::Atomize( $this->evaluateXPath( $variableSet, $dimensionExpression ) );
						if ( $dimension instanceof QNameValue )
						{
							$dimension = "{{$dimension->NamespaceUri}}{$dimension->LocalName}";
						}
						if ( in_array( $dimension, $covered ) ) continue;
						$covered[] = $dimension;
					}
					catch ( \Exception $ex )
					{
						$x = 1;
					}
				}
			}
		}

		// Handle any excluded dimensions
		if ( isset( $this->excludedDimensions['qname'] ) )
		foreach( $this->excludedDimensions['qname'] as $includedKey => $dimension )
		{
			$pos = array_search( $dimension, $covered );
			if ( $pos === false ) continue;
			unset( $covered[ $pos ] );
		}

		if ( isset( $this->excludedDimensions['qnameExpression'] ) )
		foreach( $this->excludedDimensions['qnameExpression'] as $includedKey => $dimensionExpression )
		{
			try
			{
				$dimension = CoreFuncs::Atomize( $this->evaluateXPath( $variableSet, $dimensionExpression ) );
				if ( $dimension instanceof QNameValue )
				{
					$dimension = "{{$dimension->NamespaceUri}}{$dimension->LocalName}";
				}
				$pos = array_search( $dimension, $covered );
				if ( $pos === false ) continue;
				unset( $covered[ $pos ] );
			}
			catch ( \Exception $ex )
			{
				$x = 1;
			}
		}

		// Add the the values in $covered to the binding
		if ( $factVariableBinding )
		{
			$factVariableBinding->aspectsCovered = array_unique(
				$this->cover
					? array_merge( $factVariableBinding->aspectsCovered, $covered )
					: array_diff( $factVariableBinding->aspectsCovered, $covered )
			);
		}

		return $covered;
	}