1 <?php
2 3 4 5 6
7 class ImageEditor extends Controller {
8
9 static $allowed_actions = array(
10 '*' => 'CMS_ACCESS_CMSMain'
11 );
12
13 public $fileToEdit = "";
14
15 public $fileToEditOnlyName = "";
16
17 18 19 20 21 22
23 public function index() {
24 Requirements::clear();
25 Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/prototype/prototype.js');
26 Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/scriptaculous.js');
27 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Utils.js');
28
29 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Image.js');
30
31 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Resizeable.js');
32 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Effects.js');
33 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Environment.js');
34 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Crop.js');
35 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Resize.js');
36 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageBox.js');
37 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageEditor.js');
38 Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/DocumentBody.js');
39
40 Requirements::javascript(SAPPHIRE_DIR . '/javascript/loader.js');
41 Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/behaviour/behaviour.js');
42 Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.js');
43 Requirements::css(CMS_DIR . 'css/ImageEditor/ImageEditor.css');
44
45 if(!isset($this->requestParams['fileToEdit'])) $this->raiseError();
46 $fileWithPath = $this->requestParams['fileToEdit'];
47 $this->fileToEdit = $this->file2Origin($fileWithPath);
48 $this->fileToEditOnlyName = $this->urlToFilename($this->fileToEdit);
49 return $this->renderWith(__CLASS__);
50 }
51
52 53 54 55 56 57 58 59 60 61
62 public function manipulate() {
63 $fileName = $this->requestParams['file'];
64 if(strpos($fileName,'?') !== false) $fileName = substr($fileName,0,strpos($fileName,'?'));
65 $command = $this->requestParams['command'];
66 $this->checkFileExists($fileName);
67 $fileInfo = pathinfo($fileName);
68 $gd = new GD($this->url2File($fileName));
69 switch($command) {
70 case 'rotate':
71 $gd = $gd->rotate(90);
72 break;
73 case 'resize':
74 $imageNewWidth = $_POST['newImageWidth'];
75 $imageNewHeight = $_POST['newImageHeight'];
76 $gd = $gd->resize($imageNewWidth,$imageNewHeight);
77 break;
78 case 'crop':
79 $top = $_POST['top'];
80 $left = $_POST['left'];
81 $width = $_POST['width'];
82 $height = $_POST['height'];
83 $gd = $gd->crop($top,$left,$width,$height);
84 break;
85 case 'greyscale':
86 $gd = $gd->greyscale();
87 break;
88 case 'sepia':
89 $gd = $gd->sepia();
90 break;
91 case 'blur':
92 $gd = $gd->blur();
93 break;
94 case 'adjust-contrast':
95 $value = intval($_POST['value']);
96 $gd = $gd->contrast($value);
97 break;
98 case 'adjust-brightness':
99 $value = intval($_POST['value']);
100 $gd = $gd->brightness($value);
101 break;
102 case 'adjust-gamma':
103 $value = floatval($_POST['value']);
104 $gd = $gd->gamma($value);
105 break;
106 }
107 $rand = md5(rand(1,100000));
108 $gd->writeTo(ASSETS_PATH . '/_tmp/' . $rand . '.' . $fileInfo['extension']);
109 return $this->getImageInfoInJSON($gd,ASSETS_PATH . '/_tmp/' . $rand . '.' . $fileInfo['extension']);
110 }
111
112 113 114 115 116 117 118 119 120 121
122
123 public function save() {
124 if(isset($this->requestParams['originalFile']) && isset($this->requestParams['editedFile'])) {
125 $originalFile = $this->requestParams['originalFile'];
126 $editedFile = $this->requestParams['editedFile'];
127 if(strpos($originalFile,'?') !== false) $originalFile = substr($originalFile,0,strpos($originalFile,'?'));
128 if($this->checkFileExists($originalFile) && $this->checkFileExists($editedFile)) {
129 if($editedFile != $originalFile && copy($this->url2File($editedFile),$this->url2File($originalFile))) {
130 $image = DataObject::get_one('File','"Filename" = \'' . substr($this->url2File($originalFile),3) . '\'');
131 $image->deleteFormattedImages();
132 $image->generateFormattedImage('AssetLibraryPreview');
133 } else {
134 $this->raiseError();
135 }
136 } else {
137 $this->raiseError();
138 }
139 } else {
140 $this->raiseError();
141 }
142 return 'parent.parent.parent.statusMessage(\'Image saved\',\'good\',false);';
143 }
144
145 146 147 148 149 150 151 152
153
154 public function close() {
155 $tmpDir = ASSETS_PATH . '/_tmp';
156 if(file_exists($tmpDir)) {
157 Filesystem::removeFolder($tmpDir);
158 mkdir($tmpDir, Filesystem::$folder_create_mask);
159 }
160 }
161
162 163 164 165 166 167 168 169
170
171 private function getImageInfoInJSON(GD $gd,$file) {
172 return '{"fileName":"' . $file . '","width":' . $gd->getWidth() . ',"height":' . $gd->getHeight() . '}';
173 }
174
175 176 177 178 179 180 181
182
183 private function file2Origin($file) {
184 $file = str_replace('_resampled/','',$file);
185 $file = str_replace('_resampled/','',$file);
186 $file = str_replace('AssetLibraryPreview-','',$file);
187 $this->checkFileExists($file);
188 return $file;
189 }
190 191 192 193 194 195 196
197
198 private function url2File($url) {
199 return '..' . substr($url,strpos($url,'/assets'));
200 }
201
202 203 204 205 206 207 208 209 210
211
212 private function checkFileExists($url) {
213 if(strpos($url,'?') !== false) $url = substr($url,0,strpos($url,'?'));
214 $pathInfo = pathinfo($url);
215 if(count($pathInfo) < 3) $this->raiseError();
216 if(!in_array($pathInfo['extension'],array('jpeg','jpg','jpe','png','gif','JPEG','JPG','JPE','PNG','GIF'))) $this->raiseError();
217 $path = explode('/',$pathInfo['dirname']);
218 if(count($path) > 1) {
219 $assetId = array_search('assets',$path);
220 if($assetId > 0) {
221 $realPath = '../' . implode('/',array_slice($path,$assetId,count($path) - $assetId));
222 if(strpos($pathInfo['basename'],'AssetLibraryPreview') !== false) {
223 $realPath .= '/' . substr($pathInfo['basename'],strpos($pathInfo['basename'],'-'));
224 } else {
225 $realPath .= '/' . $pathInfo['basename'];
226 }
227 } else {
228 $this->raiseError();
229 }
230 if(file_exists($realPath)) {
231 return true;
232 } else {
233 $this->raiseError();
234 }
235 } else {
236 $this->raiseError();
237 }
238 }
239
240 241 242 243 244 245
246
247 private function raiseError($message = "") {
248 echo "parent.parent.parent.statusMessage('Error: " . $message . "','bad',false);";
249 exit();
250 }
251
252 253 254 255 256 257
258
259 private function urlToFilename($url) {
260 $path = pathinfo($url);
261 return $path['filename'] . "." . substr($path['extension'],0,strpos($path['extension'],'?'));
262 }
263 }
264
265 ?>
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-