PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/library/Framework/Framework.Functions.php

https://github.com/dinotest/vanilla-test
PHP | 1010 lines | 764 code | 93 blank | 153 comment | 268 complexity | 6b45af085488b07d0b8c3c3960d57eb6 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. <?php
  2. /**
  3. * Non-application specific helper functions
  4. * Applications utilizing this file: Vanilla; Filebrowser;
  5. *
  6. * Copyright 2003 Mark O'Sullivan
  7. * This file is part of Lussumo's Software Library.
  8. * Lussumo's Software Library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
  9. * Lussumo's Software Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  10. * You should have received a copy of the GNU General Public License along with Vanilla; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  11. * The latest source code is available at www.lussumo.com
  12. * Contact Mark O'Sullivan at mark [at] lussumo [dot] com
  13. *
  14. * @author Mark O'Sullivan
  15. * @copyright 2003 Mark O'Sullivan
  16. * @license http://lussumo.com/community/gpl.txt GPL 2
  17. * @package Framework
  18. * @version @@FRAMEWORK-VERSION@@
  19. */
  20. function AddConfigurationSetting(&$Context, $SettingName, $SettingValue = '1') {
  21. if (!array_key_exists($SettingName, $Context->Configuration) || $Context->Configuration[$SettingName] != $SettingValue) {
  22. $Context->Configuration[$SettingName] = '';
  23. $SettingsManager = $Context->ObjectFactory->NewContextObject($Context, 'ConfigurationManager');
  24. $SettingsFile = $Context->Configuration['APPLICATION_PATH'].'conf/settings.php';
  25. $SettingsManager->DefineSetting($SettingName, $SettingValue, 1);
  26. $SettingsManager->SaveSettingsToFile($SettingsFile);
  27. }
  28. }
  29. function AddDaysToTimeStamp($TimeStamp, $NumberOfDaysToAdd) {
  30. if ($NumberOfDaysToAdd == 0) {
  31. return $TimeStamp;
  32. } else {
  33. return strtotime('+'.$NumberOfDaysToAdd.' day', $TimeStamp);
  34. }
  35. }
  36. // Append a folder (or file) to an existing path (ensures the / exists)
  37. function AppendFolder($RootPath, $FolderToAppend) {
  38. if (substr($RootPath, strlen($RootPath)-1, strlen($RootPath)) == '/') $RootPath = substr($RootPath, 0, strlen($RootPath) - 1);
  39. if (substr($FolderToAppend,0,1) == '/') $FolderToAppend = substr($FolderToAppend,1,strlen($FolderToAppend));
  40. return $RootPath.'/'.$FolderToAppend;
  41. }
  42. /**
  43. * Appends code to a php file, typically used for configuration.
  44. *
  45. * The php ending tag "?>" should be either on its own line,
  46. * or be ommited all together
  47. *
  48. * @param string $File Path to configuration file.
  49. * @param string $Append Code to append.
  50. * @return boolean
  51. */
  52. function AppendToConfigurationFile($File, $Append) {
  53. $Success = 0;
  54. if (file_exists($File)) {
  55. $Lines = file($File);
  56. for ($i=0, $c=count($Lines); $i < $c; $i++) {
  57. if (substr(trim($Lines[$i]), 0, 2) == '?>') {
  58. array_splice($Lines, $i);
  59. break;
  60. }
  61. }
  62. $Lines[] = rtrim($Append) . "\r\n";
  63. $Handle = @fopen($File, 'wb');
  64. if ($Handle) {
  65. $Success = @fwrite($Handle, implode('', $Lines));
  66. @fclose($Handle);
  67. }
  68. }
  69. return $Success;
  70. }
  71. /**
  72. * Makes sure that a url and some parameters are concatentated properly
  73. * (ie. an ampersand is used instead of a question mark when necessary)
  74. *
  75. * @param string $Url
  76. * @param string $Parameters
  77. * @return string
  78. */
  79. function AppendUrlParameters($Url, $Parameters) {
  80. $ReturnUrl = $Url;
  81. $ReturnUrl .= (strpos($Url, '?') === false) ? '?' : '&';
  82. $ReturnUrl .= $Parameters;
  83. return $ReturnUrl;
  84. }
  85. // Make sure objects can be cloned in PHP 4 and 5.
  86. // Example: $NewObject = clone ($ObjectName);
  87. // Note: Make sure the space appears between "clone" and the
  88. // first parentheses so that the clone statement in 5
  89. // doesn't break.
  90. if (version_compare(phpversion(), '5.0') < 0) {
  91. eval('
  92. function clone($object) {
  93. return $object;
  94. }
  95. ');
  96. }
  97. // Append two paths
  98. function ConcatenatePath($OriginalPath, $PathToConcatenate) {
  99. global $Configuration;
  100. if (strpos($PathToConcatenate, $Configuration['HTTP_METHOD'].'://') !== false) return $PathToConcatenate;
  101. if (substr($OriginalPath, strlen($OriginalPath)-1, strlen($OriginalPath)) != '/') $OriginalPath .= '/';
  102. if (substr($PathToConcatenate,0,1) == '/') $PathToConcatenate = substr($PathToConcatenate,1,strlen($PathToConcatenate));
  103. return $OriginalPath.$PathToConcatenate;
  104. }
  105. // Based on the total number of items and the number of items per page,
  106. // this function will calculate how many pages there are.
  107. // Returns the number of pages available
  108. function CalculateNumberOfPages($ItemCount, $ItemsPerPage) {
  109. $TmpCount = ($ItemCount/$ItemsPerPage);
  110. $RoundedCount = intval($TmpCount);
  111. $PageCount = 0;
  112. if ($TmpCount > 1) {
  113. if ($TmpCount > $RoundedCount) {
  114. $PageCount = $RoundedCount + 1;
  115. } else {
  116. $PageCount = $RoundedCount;
  117. }
  118. } else {
  119. $PageCount = 1;
  120. }
  121. return $PageCount;
  122. }
  123. function CleanupString($InString) {
  124. $Code = explode(',', '&lt;,&gt;,&#039;,&amp;,&quot;,À,Á,Â,Ã,Ä,&Auml;,Å,Ā,Ą,Ă,Æ,Ç,Ć,Č,Ĉ,Ċ,Ď,Đ,Ð,È,É,Ê,Ë,Ē,Ę,Ě,Ĕ,Ė,Ĝ,Ğ,Ġ,Ģ,Ĥ,Ħ,Ì,Í,Î,Ï,Ī,Ĩ,Ĭ,Į,İ,IJ,Ĵ,Ķ,Ł,Ľ,Ĺ,Ļ,Ŀ,Ñ,Ń,Ň,Ņ,Ŋ,Ò,Ó,Ô,Õ,Ö,&Ouml;,Ø,Ō,Ő,Ŏ,Œ,Ŕ,Ř,Ŗ,Ś,Š,Ş,Ŝ,Ș,Ť,Ţ,Ŧ,Ț,Ù,Ú,Û,Ü,Ū,&Uuml;,Ů,Ű,Ŭ,Ũ,Ų,Ŵ,Ý,Ŷ,Ÿ,Ź,Ž,Ż,Þ,Þ,à,á,â,ã,ä,&auml;,å,ā,ą,ă,æ,ç,ć,č,ĉ,ċ,ď,đ,ð,è,é,ê,ë,ē,ę,ě,ĕ,ė,ƒ,ĝ,ğ,ġ,ģ,ĥ,ħ,ì,í,î,ï,ī,ĩ,ĭ,į,ı,ij,ĵ,ķ,ĸ,ł,ľ,ĺ,ļ,ŀ,ñ,ń,ň,ņ,ʼn,ŋ,ò,ó,ô,õ,ö,&ouml;,ø,ō,ő,ŏ,œ,ŕ,ř,ŗ,š,ù,ú,û,ü,ū,&uuml;,ů,ű,ŭ,ũ,ų,ŵ,ý,ÿ,ŷ,ž,ż,ź,þ,ß,ſ,А,Б,В,Г,Д,Е,Ё,Ж,З,И,Й,К,Л,М,Н,О,П,Р,С,Т,У,Ф,Х,Ц,Ч,Ш,Щ,Ъ,Ы,Э,Ю,Я,а,б,в,г,д,е,ё,ж,з,и,й,к,л,м,н,о,п,р,с,т,у,ф,х,ц,ч,ш,щ,ъ,ы,э,ю,я');
  125. $Translation = explode(',', ',,,,,A,A,A,A,Ae,A,A,A,A,A,Ae,C,C,C,C,C,D,D,D,E,E,E,E,E,E,E,E,E,G,G,G,G,H,H,I,I,I,I,I,I,I,I,I,IJ,J,K,K,K,K,K,K,N,N,N,N,N,O,O,O,O,Oe,Oe,O,O,O,O,OE,R,R,R,S,S,S,S,S,T,T,T,T,U,U,U,Ue,U,Ue,U,U,U,U,U,W,Y,Y,Y,Z,Z,Z,T,T,a,a,a,a,ae,ae,a,a,a,a,ae,c,c,c,c,c,d,d,d,e,e,e,e,e,e,e,e,e,f,g,g,g,g,h,h,i,i,i,i,i,i,i,i,i,ij,j,k,k,l,l,l,l,l,n,n,n,n,n,n,o,o,o,o,oe,oe,o,o,o,o,oe,r,r,r,s,u,u,u,ue,u,ue,u,u,u,u,u,w,y,y,y,z,z,z,t,ss,ss,A,B,V,G,D,E,YO,ZH,Z,I,Y,K,L,M,N,O,P,R,S,T,U,F,H,C,CH,SH,SCH,Y,Y,E,YU,YA,a,b,v,g,d,e,yo,zh,z,i,y,k,l,m,n,o,p,r,s,t,u,f,h,c,ch,sh,sch,y,y,e,yu,ya');
  126. $sReturn = $InString;
  127. $sReturn = str_replace($Code, $Translation, $sReturn);
  128. $sReturn = urldecode($sReturn);
  129. $sReturn = preg_replace('/[^A-Za-z0-9 ]/', '', $sReturn);
  130. $sReturn = str_replace(' ', '-', $sReturn);
  131. return strtolower(str_replace('--', '-', $sReturn));
  132. }
  133. function CreateArrayEntry(&$Array, $Key, $Value) {
  134. if (!array_key_exists($Key, $Array)) $Array[$Key] = $Value;
  135. }
  136. // performs the opposite of htmlentities
  137. function DecodeHtmlEntities($String) {
  138. /*
  139. $TranslationTable = get_html_translation_table(HTML_ENTITIES);
  140. print_r($TranslationTable);
  141. $TranslationTable = array_flip($TranslationTable);
  142. return strtr($String, $TranslationTable);
  143. return html_entity_decode(htmlentities($String, ENT_COMPAT, 'UTF-8'));
  144. */
  145. $String= html_entity_decode($String,ENT_QUOTES,'ISO-8859-1'); #NOTE: UTF-8 does not work!
  146. $String= preg_replace('/&#(\d+);/me','chr(\\1)',$String); #decimal notation
  147. $String= preg_replace('/&#x([a-f0-9]+);/mei','chr(0x\\1)',$String); #hex notation
  148. return $String;
  149. }
  150. // Functions
  151. function DefineExtensions(&$Context) {
  152. $Extensions = array();
  153. $CurrExtensions = array();
  154. $CurrentExtensions = @file($Context->Configuration["APPLICATION_PATH"].'conf/extensions.php');
  155. if (!$CurrentExtensions) {
  156. $Context->WarningCollector->Add($Context->GetDefinition('ErrReadFileExtensions').$Context->Configuration["APPLICATION_PATH"].'conf/extensions.php');
  157. } else {
  158. foreach ($CurrentExtensions as $ExLine) {
  159. if (substr($ExLine, 0, 7) == 'include') {
  160. $CurrExtensions[] = substr(trim($ExLine), 43, -15);
  161. }
  162. }
  163. }
  164. // Examine Extensions directory
  165. $FolderHandle = @opendir($Context->Configuration["EXTENSIONS_PATH"]);
  166. if (!$FolderHandle) {
  167. $Context->WarningCollector->Add(
  168. str_replace("//1", $Context->Configuration["EXTENSIONS_PATH"], $Context->GetDefinition('ErrOpenDirectoryExtensions')));
  169. return false;
  170. } else {
  171. // Loop through each Extension folder
  172. while (false !== ($Item = readdir($FolderHandle))) {
  173. $Extension = $Context->ObjectFactory->NewObject($Context, 'Extension');
  174. $RecordItem = true;
  175. // skip directories and hidden files
  176. if (
  177. strlen($Item) < 1
  178. || !is_dir($Context->Configuration["EXTENSIONS_PATH"].$Item)
  179. || !file_exists($Context->Configuration["EXTENSIONS_PATH"].$Item.'/default.php')
  180. ) continue;
  181. // Retrieve Extension properties
  182. $Lines = @file($Context->Configuration["EXTENSIONS_PATH"].$Item.'/default.php');
  183. if (!$Lines) {
  184. $Context->WarningCollector->Add($Context->GetDefinition('ErrReadExtensionDefinition')." {$Item}");
  185. } else {
  186. // We only examine the first 30 lines of the file
  187. $Header = array_slice($Lines, 0, 30);
  188. $Extension->FileName = $Item."/default.php";
  189. foreach ($Header as $CurrentLine) {
  190. @list($key, $val) = @explode(': ', trim($CurrentLine), 2);
  191. switch ($key) {
  192. case 'Extension Name':
  193. $Extension->Name = FormatStringForDisplay($val);
  194. break;
  195. case 'Extension Url':
  196. $Extension->Url = FormatStringForDisplay($val);
  197. break;
  198. case 'Description':
  199. $Extension->Description = FormatStringForDisplay($val);
  200. break;
  201. case 'Version':
  202. $Extension->Version = FormatStringForDisplay($val);
  203. break;
  204. case 'Author':
  205. $Extension->Author = FormatStringForDisplay($val);
  206. break;
  207. case 'Author Url':
  208. $Extension->AuthorUrl = FormatStringForDisplay($val);
  209. break;
  210. default:
  211. // nothing
  212. }
  213. }
  214. if ($Extension->IsValid()) {
  215. $Extension->Enabled = in_array($Item, $CurrExtensions);
  216. $Extensions[FormatExtensionKey($Extension->Name)] = $Extension;
  217. }
  218. }
  219. }
  220. ksort($Extensions);
  221. return $Extensions;
  222. }
  223. }
  224. // This function is compliments of Entriple on the Lussumo Community
  225. function DefineVerificationKey() {
  226. return md5(
  227. sprintf(
  228. '%04x%04x%04x%03x4%04x%04x%04x%04x',
  229. mt_rand(0, 65535),
  230. mt_rand(0, 65535),
  231. mt_rand(0, 4095),
  232. bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '01', 6, 2)),
  233. mt_rand(0, 65535),
  234. mt_rand(0, 65535),
  235. mt_rand(0, 65535),
  236. mt_rand(0, 65535)
  237. )
  238. );
  239. }
  240. if (!function_exists('file_get_contents')) {
  241. /**
  242. * file_get_contents function for php 4.1.x and 4.2.x
  243. *
  244. * It is not the equivalent of the built-in php one
  245. * since it will always read the file in binary mode.
  246. *
  247. * @param string $FileName
  248. * @return unknown
  249. */
  250. function file_get_contents($FileName) {
  251. $Fp = fopen($FileName, 'rb');
  252. if ($Fp) {
  253. $Content = '';
  254. while (!feof($Fp)) {
  255. $Content .= fread($Fp, 4096);
  256. }
  257. return $Content;
  258. }
  259. return false;
  260. }
  261. }
  262. // return the opposite of the given boolean value
  263. function FlipBool($Bool) {
  264. $Bool = ForceBool($Bool, 0);
  265. return $Bool?0:1;
  266. }
  267. // Take a value and force it to be an array.
  268. function ForceArray($InValue, $DefaultValue) {
  269. if(is_array($InValue)) {
  270. $aReturn = $InValue;
  271. } else {
  272. // assume it's a string
  273. $sReturn = trim($InValue);
  274. $length = strlen($sReturn);
  275. if (empty($length) && strlen($sReturn) == 0) {
  276. $aReturn = $DefaultValue;
  277. } else {
  278. $aReturn = array($sReturn);
  279. }
  280. }
  281. return $aReturn;
  282. }
  283. // Force a boolean value
  284. // Accept a default value if the input value does not represent a boolean value
  285. function ForceBool($InValue, $DefaultBool) {
  286. // If the invalue doesn't exist (ie an array element that doesn't exist) use the default
  287. if (!$InValue) return $DefaultBool;
  288. $InValue = strtoupper($InValue);
  289. if ($InValue == 1) {
  290. return 1;
  291. } elseif ($InValue === 0) {
  292. return 0;
  293. } elseif ($InValue == 'Y') {
  294. return 1;
  295. } elseif ($InValue == 'N') {
  296. return 0;
  297. } elseif ($InValue == 'TRUE') {
  298. return 1;
  299. } elseif ($InValue == 'FALSE') {
  300. return 0;
  301. } else {
  302. return $DefaultBool;
  303. }
  304. }
  305. // Take a value and force it to be a float (decimal) with a specific number of decimal places.
  306. function ForceFloat($InValue, $DefaultValue, $DecimalPlaces = 2) {
  307. $fReturn = floatval($InValue);
  308. if ($fReturn == 0) $fReturn = $DefaultValue;
  309. $fReturn = number_format($fReturn, $DecimalPlaces);
  310. return $fReturn;
  311. }
  312. // Check both the get and post incoming data for a variable
  313. function ForceIncomingArray($VariableName, $DefaultValue) {
  314. // First check the querystring
  315. $aReturn = ForceSet(@$_GET[$VariableName], $DefaultValue);
  316. $aReturn = ForceArray($aReturn, $DefaultValue);
  317. // If the default value was defined, then check the post variables
  318. if ($aReturn == $DefaultValue) {
  319. $aReturn = ForceSet(@$_POST[$VariableName], $DefaultValue);
  320. $aReturn = ForceArray($aReturn, $DefaultValue);
  321. }
  322. return $aReturn;
  323. }
  324. // Check both the get and post incoming data for a variable
  325. function ForceIncomingBool($VariableName, $DefaultBool) {
  326. // First check the querystring
  327. $bReturn = ForceSet(@$_GET[$VariableName], $DefaultBool);
  328. $bReturn = ForceBool($bReturn, $DefaultBool);
  329. // If the default value was defined, then check the post variables
  330. if ($bReturn == $DefaultBool) {
  331. $bReturn = ForceSet(@$_POST[$VariableName], $DefaultBool);
  332. $bReturn = ForceBool($bReturn, $DefaultBool);
  333. }
  334. return $bReturn;
  335. }
  336. function ForceIncomingCookieString($VariableName, $DefaultValue) {
  337. $sReturn = ForceSet(@$_COOKIE[$VariableName], $DefaultValue);
  338. $sReturn = ForceString($sReturn, $DefaultValue);
  339. return $sReturn;
  340. }
  341. // Check both the get and post incoming data for a variable
  342. // Does not allow integers to be less than 0
  343. function ForceIncomingInt($VariableName, $DefaultValue) {
  344. // First check the querystring
  345. $iReturn = ForceSet(@$_GET[$VariableName], $DefaultValue);
  346. $iReturn = ForceInt($iReturn, $DefaultValue);
  347. // If the default value was defined, then check the form variables
  348. if ($iReturn == $DefaultValue) {
  349. $iReturn = ForceSet(@$_POST[$VariableName], $DefaultValue);
  350. $iReturn = ForceInt($iReturn, $DefaultValue);
  351. }
  352. // If the value found was less than 0, set it to the default value
  353. if($iReturn < 0) $iReturn = $DefaultValue;
  354. return $iReturn;
  355. }
  356. // Check both the get and post incoming data for a variable
  357. function ForceIncomingString($VariableName, $DefaultValue) {
  358. if (isset($_GET[$VariableName])) {
  359. return Strip_Slashes(ForceString($_GET[$VariableName], $DefaultValue));
  360. } elseif (isset($_POST[$VariableName])) {
  361. return Strip_Slashes(ForceString($_POST[$VariableName], $DefaultValue));
  362. } else {
  363. return $DefaultValue;
  364. }
  365. }
  366. // Take a value and force it to be an integer.
  367. function ForceInt($InValue, $DefaultValue) {
  368. $iReturn = intval($InValue);
  369. return ($iReturn == 0) ? $DefaultValue : $iReturn;
  370. }
  371. // Takes a variable and checks to see if it's set.
  372. // Returns the value if set, or the default value if not set.
  373. function ForceSet($InValue, $DefaultValue) {
  374. return isset($InValue) ? $InValue : $DefaultValue;
  375. }
  376. // Take a value and force it to be a string.
  377. function ForceString($InValue, $DefaultValue) {
  378. if (is_string($InValue)) {
  379. $sReturn = trim($InValue);
  380. if (empty($sReturn) && strlen($sReturn) == 0) $sReturn = $DefaultValue;
  381. } else {
  382. $sReturn = $DefaultValue;
  383. }
  384. return $sReturn;
  385. }
  386. /**
  387. * Check if the cookie domain is valid.
  388. * @todo the Pattern is quite loose
  389. * (don't ckeck the doamin names start by a letter or a digit, allow domain)
  390. * @param $CookieDomain string
  391. * @return string
  392. */
  393. function FormatCookieDomain($CookieDomain) {
  394. $Pattern = '/^[\.-_~a-zA-Z0-9]*\.?[-_~a-zA-Z0-9]+\.[-_~a-zA-Z0-9]+$/';
  395. $Match = preg_match($Pattern, $CookieDomain);
  396. if ($Match) {
  397. return $CookieDomain;
  398. } else {
  399. return '';
  400. }
  401. }
  402. function FormatExtensionKey($Key) {
  403. return preg_replace("/[^[:alnum:]]/i", '', unhtmlspecialchars($Key));
  404. }
  405. function FormatFileSize($FileSize) {
  406. if ($FileSize > 1048576) {
  407. return intval((($FileSize / 1048576) * 100) + 0.5) / 100 ."mb";
  408. } elseif ($FileSize > 1024) {
  409. return ceil($FileSize / 1024)."kb";
  410. } else {
  411. return $FileSize."b";
  412. }
  413. }
  414. function FormatHyperlink($InString, $ExternalTarget = '1', $LinkText = '', $CssClass = '') {
  415. $Display = $LinkText;
  416. if (strpos($InString, 'http://') == 0 && strpos($InString, 'http://') !== false) {
  417. if ($LinkText == '') {
  418. $Display = $InString;
  419. if (substr($Display, strlen($Display)-1,1) == '/') $Display = substr($Display, 0, strlen($Display)-1);
  420. $Display = str_replace('http://', '', $Display);
  421. }
  422. } elseif (strpos($InString, 'mailto:') == 0 && strpos($InString, 'mailto:') !== false) {
  423. if ($LinkText == '') {
  424. $Display = str_replace('mailto:', '', $InString);
  425. }
  426. } elseif (strpos($InString, 'ftp://') == 0 && strpos($InString, 'ftp://') !== false) {
  427. if ($LinkText == '') {
  428. $Display = str_replace('ftp://', '', $InString);
  429. }
  430. } elseif (strpos($InString, 'aim:goim?screenname=') == 0 && strpos($InString, 'aim:goim?screenname=') !== false) {
  431. if ($LinkText == '') {
  432. $Display = str_replace('aim:goim?screenname=', '', $InString);
  433. }
  434. } else {
  435. return $LinkText == '' ? $InString : $LinkText;
  436. }
  437. return '<a href="'.$InString.'"'.($CssClass != '' ? ' class="'.$CssClass.'"' : '').'>'.$Display.'</a>';
  438. }
  439. function FormatHtmlStringForNonDisplay($inValue) {
  440. return str_replace("\r\n", '<br />', htmlspecialchars($inValue));
  441. }
  442. function FormatHtmlStringInline($inValue, $StripSlashes = '0', $StripTags = '0') {
  443. // $sReturn = ForceString($inValue, '');
  444. $sReturn = $inValue;
  445. if ($StripTags) $sReturn = strip_tags($sReturn);
  446. if (ForceBool($StripSlashes, 0)) $sReturn = Strip_Slashes($sReturn);
  447. return str_replace("\r\n", ' ', htmlspecialchars($sReturn));
  448. }
  449. function FormatPlural($Number, $Singular, $Plural) {
  450. return ($Number == 1) ? $Singular : $Plural;
  451. }
  452. // Formats a value so it's safe to insert into the database
  453. function FormatStringForDatabaseInput($inValue, $bStripHtml = '0') {
  454. $bStripHtml = ForceBool($bStripHtml, 0);
  455. // $sReturn = stripslashes($inValue);
  456. $sReturn = $inValue;
  457. if ($bStripHtml) $sReturn = trim(strip_tags($sReturn));
  458. // return MAGIC_QUOTES_ON ? $sReturn : addslashes($sReturn);
  459. return addslashes($sReturn);
  460. }
  461. // Takes a user defined string and formats it for page display.
  462. // You can optionally remove html from the string.
  463. function FormatStringForDisplay($inValue, $bStripHtml = true, $AllowEncodedQuotes = true) {
  464. $sReturn = trim($inValue);
  465. if ($bStripHtml) $sReturn = strip_tags($sReturn);
  466. if (!$AllowEncodedQuotes) $sReturn = preg_replace('/("|\')/', '', $sReturn);
  467. global $Configuration;
  468. $sReturn = htmlspecialchars($sReturn, ENT_QUOTES, $Configuration['CHARSET']);
  469. if ($bStripHtml) $sReturn = str_replace("\r\n", "<br />", $sReturn);
  470. return $sReturn;
  471. }
  472. function GetBasicCheckBox($Name, $Value = 1, $Checked, $Attributes = '') {
  473. return '<input type="checkbox" name="'.$Name.'" value="'.$Value.'" '.(($Checked == 1)?' checked="checked"':'').' '.$Attributes.' />';
  474. }
  475. function GetBool($Bool, $True = 'Yes', $False = 'No') {
  476. return ($Bool ? $True : $False);
  477. }
  478. function GetDynamicCheckBox($Name, $Value = 1, $Checked, $OnClick, $Text, $Attributes = '', $CheckBoxID = '') {
  479. if ($CheckBoxID == '') $CheckBoxID = $Name.'ID';
  480. $Attributes .= ' id="'.$CheckBoxID.'"';
  481. if ($OnClick != '') $Attributes .= ' onclick="'.$OnClick.'"';
  482. return '<label for="'.$CheckBoxID.'">'.GetBasicCheckBox($Name, $Value, $Checked, $Attributes).' '.$Text.'</label>';
  483. }
  484. function GetEmail($Email, $LinkText = '') {
  485. if ($Email == '') {
  486. return '&nbsp;';
  487. } else {
  488. $EmailParts = explode('@', $Email);
  489. if (count($EmailParts) == 2) {
  490. $ScriptID = 'WriteEmail_' . rand();
  491. return "<script id=\"".$ScriptID."\" type=\"text/javascript\">\r\nWriteEmail('".$EmailParts[1]."', '".$EmailParts[0]."', '".$LinkText."', '".$ScriptID."');\r\n</script>";
  492. } else {
  493. // Failsafe
  494. return '<a href="mailto:'.$Email.'">'.($LinkText==''?$Email:$LinkText).'</a>';
  495. }
  496. }
  497. }
  498. function GetImage($ImageUrl, $Height = '', $Width = '', $TagIdentifier = '', $EmptyImageReplacement = '&nbsp;') {
  499. $sReturn = '';
  500. if (ReturnNonEmpty($ImageUrl) == '&nbsp;') {
  501. $sReturn = $EmptyImageReplacement;
  502. } else {
  503. $sReturn = '<img src="'.$ImageUrl.'"';
  504. if ($Height != '') $sReturn .= ' height="'.$Height.'"';
  505. if ($Width != '') $sReturn .= ' width="'.$Width.'"';
  506. if ($TagIdentifier != '') $sReturn .= ' id="'.$TagIdentifier.'"';
  507. $sReturn .= ' alt="" />';
  508. }
  509. return $sReturn;
  510. }
  511. function GetRemoteIp($FormatIpForDatabaseInput = '0') {
  512. $FormatIpForDatabaseInput = ForceBool($FormatIpForDatabaseInput, 0);
  513. $sReturn = ForceString(@$_SERVER['REMOTE_ADDR'], '');
  514. if (strlen($sReturn) > 20) $sReturn = substr($sReturn, 0, 19);
  515. if ($FormatIpForDatabaseInput) $sReturn = FormatStringForDatabaseInput($sReturn, 1);
  516. return $sReturn;
  517. }
  518. /**
  519. * Return the request URL
  520. *
  521. * The returned URL is tainted (based on $_SERVER['QUERY_STRING']).
  522. * However, by default ($FormatUrlForDisplay == true), the url is safe for html used.
  523. *
  524. * @param boolean $FormatUrlForDisplay Set to false to return an unformatted (and tainted) URL
  525. * @return string
  526. */
  527. function GetRequestUri($FormatUrlForDisplay='1') {
  528. global $Configuration;
  529. $Host = ForceString($_SERVER['HTTP_HOST'], '');
  530. if ($Host != '') $Host = PrependString($Configuration['HTTP_METHOD'].'://', $Host);
  531. $Path = @$_SERVER['REQUEST_URI'];
  532. // If the path wasn't provided in the REQUEST_URI variable, let's look elsewhere for it
  533. if ($Path == '') $Path = @$_SERVER['HTTP_X_REWRITE_URL']; // Some servers use this instead
  534. // If the path still wasn't found, let's try building it with other variables
  535. if ($Path == '') {
  536. $Path = @$_SERVER['SCRIPT_NAME'];
  537. $Path .= (@$_SERVER['QUERY_STRING'] == '' ? '' : '?' . @$_SERVER['QUERY_STRING']);
  538. }
  539. $FullPath = ConcatenatePath($Host, $Path);
  540. return $FormatUrlForDisplay ? FormatStringForDisplay($FullPath) : $FullPath;
  541. }
  542. function GetTableName($Key, $TableCollection, $Prefix) {
  543. global $DatabasePrefixLessTables;
  544. $DatabasePrefixLessTables = ForceArray($DatabasePrefixLessTables, array('User'));
  545. if (in_array($Key, $DatabasePrefixLessTables)) {
  546. return $TableCollection[$Key];
  547. } else {
  548. return $Prefix.$TableCollection[$Key];
  549. }
  550. }
  551. function GetUrl($Configuration, $PageName, $Divider = '', $Key = '', $Value = '', $PageNumber='', $Querystring='', $Suffix = '') {
  552. if ($Configuration['URL_BUILDING_METHOD'] == 'mod_rewrite') {
  553. if ($PageName == './') $PageName = 'index.php';
  554. return $Configuration['BASE_URL']
  555. .($PageName == 'index.php' && $Value != '' ? '' : $Configuration['REWRITE_'.$PageName])
  556. .(strlen($Value) != 0 ? $Divider : '')
  557. .(strlen($Value) != 0 ? $Value.'/' : '')
  558. .(($PageNumber != '' && $PageNumber != '0' && $PageNumber != '1') ? $PageNumber.'/' : '')
  559. .($Suffix != '' ? $Suffix : '')
  560. .($Querystring != '' && substr($Querystring, 0, 1) != '#' ? '?' : '')
  561. .($Querystring != '' ? $Querystring : '');
  562. } else {
  563. if ($PageName == './' || $PageName == 'index.php') $PageName = '';
  564. $sReturn = ($Value != '' && $Value != '0' ? $Key.'='.$Value : '');
  565. if ($PageNumber != '') {
  566. if ($sReturn != '') $sReturn .= '&amp;';
  567. $sReturn .= 'page='.$PageNumber;
  568. }
  569. if ($Querystring != '' && substr($Querystring, 0, 1) != '#') {
  570. if ($sReturn != '') $sReturn .= '&amp;';
  571. $sReturn .= $Querystring;
  572. }
  573. if ($sReturn != '') $sReturn = '?'.$sReturn;
  574. if ($Querystring != '' && substr($Querystring, 0, 1) == '#') $sReturn .= $Querystring;
  575. return $Configuration['BASE_URL'].$PageName.$sReturn;
  576. }
  577. }
  578. // Create the html_entity_decode function for users prior to PHP 4.3.0
  579. if (!function_exists('html_entity_decode')) {
  580. function html_entity_decode($String) {
  581. return strtr($String, array_flip(get_html_translation_table(HTML_ENTITIES)));
  582. }
  583. }
  584. // allows inline if statements
  585. function Iif($Condition, $True, $False) {
  586. return $Condition ? $True : $False;
  587. }
  588. function ThemeFile(&$Context, $FileName) {
  589. $ThemeFileArray = file(ThemeFilePath($Context->Configuration, $FileName));
  590. if (is_array($ThemeFileArray)) {
  591. $ThemeFile = implode('', $ThemeFileArray);
  592. return $ThemeFile;
  593. } else {
  594. // Throw a fatal error because the theme file wasn't found
  595. $Context->ErrorManager->AddError($Context, 'Framework.Functions', 'ThemeFile', 'The requested theme file could not be found.', $FileName, 1);
  596. }
  597. }
  598. // Checks for a custom version of the specified file
  599. // Returns the path to the custom file (if it exists) or the default otherwise
  600. function ThemeFilePath($Configuration, $FileName) {
  601. if (file_exists($Configuration['THEME_PATH'].$FileName)) {
  602. return $Configuration['THEME_PATH'].$FileName;
  603. } else {
  604. return $Configuration["APPLICATION_PATH"]."themes/".$FileName;
  605. }
  606. }
  607. function MysqlDateTime($Timestamp = '') {
  608. if ($Timestamp == '') $Timestamp = mktime();
  609. return date('Y-m-d H:i:s', $Timestamp);
  610. }
  611. function OpenURL($URL, &$Context) {
  612. $ParsedUrl = parse_url($URL);
  613. $Host = ForceString(@$ParsedUrl['host'], '');
  614. $Port = ForceInt(@$ParsedUrl['port'], 0);
  615. if ($Port == 0) $Port = 80;
  616. $Path = (array_key_exists('path', $ParsedUrl)) ? $ParsedUrl['path'] : '';
  617. if (empty($Path)) $Path = '/';
  618. if (array_key_exists('query', $ParsedUrl) && $ParsedUrl['query'] != '') {
  619. // Do some encoding and cleanup on the querystring
  620. $QueryString = urlencode($ParsedUrl['query']);
  621. $QueryString = str_replace(array('%26', '%3D'), array('&', '='), $QueryString);
  622. $Path .= '?' . $QueryString;
  623. }
  624. $UrlContents = false;
  625. if (empty($Host)) {
  626. $Context->WarningCollector->Add(str_replace('\\1', $URL, $Context->GetDefinition('InvalidHostName')));
  627. } else {
  628. $Headers = "GET $Path HTTP/1.0\r\nHost: $Host\r\n\r\n";
  629. // echo("<div>$Headers</div>");
  630. $ErrorNumber = '';
  631. $ErrorMessage = '';
  632. $Handle = @fsockopen($Host, $Port, $ErrorNumber, $ErrorMessage, 30);
  633. if (!$Handle) {
  634. $Context->WarningCollector->Add(str_replace('\\1', $Host, $Context->GetDefinition("ErrorFopen")).($php_errormsg ? str_replace('\\1', $php_errormsg, $Context->GetDefinition('ErrorFromPHP')) : ''));
  635. } else {
  636. fwrite($Handle, $Headers);
  637. $UrlContents = '';
  638. $HeaderFinished = false;
  639. $String = '';
  640. while (!feof($Handle)) {
  641. $String = fgets($Handle, 128);
  642. if ($HeaderFinished) $UrlContents .= $String;
  643. if ($String == "\r\n") $HeaderFinished = true;
  644. }
  645. fclose($Handle);
  646. }
  647. }
  648. return $UrlContents;
  649. }
  650. function PrefixString($string, $prefix, $length) {
  651. if (strlen($string) >= $length) {
  652. return $string;
  653. } else {
  654. return substr(($prefix.$string),strlen($prefix.$string)-$length, $length);
  655. }
  656. }
  657. function PrependString($Prepend, $String) {
  658. if ($String == '') return '';
  659. if (is_array($Prepend)){
  660. foreach ($Prepend as $str) {
  661. $pos = strpos(strtolower($String), strtolower($str));
  662. if ($pos !== false && $pos == 0) {
  663. $Prepend = '';
  664. }
  665. }
  666. // If the string doesn't start with any array elements, prepend the first element
  667. if ($Prepend <> '') $Prepend = $Prepend[0];
  668. } else {
  669. $pos = strpos(strtolower($String), strtolower($Prepend));
  670. if ($pos !== false && $pos == 0) $Prepend = '';
  671. }
  672. return $Prepend.$String;
  673. }
  674. /**
  675. * Redirect to an other page
  676. *
  677. * @todo Should the Location be encoded in function?
  678. * @param string $Location Absolute URL
  679. * @param string $Code Status code
  680. * @param string $Name Name of the page
  681. * @param bool $Die Should the script terminate
  682. * @return void
  683. */
  684. function Redirect($Location, $Code = '302', $Name = '', $Die = 1) {
  685. // Set status
  686. $CodeList = array(
  687. '301' => 'Moved Permanently',
  688. '303' => 'See Other'
  689. );
  690. if ($Code && array_key_exists($Code, $CodeList)) {
  691. Header( 'HTTP/1.1 ' . $Code . ' ' . $CodeList[$Code] );
  692. }
  693. //Strip CRLFs and replace &amp; with & (case insensitive)
  694. $Location = preg_replace(array('/\r\n/', '/&amp;/i'), array('', '&'), $Location);
  695. //$Location have to be well encoded.
  696. header('Location: ' . $Location);
  697. if ($Die) {
  698. @ob_end_clean();
  699. if (isset($_SERVER['REQUEST_METHOD']) &&
  700. $_SERVER['REQUEST_METHOD'] != 'HEAD')
  701. {
  702. if (!$Name) {
  703. $Name = $Location;
  704. }
  705. // display a lick in case the redirect fails
  706. echo '<a href="' . $Location . '">' . FormatStringForDisplay($Name) . '</a>';
  707. }
  708. //global $Context;
  709. //$Context->Unload();
  710. die();
  711. }
  712. }
  713. function RemoveIllegalChars($FileName) {
  714. return preg_replace('![\s<"\']+!s', '', $FileName);
  715. }
  716. function RenderThemeFile($Context, $ThemeFile) {
  717. echo $ThemeFile;
  718. }
  719. function ReplaceThemeFile($Context, $Replacements, $ThemeFile) {
  720. $theme_file = $ThemeFile;
  721. // Perform standard replacements
  722. while (list($key, $replacement) = each($Replacements)) {
  723. $theme_file = str_replace('['.$key.']', $replacement, $theme_file);
  724. }
  725. // Perform dictionary replacements
  726. // Perform configuration replacements
  727. return $theme_file;
  728. }
  729. // If a value is empty, return the non-empty value
  730. function ReturnNonEmpty($InValue, $NonEmptyValue = '&nbsp;') {
  731. return trim($InValue) == '' ? $NonEmptyValue : $InValue;
  732. }
  733. function SaveAsDialogue($FolderPath, $FileName, $DeleteFile = '0') {
  734. $DeleteFile = ForceBool($DeleteFile, 0);
  735. if ($FolderPath != '') {
  736. if (substr($FolderPath,strlen($FolderPath)-1) != '/') $FolderPath = $FolderPath.'/';
  737. }
  738. $FolderPath = $FolderPath.$FileName;
  739. header('Pragma: public');
  740. header('Expires: 0');
  741. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  742. header('Content-Type: application/force-download');
  743. header('Content-Type: application/octet-stream');
  744. header('Content-Type: application/download');
  745. header('Content-Disposition: attachment; filename="'.$FileName.'"');
  746. header('Content-Transfer-Encoding: binary');
  747. readfile($FolderPath);
  748. if ($DeleteFile) unlink($FolderPath);
  749. die();
  750. }
  751. function SerializeArray($InArray) {
  752. $sReturn = '';
  753. if (is_array($InArray)) {
  754. if (count($InArray) > 0) {
  755. $sReturn = serialize($InArray);
  756. $sReturn = addslashes($sReturn);
  757. }
  758. }
  759. return $sReturn;
  760. }
  761. // Cuts a string to the specified length.
  762. // Then moves back to the previous space so words are not sliced half-way through.
  763. function SliceString($InString, $Length) {
  764. $Space = ' ';
  765. $sReturn = '';
  766. if (strlen($InString) > $Length) {
  767. $sReturn = substr(trim($InString), 0, $Length);
  768. $sReturn = substr($sReturn, 0, strlen($sReturn) - strpos(strrev($sReturn), $Space));
  769. $sReturn .= '...';
  770. } else {
  771. $sReturn = $InString;
  772. }
  773. return $sReturn;
  774. }
  775. function Strip_Slashes($InString) {
  776. return MAGIC_QUOTES_ON ? stripslashes($InString) : $InString;
  777. }
  778. function SubtractDaysFromTimeStamp($TimeStamp, $NumberOfDaysToSubtract) {
  779. if ($NumberOfDaysToSubtract == 0) {
  780. return $TimeStamp;
  781. } else {
  782. return strtotime('-'.$NumberOfDaysToSubtract.' day', $TimeStamp);
  783. }
  784. }
  785. function TimeDiff(&$Context, $Time, $TimeToCompare = '') {
  786. if ($TimeToCompare == '') $TimeToCompare = time();
  787. $Difference = $TimeToCompare-$Time;
  788. $Days = floor($Difference/60/60/24);
  789. if ($Days > 7) {
  790. return date($Context->GetDefinition('OldPostDateFormatCode'), $Time);
  791. } elseif ($Days > 1) {
  792. return str_replace('//1', $Days, $Context->GetDefinition('XDaysAgo'));
  793. } elseif ($Days == 1) {
  794. return str_replace('//1', $Days, $Context->GetDefinition('XDayAgo'));
  795. } else {
  796. $Difference -= $Days*60*60*24;
  797. $Hours = floor($Difference/60/60);
  798. if ($Hours > 1) {
  799. return str_replace('//1', $Hours, $Context->GetDefinition('XHoursAgo'));
  800. } elseif ($Hours == 1) {
  801. return str_replace('//1', $Hours, $Context->GetDefinition('XHourAgo'));
  802. } else {
  803. $Difference -= $Hours*60*60;
  804. $Minutes = floor($Difference/60);
  805. if ($Minutes > 1) {
  806. return str_replace('//1', $Minutes, $Context->GetDefinition('XMinutesAgo'));
  807. } elseif ($Minutes == 1) {
  808. return str_replace('//1', $Minutes, $Context->GetDefinition('XMinuteAgo'));
  809. } else {
  810. $Difference -= $Minutes*60;
  811. $Seconds = $Difference;
  812. if ($Seconds == 1) {
  813. return str_replace('//1', $Seconds, $Context->GetDefinition('XSecondAgo'));
  814. } else {
  815. return str_replace('//1', $Seconds, $Context->GetDefinition('XSecondsAgo'));
  816. }
  817. }
  818. }
  819. }
  820. }
  821. function unhtmlspecialchars($String) {
  822. $String = str_replace('&amp;', '&', $String);
  823. $String = str_replace('&#039;', '\'', $String);
  824. $String = str_replace('&quot;', '\"', $String);
  825. $String = str_replace('&lt;', '<', $String);
  826. $String = str_replace('&gt;', '>', $String);
  827. return $String;
  828. }
  829. // Convert a datetime to a timestamp
  830. function UnixTimestamp($DateTime) {
  831. if (preg_match('/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/', $DateTime, $Matches)) {
  832. $Year = $Matches[1];
  833. $Month = $Matches[2];
  834. $Day = $Matches[3];
  835. $Hour = $Matches[4];
  836. $Minute = $Matches[5];
  837. $Second = $Matches[6];
  838. return mktime($Hour, $Minute, $Second, $Month, $Day, $Year);
  839. } elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $DateTime, $Matches)) {
  840. $Year = $Matches[1];
  841. $Month = $Matches[2];
  842. $Day = $Matches[3];
  843. return mktime(0, 0, 0, $Month, $Day, $Year);
  844. }
  845. }
  846. function UnserializeArray($InSerialArray) {
  847. $aReturn = array();
  848. if ($InSerialArray != '' && !is_array($InSerialArray)) {
  849. $aReturn = unserialize($InSerialArray);
  850. if (is_array($aReturn)) {
  851. $Count = count($aReturn);
  852. $i = 0;
  853. for ($i = 0; $i < $Count; $i++) {
  854. $aReturn[$i] = array_map('Strip_Slashes', $aReturn[$i]);
  855. }
  856. }
  857. }
  858. return $aReturn;
  859. }
  860. function UnserializeAssociativeArray($InSerialArray) {
  861. $aReturn = array();
  862. if ($InSerialArray != '' && !is_array($InSerialArray)) {
  863. $aReturn = @unserialize($InSerialArray);
  864. if (!is_array($aReturn)) $aReturn = array();
  865. }
  866. return $aReturn;
  867. }
  868. // Instantiate a simple validator
  869. function Validate($InputName, $IsRequired, $Value, $MaxLength, $ValidationExpression, &$Context) {
  870. $Validator = $Context->ObjectFactory->NewContextObject($Context, 'Validator');
  871. $Validator->InputName = $InputName;
  872. $Validator->isRequired = $IsRequired;
  873. $Validator->Value = $Value;
  874. $Validator->MaxLength = $MaxLength;
  875. if ($ValidationExpression != '') {
  876. $Validator->ValidationExpression = $ValidationExpression;
  877. $Validator->ValidationExpressionErrorMessage = $Context->GetDefinition('ErrImproperFormat').' '.$InputName;
  878. }
  879. return $Validator->Validate();
  880. }
  881. function WriteEmail($Email, $LinkText = '') {
  882. echo(GetEmail($Email, $LinkText));
  883. }
  884. // Taken and modified from Mark's CategoryJumper extension
  885. function MoveDiscussionForm(&$Context, $SessionPostBackKey, $DiscussionID) {
  886. $CategoryManager = $Context->ObjectFactory->NewContextObject($Context, 'CategoryManager');
  887. $CategoryData = $CategoryManager->GetCategories(0, 1);
  888. if (!$CategoryData) {
  889. return '';
  890. }
  891. else {
  892. $Select = $Context->ObjectFactory->NewObject($Context, 'Select');
  893. $Select->Name = 'CategoryID';
  894. $Select->SelectedValue = ForceIncomingInt('MoveDiscussionDropdown', 0);
  895. $Select->Attributes .= " id=\"MoveDiscussionDropdown\" onchange=\"if (confirm('".$Context->GetDefinition("ConfirmMoveDiscussion")."')) DiscussionSwitch('".$Context->Configuration['WEB_ROOT']."ajax/switch.php', 'Move', '".$DiscussionID."', ''+this.options[this.selectedIndex].value+'', 'MoveDiscussion', '".$SessionPostBackKey."'); return false;\"";
  896. $Select->AddOption(0, $Context->GetDefinition('SelectCategoryToMoveTo'));
  897. $LastBlocked = -1;
  898. $cat = $Context->ObjectFactory->NewObject($Context, 'Category');
  899. while ($Row = $Context->Database->GetRow($CategoryData)) {
  900. $cat->Clear();
  901. $cat->GetPropertiesFromDataSet($Row);
  902. if ($cat->Blocked != $LastBlocked && $LastBlocked != -1) {
  903. $Select->AddOption('-1', '---', " disabled=\"disabled\"");
  904. }
  905. $Select->AddOption($cat->CategoryID, $cat->Name);
  906. $LastBlocked = $cat->Blocked;
  907. }
  908. return "<form id=\"frmMoveDiscussion\"
  909. name=\"frmMoveDiscussion\"
  910. method=\"post\"
  911. action=\"".$Context->Configuration['WEB_ROOT']."post.php\">".
  912. $Select->Get()."
  913. </form>";
  914. }
  915. }
  916. ?>