public function getIndex($pageNo = 0) { $pageNo = intval($pageNo); $itemsPerPage = intval(Config::get("custom.num_playlists_per_page")); $itemOffset = $pageNo * $itemsPerPage; $numPlaylists = Playlist::accessibleToPublic()->belongsToShow(false)->count(); $numPages = ceil($numPlaylists / $itemsPerPage); $playlists = Playlist::accessibleToPublic()->belongsToShow(false)->orderBy("name", "asc")->orderBy("description", "asc")->skip($itemOffset)->take($itemsPerPage)->get(); if ($pageNo > 0 && $playlists->count() === 0) { App::abort(404); } $coverArtResolutions = Config::get("imageResolutions.coverArt"); $playlistTableData = array(); foreach ($playlists as $i => $item) { $thumbnailUri = Config::get("custom.default_cover_uri"); if (!Config::get("degradedService.enabled")) { $thumbnailUri = $item->getCoverArtUri($coverArtResolutions['thumbnail']['w'], $coverArtResolutions['thumbnail']['h']); } $playlistTableData[] = array("uri" => $item->getUri(), "title" => $item->generateName(), "escapedDescription" => !is_null($item->description) ? e($item->description) : null, "playlistName" => null, "episodeNo" => null, "thumbnailUri" => $thumbnailUri, "thumbnailFooter" => null, "duration" => null, "active" => false); } $playlistFragment = count($playlistTableData) > 0 ? View::make("fragments.home.playlist", array("stripedTable" => true, "headerRowData" => null, "tableData" => $playlistTableData)) : null; $pageNumbers = array(); for ($i = 0; $i < $numPages; $i++) { $pageNumbers[] = array("num" => $i + 1, "uri" => URL::route("playlists", array($i)), "active" => $i === $pageNo); } $openGraphProperties = array(); $openGraphProperties[] = array("name" => "video:release_date", "content" => null); foreach ($playlistTableData as $a) { $openGraphProperties[] = array("name" => "og:see_also", "content" => $a['uri']); } $view = View::make("home.playlists.index"); $view->playlistFragment = $playlistFragment; $view->pageSelectorFragment = View::make("fragments.home.pageSelector", array("nextUri" => $pageNo < $numPages - 1 ? URL::route("playlists", array($pageNo + 1)) : null, "prevUri" => $pageNo > 0 ? URL::route("playlists", array($pageNo - 1)) : null, "numbers" => $pageNumbers)); $this->setContent($view, "playlists", "playlists", $openGraphProperties, "Playlists"); }
public function handleRequest($playlistId, $mediaItemId) { $playlist = Playlist::with("show", "mediaItems")->accessible()->accessibleToPublic()->find(intval($playlistId)); $mediaItem = null; if (!is_null($playlist)) { $mediaItem = $playlist->mediaItems()->accessible()->find($mediaItemId); } if (is_null($mediaItem)) { $this->do404Response($this->getDisableRedirect()); return; } $this->prepareResponse($playlist, $mediaItem); }
private function checkPlaylistsForReindex() { // check for media items which which should be reindexed because their accessibiliy has changed $playlistsToReindex = Playlist::upToDateInIndex()->where(function ($q) { $q->where(function ($q) { $q->accessibleToPublic()->where("in_index", false); })->orWhere(function ($q) { $q->notAccessibleToPublic()->where("in_index", true); }); })->get(); foreach ($playlistsToReindex as $a) { // touching will increment the version number $a->touch(); $this->info("Playlist with id " . $a->id . " queued for reindex."); } }
/** * Run the database seeds. * * @return void */ public function run() { // presumes that media items already exist and ids from autoincrement DB::transaction(function () { $playlist = new Playlist(array("name" => "Roses 2014!", "enabled" => true, "description" => "Description about roses 2014 series.", "series_no" => 1, "scheduled_publish_time" => Carbon::now())); $playlist->show()->associate(Show::find(1)); $playlist->save(); $playlist->mediaItems()->attach(MediaItem::find(1), array("position" => 0)); $playlist->mediaItems()->attach(MediaItem::find(2), array("position" => 1)); }); DB::transaction(function () { $playlist = Playlist::create(array("name" => "Top Shows", "enabled" => true, "description" => "LA1:TV's top shows for 2014.", "scheduled_publish_time" => Carbon::now())); $playlist->mediaItems()->attach(MediaItem::find(2), array("position" => 0)); }); $this->command->info('Playlists created and media items added!'); }
protected static function boot() { parent::boot(); self::saving(function ($model) { if ($model->enabled && is_null($model->scheduled_publish_time)) { throw new Exception("A Playlist which is enabled must have a scheduled publish time."); } else { if ($model->show_id === NULL) { if ($model->name === NULL) { throw new Exception("A name must be specified."); } else { if ($model->series_no !== NULL) { throw new Exception("A standard playlist cannot have a series number."); } } } else { if ($model->series_no === NULL) { throw new Exception("Series number required."); } } } // transaction ended in "saved" event // needed to make sure if search index version number is incremented it // takes effect at the same time that the rest of the media item is updated DB::beginTransaction(); // assume that something has changed and force ths item to be reindexed $a = Playlist::with("mediaItems")->find(intval($model->id)); // $a may be null if this item is currently being created // when the item is being created pending_search_index_version defaults to 1 // meaning the item will be indexed if (!is_null($a)) { // make sure get latest version number. The version in $model might have changed before the transaction started $currentPendingIndexVersion = intval($a->pending_search_index_version); $model->pending_search_index_version = $currentPendingIndexVersion + 1; // also force reindex of all items that are currently in the playlist foreach ($a->mediaItems as $mediaItem) { $mediaItem->touch(); } } return true; }); self::saved(function ($model) { DB::commit(); }); }
/** * Run the database seeds. * * @return void */ public function run() { DB::statement('SET FOREIGN_KEY_CHECKS=0;'); LiveStream::truncate(); MediaItem::truncate(); MediaItemComment::truncate(); MediaItemLike::truncate(); MediaItemLiveStream::truncate(); MediaItemVideo::truncate(); Permission::truncate(); PermissionGroup::truncate(); QualityDefinition::truncate(); LiveStreamUri::truncate(); Playlist::truncate(); Show::truncate(); SiteUser::truncate(); User::truncate(); VideoFile::truncate(); DB::table("media_item_to_playlist")->truncate(); DB::table("permission_to_group")->truncate(); DB::table("user_to_group")->truncate(); DB::statement('SET FOREIGN_KEY_CHECKS=1;'); $this->command->info('Tables truncated!'); }
public function postDelete() { Auth::getUser()->hasPermissionOr401(Config::get("permissions.playlists"), 1); $resp = array("success" => false); if (FormHelpers::hasPost("id")) { $id = intval($_POST["id"], 10); DB::transaction(function () use(&$id, &$resp) { $playlist = Playlist::find($id); if (!is_null($playlist)) { // mark any related files as no longer in use (so they will be removed) Upload::delete(array($playlist->sideBannerFile, $playlist->sideBannerFillFile, $playlist->coverFile, $playlist->coverArtFile)); $customUriModel = $playlist->customUri; if (!is_null($customUriModel)) { $customUriModel->delete(); } if ($playlist->delete() === false) { throw new Exception("Error deleting Playlist."); } $resp['success'] = true; } }); } return Response::json($resp); }
private function updatePlaylistsIndex() { $entries = ["toAdd" => [], "toRemove" => []]; $changedPlaylists = DB::transaction(function () { return Playlist::with("show")->needsReindexing()->get(); }); foreach ($changedPlaylists as $playlist) { if ($playlist->getIsAccessibleToPublic()) { $entries["toAdd"][] = ["model" => $playlist, "data" => $this->getPlaylistData($playlist, $this->coverArtWidth, $this->coverArtHeight)]; } else { // this item is no longer accessible so remove it from the index $entries["toRemove"][] = ["model" => $playlist]; } } $this->syncIndexType("playlist", new Playlist(), $entries); }
protected function setContent($content, $navPage, $cssPageId, $openGraphProperties = array(), $title = NULL, $statusCode = 200, $twitterProperties = null, $sideBannersImageUrl = null, $sideBannersFillImageUrl = null) { $description = Config::get("custom.site_description"); $registerPushNotificationEndpointUrl = Config::get("pushNotifications.enabled") ? URL::route("ajax-registerPushNotificationEndpoint") : null; $view = View::make("layouts.home.master"); $view->version = !is_null(DebugHelpers::getVersion()) ? DebugHelpers::getVersion() : "[Unknown]"; $view->baseUrl = URL::to("/"); $view->currentNavPage = $navPage; $view->cssPageId = $cssPageId; $view->title = "LA1:TV"; if (!is_null($title)) { $view->title .= ": " . $title; } $view->description = $description; $view->content = $content; $view->allowRobots = true; $view->manifestUri = URL::route('manifest'); $view->cssBootstrap = asset("assets/css/bootstrap/home.css"); $view->requireJsBootstrap = asset("assets/scripts/bootstrap/home.js"); $view->loggedIn = Facebook::isLoggedIn(); $view->sideBannersImageUrl = $sideBannersImageUrl; $view->sideBannersFillImageUrl = $sideBannersFillImageUrl; $view->sideBannersOn = !is_null($sideBannersImageUrl) || !is_null($sideBannersFillImageUrl); $view->supportEmail = Config::get("contactEmails.development"); $view->pageData = array("baseUrl" => URL::to("/"), "cookieDomain" => Config::get("cookies.domain"), "cookieSecure" => Config::get("ssl.enabled"), "assetsBaseUrl" => asset(""), "serviceWorkerUrl" => URL::route("home-service-worker"), "logUri" => Config::get("custom.log_uri"), "debugId" => DebugHelpers::getDebugId(), "sessionId" => Session::getId(), "csrfToken" => Csrf::getToken(), "loggedIn" => Facebook::isLoggedIn(), "gaEnabled" => Config::get("googleAnalytics.enabled"), "notificationServiceUrl" => Config::get("notificationService.url"), "registerPushNotificationEndpointUrl" => $registerPushNotificationEndpointUrl, "promoAjaxUri" => Config::get("custom.live_shows_uri"), "env" => App::environment(), "version" => DebugHelpers::getVersion(), "degradedService" => Config::get("degradedService.enabled")); $facebookAppId = Config::get("facebook.appId"); $defaultOpenGraphProperties = array(); if (!is_null($facebookAppId)) { $defaultOpenGraphProperties[] = array("name" => "fb:app_id", "content" => $facebookAppId); } $defaultOpenGraphProperties[] = array("name" => "og:title", "content" => "LA1:TV"); $defaultOpenGraphProperties[] = array("name" => "og:url", "content" => Request::url()); $defaultOpenGraphProperties[] = array("name" => "og:locale", "content" => "en_GB"); $defaultOpenGraphProperties[] = array("name" => "og:site_name", "content" => "LA1:TV"); $defaultOpenGraphProperties[] = array("name" => "og:description", "content" => $description); $defaultOpenGraphProperties[] = array("name" => "og:image", "content" => Config::get("custom.open_graph_logo_uri")); $finalOpenGraphProperties = $this->mergeProperties($defaultOpenGraphProperties, $openGraphProperties); $finalTwitterProperties = array(); if (!is_null($twitterProperties)) { $defaultTwitterProperties = array(array("name" => "card", "content" => "summary"), array("name" => "site", "content" => "@LA1TV"), array("name" => "description", "content" => str_limit($description, 197, "...")), array("name" => "image", "content" => Config::get("custom.twitter_card_logo_uri"))); $finalTwitterProperties = $this->mergeProperties($defaultTwitterProperties, $twitterProperties); } $view->openGraphProperties = $finalOpenGraphProperties; $view->twitterProperties = $finalTwitterProperties; $view->searchEnabled = Config::get("search.enabled"); $view->searchQueryAjaxUri = Config::get("custom.search_query_uri"); $view->loginUri = URLHelpers::generateLoginUrl(); $view->homeUri = Config::get("custom.base_url"); $view->guideUri = Config::get("custom.base_url") . "/guide"; $view->blogUri = Config::get("custom.blog_url"); $view->contactUri = Config::get("custom.base_url") . "/contact"; $view->accountUri = Config::get("custom.base_url") . "/account"; $view->adminUri = Config::get("custom.base_url") . "/admin"; // recent shows in dropdown $shows = Show::getCachedActiveShows(); $view->showsDropdown = array(); foreach ($shows as $a) { $view->showsDropdown[] = array("uri" => Config::get("custom.base_url") . "/show/" . $a->id, "text" => $a->name); } $view->showsUri = Config::get("custom.base_url") . "/shows"; // recent playlists dropdown $playlists = Playlist::getCachedActivePlaylists(false); $view->playlistsDropdown = array(); foreach ($playlists as $a) { $view->playlistsDropdown[] = array("uri" => Config::get("custom.base_url") . "/playlist/" . $a->id, "text" => $a->name); } $view->playlistsUri = Config::get("custom.base_url") . "/playlists"; $liveStreams = LiveStream::getCachedSiteLiveStreams(); $view->liveStreamsDropdown = array(); foreach ($liveStreams as $a) { $view->liveStreamsDropdown[] = array("uri" => Config::get("custom.base_url") . "/livestream/" . $a->id, "text" => $a->name); } $contentSecurityPolicyDomains = MediaItemLiveStream::getCachedLiveStreamDomains(); $response = new MyResponse($view, $statusCode); // disable csp for main site because causing too many issues with live streams (and clappr uses unsafe evals etc) $response->enableContentSecurityPolicy(false); //$response->setContentSecurityPolicyDomains($contentSecurityPolicyDomains); $this->layout = $response; }
public function postPlaylistInfo($id) { $playlist = Playlist::accessibleToPublic()->find(intval($id)); if (is_null($playlist)) { App::abort(404); } $data = array(); $mediaItems = $playlist->mediaItems()->accessible()->orderBy("media_item_to_playlist.position")->get(); $mediaItems->load("videoItem", "liveStreamItem", "liveStreamItem.stateDefinition"); foreach ($mediaItems as $a) { $vod = null; $stream = null; if (!is_null($a->videoItem)) { $available = false; if (!Config::get("degradedService.enabled")) { $available = $a->videoItem->getIsLive(); } $vod = array("available" => $available); } if (!is_null($a->liveStreamItem)) { $stream = array("state" => intval($a->liveStreamItem->getResolvedStateDefinition()->id)); } $data[] = array("id" => intval($a->id), "vod" => $vod, "stream" => $stream, "url" => $playlist->getMediaItemUri($a)); } return Response::json($data); }
public function generatePlaylistMediaItemResponseData($playlistId, $mediaItemId, $showStreamUris, $showVodUris) { $playlist = Playlist::accessible()->find(intval($playlistId)); if (is_null($playlist)) { return $this->generateNotFound(); } $mediaItem = $playlist->mediaItems()->accessible()->find(intval($mediaItemId)); if (is_null($mediaItem)) { return $this->generateNotFound(); } $mediaItem->load("liveStreamItem", "liveStreamItem.stateDefinition", "liveStreamItem.liveStream", "videoItem", "videoItem.sourceFile.vodData"); $data = $this->mediaItemTransformer->transform([$playlist, $mediaItem], $this->getMediaItemTransformerOptions($showStreamUris, $showVodUris)); return new ApiResponseData($data); }
public function postRegisterLike($playlistId, $mediaItemId) { $playlist = Playlist::accessibleToPublic()->find($playlistId); if (is_null($playlist)) { App::abort(404); } $mediaItem = $playlist->mediaItems()->accessible()->find($mediaItemId); if (is_null($mediaItem)) { App::abort(404); } $success = false; if (isset($_POST['type'])) { $type = $_POST['type']; if ($type === "like" || $type === "dislike" || $type === "reset") { // an item can only be liked when it has an accessible video, or live stream which is enabled and not in the 'not live' state $mediaItemVideo = $mediaItem->videoItem; $mediaItemLiveStream = $mediaItem->liveStreamItem; $mediaItemVideoAccessible = false; if (!Config::get("degradedService.enabled")) { $mediaItemVideoAccessible = !is_null($mediaItemVideo) && $mediaItemVideo->getIsLive(); } $mediaItemLiveStreamValidState = !is_null($mediaItemLiveStream) && $mediaItemLiveStream->getIsAccessible() && intval($mediaItemLiveStream->getResolvedStateDefinition()->id) !== 1; if ($mediaItemVideoAccessible || $mediaItemLiveStreamValidState) { $user = Facebook::getUser(); if (!is_null($user)) { if ($type === "like") { $mediaItem->registerLike($user); } else { if ($type === "dislike") { $mediaItem->registerDislike($user); } else { if ($type === "reset") { $mediaItem->removeLike($user); } } } $success = true; } } } } return Response::json(array("success" => $success)); }