diff --git a/airtime_mvc/application/forms/SmartBlockCriteria.php b/airtime_mvc/application/forms/SmartBlockCriteria.php index f635dab18..07605bd91 100644 --- a/airtime_mvc/application/forms/SmartBlockCriteria.php +++ b/airtime_mvc/application/forms/SmartBlockCriteria.php @@ -93,6 +93,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm "items" => "items" ); + $modRows = array(); + // load type $out = CcBlockQuery::create()->findPk($p_blockId); if ($out->getDbType() == "static") { @@ -113,10 +115,21 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm $this->addElement($spType); // load criteria from db - $out = CcBlockcriteriaQuery::create()->findByDbBlockId($p_blockId); - + $out = CcBlockcriteriaQuery::create()->orderByDbCriteria()->findByDbBlockId($p_blockId); $storedCrit = array(); + + /* Store the previous criteria value + * We will use this to check if the current row has the same + * critieria value. If so, we know that this is a modifier row + + $tempCrit = ''; + $modrows = array(); + $critRowNum = 0; + $modRowNum = 0; + $j = 0; + */ foreach ($out as $crit) { + //$tempCrit = $crit->getDbCriteria(); $criteria = $crit->getDbCriteria(); $modifier = $crit->getDbModifier(); $value = $crit->getDbValue(); @@ -127,7 +140,19 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm }else{ $storedCrit["crit"][] = array("criteria"=>$criteria, "value"=>$value, "modifier"=>$modifier, "extra"=>$extra); } + /* + //check if row is a modifier row + if ($critRowNum > 0 && strcmp($tempCrit, $storedCrit["crit"][$critRowNum-1]["criteria"])==0) { + $modrows[$j][$] = $modRowNum; + $modRowNum++; + } else if ($critRowNum > 0) { + $modRowNum = 0; + $j++; + } + $critRowNum++; + */ } + //Logging::log($modrows); $openSmartBlockOption = false; if (!empty($storedCrit)) { @@ -192,6 +217,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm $criteriaExtra->setAttrib('disabled', 'disabled'); } $this->addElement($criteriaExtra); + } $limit = new Zend_Form_Element_Select('sp_limit_options'); @@ -239,10 +265,11 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm $shuffle->setLabel('Shuffle'); $shuffle->setDecorators(array('viewHelper')); $this->addElement($shuffle); - + $this->setDecorators(array( array('ViewScript', array('viewScript' => 'form/smart-block-criteria.phtml', "openOption"=> $openSmartBlockOption, - 'criteriasLength' => count($criteriaOptions), 'poolCount' => $files['count'])) + 'criteriasLength' => count($criteriaOptions), 'poolCount' => $files['count'], 'modRows' => $modRows)) )); } + } diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index 7eea1ab4d..f9d350aef 100644 --- a/airtime_mvc/application/models/Block.php +++ b/airtime_mvc/application/models/Block.php @@ -943,12 +943,68 @@ EOT; if(count($error) > 0){ $errors[] = array("element"=>"sp_criteria_field_".$key, "msg"=>$error); } - } + }// foreach + + $modrowSize = count($data['modrow']); + for ($i = 0; $i < $modrowSize; $i++) { + foreach ($data['modrow'][$i] as $key=>$d){ + $error = array(); + // check for not selected select box + if ($d['sp_criteria_field'] == "0" || $d['sp_criteria_modifier'] == "0"){ + $error[] = "You must select Criteria and Modifier"; + } else { + $column = CcFilesPeer::getTableMap()->getColumnByPhpName(self::$criteria2PeerMap[$d['sp_criteria_field']]); + // validation on type of column + if ($d['sp_criteria_field'] == 'length') { + if (!preg_match("/(\d{2}):(\d{2}):(\d{2})/", $d['sp_criteria_value'])) { + $error[] = "'Length' should be in '00:00:00' format"; + } + } else if ($column->getType() == PropelColumnTypes::TIMESTAMP) { + if (!preg_match("/(\d{4})-(\d{2})-(\d{2})/", $d['sp_criteria_value'])) { + $error[] = "The value should be in timestamp format(eg. 0000-00-00 or 00-00-00 00:00:00"; + } else if (!Application_Common_DateHelper::checkDateTimeRangeForSQL($d['sp_criteria_value'])) { + // check for if it is in valid range( 1753-01-01 ~ 12/31/9999 ) + $error[] = "$d[sp_criteria_value] is not a valid date/time string"; + } + + if (isset($d['sp_criteria_extra'])) { + if (!preg_match("/(\d{4})-(\d{2})-(\d{2})/", $d['sp_criteria_extra'])) { + $error[] = "The value should be in timestamp format(eg. 0000-00-00 or 00-00-00 00:00:00"; + } else if (!Application_Common_DateHelper::checkDateTimeRangeForSQL($d['sp_criteria_extra'])) { + // check for if it is in valid range( 1753-01-01 ~ 12/31/9999 ) + $error[] = "$d[sp_criteria_extra] is not a valid date/time string"; + } + } + } else if ($column->getType() == PropelColumnTypes::INTEGER) { + if (!is_numeric($d['sp_criteria_value'])) { + $error[] = "The value has to be numeric"; + } + // length check + if (intval($d['sp_criteria_value']) >= pow(2,31)) { + $error[] = "The value should be less then 2147483648"; + } + } else if ($column->getType() == PropelColumnTypes::VARCHAR) { + if (strlen($d['sp_criteria_value']) > $column->getSize()) { + $error[] = "The value should be less ".$column->getSize()." characters"; + } + } + } + + if ($d['sp_criteria_value'] == "") { + $error[] = "Value cannot be empty"; + } + if(count($error) > 0){ + $errors[] = array("element"=>"sp_criteria_field_".$key."_".$i, "msg"=>$error); + } + $count++; + }//end mod foreach + }//for loop + $result = count($errors) > 0 ? 1 :0; if ($result == 0) { $this->storeCriteriaIntoDb($data); } - + //get number of files that meet the criteria $files = $this->getListofFilesMeetCriteria(); @@ -970,6 +1026,23 @@ EOT; $qry->setDbExtra($d['sp_criteria_extra']); } $qry->save(); + } + + //insert modifier rows + $modrowSize = count($p_criteriaData['modrow']); + for ($i = 0; $i < $modrowSize; $i++) { + foreach( $p_criteriaData['modrow'][$i] as $d){ + $qry = new CcBlockcriteria(); + $qry->setDbCriteria($d['sp_criteria_field']) + ->setDbModifier($d['sp_criteria_modifier']) + ->setDbValue($d['sp_criteria_value']) + ->setDbBlockId($this->id); + + if (isset($d['sp_criteria_extra'])) { + $qry->setDbExtra($d['sp_criteria_extra']); + } + $qry->save(); + } } // insert limit info @@ -1094,14 +1167,40 @@ EOT; { $fieldNames = array('sp_criteria_field', 'sp_criteria_modifier', 'sp_criteria_value', 'sp_criteria_extra'); $output = array(); - foreach ($p_criteria as $ele) { - $index = strrpos($ele['name'], '_'); - $fieldName = substr($ele['name'], 0, $index); - if (in_array($fieldName, $fieldNames)) { - $rowNum = intval(substr($ele['name'], $index+1)); - $output['criteria'][$rowNum][$fieldName] = trim($ele['value']); - }else{ - $output['etc'][$ele['name']] = $ele['value']; + foreach ($p_criteria as $ele) { + + $index = strrpos($ele['name'], '_'); + + /* Get criteria row index. + * We only need this if there is a modifier row + */ + $tempName = $ele['name']; + preg_match('/^\D*(?=\d)/', $tempName, $r); + $critIndexPos = strlen($r[0]); + $critIndex = $tempName[$critIndexPos]; + + $fieldName = substr($ele['name'], 0, $index); + + /* Determine if this is a modifier row + * We will know if $fieldName's last character is an integer + */ + $modRow = $fieldName[strlen($fieldName)-1]; + if (!preg_match("/^[a-zA-Z]$/", $modRow)) { + $modIndex = strrpos($fieldName, '_'); + $fieldName = substr($fieldName, 0, $modIndex); + if (in_array($fieldName, $fieldNames)) { + $rowNum = intval($tempName[strlen($tempName)-1]); + $output['modrow'][$critIndex][$rowNum][$fieldName] = trim($ele['value']); + }else{ + $output['etc'][$ele['name']] = $ele['value']; + } + } else { + if (in_array($fieldName, $fieldNames)) { + $rowNum = intval(substr($ele['name'], $index+1)); + $output['criteria'][$rowNum][$fieldName] = trim($ele['value']); + }else{ + $output['etc'][$ele['name']] = $ele['value']; + } } } diff --git a/airtime_mvc/application/views/scripts/form/smart-block-criteria.phtml b/airtime_mvc/application/views/scripts/form/smart-block-criteria.phtml index 90a171831..a4dcc746e 100644 --- a/airtime_mvc/application/views/scripts/form/smart-block-criteria.phtml +++ b/airtime_mvc/application/views/scripts/form/smart-block-criteria.phtml @@ -28,8 +28,10 @@
0) && ($this->element->getElement("sp_criteria_field_".$i)->getAttrib('disabled') == 'disabled')) { echo 'style=display:none'; } ?>> - element->getElement("sp_criteria_field_".$i) ?> + + + element->getElement("sp_criteria_modifier_".$i) ?> element->getElement("sp_criteria_value_".$i) ?> element->getElement("sp_criteria_extra_".$i)->getAttrib("disabled") == "disabled"?'style="display:none;"':""?>> to element->getElement('sp_criteria_extra_'.$i) ?> @@ -38,7 +40,21 @@
- + modRows[$i]; $j++) {?> +
+ element->getElement("sp_criteria_field_".$i."_".$j) ?> + + + + element->getElement("sp_criteria_modifier_".$i."_".$j) ?> + element->getElement("sp_criteria_value_".$i."_".$j) ?> + element->getElement("sp_criteria_extra_".$i."_".$j)->getAttrib("disabled") == "disabled"?'style="display:none;"':""?>> to element->getElement('sp_criteria_extra_'.$i."_".$j) ?> + + + +
+
+
diff --git a/airtime_mvc/public/js/airtime/playlist/smart_playlistbuilder.js b/airtime_mvc/public/js/airtime/playlist/smart_playlistbuilder.js index af82f0893..c0b595ed9 100644 --- a/airtime_mvc/public/js/airtime/playlist/smart_playlistbuilder.js +++ b/airtime_mvc/public/js/airtime/playlist/smart_playlistbuilder.js @@ -5,6 +5,7 @@ $(document).ready(function() { function setSmartPlaylistEvents() { var form = $('#smart-playlist-form'); + /********** ADD CRITERIA ROW **********/ form.find('.criteria_add').live('click', function(){ var div = $('dd[id="sp_criteria-element"]').children('div:visible:last').next(); @@ -18,7 +19,55 @@ function setSmartPlaylistEvents() { appendAddButton(); removeButtonCheck(); }); + + /********** ADD MODIFIER ROW **********/ + form.find('a[id^="modifier_add"]').live('click', function(){ + var id = $(this).attr('id'), + row_index = id.charAt(id.length-1), + mod_index, + criteria_value = $(this).siblings('select[name^="sp_criteria_field"]').val(); + + //get index for the new modifier row + if ($(this).parent().find('select[name^="sp_criteria_modifier_'+row_index+'_"]').length == 0) { + mod_index = 0; + } else { + var last_mod = $(this).parent().find('select[name^="sp_criteria_modifier_'+row_index+'_"]:last'); + var last_mod_id = last_mod.attr('id'); + mod_index = parseInt(last_mod_id.substr(last_mod_id.length-1))+1; + } + + //make new modifier row + var newRow = $(this).parent().clone(), + newRowCrit = newRow.find('select[name^="sp_criteria_field"]'), + newRowMod = newRow.find('select[name^="sp_criteria_modifier"]'), + newRowVal = newRow.find('input[name^="sp_criteria_value"]'), + newRowExtra = newRow.find('input[name^="sp_criteria_extra"]'), + newRowRemove = newRow.find('a[id^="criteria_remove"]'); + + //append modifier index to the new modifier row + newRowCrit.attr('name', 'sp_criteria_field_'+row_index+'_'+mod_index); + newRowCrit.attr('id', 'sp_criteria_field_'+row_index+'_'+mod_index); + newRowCrit.val(criteria_value); + newRowMod.attr('name', 'sp_criteria_modifier_'+row_index+'_'+mod_index); + newRowMod.attr('id', 'sp_criteria_modifier_'+row_index+'_'+mod_index); + newRowMod.val('0'); + newRowVal.attr('name', 'sp_criteria_value_'+row_index+'_'+mod_index); + newRowVal.attr('id', 'sp_criteria_value_'+row_index+'_'+mod_index); + newRowVal.val(''); + newRowExtra.attr('name', 'sp_criteria_extra_'+row_index+'_'+mod_index); + newRowExtra.attr('id', 'sp_criteria_extra_'+row_index+'_'+mod_index); + newRowExtra.val(''); + disableAndHideExtraField(newRowVal); + sizeTextBoxes(newRowVal, 'sp_extra_input_text', 'sp_input_text'); + newRowRemove.attr('id', 'criteria_remove_'+row_index+'_'+mod_index); + + //remove the 'criteria add' button from new modifier row + newRow.find('.criteria_add').remove(); + + $(this).parent().after(newRow); + }); + /********** REMOVE ROW **********/ form.find('a[id^="criteria_remove"]').live('click', function(){ var curr = $(this).parent(); var curr_pos = curr.index(); @@ -105,6 +154,7 @@ function setSmartPlaylistEvents() { removeButtonCheck(); }); + /********** SAVE ACTION **********/ form.find('button[id="save_button"]').live("click", function(event){ var data = $('form').serializeArray(), save_action = 'Playlist/smart-block-criteria-save', @@ -115,6 +165,7 @@ function setSmartPlaylistEvents() { }); }); + /********** GENERATE ACTION **********/ form.find('button[id="generate_button"]').live("click", function(event){ var data = $('form').serializeArray(), generate_action = 'Playlist/smart-block-generate', @@ -125,6 +176,7 @@ function setSmartPlaylistEvents() { }); }); + /********** SHUFFLE ACTION **********/ form.find('button[id="shuffle_button"]').live("click", function(event){ var data = $('form').serializeArray(), shuffle_action = 'Playlist/smart-block-shuffle', @@ -135,10 +187,12 @@ function setSmartPlaylistEvents() { }); }); + /********** CHANGE PLAYLIST TYPE **********/ form.find('dd[id="sp_type-element"]').live("change", function(){ setupUI(); }); + /********** CRITERIA CHANGE **********/ form.find('select[id^="sp_criteria"]:not([id^="sp_criteria_modifier"])').live("change", function(){ var index_name = $(this).attr('id'), index_num = index_name.charAt(index_name.length-1); @@ -148,6 +202,7 @@ function setSmartPlaylistEvents() { populateModifierSelect(this); }); + /********** MODIFIER CHANGE **********/ form.find('select[id^="sp_criteria_modifier"]').live("change", function(){ var criteria_value = $(this).next(), index_name = criteria_value.attr('id'), @@ -159,32 +214,39 @@ function setSmartPlaylistEvents() { disableAndHideExtraField(criteria_value, index_num); } }); - + setupUI(); appendAddButton(); removeButtonCheck(); } +var static_length = $('.playlist_title').children('h4[id$="_length"]').text(); + +/* +function setStaticLengthHolder(lenVal) { + static_length = lenVal; +} +*/ + function setupUI() { var playlist_type = $('input:radio[name=sp_type]:checked').val(); + var target_length = $('input[name="sp_limit_value"]').val(); + if (target_length == '') { + target_length = '0.0'; + } + + var dynamic_length = target_length; if ($('#obj_type').val() == 'block') { if (playlist_type == "0") { $('button[id="generate_button"]').show(); - $('button[id="shuffle_button"]').show(); - //$('#spl_sortable').unblock(); - //$('#spl_sortable').css("position", "static"); + $('button[id="shuffle_button"]').show(); $('#spl_sortable').show(); + //$('.playlist_title').children('h4[id$="_length"]').text(static_length); } else { $('button[id="generate_button"]').hide(); $('button[id="shuffle_button"]').hide(); - /* - $('#spl_sortable').block({ - message: "", - theme: true, - applyPlatformOpacityRules: false - }); - */ $('#spl_sortable').hide(); + //$('.playlist_title').children('h4[id$="_length"]').text(dynamic_length); } } @@ -241,27 +303,33 @@ function sizeTextBoxes(ele, classToRemove, classToAdd) { } function populateModifierSelect(e) { - var criteria = $(e).val(), - criteria_type = criteriaTypes[criteria], - div = $(e); - - $(e).next().children().remove(); + /*var criteria = $(e).val(), + criteria_type = criteriaTypes[criteria],*/ + var criteria_type = getCriteriaOptionType(e), + div = $(e).siblings('select[id^="sp_criteria_modifier"]'); + + div.children().remove(); if (criteria_type == 's') { $.each(stringCriteriaOptions, function(key, value){ - div.next().append($('') - .attr('value', key) - .text(value)); + div.append($('') + .attr('value', key) + .text(value)); }); } else { $.each(numericCriteriaOptions, function(key, value){ - div.next().append($('') - .attr('value', key) - .text(value)); + div.append($('') + .attr('value', key) + .text(value)); }); } } +function getCriteriaOptionType(e) { + var criteria = $(e).val(); + return criteriaTypes[criteria]; +} + function callback(data, type) { var form = $('#smart-playlist-form'), json = $.parseJSON(data); @@ -281,8 +349,11 @@ function callback(data, type) { form = $('#smart-playlist-form'); if (type == 'shuffle') { form.find('.success').text('Playlist shuffled'); - } else { + } else if (type == 'generate') { form.find('.success').text('Smart playlist generated and saved'); + //redraw library table so the length gets updated + var dt = $('table[id="library_display"]').dataTable(); + dt.fnStandingRedraw(); } form.find('.success').show(); form.find('#smart_playlist_options').removeClass("closed");