1

I am using yii\bootstrap\Carousel and my image filename are stored in the database. Therefore, I need to retrieve the image file names and wrap them as image source and valid url before passing them to the Carousel widget. I have tried to perform this task from the controller but I am getting a challenge whereby nothing is passed in the array or an Invalid argument supplied for foreach() error message is returned. Here is my code:

Controller view action:

/**
 * Displays a single Listing model.
 * @param integer $id
 * @return mixed
 */
public function actionView($id)
{
    $model = $this->findModel($id);

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['view', 'id' => $model->listing_id]);
    } else {
        $count = \common\models\ListingImages::find()->count();
        // $query = new yii\db\Query;
        $images = \common\models\ListingImages::find()->where(['listing_id' => $model->listing_id])->all();

        if($count>0){
            $directory = Yii::$app->params['uploadUrl']; 
            $items = [];
            foreach($images as $image){
                $image_url_link = $image->image_url_link;
                $path = '@web/'. $directory . $image_url_link;
                $image_path = Html::img($path);
                $items = ArrayHelper::merge($image_path, $items);
            }
        } else {
            $items = [];
        }

        // echo var_dump($items);
        return $this->render('view', ['model' => $model, 'items' => $items]);
    }
}

And here is my view.php code:

<?php

use yii\helpers\Html;
use kartik\detail\DetailView;
use kartik\datecontrol\DateControl;
use yii\helpers\ArrayHelper;

/**
 * @var yii\web\View $this
 * @var common\models\Listing $model
 */

$this->title = $model->listing_title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Listings'), 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;

?>
<div>
    <p>
        <?= Html::a('Update', ['update', 'id' => $model->listing_id], ['class' => 'btn btn-primary']) ?>
        <?= Html::a('Delete', ['delete', 'id' => $model->listing_id], [
            'class' => 'btn btn-danger',
            'data' => [
                'confirm' => 'Are you sure you want to delete this Listing?',
                'method' => 'post',
            ],
        ]) ?>
    </p>

    <?php if (Yii::$app->session->hasFlash('delete_unsuccessful')): ?>
        <div class="alert alert-error alert-dismissable">
        <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
        <h4><i class="icon fa fa-check"></i>Unable to Delete!</h4>
        <?= Yii::$app->session->getFlash('delete_unsuccessful') ?>
        </div>
    <?php endif; ?>
</div>

<div class="row">
    <div class="col-md-8">
        <div class="box box-info">
            <div class="box-header with-border">
                <h3 class="box-title">Listing Images</h3>
            </div>
            <!-- /.box-header -->
            <div class="box-body">
                <?php echo yii\bootstrap\Carousel::widget(['items'=>$items]); ?>
            </div>
        </div>
    </div>
</div>

What I am expecting in the items array is something like

$items=[
  '<img src="http://placehold.it/1000x1000?text=Product+01">', 
'<img src="http://placehold.it/1000x1000?text=Product+02">', 
'<img src="http://placehold.it/1000x1000?text=Product+03">', 
'<img src="http://placehold.it/1000x1000?text=Product+04">', 
'<img src="http://placehold.it/1000x1000?text=Product+05">', 
'<img src="http://placehold.it/1000x1000?text=Product+06">', 
'<img src="http://placehold.it/1000x1000?text=Product+07">', 
'<img src="http://placehold.it/1000x1000?text=Product+08">'
];

Kindly assist me on where I am going wrong. I don't seem to find an answer online.

EDIT

This is what I get when I var_dump the variable $images just before the if function...

array(5) { [0]=> object(common\models\ListingImages)#167 (12) { ["filename"]=> NULL ["image"]=> NULL ["_attributes":"yii\db\BaseActiveRecord":private]=> array(7) { ["image_id"]=> int(9) ["listing_id"]=> int(28) ["image_url_link"]=> string(36) "sLgINOnRlkJuu6uKYwnAchcJswaiHxM-.jpg" ["updated_at"]=> string(19) "2018-11-09 12:48:34" ["created_at"]=> string(19) "2018-11-09 12:48:34" ["created_by"]=> int(2) ["active"]=> string(1) "Y" } ["_oldAttributes":"yii\db\BaseActiveRecord":private]=> array(7) { ["image_id"]=> int(9) ["listing_id"]=> int(28) ["image_url_link"]=> string(36) "sLgINOnRlkJuu6uKYwnAchcJswaiHxM-.jpg" ["updated_at"]=> string(19) "2018-11-09 12:48:34" ["created_at"]=> string(19) "2018-11-09 12:48:34" ["created_by"]=> int(2) ["active"]=> string(1) "Y" } ["_related":"yii\db\BaseActiveRecord":private]=> array(0) { } ["_relationsDependencies":"yii\db\BaseActiveRecord":private]=> array(0) { } ["_errors":"yii\base\Model":private]=> NULL ["_validators":"yii\base\Model":private]=> NULL ["_scenario":"yii\base\Model":private]=> string(7) "default" ["_events":"yii\base\Component":private]=> array(0) { } ["_eventWildcards":"yii\base\Component":private]=> array(0) { } ["_behaviors":"yii\base\Component":private]=> array(0) { } } [1]=> object(common\models\ListingImages)#178 (12) { ["filename"]=> NULL ["image"]=> NULL ["_attributes":"yii\db\BaseActiveRecord":private]=> array(7) { ["image_id"]=> int(10) ["listing_id"]=> int(28) ["image_url_link"]=> string(36) "ZKTPUE_dR7P3lF7CT9UZnOcC0ZL2Ws43.jpg" ["updated_at"]=> string(19) "2018-11-09 12:48:34" ["created_at"]=> string(19) "2018-11-09 12:48:34" ["created_by"]=> int(2) ["active"]=> string(1) "Y" } ["_oldAttributes":"yii\db\BaseActiveRecord":private]=> array(7) { ["image_id"]=> int(10) ["listing_id"]=> int(28) ["image_url_link"]=> string(36) "ZKTPUE_dR7P3lF7CT9UZnOcC0ZL2Ws43.jpg" ["updated_at"]=> string(19) "2018-11-09 12:48:34" ["created_at"]=> string(19) "2018-11-09 12:48:34" ["created_by"]=> int(2) ["active"]=> string(1) "Y" } ["_related":"yii\db\BaseActiveRecord":private]=> array(0) { } ["_relationsDependencies":"yii\db\BaseActiveRecord":private]=> array(0) { } ["_errors":"yii\base\Model":private]=> NULL ["_validators":"yii\base\Model":private]=> NULL ["_scenario":"yii\base\Model":private]=> string(7) "default" ["_events":"yii\base\Component":private]=> array(0) { } ["_eventWildcards":"yii\base\Component":private]=> array(0) { } ["_behaviors":"yii\base\Component":private]=> array(0) { } } [2]=> object(common\models\ListingImages)#179 (12) { ["filename"]=> NULL ["image"]=> NULL ["_attributes":"yii\db\BaseActiveRecord":private]=> array(7) { ["image_id"]=> int(11) ["listing_id"]=> int(28) ["image_url_link"]=> string(36) "vSZYiTTk1-bPk9MNGQ4RuU1Rih3adfgJ.jpg" ["updated_at"]=> string(19) "2018-11-09 12:48:35" ["created_at"]=> string(19) "2018-11-09 12:48:35" ["created_by"]=> int(2) ["active"]=> string(1) "Y" } ["_oldAttributes":"yii\db\BaseActiveRecord":private]=> array(7) { ["image_id"]=> int(11) ["listing_id"]=> int(28) ["image_url_link"]=> string(36) "vSZYiTTk1-bPk9MNGQ4RuU1Rih3adfgJ.jpg" ["updated_at"]=> string(19) "2018-11-09 12:48:35" ["created_at"]=> string(19) "2018-11-09 12:48:35" ["created_by"]=> int(2) ["active"]=> string(1) "Y" } ["_related":"yii\db\BaseActiveRecord":private

All the database values are loaded as expected.

Community
  • 1
  • 1
japheth
  • 373
  • 1
  • 10
  • 34
  • when it shows you the message for the invalid arguments in `foreach` are you sure it is retrieving the record from the databases against the given condition, can you add a sample array that is retrieved from the database against the query in your question – Muhammad Omer Aslam Nov 15 '18 at 12:59
  • @MuhammadOmerAslam, when I `var_dump` the `$images` variable just before the foreach loop, this is what I get an array with database values as expected. I have tried to edit the question to add the array but I am not seeing the edit option. – japheth Nov 15 '18 at 18:06
  • Actually, I noticed that the `invalid arguments in foreach` error is caused by this line, when trying to merge arrays into one: `$items = ArrayHelper::merge($image_path, $items);` and not the loop of the database items. – japheth Nov 15 '18 at 18:15
  • So, where the problem is is here: `$image_path = Html::img($path);`. It is returning an empty value that cuases an error when the ArrayHelper tries to merge to an array. Should that statement be like that? – japheth Nov 15 '18 at 18:17

1 Answers1

1

Well i don't find any good reason to use ArrayHelper::merge($image_path, $items); here as your variable $image_path is a string and not an array and ArrayHelper::merge() requires both parameters as arrays and not string, if you are worried about the duplicated images and want the output array to have unique images only you can simply change the code inside your action to the following.

$items = [];
foreach ($images as $image) {
    $image_url_link = "1000x1000";
    $path = '@web/' . "my-uploads" . $image_url_link;
    $items[] = \yii\helpers\Html::img($path);
}
$items = array_unique($items);
Muhammad Omer Aslam
  • 22,976
  • 9
  • 42
  • 68