AR array problem

Hello everyone,

My experiment may be a bizarre and a dodgy but the situation:

I’ve retrieved a serialized array from my db and unserialized it.

Because it’s a 2D array i select the index of which i want to change the content and sent it to an update form, no problem so far.

When i save i have to take the original unserialized array and change the data for the index, he doesn’t want to do that, leaving me a bit with a problem, can anybody tell me why and maybe a hit to the right direction?


public function actionUpdateTest()


	{

	

		//get form model

		$model= new formUpdateCollectionItem();

		//get ar model

		$model2 = $this->loadModel();

		

		//form model attributes to selected ones from ar model

		$model->attributes = $model2->collection[$_GET['index']];


		if(isset($_POST['formUpdateCollectionItem']))


		{

			

			//doesn't set my data right

			$model2['collection'][$_GET['index']]['name'] == $_POST['formUpdateCollectionItem']['name'];

			$model2['collection'][$_GET['index']]['points'] == $_POST['formUpdateCollectionItem']['points'];

			

			$model2->collection = serialize($model2->collection);

			if($model2->save())

				echo("okeeeeee");	


		}


		$this->render('updatetest', array('model'=>$model));


	}


public function loadModel()


	{


		if($this->_model===null)


		{


			if(isset($_GET['id'])){


				$this->_model=serialTest::getProfileSerial($_GET['id']);


                		$this->_model->collection = unserialize($this->_model->collection);

                		}


                }


			if($this->_model===null)


				throw new CHttpException(404,'The requested page does not exist.');


		return $this->_model;


	}

You use == instead of =

Hi,

Thanks but that didn’t seem to work :(




                        $model2['collection'][$_GET['index']]['name'] == $_POST['formUpdateCollectionItem']['name'];

                        $model2['collection'][$_GET['index']]['points'] == $_POST['formUpdateCollectionItem']['points'];



These lines don’t do a thing. double-equal is for comparing, single equal is for setting

I know, i changed it afterwards from = to ==, i had a doubt

Do you have valid data in both $_GET and $_POST? I guess you POST on update.

/Tommy

i think Tommy is right, i think you will not be getting $_GET[‘index’] value after post of form


public function actionUpdateTest()


	{

	

		//get form model

		$model= new formUpdateCollectionItem();

		//get ar model

		$model2 = $this->loadModel();

		

		//form model attributes to selected ones from ar model

		$model->attributes = $model2->collection[$_GET['index']];

		$model->attributes['index'] = $_GET['index'];

		


		if(isset($_POST['formUpdateCollectionItem']))


		{

			

			//doesn't set my data right

			$model2['collection'][$_POST['index']]['name'] = $_POST['formUpdateCollectionItem']['name'];

			$model2['collection'][$_POST['index']]['points'] = $_POST['formUpdateCollectionItem']['points'];

			

			$model2->collection = serialize($model2['collection']);

			if($model2->save())

				echo("okeeeeee");


		}


		


		$this->render('updatetest', array('model'=>$model));


	}

alright i changed the $_GET to $_POST, but no change…

the other parts of code:


<?php 


class formUpdateCollectionItem extends CFormModel

{

	public $index;

	public $name;

	public $points;


	/**

	 * Declares the validation rules.

	 */

	public function rules()

	{

		return array(

			// name, email, subject and body are required

			array('name, points', 'required'),

		);

	}


	/**

	 * Declares customized attribute labels.

	 * If not declared here, an attribute would have a label that is

	 * the same as its name with the first letter in upper case.

	 */

	public function attributeLabels()

	{

		return array(

			'name'=>'Skill Name',

			'points'=>'Skill Points',

		);

	}

}


<?php

$this->breadcrumbs=array(

	'Serial Tests'=>array('index'),

	$model->index=>array('view','index'=>$model->index),

	'Update',

);

?>


<h1>Update serialTest <?php echo $model->index; ?></h1>


<ul class="actions">

	<li><?php echo CHtml::link('List serialTest',array('index')); ?></li>

	<li><?php echo CHtml::link('Create serialTest',array('create')); ?></li>

		<li><?php echo CHtml::link('Manage serialTest',array('admin')); ?></li>

</ul><!-- actions -->


<div class="form">


<?php echo CHtml::beginForm(); ?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


	<div class="row">

		<?php echo CHtml::activeHiddenField($model,'index'); ?>

		<?php echo CHtml::activeLabelEx($model,'name'); ?>

		<?php echo CHtml::activeTextField($model,'name'); ?>

		<?php echo CHtml::activeLabelEx($model,'points'); ?>

		<?php echo CHtml::activeTextField($model,'points'); ?>

	</div>


	<div class="row buttons">

		<?php echo CHtml::submitButton('Save'); ?>

	</div>


<?php echo CHtml::endForm(); ?>


</div><!-- form -->


<?php


class serialTest extends CActiveRecord

{

	/**

	 * The followings are the available columns in table 'serialTest':

	 * @var integer $id

	 * @var string $collection

	 */


	/**

	 * Returns the static model of the specified AR class.

	 * @return CActiveRecord the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'serialTest';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('collection', 'required'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'Id',

			'collection' => 'Collection',

		);

	}

	

	public function getProfileSerial($userId)

	{

		$Criteria = new CDbCriteria();


		$Criteria->condition = "id = :id";


		$Criteria->params = array (':id' => $userId);


	  	 return self::model()->find($Criteria);

	}

}

I hope this helps to find my problem :s

is there still someone who can help me please.

Normally my array obtaint from loadModel() is given by value so i should be able to change it but still there’s no change. Is there some function for this?

When you reload the model loadModel() uses $_GET[‘id’]. I think you need to save the ‘id’ and modify the logic to use the appropriate variable on reentering the update action with the submitted form.

/Tommy

loadModel() retrieves the data from the db without a problem, to check this I’ve dumped the data to the page using var_dump and print_r to see if i got the right data retrieved

the logic i used (more or less):

  1. retrieve the collection from my db

  2. unserialize() my collection

  3. with the index $_GET[‘index’] i get the right secondary indicator for the sub-arrays

  4. i put them into the model so i can display them in a form.

//no problem so far

  1. i edit the array

  2. put the modified array back into to main array

  3. serialize()

  4. save()

point 6 is where it all goes terribly wrong he doesn’t want to copy $model to $model2->collection[$_GET[‘index’]] = $model;


public function actionUpdateTest()


	{

		$model= new formUpdateCollectionItem();

		$model2 = $this->loadModel();

		


		if(isset($_POST['formUpdateCollectionItem']))


		{		

			$model2['collection'][$_POST['formUpdateCollectionItem']['index']]['name'] = $_POST['formUpdateCollectionItem']['name'];

			$model2['collection'][$_POST['formUpdateCollectionItem']['index']]['points'] = $_POST['formUpdateCollectionItem']['points'];

			

			print_r($model);

			print_r($model2['collection'][$_GET['index']]);

			$model2->collection = serialize($model2['collection']);

			$model2->save();

		}

		

		$model->attributes = $model2->collection[$_GET['index']];

		$model->index = $_GET['index'];

		


		$this->render('updatetest', array('model'=>$model));


	}

I narrowed it down as much as possible but i don’t know how i can change this:

$model2[‘collection’][$_POST[‘formUpdateCollectionItem’][‘index’]][‘name’] = $_POST[‘formUpdateCollectionItem’][‘name’];

$model2[‘collection’][$_POST[‘formUpdateCollectionItem’][‘index’]][‘points’] = $_POST[‘formUpdateCollectionItem’][‘points’];

Yii just doesn’t want to commit the $_POST data to the $model2->collection[] data

just a small question the db columns for which yii creates corresponding vars are, i hope, ‘public’ and not protected or something? or something within yii that prevents arrays being altered

Alright!

After many attempts and rewrites and searches on the web i found a way to pull this off.

How you might ask, well, shorter is not always better nor right,

apparently $model2->collection has a variable access modifier or something alike on it so you can’t change data directly, you need and temp variable $temp;


public function actionUpdateTest()


	{

		$model= new formUpdateCollectionItem();

		$model2 = serialTest::getProfileSerial($_GET['id']);

		$model2->collection = unserialize($model2->collection);

		print_r($model2->collection);


		if(isset($_POST['formUpdateCollectionItem']))


		{		

			$temp = $model2->collection; //SOLUTION ALTHOUGH NOT TO CLEAN I FIND

			$temp[$_GET['index']]['name'] = $_POST['formUpdateCollectionItem']['name'];

			$temp[$_GET['index']]['points'] = $_POST['formUpdateCollectionItem']['points'];

			

			$model2->collection = serialize($temp);

			$model2->save();

		}

		

		$model->attributes = $model2->collection[$_GET['index']];

		$model->index = $_GET['index'];

		


		$this->render('updatetest', array('model'=>$model));


	}

maybe one of the devteam members could see to this or something?

Thanks everybody for helping me along!

Hi webscriptz.be

were there any error message for doing?




$model2->collection['x'] = 'y';

$model2->collection = serialize($model2->collection);



No i got not one error, and loadModel() works perfectly.

the only problem was that i couldn’t change $model2->collection after being unserialize(), but when i passed it to $temp = $model2->collection and store everything from my collection array and changed the data with that from the post data, I had no problem at all saving that which is weird.