1 <?php
2
3 class FileDataObjectManager extends DataObjectManager {
4 static $url_handlers = array(
5 'import/$ID' => 'handleImport'
6 );
7
8 public static $upgrade_audio = true;
9 public static $upgrade_video = true;
10 public static $upgrade_image = true;
11
12 public $view;
13 public $default_view = "grid";
14 protected $allowedFileTypes;
15 protected $limitFileTypes;
16 protected $uploadLimit = "20";
17 protected $uploadMaxSize = 0;
18 protected $allowUploadFolderSelection = false;
19 protected $enableUploadDebugging = false;
20 protected $customPreviewField = false;
21 public $hasDataObject = true;
22 public $importClass = "File";
23
24 protected $permissions = array(
25 "add",
26 "edit",
27 "show",
28 "delete",
29 "upload",
30 "import"
31 );
32 public = "FileDataObjectManager_Popup";
33 public $itemClass = "FileDataObjectManager_Item";
34 public $template = "FileDataObjectManager";
35 public = "DataObjectManager_popup";
36
37 public $gridLabelField;
38 public $pluralTitle;
39 public $browseButtonText = 'Upload files';
40
41 public $uploadFolder = "Uploads";
42
43
44
45 public function __construct($controller, $name = null, $sourceClass = null, $fileFieldName = null, $fieldList = null, $detailFormFields = null, $sourceFilter = "", $sourceSort = "", $sourceJoin = "") {
46 if(!class_exists("MultiUploadField"))
47 die("<strong>"._t('DataObjectManager.ERROR','Error')."</strong>: "._t('FileDataObjectManager.SWFUPLOAD','DataObjectManager requires the SWFUpload module.'));
48 parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
49
50 $SNG = singleton($this->sourceClass());
51 if($fileFieldName === null) {
52 if($has_ones = $SNG->stat('has_one')) {
53 foreach($has_ones as $relation => $value) {
54 if($value == "File" || is_subclass_of($value,"File")) {
55 $fileFieldName = $relation;
56 $fileClassName = $value;
57 break;
58 }
59 }
60 }
61 }
62
63 if(isset($_REQUEST['ctf'][$this->Name()])) {
64 $this->view = $_REQUEST['ctf'][$this->Name()]['view'];
65 $this->search = $_REQUEST['ctf'][$this->Name()]['search'];
66 }
67 if($this->sourceClass() == "File" || is_subclass_of($this->sourceClass(), "File")) {
68 $this->hasDataObject = false;
69 $this->fileFieldName = $name;
70 $this->fileClassName = $this->sourceClass();
71 $this->dataObjectFieldName = null;
72 }
73 else {
74 $this->dataObjectFieldName = $name;
75 $this->fileFieldName = $fileFieldName;
76 $this->fileClassName = $SNG->has_one($this->fileFieldName);
77 if(!$this->fileClassName)
78 die("<strong>FileDataObjectManager::__construct():</strong>"._t('FileDataObjectManager.FILERELATION','Could not determine file relationship'));
79 }
80
81 $this->controllerClassName = $controller->class;
82 if($key = array_search($this->controllerClassName, $SNG->stat('has_one')))
83 $this->controllerFieldName = $key;
84 else
85 $this->controllerFieldName = $this->controllerClassName;
86 $this->controllerID = $controller->ID;
87
88 if($types = Object::get_static($this->fileClassName,'allowed_file_types'))
89 $this->setAllowedFileTypes($types);
90
91 $this->setAllowedFileTypes(File::$allowed_extensions);
92
93 $this->setBrowseButtonText(_t('FileDataObjectManager.UPLOAD_FILES', 'Upload files'));
94
95 if (property_exists('WebylonSiteConfig', 'max_file_upload_size')) {
96 $this->uploadMaxSize = WebylonSiteConfig::$max_file_upload_size;
97 } else {
98 $this->uploadMaxSize = ((int)ini_get('upload_max_filesize')) * 1024 * 1024;
99 }
100 }
101
102 public function getQueryString($params = array()) {
103 $view = isset($params['view'])? $params['view'] : $this->view;
104 return parent::getQueryString($params)."&ctf[{$this->Name()}][view]={$view}";
105 }
106
107 public function setGridLabelField($fieldName) {
108 $this->gridLabelField = $fieldName;
109 }
110
111 public function GridLink() {
112 return $this->RelativeLink(array('view' => 'grid'));
113 }
114
115 public function ListLink() {
116 return $this->RelativeLink(array('view' => 'list'));
117 }
118
119 public function GridView() {
120 return $this->ListStyle() == "grid";
121 }
122
123 public function ListView() {
124 return $this->ListStyle() == "list";
125 }
126
127 public function ListStyle() {
128 return $this->view ? $this->view : $this->default_view;
129 }
130
131
132 public function ImportDropdown() {
133 return new HTMLDropdownField('ImportFolder','',$this->getImportFolderHierarchy(0),null, null, "-- "._t('DataObjectManager.SELECTFOLDER', 'Select a folder')." --");
134 }
135
136 protected function importLinkFor($file) {
137 return $this->BaseLink()."/import/$file->ID";
138 }
139
140 protected function getImportFolderHierarchy($parentID, $level = 0) {
141 $options = array();
142 if($children = DataObject::get("Folder", "ParentID = $parentID")) {
143 foreach($children as $child) {
144 $indent="";
145 for($i=0;$i<$level;$i++) $indent .= " ";
146 $files = DataObject::get($this->importClass, "ClassName != 'Folder' AND ParentID = $child->ID");
147 $count = $files ? $files->Count() : "0";
148 $options[$this->importLinkFor($child)] = $indent.$child->Title . " <span>($count files)</span>";
149 $options += $this->getImportFolderHierarchy($child->ID, $level+1);
150 }
151 }
152 return $options;
153 }
154
155 protected function getUploadFolderHierarchy($parentID, $level = 0) {
156 $options = array();
157 if($children = DataObject::get("Folder", "ParentID = $parentID")) {
158 foreach($children as $child) {
159 $indent="";
160 for($i=0;$i<$level;$i++) $indent .= " ";
161 $options[$child->ID] = empty($child->Title) ? "<em>$indent Untitled</em>" : $indent.$child->Title;
162 $options += $this->getUploadFolderHierarchy($child->ID, $level+1);
163 }
164 }
165 return $options;
166 }
167
168
169 public function setAllowedFileTypes($types = array()) {
170 171 172 173 174 175 176
177 $this->allowedFileTypes = $types;
178 }
179
180 public function getAllowedFileTypes() {
181 return $this->allowedFileTypes;
182 }
183
184 public function setUploadLimit($num) {
185 $this->uploadLimit = $num;
186 }
187
188 public function getUploadLimit() {
189 return $this->uploadLimit;
190 }
191
192 public function setBrowseButtonText($text) {
193 $this->browseButtonText = $text;
194 }
195
196 public function getBrowseButtonText() {
197 return $this->browseButtonText;
198 }
199
200 public function ButtonAddTitle() {
201 return $this->addTitle ? $this->addTitle : $this->PluralTitle();
202 }
203
204 public function allowUploadFolderSelection() {
205 $this->allowUploadFolderSelection = true;
206 }
207
208 public function enableUploadDebugging() {
209 $this->enableUploadDebugging = true;
210 }
211
212 public function setDefaultView($type) {
213 $this->default_view = $type;
214 }
215
216 public function upload() {
217 if(!$this->can('add')) return;
218 $form = $this->UploadForm();
219 if(is_string($form))
220 return $this->customise(array(
221 'String' => true,
222 'NestedController' => $this->isNested,
223 'DetailForm' => $this->UploadForm(),
224 ))->renderWith($this->templatePopup);
225 else {
226 $form = $this->UploadForm();
227 return $this->customise(array(
228 'String' => is_string($form),
229 'DetailForm' => $form
230 ))->renderWith($this->templatePopup);
231 }
232 }
233
234 public function UploadLink() {
235 $link = Controller::join_links($this->BaseLink(),'/upload');
236 if (Translatable::get_allowed_locales()) {
237 $link .= '?locale=' . Translatable::get_current_locale();
238 }
239 return $link;
240 }
241
242 protected function getUploadFields() {
243 $uploadUrl = Director::absoluteURL('admin/FileDataObjectManager/handleupload');
244 if (isset($_GET['locale']) && (array_search($_GET['locale'], Translatable::get_allowed_locales()) !== false)) {
245 $uploadUrl .= '?locale=' . $_GET['locale'];
246 }
247 $fields = new FieldSet(
248 new HeaderField($title = sprintf(_t('DataObjectManager.ADDITEM', 'Add %s'),$this->PluralTitle()), $headingLevel = 2),
249 new HeaderField($title = _t('DataObjectManager.UPLOADFROMPC', 'Upload from my computer'), $headingLevel = 3),
250 new MultiUploadField(
251 "UploadForm",
252 "Upload",
253 "",
254 array(
255 'file_upload_limit' => $this->getUploadLimit(),
256 'file_queue_limit' => $this->getUploadLimit(),
257 'browse_button_text' => $this->getBrowseButtonText(),
258 'upload_url' => $uploadUrl,
259 'required' => 'true'
260 )
261 )
262 );
263
264 if($this->allowUploadFolderSelection)
265 $fields->insertBefore(new HTMLDropdownField('UploadFolder','',$this->getUploadFolderHierarchy(0),null, null, "-- Select a folder --"),"Upload");
266 return $fields;
267 }
268
269 public function UploadForm() {
270
271
272 $className = $this->sourceClass();
273 $childData = new $className();
274 $validator = $this->getValidatorFor($childData);
275 if($this->Can('upload')) {
276 MultiUploadConfig::addStaticPostParams(array(
277 'dataObjectClassName' => $this->sourceClass(),
278 'dataObjectFieldName' => $this->dataObjectFieldName,
279 'fileFieldName' => $this->fileFieldName,
280 'fileClassName' => $this->fileClassName,
281 'parentIDName' => $this->getParentIdName( $this->getParentClass(), $this->sourceClass() ),
282 'controllerID' => $this->controllerID,
283 'OverrideUploadFolder' => $this->getUploadFolder(),
284 'hasDataObject' => $this->hasDataObject ? 1 : 0
285 ));
286
287 if($this->allowUploadFolderSelection)
288 MultiUploadConfig::addDynamicPostParam('UploadFolder',$this->popupClass.'_UploadForm_UploadFolder');
289
290 if($this->getAllowedFileTypes())
291 MultiUploadConfig::addFileTypes($this->getAllowedFileTypes());
292
293 if($this->uploadMaxSize)
294 MultiUploadConfig::$file_size_limit = $this->uploadMaxSize;
295
296 if($this->enableUploadDebugging)
297 MultiUploadConfig::set_var('debug','true');
298 }
299
300 $fields = $this->Can('upload') ? $this->getUploadFields() : new FieldSet(
301 new HeaderField($title = sprintf(_t('DataObjectManager.ADD', 'Add %s'),$this->PluralTitle()), $headingLevel = 2)
302 );
303
304 $form = Object::create(
305 $this->popupClass,
306 $this,
307 'UploadForm',
308 $fields,
309 $validator,
310 false,
311 $childData
312 );
313 $action = $this->Can('upload') ? new FieldSet(new FormAction('saveUploadForm', 'Upload')) : new FieldSet();
314 $form->setActions($action);
315 if($this->Can('import')) {
316 $header = new HeaderField($title = _t('DataObjectManager.IMPORTFROMFOLDER', 'Import from an existing folder'), $headingLevel = 3);
317 $holder = new LiteralField("holder","<div class='ajax-loader'></div><div id='import-holder'></div>");
318 if(!isset($_POST['uploaded_files']))
319 return $form->forTemplate() . $header->Field() . $this->ImportDropdown()->Field() . $holder->Field();
320 else
321 return $form;
322 }
323 return $form;
324
325 }
326
327 public function saveUploadForm() {
328 if(isset($_POST['uploaded_files']) && is_array($_POST['uploaded_files'])) {
329 $form = $this->EditUploadedForm();
330 return $this->customise(array(
331 'String' => is_string($form),
332 'DetailForm' => $form
333 ))->renderWith($this->templatePopup);
334 }
335 }
336
337 protected function getChildDataObj() {
338 $class = $this->sourceClass();
339 return new $class();
340 }
341
342 public function setPreviewFieldFor($fields) {
343 $this->customPreviewField = $fields;
344 }
345
346 public function getPreviewFieldFor($fileObject, $size = 150) {
347 if ($this->customPreviewField) {
348 return $this->customPreviewField;
349 }
350
351 if($fileObject instanceof Image) {
352 $URL = $fileObject->getHeight() > $size ? $fileObject->SetHeight($size)->URL : $fileObject->URL
353 ;
354 return new LiteralField("icon",
355 "<div class='current-image'><img src='$URL' alt='' /><h3>$fileObject->Filename</h3></div>"
356 );
357 }
358 else {
359 $URL = $fileObject->Icon();
360 return new LiteralField("icon",
361 "<h3><img src='$URL' alt='' /><span>$fileObject->Filename</span></h3>"
362 );
363 }
364 }
365
366 protected function () {
367 Requirements::clear();
368 if($this->isNested)
369 Requirements::customScript("parent.jQuery('#iframe_".$this->id()." a').click();");
370 else {
371 Requirements::customScript("
372 var container = parent.jQuery('#".$this->id()."');
373 parent.jQuery('#facebox').fadeOut(function() {
374 parent.jQuery('#facebox .content').removeClass().addClass('content');
375 parent.jQuery('#facebox_overlay').remove();
376 parent.jQuery('#facebox .loading').remove();
377 parent.refresh(container, container.attr('href'));
378 });");
379 }
380 return $this->customise(array(
381 'String' => true,
382 'DetailForm' => 'Closing...'
383 ))->renderWith($this->templatePopup);
384 }
385
386 public function EditUploadedForm() {
387 if(!$this->hasDataObject)
388 return $this->closePopup();
389
390 $childData = $this->getChildDataObj();
391 $validator = $this->getValidatorFor($childData);
392 $fields = $this->getFieldsFor($childData);
393 $fields->removeByName($this->fileFieldName);
394 $total = 0;
395 if(isset($_POST['totalsize'])){
396 $total = $_POST['totalsize'];
397 }else{
398 if(isset($_POST['uploaded_files'])){
399 $total = sizeof($_POST['uploaded_files']);
400 }
401 }
402 $index = isset($_POST['index']) ? $_POST['index'] + 1 : 1;
403 $fields->push(new HiddenField('totalsize','',$total));
404 $fields->push(new HiddenField('index','',$index));
405 if(isset($_POST['uploaded_files']) && is_array($_POST['uploaded_files'])) {
406 $remaining_files = $_POST['uploaded_files'];
407 $current = $remaining_files[0];
408 $dataObject = DataObject::get_by_id($this->sourceClass(), $current);
409 $fileObject = $dataObject->obj($this->fileFieldName);
410 $fields->push(new HiddenField('current','',$current));
411 unset($remaining_files[0]);
412 if(!$fields->loaded) {
413 foreach($remaining_files as $id)
414 $fields->push(new LiteralField("u-$id","<input type='hidden' name='uploaded_files[]' value='$id' />"));
415 $first = $fields->First()->Name();
416 $fields->insertBefore(new HeaderField("Header",_t('DataObjectManager.EDITINGFILE','Editing file')." $index "._t('DataObjectManager.OF','of')." $total",2), $first);
417 $fields->insertBefore($this->getPreviewFieldFor($fileObject), $first);
418 }
419 }
420
421 $form = Object::create(
422 $this->popupClass,
423 $this,
424 'EditUploadedForm',
425 $fields,
426 $validator,
427 false,
428 $childData
429 );
430 $form->setActions(new FieldSet(new FormAction("saveEditUploadedForm", $index == $total ? _t('DataObjectManager.BUTTONFINISH', 'Finish') : _t('DataObjectManager.BUTTONNEXT', 'Next'))));
431 if(isset($dataObject) && $dataObject)
432 $form->loadDataFrom($dataObject);
433 $fields->loaded = true;
434 return $form;
435 }
436
437 function saveEditUploadedForm($data, $form) {
438 $obj = DataObject::get_by_id($this->sourceClass(), $data['current']);
439 $form->saveInto($obj);
440 $obj->write();
441 if(isset($data['uploaded_files']) && is_array($data['uploaded_files'])) {
442 $form = $this->EditUploadedForm();
443 return $this->customise(array(
444 'String' => is_string($form),
445 'DetailForm' => $form
446 ))->renderWith($this->templatePopup);
447 }
448 else {
449 return $this->closePopup();
450 }
451 }
452
453 public function handleImport($request) {
454 $this->importFolderID = $request->param('ID');
455 die($this->ImportForm($this->importFolderID)->forTemplate());
456 }
457
458 protected function getImportFields() {
459 return new FieldSet(
460 new HiddenField('dataObjectClassName','',$this->sourceClass()),
461 new HiddenField('fileFieldName','', $this->fileFieldName),
462 new HiddenField('parentIDName','', $this->getParentIdName( $this->getParentClass(), $this->sourceClass() )),
463 new HiddenField('controllerID','',$this->controllerID)
464 );
465 }
466
467 protected function ImportForm($folder_id = null) {
468 $folder_id = isset($_POST['folder_id']) ? $_POST['folder_id'] : $this->importFolderID;
469 ;
470 if($files = DataObject::get($this->importClass, "ClassName != 'Folder' AND ParentID = $folder_id"))
471 $fields = $this->getImportFields();
472 $fields->push(new HiddenField('folder_id','',$folder_id));
473 $fields->push(new LiteralField('select','<div class="select"><span>Select</span>: <a href="javascript:void(0)" rel="all">all</a> | <a href="javascript:void(0)" rel="none">none</a></div>'));
474 $fields->push(new LiteralField("ul","<ul>"));
475 foreach($files as $file) {
476 if($file instanceof Image) {
477 if($img = $file->CroppedImage(35,35))
478 $icon = $img->URL;
479 else
480 $icon = "";
481 }
482 elseif($file instanceof File)
483 $icon = $file->Icon();
484 else
485 $icon = "";
486
487 $title = strlen($file->Title) > 30 ? substr($file->Title, 0, 30)."..." : $file->Title;
488 $types = $this->getAllowedFileTypes();
489 if(is_array($types) && !empty($types))
490 $allowed = in_array($file->Extension, $types);
491 else
492 $allowed = true;
493
494 $class = !$allowed ? "class='disabled'" : "";
495 $disabled = !$allowed ? "disabled='disabled'" : "";
496
497 $fields->push(new LiteralField("li-$file->ID",
498 "<li $class>
499 <span class='import-checkbox'><input $disabled type='checkbox' name='imported_files[]' value='$file->ID' /></span>
500 <span class='import-icon'><img src='$icon' alt='' /></span>
501 <span class='import-title'>".$title."</span>
502 </li>"
503 ));
504 }
505 $fields->push(new LiteralField("_ul","</ul>"));
506 return new Form(
507 $this,
508 "ImportForm",
509 $fields,
510 new FieldSet(new FormAction('saveImportForm','Import'))
511 );
512 }
513
514 public function saveImportForm($data, $form) {
515 if(isset($data['imported_files']) && is_array($data['imported_files'])) {
516 $_POST['uploaded_files'] = array();
517
518 foreach($data['imported_files'] as $file_id) {
519 $file = DataObject::get_by_id("File",$file_id);
520
521
522
523 if($this->fileClassName != "File" && $file->ClassName != $this->fileClassName) {
524 $file = $file->newClassInstance($this->fileClassName);
525 $file->write();
526 }
527 $owner_id = $data['parentIDName'];
528 if($this->hasDataObject) {
529 $do_class = $data['dataObjectClassName'];
530 $idxfield = $data['fileFieldName']."ID";
531 $obj = new $do_class();
532 $obj->$idxfield = $file_id;
533 $obj->$owner_id = $data['controllerID'];
534 $obj->write();
535 $_POST['uploaded_files'][] = $obj->ID;
536 }
537 else {
538 if($file = DataObject::get_by_id($this->fileClassName, $file_id)) {
539 $id_field = $this->controllerFieldName."ID";
540
541 if($file->hasField($owner_id)) {
542 $file->$owner_id = $this->controllerID;
543 $file->write();
544 }
545 }
546 }
547 }
548 $form = $this->EditUploadedForm();
549 return $this->customise(array(
550 'String' => is_string($form),
551 'DetailForm' => $form
552 ))->renderWith($this->templatePopup);
553
554 }
555 }
556 public function setUploadFolder($override) {
557 $this->uploadFolder = $override;
558 }
559 public function getUploadFolder() {
560 return $this->uploadFolder;
561 }
562
563 public function getCleanUploadFolder() {
564 $path = str_replace(ASSETS_DIR."/","",$this->getUploadFolder());
565 if(substr($path,-1)=="/") $path = substr($path,0, -1);
566 return $path;
567 }
568
569 function handleItem($request) {
570 return new FileDataObjectManager_ItemRequest($this, $request->param('ID'));
571 }
572 }
573
574 class FileDataObjectManager_Controller extends Controller {
575 public function handleupload() {
576 $rs = false;
577 $message = '';
578 if(isset($_FILES['upload_file']) && !empty($_FILES['upload_file'])) {
579 $do_class = $_POST['dataObjectClassName'];
580 $hasDataObject = $_POST['hasDataObject'];
581 $idxfield = $_POST['fileFieldName']."ID";
582 $file_class = $_POST['fileClassName'];
583 $file = new $file_class();
584
585 if(isset($_POST['UploadFolder'])) {
586 $folder = DataObject::get_by_id("Folder",$_POST['UploadFolder']);
587 $path = str_replace(ASSETS_DIR."/","",$folder->Filename);
588 if(substr($path,-1)=="/") $path = substr($path,0, -1);
589 }
590 else {
591 $path = str_replace(ASSETS_DIR."/","",$_POST['OverrideUploadFolder']);
592 if(substr($path,-1)=="/") $path = substr($path,0, -1);
593 }
594
595 try {
596 if(!class_exists("Upload")) {
597 throw new ValidationException(_t("FileDataObjectManager.NoUploadClass", "No Upload class!"), E_USER_WARNING);
598 }
599 $u = new Upload();
600 $u->validator->setAllowedExtensions(File::$allowed_extensions);
601 $oldMaxSizes = false;
602 if ($hasDataObject && class_exists('ImageAutoResize') && ($obj = new $do_class()) && method_exists($obj, 'AutoresizeMaxWidth')) {
603 $oldMaxSizes = ImageAutoResize::get_max_size();
604 $maxWidth = ($obj->AutoresizeMaxWidth() > 0) ? $obj->AutoresizeMaxWidth() : $oldMaxSizes['Width'];
605 $maxHeight = ($obj->AutoresizeMaxHeight() > 0) ? $obj->AutoresizeMaxHeight() : $oldMaxSizes['Height'];
606 ImageAutoResize::set_max_size($maxWidth, $maxHeight);
607 }
608 if (!$u->loadIntoFile($_FILES['upload_file'], $file, $path)) {
609 if ($u->isError()) {
610 $errors = implode("; ", $u->getErrors());
611 } else {
612 $errors = _t("FileDataObjectManager.UploadError", "Upload Error");
613 }
614 throw new ValidationException($errors, E_USER_WARNING);
615 }
616 if(isset($_POST['UploadFolder']))
617 $file->setField("ParentID",$folder->ID);
618
619
620 if($file->class == "File") {
621 $ext = strtolower($file->Extension);
622 if(in_array($ext, MP3::$allowed_file_types) && FileDataObjectManager::$upgrade_audio)
623 $file = $file->newClassInstance("MP3");
624 else if(in_array($ext, array('jpg','jpeg','gif','png')) && FileDataObjectManager::$upgrade_image)
625 $file = $file->newClassInstance("Image");
626 else if(in_array($ext, FLV::$allowed_file_types) && FileDataObjectManager::$upgrade_video)
627 $file = $file->newClassInstance("FLV");
628 }
629
630 $file->OwnerID = Member::currentUserID();
631 if($hasDataObject) {
632 $obj = new $do_class();
633 $file->write();
634 $obj->$idxfield = $file->ID;
635 $ownerID = $_POST['parentIDName'];
636 $obj->$ownerID = $_POST['controllerID'];
637 if (isset($_GET['locale']) && (array_search($_GET['locale'], Translatable::get_allowed_locales()) !== false)) {
638 $obj->Locale = $_GET['locale'];
639 }
640 $obj->write();
641 $rs = true;
642 $message = $obj->ID;
643 }
644 else {
645 $ownerID = $_POST['parentIDName'];
646 $file->$ownerID = $_POST['controllerID'];
647 $file->write();
648 $rs = true;
649 $message = $file->ID;
650 }
651 if ($oldMaxSizes) {
652 ImageAutoResize::set_max_size($oldMaxSizes['Width'], $oldMaxSizes['Height']);
653 }
654 } catch (Exception $e) {
655 $rs = false;
656 if (method_exists($e,'getResult') && $e->getResult()) {
657 $message = $e->getResult()->message();
658 } else {
659 $message = $e->getMessage();
660 }
661 }
662 }
663 echo json_encode(array('rs' => $rs, 'message' => $message));
664
665
666 }
667 }
668
669 class FileDataObjectManager_Item extends DataObjectManager_Item {
670 function __construct(DataObject $item, ComplexTableField $parent) {
671 parent::__construct($item, $parent);
672 }
673
674 public function IsFile() {
675 return $this instanceof File;
676 }
677
678 public function FileIcon() {
679 if($this->parent->hasDataObject) {
680 $field = $this->parent->fileFieldName."ID";
681 $file = DataObject::get_by_id($this->parent->fileClassName, $this->item->$field);
682 }
683 else
684 $file = $this->item;
685
686 if($file && $file->ID) {
687 if($file instanceof Image)
688 $img = $file;
689 else {
690 $ext = $file->Extension;
691 $imgExts = array('jpg','jpeg','gif');
692 if(in_array($ext, $imgExts)) {
693 $img = new Image_Cached($file->Filename);
694 $img->ID = $file->ID;
695 }
696 }
697 return (isset($img) && (is_subclass_of($img,'Image_Cached') || $file instanceof Image)) ? $img->CroppedImage(50,50)->URL : $file->Icon();
698
699 }
700 else return "{$this->item->$field}";
701 }
702
703 public function FileLabel() {
704 $idField = $this->parent->fileFieldName."ID";
705 if($this->parent->gridLabelField) {
706 $field = $this->parent->gridLabelField;
707 return $this->$field;
708 }
709 else if(!$this->hasDataObject)
710 $label = $this->item->Title;
711 else if($file = DataObject::get_by_id($this->parent->fileClassName, $this->item->$idField))
712 $label = $file->Title;
713 else
714 $label = "";
715 return strlen($label) > 30 ? substr($label, 0, 30)."..." : $label;
716 }
717
718 }
719
720
721 class extends DataObjectManager_Popup {
722 function __construct($controller, $name, $fields, $validator, $readonly, $dataObject) {
723 parent::__construct($controller, $name, $fields, $validator, $readonly, $dataObject);
724
725
726
727
728
729 Requirements::javascript('dataobject_manager/javascript/filedataobjectmanager_popup.js');
730 }
731 }
732
733 class FileDataObjectManager_ItemRequest extends DataObjectManager_ItemRequest {
734 function __construct($ctf, $itemID) {
735 parent::__construct($ctf, $itemID);
736 }
737
738 function DetailForm($childID = null) {
739 $form = parent::DetailForm($childID);
740 if($this->dataObj()->hasExtension('Translatable')) {
741 $excludeFields = array(
742 'SortOrder',
743 );
744 $fields = $form->Fields();
745
746 $originalRecord = $this->dataObj()->getTranslation(Translatable::default_locale());
747
748
749 $translations = $this->dataObj()->getTranslations();
750 if(!$originalRecord) {
751 $originalRecord = ($translations) ? $translations->First() : null;
752 }
753 $isTranslationMode = $this->dataObj()->Locale != Translatable::default_locale();
754
755
756
757
758 $alreadyTranslatedLocales = $this->dataObj()->getTranslatedLocales();
759 $alreadyTranslatedLocales[$this->dataObj()->ID] = $this->dataObj()->Locale;
760
761 if($originalRecord && $isTranslationMode) {
762 $originalLangID = Session::get($this->dataObj()->ID . '_originalLangID');
763
764 $translatableFieldNames = $this->dataObj()->getTranslatableFields();
765 $allDataFields = $fields->dataFields();
766
767 $transformation = new Translatable_Transformation($originalRecord);
768
769
770
771 foreach($allDataFields as $dataField) {
772 if($dataField instanceof HiddenField) continue;
773 if(in_array($dataField->Name(), $excludeFields)) continue;
774 if(array_key_exists($dataField->Name(), $this->dataObj()->has_one())) continue;
775
776 if(in_array($dataField->Name(), $translatableFieldNames)) {
777
778 $fields->replaceField($dataField->Name(), $transformation->transformFormField($dataField));
779 } else {
780
781 $fields->replaceField($dataField->Name(), $dataField->performReadonlyTransformation());
782 }
783 }
784 }
785
786
787 $dropdown = new LanguageDropdownField(
788 'NewTransLang',
789 _t('DataObjectManager.LANGDROPDOWNLABEL', 'Language'),
790 $alreadyTranslatedLocales,
791 $this->dataObj()->class,
792 'Locale-English'
793 );
794
795 $action = new InlineFormAction(
796 'createtranslation',
797 _t('DataObjectManager.CREATETRANSBUTTON',
798 "Create translation")
799 );
800
801 if($alreadyTranslatedLocales) {
802 $header = new HeaderField(
803 'ExistingTransHeader',
804 _t('DataObjectManager.EXISTINGTRANSTABLE', 'Existing Translations'),
805 4
806 );
807 $relationName = $this->ctf->Name();
808 $existingTransHTML = '<ul>';
809 foreach($translations as $translation) {
810 $mainLangStyle = '';
811 if ($translation->Locale == Translatable::default_locale()) {
812 $mainLangStyle = ' style="font-weight: bold;"';
813 }
814 $existingTransHTML .= sprintf('<li'.$mainLangStyle.'><a href="%s">%s</a></li>',
815 sprintf('admin/EditForm/field/%s/item/%d/edit', $relationName, $translation->ID),
816 i18n::get_locale_name($translation->Locale)
817 );
818
819 }
820 $existingTransHTML .= '</ul>';
821 $table = new LiteralField('existingtrans',$existingTransHTML);
822 }
823
824 $action->includeDefaultJS = false;
825 if($fields->hasTabSet()) {
826 $fields->findOrMakeTab(
827 'Root.Translations',
828 _t("DataObjectManager.TRANSLATIONSTAB", "Translations")
829 );
830 $fields->addFieldToTab('Root.Translations', $header);
831 $fields->addFieldToTab('Root.Translations', $table);
832 $fields->addFieldToTab('Root.Translations', $dropdown);
833 $fields->addFieldToTab('Root.Translations', $action);
834 } else {
835 $fields->insertAfter($action, 'Image');
836 $fields->insertAfter($dropdown, 'Image');
837 $fields->insertAfter($table, 'Image');
838 $fields->insertAfter($header, 'Image');
839 }
840
841 $form->Fields()->setForm($form);
842 }
843
844 return $form;
845 }
846
847 function createtranslation($data, $form, $edit) {
848 $langCode = Convert::raw2sql($data['NewTransLang']);
849 if (isset($data['ctf']) && is_array($data['ctf'])) {
850 if ($parentObject = DataObject::get_by_id($data['ctf']['parentClass'], (int)$data['ctf']['sourceID'])) {
851 $parentField = array_search($data['ctf']['parentClass'], $this->dataObj()->has_one());
852 if ($localParentObject = $parentObject->getTranslation($langCode)) {
853 Translatable::set_current_locale($langCode);
854 $translatedRecord = $this->dataObj()->createTranslation($langCode);
855 $translatedRecord->{"{$parentField}ID"} = $localParentObject->ID;
856 $translatedRecord->write();
857
858 $newRequest = new FileDataObjectManager_ItemRequest($this->ctf, $translatedRecord->ID);
859
860 return Director::redirect(Controller::join_links($newRequest->ctf->BaseLink(),'/item/'.$translatedRecord->ID.'/edit'));
861
862
863 return $newRequest->edit(null);
864 }
865 }
866 }
867 }
868 }
869
870 ?>
871
[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.
-