formsfile-uploadyiiyii-widgets

How to save a binary directly to a database table field (JSON data) in Yii?


I'm working on a Yii project with a database, containing a table, where almost all it's data is saved in a field as JSON (it's crazy, but it is so as it is):

id      INTEGER
user_id INTEGER
data    LONGTEXT

This "JSON field" data has following structure and contains inter alia an image:

{
   "id":"1",
   "foo":"bar",
   ...
   "bat":{
      "baz":"buz",
      "name":"Joe Doe",
      "my_picture":"iVBORw0KGgoAAAANSUhEUgAAAGQA...", <-- binary
      ...
    }
}

Displaying it is no problem, but now I want to make the data ediable. My form looks like this:

<?php
$form=$this->beginWidget('CActiveForm', array(
    'id' => 'insurance-form',
    'htmlOptions' => array('enctype' => 'multipart/form-data'),
    'enableAjaxValidation'=>false,
));
?>
<div class="row">
    <?php echo $form->labelEx($model, 'provider_name'); ?>
    <?php
    echo $form->textField($model, 'data[provider][name]', array(
        'size'=>60, 'maxlength'=>255, "autocomplete"=>"off"
    ));
    ?>
    <?php echo $form->error($model, 'data[provider][name]'); ?>
</div>

It works.

I know, that for image upload I need fileField(...), but cannot find out, how to configure it in order to save the image directly to the database. How to do his?


Solution

  • view

    <div class="row">
        <?php echo $form->labelEx($model, 'provider_name'); ?>
        <?php
        echo $form->fileField($model, 'data[provider][name]', array());
        ?>
        <?php echo $form->error($model, 'data[provider][name]'); ?>
    </div>
    

    controller

    public function actionUpdate($id)
    {
        $model = $this->loadModel($id);
    
        if(isset($_POST['External'])) {
            $modelDataArray = $model->data;
    
            // adding the image as string to the POSted data
            if (isset($_FILES['MyModel']['name']['data']['provider']['picture'])) {
                $_POST['MyModel']['data']['provider']['picture'] = base64_encode(
                    file_get_contents($_FILES['MyModel']['tmp_name']['data']['provider']['picture'])
                );
            }
    
            $inputFieldData = $_POST['MyModel']['data'];            
            $updatedDataArray = array_replace_recursive($modelDataArray, $inputFieldData);
    
            $model->attributes = $_POST['MyModel'];
            $updatedDataJson = json_encode($updatedDataArray);
            $model->setAttribute('data', $updatedDataJson);
    
            if($model->save()) {
                $this->redirect(array('view', 'id' => $model->id));
            }
        }
    
        $this->render('update', array(
            'model' => $model,
        ));
    }
    

    CActiveRecord model

    no special changes