PageRenderTime 26ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/phpical2/functions/calendar_functions.php

https://gitlab.com/endomorphosis/fusenews
PHP | 277 lines | 153 code | 25 blank | 99 comment | 71 complexity | db59f29c30209ad9c42e763252858131 MD5 | raw file
  1. <?php
  2. // This function returns a list of all calendars that the current user
  3. // has access to. Basically, all local calendars found in the calendar
  4. // directory, plus any webcals listed in the configuration file, but
  5. // excluding blacklisted calendars and locked calendars which the user,
  6. // if logged in, does not have access to.
  7. //
  8. // $username = The username. Empty if no username provided.
  9. // $password = The password. Empty if no password provided.
  10. // $cal_filename = The calendar name without .ics.
  11. // $admin = True if this is an administrative request, in
  12. // which case all local calendars only will be
  13. // returned.
  14. function availableCalendars($username, $password, $cal_filename, $admin = false) {
  15. // Import globals.
  16. global $list_webcals, $blacklisted_cals, $locked_cals, $locked_map, $apache_map, $lang, $_SERVER, $phpiCal_config;
  17. // Create the list of available calendars.
  18. $calendars = array();
  19. // Grab any HTTP authentication.
  20. unset($http_user);
  21. if ((isset($_SERVER['PHP_AUTH_USER'])) && ($phpiCal_config->allow_login == 'yes')) {
  22. $http_user = $_SERVER['PHP_AUTH_USER'];
  23. }
  24. // Grab the list of unlocked calendars.
  25. $unlocked_cals = array();
  26. if (isset($locked_map["$username:$password"])) {
  27. $unlocked_cals = $locked_map["$username:$password"];
  28. }
  29. // Make a local copy of the requested calendars.
  30. if (!is_array($cal_filename))
  31. $cal_filename_local = array($cal_filename);
  32. else
  33. $cal_filename_local = $cal_filename;
  34. // Create the list of available calendars.
  35. $calendars = array();
  36. // This array keeps track of paths we need to search.
  37. $search_paths = array($phpiCal_config->calendar_path);
  38. // Add web calendars.
  39. if ($cal_filename_local[0] == $phpiCal_config->ALL_CALENDARS_COMBINED || $admin) {
  40. if (!isset($http_user) && !$admin) {
  41. foreach ($list_webcals as $file) {
  42. // Make sure the URL ends with .ics.
  43. if (!is_string($file)) continue;
  44. // Add this calendar.
  45. array_push($calendars, $file);
  46. }
  47. }
  48. }
  49. // Set some booleans that will dictate our search.
  50. $find_all = ($cal_filename_local[0] == $phpiCal_config->ALL_CALENDARS_COMBINED || $admin);
  51. // Process all search paths.
  52. while (!empty($search_paths)) {
  53. // Read the next search path.
  54. $search_path = array_pop($search_paths);
  55. // This array keeps track of filenames we need to look at.
  56. $files = array();
  57. // Build the list of files we need to check.
  58. //
  59. // We do a full directory search if we are supposed to find all
  60. // calendars, the calendar we're looking for may be in a
  61. // subdirectory, or we are supporting the iCal repository format.
  62. // The latter is necessary because the calendar name cannot be
  63. // used to identify the calendar filename.
  64. if ($find_all || $phpiCal_config->recursive_path == 'yes' || $phpiCal_config->support_ical == 'yes') {
  65. // Open the directory.
  66. $dir_handle = opendir($search_path)
  67. or die(error(sprintf($lang['l_error_path'], $search_path), implode(',', $cal_filename)));
  68. if ($dir_handle === false)
  69. die(error(sprintf($lang['l_error_path'], $search_path), implode(',', $cal_filename)));
  70. // Add each file in the directory that does not begin with a dot.
  71. while (false !== ($file = readdir($dir_handle))) {
  72. // Make sure this is not a dot file.
  73. if (preg_match("/^\./", $file)) continue;
  74. array_push($files, "$search_path/$file");
  75. }
  76. } else {
  77. // The file process block below expects actual filenames. So
  78. // we have to append '.ics' to the passed in calendar names.
  79. foreach ($cal_filename_local as $filename) {
  80. array_push($files, "$search_path/$filename".".ics");
  81. }
  82. }
  83. // Process files.
  84. foreach ($files as $file) {
  85. // Push directories onto the search paths if recursive paths is
  86. // turned on.
  87. if (is_dir($file)) {
  88. if ($phpiCal_config->recursive_path == 'yes') array_push($search_paths, $file);
  89. continue;
  90. }
  91. // Make sure the file is real.
  92. if (!is_file($file)) continue;
  93. // Remove any php files.
  94. if (preg_match("/^.*\.php$/i", $file)) continue;
  95. # remove publish log file
  96. if ($file == 'publish_log.txt') continue;
  97. // Make sure this is not a blacklisted calendar.
  98. $cal_name = getCalendarName($file);
  99. if (in_array($cal_name, $blacklisted_cals)) continue;
  100. // If HTTP authenticated, make sure this calendar is available
  101. // to the user.
  102. if (isset($http_user) && isset($apache_map[$http_user]) && !in_array($cal_name, $apache_map[$http_user])) continue;
  103. // Make sure this calendar is not locked.
  104. if (!$admin && in_array($cal_name, $locked_cals) && !in_array($cal_name, $unlocked_cals)) continue;
  105. // Add this calendar if we're looking for it, and remove it's name
  106. // from the local list because we've found it.
  107. if ($find_all || in_array($cal_name, $cal_filename_local)) {
  108. array_push($calendars, $file);
  109. $cal_filename_local = array_diff($cal_filename_local, array($cal_name));
  110. // If the local list is empty, we're done.
  111. if (empty($cal_filename_local)) break 2;
  112. }
  113. }
  114. }
  115. // Return the sorted calendar list.
  116. natcasesort($calendars);
  117. return $calendars;
  118. }
  119. // This function returns the result of the availableCalendars function
  120. // but only includes the calendar names.
  121. //
  122. // $username = The username. Empty if no username provided.
  123. // $password = The password. Empty if no password provided.
  124. // $cal_filename = The calendar name without .ics.
  125. // $admin = True if this is an administrative request, in
  126. // which case all local calendars only will be
  127. // returned.
  128. function availableCalendarNames($username, $password, $cal_filename, $admin = false) {
  129. // Grab the available calendar paths.
  130. $calendars = availableCalendars($username, $password, $cal_filename, $admin);
  131. // Strip the paths off the calendars.
  132. foreach (array_keys($calendars) as $key) {
  133. $calendars[$key] = getCalendarName($key);
  134. }
  135. // Return the sorted calendar names.
  136. natcasesort($calendars);
  137. return $calendars;
  138. }
  139. // This function returns the calendar name for the specified calendar path.
  140. //
  141. // $cal_path = The path to the calendar file.
  142. function getCalendarName($cal_path) {
  143. global $phpiCal_config;
  144. // If iCal is supported, check the directory for an Info.plist.
  145. if ($phpiCal_config->support_ical == 'yes') {
  146. // Look for the Info.plist file.
  147. $plist_filename = dirname($cal_path)."/Info.plist";
  148. if (is_file($plist_filename)) {
  149. // Read the Info.plist.
  150. $handle = fopen($plist_filename, 'r');
  151. $contents = fread($handle, filesize($plist_filename));
  152. fclose($handle);
  153. // Pull out the calendar name.
  154. $num_matches = preg_match("/<key>Title<\/key>\s*?<string>(.+?)<\/string>/i", $contents, $matches);
  155. if ($num_matches > 0)
  156. return $matches[1];
  157. }
  158. }
  159. // At this point, just pull the name off the file.
  160. return str_replace(".ics", '', basename($cal_path));
  161. }
  162. // This function prints out the calendars available to the user, for
  163. // selection. Should be enclosed within a <select>...</select>, which
  164. // is not printed out by this function.
  165. //
  166. // $cals = The calendars (entire path, e.g. from availableCalendars).
  167. function display_ical_list($cals, $pick=FALSE) {
  168. global $cal, $current_view, $getdate, $lang, $calendar_lang, $all_cal_comb_lang, $cal_filelist, $cal_displaynames, $list_webcals, $phpiCal_config;
  169. // Print each calendar option.
  170. $return = '';
  171. foreach ($cals as $cal_tmp) {
  172. // Format the calendar path for display.
  173. //
  174. // Only display the calendar name, replace all instances of "32" with " ",
  175. // and remove the .ics suffix.
  176. $cal_displayname_tmp = getCalendarName($cal_tmp);
  177. #$cal_displayname_tmp = str_replace("32", " ", $cal_displayname_tmp);
  178. #overwrite the display name if we already have a real name
  179. if (is_numeric(array_search($cal_tmp, $cal_filelist))){
  180. $cal_displayname_tmp = $cal_displaynames[array_search($cal_tmp,$cal_filelist)];
  181. }else{
  182. # pull the name from the $cal_tmp file
  183. $cal_tmp2 = str_replace('webcal://','http://',$cal_tmp);
  184. $ifile = @fopen($cal_tmp2, "r");
  185. if ($ifile == FALSE) exit(error($lang['l_error_cantopen'], $cal_tmp));
  186. while (!feof($ifile)) {
  187. $line = fgets($ifile, 1024);
  188. $line = trim($line);
  189. if (ereg ("([^:]+):(.*)", $line, $regs)){
  190. $field = $regs[1];
  191. $data = $regs[2];
  192. $property = $field;
  193. $prop_pos = strpos($property,';');
  194. if ($prop_pos !== false) $property = substr($property,0,$prop_pos);
  195. $property = strtoupper($property);
  196. if ($property == "X-WR-CALNAME"){
  197. $cal_displayname_tmp = stripslashes($data);
  198. break;
  199. }
  200. }
  201. #stop reading if we find an event or timezone before there's a name
  202. if ($line == "BEGIN:VTIMEZONE" ||$line == "BEGIN:VEVENT") break;
  203. }
  204. }
  205. // If this is a webcal, add 'Webcal' to the display name.
  206. if (preg_match("/^(https?|webcal):\/\//i", $cal_tmp)) {
  207. $cal_displayname_tmp .= " Webcal";
  208. }
  209. // Otherwise, remove all the path information, since that should
  210. // not be used to identify local calendars. Also add the calendar
  211. // label to the display name.
  212. else {
  213. // Strip path and .ics suffix.
  214. $cal_tmp = getCalendarName($cal_tmp);
  215. // Add calendar label.
  216. $cal_displayname_tmp .= " $calendar_lang";
  217. }
  218. // Encode the calendar path.
  219. $cal_encoded_tmp = urlencode($cal_tmp);
  220. if(in_array($cal_tmp, $list_webcals)){
  221. $cal_encoded_tmp = md5($phpiCal_config->salt.$cal_tmp);;
  222. }
  223. // Display the option.
  224. //
  225. // The submitted calendar will be encoded, and always use http://
  226. // if it is a webcal. So that is how we perform the comparison when
  227. // trying to figure out if this is the selected calendar.
  228. if($pick) {
  229. if (in_array($cal_encoded_tmp, explode(",", $cal)) || count($cals) == count(explode(",", $cal))) {
  230. $return .= "<option value=\"$cal_encoded_tmp\" selected=\"selected\">$cal_displayname_tmp</option>\n";
  231. } else {
  232. $return .= "<option value=\"$cal_encoded_tmp\">$cal_displayname_tmp</option>\n";
  233. }
  234. } else {
  235. $cal_httpPrefix_tmp = str_replace('webcal://', 'http://', $cal_tmp);
  236. if ($cal_encoded_tmp == urldecode($cal)) {
  237. $return .= "<option value=\"$current_view.php?cal=$cal_encoded_tmp&amp;getdate=$getdate\" selected=\"selected\">$cal_displayname_tmp</option>";
  238. } else {
  239. $return .= "<option value=\"$current_view.php?cal=$cal_encoded_tmp&amp;getdate=$getdate\">$cal_displayname_tmp</option>";
  240. }
  241. }
  242. }
  243. // option to open all (non-web) calenders together
  244. if (!$pick) {
  245. if ($cal == $phpiCal_config->ALL_CALENDARS_COMBINED) {
  246. $return .= "<option value=\"$current_view.php?cal=$phpiCal_config->ALL_CALENDARS_COMBINED&amp;getdate=$getdate\" selected=\"selected\">$all_cal_comb_lang</option>";
  247. } else {
  248. $return .= "<option value=\"$current_view.php?cal=$phpiCal_config->ALL_CALENDARS_COMBINED&amp;getdate=$getdate\">$all_cal_comb_lang</option>";
  249. }
  250. }
  251. return $return;
  252. }