Bem, vou tentar aqui a minha sorte, espero encontrar alguem que me consiga ajudar
Então é assim, tenho 3 models:
Music
MusicGenre
MusicLink
ambos models correspondem a 3 tabelas, sendo a MusicGenre e MusicLink, tabelas auxiliares, que fazem a ligação entre a tabela Music, e as tabelas Genres e Links, respetivamente, isto porque uma Música pode ter varios links de ficheiros, bem como ter varios estilos.
no MusicController tenho a action create e update, entre outras
no form associado a essas actions, tenho para alem dos campos da tabela/model music mais 2 campos, um campo para escolher os genres musicais, o que existe aqui no forum, quando se cria um topico, e permite meter varias tags, usando o Select2, que envia os ids dos generos por post, num unico indice, em que os valores são separados por virgulas (ex: MusicGenre[genre_id] = 1,7,32,4)
tenho depois um outro campo de texto, que corresponde ao link da musica, sendo que este campo pode ser clonado até ter 6 copias, usando o plugin RelCopy, e envia varios links, caso existam, por exemplo: MusicLink[link][0] = http://servidor.com/musica1.mp.3, MusicLink[link][1] = http://servidor.com/musica2.mp.3
O meu problema está em como guardar estes dados correctamente ?
até agora, tenho este codigo:
MusicController.php
[CODE]/**
-
Creates a new model.
-
If creation is successful, the browser will be redirected to the ‘view’ page.
*/
public function actionCreate()
{
$music = new Music;
$genre = new MusicGenre;
$link = new MusicLink;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($music);
if(isset($_POST[‘Music’]) && isset($_POST[‘MusicGenre’]))
{
CActiveForm::validate($genre);
CActiveForm::validate($link);
$music->attributes=$_POST['Music'];
if($music->save()){
foreach(explode(',',$_POST['MusicGenre']['genre_id']) as $gen)
{
$genre=new MusicGenre;
$genre->genre_id = $gen;
$genre->music_id = $music->id;
if($genre->validate())
$valid[]=true;
else
$valid[]=false;
}
foreach($_POST['MusicLink']['links'] as $lnk)
{
$link=new MusicLink;
$link->link = $lnk;
$link->music_id = $music->id;
$link->host = MusicLink::model()->getHoster($lnk);
if($link->validate())
$valid[]=true;
else
$valid[]=false;
}
if(!in_array(false,$valid)){
$genre->save();
$link->save();
$this->redirect(array('view','id'=>$music->id));
}
}
}
$this->render(‘create’,array(
‘music’=>$music,
‘genre’=>$genre,
‘link’=>$link,
));
}
/**
-
Updates a particular model.
-
If update is successful, the browser will be redirected to the ‘view’ page.
-
@param integer $id the ID of the model to be updated
*/
public function actionUpdate($id)
{
$music = $this->loadModel($id);
$genre = MusicGenre::model()->findByAttributes(array(‘music_id’=>$id));//new MusicGenre;
$link = MusicLink::model()->findAll(‘music_id=:mID’,array(’:mID’=>$id));;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($music);
if(isset($_POST[‘Music’]) && isset($_POST[‘MusicGenre’]))
{
$music->attributes=$_POST['Music'];
if($music->save()){
foreach(explode(',',$_POST['MusicGenre']['genre_id']) as $gen)
{
//$genre = MusicGenre::model()->findByAttributes(array('music_id'=>$music->id));
$genre->genre_id = Genre::model()->nameToId($gen);
$genre->music_id = $music->id;
$valid[]=$genre->save();
}
foreach($_POST['MusicLink']['links'] as $lid => $lnk)
{
$link = MusicLink::model()->find('music_id=:mID AND id=:lID',array(':mID'=>$music->id,':lID'=>$lid));
if($link == null){
$link=new MusicLink;
$link->link = $lnk;
$link->music_id = $music->id;
$link->host = MusicLink::model()->getHoster($lnk);
$valid[]=$link->save();
}else if($link->link != $lnk){
$link->link = $lnk;
$link->music_id = $music->id;
$link->host = MusicLink::model()->getHoster($lnk);
$valid[]=$link->save();
}
}
if(!in_array(false,$valid))
$this->redirect(array('view','id'=>$music->id));
}
}
$this->render(‘update’,array(
‘music’=>$music,
‘genre’=>$genre,
‘link’=>$link,
));
}
[/CODE]
\music\_form.php
<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array(
'id'=>'music-form',
'type' => 'horizontal',
'customCssErrors' => 'inline',
'enableAjaxValidation'=>false,
)); ?>
<fieldset>
<legend>
<?php echo $music->isNewRecord ? Yii::t('b2r','Create Music') : Yii::t('b2r','Update Music') ;?>
</legend>
<p class="help-block well well-small"><?php echo Yii::t('b2r','Fields with <span class="required">*</span> are required.'); ?>
</p>
<?php
$models = array($music,$genre);
if (is_array($link))
foreach ($link as $lnk)
$models[] = $lnk;
else
$models[] = $link;
//die(var_dump($models));
?>
<?php echo $form->errorSummary($models); ?>
<div class="span6 first">
<?php echo $form->textFieldRow($music,'artist',array('class'=>'span12','maxlength'=>255)); ?>
<?php echo $form->textFieldRow($music,'title',array('class'=>'span12','maxlength'=>255)); ?>
<?php echo $form->textAreaRow($music,'desc',array('rows'=>3, 'cols'=>60, 'class'=>'span12')); ?>
<?php echo $form->select2Row($genre, 'genre_id', array(
'asDropDownList' => false,
'val' => MusicGenre::model()->getMusicGenresNames($music->id),
'options' => array(
'data' => Genre::model()->getGenres(),
'placeholder' => 'Escreva um ou mais categorias, separadas por virgulas',
'containerCssClass' => 'span12',
'tokenSeparators' => array(','),
'multiple'=>true,
'width'=>'none',
'initSelection' => 'js:function (element, callback) {
var val = [];
$(element.val().split(",")).each(function () {
val.push({id: this, text: this});
});
callback(val);
}'
)
)); ?>
<?php echo $form->maskedTextFieldRow($music,'length',array('mask'=>'99:99?:99','htmlOptions'=>array('class'=>'span12','maxlength'=><img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />),array('hint'=>Yii::t('b2r','No formato {f1} ou {f2}',array('{f1}'=>'<i class="label label-info">MM:SS</i>','{f2}'=>'<i class="label label-info">HH:MM:SS</i>')))); ?>
<?php echo $form->maskedTextFieldRow($music,'size',array('mask'=>'?~~~.~~','charMap'=>array('~'=>'^[0-9]+(\.)?[0-9]{0,2} ),'placeholder'=>'0','htmlOptions'=>array('class'=>'span12','maxlength'=><img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />),array('hint'=>Yii::t('b2r','No formato {f1} ou {f2}',array('{f1}'=>'<i class="label label-info">xx.xx</i>','{f2}'=>'<i class="label label-info">xxx.xx</i>')))); ?>
</div>
<div class="span6">
<div class="controls">
<ul class="thumbnails">
<li class="span5">
<a class="thumbnail">
<?php echo CHtml::image('/images/capa.gif',Yii::t('b2r','Previsualização da Imagem'),
array('id'=>'previewHolder','width'=>'170px','height'=>'170px')); ?>
</a>
</li>
</ul>
</div>
<?php echo $form->textFieldRow($music,'image',array('class'=>'span8','maxlength'=>255),array('controlCss'=>'skipcopy','append'=>'<a href="#" id="findcover" data-toggle="tooltip" title="'.Yii::t('b2r','Procurar capa no Google').'"><i class="icon-circle-arrow-right"></i></a>')); ?>
<?php
if ($music->isNewRecord){
echo $form->textFieldRow($link,'link',
array('name'=>'MusicLink[links][0]','value'=>'','maxlength'=>255, 'class'=>'span8'),
array('controlCss'=>'copy clonable','append'=>'<a id="copylink" href="#" rel=".copy"><i class="icon-plus"></i></a> ')
);
}else{
$last = count($link)-1;
foreach ($link as $k => $v)
die(var_dump($link));
$id = (is_null($v)) ? $k : $v->id;
if($k == $last)
echo $form->textFieldRow($v,'link',
array('name'=>'MusicLink[links]['.$id.']','maxlength'=>255, 'class'=>'span8'),
array('controlCss'=>'copy clonable','label'=>'<span class="required">*</span>','append'=>'<a id="copylink" href="#" rel=".copy"><i class="icon-plus"></i></a> ')
);
else
echo $form->textFieldRow($v,'link',
array('name'=>'MusicLink[links]['.$id.']','maxlength'=>255, 'class'=>'span8'),
array('controlCss'=>'clonable')
);
}
?>
<?php
$this->widget('ext.jqrelcopy.JQRelcopy',array(
//the id of the 'Copy' link in the view, see below.
'id' => 'copylink',
//add a icon image tag instead of the text
//leave empty to disable removing
'removeText' => '<i class="icon-remove"></i>',
//htmlOptions of the remove link
'removeHtmlOptions' => array('style'=>'margin-left:2px;padding:3px 10px;','class'=>'btn btn-small btn-danger'),
//options of the plugin, see [url="http://www.andresvidal.com/labs/relcopy.html"]http://www.andresvid...bs/relcopy.html[/url]
'options' => array(
//A class to attach to each copy
'copyClass'=>'newcopy',
// The number of allowed copies. Default: 0 is unlimited
'limit'=>6,
//Option to clear each copies text input fields or textarea
'clearInputs'=>true,
//A jQuery selector used to exclude an element and its children
'excludeSelector'=>'.skipcopy',
//Additional HTML to attach at the end of each copy.
//'append'=>CHtml::tag('span',array('class'=>'hint'),'You can remove this line'),
//'jsAfterNewId' => "if(typeof $(this > input).attr('name') !== 'undefined'){ $(this > input).attr('name', $(this > input).attr('name').replace('new', 'new_'+counter));}",
)
));
?>
</div>
<?php $collapse = $this->beginWidget('bootstrap.widgets.TbCollapse',array('htmlOptions'=>array('class'=>'span12 first'))); ?>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse"
data-parent="#accordion2" href="#collapseOne">
Avançado
</a>
</div>
<div id="collapseOne" class="accordion-body collapse">
<div class="accordion-inner">
<?php echo $form->textFieldRow($music,'bitrate',array('class'=>'span9')); ?>
</div>
</div>
</div>
<?php $this->endWidget(); ?>
</fieldset>
<div class="form-actions">
<?php $this->widget('bootstrap.widgets.TbButton', array(
'buttonType'=>'submit',
'type'=>'primary',
'label'=>$music->isNewRecord ? Yii::t('b2r','Create') : Yii::t('b2r','Save'),
)); ?>
</div>
<?php $this->endWidget(); ?>
<?php Yii::app()->clientScript->registerScript('script', "
$('#Music_image').change(function() {
$('#previewHolder').attr('src',$(this).val());
});
$('#findcover').click(function() {
var q = $('#Music_artist').val();
q += ' - '+$('#Music_title').val();
q += ' cover';
window.open('https://www.google.pt/search?q='+escape(q)+'&tbm=isch', '_blank');
});
"
, CClientScript::POS_READY);?>
O codigo funciona, mas tem alguns "bugs".
imaginando que se tenta enviar o form, a faltar algum campo obrigatorio do model Music e os 2 campos dos models MusicLink e MusicGenre por preencher, ele ai valida os 3 models, e não guarda nenhum.
Mas se preencher todos os campos do model Music e deixar por preencher algum campo dos models MusicLink ou MusicGenre, ele ai guarda a musica, e não consigo fazer com que ele valide os outros 2 models alem do MUSIC e que retorne para o form, como é o habitual…
não sei que consegui explicar bem, isto ta-me a matar o juiso…
Estou a usar a Yii 1.1.14, com o YiiBoilerplate e Yiibooster
ficam aqui os links para os plugins usados e mensionados…:
http://www.andresvid…bs/relcopy.html