UnitsEntity.class.inc in Units of Measurement 7.2
Definition of UnitsEntity class.
File
includes/UnitsEntity.class.incView source
<?php
/**
* @file
* Definition of UnitsEntity class.
*/
/**
* Units of measurement entity class.
*/
class UnitsEntity extends Entity implements UnitsMathematicalExpression {
/**
* Decomposition mathematical expression of this unit of measurement.
*
* @var UnitsMathematicalExpressionWrapper
*/
public $decomposition;
/**
* Determine physical dimension of this mathematical expression.
*
* @return array
* Dimension array of this mathematical expression
*/
public function dimension() {
return is_object($this->decomposition) ? $this
->decompose()
->dimension() : array(
$this
->identifier() => 1,
);
}
/**
* Test whether this mathematical expression includes a dimensionless member.
*
* Whether this mathematical expression contains at least 1 dimensionless
* member.
*
* @return bool
* Whether this mathematical expression contains at least 1 dimensionless
* member
*/
public function containsDimensionlessMember() {
// TODO: should we simply return FALSE or we are to actually verify the
// dimension of this unit?
$dimension = $this
->dimension();
return empty($dimension);
}
/**
* Format a certain amount of quantity within this mathematical expression.
*
* @param float $quantity
* Quantity to be formatted
*
* @return UnitsMathematicalExpression
* Formatted quantity into this mathematical expression. Sometimes the
* mathematical expression itself must mutate in order to format the
* quantity. So the returned mathematical expression may not necessarily be
* the mathematical expression on which this method was invoked. For
* example, the expression "unit" would mutate into "1 * unit" in order to
* have a dimensionless member and therefore be able to format the $quantity
*/
public function formatQuantity($quantity) {
// We expand this unit into "1 * $this" so we have get a dimensionless
// member that can be formatted. In case this unit decomposes non-linearly,
// we use "quantity" operator instead of multiplication.
$operator = $this
->isLinear() ? 'multiply' : 'non_linear';
return units_mathematical_expression_operator_construct(units_get_operator($operator), new UnitsConstantMathematicalExpression(1), $this)
->formatQuantity($quantity);
}
/**
* Numerically evaluate this mathematical expression.
*
* @return float
* Numerical value of this mathematical expression
*/
public function evaluate() {
return is_object($this->decomposition) ? $this
->decompose()
->evaluate() : NULL;
}
/**
* Decompose (simplify) this mathematical expression.
*
* @return UnitsMathematicalExpression
* Decomposed (simplified) version of this mathematical expression
*/
public function decompose() {
if (is_object($this->decomposition)) {
return $this->decomposition
->getExpression()
->decompose();
}
return $this;
}
/**
* Create inverse decomposition mathematical expression.
*
* @return UnitsMathematicalExpression
* Inverse decomposition mathematical expression
*/
public function inverseDecompose() {
$decomposition = $this
->decompose();
if (!$this
->isLinear()) {
$straight_decomposition = $decomposition;
$decomposition = new UnitsConstantMathematicalExpression(UNITS_QUANTITY);
while (get_class($straight_decomposition) == 'UnitsMathematicalOperatorLinear') {
$operand1 = $straight_decomposition
->operand1();
$operand2 = $straight_decomposition
->operand2();
$operand_to_isolate = strpos($operand1
->toPostfix(), UNITS_QUANTITY) !== FALSE ? 1 : 2;
$decomposition = $straight_decomposition
->isolateOperand($decomposition, $operand_to_isolate);
$straight_decomposition = $operand_to_isolate == 1 ? $operand1 : $operand2;
}
}
return $decomposition;
}
/**
* Represent this mathematical expression in postfix notation.
*
* Represent this mathematical expression in postfix (reverse polish)
* notation.
*
* @param array $options
* Options regarding how to format this mathematical expression
*
* @return string
* Postfix (reverse polish) notation representation of this mathematical
* expression
*/
public function toPostfix($options = array()) {
return $this
->identifier();
}
/**
* Represent this mathematical expression in human-friendly infix notation.
*
* @param array $options
* Options regarding how to format this mathematical expression
*
* @return string
* Human-friendly formatted version of this mathematical expression taking
* into account provided $options
*/
public function toInfix($options = array()) {
return $this
->identifier();
}
/**
* Whether this expression is linearly decomposable.
*
* @return bool
* Whether this expression is linearly decomposable, i.e. its decomposition
* can be plugged in into another mathematical expression via multiplication
* without losing sense
*/
public function isLinear() {
$result = db_select('units_mathematical_expression_postfix', 'e')
->fields('e', array(
'value_string',
))
->condition('mathematical_expression_id', $this->decomposition_mathematical_expression_id)
->condition('type', UNITS_TOKEN_TYPE_CONSTANT)
->condition('value_string', UNITS_QUANTITY)
->execute();
return $result
->rowCount() == 0;
}
/**
* Save the mathematical expression into database.
*
* @param int $mathematical_expression_id
* If the ID of the mathematical expression is known, under which it should
* be saved, provide it here. Otherwise it will be generated automatically
* @param int $order
* Order of this member when the mathematical expression is written down in
* postfix notation. Primarily this argument is used for internal purposes
*
* @return int
* Mathematical expression ID under which this expression has been save in
* the database
*/
public function unitsMathematicalExpressionSave($mathematical_expression_id, &$order) {
if (!$mathematical_expression_id) {
// TODO: this should be possible to do as: INSERT INTO ... FROM SELECT ... thereby making unnecessary the transaction.
// See https://www.drupal.org/node/310079 for more details.
$transaction = db_transaction();
$select = db_select('units_mathematical_expression_postfix', 'e');
$select
->addExpression('MAX(e.mathematical_expression_id) + 1', 'mathematical_expression_id');
$mathematical_expression_id = $select
->execute()
->fetchField();
if (!$mathematical_expression_id) {
$mathematical_expression_id = 1;
}
}
db_insert('units_mathematical_expression_postfix')
->fields(array(
'type' => UNITS_TOKEN_TYPE_UNIT,
'mathematical_expression_id' => $mathematical_expression_id,
'value_string' => $this
->identifier(),
'postfix_order' => ++$order,
))
->execute();
return $mathematical_expression_id;
}
}
Classes
Name | Description |
---|---|
UnitsEntity | Units of measurement entity class. |