1

I'm trying to display link to an album/view through image that belongs to that album. I have my model 'Album' and there I have the relation with my 'Photo' model, which represents table where pictures are saved(or to be more accurate-picture names, pictures are saved in the folder 'uploads':

public function relations()
{
        return array(
                    'photos' => array(self::HAS_MANY, 'Photo', 'album_id'),
    );
}

Now I'm displaying album/index view, where I parse $dataProvider object which contains all my albums. Now that $dataProvider is parsed to a _view view and there I'm trying to access pictures (actually I just need one picture per album) that belongs to each album displayed. That picture will represent the link to an album/view view where one can see all pictures belonging to that album. I have no ide how to do that. I've tried with:

CHtml::link(
                    CHtml::image(Yii::app()->request->baseUrl."/uploads/thumbs/".$data->photos->name),
                    array('view', 'id'=>$data->id));

and I got the error: Trying to get property of non-object

PS: I have no problem with displaying all pictures within one album in album/view view (but these cross controllers, cross table whatever things are giving me hard time). There I have nested photo/index view, and the pictures are displayed like this:

echo CHtml::link(
                    CHtml::image(Yii::app()->request->baseUrl."/uploads/thumbs/".$data->name),
                    Yii::app()->request->baseUrl."/uploads/".$data->name ),

(as a link I'm displaying thumbnail of an image, that why i have "/uploads/thumbs/". "name" is column in table which represents filename of an image)

Edit 1

@Stu

in my album where I have three photos this:

array (size=3)
  0 => 
    object(Photo)[84]
      private '_uploads' => null
      private '_new' (CActiveRecord) => boolean false
      private '_attributes' (CActiveRecord) => 
        array (size=6)
          'id' => string '1' (length=1)
          'album_id' => string '1' (length=1)
          'name' => string 'WP_20140907_18_34_12_Pro.jpg' (length=28)
          'caption' => string 'Balerina' (length=8)
          'date_created' => string '2014-10-27 19:56:13' (length=19)
          'date_updated' => null
      private '_related' (CActiveRecord) => 
        array (size=0)
          empty
      private '_c' (CActiveRecord) => null
      private '_pk' (CActiveRecord) => string '1' (length=1)
      private '_alias' (CActiveRecord) => string 't' (length=1)
      private '_errors' (CModel) => 
        array (size=0)
          empty
      private '_validators' (CModel) => null
      private '_scenario' (CModel) => string 'update' (length=6)
      private '_e' (CComponent) => null
      private '_m' (CComponent) => null
  1 => 
    object(Photo)[85]
      private '_uploads' => null
      private '_new' (CActiveRecord) => boolean false
      private '_attributes' (CActiveRecord) => 
        array (size=6)
          'id' => string '2' (length=1)
          'album_id' => string '1' (length=1)
          'name' => string 'WP_20140907_18_49_33_Pro.jpg' (length=28)
          'caption' => string '' (length=0)
          'date_created' => string '2014-10-27 19:56:45' (length=19)
          'date_updated' => null
      private '_related' (CActiveRecord) => 
        array (size=0)
          empty
      private '_c' (CActiveRecord) => null
      private '_pk' (CActiveRecord) => string '2' (length=1)
      private '_alias' (CActiveRecord) => string 't' (length=1)
      private '_errors' (CModel) => 
        array (size=0)
          empty
      private '_validators' (CModel) => null
      private '_scenario' (CModel) => string 'update' (length=6)
      private '_e' (CComponent) => null
      private '_m' (CComponent) => null
  2 => 
    object(Photo)[86]
      private '_uploads' => null
      private '_new' (CActiveRecord) => boolean false
      private '_attributes' (CActiveRecord) => 
        array (size=6)
          'id' => string '3' (length=1)
          'album_id' => string '1' (length=1)
          'name' => string 'WP_20140907_18_49_38_Pro.jpg' (length=28)
          'caption' => string '' (length=0)
          'date_created' => string '2014-10-27 20:00:41' (length=19)
          'date_updated' => null
      private '_related' (CActiveRecord) => 
        array (size=0)
          empty
      private '_c' (CActiveRecord) => null
      private '_pk' (CActiveRecord) => string '3' (length=1)
      private '_alias' (CActiveRecord) => string 't' (length=1)
      private '_errors' (CModel) => 
        array (size=0)
          empty
      private '_validators' (CModel) => null
      private '_scenario' (CModel) => string 'update' (length=6)
      private '_e' (CComponent) => null
      private '_m' (CComponent) => null

Edit 2

This is really driving me crazy... In the same Album model, I have the other relation with other table "user":

public function relations()
    {
        return array(
            'owner' => array(self::BELONGS_TO, 'User', 'owner_id'),
            ...
        );
    }

And I have no problem accessing attributes in the User model within album view, checked the var_dump($data->owner):

object(User)[83]
  public 'passSave' => null
  public 'passRepeat' => null
  private '_new' (CActiveRecord) => boolean false
  private '_attributes' (CActiveRecord) => 
    array (size=7)
      'id' => string '1' (length=1)
      'email' => string 'fdhghhg@gmail.com' (length=25)
      'username' => string 'admin' (length=5)
      'firstname' => string 'Emina' (length=5)
      'lastname' => string 'Hasanović' (length=10)
      'pass' => string 'sa1aY64JOY94w' (length=13)
      'date_created' => string '2014-10-27 11:20:55' (length=19)
  private '_related' (CActiveRecord) => 
    array (size=0)
      empty
  private '_c' (CActiveRecord) => null
  private '_pk' (CActiveRecord) => string '1' (length=1)
  private '_alias' (CActiveRecord) => string 't' (length=1)
  private '_errors' (CModel) => 
    array (size=0)
      empty
  private '_validators' (CModel) => null
  private '_scenario' (CModel) => string 'update' (length=6)
  private '_e' (CComponent) => null
  private '_m' (CComponent) => null

It's the exact same output as with var_dump($data->lastPhoto) (just with it's own attributes), but when I try with $data->lastPhoto->name it's Trying to get property of non-object, while $data->owner->username works just well

Edit 3

Here is my Album model:

<?php

/**
 * This is the model class for table "album".
 *
 * The followings are the available columns in table 'album':
 * @property string $id
 * @property string $name
 * @property string $owner_id
 * @property integer $shareable
 * @property string $date_created
 *
 * The followings are the available model relations:
 * @property User $owner
 * @property Photo[] $photos
 */
class Album extends CActiveRecord
{

    public function tableName()
    {
        return 'album';
    }


    public function rules()
    {

        return array(
            array('name', 'required'),
            array('shareable', 'numerical', 'integerOnly'=>true),
            array('name', 'length', 'max'=>100),
            array('owner_id', 'length', 'max'=>10),
            array('name', 'safe', 'on'=>'search'),
        );
    }

        protected Function beforeSave() {
            if(parent::beforeSave()) {
                if($this->isNewRecord) {
                    $this->owner_id=Yii::app()->user->getId();
                }
                return true;
            }
            else 
                return false;            
        }


    public function relations()
    {           
        return array(
            'owner' => array(self::BELONGS_TO, 'User', 'owner_id'),
            'photos' => array(self::HAS_MANY, 'Photo', 'album_id'),
                        'lastPhoto' => array(self::HAS_ONE, 'Photo', 'album_id', 'order'=>'lastPhoto.id DESC'),
        );
    }

        public function scopes()
        {
            return array(
                'mine'=>array(
                    'order'=>'date_created DESC',
                    'condition'=>'owner_id=:owner',
                    'params'=>array(
                        'owner'=>Yii::app()->user->getId(),
                    )
                )
            );
        }    

    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'name' => 'Name',
            'owner_id' => 'Owner',
            'shareable' => 'Shareable',
            'date_created' => 'Date Created',
        );
    }


    public function search()
    {           

        $criteria=new CDbCriteria;    

        $criteria->compare('name',$this->name,true);            
        $criteria->compare('shareable',$this->shareable);           

        $criteria->scopes='mine';
        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }

    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }
}

Controller action is(from AlbumController):

public function actionIndex()
    {
                $dataProvider=new CActiveDataProvider('Album', array( 
                        'criteria'=>array(
                            'condition'=>'shareable=1',
                            'order'=>'date_created DESC'    
                            )
                        )
                );

        $this->render('index',array(
            'dataProvider'=>$dataProvider,
        ));
    }

And the view files are album/index.php:

<h1>Albums</h1>

<?php $this->widget('zii.widgets.CListView', array(
    'dataProvider'=>$dataProvider,
    'itemView'=>'_view',
)); ?> 

_view.php:

<div class="view">

        <h><?php // echo CHtml::encode($data->name); ?></h1>        

        <h1>
           echo CHtml::link(
                    CHtml::image(Yii::app()->request->baseUrl."/uploads/thumbs".$data->lastPhoto->name),
                    array('view', 'id'=>$data->id));                   

        ?>
        </h1>

        <br />
        <br />


    <b><?php  echo CHtml::encode($data->getAttributeLabel('shareable')); ?>:</b>
    <?php echo CHtml::encode($data->shareable)? 'Public' : 'No'; ?>
    <br />

    <b><?php  echo 'Created by'; ?>:</b>
    <?php echo CHtml::encode($data->owner->fullName()); ?>


    <b><?php  echo 'on Date'; ?>:</b>
    <?php echo CHtml::encode($data->date_created); ?>
    <br />

</div>
lin
  • 17,956
  • 4
  • 59
  • 83
  • `photos' => array(self::HAS_MANY, 'Photo', 'album_id'),` is implying your model has many photos, so in your view, `$data->photos` will probably be an array of photo models, not a model itself? – Stu Nov 06 '14 at 10:46
  • Well yes, that makes sense (I'm new to Yii so I don't now much). Now the question is, how to get first element of an array of photos belonging to that album and get to the attribute 'name' through relation 'photos' in my view – Emina Kešetović Nov 06 '14 at 11:34

1 Answers1

0

To get the first item in the photos relation, you could just call the first array value, although you may need to put some extra conditions in just in case it's an empty array and there's no value at all.

CHtml::link(
    CHtml::image(Yii::app()->request->baseUrl."/uploads/thumbs/".$data->photos[0]->name),
    array('view', 'id'=>$data->id)
);

Edit

Another option would be to limit the relation to only pull one row, rather than pulling all the relations and only using the first one:

public function relations()
{
    return array(
        ...
        'lastPhoto' => array(self::HAS_ONE, 'Photo', 'album_id', 'order'=>'lastPhoto.id DESC'),
        ...
    );
}

And call like so:

CHtml::link(
    CHtml::image(Yii::app()->request->baseUrl."/uploads/thumbs/".$data->lastPhoto->name),
    array('view', 'id'=>$data->id)
);
Stu
  • 4,160
  • 24
  • 43
  • I tried that already but I got the error: **Undefined offset: 0** – Emina Kešetović Nov 06 '14 at 11:45
  • what does `var_dump($data->photos);` output? – Stu Nov 06 '14 at 11:46
  • to an edit: tried that and again error: **Trying to get property of non-object** and here is output of var_dump($data->lastPhoto): http://pokit.org/get/?44503ed3e989f7a03185fda19dc88525.jpg – Emina Kešetović Nov 06 '14 at 15:12
  • That's odd, as you can see from the var dump, the Photo object has in the `_attributes` array a `name` with a value. This should be output through `$data->lastPhoto->name`. Can you post as an edit to your question the the controller action you're calling here, the Album model and the view file that's rendering? there must be something else preventing you from accessing it, as if the var_dump shows there's a value there, I can't see a reason it wouldn't output when you call it. – Stu Nov 07 '14 at 07:22
  • I got it! I was reading your answer and it just came to me... I had "Trying to get property of non-object" error, because of one test album that had no pictures in it. I've deleted that album and everything works just fine now. Such a dumb mistake. I didn't put any code to verify if the variable is empty. Now in my view I have `photos==NULL) { echo CHtml::link(CHtml::encode($data->name), array('view', 'id'=>$data->id)); } } else { echo CHtml::link(CHtml::image(Yii::app()->request->baseUrl.$data->photos[0]->getThumb()),array('view', 'id'=>$data->id));` – Emina Kešetović Nov 07 '14 at 11:39