PageRenderTime 57ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/inc/functions/shared.php

https://github.com/asdfdotdev/Helios-Calendar
PHP | 1187 lines | 909 code | 60 blank | 218 comment | 93 complexity | b9f9f2eb61adf88615ad7826fae5a42f MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * @package Helios Calendar
  4. * @license GNU General Public License version 2 or later; see LICENSE
  5. */
  6. if(!defined('isHC')){exit(-1);}
  7. require_once(HCPATH."/inc/dbwrapper.php");
  8. /**
  9. * Writes cache files.
  10. * @since 2.0.0
  11. * @version 2.2.1
  12. * @param int $cID Cache file to be created 0 = settings.php, 1 = settings_named.php, 2 = locList(a).php, 3 = meta.php, 4 = selCity(a).php, 5 = selPostal(a).php, 6 = Cache Age File (Default:0)
  13. * @param int $a [optional] Version of file to create. 0 = public calendar, 1 = admin console (Default:0, Used for $cID = 2/4/5 only.)
  14. * @return void
  15. */
  16. function buildCache($cID = 0, $a = 0){
  17. global $hc_cfg, $hc_lang_search;
  18. if(!is_writable(HCPATH.'/cache/'))
  19. exit("Cache directory cannot be written to.");
  20. $f = ($a == 1) ? 'a' : '';
  21. $hc_fetch_settings = '1,2,3,4,7,8,9,10,11,12,13,14,15,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,40,41,42,43,44,45,48,49,';
  22. $hc_fetch_settings .= '50,51,52,54,53,55,56,59,60,61,62,63,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,';
  23. $hc_fetch_settings .= '90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,113,114,115,126,127,128,129,130,131,132,133,134';
  24. switch($cID){
  25. case 1:
  26. if(defined('HC_Named')){
  27. if(!file_exists(HCPATH . '/cache/settings_named.php')){
  28. $result = doQuery("SELECT PkID, Name FROM " . HC_TblPrefix . "settings WHERE PkID IN (".$hc_fetch_settings.") AND SettingValue != '' AND Name IS NOT NULL ORDER BY Name");
  29. if(hasRows($result)){
  30. ob_start();
  31. $fp = fopen(HCPATH . '/cache/settings_named.php', 'w');
  32. fwrite($fp, "<?php\n//\tHelios Named Config Cache - Delete this file when upgrading.\n\n");
  33. fwrite($fp, "\$hc_cfg_named = array(\n");
  34. while($row = hc_mysql_fetch_row($result)){
  35. fwrite($fp, "'" . $row[1] . "'\t=>\t\$hc_cfg[".$row[0]."],\n");
  36. }
  37. fwrite($fp, "'category_columns'\t=>\t\$hc_cfg['CatCols'],\n");
  38. fwrite($fp, ");\n?>");
  39. fclose($fp);
  40. ob_end_clean();
  41. } else {
  42. exit(handleError(0, "Setting Data Missing."));
  43. }
  44. }
  45. }
  46. break;
  47. case 2:
  48. if(!file_exists(HCPATH.'/cache/locList'.$f.'.php')){
  49. $q = ($a == 0) ? 'AND IsPublic = 1' : '';
  50. $result = doQuery("SELECT PkID, Name FROM " . HC_TblPrefix . "locations WHERE IsActive = 1 " . $q . " ORDER BY Name");
  51. ob_start();
  52. $fp = fopen(HCPATH.'/cache/locList'.$f.'.php', 'w');
  53. fwrite($fp, "<?php\n//\tHelios Location List - Delete this file when upgrading.\n\n");
  54. fwrite($fp, "\$NewAll = (isset(\$NewAll)) ? \$NewAll : '';?>\n\n");
  55. echo '<select name="locListI" id="locListI" onchange="if(isNaN(this.options[this.selectedIndex].value)){splitLocation(this.options[this.selectedIndex].value);}">';
  56. if(hasRows($result)){
  57. echo "\n\t" . '<option value="0|"><?php echo $NewAll;?></option>';
  58. echo "\n\t" . '<option value="-1">-------------------------</option>';
  59. while($row = hc_mysql_fetch_row($result)){
  60. echo "\n\t" . '<option value="'.$row[0].'|'.cOut($row[1]).'">' . cOut($row[1]) . '</option>';
  61. }
  62. } else {
  63. echo "\n\t" . '<option value="0">' . $hc_lang_core['NoLocList'] . '</option>';
  64. }
  65. echo "\n" . '</select><br />';
  66. fwrite($fp, ob_get_contents());
  67. fclose($fp);
  68. ob_end_clean();
  69. }
  70. break;
  71. case 3:
  72. if(!file_exists(HCPATH . '/cache/meta.php')){
  73. ob_start();
  74. $fp = fopen(HCPATH . '/cache/meta.php', 'w');
  75. fwrite($fp, "<?php\n//\tHelios Meta Cache - Delete this file when upgrading.\n\n");
  76. fwrite($fp, "\$hc_meta = array(\n");
  77. $result = doQuery("SELECT * FROM " . HC_TblPrefix . "settingsmeta");
  78. $x = 1;
  79. $pairs = array(1 => 1,2 => 2,3 => 'submit',4 => 'search',5 => 'searchresult',6 => 'signup',7 => 'send',8 => 'rsvp',9 => 'tools',10 => 'rss',
  80. 11 => 'newsletter',12 => 'archive',13 => 'filter', 14 => 'digest', 15 => 'signin', 16 => 'acc');
  81. while($row = hc_mysql_fetch_row($result)){
  82. fwrite($fp, "\n'".$pairs[$x]."'\t=>\tarray('title' => '".cIn($row[3])."', 'keywords' => '".cIn($row[1])."', 'desc' => '".cIn($row[2])."'),");
  83. ++$x;
  84. }
  85. fwrite($fp, "\n);\n?>");
  86. fwrite($fp, ob_get_contents());
  87. fclose($fp);
  88. ob_end_clean();
  89. }
  90. break;
  91. case 4:
  92. if(!file_exists(HCPATH . '/cache/selCity'.$f.'.php')){
  93. ob_start();
  94. $fp = fopen(HCPATH . '/cache/selCity'.$f.'.php', 'w');
  95. fwrite($fp, "<?php\n//\tHelios City Select List Cache - Delete this file when upgrading.\n?>\n");
  96. fwrite($fp, "\n<select name=\"city\" id=\"city\" disabled=\"disabled\">");
  97. fwrite($fp, "\n<option value=\"\">" . $hc_lang_search['City0'] . "</option>");
  98. $cities = getCities($a);
  99. foreach($cities as $val){
  100. if($val != '')
  101. fwrite($fp, "\n<option value=\"" . $val . "\">" . $val . "</option>");
  102. }
  103. fwrite($fp, "\n</select>");
  104. fwrite($fp, ob_get_contents());
  105. fclose($fp);
  106. ob_end_clean();
  107. }
  108. break;
  109. case 5:
  110. if(!file_exists(HCPATH . '/cache/selPostal'.$f.'.php')){
  111. ob_start();
  112. $fp = fopen(HCPATH . '/cache/selPostal'.$f.'.php', 'w');
  113. fwrite($fp, "<?php\n//\tHelios Postal Code Select List Cache - Delete this file when upgrading.\n?>\n");
  114. fwrite($fp, "\n<select name=\"postal\" id=\"postal\" disabled=\"disabled\">");
  115. fwrite($fp, "\n<option value=\"\">" . $hc_lang_search['Postal0'] . "</option>");
  116. $codes = getPostal($a);
  117. foreach($codes as $val){
  118. if($val != '')
  119. fwrite($fp, "\n<option value=\"" . $val . "\">" . $val . "</option>");
  120. }
  121. fwrite($fp, "\n</select>");
  122. fwrite($fp, ob_get_contents());
  123. fclose($fp);
  124. ob_end_clean();
  125. }
  126. break;
  127. case 6:
  128. $cache_date = date("Ymd");
  129. if(!file_exists(HCPATH . '/cache/'.$cache_date.'.php')){
  130. clearCache();
  131. ob_start();
  132. $fp = fopen(HCPATH . '/cache/'.$cache_date.'.php', 'w');
  133. fwrite($fp, "<?php\n/*\n\tHelios Cache Age File. - Delete this file when upgrading.\n*/\n?>");
  134. fclose($fp);
  135. ob_end_clean();
  136. }
  137. break;
  138. default:
  139. if(!file_exists(HCPATH . '/cache/settings.php')){
  140. $result = doQuery("SELECT PkID, SettingValue FROM " . HC_TblPrefix . "settings WHERE PkID IN (".$hc_fetch_settings.") ORDER BY PkID");
  141. if(hasRows($result)){
  142. ob_start();
  143. $fp = fopen(HCPATH . '/cache/settings.php', 'w');
  144. fwrite($fp, "<?php\n//\tHelios Config Cache - Delete this file when upgrading.\n\n");
  145. fwrite($fp, "\$hc_cfg = array(\n");
  146. while($row = hc_mysql_fetch_row($result)){
  147. fwrite($fp, $row[0] . " => \"" . str_replace("\"","'",$row[1]) . "\",\n");
  148. }
  149. fwrite($fp, "200 => \"hc_" . sha1(md5(CalRoot) . HC_Rando) . "\",\n");
  150. fwrite($fp, "201 => \"helios_" . md5(CalRoot . HC_Rando) . "\",\n");
  151. fwrite($fp, "\"CatCols\" => \"3\",\n");
  152. fwrite($fp, "\"CatLinks\" => \"1\",\n");
  153. fwrite($fp, "\"IsRSVP\" => \"1\",\n");
  154. fwrite($fp, "\"OLImages\" => \"".CalRoot."/img/ol/\",\n");
  155. $resultE = doQuery("SELECT MIN(StartDate), MAX(StartDate) FROM " . HC_TblPrefix . "events WHERE IsApproved = 1 AND IsActive = 1");
  156. if(hasRows($resultE)){
  157. $first = (strtotime(hc_mysql_result($resultE,0,0)) < date("U",mktime(0,0,0,date("m"),date("d"),date("Y")))) ? strtotime(hc_mysql_result($resultE,0,0)) : date("U",mktime(0,0,0,date("m"),date("d"),date("Y")));
  158. fwrite($fp, "\"First\" => \"" . $first . "\",\n");
  159. fwrite($fp, "\"Last\" => \"" . strtotime(hc_mysql_result($resultE,0,1)) . "\",\n");
  160. }
  161. $news = date("Y-m-d");
  162. $resultN = doQuery("SELECT MIN(SentDate) FROM " . HC_TblPrefix . "newsletters WHERE STATUS > 0 AND IsArchive = 1 AND IsActive = 1 AND ArchiveContents != ''");
  163. if(hasRows($resultN) && hc_mysql_result($resultN,0,0) != ''){
  164. $news = hc_mysql_result($resultN,0,0);
  165. }
  166. fwrite($fp, "\"News\" => \"" . $news . "\",\n");
  167. fwrite($fp, ");\n?>");
  168. fclose($fp);
  169. ob_end_clean();
  170. } else {
  171. exit(handleError(0, "Setting Data Missing."));
  172. }
  173. }
  174. break;
  175. }
  176. }
  177. /**
  178. * Delete cache files. Filters for filenames starting with a period. Generates redirect index.html file to prevent cache directory browsing.
  179. * @since 2.0.0
  180. * @version 2.0.0
  181. * @return void
  182. */
  183. function clearCache(){
  184. global $hc_cfg;
  185. foreach(glob(HCPATH.'/cache/*') as $filename) {
  186. if(substr(basename($filename), 0, 1) != '.')
  187. unlink($filename);
  188. }
  189. $fp = fopen(HCPATH . '/cache/index.html', 'w');
  190. fwrite($fp, "<html><head><title></title><META HTTP-EQUIV=\"Refresh\" CONTENT=\"0; URL=../\"></head><body></body></html>");
  191. fclose($fp);
  192. if(function_exists('apc_clear_cache') && $hc_cfg[128] == 2){
  193. $api_users = (apc_exists(HC_APCPrefix.'users')) ? apc_fetch(HC_APCPrefix.'users') : array();
  194. apc_user_write_cache($api_users);
  195. $iterator = new APCIterator('user', NULL, APC_ITER_KEY);
  196. foreach ($iterator as $key => $data) {
  197. if(preg_match('/^'.HC_APCPrefix.'/',$key))
  198. apc_delete($key);
  199. }
  200. }
  201. }
  202. /**
  203. * Output headers to prevent browser caching of action pages.
  204. * @since 2.0.0
  205. * @version 2.0.0
  206. * @return void
  207. */
  208. function action_headers(){
  209. header('Expires: Wed, 3 May 1979 12:34:56 GMT');
  210. header('Last-Modified: '.date("D, d M Y H:i:s").'GMT');
  211. header('Pragma: no-cache');
  212. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  213. }
  214. /**
  215. * Require post only access method.
  216. * @since 2.0.0
  217. * @version 2.0.0
  218. * @return void
  219. */
  220. function post_only(){
  221. if($_SERVER['REQUEST_METHOD'] != 'POST'){
  222. if(function_exists('http_response_code'))
  223. http_response_code(405);
  224. else
  225. header('HTTP/1.1 405 Method Not Allowed');
  226. exit;
  227. }
  228. }
  229. /**
  230. * Output tweet with current hashtag setting.
  231. * @since 2.0.0
  232. * @version 2.0.0
  233. * @param string $tweet tweet string
  234. * @return void
  235. */
  236. function build_tweet($tweet){
  237. global $hc_cfg;
  238. echo cIn($tweet.' '.$hc_cfg[59]);
  239. }
  240. /**
  241. * Replace "Smart Quotes", em dash and other web unsafe characters with web safe equivalent.
  242. * @since 2.0.0
  243. * @version 2.0.0
  244. * @param string $value string to be filtered
  245. * @param integer $filter [optional] 0 = Maintain Double Quotes, 1 = Replace Double Quotes w/Single Quotes (Default:1)
  246. * @return string filtered string
  247. */
  248. function cleanQuotes($value,$filter = 1){
  249. $badChars = array('/' . chr(145) . '/','/' . chr(146) . '/','/' . chr(147) . '/','/' . chr(148) . '/','/' . chr(151). '/',"/\\" . chr(92) . "/");
  250. $goodChars = ($filter == 1) ? array("'", "'", "'", "'", '-', "") : array("'", "'", "\"", "\"", '-', "");
  251. $value = preg_replace($badChars,$goodChars,$value);
  252. return $value;
  253. }
  254. /**
  255. * Remove all line breaks and carriage returns, condense string to single line.
  256. * @since 2.0.0
  257. * @version 2.0.0
  258. * @param string $value string to be filtered
  259. * @return string filtered string
  260. */
  261. function cleanBreaks($value){
  262. $badChars = array('/' . chr(10) . '/','/' . chr(13) . '/','/\\\n/','/\\\r/');
  263. $goodChars = array("", "", "", "");
  264. $value = preg_replace($badChars,$goodChars,$value);
  265. return $value;
  266. }
  267. /**
  268. * Filter special characters that break CSV files in most editors.
  269. * @since 2.2.0
  270. * @version 2.2.0
  271. * @param string $value string to be filtered
  272. * @return string filtered string
  273. */
  274. function cleanCSV($value){
  275. $value = cleanQuotes($value,1);
  276. $badChars = array('/\'/','/,/');
  277. $goodChars = array("\\'", "\\,");
  278. $value = preg_replace($badChars,$goodChars,$value);
  279. return $value;
  280. }
  281. /**
  282. * Filter value for use in MySQL query to protect against SQL injection and convert text to proper character encoding (for international support). Wrapper for hc_mysql_real_escape_string().
  283. * @since 2.0.0
  284. * @version 2.0.2
  285. * @param string $value string to be filtered
  286. * @param integer $filter [optional] 0 = Maintain Double Quotes, 1 = Replace Double Quotes w/Single Quotes (Default:1)
  287. * @return string filtered (character converted, if required) string
  288. */
  289. function cIn($value,$filter = 1) {
  290. global $hc_lang_config;
  291. $value = ($filter == 1) ? str_replace("\"", "'", $value) : $value;
  292. if(defined('CONVERT_CHRSET') && function_exists('mb_convert_encoding'))
  293. $value = mb_convert_encoding($value, CONVERT_CHRSET, $hc_lang_config['CharSet']);
  294. return hc_mysql_real_escape_string($value);
  295. }
  296. /**
  297. * Removes escape backslash when present for output to page, wrapper for stripslashes().
  298. * @since 2.0.0
  299. * @version 2.0.0
  300. * @param string $value string to be filtered
  301. * @return string filtered string
  302. */
  303. function cOut($value){
  304. return stripslashes($value);
  305. }
  306. /**
  307. * Check MySQL result set for minimum row count, wrapper for hc_mysql_num_rows().
  308. * @since 2.0.0
  309. * @version 2.1.0
  310. * @param resource $result MySQL result set
  311. * @param integer $min result set must have at least one more than this many rows (Default:0)
  312. * @return boolean row count is greater than $min
  313. */
  314. function hasRows($result,$min = 0){
  315. if(!$result)
  316. return;
  317. $chk_row_cnt = hc_mysql_num_rows($result);
  318. return ($chk_row_cnt > $min) ? true : false;
  319. }
  320. /**
  321. * Wrapper for TinyMCE. Creates TinyMCE editor for the passed textarea IDs.
  322. * @since 2.0.0
  323. * @version 2.2.1
  324. * @param string $width width of the editor. Variable width is recommended. Pass empty string to use CSS override. (TinyMCE v4 Only, use theme CSS classes for v3)
  325. * @param integer $admin [optional] 0 = create public style editor, 1 = create admin style editor (Default:0)
  326. * @param integer $override [optional] 0 = use default editor setting, 1 = override default setting, force plian textarea & disable editor (Default:0)
  327. * @param string $textName comma separated list of textarea ids to convert to TinyMCE editors. (TinyMCE v3 Only, use mce_edit CSS class for v4)
  328. * @return void
  329. */
  330. function makeTinyMCE($width, $admin = 0, $override = 0, $textName = ''){
  331. global $hc_cfg, $hc_lang_config;
  332. if($hc_cfg[30] == 0 || $override == 1)
  333. return -1;
  334. $style = ($admin == 0) ? CalRoot.'/themes/tinymce.css' : AdminRoot.'/css/tinymce.css';
  335. if($hc_cfg[30] == 2){
  336. echo '
  337. <script type="text/javascript" src="'.CalRoot.'/inc/tinymce/tinymce.min.js"></script>
  338. <script type="text/javascript">
  339. tinymce.init({
  340. selector : "textarea.mce_edit",
  341. browser_spellcheck : true,
  342. theme: "modern",
  343. toolbar_items_size : "small",'.($width != '' ? '
  344. width: "'.$width.'",':'').'
  345. plugins: [
  346. "'.($admin == 1 ? 'media ':'').'advlist anchor autolink autoresize charmap code colorpicker contextmenu directionality emoticons fullscreen",
  347. "hr image insertdatetime layer link lists nonbreaking noneditable pagebreak paste preview print searchreplace tabfocus table template textcolor textpattern",
  348. "visualblocks visualchars wordcount"
  349. ],
  350. toolbar1: "'.($admin == 1 ? 'insertfile ':'').'image | bold italic forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | emoticons",
  351. extended_valid_elements: ""
  352. +"a[accesskey|charset|class|coords|dir<ltr?rtl|href|hreflang|id|lang|name|rel|rev|shape<circle?default?poly?rect|style|tabindex|title|target|type],"
  353. +"abbr[class|dir<ltr?rtl|id|lang|style|title],"
  354. +"acronym[class|dir<ltr?rtl|id|id|lang|style|title],"
  355. +"blockquote[cite|class|dir<ltr?rtl|id|lang|style|title],"
  356. +"br[class|clear<all?left?none?right|id|style|title],"
  357. +"caption[align<bottom?left?right?top|class|dir<ltr?rtl|id|lang|style|title],"
  358. +"center[class|dir<ltr?rtl|id|lang|style|title],"
  359. +"cite[class|dir<ltr?rtl|id|lang|style|title],"
  360. +"dd[class|dir<ltr?rtl|id|lang|style|title],"
  361. +"del[cite|class|datetime|dir<ltr?rtl|id|lang|style|title],"
  362. +"dfn[class|dir<ltr?rtl|id|lang|style|title],"
  363. +"dir[class|compact<compact|dir<ltr?rtl|id|lang|style|title],"
  364. +"div[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|style|title],"
  365. +"dl[class|compact<compact|dir<ltr?rtl|id|lang|style|title],"
  366. +"dt[class|dir<ltr?rtl|id|lang|style|title],"
  367. +"em/i[class|dir<ltr?rtl|id|lang|style|title],"
  368. +"font[class|color|dir<ltr?rtl|face|id|lang|size|style|title],"
  369. +"hr[align<center?left?right|class|dir<ltr?rtl|id|lang|noshade<noshade|size|style|title|width],"
  370. +"img[align<bottom?left?middle?right?top|alt|border|class|dir<ltr?rtl|height|hspace|id|ismap<ismap|lang|longdesc|name|src|style|title|usemap|vspace|width],"
  371. +"legend[align<bottom?left?right?top|accesskey|class|dir<ltr?rtl|id|lang|style|title],"
  372. +"li[class|dir<ltr?rtl|id|lang|style|title|type|value],"
  373. +"menu[class|compact<compact|dir<ltr?rtl|id|lang|style|title],"
  374. +"ol[class|compact<compact|dir<ltr?rtl|id|lang|start|style|title|type],"
  375. +"p[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|style|title],"
  376. +"pre/listing/plaintext/xmp[align|class|dir<ltr?rtl|id|lang|style|title|width],"
  377. +"q[cite|class|dir<ltr?rtl|id|lang|style|title],"
  378. +"small[class|dir<ltr?rtl|id|lang|style|title],"
  379. +"span[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|style|title],"
  380. +"strike[class|class|dir<ltr?rtl|id|lang|style|title],"
  381. +"strong/b[class|dir<ltr?rtl|id|lang|style|title],"
  382. +"style[dir<ltr?rtl|lang|media|title|type],"
  383. +"sub[class|dir<ltr?rtl|id|lang|style|title],"
  384. +"sup[class|dir<ltr?rtl|id|lang|style|title],"
  385. +"table[align<center?left?right|bgcolor|border|cellpadding|cellspacing|class|dir<ltr?rtl|frame|height|id|lang|rules|style|summary|title|width],"
  386. +"td[abbr|align<center?char?justify?left?right|axis|bgcolor|char|charoff|class|colspan|dir<ltr?rtl|headers|height|id|lang|nowrap<nowrap|rowspan|scope<col?colgroup?row?rowgroup|style|title|valign<baseline?bottom?middle?top|width],"
  387. +"tr[abbr|align<center?char?justify?left?right|bgcolor|char|charoff|class|rowspan|dir<ltr?rtl|id|lang|style|title|valign<baseline?bottom?middle?top],"
  388. +"tt[class|dir<ltr?rtl|id|lang|style|title],"
  389. +"u[class|dir<ltr?rtl|id|lang|style|title],"
  390. +"ul[class|compact<compact|dir<ltr?rtl|id|lang|style|title|type],"
  391. +"var[class|dir<ltr?rtl|id|lang|style|title]",
  392. relative_urls : false,
  393. remove_script_host : false,
  394. });
  395. </script>
  396. <link rel="stylesheet" type="text/css" href="'.$style.'">';
  397. } elseif ($hc_cfg[30] == 1) {
  398. echo '
  399. <script src="'.CalRoot.'/inc/tiny_mce/tiny_mce_gzip.js"></script>
  400. <script>
  401. //<!--
  402. tinyMCE_GZ.init({
  403. plugins : "advhr,advimage,advlink,advlist,autolink,autoresize,contextmenu,fullscreen,inlinepopups,insertdatetime,layer,media,paste,preview,searchreplace,spellchecker,style,tabfocus,table,visualblocks,visualchars,wordcount,xhtmlxtras",
  404. theme : "advanced",language : "'.$hc_lang_config['TinyMCELang'].'",disk_cache : true,debug : false});
  405. tinyMCE.init({
  406. setup : function(ed) {ed.onInit.add(function() {ed.settings.file_browser_callback = null;});},
  407. cleanup : true,
  408. '.(($hc_lang_config['Direction'] == 0) ? 'directionality : "rtl",' : '').
  409. 'mode : "exact",
  410. editor_selector : "'.$textName.'",
  411. theme : "advanced",
  412. language : "'.$hc_lang_config['TinyMCELang'].'",
  413. skin : "o2k7",
  414. skin_variant : "silver",
  415. elements : "'.$textName.'",
  416. entity_encoding : "raw",
  417. plugins : "advhr,advimage,advlink,advlist,autolink,autoresize,contextmenu,emotions,fullscreen,inlinepopups,layer,media,paste,preview,searchreplace,spellchecker,style,tabfocus,table,visualblocks,visualchars,wordcount,xhtmlxtras",
  418. '.(($admin == 1) ? 'theme_advanced_buttons1 : "fontsizeselect,|,fontselect,|,bold,italic,underline,strikethrough,|,bullist,numlist,|,justifyleft,justifycenter,justifyright,|,outdent,indent,sup,sub,|,replace,|,visualchars",
  419. theme_advanced_buttons2 : "pastetext,pasteword,|,link,unlink,anchor,|,image,insertimage,media,charmap,emotions,|,forecolor,backcolor,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,removeformat,cleanup,|,undo,redo",
  420. theme_advanced_buttons3 : "tablecontrols,visualaid,insertlayer,moveforward,movebackward,absolute,|,advhr,|,visualblocks,code,|,fullscreen,preview,|,spellchecker,|,help",
  421. theme_advanced_buttons4 : "",':
  422. 'theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,bullist,numlist,separator,justifyleft,justifycenter,justifyright,separator,link,unlink,image,separator,undo,redo,code,spellchecker,pastetext,pasteword,|,preview",
  423. theme_advanced_buttons2 : "",
  424. valid_elements : ""
  425. +"a[accesskey|charset|class|coords|dir<ltr?rtl|href|hreflang|id|lang|name|rel|rev|shape<circle?default?poly?rect|style|tabindex|title|target|type],"
  426. +"abbr[class|dir<ltr?rtl|id|lang|style|title],"
  427. +"acronym[class|dir<ltr?rtl|id|id|lang|style|title],"
  428. +"blockquote[cite|class|dir<ltr?rtl|id|lang|style|title],"
  429. +"br[class|clear<all?left?none?right|id|style|title],"
  430. +"caption[align<bottom?left?right?top|class|dir<ltr?rtl|id|lang|style|title],"
  431. +"center[class|dir<ltr?rtl|id|lang|style|title],"
  432. +"cite[class|dir<ltr?rtl|id|lang|style|title],"
  433. +"dd[class|dir<ltr?rtl|id|lang|style|title],"
  434. +"del[cite|class|datetime|dir<ltr?rtl|id|lang|style|title],"
  435. +"dfn[class|dir<ltr?rtl|id|lang|style|title],"
  436. +"dir[class|compact<compact|dir<ltr?rtl|id|lang|style|title],"
  437. +"div[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|style|title],"
  438. +"dl[class|compact<compact|dir<ltr?rtl|id|lang|style|title],"
  439. +"dt[class|dir<ltr?rtl|id|lang|style|title],"
  440. +"em/i[class|dir<ltr?rtl|id|lang|style|title],"
  441. +"font[class|color|dir<ltr?rtl|face|id|lang|size|style|title],"
  442. +"hr[align<center?left?right|class|dir<ltr?rtl|id|lang|noshade<noshade|size|style|title|width],"
  443. +"img[align<bottom?left?middle?right?top|alt|border|class|dir<ltr?rtl|height|hspace|id|ismap<ismap|lang|longdesc|name|src|style|title|usemap|vspace|width],"
  444. +"legend[align<bottom?left?right?top|accesskey|class|dir<ltr?rtl|id|lang|style|title],"
  445. +"li[class|dir<ltr?rtl|id|lang|style|title|type|value],"
  446. +"menu[class|compact<compact|dir<ltr?rtl|id|lang|style|title],"
  447. +"ol[class|compact<compact|dir<ltr?rtl|id|lang|start|style|title|type],"
  448. +"p[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|style|title],"
  449. +"pre/listing/plaintext/xmp[align|class|dir<ltr?rtl|id|lang|style|title|width],"
  450. +"q[cite|class|dir<ltr?rtl|id|lang|style|title],"
  451. +"small[class|dir<ltr?rtl|id|lang|style|title],"
  452. +"span[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|style|title],"
  453. +"strike[class|class|dir<ltr?rtl|id|lang|style|title],"
  454. +"strong/b[class|dir<ltr?rtl|id|lang|style|title],"
  455. +"style[dir<ltr?rtl|lang|media|title|type],"
  456. +"sub[class|dir<ltr?rtl|id|lang|style|title],"
  457. +"sup[class|dir<ltr?rtl|id|lang|style|title],"
  458. +"table[align<center?left?right|bgcolor|border|cellpadding|cellspacing|class|dir<ltr?rtl|frame|height|id|lang|rules|style|summary|title|width],"
  459. +"td[abbr|align<center?char?justify?left?right|axis|bgcolor|char|charoff|class|colspan|dir<ltr?rtl|headers|height|id|lang|nowrap<nowrap|rowspan|scope<col?colgroup?row?rowgroup|style|title|valign<baseline?bottom?middle?top|width],"
  460. +"tr[abbr|align<center?char?justify?left?right|bgcolor|char|charoff|class|rowspan|dir<ltr?rtl|id|lang|style|title|valign<baseline?bottom?middle?top],"
  461. +"tt[class|dir<ltr?rtl|id|lang|style|title],"
  462. +"u[class|dir<ltr?rtl|id|lang|style|title],"
  463. +"ul[class|compact<compact|dir<ltr?rtl|id|lang|style|title|type],"
  464. +"var[class|dir<ltr?rtl|id|lang|style|title]",').'
  465. theme_advanced_toolbar_location : "top",
  466. theme_advanced_toolbar_align : "left",
  467. theme_advanced_statusbar_location : "bottom",
  468. theme_advanced_resizing : true,
  469. theme_advanced_resize_horizontal : false,
  470. apply_source_formatting : false,
  471. relative_urls : false,
  472. remove_script_host : false,
  473. spellchecker_languages : "'.$hc_lang_config['TinyMCESpell'].'"
  474. });
  475. //-->
  476. </script>';
  477. }
  478. }
  479. /**
  480. * Output feedback dialog.
  481. * @since 2.0.0
  482. * @version 2.0.0
  483. * @param integer $type 1 = Success, 2 = Warning, 3 = Error (Default: Success).
  484. * @param string $fmessage feedback message to ouput in dialog.
  485. * @return void
  486. */
  487. function feedback($type, $fmessage){
  488. $fType = "success";
  489. $fIcon = "success.png";
  490. switch($type){
  491. case 2:
  492. $fType = "warning";
  493. break;
  494. case 3:
  495. $fType = "error";
  496. break;
  497. }
  498. echo '
  499. <div'.($type == 1 ? ' id="hc_dialog"':'').' class="feedback '.$fType.'" style="opacity:1;"><img src="'.CalRoot.'/img/feedback/'.$fType.'.png" alt="" />&nbsp;'.$fmessage.'</div>';
  500. }
  501. /**
  502. * Convert MySQL date (YYYY-MM-DD) or timestamp (YYYY-MM-DD HH:MM:SS) to passed format.
  503. * @since 2.0.0
  504. * @version 2.0.0
  505. * @param datetime $timeStamp MySQL timestamp
  506. * @param string $dateFormat date format string, accepts string of strftime format parameters.
  507. * @return string formatted date.
  508. */
  509. function stampToDate($timeStamp, $dateFormat){
  510. $theDate = ($timeStamp != '') ? strftime($dateFormat, strtotime($timeStamp)) : '';
  511. return $theDate;
  512. }
  513. /**
  514. * Convert Helios date to MySQL timestamp.
  515. * @since 2.0.0
  516. * @version 2.0.0
  517. * @param string $theDate date string
  518. * @param string $dateFormat format of passed date, accepts: %d/%m/%y, %m/%d/%y or %y/%m/%d
  519. * @return string date in MySQL date format (YYYY-MM-DD)
  520. */
  521. function dateToMySQL($theDate, $dateFormat){
  522. $theDate = str_replace("%","",$theDate);
  523. $dateParts = explode('/',$theDate);
  524. if(!isset($dateParts[2]))
  525. return NULL;
  526. $theDate = NULL;
  527. switch(strToLower($dateFormat)){
  528. case '%d/%m/%y':
  529. if(checkdate($dateParts[1],$dateParts[0],$dateParts[2]))
  530. $theDate = strftime("%Y-%m-%d", mktime(0,0,0,$dateParts[1],$dateParts[0],$dateParts[2]));
  531. break;
  532. case '%m/%d/%y' :
  533. if(checkdate($dateParts[0],$dateParts[1],$dateParts[2]))
  534. $theDate = strftime("%Y-%m-%d", mktime(0,0,0,$dateParts[0],$dateParts[1],$dateParts[2]));
  535. break;
  536. case '%y/%m/%d':
  537. if(checkdate($dateParts[1],$dateParts[2],$dateParts[0]))
  538. $theDate = strftime("%Y-%m-%d", mktime(0,0,0,$dateParts[1],$dateParts[2],$dateParts[0]));
  539. break;
  540. }
  541. return $theDate;
  542. }
  543. /**
  544. * Output event category checkbox inputs.
  545. * @since 2.0.0
  546. * @version 2.0.0
  547. * @param string $frmName name attribute of form the inputs are to be output for
  548. * @param integer $columns number of columns to output
  549. * @param string $query [optional] MySQL query to generate category list (Default: NULL = List all categories, unchecked)
  550. * @param integer $showLinks [optional] 0 = Do NOT Show Select/Deselect Links, 1 = Show Links (Default:1)
  551. * @return void
  552. */
  553. function getCategories($frmName, $columns, $query = NULL, $showLinks = 1){
  554. global $hc_cfg, $hc_lang_config, $hc_lang_core;
  555. if(!isset($query))
  556. $query = "SELECT c.PkID, c.CategoryName, c.ParentID, c.CategoryName as Sort, NULL as Selected
  557. FROM " . HC_TblPrefix . "categories c
  558. LEFT JOIN " . HC_TblPrefix . "eventcategories ec ON (c.PkID = ec.CategoryID)
  559. WHERE c.ParentID = 0 AND c.IsActive = 1
  560. GROUP BY c.PkID, c.CategoryName, c.ParentID
  561. UNION SELECT c.PkID, c.CategoryName, c.ParentID, c2.CategoryName as Sort, NULL as Selected
  562. FROM " . HC_TblPrefix . "categories c
  563. LEFT JOIN " . HC_TblPrefix . "categories c2 ON (c.ParentID = c2.PkID)
  564. LEFT JOIN " . HC_TblPrefix . "eventcategories ec ON (c.PkID = ec.CategoryID)
  565. WHERE c.ParentID > 0 AND c.IsActive = 1
  566. GROUP BY c.PkID, c.CategoryName, c.ParentID, c2.CategoryName
  567. ORDER BY Sort, ParentID, CategoryName";
  568. $result = doQuery($query);
  569. if(!hasRows($result))
  570. return 0;
  571. $cnt = 1;
  572. echo '
  573. <div class="catCol">';
  574. while($row = hc_mysql_fetch_row($result)){
  575. if($cnt > ceil(hc_mysql_num_rows($result) / $columns) && $row[2] == 0){
  576. echo ($cnt > 1) ? '
  577. </div>' : '';
  578. echo '
  579. <div class="catCol">';
  580. $cnt = 1;}
  581. $sub = ($row[2] != 0) ? ' class="sub"' : '';
  582. $check = ($row[4] != '') ? 'checked="checked" ' : '';
  583. echo '
  584. <label for="catID_' . $row[0] . '"'.$sub.'><input name="catID[]" id="catID_'.$row[0].'" type="checkbox" '.$check.'value="'.$row[0].'" />'.cOut($row[1]).'</label>';
  585. ++$cnt;
  586. }
  587. echo '
  588. </div>';
  589. if($cnt == 0 || $showLinks == 0)
  590. return 0;
  591. echo '
  592. <div class="catCtrl">
  593. [ <a href="javascript:;" onclick="checkAllArray(\'' . $frmName . '\', \'catID[]\');">' . $hc_lang_core['SelectAll'] . '</a>
  594. &nbsp;|&nbsp; <a href="javascript:;" onclick="uncheckAllArray(\'' . $frmName . '\', \'catID[]\');">' . $hc_lang_core['DeselectAll'] . '</a> ]
  595. </div>';
  596. }
  597. /**
  598. * Retrieve all location cities. Includes both Custom & Saved Location cities.
  599. * @since 2.0.0
  600. * @version 2.0.0
  601. * @param integer $type [optional] 0 = cities for active events only, 1 = cities for all events (Default:0)
  602. * @return array sorted alphabetically
  603. */
  604. function getCities($type = 0){
  605. $sqlWhere = ($type == 0) ? " e.StartDate >= '". cIn(SYSDATE) . "' AND " : "";
  606. $result = doQuery("SELECT e.LocationCity, l.City
  607. FROM " . HC_TblPrefix . "events as e
  608. LEFT JOIN " . HC_TblPrefix . "locations as l ON (e.LocID = l.PkID)
  609. WHERE " . $sqlWhere . " (e.IsActive = 1 AND e.IsApproved = 1) OR (l.IsActive = 1) GROUP BY LocationCity, City");
  610. $cities = array();
  611. while($row = hc_mysql_fetch_row($result)){
  612. if($row[1] == '')
  613. $cities[strtolower($row[0] . $row[1])] = $row[0] . $row[1];
  614. else
  615. $cities[strtolower($row[1])] = $row[1];
  616. }
  617. array_filter($cities);
  618. ksort($cities);
  619. array_unique($cities);
  620. return $cities;
  621. }
  622. /**
  623. * Retrieve all location postal codes. Includes both Custom & Saved Location postal codes.
  624. * @since 2.0.0
  625. * @version 2.0.0
  626. * @param integer $type [optional] 0 = postal codes for active events only, 1 = postal codes for all events (Default:0)
  627. * @return array sorted numerically
  628. */
  629. function getPostal($type = 0){
  630. $sqlWhere = ($type == 0) ? " e.StartDate >= '" . cIn(SYSDATE) . "' AND " : "";
  631. $result = doQuery("SELECT e.LocationZip, l.Zip
  632. FROM " . HC_TblPrefix . "events as e
  633. LEFT JOIN " . HC_TblPrefix . "locations as l ON (e.LocID = l.PkID)
  634. WHERE " . $sqlWhere . " (e.IsActive = 1 AND e.IsApproved = 1) OR (l.IsActive = 1) GROUP BY LocationZip, Zip");
  635. $postal = array();
  636. while($row = hc_mysql_fetch_row($result)){
  637. if($row[1] == '')
  638. $postal[strtolower($row[0] . $row[1])] = $row[0] . $row[1];
  639. else
  640. $postal[strtolower($row[1])] = $row[1];
  641. }
  642. array_filter($postal);
  643. ksort($postal);
  644. array_unique($postal);
  645. return $postal;
  646. }
  647. /**
  648. * Escape, using a backslash, common special characters, including: \ ' " and ,
  649. * @since 2.0.0
  650. * @version 2.0.0
  651. * @param string $value string to filter
  652. * @return string filtered string
  653. */
  654. function cleanSpecialChars($value){
  655. $badChars = array('/&nbsp;/','/\\\\/','/\'/','/"/','/,/');
  656. $goodChars = array(" ","\\\\\\","\\'","\\\"","\,");
  657. $value = preg_replace($badChars,$goodChars,$value);
  658. return $value;
  659. }
  660. /**
  661. * Filter XML special characters with HTML entity number, including: ndash nbsp & " ' < > $ ? ldquo lsquo rdquo rsquo
  662. * @since 2.0.0
  663. * @version 2.0.0
  664. * @param string $value string to filter
  665. * @param integer $purge [optional] 0 = replace special characters with safe alternative, 1 = remove special characters (Default:0)
  666. * @return string filtered string
  667. */
  668. function cleanXMLChars($value, $purge = 0){
  669. $badChars = array('/&ndash;/','/&nbsp;/','/&(?=[A-Z|a-z|0-9|\s])/','/\"/','/\'/','/</','/>/','/\$/','/\?/','/&ldquo;/','/&lsquo;/','/&rdquo;/','/&rsquo;/');
  670. $goodChars = ($purge == 0) ?
  671. array("-"," ","&#38;","&#34;","&#39;","&#60;","&#62;","&#36;","&#63;","&#34;","&#39;","&#34;","&#39;") :
  672. array("","","","","","","","","","","","","");
  673. $value = preg_replace($badChars,$goodChars,$value);
  674. return $value;
  675. }
  676. /**
  677. * Generate localized address format.
  678. * @since 2.0.0
  679. * @version 2.0.0
  680. * @param string $add address part one
  681. * @param string $add2 [optional] address part two (suite/apt./etc.)
  682. * @param string $city city
  683. * @param string $region [optional] region (state/province/etc.)
  684. * @param string $postal zip/postal/post code
  685. * @param string $country country
  686. * @param integer $addType [optional] 1 = US/Can/Aus format, 0 = European format (Default:1)
  687. * @return string formatted address string
  688. */
  689. function buildAddress($add,$add2,$city,$region,$postal,$country,$addType = 1){
  690. $address = ($addType == 1) ? '[add][add2][city], [region] [postal] [country]' : '[add][add2][postal] [city][country]';
  691. $address = ($add != '') ? str_replace('[add]',$add.'<br />',$address) : $address;
  692. $address = ($add2 != '') ? str_replace('[add2]',$add2.'<br />',$address) : $address;
  693. $address = ($city != '') ? str_replace('[city]',$city,$address) : $address;
  694. $address = ($region != '') ? str_replace('[region]',$region,$address) : $address;
  695. $address = ($postal != '') ? str_replace('[postal]',$postal,$address) : $address;
  696. $address = ($country != '') ? str_replace('[country]','<br />'.$country,$address) : $address;
  697. $address = preg_replace('/\[+[(a-z|0-9)]*\]+/','',$address);
  698. return $address;
  699. }
  700. /**
  701. * Retrieve array of XML tags (elements).
  702. * @since 2.1.0
  703. * @version 2.1.0
  704. * @param string $root_tag XML document tag (element).
  705. * @param string $xml XML data to be parsed.
  706. * @return array array of tags (elements) and their contents.
  707. */
  708. function xml_elements($root_tag, $xml){
  709. $found = preg_match_all('#<'.$root_tag.'(?:\s+[^>]+)?>(.*?)</'.$root_tag.'>#s',$xml, $matches, PREG_PATTERN_ORDER);
  710. if ($found != false)
  711. return $matches[1];
  712. }
  713. /**
  714. * Retrieve value of an xml tag (element).
  715. * @since 2.1.0
  716. * @version 2.1.0
  717. * @param string $tag xml document tag (element). Contents of this tag will be returned within the array elements.
  718. * @param string $xml xml data to be parsed.
  719. * @return array array of sub tags (elements) and their contents.
  720. */
  721. function xml_tag_value($tag, $data) {
  722. $found = preg_match('#<'.$tag.'(?:\s+[^>]+)?>(.*?)</'.$tag.'>#s', $data, $matches);
  723. if ($found != false)
  724. return $matches[1];
  725. }
  726. /**
  727. * Convert XML document to array.
  728. * @since 2.0.0
  729. * @version 2.0.0
  730. * @param string $xml xml document
  731. * @return array array of document contents
  732. */
  733. function xml2array($xml) {
  734. $theArry = array();
  735. $regElem = '/<(\w+)\s*([^\/>]*)\s*(?:\/>|>(.*)<\/\s*\\1\s*>)/s';
  736. $regAtt = '/(\w+)=(?:"|\')([^"\']*)(:?"|\')/';
  737. preg_match_all($regElem, $xml, $elem);
  738. foreach($elem[1] as $key => $val) {
  739. $theArry[$key]["name"] = $elem[1][$key];
  740. if($attributes = trim($elem[2][$key])){
  741. preg_match_all($regAtt, $attributes, $att);
  742. foreach ($att[1] as $key => $val){$theArry[$key]["attributes"][$att[1][$key]] = $att[2][$key];}
  743. }
  744. $end = strpos($elem[3][$key], "<");
  745. if($end > 0)
  746. $theArry[$key]["value"] = substr($elem[3][$key], 0, $end);
  747. if(preg_match($regElem, $elem[3][$key]))
  748. $theArry[$key]["elements"] = xml2array($elem[3][$key]);
  749. else if ($elem[3][$key])
  750. $theArry[$key]["value"] = $elem[3][$key];
  751. }
  752. return $theArry;
  753. }
  754. /**
  755. * Master email function, use for all emails (public calendar & admin console) except newsletter mailings, wrapper for PHPMailer.
  756. * @since 2.0.0
  757. * @version 2.2.0
  758. * @param string $toName name of email recipient
  759. * @param string|array $toAddress email address of recipient OR array of recipients array($name => $address)
  760. * @param string $subj subject line of the email
  761. * @param string $msg message body/contents of the email
  762. * @param string $fromName name of email sender
  763. * @param string $fromAddress email Address of email sender
  764. * @param array $attach Files to attach to email. (Data String, Filename, MIME Type)
  765. * @param boolean $debug [optional] true = output PHPMailer() SMTP debug info, false = no output (Default:false)
  766. * @return void
  767. */
  768. function reMail($toName,$toAddress,$subj,$msg,$fromName = '',$fromAddress = '',$attach = NULL,$debug = false){
  769. global $hc_cfg, $hc_lang_core, $hc_lang_config;
  770. if(emailStatus() != 1)
  771. return -1;
  772. emailStop();
  773. if($hc_cfg[78] == '' || $hc_cfg[79] == '')
  774. exit($hc_lang_core['NoEmail']);
  775. include_once(HCPATH.HCINC.'/phpmailer/class.phpmailer.php');
  776. $fromName = ($fromName == '') ? $hc_cfg[79] : $fromName;
  777. $fromAddress = ($fromAddress == '') ? $hc_cfg[78] : $fromAddress;
  778. $mail = new PHPMailer();
  779. $host = gethostbynamel('');
  780. $mail->AddCustomHeader($mail->HeaderLine('X-Helios_Calendar-Version',$hc_cfg[49]));
  781. $mail->AddCustomHeader($mail->HeaderLine('X-Helios_Calendar-ID',md5($hc_cfg[19])));
  782. $mail->AddCustomHeader($mail->HeaderLine('X-Helios_Calendar-IP',$host[0]));
  783. /* End Edit Restriction
  784. */
  785. $mail->CreateHeader();
  786. $mail->IsHTML(true);
  787. $mail->CharSet = (defined('CONVERT_CHRSET') && function_exists('mb_convert_encoding')) ? CONVERT_CHRSET : $hc_lang_config['CharSet'];
  788. if($attach != NULL){
  789. $mail->AddStringAttachment("$attach[0]","$attach[1]","base64","$attach[2]");
  790. }
  791. if(is_array($toAddress)){
  792. $mail->SingleToArray = $toAddress;
  793. foreach($toAddress as $name => $address){
  794. $mail->AddAddress($address,$name);
  795. }
  796. } else {
  797. $mail->AddAddress($toAddress,$toName);
  798. }
  799. if($hc_cfg[71] == 1){
  800. $mail->IsSMTP();
  801. $mail->SMTPKeepAlive = false;
  802. $mail->SMTPDebug = $debug;
  803. $mail->Host = $hc_cfg[72];
  804. $mail->Port = $hc_cfg[73];
  805. if($hc_cfg[77] == 1){
  806. $mail->SMTPAuth = true;
  807. $mail->Username = $hc_cfg[75];
  808. $mail->Password = base64_decode($hc_cfg[76]);
  809. }
  810. if($hc_cfg[74] == 1){
  811. $mail->SMTPSecure = "tls";
  812. } elseif($hc_cfg[74] == 2){
  813. $mail->SMTPSecure = "ssl";
  814. }
  815. } else {
  816. $mail->IsMail();
  817. }
  818. $mail->Sender = $hc_cfg[78];
  819. $mail->From = $fromAddress;
  820. $mail->FromName = cOut($fromName);
  821. $mail->AddReplyTo($fromAddress, $fromName);
  822. $mail->Subject = $subj;
  823. $mail->Body = $msg;
  824. $mail->AltBody = strip_tags(str_replace("<br />", "\n", $msg));
  825. try{
  826. $mail->Send();
  827. } catch (phpmailerException $e) {
  828. exit($e);
  829. } catch (Exception $e) {
  830. exit($e);
  831. }
  832. if($hc_cfg[71] == 1){$mail->SmtpClose();}
  833. emailGo();
  834. }
  835. /**
  836. * Output CAPTCHA JavaScript validation based on CAPTCHA setting type and active form.
  837. * @since 2.0.0
  838. * @version 2.0.0
  839. * @param datatype $where form to generate CAPTCHA for: 1 = Event Submission, 2 = Email to Friend, 3 = Event RSVP, 4 = Newsletter Sign-up/Edit
  840. * @return void
  841. */
  842. function captchaValidation($where){
  843. global $hc_captchas, $hc_cfg, $hc_lang_core;
  844. if($hc_cfg[65] == 0 || !in_array($where, $hc_captchas))
  845. return 0;
  846. $which = ($hc_cfg[65] == 1) ? 'proof' : 'recaptcha_response_field';
  847. echo '
  848. err += reqField(document.getElementById("'.$which.'"),"'.$hc_lang_core['Authentication'].'\n");';
  849. }
  850. /**
  851. * Output CAPTCHA Challenge based on CAPTCHA setting type.
  852. * @since 2.0.0
  853. * @version 2.2.0
  854. * @param integer $admin Where is the CAPTCHA being used? admin console 1 = hide notice, use proper session & force reCAPTCHA theme, 0 = output notice, use proper session & use reCAPTCHA theme settings (Default:0)
  855. * @return void
  856. */
  857. function buildCaptcha($admin = 0){
  858. global $hc_cfg, $hc_lang_core;
  859. if($hc_cfg[65] == 1){
  860. if(!function_exists('imagecreate')){
  861. echo 'imagecreate function unavailable';
  862. return 0;}
  863. echo ($admin == 0) ? '<label class="blank">&nbsp;</label><p>'.$hc_lang_core['CapNotice'].'</p>' : '';
  864. echo '
  865. <label class="blank">&nbsp;</label>
  866. <img src="'.CalRoot.'/inc/captcha.php'.(($admin == 1) ? '?admin=1':'').'" width="250" alt="" id="cap_img" />
  867. <br /><br />
  868. <label for="proof">'.$hc_lang_core['ImageText'].'</label>
  869. <input onblur="testCAPTCHA();" name="proof" id="proof" type="text" maxlength="8" size="8" value="" required="required" />
  870. <div id="capChk"><a href="javascript:;" onclick="testCAPTCHA();" tabindex="-1" rel="nofollow">'.$hc_lang_core['Confirm'].'</a></div>';
  871. } elseif($hc_cfg[65] == 2) {
  872. if($hc_cfg[67] == ''){
  873. echo '<b>reCAPTCHA API Key Missing.</b>';
  874. return 0;}
  875. echo '<label class="blank">&nbsp;</label>';
  876. include(HCPATH . HCINC .'/api/recaptcha/recaptchalib.php');
  877. $error = '';
  878. echo '<script type="text/javascript">
  879. var RecaptchaOptions = {
  880. theme : \''.(($admin > 0) ? 'white' : $hc_cfg[90]).'\'
  881. ,lang : \'en\'
  882. };
  883. </script>
  884. '.recaptcha_get_html($hc_cfg[67], $error);
  885. }
  886. }
  887. /**
  888. * Test user CAPTCHA response. If response fails exit with notice.
  889. * @since 2.0.0
  890. * @version 2.0.0
  891. * @param string $proof users submitted response to the CAPTCHA
  892. * @param string $challenge required response generated by CAPTCHA
  893. * @param integer $checkMe form being checked, ensures CAPTCHA is active & required for the submission to be processed, 1 = Event Submission, 2 = Email to Friend, 3 = Event RSVP, 4 = Newsletter Sign-up/Edit
  894. * @return void
  895. */
  896. function spamIt($proof, $challenge, $checkMe){
  897. global $hc_cfg, $hc_lang_core;
  898. $spam = 0;
  899. $active = explode(",", $hc_cfg[32]);
  900. if(in_array($checkMe, $active)){
  901. if($hc_cfg[65] == 1){
  902. $spam = ($challenge != md5($proof)) ? 1 : 0;
  903. } elseif($hc_cfg[65] == 2){
  904. include(HCPATH . HCINC .'/api/recaptcha/recaptchalib.php');
  905. $resp = recaptcha_check_answer ($hc_cfg[68],$_SERVER["REMOTE_ADDR"],$challenge,$proof);
  906. if(!$resp->is_valid)
  907. $spam = 1;
  908. }
  909. if($spam != 0)
  910. exit($hc_lang_core['CAPTCHAFail']);
  911. }
  912. return;
  913. }
  914. /**
  915. * Output JavaScript function permitting user verification of response for Helios Native CAPTCHA.
  916. * @since 2.0.0
  917. * @version 2.0.0
  918. * @return void
  919. */
  920. function testCaptcha(){
  921. global $hc_lang_core;
  922. echo '
  923. function testCAPTCHA(){
  924. if(document.getElementById("proof").value != "")
  925. ajxOutput("'.CalRoot.'/inc/captcha_chk.php?capEntered=" + document.getElementById("proof").value, "capChk", "'.CalRoot.'");
  926. else
  927. alert("'.$hc_lang_core['Warn'].'");
  928. }';
  929. }
  930. /**
  931. * Verify password meets minimum complexity requirements: 6 characters, 1 numeric, 1 capitalized and 1 non-alphanumeric character.
  932. * @since 2.0.0
  933. * @version 2.0.0
  934. * @param string $pswd password string
  935. * @return boolean password meets requirements
  936. */
  937. function validPassword($pswd){
  938. if(strlen($pswd) < 6)
  939. return false;
  940. if(!preg_match('/[0-9]/',$pswd))
  941. return false;
  942. if(!preg_match('/[A-Z]/',$pswd))
  943. return false;
  944. if(!preg_match('/[^a-zA-Z0-9_]/',$pswd))
  945. return false;
  946. return true;
  947. }
  948. /**
  949. * Terminate execution and redirect to public calendar homepage with a 301 response.
  950. * @since 2.0.0
  951. * @version 2.0.0
  952. * @return void
  953. */
  954. function go_home(){
  955. header("HTTP/1.1 301 Moved Permanently");
  956. header("Location: ".CalRoot);
  957. exit();
  958. }
  959. /**
  960. * Truncate passed string to space nearest limit when size exceeds limit.
  961. * @since 2.0.0
  962. * @version 2.2.1
  963. * @param string $txt string to be inspected
  964. * @param integer $limit maximum length of $txt before it is truncated
  965. * @return string truncated string
  966. */
  967. function clean_truncate($txt,$limit){
  968. if(strlen($txt) <= $limit)
  969. return $txt;
  970. $space = strpos($txt," ",($limit-5));
  971. return ($space > 0) ? substr($txt,0,$space).'...' : substr($txt,0,$limit).'...';
  972. }
  973. /**
  974. * Filter accented characters from passed string replace with ASCII alternative, wrapper for iconv().
  975. * @since 2.1.0
  976. * @version 2.1.0
  977. * @param string $txt string to be filtered
  978. * @return string string with accented characters removed
  979. */
  980. function clean_accents($txt){
  981. global $hc_lang_config;
  982. if(function_exists('iconv'))
  983. $txt = str_replace("'", '',iconv($hc_lang_config['CharSet'], 'ASCII//TRANSLIT//IGNORE', $txt));
  984. return $txt;
  985. }
  986. /**
  987. * Used by reMail(), do not call this function directly.
  988. */
  989. function emailStop(){
  990. $_SESSION['EmailHalt'] = true;
  991. }
  992. /**
  993. * Used by reMail(), do not call this function directly.
  994. */
  995. function emailGo(){
  996. if(isset($_SESSION['EmailHalt']))
  997. unset($_SESSION['EmailHalt']);
  998. }
  999. /**
  1000. * Used by reMail(), do not call this function directly.
  1001. */
  1002. function emailStatus(){
  1003. return (isset($_SESSION['EmailHalt'])) ? 0 : 1;
  1004. }
  1005. /**
  1006. * Write APC user access cache to the database.
  1007. * @since 2.2.0
  1008. * @version 2.2.0
  1009. * @return void
  1010. */
  1011. function apc_user_write_cache($users = array()){
  1012. global $hc_cfg;
  1013. if(count($users) > 0){
  1014. $cases = '';
  1015. foreach($users as $save){
  1016. $cases .= " WHEN '".cIn($save[1])."' THEN (APICnt + ".cIn($save[0]).")";
  1017. }
  1018. doQuery("UPDATE " . HC_TblPrefix . "users SET APICnt = CASE NetworkName $cases ELSE APICnt END");
  1019. $new_age = date("U")+($hc_cfg[131]*60);
  1020. apc_store(HC_APCPrefix.'users_age',$new_age);
  1021. apc_delete(HC_APCPrefix.'users');
  1022. }
  1023. }
  1024. /**
  1025. * Generate and output form token to reduce CSRF risk.
  1026. * @since 2.2.0
  1027. * @version 2.2.0
  1028. * @param integer $return Action to perform with the generated token. 0 = Echo as hidden form input, 1 = Return token value as string. DEFAULT:0
  1029. * @return void|string If $return is 1 the token string will be returned. Otherwise no return occurs.
  1030. */
  1031. function set_form_token($return = 0){
  1032. global $hc_cfg;
  1033. $token = md5(sha1(AdminRoot.session_id().rand()));
  1034. $_SESSION['CurrentToken'] = $token;
  1035. echo ($return == 0) ? '
  1036. <input type="hidden" name="token" id="token" value="'.$token.'" />' : '';
  1037. return ($return == 0) ? NULL : $token;
  1038. }
  1039. /**
  1040. * Check submitted form token against current assigned token.
  1041. * @since 2.2.0
  1042. * @version 2.2.0
  1043. * @param string $chk_token The submitted token, will be checked against the user's current token.
  1044. * @return boolean Does the token match the user's current assigned token?
  1045. */
  1046. function check_form_token($chk_token){
  1047. return ($chk_token == $_SESSION['CurrentToken']) ? true : false;
  1048. }
  1049. /**
  1050. * Create CSV of RSVPs for a given event.
  1051. * @since 2.2.0
  1052. * @version 2.2.0
  1053. * @param integer $event_id ID # of the event to retrieve RSVPs for.
  1054. * @return string RSVP data in CSV format.
  1055. */
  1056. function fetch_event_rsvp($event_id = 0,$header){
  1057. if(!is_numeric($event_id) || $event_id <= 0)
  1058. return NULL;
  1059. $result = doQuery("SELECT r.Name, r.Email, r.Phone, r.Address, r.Address2, r.City, r.State, r.Zip, r.RegisteredAt, r.GroupID
  1060. FROM " . HC_TblPrefix . "registrants r
  1061. WHERE EventID = '" . cIn($event_id) . "'
  1062. GROUP BY r.PkID, r.Name, r.Email, r.Phone, r.Address, r.Address2, r.City, r.State, r.Zip, r.RegisteredAt, r.GroupID
  1063. ORDER BY RegisteredAt, GroupID");
  1064. $rsvps = "";
  1065. if(hasRows($result)){
  1066. $rsvps = $header;
  1067. while($row = hc_mysql_fetch_row($result)){
  1068. $rsvps .= "\n".'"'.clean_csv($row[0]).'","'.clean_csv($row[1]).'","'.clean_csv($row[2]).'","'.clean_csv($row[3]).'","'.clean_csv($row[4]).'","'.
  1069. clean_csv($row[5]).'","'.clean_csv($row[6]).'","'.clean_csv($row[7]).'","'.clean_csv($row[8]).'","'.clean_csv($row[9]).'"';
  1070. }
  1071. }
  1072. return $rsvps;
  1073. }
  1074. /**
  1075. * Escape special characters for use as CSV content.
  1076. * @since 2.2.0
  1077. * @version 2.2.0
  1078. * @param string $value Content string to be filtered.
  1079. * @return string filtered string.
  1080. */
  1081. function clean_csv($value){
  1082. $badChars = array('/"/','/,/','/\'/',);
  1083. $goodChars = array("\\\"", "\\\'", "\\\'");
  1084. $value = preg_replace($badChars,$goodChars,$value);
  1085. return $value;
  1086. }
  1087. /**
  1088. * Removes illegal characters from a string for use as filename.
  1089. * @since 2.2.0
  1090. * @version 2.2.0
  1091. * @param string $value Filename string to be filtered.
  1092. * @return string filtered file name safe for use.
  1093. */
  1094. function clean_filename($value){
  1095. $badChars = array('/\\\/','/\//','/:/','/[*]/','/\?/','/"/','/</','/>/','/\|/','/\./','/\'/');
  1096. $value = preg_replace($badChars,"",$value);
  1097. return $value;
  1098. }
  1099. ?>