Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
systems:yii2:file_upload [2018/02/28 16:28]
smayr [Model]
systems:yii2:file_upload [2018/03/01 16:22] (current)
smayr [View]
Line 468: Line 468:
  
 == Example Image Upload and Save Filename in DB == == Example Image Upload and Save Filename in DB ==
 +
 +=== Model ===
 +In the model, override ''afterSave()'' to store image file to server, and its path in the database. Eg: ''@app/models/Organization.php'':
 +<code php>
 +public function afterSave($insert, $changedAttributes)
 +{
 +    if(isset($this->logo)) {
 +        $this->logo = UploadedFile::getInstance($this, 'logo');
 +        if(is_object($this->logo)) {
 +            $path = Yii::$app->basePath . '/images/';                  // set directory path to save image
 +            $this->logo->saveAs("{$path}{$this->id}_{$this->logo}");   // saving image in folder
 +            $this->logo = "{$this->id}_{$this->logo}";                 // appending id to image name            
 +            \Yii::$app->db->createCommand()
 +                  ->update('organization', ['logo' => $this->logo], 'id = "'.$this->id.'"')
 +                  ->execute();    // manually update image name to db
 +        }
 +    }
 +}
 +</code>
  
 === Controller === === Controller ===
  
-Add action ''actionCreate()'' to model (here it is model ''organization''), and override ''afterSave()'' to store image file to server, and its path in the database:+Add action ''actionCreate()'' to controller. Eg: ''@app/controllers/OrganizationController.php'':
 <code php> <code php>
 public function actionCreate() public function actionCreate()
Line 485: Line 504:
   }   }
 } }
 +</code>
  
-public function afterSave($insert, $changedAttributes) +=== View === 
-+<code php
-    if(isset($this->logo)) { +<?$form->field($model, 'logo')->fileInput(['class'=>'form-control']?>
-        $this->logo = UploadedFile::getInstance($this, 'logo')+
-        if(is_object($this->logo)) { +
-            $path = Yii::$app->basePath . '/images/';               // set directory path to save image +
-            $this->logo->saveAs($path.$this->id."_".$this->logo);   // saving image in folder +
-            $this->logo = $this->id."_".$this->logo;                // appending id to image name             +
-            \Yii::$app->db->createCommand() +
-                  ->update('organization', ['logo' => $this->logo], 'id = "'.$this->id.'"') +
-                  ->execute();    // manually update image name to db +
-        } +
-    } +
-}+
 </code> </code>
  
Line 507: Line 516:
  
 === Model === === Model ===
 +File ''@app/models/ImageFileUpload.php'':
 <code php> <code php>
 <?php <?php
Line 572: Line 582:
 </code> </code>
  
 +File ''@app/models/Tool.php'':
 +<code php>
 +<?php
 +
 +namespace app\models;
 +
 +use Yii;
 +use yii\base\Model;         // parent for model classes not associated with database tables
 +//use yii\db\ActiveRecord;  // parent for model classes that do correspond to database tables
 +
 +define('PNG_DPI',      75);
 +define('LABEL_DPI',    300);
 +define('LABEL_WIDTH',  6);
 +define('LABEL_HEIGHT', 4);
 +define('LABEL_MARGIN', 5);
 +define('PNG_FONT',     5);
 +
 +/**
 + * This is the model class for table "Tools".
 + *
 + * @property array $countries
 + * @property array $countryNames
 + * @property array $languages
 + * @property array $states
 + */
 +class Tool extends Model
 +{
 +    //...
 +    
 +    /**
 +     * @inheritdoc
 +     * Usage: 
 +       return '<img src="data:image/png;base64,' . base64_encode(\app\models\Tool::generateEmptyPng()) . '"/>';
 +     */
 +    public static function generateEmptyPng() 
 +    {
 +        $image  = imagecreate(PNG_DPI * LABEL_WIDTH, PNG_DPI * LABEL_HEIGHT);
 +        $canvas = imagecreate(PNG_DPI * LABEL_WIDTH, PNG_DPI * LABEL_HEIGHT);
 +        
 +        // Setup color
 +        //$color_background = imagecolorallocate($image, 255, 255, 255);  // Background = white
 +        $color_background = imagecolorallocate($image, 200, 200, 200);  // Background = gray
 +        $color_text       = imagecolorallocate($image, 0, 0, 0);        // Foreground = black
 +        
 +        // Background
 +        imagefill($image, 0, 0, $color_background);
 +        
 +        // Image border
 +        //imagerectangle($image, 
 +        //    LABEL_MARGIN, LABEL_MARGIN,
 +        //    (LABEL_WIDTH*PNG_DPI)-LABEL_MARGIN, 
 +        //    (LABEL_HEIGHT*PNG_DPI)-LABEL_MARGIN,
 +        //    $color_text
 +        //);
 +        
 +        // Text content
 +        imagestring($image, PNG_FONT, 20, 20, 'NO IMAGE FILE', $color_text);
 +
 +        // Copy image to target canvas
 +        imagecopy(
 +            $canvas,                  // dst
 +            $image,                   // src
 +            0, 0,                     // dst x,y
 +            0, 0,                     // src x,y
 +            (LABEL_WIDTH  * PNG_DPI), // src width
 +            (LABEL_HEIGHT * PNG_DPI)  // src height
 +        );
 +        imagedestroy($image);
 +
 +        // Capture the full image from canvas
 +        ob_start();
 +        imagepng($canvas);
 +        $imageData = ob_get_contents();
 +        ob_end_clean();
 +
 +        return $imageData;
 +    }
 +}
 +?>
 +</code>
 === Controller === === Controller ===
  
 +File ''@app/controllers/ItemController.php'':
 <code php> <code php>
 //... //...
Line 650: Line 741:
  
 === View === === View ===
 +
 +File ''@app/views/item/upload-image'':
 +<code php>
 +<?php
 +use yii\helpers\Html;
 +use yii\helpers\Url;
 +use yii\widgets\ActiveForm;
 +use yii\helpers\ArrayHelper;
 +
 +$this->title = Yii::t('app', 'Image Upload');
 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Item'), 'url' => ['index']];
 +$this->params['breadcrumbs'][] = ['label' => "{$item->code} {$item->description}", 'url' => ['index']];
 +$this->params['breadcrumbs'][] = $this->title;
 +
 +?>
 +
 +<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
 +
 +    <h2><?= $this->title ?></h2>
 +    
 +    <div class="col-lg-12">
 +        <?php if(Yii::$app->session->hasFlash('success')): ?>
 +            <div class="alert alert-success" role="alert">
 +                <?= Yii::$app->session->getFlash('success'); ?>
 +            </div>
 +        <?php endif; ?>
 +        <?php if(Yii::$app->session->hasFlash('error')): ?>
 +            <div class="alert alert-danger" role="alert">
 +                <?= Yii::$app->session->getFlash('error'); ?>
 +            </div>
 +        <?php endif; ?>
 +    </div>
 +    
 +    <?= $form->field($model, 'imageFile')->fileInput(['class'=>'form-control']) ?>
 +
 +    <button class='btn btn-success'>Submit</button>
 +
 +<?php ActiveForm::end() ?>
 +</code>
 +
 +File ''@app/views/item/view.php'' to call ''@app/views/item/upload-image.php'' action:
 +<code php>
 +<?php
 +  $itemImage = (!empty($model->image_file) ? 
 +     Yii::$app->homeUrl . 'img/data/' . Yii::$app->controller->id . "/{$model->image_file}"
 +     ''
 +  );
 +?>
 +
 +<!-- Image Thumbnail -->
 +<?php if(!empty($itemImage)): ?>
 +    <img class="img-thumbnail" src="<?= $itemImage ?>" alt="Item Image">
 +<?php else: ?>
 +    <img class="img-thumbnail" src="data:image/png;base64,<?= base64_encode(\app\models\Tool::generateEmptyPng()) ?>"/>
 +<?php endif; ?>
 +
 +<!-- Button trigger modal for Image -->
 +<?= Html::button('<i class="fa fa-image" aria-hidden="true"></i> ' . Yii::t('app', 'View Image'), [
 +    'class'       => 'btn btn-default', 
 +    'data-toggle' => "modal",
 +    'data-target' => "#modalImagePreview"
 +]) ?>
 +<?= Html::a('<i class="fa fa-plus" aria-hidden="true"></i> ' . Yii::t('app', 'Add Image'), ['upload-image', 'id' => $model->id], ['class' => 'btn btn-default']) ?>
 +
 +<!-- Modal for Image -->
 +<div class="modal fade" id="modalImagePreview" tabindex="-1" role="dialog">
 +  <div class="modal-dialog modal-lg" role="document">
 +    <div class="modal-content">
 +      <div class="modal-header">
 +        <h5 class="modal-title">Item Image</h5>
 +        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
 +          <span aria-hidden="true">&times;</span>
 +        </button>
 +      </div>
 +      <div class="modal-body">
 +        <?php if(!empty($itemImage)): ?>
 +            <img class="img-fluid" src="<?= $itemImage ?>" alt="Item Image">
 +        <?php else: ?>
 +            <img class="img-fluid" src="data:image/png;base64,<?= base64_encode(\app\models\Tool::generateEmptyPng()) ?>"/>
 +        <?php endif; ?>
 +      </div>
 +      <div class="modal-footer">
 +        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
 +      </div>
 +    </div>
 +  </div>
 +</div>
 +</code>
 +
 +Or simply use the Yii modal helper:
 +<code php>
 +<?php
 +    $itemImage = (!empty($model->image_file) ? 
 +        Yii::$app->homeUrl . 'img/data/' . Yii::$app->controller->id . "/{$model->image_file}"
 +        ''
 +    );
 +
 +    // Image Thumbnail
 +    if(!empty($itemImage)) {
 +        echo "<img class='img-thumbnail' src='{$itemImage}' alt='Item Image'>";
 +    } else {
 +        echo "<img class='img-thumbnail' src='data:image/png;base64," . base64_encode(\app\models\Tool::generateEmptyPng()) . "'/>";
 +    }
 +    
 +    echo Html::a('<i class="fa fa-plus" aria-hidden="true"></i> ' . Yii::t('app', 'Add Image'), 
 +        ['upload-image', 'id' => $model->id], 
 +        ['class' => 'btn btn-default']
 +    );
 +
 +    // Modal Window
 +    yii\bootstrap\Modal::begin([
 +        'header' => '<h4>Item Image</h4>',
 +        'size'   => yii\bootstrap\Modal::SIZE_LARGE,
 +        'toggleButton' => [
 +            'label' => '<i class="fa fa-image" aria-hidden="true"></i> ' . Yii::t('app', 'View Image'), 
 +            'class' => 'btn btn-default'
 +        ],
 +    ]);
 +
 +    if(!empty($itemImage)) {
 +        echo "<img class='img-fluid' src='{$itemImage}' alt='Item Image'>";
 +    } else {
 +        echo "<img class='img-fluid' src='data:image/png;base64," . base64_encode(\app\models\Tool::generateEmptyPng()) . "'/>";
 +    }
 +    echo '<div class="modal-footer">';
 +    echo '    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>';
 +    echo '</div>';
 +
 +    yii\bootstrap\Modal::end();  
 +?>
 +</code>