@@ -85,6 +87,7 @@
+
@@ -229,6 +232,12 @@
+
+
+
+
+
+
diff --git a/CREDITS b/CREDITS
index ffa2ce2b6..801f38ef4 100644
--- a/CREDITS
+++ b/CREDITS
@@ -6,7 +6,8 @@ Version 1.6.0
-------------
This version marks a major change to the project, completely replacing the
custom audio player with liquidsoap, dropping the custom desktop GUI, and
-completely rewriting the web interface.
+completely rewriting the web interface. The project has also been renamed
+from "Campcaster" to "Airtime" for this release.
Paul Baranowski (paul.baranowski@sourcefabric.org)
Role: Project Lead / Software Developer
@@ -20,6 +21,12 @@ Naomi Aro (naomi.aro@sourcefabric.org)
- New User Interface
- Conversion to Propel DB backend
+Martin Konecny (martin.konecny@sourcefabric.org)
+ Role:Software Developer
+ Highlights:
+ - New User Interface
+ - Scheduler
+
Daniel James
Role: Documentor & QA
diff --git a/INSTALL b/INSTALL
index 654f8ff4e..9da745be8 100644
--- a/INSTALL
+++ b/INSTALL
@@ -2,22 +2,22 @@
Copyright (c) 2010 Sourcefabric O.P.S.
- This file is part of the Campcaster project.
+ This file is part of the Airtime project.
http://campcaster.sourcefabric.org/
To report bugs, send an e-mail to contact@sourcefabric.org
- Campcaster is free software; you can redistribute it and/or modify
+ Airtime is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
- Campcaster is distributed in the hope that it will be useful,
+ Airtime is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with Campcaster; if not, write to the Free Software
+ along with Airtime; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------------
diff --git a/README b/README
index c1f2d1ff5..12d5f96e4 100644
--- a/README
+++ b/README
@@ -1,94 +1,45 @@
=========================================================================
-========================== CAMPCASTER ===============================
+========================== AIRTIME =================================
=========================================================================
-Campcaster is the first free and open radio management software that
-provides live studio broadcast capabilities as well as remote automation
-in one integrated system.
+Airtime is an open source application that provides remote automation
+of a radio station.
-Campcaster has three audio outputs: one for live broadcasting, one for
-previewing audio, and one for automated scheduled playback.
-
-Major features of Campcaster:
- * Live, in-studio playout. Campcaster Studio enables station personnel
- to play out both individual sound files and playlists such as
- advertising blocks or entire programs.
+Major features:
* Web-based remote station management. Authorized personnel can add
program material, create playlists, and schedule programming all via
- Campcaster's web interface.
- * Automation. Campcaster has a scheduler function that enables users to
+ a web interface.
+ * Automation. Airtime has a scheduler function that enables users to
set playlists for playback at a date and time of their choosing.
Playlists can be played back multiple times.
- * Playlists. Campcaster allows users to create playlists that can be
+ * Playlists. Airtime allows users to create playlists that can be
either played on-demand in the Studio or in automated mode. Playlists
can be nested inside each other, so for example, a playlist with a
block of ads can be inside of a playlist with a music program.
* Centralized archives of station program material. Station personnel
have a searchable, browseable central archive that is accessible both
in the office and via the web.
- * Solid, fast playback. Campcaster uses the popular Gstreamer
+ * Solid, fast playback. Airtime uses the open source Liquidsoap
multimedia framework for clean, reliable, fast playback.
- * Program sharing. Stations can share both playlists and files with a
- designated, centralized 'network hub.' This enables the creation of
- 'virtual radio networks' connected via the Internet.
- * Search-based backup. You can backup all station archives at the click
- of a button, or only backup certain files based on search terms, so
- that backup files can be made of only a certain program or of all
- files created by a certain user.
- * Localization. Campcaster is multilingual and supports Unicode. It
- also is very easy to create language localizations.
- * No restrictions. Multiple instances of the Campcaster Studio program
- can access the same archive on the office network, and there are no
- worries about hardware dongles or keys limiting access on multiple PCs.
- * Innovative design. Campcaster's user interface – the product of
- Parsons School of Design's “Design and Communication” program -
- introduces a number of innovations, including the 'Scratchpad',
- a list of recently-used files and playlists.
* Open, extensible architecture. Stations are free to extend and alter
- all parts of the Campcaster program code, which makes extensive use
- of XML-RPC APIs.
+ all parts of the program code.
INSTALLATION
------------
Please see this page for a typical user installation:
-http://en.flossmanuals.net/Campcaster
+http://en.flossmanuals.net/Airtime
If you are a developer, please see this page:
-http://wiki.sourcefabric.org/display/CC/Campcaster+Dev+Site
+http://wiki.sourcefabric.org/display/CC/Airtime+Dev+Site
Quick links to our resources
----------------------------
- User Manual: http://en.flossmanuals.net/Campcaster/Introduction
+ User Manual: http://en.flossmanuals.net/Airtime/Introduction
Forums and mailing lists: http://forum.sourcefabric.org
Bug Tracking: http://dev.sourcefabric.org
Code view/review: http://code.sourcefabric.org
Public source code hosting: http://github.com/sourcefabric
- Download link: https://sourceforge.net/projects/campcaster/files/
+ Download link: https://sourceforge.net/projects/airtime/files/
Developer's wiki: http://wiki.sourcefabric.org
-
--------------------------------------------------------------------------
-
- Copyright (c) 2010 Sourcefabric O.P.S.
-
- This file is part of the Campcaster project.
- http://campcaster.sourcefabric.org/
- To report bugs, send an e-mail to campcaster-support@lists.sourcefabric.org
-
- Campcaster is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- Campcaster is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Campcaster; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
--------------------------------------------------------------------------
-
diff --git a/application/Bootstrap.php b/application/Bootstrap.php
index 43d6f69a0..a2b759a9d 100644
--- a/application/Bootstrap.php
+++ b/application/Bootstrap.php
@@ -53,6 +53,8 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
$view = $this->getResource('view');
$view->headScript()->appendFile('/js/libs/jquery-1.4.4.min.js','text/javascript');
$view->headScript()->appendFile('/js/libs/jquery-ui-1.8.7.custom.min.js','text/javascript');
+ $view->headScript()->appendFile('/js/playlist/playlist.js','text/javascript');
+ $view->headScript()->appendFile('/js/progressbar/jquery.progressbar.min.js','text/javascript');
}
}
diff --git a/application/configs/application.ini b/application/configs/application.ini
index 88feac347..836d659da 100644
--- a/application/configs/application.ini
+++ b/application/configs/application.ini
@@ -12,9 +12,9 @@ resources.view[] =
resources.db.adapter = "Pdo_Pgsql"
resources.db.params.charset = "utf8"
resources.db.params.host = "localhost"
-resources.db.params.username = "campcaster"
-resources.db.params.password = "campcaster"
-resources.db.params.dbname = "campcaster"
+resources.db.params.username = "airtime"
+resources.db.params.password = "airtime"
+resources.db.params.dbname = "airtime"
[staging : production]
diff --git a/application/configs/conf.php b/application/configs/conf.php
index 7779721b5..c46d38b69 100644
--- a/application/configs/conf.php
+++ b/application/configs/conf.php
@@ -8,11 +8,11 @@ global $CC_CONFIG;
$CC_CONFIG = array(
// Database config
'dsn' => array(
- 'username' => 'campcaster',
- 'password' => 'campcaster',
+ 'username' => 'airtime',
+ 'password' => 'airtime',
'hostspec' => 'localhost',
'phptype' => 'pgsql',
- 'database' => 'campcaster',
+ 'database' => 'airtime',
),
// Name of the web server user
@@ -173,4 +173,4 @@ set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath']
//$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC);
-?>
\ No newline at end of file
+?>
diff --git a/application/configs/propel-config.php b/application/configs/propel-config.php
index 768c5b151..22571384c 100644
--- a/application/configs/propel-config.php
+++ b/application/configs/propel-config.php
@@ -1,6 +1,6 @@
array (
diff --git a/application/controllers/LibraryController.php b/application/controllers/LibraryController.php
index 7af3b62fd..da98fae22 100644
--- a/application/controllers/LibraryController.php
+++ b/application/controllers/LibraryController.php
@@ -2,7 +2,9 @@
class LibraryController extends Zend_Controller_Action
{
+
protected $pl_sess = null;
+
protected $search_sess = null;
public function init()
@@ -18,6 +20,7 @@ class LibraryController extends Zend_Controller_Action
->addActionContext('upload', 'json')
->addActionContext('delete', 'json')
->addActionContext('context-menu', 'json')
+ ->addActionContext('quick-search', 'json')
->initContext();
$this->pl_sess = new Zend_Session_Namespace(UI_PLAYLIST_SESSNAME);
@@ -26,16 +29,17 @@ class LibraryController extends Zend_Controller_Action
public function indexAction()
{
- $this->view->headScript()->appendFile('/js/campcaster/onready/library.js','text/javascript');
+ $this->view->headScript()->appendFile('/js/airtime/onready/library.js','text/javascript');
$this->view->headScript()->appendFile('/js/contextmenu/jjmenu.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/contextmenu.css');
$this->_helper->layout->setLayout('library');
+ unset($this->search_sess->page);
unset($this->search_sess->md);
- unset($this->search_sess->order);
-
+
$this->_helper->actionStack('contents', 'library');
+ $this->_helper->actionStack('quick-search', 'library');
$this->_helper->actionStack('index', 'sideplaylist');
}
@@ -59,7 +63,7 @@ class LibraryController extends Zend_Controller_Action
}
$menu[] = array('action' => array('type' => 'gourl', 'url' => '/Library/edit-file-md/id/#id#'),
- 'title' => 'Info');
+ 'title' => 'Edit Metadata');
}
else if($type === "pl") {
@@ -94,7 +98,7 @@ class LibraryController extends Zend_Controller_Action
public function deleteAction()
{
$id = $this->_getParam('id');
-
+
if (!is_null($id)) {
$file = StoredFile::Recall($id);
@@ -120,17 +124,55 @@ class LibraryController extends Zend_Controller_Action
public function contentsAction()
{
- $this->view->headScript()->appendFile('/js/campcaster/library/library.js','text/javascript');
-
+ $this->view->headScript()->appendFile('/js/airtime/library/library.js','text/javascript');
+
$this->_helper->viewRenderer->setResponseSegment('library');
- $order["category"] = $this->_getParam('ob', "dc:creator");
- $order["order"] = $this->_getParam('order', "asc");
+ $cat = $this->_getParam('ob', null);
+ $or = $this->_getParam('order', null);
+ $page = $this->_getParam('page', null);
- $this->search_sess->order = $order;
- $md = isset($this->search_sess->md) ? $this->search_sess->md : array();
+ if(!is_null($cat) && !is_null($or)) {
+ $order["category"] = $cat;
+ $order["order"] = $or;
+ $this->search_sess->order = $order;
+ }
+ else if(isset($this->search_sess->order)){
+ $order = $this->search_sess->order;
+ }
+ else{
+ $order = null;
+ }
- $this->view->files = StoredFile::searchFiles($md, $order);
+ if (isset($this->search_sess->page)) {
+ $last_page = $this->search_sess->page;
+ }
+ else{
+ $last_page = null;
+ }
+
+ if(isset($this->search_sess->md)){
+ $md = $this->search_sess->md;
+ $quick = false;
+ }
+ else if(isset($this->search_sess->quick)) {
+ $md = $this->search_sess->quick;
+ $quick = true;
+ }
+ else {
+ $md = array();
+ $quick = false;
+ }
+
+ $currpage = isset($page) ? $page : $last_page;
+ $this->search_sess->page = $currpage;
+
+ $count = StoredFile::searchFiles($md, $order, true, null, null, $quick);
+
+ $paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Null($count));
+ $paginator->setCurrentPageNumber($currpage);
+ $this->view->paginator = $paginator;
+ $this->view->files = StoredFile::searchFiles($md, $order, false, $paginator->getCurrentPageNumber(), $paginator->getItemCountPerPage(), $quick);
}
public function editFileMdAction()
@@ -156,7 +198,52 @@ class LibraryController extends Zend_Controller_Action
$this->view->form = $form;
}
+ public function quickSearchAction()
+ {
+ $this->view->headScript()->appendFile('/js/airtime/library/quicksearch.js','text/javascript');
+ $this->_helper->viewRenderer->setResponseSegment('quick_search');
+
+ $this->view->qs_value = $this->search_sess->quick_string;
+
+ $format = $this->_getParam('format', 'layout');
+
+ if($format !== 'json')
+ return;
+
+ $search = $this->_getParam('search', null);
+ $this->search_sess->quick_string = $search;
+
+ $categories = array("dc:title", "dc:creator", "dc:source", "ls:type");
+ $keywords = explode(" ", $search);
+
+ $md = array();
+
+ for($group_id=1; $group_id <= count($keywords); $group_id++) {
+
+ for($row_id=1; $row_id <= count($categories); $row_id++) {
+
+ $md["group_".$group_id]["row_".$row_id]["metadata"] = $categories[$row_id-1];
+ $md["group_".$group_id]["row_".$row_id]["match"] = "0";
+ $md["group_".$group_id]["row_".$row_id]["search"] = $keywords[$group_id-1];
+ }
+ }
+
+ $this->search_sess->quick = $md;
+
+ $currpage = isset($this->search_sess->page) ? $this->search_sess->page : null;
+ $order = isset($this->search_sess->order) ? $this->search_sess->order : null;
+ $count = StoredFile::searchFiles($md, $order, true, null, null, true);
+
+ $paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Null($count));
+ $paginator->setCurrentPageNumber($currpage);
+ $this->view->paginator = $paginator;
+ $this->view->files = StoredFile::searchFiles($md, $order, false, $paginator->getCurrentPageNumber(), $paginator->getItemCountPerPage(), true);
+
+ $this->view->html = $this->view->render('library/contents.phtml');
+ unset($this->view->files);
+ unset($this->view->paginator);
+ }
}
@@ -173,3 +260,5 @@ class LibraryController extends Zend_Controller_Action
+
+
diff --git a/application/controllers/PlaylistController.php b/application/controllers/PlaylistController.php
index d73ef2a06..bd1790e03 100644
--- a/application/controllers/PlaylistController.php
+++ b/application/controllers/PlaylistController.php
@@ -136,7 +136,7 @@ class PlaylistController extends Zend_Controller_Action
public function editAction()
{
- $this->view->headScript()->appendFile('/js/campcaster/playlist/playlist.js','text/javascript');
+ $this->view->headScript()->appendFile('/js/airtime/playlist/playlist.js','text/javascript');
$pl_id = $this->_getParam('id', null);
$display = $this->_getParam('view', null);
diff --git a/application/controllers/PluploadController.php b/application/controllers/PluploadController.php
index ffaff33e8..9b1792e7c 100644
--- a/application/controllers/PluploadController.php
+++ b/application/controllers/PluploadController.php
@@ -165,7 +165,7 @@ class PluploadController extends Zend_Controller_Action
$view->headScript()->appendFile('/js/plupload/plupload.full.min.js','text/javascript');
$view->headScript()->appendFile('/js/plupload/jquery.plupload.queue.min.js','text/javascript');
- $view->headScript()->appendFile('/js/campcaster/library/plupload.js','text/javascript');
+ $view->headScript()->appendFile('/js/airtime/library/plupload.js','text/javascript');
$view->headLink()->appendStylesheet('/css/plupload.queue.css');
}
diff --git a/application/controllers/ScheduleController.php b/application/controllers/ScheduleController.php
index 651efb191..ec1aab5ac 100644
--- a/application/controllers/ScheduleController.php
+++ b/application/controllers/ScheduleController.php
@@ -29,7 +29,7 @@ class ScheduleController extends Zend_Controller_Action
$this->view->headScript()->appendFile('/js/contextmenu/jquery.contextMenu.js','text/javascript');
$this->view->headScript()->appendFile('/js/qtip/jquery.qtip-1.0.0.min.js','text/javascript');
- $this->view->headScript()->appendFile('/js/campcaster/schedule/schedule.js','text/javascript');
+ $this->view->headScript()->appendFile('/js/airtime/schedule/schedule.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/jquery.contextMenu.css');
$this->view->headLink()->appendStylesheet('/css/fullcalendar.css');
@@ -177,8 +177,7 @@ class ScheduleController extends Zend_Controller_Action
public function viewPlaylistAction()
{
- $this->view->headScript()->appendFile('/js/playlist/playlist.js','text/javascript');
- $this->view->headScript()->appendFile('/js/progressbar/jquery.progressbar.min.js','text/javascript');
+ //TODO: insert code for datagrid
}
public function getCurrentPlaylistAction()
diff --git a/application/controllers/SearchController.php b/application/controllers/SearchController.php
index a96248964..d31bbae12 100644
--- a/application/controllers/SearchController.php
+++ b/application/controllers/SearchController.php
@@ -2,23 +2,42 @@
class SearchController extends Zend_Controller_Action
{
+ protected $search_sess = null;
- protected $form;
- protected $search_sess = null;
+ private function addGroup($group_id) {
+
+ $form = new Application_Form_AdvancedSearch();
+
+ $form->addGroup($group_id, 1);
+ $group = $form->getSubForm('group_'.$group_id);
+
+ return $group->__toString();
+ }
+
+ private function addFieldToGroup($group_id, $row_id) {
+
+ $form = new Application_Form_AdvancedSearch();
+
+ $form->addGroup($group_id);
+ $group = $form->getSubForm('group_'.$group_id);
+
+ $group->addRow($row_id);
+
+ return $group->__toString();
+ }
public function init()
{
- if(!Zend_Auth::getInstance()->hasIdentity())
+ if(!Zend_Auth::getInstance()->hasIdentity())
{
$this->_redirect('login/index');
}
$ajaxContext = $this->_helper->getHelper('AjaxContext');
- $ajaxContext->addActionContext('newfield', 'html')
- ->addActionContext('display', 'json')
+ $ajaxContext->addActionContext('newfield', 'json')
+ ->addActionContext('newgroup', 'json')
->initContext();
- $this->form = new Application_Form_AdvancedSearch();
$this->search_sess = new Zend_Session_Namespace("search");
}
@@ -26,80 +45,82 @@ class SearchController extends Zend_Controller_Action
{
$this->_helper->layout->setLayout('search');
- $this->view->headScript()->appendFile('/js/campcaster/onready/search.js','text/javascript');
+ $this->view->headScript()->appendFile('/js/airtime/onready/search.js','text/javascript');
$this->view->headScript()->appendFile('/js/contextmenu/jjmenu.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/contextmenu.css');
- $this->_helper->actionStack('display', 'search');
$this->_helper->actionStack('contents', 'library');
+ $this->_helper->actionStack('display', 'search');
$this->_helper->actionStack('index', 'sideplaylist');
}
public function displayAction()
{
- $this->view->headScript()->appendFile('/js/campcaster/library/advancedsearch.js','text/javascript');
+ $this->view->headScript()->appendFile('/js/airtime/library/advancedsearch.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/library_search.css');
$this->_helper->viewRenderer->setResponseSegment('search');
$request = $this->getRequest();
- $this->form = new Application_Form_AdvancedSearch();
- $form = $this->form;
+ $form = new Application_Form_AdvancedSearch();
+ $this->view->form = $form;
// Form has not been submitted - displayed using layouts
if (!$request->isPost()) {
- unset($this->search_sess->md);
- unset($this->search_sess->order);
+ $form->addGroup(1, 1);
- $sub = new Application_Form_AdvancedSearchRow(1);
- $form->addSubForm($sub, 'row_1');
- $form->getSubForm('row_1')->removeDecorator('DtDdWrapper');
+ $this->search_sess->next_group = 2;
+ $this->search_sess->next_row[1] = 2;
- $this->view->form = $form;
return;
}
- // Form has been submitted - run data through preValidation()
+ $this->view->md = $request->getPost();
+
+ // Form has been submitted
$form->preValidation($request->getPost());
if (!$form->isValid($request->getPost())) {
- $this->view->form = $form->__toString();
return;
}
- // form was submitted, send back strings to json response.
- $info = $form->getValues();
- $this->search_sess->md = $info;
- $order = isset($this->search_sess->order) ? $this->search_sess->order : NULL;
+ // valid form was submitted set as search criteria.
+ $this->view->md = $form->getValues();
+ $this->search_sess->md = $form->getValues();
- $this->view->files = StoredFile::searchFiles($info, $order);
-
- if (count($this->view->files) > 0) {
- $this->view->results = $this->view->render('library/update.phtml');
- }
- else {
- $this->view->results = "No Results
";
- }
- unset($this->view->files);
+ //make sure to start on first page of new results.
+ unset($this->search_sess->page);
}
public function newfieldAction()
{
- $id = $this->_getParam('id', 1);
+ $group_id = $this->_getParam('group', 1);
+ $row_id = $this->search_sess->next_row[$group_id];
- $this->form->addSubForm(new Application_Form_AdvancedSearchRow($id), 'row_'.$id, $id);
+ $this->view->html = $this->addFieldToGroup($group_id, $row_id);
+ $this->view->row = $row_id;
- $this->form->getSubForm('row_'.$id)->removeDecorator('DtDdWrapper');
- $e = $this->form->getSubForm('row_'.$id);
-
- $this->view->field = $e->__toString();
+ $this->search_sess->next_row[$group_id] = $row_id + 1;
}
+ public function newgroupAction()
+ {
+ $group_id = $this->search_sess->next_group;
+
+ $this->view->html = $this->addGroup($group_id);
+
+ $this->search_sess->next_group = $group_id + 1;
+ $this->search_sess->next_row[$group_id] = 2;
+ }
+
+
}
+
+
diff --git a/application/controllers/SideplaylistController.php b/application/controllers/SideplaylistController.php
index cebef65c7..6c9f31310 100644
--- a/application/controllers/SideplaylistController.php
+++ b/application/controllers/SideplaylistController.php
@@ -17,7 +17,7 @@ class SideplaylistController extends Zend_Controller_Action
public function indexAction()
{
- $this->view->headScript()->appendFile('/js/campcaster/library/spl.js','text/javascript');
+ $this->view->headScript()->appendFile('/js/airtime/library/spl.js','text/javascript');
$this->_helper->viewRenderer->setResponseSegment('spl');
diff --git a/application/forms/AdvancedSearch.php b/application/forms/AdvancedSearch.php
index 4c915c38e..f8fae8705 100644
--- a/application/forms/AdvancedSearch.php
+++ b/application/forms/AdvancedSearch.php
@@ -5,12 +5,34 @@ class Application_Form_AdvancedSearch extends Zend_Form
public function init()
{
- $this->addElement('hidden', 'search_next_id', array(
- 'value' => 2
- ));
- $this->getElement('search_next_id')->removeDecorator('Label')->removeDecorator('HtmlTag');
+ // Add the add button
+ $this->addElement('button', 'search_add_group', array(
+ 'ignore' => true,
+ 'label' => 'Add',
+ 'order' => '-2'
+ ));
+ $this->getElement('search_add_group')->removeDecorator('DtDdWrapper');
+
+ // Add the submit button
+ $this->addElement('submit', 'search_submit', array(
+ 'ignore' => true,
+ 'label' => 'Submit',
+ 'order' => '-1'
+ ));
+ $this->getElement('search_submit')->removeDecorator('DtDdWrapper');
}
+ public function addGroup($group_id, $row_id=null) {
+
+ $this->addSubForm(new Application_Form_AdvancedSearchGroup(), 'group_'.$group_id, $group_id);
+ $this->getSubForm('group_'.$group_id)->removeDecorator('DtDdWrapper');
+
+ if(!is_null($row_id)) {
+ $subGroup = $this->getSubForm('group_'.$group_id);
+ $subGroup->addRow($row_id);
+ }
+ }
+
public function preValidation(array $data) {
function findId($name) {
@@ -18,34 +40,26 @@ class Application_Form_AdvancedSearch extends Zend_Form
return $t[1];
}
- // array_filter callback
function findFields($field) {
- return strpos($field, 'row') !== false;
+ return strpos($field, 'group') !== false;
}
- $fields = array_filter(array_keys($data), 'findFields');
+ $groups = array_filter(array_keys($data), 'findFields');
- foreach ($fields as $field) {
- // use id to set new order
- $id = findId($field);
- $this->addNewField($data, $id);
+ foreach ($groups as $group) {
+
+ $group_id = findId($group);
+ $this->addGroup($group_id);
+
+ $subGroup = $this->getSubForm($group);
+
+ foreach (array_keys($data[$group]) as $row) {
+
+ $row_id = findId($row);
+ $subGroup->addRow($row_id, $data[$group][$row]);
+ }
}
+
}
-
- public function addNewField($data, $id) {
-
- $sub = new Application_Form_AdvancedSearchRow($id);
-
- $values = array("metadata_".$id => $data["row_".$id]["metadata_".$id],
- "match_".$id => $data["row_".$id]["match_".$id],
- "search_".$id => $data["row_".$id]["search_".$id]);
-
- $sub->setDefaults($values);
-
- $this->addSubForm($sub, 'row_'.$id, $id);
- $this->getSubForm('row_'.$id)->removeDecorator('DtDdWrapper');
- }
-
-
}
diff --git a/application/forms/AdvancedSearchGroup.php b/application/forms/AdvancedSearchGroup.php
new file mode 100644
index 000000000..5a5541673
--- /dev/null
+++ b/application/forms/AdvancedSearchGroup.php
@@ -0,0 +1,29 @@
+addElement('button', 'search_add_row', array(
+ 'ignore' => true,
+ 'label' => 'Add',
+ 'order' => '-2'
+ ));
+ $this->getElement('search_add_row')->removeDecorator('DtDdWrapper');
+ }
+
+ public function addRow($row_id, $data=null) {
+
+ $this->addSubForm(new Application_Form_AdvancedSearchRow(), 'row_'.$row_id, $row_id);
+ $row = $this->getSubForm('row_'.$row_id);
+ $row->removeDecorator('DtDdWrapper');
+
+ if(!is_null($data)) {
+ $row->setDefaults($data);
+ }
+ }
+
+
+}
+
diff --git a/application/forms/AdvancedSearchRow.php b/application/forms/AdvancedSearchRow.php
index a647e7656..b50cfb176 100644
--- a/application/forms/AdvancedSearchRow.php
+++ b/application/forms/AdvancedSearchRow.php
@@ -2,22 +2,11 @@
class Application_Form_AdvancedSearchRow extends Zend_Form_SubForm
{
-
- protected $_rowid;
-
- public function __construct($id = null)
- {
- $this->_rowid = $id;
- parent::__construct();
- }
-
public function init()
{
- $id = $this->_rowid;
-
$this->addElement(
'select',
- 'metadata_'.$id,
+ 'metadata',
array(
'required' => true,
'multiOptions' => array(
@@ -50,11 +39,11 @@ class Application_Form_AdvancedSearchRow extends Zend_Form_SubForm
),
)
);
- $this->getElement('metadata_'.$id)->removeDecorator('Label')->removeDecorator('HtmlTag');
+ $this->getElement('metadata')->removeDecorator('Label')->removeDecorator('HtmlTag');
$this->addElement(
'select',
- 'match_'.$id,
+ 'match',
array(
'required' => true,
'multiOptions' => array(
@@ -68,12 +57,12 @@ class Application_Form_AdvancedSearchRow extends Zend_Form_SubForm
),
)
);
- $this->getElement('match_'.$id)->removeDecorator('Label')->removeDecorator('HtmlTag');
+ $this->getElement('match')->removeDecorator('Label')->removeDecorator('HtmlTag');
- $this->addElement('text', 'search_'.$id, array(
+ $this->addElement('text', 'search', array(
'required' => true,
));
- $this->getElement('search_'.$id)->removeDecorator('Label')->removeDecorator('HtmlTag');
+ $this->getElement('search')->removeDecorator('Label')->removeDecorator('HtmlTag');
}
diff --git a/application/layouts/scripts/layout.phtml b/application/layouts/scripts/layout.phtml
index b85faa6b4..d9d756fec 100644
--- a/application/layouts/scripts/layout.phtml
+++ b/application/layouts/scripts/layout.phtml
@@ -3,7 +3,7 @@
- Campcaster
+ Airtime
headScript() ?>
headLink() ?>
@@ -11,7 +11,17 @@
navigation()->menu()->setRenderInvisible(true) ?>
-layout()->content ?>
-
+layout()->content ?>
+
+
+
+
Previous:
Current:
Upcoming:
+
+
+