Merge pull request #117 from sourcefabric/saas-dev-schedule-widget-angular

Saas dev schedule widget angular
This commit is contained in:
Albert Santoni 2015-07-01 15:05:59 -04:00
commit 00dfd64677
4 changed files with 117 additions and 85 deletions

View file

@ -57,83 +57,83 @@ class WidgetHelper
return $result; return $result;
} }
// Second version of this function. /**
// Removing "next" days and creating two weekly arrays * Returns a weeks worth of shows in UTC, and an info array of the current week's days.
public static function getWeekInfoV2($timezone) * Returns an array of two arrays:
*
* The first array is 7 consecutive week days, starting with the current day.
*
* The second array contains shows scheduled during the 7 week days in the first array.
* The shows returned in this array are not in any order and are in UTC.
*
* We don't do any timezone conversion in this function on purpose. All timezone conversion
* and show time ordering should be done on the frontend.
*
* @return array
*/
public static function getWeekInfoV2()
{ {
//weekStart is in station time.
//$weekStartDateTime = Application_Common_DateHelper::getWeekStartDateTime();
$weekStartDateTime = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone())); $weekStartDateTime = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone()));
$maxNumOFWeeks = 2;
$result = array(); $result = array();
// default to the station timezone
$timezone = Application_Model_Preference::GetDefaultTimezone();
$userDefinedTimezone = strtolower($timezone);
// if the timezone defined by the user exists, use that
if (array_key_exists($userDefinedTimezone, timezone_abbreviations_list())) {
$timezone = $userDefinedTimezone;
}
$utcTimezone = new DateTimeZone("UTC"); $utcTimezone = new DateTimeZone("UTC");
$weekStartDateTime->setTimezone($utcTimezone); $weekStartDateTime->setTimezone($utcTimezone);
// When querying for shows we need the start and end date range to have // Use this variable as the start date/time range when querying
// a time of "00:00". $utcDayStart is used below when querying for shows. // for shows. We set it to 1 day prior to the beginning of the
$utcDayStartDT = clone $weekStartDateTime; // schedule widget data to account for show date changes when
$utcDayStartDT->setTime(0, 0, 0); // converting their start day/time to the client's local timezone.
$utcDayStart = $utcDayStartDT->format(DEFAULT_TIMESTAMP_FORMAT); $showQueryDateRangeStart = clone $weekStartDateTime;
$weekCounter = 0; $showQueryDateRangeStart->sub(new DateInterval("P1D"));
while ($weekCounter < $maxNumOFWeeks) { $showQueryDateRangeStart->setTime(0, 0, 0);
for ($dayOfWeekCounter = 0; $dayOfWeekCounter < DAYS_PER_WEEK; $dayOfWeekCounter++) {
$dateParse = date_parse($weekStartDateTime->format(DEFAULT_TIMESTAMP_FORMAT));
$result[$weekCounter][$dayOfWeekCounter]["dayOfMonth"] = $dateParse["day"]; for ($dayOfWeekCounter = 0; $dayOfWeekCounter < DAYS_PER_WEEK; $dayOfWeekCounter++) {
$result[$weekCounter][$dayOfWeekCounter]["dayOfWeek"] = strtoupper(date("D", $weekStartDateTime->getTimestamp())); $dateParse = date_parse($weekStartDateTime->format("Y-m-d H:i:s"));
//have to be in station timezone when adding 1 day for daylight savings. // Associate data to its date so that when we convert this array
$weekStartDateTime->setTimezone(new DateTimeZone($timezone)); // to json the order remains the same - in chronological order.
$weekStartDateTime->add(new DateInterval('P1D')); // We also format the key to be for example: "2015-6-1" to match
// javascript date formats so it's easier to sort the shows by day.
$result["weekDays"][$weekStartDateTime->format("Y-n-j")] = array();
$result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfMonth"] = $dateParse["day"];
$result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfWeek"] = strtoupper(date("D", $weekStartDateTime->getTimestamp()));
//convert back to UTC to get the actual timestamp used for search. // Shows scheduled for this day will get added to this array when
$weekStartDateTime->setTimezone($utcTimezone); // we convert the show times to the client's local timezone in weekly-program.phtml
$result["weekDays"][$weekStartDateTime->format("Y-n-j")]["shows"] = array();
// When querying for shows we need the start and end date range to have // $weekStartDateTime has to be in station timezone when adding 1 day for daylight savings.
// a time of "00:00". // TODO: is this necessary since we set the time to "00:00" ?
$utcDayEndDT = clone $weekStartDateTime; $stationTimezone = Application_Model_Preference::GetDefaultTimezone();
$utcDayEndDT->setTime(0, 0, 0); $weekStartDateTime->setTimezone(new DateTimeZone($stationTimezone));
$utcDayEnd = $utcDayEndDT->format(DEFAULT_TIMESTAMP_FORMAT);
$shows = Application_Model_Show::getNextShows($utcDayStart, "ALL", $utcDayEnd);
$utcDayStart = $utcDayEnd;
// convert to user-defined timezone, or default to station $weekStartDateTime->add(new DateInterval('P1D'));
Application_Common_DateHelper::convertTimestampsToTimezone(
$shows,
array("starts", "ends", "start_timestamp", "end_timestamp"),
$timezone
);
//convert back to UTC to get the actual timestamp used for search.
foreach($shows as &$show) { $weekStartDateTime->setTimezone($utcTimezone);
$startParseDate = date_parse($show['starts']);
$show["show_start_hour"] = str_pad($startParseDate["hour"], 2, "0", STR_PAD_LEFT).":".str_pad($startParseDate["minute"], 2, 0, STR_PAD_LEFT);
$endParseDate = date_parse($show['ends']);
$show["show_end_hour"] = str_pad($endParseDate["hour"], 2, 0, STR_PAD_LEFT).":".str_pad($endParseDate["minute"],2, 0, STR_PAD_LEFT);
}
$result[$weekCounter][$dayOfWeekCounter]["shows"] = $shows;
}
$weekCounter += 1;
} }
// Use this variable as the end date/time range when querying
// for shows. We set it to 1 day after the end of the schedule
// widget data to account for show date changes when converting
// their start day/time to the client's local timezone.
$showQueryDateRangeEnd = clone $weekStartDateTime;
$showQueryDateRangeEnd->setTime(23, 59, 0);
$shows = Application_Model_Show::getNextShows(
$showQueryDateRangeStart->format("Y-m-d H:i:s"),
"ALL",
$showQueryDateRangeEnd->format("Y-m-d H:i:s"));
$result["shows"] = $shows;
// XSS exploit prevention // XSS exploit prevention
SecurityHelper::htmlescape_recursive($result); SecurityHelper::htmlescape_recursive($result);
// convert image paths to point to api endpoints // convert image paths to point to api endpoints
//TODO: do we need this here?
self::findAndConvertPaths($result); self::findAndConvertPaths($result);
return $result; return $result;

View file

@ -84,7 +84,6 @@ class EmbedController extends Zend_Controller_Action
$request = $this->getRequest(); $request = $this->getRequest();
$widgetStyle = $request->getParam('style'); $widgetStyle = $request->getParam('style');
if ($widgetStyle == "premium") { if ($widgetStyle == "premium") {
$this->view->widgetStyle = "premium"; $this->view->widgetStyle = "premium";
@ -95,10 +94,9 @@ class EmbedController extends Zend_Controller_Action
} }
$this->view->jquery = Application_Common_HTTPHelper::getStationUrl() . "widgets/js/jquery-1.6.1.min.js?".$CC_CONFIG['airtime_version']; $this->view->jquery = Application_Common_HTTPHelper::getStationUrl() . "widgets/js/jquery-1.6.1.min.js?".$CC_CONFIG['airtime_version'];
$weeklyScheduleData = WidgetHelper::getWeekInfoV2($this->getRequest()->getParam("timezone")); $weeklyScheduleData = WidgetHelper::getWeekInfoV2();
// Return only the current week's schedule data. In the future we may use the next week's data. $this->view->schedule_data = json_encode($weeklyScheduleData);
$this->view->weeklyScheduleData = ($weeklyScheduleData[0]);
$currentDay = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone())); $currentDay = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone()));
//day of the month without leading zeros (1 to 31) //day of the month without leading zeros (1 to 31)

View file

@ -2,13 +2,20 @@
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js" type="text/javascript"></script>
<link rel="stylesheet" href="<?php echo $this->css?>" type="text/css"> <link rel="stylesheet" href="<?php echo $this->css?>" type="text/css">
<script src="<?php echo $this->jquery ?>" type="text/javascript"></script> <script src="<?php echo $this->jquery ?>" type="text/javascript"></script>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,300,700' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Roboto:400,100,300,700' rel='stylesheet' type='text/css'>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
//initialize first day to active
$('.tabs').find("li").first().addClass("active");
$('.schedule_content').find('.schedule_item').first().addClass("active");
$('.tabs li').click(function(){ $('.tabs li').click(function(){
var tab_id = $(this).attr('data-tab'); //var tab_id = $(this).attr('data-tab');
var tab_id = "day-"+$(this).find('span').text();
$('.tabs li').removeClass('active'); $('.tabs li').removeClass('active');
$('.schedule_item').removeClass('active'); $('.schedule_item').removeClass('active');
@ -18,38 +25,65 @@
}); });
}); });
String.prototype.paddingLeft = function(paddingValue) {
return String(paddingValue + this).slice(-paddingValue.length);
};
var schedule_data = <?php echo $this->schedule_data; ?>;
var app = angular.module('scheduleWidget', []);
app.controller('scheduleController', ['$scope', '$window', function($scope, $window) {
// Loop through every show and assign it to the corresponding day of the week's
// show array.
angular.forEach($window.schedule_data["shows"], function(value, key) {
// First we have to create a Date object out of the show time in UTC.
// Then we can format the string in the client's local timezone.
var start_date = new Date(value.starts + " UTC");
var end_date = new Date(value.ends + " UTC");
// This variable is used to identify which schedule_data object (which day of the week)
// we should assign the show to.
// NOTE: we have to add 1 to the month because javascript's Date.getMonth()
// function returns the month number starting with an index of 0. In PHP,
// the months are indexed starting at 1.
var format_start_date = start_date.getFullYear() + "-" + (start_date.getMonth()+1) + "-" + start_date.getDate();
if ($window.schedule_data["weekDays"][format_start_date] !== undefined) {
$window.schedule_data["weekDays"][format_start_date]["shows"].push(
{
"show_start_hour": start_date.getHours().toString().paddingLeft("00")+":"+ start_date.getMinutes().toString().paddingLeft("00"),
"show_end_hour": end_date.getHours().toString().paddingLeft("00")+":"+ end_date.getMinutes().toString().paddingLeft("00"),
"name": value.name
});
}
});
$scope.weekDays = $window.schedule_data["weekDays"];
$scope.isEmpty = function(obj) {
return obj.length == 0;
};
}]);
</script> </script>
</head> </head>
<body> <body ng-app="scheduleWidget" ng-controller="scheduleController">
<div class="schedule tab_content current"> <div class="schedule tab_content current">
<ul class="tabs"> <ul class="tabs">
<?php <li ng-repeat="x in weekDays track by $index">
foreach($this->weeklyScheduleData as $day => $data) { {{x.dayOfWeek}}<span>{{x.dayOfMonth}}</span>
$activeClass = $this->currentDayOfMonth == $data["dayOfMonth"] ? "active" : ""; </li>
echo "<li class='".$activeClass."' data-tab='day-".$data["dayOfMonth"]."'>" . $data["dayOfWeek"] . "<span>" . $data["dayOfMonth"] . "</span></li>";
}?>
</ul> </ul>
<div class="schedule_content"> <div class="schedule_content">
<?php <div ng-repeat="x in weekDays track by $index" ng-attr-id="{{'day-' + x.dayOfMonth}}" class="schedule_item">
foreach($this->weeklyScheduleData as $day => $data) { <div ng-if="isEmpty(x.shows)" class="row empty-schedule">Looks like there are no shows scheduled on this day.</div>
$activeClass = $this->currentDayOfMonth == $data["dayOfMonth"] ? "active" : ""; <div ng-repeat="show in x.shows" class="row">
<div class="time_grid">{{show.show_start_hour}} - {{show.show_end_hour}}</div>
echo "<div id='day-".$data["dayOfMonth"]."' class='schedule_item ".$activeClass."'>"; <div class="name_grid">{{show.name}}</div>
if (count($data["shows"]) == 0) { </div>
echo "<div class='row empty-schedule'>Looks like there are no shows scheduled on this day.</div>"; </div>
} else {
foreach ($data["shows"] as $show => $showData) {
echo "<div class='row'>";
echo "<div class='time_grid'>" . $showData["show_start_hour"] . ' - ' . $showData["show_end_hour"] . "</div>";
echo "<div class='name_grid'>" . $showData["name"] . "</div>";
echo "</div>";
}
}
echo "</div>";
}?>
</div> </div>
<div class="weekly-schedule-widget-footer" <?php if ($this->widgetStyle == "premium") echo "style='display:none'"; ?>> <div class="weekly-schedule-widget-footer" <?php if ($this->widgetStyle == "premium") echo "style='display:none'"; ?>>

View file

@ -186,7 +186,7 @@ background: rgba(53, 53, 53, 1.0);
} }
.schedule_item div.name_grid { .schedule_item div.name_grid {
width: 72%; width: 70%;
} }
} }