Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MyRadio_Event (Grouping Timeslots across shows) #929

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions schema/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"\\MyRadio\\ServiceAPI\\MyRadio_Show": "show",
"\\MyRadio\\ServiceAPI\\MyRadio_Season": "season",
"\\MyRadio\\ServiceAPI\\MyRadio_Timeslot": "timeslot",
"\\MyRadio\\ServiceAPI\\MyRadio_Event": "event",
"\\MyRadio\\ServiceAPI\\MyRadio_Album": "album",
"\\MyRadio\\ServiceAPI\\MyRadio_Demo": "demo",
"\\MyRadio\\ServiceAPI\\MyRadio_List": "list",
Expand Down Expand Up @@ -145,11 +146,12 @@
}
},
"anyOf": [{
"required": ["eduroam"]
},
{
"required": ["email"]
}]
"required": ["eduroam"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice linting tho

},
{
"required": ["email"]
}
]
}
}
}
}
22 changes: 22 additions & 0 deletions schema/patches/5.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
BEGIN;

create table schedule.events
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider consistent singular/plural table names? (e.g. member, show_season)

(
event_id text not null
constraint events_pk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary, PRIMARY KEY would suffice

primary key,
title text not null,
description text
);

create table schedule.event_timeslots
(
event_id text not null
constraint event_timeslots_events_event_id_fk
references schedule.events,
show_season_timeslot_id int not null
constraint event_timeslots_show_season_timeslot_show_season_timeslot_id_fk
references schedule.show_season_timeslot
);

COMMIT;
200 changes: 200 additions & 0 deletions src/Classes/ServiceAPI/MyRadio_Event.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
<?php

/**
* Provides the Event class for MyRadio
*/

namespace MyRadio\ServiceAPI;

use MyRadio\MyRadio\CoreUtils;
use MyRadio\MyRadioException;

/**
* The MyRadio_Event class provides and stores information about timeslots grouped together into an event
*
* @uses \Database
*/

class MyRadio_Event extends ServiceAPI
{
/**
* The ID of the Event
* Unique name, i.e. for URL
* @var string
*/
private $event_id;

/**
* The Title of the Event
* @var string
*/
private $title;

/**
* The Description of the Event
*/
private $description;

/**
* The Timeslots part of this event
* @var int[]
*/
private $timeslots;

public function __construct($data)
{
parent::__construct();
$this->event_id = $data["event_id"];
$this->title = $data["title"];
$this->description = $data["description"];
$this->timeslots = $data["timeslots"];
}

public function getID()
{
return $this->event_id;
}

/**
* Get the title of the event
* @return string
*/
public function getTitle()
{
return $this->title;
}

/**
* Get the description of the event
* @return string
*/
public function getDescription()
{
return $this->description;
}

/**
* Get the timeslots that are part of the event
* @return MyRadio_Timeslot[]
*/
public function getTimeslots()
{
if (!isset($this->timeslots)) {
$sql = "SELECT show_season_timeslot_id FROM schedule.event_timeslots
INNER JOIN schedule.show_season_timeslot USING (show_season_timeslot_id)
WHERE event_id = $1
ORDER BY start_time";
$rows = self::$db->fetchAll($sql, [$this->getID()]);
foreach ($rows as $row) {
$this->timeslots[] = intval($row["show_season_timeslot_id"]);
}
}
return MyRadio_Timeslot::resultSetToObjArray($this->timeslots);
}

public function toDataSource($mixins = [])
{
return [
"id" => $this->getID(),
"title" => $this->getTitle(),
"description" => $this->getDescription(),
"timeslots" => $this->timeslots,
];
}

/**
* Get all events
* @return MyRadio_Event[]
*/
public static function getAll()
{
$sql = "SELECT event_id, title, description FROM schedule.events";
$rows = self::$db->fetchAll($sql);

$events = [];
foreach ($rows as $row) {
$new_event = new self($row);
$new_event->getTimeslots();
$events[] = $new_event;
}

return CoreUtils::setToDataSource($events);
}

protected static function factory($itemid)
{
$sql = "SELECT event_id, title, description FROM schedule.events
WHERE event_id = $1 LIMIT 1";
$result = self::$db->fetchOne($sql, [$itemid]);

if (empty($result)) {
throw new MyRadioException("That Event doesn't exist.", 404);
}

$new_event = new self($result);
$new_event->getTimeslots();
return $new_event;
}

/**
* Creates a new MyRadio_Event and returns it as an object
*
* @param array $params
* Required: event_id, title
* Optional: description
*
* @return MyRadio_Event
*
* @throws MyRadioException
*/

public static function create($params = [])
{
// Check Required Fields
$required = ["event_id", "title"];
foreach ($required as $field) {
if (!isset($params[$field])) {
throw new MyRadioException("Parameter " . $field . "wasn't provided.", 400);
}
}

// Check Unique ID
$result = self::$db->fetchOne("SELECT COUNT(1) FROM schedule.events
WHERE event_id = $1", [$params["event_id"]]);

if (sizeof($result) > 0) {
throw new MyRadioException("Event ID isn't unique.", 400);
}

// Add Event
self::$db->query("INSERT INTO schedule.events
(event_id, title, description)
VALUES ($1, $2, $3)", [$params["event_id"], $params["title"], $params["description"]]);

return self::getInstance($params["event_id"]);
}

/**
* Add timeslot to event
*
* @param $timeslotID
*
* @throws MyRadioException
*/

public function addTimeslot($timeslotID)
{
try {
MyRadio_Timeslot::getInstance($timeslotID);
if (!in_array($timeslotID, $this->timeslots)) {
$this->timeslots[] = $timeslotID;
self::$db->query("INSERT INTO schedule.event_timeslots
(event_id, show_season_timeslot_id)
VALUES ($1, $2)", [$this->getID(), $timeslotID]);
}
} catch (MyRadioException $e) {
// Timeslot doesn't exist
throw $e;
}
}
}
36 changes: 36 additions & 0 deletions src/Classes/ServiceAPI/MyRadio_Timeslot.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class MyRadio_Timeslot extends MyRadio_Metadata_Common
private $timeslot_num;
protected $owner;
protected $credits;
private $events;

protected function __construct($timeslot_id)
{
Expand Down Expand Up @@ -142,6 +143,11 @@ protected function __construct($timeslot_id)
$this->credits[] = ['type' => (int)$credit_types[$i], 'memberid' => $credits[$i],
'User' => MyRadio_User::getInstance($credits[$i]),];
}

// Deal with Events the timeslot could be a part of
$this->events = self::$db->fetchColumn("SELECT event_id FROM schedule.event_timeslots
WHERE show_season_timeslot_id = $1", [$this->timeslot_id]);

}

public function getMeta($meta_string)
Expand Down Expand Up @@ -216,6 +222,35 @@ public function getEndTime()
return $this->getStartTime() + $duration;
}

/**
* Returns the events the timeslot is a part of
*
* @return MyRadio_Event[]
*/
public function getEvents(){
return MyRadio_Event::resultSetToObjArray($this->events);
}

/**
* Can add this timeslot to an event
*
* @param $event_id
*
* @return MyRadio_Event
*
* @throws MyRadioException
*/

public function addEvent($event_id){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how I feel about having the same-ish method in both Event and Timeslot… but feel free to overrule me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't hurt

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can actually

try{
$event = MyRadio_Event::getInstance($event_id);
$event->addTimeslot($this->getID());
return $event;
}catch (MyRadioException $e){
throw $e;
}
}

/**
* Gets the Timeslot that is on after this.
*
Expand Down Expand Up @@ -342,6 +377,7 @@ public function toDataSource($mixins = [])
'mixcloud_status' => $this->getMeta('upload_state'),
'mixcloud_starttime' => $this->getMeta('upload_starttime'),
'mixcloud_endtime' => $this->getMeta('upload_endtime'),
'events' => $this->events,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're gonna want to recursively toDataSource this (or use the appropriate CoreUtil), otherwise you'll JSON-encode an array of MyRadio_Event classes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, it'll just be the ids, that why $this->events not $this->getEvents()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We sure we want that? Perhaps make it a mixin to getEvents() - saves N API calls, where N is the number of events

'rejectlink' => [
'display' => 'icon',
'value' => 'trash',
Expand Down