Changeset 4314 in subversion
- Timestamp:
- Dec 7, 2010 5:07:39 PM (2 years ago)
- Location:
- branches/devel-addressbook
- Files:
-
- 20 edited
-
config/main.inc.php.dist (modified) (1 diff)
-
index.php (modified) (1 diff)
-
program/include/rcmail.php (modified) (1 diff)
-
program/include/rcube_contacts.php (modified) (1 diff)
-
program/include/rcube_vcard.php (modified) (5 diffs)
-
program/js/app.js (modified) (8 diffs)
-
program/localization/en_US/labels.inc (modified) (1 diff)
-
program/localization/en_US/messages.inc (modified) (1 diff)
-
program/steps/addressbook/edit.inc (modified) (2 diffs)
-
program/steps/addressbook/func.inc (modified) (6 diffs)
-
program/steps/addressbook/save.inc (modified) (2 diffs)
-
program/steps/addressbook/show.inc (modified) (2 diffs)
-
program/steps/mail/compose.inc (modified) (1 diff)
-
skins/default/addressbook.css (modified) (2 diffs)
-
skins/default/common.css (modified) (1 diff)
-
skins/default/functions.js (modified) (3 diffs)
-
skins/default/mail.css (modified) (1 diff)
-
skins/default/templates/contact.html (modified) (1 diff)
-
skins/default/templates/contactadd.html (modified) (2 diffs)
-
skins/default/templates/contactedit.html (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/devel-addressbook/config/main.inc.php.dist
r4239 r4314 286 286 // mime magic database 287 287 $rcmail_config['mime_magic'] = '/usr/share/misc/magic'; 288 289 // path to imagemagick identify binary 290 $rcmail_config['im_identify_path'] = null; 291 292 // path to imagemagick convert binary 293 $rcmail_config['im_convert_path'] = null; 294 295 // maximum size of uploaded contact photos 296 $rcmail_config['contact_photo_size'] = 160; 288 297 289 298 // Enable DNS checking for e-mail address validation -
branches/devel-addressbook/index.php
r4297 r4314 214 214 'add' => 'edit.inc', 215 215 'photo' => 'show.inc', 216 'upload-photo' => 'save.inc', 216 217 'group-create' => 'groups.inc', 217 218 'group-rename' => 'groups.inc', -
branches/devel-addressbook/program/include/rcmail.php
r4283 r4314 1294 1294 1295 1295 /** 1296 * Use imagemagick or GD lib to read image properties 1297 * 1298 * @param string Absolute file path 1299 * @return mixed Hash array with image props like type, width, height or False on error 1300 */ 1301 public static function imageprops($filepath) 1302 { 1303 $rcmail = rcmail::get_instance(); 1304 if ($cmd = $rcmail->config->get('im_identify_path', false)) { 1305 list(, $type, $size) = explode(' ', strtolower(rcmail::exec($cmd. ' 2>/dev/null {in}', array('in' => $filepath)))); 1306 if ($size) 1307 list($width, $height) = explode('x', $size); 1308 } 1309 else if (function_exists('getimagesize')) { 1310 $imsize = @getimagesize($filepath); 1311 $width = $imsize[0]; 1312 $height = $imsize[1]; 1313 $type = preg_replace('!image/!', '', $imsize['mime']); 1314 } 1315 1316 return $type ? array('type' => $type, 'width' => $width, 'height' => $height) : false; 1317 } 1318 1319 1320 /** 1321 * Convert an image to a given size and type using imagemagick (ensures input is an image) 1322 * 1323 * @param $p['in'] Input filename (mandatory) 1324 * @param $p['out'] Output filename (mandatory) 1325 * @param $p['size'] Width x height of resulting image, e.g. "160x60" 1326 * @param $p['type'] Output file type, e.g. "jpg" 1327 * @param $p['-opts'] Custom command line options to ImageMagick convert 1328 * @return Success of convert as true/false 1329 */ 1330 public static function imageconvert($p) 1331 { 1332 $result = false; 1333 $rcmail = rcmail::get_instance(); 1334 $convert = $rcmail->config->get('im_convert_path', false); 1335 $identify = $rcmail->config->get('im_identify_path', false); 1336 1337 // imagemagick is required for this 1338 if (!$convert) 1339 return false; 1340 1341 if (!(($imagetype = @exif_imagetype($p['in'])) && ($type = image_type_to_extension($imagetype, false)))) 1342 list(, $type) = explode(' ', strtolower(rcmail::exec($identify . ' 2>/dev/null {in}', $p))); # for things like eps 1343 1344 $type = strtr($type, array("jpeg" => "jpg", "tiff" => "tif", "ps" => "eps", "ept" => "eps")); 1345 $p += array('type' => $type, 'types' => "bmp,eps,gif,jp2,jpg,png,svg,tif", 'quality' => 75); 1346 $p['-opts'] = array('-resize' => $p['size'].'>') + (array)$p['-opts']; 1347 1348 if (in_array($type, explode(',', $p['types']))) # Valid type? 1349 $result = rcmail::exec($convert . ' 2>&1 -flatten -auto-orient -colorspace RGB -quality {quality} {-opts} {in} {type}:{out}', $p) === ""; 1350 1351 return $result; 1352 } 1353 1354 1355 /** 1356 * Construct shell command, execute it and return output as string. 1357 * Keywords {keyword} are replaced with arguments 1358 * 1359 * @param $cmd Format string with {keywords} to be replaced 1360 * @param $values (zero, one or more arrays can be passed) 1361 * @return output of command. shell errors not detectable, see error_log in /www/server/logs 1362 */ 1363 public static function exec(/* $cmd, $values1 = array(), ... */) 1364 { 1365 $args = func_get_args(); 1366 $cmd = array_shift($args); 1367 $values = $replacements = array(); 1368 1369 // merge values into one array 1370 foreach ($args as $arg) 1371 $values += (array)$arg; 1372 1373 preg_match_all('/({(-?)([a-z]\w*)})/', $cmd, $matches, PREG_SET_ORDER); 1374 foreach ($matches as $tags) { 1375 list(, $tag, $option, $key) = $tags; 1376 $parts = array(); 1377 1378 if ($option) { 1379 foreach ((array)$values["-$key"] as $key => $value) { 1380 if ($value === true || $value === false || $value === null) 1381 $parts[] = $value ? $key : ""; 1382 else foreach ((array)$value as $val) 1383 $parts[] = "$key " . escapeshellarg($val); 1384 } 1385 } 1386 else { 1387 foreach ((array)$values[$key] as $value) 1388 $parts[] = escapeshellarg($value); 1389 } 1390 1391 $replacements[$tag] = join(" ", $parts); 1392 } 1393 1394 // use strtr behaviour of going through source string once 1395 $cmd = strtr($cmd, $replacements); 1396 1397 return (string)shell_exec($cmd); 1398 } 1399 1400 1401 /** 1296 1402 * Helper method to set a cookie with the current path and host settings 1297 1403 * -
branches/devel-addressbook/program/include/rcube_contacts.php
r4297 r4314 502 502 list($field, $section) = explode(':', $key); 503 503 foreach ((array)$values as $value) { 504 if (is _array($value) || strlen($value))504 if (isset($value)) 505 505 $vcard->set($field, $value, $section); 506 506 } -
branches/devel-addressbook/program/include/rcube_vcard.php
r4298 r4314 33 33 'N' => array(array('','','','','')), 34 34 ); 35 private $fieldmap = array('pho to' => 'PHOTO', 'phone' => 'TEL', 'birthday' => 'BDAY', 'website' => 'URL', 'notes' => 'NOTE', 'email' => 'EMAIL', 'address' => 'ADR', 'gender' => 'X-GENDER', 'maidenname' => 'X-MAIDENNAME', 'gender' => 'X-GENDER');35 private $fieldmap = array('phone' => 'TEL', 'birthday' => 'BDAY', 'website' => 'URL', 'notes' => 'NOTE', 'email' => 'EMAIL', 'address' => 'ADR', 'gender' => 'X-GENDER', 'maidenname' => 'X-MAIDENNAME', 'gender' => 'X-GENDER'); 36 36 private $typemap = array('iPhone' => 'mobile', 'CELL' => 'mobile'); 37 37 private $phonetypemap = array('HOME1' => 'HOME', 'BUSINESS1' => 'WORK', 'BUSINESS2' => 'WORK2', 'WORKFAX' => 'BUSINESSFAX'); … … 68 68 { 69 69 $this->raw = self::vcard_decode($vcard); 70 70 71 71 // resolve charset parameters 72 72 if ($charset == null) … … 152 152 } 153 153 154 // copy photo data 155 if ($this->raw['PHOTO']) 156 $out['photo'] = $this->raw['PHOTO'][0][0]; 157 154 158 return $out; 155 159 } … … 235 239 236 240 case 'photo': 237 $encoded = base64_decode($value, true) ? true : false;238 $this->raw['PHOTO'][ ] = array(0 => $encoded ? $value : base64_encode($value), array('BASE64'));241 $encoded = !preg_match('![^a-z0-9/=+-]!i', $value); 242 $this->raw['PHOTO'][0] = array(0 => $encoded ? $value : base64_encode($value), 'BASE64' => true); 239 243 break; 240 244 … … 270 274 $type = $this->phonetypemap[$type]; 271 275 272 if ( $tag = $this->fieldmap[$field]) {276 if (($tag = $this->fieldmap[$field]) && (is_array($value) || strlen($value))) { 273 277 $index = count($this->raw[$tag]); 274 278 $this->raw[$tag][$index] = (array)$value; -
branches/devel-addressbook/program/js/app.js
r4297 r4314 320 320 if ((this.env.action=='add' || this.env.action=='edit') && this.gui_objects.editform) { 321 321 this.enable_command('save', true); 322 this.enable_command('upload-photo', this.env.coltypes.photo ? true : false); 323 this.enable_command('delete-photo', this.env.coltypes.photo && this.env.action == 'edit'); 322 324 $("input[type='text']").first().select(); 323 325 324 326 for (var col in this.env.coltypes) 325 327 this.init_edit_field(col, null); 326 327 $('#contactpicframe').click(function(){ ref.upload_contact_photo(this); return false; });328 328 329 329 $('.contactfieldgroup .row a.deletebutton').click(function(){ ref.delete_edit_field(this); return false }); … … 447 447 if (!this.commands[command]) { 448 448 // pass command to parent window 449 if (this.env.framed && parent.rcmail && parent.rcmail .command)449 if (this.env.framed && parent.rcmail && parent.rcmail != this && parent.rcmail.command) 450 450 parent.rcmail.command(command, props); 451 451 … … 1011 1011 } 1012 1012 break; 1013 1014 case 'upload-photo': 1015 this.upload_contact_photo(props); 1016 break; 1017 1018 case 'delete-photo': 1019 this.replace_contact_photo('-del-'); 1020 break; 1013 1021 1014 1022 // user settings commands … … 3182 3190 // create hidden iframe and post upload form 3183 3191 if (send) { 3184 var ts = new Date().getTime(); 3185 var frame_name = 'rcmupload'+ts; 3186 3187 // have to do it this way for IE 3188 // otherwise the form will be posted to a new window 3189 if (document.all) { 3190 var html = '<iframe name="'+frame_name+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>'; 3191 document.body.insertAdjacentHTML('BeforeEnd',html); 3192 } 3193 else { // for standards-compilant browsers 3194 var frame = document.createElement('iframe'); 3195 frame.name = frame_name; 3196 frame.style.border = 'none'; 3197 frame.style.width = 0; 3198 frame.style.height = 0; 3199 frame.style.visibility = 'hidden'; 3200 document.body.appendChild(frame); 3201 } 3202 3203 // handle upload errors, parsing iframe content in onload 3204 $(frame_name).bind('load', {ts:ts}, function(e) { 3192 this.async_upload_form(form, 'upload', function(e) { 3205 3193 var d, content = ''; 3206 3194 try { … … 3222 3210 rcmail.env.uploadframe = e.data.ts; 3223 3211 }); 3224 3225 form.target = frame_name;3226 form.action = this.env.comm_path+'&_action=upload&_uploadid='+ts;3227 form.setAttribute('enctype', 'multipart/form-data');3228 form.submit();3229 3212 3230 3213 // display upload indicator and cancel button … … 4084 4067 var col = $(elem).attr('rel'), 4085 4068 colprop = this.env.coltypes[col], 4086 addmenu = $(elem).parents('div.contactfieldgroup').parent().find('select.addfieldmenu'); 4069 fieldset = $(elem).parents('fieldset.contactfieldgroup'), 4070 addmenu = fieldset.parent().find('select.addfieldmenu'); 4087 4071 4088 4072 // just clear input but don't hide the last field 4089 4073 if (--colprop.count <= 0 && colprop.visible) 4090 4074 $(elem).parent().children('input').val('').blur(); 4091 else 4075 else { 4092 4076 $(elem).parents('div.row').remove(); 4077 // hide entire fieldset if no more rows 4078 if (!fieldset.children('div.row').length) 4079 fieldset.hide(); 4080 } 4093 4081 4094 // TODO:enable option in add-field selector or insert it if necessary4082 // enable option in add-field selector or insert it if necessary 4095 4083 if (addmenu.length) { 4096 4084 var option = addmenu.children('option[value="'+col+'"]'); … … 4101 4089 } 4102 4090 else 4103 alert('addmennu not found') 4104 }; 4105 4106 4107 this.upload_contact_photo = function(frame) 4108 { 4109 // TODO: implement this 4091 alert('addmennu not found') 4092 }; 4093 4094 4095 this.upload_contact_photo = function(form) 4096 { 4097 if (form && form.elements._photo.value) { 4098 this.async_upload_form(form, 'upload-photo', function(e) { 4099 rcmail.set_busy(false, null, rcmail.photo_upload_id); 4100 }); 4101 4102 // display upload indicator 4103 this.photo_upload_id = this.set_busy(true, 'uploading'); 4104 } 4105 }; 4106 4107 this.replace_contact_photo = function(id) 4108 { 4109 $('#ff_photo').val(id); 4110 4111 var buttons = this.buttons['upload-photo']; 4112 for (var n=0; n < buttons.length; n++) 4113 $('#'+buttons[n].id).html(this.get_label(id == '-del-' ? 'addphoto' : 'replacephoto')); 4114 4115 var img_src = id == '-del-' ? this.env.photo_placeholder : 4116 this.env.comm_path + '&_action=photo&_source=' + this.env.source + '&_cid=' + this.env.cid + '&_photo=' + id; 4117 $(this.gui_objects.contactphoto).children('img').attr('src', img_src); 4118 4119 this.enable_command('delete-photo', id != '-del-'); 4120 }; 4121 4122 this.photo_upload_end = function() 4123 { 4124 this.set_busy(false, null, this.photo_upload_id); 4125 delete this.photo_upload_id; 4110 4126 }; 4111 4127 … … 5376 5392 }; 5377 5393 5394 // post the given form to a hidden iframe 5395 this.async_upload_form = function(form, action, onload) 5396 { 5397 var ts = new Date().getTime(); 5398 var frame_name = 'rcmupload'+ts; 5399 5400 // have to do it this way for IE 5401 // otherwise the form will be posted to a new window 5402 if (document.all) { 5403 var html = '<iframe name="'+frame_name+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>'; 5404 document.body.insertAdjacentHTML('BeforeEnd', html); 5405 } 5406 else { // for standards-compilant browsers 5407 var frame = document.createElement('iframe'); 5408 frame.name = frame_name; 5409 frame.style.border = 'none'; 5410 frame.style.width = 0; 5411 frame.style.height = 0; 5412 frame.style.visibility = 'hidden'; 5413 document.body.appendChild(frame); 5414 } 5415 5416 // handle upload errors, parsing iframe content in onload 5417 $(frame_name).bind('load', {ts:ts}, onload); 5418 5419 form.target = frame_name; 5420 form.action = this.env.comm_path + '&_action=' + action + '&_uploadid=' + ts; 5421 form.setAttribute('enctype', 'multipart/form-data'); 5422 form.submit(); 5423 }; 5424 5378 5425 // starts interval for keep-alive/check-recent signal 5379 5426 this.start_keepalive = function() -
branches/devel-addressbook/program/localization/en_US/labels.inc
r4285 r4314 289 289 $labels['save'] = 'Save'; 290 290 $labels['delete'] = 'Delete'; 291 $labels['addphoto'] = 'Add'; 292 $labels['replacephoto'] = 'Replace'; 291 293 292 294 $labels['newcontact'] = 'Create new contact card'; -
branches/devel-addressbook/program/localization/en_US/messages.inc
r4190 r4314 129 129 $messages['messagemarked'] = 'Message(s) marked successfully'; 130 130 $messages['autocompletechars'] = 'Enter at least $min characters for autocompletion'; 131 $messages['invalidimageformat'] = 'Not a valid image format'; 131 132 132 133 ?> -
branches/devel-addressbook/program/steps/addressbook/edit.inc
r4242 r4314 125 125 126 126 127 function rcmail_upload_photo_form($attrib) 128 { 129 global $OUTPUT; 130 131 // add ID if not given 132 if (!$attrib['id']) 133 $attrib['id'] = 'rcmUploadbox'; 134 135 // find max filesize value 136 $max_filesize = parse_bytes(ini_get('upload_max_filesize')); 137 $max_postsize = parse_bytes(ini_get('post_max_size')); 138 if ($max_postsize && $max_postsize < $max_filesize) 139 $max_filesize = $max_postsize; 140 $max_filesize = show_bytes($max_filesize); 141 142 $hidden = new html_hiddenfield(array('name' => '_cid', 'value' => $GLOBALS['cid'])); 143 $input = new html_inputfield(array('type' => 'file', 'name' => '_photo', 'size' => $attrib['size'])); 144 $button = new html_inputfield(array('type' => 'button')); 145 146 $out = html::div($attrib, 147 $OUTPUT->form_tag(array('name' => 'uploadform', 'method' => 'post', 'enctype' => 'multipart/form-data'), 148 $hidden->show() . 149 html::div(null, $input->show()) . 150 html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) . 151 html::div('buttons', 152 $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' . 153 $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('upload-photo', this.form)")) 154 ) 155 ) 156 ); 157 158 $OUTPUT->add_label('addphoto','replacephoto'); 159 $OUTPUT->add_gui_object('uploadbox', $attrib['id']); 160 return $out; 161 } 162 163 127 164 // similar function as in /steps/settings/edit_identity.inc 128 165 function get_form_tags($attrib) … … 157 194 $OUTPUT->add_handler('contactedithead', 'rcmail_contact_edithead'); 158 195 $OUTPUT->add_handler('contacteditform', 'rcmail_contact_editform'); 196 $OUTPUT->add_handler('contactphoto', 'rcmail_contact_photo'); 197 $OUTPUT->add_handler('photouploadform', 'rcmail_upload_photo_form'); 159 198 160 199 if (!$CONTACTS->get_result() && $OUTPUT->template_exists('contactadd')) -
branches/devel-addressbook/program/steps/addressbook/func.inc
r4298 r4314 100 100 } 101 101 102 $OUTPUT->set_env('photocol', is_array($CONTACT_COLTYPES['photo'])); 103 102 104 103 105 function rcmail_directory_list($attrib) … … 288 290 $form = $plugin['form']; 289 291 $record = $plugin['record']; 290 $formdata = array();291 292 $edit_mode = $RCMAIL->action != 'show'; 292 $pic_img = $attrib['picplaceholder'] ? $CONFIG['skin_path'] . $attrib['picplaceholder'] : 'program/blank.gif';293 293 $del_button = $attrib['deleteicon'] ? html::img(array('src' => $CONFIG['skin_path'] . $attrib['deleteicon'], 'alt' => rcube_label('delete'))) : rcube_label('delete'); 294 unset($attrib[' picplaceholder'], $attrib['deleteicon']);294 unset($attrib['deleteicon']); 295 295 $out = ''; 296 296 … … 322 322 if ($section == 'head') { 323 323 $content = ''; 324 325 if ($coltypes['photo']) {326 if ($record['photo'])327 $pic_img = $RCMAIL->url(array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $_REQUEST['_source']));328 $img = html::img(array('src' => $pic_img, 'border' => 1, 'alt' => ''));329 if ($edit_mode) {330 $label = $record['photo'] ? rcube_label('replacephoto') : rcube_label('addphoto');331 $img = html::a(array('href' => '#', 'id' => 'contactpicframe', 'title' => $label), $img);332 }333 $content .= html::div('contactpic', $img);334 }335 324 336 325 $names_arr = array($record['prefix'], $record['firstname'], $record['middlename'], $record['surname'], $record['suffix']); … … 466 455 467 456 $coltypes[$field] = (array)$colprop + $coltypes[$field]; 468 $formdata[$field][] = array('subtype' => $subtype, 'value' => $val);469 457 470 458 if ($colprop['subtypes'] || $colprop['limit'] != 1) … … 525 513 526 514 if ($edit_mode) { 527 $RCMAIL->output->set_env('contactdata', $formdata);528 515 $RCMAIL->output->set_env('coltypes', $coltypes + $coltype_lables); 529 516 $RCMAIL->output->set_env('delbutton', $del_button); … … 532 519 533 520 return $out; 521 } 522 523 524 function rcmail_contact_photo($attrib) 525 { 526 global $CONTACTS, $CONTACT_COLTYPES, $RCMAIL, $CONFIG; 527 528 if ($result = $CONTACTS->get_result()) 529 $record = $result->first(); 530 531 $photo_img = $attrib['placeholder'] ? $CONFIG['skin_path'] . $attrib['placeholder'] : 'program/blank.gif'; 532 unset($attrib['placeholder']); 533 534 if ($CONTACT_COLTYPES['photo']) { 535 $RCMAIL->output->set_env('photo_placeholder', $photo_img); 536 537 if ($record['photo']) 538 $photo_img = $RCMAIL->url(array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $_REQUEST['_source'])); 539 $img = html::img(array('src' => $photo_img, 'border' => 1, 'alt' => '')); 540 $content = html::div($attrib, $img); 541 542 if ($RCMAIL->action == 'edit' || $RCMAIL->action == 'add') { 543 $RCMAIL->output->add_gui_object('contactphoto', $attrib['id']); 544 $hidden = new html_hiddenfield(array('name' => '_photo', 'id' => 'ff_photo')); 545 $content .= $hidden->show(); 546 } 547 } 548 549 return $content; 534 550 } 535 551 -
branches/devel-addressbook/program/steps/addressbook/save.inc
r4289 r4314 31 31 32 32 33 // handle photo upload for contacts 34 if ($RCMAIL->action == 'upload-photo') { 35 // clear all stored output properties (like scripts and env vars) 36 $OUTPUT->reset(); 37 38 if ($filepath = $_FILES['_photo']['tmp_name']) { 39 // TODO: check file type and resize image 40 $imageprop = rcmail::imageprops($_FILES['_photo']['tmp_name']); 41 42 if ($imageprop['width'] && $imageprop['height']) { 43 $maxsize = $RCMAIL->config->get('contact_photo_size', 160); 44 $tmpfname = tempnam($RCMAIL->config->get('temp_dir'), 'rcmImgConvert'); 45 $save_hook = 'attachment_upload'; 46 47 // scale image to a maximum size 48 if (($imageprop['width'] > $maxsize || $imageprop['height'] > $maxsize) && 49 (rcmail::imageconvert(array('in' => $filepath, 'out' => $tmpfname, 'size' => $maxsize.'x'.$maxsize, 'type' => $imageprop['type'])) !== false)) { 50 $filepath = $tmpfname; 51 $save_hook = 'attachment_save'; 52 } 53 54 // save uploaded file in storage backend 55 $attachment = $RCMAIL->plugins->exec_hook($save_hook, array( 56 'path' => $filepath, 57 'size' => $_FILES['_photo']['size'], 58 'name' => $_FILES['_photo']['name'], 59 'mimetype' => rc_mime_content_type($filepath, $_FILES['_photo']['name'], 'image/' . $imageprop['type']) 60 )); 61 } 62 else 63 $attachment['error'] = rcube_label('invalidimageformat'); 64 65 if ($attachment['status'] && !$attachment['abort']) { 66 $file_id = $attachment['id']; 67 $_SESSION['contacts']['files'][$file_id] = $attachment; 68 $OUTPUT->command('replace_contact_photo', $file_id); 69 } 70 else { // upload failed 71 $err = $_FILES['_photo']['error']; 72 if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) 73 $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize')))))); 74 else if ($attachment['error']) 75 $msg = $attachment['error']; 76 else 77 $msg = rcube_label('fileuploaderror'); 78 79 $OUTPUT->command('display_message', $msg, 'error'); 80 } 81 } 82 else if ($_SERVER['REQUEST_METHOD'] == 'POST') { 83 // if filesize exceeds post_max_size then $_FILES array is empty, 84 // show filesizeerror instead of fileuploaderror 85 if ($maxsize = ini_get('post_max_size')) 86 $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes($maxsize))))); 87 else 88 $msg = rcube_label('fileuploaderror'); 89 90 $OUTPUT->command('display_message', $msg, 'error'); 91 } 92 93 $OUTPUT->command('photo_upload_end'); 94 $OUTPUT->send('iframe'); 95 } 96 97 33 98 // read POST values into hash array 34 99 $a_record = array(); … … 88 153 } 89 154 155 // get raw photo data if changed 156 if (isset($a_record['photo'])) { 157 if ($a_record['photo'] == '-del-') { 158 $a_record['photo'] = ''; 159 } 160 else if ($tempfile = $_SESSION['contacts']['files'][$a_record['photo']]) { 161 $tempfile = $RCMAIL->plugins->exec_hook('attachment_get', $tempfile); 162 if ($tempfile['status']) 163 $a_record['photo'] = $tempfile['data'] ? $tempfile['data'] : @file_get_contents($tempfile['path']); 164 } 165 else 166 unset($a_record['photo']); 167 168 // cleanup session data 169 $RCMAIL->plugins->exec_hook('attachments_cleanup', array()); 170 $RCMAIL->session->remove('contacts'); 171 } 172 90 173 // update an existing contact 91 174 if (!empty($cid)) -
branches/devel-addressbook/program/steps/addressbook/show.inc
r4300 r4314 28 28 // return raw photo of the given contact 29 29 if ($RCMAIL->action == 'photo') { 30 if ($record['photo']) { 30 if (($file_id = get_input_value('_photo', RCUBE_INPUT_GPC)) && ($tempfile = $_SESSION['contacts']['files'][$file_id])) { 31 $tempfile = $RCMAIL->plugins->exec_hook('attachment_display', $tempfile); 32 if ($tempfile['status']) { 33 if ($tempfile['data']) 34 $data = $tempfile['data']; 35 else if ($tempfile['path']) 36 $data = file_get_contents($tempfile['path']); 37 } 38 } 39 else if ($record['photo']) { 31 40 $data = is_array($record['photo']) ? $record['photo'][0] : $record['photo']; 32 if (!preg_match('![^a-z0-9/ +-]!i', $data))41 if (!preg_match('![^a-z0-9/=+-]!i', $data)) 33 42 $data = base64_decode($data, true); 34 43 } … … 181 190 $OUTPUT->add_handler('contacthead', 'rcmail_contact_head'); 182 191 $OUTPUT->add_handler('contactdetails', 'rcmail_contact_details'); 192 $OUTPUT->add_handler('contactphoto', 'rcmail_contact_photo'); 183 193 184 194 $OUTPUT->send('contact'); -
branches/devel-addressbook/program/steps/mail/compose.inc
r4190 r4314 1130 1130 $out = html::div($attrib, 1131 1131 $OUTPUT->form_tag(array('name' => 'uploadform', 'method' => 'post', 'enctype' => 'multipart/form-data'), 1132 html::div(null, rcmail_compose_attachment_field(array('size' => $attrib[ attachmentfieldsize]))) .1132 html::div(null, rcmail_compose_attachment_field(array('size' => $attrib['attachmentfieldsize']))) . 1133 1133 html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) . 1134 1134 html::div('buttons', -
branches/devel-addressbook/skins/default/addressbook.css
r4300 r4314 275 275 } 276 276 277 #contact head .contactpic277 #contactphoto 278 278 { 279 279 float: right; 280 width: 50px; 281 min-height: 50px; 280 width: 60px; 281 margin-left: 3em; 282 margin-right: 4px; 283 } 284 285 #contactpic 286 { 287 width: 60px; 288 min-height: 60px; 282 289 border: 1px solid #ccc; 283 290 background: white; 284 margin-left: 3em; 285 } 286 287 #contacthead .contactpic img { 288 width: 50px; 291 } 292 293 #contactpic img { 294 width: 60px; 295 } 296 297 #contactphoto .formlinks 298 { 299 margin-top: 0.5em; 300 text-align: center; 289 301 } 290 302 … … 354 366 } 355 367 368 #upload-form 369 { 370 padding: 6px; 371 } 372 373 #upload-form div 374 { 375 padding: 2px; 376 } -
branches/devel-addressbook/skins/default/common.css
r4227 r4314 118 118 color: #666; 119 119 font-size: 11px; 120 } 121 122 .formlinks a, 123 .formlinks a:visited 124 { 125 color: #CC0000; 126 font-size: 11px; 127 text-decoration: none; 128 } 129 130 .formlinks a.disabled, 131 .formlinks a.disabled:visited 132 { 133 color: #999999; 120 134 } 121 135 -
branches/devel-addressbook/skins/default/functions.js
r4297 r4314 88 88 composemenu: {id:'composeoptionsmenu', editable:1}, 89 89 // toggle: #1486823, #1486930 90 uploadmenu: {id:'attachment-form', editable:1, above:1, toggle:!bw.ie&&!bw.linux } 90 uploadmenu: {id:'attachment-form', editable:1, above:1, toggle:!bw.ie&&!bw.linux }, 91 uploadform: {id:'upload-form', editable:1, toggle:true} 91 92 }; 92 93 … … 129 130 if (!above && pos.top + ref.offsetHeight + obj.height() > window.innerHeight) 130 131 above = true; 132 133 if (pos.left + obj.width() > window.innerWidth) 134 pos.left = window.innerWidth - obj.width() - 30; 131 135 132 136 obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.offsetHeight)) }); … … 494 498 rcmail_ui.init_compose_form(); 495 499 } 500 else if (rcmail.env.task == 'addressbook') { 501 rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); }); 502 } 496 503 } 497 504 -
branches/devel-addressbook/skins/default/mail.css
r4184 r4314 1339 1339 } 1340 1340 1341 .formlinks a,1342 .formlinks a:visited1343 {1344 color: #999999;1345 font-size: 11px;1346 text-decoration: none;1347 }1348 1349 .formlinks a,1350 .formlinks a:visited1351 {1352 color: #CC0000;1353 }1354 1355 1341 #compose-editorfooter 1356 1342 { -
branches/devel-addressbook/skins/default/templates/contact.html
r4297 r4314 10 10 <div id="contact-title" class="boxtitle"><roundcube:label name="contactproperties" /></div> 11 11 <div id="contact-details" class="boxcontent"> 12 <roundcube:object name="contacthead" id="contacthead" picPlaceholder="/images/contactpic.png" /> 12 <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" /></div> 13 <roundcube:object name="contacthead" id="contacthead" photoplaceholder="/images/contactpic.png" /> 14 <div style="clear:both"></div> 13 15 <div id="contacttabs"> 14 16 <roundcube:object name="contactdetails" /> -
branches/devel-addressbook/skins/default/templates/contactadd.html
r4297 r4314 6 6 <script type="text/javascript" src="/functions.js"></script> 7 7 </head> 8 <body class="iframe" >8 <body class="iframe" onload="rcube_init_mail_ui()"> 9 9 10 10 <div id="contact-title" class="boxtitle"><roundcube:label name="addcontact" /></div> 11 11 <div id="contact-details" class="boxcontent"> 12 12 <form name="editform" method="post" action="./"> 13 <roundcube:object name="contactedithead" id="contacthead" size="16" form="editform" picPlaceholder="/images/contactpic.png" /> 13 <div id="contactphoto"> 14 <roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" /> 15 <div class="formlinks"> 16 <roundcube:button command="upload-photo" id="uploadformlink" type="link" label="addphoto" class="disabled" classAct="active" onclick="rcmail_ui.show_popup('uploadform', true);return false" condition="env:photocol" /><br/> 17 <roundcube:button command="delete-photo" type="link" label="delete" class="disabled" classAct="active" condition="env:photocol" /> 18 </div> 19 </div> 20 <roundcube:object name="contactedithead" id="contacthead" size="16" form="editform" /> 21 <div style="clear:both"></div> 22 14 23 <div id="contacttabs"> 15 24 <roundcube:object name="contacteditform" size="40" textareacols="60" deleteIcon="/images/icons/delete.png" form="editform" /> … … 21 30 </form> 22 31 </div> 32 33 <roundcube:object name="photoUploadForm" id="upload-form" size="30" class="popupmenu" /> 34 23 35 <script type="text/javascript">rcube_init_tabs('contacttabs')</script> 24 36 -
branches/devel-addressbook/skins/default/templates/contactedit.html
r4297 r4314 6 6 <script type="text/javascript" src="/functions.js"></script> 7 7 </head> 8 <body class="iframe" >8 <body class="iframe" onload="rcube_init_mail_ui()"> 9 9 10 10 <div id="contact-title" class="boxtitle"><roundcube:label name="editcontact" /></div> 11 11 <div id="contact-details" class="boxcontent"> 12 12 <form name="editform" method="post" action="./"> 13 <roundcube:object name="contactedithead" id="contacthead" size="16" form="editform" picPlaceholder="/images/contactpic.png" /> 13 <div id="contactphoto"> 14 <roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" /> 15 <div class="formlinks"> 16 <roundcube:button command="upload-photo" id="uploadformlink" type="link" label="replacephoto" class="disabled" classAct="active" onclick="rcmail_ui.show_popup('uploadform', true);return false" condition="env:photocol" /><br/> 17 <roundcube:button command="delete-photo" type="link" label="delete" class="disabled" classAct="active" condition="env:photocol" /> 18 </div> 19 </div> 20 <roundcube:object name="contactedithead" id="contacthead" size="16" form="editform" /> 21 <div style="clear:both"></div> 22 14 23 <div id="contacttabs"> 15 24 <roundcube:object name="contacteditform" size="40" textareacols="60" deleteIcon="/images/icons/delete.png" form="editform" /> … … 21 30 </form> 22 31 </div> 32 33 <roundcube:object name="photoUploadForm" id="upload-form" size="30" class="popupmenu" /> 34 23 35 <script type="text/javascript">rcube_init_tabs('contacttabs')</script> 24 36
Note: See TracChangeset
for help on using the changeset viewer.
