1

I am new to the YII2 PHP framework. I want to implement Ckeditor in my TextArea. I got the library, but try to find an upload file using CKeidtor. I didn't get any idea how to implement file uploading in CkEditor. Library For CkEditor

9
  • you mean adding image in editor? Commented Sep 13, 2017 at 11:59
  • Yes. Can you help me please? Commented Sep 13, 2017 at 12:01
  • did you tried using clicking on image icon? it ask for url Commented Sep 13, 2017 at 12:02
  • That doesn't upload the image on server. Just show dialog box only. We have to code on that/ I am confuse how to do that. Commented Sep 13, 2017 at 12:03
  • 1
    try this <?= $form->field($model, 'email_content')->widget(CKEditor::className(), [ 'options' => ['rows' => 6], 'clientOptions' => [ 'filebrowserUploadUrl' => Url::to(['ckeditor/url']) ], 'preset' => 'full' ]) ?> it will show you upload option and you need to write upload action your own Commented Sep 13, 2017 at 12:27

2 Answers 2

1

If you are still looking for the solution or for other people. 2amigos built an amazing Library for ckeditor in Yii2. To implement it with image upload option you should set it like below:

 <?= $form->field($model, 'yourParameter')
         ->widget(CKEditor::className(), 
            [
              'options' => [], 
              'preset' => 'custom',
              'clientOptions' => [
                  'extraPlugins' => '',
                  'height' => 500,

                  //Here you give the action who will handle the image upload 
                  'filebrowserUploadUrl' => '/site/ckeditor_image_upload',

                  'toolbarGroups' => [
                      ['name' => 'undo'],
                      ['name' => 'basicstyles', 'groups' => ['basicstyles', 'cleanup']],
                      ['name' => 'paragraph', 'groups' => ['list', 'indent', 'blocks', 'align', 'bidi' ]],
                      ['name' => 'styles'],
                      ['name' => 'links', 'groups' => ['links', 'insert']]
                  ]

              ]

            ]) 

?>

Now because you have to build the image upload handler yourself, here is an example of how you should do it.

public function actionCkeditor_image_upload()
{       
    $funcNum = $_REQUEST['CKEditorFuncNum'];

    if($_FILES['upload']) {

      if (($_FILES['upload'] == "none") OR (empty($_FILES['upload']['name']))) {
      $message = Yii::t('app', "Please Upload an image.");
      }

      else if ($_FILES['upload']["size"] == 0 OR $_FILES['upload']["size"] > 5*1024*1024)
      {
      $message = Yii::t('app', "The image should not exceed 5MB.");
      }

      else if ( ($_FILES['upload']["type"] != "image/jpg") 
                AND ($_FILES['upload']["type"] != "image/jpeg") 
                AND ($_FILES['upload']["type"] != "image/png"))
      {
      $message = Yii::t('app', "The image type should be JPG , JPEG Or PNG.");
      }

      else if (!is_uploaded_file($_FILES['upload']["tmp_name"])){

      $message = Yii::t('app', "Upload Error, Please try again.");
      }

      else {
        //you need this (use yii\db\Expression;) for RAND() method 
        $random = rand(0123456789, 9876543210);

        $extension = pathinfo($_FILES['upload']['name'], PATHINFO_EXTENSION);

        //Rename the image here the way you want
        $name = date("m-d-Y-h-i-s", time())."-".$random.'.'.$extension; 

        // Here is the folder where you will save the images
        $folder = 'uploads/ckeditor_images/';  

        $url = Yii::$app->urlManager->createAbsoluteUrl($folder.$name);

        move_uploaded_file( $_FILES['upload']['tmp_name'], $folder.$name );

      }

      echo '<script type="text/javascript">window.parent.CKEDITOR.tools.callFunction("'
           .$funcNum.'", "'.$url.'", "'.$message.'" );</script>';

    }


}

Now because of CSRF-Token issue, the plugin can have problem sometimes. To solve it you can deactivate the CSRF Token only on this action like below:

 public function beforeAction($action)
{            
    if ($action->id == 'ckeditor_image_upload') {
        $this->enableCsrfValidation = false;
    }

    return parent::beforeAction($action);
}

The Image option is now ready to use.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your effort. i will check it tonight. For your effort -> up vote.
@NcitCosmos Can you provide the error message in your console or in your Network Panel?
0

For those who, as I did, looking for complete guide of file uploading with CKEditor (based on Francis's solution).

First of the wall, you should use 2amigos widget to get your life easier.

Render that widget in the view you want to contain CKEditor:

<?= $form->field($model, 'YOUR_FIELD_NAME')->widget(CKEditor::className(), [
    'preset' => 'full',
    'clientOptions' => [
        'filebrowserUploadUrl' => '/CONTROLLER_NAME/upload',
        'filebrowserBrowseUrl' => '/CONTROLLER_NAME/browse'
    ]
]);
?>

In code above, I've used full preset, you can use any one you like (or customize it with 'custom' value).

Note: you should attach your controller name in url strings, so it can be used both create and update actions


'filebrowserUploadUrl' => 'upload'

Here you should type name of action which will process file uploading. Francis do great job with example, so I can only say it should return JSON with such format:

//In case of success:
return [
                'fileName' => $NAME_OF_THE_FILE,
                'uploaded' => true,
                'url' => $URL_TO_SHOW_THE_FILE,
            ];
//In case of error:
return [
            'error' => [
                'message' => $MESSAGE_TEXT,
            ],
        ];

If your action will return anything but that JSON - it will show you alert with 'undefined' or 'Incorrect server response' message.


filebrowserBrowseUrl' => 'browse'

If you don't want to let users to browse uploaded files - just remove that line from widget options.

In other case you should add actionBrowse method to your controller, which will render page to browse and select images.

Controller method:

public function actionBrowse(){
    //get function num to pass it to the view (need to be called to pass data of selected file to CKEditor)
    $CKEditorFuncNum = Yii::$app->request->get('CKEditorFuncNum');

    //get list of uploaded files 
    $files = yii\helpers\FileHelper::findFiles($PATH_TO_FOLDER);

    return $this->renderAjax('browse', [
        'funcNum' => $CKEditorFuncNum,
        'files' => $files,
    ]);
}

Note: that view will be opened as modal dialog, so I prefer to use renderAjax instead of render function to avoid rendering layout. But I'll not recommend you to use renderPartial if you want to use asset bundles

View file:

use yii\helpers\Html;

\backend\assets\AppAsset::register($this);

?>
<div class="container">

<h1><?= Html::encode(Yii::t('common', 'Choose any file')) ?></h1>

<?php if (!empty($files)): ?>
    <div class="row">
        <?php foreach ($files as $file):
            $url = "/$file"; ?>
        <div class="col-md-4 mb-2">
            <img 
                src="<?= $url ?>" 
                class="img-thumbnail" 
                style="cursor: pointer; margin-bottom: 2rem"
                onClick="selectImage(<?= $funcNum ?>, '<?= $url ?>')"
            />
        </div>
        <?php endforeach; ?>
    </div>
<?php endif; ?>
</div>
<script type="text/javascript">
    function selectImage(funcNum, url){
        window.opener.CKEDITOR.tools.callFunction(funcNum, url)
        window.close()
    }
</script>

selectImage function here will call CKEditor function to pass image url to file upload modal and then close modal dialog.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.