Skip to content

Instantly share code, notes, and snippets.

@mdmunir
Last active July 9, 2017 01:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdmunir/f61cf632070d017beb4cdecceae77ecc to your computer and use it in GitHub Desktop.
Save mdmunir/f61cf632070d017beb4cdecceae77ecc to your computer and use it in GitHub Desktop.
Yii2 Tinymce widget
<?php
namespace app\controllers;
use Yii;
use mdm\upload\FileModel;
use yii\web\NotFoundHttpException;
use yii\imagine\Image;
use yii\helpers\FileHelper;
use yii\web\UploadedFile;
use yii\helpers\Url;
/**
* Use to show or download uploaded file. Add configuration to your application
*
* Then you can show your file in url `Url::to(['/image', 'id' => $file_id, 'width' => 50])`
*
* @author Misbahul D Munir <misbahuldmunir@gmail.com>
* @since 1.0
*/
class ImageController extends \yii\web\Controller
{
public $defaultAction = 'show';
public $savePath = '@runtime/thumbnails';
public $enableCsrfValidation = false;
/**
* Show file
* @param integer $id
*/
public function actionShow($id, $width = null, $height = null)
{
$model = $this->findModel($id);
$response = Yii::$app->getResponse();
if ($width === null && $height === null) {
return $response->sendFile($model->filename, $model->name, [
'mimeType' => $model->type,
'fileSize' => $model->size,
'inline' => true
]);
} else {
$dir = '';
if ($width !== null) {
$dir .= 'w' . (int) $width;
}
if ($height !== null) {
$dir .= 'h' . (int) $height;
}
$filename = sprintf('%s/%s/%x/%d_%s', Yii::getAlias($this->savePath), $dir, $id % 255, $id, $model->name);
if (!file_exists($filename)) {
FileHelper::createDirectory(dirname($filename));
$image = Image::thumbnail($model->filename, $width, $height);
$image->save($filename);
}
return $response->sendFile($filename, $model->name, [
'mimeType' => $model->type,
'inline' => true
]);
}
}
public function actionTinymceUpload()
{
Yii::$app->getResponse()->format = 'json';
$model = FileModel::saveAs('file', [
'saveCallback' => [$this, 'fixImageOrientation']
]);
if ($model) {
return ['location' => Url::to(['show', 'id' => $model->id], true)];
}
}
/**
*
* @param FileModel $model
*/
public function fixImageOrientation($model)
{
$map = [3 => 180, 6 => 90, 8 => -90];
$exif = exif_read_data($model->file->tempName);
if (!empty($exif['Orientation']) && isset($map[$exif['Orientation']])) {
Image::getImagine()->open($model->file->tempName)
->rotate($map[$exif['Orientation']])->strip()
->save($model->filename);
return true;
}
return $model->file->saveAs($model->filename, false);
}
/**
* Get model
* @param integer $id
* @return FileModel
* @throws NotFoundHttpException
*/
protected function findModel($id)
{
if (($model = FileModel::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
<?php
namespace app\widgets;
use Yii;
use yii\helpers\Html;
use yii\helpers\Json;
use yii\web\JsExpression;
use app\assets\TinymceAsset;
/**
* Description of Tinymce
*
* @author Misbahul D Munir <misbahuldmunir@gmail.com>
* @since 1.0
*/
class Tinymce extends \yii\widgets\InputWidget
{
public $clientOptions = [];
public function run()
{
$view = $this->view;
$clientOptions = $this->clientOptions;
if (empty($this->options['id'])) {
$this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId();
}
$clientOptions['selector'] = '#' . $this->options['id'];
$fileId = $this->options['id'] . '_file_input';
if (!isset($clientOptions['file_browser_callback'])) {
$callback = <<<JS
function(field_name, url, type, win) {
$('#$fileId').data('field_name', field_name);
$('#$fileId').trigger('click');
}
JS;
$clientOptions['file_browser_callback'] = new JsExpression($callback);
}
$imageUploadUrl = Json::encode(\yii\helpers\ArrayHelper::getValue($clientOptions, 'images_upload_url'));
$options = Json::encode($clientOptions);
$js = <<<JS
tinymce.init($options);
$('#$fileId').change(function(){
var input = this;
if (input.files && input.files[0]) {
var formData = new FormData();
formData.append('file', input.files[0]);
jQuery.ajax({
type: 'POST',
url: $imageUploadUrl,
data: formData,
contentType: false,
processData: false,
cache: false,
//dataType: 'json',
success: function(r) {
var fname = $(input).data('field_name');
$('#'+fname).val(r.location);
}
});
}
});
JS;
$view->registerJs($js);
TinymceAsset::register($view);
if ($this->hasModel()) {
echo Html::activeTextarea($this->model, $this->attribute, $this->options);
} else {
echo Html::textarea($this->name, $this->value, $this->options);
}
echo Html::fileInput('', '', ['id' => $fileId, 'style' => 'visibility:hidden;']);
}
}
<?php
namespace app\assets;
use Yii;
/**
* Description of TinymceAsset
*
* @author Misbahul D Munir <misbahuldmunir@gmail.com>
* @since 1.0
*/
class TinymceAsset extends \yii\web\AssetBundle
{
public $apiKey;
public $depends = ['yii\web\JqueryAsset'];
public function init()
{
parent::init();
if (empty($this->js)) {
$this->js = [
'http://cloud.tinymce.com/stable/tinymce.min.js' . ($this->apiKey ? "?apiKey={$this->apiKey}" : ''),
];
}
}
}
<?= $form->field($model, 'content')->widget('app\widgets\Tinymce',[
'options' => ['style' => 'height: 500px;'],
'clientOptions' => [
'plugins' => 'image',
'images_upload_url' => Url::to(['/image/tinymce-upload']),
'relative_urls' => false,
'remove_script_host' => false,
'file_browser_callback_types'=> 'image',
'menubar' => false,
]
]) ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment