PageRenderTime 66ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 1ms

/t3lib/class.t3lib_div.php

https://github.com/andreaswolf/typo3-tceforms
PHP | 5934 lines | 3457 code | 442 blank | 2035 comment | 812 complexity | 4e085c661bbfef0fe2b99e3cc6566e03 MD5 | raw file
Possible License(s): Apache-2.0, BSD-2-Clause, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /***************************************************************
  3. * Copyright notice
  4. *
  5. * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
  6. * All rights reserved
  7. *
  8. * This script is part of the TYPO3 project. The TYPO3 project is
  9. * free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * The GNU General Public License can be found at
  15. * http://www.gnu.org/copyleft/gpl.html.
  16. * A copy is found in the textfile GPL.txt and important notices to the license
  17. * from the author is found in LICENSE.txt distributed with these scripts.
  18. *
  19. *
  20. * This script 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
  23. * GNU General Public License for more details.
  24. *
  25. * This copyright notice MUST APPEAR in all copies of the script!
  26. ***************************************************************/
  27. /**
  28. * Contains the reknown class "t3lib_div" with general purpose functions
  29. *
  30. * $Id$
  31. * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
  32. * XHTML compliant
  33. * Usage counts are based on search 22/2 2003 through whole source including tslib/
  34. *
  35. * @author Kasper Skårhøj <kasperYYYY@typo3.com>
  36. */
  37. /**
  38. * [CLASS/FUNCTION INDEX of SCRIPT]
  39. *
  40. *
  41. *
  42. * 232: class t3lib_div
  43. *
  44. * SECTION: GET/POST Variables
  45. * 262: function _GP($var)
  46. * 280: function _GET($var=NULL)
  47. * 297: function _POST($var=NULL)
  48. * 313: function _GETset($inputGet,$key='')
  49. * 336: function GPvar($var,$strip=0)
  50. * 353: function GParrayMerged($var)
  51. *
  52. * SECTION: IMAGE FUNCTIONS
  53. * 397: function gif_compress($theFile, $type)
  54. * 425: function png_to_gif_by_imagemagick($theFile)
  55. * 450: function read_png_gif($theFile,$output_png=0)
  56. *
  57. * SECTION: STRING FUNCTIONS
  58. * 499: function fixed_lgd($string,$origChars,$preStr='...')
  59. * 524: function fixed_lgd_pre($string,$chars)
  60. * 538: function fixed_lgd_cs($string,$chars)
  61. * 555: function breakTextForEmail($str,$implChar=LF,$charWidth=76)
  62. * 574: function breakLinesForEmail($str,$implChar=LF,$charWidth=76)
  63. * 610: function cmpIP($baseIP, $list)
  64. * 626: function cmpIPv4($baseIP, $list)
  65. * 668: function cmpIPv6($baseIP, $list)
  66. * 711: function IPv6Hex2Bin ($hex)
  67. * 726: function normalizeIPv6($address)
  68. * 782: function validIPv6($ip)
  69. * 805: function cmpFQDN($baseIP, $list)
  70. * 835: function inList($list,$item)
  71. * 847: function rmFromList($element,$list)
  72. * 863: function expandList($list)
  73. * 894: function intInRange($theInt,$min,$max=2000000000,$zeroValue=0)
  74. * 910: function intval_positive($theInt)
  75. * 923: function int_from_ver($verNumberStr)
  76. * 934: function compat_version($verNumberStr)
  77. * 952: function md5int($str)
  78. * 965: function shortMD5($input, $len=10)
  79. * 978: function uniqueList($in_list, $secondParameter=NULL)
  80. * 992: function split_fileref($fileref)
  81. * 1030: function dirname($path)
  82. * 1046: function modifyHTMLColor($color,$R,$G,$B)
  83. * 1066: function modifyHTMLColorAll($color,$all)
  84. * 1077: function rm_endcomma($string)
  85. * 1090: function danish_strtoupper($string)
  86. * 1105: function convUmlauts($str)
  87. * 1118: function testInt($var)
  88. * 1130: function isFirstPartOfStr($str,$partStr)
  89. * 1146: function formatSize($sizeInBytes,$labels='')
  90. * 1181: function convertMicrotime($microtime)
  91. * 1195: function splitCalc($string,$operators)
  92. * 1217: function calcPriority($string)
  93. * 1258: function calcParenthesis($string)
  94. * 1284: function htmlspecialchars_decode($value)
  95. * 1299: function deHSCentities($str)
  96. * 1312: function slashJS($string,$extended=0,$char="'")
  97. * 1325: function rawUrlEncodeJS($str)
  98. * 1337: function rawUrlEncodeFP($str)
  99. * 1348: function validEmail($email)
  100. * 1363: function formatForTextarea($content)
  101. *
  102. * SECTION: ARRAY FUNCTIONS
  103. * 1394: function inArray($in_array,$item)
  104. * 1411: function intExplode($delim, $string)
  105. * 1430: function revExplode($delim, $string, $count=0)
  106. * 1450: function trimExplode($delim, $string, $onlyNonEmptyValues=0)
  107. * 1472: function uniqueArray($valueArray)
  108. * 1484: function removeArrayEntryByValue($array,$cmpValue)
  109. * 1513: function implodeArrayForUrl($name,$theArray,$str='',$skipBlank=0,$rawurlencodeParamName=0)
  110. * 1538: function explodeUrl2Array($string,$multidim=FALSE)
  111. * 1564: function compileSelectedGetVarsFromArray($varList,$getArray,$GPvarAlt=1)
  112. * 1587: function addSlashesOnArray(&$theArray)
  113. * 1611: function stripSlashesOnArray(&$theArray)
  114. * 1633: function slashArray($arr,$cmd)
  115. * 1650: function array_merge_recursive_overrule($arr0,$arr1,$notAddKeys=0,$includeEmtpyValues=true)
  116. * 1683: function array_merge($arr1,$arr2)
  117. * 1696: function csvValues($row,$delim=',',$quote='"')
  118. *
  119. * SECTION: HTML/XML PROCESSING
  120. * 1738: function get_tag_attributes($tag)
  121. * 1775: function split_tag_attributes($tag)
  122. * 1809: function implodeAttributes($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)
  123. * 1836: function implodeParams($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)
  124. * 1851: function wrapJS($string, $linebreak=TRUE)
  125. * 1882: function xml2tree($string,$depth=999)
  126. * 1969: function array2xml($array,$NSprefix='',$level=0,$docTag='phparray',$spaceInd=0, $options=array(),$stackData=array())
  127. * 2088: function xml2array($string,$NSprefix='',$reportDocTag=FALSE)
  128. * 2198: function xmlRecompileFromStructValArray($vals)
  129. * 2242: function xmlGetHeaderAttribs($xmlData)
  130. *
  131. * SECTION: FILES FUNCTIONS
  132. * 2275: function getURL($url, $includeHeader=0)
  133. * 2342: function writeFile($file,$content)
  134. * 2367: function fixPermissions($file)
  135. * 2384: function writeFileToTypo3tempDir($filepath,$content)
  136. * 2427: function mkdir($theNewFolder)
  137. * 2446: function mkdir_deep($destination,$deepDir)
  138. * 2468: function get_dirs($path)
  139. * 2493: function getFilesInDir($path,$extensionList='',$prependPath=0,$order='')
  140. * 2547: function getAllFilesAndFoldersInPath($fileArr,$path,$extList='',$regDirs=0,$recursivityLevels=99)
  141. * 2570: function removePrefixPathFromList($fileArr,$prefixToRemove)
  142. * 2586: function fixWindowsFilePath($theFile)
  143. * 2598: function resolveBackPath($pathStr)
  144. * 2626: function locationHeaderUrl($path)
  145. *
  146. * SECTION: DEBUG helper FUNCTIONS
  147. * 2666: function debug_ordvalue($string,$characters=100)
  148. * 2683: function view_array($array_in)
  149. * 2711: function print_array($array_in)
  150. * 2726: function debug($var="",$brOrHeader=0)
  151. * 2757: function debug_trail()
  152. * 2779: function debugRows($rows,$header='')
  153. *
  154. * SECTION: SYSTEM INFORMATION
  155. * 2857: function getThisUrl()
  156. * 2873: function linkThisScript($getParams=array())
  157. * 2897: function linkThisUrl($url,$getParams=array())
  158. * 2920: function getIndpEnv($getEnvName)
  159. * 3113: function milliseconds()
  160. * 3125: function clientInfo($useragent='')
  161. *
  162. * SECTION: TYPO3 SPECIFIC FUNCTIONS
  163. * 3212: function getFileAbsFileName($filename,$onlyRelative=1,$relToTYPO3_mainDir=0)
  164. * 3248: function validPathStr($theFile)
  165. * 3259: function isAbsPath($path)
  166. * 3270: function isAllowedAbsPath($path)
  167. * 3287: function verifyFilenameAgainstDenyPattern($filename)
  168. * 3305: function upload_copy_move($source,$destination)
  169. * 3331: function upload_to_tempfile($uploadedFileName)
  170. * 3349: function unlink_tempfile($uploadedTempFileName)
  171. * 3365: function tempnam($filePrefix)
  172. * 3379: function stdAuthCode($uid_or_record,$fields='',$codeLength=8)
  173. * 3410: function cHashParams($addQueryParams)
  174. * 3433: function hideIfNotTranslated($l18n_cfg_fieldValue)
  175. * 3448: function readLLfile($fileRef,$langKey)
  176. * 3472: function readLLXMLfile($fileRef,$langKey)
  177. * 3589: function llXmlAutoFileName($fileRef,$language)
  178. * 3633: function loadTCA($table)
  179. * 3653: function resolveSheetDefInDS($dataStructArray,$sheet='sDEF')
  180. * 3686: function resolveAllSheetsInDS($dataStructArray)
  181. * 3715: function callUserFunction($funcName,&$params,&$ref,$checkPrefix='user_',$silent=0)
  182. * 3813: function &getUserObj($classRef,$checkPrefix='user_',$silent=0)
  183. * 3871: function &makeInstance($className)
  184. * 3883: function makeInstanceClassName($className)
  185. * 3897: function &makeInstanceService($serviceType, $serviceSubType='', $excludeServiceKeys=array())
  186. * 3961: function plainMailEncoded($email,$subject,$message,$headers='',$enc='',$charset='',$dontEncodeHeader=false)
  187. * 4031: function quoted_printable($string,$maxlen=76)
  188. * 4078: function encodeHeader($line,$enc='',$charset='ISO-8859-1')
  189. * 4121: function substUrlsInPlainText($message,$urlmode='76',$index_script_url='')
  190. * 4155: function makeRedirectUrl($inUrl,$l=0,$index_script_url='')
  191. * 4182: function freetypeDpiComp($font_size)
  192. * 4194: function initSysLog()
  193. * 4251: function sysLog($msg, $extKey, $severity=0)
  194. * 4334: function devLog($msg, $extKey, $severity=0, $dataVar=FALSE)
  195. * 4355: function arrayToLogString($arr, $valueList=array(), $valueLength=20)
  196. * 4378: function imageMagickCommand($command, $parameters, $path='')
  197. * 4425: function unQuoteFilenames($parameters,$unQuote=FALSE)
  198. * 4459: function quoteJSvalue($value, $inScriptTags = false)
  199. *
  200. * TOTAL FUNCTIONS: 138
  201. * (This index is automatically created/updated by the extension "extdeveval")
  202. *
  203. */
  204. // a tabulator
  205. define('TAB', chr(9));
  206. // a linefeed
  207. define('LF', chr(10));
  208. // a carriage return
  209. define('CR', chr(13));
  210. // a CR-LF combination
  211. define('CRLF', CR . LF);
  212. /**
  213. * The legendary "t3lib_div" class - Miscellaneous functions for general purpose.
  214. * Most of the functions does not relate specifically to TYPO3
  215. * However a section of functions requires certain TYPO3 features available
  216. * See comments in the source.
  217. * You are encouraged to use this library in your own scripts!
  218. *
  219. * USE:
  220. * The class is intended to be used without creating an instance of it.
  221. * So: Don't instantiate - call functions with "t3lib_div::" prefixed the function name.
  222. * So use t3lib_div::[method-name] to refer to the functions, eg. 't3lib_div::milliseconds()'
  223. *
  224. * @author Kasper Skårhøj <kasperYYYY@typo3.com>
  225. * @package TYPO3
  226. * @subpackage t3lib
  227. */
  228. final class t3lib_div {
  229. // Severity constants used by t3lib_div::sysLog()
  230. const SYSLOG_SEVERITY_INFO = 0;
  231. const SYSLOG_SEVERITY_NOTICE = 1;
  232. const SYSLOG_SEVERITY_WARNING = 2;
  233. const SYSLOG_SEVERITY_ERROR = 3;
  234. const SYSLOG_SEVERITY_FATAL = 4;
  235. /**
  236. * Singleton instances returned by makeInstance, using the class names as
  237. * array keys
  238. *
  239. * @var array<t3lib_Singleton>
  240. */
  241. protected static $singletonInstances = array();
  242. /**
  243. * Instances returned by makeInstance, using the class names as array keys
  244. *
  245. * @var array<array><object>
  246. */
  247. protected static $nonSingletonInstances = array();
  248. /**
  249. * Register for makeInstance with given class name and final class names to reduce number of class_exists() calls
  250. *
  251. * @var array Given class name => final class name
  252. */
  253. protected static $finalClassNameRegister = array();
  254. /*************************
  255. *
  256. * GET/POST Variables
  257. *
  258. * Background:
  259. * Input GET/POST variables in PHP may have their quotes escaped with "\" or not depending on configuration.
  260. * TYPO3 has always converted quotes to BE escaped if the configuration told that they would not be so.
  261. * But the clean solution is that quotes are never escaped and that is what the functions below offers.
  262. * Eventually TYPO3 should provide this in the global space as well.
  263. * In the transitional phase (or forever..?) we need to encourage EVERY to read and write GET/POST vars through the API functions below.
  264. *
  265. *************************/
  266. /**
  267. * Returns the 'GLOBAL' value of incoming data from POST or GET, with priority to POST (that is equalent to 'GP' order)
  268. * Strips slashes from all output, both strings and arrays.
  269. * To enhancement security in your scripts, please consider using t3lib_div::_GET or t3lib_div::_POST if you already know by which method your data is arriving to the scripts!
  270. * Usage: 537
  271. *
  272. * @param string GET/POST var to return
  273. * @return mixed POST var named $var and if not set, the GET var of the same name.
  274. */
  275. public static function _GP($var) {
  276. if (empty($var)) {
  277. return;
  278. }
  279. $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var];
  280. if (isset($value)) {
  281. if (is_array($value)) {
  282. self::stripSlashesOnArray($value);
  283. } else {
  284. $value = stripslashes($value);
  285. }
  286. }
  287. return $value;
  288. }
  289. /**
  290. * Returns the global arrays $_GET and $_POST merged with $_POST taking precedence.
  291. *
  292. * @param string Key (variable name) from GET or POST vars
  293. * @return array Returns the GET vars merged recursively onto the POST vars.
  294. */
  295. public static function _GPmerged($parameter) {
  296. $postParameter = (isset($_POST[$parameter]) && is_array($_POST[$parameter])) ? $_POST[$parameter] : array();
  297. $getParameter = (isset($_GET[$parameter]) && is_array($_GET[$parameter])) ? $_GET[$parameter] : array();
  298. $mergedParameters = self::array_merge_recursive_overrule($getParameter, $postParameter);
  299. self::stripSlashesOnArray($mergedParameters);
  300. return $mergedParameters;
  301. }
  302. /**
  303. * Returns the global $_GET array (or value from) normalized to contain un-escaped values.
  304. * ALWAYS use this API function to acquire the GET variables!
  305. * Usage: 27
  306. *
  307. * @param string Optional pointer to value in GET array (basically name of GET var)
  308. * @return mixed If $var is set it returns the value of $_GET[$var]. If $var is NULL (default), returns $_GET itself. In any case *slashes are stipped from the output!*
  309. * @see _POST(), _GP(), _GETset()
  310. */
  311. public static function _GET($var = NULL) {
  312. $value = ($var === NULL) ? $_GET : (empty($var) ? NULL : $_GET[$var]);
  313. if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
  314. if (is_array($value)) {
  315. self::stripSlashesOnArray($value);
  316. } else {
  317. $value = stripslashes($value);
  318. }
  319. }
  320. return $value;
  321. }
  322. /**
  323. * Returns the global $_POST array (or value from) normalized to contain un-escaped values.
  324. * ALWAYS use this API function to acquire the $_POST variables!
  325. * Usage: 41
  326. *
  327. * @param string Optional pointer to value in POST array (basically name of POST var)
  328. * @return mixed If $var is set it returns the value of $_POST[$var]. If $var is NULL (default), returns $_POST itself. In any case *slashes are stipped from the output!*
  329. * @see _GET(), _GP()
  330. */
  331. public static function _POST($var = NULL) {
  332. $value = ($var === NULL) ? $_POST : (empty($var) ? NULL : $_POST[$var]);
  333. if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
  334. if (is_array($value)) {
  335. self::stripSlashesOnArray($value);
  336. } else {
  337. $value = stripslashes($value);
  338. }
  339. }
  340. return $value;
  341. }
  342. /**
  343. * Writes input value to $_GET.
  344. * Usage: 2
  345. *
  346. * @param mixed $inputGet
  347. * array or single value to write to $_GET. Values should NOT be
  348. * escaped at input time (but will be escaped before writing
  349. * according to TYPO3 standards).
  350. * @param string $key
  351. * alternative key; If set, this will not set the WHOLE GET array,
  352. * but only the key in it specified by this value!
  353. * You can specify to replace keys on deeper array levels by
  354. * separating the keys with a pipe.
  355. * Example: 'parentKey|childKey' will result in
  356. * array('parentKey' => array('childKey' => $inputGet))
  357. *
  358. * @return void
  359. */
  360. public static function _GETset($inputGet, $key = '') {
  361. // adds slashes since TYPO3 standard currently is that slashes
  362. // must be applied (regardless of magic_quotes setting)
  363. if (is_array($inputGet)) {
  364. self::addSlashesOnArray($inputGet);
  365. } else {
  366. $inputGet = addslashes($inputGet);
  367. }
  368. if ($key != '') {
  369. if (strpos($key, '|') !== FALSE) {
  370. $pieces = explode('|', $key);
  371. $newGet = array();
  372. $pointer =& $newGet;
  373. foreach ($pieces as $piece) {
  374. $pointer =& $pointer[$piece];
  375. }
  376. $pointer = $inputGet;
  377. $mergedGet = self::array_merge_recursive_overrule(
  378. $_GET, $newGet
  379. );
  380. $_GET = $mergedGet;
  381. $GLOBALS['HTTP_GET_VARS'] = $mergedGet;
  382. } else {
  383. $_GET[$key] = $inputGet;
  384. $GLOBALS['HTTP_GET_VARS'][$key] = $inputGet;
  385. }
  386. } elseif (is_array($inputGet)) {
  387. $_GET = $inputGet;
  388. $GLOBALS['HTTP_GET_VARS'] = $inputGet;
  389. }
  390. }
  391. /**
  392. * Wrapper for the RemoveXSS function.
  393. * Removes potential XSS code from an input string.
  394. *
  395. * Using an external class by Travis Puderbaugh <kallahar@quickwired.com>
  396. *
  397. * @param string Input string
  398. * @return string Input string with potential XSS code removed
  399. */
  400. public static function removeXSS($string) {
  401. require_once(PATH_typo3 . 'contrib/RemoveXSS/RemoveXSS.php');
  402. $string = RemoveXSS::process($string);
  403. return $string;
  404. }
  405. /*************************
  406. *
  407. * IMAGE FUNCTIONS
  408. *
  409. *************************/
  410. /**
  411. * Compressing a GIF file if not already LZW compressed.
  412. * This function is a workaround for the fact that ImageMagick and/or GD does not compress GIF-files to their minimun size (that is RLE or no compression used)
  413. *
  414. * The function takes a file-reference, $theFile, and saves it again through GD or ImageMagick in order to compress the file
  415. * GIF:
  416. * If $type is not set, the compression is done with ImageMagick (provided that $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'] is pointing to the path of a lzw-enabled version of 'convert') else with GD (should be RLE-enabled!)
  417. * If $type is set to either 'IM' or 'GD' the compression is done with ImageMagick and GD respectively
  418. * PNG:
  419. * No changes.
  420. *
  421. * $theFile is expected to be a valid GIF-file!
  422. * The function returns a code for the operation.
  423. * Usage: 9
  424. *
  425. * @param string Filepath
  426. * @param string See description of function
  427. * @return string Returns "GD" if GD was used, otherwise "IM" if ImageMagick was used. If nothing done at all, it returns empty string.
  428. */
  429. public static function gif_compress($theFile, $type) {
  430. $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
  431. $returnCode = '';
  432. if ($gfxConf['gif_compress'] && strtolower(substr($theFile, -4, 4)) == '.gif') { // GIF...
  433. if (($type == 'IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw']) { // IM
  434. // use temporary file to prevent problems with read and write lock on same file on network file systems
  435. $temporaryName = dirname($theFile) . '/' . md5(uniqid()) . '.gif';
  436. // rename could fail, if a simultaneous thread is currently working on the same thing
  437. if (@rename($theFile, $temporaryName)) {
  438. $cmd = self::imageMagickCommand('convert', '"' . $temporaryName . '" "' . $theFile . '"', $gfxConf['im_path_lzw']);
  439. t3lib_utility_Command::exec($cmd);
  440. unlink($temporaryName);
  441. }
  442. $returnCode = 'IM';
  443. if (@is_file($theFile)) {
  444. self::fixPermissions($theFile);
  445. }
  446. } elseif (($type == 'GD' || !$type) && $gfxConf['gdlib'] && !$gfxConf['gdlib_png']) { // GD
  447. $tempImage = imageCreateFromGif($theFile);
  448. imageGif($tempImage, $theFile);
  449. imageDestroy($tempImage);
  450. $returnCode = 'GD';
  451. if (@is_file($theFile)) {
  452. self::fixPermissions($theFile);
  453. }
  454. }
  455. }
  456. return $returnCode;
  457. }
  458. /**
  459. * Converts a png file to gif.
  460. * This converts a png file to gif IF the FLAG $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] is set true.
  461. * Usage: 5
  462. *
  463. * @param string $theFile the filename with path
  464. * @return string new filename
  465. */
  466. public static function png_to_gif_by_imagemagick($theFile) {
  467. if ($GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif']
  468. && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im']
  469. && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']
  470. && strtolower(substr($theFile, -4, 4)) == '.png'
  471. && @is_file($theFile)) { // IM
  472. $newFile = substr($theFile, 0, -4) . '.gif';
  473. $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']);
  474. t3lib_utility_Command::exec($cmd);
  475. $theFile = $newFile;
  476. if (@is_file($newFile)) {
  477. self::fixPermissions($newFile);
  478. }
  479. // unlink old file?? May be bad idea bacause TYPO3 would then recreate the file every time as TYPO3 thinks the file is not generated because it's missing!! So do not unlink $theFile here!!
  480. }
  481. return $theFile;
  482. }
  483. /**
  484. * Returns filename of the png/gif version of the input file (which can be png or gif).
  485. * If input file type does not match the wanted output type a conversion is made and temp-filename returned.
  486. * Usage: 2
  487. *
  488. * @param string Filepath of image file
  489. * @param boolean If set, then input file is converted to PNG, otherwise to GIF
  490. * @return string If the new image file exists, it's filepath is returned
  491. */
  492. public static function read_png_gif($theFile, $output_png = 0) {
  493. if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] && @is_file($theFile)) {
  494. $ext = strtolower(substr($theFile, -4, 4));
  495. if (
  496. ((string) $ext == '.png' && $output_png) ||
  497. ((string) $ext == '.gif' && !$output_png)
  498. ) {
  499. return $theFile;
  500. } else {
  501. $newFile = PATH_site . 'typo3temp/readPG_' . md5($theFile . '|' . filemtime($theFile)) . ($output_png ? '.png' : '.gif');
  502. $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']);
  503. t3lib_utility_Command::exec($cmd);
  504. if (@is_file($newFile)) {
  505. self::fixPermissions($newFile);
  506. return $newFile;
  507. }
  508. }
  509. }
  510. }
  511. /*************************
  512. *
  513. * STRING FUNCTIONS
  514. *
  515. *************************/
  516. /**
  517. * Truncates a string with appended/prepended "..." and takes current character set into consideration.
  518. * Usage: 75
  519. *
  520. * @param string string to truncate
  521. * @param integer must be an integer with an absolute value of at least 4. if negative the string is cropped from the right end.
  522. * @param string appendix to the truncated string
  523. * @return string cropped string
  524. */
  525. public static function fixed_lgd_cs($string, $chars, $appendString = '...') {
  526. if (is_object($GLOBALS['LANG'])) {
  527. return $GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet, $string, $chars, $appendString);
  528. } elseif (is_object($GLOBALS['TSFE'])) {
  529. $charSet = ($GLOBALS['TSFE']->renderCharset != '' ? $GLOBALS['TSFE']->renderCharset : $GLOBALS['TSFE']->defaultCharSet);
  530. return $GLOBALS['TSFE']->csConvObj->crop($charSet, $string, $chars, $appendString);
  531. } else {
  532. // this case should not happen
  533. $csConvObj = self::makeInstance('t3lib_cs');
  534. return $csConvObj->crop('iso-8859-1', $string, $chars, $appendString);
  535. }
  536. }
  537. /**
  538. * Breaks up a single line of text for emails
  539. * Usage: 5
  540. *
  541. * @param string The string to break up
  542. * @param string The string to implode the broken lines with (default/typically \n)
  543. * @param integer The line length
  544. * @return string
  545. */
  546. public static function breakLinesForEmail($str, $implChar = LF, $charWidth = 76) {
  547. $lines = array();
  548. $l = $charWidth;
  549. $p = 0;
  550. while (strlen($str) > $p) {
  551. $substr = substr($str, $p, $l);
  552. if (strlen($substr) == $l) {
  553. $count = count(explode(' ', trim(strrev($substr))));
  554. if ($count > 1) { // OK...
  555. $parts = explode(' ', strrev($substr), 2);
  556. $theLine = strrev($parts[1]);
  557. } else {
  558. $afterParts = explode(' ', substr($str, $l + $p), 2);
  559. $theLine = $substr . $afterParts[0];
  560. }
  561. if (!strlen($theLine)) {
  562. break;
  563. } // Error, because this would keep us in an endless loop.
  564. } else {
  565. $theLine = $substr;
  566. }
  567. $lines[] = trim($theLine);
  568. $p += strlen($theLine);
  569. if (!trim(substr($str, $p, $l))) {
  570. break;
  571. } // added...
  572. }
  573. return implode($implChar, $lines);
  574. }
  575. /**
  576. * Match IP number with list of numbers with wildcard
  577. * Dispatcher method for switching into specialised IPv4 and IPv6 methods.
  578. * Usage: 10
  579. *
  580. * @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR
  581. * @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168). If list is "*" no check is done and the function returns TRUE immediately. An empty list always returns FALSE.
  582. * @return boolean True if an IP-mask from $list matches $baseIP
  583. */
  584. public static function cmpIP($baseIP, $list) {
  585. $list = trim($list);
  586. if ($list === '') {
  587. return FALSE;
  588. } elseif ($list === '*') {
  589. return TRUE;
  590. }
  591. if (strpos($baseIP, ':') !== FALSE && self::validIPv6($baseIP)) {
  592. return self::cmpIPv6($baseIP, $list);
  593. } else {
  594. return self::cmpIPv4($baseIP, $list);
  595. }
  596. }
  597. /**
  598. * Match IPv4 number with list of numbers with wildcard
  599. *
  600. * @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR
  601. * @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168)
  602. * @return boolean True if an IP-mask from $list matches $baseIP
  603. */
  604. public static function cmpIPv4($baseIP, $list) {
  605. $IPpartsReq = explode('.', $baseIP);
  606. if (count($IPpartsReq) == 4) {
  607. $values = self::trimExplode(',', $list, 1);
  608. foreach ($values as $test) {
  609. list($test, $mask) = explode('/', $test);
  610. if (intval($mask)) {
  611. // "192.168.3.0/24"
  612. $lnet = ip2long($test);
  613. $lip = ip2long($baseIP);
  614. $binnet = str_pad(decbin($lnet), 32, '0', STR_PAD_LEFT);
  615. $firstpart = substr($binnet, 0, $mask);
  616. $binip = str_pad(decbin($lip), 32, '0', STR_PAD_LEFT);
  617. $firstip = substr($binip, 0, $mask);
  618. $yes = (strcmp($firstpart, $firstip) == 0);
  619. } else {
  620. // "192.168.*.*"
  621. $IPparts = explode('.', $test);
  622. $yes = 1;
  623. foreach ($IPparts as $index => $val) {
  624. $val = trim($val);
  625. if (strcmp($val, '*') && strcmp($IPpartsReq[$index], $val)) {
  626. $yes = 0;
  627. }
  628. }
  629. }
  630. if ($yes) {
  631. return TRUE;
  632. }
  633. }
  634. }
  635. return FALSE;
  636. }
  637. /**
  638. * Match IPv6 address with a list of IPv6 prefixes
  639. *
  640. * @param string $baseIP is the current remote IP address for instance
  641. * @param string $list is a comma-list of IPv6 prefixes, could also contain IPv4 addresses
  642. * @return boolean True if an baseIP matches any prefix
  643. */
  644. public static function cmpIPv6($baseIP, $list) {
  645. $success = FALSE; // Policy default: Deny connection
  646. $baseIP = self::normalizeIPv6($baseIP);
  647. $values = self::trimExplode(',', $list, 1);
  648. foreach ($values as $test) {
  649. list($test, $mask) = explode('/', $test);
  650. if (self::validIPv6($test)) {
  651. $test = self::normalizeIPv6($test);
  652. if (intval($mask)) {
  653. switch ($mask) { // test on /48 /64
  654. case '48':
  655. $testBin = substr(self::IPv6Hex2Bin($test), 0, 48);
  656. $baseIPBin = substr(self::IPv6Hex2Bin($baseIP), 0, 48);
  657. $success = strcmp($testBin, $baseIPBin) == 0 ? TRUE : FALSE;
  658. break;
  659. case '64':
  660. $testBin = substr(self::IPv6Hex2Bin($test), 0, 64);
  661. $baseIPBin = substr(self::IPv6Hex2Bin($baseIP), 0, 64);
  662. $success = strcmp($testBin, $baseIPBin) == 0 ? TRUE : FALSE;
  663. break;
  664. default:
  665. $success = FALSE;
  666. }
  667. } else {
  668. if (self::validIPv6($test)) { // test on full ip address 128 bits
  669. $testBin = self::IPv6Hex2Bin($test);
  670. $baseIPBin = self::IPv6Hex2Bin($baseIP);
  671. $success = strcmp($testBin, $baseIPBin) == 0 ? TRUE : FALSE;
  672. }
  673. }
  674. }
  675. if ($success) {
  676. return TRUE;
  677. }
  678. }
  679. return FALSE;
  680. }
  681. /**
  682. * [Describe function...]
  683. *
  684. * @param [type] $hex: ...
  685. * @return [type] ...
  686. */
  687. public static function IPv6Hex2Bin($hex) {
  688. $bin = '';
  689. $hex = str_replace(':', '', $hex); // Replace colon to nothing
  690. for ($i = 0; $i < strlen($hex); $i = $i + 2) {
  691. $bin .= chr(hexdec(substr($hex, $i, 2)));
  692. }
  693. return $bin;
  694. }
  695. /**
  696. * Normalize an IPv6 address to full length
  697. *
  698. * @param string Given IPv6 address
  699. * @return string Normalized address
  700. */
  701. public static function normalizeIPv6($address) {
  702. $normalizedAddress = '';
  703. $stageOneAddress = '';
  704. $chunks = explode('::', $address); // Count 2 if if address has hidden zero blocks
  705. if (count($chunks) == 2) {
  706. $chunksLeft = explode(':', $chunks[0]);
  707. $chunksRight = explode(':', $chunks[1]);
  708. $left = count($chunksLeft);
  709. $right = count($chunksRight);
  710. // Special case: leading zero-only blocks count to 1, should be 0
  711. if ($left == 1 && strlen($chunksLeft[0]) == 0) {
  712. $left = 0;
  713. }
  714. $hiddenBlocks = 8 - ($left + $right);
  715. $hiddenPart = '';
  716. $h = 0;
  717. while ($h < $hiddenBlocks) {
  718. $hiddenPart .= '0000:';
  719. $h++;
  720. }
  721. if ($left == 0) {
  722. $stageOneAddress = $hiddenPart . $chunks[1];
  723. } else {
  724. $stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1];
  725. }
  726. } else {
  727. $stageOneAddress = $address;
  728. }
  729. // normalize the blocks:
  730. $blocks = explode(':', $stageOneAddress);
  731. $divCounter = 0;
  732. foreach ($blocks as $block) {
  733. $tmpBlock = '';
  734. $i = 0;
  735. $hiddenZeros = 4 - strlen($block);
  736. while ($i < $hiddenZeros) {
  737. $tmpBlock .= '0';
  738. $i++;
  739. }
  740. $normalizedAddress .= $tmpBlock . $block;
  741. if ($divCounter < 7) {
  742. $normalizedAddress .= ':';
  743. $divCounter++;
  744. }
  745. }
  746. return $normalizedAddress;
  747. }
  748. /**
  749. * Validate a given IP address.
  750. *
  751. * Possible format are IPv4 and IPv6.
  752. *
  753. * @param string IP address to be tested
  754. * @return boolean True if $ip is either of IPv4 or IPv6 format.
  755. */
  756. public static function validIP($ip) {
  757. return (filter_var($ip, FILTER_VALIDATE_IP) !== FALSE);
  758. }
  759. /**
  760. * Validate a given IP address to the IPv4 address format.
  761. *
  762. * Example for possible format: 10.0.45.99
  763. *
  764. * @param string IP address to be tested
  765. * @return boolean True if $ip is of IPv4 format.
  766. */
  767. public static function validIPv4($ip) {
  768. return (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== FALSE);
  769. }
  770. /**
  771. * Validate a given IP address to the IPv6 address format.
  772. *
  773. * Example for possible format: 43FB::BB3F:A0A0:0 | ::1
  774. *
  775. * @param string IP address to be tested
  776. * @return boolean True if $ip is of IPv6 format.
  777. */
  778. public static function validIPv6($ip) {
  779. return (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE);
  780. }
  781. /**
  782. * Match fully qualified domain name with list of strings with wildcard
  783. *
  784. * @param string The current remote IP address for instance, typ. REMOTE_ADDR
  785. * @param string A comma-list of domain names to match with. *-wildcard allowed but cannot be part of a string, so it must match the full host name (eg. myhost.*.com => correct, myhost.*domain.com => wrong)
  786. * @return boolean True if a domain name mask from $list matches $baseIP
  787. */
  788. public static function cmpFQDN($baseIP, $list) {
  789. if (count(explode('.', $baseIP)) == 4) {
  790. $resolvedHostName = explode('.', gethostbyaddr($baseIP));
  791. $values = self::trimExplode(',', $list, 1);
  792. foreach ($values as $test) {
  793. $hostNameParts = explode('.', $test);
  794. $yes = 1;
  795. foreach ($hostNameParts as $index => $val) {
  796. $val = trim($val);
  797. if (strcmp($val, '*') && strcmp($resolvedHostName[$index], $val)) {
  798. $yes = 0;
  799. }
  800. }
  801. if ($yes) {
  802. return TRUE;
  803. }
  804. }
  805. }
  806. return FALSE;
  807. }
  808. /**
  809. * Checks if a given URL matches the host that currently handles this HTTP request.
  810. * Scheme, hostname and (optional) port of the given URL are compared.
  811. *
  812. * @param string $url: URL to compare with the TYPO3 request host
  813. * @return boolean Whether the URL matches the TYPO3 request host
  814. */
  815. public static function isOnCurrentHost($url) {
  816. return (stripos($url . '/', self::getIndpEnv('TYPO3_REQUEST_HOST') . '/') === 0);
  817. }
  818. /**
  819. * Check for item in list
  820. * Check if an item exists in a comma-separated list of items.
  821. * Usage: 163
  822. *
  823. * @param string comma-separated list of items (string)
  824. * @param string item to check for
  825. * @return boolean true if $item is in $list
  826. */
  827. public static function inList($list, $item) {
  828. return (strpos(',' . $list . ',', ',' . $item . ',') !== FALSE ? TRUE : FALSE);
  829. }
  830. /**
  831. * Removes an item from a comma-separated list of items.
  832. * Usage: 1
  833. *
  834. * @param string element to remove
  835. * @param string comma-separated list of items (string)
  836. * @return string new comma-separated list of items
  837. */
  838. public static function rmFromList($element, $list) {
  839. $items = explode(',', $list);
  840. foreach ($items as $k => $v) {
  841. if ($v == $element) {
  842. unset($items[$k]);
  843. }
  844. }
  845. return implode(',', $items);
  846. }
  847. /**
  848. * Expand a comma-separated list of integers with ranges (eg 1,3-5,7 becomes 1,3,4,5,7).
  849. * Ranges are limited to 1000 values per range.
  850. *
  851. * @param string comma-separated list of integers with ranges (string)
  852. * @return string new comma-separated list of items
  853. * @author Martin Kutschker <martin.kutschker@activesolution.at>
  854. */
  855. public static function expandList($list) {
  856. $items = explode(',', $list);
  857. $list = array();
  858. foreach ($items as $item) {
  859. $range = explode('-', $item);
  860. if (isset($range[1])) {
  861. $runAwayBrake = 1000;
  862. for ($n = $range[0]; $n <= $range[1]; $n++) {
  863. $list[] = $n;
  864. $runAwayBrake--;
  865. if ($runAwayBrake <= 0) {
  866. break;
  867. }
  868. }
  869. } else {
  870. $list[] = $item;
  871. }
  872. }
  873. return implode(',', $list);
  874. }
  875. /**
  876. * Forces the integer $theInt into the boundaries of $min and $max. If the $theInt is 'false' then the $zeroValue is applied.
  877. * Usage: 224
  878. *
  879. * @param integer Input value
  880. * @param integer Lower limit
  881. * @param integer Higher limit
  882. * @param integer Default value if input is false.
  883. * @return integer The input value forced into the boundaries of $min and $max
  884. */
  885. public static function intInRange($theInt, $min, $max = 2000000000, $zeroValue = 0) {
  886. // Returns $theInt as an integer in the integerspace from $min to $max
  887. $theInt = intval($theInt);
  888. if ($zeroValue && !$theInt) {
  889. $theInt = $zeroValue;
  890. } // If the input value is zero after being converted to integer, zeroValue may set another default value for it.
  891. if ($theInt < $min) {
  892. $theInt = $min;
  893. }
  894. if ($theInt > $max) {
  895. $theInt = $max;
  896. }
  897. return $theInt;
  898. }
  899. /**
  900. * Returns the $integer if greater than zero, otherwise returns zero.
  901. * Usage: 1
  902. *
  903. * @param integer Integer string to process
  904. * @return integer
  905. */
  906. public static function intval_positive($theInt) {
  907. $theInt = intval($theInt);
  908. if ($theInt < 0) {
  909. $theInt = 0;
  910. }
  911. return $theInt;
  912. }
  913. /**
  914. * Returns an integer from a three part version number, eg '4.12.3' -> 4012003
  915. * Usage: 2
  916. *
  917. * @param string Version number on format x.x.x
  918. * @return integer Integer version of version number (where each part can count to 999)
  919. */
  920. public static function int_from_ver($verNumberStr) {
  921. $verParts = explode('.', $verNumberStr);
  922. return intval((int) $verParts[0] . str_pad((int) $verParts[1], 3, '0', STR_PAD_LEFT) . str_pad((int) $verParts[2], 3, '0', STR_PAD_LEFT));
  923. }
  924. /**
  925. * Returns true if the current TYPO3 version (or compatibility version) is compatible to the input version
  926. * Notice that this function compares branches, not versions (4.0.1 would be > 4.0.0 although they use the same compat_version)
  927. *
  928. * @param string Minimum branch number required (format x.y / e.g. "4.0" NOT "4.0.0"!)
  929. * @return boolean Returns true if this setup is compatible with the provided version number
  930. * @todo Still needs a function to convert versions to branches
  931. */
  932. public static function compat_version($verNumberStr) {
  933. global $TYPO3_CONF_VARS;
  934. $currVersionStr = $TYPO3_CONF_VARS['SYS']['compat_version'] ? $TYPO3_CONF_VARS['SYS']['compat_version'] : TYPO3_branch;
  935. if (self::int_from_ver($currVersionStr) < self::int_from_ver($verNumberStr)) {
  936. return FALSE;
  937. } else {
  938. return TRUE;
  939. }
  940. }
  941. /**
  942. * Makes a positive integer hash out of the first 7 chars from the md5 hash of the input
  943. * Usage: 5
  944. *
  945. * @param string String to md5-hash
  946. * @return integer Returns 28bit integer-hash
  947. */
  948. public static function md5int($str) {
  949. return hexdec(substr(md5($str), 0, 7));
  950. }
  951. /**
  952. * Returns the first 10 positions of the MD5-hash (changed from 6 to 10 recently)
  953. *
  954. * Usage: 37
  955. *
  956. * @param string Input string to be md5-hashed
  957. * @param integer The string-length of the output
  958. * @return string Substring of the resulting md5-hash, being $len chars long (from beginning)
  959. */
  960. public static function shortMD5($input, $len = 10) {
  961. return substr(md5($input), 0, $len);
  962. }
  963. /**
  964. * Returns a proper HMAC on a given input string and secret TYPO3 encryption key.
  965. *
  966. * @param string Input string to create HMAC from
  967. * @return string resulting (hexadecimal) HMAC currently with a length of 40 (HMAC-SHA-1)
  968. */
  969. public static function hmac($input) {
  970. $hashAlgorithm = 'sha1';
  971. $hashBlocksize = 64;
  972. $hmac = '';
  973. if (extension_loaded('hash') && function_exists('hash_hmac') && function_exists('hash_algos') && in_array($hashAlgorithm, hash_algos())) {
  974. $hmac = hash_hmac($hashAlgorithm, $input, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
  975. } else {
  976. // outer padding
  977. $opad = str_repeat(chr(0x5C), $hashBlocksize);
  978. // innner padding
  979. $ipad = str_repeat(chr(0x36), $hashBlocksize);
  980. if (strlen($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) > $hashBlocksize) {
  981. // keys longer than blocksize are shorten
  982. $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])), $hashBlocksize, chr(0x00));
  983. } else {
  984. // keys shorter than blocksize are zero-padded
  985. $key = str_pad($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], $hashBlocksize, chr(0x00));
  986. }
  987. $hmac = call_user_func($hashAlgorithm, ($key ^ $opad) . pack('H*', call_user_func($hashAlgorithm, ($key ^ $ipad) . $input)));
  988. }
  989. return $hmac;
  990. }
  991. /**
  992. * Takes comma-separated lists and arrays and removes all duplicates
  993. * If a value in the list is trim(empty), the value is ignored.
  994. * Usage: 16
  995. *
  996. * @param string Accept multiple parameters wich can be comma-separated lists of values and arrays.
  997. * @param mixed $secondParameter: Dummy field, which if set will show a warning!
  998. * @return string Returns the list without any duplicates of values, space around values are trimmed
  999. */
  1000. public static function uniqueList($in_list, $secondParameter = NULL) {
  1001. if (is_array($in_list)) {
  1002. throw new InvalidArgumentException(
  1003. 'TYPO3 Fatal Error: t3lib_div::uniqueList() does NOT support array arguments anymore! Only string comma lists!',
  1004. 1270853885
  1005. );
  1006. }
  1007. if (isset($secondParameter)) {
  1008. throw new InvalidArgumentException(
  1009. 'TYPO3 Fatal Error: t3lib_div::uniqueList() does NOT support more than a single argument value anymore. You have specified more than one!',
  1010. 1270853886
  1011. );
  1012. }
  1013. return implode(',', array_unique(self::trimExplode(',', $in_list, 1)));
  1014. }
  1015. /**
  1016. * Splits a reference to a file in 5 parts
  1017. * Usage: 43
  1018. *
  1019. * @param string Filename/filepath to be analysed
  1020. * @return array Contains keys [path], [file], [filebody], [fileext], [realFileext]
  1021. */
  1022. public static function split_fileref($fileref) {
  1023. $reg = array();
  1024. if (preg_match('/(.*\/)(.*)$/', $fileref, $reg)) {
  1025. $info['path'] = $reg[1];
  1026. $info['file'] = $reg[2];
  1027. } else {
  1028. $info['path'] = '';
  1029. $info['file'] = $fileref;
  1030. }
  1031. $reg = '';
  1032. if (!is_dir($fileref) && preg_match('/(.*)\.([^\.]*$)/', $info['file'], $reg)) {
  1033. $info['filebody'] = $reg[1];
  1034. $info['fileext'] = strtolower($reg[2]);
  1035. $info['realFileext'] = $reg[2];
  1036. } else {
  1037. $info['filebody'] = $info['file'];
  1038. $info['fileext'] = '';
  1039. }
  1040. reset($info);
  1041. return $info;
  1042. }
  1043. /**
  1044. * Returns the directory part of a path without trailing slash
  1045. * If there is no dir-part, then an empty string is returned.
  1046. * Behaviour:
  1047. *
  1048. * '/dir1/dir2/script.php' => '/dir1/dir2'
  1049. * '/dir1/' => '/dir1'
  1050. * 'dir1/script.php' => 'dir1'
  1051. * 'd/script.php' => 'd'
  1052. * '/script.php' => ''
  1053. * '' => ''
  1054. * Usage: 5
  1055. *
  1056. * @param string Directory name / path
  1057. * @return string Processed input value. See function description.
  1058. */
  1059. public static function dirname($path) {
  1060. $p = self::revExplode('/', $path, 2);
  1061. return count($p) == 2 ? $p[0] : '';
  1062. }
  1063. /**
  1064. * Modifies a HTML Hex color by adding/subtracting $R,$G and $B integers
  1065. * Usage: 11
  1066. *
  1067. * @param string A hexadecimal color code, #xxxxxx
  1068. * @param integer Offset value 0-255
  1069. * @param integer Offset value 0-255
  1070. * @param integer Offset value 0-255
  1071. * @return string A hexadecimal color code, #xxxxxx, modified according to input vars
  1072. * @see modifyHTMLColorAll()
  1073. */
  1074. public static function modifyHTMLColor($color, $R, $G, $B) {
  1075. // This takes a hex-color (# included!) and adds $R, $G and $B to the HTML-color (format: #xxxxxx) and returns the new color
  1076. $nR = self::intInRange(hexdec(substr($color, 1, 2)) + $R, 0, 255);
  1077. $nG = self::intInRange(hexdec(substr($color, 3, 2)) + $G, 0, 255);
  1078. $nB = self::intInRange(hexdec(substr($color, 5, 2)) + $B, 0, 255);
  1079. return '#' .
  1080. substr('0' . dechex($nR), -2) .
  1081. substr('0' . dechex($nG), -2) .
  1082. substr('0' . dechex($nB), -2);
  1083. }
  1084. /**
  1085. * Modifies a HTML Hex color by adding/subtracting $all integer from all R/G/B channels
  1086. * Usage: 6
  1087. *
  1088. * @param string A hexadecimal color code, #xxxxxx
  1089. * @param integer Offset value 0-255 for all three channels.
  1090. * @return string A hexadecimal color code, #xxxxxx, modified according to input vars
  1091. * @see modifyHTMLColor()
  1092. */
  1093. public static function modifyHTMLColorAll($color, $all) {
  1094. return self::modifyHTMLColor($color, $all, $all, $all);
  1095. }
  1096. /**
  1097. * Removes comma (if present) in the end of string
  1098. * Usage: 2
  1099. *
  1100. * @param string String from which the comma in the end (if any) will be removed.
  1101. * @return string
  1102. * @deprecated since TYPO3 4.5, will be removed in TYPO3 4.7 - Use rtrim() directly
  1103. */
  1104. public static function rm_endcomma($string) {
  1105. self::logDeprecatedFunction();
  1106. return rtrim($string, ',');
  1107. }
  1108. /**
  1109. * Tests if the input can be interpreted as integer.
  1110. *
  1111. * @param mixed Any input variable to test
  1112. * @return boolean Returns true if string is an integer
  1113. */
  1114. public static function testInt($var) {
  1115. if ($var === '') {
  1116. return FALSE;
  1117. }
  1118. return (string) intval($var) === (string) $var;
  1119. }
  1120. /**
  1121. * Returns true if the first part of $str matches the string $partStr
  1122. * Usage: 59
  1123. *
  1124. * @param string Full string to check
  1125. * @param string Reference string which must be found as the "first part" of the full string
  1126. * @return boolean True if $partStr was found to be equal to the first part of $str
  1127. */
  1128. public static function isFirstPartOfStr($str, $partStr) {
  1129. return $partStr != '' && strpos((string) $str, (string) $partStr, 0) === 0;
  1130. }
  1131. /**
  1132. * Formats the input integer $sizeInBytes as bytes/kilobytes/megabytes (-/K/M)
  1133. * Usage: 53
  1134. *
  1135. * @param integer Number of bytes to format.
  1136. * @param string Labels for bytes, kilo, mega and giga separated by vertical bar (|) and possibly encapsulated in "". Eg: " | K| M| G" (which is the default value)
  1137. * @return string Formatted representation of the byte number, for output.
  1138. */
  1139. public static function formatSize($sizeInBytes, $labels = '') {
  1140. // Set labels:
  1141. if (strlen($labels) == 0) {
  1142. $labels = ' | K| M| G';
  1143. } else {
  1144. $labels = str_replace('"', '', $labels);
  1145. }
  1146. $labelArr = explode('|', $labels);
  1147. // Find size:
  1148. if ($sizeInBytes > 900) {
  1149. if ($sizeInBytes > 900000000) { // GB
  1150. $val = $sizeInBytes / (1024 * 1024 * 1024);
  1151. return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[3];
  1152. }
  1153. elseif ($sizeInBytes > 900000) { // MB
  1154. $val = $sizeInBytes / (1024 * 1024);
  1155. return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[2];
  1156. } else { // KB
  1157. $val = $sizeInBytes / (1024);
  1158. return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[1];
  1159. }
  1160. } else { // Bytes
  1161. return $sizeInBytes . $labelArr[0];
  1162. }
  1163. }
  1164. /**
  1165. * Returns microtime input to milliseconds
  1166. * Usage: 2
  1167. *
  1168. * @param string Microtime
  1169. * @return integer Microtime input string converted to an integer (milliseconds)
  1170. */
  1171. public static function convertMicrotime($microtime) {
  1172. $parts = explode(' ', $microtime);
  1173. return round(($parts[0] + $parts[1]) * 1000);
  1174. }
  1175. /**
  1176. * This splits a string by the chars in $operators (typical /+-*) and returns an array with them in
  1177. * Usage: 2
  1178. *
  1179. * @param string Input string, eg "123 + 456 / 789 - 4"
  1180. * @param string Operators to split by, typically "/+-*"
  1181. * @return array Array with operators and operands separated.
  1182. * @see tslib_cObj::calc(), tslib_gifBuilder::calcOffset()
  1183. */
  1184. public static function splitCalc($string, $operators) {
  1185. $res = Array();
  1186. $sign = '+';
  1187. while ($string) {
  1188. $valueLen = strcspn($string, $operators);
  1189. $value = substr($string, 0, $valueLen);
  1190. $res[] = Array($sign, trim($value));
  1191. $sign = substr($string, $valueLen, 1);
  1192. $string = substr($string, $valueLen + 1);
  1193. }
  1194. reset($res);
  1195. return $res;
  1196. }
  1197. /**
  1198. * Calculates the input by +,-,*,/,%,^ with priority to + and -
  1199. * Usage: 1
  1200. *
  1201. * @param string Input string, eg "123 + 456 / 789 - 4"
  1202. * @return integer Calculated value. Or error string.
  1203. * @see calcParenthesis()
  1204. */
  1205. public static function calcPriority($string) {
  1206. $string = preg_replace('/[[:space:]]*/', '', $string); // removing all whitespace
  1207. $string = '+' . $string; // Ensuring an operator for the first entrance
  1208. $qm = '\*\/\+-^%';
  1209. $regex = '([' . $qm . '])([' . $qm . ']?[0-9\.]*)';
  1210. // split the expression here:
  1211. $reg = array();
  1212. preg_match_all('/' . $regex . '/', $string, $reg);
  1213. reset($reg[2]);
  1214. $number = 0;
  1215. $Msign = '+';
  1216. $err = '';
  1217. $buffer = doubleval(current($reg[2]));
  1218. next($reg[2]); // Advance pointer
  1219. while (list($k, $v) = each($reg[2])) {
  1220. $v = doubleval($v);
  1221. $sign = $reg[1][$k];
  1222. if ($sign == '+' || $sign == '-') {
  1223. $number = $Msign == '-' ? $number -= $buffer : $number += $buffer;
  1224. $Msign = $sign;
  1225. $buffer = $v;
  1226. } else {
  1227. if ($sign == '/') {
  1228. if ($v) {
  1229. $buffer /= $v;
  1230. } else {
  1231. $err = 'dividing by zero';
  1232. }
  1233. }
  1234. if ($sign == '%') {
  1235. if ($v) {
  1236. $buffer %= $v;
  1237. } else {
  1238. $err = 'dividing by zero';
  1239. }
  1240. }
  1241. if ($sign == '*') {
  1242. $buffer *= $v;
  1243. }
  1244. if ($sign == '^') {
  1245. $buffer = pow($buffer, $v);
  1246. }
  1247. }
  1248. }
  1249. $number = $Msign == '-' ? $number -= $buffer : $number += $buffer;
  1250. return $err ? 'ERROR: ' . $err : $number;
  1251. }
  1252. /**
  1253. * Calculates the input with parenthesis levels
  1254. * Usage: 2
  1255. *
  1256. * @param string Input string, eg "(123 + 456) / 789 - 4"
  1257. * @return integer Calculated value. Or error string.
  1258. * @see calcPriority(), tslib_cObj::stdWrap()
  1259. */
  1260. public static function calcParenthesis($string) {
  1261. $securC = 100;
  1262. do {
  1263. $valueLenO = strcspn($string, '(');
  1264. $valueLenC = strcspn($string, ')');
  1265. if ($valueLenC == strlen($string) || $valueLenC < $valueLenO) {
  1266. $value = self::calcPriority(substr($string, 0, $valueLenC));
  1267. $string = $value . substr($string, $valueLenC + 1);
  1268. return $string;
  1269. } else {
  1270. $string = substr($string, 0, $valueLenO) . self::calcParenthesis(substr($string, $valueLenO + 1));
  1271. }
  1272. // Security:
  1273. $securC--;
  1274. if ($securC <= 0) {
  1275. break;
  1276. }
  1277. } while ($valueLenO < strlen($string));
  1278. return $string;
  1279. }
  1280. /**
  1281. * Inverse version of htmlspecialchars()
  1282. * Usage: 4
  1283. *
  1284. * @param string Value where &gt;, &lt;, &quot; and &amp; should be converted to regular chars.
  1285. * @return string Converted result.
  1286. */
  1287. public static function htmlspecialchars_decode($value) {
  1288. $value = str_replace('&gt;', '>', $value);
  1289. $value = str_replace('&lt;', '<', $value);
  1290. $value = str_replace('&quot;', '"', $value);
  1291. $value = str_replace('&amp;', '&', $value);
  1292. return $value;
  1293. }
  1294. /**
  1295. * Re-converts HTML entities if they have been converted by htmlspecialchars()
  1296. * Usage: 10
  1297. *
  1298. * @param string String which contains eg. "&amp;amp;" which should stay "&amp;". Or "&amp;#1234;" to "&#1234;". Or "&amp;#x1b;" to "&#x1b;"
  1299. * @return string Converted result.
  1300. */
  1301. public static function deHSCentities($str) {
  1302. return preg_replace('/&amp;([#[:alnum:]]*;)/', '&\1', $str);
  1303. }
  1304. /**
  1305. * This function is used to escape any ' -characters when transferring text to JavaScript!
  1306. * Usage: 3
  1307. *
  1308. * @param string String to escape
  1309. * @param boolean If set, also backslashes are escaped.
  1310. * @param string The character to escape, default is ' (single-quote)
  1311. * @return string Processed input string
  1312. */
  1313. public static function slashJS($string, $extended = 0, $char = "'") {
  1314. if ($extended) {
  1315. $string = str_replace("\\", "\\\\", $string);
  1316. }
  1317. return str_replace($char, "\\" . $char, $string);
  1318. }
  1319. /**
  1320. * Version of rawurlencode() where all spaces (%20) are re-converted to space-characters.
  1321. * Usefull when passing text to JavaScript where you simply url-encode it to get around problems with syntax-errors, linebreaks etc.
  1322. * Usage: 4
  1323. *
  1324. * @param string String to raw-url-encode with spaces preserved
  1325. * @return string Rawurlencoded result of input string, but with all %20 (space chars) converted to real spaces.
  1326. */
  1327. public static function rawUrlEncodeJS($str) {
  1328. return str_replace('%20', ' ', rawurlencode($str));
  1329. }
  1330. /**
  1331. * rawurlencode which preserves "/" chars
  1332. * Usefull when filepaths should keep the "/" chars, but have all other special chars encoded.
  1333. * Usage: 5
  1334. *
  1335. * @param string Input string
  1336. * @return string Output string
  1337. */
  1338. public static function rawUrlEncodeFP($str) {
  1339. return str_replace('%2F', '/', rawurlencode($str));
  1340. }
  1341. /**
  1342. * Checking syntax of input email address
  1343. * Usage: 5
  1344. *
  1345. * @param string Input string to evaluate
  1346. * @return boolean Returns true if the $email address (input string…

Large files files are truncated, but you can click here to view the full file