Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
<?php

namespace PhpOffice\PhpSpreadsheet\Calculation;

< class Database < { < /** < * fieldExtract. < * < * Extracts the column ID to use for the data field. < * < * @param mixed[] $database The range of cells that makes up the list or database. < * A database is a list of related data in which rows of related < * information are records, and columns of data are fields. The < * first row of the list contains labels for each column. < * @param mixed $field Indicates which column is used in the function. Enter the < * column label enclosed between double quotation marks, such as < * "Age" or "Yield," or a number (without quotation marks) that < * represents the position of the column within the list: 1 for < * the first column, 2 for the second column, and so on. < * < * @return null|string < */ < private static function fieldExtract($database, $field) < { < $field = strtoupper(Functions::flattenSingleValue($field)); < $fieldNames = array_map('strtoupper', array_shift($database)); < < if (is_numeric($field)) { < $keys = array_keys($fieldNames); < < return $keys[$field - 1]; < } < $key = array_search($field, $fieldNames); < < return ($key) ? $key : null; < } <
/**
< * filter. < * < * Parses the selection criteria, extracts the database rows that match those criteria, and < * returns that subset of rows. < * < * @param mixed[] $database The range of cells that makes up the list or database. < * A database is a list of related data in which rows of related < * information are records, and columns of data are fields. The < * first row of the list contains labels for each column. < * @param mixed[] $criteria The range of cells that contains the conditions you specify. < * You can use any range for the criteria argument, as long as it < * includes at least one column label and at least one cell below < * the column label in which you specify a condition for the < * column.
> * @deprecated 1.17.0
*
< * @return array of mixed
> * @codeCoverageIgnore
*/
< private static function filter($database, $criteria) < { < $fieldNames = array_shift($database); < $criteriaNames = array_shift($criteria); < < // Convert the criteria into a set of AND/OR conditions with [:placeholders] < $testConditions = $testValues = []; < $testConditionsCount = 0; < foreach ($criteriaNames as $key => $criteriaName) { < $testCondition = []; < $testConditionCount = 0; < foreach ($criteria as $row => $criterion) { < if ($criterion[$key] > '') { < $testCondition[] = '[:' . $criteriaName . ']' . Functions::ifCondition($criterion[$key]); < ++$testConditionCount; < } < } < if ($testConditionCount > 1) { < $testConditions[] = 'OR(' . implode(',', $testCondition) . ')'; < ++$testConditionsCount; < } elseif ($testConditionCount == 1) { < $testConditions[] = $testCondition[0]; < ++$testConditionsCount; < } < } < < if ($testConditionsCount > 1) { < $testConditionSet = 'AND(' . implode(',', $testConditions) . ')'; < } elseif ($testConditionsCount == 1) { < $testConditionSet = $testConditions[0]; < } < < // Loop through each row of the database < foreach ($database as $dataRow => $dataValues) { < // Substitute actual values from the database row for our [:placeholders] < $testConditionList = $testConditionSet; < foreach ($criteriaNames as $key => $criteriaName) { < $k = array_search($criteriaName, $fieldNames); < if (isset($dataValues[$k])) { < $dataValue = $dataValues[$k]; < $dataValue = (is_string($dataValue)) ? Calculation::wrapResult(strtoupper($dataValue)) : $dataValue; < $testConditionList = str_replace('[:' . $criteriaName . ']', $dataValue, $testConditionList); < } < } < // evaluate the criteria against the row data < $result = Calculation::getInstance()->_calculateFormulaValue('=' . $testConditionList); < // If the row failed to meet the criteria, remove it from the database < if (!$result) { < unset($database[$dataRow]); < } < } < < return $database; < } < < private static function getFilteredColumn($database, $field, $criteria)
> class Database
{
< // reduce the database to a set of rows that match all the criteria < $database = self::filter($database, $criteria); < // extract an array of values for the requested column < $colData = []; < foreach ($database as $row) { < $colData[] = $row[$field]; < } < < return $colData; < } <
/** * DAVERAGE. * * Averages the values in a column of a list or database that match conditions you specify. * * Excel Function: * DAVERAGE(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DAverage class instead * A database is a list of related data in which rows of related > * @see Database\DAverage::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string */ public static function DAVERAGE($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return Statistical::AVERAGE( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DAverage::evaluate($database, $field, $criteria);
} /** * DCOUNT. * * Counts the cells that contain numbers in a column of a list or database that match conditions * that you specify. * * Excel Function: * DCOUNT(database,[field],criteria) *
< * Excel Function: < * DAVERAGE(database,field,criteria)
> * @deprecated 1.17.0 > * Use the evaluate() method in the Database\DCount class instead > * @see Database\DCount::evaluate()
* * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column.
< * @param int|string $field Indicates which column is used in the function. Enter the
> * @param null|int|string $field Indicates which column is used in the function. Enter the
* column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. *
< * @return int
> * @return int|string
* * @TODO The field argument is optional. If field is omitted, DCOUNT counts all records in the * database that match the criteria. */ public static function DCOUNT($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return Statistical::COUNT( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DCount::evaluate($database, $field, $criteria);
} /** * DCOUNTA. * * Counts the nonblank cells in a column of a list or database that match conditions that you specify. * * Excel Function: * DCOUNTA(database,[field],criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DCountA class instead * A database is a list of related data in which rows of related > * @see Database\DCountA::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. *
< * @return int < * < * @TODO The field argument is optional. If field is omitted, DCOUNTA counts all records in the < * database that match the criteria.
> * @return int|string
*/ public static function DCOUNTA($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // reduce the database to a set of rows that match all the criteria < $database = self::filter($database, $criteria); < // extract an array of values for the requested column < $colData = []; < foreach ($database as $row) { < $colData[] = $row[$field]; < } < < // Return < return Statistical::COUNTA( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DCountA::evaluate($database, $field, $criteria);
} /** * DGET. * * Extracts a single value from a column of a list or database that matches conditions that you * specify. * * Excel Function: * DGET(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DGet class instead * A database is a list of related data in which rows of related > * @see Database\DGet::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return mixed */ public static function DGET($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < $colData = self::getFilteredColumn($database, $field, $criteria); < if (count($colData) > 1) { < return Functions::NAN(); < } < < return $colData[0];
> return Database\DGet::evaluate($database, $field, $criteria);
} /** * DMAX. * * Returns the largest number in a column of a list or database that matches conditions you that * specify. * * Excel Function: * DMAX(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DMax class instead * A database is a list of related data in which rows of related > * @see Database\DMax::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. *
< * @return float
> * @return null|float|string
*/ public static function DMAX($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return Statistical::MAX( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DMax::evaluate($database, $field, $criteria);
} /** * DMIN. * * Returns the smallest number in a column of a list or database that matches conditions you that * specify. * * Excel Function: * DMIN(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DMin class instead * A database is a list of related data in which rows of related > * @see Database\DMin::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. *
< * @return float
> * @return null|float|string
*/ public static function DMIN($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return Statistical::MIN( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DMin::evaluate($database, $field, $criteria);
} /** * DPRODUCT. * * Multiplies the values in a column of a list or database that match conditions that you specify. * * Excel Function: * DPRODUCT(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DProduct class instead * A database is a list of related data in which rows of related > * @see Database\DProduct::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. *
< * @return float
> * @return float|string
*/ public static function DPRODUCT($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return MathTrig::PRODUCT( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DProduct::evaluate($database, $field, $criteria);
} /** * DSTDEV. * * Estimates the standard deviation of a population based on a sample by using the numbers in a * column of a list or database that match conditions that you specify. * * Excel Function: * DSTDEV(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DStDev class instead * A database is a list of related data in which rows of related > * @see Database\DStDev::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string */ public static function DSTDEV($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return Statistical::STDEV( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DStDev::evaluate($database, $field, $criteria);
} /** * DSTDEVP. * * Calculates the standard deviation of a population based on the entire population by using the * numbers in a column of a list or database that match conditions that you specify. * * Excel Function: * DSTDEVP(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DStDevP class instead * A database is a list of related data in which rows of related > * @see Database\DStDevP::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string */ public static function DSTDEVP($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return Statistical::STDEVP( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DStDevP::evaluate($database, $field, $criteria);
} /** * DSUM. * * Adds the numbers in a column of a list or database that match conditions that you specify. * * Excel Function: * DSUM(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DSum class instead * A database is a list of related data in which rows of related > * @see Database\DSum::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. *
< * @return float
> * @return null|float|string
*/ public static function DSUM($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return MathTrig::SUM( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DSum::evaluate($database, $field, $criteria);
} /** * DVAR. * * Estimates the variance of a population based on a sample by using the numbers in a column * of a list or database that match conditions that you specify. * * Excel Function: * DVAR(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DVar class instead * A database is a list of related data in which rows of related > * @see Database\DVar::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string (string if result is an error) */ public static function DVAR($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return Statistical::VARFunc( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DVar::evaluate($database, $field, $criteria);
} /** * DVARP. * * Calculates the variance of a population based on the entire population by using the numbers * in a column of a list or database that match conditions that you specify. * * Excel Function: * DVARP(database,field,criteria) *
> * @deprecated 1.17.0 * @param mixed[] $database The range of cells that makes up the list or database. > * Use the evaluate() method in the Database\DVarP class instead * A database is a list of related data in which rows of related > * @see Database\DVarP::evaluate() * information are records, and columns of data are fields. The > *
* first row of the list contains labels for each column. * @param int|string $field Indicates which column is used in the function. Enter the * column label enclosed between double quotation marks, such as * "Age" or "Yield," or a number (without quotation marks) that * represents the position of the column within the list: 1 for * the first column, 2 for the second column, and so on. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * * @return float|string (string if result is an error) */ public static function DVARP($database, $field, $criteria) {
< $field = self::fieldExtract($database, $field); < if ($field === null) { < return null; < } < < // Return < return Statistical::VARP( < self::getFilteredColumn($database, $field, $criteria) < );
> return Database\DVarP::evaluate($database, $field, $criteria);
} }