diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index 8666d60bf..454bc4cba 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -15,7 +15,6 @@ require_once __DIR__.'/controllers/plugins/RabbitMqPlugin.php'; date_default_timezone_set(Application_Model_Preference::GetTimezone()); - global $CC_CONFIG; $airtime_version = Application_Model_Preference::GetAirtimeVersion(); $uniqueid = Application_Model_Preference::GetUniqueId(); @@ -105,6 +104,10 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap protected function _initZFDebug() { + + Zend_Controller_Front::getInstance()->throwExceptions(true); + + /* if (APPLICATION_ENV == "development") { $autoloader = Zend_Loader_Autoloader::getInstance(); $autoloader->registerNamespace('ZFDebug'); @@ -121,6 +124,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap $frontController = $this->getResource('frontController'); $frontController->registerPlugin($debug); } + */ } protected function _initRouter() diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 95ca8a4e8..57b4efddd 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -347,7 +347,6 @@ class ApiController extends Zend_Controller_Action $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); - $schedule_group_id = $this->_getParam("schedule_id"); $media_id = $this->_getParam("media_id"); Logging::debug("Received notification of new media item start: $media_id"); $result = Application_Model_Schedule::UpdateMediaPlayedStatus($media_id); @@ -355,12 +354,26 @@ class ApiController extends Zend_Controller_Action //set a 'last played' timestamp for media item //needed for smart blocks try { - $file_id = Application_Model_Schedule::GetFileId($media_id); - if (!is_null($file_id)) { - //we are dealing with a file not a stream - $file = Application_Model_StoredFile::Recall($file_id); - $now = new DateTime("now", new DateTimeZone("UTC")); - $file->setLastPlayedTime($now); + $mediaType = Application_Model_Schedule::GetType($media_id); + var_dump($mediaType); + if ($mediaType == 'file') { + $file_id = Application_Model_Schedule::GetFileId($media_id); + if (!is_null($file_id)) { + //we are dealing with a file not a stream + $file = Application_Model_StoredFile::Recall($file_id); + $now = new DateTime("now", new DateTimeZone("UTC")); + $file->setLastPlayedTime($now); + } + } else { + // webstream + $stream_id = Application_Model_Schedule::GetStreamId($media_id); + var_dump($stream_id); + if (!is_null($stream_id)) { + $webStream = new Application_Model_Webstream($stream_id); + var_dump($webStream); + $now = new DateTime("now", new DateTimeZone("UTC")); + $webStream->setLastPlayed($now); + } } } catch (Exception $e) { Logging::info($e); @@ -689,11 +702,11 @@ class ApiController extends Zend_Controller_Action { $request = $this->getRequest(); $dir_id = $request->getParam('dir_id'); - $all = $request->getParam('all'); + $all = $request->getParam('all'); Logging::info("All param is: $all"); - $this->view->files = + $this->view->files = Application_Model_StoredFile::listAllFiles($dir_id,$all); } diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index cba555785..cc13cd649 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -19,7 +19,6 @@ class LibraryController extends Zend_Controller_Action ->addActionContext('get-upload-to-soundcloud-status', 'json') ->addActionContext('set-num-entries', 'json') ->initContext(); - } public function indexAction() diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index e55fa52fc..fb8ff7020 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -894,7 +894,7 @@ SQL; new DateTimeZone(date_default_timezone_get())); $start_dt->setTimezone(new DateTimeZone('UTC')); - $end_dt = new DateTime($data['add_show_end_date_no_repeat']." ".$data['add_show_end_time'], + $end_dt = new DateTime($data['add_show_end_date_no_repeat']." ".$data['add_show_end_time'], new DateTimeZone(date_default_timezone_get())); $end_dt->setTimezone(new DateTimeZone('UTC')); @@ -1159,10 +1159,26 @@ SQL; return $overlapping; } + public static function GetType($p_scheduleId){ + $scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId); + if ($scheduledItem->getDbFileId() == null) { + return 'webstream'; + } else { + return 'file'; + } + } + public static function GetFileId($p_scheduleId) { $scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId); return $scheduledItem->getDbFileId(); } + + public static function GetStreamId($p_scheduleId) + { + $scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId); + + return $scheduledItem->getDbStreamId(); + } } diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index d84e74bd5..e88184a3d 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -647,7 +647,7 @@ class Application_Model_StoredFile $displayColumns = array("id", "track_title", "artist_name", "album_title", "genre", "length", "year", "utime", "mtime", "ftype", "track_number", "mood", "bpm", "composer", "info_url", "bit_rate", "sample_rate", "isrc_number", "encoded_by", "label", "copyright", "mime", - "language", "filepath", "owner", "conductor", "replay_gain" + "language", "filepath", "owner", "conductor", "replay_gain", "lptime" ); //Logging::info($datatables); @@ -686,8 +686,13 @@ class Application_Model_StoredFile } elseif ($key === "replay_gain") { $plSelect[] = "NULL::NUMERIC AS ".$key; $blSelect[] = "NULL::NUMERIC AS ".$key; - $fileSelect[] = "replay_gain AS $key"; + $fileSelect[] = $key; $streamSelect[] = "NULL::NUMERIC AS ".$key; + } elseif ($key === "lptime") { + $plSelect[] = "NULL::TIMESTAMP AS ".$key; + $blSelect[] = "NULL::TIMESTAMP AS ".$key; + $fileSelect[] = $key; + $streamSelect[] = $key; } //same columns in each table. else if (in_array($key, array("length", "utime", "mtime"))) { diff --git a/airtime_mvc/application/models/Webstream.php b/airtime_mvc/application/models/Webstream.php index 4f721c567..9b054fa04 100644 --- a/airtime_mvc/application/models/Webstream.php +++ b/airtime_mvc/application/models/Webstream.php @@ -170,7 +170,7 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable $valid['url'][1] = 'URL should be of form "http://domain"'; } elseif (strlen($url) > 512) { $valid['url'][0] = false; - $valid['url'][1] = 'URL should be 512 characters or less'; + $valid['url'][1] = 'URL should be 512 characters or less'; } else { try { @@ -220,6 +220,12 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable { } + + public function setLastPlayed($timestamp) + { + $this->webstream->setDbLPtime($timestamp); + $this->webstream->save(); + } private static function getUrlData($url) { @@ -242,7 +248,7 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable private static function getXspfUrl($url) { - $content = self::getUrlData($url); + $content = self::getUrlData($url); $dom = new DOMDocument; //TODO: What if invalid xml? @@ -261,8 +267,8 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable private static function getPlsUrl($url) { - $content = self::getUrlData($url); - $ini = parse_ini_string($content, true); + $content = self::getUrlData($url); + $ini = parse_ini_string($content, true); if ($ini !== false && isset($ini["playlist"]) && isset($ini["playlist"]["File1"])) { return $ini["playlist"]["File1"]; @@ -273,7 +279,7 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable private static function getM3uUrl($url) { - $content = self::getUrlData($url); + $content = self::getUrlData($url); //split into lines: $delim = "\n"; diff --git a/airtime_mvc/application/models/airtime/map/CcWebstreamTableMap.php b/airtime_mvc/application/models/airtime/map/CcWebstreamTableMap.php index 5121aa39b..c4b28a516 100644 --- a/airtime_mvc/application/models/airtime/map/CcWebstreamTableMap.php +++ b/airtime_mvc/application/models/airtime/map/CcWebstreamTableMap.php @@ -41,11 +41,12 @@ class CcWebstreamTableMap extends TableMap { $this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null); $this->addColumn('NAME', 'DbName', 'VARCHAR', true, 255, null); $this->addColumn('DESCRIPTION', 'DbDescription', 'VARCHAR', true, 255, null); - $this->addColumn('URL', 'DbUrl', 'VARCHAR', true, 255, null); + $this->addColumn('URL', 'DbUrl', 'VARCHAR', true, 512, null); $this->addColumn('LENGTH', 'DbLength', 'VARCHAR', true, null, '00:00:00'); $this->addColumn('CREATOR_ID', 'DbCreatorId', 'INTEGER', true, null, null); $this->addColumn('MTIME', 'DbMtime', 'TIMESTAMP', true, 6, null); $this->addColumn('UTIME', 'DbUtime', 'TIMESTAMP', true, 6, null); + $this->addColumn('LPTIME', 'DbLPtime', 'TIMESTAMP', false, 6, null); $this->addColumn('MIME', 'DbMime', 'VARCHAR', false, 255, null); // validators } // initialize() diff --git a/airtime_mvc/application/models/airtime/om/BaseCcWebstream.php b/airtime_mvc/application/models/airtime/om/BaseCcWebstream.php index e5faf12fd..6f6e16e2b 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcWebstream.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcWebstream.php @@ -73,6 +73,12 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent */ protected $utime; + /** + * The value for the lptime field. + * @var string + */ + protected $lptime; + /** * The value for the mime field. * @var string @@ -245,6 +251,39 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent } } + /** + * Get the [optionally formatted] temporal [lptime] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw DateTime object will be returned. + * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getDbLPtime($format = 'Y-m-d H:i:s') + { + if ($this->lptime === null) { + return null; + } + + + + try { + $dt = new DateTime($this->lptime); + } catch (Exception $x) { + throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->lptime, true), $x); + } + + if ($format === null) { + // Because propel.useDateTimeClass is TRUE, we return a DateTime object. + return $dt; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $dt->format('U')); + } else { + return $dt->format($format); + } + } + /** * Get the [mime] column value. * @@ -473,6 +512,55 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent return $this; } // setDbUtime() + /** + * Sets the value of [lptime] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will + * be treated as NULL for temporal objects. + * @return CcWebstream The current object (for fluent API support) + */ + public function setDbLPtime($v) + { + // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') + // -- which is unexpected, to say the least. + if ($v === null || $v === '') { + $dt = null; + } elseif ($v instanceof DateTime) { + $dt = $v; + } else { + // some string/numeric value passed; we normalize that so that we can + // validate it. + try { + if (is_numeric($v)) { // if it's a unix timestamp + $dt = new DateTime('@'.$v, new DateTimeZone('UTC')); + // We have to explicitly specify and then change the time zone because of a + // DateTime bug: http://bugs.php.net/bug.php?id=43003 + $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); + } else { + $dt = new DateTime($v); + } + } catch (Exception $x) { + throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x); + } + } + + if ( $this->lptime !== null || $dt !== null ) { + // (nested ifs are a little easier to read in this case) + + $currNorm = ($this->lptime !== null && $tmpDt = new DateTime($this->lptime)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; + $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; + + if ( ($currNorm !== $newNorm) // normalized values don't match + ) + { + $this->lptime = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); + $this->modifiedColumns[] = CcWebstreamPeer::LPTIME; + } + } // if either are not null + + return $this; + } // setDbLPtime() + /** * Set the value of [mime] column. * @@ -537,7 +625,8 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent $this->creator_id = ($row[$startcol + 5] !== null) ? (int) $row[$startcol + 5] : null; $this->mtime = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null; $this->utime = ($row[$startcol + 7] !== null) ? (string) $row[$startcol + 7] : null; - $this->mime = ($row[$startcol + 8] !== null) ? (string) $row[$startcol + 8] : null; + $this->lptime = ($row[$startcol + 8] !== null) ? (string) $row[$startcol + 8] : null; + $this->mime = ($row[$startcol + 9] !== null) ? (string) $row[$startcol + 9] : null; $this->resetModified(); $this->setNew(false); @@ -546,7 +635,7 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent $this->ensureConsistency(); } - return $startcol + 9; // 9 = CcWebstreamPeer::NUM_COLUMNS - CcWebstreamPeer::NUM_LAZY_LOAD_COLUMNS). + return $startcol + 10; // 10 = CcWebstreamPeer::NUM_COLUMNS - CcWebstreamPeer::NUM_LAZY_LOAD_COLUMNS). } catch (Exception $e) { throw new PropelException("Error populating CcWebstream object", $e); @@ -888,6 +977,9 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent return $this->getDbUtime(); break; case 8: + return $this->getDbLPtime(); + break; + case 9: return $this->getDbMime(); break; default: @@ -921,7 +1013,8 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent $keys[5] => $this->getDbCreatorId(), $keys[6] => $this->getDbMtime(), $keys[7] => $this->getDbUtime(), - $keys[8] => $this->getDbMime(), + $keys[8] => $this->getDbLPtime(), + $keys[9] => $this->getDbMime(), ); return $result; } @@ -978,6 +1071,9 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent $this->setDbUtime($value); break; case 8: + $this->setDbLPtime($value); + break; + case 9: $this->setDbMime($value); break; } // switch() @@ -1012,7 +1108,8 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent if (array_key_exists($keys[5], $arr)) $this->setDbCreatorId($arr[$keys[5]]); if (array_key_exists($keys[6], $arr)) $this->setDbMtime($arr[$keys[6]]); if (array_key_exists($keys[7], $arr)) $this->setDbUtime($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setDbMime($arr[$keys[8]]); + if (array_key_exists($keys[8], $arr)) $this->setDbLPtime($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setDbMime($arr[$keys[9]]); } /** @@ -1032,6 +1129,7 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent if ($this->isColumnModified(CcWebstreamPeer::CREATOR_ID)) $criteria->add(CcWebstreamPeer::CREATOR_ID, $this->creator_id); if ($this->isColumnModified(CcWebstreamPeer::MTIME)) $criteria->add(CcWebstreamPeer::MTIME, $this->mtime); if ($this->isColumnModified(CcWebstreamPeer::UTIME)) $criteria->add(CcWebstreamPeer::UTIME, $this->utime); + if ($this->isColumnModified(CcWebstreamPeer::LPTIME)) $criteria->add(CcWebstreamPeer::LPTIME, $this->lptime); if ($this->isColumnModified(CcWebstreamPeer::MIME)) $criteria->add(CcWebstreamPeer::MIME, $this->mime); return $criteria; @@ -1101,6 +1199,7 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent $copyObj->setDbCreatorId($this->creator_id); $copyObj->setDbMtime($this->mtime); $copyObj->setDbUtime($this->utime); + $copyObj->setDbLPtime($this->lptime); $copyObj->setDbMime($this->mime); if ($deepCopy) { @@ -1331,6 +1430,7 @@ abstract class BaseCcWebstream extends BaseObject implements Persistent $this->creator_id = null; $this->mtime = null; $this->utime = null; + $this->lptime = null; $this->mime = null; $this->alreadyInSave = false; $this->alreadyInValidation = false; diff --git a/airtime_mvc/application/models/airtime/om/BaseCcWebstreamPeer.php b/airtime_mvc/application/models/airtime/om/BaseCcWebstreamPeer.php index 4ec74befd..c1b2f7221 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcWebstreamPeer.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcWebstreamPeer.php @@ -26,7 +26,7 @@ abstract class BaseCcWebstreamPeer { const TM_CLASS = 'CcWebstreamTableMap'; /** The total number of columns. */ - const NUM_COLUMNS = 9; + const NUM_COLUMNS = 10; /** The number of lazy-loaded columns. */ const NUM_LAZY_LOAD_COLUMNS = 0; @@ -55,6 +55,9 @@ abstract class BaseCcWebstreamPeer { /** the column name for the UTIME field */ const UTIME = 'cc_webstream.UTIME'; + /** the column name for the LPTIME field */ + const LPTIME = 'cc_webstream.LPTIME'; + /** the column name for the MIME field */ const MIME = 'cc_webstream.MIME'; @@ -74,12 +77,12 @@ abstract class BaseCcWebstreamPeer { * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ private static $fieldNames = array ( - BasePeer::TYPE_PHPNAME => array ('DbId', 'DbName', 'DbDescription', 'DbUrl', 'DbLength', 'DbCreatorId', 'DbMtime', 'DbUtime', 'DbMime', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbName', 'dbDescription', 'dbUrl', 'dbLength', 'dbCreatorId', 'dbMtime', 'dbUtime', 'dbMime', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::NAME, self::DESCRIPTION, self::URL, self::LENGTH, self::CREATOR_ID, self::MTIME, self::UTIME, self::MIME, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'NAME', 'DESCRIPTION', 'URL', 'LENGTH', 'CREATOR_ID', 'MTIME', 'UTIME', 'MIME', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'name', 'description', 'url', 'length', 'creator_id', 'mtime', 'utime', 'mime', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) + BasePeer::TYPE_PHPNAME => array ('DbId', 'DbName', 'DbDescription', 'DbUrl', 'DbLength', 'DbCreatorId', 'DbMtime', 'DbUtime', 'DbLPtime', 'DbMime', ), + BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbName', 'dbDescription', 'dbUrl', 'dbLength', 'dbCreatorId', 'dbMtime', 'dbUtime', 'dbLPtime', 'dbMime', ), + BasePeer::TYPE_COLNAME => array (self::ID, self::NAME, self::DESCRIPTION, self::URL, self::LENGTH, self::CREATOR_ID, self::MTIME, self::UTIME, self::LPTIME, self::MIME, ), + BasePeer::TYPE_RAW_COLNAME => array ('ID', 'NAME', 'DESCRIPTION', 'URL', 'LENGTH', 'CREATOR_ID', 'MTIME', 'UTIME', 'LPTIME', 'MIME', ), + BasePeer::TYPE_FIELDNAME => array ('id', 'name', 'description', 'url', 'length', 'creator_id', 'mtime', 'utime', 'lptime', 'mime', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) ); /** @@ -89,12 +92,12 @@ abstract class BaseCcWebstreamPeer { * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 */ private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbName' => 1, 'DbDescription' => 2, 'DbUrl' => 3, 'DbLength' => 4, 'DbCreatorId' => 5, 'DbMtime' => 6, 'DbUtime' => 7, 'DbMime' => 8, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbName' => 1, 'dbDescription' => 2, 'dbUrl' => 3, 'dbLength' => 4, 'dbCreatorId' => 5, 'dbMtime' => 6, 'dbUtime' => 7, 'dbMime' => 8, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::NAME => 1, self::DESCRIPTION => 2, self::URL => 3, self::LENGTH => 4, self::CREATOR_ID => 5, self::MTIME => 6, self::UTIME => 7, self::MIME => 8, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'NAME' => 1, 'DESCRIPTION' => 2, 'URL' => 3, 'LENGTH' => 4, 'CREATOR_ID' => 5, 'MTIME' => 6, 'UTIME' => 7, 'MIME' => 8, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'name' => 1, 'description' => 2, 'url' => 3, 'length' => 4, 'creator_id' => 5, 'mtime' => 6, 'utime' => 7, 'mime' => 8, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) + BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbName' => 1, 'DbDescription' => 2, 'DbUrl' => 3, 'DbLength' => 4, 'DbCreatorId' => 5, 'DbMtime' => 6, 'DbUtime' => 7, 'DbLPtime' => 8, 'DbMime' => 9, ), + BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbName' => 1, 'dbDescription' => 2, 'dbUrl' => 3, 'dbLength' => 4, 'dbCreatorId' => 5, 'dbMtime' => 6, 'dbUtime' => 7, 'dbLPtime' => 8, 'dbMime' => 9, ), + BasePeer::TYPE_COLNAME => array (self::ID => 0, self::NAME => 1, self::DESCRIPTION => 2, self::URL => 3, self::LENGTH => 4, self::CREATOR_ID => 5, self::MTIME => 6, self::UTIME => 7, self::LPTIME => 8, self::MIME => 9, ), + BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'NAME' => 1, 'DESCRIPTION' => 2, 'URL' => 3, 'LENGTH' => 4, 'CREATOR_ID' => 5, 'MTIME' => 6, 'UTIME' => 7, 'LPTIME' => 8, 'MIME' => 9, ), + BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'name' => 1, 'description' => 2, 'url' => 3, 'length' => 4, 'creator_id' => 5, 'mtime' => 6, 'utime' => 7, 'lptime' => 8, 'mime' => 9, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) ); /** @@ -174,6 +177,7 @@ abstract class BaseCcWebstreamPeer { $criteria->addSelectColumn(CcWebstreamPeer::CREATOR_ID); $criteria->addSelectColumn(CcWebstreamPeer::MTIME); $criteria->addSelectColumn(CcWebstreamPeer::UTIME); + $criteria->addSelectColumn(CcWebstreamPeer::LPTIME); $criteria->addSelectColumn(CcWebstreamPeer::MIME); } else { $criteria->addSelectColumn($alias . '.ID'); @@ -184,6 +188,7 @@ abstract class BaseCcWebstreamPeer { $criteria->addSelectColumn($alias . '.CREATOR_ID'); $criteria->addSelectColumn($alias . '.MTIME'); $criteria->addSelectColumn($alias . '.UTIME'); + $criteria->addSelectColumn($alias . '.LPTIME'); $criteria->addSelectColumn($alias . '.MIME'); } } diff --git a/airtime_mvc/application/models/airtime/om/BaseCcWebstreamQuery.php b/airtime_mvc/application/models/airtime/om/BaseCcWebstreamQuery.php index 101bbfbd1..6f5becfb6 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcWebstreamQuery.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcWebstreamQuery.php @@ -14,6 +14,7 @@ * @method CcWebstreamQuery orderByDbCreatorId($order = Criteria::ASC) Order by the creator_id column * @method CcWebstreamQuery orderByDbMtime($order = Criteria::ASC) Order by the mtime column * @method CcWebstreamQuery orderByDbUtime($order = Criteria::ASC) Order by the utime column + * @method CcWebstreamQuery orderByDbLPtime($order = Criteria::ASC) Order by the lptime column * @method CcWebstreamQuery orderByDbMime($order = Criteria::ASC) Order by the mime column * * @method CcWebstreamQuery groupByDbId() Group by the id column @@ -24,6 +25,7 @@ * @method CcWebstreamQuery groupByDbCreatorId() Group by the creator_id column * @method CcWebstreamQuery groupByDbMtime() Group by the mtime column * @method CcWebstreamQuery groupByDbUtime() Group by the utime column + * @method CcWebstreamQuery groupByDbLPtime() Group by the lptime column * @method CcWebstreamQuery groupByDbMime() Group by the mime column * * @method CcWebstreamQuery leftJoin($relation) Adds a LEFT JOIN clause to the query @@ -45,6 +47,7 @@ * @method CcWebstream findOneByDbCreatorId(int $creator_id) Return the first CcWebstream filtered by the creator_id column * @method CcWebstream findOneByDbMtime(string $mtime) Return the first CcWebstream filtered by the mtime column * @method CcWebstream findOneByDbUtime(string $utime) Return the first CcWebstream filtered by the utime column + * @method CcWebstream findOneByDbLPtime(string $lptime) Return the first CcWebstream filtered by the lptime column * @method CcWebstream findOneByDbMime(string $mime) Return the first CcWebstream filtered by the mime column * * @method array findByDbId(int $id) Return CcWebstream objects filtered by the id column @@ -55,6 +58,7 @@ * @method array findByDbCreatorId(int $creator_id) Return CcWebstream objects filtered by the creator_id column * @method array findByDbMtime(string $mtime) Return CcWebstream objects filtered by the mtime column * @method array findByDbUtime(string $utime) Return CcWebstream objects filtered by the utime column + * @method array findByDbLPtime(string $lptime) Return CcWebstream objects filtered by the lptime column * @method array findByDbMime(string $mime) Return CcWebstream objects filtered by the mime column * * @package propel.generator.airtime.om @@ -363,6 +367,37 @@ abstract class BaseCcWebstreamQuery extends ModelCriteria return $this->addUsingAlias(CcWebstreamPeer::UTIME, $dbUtime, $comparison); } + /** + * Filter the query on the lptime column + * + * @param string|array $dbLPtime The value to use as filter. + * Accepts an associative array('min' => $minValue, 'max' => $maxValue) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return CcWebstreamQuery The current query, for fluid interface + */ + public function filterByDbLPtime($dbLPtime = null, $comparison = null) + { + if (is_array($dbLPtime)) { + $useMinMax = false; + if (isset($dbLPtime['min'])) { + $this->addUsingAlias(CcWebstreamPeer::LPTIME, $dbLPtime['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($dbLPtime['max'])) { + $this->addUsingAlias(CcWebstreamPeer::LPTIME, $dbLPtime['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + return $this->addUsingAlias(CcWebstreamPeer::LPTIME, $dbLPtime, $comparison); + } + /** * Filter the query on the mime column * diff --git a/airtime_mvc/build/schema.xml b/airtime_mvc/build/schema.xml index b9899cca8..d56927199 100644 --- a/airtime_mvc/build/schema.xml +++ b/airtime_mvc/build/schema.xml @@ -425,6 +425,7 @@ + diff --git a/airtime_mvc/build/sql/schema.sql b/airtime_mvc/build/sql/schema.sql index cc47701c6..332715b22 100644 --- a/airtime_mvc/build/sql/schema.sql +++ b/airtime_mvc/build/sql/schema.sql @@ -638,6 +638,7 @@ CREATE TABLE "cc_webstream" "creator_id" INTEGER NOT NULL, "mtime" TIMESTAMP(6) NOT NULL, "utime" TIMESTAMP(6) NOT NULL, + "lptime" TIMESTAMP(6), "mime" VARCHAR(255), PRIMARY KEY ("id") ); diff --git a/airtime_mvc/public/index.php b/airtime_mvc/public/index.php index 78f94c489..fba26a71a 100644 --- a/airtime_mvc/public/index.php +++ b/airtime_mvc/public/index.php @@ -1,8 +1,12 @@ bootstrap()->run(); } } catch (Exception $e) { + echo $e->getMessage(); Logging::info($e->getMessage()); } diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index 8024b827c..78efad4ed 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -400,7 +400,8 @@ var AIRTIME = (function(AIRTIME) { /* Year */ { "sTitle" : "Year" , "mDataProp" : "year" , "bVisible" : false , "sClass" : "library_year" , "sWidth" : "60px" } , /* Length */ { "sTitle" : "Length" , "mDataProp" : "length" , "sClass" : "library_length" , "sWidth" : "80px" } , /* Upload Time */ { "sTitle" : "Uploaded" , "mDataProp" : "utime" , "sClass" : "library_upload_time" , "sWidth" : "125px" } , - /* Last Modified */ { "sTitle" : "Last Modified" , "mDataProp" : "mtime" , "bVisible" : false , "sClass" : "library_modified_time" , "sWidth" : "125px" } , + /* Last Modified */ { "sTitle" : "Last Modified" , "mDataProp" : "mtime" , "bVisible" : false , "sClass" : "library_modified_time" , "sWidth" : "125px" } , + /* Last Played */ { "sTitle" : "Last Played " , "mDataProp" : "lptime" , "bVisible" : false , "sClass" : "library_modified_time" , "sWidth" : "125px" } , /* Track Number */ { "sTitle" : "Track" , "mDataProp" : "track_number" , "bVisible" : false , "sClass" : "library_track" , "sWidth" : "65px" } , /* Mood */ { "sTitle" : "Mood" , "mDataProp" : "mood" , "bVisible" : false , "sClass" : "library_mood" , "sWidth" : "70px" } , /* BPM */ { "sTitle" : "BPM" , "mDataProp" : "bpm" , "bVisible" : false , "sClass" : "library_bpm" , "sWidth" : "50px" } , @@ -1051,8 +1052,8 @@ function validateAdvancedSearch(divs) { } function addRemoveValidationIcons(valid, field) { - var validIndicator = "", - invalidIndicator = ""; + var validIndicator = "", + invalidIndicator = ""; if (valid) { if (!field.closest('div').children(':last-child').hasClass('checked-icon')) { diff --git a/airtime_mvc/public/js/airtime/library/spl.js b/airtime_mvc/public/js/airtime/library/spl.js index 907078e18..357bf87be 100644 --- a/airtime_mvc/public/js/airtime/library/spl.js +++ b/airtime_mvc/public/js/airtime/library/spl.js @@ -635,7 +635,9 @@ var AIRTIME = (function(AIRTIME){ if (json.error !== undefined) { alert(json.error); } - AIRTIME.playlist.fnOpenPlaylist(json); + if (json.html !== undefined) { + AIRTIME.playlist.fnOpenPlaylist(json); + } setModified(json.modified); if (obj_type == "block") { callback(data, "save"); diff --git a/airtime_mvc/public/js/datatables/plugin/dataTables.columnFilter_orig.js b/airtime_mvc/public/js/datatables/plugin/dataTables.columnFilter_orig.js new file mode 100644 index 000000000..13339de88 --- /dev/null +++ b/airtime_mvc/public/js/datatables/plugin/dataTables.columnFilter_orig.js @@ -0,0 +1,733 @@ +/* +* File: jquery.dataTables.columnFilter.js +* Version: 1.4.8. +* Author: Jovan Popovic +* +* Copyright 2011-2012 Jovan Popovic, all rights reserved. +* +* This source file is free software, under either the GPL v2 license or a +* BSD style license, as supplied with this software. +* +* This source file 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. +* +* Parameters:" +* @sPlaceHolder String Place where inline filtering function should be placed ("tfoot", "thead:before", "thead:after"). Default is "tfoot" +* @sRangeSeparator String Separator that will be used when range values are sent to the server-side. Default value is "~". +* @sRangeFormat string Default format of the From ... to ... range inputs. Default is From {from} to {to} +* @aoColumns Array Array of the filter settings that will be applied on the columns +*/ +(function ($) { + + + $.fn.columnFilter = function (options) { + + var asInitVals, i, label, th; + + //var sTableId = "table"; + var sRangeFormat = "From {from} to {to}"; + //Array of the functions that will override sSearch_ parameters + var afnSearch_ = new Array(); + var aiCustomSearch_Indexes = new Array(); + + var oFunctionTimeout = null; + + var fnOnFiltered = function () { }; + + function _fnGetColumnValues(oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty) { + /// + ///Return values in the column + /// + ///DataTables settings + ///Id of the column + ///Return only distinct values + ///Return values only from the filtered rows + ///Ignore empty cells + + // check that we have a column id + if (typeof iColumn == "undefined") return new Array(); + + // by default we only wany unique data + if (typeof bUnique == "undefined") bUnique = true; + + // by default we do want to only look at filtered data + if (typeof bFiltered == "undefined") bFiltered = true; + + // by default we do not wany to include empty values + if (typeof bIgnoreEmpty == "undefined") bIgnoreEmpty = true; + + // list of rows which we're going to loop through + var aiRows; + + // use only filtered rows + if (bFiltered == true) aiRows = oSettings.aiDisplay; + // use all rows + else aiRows = oSettings.aiDisplayMaster; // all row numbers + + // set up data array + var asResultData = new Array(); + + for (var i = 0, c = aiRows.length; i < c; i++) { + iRow = aiRows[i]; + var aData = oTable.fnGetData(iRow); + var sValue = aData[iColumn]; + + // ignore empty values? + if (bIgnoreEmpty == true && sValue.length == 0) continue; + + // ignore unique values? + else if (bUnique == true && jQuery.inArray(sValue, asResultData) > -1) continue; + + // else push the value onto the result data array + else asResultData.push(sValue); + } + + return asResultData.sort(); + } + + function _fnColumnIndex(iColumnIndex) { + if (properties.bUseColVis) + return iColumnIndex; + else + return oTable.fnSettings().oApi._fnVisibleToColumnIndex(oTable.fnSettings(), iColumnIndex); + //return iColumnIndex; + //return oTable.fnSettings().oApi._fnColumnIndexToVisible(oTable.fnSettings(), iColumnIndex); + } + + function fnCreateInput(oTable, regex, smart, bIsNumber, iFilterLength, iMaxLenght) { + var sCSSClass = "text_filter"; + if (bIsNumber) + sCSSClass = "number_filter"; + + label = label.replace(/(^\s*)|(\s*$)/g, ""); + var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch; + var search_init = 'search_init '; + var inputvalue = label; + if (currentFilter != '' && currentFilter != '^') { + if (bIsNumber && currentFilter.charAt(0) == '^') + inputvalue = currentFilter.substr(1); //ignore trailing ^ + else + inputvalue = currentFilter; + search_init = ''; + } + + var input = $(''); + if (iMaxLenght != undefined && iMaxLenght != -1) { + input.attr('maxlength', iMaxLenght); + } + th.html(input); + if (bIsNumber) + th.wrapInner(''); + else + th.wrapInner(''); + + asInitVals[i] = label; + var index = i; + + if (bIsNumber && !oTable.fnSettings().oFeatures.bServerSide) { + input.keyup(function () { + /* Filter on the column all numbers that starts with the entered value */ + oTable.fnFilter('^' + this.value, _fnColumnIndex(index), true, false); //Issue 37 + fnOnFiltered(); + }); + } else { + input.keyup(function () { + if (oTable.fnSettings().oFeatures.bServerSide && iFilterLength != 0) { + //If filter length is set in the server-side processing mode + //Check has the user entered at least iFilterLength new characters + + var currentFilter = oTable.fnSettings().aoPreSearchCols[index].sSearch; + var iLastFilterLength = $(this).data("dt-iLastFilterLength"); + if (typeof iLastFilterLength == "undefined") + iLastFilterLength = 0; + var iCurrentFilterLength = this.value.length; + if (Math.abs(iCurrentFilterLength - iLastFilterLength) < iFilterLength + //&& currentFilter.length == 0 //Why this? + ) { + //Cancel the filtering + return; + } + else { + //Remember the current filter length + $(this).data("dt-iLastFilterLength", iCurrentFilterLength); + } + } + /* Filter on the column (the index) of this element */ + oTable.fnFilter(this.value, _fnColumnIndex(index), regex, smart); //Issue 37 + fnOnFiltered(); + }); + } + + input.focus(function () { + if ($(this).hasClass("search_init")) { + $(this).removeClass("search_init"); + this.value = ""; + } + }); + input.blur(function () { + if (this.value == "") { + $(this).addClass("search_init"); + this.value = asInitVals[index]; + } + }); + } + + function fnCreateRangeInput(oTable) { + + //var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch; + th.html(_fnRangeLabelPart(0)); + var sFromId = oTable.attr("id") + '_range_from_' + i; + var from = $(''); + th.append(from); + th.append(_fnRangeLabelPart(1)); + var sToId = oTable.attr("id") + '_range_to_' + i; + var to = $(''); + th.append(to); + th.append(_fnRangeLabelPart(2)); + th.wrapInner(''); + var index = i; + aiCustomSearch_Indexes.push(i); + + + + //------------start range filtering function + + + /* Custom filtering function which will filter data in column four between two values + * Author: Allan Jardine, Modified by Jovan Popovic + */ + //$.fn.dataTableExt.afnFiltering.push( + oTable.dataTableExt.afnFiltering.push( + function (oSettings, aData, iDataIndex) { + if (oTable.attr("id") != oSettings.sTableId) + return true; + // Try to handle missing nodes more gracefully + if (document.getElementById(sFromId) == null) + return true; + var iMin = document.getElementById(sFromId).value * 1; + var iMax = document.getElementById(sToId).value * 1; + var iValue = aData[_fnColumnIndex(index)] == "-" ? 0 : aData[_fnColumnIndex(index)] * 1; + if (iMin == "" && iMax == "") { + return true; + } + else if (iMin == "" && iValue <= iMax) { + return true; + } + else if (iMin <= iValue && "" == iMax) { + return true; + } + else if (iMin <= iValue && iValue <= iMax) { + return true; + } + return false; + } + ); + //------------end range filtering function + + + + $('#' + sFromId + ',#' + sToId, th).keyup(function () { + + var iMin = document.getElementById(sFromId).value * 1; + var iMax = document.getElementById(sToId).value * 1; + if (iMin != 0 && iMax != 0 && iMin > iMax) + return; + + oTable.fnDraw(); + fnOnFiltered(); + }); + + + } + + + function fnCreateDateRangeInput(oTable) { + th.html(_fnRangeLabelPart(0)); + var sFromId = oTable.attr("id") + '_range_from_' + i; + var from = $(''); + from.datepicker(); + th.append(from); + th.append(_fnRangeLabelPart(1)); + var sToId = oTable.attr("id") + '_range_to_' + i; + var to = $(''); + th.append(to); + th.append(_fnRangeLabelPart(2)); + th.wrapInner(''); + to.datepicker(); + var index = i; + aiCustomSearch_Indexes.push(i); + + + //------------start date range filtering function + + //$.fn.dataTableExt.afnFiltering.push( + oTable.dataTableExt.afnFiltering.push( + function (oSettings, aData, iDataIndex) { + if (oTable.attr("id") != oSettings.sTableId) + return true; + + var dStartDate = from.datepicker("getDate"); + + var dEndDate = to.datepicker("getDate"); + + if (dStartDate == null && dEndDate == null) { + return true; + } + + var dCellDate = null; + try { + if (aData[_fnColumnIndex(index)] == null || aData[_fnColumnIndex(index)] == "") + return false; + dCellDate = $.datepicker.parseDate($.datepicker.regional[""].dateFormat, aData[_fnColumnIndex(index)]); + } catch (ex) { + return false; + } + if (dCellDate == null) + return false; + + + if (dStartDate == null && dCellDate <= dEndDate) { + return true; + } + else if (dStartDate <= dCellDate && dEndDate == null) { + return true; + } + else if (dStartDate <= dCellDate && dCellDate <= dEndDate) { + return true; + } + return false; + } + ); + //------------end date range filtering function + + $('#' + sFromId + ',#' + sToId, th).change(function () { + oTable.fnDraw(); + fnOnFiltered(); + }); + + + } + + function fnCreateColumnSelect(oTable, aData, iColumn, nTh, sLabel, bRegex) { + if (aData == null) + aData = _fnGetColumnValues(oTable.fnSettings(), iColumn, true, false, true); + var index = iColumn; + var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch; + + var r = ''); + nTh.html(select); + nTh.wrapInner(''); + select.change(function () { + //var val = $(this).val(); + if ($(this).val() != "") { + $(this).removeClass("search_init"); + } else { + $(this).addClass("search_init"); + } + if (bRegex) + oTable.fnFilter($(this).val(), iColumn, bRegex); //Issue 41 + else + oTable.fnFilter(unescape($(this).val()), iColumn); //Issue 25 + fnOnFiltered(); + }); + } + + function fnCreateSelect(oTable, aData, bRegex) { + var oSettings = oTable.fnSettings(); + if (aData == null && oSettings.sAjaxSource != "" && !oSettings.oFeatures.bServerSide) { + // Add a function to the draw callback, which will check for the Ajax data having + // been loaded. Use a closure for the individual column elements that are used to + // built the column filter, since 'i' and 'th' (etc) are locally "global". + oSettings.aoDrawCallback.push({ + "fn": (function (iColumn, nTh, sLabel) { + return function () { + // Only rebuild the select on the second draw - i.e. when the Ajax + // data has been loaded. + if (oSettings.iDraw == 2 && oSettings.sAjaxSource != null && oSettings.sAjaxSource != "" && !oSettings.oFeatures.bServerSide) { + return fnCreateColumnSelect(oTable, null, _fnColumnIndex(iColumn), nTh, sLabel, bRegex); //Issue 37 + } + }; + })(i, th, label), + "sName": "column_filter_" + i + }); + } + // Regardless of the Ajax state, build the select on first pass + fnCreateColumnSelect(oTable, aData, _fnColumnIndex(i), th, label, bRegex); //Issue 37 + + } + + function fnCreateCheckbox(oTable, aData) { + + if (aData == null) + aData = _fnGetColumnValues(oTable.fnSettings(), i, true, true, true); + var index = i; + + var r = '', j, iLen = aData.length; + + //clean the string + var localLabel = label.replace('%', 'Perc').replace("&", "AND").replace("$", "DOL").replace("£", "STERL").replace("@", "AT").replace(/\s/g, "_"); + localLabel = localLabel.replace(/[^a-zA-Z 0-9]+/g, ''); + //clean the string + + //button label override + if (properties.sFilterButtonText != null || properties.sFilterButtonText != undefined) { + labelBtn = properties.sFilterButtonText; + } else { + labelBtn = label; + } + + var relativeDivWidthToggleSize = 10; + var numRow = 12; //numero di checkbox per colonna + var numCol = Math.floor(iLen / numRow); + if (iLen % numRow > 0) { + numCol = numCol + 1; + }; + + //count how many column should be generated and split the div size + var divWidth = 100 / numCol - 2; + + var divWidthToggle = relativeDivWidthToggleSize * numCol; + + if (numCol == 1) { + divWidth = 20; + } + + var divRowDef = '
'; + var divClose = '
'; + + var uniqueId = oTable.attr("id") + localLabel; + var buttonId = "chkBtnOpen" + uniqueId; + var checkToggleDiv = uniqueId + "-flt-toggle"; + r += ''; //filter button witch open dialog + r += '
'; //dialog div + //r+= '
'; //reset button and its div + r += divRowDef; + + for (j = 0; j < iLen; j++) { + + //if last check close div + if (j % numRow == 0 && j != 0) { + r += divClose + divRowDef; + } + + //check button + r += '' + aData[j] + '
'; + + var checkbox = $(r); + th.html(checkbox); + th.wrapInner(''); + //on every checkbox selection + checkbox.change(function () { + + var search = ''; + var or = '|'; //var for select checks in 'or' into the regex + var resSize = $('input:checkbox[name="' + localLabel + '"]:checked').size(); + $('input:checkbox[name="' + localLabel + '"]:checked').each(function (index) { + + //search = search + ' ' + $(this).val(); + //concatenation for selected checks in or + if ((index == 0 && resSize == 1) + || (index != 0 && index == resSize - 1)) { + or = ''; + } + //trim + search = search.replace(/^\s+|\s+$/g, ""); + search = search + $(this).val() + or; + or = '|'; + + }); + + for (var jj = 0; jj < iLen; jj++) { + if (search != "") { + $('#' + aData[jj]).removeClass("search_init"); + } else { + $('#' + aData[jj]).addClass("search_init"); + } + } + + //execute search + oTable.fnFilter(search, index, true, false); + fnOnFiltered(); + }); + } + + //filter button + $('#' + buttonId).button(); + //dialog + $('#' + checkToggleDiv).dialog({ + //height: 140, + autoOpen: false, + //show: "blind", + hide: "blind", + buttons: [{ + text: "Reset", + click: function () { + //$('#'+buttonId).removeClass("filter_selected"); //LM remove border if filter selected + $('input:checkbox[name="' + localLabel + '"]:checked').each(function (index3) { + $(this).attr('checked', false); + $(this).addClass("search_init"); + }); + oTable.fnFilter('', index, true, false); + fnOnFiltered(); + return false; + } + }, + { + text: "Close", + click: function () { $(this).dialog("close"); } + } + ] + }); + + + $('#' + buttonId).click(function () { + + $('#' + checkToggleDiv).dialog('open'); + var target = $(this); + $('#' + checkToggleDiv).dialog("widget").position({ my: 'top', + at: 'bottom', + of: target + }); + + return false; + }); + + var fnOnFilteredCurrent = fnOnFiltered; + + fnOnFiltered = function () { + var target = $('#' + buttonId); + $('#' + checkToggleDiv).dialog("widget").position({ my: 'top', + at: 'bottom', + of: target + }); + fnOnFilteredCurrent(); + }; + //reset + /* + $('#'+buttonId+"Reset").button(); + $('#'+buttonId+"Reset").click(function(){ + $('#'+buttonId).removeClass("filter_selected"); //LM remove border if filter selected + $('input:checkbox[name="'+localLabel+'"]:checked').each(function(index3) { + $(this).attr('checked', false); + $(this).addClass("search_init"); + }); + oTable.fnFilter('', index, true, false); + return false; + }); + */ + } + + + + + function _fnRangeLabelPart(iPlace) { + switch (iPlace) { + case 0: + return sRangeFormat.substring(0, sRangeFormat.indexOf("{from}")); + case 1: + return sRangeFormat.substring(sRangeFormat.indexOf("{from}") + 6, sRangeFormat.indexOf("{to}")); + default: + return sRangeFormat.substring(sRangeFormat.indexOf("{to}") + 4); + } + } + + + + + oTable = this; + + var defaults = { + sPlaceHolder: "foot", + sRangeSeparator: "~", + iFilteringDelay: 500, + aoColumns: null, + sRangeFormat: "From {from} to {to}" + }; + + properties = $.extend(defaults, options); + + return this.each(function () { + + if (!oTable.fnSettings().oFeatures.bFilter) + return; + asInitVals = new Array(); + + aoFilterCells = oTable.fnSettings().aoFooter[0]; + + var oHost = oTable.fnSettings().nTFoot; //Before fix for ColVis + var sFilterRow = "tr"; //Before fix for ColVis + + if (properties.sPlaceHolder == "head:after") { + var tr = $("tr:first", oTable.fnSettings().nTHead).detach(); + //tr.appendTo($(oTable.fnSettings().nTHead)); + if (oTable.fnSettings().bSortCellsTop) { + tr.prependTo($(oTable.fnSettings().nTHead)); + //tr.appendTo($("thead", oTable)); + aoFilterCells = oTable.fnSettings().aoHeader[1]; + } + else { + tr.appendTo($(oTable.fnSettings().nTHead)); + //tr.prependTo($("thead", oTable)); + aoFilterCells = oTable.fnSettings().aoHeader[0]; + } + + sFilterRow = "tr:last"; + oHost = oTable.fnSettings().nTHead; + + } else if (properties.sPlaceHolder == "head:before") { + + if (oTable.fnSettings().bSortCellsTop) { + var tr = $("tr:first", oTable.fnSettings().nTHead).detach(); + tr.appendTo($(oTable.fnSettings().nTHead)); + aoFilterCells = oTable.fnSettings().aoHeader[1]; + } else { + aoFilterCells = oTable.fnSettings().aoHeader[0]; + } + /*else { + //tr.prependTo($("thead", oTable)); + sFilterRow = "tr:first"; + }*/ + + sFilterRow = "tr:first"; + + oHost = oTable.fnSettings().nTHead; + + + } + + //$(sFilterRow + " th", oHost).each(function (index) {//bug with ColVis + $(aoFilterCells).each(function (index) {//fix for ColVis + i = index; + var aoColumn = { type: "text", + bRegex: false, + bSmart: true, + iMaxLenght: -1, + iFilterLength: 0 + }; + if (properties.aoColumns != null) { + if (properties.aoColumns.length < i || properties.aoColumns[i] == null) + return; + aoColumn = properties.aoColumns[i]; + } + //label = $(this).text(); //Before fix for ColVis + label = $($(this)[0].cell).text(); //Fix for ColVis + if (aoColumn.sSelector == null) { + //th = $($(this)[0]);//Before fix for ColVis + th = $($(this)[0].cell); //Fix for ColVis + } + else { + th = $(aoColumn.sSelector); + if (th.length == 0) + th = $($(this)[0].cell); + } + + if (aoColumn != null) { + if (aoColumn.sRangeFormat != null) + sRangeFormat = aoColumn.sRangeFormat; + else + sRangeFormat = properties.sRangeFormat; + switch (aoColumn.type) { + case "null": + break; + case "number": + fnCreateInput(oTable, true, false, true, aoColumn.iFilterLength, aoColumn.iMaxLenght); + break; + case "select": + if (aoColumn.bRegex != true) + aoColumn.bRegex = false; + fnCreateSelect(oTable, aoColumn.values, aoColumn.bRegex); + break; + case "number-range": + fnCreateRangeInput(oTable); + break; + case "date-range": + fnCreateDateRangeInput(oTable); + break; + case "checkbox": + fnCreateCheckbox(oTable, aoColumn.values); + break; + case "text": + default: + bRegex = (aoColumn.bRegex == null ? false : aoColumn.bRegex); + bSmart = (aoColumn.bSmart == null ? false : aoColumn.bSmart); + fnCreateInput(oTable, bRegex, bSmart, false, aoColumn.iFilterLength, aoColumn.iMaxLenght); + break; + + } + } + }); + + for (j = 0; j < aiCustomSearch_Indexes.length; j++) { + //var index = aiCustomSearch_Indexes[j]; + var fnSearch_ = function () { + var id = oTable.attr("id"); + return $("#" + id + "_range_from_" + aiCustomSearch_Indexes[j]).val() + properties.sRangeSeparator + $("#" + id + "_range_to_" + aiCustomSearch_Indexes[j]).val() + } + afnSearch_.push(fnSearch_); + } + + if (oTable.fnSettings().oFeatures.bServerSide) { + + var fnServerDataOriginal = oTable.fnSettings().fnServerData; + + oTable.fnSettings().fnServerData = function (sSource, aoData, fnCallback) { + + for (j = 0; j < aiCustomSearch_Indexes.length; j++) { + var index = aiCustomSearch_Indexes[j]; + + for (k = 0; k < aoData.length; k++) { + if (aoData[k].name == "sSearch_" + index) + aoData[k].value = afnSearch_[j](); + } + } + aoData.push({ "name": "sRangeSeparator", "value": properties.sRangeSeparator }); + + if (fnServerDataOriginal != null) { + try { + fnServerDataOriginal(sSource, aoData, fnCallback, oTable.fnSettings()); //TODO: See Issue 18 + } catch (ex) { + fnServerDataOriginal(sSource, aoData, fnCallback); + } + } + else { + $.getJSON(sSource, aoData, function (json) { + fnCallback(json) + }); + } + }; + + } + + }); + + }; + + + + +})(jQuery); \ No newline at end of file