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

/app/modules/dining/DiningWebModule.php

http://github.com/modolabs/Kurogo-Mobile-Web
PHP | 359 lines | 286 code | 58 blank | 15 comment | 43 complexity | 7a96bfa8f59b53f5e0373a8790716d5e MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1
  1. <?php
  2. /*
  3. * Copyright © 2010 - 2013 Modo Labs Inc. All rights reserved.
  4. *
  5. * The license governing the contents of this file is located in the LICENSE
  6. * file located at the root directory of this distribution. If the LICENSE file
  7. * is missing, please contact sales@modolabs.com.
  8. *
  9. */
  10. includePackage('Locations');
  11. class DiningWebModule extends WebModule {
  12. protected $id = 'dining';
  13. protected $DEFAULT_LOCATION_MODEL_CLASS = 'LocationsDataModel';
  14. protected $shouldGenerateNativeWebTemplates = true;
  15. protected $SHOW_HOURS_STATUS = true;
  16. protected $SHOW_EVENT_DETAILS = true;
  17. protected $timezone;
  18. protected $feeds;
  19. protected function loadFeed($feedID) {
  20. $feedData = $this->feeds[$feedID];
  21. $modelClass = isset($feedData['MODEL_CLASS']) ? $feedData['MODEL_CLASS'] : $this->DEFAULT_LOCATION_MODEL_CLASS;
  22. return LocationsDataModel::factory($modelClass, $feedData);
  23. }
  24. protected function linkForSchedule(KurogoObject $event, $data=null) {
  25. $subtitle = DateFormatter::formatDateRange($event->getRange(), DateFormatter::NO_STYLE, DateFormatter::SHORT_STYLE);
  26. $current = $this->getArg('time', time(), FILTER_VALIDATE_INT);
  27. $beginningOfDay = mktime(0, 0, 0, date('n', $current), date('j', $current));
  28. $endOfDay = mktime(23, 59, 59, date('n', $current), date('j', $current));
  29. $eventStart = $event->getStart();
  30. $eventEnd = $event->getEnd();
  31. if ($eventStart < $beginningOfDay) {
  32. // if starts more than one day before, put the date
  33. if ($eventStart < strtotime('-1 day', $beginningOfDay)) {
  34. $startDate = DateFormatter::formatDate($eventStart, DateFormatter::SHORT_STYLE, DateFormatter::NO_STYLE);
  35. } else {
  36. $startDate = $this->getLocalizedString('THE_PREVIOUS_DAY'); //'the previous day'
  37. }
  38. $subtitle = $this->getLocalizedString('IF_STARTS_EARLIER_DATE', $startDate) . $subtitle;
  39. }
  40. if ($eventEnd > $endOfDay) {
  41. // if ends more than one day after, put the date
  42. if ($eventEnd > strtotime('+1 day', $endOfDay)) {
  43. $endDate = DateFormatter::formatDate($eventEnd, DateFormatter::SHORT_STYLE, DateFormatter::NO_STYLE);
  44. } else {
  45. $endDate = $this->getLocalizedString('THE_FOLLOWING_DAY'); //'the following day'
  46. }
  47. $subtitle .= $this->getLocalizedString('IF_ENDS_LATER_DATE', $endDate);
  48. }
  49. $options = array(
  50. 'id' => $event->getID(),
  51. 'time' => $event->getStart()
  52. );
  53. if (isset($data['section'])) {
  54. $options['section'] = $data['section'];
  55. }
  56. if (isset($data['groupID'])) {
  57. $options['groupID'] = $data['groupID'];
  58. }
  59. $class = '';
  60. if($this->SHOW_EVENT_DETAILS) {
  61. $url = $this->buildBreadcrumbURL('schedule', $options, true);
  62. }else {
  63. $url = false;
  64. }
  65. if ($event->getRange()->contains(new TimeRange(time()))) {
  66. $class = 'open';
  67. } else {
  68. $class = 'closed';
  69. }
  70. return array(
  71. 'title' => $event->getTitle(),
  72. 'subtitle' => $subtitle,
  73. 'url' => $url,
  74. 'listclass' => ($this->SHOW_HOURS_STATUS) ? $class : null,
  75. );
  76. }
  77. protected function valueForType($type, $value) {
  78. $valueForType = $value;
  79. switch ($type) {
  80. case 'datetime':
  81. $valueForType = DateFormatter::formatDateRange($value, DateFormatter::LONG_STYLE, DateFormatter::NO_STYLE);
  82. if ($value instanceOf TimeRange) {
  83. $timeString = DateFormatter::formatDateRange($value, DateFormatter::NO_STYLE, DateFormatter::MEDIUM_STYLE);
  84. $valueForType .= "<br />\n" . $timeString;
  85. }
  86. break;
  87. case 'url':
  88. $valueForType = str_replace("http://http://", "http://", $value);
  89. if (strlen($valueForType) && !preg_match('/^http\:\/\//', $valueForType)) {
  90. $valueForType = 'http://'.$valueForType;
  91. }
  92. break;
  93. case 'phone':
  94. $valueForType = PhoneFormatter::formatPhone($value);
  95. break;
  96. case 'email':
  97. $valueForType = str_replace('@', '@&shy;', $value);
  98. break;
  99. case 'category':
  100. $valueForType = $this->formatTitle($value);
  101. break;
  102. }
  103. return $valueForType;
  104. }
  105. protected function urlForType($type, $value) {
  106. $urlForType = null;
  107. switch ($type) {
  108. case 'url':
  109. $urlForType = str_replace("http://http://", "http://", $value);
  110. if (strlen($urlForType) && !preg_match('/^http\:\/\//', $urlForType)) {
  111. $urlForType = 'http://'.$urlForType;
  112. }
  113. break;
  114. case 'phone':
  115. $urlForType = PhoneFormatter::getPhoneURL($value);
  116. break;
  117. case 'email':
  118. $urlForType = "mailto:$value";
  119. break;
  120. case 'category':
  121. $urlForType = $this->categoryURL($value, false);
  122. break;
  123. }
  124. return $urlForType;
  125. }
  126. protected function initialize() {
  127. $this->timezone = Kurogo::siteTimezone();
  128. $this->feeds = $this->getModuleSections('feeds');
  129. $this->SHOW_HOURS_STATUS = $this->getOptionalModuleVar('SHOW_HOURS_STATUS', true);
  130. $this->SHOW_EVENT_DETAILS = $this->getOptionalModuleVar('SHOW_EVENT_DETAILS', true);
  131. }
  132. protected function initializeIndex() {
  133. $breadcrumbs = $this->page != 'pane';
  134. // get location data models
  135. $locationDataModels = array();
  136. $groupedLocations = array();
  137. foreach ($this->feeds as $feedID => $feed) {
  138. $locationDataModels[$feedID] = $this->loadFeed($feedID);
  139. $groupedLocations[$feedID]['title'] = isset($feed['title']) ? $feed['title'] : null;
  140. }
  141. foreach ($locationDataModels as $feedID => $model) {
  142. if ($this->getOptionalModuleVar('SHOW_OPEN_AT_TOP', 0)) {
  143. $model->setSortByOpen();
  144. }
  145. $locations = $model->getLocations();
  146. $locationLinks = array();
  147. foreach ($locations as $location) {
  148. if ($location->hasAttribute('events')) {
  149. $subtitle = '';
  150. $currentEvents = $location->getCurrentEvents(time());
  151. $nextEvent = $location->getNextEvent(true);
  152. if (count($currentEvents)>0) {
  153. $events = array();
  154. $lastTime = null;
  155. foreach ($currentEvents as $event) {
  156. if ($event->getEnd() > $lastTime) {
  157. $lastTime = $event->getEnd();
  158. }
  159. $eventSummary = $event->getTitle();
  160. if (strlen($eventSummary)) {
  161. $events[] = $eventSummary . ': ' . EventsDataModel::timeText($event, true);
  162. } else {
  163. $events[] = EventsDataModel::timeText($event, true);
  164. }
  165. }
  166. $subtitle .= implode("<br />", $events);
  167. } else {
  168. if ($nextEvent) {
  169. $eventSummary = $nextEvent->getTitle();
  170. if (strlen($eventSummary)) {
  171. $subtitle .= $this->getLocalizedString('NEXT_EVENT') . $eventSummary . ': ' . EventsDataModel::timeText($nextEvent);
  172. } else {
  173. $subtitle .= $this->getLocalizedString('NEXT_EVENT') . EventsDataModel::timeText($nextEvent);
  174. }
  175. }
  176. }
  177. } else {
  178. // Dining module requires events attribute so skip this location
  179. // if it does not contain any events. Events don't necessarily need
  180. // to be currently occurring, but each location needs an events data model.
  181. continue;
  182. }
  183. $summary = $location->getAttribute('summary');
  184. if (strlen($summary)) {
  185. $subtitle = $summary.'<br />'.$subtitle;
  186. }
  187. $locationLinks[] = array(
  188. 'title' => $location->getTitle(),
  189. 'subtitle' => $subtitle,
  190. 'url' => $this->buildBreadcrumbURL('detail', array('groupID' => $feedID, 'id' => $location->getID()), $breadcrumbs),
  191. 'listclass' => ($this->SHOW_HOURS_STATUS) ? $location->getListClass() : null,
  192. );
  193. }
  194. $groupedLocations[$feedID]['items'] = $locationLinks;
  195. }
  196. $this->assign('groupedLocations', $groupedLocations);
  197. }
  198. protected function initializeDetail() {
  199. $feedID = $this->getArg('groupID');
  200. $locationID = $this->getArg('id');
  201. // specified date for events
  202. $current = $this->getArg('time', time(), FILTER_VALIDATE_INT);
  203. $next = strtotime("+1 day", $current);
  204. $prev = strtotime("-1 day", $current);
  205. $model = $this->loadFeed($feedID);
  206. $location = $model->getLocation($locationID);
  207. if ($location->hasAttribute('maploc')
  208. && $link = Kurogo::moduleLinkForValue('map', $location->getAttribute('maploc'), $this)) {
  209. $link['title'] = $this->getLocalizedString('VIEW_ON_MAP');
  210. $this->assign('location', array($link));
  211. }
  212. if ($location->hasAttribute('events')) {
  213. $events = $location->getTodaysEvents($current);
  214. $eventLinks = array();
  215. foreach ($events as $event) {
  216. $eventLink = $this->linkForSchedule($event, array('section' => $locationID, 'groupID' => $feedID));
  217. $eventLinks[] = $eventLink;
  218. }
  219. }
  220. $nextURL = $this->buildBreadcrumbURL('detail', array('id' => $locationID, 'groupID' => $feedID, 'time' => $next), false);
  221. $prevURL = $this->buildBreadcrumbURL('detail', array('id' => $locationID, 'groupID' => $feedID, 'time' => $prev), false);
  222. $dayRange = new DayRange(time());
  223. $this->assign('title', $location->getTitle());
  224. $this->assign('description', $location->getDescription());
  225. $this->assign('current', $current);
  226. $this->assign('events', $eventLinks);
  227. $this->assign('next', $next);
  228. $this->assign('prev', $prev);
  229. $this->assign('nextURL', $nextURL);
  230. $this->assign('prevURL', $prevURL);
  231. $this->assign('titleDateFormat', $this->getLocalizedString('MEDIUM_DATE_FORMAT'));
  232. $this->assign('linkDateFormat', $this->getLocalizedString('SHORT_DAY_FORMAT'));
  233. $this->assign('isToday', $dayRange->contains(new TimeRange($current)));
  234. }
  235. protected function initializeSchedule() {
  236. $locationID = $this->getArg('section');
  237. $eventID = $this->getArg('id');
  238. $feedID = $this->getArg('groupID');
  239. $model = $this->loadFeed($feedID);
  240. $location = $model->getLocation($locationID);
  241. $locationEvents = $location->getAttribute('events');
  242. $time = $this->getArg('time', time(), FILTER_VALIDATE_INT);
  243. if ($event = $locationEvents->getItem($eventID, $time)) {
  244. $this->assign('event', $event);
  245. } else {
  246. throw new KurogoUserException($this->getLocalizedString('EVENT_NOT_FOUND'));
  247. }
  248. $eventFields = $this->getModuleSections('schedule-detail');
  249. $fields = array();
  250. foreach ($eventFields as $key => $info) {
  251. $field = array();
  252. $value = $event->get_attribute($key);
  253. if (empty($value)) { continue; }
  254. if (isset($info['label'])) {
  255. $field['label'] = $info['label'];
  256. }
  257. if (isset($info['class'])) {
  258. $field['class'] = $info['class'];
  259. }
  260. if (Kurogo::arrayVal($info, 'nl2br')) {
  261. $value = nl2br($value);
  262. }
  263. if (isset($info['type'])) {
  264. $field['title'] = $this->valueForType($info['type'], $value);
  265. $field['url'] = $this->urlForType($info['type'], $value);
  266. } elseif (isset($info['module'])) {
  267. $field = array_merge($field, Kurogo::moduleLinkForValue($info['module'], $value, $this, $event));
  268. } else {
  269. $field['title'] = $value;
  270. }
  271. $fields[] = $field;
  272. }
  273. $this->assign('fields', $fields);
  274. }
  275. protected function initializeForPage() {
  276. switch ($this->page) {
  277. case 'index' :
  278. case 'pane' :
  279. $this->initializeIndex();
  280. break;
  281. case 'detail' :
  282. $this->initializeDetail();
  283. break;
  284. case 'schedule' :
  285. $this->initializeSchedule();
  286. break;
  287. }
  288. }
  289. public function nativeWebTemplateAssets() {
  290. return array(
  291. '/common/images/location-status-closed.png',
  292. '/common/images/location-status-open.png',
  293. '/common/images/location-status-restricted.png',
  294. '/common/images/location-status-unknown.png',
  295. '/common/images/location-status-closed@2x.png',
  296. '/common/images/location-status-open@2x.png',
  297. '/common/images/location-status-restricted@2x.png',
  298. '/common/images/location-status-unknown@2x.png',
  299. );
  300. }
  301. }