Jump to content
Larry Ullman's Book Forums

Jonathon

Members
  • Posts

    1064
  • Joined

  • Last visited

  • Days Won

    55

Posts posted by Jonathon

  1. Hi Thomas,

     

    I'll definitely keep building. This practice one has been so much help in terms of putting ideas into practice and expanding them. It's also made me write processes that haven't been explicitly covered in the book. So I'll keep with this one for a while, then look to start a fresh.

  2. Just a quick question,

     

    When you finish part 2 of the book, would you say that there is the point where everything you are going to cover regarding the creation of a fully functional website with yii is finished. Much as I want to read the whole book first the practice website i've been building has been great through these chapters. But i'd like to maybe start a more production version. I just don't want to start it prematurely and find that I've been doing something wrong and have to redo everything. 

     

    For instance, had I started a couple of chapters ago, I'd have been doing all the $dataProvider stuff wrong and lost all the built in functionality.

     

    Looking at the TOC I only really see as Chapter 17: Internationalization and maybe Chapter 19: Advanced Database Issues as a possible area that I may approach wrongly. However i'm not sure how easy it would be to undo any areas that i've approached poorly by Yii standards.

     

    Thanks

     

    Jonathon

  3. Thanks for the nice words Larry and the help that you and Antonio have helped me with recently. I appreciate it.

     

    As for the answer to this piece. You can't access the $dataProvider as an array like that, but I have figured out how to do it.

     

     

    $dataProvider->Data[0]['Area']['name']
    

     

    If an area has no items then this causes an index error as the array doesn't exist. So I just test for it's presence before loading the page and if it doesn't exist I show a "No records message"

     

    Jonathon

  4. I actually rewrote the code and it looks like this. This code works fine, displays the correct number of records (It didn't before it just showed 1 record of 1, ven though it returned more than 1 record) and is sortable.

     

    Controller

     

    		$dataProvider=new CActiveDataProvider('Item', array(
    			'criteria' => array(
    			'with' =>'Area',
    			'condition' => 't.area_id=:id', // primary Item table `area_id` = id passed in url
    			'params' => array(':id'=>$id)
     		),
    			'sort'=>array(
    			'attributes'=>array(
    				'title'=>array(
    				'asc'=>'title',
    				'desc'=>'title DESC'
    			  ),
    			  	'price'=>array(
    			  	'asc'=>'price',
    				'desc'=>'price DESC'
    			  )
    		 )
    	),
    			'pagination'=>array(
    				'pageSize'=>5,
    			)
     ));		
    			
    		$this->render('index',array(
    			'dataProvider'=>$dataProvider,
    		));
    
    

     

     

    In the _view I just accessed the data like so

     

    $data->title; // etc
    

     

    This is an Area controller and view however. Not sure if that matters??

     

    I have 1 final thing to tidy this up

     

    In the index.php view I just want to set the <h1>

     

    I am having a little problem doing that

     

    I am using the $dataProvider object that is passed to index view. But I can't seem to be able to access the relationName or related models directly like $dataProvider->Area->name so I can print the <h1> tag.

     

    Should I just add another $model when i render the view?? I feel like I shouldn't need to do this to access the information, but maybe i'm wrong.

     

    Hopefully that progress will be ok in Yii terms and helpful to others.

  5. Thanks Thomas,

     

    You know I actually was half way through writing my ideas down in a private message to help me fix the last part. And whilst trying to explain my thoughts (as I haven't looked at this for a good few days). I thought i'd just try to see how my ideas got on and it worked. I'm sure I tried something very similar before, must have just missed something out and it was failing.

     

    Rubber ducking as Larry calls it! 

     

    Thanks 

     

    Thomas for your help  :D

  6. How I went about this was this for those interested: 

     

    Model

     

    public function activateUser($x, $y)
    	{
    		$model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y));
    		
    		if($model === NULL)
    		{
    		// No records returned throw error
    		throw new InvalidActivationException("Something bad happened");
    
    		} else {
    			// Record returned, validate new record
    			if($model->validate())
    			{
    				$model->active = NULL;
    				
    					if($model->save()) 
    					{
    					    return true;
    					}
    			}
    		}
    	}
    

     

     

    And in the controller:

     

    Controller
    
    // rest of $_GET checks
    
                                     try{
    					// try to activate the user
    					$register_success = User::model()->activateUser($x, $y);
    
                                            if($register_success == true)
                                            {
                                            // Set success message
    						Yii::app()->user->setFlash('success','You have now been registered!');
    						// render view
    						$this->render('verify');
                                            }
    										
    				} catch (InvalidActivationException $invalidActivationMessage) {
    					
    					 // Set error message	
    					 Yii::app()->user->setFlash('error',$invalidActivationMessage->getMessage());
    					 // render view
    					 $this->render('verify');
    				}
    
    			} else {
    				
    				// Set error message	
    				Yii::app()->user->setFlash('error','Bad activation length');
    				// render view
    				$this->render('verify');
    			} 
    
    		} else {
    			
    				// Set error message
    				Yii::app()->user->setFlash('error','Bad email format');
    				// render view
    				$this->render('verify');
    		}
    		
    	}
    
  7. Ok, i've made some progress here.

     

    public function actionIndex($id)
    	{
    		
    		//->with('areaItems')->find('t.id=:id', array(':id'=>$id))
    		
    		$dataProvider=new CActiveDataProvider('Area', array(
    			'criteria' => array(
    			'with' =>'areaItems',
    			'condition' => 't.id=:area_id',
    			'params' => array(':area_id'=>$id),
    		
    			),
    			'sort'=>array(
    			'attributes'=>array(
    				'title'=>array(
    				'asc'=>'title',
    				'desc'=>'title DESC'
    			  ),
    			  	'price'=>array(
    			  	'asc'=>'price',
    				'desc'=>'price DESC'
    			  )
    		 )
    	)
    		));
    		$this->render('index',array(
    			'dataProvider'=>$dataProvider,
    		));
    

     

    That now makes the links on teh clistView display as links. Which is a good step. My problem now is that when I try to sort these results I always get a 

     

    CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'price' in 'order clause'.
    
    

    I've tried referencing the related table by relation ("AreaItems.price") and also by table name ("item.price"). But all methods seem to fail.

  8. What I went for was:

    				Controller
    
    // rest of $_GET checks
    
                                     try{
    					// try to activate the user
    					User::model()->activateUser($x, $y);
    										
    				} catch (InvalidActivationException $invalidActivationMessage) {
    					
    					 // Set error message	
    					 Yii::app()->user->setFlash('error',$invalidActivationMessage->getMessage());
    					 // render view
    					 $this->render('verify');
    				}
    
    			} else {
    				
    				// Set error message	
    				Yii::app()->user->setFlash('error','Bad activation length');
    				// render view
    				$this->render('verify');
    			} 
    
    		} else {
    			
    				// Set error message
    				Yii::app()->user->setFlash('error','Bad email format');
    				// render view
    				$this->render('verify');
    		}
    		
    	}
    
    

     

    I put in my own custom exception like Antonio said

     

    Model.php was

     

    	public function activateUser($x, $y)
    	{
    		$model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y));
    		
    		if($model === NULL)
    		{
    		// No records returned throw error
    		throw new InvalidActivationException("Something bad happened");
    
    		} else {
    			// Record returned, validate new record
    			if($model->validate())
    			{
    				$model->active = NULL;
    				
    					if($model->save()) 
    					{
    					
    					}
    			}
    		}
    	}
    
    

     

    I wasn't sure exactly how to link the Model and controller when returning the boolean value. I'm sure it's pretty straight forward but today it's not happening for me.  :wacko:

  9. Hi Larry and all,

     

    I've got a small function in my user controller that just confirms an email address and activation code, I then use this to activate a user.

     

    // Start of function code is $x and $ y valid etc			
    	
                           User::model()->activateUser($x, $y);
    				
    			} else {
    				
    				Yii::app()->user->setFlash('error','Bad activation length');
    				$this->render('verify');
    			} 
    		} else {
    				Yii::app()->user->setFlash('error','Bad email format');
    				$this->render('verify');
    		}
    
    

     

    So in short, if $x or $y are invalid I set the flash message which works fine. However, I call this function (in bold) to update my User model.

     


    	public function activateUser($x, $y)
    	{
    		$model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y));
    		
    		if($model === NULL)
    		{
    
    		        throw new CDbException('These credentials, didn\'t match any records on file'); 
    } else { 
    // Record returned validate new record 
    if($model->validate()) {
     $model->active = NULL; 
    if($model->save()) 
    { 
    return 'ACTIVATED'; 
    }

     

     

     

     

     

     

     

     

    So I wasn't sure how I pass a database error in a tidy way, like a flash message to say to the user "These credentials didn't match anything on file." This just provides the detailed error report. Because you can't use $this-> render() from inside the model()??? In the same way I couldn't figure out how to go about passing a success 'Activated' message either. 

     

     

    Thanks

     

    Jonathon

  10. Hi,

     

    I'm building a little demo site in Yii. I wanted to give sellers some stats back on their items. These are the things i'd come up with so far. I haven't identified how I'm going to manage updating them and retrieving them yet. Just what i'm going to collect

     

    viewed items table:

     

    - id

    - session_id

    - user_id (For users that are logged in, NULL otherwise)

    - item_id

    - time_started

    - time_ended

     

    Through this I thought I could give sellers information on:

     

    - how many views

    - how many unique views

    - average time viewing the item

    - Also I could in some way through the session_id find "related items" or a "people who viewed this item also viewed this item"

     

    That's as far as i've got. Feel free to add or comment on them.

×
×
  • Create New...