Get calculated cell value

@deprecated		Since version 1.7.8 for planned changes to cell for array formula handling

@param	boolean $resetLog  Whether the calculation engine logger should be reset or not
@return	mixed
@throws	PHPExcel_Exception
348001
public function getCalculatedValue($resetLog = TRUE)
	{
//echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL;
		if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) {
			try {
//echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL;
				$result = PHPExcel_Calculation::getInstance(
					$this->getWorksheet()->getParent()
				)->calculateCellValue($this,$resetLog);
//echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL;
				//	We don't yet handle array returns
				if (is_array($result)) {
					while (is_array($result)) {
						$result = array_pop($result);
					}
				}
			} catch ( PHPExcel_Exception $ex ) {
				if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) {
//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL;
					return $this->_calculatedValue; // Fallback for calculations referencing external files.
				}
//echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL;
				$result = '#N/A';
				throw new PHPExcel_Calculation_Exception(
					$this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage()
				);
			}

			if ($result === '#Not Yet Implemented') {
//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL;
				return $this->_calculatedValue; // Fallback if calculation engine does not support the formula.
			}
//echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL;
			return $result;
		} elseif($this->_value instanceof PHPExcel_RichText) {
//		echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'<br />';
			return $this->_value->getPlainText();
		}
//		echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'<br />';
		return $this->_value;
	}
581519
public function getColumnValueRaw($record, $column)
    {
        $columnName = $column->columnName;

        /*
         * Handle taking value from model relation.
         */
        if ($column->valueFrom && $column->relation) {
            $columnName = $column->relation;

            if (!array_key_exists($columnName, $record->getRelations())) {
                $value = null;
            }
            elseif ($this->isColumnRelated($column, true)) {
                $value = $record->{$columnName}->lists($column->valueFrom);
            }
            elseif ($this->isColumnRelated($column) || $this->isColumnPivot($column)) {
                $value = $record->{$columnName}
                    ? $column->getValueFromData($record->{$columnName})
                    : null;
            }
            else {
                $value = null;
            }
        }
        /*
         * Handle taking value from model attribute.
         */
        elseif ($column->valueFrom) {
            $value = $column->getValueFromData($record);
        }
        /*
         * Otherwise, if the column is a relation, it will be a custom select,
         * so prevent the Model from attempting to load the relation
         * if the value is NULL.
         */
        else {
            if ($record->hasRelation($columnName) && array_key_exists($columnName, $record->attributes)) {
                $value = $record->attributes[$columnName];
            // Load the value from the relationship counter if useRelationCount is specified
            } elseif ($column->relation && @$column->config['useRelationCount']) {
                $value = $record->{"{$column->relation}_count"};
            } else {
                $value = $record->{$columnName};
            }
        }

        /**
         * @event backend.list.overrideColumnValueRaw
         * Overrides the raw column value in a list widget.
         *
         * If a value is returned from this event, it will be used as the raw value for the provided column.
         * `$value` is passed by reference so modifying the variable in place is also supported. Example usage:
         *
         *     Event::listen('backend.list.overrideColumnValueRaw', function($listWidget, $record, $column, &$value) {
         *         $value .= '-modified';
         *     });
         *
         * Or
         *
         *     $listWidget->bindEvent('list.overrideColumnValueRaw', function ($record, $column, $value) {
         *         return 'No values for you!';
         *     });
         *
         */
        if ($response = $this->fireSystemEvent('backend.list.overrideColumnValueRaw', [$record, $column, &$value])) {
            $value = $response;
        }

        return $value;
    }
138575
public static function log( $log ) {
	
		if ( ! self::is_debug() ) {
			return;
		}

		if ( is_bool( $log ) ) {
			$log = $log ? 'true' : 'false';
		}

		/**
		 * __FILE__
		 * __LINE__
		 * https://stackoverflow.com/questions/1252529/get-code-line-and-file-thats-executing-the-current-function-in-php
		 */
		$bt = debug_backtrace();
		$caller = array_shift( $bt );

		error_log( print_r( $caller['file'] . ' Line: ' . $caller['line'], true ) );
		error_log( print_r( $log, true ) );

		// if ( is_array( $log ) || is_object( $log ) ) {
		//  error_log( print_r( $log, true ) );
		// } else {
		//  error_log( $log );
		// }

	}
140390
public static function COUNTBLANK()
    {
        $returnValue = 0;

        // Loop through arguments
        $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());
        foreach ($aArgs as $arg) {
            // Is it a blank cell?
            if ((is_null($arg)) || ((is_string($arg)) && ($arg == ''))) {
                ++$returnValue;
            }
        }

        return $returnValue;
    }
827813
public function ProcessEvaluationResult( $log )
	{
		$countSatisfied = count( $this->satisfied );
		$countNotSatisfied = count( $this->notSatisfied );
		$vars = array_map( function( $param ) { return $param->result; }, $this->parameters );
		$provider = new XPath2ItemProvider( XPath2Item::fromValue( $countSatisfied ) );

		if ( ! $this->test )
		{
			$this->success = $countSatisfied > 0 || $countNotSatisfied > 0;
			$message = $this->success ? "succeeded" : "failed";
			// \XBRL_Log::getInstance()->info("Existence assertion result for '{$this->label}' $message: There are {$countSatisfied} satisfied and {$countNotSatisfied} not satisfied existence evaluations." );
			\XBRL_Log::getInstance()->formula_evaluation(
				"Existence assertion",
				"Result for '{$this->id} ($this->linkbase)' $message: There are {$countSatisfied} satisfied and {$countNotSatisfied} not satisfied existence evaluations.",
				array(
					'formula' => $this->label,
					'state' => $message,
					'countSatisfied' => $countSatisfied,
					'countNotSatisfied' => $countNotSatisfied
				)
			);
		}
		else
		{
			$result = CoreFuncs::BooleanValue( $this->evaluateXPathExpression( $this, $this->testXPath2Expression, $vars, null, $provider ) );
			$this->success = $result instanceof CoreFuncs::$True;
			$message = $this->success ? "succeeded" : "failed";

			$evaluationResult = array( 'vars' => $vars, 'lastFactBinding' => array(), 'uncoveredAspectFacts' => array() );

			$this->satisfied = $this->success ? array( $evaluationResult ) : array();
			$this->notSatisfied = $this->success ? array() : array( $evaluationResult );
			$countSatisfied = count( $this->satisfied );
			$countNotSatisfied = count( $this->notSatisfied );
			// \XBRL_Log::getInstance()->info("Existence assertion result for '{$this->label}' with test expression $message: There are {$countSatisfied} satisfied and {$countNotSatisfied} not satisfied existence evaluations." );
			\XBRL_Log::getInstance()->formula_evaluation(
				"Existence assertion",
				"Result for '{$this->id} ($this->linkbase)' with test expression $message: There are {$countSatisfied} satisfied and {$countNotSatisfied} not satisfied existence evaluations.",
				array(
					'formula' => $this->label,
					'state' => $message,
					'countSatisfied' => $countSatisfied,
					'countNotSatisfied' => $countNotSatisfied,
					'test' => $this->test
				)
			);
		}

		// This can be used by message exressions
		$vars[ "{{$this->namespace}}test-expression" ] = $this->test;

		if ( $this->success )
		{
			$this->generatedSatisifiedMessages = $this->processMessages( $this->satisfiedMessages, $vars, $provider );
		}
		else
		{
			$this->generatedUnsatisifiedMessages = $this->processMessages( $this->unsatisfiedMessages, $vars, $provider );
		}
	}
895625
public function getHyperlink()
	{
		if (!isset($this->_parent)) {
			throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet');
		}

		return $this->getWorksheet()->getHyperlink($this->getCoordinate());
	}
1195886
public function specEnd($log = null)
    {
        $isOk = $log->passed() ? "ok" : "not ok";

        switch ($log->type()) {
            case 'skipped':
            case 'pending':
            case 'excluded':
                $prefix = "# {$log->type()} ";
                break;
            default:
                $prefix = '- ';
                break;
        }
        $message = $prefix . trim(implode(" ", $log->messages()));
        $this->_counter++;

        $this->write("{$isOk} {$this->_counter} {$message}\n");

        if ($exception = $log->exception()) {
            $this->write('# Exception: `' . get_class($exception) .'` Code(' . $exception->getCode() . '):' . "\n");
            $this->write('# Message: ' . $exception->getMessage() . "\n");
        } else {
            foreach ($log->children() as $log) {
                if ($log->passed()) {
                    continue;
                }
                $toString = function ($instance) {
                    return 'an instance of `' . get_class($instance) . '`';
                };
                foreach ($log->data() as $key => $value) {
                    $key = ucfirst($key);
                    $value = Text::toString($value, ['object' => ['method' => $toString]]);
                    $this->write("# {$key}: {$value}\n");
                }
            }
        }
    }
980522
public function getCell($pCoordinate = 'A1')
    {
        // Check cell collection
        if ($this->_cellCollection->isDataSet($pCoordinate)) {
            return $this->_cellCollection->getCacheData($pCoordinate);
        }

        // Worksheet reference?
        if (strpos($pCoordinate, '!') !== false) {
            $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);
			return $this->_parent->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]);
        }

        // Named range?
        if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&
            (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {
            $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);
            if ($namedRange !== NULL) {
                $pCoordinate = $namedRange->getRange();
                return $namedRange->getWorksheet()->getCell($pCoordinate);
            }
        }

        // Uppercase coordinate
        $pCoordinate = strtoupper($pCoordinate);

        if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) {
            throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.');
        } elseif (strpos($pCoordinate, '$') !== false) {
            throw new PHPExcel_Exception('Cell coordinate must not be absolute.');
        }

        // Create new cell object
        return $this->_createNewCell($pCoordinate);
    }
655598
private function _parseFormula($formula, PHPExcel_Cell $pCell = null)
    {
        if (($formula = $this->convertMatrixReferences(trim($formula))) === false) {
            return false;
        }

        //    If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),
        //        so we store the parent worksheet so that we can re-attach it when necessary
        $pCellParent = ($pCell !== null) ? $pCell->getWorksheet() : null;

        $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION.
                               '|'.self::CALCULATION_REGEXP_CELLREF.
                               '|'.self::CALCULATION_REGEXP_NUMBER.
                               '|'.self::CALCULATION_REGEXP_STRING.
                               '|'.self::CALCULATION_REGEXP_OPENBRACE.
                               '|'.self::CALCULATION_REGEXP_NAMEDRANGE.
                               '|'.self::CALCULATION_REGEXP_ERROR.
                             ')/si';

        //    Start with initialisation
        $index = 0;
        $stack = new PHPExcel_Calculation_Token_Stack;
        $output = array();
        $expectingOperator = false;                    //    We use this test in syntax-checking the expression to determine when a
                                                    //        - is a negation or + is a positive operator rather than an operation
        $expectingOperand = false;                    //    We use this test in syntax-checking the expression to determine whether an operand
                                                    //        should be null in a function call
        //    The guts of the lexical parser
        //    Loop through the formula extracting each operator and operand in turn
        while (true) {
//echo 'Assessing Expression '.substr($formula, $index), PHP_EOL;
            $opCharacter = $formula{$index};    //    Get the first character of the value at the current index position
//echo 'Initial character of expression block is '.$opCharacter, PHP_EOL;
            if ((isset(self::$comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$comparisonOperators[$formula{$index+1}]))) {
                $opCharacter .= $formula{++$index};
//echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL;
            }

            //    Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand
            $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match);
//echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL;
//var_dump($match);

            if ($opCharacter == '-' && !$expectingOperator) {                //    Is it a negation instead of a minus?
//echo 'Element is a Negation operator', PHP_EOL;
                $stack->push('Unary Operator', '~');                            //    Put a negation on the stack
                ++$index;                                                    //        and drop the negation symbol
            } elseif ($opCharacter == '%' && $expectingOperator) {
//echo 'Element is a Percentage operator', PHP_EOL;
                $stack->push('Unary Operator', '%');                            //    Put a percentage on the stack
                ++$index;
            } elseif ($opCharacter == '+' && !$expectingOperator) {            //    Positive (unary plus rather than binary operator plus) can be discarded?
//echo 'Element is a Positive number, not Plus operator', PHP_EOL;
                ++$index;                                                    //    Drop the redundant plus symbol
            } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) {    //    We have to explicitly deny a tilde or pipe, because they are legal
                return $this->raiseFormulaError("Formula Error: Illegal character '~'");                //        on the stack but not in the input expression

            } elseif ((isset(self::$operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) {    //    Are we putting an operator on the stack?
//echo 'Element with value '.$opCharacter.' is an Operator', PHP_EOL;
                while ($stack->count() > 0 &&
                    ($o2 = $stack->last()) &&
                    isset(self::$operators[$o2['value']]) &&
                    @(self::$operatorAssociativity[$opCharacter] ? self::$operatorPrecedence[$opCharacter] < self::$operatorPrecedence[$o2['value']] : self::$operatorPrecedence[$opCharacter] <= self::$operatorPrecedence[$o2['value']])) {
                    $output[] = $stack->pop();                                //    Swap operands and higher precedence operators from the stack to the output
                }
                $stack->push('Binary Operator', $opCharacter);    //    Finally put our current operator onto the stack
                ++$index;
                $expectingOperator = false;

            } elseif ($opCharacter == ')' && $expectingOperator) {            //    Are we expecting to close a parenthesis?
//echo 'Element is a Closing bracket', PHP_EOL;
                $expectingOperand = false;
                while (($o2 = $stack->pop()) && $o2['value'] != '(') {        //    Pop off the stack back to the last (
                    if ($o2 === null) {
                        return $this->raiseFormulaError('Formula Error: Unexpected closing brace ")"');
                    } else {
                        $output[] = $o2;
                    }
                }
                $d = $stack->last(2);
                if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) {    //    Did this parenthesis just close a function?
                    $functionName = $matches[1];                                        //    Get the function name
//echo 'Closed Function is '.$functionName, PHP_EOL;
                    $d = $stack->pop();
                    $argumentCount = $d['value'];        //    See how many arguments there were (argument count is the next value stored on the stack)
//if ($argumentCount == 0) {
//    echo 'With no arguments', PHP_EOL;
//} elseif ($argumentCount == 1) {
//    echo 'With 1 argument', PHP_EOL;
//} else {
//    echo 'With '.$argumentCount.' arguments', PHP_EOL;
//}
                    $output[] = $d;                        //    Dump the argument count on the output
                    $output[] = $stack->pop();            //    Pop the function and push onto the output
                    if (isset(self::$controlFunctions[$functionName])) {
//echo 'Built-in function '.$functionName, PHP_EOL;
                        $expectedArgumentCount = self::$controlFunctions[$functionName]['argumentCount'];
                        $functionCall = self::$controlFunctions[$functionName]['functionCall'];
                    } elseif (isset(self::$PHPExcelFunctions[$functionName])) {
//echo 'PHPExcel function '.$functionName, PHP_EOL;
                        $expectedArgumentCount = self::$PHPExcelFunctions[$functionName]['argumentCount'];
                        $functionCall = self::$PHPExcelFunctions[$functionName]['functionCall'];
                    } else {    // did we somehow push a non-function on the stack? this should never happen
                        return $this->raiseFormulaError("Formula Error: Internal error, non-function on stack");
                    }
                    //    Check the argument count
                    $argumentCountError = false;
                    if (is_numeric($expectedArgumentCount)) {
                        if ($expectedArgumentCount < 0) {
//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount), PHP_EOL;
                            if ($argumentCount > abs($expectedArgumentCount)) {
                                $argumentCountError = true;
                                $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount);
                            }
                        } else {
//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount, PHP_EOL;
                            if ($argumentCount != $expectedArgumentCount) {
                                $argumentCountError = true;
                                $expectedArgumentCountString = $expectedArgumentCount;
                            }
                        }
                    } elseif ($expectedArgumentCount != '*') {
                        $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch);
//print_r($argMatch);
//echo PHP_EOL;
                        switch ($argMatch[2]) {
                            case '+':
                                if ($argumentCount < $argMatch[1]) {
                                    $argumentCountError = true;
                                    $expectedArgumentCountString = $argMatch[1].' or more ';
                                }
                                break;
                            case '-':
                                if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) {
                                    $argumentCountError = true;
                                    $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3];
                                }
                                break;
                            case ',':
                                if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) {
                                    $argumentCountError = true;
                                    $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3];
                                }
                                break;
                        }
                    }
                    if ($argumentCountError) {
                        return $this->raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected");
                    }
                }
                ++$index;

            } elseif ($opCharacter == ',') {            //    Is this the separator for function arguments?
//echo 'Element is a Function argument separator', PHP_EOL;
                while (($o2 = $stack->pop()) && $o2['value'] != '(') {        //    Pop off the stack back to the last (
                    if ($o2 === null) {
                        return $this->raiseFormulaError("Formula Error: Unexpected ,");
                    } else {
                        $output[] = $o2;    // pop the argument expression stuff and push onto the output
                    }
                }
                //    If we've a comma when we're expecting an operand, then what we actually have is a null operand;
                //        so push a null onto the stack
                if (($expectingOperand) || (!$expectingOperator)) {
                    $output[] = array('type' => 'NULL Value', 'value' => self::$excelConstants['NULL'], 'reference' => null);
                }
                // make sure there was a function
                $d = $stack->last(2);
                if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) {
                    return $this->raiseFormulaError("Formula Error: Unexpected ,");
                }
                $d = $stack->pop();
                $stack->push($d['type'], ++$d['value'], $d['reference']);    // increment the argument count
                $stack->push('Brace', '(');    // put the ( back on, we'll need to pop back to it again
                $expectingOperator = false;
                $expectingOperand = true;
                ++$index;

            } elseif ($opCharacter == '(' && !$expectingOperator) {
//                echo 'Element is an Opening Bracket<br />';
                $stack->push('Brace', '(');
                ++$index;

            } elseif ($isOperandOrFunction && !$expectingOperator) {    // do we now have a function/variable/number?
                $expectingOperator = true;
                $expectingOperand = false;
                $val = $match[1];
                $length = strlen($val);
//                echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />';

                if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) {
                    $val = preg_replace('/\s/u', '', $val);
//                    echo 'Element '.$val.' is a Function<br />';
                    if (isset(self::$PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$controlFunctions[strtoupper($matches[1])])) {    // it's a function
                        $stack->push('Function', strtoupper($val));
                        $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch);
                        if ($ax) {
                            $stack->push('Operand Count for Function '.strtoupper($val).')', 0);
                            $expectingOperator = true;
                        } else {
                            $stack->push('Operand Count for Function '.strtoupper($val).')', 1);
                            $expectingOperator = false;
                        }
                        $stack->push('Brace', '(');
                    } else {    // it's a var w/ implicit multiplication
                        $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => null);
                    }
                } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) {
//                    echo 'Element '.$val.' is a Cell reference<br />';
                    //    Watch for this case-change when modifying to allow cell references in different worksheets...
                    //    Should only be applied to the actual cell column, not the worksheet name

                    //    If the last entry on the stack was a : operator, then we have a cell range reference
                    $testPrevOp = $stack->last(1);
                    if ($testPrevOp['value'] == ':') {
                        //    If we have a worksheet reference, then we're playing with a 3D reference
                        if ($matches[2] == '') {
                            //    Otherwise, we 'inherit' the worksheet reference from the start cell reference
                            //    The start of the cell range reference should be the last entry in $output
                            $startCellRef = $output[count($output)-1]['value'];
                            preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches);
                            if ($startMatches[2] > '') {
                                $val = $startMatches[2].'!'.$val;
                            }
                        } else {
                            return $this->raiseFormulaError("3D Range references are not yet supported");
                        }
                    }

                    $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val);
//                    $expectingOperator = FALSE;
                } else {    // it's a variable, constant, string, number or boolean
//                    echo 'Element is a Variable, Constant, String, Number or Boolean<br />';
                    //    If the last entry on the stack was a : operator, then we may have a row or column range reference
                    $testPrevOp = $stack->last(1);
                    if ($testPrevOp['value'] == ':') {
                        $startRowColRef = $output[count($output)-1]['value'];
                        $rangeWS1 = '';
                        if (strpos('!', $startRowColRef) !== false) {
                            list($rangeWS1, $startRowColRef) = explode('!', $startRowColRef);
                        }
                        if ($rangeWS1 != '') {
                            $rangeWS1 .= '!';
                        }
                        $rangeWS2 = $rangeWS1;
                        if (strpos('!', $val) !== false) {
                            list($rangeWS2, $val) = explode('!', $val);
                        }
                        if ($rangeWS2 != '') {
                            $rangeWS2 .= '!';
                        }
                        if ((is_integer($startRowColRef)) && (ctype_digit($val)) &&
                            ($startRowColRef <= 1048576) && ($val <= 1048576)) {
                            //    Row range
                            $endRowColRef = ($pCellParent !== null) ? $pCellParent->getHighestColumn() : 'XFD';    //    Max 16,384 columns for Excel2007
                            $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef;
                            $val = $rangeWS2.$endRowColRef.$val;
                        } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) &&
                            (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) {
                            //    Column range
                            $endRowColRef = ($pCellParent !== null) ? $pCellParent->getHighestRow() : 1048576;        //    Max 1,048,576 rows for Excel2007
                            $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1';
                            $val = $rangeWS2.$val.$endRowColRef;
                        }
                    }

                    $localeConstant = false;
                    if ($opCharacter == '"') {
//                        echo 'Element is a String<br />';
                        //    UnEscape any quotes within the string
                        $val = self::wrapResult(str_replace('""', '"', self::unwrapResult($val)));
                    } elseif (is_numeric($val)) {
//                        echo 'Element is a Number<br />';
                        if ((strpos($val, '.') !== false) || (stripos($val, 'e') !== false) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {
//                            echo 'Casting '.$val.' to float<br />';
                            $val = (float) $val;
                        } else {
//                            echo 'Casting '.$val.' to integer<br />';
                            $val = (integer) $val;
                        }
                    } elseif (isset(self::$excelConstants[trim(strtoupper($val))])) {
                        $excelConstant = trim(strtoupper($val));
//                        echo 'Element '.$excelConstant.' is an Excel Constant<br />';
                        $val = self::$excelConstants[$excelConstant];
                    } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$localeBoolean)) !== false) {
//                        echo 'Element '.$localeConstant.' is an Excel Constant<br />';
                        $val = self::$excelConstants[$localeConstant];
                    }
                    $details = array('type' => 'Value', 'value' => $val, 'reference' => null);
                    if ($localeConstant) {
                        $details['localeValue'] = $localeConstant;
                    }
                    $output[] = $details;
                }
                $index += $length;

            } elseif ($opCharacter == '$') {    // absolute row or column range
                ++$index;
            } elseif ($opCharacter == ')') {    // miscellaneous error checking
                if ($expectingOperand) {
                    $output[] = array('type' => 'NULL Value', 'value' => self::$excelConstants['NULL'], 'reference' => null);
                    $expectingOperand = false;
                    $expectingOperator = true;
                } else {
                    return $this->raiseFormulaError("Formula Error: Unexpected ')'");
                }
            } elseif (isset(self::$operators[$opCharacter]) && !$expectingOperator) {
                return $this->raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'");
            } else {    // I don't even want to know what you did to get here
                return $this->raiseFormulaError("Formula Error: An unexpected error occured");
            }
            //    Test for end of formula string
            if ($index == strlen($formula)) {
                //    Did we end with an operator?.
                //    Only valid for the % unary operator
                if ((isset(self::$operators[$opCharacter])) && ($opCharacter != '%')) {
                    return $this->raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands");
                } else {
                    break;
                }
            }
            //    Ignore white space
            while (($formula{$index} == "\n") || ($formula{$index} == "\r")) {
                ++$index;
            }
            if ($formula{$index} == ' ') {
                while ($formula{$index} == ' ') {
                    ++$index;
                }
                //    If we're expecting an operator, but only have a space between the previous and next operands (and both are
                //        Cell References) then we have an INTERSECTION operator
//                echo 'Possible Intersect Operator<br />';
                if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) &&
                    ($output[count($output)-1]['type'] == 'Cell Reference')) {
//                    echo 'Element is an Intersect Operator<br />';
                    while ($stack->count() > 0 &&
                        ($o2 = $stack->last()) &&
                        isset(self::$operators[$o2['value']]) &&
                        @(self::$operatorAssociativity[$opCharacter] ? self::$operatorPrecedence[$opCharacter] < self::$operatorPrecedence[$o2['value']] : self::$operatorPrecedence[$opCharacter] <= self::$operatorPrecedence[$o2['value']])) {
                        $output[] = $stack->pop();                                //    Swap operands and higher precedence operators from the stack to the output
                    }
                    $stack->push('Binary Operator', '|');    //    Put an Intersect Operator on the stack
                    $expectingOperator = false;
                }
            }
        }

        while (($op = $stack->pop()) !== null) {    // pop everything off the stack and push onto output
            if ((is_array($op) && $op['value'] == '(') || ($op === '(')) {
                return $this->raiseFormulaError("Formula Error: Expecting ')'");    // if there are any opening braces on the stack, then braces were unbalanced
            }
            $output[] = $op;
        }
        return $output;
    }
1291116
public function getCompiledUpdate(string $table='', bool $reset=TRUE): string
	{
		return $this->_getCompile('update', $table, $reset);
	}
112408
final public function count($table = '', $resetselect = true)
    {

        if (!empty($table)) {
            $this->traceTableAlias($table);
            $this->fromTable($table);
        }
        $sql = $this->compile($this->_countString . $this->identifiers('totalcount'), true);
        $statement = $this->DBO->prepare($sql);

        $results = $statement->execute();

        if ($resetselect) $this->resetSelect();
        if ($results->rowCount() == 0) return '0';

        $row = $results->fetchObject();

        return $row->totalcount;
    }
302374
public function ProcessEvaluationResult( $log )
	{
		global $debug_statements;

		if ( $debug_statements )
		{
			\XBRL_Log::getInstance()->info( "Output instance document ({$this->label})" );
		}

		// Any additional namespaces
		if ( ! $this->factsContainer->namespaces )
		{
			$this->factsContainer->namespaces = $this->xbrlInstance->getInstanceNamespaces();
		}
		$namespaces =& $this->factsContainer->namespaces;

		$taxonomy = $this->xbrlTaxonomy;
		$primaryItems = $taxonomy->getDefinitionPrimaryItems( false );

		foreach ( $this->evaluationResults as $evaluationResultGUID => $evaluationResult )
		{
			// Only use results generated by this variable set.  Other results may exist added as a result of a scope variable arc.
			if ( isset( $evaluationResult['variableSet'] ) && $evaluationResult['variableSet'] != $this->label ) continue;

			// Clear any previous value
			$primaryItemRoles = null;

			if ( $evaluationResult['result'] instanceof XPath2NodeIterator )
			{
				$count = $evaluationResult['result']->getCount();
				if ( $count > 1 )
				{
					$log->formula_validation( "Formula", "The formula result is not a single value",
						array(
							'formula' => $this->label,
							'error' => 'xbrlfe:nonSingletonOutputValue'
						)
					);
				}

				if ( $count == 0 )
				{
					$evaluationResult['result'] = Undefined::getValue();
				}
				else
				{
					$evaluationResult['result']->rewind();
					$evaluationResult['result'] = $evaluationResult['result']->getCurrent()->getValue();
				}
			}

			// Source evaluation has to be done within the context of a
			// produced fact because the source may reference a variable

			// Use the concept aspect flag in case the formula source is formula:uncovered
			// If there is no valid source an exception will be thrown
			$sourceFact = $this->getSourceFact( $this->source, $evaluationResult, ASPECT_CONCEPT, \XBRL_Log::getInstance() );

			$contextRef = null;
			if ( $sourceFact )
			{
				// Get the context ref from the source
				$contextRef = FactValues::getContextRef( $sourceFact );
			}
			else
			{
				// Use the context ref of one of the formula variables
				$variableRefs = $this->getVariableRefs();
				foreach ( $variableRefs as $variableRef )
				{
					$contextFact = $this->getSourceFact( $variableRef, $evaluationResult, ASPECT_CONCEPT, \XBRL_Log::getInstance() );
					// As well as being null the returned context fact could be aN XPath2Item (fallback value)
					if ( ! $contextFact ) continue;
					if ( $contextFact instanceof XPath2NodeIterator )
					{
						$clone = $contextFact->CloneInstance();
						$clone->Reset();
						if ( $clone->MoveNext() )
						{
							$contextFact = $clone->getCurrent();
						}
					}
					if ( ! $contextFact instanceof DOMXPathNavigator ) continue;

					$contextRef = FactValues::getContextRef( $contextFact );
					break;
				}
			}

			// Get the unit ref from the source
			// $unitRef = FactValues::getUnitRef( $sourceFact );

			// Get the context of the formula source fact
			$orginalContext = $contextRef ? $this->xbrlInstance->getContext( $contextRef ) : array();

			// Get the concept RAV
			$conceptQName = $this->getConceptAspectQName( $sourceFact, $evaluationResult, $log );

			// Get the entity identifier RAV
			$entityIdentifier = $this->getEntityIdentifierAspectValue( $this->source, $evaluationResult, $log );

			// Get the location RAV
			$locationQName = $this->getLocationAspect( $this->source, $evaluationResult, $log );

			// Get the period RAV
			$period = $this->getPeriodAspectValue( $this->source, $evaluationResult, $log );

			// Get the scenario RAV
			$componentType = 'scenario';
			foreach ( Formula::$componentPaths as $componentPath )
			{
				if ( ! in_array( $componentType, $componentPath ) ) continue;
				$this->scenariosComponentPath = $componentPath;
				$scenarios = $this->getComponentAspectValue( $this->source, $this->aspectModel == 'dimensional' ? ASPECT_NON_XDT_SCENARIO : ASPECT_COMPLETE_SCENARIO, $componentType, $evaluationResult, $log );
				if ( $scenarios ) break;
			}

			// Get the segment RAV
			$componentType = 'segment';
			foreach ( Formula::$componentPaths as $componentPath )
			{
				if ( ! in_array( $componentType, $componentPath ) ) continue;
				$this->segmentsComponentPath = $componentPath;
				$segments = $this->getComponentAspectValue( $this->source, $this->aspectModel == 'dimensional' ? ASPECT_NON_XDT_SEGMENT : ASPECT_COMPLETE_SEGMENT, $componentType, $evaluationResult, $log );
				if ( $segments ) break;
			}

			$contextDimensions = array();
			$elementTaxonomy = $taxonomy->getTaxonomyForNamespace( $conceptQName->namespaceURI );
			$conceptElement = $elementTaxonomy->getElementByName( $conceptQName->localName );

			if ( $this->aspectModel == 'dimensional' )
			{
				// Remove any XDT components from the segments and scenarios list
				unset( $scenarios['explicitMember'] );
				unset( $scenarios['typedMember'] );
				unset( $segments['explicitMember'] );
				unset( $segments['typedMember'] );

				$conceptPrimaryItemId = "{$elementTaxonomy->getTaxonomyXSD()}#{$conceptElement['id']}";
				$contextDimensions = array();
				$typedDimensions = array();
				// Only need to process these if the target concept is a primary item
				if ( isset( $primaryItems[ $conceptPrimaryItemId ] ) )
				{
					$primaryItemRoles = $taxonomy->getPrimaryItemDRS( $primaryItems[ $conceptPrimaryItemId ]);

					// Record if ANY of the hyercubes linked to the primary item are not closed
					$isClosed = true;

					// Get a list of all the possoble explicit dimensions
					$explicitTaxonomyDimensions = array();
					$typedTaxonomyDimensions = array();

					foreach ( $primaryItemRoles as $HypercubeId => $roles )
					{
						foreach ( $roles as $roleUri => $details )
						{
							$contextElement = $details['parents'][ $conceptPrimaryItemId ]['contextElement'];

							if ( ! $details['parents'][ $conceptPrimaryItemId ]['closed'] )
							{
								$isClosed = false;
							}

							foreach ( $details['dimensions'] as $dimensionId => $dimension )
							{
								// Get the element
								$dimTaxonomy = $taxonomy->getTaxonomyForXSD( $dimensionId );
								$dimElement = $dimTaxonomy->getElementById( $dimensionId );
								$dimQName = new QName( null, $dimTaxonomy->getNamespace(), $dimElement['name'] );
								if ( ! isset( $dimension['explicit'] ) || $dimension['explicit'] )
								{
									$explicitTaxonomyDimensions[ $dimQName->clarkNotation() ] = $isClosed;
								}
								else
								{
									$typedTaxonomyDimensions[ $dimQName->clarkNotation() ] = $isClosed;
								}
							}
						}
					}

					// $explicitTaxonomyDimensions = array_unique( $explicitTaxonomyDimensions );
					// $typedTaxonomyDimensions = array_unique( $typedTaxonomyDimensions );

					$aspectsDefinedDimensions = array_reduce( $evaluationResult['defined'],
						function( $carry, $aspectsDefined ) {
							return array_unique( array_merge( $carry, array_filter( $aspectsDefined, function( $aspect ) { return $aspect[0] != '\\'; } ) ) );
						}, array() );

					foreach ( $aspectsDefinedDimensions as $aspectsDefinedDimension )
					{
						// Look to see if the aspect defined dimension is defined as a hypercube dimension
						if ( isset( $explicitTaxonomyDimensions[ $aspectsDefinedDimension ] ) ||
							 isset( $typedTaxonomyDimensions[ $aspectsDefinedDimension ] ) )
						{
							// It is so nothing to do
							continue;
						}

						if ( $isClosed )
						{
							// Can't warn here because a scenario is that there is a context dimension to be removed
						}

						// It's not so get the element find out if the dimension is typed or explicit
						$dimensionQName = qname( $aspectsDefinedDimension );
						$dimTaxonomy = $taxonomy->getTaxonomyForNamespace( $dimensionQName->namespaceURI );
						$dimElement = $dimTaxonomy->getElementByName( $dimensionQName->localName );
						if ( isset( $dimElement['typedDomainRef'] ) )
						{
							$typedTaxonomyDimensions[ $aspectsDefinedDimension ] = $isClosed;
						}
						else
						{
							$explicitTaxonomyDimensions[ $aspectsDefinedDimension ] = $isClosed;
						}
					}

					// This function has taken a lot of deliberation.  Here's a summary I'm writing in one of my less confused
					// moments. By this line $explicitTaxonomyDimensions will contain either a list of dimensions associated with
					// the hypercubes of the primary item and/or those which are uncovered dimensions.  A dimension is necessary
					// before calling getExplicitDimensionAspectValue() because this function and any rules is uses may need
					// to resolve the 'uncovered' QName if it is used as a rule source and this resolution will require the name
					// of an uncovered dimension.  As a result one of the following will be true.  If not, it means there will
					// be no OCC dimension values to worry about.
					//
					// 1) There are dimensions associated with the primary item hypercubes
					// 2) There are dimensions discovered and added to the 'aspectsDefined' list
					// 3) There are no dimensions but there is a rule that might add a dimension(*)
					//
					// These conditions are additive.  For example there may be hypercube dimensions and discovered dimensions
					// and one or more rules.
					// If there are no dimensions (hypercube or discovered) there may be one or more rules.  In this case
					// a dummy rule will be added to $explicitTaxonomyDimensions so the getExplicitDimensionAspectValue() will
					// be called.
					// Finally, there there is no information here about whether an exising uncovered dimension belongs to
					// a segment or scenario so definately not about whether the componet is a child of the entity node.
					// To handle this, the getExplicitDimensionAspectValue() may be called up to four times - once each for
					// the combinations of scenario/segment and entity/not entity child.
					//
					// These note apply equally to processing the $typedTaxonomyDimensions variable.

					if ( ! $explicitTaxonomyDimensions && $this->explicitDimensionRule )
					{
						// Add a dummy dimension so the rule(s) have chance to run
						$explicitTaxonomyDimensions[''] = $isClosed;
					}

					// BMS 2018-02-19 Updated to combine dimension results before validating them and their paths
					$dimensionsResult = array();
					// Get the explicit dimension RAV
					foreach ( $explicitTaxonomyDimensions as $dimension => $closed )
					foreach ( Formula::$componentPaths as $componentPath )
					{
						$componentType = in_array( "scenario", $componentPath ) ? 'scenario' : 'segment';

						// This class variable is used to pass component path information to the ExplicitDimension instance
						$this->explicitDimensionsComponentPath = $componentPath;
						$explicitDimensionsResult = $this->getExplicitDimensionAspectValue( $this->source, $componentPath, $evaluationResult, $dimension, $log );
						if ( $explicitDimensionsResult )
						{
							$dimensionsResult = array_merge( $dimensionsResult, $explicitDimensionsResult );
							// // Check the dimension(s) and primary item
							// // Chack is the segment/scenario path is consistent with the context element of the primary item
							// $componentPath = $this->validateContextDimensions( $taxonomy, $conceptPrimaryItemId, $explicitDimensionsResult, $primaryItemRoles, $componentPath );
							// $contextDimensions['explicitMember'][ $dimension ] = array(
							// 	'dimensions' => $explicitDimensionsResult,
							// 	'paths' => $componentPath
							// );
							break;
						}
					}

					if ( ! $typedTaxonomyDimensions && $this->typedDimensionRule )
					{
						// Add a dummy dimension so the rule(s) have chance to run
						$typedTaxonomyDimensions[''] = $isClosed;
					}

					// Get the typed dimension RAV
					foreach ( $typedTaxonomyDimensions as $dimension => $closed )
					foreach ( Formula::$componentPaths as $componentPath )
					{
						$componentType = in_array( "scenario", $componentPath ) ? 'scenario' : 'segment';

						// This class variable is used to pass component path information to the TypedDimension instance
						$this->typedDimensionsComponentPath = $componentPath;
						$typedDimensionsResult = $this->getTypedDimensionAspectValue( $this->source, $componentPath, $evaluationResult, $dimension, $log );
						if ( $typedDimensionsResult )
						{
							$dimensionsResult = array_merge( $dimensionsResult, $typedDimensionsResult );
							// // Check the dimension(s) and primary item
							// // Is the segment/scenario path is consistent with the context element of the primary item
							// $componentPath = $this->validateContextDimensions( $taxonomy, $conceptPrimaryItemId, $typedDimensionsResult, $primaryItemRoles, $componentPath );
							// $contextDimensions['typedMember'][ $dimension ] = array(
							// 	'dimensions' => $typedDimensionsResult,
							// 	'paths' => $componentPath
							// );
							break;
						}
					}

					// Check the dimension(s) and primary item
					$componentPath = $this->validateContextDimensionsAlt( $conceptPrimaryItemId, $dimensionsResult, $primaryItemRoles, $componentPath );
					$contextDimensions = array();
					foreach ( $dimensionsResult as $dimensionId => $members )
					{
						$qname = qname( $dimensionId, $this->nsMgr->getNamespaces() );
						$memberType = in_array( $qname->clarkNotation(), $this->typedDimensions ) ? 'typedMember' : 'explicitMember';
						if ( ! isset( $contextDimensions[ $memberType ][ $qname->clarkNotation() ] ) )
						{
							$contextDimensions[ $memberType ][ $qname->clarkNotation() ] = array(
								'dimensions' => array(),
								'paths' => $componentPath
							);
						}
						$contextDimensions[ $memberType ][ $qname->clarkNotation() ]['dimensions'] = array( $dimensionId => $members );
					}
				}
			}

			// Create a context
			$newContext = array();
			// Any additional namespaces
			// $namespaces = $this->xbrlInstance->getInstanceNamespaces();

			$addPath = function( $context, $path, $extra, $values )
			{
				$selected = &$context;
				foreach ( $path as $element )
				{
					if ( ! isset( $selected[ $element ] ) )
					{
						$selected[ $element ] = array();
					}

					$selected = &$selected[ $element ];
				}

				if ( $extra )
				{
					if ( ! isset( $selected[ $extra ] ) )
					{
						$selected[ $extra ] = array();
					}
					$selected = &$selected[ $extra ];
				}

				$selected = array_merge( $selected, $values );
				unset( $selected );

				return $context;
			};

			if ( $entityIdentifier )
			{
				$newContext['entity']['identifier'] = $entityIdentifier;
			}

			if ( $period )
			{
				$newContext['period'] = $period;
			}

			if ( $scenarios )
			{
				// Need to add the scenarios to the correct path
				$extra = $this->scenarioRule ? '' : '';
				$newContext = $addPath( $newContext, $this->scenariosComponentPath, $extra, $scenarios );
				// $newContext['scenario']['member'] = $scenarios;
			}

			if ( $segments )
			{
				// Need to add the segments to the correct path
				// BMS 2018-02-19 Conflict here between when an 'extra' value of member is needed and when not.
				// BMS 2018-03-22 I believe this issue is resolved.  An additional 'extra' value is not required.
				//				  See the note of the same date in getComponentAspectValue()
				//
				$extra = $this->segmentRule ? '' : '';
				$newContext = $addPath( $newContext, $this->segmentsComponentPath, $extra, $segments );
			}

			if ( $contextDimensions )
			{
				foreach ( $contextDimensions as $memberType => $dimensions )
				{
					foreach ( $dimensions as $aspectDimension => $details )
					{
						$paths = $details['paths'];
						$dimensions = Dimension::IndexToContext( $details['dimensions'] );
						$newContext = $addPath( $newContext, $paths, $memberType, $dimensions );
					}
				}
			}

			// $originalContextHash = $this->hashArray( $orginalContext );

			// A precautionary measure.  You know, just in case.
			if ( is_null( $this->factsContainer ) )
			{
				$this->factsContainer = new GeneratedFacts();
			}

			if ( ! $evaluationResult['isTuple'] )
			{
				$hash = $this->hashArray( $newContext );

				if ( isset( $this->factsContainer->contextHashes[ $hash['hash'] ] ) )
				{
					// Since it is equivalent to an existing context, use the existing context ref
					$contextRef = $this->factsContainer->contextHashes[ $hash['hash'] ];
				}
				else
				{
					if ( ! $contextRef )
					{
						$contextRef = "context";
					}

					if ( isset( $this->factsContainer->contexts[ $contextRef ] ) )
					{
						// The contextRef has been used but the hash is not the same
						// So generate a new context ref and carry on
						if ( isset( $this->factsContainer->contextRefIndexes[ $contextRef ] ) )
						{
							$index = $this->factsContainer->contextRefIndexes[ $contextRef ];
							$index++;
							$this->factsContainer->contextRefIndexes[ $contextRef ] = $index;
							$contextRef .= "-$index";
						}
						else
						{
							$index = 1;
							$this->factsContainer->contextRefIndexes[ $contextRef ] = $index;
							$contextRef .= "-$index";
						}
					}

					// // BMS 2018-04-04 Moved up
					// if ( ! $contextRef )
					// {
					// 	$contextRef = "context";
					// }

					$this->factsContainer->contextHashes[ $hash['hash'] ] = $contextRef;
					$this->factsContainer->contexts[ $contextRef ] = $newContext;
				}
			}

			// Create a fact
			$fact = array();

			// BMS 2018-04-01 Check to see if the qname namespace is a taxonomy
			$tax = $this->xbrlTaxonomy->getTaxonomyForNamespace( $conceptQName->namespaceURI );
			if ( $tax )
			{
				// Set the qname prefix
				$conceptQName->prefix = $tax->getPrefix();
			}

			// If this prefix does not exist in the namespace list add it.
			if ( ! isset( $namespaces[ $conceptQName->prefix ] ) )
			{
				$namespaces[ $conceptQName->prefix ] = $conceptQName->namespaceURI;
			}

			$fact['concept'] = $conceptQName;
			$fact['contextRef'] = $evaluationResult['isTuple'] ? null : $contextRef;

			if ( $evaluationResult['result'] instanceof Undefined )
			{
				$fact['value'] = null;
			}
			else if ( $evaluationResult['result'] instanceof DOMXPathNavigator )
			{
				$value = $evaluationResult['result']->getValue();
				$fact['value'] = ! $value && FactValues::isNull( $evaluationResult['result'] )
					? null
					: $value;
			}
			else
			{
				$fact['value'] = $evaluationResult['result'] instanceof XPath2Item || $evaluationResult['result'] instanceof DecimalValue
					  ? $evaluationResult['result']->getValue()
					  : ( $evaluationResult['result'] instanceof CoreFuncs::$False
					  		? "false"
					  		: ( $evaluationResult['result'] instanceof CoreFuncs::$True
					  				? 'true'
					  				: $evaluationResult['result']
					  		  )
						);
			}

			$unit = null;
			$typeIsNumeric = false;
			// BMS 2018-04-09 Extra test candidate not required any more but it doesn't hurt.
			if ( \XBRL_Types::getInstance()->resolvesToBaseType( $conceptElement['type'], array( 'xs:decimal', 'xsd:decimal' ) ) )
			{
				$typeIsNumeric = true;
				// Create a unit
				$unit = $this->getUnitAspectValue( $this->source, $evaluationResult, $log );
				$unitRule = Unit::fromArray( $this->unitRule );
				$namespaces = array_merge( $namespaces, $unitRule->getAdditionalNamespaces( $this, $evaluationResult ) );
			}

			if ( $typeIsNumeric && is_numeric( $fact['value'] ) )
			{
				if ( ! is_null( $this->precisionRule ) )
				{
					if ( is_numeric( $this->precisionRule ) )
					{
						$fact['precision'] = $this->precisionRule;
					}
					else
					{
						if ( ! $this->precisionRuleXPath )
						{
							$this->precisionRuleXPath = XPath2Expression::Compile( $this->precisionRule, $this->nsMgr );
						}

						$result = CoreFuncs::Atomize( $this->evaluateXPathExpression( $this, $this->precisionRuleXPath, $this->getParametersAsVars( $evaluationResult['vars'] ) ) );
						$fact['precision'] = $result instanceof XPath2Item
							? $result->getValue()
							: $result;
					}
				}
				else if ( ! is_null( $this->decimalsRule ) )
				{
					if ( is_numeric( $this->decimalsRule ) )
					{
						$fact['decimals'] = $this->decimalsRule;
					}
					else
					{
						if ( ! $this->decimalsRuleXPath )
						{
							$this->decimalsRuleXPath = XPath2Expression::Compile( $this->decimalsRule, $this->nsMgr );
						}

						$result = CoreFuncs::Atomize( $this->evaluateXPathExpression( $this, $this->decimalsRuleXPath, $this->getParametersAsVars( $evaluationResult['vars'] ) ) );
						$fact['decimals'] = $result instanceof XPath2Item
							? $result->getValue()
							: $result;
					}
				}
				else
				{
					// This is the default rule specified in the formula specification section 2.1.1.1 (last sentence).
					$fact['precision'] = "0";
				}

				if ( isset( $fact['decimals'] ) )
				{
					$fact['value'] = number_format( $fact['value'], $fact['decimals'] == INF || $fact['decimals'] == 'INF' ? null : $fact['decimals'], ".", "" );
				}
			}

			if ( $unit )
			{
				$hash = $this->hashArray( reset( $unit ) );
				if ( isset( $this->factsContainer->unitHashes[ $hash['hash'] ] ) )
				{
					// Since it is equivalent to an existing unit, use the existing unit ref
					$unitRef = $this->factsContainer->unitHashes[ $hash['hash'] ];
				}
				else
				{
					$unitRef = key( $unit );
					if ( isset( $this->factsContainer->units[ $unitRef ] ) )
					{
						// The unitRef has been used but the hash is not the same
						// So generate a new context ref and carry on
						if ( isset( $this->factsContainer->unitRefIndexes[ $unitRef ] ) )
						{
							$index = $this->factsContainer->unitRefIndexes[ $unitRef ];
							$index++;
							$this->factsContainer->unitRefIndexes[ $unitRef ] = $index;
							$unitRef .= "-$index";
						}
						else
						{
							$index = 1;
							$this->factsContainer->unitRefIndexes[ $unitRef ] = $index;
							$unitRef .= "-$index";
						}
					}

					$this->factsContainer->unitHashes[ $hash['hash'] ] = $unitRef;
					$this->factsContainer->units[ $unitRef ] = reset( $unit );
				}

				$fact['unitRef'] = $unitRef;
			}
			else
			{
				// If the fact is numeric then there MUST be a unit RAV
				if ( $typeIsNumeric && is_numeric( $fact['value'] ) )
				{
					$log->formula_validation( "Unit aspect", "No aspect for numeric fact",
						array(
							'formula' => $this->label,
							'error' => 'xbrlfe:missingUnitRule'
						)
					);
				}
			}

			// Copy over any tuple information
			if ( isset( $evaluationResult['tuple'] ) )
			{
				$fact['tuple'] = $evaluationResult['tuple'];
				$fact['parentTupleGUID'] = $evaluationResult['parentTupleGUID'];
			}

			$fact['isTuple'] = $evaluationResult['isTuple'];

			$this->factsContainer->facts[ $this->label ][ $evaluationResultGUID ] = $fact;
			$this->factsContainer->vars[ $this->label ][ $evaluationResultGUID ] = $evaluationResult['vars'];
			$this->factsContainer->sources[ $this->label ] = $this->conceptRule ? null : $sourceFact;
			// $this->factsContainer->namespaces = $namespaces;
		}
	}
809796
public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b)
    {
        if ($a->getRow() < $b->getRow()) {
            return -1;
        } elseif ($a->getRow() > $b->getRow()) {
            return 1;
        } elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) {
            return -1;
        } else {
            return 1;
        }
    }
121601
public function getFormattedValue()
	{
		return (string) PHPExcel_Style_NumberFormat::toFormattedString(
				$this->getCalculatedValue(),
				$this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex())
					->getNumberFormat()->getFormatCode()
			);
	}
44813
public static function getInstance(PHPExcel $workbook = NULL) {
		if ($workbook !== NULL) {
    		if (isset(self::$_workbookSets[$workbook->getID()])) {
    			return self::$_workbookSets[$workbook->getID()];
    		}
			return new PHPExcel_Calculation($workbook);
		}

		if (!isset(self::$_instance) || (self::$_instance === NULL)) {
			self::$_instance = new PHPExcel_Calculation();
		}

		return self::$_instance;
	}
778293
public function bindValue(PHPExcel_Cell $cell, $value = null)
    {
        // sanitize UTF-8 strings
        if (is_string($value)) {
            $value = PHPExcel_Shared_String::SanitizeUTF8($value);
        }

        // Find out data type
        $dataType = parent::dataTypeForValue($value);

        // Style logic - strings
        if ($dataType === PHPExcel_Cell_DataType::TYPE_STRING && !$value instanceof PHPExcel_RichText) {
            //    Test for booleans using locale-setting
            if ($value == PHPExcel_Calculation::getTRUE()) {
                $cell->setValueExplicit( TRUE, PHPExcel_Cell_DataType::TYPE_BOOL);
                return true;
            } elseif($value == PHPExcel_Calculation::getFALSE()) {
                $cell->setValueExplicit( FALSE, PHPExcel_Cell_DataType::TYPE_BOOL);
                return true;
            }

            // Check for number in scientific format
            if (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NUMBER.'$/', $value)) {
                $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                return true;
            }

            // Check for fraction
            if (preg_match('/^([+-]?)\s*([0-9]+)\s?\/\s*([0-9]+)$/', $value, $matches)) {
                // Convert value to number
                $value = $matches[2] / $matches[3];
                if ($matches[1] == '-') $value = 0 - $value;
                $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                // Set style
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getNumberFormat()->setFormatCode( '??/??' );
                return true;
            } elseif (preg_match('/^([+-]?)([0-9]*) +([0-9]*)\s?\/\s*([0-9]*)$/', $value, $matches)) {
                // Convert value to number
                $value = $matches[2] + ($matches[3] / $matches[4]);
                if ($matches[1] == '-') $value = 0 - $value;
                $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                // Set style
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getNumberFormat()->setFormatCode( '# ??/??' );
                return true;
            }

            // Check for percentage
            if (preg_match('/^\-?[0-9]*\.?[0-9]*\s?\%$/', $value)) {
                // Convert value to number
                $value = (float) str_replace('%', '', $value) / 100;
                $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                // Set style
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00 );
                return true;
            }

            // Check for currency
            $currencyCode = PHPExcel_Shared_String::getCurrencyCode();
            $decimalSeparator = PHPExcel_Shared_String::getDecimalSeparator();
            $thousandsSeparator = PHPExcel_Shared_String::getThousandsSeparator();
            if (preg_match('/^'.preg_quote($currencyCode).' *(\d{1,3}('.preg_quote($thousandsSeparator).'\d{3})*|(\d+))('.preg_quote($decimalSeparator).'\d{2})?$/', $value)) {
                // Convert value to number
                $value = (float) trim(str_replace(array($currencyCode, $thousandsSeparator, $decimalSeparator), array('', '', '.'), $value));
                $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                // Set style
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getNumberFormat()->setFormatCode(
                        str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE )
                    );
                return true;
            } elseif (preg_match('/^\$ *(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) {
                // Convert value to number
                $value = (float) trim(str_replace(array('$',','), '', $value));
                $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                // Set style
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE );
                return true;
            }

            // Check for time without seconds e.g. '9:45', '09:45'
            if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d$/', $value)) {
                // Convert value to number
                list($h, $m) = explode(':', $value);
                $days = $h / 24 + $m / 1440;
                $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                // Set style
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3 );
                return true;
            }

            // Check for time with seconds '9:45:59', '09:45:59'
            if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $value)) {
                // Convert value to number
                list($h, $m, $s) = explode(':', $value);
                $days = $h / 24 + $m / 1440 + $s / 86400;
                // Convert value to number
                $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                // Set style
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4 );
                return true;
            }

            // Check for datetime, e.g. '2008-12-31', '2008-12-31 15:59', '2008-12-31 15:59:10'
            if (($d = PHPExcel_Shared_Date::stringToExcel($value)) !== false) {
                // Convert value to number
                $cell->setValueExplicit($d, PHPExcel_Cell_DataType::TYPE_NUMERIC);
                // Determine style. Either there is a time part or not. Look for ':'
                if (strpos($value, ':') !== false) {
                    $formatCode = 'yyyy-mm-dd h:mm';
                } else {
                    $formatCode = 'yyyy-mm-dd';
                }
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getNumberFormat()->setFormatCode($formatCode);
                return true;
            }

            // Check for newline character "\n"
            if (strpos($value, "\n") !== FALSE) {
                $value = PHPExcel_Shared_String::SanitizeUTF8($value);
                $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING);
                // Set style
                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )
                    ->getAlignment()->setWrapText(TRUE);
                return true;
            }
        }

        // Not bound yet? Use parent...
        return parent::bindValue($cell, $value);
    }
181897
public function getRowsCount($offset, $count)
    {
        //check whether worksheet name is set or not
        if ($this->worksheetName == '')
            throw new Exception('Worksheet name not specified');
        $strURI = Product::$baseProductUri . '/cells/' . $this->getFileName() .
            '/worksheets/' . $this->worksheetName . '/cells/rows?offset=' . $offset . '&count=' . $count;
        $signedURI = Utils::sign($strURI);
        $responseStream = Utils::processCommand($signedURI, 'GET', '', '');
        $json = json_decode($responseStream);
        return $json->Rows->RowsCount;

    }