]> err.no Git - sope/blob - sope-appserver/NGObjWeb/DynamicElements/WOFileUpload.m
renamed packages as discussed in the developer list
[sope] / sope-appserver / NGObjWeb / DynamicElements / WOFileUpload.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include "WOInput.h"
24 #include "common.h"
25 #import <NGMime/NGMime.h>
26 #import <NGHttp/NGHttp.h>
27
28 @interface WOFileUpload : WOInput
29 {
30   // WODynamicElement: extraAttributes
31   // WODynamicElement: otherTagString
32   // inherited: name
33   // inherited: value
34   // inherited: disabled
35 @protected
36   WOAssociation *filePath; // dispostion 'filename'
37   WOAssociation *data;     // uploaded data
38 }
39
40 @end /* WOFileUpload */
41
42 @interface WORequest(UsedPrivates)
43 - (id)httpRequest;
44 @end
45
46 @implementation WOFileUpload
47
48 static NGMimeType *multipartFormData = nil;
49
50 + (void)initialize {
51   static BOOL isInitialized = NO;
52   if (!isInitialized) {
53     isInitialized = YES;
54
55     multipartFormData = [NGMimeType mimeType:@"multipart/form-data"];
56     multipartFormData = RETAIN(multipartFormData);
57   }
58 }
59
60 - (id)initWithName:(NSString *)_name
61   associations:(NSDictionary *)_config
62   template:(WOElement *)_root {
63
64   if ((self = [super initWithName:_name associations:_config template:_root])) {
65     self->filePath = OWGetProperty(_config, @"filePath");
66     self->data     = OWGetProperty(_config, @"data");
67   }
68   return self;
69 }
70
71 #if !LIB_FOUNDATION_BOEHM_GC
72 - (void)dealloc {
73   RELEASE(self->filePath); self->filePath = nil;
74   RELEASE(self->data);     self->data     = nil;
75   [super dealloc];
76 }
77 #endif
78
79 // ******************** responder ********************
80
81 - (void)takeValuesFromRequest:(WORequest *)_request
82   inContext:(WOContext *)_ctx
83 {
84   if (![self->disabled boolValueInComponent:[_ctx component]]) {
85     NSString *currentId;
86     id       formValue  = nil;
87
88     currentId = OWFormElementName(self, _ctx);
89
90     formValue = [_request formValueForKey:currentId];
91     if (formValue) {
92       NGMimeType *contentType = [[_request httpRequest] contentType];
93       
94       if (![contentType hasSameType:multipartFormData]) {
95         NSLog(@"WARNING: tried to apply file-upload value of %@ from "
96               @"a non multipart-form request (value=%@) !",
97               [_ctx elementID], formValue);
98         return;
99       }
100   
101       //NSLog(@"%@: value=%@ ..", [self elementID], formValue);
102
103       if ([self->data isValueSettable])
104         [self->data setValue:formValue inComponent:[_ctx component]];
105
106       if ([self->filePath isValueSettable]) {
107         NGMimeMultipartBody *body = [[_request httpRequest] body];
108
109         if ([body isKindOfClass:[NGMimeMultipartBody class]]) {
110           NSArray  *parts   = [body parts];
111           unsigned i, count = [parts count];
112
113           // search for part of current form element
114           
115           for (i = 0; i < count; i++) {
116             id disposition;
117             id<NGMimePart> bodyPart;
118             
119             bodyPart = [parts objectAtIndex:i];
120             disposition =
121               [[bodyPart valuesOfHeaderFieldWithName:@"content-disposition"]
122                          nextObject];
123             
124             if (disposition) {
125               static Class DispClass = Nil;
126               NSString *formName;
127               
128               if (DispClass == Nil)
129                 DispClass = [NGMimeContentDispositionHeaderField class];
130               
131               if (![disposition isKindOfClass:DispClass]) {
132                 disposition =
133                   [[DispClass alloc] initWithString:[disposition stringValue]];
134                 AUTORELEASE(disposition);
135               }
136               
137               formName =
138                 [(NGMimeContentDispositionHeaderField *)disposition name];
139               
140               if ([formName isEqualToString:currentId]) {
141                 [self->filePath
142                      setValue:[disposition filename]
143                      inComponent:[_ctx component]];
144                 break;
145               }
146             }
147           }
148         }
149       }
150     }
151   }
152 }
153
154 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
155   if (![[_ctx request] isFromClientComponent]) {
156     NSString *v = [self->value stringValueInComponent:[_ctx component]];
157       
158     WOResponse_AddCString(_response, "<input type=\"file\" name=\"");
159     [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
160     WOResponse_AddChar(_response, '"');
161     if (v) {
162       WOResponse_AddCString(_response, " value=\"");
163       [_response appendContentHTMLAttributeValue:v];
164       WOResponse_AddChar(_response, '"');
165     }
166     [self appendExtraAttributesToResponse:_response inContext:_ctx];
167   
168     if (self->otherTagString) {
169       WOResponse_AddString(_response,
170                            [self->otherTagString stringValueInComponent:
171                                 [_ctx component]]);
172     }
173     WOResponse_AddCString(_response, " />");
174   }
175 }
176
177 /* description */
178
179 - (NSString *)associationDescription {
180   NSMutableString *str = [[NSMutableString alloc] init];
181   [str appendString:[super associationDescription]];
182
183   if (self->filePath) [str appendFormat:@" path=%@", self->filePath];
184   if (self->data)     [str appendFormat:@" data=%@", self->data];
185
186   return AUTORELEASE(str);
187 }
188
189 @end /* WOFileUpload */