PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/phpexcel/PHPExcel/Calculation/TextData.php

http://github.com/moodle/moodle
PHP | 651 lines | 373 code | 91 blank | 187 comment | 104 complexity | 988441b6a212f4fcd6b83b0e1ee2c14c MD5 | raw file
Possible License(s): MIT, AGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, Apache-2.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /** PHPExcel root directory */
  3. if (!defined('PHPEXCEL_ROOT')) {
  4. /**
  5. * @ignore
  6. */
  7. define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
  8. require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
  9. }
  10. /**
  11. * PHPExcel_Calculation_TextData
  12. *
  13. * Copyright (c) 2006 - 2015 PHPExcel
  14. *
  15. * This library is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU Lesser General Public
  17. * License as published by the Free Software Foundation; either
  18. * version 2.1 of the License, or (at your option) any later version.
  19. *
  20. * This library is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  23. * Lesser General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU Lesser General Public
  26. * License along with this library; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. *
  29. * @category PHPExcel
  30. * @package PHPExcel_Calculation
  31. * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  32. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  33. * @version ##VERSION##, ##DATE##
  34. */
  35. class PHPExcel_Calculation_TextData
  36. {
  37. private static $invalidChars;
  38. private static function unicodeToOrd($c)
  39. {
  40. if (ord($c{0}) >=0 && ord($c{0}) <= 127) {
  41. return ord($c{0});
  42. } elseif (ord($c{0}) >= 192 && ord($c{0}) <= 223) {
  43. return (ord($c{0})-192)*64 + (ord($c{1})-128);
  44. } elseif (ord($c{0}) >= 224 && ord($c{0}) <= 239) {
  45. return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128);
  46. } elseif (ord($c{0}) >= 240 && ord($c{0}) <= 247) {
  47. return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128);
  48. } elseif (ord($c{0}) >= 248 && ord($c{0}) <= 251) {
  49. return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128);
  50. } elseif (ord($c{0}) >= 252 && ord($c{0}) <= 253) {
  51. return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128);
  52. } elseif (ord($c{0}) >= 254 && ord($c{0}) <= 255) {
  53. // error
  54. return PHPExcel_Calculation_Functions::VALUE();
  55. }
  56. return 0;
  57. }
  58. /**
  59. * CHARACTER
  60. *
  61. * @param string $character Value
  62. * @return int
  63. */
  64. public static function CHARACTER($character)
  65. {
  66. $character = PHPExcel_Calculation_Functions::flattenSingleValue($character);
  67. if ((!is_numeric($character)) || ($character < 0)) {
  68. return PHPExcel_Calculation_Functions::VALUE();
  69. }
  70. if (function_exists('mb_convert_encoding')) {
  71. return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES');
  72. } else {
  73. return chr(intval($character));
  74. }
  75. }
  76. /**
  77. * TRIMNONPRINTABLE
  78. *
  79. * @param mixed $stringValue Value to check
  80. * @return string
  81. */
  82. public static function TRIMNONPRINTABLE($stringValue = '')
  83. {
  84. $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue);
  85. if (is_bool($stringValue)) {
  86. return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  87. }
  88. if (self::$invalidChars == null) {
  89. self::$invalidChars = range(chr(0), chr(31));
  90. }
  91. if (is_string($stringValue) || is_numeric($stringValue)) {
  92. return str_replace(self::$invalidChars, '', trim($stringValue, "\x00..\x1F"));
  93. }
  94. return null;
  95. }
  96. /**
  97. * TRIMSPACES
  98. *
  99. * @param mixed $stringValue Value to check
  100. * @return string
  101. */
  102. public static function TRIMSPACES($stringValue = '')
  103. {
  104. $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue);
  105. if (is_bool($stringValue)) {
  106. return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  107. }
  108. if (is_string($stringValue) || is_numeric($stringValue)) {
  109. return trim(preg_replace('/ +/', ' ', trim($stringValue, ' ')), ' ');
  110. }
  111. return null;
  112. }
  113. /**
  114. * ASCIICODE
  115. *
  116. * @param string $characters Value
  117. * @return int
  118. */
  119. public static function ASCIICODE($characters)
  120. {
  121. if (($characters === null) || ($characters === '')) {
  122. return PHPExcel_Calculation_Functions::VALUE();
  123. }
  124. $characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters);
  125. if (is_bool($characters)) {
  126. if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
  127. $characters = (int) $characters;
  128. } else {
  129. $characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  130. }
  131. }
  132. $character = $characters;
  133. if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) {
  134. if (mb_strlen($characters, 'UTF-8') > 1) {
  135. $character = mb_substr($characters, 0, 1, 'UTF-8');
  136. }
  137. return self::unicodeToOrd($character);
  138. } else {
  139. if (strlen($characters) > 0) {
  140. $character = substr($characters, 0, 1);
  141. }
  142. return ord($character);
  143. }
  144. }
  145. /**
  146. * CONCATENATE
  147. *
  148. * @return string
  149. */
  150. public static function CONCATENATE()
  151. {
  152. $returnValue = '';
  153. // Loop through arguments
  154. $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());
  155. foreach ($aArgs as $arg) {
  156. if (is_bool($arg)) {
  157. if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
  158. $arg = (int) $arg;
  159. } else {
  160. $arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  161. }
  162. }
  163. $returnValue .= $arg;
  164. }
  165. return $returnValue;
  166. }
  167. /**
  168. * DOLLAR
  169. *
  170. * This function converts a number to text using currency format, with the decimals rounded to the specified place.
  171. * The format used is $#,##0.00_);($#,##0.00)..
  172. *
  173. * @param float $value The value to format
  174. * @param int $decimals The number of digits to display to the right of the decimal point.
  175. * If decimals is negative, number is rounded to the left of the decimal point.
  176. * If you omit decimals, it is assumed to be 2
  177. * @return string
  178. */
  179. public static function DOLLAR($value = 0, $decimals = 2)
  180. {
  181. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  182. $decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals);
  183. // Validate parameters
  184. if (!is_numeric($value) || !is_numeric($decimals)) {
  185. return PHPExcel_Calculation_Functions::NaN();
  186. }
  187. $decimals = floor($decimals);
  188. $mask = '$#,##0';
  189. if ($decimals > 0) {
  190. $mask .= '.' . str_repeat('0', $decimals);
  191. } else {
  192. $round = pow(10, abs($decimals));
  193. if ($value < 0) {
  194. $round = 0-$round;
  195. }
  196. $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round);
  197. }
  198. return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask);
  199. }
  200. /**
  201. * SEARCHSENSITIVE
  202. *
  203. * @param string $needle The string to look for
  204. * @param string $haystack The string in which to look
  205. * @param int $offset Offset within $haystack
  206. * @return string
  207. */
  208. public static function SEARCHSENSITIVE($needle, $haystack, $offset = 1)
  209. {
  210. $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle);
  211. $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack);
  212. $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset);
  213. if (!is_bool($needle)) {
  214. if (is_bool($haystack)) {
  215. $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  216. }
  217. if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) {
  218. if (PHPExcel_Shared_String::CountCharacters($needle) == 0) {
  219. return $offset;
  220. }
  221. if (function_exists('mb_strpos')) {
  222. $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8');
  223. } else {
  224. $pos = strpos($haystack, $needle, --$offset);
  225. }
  226. if ($pos !== false) {
  227. return ++$pos;
  228. }
  229. }
  230. }
  231. return PHPExcel_Calculation_Functions::VALUE();
  232. }
  233. /**
  234. * SEARCHINSENSITIVE
  235. *
  236. * @param string $needle The string to look for
  237. * @param string $haystack The string in which to look
  238. * @param int $offset Offset within $haystack
  239. * @return string
  240. */
  241. public static function SEARCHINSENSITIVE($needle, $haystack, $offset = 1)
  242. {
  243. $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle);
  244. $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack);
  245. $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset);
  246. if (!is_bool($needle)) {
  247. if (is_bool($haystack)) {
  248. $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  249. }
  250. if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) {
  251. if (PHPExcel_Shared_String::CountCharacters($needle) == 0) {
  252. return $offset;
  253. }
  254. if (function_exists('mb_stripos')) {
  255. $pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8');
  256. } else {
  257. $pos = stripos($haystack, $needle, --$offset);
  258. }
  259. if ($pos !== false) {
  260. return ++$pos;
  261. }
  262. }
  263. }
  264. return PHPExcel_Calculation_Functions::VALUE();
  265. }
  266. /**
  267. * FIXEDFORMAT
  268. *
  269. * @param mixed $value Value to check
  270. * @param integer $decimals
  271. * @param boolean $no_commas
  272. * @return boolean
  273. */
  274. public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = false)
  275. {
  276. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  277. $decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals);
  278. $no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas);
  279. // Validate parameters
  280. if (!is_numeric($value) || !is_numeric($decimals)) {
  281. return PHPExcel_Calculation_Functions::NaN();
  282. }
  283. $decimals = floor($decimals);
  284. $valueResult = round($value, $decimals);
  285. if ($decimals < 0) {
  286. $decimals = 0;
  287. }
  288. if (!$no_commas) {
  289. $valueResult = number_format($valueResult, $decimals);
  290. }
  291. return (string) $valueResult;
  292. }
  293. /**
  294. * LEFT
  295. *
  296. * @param string $value Value
  297. * @param int $chars Number of characters
  298. * @return string
  299. */
  300. public static function LEFT($value = '', $chars = 1)
  301. {
  302. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  303. $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars);
  304. if ($chars < 0) {
  305. return PHPExcel_Calculation_Functions::VALUE();
  306. }
  307. if (is_bool($value)) {
  308. $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  309. }
  310. if (function_exists('mb_substr')) {
  311. return mb_substr($value, 0, $chars, 'UTF-8');
  312. } else {
  313. return substr($value, 0, $chars);
  314. }
  315. }
  316. /**
  317. * MID
  318. *
  319. * @param string $value Value
  320. * @param int $start Start character
  321. * @param int $chars Number of characters
  322. * @return string
  323. */
  324. public static function MID($value = '', $start = 1, $chars = null)
  325. {
  326. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  327. $start = PHPExcel_Calculation_Functions::flattenSingleValue($start);
  328. $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars);
  329. if (($start < 1) || ($chars < 0)) {
  330. return PHPExcel_Calculation_Functions::VALUE();
  331. }
  332. if (is_bool($value)) {
  333. $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  334. }
  335. if (function_exists('mb_substr')) {
  336. return mb_substr($value, --$start, $chars, 'UTF-8');
  337. } else {
  338. return substr($value, --$start, $chars);
  339. }
  340. }
  341. /**
  342. * RIGHT
  343. *
  344. * @param string $value Value
  345. * @param int $chars Number of characters
  346. * @return string
  347. */
  348. public static function RIGHT($value = '', $chars = 1)
  349. {
  350. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  351. $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars);
  352. if ($chars < 0) {
  353. return PHPExcel_Calculation_Functions::VALUE();
  354. }
  355. if (is_bool($value)) {
  356. $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  357. }
  358. if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) {
  359. return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8');
  360. } else {
  361. return substr($value, strlen($value) - $chars);
  362. }
  363. }
  364. /**
  365. * STRINGLENGTH
  366. *
  367. * @param string $value Value
  368. * @return string
  369. */
  370. public static function STRINGLENGTH($value = '')
  371. {
  372. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  373. if (is_bool($value)) {
  374. $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  375. }
  376. if (function_exists('mb_strlen')) {
  377. return mb_strlen($value, 'UTF-8');
  378. } else {
  379. return strlen($value);
  380. }
  381. }
  382. /**
  383. * LOWERCASE
  384. *
  385. * Converts a string value to upper case.
  386. *
  387. * @param string $mixedCaseString
  388. * @return string
  389. */
  390. public static function LOWERCASE($mixedCaseString)
  391. {
  392. $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);
  393. if (is_bool($mixedCaseString)) {
  394. $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  395. }
  396. return PHPExcel_Shared_String::StrToLower($mixedCaseString);
  397. }
  398. /**
  399. * UPPERCASE
  400. *
  401. * Converts a string value to upper case.
  402. *
  403. * @param string $mixedCaseString
  404. * @return string
  405. */
  406. public static function UPPERCASE($mixedCaseString)
  407. {
  408. $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);
  409. if (is_bool($mixedCaseString)) {
  410. $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  411. }
  412. return PHPExcel_Shared_String::StrToUpper($mixedCaseString);
  413. }
  414. /**
  415. * PROPERCASE
  416. *
  417. * Converts a string value to upper case.
  418. *
  419. * @param string $mixedCaseString
  420. * @return string
  421. */
  422. public static function PROPERCASE($mixedCaseString)
  423. {
  424. $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);
  425. if (is_bool($mixedCaseString)) {
  426. $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  427. }
  428. return PHPExcel_Shared_String::StrToTitle($mixedCaseString);
  429. }
  430. /**
  431. * REPLACE
  432. *
  433. * @param string $oldText String to modify
  434. * @param int $start Start character
  435. * @param int $chars Number of characters
  436. * @param string $newText String to replace in defined position
  437. * @return string
  438. */
  439. public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText)
  440. {
  441. $oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText);
  442. $start = PHPExcel_Calculation_Functions::flattenSingleValue($start);
  443. $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars);
  444. $newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText);
  445. $left = self::LEFT($oldText, $start-1);
  446. $right = self::RIGHT($oldText, self::STRINGLENGTH($oldText)-($start+$chars)+1);
  447. return $left.$newText.$right;
  448. }
  449. /**
  450. * SUBSTITUTE
  451. *
  452. * @param string $text Value
  453. * @param string $fromText From Value
  454. * @param string $toText To Value
  455. * @param integer $instance Instance Number
  456. * @return string
  457. */
  458. public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0)
  459. {
  460. $text = PHPExcel_Calculation_Functions::flattenSingleValue($text);
  461. $fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText);
  462. $toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText);
  463. $instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance));
  464. if ($instance == 0) {
  465. if (function_exists('mb_str_replace')) {
  466. return mb_str_replace($fromText, $toText, $text);
  467. } else {
  468. return str_replace($fromText, $toText, $text);
  469. }
  470. } else {
  471. $pos = -1;
  472. while ($instance > 0) {
  473. if (function_exists('mb_strpos')) {
  474. $pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8');
  475. } else {
  476. $pos = strpos($text, $fromText, $pos+1);
  477. }
  478. if ($pos === false) {
  479. break;
  480. }
  481. --$instance;
  482. }
  483. if ($pos !== false) {
  484. if (function_exists('mb_strlen')) {
  485. return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText);
  486. } else {
  487. return self::REPLACE($text, ++$pos, strlen($fromText), $toText);
  488. }
  489. }
  490. }
  491. return $text;
  492. }
  493. /**
  494. * RETURNSTRING
  495. *
  496. * @param mixed $testValue Value to check
  497. * @return boolean
  498. */
  499. public static function RETURNSTRING($testValue = '')
  500. {
  501. $testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue);
  502. if (is_string($testValue)) {
  503. return $testValue;
  504. }
  505. return null;
  506. }
  507. /**
  508. * TEXTFORMAT
  509. *
  510. * @param mixed $value Value to check
  511. * @param string $format Format mask to use
  512. * @return boolean
  513. */
  514. public static function TEXTFORMAT($value, $format)
  515. {
  516. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  517. $format = PHPExcel_Calculation_Functions::flattenSingleValue($format);
  518. if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) {
  519. $value = PHPExcel_Calculation_DateTime::DATEVALUE($value);
  520. }
  521. return (string) PHPExcel_Style_NumberFormat::toFormattedString($value, $format);
  522. }
  523. /**
  524. * VALUE
  525. *
  526. * @param mixed $value Value to check
  527. * @return boolean
  528. */
  529. public static function VALUE($value = '')
  530. {
  531. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  532. if (!is_numeric($value)) {
  533. $numberValue = str_replace(
  534. PHPExcel_Shared_String::getThousandsSeparator(),
  535. '',
  536. trim($value, " \t\n\r\0\x0B" . PHPExcel_Shared_String::getCurrencyCode())
  537. );
  538. if (is_numeric($numberValue)) {
  539. return (float) $numberValue;
  540. }
  541. $dateSetting = PHPExcel_Calculation_Functions::getReturnDateType();
  542. PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
  543. if (strpos($value, ':') !== false) {
  544. $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($value);
  545. if ($timeValue !== PHPExcel_Calculation_Functions::VALUE()) {
  546. PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);
  547. return $timeValue;
  548. }
  549. }
  550. $dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value);
  551. if ($dateValue !== PHPExcel_Calculation_Functions::VALUE()) {
  552. PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);
  553. return $dateValue;
  554. }
  555. PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);
  556. return PHPExcel_Calculation_Functions::VALUE();
  557. }
  558. return (float) $value;
  559. }
  560. }