Commit a8aa0f7dbe955359087b620c61586abb4ef4490b
1 parent
f80d13c8
Add new noam148 module because of search error
Showing
42 changed files
with
2601 additions
and
2 deletions
Show diff stats
1 | +MIT License | ||
2 | + | ||
3 | +Copyright (c) 2016 noam148 | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | +of this software and associated documentation files (the "Software"), to deal | ||
7 | +in the Software without restriction, including without limitation the rights | ||
8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | +copies of the Software, and to permit persons to whom the Software is | ||
10 | +furnished to do so, subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in all | ||
13 | +copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | +SOFTWARE. |
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager; | ||
4 | + | ||
5 | +use Yii; | ||
6 | +use yii\base\UnknownClassException; | ||
7 | +use yii\base\InvalidConfigException; | ||
8 | +use yii\web\AssetManager; | ||
9 | +use backend\components\noam148\imagemanager\assets\ImageManagerModuleAsset; | ||
10 | + | ||
11 | +/** | ||
12 | + * imagemanager module definition class | ||
13 | + */ | ||
14 | +class Module extends \yii\base\Module | ||
15 | +{ | ||
16 | + | ||
17 | + public $defaultRoute = 'manager'; | ||
18 | + //stylesheet for modal iframe | ||
19 | + public $cssFiles = []; | ||
20 | + //allowed Extensions for upload | ||
21 | + public $allowedFileExtensions = ['jpg', 'jpeg', 'gif', 'png']; | ||
22 | + //set assetPublishedUrl | ||
23 | + public $assetPublishedUrl; | ||
24 | + | ||
25 | + /** | ||
26 | + * @var bool|callable Variable that defines if the upload action will be available | ||
27 | + * This variable defaults to true, to enable uploading by default | ||
28 | + * It is also possible to give a callable function, in which case the function will be executed | ||
29 | + */ | ||
30 | + public $canUploadImage = true; | ||
31 | + | ||
32 | + /** | ||
33 | + * @var bool|callable Variable that defines if the delete action will be available | ||
34 | + * This variable default to true, to enable removal if image | ||
35 | + * It is also possible to give a callable function, in which case the function will be executed | ||
36 | + */ | ||
37 | + public $canRemoveImage = true; | ||
38 | + | ||
39 | + /** | ||
40 | + * @var bool|callable Variable that defines if blameable behavior is used. | ||
41 | + * This can be a boolean, or a callable function that returns a boolean | ||
42 | + */ | ||
43 | + public $setBlameableBehavior = false; | ||
44 | + | ||
45 | + /** | ||
46 | + * @var bool|callable Variable that defines if the original image that was used to make the crop will be deleted after the cropped image has been saved | ||
47 | + * By default the original and the cropped image will both be saved, this function can also be a callable. | ||
48 | + */ | ||
49 | + public $deleteOriginalAfterEdit = false; | ||
50 | + | ||
51 | + /** | ||
52 | + * @inheritdoc | ||
53 | + */ | ||
54 | + public function init() | ||
55 | + { | ||
56 | + parent::init(); | ||
57 | + //set language | ||
58 | + if (!isset(Yii::$app->i18n->translations['imagemanager'])) { | ||
59 | + Yii::$app->i18n->translations['imagemanager'] = [ | ||
60 | + 'class' => 'yii\i18n\PhpMessageSource', | ||
61 | + 'sourceLanguage' => 'en', | ||
62 | + 'basePath' => '@noam148/imagemanager/messages' | ||
63 | + ]; | ||
64 | + } | ||
65 | + //check extensions | ||
66 | + $this->_checkExtensionsExists(); | ||
67 | + //check mediaPath isset | ||
68 | + if (Yii::$app->imagemanager->mediaPath === null) { | ||
69 | + throw new InvalidConfigException("Component param 'mediaPath' need to be set to a location"); | ||
70 | + } | ||
71 | + //set asset path | ||
72 | + $this->assetPublishedUrl = (new AssetManager)->getPublishedUrl("@vendor/noam148/yii2-image-manager/assets/source"); | ||
73 | + | ||
74 | + // Check if the canRemoveImage variable is callable | ||
75 | + if (is_callable($this->canRemoveImage)) { | ||
76 | + $this->canRemoveImage = call_user_func($this->canRemoveImage); | ||
77 | + } | ||
78 | + | ||
79 | + // Check if the canUploadImage variable is callable | ||
80 | + if (is_callable($this->canUploadImage)) { | ||
81 | + $this->canUploadImage = call_user_func($this->canUploadImage); | ||
82 | + } | ||
83 | + | ||
84 | + // Check if blameable behavior is callable | ||
85 | + if (is_callable($this->setBlameableBehavior)) | ||
86 | + $this->setBlameableBehavior = call_user_func($this->setBlameableBehavior); | ||
87 | + | ||
88 | + // Check if the Delete original after crop variable is callable | ||
89 | + if (is_callable($this->deleteOriginalAfterEdit)) | ||
90 | + $this->deleteOriginalAfterEdit = call_user_func($this->deleteOriginalAfterEdit); | ||
91 | + | ||
92 | + // Check if the variable configuration is correct in order for the module to function | ||
93 | + $this->_checkVariableConfiguration(); | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * Check if extensions exists | ||
98 | + * @throws UnknownClassException Throw error if extension is not found | ||
99 | + */ | ||
100 | + private function _checkExtensionsExists() | ||
101 | + { | ||
102 | + //kartik file uploaded is installed | ||
103 | + if (!class_exists('kartik\file\FileInput')) { | ||
104 | + throw new UnknownClassException("Can't find: kartik\\file\FileInput. Install \"kartik-v/yii2-widget-fileinput\": \"@dev\""); | ||
105 | + } | ||
106 | + //check Yii imagine is installed | ||
107 | + if (!class_exists('yii\imagine\Image')) { | ||
108 | + throw new UnknownClassException("Can't find: yii\imagine\Image. Install \"yiisoft/yii2-imagine\": \"~2.0.0\""); | ||
109 | + } | ||
110 | + } | ||
111 | + | ||
112 | + /** | ||
113 | + * Check if the module variables have the content that is expected | ||
114 | + * @throws InvalidConfigException | ||
115 | + */ | ||
116 | + private function _checkVariableConfiguration() | ||
117 | + { | ||
118 | + // Check if the canUploadImage is boolean | ||
119 | + if (!is_bool($this->canUploadImage)) { | ||
120 | + throw new InvalidConfigException('$canUploadImage variable only supports a boolean value, if you have a custom function you must return a boolean.'); | ||
121 | + } | ||
122 | + // Check if the canRemoveImage is boolean | ||
123 | + if (!is_bool($this->canRemoveImage)) { | ||
124 | + throw new InvalidConfigException('$removeImageAllowed variable only supports a boolean value, if you have a custom function you must return a boolean.'); | ||
125 | + } | ||
126 | + // Check if the setBlamableBehavior is boolean | ||
127 | + if (!is_bool($this->setBlameableBehavior)) | ||
128 | + throw new InvalidConfigException('$setBlameableBehavior only supports a boolean value, if you have a custom function make sure that you return a boolean.'); | ||
129 | + // Check if the deleteOriginalAfterEdit is boolean | ||
130 | + if (!is_bool($this->deleteOriginalAfterEdit)) | ||
131 | + throw new InvalidConfigException('$deleteOriginalAfterEdit only supports boolean value, if you have a custom function make sure that your return a boolean.'); | ||
132 | + | ||
133 | + // Check if the blameable behavior is set to true | ||
134 | + if ($this->setBlameableBehavior) { | ||
135 | + // Get the migration record | ||
136 | + $mRecordMigrationRun = Yii::$app->db->createCommand('SELECT * FROM {{%migration}} WHERE `version` = \'m170223_113221_addBlameableBehavior\'')->queryOne(); | ||
137 | + if ($mRecordMigrationRun === false) { | ||
138 | + throw new InvalidConfigException('Image Manager: You have not run the latest migration, see the documentation how to do this.'); | ||
139 | + } | ||
140 | + } | ||
141 | + } | ||
142 | + | ||
143 | +} |
1 | +Image manager for Yii2 | ||
2 | +======================== | ||
3 | + | ||
4 | +A Yii2 module/widget for upload, manage and cropping images | ||
5 | + | ||
6 | +Installation | ||
7 | +------------ | ||
8 | +The preferred way to install this extension is through [composer](http://getcomposer.org/download/). | ||
9 | + | ||
10 | +* Either run | ||
11 | + | ||
12 | +``` | ||
13 | +php composer.phar require "noam148/yii2-image-manager" "*" | ||
14 | +``` | ||
15 | +or add | ||
16 | + | ||
17 | +```json | ||
18 | +"noam148/yii2-image-manager" : "*" | ||
19 | +``` | ||
20 | + | ||
21 | +to the require section of your application's `composer.json` file. | ||
22 | + | ||
23 | +* Run the migrate to create the ImageManager table | ||
24 | +``` | ||
25 | +yii migrate --migrationPath=@noam148/imagemanager/migrations | ||
26 | +``` | ||
27 | + | ||
28 | +* Add a new component in `components` section of your application's configuration file, for example: | ||
29 | + | ||
30 | +```php | ||
31 | +'components' => [ | ||
32 | + 'imagemanager' => [ | ||
33 | + 'class' => 'noam148\imagemanager\components\ImageManagerGetPath', | ||
34 | + //set media path (outside the web folder is possible) | ||
35 | + 'mediaPath' => '/path/where/to/store/images/media/imagemanager', | ||
36 | + //path relative web folder to store the cache images | ||
37 | + 'cachePath' => 'assets/images', | ||
38 | + //use filename (seo friendly) for resized images else use a hash | ||
39 | + 'useFilename' => true, | ||
40 | + //show full url (for example in case of a API) | ||
41 | + 'absoluteUrl' => false, | ||
42 | + 'databaseComponent' => 'db' // The used database component by the image manager, this defaults to the Yii::$app->db component | ||
43 | + ], | ||
44 | +], | ||
45 | +``` | ||
46 | + | ||
47 | +and in `modules` section, for example: | ||
48 | + | ||
49 | +```php | ||
50 | +'modules' => [ | ||
51 | + 'imagemanager' => [ | ||
52 | + 'class' => 'noam148\imagemanager\Module', | ||
53 | + //set accces rules () | ||
54 | + 'canUploadImage' => true, | ||
55 | + 'canRemoveImage' => function(){ | ||
56 | + return true; | ||
57 | + }, | ||
58 | + 'deleteOriginalAfterEdit' => false, // false: keep original image after edit. true: delete original image after edit | ||
59 | + // Set if blameable behavior is used, if it is, callable function can also be used | ||
60 | + 'setBlameableBehavior' => false, | ||
61 | + //add css files (to use in media manage selector iframe) | ||
62 | + 'cssFiles' => [ | ||
63 | + 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css', | ||
64 | + ], | ||
65 | + ], | ||
66 | +], | ||
67 | +``` | ||
68 | + | ||
69 | +Usage | ||
70 | +----- | ||
71 | +To reach the imagemanager module go to: | ||
72 | +``` | ||
73 | +http://www.example.com/imagemanager | ||
74 | +``` | ||
75 | + | ||
76 | + | ||
77 | + | ||
78 | +To load the image picker see below (make sure you have a field in you table where the module can store 'id' of the ImageManager table): | ||
79 | + | ||
80 | +```php | ||
81 | +echo $form->field($model, 'ImageManager_id_avatar')->widget(\noam148\imagemanager\components\ImageManagerInputWidget::className(), [ | ||
82 | + 'aspectRatio' => (16/9), //set the aspect ratio | ||
83 | + 'cropViewMode' => 1, //crop mode, option info: https://github.com/fengyuanchen/cropper/#viewmode | ||
84 | + 'showPreview' => true, //false to hide the preview | ||
85 | + 'showDeletePickedImageConfirm' => false, //on true show warning before detach image | ||
86 | +]); | ||
87 | +``` | ||
88 | + | ||
89 | + | ||
90 | + | ||
91 | +If you want to use a image: | ||
92 | + | ||
93 | +```php | ||
94 | +/* | ||
95 | + * $ImageManager_id (id that is store in the ImageManager table) | ||
96 | + * $width/$height width height of the image | ||
97 | + * $thumbnailMode = "outbound" or "inset" | ||
98 | + */ | ||
99 | +\Yii::$app->imagemanager->getImagePath($ImageManager_id, $width, $height,$thumbnailMode) | ||
100 | +``` | ||
101 | + | ||
102 | +Support CKEditor & TinyMce | ||
103 | +----- | ||
104 | +For using the filebrowser in CKEditor add the filebrowserImageBrowseUrl to the clientOptions of the CKEditor widget. I test it only for the CKEditor from 2amigOS but it need to work on other CKEditor widgets. | ||
105 | + | ||
106 | +```php | ||
107 | +use dosamigos\ckeditor\CKEditor; | ||
108 | + | ||
109 | + echo $form->field($model, 'text')->widget(CKEditor::className(), [ | ||
110 | + 'options' => ['rows' => 6], | ||
111 | + 'preset' => 'basic', | ||
112 | + 'clientOptions' => [ | ||
113 | + 'filebrowserImageBrowseUrl' => yii\helpers\Url::to(['imagemanager/manager', 'view-mode'=>'iframe', 'select-type'=>'ckeditor']), | ||
114 | + ] | ||
115 | +]); | ||
116 | +``` | ||
117 | + | ||
118 | +For using the filebrowser in TinyMce add the file_browser_callback to the clientOptions of the TinyMce widget. I test it only for the TinyMce from 2amigOS but it need to work on other TinyMce widgets. (don't forget add 'image' to your 'plugins' array) | ||
119 | + | ||
120 | +```php | ||
121 | +use dosamigos\tinymce\TinyMce; | ||
122 | + | ||
123 | +echo $form->field($model, 'text')->widget(TinyMce::className(), [ | ||
124 | + 'options' => ['rows' => 6], | ||
125 | + 'language' => 'nl', | ||
126 | + 'clientOptions' => [ | ||
127 | + 'file_browser_callback' => new yii\web\JsExpression("function(field_name, url, type, win) { | ||
128 | + window.open('".yii\helpers\Url::to(['imagemanager/manager', 'view-mode'=>'iframe', 'select-type'=>'tinymce'])."&tag_name='+field_name,'','width=800,height=540 ,toolbar=no,status=no,menubar=no,scrollbars=no,resizable=no'); | ||
129 | + }"), | ||
130 | + 'plugins' => [ | ||
131 | + "advlist autolink lists link charmap print preview anchor", | ||
132 | + "searchreplace visualblocks code fullscreen", | ||
133 | + "insertdatetime media table contextmenu paste image" | ||
134 | + ], | ||
135 | + 'toolbar' => "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" | ||
136 | + ] | ||
137 | +]); | ||
138 | +``` | ||
139 | + | ||
140 | +**If you got questions, tips or feedback? Please, let me know!** | ||
0 | \ No newline at end of file | 141 | \ No newline at end of file |
backend/components/noam148/imagemanager/assets/ImageManagerInputAsset.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager\assets; | ||
4 | + | ||
5 | +use yii\web\AssetBundle; | ||
6 | + | ||
7 | +/** | ||
8 | + * ImageManagerInputAsset. | ||
9 | + */ | ||
10 | +class ImageManagerInputAsset extends AssetBundle | ||
11 | +{ | ||
12 | + public $sourcePath = '@vendor/noam148/yii2-image-manager/assets/source'; | ||
13 | + public $css = [ | ||
14 | + 'css/imagemanager.input.css', | ||
15 | + ]; | ||
16 | + public $js = [ | ||
17 | + 'js/script.imagemanager.input.js', | ||
18 | + ]; | ||
19 | + public $depends = [ | ||
20 | + 'yii\web\JqueryAsset', | ||
21 | + 'yii\bootstrap\BootstrapPluginAsset', | ||
22 | + ]; | ||
23 | +} | ||
0 | \ No newline at end of file | 24 | \ No newline at end of file |
backend/components/noam148/imagemanager/assets/ImageManagerModuleAsset.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager\assets; | ||
4 | + | ||
5 | +use yii\web\AssetBundle; | ||
6 | + | ||
7 | +/** | ||
8 | + * ImageManagerModuleAsset. | ||
9 | + */ | ||
10 | +class ImageManagerModuleAsset extends AssetBundle | ||
11 | +{ | ||
12 | + public $sourcePath = '@vendor/noam148/yii2-image-manager/assets/source'; | ||
13 | + public $css = [ | ||
14 | + 'css/cropper.min.css', | ||
15 | + 'css/imagemanager.module.css', | ||
16 | + ]; | ||
17 | + public $js = [ | ||
18 | + 'js/cropper.min.js', | ||
19 | + 'js/script.imagemanager.module.js', | ||
20 | + ]; | ||
21 | + public $depends = [ | ||
22 | + 'yii\web\JqueryAsset', | ||
23 | + 'yii\bootstrap\BootstrapPluginAsset', | ||
24 | + ]; | ||
25 | +} | ||
0 | \ No newline at end of file | 26 | \ No newline at end of file |
backend/components/noam148/imagemanager/assets/source/css/cropper.min.css
0 → 100644
1 | +/*! | ||
2 | + * Cropper v2.3.2 | ||
3 | + * https://github.com/fengyuanchen/cropper | ||
4 | + * | ||
5 | + * Copyright (c) 2014-2016 Fengyuan Chen and contributors | ||
6 | + * Released under the MIT license | ||
7 | + * | ||
8 | + * Date: 2016-06-08T12:14:46.286Z | ||
9 | + */.cropper-container{font-size:0;line-height:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;direction:ltr!important;-ms-touch-action:none;touch-action:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.cropper-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:100%;min-height:0!important;max-height:none!important;image-orientation:0deg!important}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-wrap-box{overflow:hidden}.cropper-drag-box{opacity:0;background-color:#fff;filter:alpha(opacity=0)}.cropper-dashed,.cropper-modal{opacity:.5;filter:alpha(opacity=50)}.cropper-modal{background-color:#000}.cropper-view-box{display:block;overflow:hidden;width:100%;height:100%;outline:#39f solid 1px;outline-color:rgba(51,153,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #eee}.cropper-dashed.dashed-h{top:33.33333%;left:0;width:100%;height:33.33333%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.33333%;width:33.33333%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-center{position:absolute;top:50%;left:50%;display:block;width:0;height:0;opacity:.75;filter:alpha(opacity=75)}.cropper-center:after,.cropper-center:before{position:absolute;display:block;content:' ';background-color:#eee}.cropper-center:before{top:0;left:-3px;width:7px;height:1px}.cropper-center:after{top:-3px;left:0;width:1px;height:7px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;opacity:.1;filter:alpha(opacity=10)}.cropper-face{top:0;left:0;background-color:#fff}.cropper-line,.cropper-point{background-color:#39f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;opacity:1;filter:alpha(opacity=100)}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:' ';opacity:0;background-color:#39f;filter:alpha(opacity=0)}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}}.cropper-invisible{opacity:0;filter:alpha(opacity=0)}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{position:absolute;display:block;width:0;height:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed} | ||
0 | \ No newline at end of file | 10 | \ No newline at end of file |
backend/components/noam148/imagemanager/assets/source/css/imagemanager.input.css
0 → 100644
1 | +#modal-imagemanager { | ||
2 | + z-index: 999999; | ||
3 | +} | ||
4 | + | ||
5 | +#modal-imagemanager .modal-header h4 { | ||
6 | + margin: 0; | ||
7 | +} | ||
8 | + | ||
9 | +#modal-imagemanager iframe { | ||
10 | + border: none; | ||
11 | + width: 100%; | ||
12 | + min-height: 500px; | ||
13 | +} | ||
14 | + | ||
15 | +.image-manager-input { | ||
16 | +} | ||
17 | + | ||
18 | +.image-manager-input .image-wrapper { | ||
19 | + margin-top: 10px; | ||
20 | + border: 1px solid #ddd; | ||
21 | + border-radius: 4px; | ||
22 | + display: inline-block; | ||
23 | + padding: 4px; | ||
24 | + background: #FFF; | ||
25 | +} | ||
26 | + | ||
27 | +.image-manager-input .image-wrapper .img-preview { | ||
28 | + background: #dadada; | ||
29 | + max-width: 200px; | ||
30 | + max-height: 200px; | ||
31 | + height: auto; | ||
32 | + line-height: 1.42857; | ||
33 | +} | ||
0 | \ No newline at end of file | 34 | \ No newline at end of file |
backend/components/noam148/imagemanager/assets/source/css/imagemanager.module.css
0 → 100644
1 | +/*CSS for module*/ | ||
2 | +#module-imagemanager { | ||
3 | + padding-left: 0; | ||
4 | + padding-right: 0; | ||
5 | +} | ||
6 | + | ||
7 | +#module-imagemanager > .row { | ||
8 | + margin: 0; | ||
9 | +} | ||
10 | + | ||
11 | +#module-imagemanager.tinymce, | ||
12 | +#module-imagemanager.ckeditor { | ||
13 | + padding: 15px; | ||
14 | +} | ||
15 | + | ||
16 | +/*overview*/ | ||
17 | +#module-imagemanager > .row .col-overview { | ||
18 | + padding-left: 0; | ||
19 | + padding-right: 0; | ||
20 | + border-right: 1px solid #ddd; | ||
21 | + height: 100%; | ||
22 | + overflow: auto; | ||
23 | +} | ||
24 | + | ||
25 | +#module-imagemanager > .row .col-overview .item-overview { | ||
26 | + max-height: 500px; | ||
27 | + overflow: auto; | ||
28 | +} | ||
29 | + | ||
30 | +#module-imagemanager > .row .col-overview .item-overview .item { | ||
31 | + position: relative; | ||
32 | + overflow: hidden; | ||
33 | + width: 128px; | ||
34 | + height: 128px; | ||
35 | + cursor: pointer; | ||
36 | +} | ||
37 | + | ||
38 | +#module-imagemanager > .row .col-overview .item-overview .item.selected { | ||
39 | + background: #00ac24; | ||
40 | +} | ||
41 | + | ||
42 | +#module-imagemanager > .row .col-overview .item-overview .item .thumbnail { | ||
43 | + margin-bottom: 0; | ||
44 | +} | ||
45 | + | ||
46 | +#module-imagemanager > .row .col-overview .item-overview .item .thumbnail img { | ||
47 | + max-height: 118px; | ||
48 | + background: #dadada; | ||
49 | +} | ||
50 | + | ||
51 | +#module-imagemanager > .row .col-overview .item-overview .item .thumbnail .filename { | ||
52 | + background-color: rgba(255, 255, 255, 0.9); | ||
53 | + position: absolute; | ||
54 | + bottom: 4px; | ||
55 | + left: 4px; | ||
56 | + right: 4px; | ||
57 | + max-height: 100%; | ||
58 | + overflow: hidden; | ||
59 | + white-space: nowrap; | ||
60 | + text-overflow: ellipsis; | ||
61 | + padding: 0 10px; | ||
62 | +} | ||
63 | + | ||
64 | +/*edit column*/ | ||
65 | +#module-imagemanager > .row .col-image-editor { | ||
66 | + padding-left: 0; | ||
67 | + display: none; | ||
68 | +} | ||
69 | + | ||
70 | +/*cropper*/ | ||
71 | +#module-imagemanager > .row .col-image-editor .image-cropper .image-wrapper { | ||
72 | + max-height: 460px; | ||
73 | +} | ||
74 | + | ||
75 | +#module-imagemanager > .row .col-image-editor .image-cropper .image-wrapper img#image-cropper { | ||
76 | + max-width: 100%; | ||
77 | +} | ||
78 | + | ||
79 | +/*options*/ | ||
80 | +#module-imagemanager > .row .col-options { | ||
81 | + padding-right: 0; | ||
82 | +} | ||
83 | + | ||
84 | +/*File upload*/ | ||
85 | +#module-imagemanager > .row .col-options .file-input .form-control { | ||
86 | + display: none; | ||
87 | +} | ||
88 | + | ||
89 | +#module-imagemanager > .row .col-options .form-group .file-input .input-group, | ||
90 | +#module-imagemanager > .row .col-options .form-group .file-input .input-group .input-group-btn { | ||
91 | + float: left; | ||
92 | +} | ||
93 | + | ||
94 | +#module-imagemanager > .row .col-options .form-group .btn-add-flyleaf { | ||
95 | + float: left; | ||
96 | +} | ||
97 | + | ||
98 | +/*details*/ | ||
99 | +#module-imagemanager > .row .col-options .image-info { | ||
100 | + margin-top: 10px; | ||
101 | +} | ||
102 | + | ||
103 | +#module-imagemanager > .row .col-options .image-info .thumbnail { | ||
104 | + margin-bottom: 10px; | ||
105 | +} | ||
106 | + | ||
107 | +#module-imagemanager > .row .col-options .image-info .thumbnail img { | ||
108 | + max-width: 100%; | ||
109 | + background: #dadada; | ||
110 | +} | ||
111 | + | ||
112 | +#module-imagemanager > .row .col-options .image-info .edit-buttons { | ||
113 | + margin-bottom: 10px; | ||
114 | +} | ||
115 | + | ||
116 | +#module-imagemanager > .row .col-options .image-info .details { | ||
117 | +} | ||
118 | + | ||
119 | +#module-imagemanager > .row .col-options .image-info .details .fileName { | ||
120 | + font-weight: bold; | ||
121 | + overflow: hidden; | ||
122 | + white-space: nowrap; | ||
123 | + text-overflow: ellipsis; | ||
124 | +} | ||
125 | + | ||
126 | +#module-imagemanager > .row .col-options .image-info .pick-image-item { | ||
127 | + margin-top: 10px; | ||
128 | +} | ||
129 | + | ||
130 | +#module-imagemanager a.delete-image-item { | ||
131 | + margin-top: 5px; | ||
132 | +} | ||
0 | \ No newline at end of file | 133 | \ No newline at end of file |
backend/components/noam148/imagemanager/assets/source/img/img_no-image.png
0 → 100644
8.26 KB
backend/components/noam148/imagemanager/assets/source/js/cropper.min.js
0 → 100644
1 | +/*! | ||
2 | + * Cropper v2.3.2 | ||
3 | + * https://github.com/fengyuanchen/cropper | ||
4 | + * | ||
5 | + * Copyright (c) 2014-2016 Fengyuan Chen and contributors | ||
6 | + * Released under the MIT license | ||
7 | + * | ||
8 | + * Date: 2016-06-08T12:14:46.286Z | ||
9 | + */ | ||
10 | +!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t("object"==typeof exports?require("jquery"):jQuery)}(function(t){"use strict";function i(t){return"number"==typeof t&&!isNaN(t)}function e(t){return"undefined"==typeof t}function s(t,e){var s=[];return i(e)&&s.push(e),s.slice.apply(t,s)}function a(t,i){var e=s(arguments,2);return function(){return t.apply(i,e.concat(s(arguments)))}}function o(t){var i=t.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i);return i&&(i[1]!==C.protocol||i[2]!==C.hostname||i[3]!==C.port)}function h(t){var i="timestamp="+(new Date).getTime();return t+(-1===t.indexOf("?")?"?":"&")+i}function n(t){return t?' crossOrigin="'+t+'"':""}function r(t,i){var e;return t.naturalWidth&&!mt?i(t.naturalWidth,t.naturalHeight):(e=document.createElement("img"),e.onload=function(){i(this.width,this.height)},void(e.src=t.src))}function p(t){var e=[],s=t.rotate,a=t.scaleX,o=t.scaleY;return i(a)&&i(o)&&e.push("scale("+a+","+o+")"),i(s)&&e.push("rotate("+s+"deg)"),e.length?e.join(" "):"none"}function c(t,i){var e,s,a=Ct(t.degree)%180,o=(a>90?180-a:a)*Math.PI/180,h=bt(o),n=Bt(o),r=t.width,p=t.height,c=t.aspectRatio;return i?(e=r/(n+h/c),s=e/c):(e=r*n+p*h,s=r*h+p*n),{width:e,height:s}}function l(e,s){var a,o,h,n=t("<canvas>")[0],r=n.getContext("2d"),p=0,l=0,d=s.naturalWidth,g=s.naturalHeight,u=s.rotate,f=s.scaleX,m=s.scaleY,v=i(f)&&i(m)&&(1!==f||1!==m),w=i(u)&&0!==u,x=w||v,C=d*Ct(f||1),b=g*Ct(m||1);return v&&(a=C/2,o=b/2),w&&(h=c({width:C,height:b,degree:u}),C=h.width,b=h.height,a=C/2,o=b/2),n.width=C,n.height=b,x&&(p=-d/2,l=-g/2,r.save(),r.translate(a,o)),v&&r.scale(f,m),w&&r.rotate(u*Math.PI/180),r.drawImage(e,$t(p),$t(l),$t(d),$t(g)),x&&r.restore(),n}function d(i){var e=i.length,s=0,a=0;return e&&(t.each(i,function(t,i){s+=i.pageX,a+=i.pageY}),s/=e,a/=e),{pageX:s,pageY:a}}function g(t,i,e){var s,a="";for(s=i,e+=i;e>s;s++)a+=Lt(t.getUint8(s));return a}function u(t){var i,e,s,a,o,h,n,r,p,c,l=new D(t),d=l.byteLength;if(255===l.getUint8(0)&&216===l.getUint8(1))for(p=2;d>p;){if(255===l.getUint8(p)&&225===l.getUint8(p+1)){n=p;break}p++}if(n&&(e=n+4,s=n+10,"Exif"===g(l,e,4)&&(h=l.getUint16(s),o=18761===h,(o||19789===h)&&42===l.getUint16(s+2,o)&&(a=l.getUint32(s+4,o),a>=8&&(r=s+a)))),r)for(d=l.getUint16(r,o),c=0;d>c;c++)if(p=r+12*c+2,274===l.getUint16(p,o)){p+=8,i=l.getUint16(p,o),mt&&l.setUint16(p,1,o);break}return i}function f(t){var i,e=t.replace(G,""),s=atob(e),a=s.length,o=new B(a),h=new y(o);for(i=0;a>i;i++)h[i]=s.charCodeAt(i);return o}function m(t){var i,e=new y(t),s=e.length,a="";for(i=0;s>i;i++)a+=Lt(e[i]);return"data:image/jpeg;base64,"+$(a)}function v(i,e){this.$element=t(i),this.options=t.extend({},v.DEFAULTS,t.isPlainObject(e)&&e),this.isLoaded=!1,this.isBuilt=!1,this.isCompleted=!1,this.isRotated=!1,this.isCropped=!1,this.isDisabled=!1,this.isReplaced=!1,this.isLimited=!1,this.wheeling=!1,this.isImg=!1,this.originalUrl="",this.canvas=null,this.cropBox=null,this.init()}var w=t(window),x=t(document),C=window.location,b=window.navigator,B=window.ArrayBuffer,y=window.Uint8Array,D=window.DataView,$=window.btoa,L="cropper",T="cropper-modal",X="cropper-hide",Y="cropper-hidden",k="cropper-invisible",M="cropper-move",W="cropper-crop",H="cropper-disabled",R="cropper-bg",z="mousedown touchstart pointerdown MSPointerDown",O="mousemove touchmove pointermove MSPointerMove",P="mouseup touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel",E="wheel mousewheel DOMMouseScroll",U="dblclick",I="load."+L,F="error."+L,j="resize."+L,A="build."+L,S="built."+L,N="cropstart."+L,_="cropmove."+L,q="cropend."+L,K="crop."+L,Z="zoom."+L,Q=/e|w|s|n|se|sw|ne|nw|all|crop|move|zoom/,V=/^data\:/,G=/^data\:([^\;]+)\;base64,/,J=/^data\:image\/jpeg.*;base64,/,tt="preview",it="action",et="e",st="w",at="s",ot="n",ht="se",nt="sw",rt="ne",pt="nw",ct="all",lt="crop",dt="move",gt="zoom",ut="none",ft=t.isFunction(t("<canvas>")[0].getContext),mt=b&&/(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(b.userAgent),vt=Number,wt=Math.min,xt=Math.max,Ct=Math.abs,bt=Math.sin,Bt=Math.cos,yt=Math.sqrt,Dt=Math.round,$t=Math.floor,Lt=String.fromCharCode;v.prototype={constructor:v,init:function(){var t,i=this.$element;if(i.is("img")){if(this.isImg=!0,this.originalUrl=t=i.attr("src"),!t)return;t=i.prop("src")}else i.is("canvas")&&ft&&(t=i[0].toDataURL());this.load(t)},trigger:function(i,e){var s=t.Event(i,e);return this.$element.trigger(s),s},load:function(i){var e,s,a=this.options,n=this.$element;if(i&&(n.one(A,a.build),!this.trigger(A).isDefaultPrevented())){if(this.url=i,this.image={},!a.checkOrientation||!B)return this.clone();if(e=t.proxy(this.read,this),V.test(i))return J.test(i)?e(f(i)):this.clone();s=new XMLHttpRequest,s.onerror=s.onabort=t.proxy(function(){this.clone()},this),s.onload=function(){e(this.response)},a.checkCrossOrigin&&o(i)&&n.prop("crossOrigin")&&(i=h(i)),s.open("get",i),s.responseType="arraybuffer",s.send()}},read:function(t){var i,e,s,a=this.options,o=u(t),h=this.image;if(o>1)switch(this.url=m(t),o){case 2:e=-1;break;case 3:i=-180;break;case 4:s=-1;break;case 5:i=90,s=-1;break;case 6:i=90;break;case 7:i=90,e=-1;break;case 8:i=-90}a.rotatable&&(h.rotate=i),a.scalable&&(h.scaleX=e,h.scaleY=s),this.clone()},clone:function(){var i,e,s=this.options,a=this.$element,r=this.url,p="";s.checkCrossOrigin&&o(r)&&(p=a.prop("crossOrigin"),p?i=r:(p="anonymous",i=h(r))),this.crossOrigin=p,this.crossOriginUrl=i,this.$clone=e=t("<img"+n(p)+' src="'+(i||r)+'">'),this.isImg?a[0].complete?this.start():a.one(I,t.proxy(this.start,this)):e.one(I,t.proxy(this.start,this)).one(F,t.proxy(this.stop,this)).addClass(X).insertAfter(a)},start:function(){var i=this.$element,e=this.$clone;this.isImg||(e.off(F,this.stop),i=e),r(i[0],t.proxy(function(i,e){t.extend(this.image,{naturalWidth:i,naturalHeight:e,aspectRatio:i/e}),this.isLoaded=!0,this.build()},this))},stop:function(){this.$clone.remove(),this.$clone=null},build:function(){var i,e,s,a=this.options,o=this.$element,h=this.$clone;this.isLoaded&&(this.isBuilt&&this.unbuild(),this.$container=o.parent(),this.$cropper=i=t(v.TEMPLATE),this.$canvas=i.find(".cropper-canvas").append(h),this.$dragBox=i.find(".cropper-drag-box"),this.$cropBox=e=i.find(".cropper-crop-box"),this.$viewBox=i.find(".cropper-view-box"),this.$face=s=e.find(".cropper-face"),o.addClass(Y).after(i),this.isImg||h.removeClass(X),this.initPreview(),this.bind(),a.aspectRatio=xt(0,a.aspectRatio)||NaN,a.viewMode=xt(0,wt(3,Dt(a.viewMode)))||0,a.autoCrop?(this.isCropped=!0,a.modal&&this.$dragBox.addClass(T)):e.addClass(Y),a.guides||e.find(".cropper-dashed").addClass(Y),a.center||e.find(".cropper-center").addClass(Y),a.cropBoxMovable&&s.addClass(M).data(it,ct),a.highlight||s.addClass(k),a.background&&i.addClass(R),a.cropBoxResizable||e.find(".cropper-line, .cropper-point").addClass(Y),this.setDragMode(a.dragMode),this.render(),this.isBuilt=!0,this.setData(a.data),o.one(S,a.built),setTimeout(t.proxy(function(){this.trigger(S),this.trigger(K,this.getData()),this.isCompleted=!0},this),0))},unbuild:function(){this.isBuilt&&(this.isBuilt=!1,this.isCompleted=!1,this.initialImage=null,this.initialCanvas=null,this.initialCropBox=null,this.container=null,this.canvas=null,this.cropBox=null,this.unbind(),this.resetPreview(),this.$preview=null,this.$viewBox=null,this.$cropBox=null,this.$dragBox=null,this.$canvas=null,this.$container=null,this.$cropper.remove(),this.$cropper=null)},render:function(){this.initContainer(),this.initCanvas(),this.initCropBox(),this.renderCanvas(),this.isCropped&&this.renderCropBox()},initContainer:function(){var t=this.options,i=this.$element,e=this.$container,s=this.$cropper;s.addClass(Y),i.removeClass(Y),s.css(this.container={width:xt(e.width(),vt(t.minContainerWidth)||200),height:xt(e.height(),vt(t.minContainerHeight)||100)}),i.addClass(Y),s.removeClass(Y)},initCanvas:function(){var i,e=this.options.viewMode,s=this.container,a=s.width,o=s.height,h=this.image,n=h.naturalWidth,r=h.naturalHeight,p=90===Ct(h.rotate),c=p?r:n,l=p?n:r,d=c/l,g=a,u=o;o*d>a?3===e?g=o*d:u=a/d:3===e?u=a/d:g=o*d,i={naturalWidth:c,naturalHeight:l,aspectRatio:d,width:g,height:u},i.oldLeft=i.left=(a-g)/2,i.oldTop=i.top=(o-u)/2,this.canvas=i,this.isLimited=1===e||2===e,this.limitCanvas(!0,!0),this.initialImage=t.extend({},h),this.initialCanvas=t.extend({},i)},limitCanvas:function(t,i){var e,s,a,o,h=this.options,n=h.viewMode,r=this.container,p=r.width,c=r.height,l=this.canvas,d=l.aspectRatio,g=this.cropBox,u=this.isCropped&&g;t&&(e=vt(h.minCanvasWidth)||0,s=vt(h.minCanvasHeight)||0,n&&(n>1?(e=xt(e,p),s=xt(s,c),3===n&&(s*d>e?e=s*d:s=e/d)):e?e=xt(e,u?g.width:0):s?s=xt(s,u?g.height:0):u&&(e=g.width,s=g.height,s*d>e?e=s*d:s=e/d)),e&&s?s*d>e?s=e/d:e=s*d:e?s=e/d:s&&(e=s*d),l.minWidth=e,l.minHeight=s,l.maxWidth=1/0,l.maxHeight=1/0),i&&(n?(a=p-l.width,o=c-l.height,l.minLeft=wt(0,a),l.minTop=wt(0,o),l.maxLeft=xt(0,a),l.maxTop=xt(0,o),u&&this.isLimited&&(l.minLeft=wt(g.left,g.left+g.width-l.width),l.minTop=wt(g.top,g.top+g.height-l.height),l.maxLeft=g.left,l.maxTop=g.top,2===n&&(l.width>=p&&(l.minLeft=wt(0,a),l.maxLeft=xt(0,a)),l.height>=c&&(l.minTop=wt(0,o),l.maxTop=xt(0,o))))):(l.minLeft=-l.width,l.minTop=-l.height,l.maxLeft=p,l.maxTop=c))},renderCanvas:function(t){var i,e,s=this.canvas,a=this.image,o=a.rotate,h=a.naturalWidth,n=a.naturalHeight;this.isRotated&&(this.isRotated=!1,e=c({width:a.width,height:a.height,degree:o}),i=e.width/e.height,i!==s.aspectRatio&&(s.left-=(e.width-s.width)/2,s.top-=(e.height-s.height)/2,s.width=e.width,s.height=e.height,s.aspectRatio=i,s.naturalWidth=h,s.naturalHeight=n,o%180&&(e=c({width:h,height:n,degree:o}),s.naturalWidth=e.width,s.naturalHeight=e.height),this.limitCanvas(!0,!1))),(s.width>s.maxWidth||s.width<s.minWidth)&&(s.left=s.oldLeft),(s.height>s.maxHeight||s.height<s.minHeight)&&(s.top=s.oldTop),s.width=wt(xt(s.width,s.minWidth),s.maxWidth),s.height=wt(xt(s.height,s.minHeight),s.maxHeight),this.limitCanvas(!1,!0),s.oldLeft=s.left=wt(xt(s.left,s.minLeft),s.maxLeft),s.oldTop=s.top=wt(xt(s.top,s.minTop),s.maxTop),this.$canvas.css({width:s.width,height:s.height,left:s.left,top:s.top}),this.renderImage(),this.isCropped&&this.isLimited&&this.limitCropBox(!0,!0),t&&this.output()},renderImage:function(i){var e,s=this.canvas,a=this.image;a.rotate&&(e=c({width:s.width,height:s.height,degree:a.rotate,aspectRatio:a.aspectRatio},!0)),t.extend(a,e?{width:e.width,height:e.height,left:(s.width-e.width)/2,top:(s.height-e.height)/2}:{width:s.width,height:s.height,left:0,top:0}),this.$clone.css({width:a.width,height:a.height,marginLeft:a.left,marginTop:a.top,transform:p(a)}),i&&this.output()},initCropBox:function(){var i=this.options,e=this.canvas,s=i.aspectRatio,a=vt(i.autoCropArea)||.8,o={width:e.width,height:e.height};s&&(e.height*s>e.width?o.height=o.width/s:o.width=o.height*s),this.cropBox=o,this.limitCropBox(!0,!0),o.width=wt(xt(o.width,o.minWidth),o.maxWidth),o.height=wt(xt(o.height,o.minHeight),o.maxHeight),o.width=xt(o.minWidth,o.width*a),o.height=xt(o.minHeight,o.height*a),o.oldLeft=o.left=e.left+(e.width-o.width)/2,o.oldTop=o.top=e.top+(e.height-o.height)/2,this.initialCropBox=t.extend({},o)},limitCropBox:function(t,i){var e,s,a,o,h=this.options,n=h.aspectRatio,r=this.container,p=r.width,c=r.height,l=this.canvas,d=this.cropBox,g=this.isLimited;t&&(e=vt(h.minCropBoxWidth)||0,s=vt(h.minCropBoxHeight)||0,e=wt(e,p),s=wt(s,c),a=wt(p,g?l.width:p),o=wt(c,g?l.height:c),n&&(e&&s?s*n>e?s=e/n:e=s*n:e?s=e/n:s&&(e=s*n),o*n>a?o=a/n:a=o*n),d.minWidth=wt(e,a),d.minHeight=wt(s,o),d.maxWidth=a,d.maxHeight=o),i&&(g?(d.minLeft=xt(0,l.left),d.minTop=xt(0,l.top),d.maxLeft=wt(p,l.left+l.width)-d.width,d.maxTop=wt(c,l.top+l.height)-d.height):(d.minLeft=0,d.minTop=0,d.maxLeft=p-d.width,d.maxTop=c-d.height))},renderCropBox:function(){var t=this.options,i=this.container,e=i.width,s=i.height,a=this.cropBox;(a.width>a.maxWidth||a.width<a.minWidth)&&(a.left=a.oldLeft),(a.height>a.maxHeight||a.height<a.minHeight)&&(a.top=a.oldTop),a.width=wt(xt(a.width,a.minWidth),a.maxWidth),a.height=wt(xt(a.height,a.minHeight),a.maxHeight),this.limitCropBox(!1,!0),a.oldLeft=a.left=wt(xt(a.left,a.minLeft),a.maxLeft),a.oldTop=a.top=wt(xt(a.top,a.minTop),a.maxTop),t.movable&&t.cropBoxMovable&&this.$face.data(it,a.width===e&&a.height===s?dt:ct),this.$cropBox.css({width:a.width,height:a.height,left:a.left,top:a.top}),this.isCropped&&this.isLimited&&this.limitCanvas(!0,!0),this.isDisabled||this.output()},output:function(){this.preview(),this.isCompleted&&this.trigger(K,this.getData())},initPreview:function(){var i,e=n(this.crossOrigin),s=e?this.crossOriginUrl:this.url;this.$preview=t(this.options.preview),this.$clone2=i=t("<img"+e+' src="'+s+'">'),this.$viewBox.html(i),this.$preview.each(function(){var i=t(this);i.data(tt,{width:i.width(),height:i.height(),html:i.html()}),i.html("<img"+e+' src="'+s+'" style="display:block;width:100%;height:auto;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;image-orientation:0deg!important;">')})},resetPreview:function(){this.$preview.each(function(){var i=t(this),e=i.data(tt);i.css({width:e.width,height:e.height}).html(e.html).removeData(tt)})},preview:function(){var i=this.image,e=this.canvas,s=this.cropBox,a=s.width,o=s.height,h=i.width,n=i.height,r=s.left-e.left-i.left,c=s.top-e.top-i.top;this.isCropped&&!this.isDisabled&&(this.$clone2.css({width:h,height:n,marginLeft:-r,marginTop:-c,transform:p(i)}),this.$preview.each(function(){var e=t(this),s=e.data(tt),l=s.width,d=s.height,g=l,u=d,f=1;a&&(f=l/a,u=o*f),o&&u>d&&(f=d/o,g=a*f,u=d),e.css({width:g,height:u}).find("img").css({width:h*f,height:n*f,marginLeft:-r*f,marginTop:-c*f,transform:p(i)})}))},bind:function(){var i=this.options,e=this.$element,s=this.$cropper;t.isFunction(i.cropstart)&&e.on(N,i.cropstart),t.isFunction(i.cropmove)&&e.on(_,i.cropmove),t.isFunction(i.cropend)&&e.on(q,i.cropend),t.isFunction(i.crop)&&e.on(K,i.crop),t.isFunction(i.zoom)&&e.on(Z,i.zoom),s.on(z,t.proxy(this.cropStart,this)),i.zoomable&&i.zoomOnWheel&&s.on(E,t.proxy(this.wheel,this)),i.toggleDragModeOnDblclick&&s.on(U,t.proxy(this.dblclick,this)),x.on(O,this._cropMove=a(this.cropMove,this)).on(P,this._cropEnd=a(this.cropEnd,this)),i.responsive&&w.on(j,this._resize=a(this.resize,this))},unbind:function(){var i=this.options,e=this.$element,s=this.$cropper;t.isFunction(i.cropstart)&&e.off(N,i.cropstart),t.isFunction(i.cropmove)&&e.off(_,i.cropmove),t.isFunction(i.cropend)&&e.off(q,i.cropend),t.isFunction(i.crop)&&e.off(K,i.crop),t.isFunction(i.zoom)&&e.off(Z,i.zoom),s.off(z,this.cropStart),i.zoomable&&i.zoomOnWheel&&s.off(E,this.wheel),i.toggleDragModeOnDblclick&&s.off(U,this.dblclick),x.off(O,this._cropMove).off(P,this._cropEnd),i.responsive&&w.off(j,this._resize)},resize:function(){var i,e,s,a=this.options.restore,o=this.$container,h=this.container;!this.isDisabled&&h&&(s=o.width()/h.width,1===s&&o.height()===h.height||(a&&(i=this.getCanvasData(),e=this.getCropBoxData()),this.render(),a&&(this.setCanvasData(t.each(i,function(t,e){i[t]=e*s})),this.setCropBoxData(t.each(e,function(t,i){e[t]=i*s})))))},dblclick:function(){this.isDisabled||(this.$dragBox.hasClass(W)?this.setDragMode(dt):this.setDragMode(lt))},wheel:function(i){var e=i.originalEvent||i,s=vt(this.options.wheelZoomRatio)||.1,a=1;this.isDisabled||(i.preventDefault(),this.wheeling||(this.wheeling=!0,setTimeout(t.proxy(function(){this.wheeling=!1},this),50),e.deltaY?a=e.deltaY>0?1:-1:e.wheelDelta?a=-e.wheelDelta/120:e.detail&&(a=e.detail>0?1:-1),this.zoom(-a*s,i)))},cropStart:function(i){var e,s,a=this.options,o=i.originalEvent,h=o&&o.touches,n=i;if(!this.isDisabled){if(h){if(e=h.length,e>1){if(!a.zoomable||!a.zoomOnTouch||2!==e)return;n=h[1],this.startX2=n.pageX,this.startY2=n.pageY,s=gt}n=h[0]}if(s=s||t(n.target).data(it),Q.test(s)){if(this.trigger(N,{originalEvent:o,action:s}).isDefaultPrevented())return;i.preventDefault(),this.action=s,this.cropping=!1,this.startX=n.pageX||o&&o.pageX,this.startY=n.pageY||o&&o.pageY,s===lt&&(this.cropping=!0,this.$dragBox.addClass(T))}}},cropMove:function(t){var i,e=this.options,s=t.originalEvent,a=s&&s.touches,o=t,h=this.action;if(!this.isDisabled){if(a){if(i=a.length,i>1){if(!e.zoomable||!e.zoomOnTouch||2!==i)return;o=a[1],this.endX2=o.pageX,this.endY2=o.pageY}o=a[0]}if(h){if(this.trigger(_,{originalEvent:s,action:h}).isDefaultPrevented())return;t.preventDefault(),this.endX=o.pageX||s&&s.pageX,this.endY=o.pageY||s&&s.pageY,this.change(o.shiftKey,h===gt?t:null)}}},cropEnd:function(t){var i=t.originalEvent,e=this.action;this.isDisabled||e&&(t.preventDefault(),this.cropping&&(this.cropping=!1,this.$dragBox.toggleClass(T,this.isCropped&&this.options.modal)),this.action="",this.trigger(q,{originalEvent:i,action:e}))},change:function(t,i){var e,s,a=this.options,o=a.aspectRatio,h=this.action,n=this.container,r=this.canvas,p=this.cropBox,c=p.width,l=p.height,d=p.left,g=p.top,u=d+c,f=g+l,m=0,v=0,w=n.width,x=n.height,C=!0;switch(!o&&t&&(o=c&&l?c/l:1),this.isLimited&&(m=p.minLeft,v=p.minTop,w=m+wt(n.width,r.left+r.width),x=v+wt(n.height,r.top+r.height)),s={x:this.endX-this.startX,y:this.endY-this.startY},o&&(s.X=s.y*o,s.Y=s.x/o),h){case ct:d+=s.x,g+=s.y;break;case et:if(s.x>=0&&(u>=w||o&&(v>=g||f>=x))){C=!1;break}c+=s.x,o&&(l=c/o,g-=s.Y/2),0>c&&(h=st,c=0);break;case ot:if(s.y<=0&&(v>=g||o&&(m>=d||u>=w))){C=!1;break}l-=s.y,g+=s.y,o&&(c=l*o,d+=s.X/2),0>l&&(h=at,l=0);break;case st:if(s.x<=0&&(m>=d||o&&(v>=g||f>=x))){C=!1;break}c-=s.x,d+=s.x,o&&(l=c/o,g+=s.Y/2),0>c&&(h=et,c=0);break;case at:if(s.y>=0&&(f>=x||o&&(m>=d||u>=w))){C=!1;break}l+=s.y,o&&(c=l*o,d-=s.X/2),0>l&&(h=ot,l=0);break;case rt:if(o){if(s.y<=0&&(v>=g||u>=w)){C=!1;break}l-=s.y,g+=s.y,c=l*o}else s.x>=0?w>u?c+=s.x:s.y<=0&&v>=g&&(C=!1):c+=s.x,s.y<=0?g>v&&(l-=s.y,g+=s.y):(l-=s.y,g+=s.y);0>c&&0>l?(h=nt,l=0,c=0):0>c?(h=pt,c=0):0>l&&(h=ht,l=0);break;case pt:if(o){if(s.y<=0&&(v>=g||m>=d)){C=!1;break}l-=s.y,g+=s.y,c=l*o,d+=s.X}else s.x<=0?d>m?(c-=s.x,d+=s.x):s.y<=0&&v>=g&&(C=!1):(c-=s.x,d+=s.x),s.y<=0?g>v&&(l-=s.y,g+=s.y):(l-=s.y,g+=s.y);0>c&&0>l?(h=ht,l=0,c=0):0>c?(h=rt,c=0):0>l&&(h=nt,l=0);break;case nt:if(o){if(s.x<=0&&(m>=d||f>=x)){C=!1;break}c-=s.x,d+=s.x,l=c/o}else s.x<=0?d>m?(c-=s.x,d+=s.x):s.y>=0&&f>=x&&(C=!1):(c-=s.x,d+=s.x),s.y>=0?x>f&&(l+=s.y):l+=s.y;0>c&&0>l?(h=rt,l=0,c=0):0>c?(h=ht,c=0):0>l&&(h=pt,l=0);break;case ht:if(o){if(s.x>=0&&(u>=w||f>=x)){C=!1;break}c+=s.x,l=c/o}else s.x>=0?w>u?c+=s.x:s.y>=0&&f>=x&&(C=!1):c+=s.x,s.y>=0?x>f&&(l+=s.y):l+=s.y;0>c&&0>l?(h=pt,l=0,c=0):0>c?(h=nt,c=0):0>l&&(h=rt,l=0);break;case dt:this.move(s.x,s.y),C=!1;break;case gt:this.zoom(function(t,i,e,s){var a=yt(t*t+i*i),o=yt(e*e+s*s);return(o-a)/a}(Ct(this.startX-this.startX2),Ct(this.startY-this.startY2),Ct(this.endX-this.endX2),Ct(this.endY-this.endY2)),i),this.startX2=this.endX2,this.startY2=this.endY2,C=!1;break;case lt:if(!s.x||!s.y){C=!1;break}e=this.$cropper.offset(),d=this.startX-e.left,g=this.startY-e.top,c=p.minWidth,l=p.minHeight,s.x>0?h=s.y>0?ht:rt:s.x<0&&(d-=c,h=s.y>0?nt:pt),s.y<0&&(g-=l),this.isCropped||(this.$cropBox.removeClass(Y),this.isCropped=!0,this.isLimited&&this.limitCropBox(!0,!0))}C&&(p.width=c,p.height=l,p.left=d,p.top=g,this.action=h,this.renderCropBox()),this.startX=this.endX,this.startY=this.endY},crop:function(){this.isBuilt&&!this.isDisabled&&(this.isCropped||(this.isCropped=!0,this.limitCropBox(!0,!0),this.options.modal&&this.$dragBox.addClass(T),this.$cropBox.removeClass(Y)),this.setCropBoxData(this.initialCropBox))},reset:function(){this.isBuilt&&!this.isDisabled&&(this.image=t.extend({},this.initialImage),this.canvas=t.extend({},this.initialCanvas),this.cropBox=t.extend({},this.initialCropBox),this.renderCanvas(),this.isCropped&&this.renderCropBox())},clear:function(){this.isCropped&&!this.isDisabled&&(t.extend(this.cropBox,{left:0,top:0,width:0,height:0}),this.isCropped=!1,this.renderCropBox(),this.limitCanvas(!0,!0),this.renderCanvas(),this.$dragBox.removeClass(T),this.$cropBox.addClass(Y))},replace:function(t,i){!this.isDisabled&&t&&(this.isImg&&this.$element.attr("src",t),i?(this.url=t,this.$clone.attr("src",t),this.isBuilt&&this.$preview.find("img").add(this.$clone2).attr("src",t)):(this.isImg&&(this.isReplaced=!0),this.options.data=null,this.load(t)))},enable:function(){this.isBuilt&&(this.isDisabled=!1,this.$cropper.removeClass(H))},disable:function(){this.isBuilt&&(this.isDisabled=!0,this.$cropper.addClass(H))},destroy:function(){var t=this.$element;this.isLoaded?(this.isImg&&this.isReplaced&&t.attr("src",this.originalUrl),this.unbuild(),t.removeClass(Y)):this.isImg?t.off(I,this.start):this.$clone&&this.$clone.remove(),t.removeData(L)},move:function(t,i){var s=this.canvas;this.moveTo(e(t)?t:s.left+vt(t),e(i)?i:s.top+vt(i))},moveTo:function(t,s){var a=this.canvas,o=!1;e(s)&&(s=t),t=vt(t),s=vt(s),this.isBuilt&&!this.isDisabled&&this.options.movable&&(i(t)&&(a.left=t,o=!0),i(s)&&(a.top=s,o=!0),o&&this.renderCanvas(!0))},zoom:function(t,i){var e=this.canvas;t=vt(t),t=0>t?1/(1-t):1+t,this.zoomTo(e.width*t/e.naturalWidth,i)},zoomTo:function(t,i){var e,s,a,o,h,n=this.options,r=this.canvas,p=r.width,c=r.height,l=r.naturalWidth,g=r.naturalHeight;if(t=vt(t),t>=0&&this.isBuilt&&!this.isDisabled&&n.zoomable){if(s=l*t,a=g*t,i&&(e=i.originalEvent),this.trigger(Z,{originalEvent:e,oldRatio:p/l,ratio:s/l}).isDefaultPrevented())return;e?(o=this.$cropper.offset(),h=e.touches?d(e.touches):{pageX:i.pageX||e.pageX||0,pageY:i.pageY||e.pageY||0},r.left-=(s-p)*((h.pageX-o.left-r.left)/p),r.top-=(a-c)*((h.pageY-o.top-r.top)/c)):(r.left-=(s-p)/2,r.top-=(a-c)/2),r.width=s,r.height=a,this.renderCanvas(!0)}},rotate:function(t){this.rotateTo((this.image.rotate||0)+vt(t))},rotateTo:function(t){t=vt(t),i(t)&&this.isBuilt&&!this.isDisabled&&this.options.rotatable&&(this.image.rotate=t%360,this.isRotated=!0,this.renderCanvas(!0))},scale:function(t,s){var a=this.image,o=!1;e(s)&&(s=t),t=vt(t),s=vt(s),this.isBuilt&&!this.isDisabled&&this.options.scalable&&(i(t)&&(a.scaleX=t,o=!0),i(s)&&(a.scaleY=s,o=!0),o&&this.renderImage(!0))},scaleX:function(t){var e=this.image.scaleY;this.scale(t,i(e)?e:1)},scaleY:function(t){var e=this.image.scaleX;this.scale(i(e)?e:1,t)},getData:function(i){var e,s,a=this.options,o=this.image,h=this.canvas,n=this.cropBox;return this.isBuilt&&this.isCropped?(s={x:n.left-h.left,y:n.top-h.top,width:n.width,height:n.height},e=o.width/o.naturalWidth,t.each(s,function(t,a){a/=e,s[t]=i?Dt(a):a})):s={x:0,y:0,width:0,height:0},a.rotatable&&(s.rotate=o.rotate||0),a.scalable&&(s.scaleX=o.scaleX||1,s.scaleY=o.scaleY||1),s},setData:function(e){var s,a,o,h=this.options,n=this.image,r=this.canvas,p={};t.isFunction(e)&&(e=e.call(this.element)),this.isBuilt&&!this.isDisabled&&t.isPlainObject(e)&&(h.rotatable&&i(e.rotate)&&e.rotate!==n.rotate&&(n.rotate=e.rotate,this.isRotated=s=!0),h.scalable&&(i(e.scaleX)&&e.scaleX!==n.scaleX&&(n.scaleX=e.scaleX,a=!0),i(e.scaleY)&&e.scaleY!==n.scaleY&&(n.scaleY=e.scaleY,a=!0)),s?this.renderCanvas():a&&this.renderImage(),o=n.width/n.naturalWidth,i(e.x)&&(p.left=e.x*o+r.left),i(e.y)&&(p.top=e.y*o+r.top),i(e.width)&&(p.width=e.width*o),i(e.height)&&(p.height=e.height*o),this.setCropBoxData(p))},getContainerData:function(){return this.isBuilt?this.container:{}},getImageData:function(){return this.isLoaded?this.image:{}},getCanvasData:function(){var i=this.canvas,e={};return this.isBuilt&&t.each(["left","top","width","height","naturalWidth","naturalHeight"],function(t,s){e[s]=i[s]}),e},setCanvasData:function(e){var s=this.canvas,a=s.aspectRatio;t.isFunction(e)&&(e=e.call(this.$element)),this.isBuilt&&!this.isDisabled&&t.isPlainObject(e)&&(i(e.left)&&(s.left=e.left),i(e.top)&&(s.top=e.top),i(e.width)?(s.width=e.width,s.height=e.width/a):i(e.height)&&(s.height=e.height,s.width=e.height*a),this.renderCanvas(!0))},getCropBoxData:function(){var t,i=this.cropBox;return this.isBuilt&&this.isCropped&&(t={left:i.left,top:i.top,width:i.width,height:i.height}),t||{}},setCropBoxData:function(e){var s,a,o=this.cropBox,h=this.options.aspectRatio;t.isFunction(e)&&(e=e.call(this.$element)),this.isBuilt&&this.isCropped&&!this.isDisabled&&t.isPlainObject(e)&&(i(e.left)&&(o.left=e.left),i(e.top)&&(o.top=e.top),i(e.width)&&(s=!0,o.width=e.width),i(e.height)&&(a=!0,o.height=e.height),h&&(s?o.height=o.width/h:a&&(o.width=o.height*h)),this.renderCropBox())},getCroppedCanvas:function(i){var e,s,a,o,h,n,r,p,c,d,g;return this.isBuilt&&ft?this.isCropped?(t.isPlainObject(i)||(i={}),g=this.getData(),e=g.width,s=g.height,p=e/s,t.isPlainObject(i)&&(h=i.width,n=i.height,h?(n=h/p,r=h/e):n&&(h=n*p,r=n/s)),a=$t(h||e),o=$t(n||s),c=t("<canvas>")[0],c.width=a,c.height=o,d=c.getContext("2d"),i.fillColor&&(d.fillStyle=i.fillColor,d.fillRect(0,0,a,o)),d.drawImage.apply(d,function(){var t,i,a,o,h,n,p=l(this.$clone[0],this.image),c=p.width,d=p.height,u=this.canvas,f=[p],m=g.x+u.naturalWidth*(Ct(g.scaleX||1)-1)/2,v=g.y+u.naturalHeight*(Ct(g.scaleY||1)-1)/2;return-e>=m||m>c?m=t=a=h=0:0>=m?(a=-m,m=0,t=h=wt(c,e+m)):c>=m&&(a=0,t=h=wt(e,c-m)),0>=t||-s>=v||v>d?v=i=o=n=0:0>=v?(o=-v,v=0,i=n=wt(d,s+v)):d>=v&&(o=0,i=n=wt(s,d-v)),f.push($t(m),$t(v),$t(t),$t(i)),r&&(a*=r,o*=r,h*=r,n*=r),h>0&&n>0&&f.push($t(a),$t(o),$t(h),$t(n)),f}.call(this)),c):l(this.$clone[0],this.image):void 0},setAspectRatio:function(t){var i=this.options;this.isDisabled||e(t)||(i.aspectRatio=xt(0,t)||NaN,this.isBuilt&&(this.initCropBox(),this.isCropped&&this.renderCropBox()))},setDragMode:function(t){var i,e,s=this.options;this.isLoaded&&!this.isDisabled&&(i=t===lt,e=s.movable&&t===dt,t=i||e?t:ut,this.$dragBox.data(it,t).toggleClass(W,i).toggleClass(M,e),s.cropBoxMovable||this.$face.data(it,t).toggleClass(W,i).toggleClass(M,e))}},v.DEFAULTS={viewMode:0,dragMode:"crop",aspectRatio:NaN,data:null,preview:"",responsive:!0,restore:!0,checkCrossOrigin:!0,checkOrientation:!0,modal:!0,guides:!0,center:!0,highlight:!0,background:!0,autoCrop:!0,autoCropArea:.8,movable:!0,rotatable:!0,scalable:!0,zoomable:!0,zoomOnTouch:!0,zoomOnWheel:!0,wheelZoomRatio:.1,cropBoxMovable:!0,cropBoxResizable:!0,toggleDragModeOnDblclick:!0,minCanvasWidth:0,minCanvasHeight:0,minCropBoxWidth:0,minCropBoxHeight:0,minContainerWidth:200,minContainerHeight:100,build:null,built:null,cropstart:null,cropmove:null,cropend:null,crop:null,zoom:null},v.setDefaults=function(i){t.extend(v.DEFAULTS,i)},v.TEMPLATE='<div class="cropper-container"><div class="cropper-wrap-box"><div class="cropper-canvas"></div></div><div class="cropper-drag-box"></div><div class="cropper-crop-box"><span class="cropper-view-box"></span><span class="cropper-dashed dashed-h"></span><span class="cropper-dashed dashed-v"></span><span class="cropper-center"></span><span class="cropper-face"></span><span class="cropper-line line-e" data-action="e"></span><span class="cropper-line line-n" data-action="n"></span><span class="cropper-line line-w" data-action="w"></span><span class="cropper-line line-s" data-action="s"></span><span class="cropper-point point-e" data-action="e"></span><span class="cropper-point point-n" data-action="n"></span><span class="cropper-point point-w" data-action="w"></span><span class="cropper-point point-s" data-action="s"></span><span class="cropper-point point-ne" data-action="ne"></span><span class="cropper-point point-nw" data-action="nw"></span><span class="cropper-point point-sw" data-action="sw"></span><span class="cropper-point point-se" data-action="se"></span></div></div>',v.other=t.fn.cropper,t.fn.cropper=function(i){var a,o=s(arguments,1);return this.each(function(){var e,s,h=t(this),n=h.data(L);if(!n){if(/destroy/.test(i))return;e=t.extend({},h.data(),t.isPlainObject(i)&&i),h.data(L,n=new v(this,e))}"string"==typeof i&&t.isFunction(s=n[i])&&(a=s.apply(n,o))}),e(a)?this:a},t.fn.cropper.Constructor=v,t.fn.cropper.setDefaults=v.setDefaults,t.fn.cropper.noConflict=function(){return t.fn.cropper=v.other,this}}); | ||
0 | \ No newline at end of file | 11 | \ No newline at end of file |
backend/components/noam148/imagemanager/assets/source/js/script.imagemanager.input.js
0 → 100644
1 | +var imageManagerInput = { | ||
2 | + baseUrl: null, | ||
3 | + //language | ||
4 | + message: null, | ||
5 | + //init imageManagerInput | ||
6 | + init: function () { | ||
7 | + //create modal | ||
8 | + imageManagerInput.initModal(); | ||
9 | + }, | ||
10 | + //creat image Manager modal | ||
11 | + initModal: function () { | ||
12 | + //check if modal not jet exists | ||
13 | + if ($("#modal-imagemanager").length === 0) { | ||
14 | + //set html modal in var | ||
15 | + var sModalHtml = '<div tabindex="-1" role="dialog" class="fade modal" id="modal-imagemanager">'; | ||
16 | + sModalHtml += '<div class="modal-dialog modal-lg">'; | ||
17 | + sModalHtml += '<div class="modal-content">'; | ||
18 | + sModalHtml += '<div class="modal-header">'; | ||
19 | + sModalHtml += '<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>'; | ||
20 | + sModalHtml += '<h4>Image manager</h4>'; | ||
21 | + sModalHtml += '</div>'; | ||
22 | + sModalHtml += '<div class="modal-body">'; | ||
23 | + sModalHtml += '<iframe src="#"></iframe>'; | ||
24 | + sModalHtml += '</div>'; | ||
25 | + sModalHtml += '</div>'; | ||
26 | + sModalHtml += '</div>'; | ||
27 | + sModalHtml += '</div>'; | ||
28 | + //prepend data to body | ||
29 | + $('body').prepend(sModalHtml); | ||
30 | + } | ||
31 | + }, | ||
32 | + //open media manager modal | ||
33 | + openModal: function (inputId, aspectRatio, cropViewMode) { | ||
34 | + //get selected item | ||
35 | + var iImageId = $("#" + inputId).val(); | ||
36 | + var srcImageIdQueryString = ""; | ||
37 | + if (iImageId !== "") { | ||
38 | + srcImageIdQueryString = "&image-id=" + iImageId; | ||
39 | + } | ||
40 | + //create iframe url | ||
41 | + var queryStringStartCharacter = ((imageManagerInput.baseUrl).indexOf('?') == -1) ? '?' : '&'; | ||
42 | + var imageManagerUrl = imageManagerInput.baseUrl + queryStringStartCharacter + "view-mode=iframe&input-id=" + inputId + "&aspect-ratio=" + aspectRatio + "&crop-view-mode=" + cropViewMode + srcImageIdQueryString; | ||
43 | + //set iframe path | ||
44 | + $("#modal-imagemanager iframe").attr("src", imageManagerUrl); | ||
45 | + //set translation title for modal header | ||
46 | + $("#modal-imagemanager .modal-dialog .modal-header h4").text(imageManagerInput.message.imageManager); | ||
47 | + //open modal | ||
48 | + $("#modal-imagemanager").modal("show"); | ||
49 | + }, | ||
50 | + //close media manager modal | ||
51 | + closeModal: function () { | ||
52 | + $("#modal-imagemanager").modal("hide"); | ||
53 | + }, | ||
54 | + //delete picked image | ||
55 | + deletePickedImage: function (inputId) { | ||
56 | + //remove value of the input field | ||
57 | + var sFieldId = inputId; | ||
58 | + var sFieldNameId = sFieldId + "_name"; | ||
59 | + var sImagePreviewId = sFieldId + "_image"; | ||
60 | + var bShowConfirm = JSON.parse($(".delete-selected-image[data-input-id='" + inputId + "']").data("show-delete-confirm")); | ||
61 | + //show warning if bShowConfirm == true | ||
62 | + if (bShowConfirm) { | ||
63 | + if (confirm(imageManagerInput.message.detachWarningMessage) == false) { | ||
64 | + return false; | ||
65 | + } | ||
66 | + } | ||
67 | + //set input data | ||
68 | + $('#' + sFieldId).val(""); | ||
69 | + $('#' + sFieldNameId).val(""); | ||
70 | + //trigger change | ||
71 | + $('#' + sFieldId).trigger("change"); | ||
72 | + //hide image | ||
73 | + $('#' + sImagePreviewId).attr("src", "").parent().addClass("hide"); | ||
74 | + //delete hide class | ||
75 | + $(".delete-selected-image[data-input-id='" + inputId + "']").addClass("hide"); | ||
76 | + } | ||
77 | +}; | ||
78 | + | ||
79 | +$(document).ready(function () { | ||
80 | + //init Image manage | ||
81 | + imageManagerInput.init(); | ||
82 | + | ||
83 | + //open media manager modal | ||
84 | + $(document).on("click", ".open-modal-imagemanager", function () { | ||
85 | + var aspectRatio = $(this).data("aspect-ratio"); | ||
86 | + var cropViewMode = $(this).data("crop-view-mode"); | ||
87 | + var inputId = $(this).data("input-id"); | ||
88 | + //open selector id | ||
89 | + imageManagerInput.openModal(inputId, aspectRatio, cropViewMode); | ||
90 | + }); | ||
91 | + | ||
92 | + //delete picked image | ||
93 | + $(document).on("click", ".delete-selected-image", function () { | ||
94 | + var inputId = $(this).data("input-id"); | ||
95 | + //open selector id | ||
96 | + imageManagerInput.deletePickedImage(inputId); | ||
97 | + }); | ||
98 | +}); | ||
0 | \ No newline at end of file | 99 | \ No newline at end of file |
backend/components/noam148/imagemanager/assets/source/js/script.imagemanager.module.js
0 → 100644
1 | +var imageManagerModule = { | ||
2 | + //params for input selector | ||
3 | + fieldId: null, | ||
4 | + cropRatio: null, | ||
5 | + cropViewMode: 1, | ||
6 | + defaultImageId: null, | ||
7 | + selectType: null, | ||
8 | + //current selected image | ||
9 | + selectedImage: null, | ||
10 | + //language | ||
11 | + message: null, | ||
12 | + //init imageManager | ||
13 | + init: function () { | ||
14 | + //init cropper | ||
15 | + $('#module-imagemanager > .row .col-image-editor .image-cropper .image-wrapper img#image-cropper').cropper({ | ||
16 | + viewMode: imageManagerModule.cropViewMode | ||
17 | + }); | ||
18 | + | ||
19 | + //preselect image if image-id isset | ||
20 | + if (imageManagerModule.defaultImageId !== "") { | ||
21 | + imageManagerModule.selectImage(imageManagerModule.defaultImageId); | ||
22 | + } | ||
23 | + | ||
24 | + //set selected after pjax complete | ||
25 | + $('#pjax-mediamanager').on('pjax:complete', function () { | ||
26 | + if (imageManagerModule.selectedImage !== null) { | ||
27 | + imageManagerModule.selectImage(imageManagerModule.selectedImage.id); | ||
28 | + } | ||
29 | + }); | ||
30 | + }, | ||
31 | + //filter result | ||
32 | + filterImageResult: function (searchTerm) { | ||
33 | + //set new url | ||
34 | + var newUrl = window.queryStringParameter.set(window.location.href, "ImageManagerSearch[globalSearch]", searchTerm); | ||
35 | + //set pjax | ||
36 | + $.pjax({ | ||
37 | + url: newUrl, | ||
38 | + container: "#pjax-mediamanager", | ||
39 | + push: false, | ||
40 | + replace: false, | ||
41 | + timeout: 5000, | ||
42 | + scrollTo: false | ||
43 | + }); | ||
44 | + }, | ||
45 | + //select an image | ||
46 | + selectImage: function (id) { | ||
47 | + //set selected class | ||
48 | + $("#module-imagemanager .item-overview .item").removeClass("selected"); | ||
49 | + $("#module-imagemanager .item-overview .item[data-key='" + id + "']").addClass("selected"); | ||
50 | + //get details | ||
51 | + imageManagerModule.getDetails(id); | ||
52 | + }, | ||
53 | + //pick the selected image | ||
54 | + pickImage: function () { | ||
55 | + //switch between select type | ||
56 | + switch (imageManagerModule.selectType) { | ||
57 | + //default widget selector | ||
58 | + case "input": | ||
59 | + //get id data | ||
60 | + var sFieldId = imageManagerModule.fieldId; | ||
61 | + var sFieldNameId = sFieldId + "_name"; | ||
62 | + var sFieldImageId = sFieldId + "_image"; | ||
63 | + //set input data | ||
64 | + $('#' + sFieldId, window.parent.document).val(imageManagerModule.selectedImage.id); | ||
65 | + $('#' + sFieldNameId, window.parent.document).val(imageManagerModule.selectedImage.fileName); | ||
66 | + $('#' + sFieldImageId, window.parent.document).attr("src", imageManagerModule.selectedImage.image).parent().removeClass("hide"); | ||
67 | + //trigger change | ||
68 | + parent.$('#' + sFieldId).trigger('change'); | ||
69 | + //show delete button | ||
70 | + $(".delete-selected-image[data-input-id='" + sFieldId + "']", window.parent.document).removeClass("hide"); | ||
71 | + //close the modal | ||
72 | + window.parent.imageManagerInput.closeModal(); | ||
73 | + break; | ||
74 | + //CKEditor selector | ||
75 | + case "ckeditor": | ||
76 | + //TinyMCE Selector | ||
77 | + case "tinymce": | ||
78 | + //check if isset image | ||
79 | + if (imageManagerModule.selectedImage !== null) { | ||
80 | + //call action by ajax | ||
81 | + $.ajax({ | ||
82 | + url: imageManagerModule.baseUrl + "/get-original-image", | ||
83 | + type: "POST", | ||
84 | + data: { | ||
85 | + ImageManager_id: imageManagerModule.selectedImage.id, | ||
86 | + _csrf: $('meta[name=csrf-token]').prop('content') | ||
87 | + }, | ||
88 | + dataType: "json", | ||
89 | + success: function (responseData, textStatus, jqXHR) { | ||
90 | + //set attributes for each selector | ||
91 | + if (imageManagerModule.selectType == "ckeditor") { | ||
92 | + var sField = window.queryStringParameter.get(window.location.href, "CKEditorFuncNum"); | ||
93 | + window.top.opener.CKEDITOR.tools.callFunction(sField, responseData); | ||
94 | + window.self.close(); | ||
95 | + } else if (imageManagerModule.selectType == "tinymce") { | ||
96 | + var sField = window.queryStringParameter.get(window.location.href, "tag_name"); | ||
97 | + window.opener.document.getElementById(sField).value = responseData; | ||
98 | + window.close(); | ||
99 | + window.opener.focus(); | ||
100 | + } | ||
101 | + }, | ||
102 | + error: function (jqXHR, textStatus, errorThrown) { | ||
103 | + alert("Error: can't get item"); | ||
104 | + } | ||
105 | + }); | ||
106 | + } else { | ||
107 | + alert("Error: image can't picked"); | ||
108 | + } | ||
109 | + break; | ||
110 | + } | ||
111 | + | ||
112 | + | ||
113 | + }, | ||
114 | + //delete the selected image | ||
115 | + deleteSelectedImage: function () { | ||
116 | + //confirm message | ||
117 | + if (confirm(imageManagerModule.message.deleteMessage)) { | ||
118 | + //close editor | ||
119 | + imageManagerModule.editor.close(); | ||
120 | + //check if isset image | ||
121 | + if (imageManagerModule.selectedImage !== null) { | ||
122 | + //call action by ajax | ||
123 | + $.ajax({ | ||
124 | + url: imageManagerModule.baseUrl + "/delete", | ||
125 | + type: "POST", | ||
126 | + data: { | ||
127 | + ImageManager_id: imageManagerModule.selectedImage.id, | ||
128 | + _csrf: $('meta[name=csrf-token]').prop('content') | ||
129 | + }, | ||
130 | + dataType: "json", | ||
131 | + success: function (responseData, textStatus, jqXHR) { | ||
132 | + //check if delete is true | ||
133 | + if (responseData.delete === true) { | ||
134 | + //delete item element | ||
135 | + $("#module-imagemanager .item-overview .item[data-key='" + imageManagerModule.selectedImage.id + "']").remove(); | ||
136 | + //add hide class to info block | ||
137 | + $("#module-imagemanager .image-info").addClass("hide"); | ||
138 | + //set selectedImage to null | ||
139 | + imageManagerModule.selectedImage = null; | ||
140 | + //close edit | ||
141 | + } else { | ||
142 | + alert("Error: item is not deleted"); | ||
143 | + } | ||
144 | + }, | ||
145 | + error: function (jqXHR, textStatus, errorThrown) { | ||
146 | + alert("Error: can't delete item"); | ||
147 | + } | ||
148 | + }); | ||
149 | + } else { | ||
150 | + alert("Error: image can't delete, no image isset set"); | ||
151 | + } | ||
152 | + } | ||
153 | + }, | ||
154 | + //get image details | ||
155 | + getDetails: function (id, pickAfterGetDetails) { | ||
156 | + //set propertie if not set | ||
157 | + pickAfterGetDetails = pickAfterGetDetails !== undefined ? pickAfterGetDetails : false; | ||
158 | + //call action by ajax | ||
159 | + $.ajax({ | ||
160 | + url: imageManagerModule.baseUrl + "/view", | ||
161 | + type: "POST", | ||
162 | + data: { | ||
163 | + ImageManager_id: id, | ||
164 | + _csrf: $('meta[name=csrf-token]').prop('content') | ||
165 | + }, | ||
166 | + dataType: "json", | ||
167 | + success: function (responseData, textStatus, jqXHR) { | ||
168 | + //set imageManagerModule.selectedImage property | ||
169 | + imageManagerModule.selectedImage = responseData; | ||
170 | + | ||
171 | + //if need to pick image? | ||
172 | + if (pickAfterGetDetails) { | ||
173 | + imageManagerModule.pickImage(); | ||
174 | + //else set data | ||
175 | + } else { | ||
176 | + //set text elements | ||
177 | + $("#module-imagemanager .image-info .fileName").text(responseData.fileName).attr("title", responseData.fileName); | ||
178 | + $("#module-imagemanager .image-info .created").text(responseData.created); | ||
179 | + $("#module-imagemanager .image-info .fileSize").text(responseData.fileSize); | ||
180 | + $("#module-imagemanager .image-info .dimensions .dimension-width").text(responseData.dimensionWidth); | ||
181 | + $("#module-imagemanager .image-info .dimensions .dimension-height").text(responseData.dimensionHeight); | ||
182 | + $("#module-imagemanager .image-info .thumbnail").html("<img src='" + responseData.image + "' alt='" + responseData.fileName + "'/>"); | ||
183 | + //remove hide class | ||
184 | + $("#module-imagemanager .image-info").removeClass("hide"); | ||
185 | + } | ||
186 | + }, | ||
187 | + error: function (jqXHR, textStatus, errorThrown) { | ||
188 | + alert("Can't view image. Error: " + jqXHR.responseText); | ||
189 | + } | ||
190 | + }); | ||
191 | + }, | ||
192 | + //upload file | ||
193 | + uploadSuccess: function (uploadResponse) { | ||
194 | + //close editor | ||
195 | + imageManagerModule.editor.close(); | ||
196 | + //reload pjax container | ||
197 | + $.pjax.reload('#pjax-mediamanager', {push: false, replace: false, timeout: 5000, scrollTo: false}); | ||
198 | + }, | ||
199 | + //editor functions | ||
200 | + editor: { | ||
201 | + //open editor block | ||
202 | + open: function () { | ||
203 | + //show editer / hide overview | ||
204 | + $("#module-imagemanager > .row .col-image-editor").show(); | ||
205 | + $("#module-imagemanager > .row .col-overview").hide(); | ||
206 | + }, | ||
207 | + //close editor block | ||
208 | + close: function () { | ||
209 | + //show overview / hide editer | ||
210 | + $("#module-imagemanager > .row .col-overview").show(); | ||
211 | + $("#module-imagemanager > .row .col-image-editor").hide(); | ||
212 | + }, | ||
213 | + //open cropper | ||
214 | + openCropper: function () { | ||
215 | + //check if isset image | ||
216 | + if (imageManagerModule.selectedImage !== null) { | ||
217 | + //call action by ajax | ||
218 | + $.ajax({ | ||
219 | + url: imageManagerModule.baseUrl + "/get-original-image", | ||
220 | + type: "POST", | ||
221 | + data: { | ||
222 | + ImageManager_id: imageManagerModule.selectedImage.id, | ||
223 | + _csrf: $('meta[name=csrf-token]').prop('content') | ||
224 | + }, | ||
225 | + dataType: "json", | ||
226 | + success: function (responseData, textStatus, jqXHR) { | ||
227 | + //hide cropper | ||
228 | + $("#module-imagemanager > .row .col-image-cropper").css("visibility", "hidden"); | ||
229 | + //set image in cropper | ||
230 | + $('#module-imagemanager > .row .col-image-editor .image-cropper .image-wrapper img#image-cropper').one('built.cropper', function () { | ||
231 | + //show cropper | ||
232 | + $("#module-imagemanager > .row .col-image-cropper").css("visibility", "visible"); | ||
233 | + }) | ||
234 | + .cropper('reset') | ||
235 | + .cropper('setAspectRatio', parseFloat(imageManagerModule.cropRatio)) | ||
236 | + .cropper('replace', responseData); | ||
237 | + //open editor | ||
238 | + imageManagerModule.editor.open(); | ||
239 | + }, | ||
240 | + error: function (jqXHR, textStatus, errorThrown) { | ||
241 | + alert("Error: can't get item"); | ||
242 | + } | ||
243 | + }); | ||
244 | + } else { | ||
245 | + alert("Error: image can't crop, no image isset set"); | ||
246 | + } | ||
247 | + }, | ||
248 | + //apply crop | ||
249 | + applyCrop: function (pickAfterCrop) { | ||
250 | + //set propertie if not set | ||
251 | + pickAfterCrop = pickAfterCrop !== undefined ? pickAfterCrop : false; | ||
252 | + //check if isset image | ||
253 | + if (imageManagerModule.selectedImage !== null) { | ||
254 | + //set image in cropper | ||
255 | + var oCropData = $('#module-imagemanager > .row .col-image-editor .image-cropper .image-wrapper img#image-cropper').cropper("getData"); | ||
256 | + //call action by ajax | ||
257 | + $.ajax({ | ||
258 | + url: imageManagerModule.baseUrl + "/crop", | ||
259 | + type: "POST", | ||
260 | + data: { | ||
261 | + ImageManager_id: imageManagerModule.selectedImage.id, | ||
262 | + CropData: oCropData, | ||
263 | + _csrf: $('meta[name=csrf-token]').prop('content') | ||
264 | + }, | ||
265 | + dataType: "json", | ||
266 | + success: function (responseData, textStatus, jqXHR) { | ||
267 | + //set cropped image | ||
268 | + if (responseData !== null) { | ||
269 | + //if pickAfterCrop is true? select directly else | ||
270 | + if (pickAfterCrop) { | ||
271 | + imageManagerModule.getDetails(responseData, true); | ||
272 | + //else select the image only | ||
273 | + } else { | ||
274 | + //set new image | ||
275 | + imageManagerModule.selectImage(responseData); | ||
276 | + //reload pjax container | ||
277 | + $.pjax.reload('#pjax-mediamanager', { | ||
278 | + push: false, | ||
279 | + replace: false, | ||
280 | + timeout: 5000, | ||
281 | + scrollTo: false | ||
282 | + }); | ||
283 | + } | ||
284 | + } | ||
285 | + //close editor | ||
286 | + imageManagerModule.editor.close(); | ||
287 | + }, | ||
288 | + error: function (jqXHR, textStatus, errorThrown) { | ||
289 | + alert("Error: item is not cropped"); | ||
290 | + } | ||
291 | + }); | ||
292 | + } else { | ||
293 | + alert("Error: image can't crop, no image isset set"); | ||
294 | + } | ||
295 | + } | ||
296 | + } | ||
297 | +}; | ||
298 | + | ||
299 | +$(document).ready(function () { | ||
300 | + //init Image manage | ||
301 | + imageManagerModule.init(); | ||
302 | + //on click select item (open view) | ||
303 | + $(document).on("click", "#module-imagemanager .item-overview .item", function () { | ||
304 | + //get id | ||
305 | + var ImageManager_id = $(this).data("key"); | ||
306 | + //select image | ||
307 | + imageManagerModule.selectImage(ImageManager_id); | ||
308 | + }); | ||
309 | + //on click pick image | ||
310 | + $(document).on("click", "#module-imagemanager .image-info .pick-image-item", function () { | ||
311 | + imageManagerModule.pickImage(); | ||
312 | + return false; | ||
313 | + }); | ||
314 | + //on click delete call "delete" | ||
315 | + $(document).on("click", "#module-imagemanager .image-info .delete-image-item", function () { | ||
316 | + imageManagerModule.deleteSelectedImage(); | ||
317 | + return false; | ||
318 | + }); | ||
319 | + //on click crop call "crop" | ||
320 | + $(document).on("click", "#module-imagemanager .image-info .crop-image-item", function () { | ||
321 | + imageManagerModule.editor.openCropper(); | ||
322 | + return false; | ||
323 | + }); | ||
324 | + //on click apply crop | ||
325 | + $(document).on("click", "#module-imagemanager .image-cropper .apply-crop", function () { | ||
326 | + imageManagerModule.editor.applyCrop(); | ||
327 | + return false; | ||
328 | + }); | ||
329 | + //on click apply crop | ||
330 | + $(document).on("click", "#module-imagemanager .image-cropper .apply-crop-select", function () { | ||
331 | + imageManagerModule.editor.applyCrop(true); | ||
332 | + return false; | ||
333 | + }); | ||
334 | + //on click cancel crop | ||
335 | + $(document).on("click", "#module-imagemanager .image-cropper .cancel-crop", function () { | ||
336 | + imageManagerModule.editor.close(); | ||
337 | + return false; | ||
338 | + }); | ||
339 | + //on keyup change set filter | ||
340 | + $(document).on("keyup change", "#input-mediamanager-search", function () { | ||
341 | + imageManagerModule.filterImageResult($(this).val()); | ||
342 | + }); | ||
343 | + | ||
344 | +}); | ||
345 | + | ||
346 | +/* | ||
347 | + * return new get param to url | ||
348 | + */ | ||
349 | +window.queryStringParameter = { | ||
350 | + get: function (uri, key) { | ||
351 | + var reParam = new RegExp('(?:[\?&]|&)' + key + '=([^&]+)', 'i'); | ||
352 | + var match = uri.match(reParam); | ||
353 | + return (match && match.length > 1) ? match[1] : null; | ||
354 | + }, | ||
355 | + set: function (uri, key, value) { | ||
356 | + //replace brackets | ||
357 | + var keyReplace = key.replace("[]", "").replace(/\[/g, "%5B").replace(/\]/g, "%5D"); | ||
358 | + //replace data | ||
359 | + var re = new RegExp("([?&])" + keyReplace + "=.*?(&|$)", "i"); | ||
360 | + var separator = uri.indexOf('?') !== -1 ? "&" : "?"; | ||
361 | + if (uri.match(re)) { | ||
362 | + return uri.replace(re, '$1' + keyReplace + "=" + value + '$2'); | ||
363 | + } | ||
364 | + else { | ||
365 | + return uri + separator + keyReplace + "=" + value; | ||
366 | + } | ||
367 | + } | ||
368 | +}; | ||
0 | \ No newline at end of file | 369 | \ No newline at end of file |
backend/components/noam148/imagemanager/components/ImageManagerGetPath.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager\components; | ||
4 | + | ||
5 | +use Yii; | ||
6 | +use yii\base\Component; | ||
7 | +use backend\components\noam148\imagemanager\models\ImageManager; | ||
8 | +use yii\base\InvalidConfigException; | ||
9 | +use yii\db\Connection; | ||
10 | + | ||
11 | +class ImageManagerGetPath extends Component | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * @var null|string $mediaPath Folder path in which the images are stored | ||
16 | + */ | ||
17 | + public $mediaPath = null; | ||
18 | + | ||
19 | + /** | ||
20 | + * @var string $cachePath cache path where store the resized images (relative from webroot (index.php)) | ||
21 | + */ | ||
22 | + public $cachePath = "assets/imagemanager"; | ||
23 | + | ||
24 | + /** | ||
25 | + * @var boolean $useFilename use original filename in generated cache file | ||
26 | + */ | ||
27 | + public $useFilename = true; | ||
28 | + | ||
29 | + /** | ||
30 | + * @var boolean $useFilename use original filename in generated cache file | ||
31 | + */ | ||
32 | + public $absoluteUrl = false; | ||
33 | + | ||
34 | + /** | ||
35 | + * @var string The DB component name that the image model uses | ||
36 | + * This defaults to the default Yii DB component: Yii::$app->db | ||
37 | + * If this component is not set, the model will default to DB | ||
38 | + */ | ||
39 | + public $databaseComponent = 'db'; | ||
40 | + | ||
41 | + /** | ||
42 | + * Init set config | ||
43 | + */ | ||
44 | + public function init() | ||
45 | + { | ||
46 | + parent::init(); | ||
47 | + // initialize the compontent with the configuration loaded from config.php | ||
48 | + \Yii::$app->set('imageresize', [ | ||
49 | + 'class' => 'noam148\imageresize\ImageResize', | ||
50 | + 'cachePath' => $this->cachePath, | ||
51 | + 'useFilename' => $this->useFilename, | ||
52 | + 'absoluteUrl' => $this->absoluteUrl, | ||
53 | + ]); | ||
54 | + | ||
55 | + if (is_callable($this->databaseComponent)) { | ||
56 | + // The database component is callable, run the user function | ||
57 | + $this->databaseComponent = call_user_func($this->databaseComponent); | ||
58 | + } | ||
59 | + | ||
60 | + // Check if the user input is correct | ||
61 | + $this->_checkVariables(); | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * Get the path for the given ImageManager_id record | ||
66 | + * @param int $ImageManager_id ImageManager record for which the path needs to be generated | ||
67 | + * @param int $width Thumbnail image width | ||
68 | + * @param int $height Thumbnail image height | ||
69 | + * @param string $thumbnailMode Thumbnail mode | ||
70 | + * @return null|string Full path is returned when image is found, null if no image could be found | ||
71 | + */ | ||
72 | + public function getImagePath($ImageManager_id, $width = 400, $height = 400, $thumbnailMode = "outbound") | ||
73 | + { | ||
74 | + //default return | ||
75 | + $return = null; | ||
76 | + $mImageManager = ImageManager::findOne($ImageManager_id); | ||
77 | + | ||
78 | + //check if not empty | ||
79 | + if ($mImageManager !== null) { | ||
80 | + //set crop mode | ||
81 | + $mode = $thumbnailMode == "outbound" ? "outbound" : "inset"; | ||
82 | + | ||
83 | + $sMediaPath = null; | ||
84 | + if ($this->mediaPath !== null) { | ||
85 | + $sMediaPath = $this->mediaPath; | ||
86 | + } | ||
87 | + | ||
88 | + $sFileExtension = pathinfo($mImageManager->fileName, PATHINFO_EXTENSION); | ||
89 | + //get image file path | ||
90 | + $sImageFilePath = $sMediaPath . '/' . $mImageManager->id . '_' . $mImageManager->fileHash . '.' . $sFileExtension; | ||
91 | + //check file exists | ||
92 | + if (file_exists($sImageFilePath)) { | ||
93 | + $return = \Yii::$app->imageresize->getUrl($sImageFilePath, $width, $height, $mode, null, $mImageManager->fileName); | ||
94 | + } else { | ||
95 | + $return = null; //isset(\Yii::$app->controller->module->assetPublishedUrl) ? \Yii::$app->controller->module->assetPublishedUrl. "/img/img_no-image.png" : null; | ||
96 | + } | ||
97 | + } | ||
98 | + return $return; | ||
99 | + } | ||
100 | + | ||
101 | + /** | ||
102 | + * Check if the user configurable variables match the criteria | ||
103 | + * @throws InvalidConfigException | ||
104 | + */ | ||
105 | + private function _checkVariables() | ||
106 | + { | ||
107 | + // Check to make sure that the $databaseComponent is a string | ||
108 | + if (!is_string($this->databaseComponent)) { | ||
109 | + throw new InvalidConfigException("Image Manager Component - Init: Database component '$this->databaseComponent' is not a string"); | ||
110 | + } | ||
111 | + | ||
112 | + // Check to make sure that the $databaseComponent object exists | ||
113 | + if (Yii::$app->get($this->databaseComponent, false) === null) { | ||
114 | + throw new InvalidConfigException("Image Manager Component - Init: Database component '$this->databaseComponent' does not exists in application configuration"); | ||
115 | + } | ||
116 | + | ||
117 | + // Check to make sure that the $databaseComponent is a yii\db\Connection object | ||
118 | + if (($databaseComponentClassName = get_class(Yii::$app->get($this->databaseComponent))) !== ($connectionClassName = Connection::className())) { | ||
119 | + throw new InvalidConfigException("Image Manager Component - Init: Database component '$this->databaseComponent' is not of type '$connectionClassName' instead it is '$databaseComponentClassName'"); | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | +} |
backend/components/noam148/imagemanager/components/ImageManagerInputWidget.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager\components; | ||
4 | + | ||
5 | +use Yii; | ||
6 | +use yii\widgets\InputWidget; | ||
7 | +use yii\helpers\Html; | ||
8 | +use yii\helpers\Json; | ||
9 | +use yii\helpers\Url; | ||
10 | +use backend\components\noam148\imagemanager\models\ImageManager; | ||
11 | +use backend\components\noam148\imagemanager\assets\ImageManagerInputAsset; | ||
12 | + | ||
13 | +class ImageManagerInputWidget extends InputWidget | ||
14 | +{ | ||
15 | + | ||
16 | + /** | ||
17 | + * @var null|integer The aspect ratio the image needs to be cropped in (optional) | ||
18 | + */ | ||
19 | + public $aspectRatio = null; //option info: https://github.com/fengyuanchen/cropper/#aspectratio | ||
20 | + | ||
21 | + /** | ||
22 | + * @var int Define the viewMode of the cropper | ||
23 | + */ | ||
24 | + public $cropViewMode = 1; //option info: https://github.com/fengyuanchen/cropper/#viewmode | ||
25 | + | ||
26 | + /** | ||
27 | + * @var bool Show a preview of the image under the input | ||
28 | + */ | ||
29 | + public $showPreview = true; | ||
30 | + | ||
31 | + /** | ||
32 | + * @var bool Show a confirmation message when de-linking a image from the input | ||
33 | + */ | ||
34 | + public $showDeletePickedImageConfirm = false; | ||
35 | + | ||
36 | + /** | ||
37 | + * @inheritdoc | ||
38 | + */ | ||
39 | + public function init() | ||
40 | + { | ||
41 | + parent::init(); | ||
42 | + //set language | ||
43 | + if (!isset(Yii::$app->i18n->translations['imagemanager'])) { | ||
44 | + Yii::$app->i18n->translations['imagemanager'] = [ | ||
45 | + 'class' => 'yii\i18n\PhpMessageSource', | ||
46 | + 'sourceLanguage' => 'en', | ||
47 | + 'basePath' => '@noam148/imagemanager/messages' | ||
48 | + ]; | ||
49 | + } | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * @inheritdoc | ||
54 | + */ | ||
55 | + public function run() | ||
56 | + { | ||
57 | + //default | ||
58 | + $ImageManager_id = null; | ||
59 | + $mImageManager = null; | ||
60 | + $sFieldId = null; | ||
61 | + //start input group | ||
62 | + $field = "<div class='image-manager-input'>"; | ||
63 | + $field .= "<div class='input-group'>"; | ||
64 | + //set input fields | ||
65 | + if ($this->hasModel()) { | ||
66 | + //get field id | ||
67 | + $sFieldId = Html::getInputId($this->model, $this->attribute); | ||
68 | + $sFieldNameId = $sFieldId . "_name"; | ||
69 | + //get attribute name | ||
70 | + $sFieldAttributeName = Html::getAttributeName($this->attribute); | ||
71 | + //get filename from selected file | ||
72 | + $ImageManager_id = $this->model->{$sFieldAttributeName}; | ||
73 | + $ImageManager_fileName = null; | ||
74 | + $mImageManager = ImageManager::findOne($ImageManager_id); | ||
75 | + if ($mImageManager !== null) { | ||
76 | + $ImageManager_fileName = $mImageManager->fileName; | ||
77 | + } | ||
78 | + //create field | ||
79 | + $field .= Html::textInput($this->attribute, $ImageManager_fileName, ['class' => 'form-control', 'id' => $sFieldNameId, 'readonly' => true]); | ||
80 | + $field .= Html::activeHiddenInput($this->model, $this->attribute, $this->options); | ||
81 | + } else { | ||
82 | + $field .= Html::textInput($this->name . "_name", null, ['readonly' => true]); | ||
83 | + $field .= Html::hiddenInput($this->name, $this->value, $this->options); | ||
84 | + } | ||
85 | + //end input group | ||
86 | + $sHideClass = $ImageManager_id === null ? 'hide' : ''; | ||
87 | + $field .= "<a href='#' class='input-group-addon btn btn-primary delete-selected-image " . $sHideClass . "' data-input-id='" . $sFieldId . "' data-show-delete-confirm='" . ($this->showDeletePickedImageConfirm ? "true" : "false") . "'><i class='glyphicon glyphicon-remove' aria-hidden='true'></i></a>"; | ||
88 | + $field .= "<a href='#' class='input-group-addon btn btn-primary open-modal-imagemanager' data-aspect-ratio='" . $this->aspectRatio . "' data-crop-view-mode='" . $this->cropViewMode . "' data-input-id='" . $sFieldId . "'>"; | ||
89 | + $field .= "<i class='glyphicon glyphicon-folder-open' aria-hidden='true'></i>"; | ||
90 | + $field .= "</a></div>"; | ||
91 | + | ||
92 | + //show preview if is true | ||
93 | + if ($this->showPreview == true) { | ||
94 | + $sHideClass = ($mImageManager == null) ? "hide" : ""; | ||
95 | + $sImageSource = isset($mImageManager->id) ? \Yii::$app->imagemanager->getImagePath($mImageManager->id, 500, 500, 'inset') : ""; | ||
96 | + | ||
97 | + $field .= '<div class="image-wrapper ' . $sHideClass . '">' | ||
98 | + . '<img id="' . $sFieldId . '_image" alt="Thumbnail" class="img-responsive img-preview" src="' . $sImageSource . '">' | ||
99 | + . '</div>'; | ||
100 | + } | ||
101 | + | ||
102 | + //close image-manager-input div | ||
103 | + $field .= "</div>"; | ||
104 | + | ||
105 | + echo $field; | ||
106 | + | ||
107 | + $this->registerClientScript(); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * Registers js Input | ||
112 | + */ | ||
113 | + public function registerClientScript() | ||
114 | + { | ||
115 | + $view = $this->getView(); | ||
116 | + ImageManagerInputAsset::register($view); | ||
117 | + | ||
118 | + //set baseUrl from image manager | ||
119 | + $sBaseUrl = Url::to(['/imagemanager/manager']); | ||
120 | + //set base url | ||
121 | + $view->registerJs("imageManagerInput.baseUrl = '" . $sBaseUrl . "';"); | ||
122 | + $view->registerJs("imageManagerInput.message = " . Json::encode([ | ||
123 | + 'imageManager' => Yii::t('imagemanager', 'Image manager'), | ||
124 | + 'detachWarningMessage' => Yii::t('imagemanager', 'Are you sure you want to detach the image?'), | ||
125 | + ]) . ";"); | ||
126 | + } | ||
127 | + | ||
128 | +} |
backend/components/noam148/imagemanager/composer.json
0 → 100644
1 | +{ | ||
2 | + "name": "noam148/yii2-image-manager", | ||
3 | + "description": "A Yii2 module/widget for upload and cropping images", | ||
4 | + "keywords": [ | ||
5 | + "yii2", | ||
6 | + "extension", | ||
7 | + "widget", | ||
8 | + "module", | ||
9 | + "image", | ||
10 | + "upload", | ||
11 | + "crop", | ||
12 | + "manager" | ||
13 | + ], | ||
14 | + "homepage": "https://github.com/noam148/yii2-image-manager", | ||
15 | + "type": "yii2-extension", | ||
16 | + "license": "BSD-3-Clause", | ||
17 | + "authors": [ | ||
18 | + { | ||
19 | + "name": "Noam148", | ||
20 | + "homepage": "https://github.com/noam148/" | ||
21 | + } | ||
22 | + ], | ||
23 | + "require": { | ||
24 | + "yiisoft/yii2": "*", | ||
25 | + "noam148/yii2-image-resize": "*", | ||
26 | + "kartik-v/yii2-widget-fileinput": "@dev" | ||
27 | + }, | ||
28 | + "autoload": { | ||
29 | + "psr-4": { | ||
30 | + "noam148\\imagemanager\\": "" | ||
31 | + } | ||
32 | + } | ||
33 | +} | ||
0 | \ No newline at end of file | 34 | \ No newline at end of file |
backend/components/noam148/imagemanager/controllers/DefaultController.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager\controllers; | ||
4 | + | ||
5 | +use yii\web\Controller; | ||
6 | + | ||
7 | +/** | ||
8 | + * Default controller for the `imagemanager` module | ||
9 | + */ | ||
10 | +class DefaultController extends Controller | ||
11 | +{ | ||
12 | + /** | ||
13 | + * Renders the index view for the module | ||
14 | + * @return string | ||
15 | + */ | ||
16 | + public function actionIndex() | ||
17 | + { | ||
18 | + return $this->render('index'); | ||
19 | + } | ||
20 | +} |
backend/components/noam148/imagemanager/controllers/ManagerController.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager\controllers; | ||
4 | + | ||
5 | +use Yii; | ||
6 | +use backend\components\noam148\imagemanager\models\ImageManager; | ||
7 | +use backend\components\noam148\imagemanager\models\ImageManagerSearch; | ||
8 | +use backend\components\noam148\imagemanager\assets\ImageManagerModuleAsset; | ||
9 | +use yii\web\Response; | ||
10 | +use yii\web\Controller; | ||
11 | +use yii\web\NotFoundHttpException; | ||
12 | +use yii\base\ErrorException; | ||
13 | +use yii\filters\VerbFilter; | ||
14 | +use yii\helpers\Url; | ||
15 | +use yii\helpers\Json; | ||
16 | +use yii\helpers\BaseFileHelper; | ||
17 | +use yii\imagine\Image; | ||
18 | +use Imagine\Image\Box; | ||
19 | +use Imagine\Image\Palette\RGB; | ||
20 | +use Imagine\Image\Point; | ||
21 | +use backend\components\noam148\imagemanager\Module; | ||
22 | + | ||
23 | +/** | ||
24 | + * Manager controller for the `imagemanager` module | ||
25 | + * @property $module Module | ||
26 | + */ | ||
27 | +class ManagerController extends Controller | ||
28 | +{ | ||
29 | + | ||
30 | + /** | ||
31 | + * @inheritdoc | ||
32 | + */ | ||
33 | + public function behaviors() | ||
34 | + { | ||
35 | + return [ | ||
36 | + 'verbs' => [ | ||
37 | + 'class' => VerbFilter::className(), | ||
38 | + 'actions' => [ | ||
39 | + 'delete' => ['POST'], | ||
40 | + ], | ||
41 | + ], | ||
42 | + ]; | ||
43 | + } | ||
44 | + | ||
45 | + /** | ||
46 | + * @inheritdoc | ||
47 | + */ | ||
48 | + public function beforeAction($action) | ||
49 | + { | ||
50 | + //disable CSRF Validation | ||
51 | + $this->enableCsrfValidation = false; | ||
52 | + return parent::beforeAction($action); | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * Lists all ImageManager models. | ||
57 | + * @return mixed | ||
58 | + */ | ||
59 | + public function actionIndex() | ||
60 | + { | ||
61 | + //set asset | ||
62 | + ImageManagerModuleAsset::register($this->view); | ||
63 | + | ||
64 | + //get iframe parameters | ||
65 | + $viewMode = Yii::$app->request->get("view-mode", "page"); | ||
66 | + $selectType = Yii::$app->request->get("select-type", "input"); | ||
67 | + $inputFieldId = Yii::$app->request->get("input-id"); | ||
68 | + $cropAspectRatio = Yii::$app->request->get("aspect-ratio"); | ||
69 | + $cropViewMode = Yii::$app->request->get("crop-view-mode", 1); | ||
70 | + $defaultImageId = Yii::$app->request->get("image-id"); | ||
71 | + | ||
72 | + //set blank layout if viewMode = iframe | ||
73 | + if ($viewMode == "iframe") { | ||
74 | + //set layout | ||
75 | + $this->layout = "blank"; | ||
76 | + | ||
77 | + //set stylesheet for modal | ||
78 | + $aCssFiles = \Yii::$app->controller->module->cssFiles; | ||
79 | + if (is_array($aCssFiles) && count($aCssFiles) > 0) { | ||
80 | + //if exists loop through files and add them to iframe mode | ||
81 | + foreach ($aCssFiles AS $cssFile) { | ||
82 | + //registrate file | ||
83 | + $this->view->registerCssFile($cssFile, ['depends' => 'yii\bootstrap\BootstrapAsset']); | ||
84 | + } | ||
85 | + } | ||
86 | + } | ||
87 | + | ||
88 | + //set baseUrl from image manager | ||
89 | + $sBaseUrl = Url::to(['/imagemanager/manager']); | ||
90 | + //set base url | ||
91 | + $this->view->registerJs("imageManagerModule.baseUrl = '" . $sBaseUrl . "';", 3); | ||
92 | + $this->view->registerJs("imageManagerModule.defaultImageId = '" . $defaultImageId . "';", 3); | ||
93 | + $this->view->registerJs("imageManagerModule.fieldId = '" . $inputFieldId . "';", 3); | ||
94 | + $this->view->registerJs("imageManagerModule.cropRatio = '" . $cropAspectRatio . "';", 3); | ||
95 | + $this->view->registerJs("imageManagerModule.cropViewMode = '" . $cropViewMode . "';", 3); | ||
96 | + $this->view->registerJs("imageManagerModule.selectType = '" . $selectType . "';", 3); | ||
97 | + $this->view->registerJs("imageManagerModule.message = " . Json::encode([ | ||
98 | + 'deleteMessage' => Yii::t('imagemanager', 'Are you sure you want to delete this image?'), | ||
99 | + ]) . ";", 3); | ||
100 | + | ||
101 | + $searchModel = new ImageManagerSearch(); | ||
102 | + # die(var_dump(Yii::$app->request->queryParams)); | ||
103 | + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); | ||
104 | + | ||
105 | + //render template | ||
106 | + return $this->render( | ||
107 | + 'index', [ | ||
108 | + 'searchModel' => $searchModel, | ||
109 | + 'dataProvider' => $dataProvider, | ||
110 | + 'viewMode' => $viewMode, | ||
111 | + 'selectType' => $selectType, | ||
112 | + ]); | ||
113 | + } | ||
114 | + | ||
115 | + /** | ||
116 | + * Creates a new ImageManager model. | ||
117 | + * If creation is successful, the browser will be redirected to the 'view' page. | ||
118 | + * @return mixed | ||
119 | + */ | ||
120 | + public function actionUpload() | ||
121 | + { | ||
122 | + //set response header | ||
123 | + Yii::$app->getResponse()->format = Response::FORMAT_JSON; | ||
124 | + // Check if the user is allowed to upload the image | ||
125 | + if (Yii::$app->controller->module->canUploadImage == false) { | ||
126 | + // Return the response array to prevent from the action being executed any further | ||
127 | + return []; | ||
128 | + } | ||
129 | + // Create the transaction and set the success variable | ||
130 | + $transaction = Yii::$app->db->beginTransaction(); | ||
131 | + $bSuccess = false; | ||
132 | + | ||
133 | + //disable Csrf | ||
134 | + Yii::$app->controller->enableCsrfValidation = false; | ||
135 | + //return default | ||
136 | + $return = $_FILES; | ||
137 | + //set media path | ||
138 | + $sMediaPath = \Yii::$app->imagemanager->mediaPath; | ||
139 | + //create the folder | ||
140 | + BaseFileHelper::createDirectory($sMediaPath); | ||
141 | + | ||
142 | + //check file isset | ||
143 | + if (isset($_FILES['imagemanagerFiles']['tmp_name'])) { | ||
144 | + //loop through each uploaded file | ||
145 | + foreach ($_FILES['imagemanagerFiles']['tmp_name'] AS $key => $sTempFile) { | ||
146 | + //collect variables | ||
147 | + $sFileName = $_FILES['imagemanagerFiles']['name'][$key]; | ||
148 | + $sFileExtension = pathinfo($sFileName, PATHINFO_EXTENSION); | ||
149 | + $iErrorCode = $_FILES['imagemanagerFiles']['error'][$key]; | ||
150 | + //if uploaded file has no error code than continue; | ||
151 | + if ($iErrorCode == 0) { | ||
152 | + //create a file record | ||
153 | + $model = new ImageManager(); | ||
154 | + $model->fileName = str_replace("_", "-", $sFileName); | ||
155 | + $model->fileHash = Yii::$app->getSecurity()->generateRandomString(32); | ||
156 | + //if file is saved add record | ||
157 | + if ($model->save()) { | ||
158 | + //move file to dir | ||
159 | + $sSaveFileName = $model->id . "_" . $model->fileHash . "." . $sFileExtension; | ||
160 | + //move_uploaded_file($sTempFile, $sMediaPath."/".$sFileName); | ||
161 | + //save with Imagine class | ||
162 | + Image::getImagine()->open($sTempFile)->save($sMediaPath . "/" . $sSaveFileName); | ||
163 | + $bSuccess = true; | ||
164 | + } | ||
165 | + } | ||
166 | + } | ||
167 | + } | ||
168 | + | ||
169 | + if ($bSuccess) { | ||
170 | + // The upload action went successful, save the transaction | ||
171 | + $transaction->commit(); | ||
172 | + } else { | ||
173 | + // There where problems during the upload, kill the transaction | ||
174 | + $transaction->rollBack(); | ||
175 | + } | ||
176 | + | ||
177 | + //echo return json encoded | ||
178 | + return $return; | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * Crop image and create new ImageManager model. | ||
183 | + * @return mixed | ||
184 | + */ | ||
185 | + public function actionCrop() | ||
186 | + { | ||
187 | + //return | ||
188 | + $return = null; | ||
189 | + //disable Csrf | ||
190 | + Yii::$app->controller->enableCsrfValidation = false; | ||
191 | + //set response header | ||
192 | + Yii::$app->getResponse()->format = Response::FORMAT_JSON; | ||
193 | + //set media path | ||
194 | + $sMediaPath = \Yii::$app->imagemanager->mediaPath; | ||
195 | + //get post | ||
196 | + $ImageManager_id = Yii::$app->request->post("ImageManager_id"); | ||
197 | + $aCropData = Yii::$app->request->post("CropData"); | ||
198 | + //get details | ||
199 | + $modelOriginal = $this->findModel($ImageManager_id); | ||
200 | + //check if path is not null | ||
201 | + if ($modelOriginal->imagePathPrivate !== null && $aCropData !== null) { | ||
202 | + //dimension | ||
203 | + $iDimensionWidth = round($aCropData['width']); | ||
204 | + $iDimensionHeight = round($aCropData['height']); | ||
205 | + //collect variables | ||
206 | + $sFileNameReplace = preg_replace("/_crop_\d+x\d+/", "", $modelOriginal->fileName); | ||
207 | + $sFileName = pathinfo($sFileNameReplace, PATHINFO_FILENAME); | ||
208 | + $sFileExtension = pathinfo($sFileNameReplace, PATHINFO_EXTENSION); | ||
209 | + $sDisplayFileName = $sFileName . "_crop_" . $iDimensionWidth . "x" . $iDimensionHeight . "." . $sFileExtension; | ||
210 | + | ||
211 | + //start transaction | ||
212 | + $transaction = Yii::$app->db->beginTransaction(); | ||
213 | + $bCropSuccess = false; | ||
214 | + | ||
215 | + //create a file record | ||
216 | + $model = new ImageManager(); | ||
217 | + $model->fileName = $sDisplayFileName; | ||
218 | + $model->fileHash = Yii::$app->getSecurity()->generateRandomString(32); | ||
219 | + //if file is saved add record | ||
220 | + if ($model->save()) { | ||
221 | + | ||
222 | + //do crop in try catch | ||
223 | + try { | ||
224 | + // create file name | ||
225 | + $sSaveFileName = $model->id . "_" . $model->fileHash . "." . $sFileExtension; | ||
226 | + | ||
227 | + // get current/original image data | ||
228 | + $imageOriginal = Image::getImagine()->open($modelOriginal->imagePathPrivate); | ||
229 | + $imageOriginalSize = $imageOriginal->getSize(); | ||
230 | + $imageOriginalWidth = $imageOriginalSize->getWidth(); | ||
231 | + $imageOriginalHeight = $imageOriginalSize->getHeight(); | ||
232 | + $imageOriginalPositionX = 0; | ||
233 | + $imageOriginalPositionY = 0; | ||
234 | + | ||
235 | + // create/calculate a canvas size (if canvas is out of the box) | ||
236 | + $imageCanvasWidth = $imageOriginalWidth; | ||
237 | + $imageCanvasHeight = $imageOriginalHeight; | ||
238 | + | ||
239 | + // update canvas width if X position of croparea is lower than 0 | ||
240 | + if ($aCropData['x'] < 0) { | ||
241 | + //set x postion to Absolute value | ||
242 | + $iAbsoluteXpos = abs($aCropData['x']); | ||
243 | + //set x position of image | ||
244 | + $imageOriginalPositionX = $iAbsoluteXpos; | ||
245 | + //add x position to canvas size | ||
246 | + $imageCanvasWidth += $iAbsoluteXpos; | ||
247 | + //update canvas width if croparea is biger than original image | ||
248 | + $iCropWidthWithoutAbsoluteXpos = ($aCropData['width'] - $iAbsoluteXpos); | ||
249 | + if ($iCropWidthWithoutAbsoluteXpos > $imageOriginalWidth) { | ||
250 | + //add ouside the box width | ||
251 | + $imageCanvasWidth += ($iCropWidthWithoutAbsoluteXpos - $imageOriginalWidth); | ||
252 | + } | ||
253 | + } else { | ||
254 | + // add if crop partly ouside image | ||
255 | + $iCropWidthWithXpos = ($aCropData['width'] + $aCropData['x']); | ||
256 | + if ($iCropWidthWithXpos > $imageOriginalWidth) { | ||
257 | + //add ouside the box width | ||
258 | + $imageCanvasWidth += ($iCropWidthWithXpos - $imageOriginalWidth); | ||
259 | + } | ||
260 | + } | ||
261 | + | ||
262 | + // update canvas height if Y position of croparea is lower than 0 | ||
263 | + if ($aCropData['y'] < 0) { | ||
264 | + //set y postion to Absolute value | ||
265 | + $iAbsoluteYpos = abs($aCropData['y']); | ||
266 | + //set y position of image | ||
267 | + $imageOriginalPositionY = $iAbsoluteYpos; | ||
268 | + //add y position to canvas size | ||
269 | + $imageCanvasHeight += $iAbsoluteYpos; | ||
270 | + //update canvas height if croparea is biger than original image | ||
271 | + $iCropHeightWithoutAbsoluteYpos = ($aCropData['height'] - $iAbsoluteYpos); | ||
272 | + if ($iCropHeightWithoutAbsoluteYpos > $imageOriginalHeight) { | ||
273 | + //add ouside the box height | ||
274 | + $imageCanvasHeight += ($iCropHeightWithoutAbsoluteYpos - $imageOriginalHeight); | ||
275 | + } | ||
276 | + } else { | ||
277 | + // add if crop partly ouside image | ||
278 | + $iCropHeightWithYpos = ($aCropData['height'] + $aCropData['y']); | ||
279 | + if ($iCropHeightWithYpos > $imageOriginalHeight) { | ||
280 | + //add ouside the box height | ||
281 | + $imageCanvasHeight += ($iCropHeightWithYpos - $imageOriginalHeight); | ||
282 | + } | ||
283 | + } | ||
284 | + | ||
285 | + // round values | ||
286 | + $imageCanvasWidthRounded = round($imageCanvasWidth); | ||
287 | + $imageCanvasHeightRounded = round($imageCanvasHeight); | ||
288 | + $imageOriginalPositionXRounded = round($imageOriginalPositionX); | ||
289 | + $imageOriginalPositionYRounded = round($imageOriginalPositionY); | ||
290 | + $imageCropWidthRounded = round($aCropData['width']); | ||
291 | + $imageCropHeightRounded = round($aCropData['height']); | ||
292 | + // set postion to 0 if x or y is less than 0 | ||
293 | + $imageCropPositionXRounded = $aCropData['x'] < 0 ? 0 : round($aCropData['x']); | ||
294 | + $imageCropPositionYRounded = $aCropData['y'] < 0 ? 0 : round($aCropData['y']); | ||
295 | + | ||
296 | +// echo "canvas: ". $imageCanvasWidth ." x ".$imageCanvasHeight ."<br />"; | ||
297 | +// echo "img pos x: ". $imageOriginalPositionX ." y ".$imageOriginalPositionY ."<br />"; | ||
298 | +// die(); | ||
299 | +// | ||
300 | + //todo: check if rotaded resize canvas (http://stackoverflow.com/questions/9971230/calculate-rotated-rectangle-size-from-known-bounding-box-coordinates) | ||
301 | + | ||
302 | + // merge current image in canvas, crop image and save | ||
303 | + $imagineRgb = new RGB(); | ||
304 | + $imagineColor = $imagineRgb->color('#FFF', 0); | ||
305 | + // create image | ||
306 | + Image::getImagine()->create(new Box($imageCanvasWidthRounded, $imageCanvasHeightRounded), $imagineColor) | ||
307 | + ->paste($imageOriginal, new Point($imageOriginalPositionXRounded, $imageOriginalPositionYRounded)) | ||
308 | + ->crop(new Point($imageCropPositionXRounded, $imageCropPositionYRounded), new Box($imageCropWidthRounded, $imageCropHeightRounded)) | ||
309 | + ->save($sMediaPath . "/" . $sSaveFileName); | ||
310 | + | ||
311 | + //set boolean crop success to true | ||
312 | + $bCropSuccess = true; | ||
313 | + | ||
314 | + //set return id | ||
315 | + $return = $model->id; | ||
316 | + | ||
317 | + // Check if the original image must be delete | ||
318 | + if ($this->module->deleteOriginalAfterEdit) { | ||
319 | + $modelOriginal->delete(); | ||
320 | + } | ||
321 | + } catch (ErrorException $e) { | ||
322 | + | ||
323 | + } | ||
324 | + } | ||
325 | + | ||
326 | + //commit transaction if boolean is true | ||
327 | + if ($bCropSuccess) { | ||
328 | + $transaction->commit(); | ||
329 | + } | ||
330 | + } | ||
331 | + | ||
332 | + //echo return json encoded | ||
333 | + return $return; | ||
334 | + } | ||
335 | + | ||
336 | + /** | ||
337 | + * Get view details | ||
338 | + * @return mixed | ||
339 | + */ | ||
340 | + public function actionView() | ||
341 | + { | ||
342 | + //disable Csrf | ||
343 | + Yii::$app->controller->enableCsrfValidation = false; | ||
344 | + //return default | ||
345 | + $return = []; | ||
346 | + //set response header | ||
347 | + Yii::$app->getResponse()->format = Response::FORMAT_JSON; | ||
348 | + //get post | ||
349 | + $ImageManager_id = Yii::$app->request->post("ImageManager_id"); | ||
350 | + //get details | ||
351 | + $model = $this->findModel($ImageManager_id); | ||
352 | + //set return details | ||
353 | + $return['id'] = $model->id; | ||
354 | + $return['fileName'] = $model->fileName; | ||
355 | + $return['created'] = Yii::$app->formatter->asDate($model->created); | ||
356 | + $return['fileSize'] = $model->imageDetails['size']; | ||
357 | + $return['dimensionWidth'] = $model->imageDetails['width']; | ||
358 | + $return['dimensionHeight'] = $model->imageDetails['height']; | ||
359 | + $return['image'] = \Yii::$app->imagemanager->getImagePath($model->id, 400, 400, "inset") . "?t=" . time(); | ||
360 | + | ||
361 | + //return json encoded | ||
362 | + return $return; | ||
363 | + } | ||
364 | + | ||
365 | + /** | ||
366 | + * Get full image | ||
367 | + * @return mixed | ||
368 | + */ | ||
369 | + public function actionGetOriginalImage() | ||
370 | + { | ||
371 | + //disable Csrf | ||
372 | + Yii::$app->controller->enableCsrfValidation = false; | ||
373 | + //set response header | ||
374 | + Yii::$app->getResponse()->format = Response::FORMAT_JSON; | ||
375 | + //get post | ||
376 | + $ImageManager_id = Yii::$app->request->post("ImageManager_id"); | ||
377 | + //get details | ||
378 | + $model = $this->findModel($ImageManager_id); | ||
379 | + //set return | ||
380 | + $return = \Yii::$app->imagemanager->getImagePath($model->id, $model->imageDetails['width'], $model->imageDetails['height'], "inset"); | ||
381 | + //return json encoded | ||
382 | + return $return; | ||
383 | + } | ||
384 | + | ||
385 | + /** | ||
386 | + * Deletes an existing ImageManager model. | ||
387 | + * If deletion is successful, the browser will be redirected to the 'index' page. | ||
388 | + * @return mixed | ||
389 | + */ | ||
390 | + public function actionDelete() | ||
391 | + { | ||
392 | + //return | ||
393 | + $return = ['delete' => false]; | ||
394 | + //set response header | ||
395 | + Yii::$app->getResponse()->format = Response::FORMAT_JSON; | ||
396 | + | ||
397 | + if (Yii::$app->controller->module->canRemoveImage == false) { | ||
398 | + // User can not remove this image, return false status | ||
399 | + return $return; | ||
400 | + } | ||
401 | + | ||
402 | + //get post | ||
403 | + $ImageManager_id = Yii::$app->request->post("ImageManager_id"); | ||
404 | + //get details | ||
405 | + $model = $this->findModel($ImageManager_id); | ||
406 | + | ||
407 | + //delete record | ||
408 | + if ($model->delete()) { | ||
409 | + $return['delete'] = true; | ||
410 | + } | ||
411 | + return $return; | ||
412 | + } | ||
413 | + | ||
414 | + /** | ||
415 | + * Finds the ImageManager model based on its primary key value. | ||
416 | + * If the model is not found, a 404 HTTP exception will be thrown. | ||
417 | + * @param integer $id | ||
418 | + * @return ImageManager the loaded model | ||
419 | + * @throws NotFoundHttpException if the model cannot be found | ||
420 | + */ | ||
421 | + protected function findModel($id) | ||
422 | + { | ||
423 | + if (($model = ImageManager::findOne($id)) !== null) { | ||
424 | + /* @var $model ImageManager */ | ||
425 | + // Get the module instance | ||
426 | + $module = Module::getInstance(); | ||
427 | + | ||
428 | + // Check if the model belongs to this user | ||
429 | + if ($module->setBlameableBehavior) { | ||
430 | + // Check if the user and record ID match | ||
431 | + if (Yii::$app->user->id != $model->createdBy) { | ||
432 | + throw new NotFoundHttpException(Yii::t('imagemanager', 'The requested image does not exist.')); | ||
433 | + } | ||
434 | + } | ||
435 | + | ||
436 | + return $model; | ||
437 | + } else { | ||
438 | + throw new NotFoundHttpException(Yii::t('imagemanager', 'The requested image does not exist.')); | ||
439 | + } | ||
440 | + } | ||
441 | + | ||
442 | +} |
backend/components/noam148/imagemanager/docs/images/img_doc-image-manager-crop.jpg
0 → 100644
75.7 KB
backend/components/noam148/imagemanager/docs/images/img_doc-image-manager.jpg
0 → 100644
62.9 KB
backend/components/noam148/imagemanager/docs/images/img_doc-image-widget-popup.jpg
0 → 100644
67.8 KB
backend/components/noam148/imagemanager/docs/images/img_doc-image-widget.jpg
0 → 100644
10 KB
backend/components/noam148/imagemanager/messages/de/imagemanager.php
0 → 100644
1 | +<?php | ||
2 | +return [ | ||
3 | + 'Are you sure you want to delete this image?' => 'Wollen Sie dieses Bild wirklich löschen?', | ||
4 | + 'Are you sure you want to detach the image?' => 'Wollen Sie dieses Bild wirklich lösen?', | ||
5 | + 'Cancel' => 'Annullieren', | ||
6 | + 'Created' => 'Erstellt', | ||
7 | + 'Crop' => 'Zuschneiden', | ||
8 | + 'Crop and select' => 'Zuschneiden und auswählen', | ||
9 | + 'Delete' => 'Löschen', | ||
10 | + 'File hash' => 'File hash', | ||
11 | + 'File name' => 'File Name', | ||
12 | + 'Modified' => 'Geändert', | ||
13 | + 'Search' => 'Suchen', | ||
14 | + 'Select' => 'Auswählen', | ||
15 | + 'Image manager' => 'Image manager', | ||
16 | + 'Upload' => 'Upload' | ||
17 | +]; |
backend/components/noam148/imagemanager/messages/en/imagemanager.php
0 → 100644
1 | +<?php | ||
2 | +return [ | ||
3 | + 'Are you sure you want to delete this image?' => 'Are you sure you want to delete this image?', | ||
4 | + 'Are you sure you want to detach the image?' => 'Are you sure you want to detach the image?', | ||
5 | + 'Cancel' => 'Cancel', | ||
6 | + 'Created' => 'Created', | ||
7 | + 'Crop' => 'Crop', | ||
8 | + 'Crop and select' => 'Crop and select', | ||
9 | + 'Delete' => 'Delete', | ||
10 | + 'File hash' => 'File hash', | ||
11 | + 'File name' => 'File name', | ||
12 | + 'Modified' => 'Modified', | ||
13 | + 'Search' => 'Search', | ||
14 | + 'Select' => 'Select', | ||
15 | + 'Image manager' => 'Image manager', | ||
16 | + 'Upload' => 'Upload' | ||
17 | +]; |
backend/components/noam148/imagemanager/messages/fr/imagemanager.php
0 → 100644
1 | +<?php | ||
2 | +return [ | ||
3 | + 'Are you sure you want to delete this image?' => 'Voulez-vous vraiment effacer cet\'image?', | ||
4 | + 'Are you sure you want to detach the image?' => 'Voules-vous détacher cet\'image?', | ||
5 | + 'Cancel' => 'Annuler', | ||
6 | + 'Created' => 'Crée', | ||
7 | + 'Crop' => 'Ajuster', | ||
8 | + 'Crop and select' => 'Ajuster et sélectionner', | ||
9 | + 'Delete' => 'Effacer', | ||
10 | + 'File hash' => 'Hash du fichier', | ||
11 | + 'File name' => 'Nom du fichier', | ||
12 | + 'Modified' => 'Modifié', | ||
13 | + 'Search' => 'Rechercher', | ||
14 | + 'Select' => 'Sélectionner', | ||
15 | + 'Image manager' => 'Image manager', | ||
16 | + 'Upload' => 'Upload' | ||
17 | +]; |
backend/components/noam148/imagemanager/messages/it/imagemanager.php
0 → 100644
1 | +<?php | ||
2 | +return [ | ||
3 | + 'Are you sure you want to delete this image?' => 'Vuole veramente cancellare questa immagine?', | ||
4 | + 'Are you sure you want to detach the image?' => 'Vuole distaccare questa immagine?', | ||
5 | + 'Cancel' => 'Cancellre', | ||
6 | + 'Created' => 'Creato', | ||
7 | + 'Crop' => 'Tagliare a formato', | ||
8 | + 'Crop and select' => 'Tagliare a formato e selezionare', | ||
9 | + 'Delete' => 'Cancellare', | ||
10 | + 'File hash' => 'File hash', | ||
11 | + 'File name' => 'Nome del file', | ||
12 | + 'Modified' => 'Modificato', | ||
13 | + 'Search' => 'Ricerca', | ||
14 | + 'Select' => 'Selezionare', | ||
15 | + 'Image manager' => 'Image manager', | ||
16 | + 'Upload' => 'Upload' | ||
17 | +]; |
backend/components/noam148/imagemanager/messages/nl/imagemanager.php
0 → 100644
1 | +<?php | ||
2 | +return [ | ||
3 | + 'Are you sure you want to delete this image?' => 'Weet je zeker dat je de afbeelding wilt verwijderen?', | ||
4 | + 'Are you sure you want to detach the image?' => 'Weet je zeker dat je de afbeelding wilt losmaken?', | ||
5 | + 'The requested image does not exist.' => 'De gevraagde afbeelding bestaat niet.', | ||
6 | + 'Cancel' => 'Annuleer', | ||
7 | + 'Created' => 'Aangemaakt', | ||
8 | + 'Created by' => 'Gemaakt door', | ||
9 | + 'Crop' => 'Bijsnijden', | ||
10 | + 'Crop and select' => 'Bijsnijden en selecteren', | ||
11 | + 'Delete' => 'Verwijderen', | ||
12 | + 'File hash' => 'Bestand hash', | ||
13 | + 'File name' => 'Bestandsnaam', | ||
14 | + 'Modified' => 'Gewijzigd', | ||
15 | + 'Modified by' => 'Gewijzigd door', | ||
16 | + 'Search' => 'Zoeken', | ||
17 | + 'Select' => 'Selecteer', | ||
18 | + 'Image manager' => 'Image manager', | ||
19 | + 'Upload' => 'Upload' | ||
20 | +]; | ||
0 | \ No newline at end of file | 21 | \ No newline at end of file |
backend/components/noam148/imagemanager/messages/ru/imagemanager.php
0 → 100644
1 | +<?php | ||
2 | +return [ | ||
3 | + 'Are you sure you want to delete this image?' => 'Вы действительно хотите удалить изображение?', | ||
4 | + 'Are you sure you want to detach the image?' => 'Вы действительно хотите открепить изображение?', | ||
5 | + 'Cancel' => 'Отменить', | ||
6 | + 'Created' => 'Создано', | ||
7 | + 'Crop' => 'Обрезать', | ||
8 | + 'Crop and select' => 'Обрезать и выбрать', | ||
9 | + 'Delete' => 'Удалить', | ||
10 | + 'File hash' => 'Хеш файла', | ||
11 | + 'File name' => 'Имя файла', | ||
12 | + 'Modified' => 'Измененл', | ||
13 | + 'Search' => 'Поиск', | ||
14 | + 'Select' => 'Выбрать', | ||
15 | + 'Image manager' => 'Менеджер изображений', | ||
16 | + 'Upload' => 'Загрузить' | ||
17 | +]; | ||
0 | \ No newline at end of file | 18 | \ No newline at end of file |
backend/components/noam148/imagemanager/migrations/m160622_085710_create_ImageManager_table.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +use yii\db\Migration; | ||
4 | + | ||
5 | +/** | ||
6 | + * Handles the creation for table `ImageManager`. | ||
7 | + */ | ||
8 | +class m160622_085710_create_ImageManager_table extends Migration | ||
9 | +{ | ||
10 | + /** | ||
11 | + * @inheritdoc | ||
12 | + */ | ||
13 | + public function up() | ||
14 | + { | ||
15 | + //ImageManager: create table | ||
16 | + $this->createTable('ImageManager', [ | ||
17 | + 'id' => $this->primaryKey(), | ||
18 | + 'fileName' => $this->string(128)->notNull(), | ||
19 | + 'fileHash' => $this->string(32)->notNull(), | ||
20 | + 'created' => $this->datetime()->notNull(), | ||
21 | + 'modified' => $this->datetime(), | ||
22 | + ]); | ||
23 | + | ||
24 | + //ImageManager: alter id column | ||
25 | + $this->alterColumn('ImageManager', 'id', 'INT(10) UNSIGNED NOT NULL AUTO_INCREMENT'); | ||
26 | + | ||
27 | + } | ||
28 | + | ||
29 | + /** | ||
30 | + * @inheritdoc | ||
31 | + */ | ||
32 | + public function down() | ||
33 | + { | ||
34 | + $this->dropTable('ImageManager'); | ||
35 | + } | ||
36 | +} | ||
0 | \ No newline at end of file | 37 | \ No newline at end of file |
backend/components/noam148/imagemanager/migrations/m170223_113221_addBlameableBehavior.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +use yii\db\Migration; | ||
4 | + | ||
5 | +class m170223_113221_addBlameableBehavior extends Migration | ||
6 | +{ | ||
7 | + public function up() | ||
8 | + { | ||
9 | + $this->addColumn('ImageManager', 'createdBy', $this->integer(10)->unsigned()->null()->defaultValue(null)); | ||
10 | + $this->addColumn('ImageManager', 'modifiedBy', $this->integer(10)->unsigned()->null()->defaultValue(null)); | ||
11 | + } | ||
12 | + | ||
13 | + public function down() | ||
14 | + { | ||
15 | + echo "m170223_113221_addBlameableBehavior cannot be reverted.\n"; | ||
16 | + | ||
17 | + return false; | ||
18 | + } | ||
19 | +} |
backend/components/noam148/imagemanager/models/ImageManager.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager\models; | ||
4 | + | ||
5 | +use backend\components\noam148\imagemanager\Module; | ||
6 | +use Yii; | ||
7 | +use yii\db\Expression; | ||
8 | +use yii\behaviors\TimestampBehavior; | ||
9 | +use yii\behaviors\BlameableBehavior; | ||
10 | + | ||
11 | +/** | ||
12 | + * This is the model class for table "ImageManager". | ||
13 | + * | ||
14 | + * @property integer $id | ||
15 | + * @property string $fileName | ||
16 | + * @property string $fileHash | ||
17 | + * @property string $created | ||
18 | + * @property string $modified | ||
19 | + * @property string $createdBy | ||
20 | + * @property string $modifiedBy | ||
21 | + */ | ||
22 | +class ImageManager extends \yii\db\ActiveRecord | ||
23 | +{ | ||
24 | + | ||
25 | + /** | ||
26 | + * Set Created date to now | ||
27 | + */ | ||
28 | + public function behaviors() | ||
29 | + { | ||
30 | + $aBehaviors = []; | ||
31 | + | ||
32 | + // Add the time stamp behavior | ||
33 | + $aBehaviors[] = [ | ||
34 | + 'class' => TimestampBehavior::className(), | ||
35 | + 'createdAtAttribute' => 'created', | ||
36 | + 'updatedAtAttribute' => 'modified', | ||
37 | + 'value' => new Expression('NOW()'), | ||
38 | + ]; | ||
39 | + | ||
40 | + // Get the imagemanager module from the application | ||
41 | + $moduleImageManager = Yii::$app->getModule('imagemanager'); | ||
42 | + /* @var $moduleImageManager Module */ | ||
43 | + if ($moduleImageManager !== null) { | ||
44 | + // Module has been loaded | ||
45 | + if ($moduleImageManager->setBlameableBehavior) { | ||
46 | + // Module has blame able behavior | ||
47 | + $aBehaviors[] = [ | ||
48 | + 'class' => BlameableBehavior::className(), | ||
49 | + 'createdByAttribute' => 'createdBy', | ||
50 | + 'updatedByAttribute' => 'modifiedBy', | ||
51 | + ]; | ||
52 | + } | ||
53 | + } | ||
54 | + | ||
55 | + return $aBehaviors; | ||
56 | + } | ||
57 | + | ||
58 | + /** | ||
59 | + * @inheritdoc | ||
60 | + */ | ||
61 | + public static function tableName() | ||
62 | + { | ||
63 | + return 'ImageManager'; | ||
64 | + } | ||
65 | + | ||
66 | + /** | ||
67 | + * Get the DB component that the model uses | ||
68 | + * This function will throw error if object could not be found | ||
69 | + * The DB connection defaults to DB | ||
70 | + * @return null|object | ||
71 | + */ | ||
72 | + public static function getDb() | ||
73 | + { | ||
74 | + // Get the image manager object | ||
75 | + $oImageManager = Yii::$app->get('imagemanager', false); | ||
76 | + | ||
77 | + if ($oImageManager === null) { | ||
78 | + // The image manager object has not been set | ||
79 | + // The normal DB object will be returned, error will be thrown if not found | ||
80 | + return Yii::$app->get('db'); | ||
81 | + } | ||
82 | + | ||
83 | + // The image manager component has been loaded, the DB component that has been entered will be loaded | ||
84 | + // By default this is the Yii::$app->db connection, the user can specify any other connection if needed | ||
85 | + return Yii::$app->get($oImageManager->databaseComponent); | ||
86 | + } | ||
87 | + | ||
88 | + /** | ||
89 | + * @inheritdoc | ||
90 | + */ | ||
91 | + public function rules() | ||
92 | + { | ||
93 | + return [ | ||
94 | + [['fileName', 'fileHash'], 'required'], | ||
95 | + [['created', 'modified'], 'safe'], | ||
96 | + [['fileName'], 'string', 'max' => 128], | ||
97 | + [['fileHash'], 'string', 'max' => 32], | ||
98 | + ]; | ||
99 | + } | ||
100 | + | ||
101 | + /** | ||
102 | + * @inheritdoc | ||
103 | + */ | ||
104 | + public function attributeLabels() | ||
105 | + { | ||
106 | + return [ | ||
107 | + 'id' => Yii::t('imagemanager', 'ID'), | ||
108 | + 'fileName' => Yii::t('imagemanager', 'File Name'), | ||
109 | + 'fileHash' => Yii::t('imagemanager', 'File Hash'), | ||
110 | + 'created' => Yii::t('imagemanager', 'Created'), | ||
111 | + 'modified' => Yii::t('imagemanager', 'Modified'), | ||
112 | + 'createdBy' => Yii::t('imagemanager', 'Created by'), | ||
113 | + 'modifiedBy' => Yii::t('imagemanager', 'Modified by'), | ||
114 | + ]; | ||
115 | + } | ||
116 | + | ||
117 | + public function afterDelete() | ||
118 | + { | ||
119 | + parent::afterDelete(); | ||
120 | + | ||
121 | + // Check if file exists | ||
122 | + if (file_exists($this->getImagePathPrivate())) { | ||
123 | + unlink($this->getImagePathPrivate()); | ||
124 | + } | ||
125 | + } | ||
126 | + | ||
127 | + /** | ||
128 | + * Get image path private | ||
129 | + * @return string|null If image file exists the path to the image, if file does not exists null | ||
130 | + */ | ||
131 | + public function getImagePathPrivate() | ||
132 | + { | ||
133 | + //set default return | ||
134 | + $return = null; | ||
135 | + //set media path | ||
136 | + $sMediaPath = \Yii::$app->imagemanager->mediaPath; | ||
137 | + $sFileExtension = pathinfo($this->fileName, PATHINFO_EXTENSION); | ||
138 | + //get image file path | ||
139 | + $sImageFilePath = $sMediaPath . '/' . $this->id . '_' . $this->fileHash . '.' . $sFileExtension; | ||
140 | + //check file exists | ||
141 | + if (file_exists($sImageFilePath)) { | ||
142 | + $return = $sImageFilePath; | ||
143 | + } | ||
144 | + return $return; | ||
145 | + } | ||
146 | + | ||
147 | + /** | ||
148 | + * Get image data dimension/size | ||
149 | + * @return array The image sizes | ||
150 | + */ | ||
151 | + public function getImageDetails() | ||
152 | + { | ||
153 | + //set default return | ||
154 | + $return = ['width' => 0, 'height' => 0, 'size' => 0]; | ||
155 | + //set media path | ||
156 | + $sMediaPath = \Yii::$app->imagemanager->mediaPath; | ||
157 | + $sFileExtension = pathinfo($this->fileName, PATHINFO_EXTENSION); | ||
158 | + //get image file path | ||
159 | + $sImageFilePath = $sMediaPath . '/' . $this->id . '_' . $this->fileHash . '.' . $sFileExtension; | ||
160 | + //check file exists | ||
161 | + if (file_exists($sImageFilePath)) { | ||
162 | + $aImageDimension = getimagesize($sImageFilePath); | ||
163 | + $return['width'] = isset($aImageDimension[0]) ? $aImageDimension[0] : 0; | ||
164 | + $return['height'] = isset($aImageDimension[1]) ? $aImageDimension[1] : 0; | ||
165 | + $return['size'] = Yii::$app->formatter->asShortSize(filesize($sImageFilePath), 2); | ||
166 | + } | ||
167 | + return $return; | ||
168 | + } | ||
169 | + | ||
170 | +} |
backend/components/noam148/imagemanager/models/ImageManagerSearch.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imagemanager\models; | ||
4 | + | ||
5 | +use Yii; | ||
6 | +use yii\base\Model; | ||
7 | +use yii\data\ActiveDataProvider; | ||
8 | +use backend\components\noam148\imagemanager\models\ImageManager; | ||
9 | +use backend\components\noam148\imagemanager\Module; | ||
10 | + | ||
11 | +/** | ||
12 | + * ImageManagerSearch represents the model behind the search form about `common\modules\imagemanager\models\ImageManager`. | ||
13 | + */ | ||
14 | +class ImageManagerSearch extends ImageManager | ||
15 | +{ | ||
16 | + public $globalSearch; | ||
17 | + | ||
18 | + /** | ||
19 | + * @inheritdoc | ||
20 | + */ | ||
21 | + public function rules() | ||
22 | + { | ||
23 | + return [ | ||
24 | + [['globalSearch'], 'safe'], | ||
25 | + ]; | ||
26 | + } | ||
27 | + | ||
28 | + /** | ||
29 | + * @inheritdoc | ||
30 | + */ | ||
31 | + public function scenarios() | ||
32 | + { | ||
33 | + // bypass scenarios() implementation in the parent class | ||
34 | + return Model::scenarios(); | ||
35 | + } | ||
36 | + | ||
37 | + /** | ||
38 | + * Creates data provider instance with search query applied | ||
39 | + * | ||
40 | + * @param array $params | ||
41 | + * | ||
42 | + * @return ActiveDataProvider | ||
43 | + */ | ||
44 | + public function search($params) | ||
45 | + { | ||
46 | + $query = ImageManager::find(); | ||
47 | + | ||
48 | + // add conditions that should always apply here | ||
49 | + | ||
50 | + $dataProvider = new ActiveDataProvider([ | ||
51 | + 'query' => $query, | ||
52 | + 'pagination' => [ | ||
53 | + 'pagesize' => 100, | ||
54 | + ], | ||
55 | + 'sort' => ['defaultOrder' => ['created' => SORT_DESC]] | ||
56 | + ]); | ||
57 | + | ||
58 | + $this->load($params); | ||
59 | + | ||
60 | + if (!$this->validate()) { | ||
61 | + // uncomment the following line if you do not want to return any records when validation fails | ||
62 | + // $query->where('0=1'); | ||
63 | + return $dataProvider; | ||
64 | + } | ||
65 | + | ||
66 | + // Get the module instance | ||
67 | + $module = Module::getInstance(); | ||
68 | + | ||
69 | + if ($module->setBlameableBehavior) { | ||
70 | + $query->andWhere(['createdBy' => Yii::$app->user->id]); | ||
71 | + } | ||
72 | + | ||
73 | + $query->orFilterWhere(['like', 'fileName', $this->globalSearch]); | ||
74 | + # ->orFilterWhere(['like', 'created', $this->globalSearch]) | ||
75 | + #->orFilterWhere(['like', 'modified', $this->globalSearch]); | ||
76 | + | ||
77 | + return $dataProvider; | ||
78 | + } | ||
79 | +} |
backend/components/noam148/imagemanager/views/default/index.php
0 → 100644
backend/components/noam148/imagemanager/views/layouts/blank.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +/* @var $this \yii\web\View */ | ||
4 | + | ||
5 | +/* @var $content string */ | ||
6 | + | ||
7 | +use yii\helpers\Html; | ||
8 | + | ||
9 | +?> | ||
10 | +<?php $this->beginPage() ?> | ||
11 | +<!DOCTYPE html> | ||
12 | +<html lang="<?= Yii::$app->language ?>"> | ||
13 | +<head> | ||
14 | + <meta charset="<?= Yii::$app->charset ?>"> | ||
15 | + <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
16 | + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui"> | ||
17 | + <?= Html::csrfMetaTags() ?> | ||
18 | + <title><?= Html::encode($this->title) ?></title> | ||
19 | + <?php $this->head() ?> | ||
20 | +</head> | ||
21 | +<body> | ||
22 | +<?php $this->beginBody() ?> | ||
23 | + | ||
24 | +<?= $content; ?> | ||
25 | + | ||
26 | +<?php $this->endBody() ?> | ||
27 | +</body> | ||
28 | +</html> | ||
29 | +<?php $this->endPage() ?> |
backend/components/noam148/imagemanager/views/manager/_item.php
0 → 100644
backend/components/noam148/imagemanager/views/manager/index.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +use yii\helpers\Url; | ||
4 | +use yii\helpers\Html; | ||
5 | +use yii\widgets\ListView; | ||
6 | +use yii\widgets\Pjax; | ||
7 | +use kartik\file\FileInput; | ||
8 | + | ||
9 | +$this->title = Yii::t('imagemanager', 'Image manager'); | ||
10 | + | ||
11 | +?> | ||
12 | +<div id="module-imagemanager" class="container-fluid <?= $selectType ?>"> | ||
13 | + <div class="row"> | ||
14 | + <div class="col-xs-6 col-sm-10 col-image-editor"> | ||
15 | + <div class="image-cropper"> | ||
16 | + <div class="image-wrapper"> | ||
17 | + <img id="image-cropper"/> | ||
18 | + </div> | ||
19 | + <div class="action-buttons"> | ||
20 | + <a href="#" class="btn btn-primary apply-crop"> | ||
21 | + <i class="fa fa-crop"></i> | ||
22 | + <span class="hidden-xs"><?= Yii::t('imagemanager', 'Crop') ?></span> | ||
23 | + </a> | ||
24 | + <?php if ($viewMode === "iframe"): ?> | ||
25 | + <a href="#" class="btn btn-primary apply-crop-select"> | ||
26 | + <i class="fa fa-crop"></i> | ||
27 | + <span class="hidden-xs"><?= Yii::t('imagemanager', 'Crop and select') ?></span> | ||
28 | + </a> | ||
29 | + <?php endif; ?> | ||
30 | + <a href="#" class="btn btn-default cancel-crop"> | ||
31 | + <i class="fa fa-undo"></i> | ||
32 | + <span class="hidden-xs"><?= Yii::t('imagemanager', 'Cancel') ?></span> | ||
33 | + </a> | ||
34 | + </div> | ||
35 | + </div> | ||
36 | + </div> | ||
37 | + <div class="col-xs-6 col-sm-10 col-overview"> | ||
38 | + <?php Pjax::begin([ | ||
39 | + 'id' => 'pjax-mediamanager', | ||
40 | + 'timeout' => '5000' | ||
41 | + ]); ?> | ||
42 | + <?= ListView::widget([ | ||
43 | + 'dataProvider' => $dataProvider, | ||
44 | + 'itemOptions' => ['class' => 'item img-thumbnail'], | ||
45 | + 'layout' => "<div class='item-overview'>{items}</div> {pager}", | ||
46 | + 'itemView' => function ($model, $key, $index, $widget) { | ||
47 | + return $this->render("_item", ['model' => $model]); | ||
48 | + }, | ||
49 | + ]) ?> | ||
50 | + <?php Pjax::end(); ?> | ||
51 | + </div> | ||
52 | + <div class="col-xs-6 col-sm-2 col-options"> | ||
53 | + <div class="form-group"> | ||
54 | + <?= Html::textInput('input-mediamanager-search', null, ['id' => 'input-mediamanager-search', 'class' => 'form-control', 'placeholder' => Yii::t('imagemanager', 'Search') . '...']) ?> | ||
55 | + </div> | ||
56 | + | ||
57 | + <?php | ||
58 | + if (Yii::$app->controller->module->canUploadImage): | ||
59 | + ?> | ||
60 | + | ||
61 | + <?= FileInput::widget([ | ||
62 | + 'name' => 'imagemanagerFiles[]', | ||
63 | + 'id' => 'imagemanager-files', | ||
64 | + 'options' => [ | ||
65 | + 'multiple' => true, | ||
66 | + 'accept' => 'image/*' | ||
67 | + ], | ||
68 | + 'pluginOptions' => [ | ||
69 | + 'uploadUrl' => Url::to(['manager/upload']), | ||
70 | + 'allowedFileExtensions' => \Yii::$app->controller->module->allowedFileExtensions, | ||
71 | + 'uploadAsync' => false, | ||
72 | + 'showPreview' => false, | ||
73 | + 'showRemove' => false, | ||
74 | + 'showUpload' => false, | ||
75 | + 'showCancel' => false, | ||
76 | + 'browseClass' => 'btn btn-primary btn-block', | ||
77 | + 'browseIcon' => '<i class="fa fa-upload"></i> ', | ||
78 | + 'browseLabel' => Yii::t('imagemanager', 'Upload') | ||
79 | + ], | ||
80 | + 'pluginEvents' => [ | ||
81 | + "filebatchselected" => "function(event, files){ $('.msg-invalid-file-extension').addClass('hide'); $(this).fileinput('upload'); }", | ||
82 | + "filebatchuploadsuccess" => "function(event, data, previewId, index) { | ||
83 | + imageManagerModule.uploadSuccess(data.jqXHR.responseJSON.imagemanagerFiles); | ||
84 | + }", | ||
85 | + "fileuploaderror" => "function(event, data) { $('.msg-invalid-file-extension').removeClass('hide'); }", | ||
86 | + ], | ||
87 | + ]) ?> | ||
88 | + | ||
89 | + <?php | ||
90 | + endif; | ||
91 | + ?> | ||
92 | + | ||
93 | + <div class="image-info hide"> | ||
94 | + <div class="thumbnail"> | ||
95 | + <img src="#"> | ||
96 | + </div> | ||
97 | + <div class="edit-buttons"> | ||
98 | + <a href="#" class="btn btn-primary btn-block crop-image-item"> | ||
99 | + <i class="fa fa-crop"></i> | ||
100 | + <span class="hidden-xs"><?= Yii::t('imagemanager', 'Crop') ?></span> | ||
101 | + </a> | ||
102 | + </div> | ||
103 | + <div class="details"> | ||
104 | + <div class="fileName"></div> | ||
105 | + <div class="created"></div> | ||
106 | + <div class="fileSize"></div> | ||
107 | + <div class="dimensions"><span class="dimension-width"></span> × <span | ||
108 | + class="dimension-height"></span></div> | ||
109 | + <?php | ||
110 | + if (Yii::$app->controller->module->canRemoveImage): | ||
111 | + ?> | ||
112 | + <a href="#" class="btn btn-xs btn-danger delete-image-item"><span | ||
113 | + class="glyphicon glyphicon-trash" | ||
114 | + aria-hidden="true"></span> <?= Yii::t('imagemanager', 'Delete') ?></a> | ||
115 | + <?php | ||
116 | + endif; | ||
117 | + ?> | ||
118 | + </div> | ||
119 | + <?php if ($viewMode === "iframe"): ?> | ||
120 | + <a href="#" | ||
121 | + class="btn btn-primary btn-block pick-image-item"><?= Yii::t('imagemanager', 'Select') ?></a> | ||
122 | + <?php endif; ?> | ||
123 | + </div> | ||
124 | + </div> | ||
125 | + </div> | ||
126 | +</div> | ||
0 | \ No newline at end of file | 127 | \ No newline at end of file |
backend/components/noam148/imageresize/ImageResize.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\components\noam148\imageresize; | ||
4 | + | ||
5 | +use Yii; | ||
6 | +use yii\helpers\Url; | ||
7 | +use yii\helpers\FileHelper; | ||
8 | +use yii\imagine\Image; | ||
9 | +use yii\base\Exception; | ||
10 | +use Imagine\Image\Box; | ||
11 | +use Imagine\Image\ManipulatorInterface; | ||
12 | + | ||
13 | +class ImageResize | ||
14 | +{ | ||
15 | + | ||
16 | + const IMAGE_OUTBOUND = ManipulatorInterface::THUMBNAIL_OUTBOUND; | ||
17 | + const IMAGE_INSET = ManipulatorInterface::THUMBNAIL_INSET; | ||
18 | + | ||
19 | + /** @var string $cachePath path alias relative with webroot where the cache files are kept */ | ||
20 | + public $cachePath = 'assets/images'; | ||
21 | + | ||
22 | + /** @var int $cacheExpire */ | ||
23 | + public $cacheExpire = 0; | ||
24 | + | ||
25 | + /** @var int $imageQuality */ | ||
26 | + public $imageQuality = 50; | ||
27 | + | ||
28 | + /** @var int $useFilename if true show filename in url */ | ||
29 | + public $useFilename = true; | ||
30 | + | ||
31 | + /** @var int $absoluteUrl if true include domain in url */ | ||
32 | + public $absoluteUrl = false; | ||
33 | + | ||
34 | + /** | ||
35 | + * Creates and caches the image thumbnail and returns full path from thumbnail file. | ||
36 | + * | ||
37 | + * @param string $filePath to original file | ||
38 | + * @param integer $width | ||
39 | + * @param integer $height | ||
40 | + * @param string $mode | ||
41 | + * @param integer $quality (1 - 100 quality) | ||
42 | + * @param string $chosenFileName (custome filename) | ||
43 | + * @return string | ||
44 | + * @throws Exception | ||
45 | + */ | ||
46 | + public function generateImage($filePath, $width, $height, $mode = "outbound", $quality = null, $chosenFileName = null) | ||
47 | + { | ||
48 | + $filePath = FileHelper::normalizePath(Yii::getAlias($filePath)); | ||
49 | + if (!is_file($filePath)) { | ||
50 | + throw new Exception("File $filePath doesn't exist"); | ||
51 | + } | ||
52 | + | ||
53 | + //set resize mode | ||
54 | + $resizeMode = null; | ||
55 | + switch ($mode) { | ||
56 | + case "outbound": | ||
57 | + $resizeMode = ImageResize::IMAGE_OUTBOUND; | ||
58 | + break; | ||
59 | + case "inset": | ||
60 | + $resizeMode = ImageResize::IMAGE_INSET; | ||
61 | + break; | ||
62 | + default: | ||
63 | + throw new Exception('generateImage $mode is not valid choose for "outbound" or "inset"'); | ||
64 | + } | ||
65 | + | ||
66 | + //create some vars | ||
67 | + $cachePath = Yii::getAlias('@webroot/' . $this->cachePath); | ||
68 | + //get fileinfo | ||
69 | + $aFileInfo = pathinfo($filePath); | ||
70 | + //set default filename | ||
71 | + $sFileHash = md5($filePath . $width . $height . $resizeMode . filemtime($filePath)); | ||
72 | + $imageFileName = null; | ||
73 | + //if $this->useFilename set to true? use seo friendly name | ||
74 | + if ($this->useFilename === true) { | ||
75 | + //set hash and default name | ||
76 | + $sFileHashShort = substr($sFileHash, 0, 6); | ||
77 | + $sFileName = $aFileInfo['filename']; | ||
78 | + //set choosen filename if $chosenFileName not null. | ||
79 | + if ($chosenFileName !== null) { | ||
80 | + $sFileName = preg_replace('/(\.\w+)$/', '', $chosenFileName); | ||
81 | + } | ||
82 | + //replace for seo friendly file name | ||
83 | + $sFilenameReplace = preg_replace("/[^\w\.\-]+/", '-', $sFileName); | ||
84 | + //set filename | ||
85 | + $imageFileName = $sFileHashShort . "_" . $sFilenameReplace; | ||
86 | + //else use file hash as filename | ||
87 | + } else { | ||
88 | + $imageFileName = $sFileHash; | ||
89 | + } | ||
90 | + | ||
91 | + $imageFileExt = "." . $aFileInfo['extension']; | ||
92 | + $imageFilePath = $cachePath . DIRECTORY_SEPARATOR . substr($imageFileName, 0, 2); | ||
93 | + $imageFile = $imageFilePath . DIRECTORY_SEPARATOR . $imageFileName . $imageFileExt; | ||
94 | + | ||
95 | + if (file_exists($imageFile)) { | ||
96 | + if ($this->cacheExpire !== 0 && (time() - filemtime($imageFile)) > $this->cacheExpire) { | ||
97 | + unlink($imageFile); | ||
98 | + } else { | ||
99 | + return $imageFile; | ||
100 | + } | ||
101 | + } | ||
102 | + //if dir not exist create cache edir | ||
103 | + if (!is_dir($imageFilePath)) { | ||
104 | + FileHelper::createDirectory($imageFilePath, 0755); | ||
105 | + } | ||
106 | + //create image | ||
107 | + $box = new Box($width, $height); | ||
108 | + $image = Image::getImagine()->open($filePath); | ||
109 | + $image = $image->thumbnail($box, $resizeMode); | ||
110 | + | ||
111 | + $options = [ | ||
112 | + 'quality' => $quality === null ? $this->imageQuality : $quality | ||
113 | + ]; | ||
114 | + $image->save($imageFile, $options); | ||
115 | + return $imageFile; | ||
116 | + } | ||
117 | + | ||
118 | + /** | ||
119 | + * Creates and caches the image and returns URL from resized file. | ||
120 | + * | ||
121 | + * @param string $filePath to original file | ||
122 | + * @param integer $width | ||
123 | + * @param integer $height | ||
124 | + * @param string $mode | ||
125 | + * @param integer $quality (1 - 100 quality) | ||
126 | + * @param string $fileName (custome filename) | ||
127 | + * @return string | ||
128 | + */ | ||
129 | + public function getUrl($filePath, $width, $height, $mode = "outbound", $quality = null, $fileName = null) | ||
130 | + { | ||
131 | + //get original file | ||
132 | + $normalizePath = FileHelper::normalizePath(Yii::getAlias($filePath)); | ||
133 | + //get cache url | ||
134 | + $cacheUrl = Yii::getAlias($this->cachePath); | ||
135 | + //generate file | ||
136 | + $resizedFilePath = self::generateImage($normalizePath, $width, $height, $mode, $quality, $fileName); | ||
137 | + //get resized file | ||
138 | + $normalizeResizedFilePath = FileHelper::normalizePath($resizedFilePath); | ||
139 | + $resizedFileName = pathinfo($normalizeResizedFilePath, PATHINFO_BASENAME); | ||
140 | + //get url | ||
141 | + $sFileUrl = Url::to('@web/' . $cacheUrl . '/' . substr($resizedFileName, 0, 2) . '/' . $resizedFileName, $this->absoluteUrl); | ||
142 | + //return path | ||
143 | + return $sFileUrl; | ||
144 | + } | ||
145 | + | ||
146 | + /** | ||
147 | + * Clear cache directory. | ||
148 | + * | ||
149 | + * @return bool | ||
150 | + */ | ||
151 | + public function clearCache() | ||
152 | + { | ||
153 | + $cachePath = Yii::getAlias('@webroot/' . $this->cachePath); | ||
154 | + //remove dir | ||
155 | + FileHelper::removeDirectory($cachePath); | ||
156 | + //creat dir | ||
157 | + return FileHelper::createDirectory($cachePath, 0755); | ||
158 | + } | ||
159 | + | ||
160 | +} |
1 | +MIT License | ||
2 | + | ||
3 | +Copyright (c) 2016 noam148 | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | +of this software and associated documentation files (the "Software"), to deal | ||
7 | +in the Software without restriction, including without limitation the rights | ||
8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | +copies of the Software, and to permit persons to whom the Software is | ||
10 | +furnished to do so, subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in all | ||
13 | +copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | +SOFTWARE. |
1 | +Image resize for Yii2 | ||
2 | +======================== | ||
3 | + | ||
4 | +A Yii2 component for resizing images and store it in a cache folder | ||
5 | + | ||
6 | +Installation | ||
7 | +------------ | ||
8 | +The preferred way to install this extension is through [composer](http://getcomposer.org/download/). | ||
9 | + | ||
10 | +* Either run | ||
11 | + | ||
12 | +``` | ||
13 | +php composer.phar require "noam148/yii2-image-resize" "*" | ||
14 | +``` | ||
15 | +or add | ||
16 | + | ||
17 | +```json | ||
18 | +"noam148/yii2-image-resize" : "*" | ||
19 | +``` | ||
20 | + | ||
21 | +to the require section of your application's `composer.json` file. | ||
22 | + | ||
23 | +* Add a new component in `components` section of your application's configuration file, for example: | ||
24 | + | ||
25 | +```php | ||
26 | +'components' => [ | ||
27 | + 'imageresize' => [ | ||
28 | + 'class' => 'noam148\imageresize\ImageResize', | ||
29 | + //path relative web folder | ||
30 | + 'cachePath' => 'assets/images', | ||
31 | + //use filename (seo friendly) for resized images else use a hash | ||
32 | + 'useFilename' => true, | ||
33 | + //show full url (for example in case of a API) | ||
34 | + 'absoluteUrl' => false, | ||
35 | + ], | ||
36 | +], | ||
37 | +``` | ||
38 | + | ||
39 | +Usage | ||
40 | +----- | ||
41 | + | ||
42 | +If you want to get a image url: | ||
43 | + | ||
44 | +```php | ||
45 | +/* | ||
46 | + * $sImageFilePath_id: (required) path to file | ||
47 | + * $width/$height: (required) width height of the image | ||
48 | + * $mode: "outbound" or "inset" | ||
49 | + * $$quality: (1 - 100) | ||
50 | + * $chosenFileName: if config -> components -> imageresize -> useFilename is true? its an option to give a custom name else use original file name | ||
51 | + */ | ||
52 | +\Yii::$app->imageresize->getUrl($sImageFilePath, $width, $height, $mode, $quality, $chosenFileName); | ||
53 | +``` | ||
54 | + | ||
55 | +**If you got questions, tips or feedback? Please, let me know!** | ||
0 | \ No newline at end of file | 56 | \ No newline at end of file |
backend/components/noam148/imageresize/composer.json
0 → 100644
1 | +{ | ||
2 | + "name": "noam148/yii2-image-resize", | ||
3 | + "description": "A Yii2 component for resizing images (on the fly)", | ||
4 | + "keywords": [ | ||
5 | + "yii2", | ||
6 | + "extension", | ||
7 | + "component", | ||
8 | + "image", | ||
9 | + "resize", | ||
10 | + "on-the-fly" | ||
11 | + ], | ||
12 | + "homepage": "https://github.com/noam148/yii2-image-resize", | ||
13 | + "type": "yii2-extension", | ||
14 | + "license": "BSD-3-Clause", | ||
15 | + "authors": [ | ||
16 | + { | ||
17 | + "name": "Noam148", | ||
18 | + "homepage": "https://github.com/noam148/" | ||
19 | + } | ||
20 | + ], | ||
21 | + "require": { | ||
22 | + "yiisoft/yii2": "*", | ||
23 | + "yiisoft/yii2-imagine": "*" | ||
24 | + }, | ||
25 | + "autoload": { | ||
26 | + "psr-4": { | ||
27 | + "noam148\\imageresize\\": "" | ||
28 | + } | ||
29 | + } | ||
30 | +} | ||
0 | \ No newline at end of file | 31 | \ No newline at end of file |
common/config/main.php
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor', | 7 | 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor', |
8 | 'modules' => [ | 8 | 'modules' => [ |
9 | 'imagemanager' => [ | 9 | 'imagemanager' => [ |
10 | - 'class' => 'noam148\imagemanager\Module', | 10 | + 'class' => 'backend\components\noam148\imagemanager\Module', |
11 | 'canUploadImage' => true, | 11 | 'canUploadImage' => true, |
12 | 'canRemoveImage' => function () { | 12 | 'canRemoveImage' => function () { |
13 | return true; | 13 | return true; |
@@ -61,8 +61,9 @@ | @@ -61,8 +61,9 @@ | ||
61 | 'filter' => [ | 61 | 'filter' => [ |
62 | 'class' => FilterHelper::className(), | 62 | 'class' => FilterHelper::className(), |
63 | ], | 63 | ], |
64 | + # пересозданный модуль, детальнее в back\com\noam\docs\why | ||
64 | 'imagemanager' => [ | 65 | 'imagemanager' => [ |
65 | - 'class' => 'noam148\imagemanager\components\ImageManagerGetPath', | 66 | + 'class' => 'backend\components\noam148\imagemanager\components\ImageManagerGetPath', |
66 | 'mediaPath' => dirname(dirname(__DIR__)) . '/storage', | 67 | 'mediaPath' => dirname(dirname(__DIR__)) . '/storage', |
67 | 'cachePath' => '../../storage/cache', | 68 | 'cachePath' => '../../storage/cache', |
68 | 'useFilename' => true, | 69 | 'useFilename' => true, |