Begin splitting the installer script into install_radio.sh and install_app.sh, and remove unused files.

This commit is contained in:
Buster Silver 2016-05-02 00:24:44 -05:00
parent 890e0fe0b9
commit 61e0811b3d
18 changed files with 199 additions and 1455 deletions

3
.gitignore vendored
View File

@ -3,6 +3,7 @@
#################
# Environment-specific files.
/tmp/
pvl.key.txt
app/config/db.conf.php
app/config/apis.conf.php
@ -268,4 +269,4 @@ pip-log.txt
web/test.php
app/modules/default/controllers/UtilController.php
node_modules/
.sass-cache/
.sass-cache/

View File

@ -6,6 +6,7 @@ return array(
'default_action' => 'index',
'custom_routes' => array(
// Homepage.
'/' => array(
'module' => 'frontend',
@ -14,62 +15,6 @@ return array(
'name' => 'home',
),
// Info pages.
'/about' => array(
'module' => 'frontend',
'controller' => 'index',
'action' => 'about',
),
'/apps' => array(
'module' => 'frontend',
'controller' => 'index',
'action' => 'app',
),
'/donate' => array(
'module' => 'frontend',
'controller' => 'index',
'action' => 'donate',
),
'/mobile' => array(
'module' => 'frontend',
'controller' => 'index',
'action' => 'mobile',
),
'/conventions' => array(
'module' => 'frontend',
'controller' => 'convention',
'action' => 'index',
),
'/contact' => array(
'module' => 'frontend',
'controller' => 'index',
'action' => 'contact',
),
// Podcasts
'/shows' => array(
'module' => 'frontend',
'controller' => 'show',
'action' => 'index',
'name' => 'show-listing',
),
// Old URLs.
'/stations/submit' => array(
'module' => 'frontend',
'controller' => 'submit',
'action' => 'station',
),
'/events' => array(
'module' => 'frontend',
'controller' => 'convention',
'action' => 'index',
),
'/events/schedule' => array(
'module' => 'frontend',
'controller' => 'schedule',
'action' => 'index',
),
),
);

View File

@ -1,67 +0,0 @@
<?php
namespace Modules\Admin\Controllers;
use \Entity\Affiliate;
use \Entity\Affiliate as Record;
class AffiliatesController extends BaseController
{
public function permissions()
{
return $this->acl->isAllowed('administer affiliates');
}
public function indexAction()
{
$records = $this->em->createQuery('SELECT r FROM Entity\Affiliate r ORDER BY r.id ASC')
->getArrayResult();
$this->view->records = $records;
}
public function editAction()
{
$form = new \App\Form($this->current_module_config->forms->affiliate);
if ($this->hasParam('id'))
{
$id = (int)$this->getParam('id');
$record = Record::find($id);
$form->setDefaults($record->toArray(FALSE, TRUE));
}
if($_POST && $form->isValid($_POST) )
{
$data = $form->getValues();
if (!($record instanceof Record))
$record = new Record;
$files = $form->processFiles('affiliates');
foreach($files as $file_field => $file_paths)
{
if (!empty($file_paths))
$data[$file_field] = $file_paths[1];
}
$record->fromArray($data);
$record->save();
$this->alert('Changes saved.', 'green');
return $this->redirectFromHere(array('action' => 'index', 'id' => NULL));
}
$this->renderForm($form, 'edit', 'Edit Record');
}
public function deleteAction()
{
$record = Record::find($this->getParam('id'));
if ($record)
$record->delete();
$this->alert('Record deleted.', 'green');
$this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL));
}
}

View File

@ -1,274 +0,0 @@
<?php
namespace Modules\Admin\Controllers;
use \Entity\Convention as Record;
use \Entity\Convention;
use \Entity\ConventionSignup;
use \Entity\ConventionArchive;
class ConventionsController extends BaseController
{
public function permissions()
{
return $this->acl->isAllowed('administer conventions');
}
protected function _getConvention()
{
if (!$this->hasParam('convention'))
throw new \App\Exception\DisplayOnly('No convention specified!');
$con_id = (int)$this->getParam('convention');
$con = Convention::find($con_id);
if ($con instanceof Convention)
{
$this->view->convention = $con;
return $con;
}
else
{
throw new \App\Exception\DisplayOnly('Convention ID not found!');
}
}
protected function _flushConventionCache()
{
\App\Cache::remove('homepage_conventions');
}
public function indexAction()
{
$this->view->coverage = Convention::getCoverageLevels();
$query = $this->em->createQuery('SELECT c FROM Entity\Convention c LEFT JOIN c.signups cs LEFT JOIN c.archives ca ORDER BY c.start_date DESC');
$this->view->pager = new \App\Paginator\Doctrine($query, $this->getParam('page', 1), 15);
}
public function editAction()
{
$form = new \App\Form($this->current_module_config->forms->convention);
if ($this->hasParam('id'))
{
$id = (int)$this->getParam('id');
$record = Record::find($id);
$form->setDefaults($record->toArray(TRUE, TRUE));
}
if($_POST && $form->isValid($_POST) )
{
$data = $form->getValues();
if (!($record instanceof Record))
$record = new Record;
$files = $form->processFiles('conventions');
foreach($files as $file_field => $file_paths)
$data[$file_field] = $file_paths[1];
$record->fromArray($data);
$record->save();
$this->_flushConventionCache();
$this->alert('Changes saved.', 'green');
return $this->redirectFromHere(array('action' => 'index', 'id' => NULL));
}
$this->renderForm($form, 'edit', 'Edit Record');
}
public function deleteAction()
{
$record = Record::find($this->getParam('id'));
if ($record)
$record->delete();
$this->_flushConventionCache();
$this->alert('Record deleted.', 'green');
$this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL));
}
/**
* Signup Management
*/
public function signupsAction()
{
$con = $this->_getConvention();
switch($this->getParam('format'))
{
case "csv":
$export_data = array();
$export_data[] = array(
'Pony/Badge Name',
'Legal Name',
'Phone Number',
'E-mail Address',
'PVL Affiliation',
'Travel Notes',
'Accommodation Notes',
);
foreach($con->signups as $row)
{
$export_data[] = array(
$row->pony_name,
$row->legal_name,
$row->phone,
$row->email,
$row->pvl_affiliation,
$row->travel_notes,
$row->accommodation_notes,
);
}
\App\Export::csv($export_data, TRUE, 'Signups - '.$con->name);
break;
case "html":
default:
$this->view->signups = $con->signups;
$this->render();
break;
}
}
public function editsignupAction()
{
$con = $this->_getConvention();
$form = ConventionSignup::getForm($con);
$id = (int)$this->getParam('id');
$record = ConventionSignup::find($id);
if ($record instanceof ConventionSignup)
$form->setDefaults($record->toArray(TRUE, TRUE));
else
throw new \App\Exception\DisplayOnly('Cannot create new signup records from this page.');
if($_POST && $form->isValid($_POST) )
{
$data = $form->getValues();
$record->fromArray($data);
$record->save();
$this->alert('Changes saved.', 'green');
$this->redirectFromHere(array('action' => 'signups', 'convention' => $con->id, 'id' => NULL));
return;
}
$this->renderForm($form, 'edit', 'Edit Signup Record');
}
public function deletesignupAction()
{
$con = $this->_getConvention();
$record = ConventionSignup::find($this->getParam('id'));
if ($record instanceof ConventionSignup)
$record->delete();
$this->alert('Record deleted.', 'green');
$this->redirectFromHere(array('action' => 'signups', 'convention' => $con->id, 'id' => NULL, 'csrf' => NULL));
}
/**
* Convention Archive Management
*/
public function archivesAction()
{
$con = $this->_getConvention();
$folders = ConventionArchive::getFolders();
$this->view->folders = $folders;
$types = ConventionArchive::getTypes();
$archives_raw = $con->archives;
$archives = array();
if (count($archives_raw) > 0)
{
foreach($archives_raw as $row)
{
$row_arr = $row->toArray();
$row_arr['type_text'] = $types[$row_arr['type']];
if ($row->playlist_id)
{
$archives[$row->playlist_id]['videos'][] = $row_arr;
}
else
{
$row_arr['videos'] = array();
$archives[$row->id] = $row_arr;
}
}
}
$archives_by_folder = array();
foreach($archives as $id => $row)
{
$archives_by_folder[$row['folder']][$id] = $row;
}
$this->view->archives = $archives_by_folder;
}
public function editarchiveAction()
{
$con = $this->_getConvention();
$form = new \App\Form($this->current_module_config->forms->conventionarchive);
if ($this->hasParam('id'))
{
$id = (int)$this->getParam('id');
$record = ConventionArchive::find($id);
$form->setDefaults($record->toArray(TRUE, TRUE));
}
if($_POST && $form->isValid($_POST) )
{
$data = $form->getValues();
if (!($record instanceof ConventionArchive))
{
$record = new ConventionArchive;
$record->convention = $con;
}
$record->fromArray($data);
$record->save();
$record->process();
$this->alert('Changes saved.', 'green');
$this->redirectFromHere(array('action' => 'archives', 'convention' => $con->id, 'id' => NULL));
return;
}
$this->view->setVar('title', 'Edit Convention Archive Item');
$this->renderForm($form);
}
public function deletearchiveAction()
{
$con = $this->_getConvention();
$record = ConventionArchive::find($this->getParam('id'));
if ($record instanceof ConventionArchive)
$record->delete();
$this->alert('Record deleted.', 'green');
$this->redirectFromHere(array('action' => 'archives', 'convention' => $con->id, 'id' => NULL, 'csrf' => NULL));
}
}

View File

@ -1,62 +0,0 @@
<?php
namespace Modules\Admin\Controllers;
use \Entity\Podcast;
use \Entity\Podcast as Record;
class PodcastsController extends BaseController
{
public function permissions()
{
return $this->acl->isAllowed('administer podcasts');
}
public function indexAction()
{
$query = $this->em->createQuery('SELECT p FROM Entity\Podcast p ORDER BY p.is_approved DESC, p.name ASC');
$this->view->pager = new \App\Paginator\Doctrine($query, $this->getParam('page', 1), 50);
}
public function editAction()
{
$form = new \App\Form($this->current_module_config->forms->podcast);
if ($this->hasParam('id'))
{
$id = (int)$this->getParam('id');
$record = Record::find($id);
$form->setDefaults($record->toArray(TRUE, TRUE));
}
if($_POST && $form->isValid($_POST) )
{
$data = $form->getValues();
if (!($record instanceof Record))
$record = new Record;
$files = $form->processFiles('podcasts');
foreach($files as $file_field => $file_paths)
$data[$file_field] = $file_paths[1];
$record->fromArray($data);
$record->save();
$this->alert('Changes saved.', 'green');
return $this->redirectFromHere(array('action' => 'index', 'id' => NULL));
}
$this->renderForm($form, 'edit', 'Edit Record');
}
public function deleteAction()
{
$record = Record::find($this->getParam('id'));
if ($record)
$record->delete();
$this->alert('Record deleted.', 'green');
$this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL));
}
}

View File

@ -1,70 +0,0 @@
<?php
namespace Modules\Admin\Controllers;
use \Entity\Rotator;
use \Entity\Rotator as Record;
class RotatorsController extends BaseController
{
public function permissions()
{
return $this->acl->isAllowed('administer rotators');
}
public function indexAction()
{
$records = $this->em->createQuery('SELECT r FROM Entity\Rotator r ORDER BY r.id ASC')
->getArrayResult();
$this->view->records = $records;
}
public function editAction()
{
$form = new \App\Form($this->current_module_config->forms->rotator);
if ($this->hasParam('id'))
{
$id = (int)$this->getParam('id');
$record = Record::find($id);
$form->setDefaults($record->toArray(FALSE, TRUE));
}
if($_POST && $form->isValid($_POST) )
{
$data = $form->getValues();
if (!($record instanceof Record))
$record = new Record;
$files = $form->processFiles('rotators');
foreach($files as $file_field => $file_paths)
{
if (!empty($file_paths))
$data[$file_field] = $file_paths[1];
}
if ($data['image_url'])
\App\Image::resizeImage($data['image_url'], $data['image_url'], 336, 280);
$record->fromArray($data);
$record->save();
$this->alert('Changes saved.', 'green');
return $this->redirectFromHere(array('action' => 'index', 'id' => NULL));
}
$this->renderForm($form, 'edit', 'Edit Record');
}
public function deleteAction()
{
$record = Record::find($this->getParam('id'));
if ($record)
$record->delete();
$this->alert('Record deleted.', 'green');
$this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL));
}
}

View File

@ -1,100 +0,0 @@
<?php
namespace Modules\Admin\Controllers;
use \Entity\Station;
use \Entity\Convention;
use \Entity\ShortUrl;
class UrlsController extends BaseController
{
public function indexAction()
{
$urls = $this->em->createQuery('SELECT su, s FROM Entity\ShortUrl su LEFT JOIN su.station s ORDER BY su.station_id, su.short_url ASC')
->getArrayResult();
$global_custom_urls = array();
$station_custom_urls = array();
foreach($urls as $url)
{
if ($url['station'])
$station_custom_urls[] = $url;
else
$global_custom_urls[] = $url;
}
$this->view->station_custom_urls = $station_custom_urls;
$this->view->global_custom_urls = $global_custom_urls;
// Auto-Generated Station URLs.
$station_details = Station::getShortNameLookup();
$station_categories = Station::getCategories();
$station_urls = array();
foreach($station_details as $short_name => $station)
{
$station['url'] = ShortUrl::getFullUrl($short_name);
$station['icon'] = $station_categories[$station['category']]['icon'];
$station_urls[$short_name] = $station;
}
$this->view->station_urls = $station_urls;
// Auto-Generated Convention Archive URLs
$convention_details = Convention::getShortNameLookup();
$convention_urls = array();
foreach($convention_details as $short_name => $convention)
{
$convention['url'] = ShortUrl::getFullUrl($short_name);
$convention_urls[$short_name] = $convention;
}
$this->view->convention_urls = $convention_urls;
}
public function editAction()
{
$form = new \App\Form($this->current_module_config->forms->url);
if ($this->hasParam('id'))
{
$record = ShortUrl::getRepository()->find($this->getParam('id'));
$form->setDefaults($record->toArray());
}
if(!empty($_POST) && $form->isValid($_POST))
{
$data = $form->getValues();
if (!($record instanceof ShortUrl))
$record = new ShortUrl;
$record->fromArray($data);
if (!$record->checkUrl())
throw new \App\Exception\DisplayOnly('This URL is already taken! Please go back and try another.');
$record->save();
$this->alert('Record updated.', 'green');
$this->redirectFromHere(array('action' => 'index', 'id' => NULL));
return;
}
$this->renderForm($form, 'edit', ($this->hasParam('id')) ? 'Edit Short URL' : 'Add Short URL');
}
public function deleteAction()
{
$id = (int)$this->getParam('id');
$record = ShortUrl::getRepository()->find($id);
if ($record instanceof ShortUrl)
$record->delete();
$this->alert('<b>Record deleted.</b>', 'green');
$this->redirectFromHere(array('action' => 'index', 'id' => NULL));
}
}

View File

@ -1,57 +0,0 @@
<?
$title = 'Manage Affiliates';
?>
<div class="buttons">
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'large success',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit')),
'icon' => 'icon-plus-sign',
'text' => 'Add New Affiliate',
)) ?>
</div>
<table class="table table-striped table-bordered table-condensed">
<colgroup>
<col width="25%" />
<col width="10%" />
<col width="65%" />
</colgroup>
<thead>
<tr>
<th>Actions</th>
<th>Image</th>
<th>Link/Description</th>
</tr>
</thead>
<tbody>
<? foreach($records as $record): ?>
<tr class="input">
<td class="center">
<div class="btn-group">
<?=$this->viewHelper->button(array(
'type' => 'small',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit', 'id' => $record['id'])),
'text' => 'Edit',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'class' => 'danger confirm-delete',
'href' => $this->viewHelper->routeFromHere(array('action' => 'delete', 'id' => $record['id'])),
'text' => 'Delete',
)) ?>
</div>
</td>
<td class="center" <? if (!$record['is_approved']): ?>style="opacity: 0.2;"<? endif; ?>><img src="<?=\App\Url::upload($record['image_url']) ?>"></td>
<td>
<div><big><?=$record['name'] ?></big></div>
<div><?=$this->viewHelper->link($record['web_url']) ?></div>
<? if ($record['description']): ?>
<div><?=$record['description'] ?></div>
<? endif; ?>
</td>
</tr>
<? endforeach; ?>
</tbody>
</table>

View File

@ -1,94 +0,0 @@
<?
$title = 'Manage Conventions';
?>
<h2><?=$convention->name ?></h2>
<h3>Manage Convention Video Archives</h3>
<div class="buttons btn-group">
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'large',
'href' => $this->viewHelper->routeFromHere(array('action' => 'index', 'convention' => NULL)),
'icon' => 'icon-arrow-left',
'text' => 'Back to Main',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'large success fancybox fancybox.ajax',
'href' => $this->viewHelper->routeFromHere(array('action' => 'editarchive')),
'icon' => 'icon-plus-sign',
'text' => 'Add New Archive',
)) ?>
</div>
<? foreach($folders as $folder_id => $folder_name): ?>
<table class="table table-striped datatable">
<colgroup>
<col width="15%" />
<col width="10%" />
<col width="75%" />
</colgroup>
<thead>
<tr>
<th colspan="3"><?=$folder_name ?></th>
</tr>
</thead>
<tbody>
<? foreach((array)$archives[$folder_id] as $id => $record): ?>
<tr class="input">
<td class="center">
<div class="btn-group">
<?=$this->viewHelper->button(array(
'type' => 'small',
'icon' => 'icon-pencil',
'class' => 'fancybox fancybox.ajax',
'href' => $this->viewHelper->routeFromHere(array('action' => 'editarchive', 'id' => $record['id'])),
'text' => 'Edit',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'icon' => 'icon-trash',
'class' => 'danger confirm-delete',
'href' => $this->viewHelper->routeFromHere(array('action' => 'deletearchive', 'id' => $record['id'])),
'text' => 'Delete',
)) ?>
</div>
</td>
<td class="center">
<img src="<?=$record['thumbnail_url'] ?>" alt="Thumbnail" style="max-width: 100%;">
</td>
<td>
<?=$record['type_text'] ?>:<br>
<big><?=$record['name'] ?></big><br>
<small><a href="<?=$record['web_url'] ?>" target="_blank"><?=$record['web_url'] ?></a></small>
</td>
</tr>
<? if ($record['videos']): ?>
<tr>
<td>&nbsp;</td>
<td colspan="2">
<table class="table datatable table-nopadding">
<colgroup>
<col width="10%">
<col width="90%">
</colgroup>
<tbody>
<? foreach($record['videos'] as $video): ?>
<tr>
<td><img src="<?=$video['thumbnail_url'] ?>" style="width: 100%;" alt="Thumbnail"></td>
<td>
<b><?=$video['name'] ?></b><br>
<small><a href="<?=$video['web_url'] ?>" target="_blank"><?=$video['web_url'] ?></a></small>
</td>
</tr>
<? endforeach; ?>
</tbody>
</table>
</td>
</tr>
<? endif; ?>
<? endforeach; ?>
</tbody>
</table>
<? endforeach; ?>

View File

@ -1,97 +0,0 @@
<?
$title = 'Manage Conventions';
?>
<div class="buttons">
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'large success',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit')),
'icon' => 'icon-plus-sign',
'text' => 'Add New Convention',
)) ?>
</div>
<?=$this->viewHelper->paginate($pager) ?>
<table class="table table-bordered table-striped table-nopadding">
<colgroup>
<col width="20%" />
<col width="3%" />
<col width="27%" />
<col width="25%" />
<col width="25%" />
</colgroup>
<thead>
<tr>
<th>Actions</th>
<th>&nbsp;</th>
<th>Name</th>
<th>Image</th>
<th>URLs</th>
</tr>
</thead>
<tbody>
<? foreach($pager as $record): ?>
<tr class="input <? if ($record['signup_enabled'] == 1): ?>text-success<? endif; ?>">
<td class="center">
<div class="btn-group">
<?=$this->viewHelper->button(array(
'type' => 'small',
'class' => ((count($record->signups) > 0) ? 'btn-primary' : '').' btn-icon-only',
'icon' => 'icon-user',
'title' => 'Signups ('.count($record->signups).')',
'href' => $this->viewHelper->routeFromHere(array('action' => 'signups', 'convention' => $record['id'])),
'text' => '',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'class' => ((count($record->archives) > 0) ? 'btn-primary' : '').' btn-icon-only',
'icon' => 'icon-facetime-video',
'title' => 'Video Archives ('.count($record->archives).')',
'href' => $this->viewHelper->routeFromHere(array('action' => 'archives', 'convention' => $record['id'])),
'text' => '',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'icon' => 'icon-pencil',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit', 'id' => $record['id'])),
'text' => 'Edit',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'icon' => 'icon-trash',
'class' => 'danger confirm-delete',
'href' => $this->viewHelper->routeFromHere(array('action' => 'delete', 'id' => $record['id'])),
'text' => 'Delete',
)) ?>
</div>
</td>
<td class="center">
<?
$level = $coverage[$record['coverage_level']];
?>
<div title="<?=$level['text'] ?>"><i class="large-icon <?=$level['icon'] ?>"></i></div>
</td>
<td>
<big><?=$record['name'] ?></big><br>
<?=$record['location'] ?><br>
<?=$record['range'] ?>
</td>
<td class="center">
<? if ($record['image_url']): ?>
<img src="<?=\App\Url::upload($record['image_url']) ?>" style="width: 100%;">
<? endif; ?>
</td>
<td>
<div>Web: <a href="<?=$record['web_url'] ?>" target="_blank"><?=$record['web_url'] ?></a></div>
<? if ($record['discount_code']): ?>
<div>Discount Code: <b><?=$record['discount_code'] ?></b></div>
<? endif; ?>
</td>
</tr>
<? endforeach; ?>
</tbody>
</table>
<?=$this->viewHelper->paginate($pager) ?>

View File

@ -1,89 +0,0 @@
<?
$title = 'Manage Conventions';
?>
<h2><?=$convention->name ?></h2>
<h3>Manage Convention Press Signups</h3>
<div class="buttons btn-group">
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'large',
'href' => $this->viewHelper->routeFromHere(array('action' => 'index', 'convention' => NULL)),
'icon' => 'icon-arrow-left',
'text' => 'Back to Main',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'large',
'href' => $this->viewHelper->routeFromHere(array('format' => 'csv')),
'icon' => 'icon-download',
'text' => 'Download Excel CSV',
)) ?>
</div>
<table class="table table-striped datatable">
<colgroup>
<col width="15%">
<col width="5%">
<col width="20%">
<col width="15%">
<col width="15%">
<col width="30%">
</colgroup>
<thead>
<tr>
<th>&nbsp;</th>
<th>&nbsp;</th>
<th>Legal / Pony Name</th>
<th>E-mail</th>
<th>Phone</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<? foreach($signups as $record): ?>
<tr class="input">
<td class="center">
<div class="btn-group">
<?=$this->viewHelper->button(array(
'type' => 'small',
'icon' => 'icon-pencil',
'class' => 'fancybox fancybox.ajax',
'href' => $this->viewHelper->routeFromHere(array('action' => 'editsignup', 'id' => $record['id'])),
'text' => 'Edit',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'icon' => 'icon-trash',
'class' => 'danger confirm-delete',
'href' => $this->viewHelper->routeFromHere(array('action' => 'deletesignup', 'id' => $record['id'])),
'text' => 'Delete',
)) ?>
</div>
</td>
<td class="center">
<img src="<?=$record->user->getAvatar() ?>" alt="Avatar">
</td>
<td>
<big><?=$record->pony_name ?></big><br>
<?=$record->legal_name ?>
</td>
<td>
<?=$this->viewHelper->mailto($record->email) ?>
</td>
<td>
<?=$record->phone ?>
</td>
<td>
<? if ($record->travel_notes): ?>
<div><b>Travel:</b> <?=nl2br($record->travel_notes) ?></div>
<? endif; ?>
<? if ($record->accommodation_notes): ?>
<div><b>Accommodations:</b> <?=nl2br($record->accommodation_notes) ?></div>
<? endif; ?>
</td>
</tr>
<? endforeach; ?>
</tbody>
</table>

View File

@ -1,97 +0,0 @@
<?
$title = 'Manage Podcasts';
?>
<div class="buttons">
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'large success',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit')),
'icon' => 'icon-plus-sign',
'text' => 'Add New Podcast',
)) ?>
</div>
<?=$this->viewHelper->paginate($pager) ?>
<table class="table datatable table-striped table-nopadding">
<colgroup>
<col width="20%" />
<col width="6%" />
<col width="7%" />
<col width="7%" />
<col width="30%" />
<col width="30%" />
</colgroup>
<thead>
<tr>
<th>Actions</th>
<th>Avatar</th>
<th>Episodes</th>
<th>PVL Traffic</th>
<th>Podcast Name</th>
<th>Latest Episode</th>
</tr>
</thead>
<tbody>
<? foreach($pager as $record): ?>
<tr class="input <? if (!$record->is_approved): ?>disabled<? endif; ?>">
<td class="center">
<div class="btn-group">
<?=$this->viewHelper->button(array(
'type' => 'small',
'class' => 'btn-primary',
'target' => '_blank',
'href' => $this->viewHelper->route(array('module' => 'podcasts', 'podcast' => $record['id'])),
'text' => 'Manage',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'icon' => 'icon-pencil',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit', 'id' => $record['id'])),
'text' => 'Edit',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'icon' => 'icon-trash',
'class' => 'danger confirm-delete',
'href' => $this->viewHelper->routeFromHere(array('action' => 'delete', 'id' => $record['id'])),
'text' => 'Delete',
)) ?>
</div>
</td>
<td class="center"><img src="<?=\App\Url::upload($record['image_url']) ?>" style="width: 64px;"></td>
<td class="center">
<big><?=number_format($record->getEpisodeCount(), 0) ?></big>
</td>
<td class="center">
<big><?=number_format($record->getEpisodePlays(), 0) ?></big>
</td>
<td>
<big><a href="<?=$this->viewHelper->route(array('controller' => 'show', 'action' => 'view', 'id' => $record['id'])) ?>" target="_blank"><?=$record['name'] ?></a></big><br>
<a href="<?=$record['web_url'] ?>" target="_blank"><?=$record['web_url'] ?></a><br>
<?=$record['description'] ?>
</td>
<td>
<?
$ep = $record->getLatestEpisode();
if ($ep): ?>
<div class="podcast-episode">
<?
$time_diff = \App\Utilities::timeDifferenceText(time(), $ep['timestamp'], 0);
?>
<small><span title="<?=date('l, F j, Y g:ia', $ep['timestamp']) ?>"><?=$time_diff ?> ago</span>:</small><br>
<a href="<?=$ep['web_url'] ?>" target="_blank"><b><?=$ep['title'] ?></b></a>
</div>
<? else: ?>
<div>
No Latest Episode
</div>
<? endif; ?>
</td>
</tr>
<? endforeach; ?>
</tbody>
</table>
<?=$this->viewHelper->paginate($pager) ?>

View File

@ -1,56 +0,0 @@
<?
$title = 'Manage Rotator Banners';
?>
<div class="buttons">
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'large success',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit')),
'icon' => 'icon-plus-sign',
'text' => 'Add New Rotator',
)) ?>
</div>
<table class="table table-striped table-bordered table-condensed">
<colgroup>
<col width="25%" />
<col width="25%" />
<col width="50%" />
</colgroup>
<thead>
<tr>
<th>Actions</th>
<th>Image</th>
<th>Link/Description</th>
</tr>
</thead>
<tbody>
<? foreach($records as $record): ?>
<tr class="input">
<td class="center">
<div class="btn-group">
<?=$this->viewHelper->button(array(
'type' => 'small',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit', 'id' => $record['id'])),
'text' => 'Edit',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'small',
'class' => 'danger confirm-delete',
'href' => $this->viewHelper->routeFromHere(array('action' => 'delete', 'id' => $record['id'])),
'text' => 'Delete',
)) ?>
</div>
</td>
<td class="center" <? if (!$record['is_approved']): ?>style="opacity: 0.2;"<? endif; ?>><img src="<?=\App\Url::upload($record['image_url']) ?>"></td>
<td>
<div><big><?=$this->viewHelper->link($record['web_url']) ?></big></div>
<? if ($record['description']): ?>
<div><?=$record['description'] ?></div>
<? endif; ?>
</td>
</tr>
<? endforeach; ?>
</tbody>
</table>

View File

@ -1,153 +0,0 @@
<?php
$title = 'URL Shortener Management';
?>
<h2>Global Custom URLs</h2>
<div class="buttons">
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'btn-large success',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit')),
'icon' => 'icon-plus-sign',
'text' => 'Add New URL',
)) ?>
</div>
<table class="table table-striped table-bordered table-condensed">
<colgroup>
<col width="20%" />
<col width="40%" />
<col width="40%" />
</colgroup>
<thead>
<tr>
<th>Actions</th>
<th>Short URL</th>
<th>Long URL</th>
</tr>
</thead>
<tbody>
<? foreach($global_custom_urls as $record): ?>
<tr class="input">
<td class="center">
<div class="btn-group">
<?=$this->viewHelper->button(array(
'type' => 'link',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit', 'id' => $record['id'])),
'icon' => 'icon-pencil',
'text' => 'Edit',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'btn-danger confirm-action',
'href' => $this->viewHelper->routeFromHere(array('action' => 'delete', 'id' => $record['id'])),
'icon' => 'icon-trash',
'text' => 'Delete',
)) ?>
</div>
</td>
<td><a href="<?=\Entity\ShortUrl::getFullUrl($record['short_url']) ?>" target="_blank"><?=\Entity\ShortUrl::getFullUrl($record['short_url']) ?></a></td>
<td><a href="<?=$record['long_url'] ?>" target="_blank"><?=$record['long_url'] ?></a></td>
</tr>
<? endforeach; ?>
</tbody>
</table>
<h2>Station Custom URLs</h2>
<table class="table table-striped table-bordered table-condensed">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="30%" />
<col width="30%" />
</colgroup>
<thead>
<tr>
<th>Actions</th>
<th>Station</th>
<th>Short URL</th>
<th>Long URL</th>
</tr>
</thead>
<tbody>
<? foreach($station_custom_urls as $record): ?>
<tr class="input">
<td class="center">
<div class="btn-group">
<?=$this->viewHelper->button(array(
'type' => 'link',
'href' => $this->viewHelper->routeFromHere(array('action' => 'edit', 'id' => $record['id'])),
'icon' => 'icon-pencil',
'text' => 'Edit',
)) ?>
<?=$this->viewHelper->button(array(
'type' => 'link',
'class' => 'btn-danger confirm-action',
'href' => $this->viewHelper->routeFromHere(array('action' => 'delete', 'id' => $record['id'])),
'icon' => 'icon-trash',
'text' => 'Delete',
)) ?>
</div>
</td>
<td><?=$record['station']['name'] ?></td>
<td><a href="<?=\Entity\ShortUrl::getFullUrl($record['short_url']) ?>" target="_blank"><?=\Entity\ShortUrl::getFullUrl($record['short_url']) ?></a></td>
<td><a href="<?=$record['long_url'] ?>" target="_blank"><?=$record['long_url'] ?></a></td>
</tr>
<? endforeach; ?>
</tbody>
</table>
<div class="row-fluid">
<div class="span6">
<h2>Stations</h2>
<p>These URLs link to the Ponyville Live! homepage and auto-play the specified station.</p>
<table class="table table-striped table-bordered table-condensed">
<colgroup>
<col width="40%" />
<col width="60%" />
</colgroup>
<thead>
<tr>
<th>Station Name</th>
<th>Station URL</th>
</tr>
</thead>
<tbody>
<? foreach($station_urls as $record): ?>
<tr class="input">
<td><i class="<?=$record['icon'] ?>"></i> <?=$record['name'] ?></td>
<td><a href="<?=$record['url'] ?>" target="_blank"><?=$record['url'] ?></a></td>
</tr>
<? endforeach; ?>
</tbody>
</table>
</div>
<div class="span6">
<h2>Convention Archives</h2>
<p>These URLs lead to the auto-generated convention archive pages for the specified convention.</p>
<table class="table table-striped table-bordered table-condensed">
<colgroup>
<col width="40%" />
<col width="60%" />
</colgroup>
<thead>
<tr>
<th>Convention Name</th>
<th>Convention URL</th>
</tr>
</thead>
<tbody>
<? foreach($convention_urls as $record): ?>
<tr class="input">
<td><?=$record['name'] ?></td>
<td><a href="<?=$record['url'] ?>" target="_blank"><?=$record['url'] ?></a></td>
</tr>
<? endforeach; ?>
</tbody>
</table>
</div>
</div>

19
install.sh Normal file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
export app_base = "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
export util_base = $app_base/util
export www_base = $app_base
export tmp_base= $app_base/tmp
cd $util_base
chmod a+x ./install_app.sh
chmod a+x ./install_radio.sh
./install_app.sh
./install_radio.sh
export external_ip = `dig +short myip.opendns.com @resolver1.opendns.com`
echo "Base installation complete!"
echo "Continue setup at http://$external_ip:8080"

122
util/install_app.sh Normal file
View File

@ -0,0 +1,122 @@
#!/usr/bin/env bash
# Add Phalcon PPA
apt-add-repository ppa:phalcon/stable
# Add MariaDB repo
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
add-apt-repository 'deb http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.0/ubuntu trusty main'
apt-get update
# Install app dependencies
apt-get -q -y install php5-fpm php5-cli php5-gd php5-mysqlnd php5-curl php5-phalcon
apt-get -q -y install nodejs npm
# Set up InfluxDB early (to allow time to initialize before setting up DBs.)
cd ~
wget http://influxdb.s3.amazonaws.com/influxdb_0.8.8_amd64.deb
dpkg -i influxdb_0.8.8_amd64.deb
service influxdb start
# Set Node.js bin alias
ln -s /usr/bin/nodejs /usr/bin/node
# Set MySQL root password
mysqladmin -u root password password
# Set up environment.
echo 'development' > $app_base/app/.env
echo "Creating temporary folders..."
mkdir -p $tmp_base
mkdir -p $tmp_base/cache
mkdir -p $tmp_base/sessions
mkdir -p $tmp_base/proxies
# Create log files.
chown -R www-data:www-data $app_base/
chmod -R 777 $tmp_base
# Nginx setup.
echo "Customizing nginx..."
service nginx stop
mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
cp /vagrant/util/vagrant_nginx /etc/nginx/nginx.conf
chown -R vagrant /var/log/nginx
unlink /etc/nginx/sites-enabled/
# Set up MySQL server.
echo "Customizing MySQL..."
cat $www_base/util/vagrant_mycnf >> /etc/mysql/my.cnf
echo "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;" | mysql -u root -ppassword
echo "CREATE DATABASE pvl CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" | mysql -u root -ppassword
service mysql restart
# Preconfigure databases
cd $www_base/util
curl -X POST "http://localhost:8086/cluster/database_configs/pvlive_stations?u=root&p=root" --data-binary @influx_pvlive_stations.json
curl -X POST "http://localhost:8086/cluster/database_configs/pvlive_analytics?u=root&p=root" --data-binary @influx_pvlive_analytics.json
# Enable PHP flags.
echo "alias phpwww='sudo -u vagrant php'" >> /home/vagrant/.profile
sed -e '/^[^;]*short_open_tag/s/=.*$/= On/' -i.bak /etc/php5/fpm/php.ini
sed -e '/^[^;]*short_open_tag/s/=.*$/= On/' -i.bak /etc/php5/cli/php.ini
mv /etc/php5/fpm/pool.d/www.conf /etc/php5/fpm/www.conf.bak
cp /vagrant/util/vagrant_phpfpm.conf /etc/php5/fpm/pool.d/www.conf
service php5-fpm restart
# Install composer.
echo "Installing Composer..."
cd /root
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
# Install Node.js and services
#cd $www_base
#npm install -g gulp
#npm install --no-bin-links
#cd $www_base/live
#npm install --no-bin-links
# Mark deployment as run.
touch $app_base/.deploy_run
# Copy sample files.
if [ ! -f $www_base/app/config/apis.conf.php ]
then
cp $www_base/app/config/apis.conf.sample.php $www_base/app/config/apis.conf.php
fi
if [ ! -f $www_base/app/config/db.conf.php ]
then
cp $www_base/app/config/db.conf.sample.php $www_base/app/config/db.conf.php
fi
if [ ! -f $www_base/app/config/influx.conf.php ]
then
cp $www_base/app/config/influx.conf.sample.php $www_base/app/config/influx.conf.php
fi
if [ ! -f $www_base/app/config/cache.conf.php ]
then
cp $www_base/app/config/cache.conf.sample.php $www_base/app/config/cache.conf.php
fi
# Run Composer.js
cd $www_base
composer install
# Shut off Cron tasks for now
service cron stop
service nginx stop

15
util/install_radio.sh Normal file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
apt-get update
apt-get -q -y install icecast2 liquidsoap
# Generate new passwords for Icecast
export icecast_pw_source=`pwgen 8`
export icecast_pw_relay=`pwgen 8`
export icecast_pw_admin=`pwgen 8`
sed -e 's/<source-password>hackme<\/source-password>/<source-password>'$icecast_pw_source'<\/source-password>/g' /etc/icecast2/icecast.xml
sed -e 's/<relay-password>hackme<\/relay-password>/<relay-password>'$icecast_pw_relay'<\/relay-password>/g' /etc/icecast2/icecast.xml
sed -e 's/<admin-password>hackme<\/admin-password>/<admin-password>'$icecast_pw_admin'<\/admin-password>/g' /etc/icecast2/icecast.xml

View File

@ -1,196 +1,54 @@
#!/bin/bash
#!/usr/bin/env bash
export util_base="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
export app_base = "$(dirname "$util_base")"
export www_base = $app_base
export tmp_base= $app_base/tmp
#
# Vagrant-specific Deploy Commands
#
export DEBIAN_FRONTEND=noninteractive
export app_base=/var/www
export tmp_base=$app_base/www_tmp
export www_base=$app_base/vagrant
if [ ! -f $app_base/.deploy_run ]
then
# Add Vagrant user to the sudoers group
echo 'vagrant ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
# Add Vagrant user to the sudoers group
echo 'vagrant ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
# Set up swap partition
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile none swap sw 0 0" >> /etc/fstab
# Set up swap partition
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile none swap sw 0 0" >> /etc/fstab
# Set up server
apt-get update
# Set up server
apt-get -q -y install software-properties-common python-software-properties
apt-get -q -y install software-properties-common python-software-properties
apt-get -q -y install vim git curl nginx
# Add Phalcon PPA
apt-add-repository ppa:phalcon/stable
# Trigger mlocate reindex.
updatedb
# Add MariaDB repo
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
add-apt-repository 'deb http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.0/ubuntu trusty main'
# Update Vagrant account permissions.
usermod -G vagrant www-data
usermod -G vagrant nobody
usermod -G www-data vagrant
apt-get update
#
# Run Common Installers
#
apt-get -q -y install vim git curl nginx mariadb-server
apt-get -q -y install php5-fpm php5-cli php5-gd php5-mysqlnd php5-curl php5-phalcon php5-redis php5-memcached
apt-get -q -y install nodejs npm
apt-get autoremove
cd $util_base;
chmod a+x ./install_app.sh
chmod a+x ./install_radio.sh
# Set up InfluxDB early (to allow time to initialize before setting up DBs.)
cd ~
wget http://influxdb.s3.amazonaws.com/influxdb_0.8.8_amd64.deb
dpkg -i influxdb_0.8.8_amd64.deb
service influxdb start
./install_app.sh
./install_radio.sh
# Set Node.js bin alias
ln -s /usr/bin/nodejs /usr/bin/node
# Set MySQL root password
mysqladmin -u root password password
# Trigger mlocate reindex.
updatedb
# Set up environment.
echo 'development' > $app_base/app/.env
echo "Creating temporary folders..."
mkdir -p $tmp_base
mkdir -p $tmp_base/cache
mkdir -p $tmp_base/sessions
mkdir -p $tmp_base/proxies
# Create log files.
echo "Setting permissions..."
touch $tmp_base/access.log
touch $tmp_base/error.log
touch $tmp_base/php_errors.log
touch $tmp_base/vagrant_import.sql
usermod -G vagrant www-data
usermod -G vagrant nobody
usermod -G www-data vagrant
chown -R vagrant:vagrant $tmp_base/
chmod -R 777 $tmp_base
# Nginx setup.
echo "Customizing nginx..."
service nginx stop
mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
cp /vagrant/util/vagrant_nginx /etc/nginx/nginx.conf
chown -R vagrant /var/log/nginx
unlink /etc/nginx/sites-enabled/
# Set up MySQL server.
echo "Customizing MySQL..."
cat $www_base/util/vagrant_mycnf >> /etc/mysql/my.cnf
echo "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;" | mysql -u root -ppassword
echo "CREATE DATABASE pvl CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" | mysql -u root -ppassword
service mysql restart
# Preconfigure databases
cd $www_base/util
curl -X POST "http://localhost:8086/cluster/database_configs/pvlive_stations?u=root&p=root" --data-binary @influx_pvlive_stations.json
curl -X POST "http://localhost:8086/cluster/database_configs/pvlive_analytics?u=root&p=root" --data-binary @influx_pvlive_analytics.json
# Enable PHP flags.
echo "alias phpwww='sudo -u vagrant php'" >> /home/vagrant/.profile
sed -e '/^[^;]*short_open_tag/s/=.*$/= On/' -i.bak /etc/php5/fpm/php.ini
sed -e '/^[^;]*short_open_tag/s/=.*$/= On/' -i.bak /etc/php5/cli/php.ini
mv /etc/php5/fpm/pool.d/www.conf /etc/php5/fpm/www.conf.bak
cp /vagrant/util/vagrant_phpfpm.conf /etc/php5/fpm/pool.d/www.conf
service php5-fpm restart
# Install composer.
echo "Installing Composer..."
cd /root
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
# Install Node.js and services
#cd $www_base
#npm install -g gulp
#npm install --no-bin-links
cd $www_base/live
npm install --no-bin-links
cp $www_base/util/vagrant_initd /etc/init/pvlnode.conf
# Mark deployment as run.
touch $app_base/.deploy_run
fi
# Copy sample files.
if [ ! -f $www_base/app/config/apis.conf.php ]
then
cp $www_base/app/config/apis.conf.sample.php $www_base/app/config/apis.conf.php
fi
if [ ! -f $www_base/app/config/db.conf.php ]
then
cp $www_base/app/config/db.conf.sample.php $www_base/app/config/db.conf.php
fi
if [ ! -f $www_base/app/config/influx.conf.php ]
then
cp $www_base/app/config/influx.conf.sample.php $www_base/app/config/influx.conf.php
fi
if [ ! -f $www_base/app/config/memcached.conf.php ]
then
cp $www_base/app/config/memcached.conf.sample.php $www_base/app/config/memcached.conf.php
fi
# Run Composer.js
cd $www_base
composer install
# Shut off Cron tasks for now
service cron stop
service nginx stop
service pvlnode stop
# Set up DB.
echo "Setting up database..."
cd $www_base/util
sudo -u vagrant php doctrine.php orm:schema-tool:drop --force
sudo -u vagrant php doctrine.php orm:schema-tool:create
sudo -u vagrant php cli.php cache:clear
sudo -u vagrant php vagrant_import.php
service pvlnode start
echo "Importing external music databases (takes a minute)..."
sudo -u vagrant php cli.php sync:long
echo "Running regular tasks..."
sudo -u vagrant php cli.php sync:short
sudo -u vagrant php cli.php sync:medium
sudo -u vagrant php cli.php sync:nowplaying
# Add cron job
echo "Installing cron job..."
crontab -u vagrant $www_base/util/vagrant_cron
service cron start
service nginx start
#
# Post-installer messages
#
echo "One-time setup complete!"
echo "Server now live at http://dev.pvlive.me"
echo "Complete remaining setup steps at http://localhost:8080"