Chapter 6 - ProjectController issue

Hi, Newbie question here.

I’ve been following the demo in the PDF version and have hit a snag on page 131.

after making all the changes and attempting to display Project Issues ( http://localhost/trackstar/index.php?r=project/view&id=1) I am greeted with the following PHP error screen:




PHP Error

Description


Missing argument 1 for ProjectController::loadModel(), 

called in /var/www/trackstar/protected/controllers/ProjectController.php on line 55 and defined


Source File


/var/www/trackstar/protected/controllers/ProjectController.php(165)


00153:             $model->attributes=$_GET['Project'];

00154: 

00155:         $this->render('admin',array(

00156:             'model'=>$model,

00157:         ));

00158:     }

00159: 

00160:     /**

00161:      * Returns the data model based on the primary key given in the GET variable.

00162:      * If the data model is not found, an HTTP exception will be raised.

00163:      * @param integer the ID of the model to be loaded

00164:      */

00165: public function loadModel($id)

00166:     {

00167:         $model=Project::model()->findByPk((int)$id);

00168:         if($model===null)

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

00170:         return $model;

00171:     }

00172: 

00173:     /**

00174:      * Performs the AJAX validation.

00175:      * @param CModel the model to be validated

00176:      */

00177:     protected function performAjaxValidation($model)


Stack Trace


#0 /var/www/trackstar/protected/controllers/ProjectController.php(55): ProjectController->loadModel()

#1 /var/www/framework/web/actions/CInlineAction.php(50): ProjectController->actionView()

#2 /var/www/framework/web/CController.php(300): CInlineAction->run()

#3 /var/www/framework/web/filters/CFilterChain.php(133): ProjectController->runAction()

#4 /var/www/framework/web/filters/CFilter.php(41): CFilterChain->run()

#5 /var/www/framework/web/CController.php(1049): CAccessControlFilter->filter()

#6 /var/www/framework/web/filters/CInlineFilter.php(59): ProjectController->filterAccessControl()

#7 /var/www/framework/web/filters/CFilterChain.php(130): CInlineFilter->filter()

#8 /var/www/framework/web/CController.php(283): CFilterChain->run()

#9 /var/www/framework/web/CController.php(257): ProjectController->runActionWithFilters()

#10 /var/www/framework/web/CWebApplication.php(324): ProjectController->run()

#11 /var/www/framework/web/CWebApplication.php(121): CWebApplication->runController()

#12 /var/www/framework/base/CApplication.php(135): CWebApplication->processRequest()

#13 /var/www/trackstar/index.php(13): CWebApplication->run()


2010-09-15 09:03:51 Apache/2.2.14 (Ubuntu) Yii Framework/1.1.4




Now, it would seem that ProjectController actionView would be the cause, but I am unsure why no parameter exists in this method:




	/**

	* Displays a particular model.

	*/

	public function actionView()

	{

		$issueDataProvider=new CActiveDataProvider('Issue', array(

		'criteria'=>array(

			'condition'=>'project_id=:projectId',

			'params'=>array(':projectId'=>$this->loadModel()->id),

			),

		'pagination'=>array(

			'pageSize'=>1,

			),

		));

		$this->render('view',array(

			'model'=>$this->loadModel(),

			'issueDataProvider'=>$issueDataProvider,

		));

	}



yet a parameter is being requested here:




	/**

	 * Returns the data model based on the primary key given in the GET variable.

	 * If the data model is not found, an HTTP exception will be raised.

	 * @param integer the ID of the model to be loaded

	 */

	public function loadModel($id)

	{

		$model=Project::model()->findByPk((int)$id);

		if($model===null)

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

		return $model;

	}



I must have missed something here. trackstar_dev and trackstar_test are identical, and phpunit tests pass.

Any ideas on where to look?

Thank you!

Hello no-one-u-know,

The code generated by the Gii CRUD generator for projects, which includes the ProjectController.php class file, as well as the code bundle you can download from Packt, has a different loadModel method defined from what you have:


/**

	 * Returns the data model based on the primary key given in the GET variable.

	 * If the data model is not found, an HTTP exception will be raised.

	 */

	public function loadModel()

	{

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

		{

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

				$this->_model=Project::model()->findbyPk($_GET['id']);

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

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

		}

		return $this->_model;

	}

This would seem to be the issue. But I am curious from where your ProjectController::loadModel() method came? Did you write this yourself, or did you use the Gii generator tool as described in the book? Also, just curious, are you using Yii v 1.1.2 as you are following along in the book?

Hi Jeff: thanks for the response.

I installed yii-1.1.4r2429 and am using the Gii generator tool - no (intentional) code was added beyond what the book instructed.

I did replace the existing loadmodule with the the following:


/**

	 * Returns the data model based on the primary key given in the GET variable.

	 * If the data model is not found, an HTTP exception will be raised.

	 */

	public function loadModel()

	{

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

		{

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

				$this->_model=Project::model()->findbyPk($_GET['id']);

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

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

		}

		return $this->_model;

	}

and reloaded http://localhost/trackstar/index.php?r=project/view&id=1. The following error appeared:




CException

Description


Property "ProjectController._model" is not defined.

Source File


/var/www/trackstar/protected/controllers/ProjectController.php(166)


00154: 

00155:         $this->render('admin',array(

00156:             'model'=>$model,

00157:         ));

00158:     }

00159: 

00160: /**

00161:          * Returns the data model based on the primary key given in the GET variable.

00162:          * If the data model is not found, an HTTP exception will be raised.

00163:          */

00164:         public function loadModel()

00165:         {

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

00167:                 {

00168:                         if(isset($_GET['id']))

00169:                                 $this->_model=Project::model()->findbyPk($_GET['id']);

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

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

00172:                 }

00173:                 return $this->_model;

00174:         }

00175: 

00176:     /**

00177:      * Performs the AJAX validation.

00178:      * @param CModel the model to be validated


Stack Trace


#0 /var/www/trackstar/protected/controllers/ProjectController.php(166): CComponent->__get('_model')

#1 /var/www/trackstar/protected/controllers/ProjectController.php(55): ProjectController->loadModel()

#2 /var/www/framework/web/actions/CInlineAction.php(50): ProjectController->actionView()

#3 /var/www/framework/web/CController.php(300): CInlineAction->run()

#4 /var/www/framework/web/filters/CFilterChain.php(133): CController->runAction(Object(CInlineAction))

#5 /var/www/framework/web/filters/CFilter.php(41): CFilterChain->run()

#6 /var/www/framework/web/CController.php(1049): CFilter->filter(Object(CFilterChain))

#7 /var/www/framework/web/filters/CInlineFilter.php(59): CController->filterAccessControl(Object(CFilterChain))

#8 /var/www/framework/web/filters/CFilterChain.php(130): CInlineFilter->filter(Object(CFilterChain))

#9 /var/www/framework/web/CController.php(283): CFilterChain->run()

#10 /var/www/framework/web/CController.php(257): CController->runActionWithFilters(Object(CInlineAction), Array)

#11 /var/www/framework/web/CWebApplication.php(324): CController->run('view')

#12 /var/www/framework/web/CWebApplication.php(121): CWebApplication->runController('project/view')

#13 /var/www/framework/base/CApplication.php(135): CWebApplication->processRequest()

#14 /var/www/trackstar/index.php(13): CApplication->run()

#15 {main}


2010-09-15 11:16:28 Apache/2.2.14 (Ubuntu) Yii Framework/1.1.4



And things were progressing fine up to this point :(

Well, this may very well be due to a small difference in the Gii code generation tool between framework versions 1.1.2 and the one you are using 1.1.4. Again, in order to ensure success and the best experience when following closely along with the examples in the book, you should do so against Yii version 1.1.2. ALL of the ideas translate just fine between what is covered in the book and the latest Yii version (1.1.4), but there may be just a few subtle code/syntax/api differences in different Yii versions.

The full ProjectController class from the book code chapter 6 (again, using Yii v 1.1.2) is the following (you will notice the private class attribute


$_model;

defined at the top, which seems not present in your code):


<?php


class ProjectController extends Controller

{

	/**

     * @var string the default layout for the views. Defaults to 'column2', meaning

     * using two-column layout. See 'protected/views/layouts/column2.php'.

     */

	public $layout='column2';


	/**

     * @var CActiveRecord the currently loaded data model instance.

     */

	private $_model;


	/**

     * @return array action filters

     */

	public function filters()

	{

		return array(

			'accessControl', // perform access control for CRUD operations

		);

	}


	/**

     * Specifies the access control rules.

     * This method is used by the 'accessControl' filter.

     * @return array access control rules

     */

	public function accessRules()

	{

		return array(

			array('allow',  // allow all users to perform 'index' and 'view' actions

				'actions'=>array('index','view'),

				'users'=>array('*'),

			),

			array('allow', // allow authenticated user to perform 'create' and 'update' actions

				'actions'=>array('create','update'),

				'users'=>array('@'),

			),

			array('allow', // allow admin user to perform 'admin' and 'delete' actions

				'actions'=>array('admin','delete'),

				'users'=>array('admin'),

			),

			array('deny',  // deny all users

				'users'=>array('*'),

			),

		);

	}


	/**

     * Displays a particular model.

     */

	public function actionView()

	{

		$issueDataProvider=new CActiveDataProvider('Issue', array(

			'criteria'=>array(

	     		'condition'=>'project_id=:projectId',

	     		'params'=>array(':projectId'=>$this->loadModel()->id),

	     	),

	     	'pagination'=>array(

	     		'pageSize'=>1,

	     	),

	     ));

		

		$this->render('view',array(

			'model'=>$this->loadModel(),

			'issueDataProvider'=>$issueDataProvider,

		));

	}


	/**

     * Creates a new model.

     * If creation is successful, the browser will be redirected to the 'view' page.

     */

	public function actionCreate()

	{

		$model=new Project;


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


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

		{

			$model->attributes=$_POST['Project'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id));

		}


		$this->render('create',array(

			'model'=>$model,

		));

	}


	/**

     * Updates a particular model.

     * If update is successful, the browser will be redirected to the 'view' page.

     */

	public function actionUpdate()

	{

		$model=$this->loadModel();


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


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

		{

			$model->attributes=$_POST['Project'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id));

		}


		$this->render('update',array(

			'model'=>$model,

		));

	}


	/**

     * Deletes a particular model.

     * If deletion is successful, the browser will be redirected to the 'index' page.

     */

	public function actionDelete()

	{

		if(Yii::app()->request->isPostRequest)

		{

			// we only allow deletion via POST request

			$this->loadModel()->delete();


			// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser

			if(!isset($_GET['ajax']))

				$this->redirect(array('index'));

		}

		else

			throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');

	}


	/**

     * Lists all models.

     */

	public function actionIndex()

	{

		$dataProvider=new CActiveDataProvider('Project');

		$this->render('index',array(

			'dataProvider'=>$dataProvider,

		));

	}


	/**

     * Manages all models.

     */

	public function actionAdmin()

	{

		$model=new Project('search');

		if(isset($_GET['Project']))

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


		$this->render('admin',array(

			'model'=>$model,

		));

	}


	/**

     * Returns the data model based on the primary key given in the GET variable.

     * If the data model is not found, an HTTP exception will be raised.

     */

	public function loadModel()

	{

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

		{

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

				$this->_model=Project::model()->findbyPk($_GET['id']);

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

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

		}

		return $this->_model;

	}


	/**

     * Performs the AJAX validation.

     * @param CModel the model to be validated

     */

	protected function performAjaxValidation($model)

	{

		if(isset($_POST['ajax']) && $_POST['ajax']==='project-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

	}

}



Thanks, I didn’t consider looking in the zip - was only looking at my pdf & comparing my work to the git repository.

doing a quick compare, I notice that the 1.1.4 generated ProjectController actionUpdate & actionDelete also have ($id) 's

I will restart the process with 1.1.2 and try again.

ok - wiped and started again with trackstar_chapter_6_rewrite.tgz and yii-1.1.2.

Things work, but I noticed two things:

  1. one can successfully create an issue for project one, (http://127.0.0.1/trackstar/index.php?r=issue/create&pid=1) but not for any others (say project 3 - http://127.0.0.1/trackstar/index.php?r=issue/create&pid=3). If you attempt to create an issue for project 3 (http://127.0.0.1/trackstar/index.php?r=issue/create&pid=3) the owner and requester pulldowns are void of any entries, and pressing create throws a PHP error:



PHP Error

Description


Trying to get property of non-object

Source File


/var/www/trackstar/protected/views/issue/view.php(34)


00022:         'name',

00023:         'description',

00024:         array(        

00025:             'name'=>'type_id',

00026:             'value'=>CHtml::encode($model->getTypeText())

00027:         ),

00028:         array(        

00029:             'name'=>'status_id',

00030:             'value'=>CHtml::encode($model->getStatusText())

00031:         ),

00032:         array(        

00033:             'name'=>'owner_id',

00034: 'value'=>CHtml::encode($model->owner->username)

00035:         ),

00036:         array(        

00037:             'name'=>'requester_id',

00038:             'value'=>CHtml::encode($model->requester->username)

00039:         ),

00040:         //'create_time',

00041:         //'create_user_id',

00042:         //'update_time',

00043:         //'update_user_id',

00044:     ),

00045: )); ?>


Stack Trace


#0 /var/www/Yii-1.1.2/framework/web/CBaseController.php(119): require()

#1 /var/www/Yii-1.1.2/framework/web/CBaseController.php(88): IssueController->renderInternal()

#2 /var/www/Yii-1.1.2/framework/web/CController.php(748): IssueController->renderFile()

#3 /var/www/Yii-1.1.2/framework/web/CController.php(687): IssueController->renderPartial()

#4 /var/www/trackstar/protected/controllers/IssueController.php(66): IssueController->render()

#5 /var/www/Yii-1.1.2/framework/web/actions/CInlineAction.php(32): IssueController->actionView()

#6 /var/www/Yii-1.1.2/framework/web/CController.php(300): CInlineAction->run()

#7 /var/www/Yii-1.1.2/framework/web/filters/CFilterChain.php(129): IssueController->runAction()

#8 /var/www/Yii-1.1.2/framework/web/filters/CFilter.php(41): CFilterChain->run()

#9 /var/www/Yii-1.1.2/framework/web/CController.php(999): CAccessControlFilter->filter()

#10 /var/www/Yii-1.1.2/framework/web/filters/CInlineFilter.php(59): IssueController->filterAccessControl()

#11 /var/www/Yii-1.1.2/framework/web/filters/CFilterChain.php(126): CInlineFilter->filter()

#12 /var/www/Yii-1.1.2/framework/web/CController.php(283): CFilterChain->run()

#13 /var/www/Yii-1.1.2/framework/web/CController.php(257): IssueController->runActionWithFilters()

#14 /var/www/Yii-1.1.2/framework/web/CWebApplication.php(320): IssueController->run()

#15 /var/www/Yii-1.1.2/framework/web/CWebApplication.php(120): CWebApplication->runController()

#16 /var/www/Yii-1.1.2/framework/base/CApplication.php(135): CWebApplication->processRequest()

#17 /var/www/trackstar/index.php(12): CWebApplication->run()


2010-09-15 16:47:01 Apache/2.2.14 (Ubuntu) Yii Framework/1.1.2



These issues will appear in the project list, but will throw the above error if you try to view them.

  1. the “issues” (http://127.0.0.1/trackstar/index.php?r=issue/index) breadcrumb link isn’t updated - the sidemenu link to “list issues” (http://127.0.0.1/trackstar/index.php?r=issue/admin&pid=3) works ok. Probably addressed at a later time, but figure I would point it out just in case.

Thanks for the assist.

I am glad you were able to get past your original issue.

User management is something that starts to be covered in Chapter 7 and 8 (after chapter 6). Consequently, we had to explicitly add user assignments via SQL in order to complete the Issue creation example. On page 120, you can see we added our two users ONLY to project #1. You would need to do something similar for other created projects in order to successfully add issues to other projects (Admittedly, this is left up to the reader to do).

Also, there may be other tweaks to the application itself (updating a breadcrumb navigation for example) that are also intentionally left up to the reader.

The book’s intention is to try to outline some real-world, practical Web Application needs and requirements and demonstrate how well Yii addresses these and how easy it is to meet such requirements using Yii. The desire is to empower the reader with enough information to feel extremely comfortable using Yii on their next real world Web application they are building. It is not the intention of the book to hand over a fully production-ready Web application, but rather to help the reader to do that themselves.

Hope this helps to clarify a little bit and better set expectations for this book.

Hi there I have had exactly the same error when using yii > 1.1.2 and following the code changes in the book.

I have managed to solve the issue however I will state now that it is late and I am trying to get as far through this book as I can so that I can start putting what I have learnt to use in a few projects I am wanting to get started. I have not fully checked the code and I am unsure if there will be other issues due to the changes I have made but it seems to be working fine at the moment.

I changed the actionView method as below:


/**

	* Displays a particular model.

	*/

	public function actionView($id)

	{

		$issueDataProvider=new CActiveDataProvider('Issue', array(

			'criteria'=>array(

				'condition'=>'project_id=:projectId',

				'params'=>array(':projectId'=>$this->loadModel($id)->id),

				),

			'pagination'=>array(

				'pageSize'=>1,

				),

			)

         );

         $this->render('view',array(

			     'model'=>$this->loadModel($id),

			     'issueDataProvider'=>$issueDataProvider,

			));

	}

As it is late and I am really tired now I have not confirmed this but it would appear that yii passes $id as a parameter when calling the actionView() method. Accepting this as a parameter and then passing it to loadObject seems to have done the trick.

If you can confirm this that would be great if not I will take another look in the morning. It seems to be working now anyway.

Excellent book so far by the way thanks a lot!

Hi all,

I got the same error on yii-1.1.5 with Gii:

Passing the $id directly solved my issue:


	public function actionView($id)

    {        

        $issueDataProvider = new CActiveDataProvider('Issue', array(

            'criteria'=>array(

                'condition'=>'project_id=:project_id',

                'params'=>array(':project_id'=>$id)

            ),

            'pagination'=>array(

                'pageSize'=>1

            )

        ));

        

        $this->render('view',array(

            'model'=>$this->loadModel($id),

            'issueDataProvider'=>$issueDataProvider,

        ));

    }

Thank you.

I’ve done the same and works fine!

Passing the $id directly works well! Thank you!

Hi, I also passed $id, and it solved the problem. Using Yii 1.1.10.

Error in this line :

‘params’ => array(’:projectId’ => $this->loadModel()->id),

Replace this line by

‘params’=>array(’:projectId’=>$this->loadModel($id)->id),

Note : If you are reading this book Agile Web Application Development with Yii 1.1 and PHP5 lot of mistake in this book read this book Web Application Development with Yii and PHP