Page MenuHomePhorge

No OneTemporary

diff --git a/CHANGELOG b/CHANGELOG
index 975e442ed..2422bb041 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,1480 +1,1487 @@
CHANGELOG RoundCube Webmail
---------------------------
+2008/09/29 (alec)
+----------
+- Added 'mime_param_folding' option with possibility to choose
+ long/non-ascii attachment names encoding eg. to be readable
+ in MS Outlook/OE (#1485320)
+- Added "advanced options" feature in User Preferences
+
2008/09/25 (alec)
----------
- Fix problem with non-ascii attachment names in Mail_mime (#1485267, #1485096)
2008/09/23 (alec)
----------
- Fix language autodetection (#1485401)
- Fix button label in folders management (#1485405)
- Fix collapsed folder not indicating unread msgs count of all subfolders (#1485403)
- Fix handling of apostrophes in filenames decoded according to rfc2231
2008/09/19 (thomasb)
----------
- Made config files location configurable (#1485215)
2008/09/16 (alec)
----------
- Reduced memory footprint when forwarding attachments (#1485345)
- Fix inline images handling when replying/forwarding html messages
- Allow and use spellcheck attribute for input/textarea fields (#1485060)
- Added icons for forwarded/forwarded+replied messages (#1485257)
- Added Reply-To to forwarded emails (#1485315)
- Display progress message for folders create/delete/rename (#1485357)
- Smart Tags and NOBR tag support in html messages (#1485363, #1485327)
2008/09/15 (thomasb)
----------
- Redesign of the identities settings (#1484042)
- Add config option to disable creation/deletion of identities (#1484498)
2008/09/15 (alec)
----------
- Added 'sendmail_delay' option to restrict messages sending interval (#1484491)
2008/09/12 (alec)
----------
- Added vertical splitter for folders list resizing
- Added possibility to view all headers in message view
- Fixed splitter drag/resize on Opera (#1485170)
- Fixed quota img height/width setting from template (#1484857)
2008/09/12 (thomasb)
----------
- Refactor drag & drop functionality. Don't rely on browser events anymore (#1484453)
- Insert "virtual" folders in subscription list (#1484779)
- Added link to open message in new window
2008/09/05 (thomasb)
----------
- Enable export of address book contacts as vCard
- Respect Content-Location headers in multipart/related messages according to RFC2110 (#1484946)
- Applied mime_decode patch by David Lublink
- Allowed max. attachment size now indicated in compose screen (#1485030)
- Also capture backspace key in list mode (#1484566)
- Allow application/pgp parts to be displayed (#1484753)
- Correctly handle options in mailto-links (#1485228)
- Immediately save sort_col/sort_order in user prefs (#1485265)
2008/09/04 (alec)
----------
- Truncate very long (above 50 characters) attachment filenames when displaying
- Support \" and \\ in quoted strings when parsing BODYSTRUCTURE (mime.inc)
- Allow 'readonly' atributes in input and textarea (#1485312)
2008/09/03 (thomasb)
----------
- Allow to auto-detect client language if none set (#1484434)
- Auto-detect the client timezone (user configurable)
2008/09/03 (alec)
----------
- Add RFC2231 header value continuations support for attachment
filenames + hack for servers that not support that feature
- Fix Reply-To header displaying (#1485314)
2008/09/02 (thomasb)
----------
- Add feature to import contacts from vcard files (#1326103)
- Mark form buttons that provide the most obvious operation (mainaction)
2008/08/30 (alec)
----------
- Improved HTML to TXT conversion by html2text class update
to version 1.0.0
2008/08/28 (alec)
----------
- Added option 'quota_zero_as_unlimited' (#1484604)
- Added PRE handling in html2text class (#1484740)
2008/08/28 (robin)
----------
- Added folder hierarchy collapsing
2008/08/27 (alec)
----------
- Added options to use syslog instead of log file (#1484850)
- Added Logging & Debugging section in Installer
- Write to smtp log also sent MDN confirmations
2008/08/26 (alec)
----------
- Removed support for PEAR::DB driver
2008/08/21 (alec)
----------
- Add Content-Length header while attachments downloading (#1484256)
- Fix In-Reply-To and References headers when composing saved draft
message (#1485288)
- Removed PHP4 class constructors
- Fix html message charset conversion for charsets with underline (#1485287)
- Fix buttons status after contacts deletion (#1485233)
2008/08/21 (estadtherr)
----------
- Fix escaping of To: and From: fields when building message body for reply
or forward in the HTML editor (#1484904)
2008/08/15 (thomasb)
----------
- Use current mailbox name in template (#1485256)
- Better fix for skipping untagged responses (#1485261)
- Added pspell support patch by Kris Steinhoff (#1483960)
- Enable spellchecker for HTML editor (#1485114)
- Respect spellcheck_uri in tinyMCE spellchecker (#1484196)
2008/08/09 (alec)
----------
- Case insensitive contacts searching using PostgreSQL (#1485259)
2008/07/31 (thomasb)
----------
- Make default imap folders configurable for each user (#1485075)
- Save outgoing mail to selectable folder (#1324581)
- Fix hiding of mark menu when clicking th button again (#1484944)
2008/07/21 (alec)
----------
- use long date format in print mode (#1485191)
2008/07/18 (alec)
----------
- Updated TinyMCE to version 3.1.0.1
2008/07/14 (thomasb)
----------
- Re-enable autocomplete attribute for login form (#1485211)
- Check PERMANENTFLAGS before saving $MDNSent flag (#1484963, #1485163)
2008/06/30 (alec)
----------
- Added flag column on messages list (#1484623)
2008/06/24 (alec)
----------
- Patched Mail/MimePart.php (http://pear.php.net/bugs/bug.php?id=14232)
2008/06/24 (alec)
----------
- Allow trash/junk subfolders to be purged (#1485085)
2008/06/20 (alec)
----------
- Added Azerbaijani translation
2008/06/20 (thomasb)
----------
- Store compose parameters in session and redirect to a unique URL
2008/06/18 (thomasb)
----------
- Fixed CRAM-MD5 authentication (#1484819)
- Add fallback to old 'skin_path' property
2008/06/16 (alec)
----------
- Fixed sending emoticons
- Fixed forwarding messages with one HTML attachment (#1484442)
- Fixed encoding of message/rfc822 attachments and image/pjpeg handling (#1484914)
2008/06/15 (alec)
----------
- Added option to select skin in user preferences
WARNING: option 'skin_path' replaced by 'skin' option!
2008/06/14 (alec)
----------
- Added option to disable displaying of attached images below the message body
2008/06/13 (alec)
----------
- Added option to display images in messages from known senders (#1484601)
- Updated PEAR::Mail_Mime
- User preferences grouped in more fieldsets
2008/06/12 (alec)
----------
- Fix corrupted MIME headers of messages in Sent folder (#1485111)
- Fixed bug in MDB2 package: http://pear.php.net/bugs/bug.php?id=14124
- Use keypress instead of keydown to select list's row (#1484816)
2008/06/11 (alec)
----------
- Don't call expunge and don't remove message row after message move
if flag_for_deletion is set to true (#1485002)
2008/06/08 (alec)
----------
- Added option to disable autocompletion from selected LDAP address books (#1484922)
2008/06/07 (thomasb)
----------
- Cleaned up localization names. Now named with lang_COUNTRY according to ISO 639-1/3166-1
- Updated Catalan localization
2008/06/06 (robin)
----------
- Add option to log successful logins
2008/06/06 (alec)
----------
- TLS support in LDAP connections: 'use_tls' property (#1485104)
2008/06/05 (alec)
----------
- Fix removing messages from search set after deleting them (#1485106)
2008/06/03 (alec)
----------
- imap.inc: Fixed iil_MultLine(): use iil_ReadBytes() instead of iil_ReadLine()
- imap.inc: Fixed iil_C_FetchStructureString() to handle many
literal strings in response (#1484969)
- imap.inc: Removed hardcoded data size in iil_ReadLine()
2008/05/30 (alec)
----------
- Support for subfolders in default/protected folders (#1484665)
- Disallowed delimiter in folder name (#1484803)
- Support " and \ in folder names
- Escape \ in login (#1484614)
2008/05/29 (thomasb)
----------
- Better HTML sanitization with the DOM-based washtml script (#1484701)
2008/05/29 (alec)
----------
- Polish localization folder renamed to pl_PL
2008/05/28 (alec)
----------
- Fixed sorting of folders with non-ascii characters
2008/05/21 (alec)
----------
- Localized pagetitle in Settings and Address Book
2008/05/19 (alec)
----------
- Fixed Mysql DDL for default identities creation (#1485070)
2008/05/16 (alec)
----------
- In Preferences added possibility to configure 'read_when_deleted',
'mdn_requests', 'flag_for_deletion' options
2008/05/15 (thomasb)
----------
- Make IMAP auth type configurable (#1483825)
- Fix empty values with FROM_UNIXTIME() in rcube_mdb2 (#1485055)
2008/05/15 (alec)
----------
- Fix attachment list on IE 6/7 (#1484807)
2008/05/12 (estadtherr)
----------
- fix JavaScript in compose.html that shows cc/bcc fields if populated
2008/05/12 (alec)
----------
- Updated PEAR::DB package to version 1.7.13
2008/05/10 (alec)
----------
- Make password input fields of type password in installer (#1484886)
2008/05/09 (alec)
----------
- Don't call CAPABILITY if was recieved as server's optional response
on connect (RFC3501 [7.1])
2008/05/08 (alec)
----------
- Don't attempt to delete cache entries if enable_caching is FALSE (#1485051)
- Optimized messages sorting on servers without sort capability (#1485049)
- Option 'use_SQL_address_book' replaced by 'address_book_type'
- Corrected message headers decoding when charset isn't specified and improved
support for native languages (#1485050, #1485048)
2008/05/07 (davidke/richs)
----------
- Completed LDAP address book support so it can now write to an LDAP server.
- Expanded LDAP configuration options to support LDAP server writes.
- Modified config/main.inc.php.dist:
New Option: $rcmail_config['use_SQL_address_book']
Changed Option: $rcmail_config['ldap_public']['Verisign']
2008/05/05 (alec)
----------
- Installer: encode special characters in DB username/password (#1485042)
- Do charset conversion also for from/to column on messages list
- Fix management of folders with national characters in names (#1485036, #1485001)
2008/05/02 (alec)
----------
- Updated MDB2 package to version 2.5.0b1
- Updated MDB2 pgsql, mysql, mysqli, sqlite drivers to version 1.5.0b1
- Updated MDB2 mssql driver to version 1.3.0b1
- Fixed identities saving when using MDB2 pgsql driver (#1485032)
2008/05/01 (alec)
----------
- Fix BCC header reset (#1484997)
2008/04/30 (thomasb)
----------
- Introduce new application class 'rcmail' and get rid of some global vars
2008/04/29 (alec)
----------
- improved messages list performance - patch from Justin Heesemann
2008/04/23 (alec)
----------
- Append skin_path to images location only when it starts
with '/' sign (#1484859)
2008/04/20 (estadtherr)
----------
- fix parse_attrib_string to handle unquoted values, which fixes
display issues with HTML messages that do not quote attributes
2008/04/17 (alec)
----------
- Fix IMAP response in message body when message has no body (#1484964)
- Updated PEAR::Auth_SASL to 1.0.2
- Fix non-RFC dates formatting (#1484901)
2008/04/16 (estadtherr)
----------
- Fix mail sending with new TinyMCE
2008/04/16 (alec)
----------
- Fix typo in set_charset() (#1484991)
- Decode entities when inserting HTML signature to plain text message (#1484990)
2008/04/15 (estadtherr)
----------
- HTML editing is now working with PHP5 updates and TinyMCE v3.0.6
- fix signature loading on Windows (#1484545)
- add language support to HTML editing (#1484862)
2008/04/15 (alec)
----------
- Fix remove signature when replying (#1333167)
- Fix problem with line with a space at the end (#1484916)
- Don't send set_env() in ajax response when env array is empty
- Fix <!DOCTYPE> tag filtering (#1484391)
- Fix <?xml> tag filtering (#1484403)
2008/04/14 (alec)
----------
- Added sections (fieldset+label) in Settings interface
2008/04/12 (alec)
----------
- Fixed and optimized 'read_when_deleted': mark as read on server side
in one action when marking as deleted, fixed js bugs when deleting
from message preview page
2008/04/12 (thomasb)
----------
- Changed codebase to PHP5 with autoloader
- Added some new classes from devel-vnext branch
2008/04/11 (alec)
----------
- Mark as read in one action with message preview (#1484972)
- Delete redundant quota reads (#1484972)
- Add options for empty trash and expunge inbox on logout (#1483863)
2008/04/10 (alec)
----------
- Add rows highlighting in onmousemove on ksearch list
- Remove lines wrapping when displaying message
- Fix month localization
- Do ob_start/ob_end_clean when reading config files (#1484624)
- Fix debug (ajax) console
2008/04/02 (alec)
----------
- Updated timezones list (#1484908)
- Fix design in Settings (#1484799)
- Fix deleting messages after clicking on "All" (#1484838)
- Fix sorting o0f message list when default folder is empty (#1484317)
- Fix creating a new folder w/a comma in its name (#1484681)
2008/04/01 (thomasb)
----------
- Fix Enter problem on login (#1484839)
- Make the http-received header in outgoing mails configurable
2008/03/30 (till)
----------
- Fix Firefox problem with ob_gzhandler (#1484932)
- Improve message previewpane - less loading (#1484316)
2008/03/28 (thomasb)
----------
- Disable installer by default; add config option to enable it again
2008/03/24 (till)
----------
- Don't send mark requests for already marked messages (#1484906)
- Fix "quote inside a quote" (#1484783)
2008/03/23 (till)
- Applied patch to strip newlines from headers (#1484811)
- Applied patch to trim login (#1484231)
- Added robots.txt
- Fix attachment problem when restoring saved draft without body (#1484506)
- Fix call to undefined function decrypt_passwd()
2008/03/21 (thomasb)
----------
- Add configurable default charset for message decoding
- Applied patch to fix mime decoding an folder subscription (#1484191)
- Applied patch to correctly quote email recipient strings (#1484191)
- Fix wrong charset aliases (#1484818 and #1484598)
- Remove hard-coded size of logo image (#1484378)
- Strip slashes from virtuser email values (#1484700)
- Fixed message part window display in IE6 (#1484610)
2008/02/28 (thomasb)
----------
- Fix folder adding/renaming inspired by #1484800
- Applied patch by Emanuele Rocca to make LDAP filters work with or without brackets
- Fix quirky message selection
- Completed installer
2008/02/20 (thomasb)
----------
- Localize folder name in page title (#1484785)
- Fix code using wrong variable name (#1484018)
- Allow to send mail with BCC recipients only
- Remove MDN headers before saving in sent folder
2008/02/12 (estadtherr)
----------
- fix switching between HTML/plain composing (#1484752)
- condense TinyMCE toolbar down to one line, removing table buttons (#1484747)
- fix image removal in message display when message HTML includes JS event handlers
2008/02/11 (thomasb)
----------
- Add function to mark the selected messages as read/unread (#1457360)
- Also do charset decoding as suggested in RFC 2231 (fix #1484321)
- Show message count in folder list and hint when creating a subfolder
2008/02/08 (thomasb)
----------
- Distinguish ssl and tls for imap connections (#1484667)
- Added some charset aliases to fix typical mis-labelling (#1484565)
2008/02/07 (thomasb)
----------
- Remember decision to display images for a certain message during session (#1484754)
- Truncate attachment filenames to 55 characters due to an IE bug (#1484757)
- Fix size of the attachment preview frame (#1484758)
2008/02/05 (thomasb)
----------
- Fix regular expression for checking e-mail address (#1484710)
- Make sending of read receipts configurable
- Respect config when localize folder names (#1484707)
- Applied patch for updating page title (#1484727, #1484650)
- Applied patch to prevent from purging inbox by uberlinuxguy (#1484449)
- Applied patch to prevent bad header delimiters (#1484751)
- Also send search request when deleting a contact (#1484620)
- Add CSS hack for Safari
2008/02/02 (thomasb)
----------
- Always update $CONFIG with user prefs (#1484729)
- Don't ask for MDN confirmations on drafted messages (#1484691)
- Also respect receipt and priority settings when re-opening a draft message
2008/01/31 (robin)
----------
- Remember search results (closes #1483883), patch by the_glu
2008/01/08 (tomekp)
----------
- add he (Hebrew) localization (#1484713)
2008/01/08 (tomekp)
----------
- update fr localization
2008/01/04 (tomekp)
- purge kur_KU because it has no messages translation
- bump copyright for all localization files
2007/12/31 (tomekp)
----------
- update es localization
2007/12/28 (tomekp)
----------
- update mk localization
2007/12/27 (tomekp)
----------
- update se localization
2007/12/13 (robin)
----------
- Add Received header on outgoing mail
2007/12/10 (estadtherr)
----------
- Upgrade to TinyMCE 2.1.3
- Allow inserting image attachments into HTML messages while composing (#1484557)
2007/12/10 (thomasb)
----------
- Delegate user-stuff to new class rcube_user
- Implement Message-Disposition-Notification (Receipts)
2007/12/05 (tomekp)
----------
- update bg, uk localization
2007/12/04 (tomekp)
----------
- update bg localization
2007/11/25 (thomasb)
----------
- Applied UID fetch patch by Glen Ogilvie
- Applied patch for correct Postgres instructions from ticket #1484674
- Fix overriding of session vars when register_globals is on (#1484670)
- Fix wrong Postgres setup instructions in INSTALL (#1484674)
- Fix bug with case-sensitive folder names (#1484245)
- Don't create default folders by default
- Added Georgian localization by Zaza Zviadadze
- Updated Russian localization
- Fixed some potential security risks (audited by Andris)
- Only show new messages if they match the current search (#1484176)
2007/11/20 (tomekp)
----------
- add Korean (kr) localization
2007/11/14 (tomekp)
----------
- update id_ID localization
2007/11/06 (thomasb)
----------
- Switch to/from when searcing in Sent folder (#1484555)
- Correctly read the References header (#1484646)
- Unset old cookie in before sending a new value (#1484639)
- Correctly decode attachments when downloading them (#1484645 and #1484642)
2007/10/22 (tomekp)
----------
- update ru, eo localizations
2007/10/17 (thomasb)
----------
- Make message listing less error prone
2007/10/10 (thomasb)
----------
- Suppress IE errors when clearing attachments form (#1484356)
- Set preferences field in user table to NULL (#1484386)
- Log error when login fails due to auto_create_user turned off
- Update UPGRADING instructions
2007/10/05 (tomekp)
----------
- Add Esperanto localization
2007/10/04 (Stiwi)
----------
- Updated German localization
2007/10/04 (yllar)
----------
- Added Malay localization
- Updated Lithuanian localization
2007/09/27 (tomekp)
----------
- Update dutch localization (closes #1484588)
2007/09/29 (thomasb)
----------
- Filter linked/imported CSS files (closes #1484056)
2007/09/27 (tomekp)
----------
- Update brazilian portuguese localization (#1484580)
2007/09/26 (thomasb)
----------
- Improve message compose screen (closes #1484383)
- Select next row after removing one from list (#1484387)
2007/09/26 (tomekp)
----------
- Add polish labels for changes in r816.
- Update polish localization (#1484579)
- Update thai localization (#1484578)
2007/09/25 (robin)
----------
- Enable drag-/dropping of folders to a new parent folder (#1457344)
2007/09/24 (robin)
----------
- Fix preview pane size for Safari & Konqueror (#1484187)
2007/09/20 (robin)
----------
- Make smtp HELO/EHLO hostname configurable (#1484067)
2007/09/19 (thomasb)
----------
- IPv6 Compatability (#1484322), Patch #1484373
- Unlock interface when message sending fails (#1484570)
- Eval PHP code in template includes (if configured)
- Show message when folder is empty. Mo more static text in table (#1484395)
- Only display unread count in page title when new messages arrived
- Show mailbox name in page title
2007/09/09 (thomasb)
----------
- Fixed wrong delete button tooltip (#1483965)
- Fixed charset encoding bug (#1484429)
- Applied patch for LDAP version (#1484552)
- Improved XHTML validation
2007/09/05 (thomasb)
----------
- Fix message list selection (#1484550)
- Better fix lowercased usernames (#1484473)
- Update pngbehavior Script as suggested in #1484490
2007/08/29 (richs)
----------
- Fixed moving/deleting messages when more than 1 is selected
2007/08/15 (thomasb)
----------
- Applied patch for LDAP contacts listing by Glen Ogilvie
- Applied patch for more address fields in LDAP contacts (#1484402)
- Close LDAP connections on script shutdown
2007/08/13 (thomasb)
----------
- Add alternative for getallheaders() (fix #1484508)
- Revert changes for mbstring usage (fix #1484509)
2007/08/10 (thomasb)
----------
- Identify mailboxes case-sensitive
- Sort mailbox list case-insensitive (closes #1484338)
- Fix display of multipart messages from Apple Mail (closes #1484027)
- Protect AJAX request from being fetched by a foreign site (XSS)
- Make autocomplete for loginform configurable by the skin template
- Fix compose function from address book (closes #1484426)
- Added //IGNORE to iconv call (patch #1484420, closes #1484023)
- Check if mbstring supports charset (#1484290 and #1484292)
- Prefer iconv over mbstring (as suggested in #1484292)
- Check filesize of template includes (#1484409)
- Updated Simplified Chinese localization
- Added Ukrainian translation
2007/08/09 (richs)
----------
- Fixed bug with buttons not dimming/enabling properly after switching folders
- Fixed compose window becoming unresponsive after saving a draft (#1484487)
- Re-enabled "Back" button in compose window now that bug #1484487 is fixed
- Fixed unresponsive interface issue when downloading attachments (#1484496)
- Lowered status message time from 5 to 3 seconds to improve responsiveness
- Added note to INSTALL about .htaccess limiting upload_max_filesize
- Raised .htaccess upload_max_filesize from 2M to 5M to differ from default php.ini
- Increased "mailboxcontrols" mail.css width from 160 to 170px to fix non-english languages (#1484499)
- Fixed empty-message sending with TinyMCE plain-text mode, or if it's not installed
2007/07/03 (thomasb)
----------
- Added Macedonian (Slavic FYROM) localization
- Fix status message bug #1484464 with regard to #1484353
- Fix address adding bug reported by David Koblas
- Applied socket error patch by Thomas Mangin
2007/06/28 (tomekp)
----------
- fix typos in Polish localization (Janusz Zamecki)
2007/06/27 (tomekp)
----------
- Update Polish (Janusz Zamecki), Croatian (Svebor Prstacic) localization
2007/06/12 (thomasb)
----------
- Updated Turkish, Polish, Finnish/Suomi, Japanese, Hungarian, Greek, Euskara localization
- Added Irish/Gaelic translation
- Little correction in Swedish translation
- Quote username for virtuser_query
- Pass-by-reference workarround for PHP5 in sendmail.inc
2007/06/04 (estadtherr)
----------
- Fixed bug in HTML->Plain editor toggling
2007/05/28 (thomasb)
---------
- Fixed buggy imap_root settings (closes #1484379)
- Prevent default events on subject links (#1484399)
- Typo in rcube_smtp.inc
2007/05/23 (estadtherr)
----------
- Upgrade to TinyMCE v2.1.1.1
2007/05/18 (thomasb)
----------
- Use HTTP-POST requests for actions that change state
2007/05/17 (thomasb)
----------
- Updated Catalan, Russian, Portuguese, Slovak and Chinese translations
- Renamed localization folder for Chinese (Big5)
- Chanegd Slovenian language code from 'si' to 'sl'
- Added Sinhala (Sri-Lanka) localization
- Use global filters and bind username/ for Ldap searches (#1484159)
- Hide quota display if imap server does not support it
- Hide address groups if no LDAP servers configured
- Add link to message subjects (closes #1484257)
- Better SQL query for contact listing/search (closes #1484369)
2007/05/13 (thomasb)
----------
- Updated Norwegian (bokmal), Czech, Danish and Portuguese (standard) translation
- Fixed marking as read in preview pane (closes #1484364)
- CSS hack to display attachments correctly in IE6
- Wrap message body text (closes #1484148)
2007/05/03 (yllar)
----------
- Updated French, Lithuanian, Armenian, Spanish and Italian translations
2007/05/01 (thomasb)
----------
- Updated German, Euskara, Hungarian, Romanian and Spanish translation
- Added Hindi and Kurdish localization
2007/04/28 (thomasb)
----------
- LDAP access is back in address book (closes #1484087)
- Added search function for contacts
- New Template parsing and output encoding
- Fixed bugs #1484119 and #1483978
2007/04/08 (thomasb)
----------
- Fixed message moving procedure (closes #1484308)
- Fixed display of multiple attachments (closes #1466563)
- Fixed check for new messages (closes #1484310)
- List attachments without filename
2007/03/27 (thomasb)
----------
- New session authentication: Change sessid cookie when login, authentication with sessauth cookie is now configurable.
Should close bugs #1483951 and #1484299
2007/03/23 (thomasb)
----------
- Correctly translate mailbox names (closes #1484276)
- Quote e-mail address links (closes #1484300)
2007/03/21 (thomasb)
----------
- Updated PEAR::Mail_mime package
- Added Persian localization
- Updated Catalan and Brazilian Portuguese translations
- Updated INSTALL manual with a note about database passwords
- Accept single quotes for HTML attributes when modifying message body (thanks Jason)
- Sanitize input for new users/identities (thanks Colin Alston)
2007/03/19 (thomasb)
----------
- Don't download HTML message parts
- Convert HTML parts to plaintext if 'prefer_html' is off
- Correctly parse message/rfc822 parts (closes #1484045)
- Code cleanup
2007/03/18 (thomasb)
----------
- Also use user_id for unique key in messages table (closes #1484074)
- Hide contacts drop down on blur (closes #1484203)
- Make entries in contacts drop down clickable
- Turn off browser autocompletion on login page
- Quote <? in text/html message parts
- Hide border around radio buttons
- Replaced old JS function calls.
2007/03/13 (thomasb)
----------
- Applied patch for attachment download by crichardson (closes #1484198)
- Fixed bug in Postgres DB handling (closes #1484068)
- Fixed bug of invalid calls to fetchRow() in rcube_db.inc (closes #1484280)
- Fixed array_merge bug (closes #1484281)
- Fixed flag for deletion in list view (closes #1484264)
- Finally support semicolons as recipient separator (closes ##1484251)
- Fixed message headers (subject) encoding
2007/03/04 (tomekp)
----------
- check if safe mode is on or not (closes #1484269)
2007/03/02 (thomasb)
----------
- Show "no subject" in message list if subject is missing (closes #1484243)
- Solved page caching of message preview (closes #1484153)
- Only use gzip compression if configured (closes #1484236)
2007/02/25 (estadtherr)
----------
- Fixed priority selector issue (#1484150)
- Upgraded to TinyMCE v2.1.0
2007/02/21 (thomasb)
----------
- Fixed some CSS issues in default skin (closes #1484210 and #1484161)
- Prevent from double quoting of numeric HTML character references (closes #1484253)
2007/02/07 (tomekp)
----------
- Updated (bg) translation (Doichin Dokov)
2007/02/06 (tomekp)
----------
- Updated (pl) translation
- Updated (pt_BR) translation (Robson F. Ramaldes)
- Big cleanup in program/localization
2007/02/05 (thomasb)
----------
- Updated Italian, Slovenian, Greek, Bulgarian, Hungarian and Croatian translation
2007/01/07 (estadtherr)
----------
- Fixed display of HTML message attachments (closes #1484178)
2007/01/07 (thomasb)
----------
- Applied patch for preview caching (closes #1484186)
- Added Thai and Vietnamese localization files
2006/12/29 (thomasb)
----------
- Added error handling for attachment uploads
- Use multibyte safe string functions where necessary (closes #1483988)
- Updated Swiss German localization (de_CH)
2006/12/22 (thomasb)
----------
- Applied security patch to validate the submitted host value (by Kees Cook)
- Applied security patch to validate input values when deleting contacts (by Kees Cook)
- Applied security patch that sanitizes emoticon paths when attaching them (by Kees Cook)
- Applied a patch to more aggressively sanitize a HTML message
- Visualize blocked images in HTML messages
2006/12/20 (thomasb)
----------
- Fixed wrong message listing when showing search results (closes #1484131)
- Introduced functions Q() and JQ() as aliases for rep_specialchars_output()
- Show remote images when opening HTML message part as attachment
2006/12/17 (thomasb)
----------
- Added patch by Ryan Rittenhouse & David Glick for a resizeable preview pane
2006/12/06 (thomasb)
----------
- Improve memory usage when sending mail (closes #1484098)
- Mark messages as read once the preview is loaded (closes #1484132)
- Include smtp final response in log (closes #1484081)
2006/12/04 (thomasb)
----------
- Corrected date string in sent message header (closes #1484125)
- Correclty choose "To" column in sent and draft mailboxes (closes #1483943)
- Changed srong tooltips for message browse buttons (closes #1483930)
2006/12/03 (estadtherr)
----------
- Added fix to convert HTML signatures for plain text messages
- Fixed signature delimeter character to be standard (Bug #1484035)
2006/12/01 (thomasb)
----------
- Implemented preview pane
- Fixed XSS vulnerability (Bug #1484109)
- Remove newlines from mail headers (Bug #1484031)
- Selection issues when moving/deleting (Bug #1484044)
- Applied patch of Clement Moulin for imap host auto-selection
- ISO-encode IMAP password for plaintext login (Bugs #1483977 & #1483886)
- Fixed folder name encoding in subscription list (Bug #1484113)
- Fixed JS errors in identity list (Bug #1484120)
- Show client debug console on debug_level 8
- Added Serbian translation
- Updated Spanish and Bulgarian localization
2006/11/22 (robin)
----------
- Fix a bug introduced with Shift-Del yesterday
2006/11/21 (robin)
----------
- Add missing nl_NL translations
- Translate foldernames in folder form (closes #1484113)
2006/11/21 (robin)
----------
- Added first and last buttons to message list, address book
and message detail
- Pressing Shift-Del bypasses Trash folder
- Enable purge command for Junk folder
2006/11/17 (robin)
----------
- Re-initialize message list after shift-select and delete
2006/11/16 (robin)
----------
- Fixed updating message list after expunge and purge
- Fetch all aliases if virtuser_query is used instead
of only the first one
2006/11/11 (estadtherr)
----------
- fixed deletion/moving of messages from within "show" page
2006/11/09 (thomasb)
----------
- Little bugfix in HTML encoding
- Fixed encoding issues and delete-on-reply problem
- Corrected template parsing
2006/11/07 (estadtherr)
----------
- Upgraded to TinyMCE v2.0.8
- Fixed CSS path for editor popups
2006/09/26 (estadtherr)
----------
- Added spellchecker plugin to TinyMCE configuration
- Fixed HTML/Plain toggle labels
2006/09/24 (thomasb)
----------
- Partial client re-write with a common list class
- Re-enabled multi select of contacts (Bug #1484017)
- Enable contact editing right after creation (Bug #1459641)
- Updated Hungarian, Estonian and Traditional Chinese localization
2006/09/19 (thomasb)
----------
- Correct UTF-7 to UTF-8 conversion if mbstring is not available
2006/09/13 (estadtherr)
----------
- Introduction of TinyMCE HTML editor support for message composition and signatures
Note : a new column is added to the "identities" database table
2006/09/12 (estadtherr)
----------
- Fixed html2text treatment of table headers (Bug #1484020)
- Fixed IMAP fetch of message body (Bug #1484019)
2006/09/08 (thomasb)
----------
- Fixed safe_mode problems (Bug #1418381)
- Fixed wrong header encoding (Bug #1483976)
2006/09/07 (thomasb)
----------
- Made automatic draft saving configurable
- Fixed JS bug when renaming folders (Bug #1483989)
- Don't wait for complete page load when calling JavaScript init()
- Some improvements to prevent session expiration
- Prevent from double submit of spell check requests
2006/09/01 (thomasb)
----------
- Imporoved message parsing and HTML validation
- Added quota display as image (by Brett Patterson)
- Corrected creation of a message-id
- Updated Norwegian (bokmal) localization
2006/08/30 (thomasb)
----------
- New indentation for quoted message text
- Improved HTML validity
2006/08/28 (estadtherr)
----------
- Fixed URL character set (Ticket #1445501)
- Fixed saving of contact into MySQL from LDAP query results (Ticket #1483820)
2006/08/25 (thomasb)
----------
- Fixed folder renaming: unsubscribe before rename (Bug #1483920)
- Finalized new message parsing (+ chaching)
- Updated SQL scripts and UPGRADING instructions
2006/08/23 (thomasb)
----------
- Updated Polish, Portuguese, Latvian, Chinese and Japanese localization
2006/08/20 (thomasb)
----------
- Fixed wrong usage of mbstring (Bug #1462439)
- Set default spelling language (Ticket #1483938)
- Added support for Nox Spell Server
2006/08/18 (thomasb)
----------
- Re-built message parsing (Bug #1327068)
Now based on the message structure delivered by the IMAP server.
- Fixed some XSS and SQL injection issues
2006/08/10 (thomasb)
----------
- Fixed charset problems with folder renaming
2006/08/04 (thomasb)
----------
- Fixed Bug in saving identities (Ticket #1483915)
- Set folder name in window title (Bug #1483919)
- Don't add imap_root to INBOX path (Bug #1483816)
- Attempt to create default folders only after login
- Avoid usage of $CONFIG in rcube_imap class
2006/07/30 (thomasb)
----------
- Alter links in HTML messages (Bug #1326402)
- Added fallback if host not found in 'mail_domain' array
- Applied patch of Charles to highlight droptargets (Ticket #1473034)
- Fixed folder renaming (Bug #1483914)
- Added confirmation message after deleting a folder
2006/07/25 (thomasb)
----------
- Made folder renaming a bit more ajax-style
- Changed rename-labels and German translation
- Fixed addressbox countbar width (Bug #1483845)
- Fixed refresh interval problems in Safari (Bug #1483902)
- Fixed clear_message_list_header() errors (Bug #1483898)
- Sanity check of $message_set in imap.inc (Bug #1443200)
- Added correct changing of message list headers for Sent folder
- Updated Spanish localization (Ticket #1483887)
- Applied patch #1483846
2006/07/24 (richs)
----------
- Draft window no longer reloads. It saves to an iframe in the background instead (fixes bug #1483869)
- Draft timer now part of program/js/app.js instead of skins/default/templates/compose.inc
- Draft saving now properly returns an error when saving fails
- Draft timer stops and resets properly when attachments are uploaded, or when saving manually
- Old compose session/attachments are now cleaned up when a new/forward/reply/draft is made/opened
2006/07/19 (thomasb)
----------
- Correct entity encoding of link urls (HTML validity)
- Improved usability in compose step (Ticket #1483807)
- Added absolute URLs to several buttons (for "open in new window")
- Applied patch #1328032
- Fixed Bug/Patch #1443200
2006/07/18 (thomasb)
----------
- Fixed password with spaces issue (Bug #1364122)
- Replaced _auth hash with second cookie (Ticket #1483811)
- Don't use get_input_value() for passwords (Bug #1468895)
- Made password encryption key configurable
- Minor bugfixes with charset encoding
- Added <label> tags to forms (Ticket #1483810)
2006/07/07 (thomasb)
----------
- Fixed INSTALL_PATH bug #1425663
2006/07/03 (richs)
----------
- Fixed compatibility with in-body email addresses containing "+" (Bug #1483836)
- Updated French localizations (Ticket #1483862)
- Incoming messages can now be moved to Drafts, edited, saved, then moved back (Feature #1436191)
- Added Firefox workaround when clicking whitespace to drag messages (Bug #1483857)
- Corrected Dutch and Italian localizations (Ticket #1483851 and #1483848)
- Enabled 'Empty' (purge) command for Junk mailbox (defined in main.inc.php)
2006/06/30 (richs)
----------
- Fixed empty INBOX compatibility bug (Patch #1443200)
- Temporarily fixed French "compact" localization (Patch #1483862)
- Fixed "Select All" not working with Delete interface button (Bug #1332434)
- Fixed messsage list column compatibility with Konqueror (Bug #1395711)
- Fixed "unread count" in window title when count changed (Bug #1483812)
- Fixed DB error when deleting from message table (Patch #1483835)
2006/06/29 (richs)
----------
- Added ability to remove attachments (Feature #1436721)
- Default folders are now auto-created on first login (Feature #1471594)
- Fixed compatibility with folder apostrophes (e.g.: Joe's Folder) (Bug #1429458)
- Corrected Italian localizations
- Tweaked rename-folder form to clear after a rename
2006/06/26 (richs)
----------
- Added button to immediately check for new messages
- New message checking now displays status "Checking for new messages..."
- New message checking now looks for unread messages in all mailboxes (Feature #1326401)
- Task buttons now respond to clicks by darkening (as in other applications)
- Fixed "Sender" column changing to "Recipient" for "Sent" and "Drafts" message lists
- Added ability to sort messages by "Size"
- Added ability to rename folders (Feature #1326396)
- Added 'protect_default_folders' option to main.inc.php to prevent renames/deletes/unsubscribes of default folders
- Corrected 5 typos of "INSTLL" to "INSTALL" in program/include/main.inc
2006/06/25
----------
- Changed behavior to include host-specific configuration (Bug #1483849)
- Assume ISO-8859-1 encoding of mail messages by default (Patch #1483839)
- Fixed spell checker to work with the new URL at google.com
- Some memory and security optimizations sendmail.inc
- Updated UGRADING description
2006/06/19
----------
- Added Drafts support (Feature #1326839) (richs)
2006/06/02
----------
- Updated Estonian localization and moved from ee to et
- Added Bulgarian localization
2006/05/25
----------
- Finalized GoogieSpell integration
2006/05/18
----------
- Added Arabic and Armenian localizations
- Updated Russian localization
- Removed MDB2 classes from repository. Install them seperately if used.
- Updated MDB2 wrapper class contributed by Lukas Kahwe Smith
- Allow & in e-mail addresses
2006/05/05
----------
- Fixed typos in function rcube_button() (Bugs #1473198 and #1473201)
- Check for zlib.output_compression before using ob_gzhandler (Bug #1471069)
- Casting date parts in iil_StrToTime() to avoid warnings (Bug #1482140)
- Corrected INSTALL description (Bug #1476106)
- Added charset to javascript HTTP headers
- Fixed Opera bug with CC and BCC fields (Bug #1474576)
- Changed login page title regarding product name (Bug #1476413)
- Pimped search function
- Applied attachment viewing/forwarding patches by Andrew Fladmark
- Applied prev/next patch by Leonard Bouchet
- Applied patches by Mark Bucciarelli
- Applied patch for requesting receipts by Salvatore Ansani
- Integrated GoogieSpell as suggested by phil (styling is not perfect yet, localization is missing)
2006/04/13
----------
- Added Slovenian localization
- Updated Portuguese localization
- Fixed parent.location problem for compose-links
- Added sort order saving patch by Jacob Brunson
- Added gzip compression support
2006/04/02
----------
- Added Lithuanian localization
- Improved search function
- Added version string as template object
- Load host-specific configuration file (see config/main.inc.php)
- New config parameter adding domain to user names for login
- Strip tags on _auth, _action, _task parameters
- Corrected labels for next/previous page buttons in address book
2006/03/23
----------
- Auto-detect mail header delimiters
- Regard daylight savings
- Localized quota display
- Started implementing search function
2006/03/20
----------
- Avoid error message when saving an unchanged identity (Bug #1429510)
- Fixed hard-coded cols selection for sent folder (Bug #1354586)
- Enable some HTML links for use with "open in new window" or "save target"
- Check meta-key instead of ctrl on Macs
- Ignore double clicks when holding down a modifier key
- Fixed reloading of the login page
- Fixed typo in compose template (Bug #1446852)
- Added compose button to message read step (Request #1433288)
- New config parameter for persistent database connections (Bug #1431817)
2006/03/14
----------
- Don't remove internal HTML tags in plaintext messages
- Improved error handling in DB connection failure
2006/02/22
----------
- Updated localizations
- Fixed bug #1435989
2006/02/19
----------
- Updated localizations
- Applied patch of Anders Karlsson
- Applied patch of Jacob Brunson
- Applied patch for virtuser_query by Robin Elfrink
- Added support for References header (patch by Auke)
- Added support for mbstring module by Tadashi Jokagi
- Added function for automatic remove of slashes on GET and POST vars
if magic_quotes is enabled
2006/02/05
----------
- Added Slovak, Hungarian, Bosnian and Croation translation
- Fixed bug when inserting signatures with !?&
- Chopping message headers before inserting into the message cache table
(to avoid bugs in Postgres)
- Allow one-char domains in e-mail addresses
- Make product name in page title configurable
- Make username available as skin object
- Added session_write_close() in rcube_db class destructor to avoid problems
in PHP 5.0.5
- Use move_uploaded_file() instead of copy() for a more secure handling of
uploaded attachments
- Additional config parameter to show/hide deleted messages
- Added periodic request for checking new mails (Request #1307821)
- Added EXPUNGE command
- Optimized loading time for mail interface
- Changed to full UTF-8 support
- Additional timezones (Patch #1389912)
- Added LDAP public search (experimental)
- Applied patch for correct ctrl/shift behavior for message selection (Bug #1326364)
- Casting to strings when adding empty headers to message cache (Bug #1406026)
- Skip sender-address as recipient when Reply-to-all
- Fixes in utf8-class
- Added patch for Quota display by Aury Fink Filho <nuny@aury.com.br>
- Added garbage collector for message cache
- Added patches for BCC headers
2005/12/16
----------
- Added Turkish and Simplified Chinese translation
- Use virtusertable to resolve e-mail addresses at login
- Configurable mail_domain used to compose correct e-mail addresses
on first login
2005/12/03
----------
- Added Finnish, Romanian, Polish, Czech, British, Norwegian, Greek, Russian,
Estonian and Chinese translation
- Get IMAP server capabilities in array
- Check for NAMESPACE capability before sending command
- Set default user language from config 'locale_string'
- Added sorting patch for message list
- Make default sort col/order configurable
- Fixed XSS in address book and identities
- Added more XSS protection (Bug #1308236)
- Added tab indexes for compose form
- Added 'changed' col to contacts table
- Support for 160-bit session hashes
- Added input check for contacts and identities (Patch #1346523)
- Added messages/warning to compose step (Patch #1323895)
- Added favicon to the default skin
- Fixed Bug #1334337 as far as possible
- Added Reply-To-All functionality (Request #1326395, Patch #1349777)
- Redesign of client side AJAX code (enable multi threading)
- Added keep-alive signal every minute
- Make logs dir configurable
- Added support for SMTPS
- Decode attachment file names
- Make delimiter for message headers configurable
- Add generic footer to sent messages
- Choose the rigt identity when replying
- Remove signature when replying (Request #1333167)
- Signatures for each identity
- Select charset when composing message
- Complete re-design of the caching mechanism
2005/08/11
----------
- Write list header to client even if list is empty
- Add functions "select all", "select none" to message list
- Improved filter for HTML messages to remove potentially malicious tags
(script, iframe, object) and event handlers.
- Buttons for next/previous message in view mode
- Add new created contact to list and show confirmation status
- Added folder management (subscribe/create/delete)
- Log message sending (SMTP log)
- Grant access for Camino browser
- Added German translation
2005/10/20
----------
- Added Swedish, Latvian, Portuguese and Catalan translation
- Make SMTP auth method configurable
- Make mailboxlist scrollable (Bug #1326372)
- Fixed SSL support
- Improved support for Courier IMAP (root folder and delimiter issues)
- Moved taskbar from bottom to top
- Added 'session_lifetime' parameter
- Fixed wrong unread count when deleting message (Bug #1332434)
- Srip tags when creating a new folder (Bug #1332084)
- Translate HTML tags in message headers (Bug #1330134)
- Correction in German translation (Bug #1329434)
- Display folder names with special chars correctly (Bug #1330157)
2005/10/07
----------
- Added French, Italian, Spanish, Danish, Dutch translation
- Clarified license (Bug #1305966)
- Fixed PHP warnings (Bug #1299403)
- Fixed english translation (Bug #1295406)
- Fixed bug #1290833: Last character of email not seen
- Fixed bug #1292199 when creating new user
- Allow more browsers (Bug #1285101)
- Added setting for showing pretty dates
- Added support for SQLite database
- Make use of message caching configurable
- Also add attachments when forwarding a message
- Long folder names will not flow over message list (Bug #1267232)
- Show nested mailboxes hieracically
- Enable IMAPS by host
2005/08/20
----------
- Improved cacheing of mailbox messagecount
- Fixed javascript bug when creating a new message folder
- Fixed javascript bugs #1260990 and #1260992: folder selection
- Make Trash folder configurable
- Auto create folders Inbox, Sent and Trash (if configured)
- Support for IMAP root folder
- Added support fot text/enriched messages
- Make list of special mailboxes configurable
diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist
index 2ac713f58..19785cba6 100644
--- a/config/main.inc.php.dist
+++ b/config/main.inc.php.dist
@@ -1,381 +1,387 @@
<?php
/*
+-----------------------------------------------------------------------+
| Main configuration file |
| |
| This file is part of the RoundCube Webmail client |
| Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
+-----------------------------------------------------------------------+
*/
$rcmail_config = array();
// system error reporting: 1 = log; 2 = report (not implemented yet), 4 = show, 8 = trace
$rcmail_config['debug_level'] = 1;
// log driver: 'syslog' or 'file'.
$rcmail_config['log_driver'] = 'file';
// Syslog ident string to use, if using the 'syslog' log driver.
$rcmail_config['syslog_id'] = 'roundcube';
// Syslog facility to use, if using the 'syslog' log driver.
// For possible values see installer or http://php.net/manual/en/function.openlog.php
$rcmail_config['syslog_facility'] = LOG_USER;
// use this folder to store log files (must be writeable for apache user)
// This is used by the 'file' log driver.
$rcmail_config['log_dir'] = 'logs/';
// use this folder to store temp files (must be writeable for apache user)
$rcmail_config['temp_dir'] = 'temp/';
// enable caching of messages and mailbox data in the local database.
// this is recommended if the IMAP server does not run on the same machine
$rcmail_config['enable_caching'] = TRUE;
// lifetime of message cache
// possible units: s, m, h, d, w
$rcmail_config['message_cache_lifetime'] = '10d';
// automatically create a new RoundCube user when log-in the first time.
// a new user will be created once the IMAP login succeeds.
// set to false if only registered users can use this service
$rcmail_config['auto_create_user'] = TRUE;
// the mail host chosen to perform the log-in
// leave blank to show a textbox at login, give a list of hosts
// to display a pulldown menu or set one host as string.
// To use SSL connection, enter ssl://hostname:993
$rcmail_config['default_host'] = '';
// TCP port used for IMAP connections
$rcmail_config['default_port'] = 143;
// IMAP auth type. Can be "auth" (CRAM-MD5), "plain" (PLAIN) or "check" to auto detect.
// Optional, defaults to "check"
$rcmail_config['imap_auth_type'] = null;
// Automatically add this domain to user names for login
// Only for IMAP servers that require full e-mail addresses for login
// Specify an array with 'host' => 'domain' values to support multiple hosts
$rcmail_config['username_domain'] = '';
// This domain will be used to form e-mail addresses of new users
// Specify an array with 'host' => 'domain' values to support multiple hosts
$rcmail_config['mail_domain'] = '';
// Path to a virtuser table file to resolve user names and e-mail addresses
$rcmail_config['virtuser_file'] = '';
// Query to resolve user names and e-mail addresses from the database
// %u will be replaced with the current username for login.
// The query should select the user's e-mail address as first col
$rcmail_config['virtuser_query'] = '';
// use this host for sending mails.
// to use SSL connection, set ssl://smtp.host.com
// if left blank, the PHP mail() function is used
$rcmail_config['smtp_server'] = '';
// SMTP port (default is 25; 465 for SSL)
$rcmail_config['smtp_port'] = 25;
// SMTP username (if required) if you use %u as the username RoundCube
// will use the current username for login
$rcmail_config['smtp_user'] = '';
// SMTP password (if required) if you use %p as the password RoundCube
// will use the current user's password for login
$rcmail_config['smtp_pass'] = '';
// SMTP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or empty to use
// best server supported one)
$rcmail_config['smtp_auth_type'] = '';
// SMTP HELO host
// Hostname to give to the remote server for SMTP 'HELO' or 'EHLO' messages
// Leave this blank and you will get the server variable 'server_name' or
// localhost if that isn't defined.
$rcmail_config['smtp_helo_host'] = '';
// Log sent messages
$rcmail_config['smtp_log'] = TRUE;
// how many seconds must pass between emails sent by a user
$rcmail_config['sendmail_delay'] = 0;
// these cols are shown in the message list
// available cols are: subject, from, to, cc, replyto, date, size, encoding, flag
$rcmail_config['list_cols'] = array('subject', 'from', 'date', 'size', 'flag');
// includes should be interpreted as PHP files
$rcmail_config['skin_include_php'] = FALSE;
// session lifetime in minutes
$rcmail_config['session_lifetime'] = 10;
// check client IP in session athorization
$rcmail_config['ip_check'] = false;
// Use an additional frequently changing cookie to athenticate user sessions.
// There have been problems reported with this feature.
$rcmail_config['double_auth'] = false;
// this key is used to encrypt the users imap password which is stored
// in the session record (and the client cookie if remember password is enabled).
// please provide a string of exactly 24 chars.
$rcmail_config['des_key'] = 'rcmail-!24ByteDESkey*Str';
// the default locale setting (leave empty for auto-detection)
// RFC1766 formatted language name like en_US, de_DE, de_CH, fr_FR, pt_BR
$rcmail_config['language'] = null;
// use this format for short date display
$rcmail_config['date_short'] = 'D H:i';
// use this format for detailed date/time formatting
$rcmail_config['date_long'] = 'd.m.Y H:i';
// use this format for today's date display
$rcmail_config['date_today'] = 'H:i';
// add this user-agent to message headers when sending
$rcmail_config['useragent'] = 'RoundCube Webmail/0.2-beta';
// use this name to compose page titles
$rcmail_config['product_name'] = 'RoundCube Webmail';
// only list folders within this path
$rcmail_config['imap_root'] = '';
// store draft message is this mailbox
// leave blank if draft messages should not be stored
$rcmail_config['drafts_mbox'] = 'Drafts';
// store spam messages in this mailbox
$rcmail_config['junk_mbox'] = 'Junk';
// store sent message is this mailbox
// leave blank if sent messages should not be stored
$rcmail_config['sent_mbox'] = 'Sent';
// move messages to this folder when deleting them
// leave blank if they should be deleted directly
$rcmail_config['trash_mbox'] = 'Trash';
// display these folders separately in the mailbox list.
// these folders will also be displayed with localized names
$rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash');
// automatically create the above listed default folders on login
$rcmail_config['create_default_folders'] = FALSE;
// protect the default folders from renames, deletes, and subscription changes
$rcmail_config['protect_default_folders'] = TRUE;
// if in your system 0 quota means no limit set this option to TRUE
$rcmail_config['quota_zero_as_unlimited'] = FALSE;
// Set TRUE if deleted messages should not be displayed
// This will make the application run slower
$rcmail_config['skip_deleted'] = FALSE;
// Set true to Mark deleted messages as read as well as deleted
// False means that a message's read status is not affected by marking it as deleted
$rcmail_config['read_when_deleted'] = TRUE;
// When a Trash folder is not present and a message is deleted, flag
// the message for deletion rather than deleting it immediately. Setting this to
// false causes deleted messages to be permanantly removed if there is no Trash folder
$rcmail_config['flag_for_deletion'] = FALSE;
// Behavior if a received message requests a message delivery notification (read receipt)
// 0 = ask the user, 1 = send automatically, 2 = ignore (never send or ask)
$rcmail_config['mdn_requests'] = 0;
// Use this charset as fallback for message decoding
$rcmail_config['default_charset'] = 'ISO-8859-1';
// Make use of the built-in spell checker. It is based on GoogieSpell.
// Since Google only accepts connections over https your PHP installatation
// requires to be compiled with Open SSL support
$rcmail_config['enable_spellcheck'] = TRUE;
// Set the spell checking engine. 'googie' is the default. 'pspell' is also available,
// but requires the Pspell extensions. When using Nox Spell Server, also set 'googie' here.
$rcmail_config['spellcheck_engine'] = 'googie';
// For a locally installed Nox Spell Server, please specify the URI to call it.
// Get Nox Spell Server from http://orangoo.com/labs/?page_id=72
// Leave empty to use the Google spell checking service, what means
// that the message content will be sent to Google in order to check spelling
$rcmail_config['spellcheck_uri'] = '';
// These languages can be selected for spell checking.
// Configure as a PHP style hash array: array('en'=>'English', 'de'=>'Deutsch');
// Leave empty for default set of Google spell check languages, should be defined
// when using local Pspell extension
$rcmail_config['spellcheck_languages'] = NULL;
// path to a text file which will be added to each sent message
// paths are relative to the RoundCube root folder
$rcmail_config['generic_message_footer'] = '';
// add a received header to outgoing mails containing the creators IP and hostname
$rcmail_config['http_received_header'] = false;
// this string is used as a delimiter for message headers when sending
// leave empty for auto-detection
$rcmail_config['mail_header_delimiter'] = NULL;
// session domain: .example.org
$rcmail_config['session_domain'] = '';
// This indicates which type of address book to use. Possible choises:
// 'sql' (default) and 'ldap'.
// If set to 'ldap' then it will look at using the first writable LDAP
// address book as the primary address book and it will not display the
// SQL address book in the 'Address Book' view.
$rcmail_config['address_book_type'] = 'sql';
// In order to enable public ldap search, configure an array like the Verisign
// example further below. if you would like to test, simply uncomment the example.
//
// If you are going to use LDAP for individual address books, you will need to
// set 'user_specific' to true and use the variables to generate the appropriate DNs to access it.
//
// The recommended directory structure for LDAP is to store all the address book entries
// under the users main entry, e.g.:
//
// o=root
// ou=people
// uid=user@domain
// mail=contact@contactdomain
//
// So the base_dn would be uid=%fu,ou=people,o=root
// The bind_dn would be the same as based_dn or some super user login.
/**
* example config for Verisign directory
*
* $rcmail_config['ldap_public']['Verisign'] = array(
* 'name' => 'Verisign.com',
* 'hosts' => array('directory.verisign.com'),
* 'port' => 389,
* 'use_tls' => false,
* 'user_specific' => false, // If true the base_dn, bind_dn and bind_pass default to the user's IMAP login.
* // %fu - The full username provided, assumes the username is an email
* // address, uses the username_domain value if not an email address.
* // %u - The username prior to the '@'.
* // %d - The domain name after the '@'.
* 'base_dn' => '',
* 'bind_dn' => '',
* 'bind_pass' => '',
* 'writable' => false, // Indicates if we can write to the LDAP directory or not.
* // If writable is true then these fields need to be populated:
* // LDAP_Object_Classes, required_fields, LDAP_rdn
* 'LDAP_Object_Classes' => array("top", "inetOrgPerson"), // To create a new contact these are the object classes to specify (or any other classes you wish to use).
* 'required_fields' => array("cn", "sn", "mail"), // The required fields needed to build a new contact as required by the object classes (can include additional fields not required by the object classes).
* 'LDAP_rdn' => 'mail', // The RDN field that is used for new entries, this field needs to be one of the search_fields, the base of base_dn is appended to the RDN to insert into the LDAP directory.
* 'ldap_version' => 3, // using LDAPv3
* 'search_fields' => array('mail', 'cn'), // fields to search in
* 'name_field' => 'cn', // this field represents the contact's name
* 'email_field' => 'mail', // this field represents the contact's e-mail
* 'surname_field' => 'sn', // this field represents the contact's last name
* 'firstname_field' => 'gn', // this field represents the contact's first name
* 'sort' => 'cn', // The field to sort the listing by.
* 'scope' => 'sub', // search mode: sub|base|list
* 'filter' => '', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act
* 'global_search' => true, // perform a global search for address auto-completion on compose
* 'fuzzy_search' => true); // server allows wildcard search
*/
// don't allow these settings to be overriden by the user
$rcmail_config['dont_override'] = array();
// allow users to add and delete sender identities
$rcmail_config['multiple_identities'] = true;
// try to load host-specific configuration
// see http://trac.roundcube.net/wiki/Howto_Config for more details
$rcmail_config['include_host_config'] = false;
// don't let users set pagesize to more than this value if set
$rcmail_config['max_pagesize'] = 200;
// mime magic database
$rcmail_config['mime_magic'] = '/usr/share/misc/magic';
// default sort col
$rcmail_config['message_sort_col'] = 'date';
// default sort order
$rcmail_config['message_sort_order'] = 'DESC';
// THIS OPTION WILL ALLOW THE INSTALLER TO RUN AND CAN EXPOSE SENSITIVE CONFIG DATA.
// ONLY ENABLE IT IF YOU'RE REALLY SURE WHAT YOU'RE DOING!
$rcmail_config['enable_installer'] = false;
// Log successful logins
$rcmail_config['log_logins'] = false;
/**
* 'Delete always'
* This setting reflects if mail should be always marked as deleted,
* even if moving to "Trash" fails. This is necessary in some setups
* because a) people may not have a Trash folder or b) they are over
* quota (and Trash is included in the quota).
*
* This is a failover setting for iil_C_Move when a message is moved
* to the Trash, and not the same as "delete_right_away".
*/
$rcmail_config['delete_always'] = false;
/***** these settings can be overwritten by user's preferences *****/
// skin name: folder from skins/
$rcmail_config['skin'] = 'default';
// show up to X items in list view
$rcmail_config['pagesize'] = 40;
// use this timezone to display date/time
$rcmail_config['timezone'] = 'auto';
// is daylight saving On?
$rcmail_config['dst_active'] = (bool)date('I');
// prefer displaying HTML messages
$rcmail_config['prefer_html'] = TRUE;
// display images in mail from known senders
$rcmail_config['addrbook_show_images'] = FALSE;
// compose html formatted messages by default
$rcmail_config['htmleditor'] = FALSE;
// show pretty dates as standard
$rcmail_config['prettydate'] = TRUE;
// save compose message every 300 seconds (5min)
$rcmail_config['draft_autosave'] = 300;
// default setting if preview pane is enabled
$rcmail_config['preview_pane'] = FALSE;
// Clear Trash on logout
$rcmail_config['logout_purge'] = FALSE;
// Compact INBOX on logout
$rcmail_config['logout_expunge'] = FALSE;
// Display attached images below the message body
$rcmail_config['inline_images'] = TRUE;
+// Encoding of long/non-ascii attachment names:
+// 0 - Full RFC 2231 compatible
+// 1 - RFC 2047 for 'name' and RFC 2231 for 'filename' parameter (Thunderbird's default)
+// 2 - Full 2047 compatible
+$rcmail_config['mime_param_folding'] = 0;
+
// end of config file
?>
diff --git a/installer/config.php b/installer/config.php
index d5e10e8b4..b0f56889d 100644
--- a/installer/config.php
+++ b/installer/config.php
@@ -1,552 +1,567 @@
<form action="index.php" method="post">
<input type="hidden" name="_step" value="2" />
<?php
// also load the default config to fill in the fields
$RCI->load_defaults();
// register these boolean fields
$RCI->config_props = array(
'ip_check' => 1,
'enable_caching' => 1,
'enable_spellcheck' => 1,
'auto_create_user' => 1,
'smtp_log' => 1,
'prefer_html' => 1,
'preview_pane' => 1,
'htmleditor' => 1,
'debug_level' => 1,
);
// allow the current user to get to the next step
$_SESSION['allowinstaller'] = true;
if (!empty($_POST['submit'])) {
echo '<p class="notice">Copy or download the following configurations and save them in two files';
echo ' (names above the text box) within the <tt>'.RCMAIL_CONFIG_DIR.'</tt> directory of your RoundCube installation.<br/>';
echo ' Make sure that there are no characters outside the <tt>&lt;?php ?&gt;</tt> brackets when saving the files.</p>';
$textbox = new html_textarea(array('rows' => 16, 'cols' => 60, 'class' => "configfile"));
echo '<div><em>main.inc.php (<a href="index.php?_getfile=main">download</a>)</em></div>';
echo $textbox->show(($_SESSION['main.inc.php'] = $RCI->create_config('main')));
echo '<div style="margin-top:1em"><em>db.inc.php (<a href="index.php?_getfile=db">download</a>)</em></div>';
echo $textbox->show($_SESSION['db.inc.php'] = $RCI->create_config('db'));
echo '<p class="hint">Of course there are more options to configure.
Have a look at the config files or visit <a href="http://trac.roundcube.net/wiki/Howto_Config">Howto_Config</a> to find out.</p>';
echo '<p><input type="button" onclick="location.href=\'./index.php?_step=3\'" value="CONTINUE" /></p>';
// echo '<style type="text/css"> .configblock { display:none } </style>';
echo "\n<hr style='margin-bottom:1.6em' />\n";
}
?>
<fieldset>
<legend>General configuration</legend>
<dl class="configblock">
<dt class="propname">product_name</dt>
<dd>
<?php
$input_prodname = new html_inputfield(array('name' => '_product_name', 'size' => 30, 'id' => "cfgprodname"));
echo $input_prodname->show($RCI->getprop('product_name'));
?>
<div>The name of your service (used to compose page titles)</div>
</dd>
<dt class="propname">temp_dir</dt>
<dd>
<?php
$input_tempdir = new html_inputfield(array('name' => '_temp_dir', 'size' => 30, 'id' => "cfgtempdir"));
echo $input_tempdir->show($RCI->getprop('temp_dir'));
?>
<div>Use this folder to store temp files (must be writeable for webserver)</div>
</dd>
<dt class="propname">ip_check</dt>
<dd>
<?php
$check_ipcheck = new html_checkbox(array('name' => '_ip_check', 'id' => "cfgipcheck"));
echo $check_ipcheck->show(intval($RCI->getprop('ip_check')), array('value' => 1));
?>
<label for="cfgipcheck">Check client IP in session authorization</label><br />
<p class="hint">This increases security but can cause sudden logouts when someone uses a proxy with changeing IPs.</p>
</dd>
<dt class="propname">des_key</dt>
<dd>
<?php
$input_deskey = new html_inputfield(array('name' => '_des_key', 'size' => 30, 'id' => "cfgdeskey"));
echo $input_deskey->show($RCI->getprop('des_key'));
?>
<div>This key is used to encrypt the users imap password before storing in the session record</div>
<p class="hint">It's a random generated string to ensure that every installation has it's own key.
If you enter it manually please provide a string of exactly 24 chars.</p>
</dd>
<dt class="propname">enable_caching</dt>
<dd>
<?php
$check_caching = new html_checkbox(array('name' => '_enable_caching', 'id' => "cfgcache"));
echo $check_caching->show(intval($RCI->getprop('enable_caching')), array('value' => 1));
?>
<label for="cfgcache">Cache messages in local database</label><br />
</dd>
<dt class="propname">enable_spellcheck</dt>
<dd>
<?php
$check_caching = new html_checkbox(array('name' => '_enable_spellcheck', 'id' => "cfgspellcheck"));
echo $check_caching->show(intval($RCI->getprop('enable_spellcheck')), array('value' => 1));
?>
<label for="cfgspellcheck">Make use of the built-in spell checker</label><br />
<p class="hint">It is based on GoogieSpell what implies that the message content will be sent to Google in order to check the spelling.</p>
</dd>
</dl>
</fieldset>
<fieldset>
<legend>Logging & Debugging</legend>
<dl class="loggingblock">
<dt class="propname">debug_level</dt>
<dd>
<?php
$value = $RCI->getprop('debug_level');
$check_debug = new html_checkbox(array('name' => '_debug_level[]'));
echo $check_debug->show(($value & 1) ? 1 : 0 , array('value' => 1, 'id' => 'cfgdebug1'));
echo '<label for="cfgdebug1">Log errors</label><br />';
echo $check_debug->show(($value & 4) ? 4 : 0, array('value' => 4, 'id' => 'cfgdebug4'));
echo '<label for="cfgdebug4">Print errors (to the browser)</label><br />';
echo $check_debug->show(($value & 8) ? 8 : 0, array('value' => 8, 'id' => 'cfgdebug8'));
echo '<label for="cfgdebug8">Verbose display (enables debug console)</label><br />';
?>
</dd>
<dt class="propname">log_driver</dt>
<dd>
<?php
$select_log_driver = new html_select(array('name' => '_log_driver', 'id' => "cfglogdriver"));
$select_log_driver->add(array('file', 'syslog'), array('file', 'syslog'));
echo $select_log_driver->show($RCI->getprop('log_driver', 'file'));
?>
<div>How to do logging? 'file' - write to files in the log directory, 'syslog' - use the syslog facility.</div>
</dd>
<dt class="propname">log_dir</dt>
<dd>
<?php
$input_logdir = new html_inputfield(array('name' => '_log_dir', 'size' => 30, 'id' => "cfglogdir"));
echo $input_logdir->show($RCI->getprop('log_dir'));
?>
<div>Use this folder to store log files (must be writeable for webserver). Note that this only applies if you are using the 'file' log_driver.</div>
</dd>
<dt class="propname">syslog_id</dt>
<dd>
<?php
$input_syslogid = new html_inputfield(array('name' => '_syslog_id', 'size' => 30, 'id' => "cfgsyslogid"));
echo $input_syslogid->show($RCI->getprop('syslog_id', 'roundcube'));
?>
<div>What ID to use when logging with syslog. Note that this only applies if you are using the 'syslog' log_driver.</div>
</dd>
<dt class="propname">syslog_facility</dt>
<dd>
<?php
$input_syslogfacility = new html_select(array('name' => '_syslog_facility', 'id' => "cfgsyslogfacility"));
$input_syslogfacility->add('user-level messages', LOG_USER);
$input_syslogfacility->add('mail subsystem', LOG_MAIL);
$input_syslogfacility->add('local level 0', LOG_LOCAL0);
$input_syslogfacility->add('local level 1', LOG_LOCAL1);
$input_syslogfacility->add('local level 2', LOG_LOCAL2);
$input_syslogfacility->add('local level 3', LOG_LOCAL3);
$input_syslogfacility->add('local level 4', LOG_LOCAL4);
$input_syslogfacility->add('local level 5', LOG_LOCAL5);
$input_syslogfacility->add('local level 6', LOG_LOCAL6);
$input_syslogfacility->add('local level 7', LOG_LOCAL7);
echo $input_syslogfacility->show($RCI->getprop('syslog_facility'), LOG_USER);
?>
<div>What ID to use when logging with syslog. Note that this only applies if you are using the 'syslog' log_driver.</div>
</dd>
</dl>
</fieldset>
<fieldset>
<legend>Database setup</legend>
<dl class="configblock" id="cgfblockdb">
<dt class="propname">db_dsnw</dt>
<dd>
<p>Database settings for read/write operations:</p>
<?php
require_once 'MDB2.php';
$supported_dbs = array('MySQL' => 'mysql', 'MySQLi' => 'mysqli',
'PgSQL' => 'pgsql', 'SQLite' => 'sqlite');
$select_dbtype = new html_select(array('name' => '_dbtype', 'id' => "cfgdbtype"));
foreach ($supported_dbs AS $database => $ext) {
if (extension_loaded($ext)) {
$select_dbtype->add($database, $ext);
}
}
$input_dbhost = new html_inputfield(array('name' => '_dbhost', 'size' => 20, 'id' => "cfgdbhost"));
$input_dbname = new html_inputfield(array('name' => '_dbname', 'size' => 20, 'id' => "cfgdbname"));
$input_dbuser = new html_inputfield(array('name' => '_dbuser', 'size' => 20, 'id' => "cfgdbuser"));
$input_dbpass = new html_passwordfield(array('name' => '_dbpass', 'size' => 20, 'id' => "cfgdbpass"));
$dsnw = MDB2::parseDSN($RCI->getprop('db_dsnw'));
echo $select_dbtype->show($RCI->is_post ? $_POST['_dbtype'] : $dsnw['phptype']);
echo '<label for="cfgdbtype">Database type</label><br />';
echo $input_dbhost->show($RCI->is_post ? $_POST['_dbhost'] : $dsnw['hostspec']);
echo '<label for="cfgdbhost">Database server</label><br />';
echo $input_dbname->show($RCI->is_post ? $_POST['_dbname'] : $dsnw['database']);
echo '<label for="cfgdbname">Database name</label><br />';
echo $input_dbuser->show($RCI->is_post ? $_POST['_dbuser'] : $dsnw['username']);
echo '<label for="cfgdbuser">Database user name (needs write permissions)</label><br />';
echo $input_dbpass->show($RCI->is_post ? $_POST['_dbpass'] : $dsnw['password']);
echo '<label for="cfgdbpass">Database password</label><br />';
?>
</dd>
</dl>
</fieldset>
<fieldset>
<legend>IMAP Settings</legend>
<dl class="configblock" id="cgfblockimap">
<dt class="propname">default_host</dt>
<dd>
<div>The IMAP host(s) chosen to perform the log-in</div>
<div id="defaulthostlist">
<?php
$text_imaphost = new html_inputfield(array('name' => '_default_host[]', 'size' => 30));
$default_hosts = $RCI->get_hostlist();
if (empty($default_hosts))
$default_hosts = array('');
$i = 0;
foreach ($default_hosts as $host) {
echo '<div id="defaulthostentry'.$i.'">' . $text_imaphost->show($host);
if ($i++ > 0)
echo '<a href="#" onclick="removehostfield(this.parentNode);return false" class="removelink" title="Remove this entry">remove</a>';
echo '</div>';
}
?>
</div>
<div><a href="javascript:addhostfield()" class="addlink" title="Add another field">add</a></div>
<p class="hint">Leave blank to show a textbox at login. To use SSL/IMAPS connection, type ssl://hostname</p>
</dd>
<dt class="propname">default_port</dt>
<dd>
<?php
$text_imapport = new html_inputfield(array('name' => '_default_port', 'size' => 6, 'id' => "cfgimapport"));
echo $text_imapport->show($RCI->getprop('default_port'));
?>
<div>TCP port used for IMAP connections</div>
</dd>
<dt class="propname">username_domain</dt>
<dd>
<?php
$text_userdomain = new html_inputfield(array('name' => '_username_domain', 'size' => 30, 'id' => "cfguserdomain"));
echo $text_userdomain->show($RCI->getprop('username_domain'));
?>
<div>Automatically add this domain to user names for login</div>
<p class="hint">Only for IMAP servers that require full e-mail addresses for login</p>
</dd>
<dt class="propname">auto_create_user</dt>
<dd>
<?php
$check_autocreate = new html_checkbox(array('name' => '_auto_create_user', 'id' => "cfgautocreate"));
echo $check_autocreate->show(intval($RCI->getprop('auto_create_user')), array('value' => 1));
?>
<label for="cfgautocreate">Automatically create a new RoundCube user when log-in the first time</label><br />
<p class="hint">A user is authenticated by the IMAP server but it requires a local record to store settings
and contacts. With this option enabled a new user record will automatically be created once the IMAP login succeeds.</p>
<p class="hint">If this option is disabled, the login only succeeds if there's a matching user-record in the local RoundCube database
what means that you have to create those records manually or disable this option after the first login.</p>
</dd>
<dt class="propname">sent_mbox</dt>
<dd>
<?php
$text_sentmbox = new html_inputfield(array('name' => '_sent_mbox', 'size' => 20, 'id' => "cfgsentmbox"));
echo $text_sentmbox->show($RCI->getprop('sent_mbox'));
?>
<div>Store sent messages is this folder</div>
<p class="hint">Leave blank if sent messages should not be stored</p>
</dd>
<dt class="propname">trash_mbox</dt>
<dd>
<?php
$text_trashmbox = new html_inputfield(array('name' => '_trash_mbox', 'size' => 20, 'id' => "cfgtrashmbox"));
echo $text_trashmbox->show($RCI->getprop('trash_mbox'));
?>
<div>Move messages to this folder when deleting them</div>
<p class="hint">Leave blank if they should be deleted directly</p>
</dd>
<dt class="propname">drafts_mbox</dt>
<dd>
<?php
$text_draftsmbox = new html_inputfield(array('name' => '_drafts_mbox', 'size' => 20, 'id' => "cfgdraftsmbox"));
echo $text_draftsmbox->show($RCI->getprop('drafts_mbox'));
?>
<div>Store draft messages is this folder</div>
</dd>
</dl>
</fieldset>
<fieldset>
<legend>SMTP Settings</legend>
<dl class="configblock" id="cgfblocksmtp">
<dt class="propname">smtp_server</dt>
<dd>
<?php
$text_smtphost = new html_inputfield(array('name' => '_smtp_server', 'size' => 30, 'id' => "cfgsmtphost"));
echo $text_smtphost->show($RCI->getprop('smtp_server'));
?>
<div>Use this host for sending mails</div>
<p class="hint">To use SSL connection, set ssl://smtp.host.com. If left blank, the PHP mail() function is used</p>
</dd>
<dt class="propname">smtp_port</dt>
<dd>
<?php
$text_smtpport = new html_inputfield(array('name' => '_smtp_port', 'size' => 6, 'id' => "cfgsmtpport"));
echo $text_smtpport->show($RCI->getprop('smtp_port'));
?>
<div>SMTP port (default is 25; 465 for SSL)</div>
</dd>
<dt class="propname">smtp_user/smtp_pass</dt>
<dd>
<?php
$text_smtpuser = new html_inputfield(array('name' => '_smtp_user', 'size' => 20, 'id' => "cfgsmtpuser"));
$text_smtppass = new html_passwordfield(array('name' => '_smtp_pass', 'size' => 20, 'id' => "cfgsmtppass"));
echo $text_smtpuser->show($RCI->getprop('smtp_user'));
echo $text_smtppass->show($RCI->getprop('smtp_pass'));
?>
<div>SMTP username and password (if required)</div>
<p>
<?php
$check_smtpuser = new html_checkbox(array('name' => '_smtp_user_u', 'id' => "cfgsmtpuseru"));
echo $check_smtpuser->show($RCI->getprop('smtp_user') == '%u' || $_POST['_smtp_user_u'] ? 1 : 0, array('value' => 1));
?>
<label for="cfgsmtpuseru">Use the current IMAP username and password for SMTP authentication</label>
</p>
</dd>
<!--
<dt class="propname">smtp_auth_type</dt>
<dd>
<?php
/*
$select_smtpauth = new html_select(array('name' => '_smtp_auth_type', 'id' => "cfgsmtpauth"));
$select_smtpauth->add(array('(auto)', 'PLAIN', 'DIGEST-MD5', 'CRAM-MD5', 'LOGIN'), array('0', 'PLAIN', 'DIGEST-MD5', 'CRAM-MD5', 'LOGIN'));
echo $select_smtpauth->show(intval($RCI->getprop('smtp_auth_type')));
*/
?>
<div>Method to authenticate at the SMTP server. Choose (auto) if you don't know what this is</div>
</dd>
-->
<dt class="propname">smtp_log</dt>
<dd>
<?php
$check_smtplog = new html_checkbox(array('name' => '_smtp_log', 'id' => "cfgsmtplog"));
echo $check_smtplog->show(intval($RCI->getprop('smtp_log')), array('value' => 1));
?>
<label for="cfgsmtplog">Log sent messages in <tt>{log_dir}/sendmail</tt> or to syslog.</label><br />
</dd>
</dl>
</fieldset>
<fieldset>
<legend>Display settings &amp; user prefs</legend>
<dl class="configblock" id="cgfblockdisplay">
<dt class="propname">language</dt>
<dd>
<?php
$input_locale = new html_inputfield(array('name' => '_language', 'size' => 6, 'id' => "cfglocale"));
echo $input_locale->show($RCI->getprop('language'));
?>
<div>The default locale setting. This also defines the language of the login screen.<br/>Leave it empty to auto-detect the user agent language.</div>
<p class="hint">Enter a <a href="http://www.faqs.org/rfcs/rfc1766">RFC1766</a> formatted language name. Examples: en_US, de_DE, de_CH, fr_FR, pt_BR</p>
</dd>
<dt class="propname">skin <span class="userconf">*</span></dt>
<dd>
<?php
$input_skin = new html_inputfield(array('name' => '_skin', 'size' => 30, 'id' => "cfgskin"));
echo $input_skin->show($RCI->getprop('skin'));
?>
<div>Name of interface skin (folder in /skins)</div>
</dd>
<dt class="propname">pagesize <span class="userconf">*</span></dt>
<dd>
<?php
$input_pagesize = new html_inputfield(array('name' => '_pagesize', 'size' => 6, 'id' => "cfgpagesize"));
echo $input_pagesize->show($RCI->getprop('pagesize'));
?>
<div>Show up to X items in list view.</div>
</dd>
<dt class="propname">prefer_html <span class="userconf">*</span></dt>
<dd>
<?php
$check_htmlview = new html_checkbox(array('name' => '_prefer_html', 'id' => "cfghtmlview", 'value' => 1));
echo $check_htmlview->show(intval($RCI->getprop('prefer_html')));
?>
<label for="cfghtmlview">Prefer displaying HTML messages</label><br />
</dd>
<dt class="propname">preview_pane <span class="userconf">*</span></dt>
<dd>
<?php
$check_prevpane = new html_checkbox(array('name' => '_preview_pane', 'id' => "cfgprevpane", 'value' => 1));
echo $check_prevpane->show(intval($RCI->getprop('preview_pane')));
?>
<label for="cfgprevpane">If preview pane is enabled</label><br />
</dd>
<dt class="propname">htmleditor <span class="userconf">*</span></dt>
<dd>
<?php
$check_htmlcomp = new html_checkbox(array('name' => '_htmleditor', 'id' => "cfghtmlcompose", 'value' => 1));
echo $check_htmlcomp->show(intval($RCI->getprop('htmleditor')));
?>
<label for="cfghtmlcompose">Compose HTML formatted messages</label><br />
</dd>
<dt class="propname">draft_autosave <span class="userconf">*</span></dt>
<dd>
<label for="cfgautosave">Save compose message every</label>
<?php
$select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => 'cfgautosave'));
$select_autosave->add('never', 0);
foreach (array(3, 5, 10) as $i => $min)
$select_autosave->add("$min min", $min*60);
echo $select_autosave->show(intval($RCI->getprop('draft_autosave')));
?>
</dd>
<dt class="propname">mdn_requests <span class="userconf">*</span></dt>
<dd>
<?php
$select_mdnreq = new html_select(array('name' => '_mdn_requests', 'id' => "cfgmdnreq"));
$select_mdnreq->add(array('ask the user', 'send automatically', 'ignore'), array(0, 1, 2));
echo $select_mdnreq->show(intval($RCI->getprop('mdn_requests')));
?>
<div>Behavior if a received message requests a message delivery notification (read receipt)</div>
</dd>
+<dt class="propname">mime_param_folding <span class="userconf">*</span></dt>
+<dd>
+<?php
+
+$select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => "cfgmimeparamfolding"));
+$select_param_folding->add('Full RFC 2231 (Roundcube, Thunderbird)', '0');
+$select_param_folding->add('RFC 2047/2231 (MS Outlook, OE)', '1');
+$select_param_folding->add('Full RFC 2047 (deprecated)', '2');
+
+echo $select_param_folding->show(intval($RCI->getprop('mime_param_folding')));
+
+?>
+<div>How to encode attachment long/non-ascii names</div>
+</dd>
+
</dl>
<p class="hint"><span class="userconf">*</span>&nbsp; These settings are defaults for the user preferences</p>
</fieldset>
<?php
echo '<p><input type="submit" name="submit" value="' . ($RCI->configured ? 'UPDATE' : 'CREATE') . ' CONFIG" ' . ($RCI->failures ? 'disabled' : '') . ' /></p>';
?>
</form>
diff --git a/program/include/html.php b/program/include/html.php
index 2d0d90b5f..9268acacc 100644
--- a/program/include/html.php
+++ b/program/include/html.php
@@ -1,662 +1,674 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/include/html.php |
| |
| This file is part of the RoundCube Webmail client |
| Copyright (C) 2005-2008, RoundCube Dev, - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
| Helper class to create valid XHTML code |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id: $
*/
/**
* Class for HTML code creation
*
* @package HTML
*/
class html
{
protected $tagname;
protected $attrib = array();
protected $allowed = array();
protected $content;
public static $common_attrib = array('id','class','style','title','align');
public static $containers = array('iframe','div','span','p','h1','h2','h3','form','textarea','table','tr','th','td','style');
public static $lc_tags = true;
/**
* Constructor
*
* @param array Hash array with tag attributes
*/
public function __construct($attrib = array())
{
if (is_array($attrib)) {
$this->attrib = $attrib;
}
}
/**
* Return the tag code
*
* @return string The finally composed HTML tag
*/
public function show()
{
return self::tag($this->tagname, $this->attrib, $this->content, array_merge(self::$common_attrib, $this->allowed));
}
/****** STATIC METHODS *******/
/**
* Generic method to create a HTML tag
*
* @param string Tag name
* @param array Tag attributes as key/value pairs
* @param string Optinal Tag content (creates a container tag)
* @param array List with allowed attributes, omit to allow all
* @return string The XHTML tag
*/
public static function tag($tagname, $attrib = array(), $content = null, $allowed_attrib = null)
{
$inline_tags = array('a','span','img');
$suffix = $attrib['nl'] || ($content && $attrib['nl'] !== false && !in_array($tagname, $inline_tags)) ? "\n" : '';
$tagname = self::$lc_tags ? strtolower($tagname) : $tagname;
if ($content || in_array($tagname, self::$containers)) {
$templ = $attrib['noclose'] ? "<%s%s>%s" : "<%s%s>%s</%s>%s";
unset($attrib['noclose']);
return sprintf($templ, $tagname, self::attrib_string($attrib, $allowed_attrib), $content, $tagname, $suffix);
}
else {
return sprintf("<%s%s />%s", $tagname, self::attrib_string($attrib, $allowed_attrib), $suffix);
}
}
/**
* Derrived method for <div> containers
*
* @param mixed Hash array with tag attributes or string with class name
* @param string Div content
* @return string HTML code
* @see html::tag()
*/
public static function div($attr = null, $cont = null)
{
if (is_string($attr)) {
$attr = array('class' => $attr);
}
return self::tag('div', $attr, $cont, array_merge(self::$common_attrib, array('onclick')));
}
/**
* Derrived method for <p> blocks
*
* @param mixed Hash array with tag attributes or string with class name
* @param string Paragraph content
* @return string HTML code
* @see html::tag()
*/
public static function p($attr = null, $cont = null)
{
if (is_string($attr)) {
$attr = array('class' => $attr);
}
return self::tag('p', $attr, $cont, self::$common_attrib);
}
/**
* Derrived method to create <img />
*
* @param mixed Hash array with tag attributes or string with image source (src)
* @return string HTML code
* @see html::tag()
*/
public static function img($attr = null)
{
if (is_string($attr)) {
$attr = array('src' => $attr);
}
return self::tag('img', $attr + array('alt' => ''), null, array_merge(self::$common_attrib, array('src','alt','width','height','border','usemap')));
}
/**
* Derrived method for link tags
*
* @param mixed Hash array with tag attributes or string with link location (href)
* @param string Link content
* @return string HTML code
* @see html::tag()
*/
public static function a($attr, $cont)
{
if (is_string($attr)) {
$attr = array('href' => $attr);
}
return self::tag('a', $attr, $cont, array_merge(self::$common_attrib, array('href','target','name','onclick','onmouseover','onmouseout','onmousedown','onmouseup')));
}
/**
* Derrived method for inline span tags
*
* @param mixed Hash array with tag attributes or string with class name
* @param string Tag content
* @return string HTML code
* @see html::tag()
*/
public static function span($attr, $cont)
{
if (is_string($attr)) {
$attr = array('class' => $attr);
}
return self::tag('span', $attr, $cont, self::$common_attrib);
}
/**
* Derrived method for form element labels
*
* @param mixed Hash array with tag attributes or string with 'for' attrib
* @param string Tag content
* @return string HTML code
* @see html::tag()
*/
public static function label($attr, $cont)
{
if (is_string($attr)) {
$attr = array('for' => $attr);
}
return self::tag('label', $attr, $cont, array_merge(self::$common_attrib, array('for')));
}
/**
* Derrived method to create <iframe></iframe>
*
* @param mixed Hash array with tag attributes or string with frame source (src)
* @return string HTML code
* @see html::tag()
*/
public static function iframe($attr = null, $cont = null)
{
if (is_string($attr)) {
$attr = array('src' => $attr);
}
return self::tag('iframe', $attr, $cont, array_merge(self::$common_attrib, array('src','name','width','height','border','frameborder')));
}
/**
* Derrived method for line breaks
*
* @return string HTML code
* @see html::tag()
*/
public static function br()
{
return self::tag('br');
}
/**
* Create string with attributes
*
* @param array Associative arry with tag attributes
* @param array List of allowed attributes
* @return string Valid attribute string
*/
public static function attrib_string($attrib = array(), $allowed = null)
{
if (empty($attrib)) {
return '';
}
$allowed_f = array_flip((array)$allowed);
$attrib_arr = array();
foreach ($attrib as $key => $value) {
// skip size if not numeric
if (($key=='size' && !is_numeric($value))) {
continue;
}
// ignore "internal" or not allowed attributes
if ($key == 'nl' || ($allowed && !isset($allowed_f[$key])) || $value === null) {
continue;
}
// skip empty eventhandlers
if (preg_match('/^on[a-z]+/', $key) && !$value) {
continue;
}
// attributes with no value
if (in_array($key, array('checked', 'multiple', 'disabled', 'selected'))) {
if ($value) {
$attrib_arr[] = sprintf('%s="%s"', $key, $key);
}
}
else if ($key=='value') {
$attrib_arr[] = sprintf('%s="%s"', $key, Q($value, 'strict', false));
}
else {
$attrib_arr[] = sprintf('%s="%s"', $key, Q($value));
}
}
return count($attrib_arr) ? ' '.implode(' ', $attrib_arr) : '';
}
}
/**
* Class to create an HTML input field
*
* @package HTML
*/
class html_inputfield extends html
{
protected $tagname = 'input';
protected $type = 'text';
protected $allowed = array('type','name','value','size','tabindex','autocomplete','checked','onchange','onclick','disabled','readonly','spellcheck','results');
public function __construct($attrib = array())
{
if (is_array($attrib)) {
$this->attrib = $attrib;
}
if ($attrib['type']) {
$this->type = $attrib['type'];
}
if ($attrib['newline']) {
$this->newline = true;
}
}
/**
* Compose input tag
*
* @param string Field value
* @param array Additional attributes to override
* @return string HTML output
*/
public function show($value = null, $attrib = null)
{
// overwrite object attributes
if (is_array($attrib)) {
$this->attrib = array_merge($this->attrib, $attrib);
}
// set value attribute
if ($value !== null) {
$this->attrib['value'] = $value;
}
// set type
$this->attrib['type'] = $this->type;
return parent::show();
}
}
/**
* Class to create an HTML password field
*
* @package HTML
*/
class html_passwordfield extends html_inputfield
{
protected $type = 'password';
}
/**
* Class to create an hidden HTML input field
*
* @package HTML
*/
class html_hiddenfield extends html_inputfield
{
protected $type = 'hidden';
protected $fields_arr = array();
protected $newline = true;
/**
* Constructor
*
* @param array Named tag attributes
*/
public function __construct($attrib = null)
{
if (is_array($attrib)) {
$this->add($attrib);
}
}
/**
* Add a hidden field to this instance
*
* @param array Named tag attributes
*/
public function add($attrib)
{
$this->fields_arr[] = $attrib;
}
/**
* Create HTML code for the hidden fields
*
* @return string Final HTML code
*/
public function show()
{
$out = '';
foreach ($this->fields_arr as $attrib) {
$out .= self::tag($this->tagname, array('type' => $this->type) + $attrib);
}
return $out;
}
}
/**
* Class to create HTML radio buttons
*
* @package HTML
*/
class html_radiobutton extends html_inputfield
{
protected $type = 'radio';
/**
* Get HTML code for this object
*
* @param string Value of the checked field
* @param array Additional attributes to override
* @return string HTML output
*/
public function show($value = '', $attrib = null)
{
// overwrite object attributes
if (is_array($attrib)) {
$this->attrib = array_merge($this->attrib, $attrib);
}
// set value attribute
$this->attrib['checked'] = ((string)$value == (string)$this->attrib['value']);
return parent::show();
}
}
/**
* Class to create HTML checkboxes
*
* @package HTML
*/
class html_checkbox extends html_inputfield
{
protected $type = 'checkbox';
/**
* Get HTML code for this object
*
* @param string Value of the checked field
* @param array Additional attributes to override
* @return string HTML output
*/
public function show($value = '', $attrib = null)
{
// overwrite object attributes
if (is_array($attrib)) {
$this->attrib = array_merge($this->attrib, $attrib);
}
// set value attribute
$this->attrib['checked'] = ((string)$value == (string)$this->attrib['value']);
return parent::show();
}
}
/**
* Class to create an HTML textarea
*
* @package HTML
*/
class html_textarea extends html
{
protected $tagname = 'textarea';
protected $allowed = array('name','rows','cols','wrap','tabindex','onchange','disabled','readonly','spellcheck');
/**
* Get HTML code for this object
*
* @param string Textbox value
* @param array Additional attributes to override
* @return string HTML output
*/
public function show($value = '', $attrib = null)
{
// overwrite object attributes
if (is_array($attrib)) {
$this->attrib = array_merge($this->attrib, $attrib);
}
// take value attribute as content
if (empty($value) && !empty($this->attrib['value'])) {
$value = $this->attrib['value'];
}
// make shure we don't print the value attribute
if (isset($this->attrib['value'])) {
unset($this->attrib['value']);
}
if (!empty($value) && !ereg('mce_editor', $this->attrib['class'])) {
$value = Q($value, 'strict', false);
}
return self::tag($this->tagname, $this->attrib, $value, array_merge(self::$common_attrib, $this->allowed));
}
}
/**
* Builder for HTML drop-down menus
* Syntax:<pre>
* // create instance. arguments are used to set attributes of select-tag
* $select = new html_select(array('name' => 'fieldname'));
*
* // add one option
* $select->add('Switzerland', 'CH');
*
* // add multiple options
* $select->add(array('Switzerland','Germany'), array('CH','DE'));
*
* // generate pulldown with selection 'Switzerland' and return html-code
* // as second argument the same attributes available to instanciate can be used
* print $select->show('CH');
* </pre>
*
* @package HTML
*/
class html_select extends html
{
protected $tagname = 'select';
protected $options = array();
protected $allowed = array('name','size','tabindex','autocomplete','multiple','onchange','disabled');
/**
* Add a new option to this drop-down
*
* @param mixed Option name or array with option names
* @param mixed Option value or array with option values
*/
public function add($names, $values = null)
{
if (is_array($names)) {
foreach ($names as $i => $text) {
$this->options[] = array('text' => $text, 'value' => $values[$i]);
}
}
else {
$this->options[] = array('text' => $names, 'value' => $values);
}
}
/**
* Get HTML code for this object
*
* @param string Value of the selection option
* @param array Additional attributes to override
* @return string HTML output
*/
public function show($select = array(), $attrib = null)
{
// overwrite object attributes
if (is_array($attrib)) {
$this->attrib = array_merge($this->attrib, $attrib);
}
$this->content = "\n";
$select = (array)$select;
foreach ($this->options as $option) {
$attr = array(
'value' => $option['value'],
'selected' => (in_array($option['value'], $select, true) ||
in_array($option['text'], $select, true)) ? 1 : null);
$this->content .= self::tag('option', $attr, Q($option['text']));
}
return parent::show();
}
}
/**
* Class to build an HTML table
*
* @package HTML
*/
class html_table extends html
{
protected $tagname = 'table';
protected $allowed = array('id','class','style','width','summary','cellpadding','cellspacing','border');
private $header = array();
private $rows = array();
private $rowindex = 0;
private $colindex = 0;
public function __construct($attrib = array())
{
$this->attrib = array_merge($attrib, array('summary' => '', 'border' => 0));
}
/**
* Add a table cell
*
* @param array Cell attributes
* @param string Cell content
*/
public function add($attr, $cont)
{
if (is_string($attr)) {
$attr = array('class' => $attr);
}
$cell = new stdClass;
$cell->attrib = $attr;
$cell->content = $cont;
$this->rows[$this->rowindex]->cells[$this->colindex] = $cell;
$this->colindex++;
if ($this->attrib['cols'] && $this->colindex == $this->attrib['cols']) {
$this->add_row();
}
}
/**
* Add a table header cell
*
* @param array Cell attributes
* @param string Cell content
*/
public function add_header($attr, $cont)
{
if (is_string($attr))
- $attr = array('class' => $attr);
+ $attr = array('class' => $attr);
$cell = new stdClass;
$cell->attrib = $attr;
$cell->content = $cont;
$this->header[] = $cell;
}
/**
* Jump to next row
*
* @param array Row attributes
*/
public function add_row($attr = array())
{
$this->rowindex++;
$this->colindex = 0;
$this->rows[$this->rowindex] = new stdClass;
$this->rows[$this->rowindex]->attrib = $attr;
$this->rows[$this->rowindex]->cells = array();
}
+ /**
+ * Set current row attrib
+ *
+ * @param array Row attributes
+ */
+ public function set_row_attribs($attr = array())
+ {
+ if (is_string($attr))
+ $attr = array('class' => $attr);
+
+ $this->rows[$this->rowindex]->attrib = $attr;
+ }
/**
* Build HTML output of the table data
*
* @param array Table attributes
* @return string The final table HTML code
*/
public function show($attrib = null)
{
if (is_array($attrib))
$this->attrib = array_merge($this->attrib, $attrib);
$thead = $tbody = "";
// include <thead>
if (!empty($this->header)) {
$rowcontent = '';
foreach ($this->header as $c => $col) {
$rowcontent .= self::tag('td', $col->attrib, $col->content);
}
$thead = self::tag('thead', null, self::tag('tr', null, $rowcontent));
}
foreach ($this->rows as $r => $row) {
$rowcontent = '';
foreach ($row->cells as $c => $col) {
$rowcontent .= self::tag('td', $col->attrib, $col->content);
}
if ($r < $this->rowindex || count($row->cells)) {
$tbody .= self::tag('tr', $row->attrib, $rowcontent);
}
}
if ($this->attrib['rowsonly']) {
return $tbody;
}
// add <tbody>
$this->content = $thead . self::tag('tbody', null, $tbody);
unset($this->attrib['cols'], $this->attrib['rowsonly']);
return parent::show();
}
}
?>
diff --git a/program/lib/Mail/mime.php b/program/lib/Mail/mime.php
index 7641b0c9b..688c326a5 100644
--- a/program/lib/Mail/mime.php
+++ b/program/lib/Mail/mime.php
@@ -1,1134 +1,1151 @@
<?php
/**
* The Mail_Mime class is used to create MIME E-mail messages
*
* The Mail_Mime class provides an OO interface to create MIME
* enabled email messages. This way you can create emails that
* contain plain-text bodies, HTML bodies, attachments, inline
* images and specific headers.
*
* Compatible with PHP versions 4 and 5
*
* LICENSE: This LICENSE is in the BSD license style.
* Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org>
* Copyright (c) 2003-2006, PEAR <pear-group@php.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of the authors, nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* @category Mail
* @package Mail_Mime
* @author Richard Heyes <richard@phpguru.org>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Cipriano Groenendal <cipri@php.net>
* @author Sean Coates <sean@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version CVS: $Id$
* @link http://pear.php.net/package/Mail_mime
*
* This class is based on HTML Mime Mail class from
* Richard Heyes <richard@phpguru.org> which was based also
* in the mime_mail.class by Tobias Ratschiller <tobias@dnet.it>
* and Sascha Schumann <sascha@schumann.cx>
*/
/**
* require PEAR
*
* This package depends on PEAR to raise errors.
*/
require_once 'PEAR.php';
/**
* require Mail_mimePart
*
* Mail_mimePart contains the code required to
* create all the different parts a mail can
* consist of.
*/
require_once 'Mail/mimePart.php';
/**
* The Mail_Mime class provides an OO interface to create MIME
* enabled email messages. This way you can create emails that
* contain plain-text bodies, HTML bodies, attachments, inline
* images and specific headers.
*
* @category Mail
* @package Mail_Mime
* @author Richard Heyes <richard@phpguru.org>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Cipriano Groenendal <cipri@php.net>
* @author Sean Coates <sean@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version Release: @package_version@
* @link http://pear.php.net/package/Mail_mime
*/
class Mail_mime
{
/**
* Contains the plain text part of the email
*
* @var string
* @access private
*/
var $_txtbody;
/**
* Contains the html part of the email
*
* @var string
* @access private
*/
var $_htmlbody;
/**
* contains the mime encoded text
*
* @var string
* @access private
*/
var $_mime;
/**
* contains the multipart content
*
* @var string
* @access private
*/
var $_multipart;
/**
* list of the attached images
*
* @var array
* @access private
*/
var $_html_images = array();
/**
* list of the attachements
*
* @var array
* @access private
*/
var $_parts = array();
/**
* Build parameters
*
* @var array
* @access private
*/
var $_build_params = array();
/**
* Headers for the mail
*
* @var array
* @access private
*/
var $_headers = array();
/**
* End Of Line sequence (for serialize)
*
* @var string
* @access private
*/
var $_eol;
/**
* Constructor function.
*
* @param string $crlf what type of linebreak to use.
* Defaults to "\r\n"
*
* @return void
*
* @access public
*/
function Mail_mime($crlf = "\r\n")
{
$this->_setEOL($crlf);
$this->_build_params = array(
'head_encoding' => 'quoted-printable',
'text_encoding' => '7bit',
'html_encoding' => 'quoted-printable',
'7bit_wrap' => 998,
'html_charset' => 'ISO-8859-1',
'text_charset' => 'ISO-8859-1',
'head_charset' => 'ISO-8859-1'
);
}
/**
* wakeup function called by unserialize. It re-sets the EOL constant
*
* @access private
* @return void
*/
function __wakeup()
{
$this->_setEOL($this->_eol);
}
/**
* Accessor function to set the body text. Body text is used if
* it's not an html mail being sent or else is used to fill the
* text/plain part that emails clients who don't support
* html should show.
*
* @param string $data Either a string or
* the file name with the contents
* @param bool $isfile If true the first param should be treated
* as a file name, else as a string (default)
* @param bool $append If true the text or file is appended to
* the existing body, else the old body is
* overwritten
*
* @return mixed true on success or PEAR_Error object
* @access public
*/
function setTXTBody($data, $isfile = false, $append = false)
{
if (!$isfile) {
if (!$append) {
$this->_txtbody = $data;
} else {
$this->_txtbody .= $data;
}
} else {
$cont = $this->_file2str($data);
if (PEAR::isError($cont)) {
return $cont;
}
if (!$append) {
$this->_txtbody = $cont;
} else {
$this->_txtbody .= $cont;
}
}
return true;
}
/**
* Adds a html part to the mail.
*
* @param string $data either a string or the file name with the
* contents
* @param bool $isfile a flag that determines whether $data is a
* filename, or a string(false, default)
*
* @return bool true on success
* @access public
*/
function setHTMLBody($data, $isfile = false)
{
if (!$isfile) {
$this->_htmlbody = $data;
} else {
$cont = $this->_file2str($data);
if (PEAR::isError($cont)) {
return $cont;
}
$this->_htmlbody = $cont;
}
return true;
}
/**
* Adds an image to the list of embedded images.
*
* @param string $file the image file name OR image data itself
* @param string $c_type the content type
* @param string $name the filename of the image.
* Only used if $file is the image data.
* @param bool $isfile whether $file is a filename or not.
* Defaults to true
*
* @return bool true on success
* @access public
*/
function addHTMLImage($file, $c_type='application/octet-stream',
$name = '', $isfile = true)
{
$filedata = ($isfile === true) ? $this->_file2str($file)
: $file;
if ($isfile === true) {
$filename = ($name == '' ? $file : $name);
} else {
$filename = $name;
}
if (PEAR::isError($filedata)) {
return $filedata;
}
$this->_html_images[] = array(
'body' => $filedata,
'name' => $filename,
'c_type' => $c_type,
'cid' => md5(uniqid(time()))
);
return true;
}
/**
* Adds a file to the list of attachments.
*
* @param string $file The file name of the file to attach
* OR the file contents itself
* @param string $c_type The content type
* @param string $name The filename of the attachment
* Only use if $file is the contents
* @param bool $isfile Whether $file is a filename or not
* Defaults to true
* @param string $encoding The type of encoding to use.
* Defaults to base64.
* Possible values: 7bit, 8bit, base64,
* or quoted-printable.
* @param string $disposition The content-disposition of this file
* Defaults to attachment.
* Possible values: attachment, inline.
* @param string $charset The character set used in the filename
* of this attachment.
* @param string $language The language of the attachment
* @param string $location The RFC 2557.4 location of the attachment
+ * @param string $n_encoding Use RFC 2047 for attachment name (Content-Type) encoding
+ * @param string $f_encoding Use RFC 2047 for attachment filename (Content-Disposition) encoding
*
* @return mixed true on success or PEAR_Error object
* @access public
*/
function addAttachment($file,
$c_type = 'application/octet-stream',
$name = '',
$isfile = true,
$encoding = 'base64',
$disposition = 'attachment',
$charset = '',
$language = '',
- $location = '')
+ $location = '',
+ $n_encoding = NULL,
+ $f_encoding = NULL)
{
$filedata = ($isfile === true) ? $this->_file2str($file)
: $file;
if ($isfile === true) {
// Force the name the user supplied, otherwise use $file
$filename = (strlen($name)) ? $name : $file;
} else {
$filename = $name;
}
if (!strlen($filename)) {
$msg = "The supplied filename for the attachment can't be empty";
$err = PEAR::raiseError($msg);
return $err;
}
$filename = $this->_basename($filename);
if (PEAR::isError($filedata)) {
return $filedata;
}
$this->_parts[] = array(
'body' => $filedata,
'name' => $filename,
'c_type' => $c_type,
'encoding' => $encoding,
'charset' => $charset,
'language' => $language,
'location' => $location,
- 'disposition' => $disposition
+ 'disposition' => $disposition,
+ 'name-encoding' => $n_encoding,
+ 'filename-encoding'=> $f_encoding
);
return true;
}
/**
* Get the contents of the given file name as string
*
* @param string $file_name path of file to process
*
* @return string contents of $file_name
* @access private
*/
function &_file2str($file_name)
{
//Check state of file and raise an error properly
if (!file_exists($file_name)) {
$err = PEAR::raiseError('File not found: ' . $file_name);
return $err;
}
if (!is_file($file_name)) {
$err = PEAR::raiseError('Not a regular file: ' . $file_name);
return $err;
}
if (!is_readable($file_name)) {
$err = PEAR::raiseError('File is not readable: ' . $file_name);
return $err;
}
//Temporarily reset magic_quotes_runtime and read file contents
if ($magic_quote_setting = get_magic_quotes_runtime()) {
set_magic_quotes_runtime(0);
}
$cont = file_get_contents($file_name);
if ($magic_quote_setting) {
set_magic_quotes_runtime($magic_quote_setting);
}
return $cont;
}
/**
* Adds a text subpart to the mimePart object and
* returns it during the build process.
*
* @param mixed &$obj The object to add the part to, or
* null if a new object is to be created.
* @param string $text The text to add.
*
* @return object The text mimePart object
* @access private
*/
function &_addTextPart(&$obj, $text)
{
$params['content_type'] = 'text/plain';
$params['encoding'] = $this->_build_params['text_encoding'];
$params['charset'] = $this->_build_params['text_charset'];
if (is_object($obj)) {
$ret = $obj->addSubpart($text, $params);
return $ret;
} else {
$ret = new Mail_mimePart($text, $params);
return $ret;
}
}
/**
* Adds a html subpart to the mimePart object and
* returns it during the build process.
*
* @param mixed &$obj The object to add the part to, or
* null if a new object is to be created.
*
* @return object The html mimePart object
* @access private
*/
function &_addHtmlPart(&$obj)
{
$params['content_type'] = 'text/html';
$params['encoding'] = $this->_build_params['html_encoding'];
$params['charset'] = $this->_build_params['html_charset'];
if (is_object($obj)) {
$ret = $obj->addSubpart($this->_htmlbody, $params);
return $ret;
} else {
$ret = new Mail_mimePart($this->_htmlbody, $params);
return $ret;
}
}
/**
* Creates a new mimePart object, using multipart/mixed as
* the initial content-type and returns it during the
* build process.
*
* @return object The multipart/mixed mimePart object
* @access private
*/
function &_addMixedPart()
{
$params = array();
$params['content_type'] = 'multipart/mixed';
//Create empty multipart/mixed Mail_mimePart object to return
$ret = new Mail_mimePart('', $params);
return $ret;
}
/**
* Adds a multipart/alternative part to a mimePart
* object (or creates one), and returns it during
* the build process.
*
* @param mixed &$obj The object to add the part to, or
* null if a new object is to be created.
*
* @return object The multipart/mixed mimePart object
* @access private
*/
function &_addAlternativePart(&$obj)
{
$params['content_type'] = 'multipart/alternative';
if (is_object($obj)) {
return $obj->addSubpart('', $params);
} else {
$ret = new Mail_mimePart('', $params);
return $ret;
}
}
/**
* Adds a multipart/related part to a mimePart
* object (or creates one), and returns it during
* the build process.
*
* @param mixed &$obj The object to add the part to, or
* null if a new object is to be created
*
* @return object The multipart/mixed mimePart object
* @access private
*/
function &_addRelatedPart(&$obj)
{
$params['content_type'] = 'multipart/related';
if (is_object($obj)) {
return $obj->addSubpart('', $params);
} else {
$ret = new Mail_mimePart('', $params);
return $ret;
}
}
/**
* Adds an html image subpart to a mimePart object
* and returns it during the build process.
*
* @param object &$obj The mimePart to add the image to
* @param array $value The image information
*
* @return object The image mimePart object
* @access private
*/
function &_addHtmlImagePart(&$obj, $value)
{
$params['content_type'] = $value['c_type'];
$params['encoding'] = 'base64';
$params['disposition'] = 'inline';
$params['dfilename'] = $value['name'];
$params['cid'] = $value['cid'];
+ if ($value['name-encoding']) {
+ $params['name-encoding'] = $value['name-encoding'];
+ }
+ if ($value['filename-encoding']) {
+ $params['filename-encoding'] = $value['filename-encoding'];
+ }
$ret = $obj->addSubpart($value['body'], $params);
return $ret;
}
/**
* Adds an attachment subpart to a mimePart object
* and returns it during the build process.
*
* @param object &$obj The mimePart to add the image to
* @param array $value The attachment information
*
* @return object The image mimePart object
* @access private
*/
function &_addAttachmentPart(&$obj, $value)
{
$params['dfilename'] = $value['name'];
$params['encoding'] = $value['encoding'];
if ($value['charset']) {
$params['charset'] = $value['charset'];
}
if ($value['language']) {
$params['language'] = $value['language'];
}
if ($value['location']) {
$params['location'] = $value['location'];
}
+ if ($value['name-encoding']) {
+ $params['name-encoding'] = $value['name-encoding'];
+ }
+ if ($value['filename-encoding']) {
+ $params['filename-encoding'] = $value['filename-encoding'];
+ }
$params['content_type'] = $value['c_type'];
$params['disposition'] = isset($value['disposition']) ?
$value['disposition'] : 'attachment';
$ret = $obj->addSubpart($value['body'], $params);
return $ret;
}
/**
* Returns the complete e-mail, ready to send using an alternative
* mail delivery method. Note that only the mailpart that is made
* with Mail_Mime is created. This means that,
* YOU WILL HAVE NO TO: HEADERS UNLESS YOU SET IT YOURSELF
* using the $xtra_headers parameter!
*
* @param string $separation The separation etween these two parts.
* @param array $build_params The Build parameters passed to the
* &get() function. See &get for more info.
* @param array $xtra_headers The extra headers that should be passed
* to the &headers() function.
* See that function for more info.
* @param bool $overwrite Overwrite the existing headers with new.
*
* @return string The complete e-mail.
* @access public
*/
function getMessage(
$separation = null,
$build_params = null,
$xtra_headers = null,
$overwrite = false
)
{
if ($separation === null) {
$separation = MAIL_MIME_CRLF;
}
$body = $this->get($build_params);
$head = $this->txtHeaders($xtra_headers, $overwrite);
$mail = $head . $separation . $body;
return $mail;
}
/**
* Builds the multipart message from the list ($this->_parts) and
* returns the mime content.
*
* @param array $build_params Build parameters that change the way the email
* is built. Should be associative. Can contain:
* head_encoding - What encoding to use for the headers.
* Options: quoted-printable or base64
* Default is quoted-printable
* text_encoding - What encoding to use for plain text
* Options: 7bit, 8bit,
* base64, or quoted-printable
* Default is 7bit
* html_encoding - What encoding to use for html
* Options: 7bit, 8bit,
* base64, or quoted-printable
* Default is quoted-printable
* 7bit_wrap - Number of characters before text is
* wrapped in 7bit encoding
* Default is 998
* html_charset - The character set to use for html.
* Default is iso-8859-1
* text_charset - The character set to use for text.
* Default is iso-8859-1
* head_charset - The character set to use for headers.
* Default is iso-8859-1
*
* @return string The mime content
* @access public
*/
function &get($build_params = null)
{
if (isset($build_params)) {
while (list($key, $value) = each($build_params)) {
$this->_build_params[$key] = $value;
}
}
if (isset($this->_headers['From'])){
//Bug #11381: Illegal characters in domain ID
if (preg_match("|(@[0-9a-zA-Z\-\.]+)|", $this->_headers['From'], $matches)){
$domainID = $matches[1];
}else{
$domainID = "@localhost";
}
foreach($this->_html_images as $i => $img){
$this->_html_images[$i]['cid'] = $this->_html_images[$i]['cid'] . $domainID;
}
}
if (count($this->_html_images) AND isset($this->_htmlbody)) {
foreach ($this->_html_images as $key => $value) {
$regex = array();
$regex[] = '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' .
preg_quote($value['name'], '#') . '\3#';
$regex[] = '#(?i)url(?-i)\(\s*(["\']?)' .
preg_quote($value['name'], '#') . '\1\s*\)#';
$rep = array();
$rep[] = '\1\2=\3cid:' . $value['cid'] .'\3';
$rep[] = 'url(\1cid:' . $value['cid'] . '\1)';
$this->_htmlbody = preg_replace($regex, $rep, $this->_htmlbody);
$this->_html_images[$key]['name'] =
$this->_basename($this->_html_images[$key]['name']);
}
}
$null = null;
$attachments = count($this->_parts) ? true : false;
$html_images = count($this->_html_images) ? true : false;
$html = strlen($this->_htmlbody) ? true : false;
$text = (!$html AND strlen($this->_txtbody)) ? true : false;
switch (true) {
case $text AND !$attachments:
$message =& $this->_addTextPart($null, $this->_txtbody);
break;
case !$text AND !$html AND $attachments:
$message =& $this->_addMixedPart();
for ($i = 0; $i < count($this->_parts); $i++) {
$this->_addAttachmentPart($message, $this->_parts[$i]);
}
break;
case $text AND $attachments:
$message =& $this->_addMixedPart();
$this->_addTextPart($message, $this->_txtbody);
for ($i = 0; $i < count($this->_parts); $i++) {
$this->_addAttachmentPart($message, $this->_parts[$i]);
}
break;
case $html AND !$attachments AND !$html_images:
if (isset($this->_txtbody)) {
$message =& $this->_addAlternativePart($null);
$this->_addTextPart($message, $this->_txtbody);
$this->_addHtmlPart($message);
} else {
$message =& $this->_addHtmlPart($null);
}
break;
case $html AND !$attachments AND $html_images:
$message =& $this->_addRelatedPart($null);
if (isset($this->_txtbody)) {
$alt =& $this->_addAlternativePart($message);
$this->_addTextPart($alt, $this->_txtbody);
$this->_addHtmlPart($alt);
} else {
$this->_addHtmlPart($message);
}
for ($i = 0; $i < count($this->_html_images); $i++) {
$this->_addHtmlImagePart($message, $this->_html_images[$i]);
}
break;
case $html AND $attachments AND !$html_images:
$message =& $this->_addMixedPart();
if (isset($this->_txtbody)) {
$alt =& $this->_addAlternativePart($message);
$this->_addTextPart($alt, $this->_txtbody);
$this->_addHtmlPart($alt);
} else {
$this->_addHtmlPart($message);
}
for ($i = 0; $i < count($this->_parts); $i++) {
$this->_addAttachmentPart($message, $this->_parts[$i]);
}
break;
case $html AND $attachments AND $html_images:
$message =& $this->_addMixedPart();
if (isset($this->_txtbody)) {
$alt =& $this->_addAlternativePart($message);
$this->_addTextPart($alt, $this->_txtbody);
$rel =& $this->_addRelatedPart($alt);
} else {
$rel =& $this->_addRelatedPart($message);
}
$this->_addHtmlPart($rel);
for ($i = 0; $i < count($this->_html_images); $i++) {
$this->_addHtmlImagePart($rel, $this->_html_images[$i]);
}
for ($i = 0; $i < count($this->_parts); $i++) {
$this->_addAttachmentPart($message, $this->_parts[$i]);
}
break;
}
if (isset($message)) {
$output = $message->encode();
$this->_headers = array_merge($this->_headers,
$output['headers']);
$body = $output['body'];
return $body;
} else {
$ret = false;
return $ret;
}
}
/**
* Returns an array with the headers needed to prepend to the email
* (MIME-Version and Content-Type). Format of argument is:
* $array['header-name'] = 'header-value';
*
* @param array $xtra_headers Assoc array with any extra headers.
* Optional.
* @param bool $overwrite Overwrite already existing headers.
*
* @return array Assoc array with the mime headers
* @access public
*/
function &headers($xtra_headers = null, $overwrite = false)
{
// Content-Type header should already be present,
// So just add mime version header
$headers['MIME-Version'] = '1.0';
if (isset($xtra_headers)) {
$headers = array_merge($headers, $xtra_headers);
}
if ($overwrite) {
$this->_headers = array_merge($this->_headers, $headers);
} else {
$this->_headers = array_merge($headers, $this->_headers);
}
$encodedHeaders = $this->_encodeHeaders($this->_headers);
return $encodedHeaders;
}
/**
* Get the text version of the headers
* (usefull if you want to use the PHP mail() function)
*
* @param array $xtra_headers Assoc array with any extra headers.
* Optional.
* @param bool $overwrite Overwrite the existing heaers with new.
*
* @return string Plain text headers
* @access public
*/
function txtHeaders($xtra_headers = null, $overwrite = false)
{
$headers = $this->headers($xtra_headers, $overwrite);
$ret = '';
foreach ($headers as $key => $val) {
$ret .= "$key: $val" . MAIL_MIME_CRLF;
}
return $ret;
}
/**
* Sets the Subject header
*
* @param string $subject String to set the subject to.
*
* @return void
* @access public
*/
function setSubject($subject)
{
$this->_headers['Subject'] = $subject;
}
/**
* Set an email to the From (the sender) header
*
* @param string $email The email address to use
*
* @return void
* @access public
*/
function setFrom($email)
{
$this->_headers['From'] = $email;
}
/**
* Add an email to the Cc (carbon copy) header
* (multiple calls to this method are allowed)
*
* @param string $email The email direction to add
*
* @return void
* @access public
*/
function addCc($email)
{
if (isset($this->_headers['Cc'])) {
$this->_headers['Cc'] .= ", $email";
} else {
$this->_headers['Cc'] = $email;
}
}
/**
* Add an email to the Bcc (blank carbon copy) header
* (multiple calls to this method are allowed)
*
* @param string $email The email direction to add
*
* @return void
* @access public
*/
function addBcc($email)
{
if (isset($this->_headers['Bcc'])) {
$this->_headers['Bcc'] .= ", $email";
} else {
$this->_headers['Bcc'] = $email;
}
}
/**
* Since the PHP send function requires you to specifiy
* recipients (To: header) separately from the other
* headers, the To: header is not properly encoded.
* To fix this, you can use this public method to
* encode your recipients before sending to the send
* function
*
* @param string $recipients A comma-delimited list of recipients
*
* @return string Encoded data
* @access public
*/
function encodeRecipients($recipients)
{
$input = array("To" => $recipients);
$retval = $this->_encodeHeaders($input);
return $retval["To"] ;
}
/**
* Encodes a header as per RFC2047
*
* @param array $input The header data to encode
* @param array $params Extra build parameters
*
* @return array Encoded data
* @access private
*/
function _encodeHeaders($input, $params = array())
{
-
$build_params = $this->_build_params;
while (list($key, $value) = each($params)) {
$build_params[$key] = $value;
}
//$hdr_name: Name of the heaer
//$hdr_value: Full line of header value.
//$atoms: The $hdr_value split into atoms*
//$atom: A single atom to encode.*
//$hdr_value_out: The recombined $hdr_val-atoms, or the encoded string.
//Note: Atom as specified here is not exactly the same as an RFC822 atom,
//as $atom's may contain just a single space.
$useIconv = true;
if (isset($build_params['ignore-iconv'])) {
$useIconv = !$build_params['ignore-iconv'];
}
foreach ($input as $hdr_name => $hdr_value) {
/*
$parts = preg_split('/([ ])/', $hdr_value, -1, PREG_SPLIT_DELIM_CAPTURE);
$atoms = array();
foreach ($parts as $part){
$atom .= $part;
$quoteMatch = preg_match_all('|"|', $atom, $matches) % 2;
if (!$quoteMatch){
$atoms[] = $atom;
$atom = null;
}
}
if ($atom){
$atoms[] = $atom;
}
foreach ($atoms as $atom){
*/
if (preg_match('#([\x80-\xFF]){1}#', $hdr_value)) {
if (function_exists('iconv_mime_encode') && $useIconv) {
$imePrefs = array();
if ($build_params['head_encoding'] == 'base64') {
$imePrefs['scheme'] = 'B';
} else {
$imePrefs['scheme'] = 'Q';
}
$imePrefs['input-charset'] = $build_params['head_charset'];
$imePrefs['output-charset'] = $build_params['head_charset'];
$imePrefs['line-length'] = 74;
$imePrefs['line-break-chars'] = "\r\n"; //Specified in RFC2047
$hdr_value = iconv_mime_encode($hdr_name, $hdr_value, $imePrefs);
$hdr_value = preg_replace("#^{$hdr_name}\:\ #", "", $hdr_value);
} elseif ($build_params['head_encoding'] == 'base64') {
//Base64 encoding has been selected.
//Base64 encode the entire string
$hdr_value = base64_encode($hdr_value);
//Generate the header using the specified params and dynamicly
//determine the maximum length of such strings.
//75 is the value specified in the RFC. The first -2 is there so
//the later regexp doesn't break any of the translated chars.
//The -2 on the first line-regexp is to compensate for the ": "
//between the header-name and the header value
$prefix = '=?' . $build_params['head_charset'] . '?B?';
$suffix = '?=';
$maxLength = 75 - strlen($prefix . $suffix) - 2;
$maxLength1stLine = $maxLength - strlen($hdr_name) - 2;
//We can cut base4 every 4 characters, so the real max
//we can get must be rounded down.
$maxLength = $maxLength - ($maxLength % 4);
$maxLength1stLine = $maxLength1stLine - ($maxLength1stLine % 4);
$cutpoint = $maxLength1stLine;
$hdr_value_out = $hdr_value;
$output = "";
while ($hdr_value_out) {
//Split translated string at every $maxLength
$part = substr($hdr_value_out, 0, $cutpoint);
$hdr_value_out = substr($hdr_value_out, $cutpoint);
$cutpoint = $maxLength;
//RFC 2047 specifies that any split header should
//be seperated by a CRLF SPACE.
if ($output) {
$output .= "\r\n ";
}
$output .= $prefix . $part . $suffix;
}
$hdr_value = $output;
} else {
//quoted-printable encoding has been selected
//Fix for Bug #10298, Ota Mares <om@viazenetti.de>
//Check if there is a double quote at beginning or end of
//the string to prevent that an open or closing quote gets
//ignored because it is encapsuled by an encoding pre/suffix.
//Remove the double quote and set the specific prefix or
//suffix variable so that we can concat the encoded string and
//the double quotes back together to get the intended string.
$quotePrefix = $quoteSuffix = '';
if ($hdr_value{0} == '"') {
$hdr_value = substr($hdr_value, 1);
$quotePrefix = '"';
}
if ($hdr_value{strlen($hdr_value)-1} == '"') {
$hdr_value = substr($hdr_value, 0, -1);
$quoteSuffix = '"';
}
//Generate the header using the specified params and dynamicly
//determine the maximum length of such strings.
//75 is the value specified in the RFC. The -2 is there so
//the later regexp doesn't break any of the translated chars.
//The -2 on the first line-regexp is to compensate for the ": "
//between the header-name and the header value
$prefix = '=?' . $build_params['head_charset'] . '?Q?';
$suffix = '?=';
$maxLength = 75 - strlen($prefix . $suffix) - 2 - 1;
$maxLength1stLine = $maxLength - strlen($hdr_name) - 2;
$maxLength = $maxLength - 1;
//Replace all special characters used by the encoder.
$search = array('=', '_', '?', ' ');
$replace = array('=3D', '=5F', '=3F', '_');
$hdr_value = str_replace($search, $replace, $hdr_value);
//Replace all extended characters (\x80-xFF) with their
//ASCII values.
$hdr_value = preg_replace('#([\x80-\xFF])#e',
'"=" . strtoupper(dechex(ord("\1")))',
$hdr_value);
//This regexp will break QP-encoded text at every $maxLength
//but will not break any encoded letters.
$reg1st = "|(.{0,$maxLength1stLine}[^\=][^\=])|";
$reg2nd = "|(.{0,$maxLength}[^\=][^\=])|";
//Fix for Bug #10298, Ota Mares <om@viazenetti.de>
//Concat the double quotes and encoded string together
$hdr_value = $quotePrefix . $hdr_value . $quoteSuffix;
$hdr_value_out = $hdr_value;
$realMax = $maxLength1stLine + strlen($prefix . $suffix);
if (strlen($hdr_value_out) >= $realMax) {
//Begin with the regexp for the first line.
$reg = $reg1st;
$output = "";
while ($hdr_value_out) {
//Split translated string at every $maxLength
//But make sure not to break any translated chars.
$found = preg_match($reg, $hdr_value_out, $matches);
//After this first line, we need to use a different
//regexp for the first line.
$reg = $reg2nd;
//Save the found part and encapsulate it in the
//prefix & suffix. Then remove the part from the
//$hdr_value_out variable.
if ($found) {
$part = $matches[0];
$len = strlen($matches[0]);
$hdr_value_out = substr($hdr_value_out, $len);
} else {
$part = $hdr_value_out;
$hdr_value_out = "";
}
//RFC 2047 specifies that any split header should
//be seperated by a CRLF SPACE
if ($output) {
$output .= "\r\n ";
}
$output .= $prefix . $part . $suffix;
}
$hdr_value_out = $output;
} else {
$hdr_value_out = $prefix . $hdr_value_out . $suffix;
}
$hdr_value = $hdr_value_out;
}
}
$input[$hdr_name] = $hdr_value;
}
return $input;
}
/**
* Set the object's end-of-line and define the constant if applicable.
*
* @param string $eol End Of Line sequence
*
* @return void
* @access private
*/
function _setEOL($eol)
{
$this->_eol = $eol;
if (!defined('MAIL_MIME_CRLF')) {
define('MAIL_MIME_CRLF', $this->_eol, true);
}
}
/**
* Get file's basename (locale independent)
*
* @param string Filename
*
* @return string Basename
* @access private
*/
function _basename($filename)
{
// basename() is not unicode safe and locale dependent
if (stristr(PHP_OS, 'win') || stristr(PHP_OS, 'netware'))
return preg_replace('/^.*[\\\\\\/]/', '', $filename);
else
return preg_replace('/^.*[\/]/', '', $filename);
}
} // End of class
diff --git a/program/lib/Mail/mimePart.php b/program/lib/Mail/mimePart.php
index bd3047724..9b9f26cc3 100644
--- a/program/lib/Mail/mimePart.php
+++ b/program/lib/Mail/mimePart.php
@@ -1,436 +1,522 @@
<?php
/**
* The Mail_mimePart class is used to create MIME E-mail messages
*
* This class enables you to manipulate and build a mime email
* from the ground up. The Mail_Mime class is a userfriendly api
* to this class for people who aren't interested in the internals
* of mime mail.
* This class however allows full control over the email.
*
* Compatible with PHP versions 4 and 5
*
* LICENSE: This LICENSE is in the BSD license style.
* Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org>
* Copyright (c) 2003-2006, PEAR <pear-group@php.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of the authors, nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* @category Mail
* @package Mail_Mime
* @author Richard Heyes <richard@phpguru.org>
* @author Cipriano Groenendal <cipri@php.net>
* @author Sean Coates <sean@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version CVS: $Id$
* @link http://pear.php.net/package/Mail_mime
*/
/**
* The Mail_mimePart class is used to create MIME E-mail messages
*
* This class enables you to manipulate and build a mime email
* from the ground up. The Mail_Mime class is a userfriendly api
* to this class for people who aren't interested in the internals
* of mime mail.
* This class however allows full control over the email.
*
* @category Mail
* @package Mail_Mime
* @author Richard Heyes <richard@phpguru.org>
* @author Cipriano Groenendal <cipri@php.net>
* @author Sean Coates <sean@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version Release: @package_version@
* @link http://pear.php.net/package/Mail_mime
*/
class Mail_mimePart {
/**
* The encoding type of this part
*
* @var string
* @access private
*/
var $_encoding;
/**
* An array of subparts
*
* @var array
* @access private
*/
var $_subparts;
/**
* The output of this part after being built
*
* @var string
* @access private
*/
var $_encoded;
/**
* Headers for this part
*
* @var array
* @access private
*/
var $_headers;
/**
* The body of this part (not encoded)
*
* @var string
* @access private
*/
var $_body;
/**
* Constructor.
*
* Sets up the object.
*
* @param $body - The body of the mime part if any.
* @param $params - An associative array of parameters:
* content_type - The content type for this part eg multipart/mixed
* encoding - The encoding to use, 7bit, 8bit, base64, or quoted-printable
* cid - Content ID to apply
* disposition - Content disposition, inline or attachment
* dfilename - Optional filename parameter for content disposition
* description - Content description
* charset - Character set to use
* @access public
*/
function Mail_mimePart($body = '', $params = array())
{
if (!defined('MAIL_MIMEPART_CRLF')) {
define('MAIL_MIMEPART_CRLF', defined('MAIL_MIME_CRLF') ? MAIL_MIME_CRLF : "\r\n", TRUE);
}
$contentType = array();
$contentDisp = array();
foreach ($params as $key => $value) {
switch ($key) {
case 'content_type':
$contentType['type'] = $value;
//$headers['Content-Type'] = $value . (isset($charset) ? '; charset="' . $charset . '"' : '');
break;
case 'encoding':
$this->_encoding = $value;
$headers['Content-Transfer-Encoding'] = $value;
break;
case 'cid':
$headers['Content-ID'] = '<' . $value . '>';
break;
case 'disposition':
$contentDisp['disp'] = $value;
break;
case 'dfilename':
$contentDisp['filename'] = $value;
$contentType['name'] = $value;
break;
case 'description':
$headers['Content-Description'] = $value;
break;
case 'charset':
$contentType['charset'] = $value;
$contentDisp['charset'] = $value;
break;
case 'language':
$contentType['language'] = $value;
$contentDisp['language'] = $value;
break;
case 'location':
$headers['Content-Location'] = $value;
break;
}
}
+
if (isset($contentType['type'])) {
$headers['Content-Type'] = $contentType['type'];
if (isset($contentType['name'])) {
$headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF;
- $headers['Content-Type'] .= $this->_buildHeaderParam('name', $contentType['name'],
- isset($contentType['charset']) ? $contentType['charset'] : 'US-ASCII',
- isset($contentType['language']) ? $contentType['language'] : NULL);
+ $headers['Content-Type'] .=
+ $this->_buildHeaderParam('name', $contentType['name'],
+ isset($contentType['charset']) ? $contentType['charset'] : 'US-ASCII',
+ isset($contentType['language']) ? $contentType['language'] : NULL,
+ isset($params['name-encoding']) ? $params['name-encoding'] : NULL);
} elseif (isset($contentType['charset'])) {
$headers['Content-Type'] .= "; charset=\"{$contentType['charset']}\"";
}
}
if (isset($contentDisp['disp'])) {
$headers['Content-Disposition'] = $contentDisp['disp'];
if (isset($contentDisp['filename'])) {
$headers['Content-Disposition'] .= ';' . MAIL_MIMEPART_CRLF;
- $headers['Content-Disposition'] .= $this->_buildHeaderParam('filename', $contentDisp['filename'],
- isset($contentDisp['charset']) ? $contentDisp['charset'] : 'US-ASCII',
- isset($contentDisp['language']) ? $contentDisp['language'] : NULL);
+ $headers['Content-Disposition'] .=
+ $this->_buildHeaderParam('filename', $contentDisp['filename'],
+ isset($contentDisp['charset']) ? $contentDisp['charset'] : 'US-ASCII',
+ isset($contentDisp['language']) ? $contentDisp['language'] : NULL,
+ isset($params['filename-encoding']) ? $params['filename-encoding'] : NULL);
}
}
-
-
-
-
+
// Default content-type
if (!isset($headers['Content-Type'])) {
$headers['Content-Type'] = 'text/plain';
}
//Default encoding
if (!isset($this->_encoding)) {
$this->_encoding = '7bit';
}
// Assign stuff to member variables
$this->_encoded = array();
$this->_headers = $headers;
$this->_body = $body;
}
/**
* encode()
*
* Encodes and returns the email. Also stores
* it in the encoded member variable
*
* @return An associative array containing two elements,
* body and headers. The headers element is itself
* an indexed array.
* @access public
*/
function encode()
{
$encoded =& $this->_encoded;
if (count($this->_subparts)) {
srand((double)microtime()*1000000);
$boundary = '=_' . md5(rand() . microtime());
$this->_headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF . "\t" . 'boundary="' . $boundary . '"';
// Add body parts to $subparts
for ($i = 0; $i < count($this->_subparts); $i++) {
$headers = array();
$tmp = $this->_subparts[$i]->encode();
foreach ($tmp['headers'] as $key => $value) {
$headers[] = $key . ': ' . $value;
}
$subparts[] = implode(MAIL_MIMEPART_CRLF, $headers) . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF . $tmp['body'] . MAIL_MIMEPART_CRLF;
}
$encoded['body'] = '--' . $boundary . MAIL_MIMEPART_CRLF .
rtrim(implode('--' . $boundary . MAIL_MIMEPART_CRLF , $subparts), MAIL_MIMEPART_CRLF) . MAIL_MIMEPART_CRLF .
'--' . $boundary.'--' . MAIL_MIMEPART_CRLF;
} else {
$encoded['body'] = $this->_getEncodedData($this->_body, $this->_encoding);
}
// Add headers to $encoded
$encoded['headers'] =& $this->_headers;
return $encoded;
}
/**
* &addSubPart()
*
* Adds a subpart to current mime part and returns
* a reference to it
*
* @param $body The body of the subpart, if any.
* @param $params The parameters for the subpart, same
* as the $params argument for constructor.
* @return A reference to the part you just added. It is
* crucial if using multipart/* in your subparts that
* you use =& in your script when calling this function,
* otherwise you will not be able to add further subparts.
* @access public
*/
function &addSubPart($body, $params)
{
$this->_subparts[] = new Mail_mimePart($body, $params);
return $this->_subparts[count($this->_subparts) - 1];
}
/**
* _getEncodedData()
*
* Returns encoded data based upon encoding passed to it
*
* @param $data The data to encode.
* @param $encoding The encoding type to use, 7bit, base64,
* or quoted-printable.
* @access private
*/
function _getEncodedData($data, $encoding)
{
switch ($encoding) {
case '8bit':
case '7bit':
return $data;
break;
case 'quoted-printable':
return $this->_quotedPrintableEncode($data);
break;
case 'base64':
return rtrim(chunk_split(base64_encode($data), 76, MAIL_MIMEPART_CRLF));
break;
default:
return $data;
}
}
/**
* quotedPrintableEncode()
*
* Encodes data to quoted-printable standard.
*
* @param $input The data to encode
* @param $line_max Optional max line length. Should
* not be more than 76 chars
*
* @access private
*/
function _quotedPrintableEncode($input , $line_max = 76)
{
$lines = preg_split("/\r?\n/", $input);
$eol = MAIL_MIMEPART_CRLF;
$escape = '=';
$output = '';
while (list(, $line) = each($lines)) {
$line = preg_split('||', $line, -1, PREG_SPLIT_NO_EMPTY);
$linlen = count($line);
$newline = '';
for ($i = 0; $i < $linlen; $i++) {
$char = $line[$i];
$dec = ord($char);
if (($dec == 32) AND ($i == ($linlen - 1))) { // convert space at eol only
$char = '=20';
} elseif (($dec == 9) AND ($i == ($linlen - 1))) { // convert tab at eol only
$char = '=09';
} elseif ($dec == 9) {
; // Do nothing if a tab.
} elseif (($dec == 61) OR ($dec < 32 ) OR ($dec > 126)) {
$char = $escape . strtoupper(sprintf('%02s', dechex($dec)));
} elseif (($dec == 46) AND (($newline == '') || ((strlen($newline) + strlen("=2E")) >= $line_max))) {
//Bug #9722: convert full-stop at bol,
//some Windows servers need this, won't break anything (cipri)
//Bug #11731: full-stop at bol also needs to be encoded
//if this line would push us over the line_max limit.
$char = '=2E';
}
//Note, when changing this line, also change the ($dec == 46)
//check line, as it mimics this line due to Bug #11731
if ((strlen($newline) + strlen($char)) >= $line_max) { // MAIL_MIMEPART_CRLF is not counted
$output .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay
$newline = '';
}
$newline .= $char;
} // end of for
$output .= $newline . $eol;
}
$output = substr($output, 0, -1 * strlen($eol)); // Don't want last crlf
return $output;
}
/**
* _buildHeaderParam()
*
* Encodes the paramater of a header.
*
* @param $name The name of the header-parameter
* @param $value The value of the paramter
* @param $charset The characterset of $value
* @param $language The language used in $value
+ * @param $paramEnc Parameter encoding type
* @param $maxLength The maximum length of a line. Defauls to 78
*
* @access private
*/
- function _buildHeaderParam($name, $value, $charset=NULL, $language=NULL, $maxLength=78)
+ function _buildHeaderParam($name, $value, $charset=NULL, $language=NULL, $paramEnc=NULL, $maxLength=78)
{
// RFC 2183/2184/2822:
// value needs encoding if contains non-ASCII chars or is longer than 78 chars
-
if (!preg_match('#[^\x20-\x7E]#', $value)) { // ASCII
$quoted = addcslashes($value, '\\"');
if (strlen($name) + strlen($quoted) + 6 <= $maxLength)
return " {$name}=\"{$quoted}\"; ";
}
+ // use quoted-printable/base64 encoding (RFC2047)
+ if ($paramEnc == 'quoted-printable' || $paramEnc == 'base64')
+ return $this->_buildRFC2047Param($name, $value, $charset, $paramEnc);
+
$encValue = preg_replace('#([^\x20-\x7E])#e', '"%" . strtoupper(dechex(ord("\1")))', $value);
$value = "$charset'$language'$encValue";
$header = " {$name}*=\"{$value}\"; ";
if (strlen($header) <= $maxLength) {
return $header;
}
$preLength = strlen(" {$name}*0*=\"");
$sufLength = strlen("\";");
- $maxLength = MAX(16, $maxLength - $preLength - $sufLength - 2);
+ $maxLength = max(16, $maxLength - $preLength - $sufLength - 2);
$maxLengthReg = "|(.{0,$maxLength}[^\%][^\%])|";
$headers = array();
$headCount = 0;
while ($value) {
$matches = array();
$found = preg_match($maxLengthReg, $value, $matches);
if ($found) {
$headers[] = " {$name}*{$headCount}*=\"{$matches[0]}\"";
$value = substr($value, strlen($matches[0]));
} else {
$headers[] = " {$name}*{$headCount}*=\"{$value}\"";
$value = "";
}
$headCount++;
}
$headers = implode(MAIL_MIMEPART_CRLF, $headers) . ';';
return $headers;
}
+
+ /**
+ * Encodes header parameter as per RFC2047 if needed (values too long will be truncated)
+ *
+ * @param string $name The parameter name
+ * @param string $value The parameter value
+ * @param string $charset The parameter charset
+ * @param string $encoding Encoding type (quoted-printable or base64)
+ * @param int $maxLength Encoded parameter max length (75 is the value specified in the RFC)
+ *
+ * @return string Parameter line
+ * @access private
+ */
+ function _buildRFC2047Param($name, $value, $charset, $encoding='quoted-printable', $maxLength=75)
+ {
+ if (!preg_match('#([^\x20-\x7E]){1}#', $value))
+ {
+ $quoted = addcslashes($value, '\\"');
+ $maxLength = $maxLength - 6;
+ if (strlen($quoted) > $maxLength)
+ {
+ // truncate filename leaving extension
+ $ext = strrchr($quoted, '.');
+ $quoted = substr($quoted, 0, $maxLength - strlen($ext));
+ // remove backslashes from the end of filename
+ preg_replace('/[\\\\]+$/', '', $quoted);
+ $quoted .= $ext;
+ }
+ }
+ else if ($encoding == 'base64')
+ {
+ $ext = strrchr($value, '.');
+ $value = substr($value, 0, strlen($value) - strlen($ext));
+
+ $ext = base64_encode($ext);
+ $value = base64_encode($value);
+
+ $prefix = '=?' . $charset . '?B?';
+ $suffix = '?=';
+ $maxLength = $maxLength - strlen($prefix . $suffix) - strlen($ext) - 2;
+
+ //We can cut base64 every 4 characters, so the real max
+ //we can get must be rounded down.
+ $maxLength = $maxLength - ($maxLength % 4);
+ $quoted = $prefix . substr($value, 0, $maxLength) . $ext . $suffix;
+ }
+ else // quoted-printable
+ {
+ $ext = strrchr($value, '.');
+ $value = substr($value, 0, strlen($value) - strlen($ext));
+
+ // Replace all special characters used by the encoder.
+ $search = array('=', '_', '?', ' ');
+ $replace = array('=3D', '=5F', '=3F', '_');
+ $ext = str_replace($search, $replace, $ext);
+ $value = str_replace($search, $replace, $value);
+
+ // Replace all extended characters (\x80-xFF) with their
+ // ASCII values.
+ $ext = preg_replace('/([\x80-\xFF])/e',
+ '"=" . strtoupper(dechex(ord("\1")))', $ext);
+ $value = preg_replace('/([\x80-\xFF])/e',
+ '"=" . strtoupper(dechex(ord("\1")))', $value);
+
+ $prefix = '=?' . $charset . '?Q?';
+ $suffix = '?=';
+
+ $maxLength = $maxLength - strlen($prefix . $suffix) - strlen($ext) - 2;
+
+ // Truncate QP-encoded text at $maxLength
+ // but not break any encoded letters.
+ if(preg_match("/^(.{0,$maxLength}[^\=][^\=])/", $value, $matches))
+ $value = $matches[1];
+
+ $quoted = $prefix . $value . $ext . $suffix;
+ }
+
+ return " {$name}=\"{$quoted}\"; ";
+ }
+
} // End of class
diff --git a/program/localization/en_GB/labels.inc b/program/localization/en_GB/labels.inc
index 13008f535..064a6881c 100644
--- a/program/localization/en_GB/labels.inc
+++ b/program/localization/en_GB/labels.inc
@@ -1,248 +1,253 @@
<?php
/*
+-----------------------------------------------------------------------+
| language/en_GB/labels.inc |
| |
| Language file of the RoundCube Webmail client |
| Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
+-----------------------------------------------------------------------+
| Author: Weiran Zhang (weiran@weiran.co.uk) |
+-----------------------------------------------------------------------+
@version $Id$
*/
$labels = array();
$labels['welcome'] = 'Welcome to $product';
$labels['username'] = 'Username';
$labels['password'] = 'Password';
$labels['server'] = 'Server';
$labels['login'] = 'Login';
$labels['logout'] = 'Logout';
$labels['mail'] = 'E-Mail';
$labels['settings'] = 'Personal Settings';
$labels['addressbook'] = 'Address Book';
$labels['inbox'] = 'Inbox';
$labels['drafts'] = 'Drafts';
$labels['sent'] = 'Sent';
$labels['trash'] = 'Deleted Items';
$labels['junk'] = 'Junk';
$labels['subject'] = 'Subject';
$labels['from'] = 'Sender';
$labels['to'] = 'Recipient';
$labels['cc'] = 'Copy';
$labels['bcc'] = 'Bcc';
$labels['replyto'] = 'Reply-To';
$labels['date'] = 'Date';
$labels['size'] = 'Size';
$labels['priority'] = 'Priority';
$labels['organization'] = 'Organisation';
$labels['reply-to'] = 'Reply-To';
$labels['mailboxlist'] = 'Folders';
$labels['messagesfromto'] = 'Messages $from to $to of $count';
$labels['messagenrof'] = 'Message $nr of $count';
$labels['moveto'] = 'move to...';
$labels['download'] = 'download';
$labels['filename'] = 'File name';
$labels['filesize'] = 'File size';
$labels['preferhtml'] = 'Display HTML';
$labels['htmlmessage'] = 'HTML Message';
$labels['showknownimages'] = 'Show images from known senders';
$labels['prettydate'] = 'Pretty dates';
$labels['addtoaddressbook'] = 'Add to address book';
$labels['sun'] = 'Sun';
$labels['mon'] = 'Mon';
$labels['tue'] = 'Tue';
$labels['wed'] = 'Wed';
$labels['thu'] = 'Thu';
$labels['fri'] = 'Fri';
$labels['sat'] = 'Sat';
$labels['sunday'] = 'Sunday';
$labels['monday'] = 'Monday';
$labels['tuesday'] = 'Tuesday';
$labels['wednesday'] = 'Wednesday';
$labels['thursday'] = 'Thursday';
$labels['friday'] = 'Friday';
$labels['saturday'] = 'Saturday';
$labels['jan'] = 'Jan';
$labels['feb'] = 'Feb';
$labels['mar'] = 'Mar';
$labels['apr'] = 'Apr';
$labels['may'] = 'May';
$labels['jun'] = 'Jun';
$labels['jul'] = 'Jul';
$labels['aug'] = 'Aug';
$labels['sep'] = 'Sep';
$labels['oct'] = 'Oct';
$labels['nov'] = 'Nov';
$labels['dec'] = 'Dec';
$labels['longjan'] = 'January';
$labels['longfeb'] = 'February';
$labels['longmar'] = 'March';
$labels['longapr'] = 'April';
$labels['longmay'] = 'May';
$labels['longjun'] = 'June';
$labels['longjul'] = 'July';
$labels['longaug'] = 'August';
$labels['longsep'] = 'September';
$labels['longoct'] = 'October';
$labels['longnov'] = 'November';
$labels['longdec'] = 'December';
$labels['today'] = 'Today';
$labels['checkmail'] = 'Check for new messages';
$labels['writenewmessage'] = 'Create a new message';
$labels['replytomessage'] = 'Reply to sender';
$labels['replytoallmessage'] = 'Reply to sender and all recipients';
$labels['forwardmessage'] = 'Forward the message';
$labels['deletemessage'] = 'Delete message';
$labels['movemessagetotrash'] = 'Move message to "Deleted Items"';
$labels['printmessage'] = 'Print this message';
$labels['previousmessage'] = 'Show the previous message';
$labels['previousmessages'] = 'Show previous set of messages';
$labels['firstmessage'] = 'Show the first message';
$labels['firstmessages'] = 'Show first set of messages';
$labels['nextmessage'] = 'Show the next message';
$labels['nextmessages'] = 'Show next set of messages';
$labels['lastmessage'] = 'Show the last message';
$labels['lastmessages'] = 'Show last set of messages';
$labels['backtolist'] = 'Back to message list';
$labels['viewsource'] = 'Show source';
$labels['markmessages'] = 'Mark messages';
$labels['markread'] = 'As read';
$labels['markunread'] = 'As unread';
$labels['markflagged'] = 'As flagged';
$labels['markunflagged'] = 'As unflagged';
$labels['select'] = 'Select';
$labels['all'] = 'All';
$labels['none'] = 'None';
$labels['unread'] = 'Unread';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
$labels['purge'] = 'Purge';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
$labels['unlimited'] = 'unlimited';
$labels['quicksearch'] = 'Quick search';
$labels['resetsearch'] = 'Reset search';
$labels['openinextwin'] = 'Open in new window';
$labels['compose'] = 'Compose a message';
$labels['savemessage'] = 'Save this draft';
$labels['sendmessage'] = 'Send now';
$labels['addattachment'] = 'Attach a file';
$labels['charset'] = 'Charset';
$labels['editortype'] = 'Editor type';
$labels['returnreceipt'] = 'Return receipt';
$labels['checkspelling'] = 'Check spelling';
$labels['resumeediting'] = 'Resume editing';
$labels['revertto'] = 'Revert to';
$labels['attachments'] = 'Attachments';
$labels['upload'] = 'Upload';
$labels['close'] = 'Close';
$labels['low'] = 'Low';
$labels['lowest'] = 'Lowest';
$labels['normal'] = 'Normal';
$labels['high'] = 'High';
$labels['highest'] = 'Highest';
$labels['nosubject'] = '(no subject)';
$labels['showimages'] = 'Display images';
$labels['alwaysshow'] = 'Always show images from $sender';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Plain text';
$labels['savesentmessagein'] = 'Save sent message in';
$labels['dontsave'] = 'don\'t save';
$labels['maxuploadsize'] = 'Maximum allowed file size is $size';
$labels['addcc'] = 'Add Cc';
$labels['addbcc'] = 'Add Bcc';
$labels['addreplyto'] = 'Add Reply-To';
$labels['mdnrequest'] = 'The sender of this message has asked to be notified when you read this message. Do you wish to notify the sender?';
$labels['receiptread'] = 'Return Receipt (read)';
$labels['yourmessage'] = 'This is a Return Receipt for your message';
$labels['receiptnote'] = 'Note: This receipt only acknowledges that the message was displayed on the recipient\'s computer. There is no guarantee that the recipient has read or understood the message contents.';
$labels['name'] = 'Display name';
$labels['firstname'] = 'First name';
$labels['surname'] = 'Last name';
$labels['email'] = 'E-Mail';
$labels['addcontact'] = 'Add new contact';
$labels['editcontact'] = 'Edit contact';
$labels['edit'] = 'Edit';
$labels['cancel'] = 'Cancel';
$labels['save'] = 'Save';
$labels['delete'] = 'Delete';
$labels['newcontact'] = 'Create new contact card';
$labels['deletecontact'] = 'Delete selected contacts';
$labels['composeto'] = 'Compose mail to';
$labels['contactsfromto'] = 'Contacts $from to $to of $count';
$labels['print'] = 'Print';
$labels['export'] = 'Export';
$labels['exportvcards'] = 'Export contacts in vCard format';
$labels['previouspage'] = 'Show previous set';
$labels['firstpage'] = 'Show first set';
$labels['nextpage'] = 'Show next set';
$labels['lastpage'] = 'Show last set';
$labels['groups'] = 'Groups';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['import'] = 'Import';
$labels['importcontacts'] = 'Import contacts';
$labels['importfromfile'] = 'Import from file:';
$labels['importreplace'] = 'Replace the entire address book';
$labels['importtext'] = 'You can upload contacts from an existing address book. We currently support importing addresses from the vCard data format.';
$labels['done'] = 'Done';
$labels['settingsfor'] = 'Settings for';
$labels['preferences'] = 'Preferences';
$labels['userpreferences'] = 'User preferences';
$labels['editpreferences'] = 'Edit user preferences';
$labels['identities'] = 'Identities';
$labels['manageidentities'] = 'Manage identities for this account';
$labels['newidentity'] = 'New identity';
$labels['newitem'] = 'New item';
$labels['edititem'] = 'Edit item';
$labels['setdefault'] = 'Set default';
$labels['autodetect'] = 'Auto';
$labels['language'] = 'Language';
$labels['timezone'] = 'Time zone';
$labels['pagesize'] = 'Rows per page';
$labels['signature'] = 'Signature';
$labels['dstactive'] = 'Summer time';
$labels['htmleditor'] = 'Compose HTML messages';
$labels['htmlsignature'] = 'HTML signature';
$labels['previewpane'] = 'Show preview pane';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
$labels['logoutcompact'] = 'Compact Inbox on logout';
$labels['uisettings'] = 'User Interface';
$labels['serversettings'] = 'Server Settings';
$labels['mailboxview'] = 'Mailbox View';
$labels['mdnrequests'] = 'Sender notifications';
$labels['askuser'] = 'ask the user';
$labels['autosend'] = 'send automatically';
$labels['ignore'] = 'ignore';
$labels['readwhendeleted'] = 'Mark the message as read on delete';
$labels['flagfordeletion'] = 'Flag the message for deletion instead of delete';
$labels['showinlineimages'] = 'Display attached images below the message';
$labels['autosavedraft'] = 'Automatically save draft';
$labels['everynminutes'] = 'every $n minutes';
$labels['never'] = 'never';
+$labels['mimeparamfolding'] = 'Attachment names';
+$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Full RFC 2047 (other)';
+$labels['advancedoptions'] = 'advanced options';
$labels['messagesdisplaying'] = 'Displaying messages';
$labels['messagescomposition'] = 'Composing messages';
$labels['folder'] = 'Folder';
$labels['folders'] = 'Folders';
$labels['foldername'] = 'Folder name';
$labels['subscribed'] = 'Subscribed';
$labels['messagecount'] = 'Messages';
$labels['create'] = 'Create';
$labels['createfolder'] = 'Create new folder';
$labels['rename'] = 'Rename';
$labels['renamefolder'] = 'Rename folder';
$labels['deletefolder'] = 'Delete folder';
$labels['managefolders'] = 'Manage folders';
$labels['specialfolders'] = 'Special folders';
$labels['sortby'] = 'Sort by';
$labels['sortasc'] = 'Sort ascending';
$labels['sortdesc'] = 'Sort descending';
?>
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index 380352e79..28aab267d 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -1,305 +1,310 @@
<?php
/*
+-----------------------------------------------------------------------+
| language/en_US/labels.inc |
| |
| Language file of the RoundCube Webmail client |
| Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
@version $Id$
*/
$labels = array();
// login page
$labels['welcome'] = 'Welcome to $product';
$labels['username'] = 'Username';
$labels['password'] = 'Password';
$labels['server'] = 'Server';
$labels['login'] = 'Login';
// taskbar
$labels['logout'] = 'Logout';
$labels['mail'] = 'E-Mail';
$labels['settings'] = 'Personal Settings';
$labels['addressbook'] = 'Address Book';
// mailbox names
$labels['inbox'] = 'Inbox';
$labels['drafts'] = 'Drafts';
$labels['sent'] = 'Sent';
$labels['trash'] = 'Trash';
$labels['junk'] = 'Junk';
// message listing
$labels['subject'] = 'Subject';
$labels['from'] = 'Sender';
$labels['to'] = 'Recipient';
$labels['cc'] = 'Copy';
$labels['bcc'] = 'Bcc';
$labels['replyto'] = 'Reply-To';
$labels['date'] = 'Date';
$labels['size'] = 'Size';
$labels['priority'] = 'Priority';
$labels['organization'] = 'Organization';
// aliases
$labels['reply-to'] = $labels['replyto'];
$labels['mailboxlist'] = 'Folders';
$labels['messagesfromto'] = 'Messages $from to $to of $count';
$labels['messagenrof'] = 'Message $nr of $count';
$labels['moveto'] = 'move to...';
$labels['download'] = 'download';
$labels['filename'] = 'File name';
$labels['filesize'] = 'File size';
$labels['preferhtml'] = 'Display HTML';
$labels['htmlmessage'] = 'HTML Message';
$labels['showknownimages'] = 'Show images from known senders';
$labels['prettydate'] = 'Pretty dates';
$labels['addtoaddressbook'] = 'Add to address book';
// weekdays short
$labels['sun'] = 'Sun';
$labels['mon'] = 'Mon';
$labels['tue'] = 'Tue';
$labels['wed'] = 'Wed';
$labels['thu'] = 'Thu';
$labels['fri'] = 'Fri';
$labels['sat'] = 'Sat';
// weekdays long
$labels['sunday'] = 'Sunday';
$labels['monday'] = 'Monday';
$labels['tuesday'] = 'Tuesday';
$labels['wednesday'] = 'Wednesday';
$labels['thursday'] = 'Thursday';
$labels['friday'] = 'Friday';
$labels['saturday'] = 'Saturday';
// months short
$labels['jan'] = 'Jan';
$labels['feb'] = 'Feb';
$labels['mar'] = 'Mar';
$labels['apr'] = 'Apr';
$labels['may'] = 'May';
$labels['jun'] = 'Jun';
$labels['jul'] = 'Jul';
$labels['aug'] = 'Aug';
$labels['sep'] = 'Sep';
$labels['oct'] = 'Oct';
$labels['nov'] = 'Nov';
$labels['dec'] = 'Dec';
// months long
$labels['longjan'] = 'January';
$labels['longfeb'] = 'February';
$labels['longmar'] = 'March';
$labels['longapr'] = 'April';
$labels['longmay'] = 'May';
$labels['longjun'] = 'June';
$labels['longjul'] = 'July';
$labels['longaug'] = 'August';
$labels['longsep'] = 'September';
$labels['longoct'] = 'October';
$labels['longnov'] = 'November';
$labels['longdec'] = 'December';
$labels['today'] = 'Today';
// toolbar buttons
$labels['checkmail'] = 'Check for new messages';
$labels['writenewmessage'] = 'Create a new message';
$labels['replytomessage'] = 'Reply to sender';
$labels['replytoallmessage'] = 'Reply to sender and all recipients';
$labels['forwardmessage'] = 'Forward the message';
$labels['deletemessage'] = 'Delete message';
$labels['movemessagetotrash'] = 'Move message to trash';
$labels['printmessage'] = 'Print this message';
$labels['previousmessage'] = 'Show the previous message';
$labels['previousmessages'] = 'Show previous set of messages';
$labels['firstmessage'] = 'Show the first message';
$labels['firstmessages'] = 'Show first set of messages';
$labels['nextmessage'] = 'Show the next message';
$labels['nextmessages'] = 'Show next set of messages';
$labels['lastmessage'] = 'Show the last message';
$labels['lastmessages'] = 'Show last set of messages';
$labels['backtolist'] = 'Back to message list';
$labels['viewsource'] = 'Show source';
$labels['markmessages'] = 'Mark messages';
$labels['markread'] = 'As read';
$labels['markunread'] = 'As unread';
$labels['markflagged'] = 'As flagged';
$labels['markunflagged'] = 'As unflagged';
$labels['select'] = 'Select';
$labels['all'] = 'All';
$labels['none'] = 'None';
$labels['unread'] = 'Unread';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
$labels['purge'] = 'Purge';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
$labels['unlimited'] = 'unlimited';
$labels['quicksearch'] = 'Quick search';
$labels['resetsearch'] = 'Reset search';
$labels['openinextwin'] = 'Open in new window';
// message compose
$labels['compose'] = 'Compose a message';
$labels['savemessage'] = 'Save this draft';
$labels['sendmessage'] = 'Send now';
$labels['addattachment'] = 'Attach a file';
$labels['charset'] = 'Charset';
$labels['editortype'] = 'Editor type';
$labels['returnreceipt'] = 'Return receipt';
$labels['checkspelling'] = 'Check spelling';
$labels['resumeediting'] = 'Resume editing';
$labels['revertto'] = 'Revert to';
$labels['attachments'] = 'Attachments';
$labels['upload'] = 'Upload';
$labels['close'] = 'Close';
$labels['low'] = 'Low';
$labels['lowest'] = 'Lowest';
$labels['normal'] = 'Normal';
$labels['high'] = 'High';
$labels['highest'] = 'Highest';
$labels['nosubject'] = '(no subject)';
$labels['showimages'] = 'Display images';
$labels['alwaysshow'] = 'Always show images from $sender';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Plain text';
$labels['savesentmessagein'] = 'Save sent message in';
$labels['dontsave'] = 'don\'t save';
$labels['maxuploadsize'] = 'Maximum allowed file size is $size';
$labels['addcc'] = 'Add Cc';
$labels['addbcc'] = 'Add Bcc';
$labels['addreplyto'] = 'Add Reply-To';
// mdn
$labels['mdnrequest'] = 'The sender of this message has asked to be notified when you read this message. Do you wish to notify the sender?';
$labels['receiptread'] = 'Return Receipt (read)';
$labels['yourmessage'] = 'This is a Return Receipt for your message';
$labels['receiptnote'] = 'Note: This receipt only acknowledges that the message was displayed on the recipient\'s computer. There is no guarantee that the recipient has read or understood the message contents.';
// address boook
$labels['name'] = 'Display name';
$labels['firstname'] = 'First name';
$labels['surname'] = 'Last name';
$labels['email'] = 'E-Mail';
$labels['addcontact'] = 'Add new contact';
$labels['editcontact'] = 'Edit contact';
$labels['edit'] = 'Edit';
$labels['cancel'] = 'Cancel';
$labels['save'] = 'Save';
$labels['delete'] = 'Delete';
$labels['newcontact'] = 'Create new contact card';
$labels['deletecontact'] = 'Delete selected contacts';
$labels['composeto'] = 'Compose mail to';
$labels['contactsfromto'] = 'Contacts $from to $to of $count';
$labels['print'] = 'Print';
$labels['export'] = 'Export';
$labels['exportvcards'] = 'Export contacts in vCard format';
$labels['previouspage'] = 'Show previous set';
$labels['firstpage'] = 'Show first set';
$labels['nextpage'] = 'Show next set';
$labels['lastpage'] = 'Show last set';
$labels['groups'] = 'Groups';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['import'] = 'Import';
$labels['importcontacts'] = 'Import contacts';
$labels['importfromfile'] = 'Import from file:';
$labels['importreplace'] = 'Replace the entire address book';
$labels['importtext'] = 'You can upload contacts from an existing address book.<br/>We currently support importing addresses from the <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> data format.';
$labels['done'] = 'Done';
// settings
$labels['settingsfor'] = 'Settings for';
$labels['preferences'] = 'Preferences';
$labels['userpreferences'] = 'User preferences';
$labels['editpreferences'] = 'Edit user preferences';
$labels['identities'] = 'Identities';
$labels['manageidentities'] = 'Manage identities for this account';
$labels['newidentity'] = 'New identity';
$labels['newitem'] = 'New item';
$labels['edititem'] = 'Edit item';
$labels['setdefault'] = 'Set default';
$labels['autodetect'] = 'Auto';
$labels['language'] = 'Language';
$labels['timezone'] = 'Time zone';
$labels['pagesize'] = 'Rows per page';
$labels['signature'] = 'Signature';
$labels['dstactive'] = 'Daylight saving time';
$labels['htmleditor'] = 'Compose HTML messages';
$labels['htmlsignature'] = 'HTML signature';
$labels['previewpane'] = 'Show preview pane';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
$labels['logoutcompact'] = 'Compact Inbox on logout';
$labels['uisettings'] = 'User Interface';
$labels['serversettings'] = 'Server Settings';
$labels['mailboxview'] = 'Mailbox View';
$labels['mdnrequests'] = 'Sender notifications';
$labels['askuser'] = 'ask the user';
$labels['autosend'] = 'send automatically';
$labels['ignore'] = 'ignore';
$labels['readwhendeleted'] = 'Mark the message as read on delete';
$labels['flagfordeletion'] = 'Flag the message for deletion instead of delete';
$labels['showinlineimages'] = 'Display attached images below the message';
$labels['autosavedraft'] = 'Automatically save draft';
$labels['everynminutes'] = 'every $n minutes';
$labels['never'] = 'never';
$labels['messagesdisplaying'] = 'Displaying messages';
$labels['messagescomposition'] = 'Composing messages';
+$labels['mimeparamfolding'] = 'Attachment names';
+$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Full RFC 2047 (other)';
+$labels['advancedoptions'] = 'advanced options';
$labels['folder'] = 'Folder';
$labels['folders'] = 'Folders';
$labels['foldername'] = 'Folder name';
$labels['subscribed'] = 'Subscribed';
$labels['messagecount'] = 'Messages';
$labels['create'] = 'Create';
$labels['createfolder'] = 'Create new folder';
$labels['rename'] = 'Rename';
$labels['renamefolder'] = 'Rename folder';
$labels['deletefolder'] = 'Delete folder';
$labels['managefolders'] = 'Manage folders';
$labels['specialfolders'] = 'Special folders';
$labels['sortby'] = 'Sort by';
$labels['sortasc'] = 'Sort ascending';
$labels['sortdesc'] = 'Sort descending';
?>
diff --git a/program/localization/pl_PL/labels.inc b/program/localization/pl_PL/labels.inc
index b35deeeee..de87be38d 100644
--- a/program/localization/pl_PL/labels.inc
+++ b/program/localization/pl_PL/labels.inc
@@ -1,253 +1,258 @@
<?php
/*
+-----------------------------------------------------------------------+
| language/pl_PL/labels.inc |
| |
| Language file of the RoundCube Webmail client |
| Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
+-----------------------------------------------------------------------+
| Author: Tomasz Pajor <t.pajor@kei.pl> |
| Sławomir Cichoń <slawek.cichon@gmail.com> |
| Janusz Zamecki <janusz@zamecki.eu> |
| Mariusz Szulerecki <nob@force.eu.org> |
| Wojciech Szczepucha <donkoyote@gmail.com> |
| Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
@version $Id: labels.inc 1404 2008-05-19 08:12:54Z alec $
*/
$labels = array();
$labels['welcome'] = 'Witamy w $product';
$labels['username'] = 'Nazwa';
$labels['password'] = 'Hasło';
$labels['server'] = 'Serwer';
$labels['login'] = 'Zaloguj';
$labels['logout'] = 'Wyloguj';
$labels['mail'] = 'Poczta';
$labels['settings'] = 'Ustawienia';
$labels['addressbook'] = 'Książka adresowa';
$labels['inbox'] = 'Odebrane';
$labels['drafts'] = 'Kopie robocze';
$labels['sent'] = 'Wysłane';
$labels['trash'] = 'Kosz';
$labels['junk'] = 'Spam';
$labels['subject'] = 'Temat';
$labels['from'] = 'Nadawca';
$labels['to'] = 'Odbiorca';
$labels['cc'] = 'Kopia';
$labels['bcc'] = 'Ukryta kopia';
$labels['replyto'] = 'Odp. do';
$labels['date'] = 'Data';
$labels['size'] = 'Rozmiar';
$labels['priority'] = 'Priorytet';
$labels['organization'] = 'Organizacja';
$labels['reply-to'] = 'Odpowiedz do';
$labels['mailboxlist'] = 'Foldery';
$labels['messagesfromto'] = 'Wiadomości od $from do $to z $count';
$labels['messagenrof'] = 'Wiadomość $nr z $count';
$labels['moveto'] = 'Przenieś do...';
$labels['download'] = 'Pobierz';
$labels['filename'] = 'Nazwa pliku';
$labels['filesize'] = 'Rozmiar pliku';
$labels['preferhtml'] = 'Domyślny HTML';
$labels['htmlmessage'] = 'Wiadomość HTML';
$labels['showknownimages'] = 'Wyświetlaj obrazki od znanych nadawców';
$labels['prettydate'] = 'Ładne daty';
$labels['showinlineimages'] = 'Wyświetlaj załączone obrazki pod treścią wiadomości';
$labels['messagesdisplaying'] = 'Wyświetlanie wiadomości';
$labels['messagescomposition'] = 'Tworzenie wiadomości';
$labels['addtoaddressbook'] = 'Dodaj do książki adresowej ';
$labels['sun'] = 'Nd';
$labels['mon'] = 'Pn';
$labels['tue'] = 'Wt';
$labels['wed'] = 'Śr';
$labels['thu'] = 'Czw';
$labels['fri'] = 'Pt';
$labels['sat'] = 'Sb';
$labels['sunday'] = 'Niedziela';
$labels['monday'] = 'Poniedziałek';
$labels['tuesday'] = 'Wtorek';
$labels['wednesday'] = 'Środa';
$labels['thursday'] = 'Czwartek';
$labels['friday'] = 'Piątek';
$labels['saturday'] = 'Sobota';
$labels['jan'] = 'sty';
$labels['feb'] = 'lut';
$labels['mar'] = 'mar';
$labels['apr'] = 'kwi';
$labels['may'] = 'maj';
$labels['jun'] = 'cze';
$labels['jul'] = 'lip';
$labels['aug'] = 'sie';
$labels['sep'] = 'wrz';
$labels['oct'] = 'paź';
$labels['nov'] = 'lis';
$labels['dec'] = 'gru';
$labels['longjan'] = 'styczeń';
$labels['longfeb'] = 'luty';
$labels['longmar'] = 'marzec';
$labels['longapr'] = 'kwiecień';
$labels['longmay'] = 'maj';
$labels['longjun'] = 'czerwiec';
$labels['longjul'] = 'lipiec';
$labels['longaug'] = 'sierpień';
$labels['longsep'] = 'wrzesień';
$labels['longoct'] = 'październik';
$labels['longnov'] = 'listopad';
$labels['longdec'] = 'grudzień';
$labels['today'] = 'Dzisiaj';
$labels['checkmail'] = 'Sprawdź skrzynkę';
$labels['writenewmessage'] = 'Utwórz nową wiadomość';
$labels['replytomessage'] = 'Odpowiedz nadawcy';
$labels['replytoallmessage'] = 'Odpowiedz wszystkim';
$labels['forwardmessage'] = 'Prześlij dalej';
$labels['deletemessage'] = 'Usuń';
$labels['movemessagetotrash'] = 'Przenieś do Kosza';
$labels['printmessage'] = 'Drukuj';
$labels['previousmessage'] = 'Pokaż poprzednią';
$labels['previousmessages'] = 'Pokaż poprzednie';
$labels['firstmessage'] = 'Pokaż pierwszą';
$labels['firstmessages'] = 'Pokaż pierwsze';
$labels['nextmessage'] = 'Pokaż następną';
$labels['nextmessages'] = 'Pokaż następne';
$labels['lastmessage'] = 'Pokaż ostatnią';
$labels['lastmessages'] = 'Pokaż ostatnie';
$labels['backtolist'] = 'Pokaż listę wiadomości';
$labels['viewsource'] = 'Pokaż źródło';
$labels['markmessages'] = 'Oznacz wiadomość';
$labels['markread'] = 'Jako przeczytaną';
$labels['markunread'] = 'Jako nieprzeczytaną';
$labels['markflagged'] = 'Jako oflagowaną';
$labels['markunflagged'] = 'Jako nieoflagowaną';
$labels['select'] = 'Zaznacz';
$labels['all'] = 'Wszystkie';
$labels['none'] = 'Anuluj';
$labels['unread'] = 'Nieprzeczytane';
$labels['compact'] = 'Porządkuj';
$labels['empty'] = 'Opróżnij';
$labels['purge'] = 'Oczyść';
$labels['quota'] = 'Użyte miejsce';
$labels['unknown'] = 'nieznane';
$labels['unlimited'] = 'bez limitu';
$labels['quicksearch'] = 'Szybkie wyszukiwanie';
$labels['resetsearch'] = 'Wyczyść filtr';
$labels['openinextwin'] = 'Otwórz w nowym oknie';
$labels['compose'] = 'Utwórz wiadomość';
$labels['savemessage'] = 'Zapisz kopię roboczą';
$labels['sendmessage'] = 'Wyślij teraz';
$labels['addattachment'] = 'Dołącz plik';
$labels['charset'] = 'Kodowanie znaków';
$labels['editortype'] = 'Typ edytora';
$labels['returnreceipt'] = 'Potwierdzenie odbioru';
$labels['checkspelling'] = 'Sprawdź pisownię';
$labels['resumeediting'] = 'Zakończ sprawdzanie pisowni';
$labels['revertto'] = 'Powróć do';
$labels['attachments'] = 'Załączniki';
$labels['upload'] = 'Wyślij';
$labels['close'] = 'Zamknij';
$labels['low'] = 'Bardzo niski';
$labels['lowest'] = 'Niski';
$labels['normal'] = 'Normalny';
$labels['high'] = 'Wysoki';
$labels['highest'] = 'Bardzo wysoki';
$labels['nosubject'] = '(brak tematu)';
$labels['showimages'] = 'Wyświetl obrazki';
$labels['alwaysshow'] = 'Zawsze wyświetlaj obrazki od $sender';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Zwykły tekst';
$labels['savesentmessagein'] = 'Zapisz wiadomość w';
$labels['dontsave'] = 'nie zapisuj';
$labels['addcc'] = 'Dodaj Cc';
$labels['addbcc'] = 'Dodaj Bcc';
$labels['addreplyto'] = 'Dodaj Reply-To';
$labels['mdnrequest'] = 'Nadawca zażądał potwierdzenia przeczytania tej wiadomości. Czy chcesz go powiadomić?';
$labels['receiptread'] = 'Potwierdzenie otrzymania';
$labels['yourmessage'] = 'To jest potwierdzenie dostarczenia Twojej wiadomości';
$labels['receiptnote'] = 'Uwaga: To potwierdzenie dostarczenia wiadomości oznacza tylko, że wiadomość została wyświetlona na komputerze adresata. Nie ma żadnej gwarancji, że odbiorca przeczytał czy też zrozumiał treść wiadomości.';
$labels['name'] = 'Nazwa';
$labels['firstname'] = 'Imię';
$labels['surname'] = 'Nazwisko';
$labels['email'] = 'E-Mail';
$labels['addcontact'] = 'Dodaj nowy kontakt do książki adresowej';
$labels['editcontact'] = 'Edytuj kontakt';
$labels['edit'] = 'Edytuj';
$labels['cancel'] = 'Anuluj';
$labels['save'] = 'Zapisz';
$labels['delete'] = 'Usuń';
$labels['newcontact'] = 'Dodaj nowy kontakt';
$labels['deletecontact'] = 'Usuń zaznaczone kontakty';
$labels['composeto'] = 'Utwórz wiadomość dla wybranych kontaktów';
$labels['contactsfromto'] = 'Kontakty od $from do $to z $count';
$labels['print'] = 'Drukuj';
$labels['export'] = 'Eksportuj';
$labels['previouspage'] = 'poprzednia strona';
$labels['firstpage'] = 'pierwsza strona';
$labels['nextpage'] = 'następna strona';
$labels['lastpage'] = 'ostatnia strona';
$labels['groups'] = 'Grupy';
$labels['personaladrbook'] = 'Książka adresowa';
$labels['settingsfor'] = 'Ustawienia dla';
$labels['preferences'] = 'Preferencje';
$labels['userpreferences'] = 'Preferencje użytkownika';
$labels['editpreferences'] = 'Edytuj preferencje';
$labels['identities'] = 'Tożsamości';
$labels['manageidentities'] = 'Zarządzaj tożsamościami';
$labels['newidentity'] = 'Nowa tożsamość';
$labels['newitem'] = 'Nowy';
$labels['edititem'] = 'Edytuj';
$labels['setdefault'] = 'Domyślna';
$labels['language'] = 'Język';
$labels['timezone'] = 'Strefa czasowa';
$labels['pagesize'] = 'Wierszy na stronie';
$labels['signature'] = 'Podpis';
$labels['dstactive'] = 'Czas letni';
$labels['htmleditor'] = 'Twórz wiadomości HTML';
$labels['htmlsignature'] = 'Podpis w HTML';
$labels['previewpane'] = 'Pokaż podgląd';
$labels['skin'] = 'Wygląd interfejsu';
$labels['logoutclear'] = 'Przy wylogowaniu opróżnij Kosz';
$labels['logoutcompact'] = 'Przy wylogowaniu porządkuj folder Odebrane';
$labels['uisettings'] = 'Interfejs użytkownika';
$labels['serversettings'] = 'Ustawienia serwera';
$labels['mailboxview'] = 'Widok skrzynki pocztowej';
$labels['mdnrequests'] = 'Potwierdzenia odbioru';
$labels['askuser'] = 'spytaj użytkownika';
$labels['autosend'] = 'wyślij automatycznie';
$labels['ignore'] = 'ignoruj';
+$labels['mimeparamfolding'] = 'Nazwy załączników';
+$labels['2231folding'] = 'zgodne z RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'zgodne z RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'zgodne z RFC 2047 (inne)';
+$labels['advancedoptions'] = 'opcje zaawansowane';
$labels['readwhendeleted'] = 'Podczas usuwania oznacz wiadomość jako przeczytaną';
$labels['flagfordeletion'] = 'Oznacz wiadomość do usunięcia zamiast ją usuwać';
$labels['autosavedraft'] = 'Automatyczny zapis tworzonej wiadomości';
$labels['everynminutes'] = 'co $n minut';
$labels['never'] = 'nigdy';
$labels['folder'] = 'Folder';
$labels['folders'] = 'Foldery';
$labels['foldername'] = 'Nazwa folderu';
$labels['subscribed'] = 'Zasubskrybowany';
$labels['messagecount'] = 'Wiadomości';
$labels['create'] = 'Utwórz';
$labels['createfolder'] = 'Utwórz nowy folder';
$labels['rename'] = 'Zmień nazwę';
$labels['renamefolder'] = 'Zmień nazwę folderu';
$labels['deletefolder'] = 'Usuń folder';
$labels['managefolders'] = 'Zarządzaj folderami';
$labels['specialfolders'] = 'Foldery specjalne';
$labels['sortby'] = 'Sortuj wg';
$labels['sortasc'] = 'Rosnąco';
$labels['sortdesc'] = 'Malejąco';
$labels['import'] = 'Importuj';
$labels['importcontacts'] = 'Import kontaktów';
$labels['importfromfile'] = 'Import z pliku:';
$labels['importreplace'] = 'Zastąp całą książkę adresową';
$labels['importtext'] = 'Możesz dodać kontakty z istniejącej książki adresowej.<br/>Aktualnie możliwy jest import kontaktów w formacie <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>.';
$labels['done'] = 'Wykonane';
$labels['autodetect'] = '- wybór automatyczny -';
$labels['maxuploadsize'] = 'Maksymalny rozmiar pliku to $size';
$labels['exportvcards'] = 'Eksport kontaktów w formacie vCard';
?>
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 543895dec..d342124a4 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -1,451 +1,457 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/steps/mail/sendmail.inc |
| |
| This file is part of the RoundCube Webmail client |
| Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
| Compose a new mail message with all headers and attachments |
| and send it using the PEAR::Net_SMTP class or with PHP mail() |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
// remove all scripts and act as called in frame
$OUTPUT->reset();
$OUTPUT->framed = TRUE;
$savedraft = !empty($_POST['_draft']) ? TRUE : FALSE;
/****** checks ********/
if (!isset($_SESSION['compose']['id'])) {
raise_error(array('code' => 500, 'file' => __FILE__, 'message' => "Invalid compose ID"), true, false);
console("Sendmail error", $_SESSION['compose']);
$OUTPUT->show_message("An internal error occured. Please try again.", 'error');
$OUTPUT->send('iframe');
}
if (!$savedraft && empty($_POST['_to']) && empty($_POST['_cc']) && empty($_POST['_bcc']) && empty($_POST['_subject']) && $_POST['_message']) {
$OUTPUT->show_message('sendingfailed', 'error');
$OUTPUT->send('iframe');
}
if(!$savedraft && !empty($CONFIG['sendmail_delay'])) {
$wait_sec = time() - intval($CONFIG['sendmail_delay']) - intval($_SESSION['last_message_time']);
if($wait_sec < 0)
{
$OUTPUT->show_message('senttooquickly', 'error', array('sec' => $wait_sec * -1));
$OUTPUT->send('iframe');
}
}
/****** message sending functions ********/
// get identity record
function rcmail_get_identity($id)
{
global $USER, $OUTPUT;
if ($sql_arr = $USER->get_identity($id))
{
$out = $sql_arr;
$out['mailto'] = $sql_arr['email'];
$name = strpos($sql_arr['name'], ",") ? '"'.$sql_arr['name'].'"' : $sql_arr['name'];
$out['string'] = sprintf('%s <%s>',
rcube_charset_convert($name, RCMAIL_CHARSET, $OUTPUT->get_charset()),
$sql_arr['email']);
return $out;
}
return FALSE;
}
/**
* go from this:
* <img src=".../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" />
*
* to this:
*
* <IMG src="cid:smiley-cool.gif"/>
* ...
* ------part...
* Content-Type: image/gif
* Content-Transfer-Encoding: base64
* Content-ID: <smiley-cool.gif>
*/
function rcmail_attach_emoticons(&$mime_message)
{
global $CONFIG;
$htmlContents = $mime_message->getHtmlBody();
// remove any null-byte characters before parsing
$body = preg_replace('/\x00/', '', $htmlContents);
$last_img_pos = 0;
$searchstr = 'program/js/tiny_mce/plugins/emotions/img/';
// keep track of added images, so they're only added once
$included_images = array();
// find emoticon image tags
while ($pos = strpos($body, $searchstr, $last_img_pos))
{
$pos2 = strpos($body, '"', $pos);
$body_pre = substr($body, 0, $pos);
$image_name = substr($body,
$pos + strlen($searchstr),
$pos2 - ($pos + strlen($searchstr)));
// sanitize image name so resulting attachment doesn't leave images dir
$image_name = preg_replace('/[^a-zA-Z0-9_\.\-]/i','',$image_name);
$body_post = substr($body, $pos2);
if (! in_array($image_name, $included_images))
{
// add the image to the MIME message
$img_file = INSTALL_PATH . '/' . $searchstr . $image_name;
if(! $mime_message->addHTMLImage($img_file, 'image/gif', '', true, $image_name))
$OUTPUT->show_message("emoticonerror", 'error');
array_push($included_images, $image_name);
}
$body = $body_pre . $img_file . $body_post;
$last_img_pos = $pos2;
}
$mime_message->setHTMLBody($body);
}
/****** compose message ********/
if (strlen($_POST['_draft_saveid']) > 3)
$olddraftmessageid = get_input_value('_draft_saveid', RCUBE_INPUT_POST);
$message_id = sprintf('<%s@%s>', md5(uniqid('rcmail'.rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host']));
// set default charset
$input_charset = $OUTPUT->get_charset();
$message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $input_charset;
$mailto_regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/');
$mailto_replace = array(', ', ', ', '', ',');
// replace new lines and strip ending ', '
$mailto = preg_replace($mailto_regexp, $mailto_replace, get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset));
$mailcc = preg_replace($mailto_regexp, $mailto_replace, get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset));
$mailbcc = preg_replace($mailto_regexp, $mailto_replace, get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset));
if (empty($mailto) && !empty($mailcc)) {
$mailto = $mailcc;
$mailcc = null;
}
else if (empty($mailto))
$mailto = 'undisclosed-recipients:;';
// get sender name and address
$identity_arr = rcmail_get_identity(get_input_value('_from', RCUBE_INPUT_POST));
$from = $identity_arr['mailto'];
if (empty($identity_arr['string']))
$identity_arr['string'] = $from;
// compose headers array
$headers = array('Date' => date('r'),
'From' => rcube_charset_convert($identity_arr['string'], RCMAIL_CHARSET, $message_charset),
'To' => $mailto);
// additional recipients
if (!empty($mailcc))
$headers['Cc'] = $mailcc;
if (!empty($mailbcc))
$headers['Bcc'] = $mailbcc;
if (!empty($identity_arr['bcc']))
$headers['Bcc'] = ($headers['Bcc'] ? $headers['Bcc'].', ' : '') . $identity_arr['bcc'];
// add subject
$headers['Subject'] = trim(get_input_value('_subject', RCUBE_INPUT_POST, FALSE, $message_charset));
if (!empty($identity_arr['organization']))
$headers['Organization'] = $identity_arr['organization'];
if (!empty($_POST['_replyto']))
$headers['Reply-To'] = preg_replace($mailto_regexp, $mailto_replace, get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset));
else if (!empty($identity_arr['reply-to']))
$headers['Reply-To'] = $identity_arr['reply-to'];
if (!empty($_SESSION['compose']['reply_msgid']))
$headers['In-Reply-To'] = $_SESSION['compose']['reply_msgid'];
if (!empty($_SESSION['compose']['references']))
$headers['References'] = $_SESSION['compose']['references'];
if (!empty($_POST['_priority']))
{
$priority = intval($_POST['_priority']);
$a_priorities = array(1=>'highest', 2=>'high', 4=>'low', 5=>'lowest');
if ($str_priority = $a_priorities[$priority])
$headers['X-Priority'] = sprintf("%d (%s)", $priority, ucfirst($str_priority));
}
if (!empty($_POST['_receipt']))
{
$headers['Return-Receipt-To'] = $identity_arr['string'];
$headers['Disposition-Notification-To'] = $identity_arr['string'];
}
// additional headers
if ($CONFIG['http_received_header'])
{
$nldlm = $RCMAIL->config->header_delimiter() . "\t";
$headers['Received'] = wordwrap('from ' . (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ?
gethostbyaddr($_SERVER['HTTP_X_FORWARDED_FOR']).' ['.$_SERVER['HTTP_X_FORWARDED_FOR'].']'.$nldlm.' via ' : '') .
gethostbyaddr($_SERVER['REMOTE_ADDR']).' ['.$_SERVER['REMOTE_ADDR'].']'.$nldlm.'with ' .
$_SERVER['SERVER_PROTOCOL'].' ('.$_SERVER['REQUEST_METHOD'].'); ' . date('r'),
69, $nldlm);
}
$headers['Message-ID'] = $message_id;
$headers['X-Sender'] = $from;
if (!empty($CONFIG['useragent']))
$headers['User-Agent'] = $CONFIG['useragent'];
$isHtmlVal = strtolower(get_input_value('_is_html', RCUBE_INPUT_POST));
$isHtml = ($isHtmlVal == "1");
// fetch message body
$message_body = get_input_value('_message', RCUBE_INPUT_POST, TRUE, $message_charset);
// remove signature's div ID
if (!$savedraft && $isHtml)
$message_body = preg_replace('/\s*id="_rc_sig"/', '', $message_body);
// append generic footer to all messages
if (!$savedraft && !empty($CONFIG['generic_message_footer']) && ($footer = file_get_contents(realpath($CONFIG['generic_message_footer']))))
$message_body .= "\r\n" . rcube_charset_convert($footer, 'UTF-8', $message_charset);
// create extended PEAR::Mail_mime instance
$MAIL_MIME = new rcube_mail_mime($RCMAIL->config->header_delimiter());
// For HTML-formatted messages, construct the MIME message with both
// the HTML part and the plain-text part
if ($isHtml)
{
$MAIL_MIME->setHTMLBody($message_body);
// add a plain text version of the e-mail as an alternative part.
$h2t = new html2text($message_body);
$plainTextPart = wordwrap($h2t->get_text(), 998, "\r\n", true);
if (!strlen($plainTextPart))
{
// empty message body breaks attachment handling in drafts
$plainTextPart = "\r\n";
}
$MAIL_MIME->setTXTBody(html_entity_decode($plainTextPart, ENT_COMPAT, 'utf-8'));
// look for "emoticon" images from TinyMCE and copy into message as attachments
rcmail_attach_emoticons($MAIL_MIME);
}
else
{
$message_body = wordwrap($message_body, 75, "\r\n");
$message_body = wordwrap($message_body, 998, "\r\n", true);
if (!strlen($message_body))
{
// empty message body breaks attachment handling in drafts
$message_body = "\r\n";
}
$MAIL_MIME->setTXTBody($message_body, FALSE, TRUE);
}
// chose transfer encoding
$charset_7bit = array('ASCII', 'ISO-2022-JP', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-15');
$transfer_encoding = in_array(strtoupper($message_charset), $charset_7bit) ? '7bit' : '8bit';
// add stored attachments, if any
if (is_array($_SESSION['compose']['attachments']))
foreach ($_SESSION['compose']['attachments'] as $id => $attachment)
{
$dispurl = '/\ssrc\s*=\s*[\'"]?\S+display-attachment\S+file=rcmfile' . $id . '[\'"]?/';
$match = preg_match($dispurl, $message_body);
if ($isHtml && ($match > 0))
{
$message_body = preg_replace($dispurl, ' src="'.$attachment['name'].'"', $message_body);
$MAIL_MIME->setHTMLBody($message_body);
$MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name']);
}
else
{
$ctype = str_replace('image/pjpeg', 'image/jpeg', $attachment['mimetype']); // #1484914
// .eml attachments send inline
$MAIL_MIME->addAttachment($attachment['path'],
$ctype,
$attachment['name'], true,
($ctype == 'message/rfc822' ? $transfer_encoding : 'base64'),
($ctype == 'message/rfc822' ? 'inline' : 'attachment'),
- $message_charset);
+ $message_charset, '', '',
+ $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,
+ $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL
+ );
}
}
// add submitted attachments
if (is_array($_FILES['_attachments']['tmp_name']))
foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath)
{
$ctype = $files['type'][$i];
$ctype = str_replace('image/pjpeg', 'image/jpeg', $ctype); // #1484914
$MAIL_MIME->addAttachment($filepath, $ctype, $files['name'][$i], true,
- ($ctype == 'message/rfc822' ? $transfer_encoding : 'base64'),
- 'attachment', $message_charset);
+ $ctype == 'message/rfc822' ? $transfer_encoding : 'base64',
+ 'attachment', $message_charset, '', '',
+ $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,
+ $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL
+ );
}
// encoding settings for mail composing
$MAIL_MIME->setParam(array(
'text_encoding' => $transfer_encoding,
'html_encoding' => 'quoted-printable',
'head_encoding' => 'quoted-printable',
'head_charset' => $message_charset,
'html_charset' => $message_charset,
'text_charset' => $message_charset,
));
// encoding subject header with mb_encode provides better results with asian characters
if (function_exists("mb_encode_mimeheader"))
{
mb_internal_encoding($message_charset);
$headers['Subject'] = mb_encode_mimeheader($headers['Subject'], $message_charset, 'Q');
mb_internal_encoding(RCMAIL_CHARSET);
}
// pass headers to message object
$MAIL_MIME->headers($headers);
// Begin SMTP Delivery Block
if (!$savedraft)
{
$sent = rcmail_deliver_message($MAIL_MIME, $from, $mailto);
// return to compose page if sending failed
if (!$sent)
{
$OUTPUT->show_message("sendingfailed", 'error');
$OUTPUT->send('iframe');
}
// save message sent time
if (!empty($CONFIG['sendmail_delay']))
$_SESSION['last_message_time'] = time();
// set replied/forwarded flag
if ($_SESSION['compose']['reply_uid'])
$IMAP->set_flag($_SESSION['compose']['reply_uid'], 'ANSWERED');
else if ($_SESSION['compose']['forward_uid'])
$IMAP->set_flag($_SESSION['compose']['forward_uid'], 'FORWARDED');
} // End of SMTP Delivery Block
// Determine which folder to save message
if ($savedraft)
$store_target = $CONFIG['drafts_mbox'];
else
$store_target = isset($_POST['_store_target']) ? get_input_value('_store_target', RCUBE_INPUT_POST) : $CONFIG['sent_mbox'];
if ($store_target)
{
// check if mailbox exists
if (!in_array_nocase($store_target, $IMAP->list_mailboxes()))
{
// folder may be existing but not subscribed (#1485241)
if (!in_array_nocase($store_target, $IMAP->list_unsubscribed()))
$store_folder = $IMAP->create_mailbox($store_target, TRUE);
else if ($IMAP->subscribe($store_target))
$store_folder = TRUE;
}
else
$store_folder = TRUE;
// append message to sent box
if ($store_folder)
$saved = $IMAP->save_message($store_target, $MAIL_MIME->getMessage());
// raise error if saving failed
if (!$saved)
{
raise_error(array('code' => 800, 'type' => 'imap', 'file' => __FILE__,
'message' => "Could not save message in $store_target"), TRUE, FALSE);
if ($savedraft) {
$OUTPUT->show_message('errorsaving', 'error');
$OUTPUT->send('iframe');
}
}
if ($olddraftmessageid)
{
// delete previous saved draft
$a_deleteid = $IMAP->search($CONFIG['drafts_mbox'], 'HEADER Message-ID', $olddraftmessageid);
$deleted = $IMAP->delete_message($IMAP->get_uid($a_deleteid[0], $CONFIG['drafts_mbox']), $CONFIG['drafts_mbox']);
// raise error if deletion of old draft failed
if (!$deleted)
raise_error(array('code' => 800, 'type' => 'imap', 'file' => __FILE__,
'message' => "Could not delete message from ".$CONFIG['drafts_mbox']), TRUE, FALSE);
}
}
if ($savedraft)
{
$msgid = strtr($message_id, array('>' => '', '<' => ''));
// remember new draft-uid
$draftids = $IMAP->search($CONFIG['drafts_mbox'], 'HEADER Message-ID', $msgid);
$_SESSION['compose']['param']['_draft_uid'] = $IMAP->get_uid($draftids[0], $CONFIG['drafts_mbox']);
// display success
$OUTPUT->show_message('messagesaved', 'confirmation');
// update "_draft_saveid" and the "cmp_hash" to prevent "Unsaved changes" warning
$OUTPUT->command('set_draft_id', $msgid);
$OUTPUT->command('compose_field_hash', true);
// start the auto-save timer again
$OUTPUT->command('auto_save_start');
$OUTPUT->send('iframe');
}
else
{
rcmail_compose_cleanup();
if ($store_folder && !$saved)
$OUTPUT->command('sent_successfully', 'error', rcube_label('errorsavingsent'));
else
$OUTPUT->command('sent_successfully', 'confirmation', rcube_label('messagesent'));
$OUTPUT->send('iframe');
}
?>
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index f115ad900..04079e16f 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -1,386 +1,398 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/steps/settings/func.inc |
| |
| This file is part of the RoundCube Webmail client |
| Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
| Provide functionality for user's settings & preferences |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
if (!$OUTPUT->ajax_call)
$OUTPUT->set_pagetitle(rcube_label('preferences'));
function rcmail_user_prefs_form($attrib)
{
global $RCMAIL;
$config = $RCMAIL->config->all();
$no_override = is_array($config['dont_override']) ? array_flip($config['dont_override']) : array();
// add some labels to client
rcube_add_label('nopagesizewarning');
list($form_start, $form_end) = get_form_tags($attrib, 'save-prefs');
unset($attrib['form']);
$out = $form_start;
$table = new html_table(array('cols' => 2));
// show language selection
if (!isset($no_override['language'])) {
$a_lang = $RCMAIL->list_languages();
asort($a_lang);
$field_id = 'rcmfd_lang';
$select_lang = new html_select(array('name' => '_language', 'id' => $field_id));
$select_lang->add(array_values($a_lang), array_keys($a_lang));
$table->add('title', html::label($field_id, Q(rcube_label('language'))));
$table->add(null, $select_lang->show($RCMAIL->user->language));
}
// show page size selection
if (!isset($no_override['timezone'])) {
$field_id = 'rcmfd_timezone';
$select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id, 'onchange' => "document.getElementById('rcmfd_dst').disabled=this.selectedIndex==0"));
$select_timezone->add(rcube_label('autodetect'), 'auto');
$select_timezone->add('(GMT -11:00) Midway Island, Samoa', '-11');
$select_timezone->add('(GMT -10:00) Hawaii', '-10');
$select_timezone->add('(GMT -9:30) Marquesas Islands', '-9.5');
$select_timezone->add('(GMT -9:00) Alaska', '-9');
$select_timezone->add('(GMT -8:00) Pacific Time (US/Canada)', '-8');
$select_timezone->add('(GMT -7:00) Mountain Time (US/Canada)', '-7');
$select_timezone->add('(GMT -6:00) Central Time (US/Canada), Mexico City', '-6');
$select_timezone->add('(GMT -5:00) Eastern Time (US/Canada), Bogota, Lima', '-5');
$select_timezone->add('(GMT -4:30) Caracas', '-4.5');
$select_timezone->add('(GMT -4:00) Atlantic Time (Canada), La Paz', '-4');
$select_timezone->add('(GMT -3:30) Nfld Time (Canada), Nfld, S. Labador', '-3.5');
$select_timezone->add('(GMT -3:00) Brazil, Buenos Aires, Georgetown', '-3');
$select_timezone->add('(GMT -2:00) Mid-Atlantic', '-2');
$select_timezone->add('(GMT -1:00) Azores, Cape Verde Islands', '-1');
$select_timezone->add('(GMT) Western Europe, London, Lisbon, Casablanca', '0');
$select_timezone->add('(GMT +1:00) Central European Time', '1');
$select_timezone->add('(GMT +2:00) EET: Kaliningrad, South Africa', '2');
$select_timezone->add('(GMT +3:00) Baghdad, Kuwait, Riyadh, Moscow, Nairobi', '3');
$select_timezone->add('(GMT +3:30) Tehran', '3.5');
$select_timezone->add('(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi', '4');
$select_timezone->add('(GMT +4:30) Kabul', '4.5');
$select_timezone->add('(GMT +5:00) Ekaterinburg, Islamabad, Karachi', '5');
$select_timezone->add('(GMT +5:30) Chennai, Kolkata, Mumbai, New Delhi', '5.5');
$select_timezone->add('(GMT +5:45) Kathmandu', '5.75');
$select_timezone->add('(GMT +6:00) Almaty, Dhaka, Colombo', '6');
$select_timezone->add('(GMT +6:30) Cocos Islands, Myanmar', '6.5');
$select_timezone->add('(GMT +7:00) Bangkok, Hanoi, Jakarta', '7');
$select_timezone->add('(GMT +8:00) Beijing, Perth, Singapore, Taipei', '8');
$select_timezone->add('(GMT +8:45) Caiguna, Eucla, Border Village', '8.75');
$select_timezone->add('(GMT +9:00) Tokyo, Seoul, Yakutsk', '9');
$select_timezone->add('(GMT +9:30) Adelaide, Darwin', '9.5');
$select_timezone->add('(GMT +10:00) EAST/AEST: Sydney, Guam, Vladivostok', '10');
$select_timezone->add('(GMT +10:30) New South Wales', '10.5');
$select_timezone->add('(GMT +11:00) Magadan, Solomon Islands', '11');
$select_timezone->add('(GMT +11:30) Norfolk Island', '11.5');
$select_timezone->add('(GMT +12:00) Auckland, Wellington, Kamchatka', '12');
$select_timezone->add('(GMT +12:45) Chatham Islands', '12.75');
$select_timezone->add('(GMT +13:00) Tonga, Pheonix Islands', '13');
$select_timezone->add('(GMT +14:00) Kiribati', '14');
$table->add('title', html::label($field_id, Q(rcube_label('timezone'))));
$table->add(null, $select_timezone->show((string)$config['timezone']));
}
// daylight savings
if (!isset($no_override['dst_active'])) {
$field_id = 'rcmfd_dst';
$input_dst = new html_checkbox(array('name' => '_dst_active', 'id' => $field_id, 'value' => 1, 'disabled' => ($config['timezone'] === 'auto')));
$table->add('title', html::label($field_id, Q(rcube_label('dstactive'))));
$table->add(null, $input_dst->show($config['dst_active']));
}
// MM: Show checkbox for toggling 'pretty dates'
if (!isset($no_override['prettydate'])) {
$field_id = 'rcmfd_prettydate';
$input_prettydate = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
$table->add('title', html::label($field_id, Q(rcube_label('prettydate'))));
$table->add(null, $input_prettydate->show($config['prettydate']?1:0));
}
// show page size selection
if (!isset($no_override['pagesize'])) {
$field_id = 'rcmfd_pgsize';
$input_pagesize = new html_inputfield(array('name' => '_pagesize', 'id' => $field_id, 'size' => 5));
$table->add('title', html::label($field_id, Q(rcube_label('pagesize'))));
$table->add(null, $input_pagesize->show($config['pagesize']));
}
// show drop-down for available skins
if (!isset($no_override['skin'])) {
$skins = rcmail_get_skins();
if (count($skins) > 1) {
$field_id = 'rcmfd_skin';
$input_skin = new html_select(array('name'=>'_skin', 'id'=>$field_id));
foreach($skins as $skin)
$input_skin->add($skin, $skin);
$table->add('title', html::label($field_id, Q(rcube_label('skin'))));
$table->add(null, $input_skin->show($config['skin']));
}
}
$out .= html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('uisettings'))) . $table->show($attrib));
$table = new html_table(array('cols' => 2));
// show config parameter for preview pane
if (!isset($no_override['preview_pane'])) {
$field_id = 'rcmfd_preview';
$input_preview = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1));
$table->add('title', html::label($field_id, Q(rcube_label('previewpane'))));
$table->add(null, $input_preview->show($config['preview_pane']?1:0));
}
if (!isset($no_override['mdn_requests'])) {
$field_id = 'rcmfd_mdn_requests';
$select_mdn_requests = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
$select_mdn_requests->add(rcube_label('askuser'), 0);
$select_mdn_requests->add(rcube_label('autosend'), 1);
$select_mdn_requests->add(rcube_label('ignore'), 2);
$table->add('title', html::label($field_id, Q(rcube_label('mdnrequests'))));
$table->add(null, $select_mdn_requests->show($config['mdn_requests']));
}
$out .= html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('mailboxview'))) . $table->show($attrib));
$table = new html_table(array('cols' => 2));
// show checkbox for HTML/plaintext messages
if (!isset($no_override['prefer_html'])) {
$field_id = 'rcmfd_htmlmsg';
$input_preferhtml = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
'onchange' => JS_OBJECT_NAME.'.toggle_prefer_html(this)'));
$table->add('title', html::label($field_id, Q(rcube_label('preferhtml'))));
$table->add(null, $input_preferhtml->show($config['prefer_html']?1:0));
}
// show checkbox for displaying images from people in the addressbook
if (!isset($no_override['addrbook_show_images'])) {
$field_id = 'rcmfd_addrbook_show_images';
$input_addrbook_show_images = new html_checkbox(array('name' => '_addrbook_show_images', 'id' => $field_id,
'value' => 1, 'disabled' => $config['prefer_html']?0:1));
$table->add('title', html::label($field_id, Q(rcube_label('showknownimages'))));
$table->add(null, $input_addrbook_show_images->show($config['addrbook_show_images']?1:0));
}
if (!isset($no_override['inline_images'])) {
$field_id = 'rcmfd_inline_images';
$input_inline_images = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
$table->add('title', html::label($field_id, Q(rcube_label('showinlineimages'))));
$table->add(null, $input_inline_images->show($config['inline_images']?1:0));
}
$out .= html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('messagesdisplaying'))) . $table->show($attrib));
$table = new html_table(array('cols' => 2));
// Show checkbox for HTML Editor
if (!isset($no_override['htmleditor'])) {
$field_id = 'rcmfd_htmleditor';
$input_htmleditor = new html_checkbox(array('name' => '_htmleditor', 'id' => $field_id, 'value' => 1));
$table->add('title', html::label($field_id, Q(rcube_label('htmleditor'))));
$table->add(null, $input_htmleditor->show($config['htmleditor']?1:0));
}
if (!isset($no_override['draft_autosave'])) {
$field_id = 'rcmfd_autosave';
$select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
$select_autosave->add(rcube_label('never'), 0);
foreach (array(3, 5, 10) as $i => $min)
$select_autosave->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min*60);
$table->add('title', html::label($field_id, Q(rcube_label('autosavedraft'))));
$table->add(null, $select_autosave->show($config['draft_autosave']));
}
+ if (!isset($no_override['mime_param_folding'])) {
+ $field_id = 'rcmfd_param_folding';
+ $select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
+ $select_param_folding->add(rcube_label('2231folding'), 0);
+ $select_param_folding->add(rcube_label('miscfolding'), 1);
+ $select_param_folding->add(rcube_label('2047folding'), 2);
+
+ $table->set_row_attribs('advanced');
+ $table->add('title', html::label($field_id, Q(rcube_label('mimeparamfolding'))));
+ $table->add(null, $select_param_folding->show($config['mime_param_folding']));
+ }
+
$out .= html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('messagescomposition'))) . $table->show($attrib));
// Configure special folders
if (!isset($no_override['default_imap_folders'])) {
$RCMAIL->imap_init(true);
$select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true, 'maxlength' => 30));
$table = new html_table(array('cols' => 2));
if (!isset($no_override['drafts_mbox'])) {
$table->add('title', Q(rcube_label('drafts')));
$table->add(null, $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox", 'onchange' => "document.getElementById('rcmfd_autosave').disabled=this.selectedIndex==0")));
}
if (!isset($no_override['sent_mbox'])) {
$table->add('title', Q(rcube_label('sent')));
$table->add(null, $select->show($config['sent_mbox'], array('name' => "_sent_mbox")));
}
if (!isset($no_override['junk_mbox'])) {
$table->add('title', Q(rcube_label('junk')));
$table->add(null, $select->show($config['junk_mbox'], array('name' => "_junk_mbox")));
}
if (!isset($no_override['trash_mbox'])) {
$table->add('title', Q(rcube_label('trash')));
$table->add(null, $select->show($config['trash_mbox'], array('name' => "_trash_mbox")));
}
$out .= html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('specialfolders'))) . $table->show($attrib));
}
$table = new html_table(array('cols' => 2));
if (!isset($no_override['read_when_deleted'])) {
$field_id = 'rcmfd_read_deleted';
$input_readdeleted = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
$table->add('title', html::label($field_id, Q(rcube_label('readwhendeleted'))));
$table->add(null, $input_readdeleted->show($config['read_when_deleted']?1:0));
}
if (!isset($no_override['flag_for_deletion'])) {
$field_id = 'rcmfd_flag_for_deletion';
$input_flagfordeletion = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
$table->add('title', html::label($field_id, Q(rcube_label('flagfordeletion'))));
$table->add(null, $input_flagfordeletion->show($config['flag_for_deletion']?1:0));
}
// Trash purging on logout
if (!isset($no_override['logout_purge'])) {
$field_id = 'rcmfd_logout_purge';
$input_purge = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
$table->add('title', html::label($field_id, Q(rcube_label('logoutclear'))));
$table->add(null, $input_purge->show($config['logout_purge']?1:0));
}
// INBOX compacting on logout
if (!isset($no_override['logout_expunge'])) {
$field_id = 'rcmfd_logout_expunge';
$input_expunge = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
$table->add('title', html::label($field_id, Q(rcube_label('logoutcompact'))));
$table->add(null, $input_expunge->show($config['logout_expunge']?1:0));
}
$out .= html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('serversettings'))) . $table->show($attrib));
return $out . $form_end;
}
function rcmail_identities_list($attrib)
{
global $OUTPUT, $USER;
// add id to message list table if not specified
if (!strlen($attrib['id']))
$attrib['id'] = 'rcmIdentitiesList';
// define list of cols to be displayed
$a_show_cols = array('name', 'email');
// create XHTML table
$out = rcube_table_output($attrib, $USER->list_identities(), $a_show_cols, 'identity_id');
// set client env
$OUTPUT->add_gui_object('identitieslist', $attrib['id']);
return $out;
}
// similar function as in /steps/addressbook/edit.inc
function get_form_tags($attrib, $action, $add_hidden=array())
{
global $EDIT_FORM, $RCMAIL;
$form_start = '';
if (!strlen($EDIT_FORM))
{
$hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task));
$hiddenfields->add(array('name' => '_action', 'value' => $action));
if ($add_hidden)
$hiddenfields->add($add_hidden);
$form_start = !strlen($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : '';
$form_start .= $hiddenfields->show();
}
$form_end = (!strlen($EDIT_FORM) && !strlen($attrib['form'])) ? '</form>' : '';
$form_name = strlen($attrib['form']) ? $attrib['form'] : 'form';
if (!strlen($EDIT_FORM))
$RCMAIL->output->add_gui_object('editform', $form_name);
$EDIT_FORM = $form_name;
return array($form_start, $form_end);
}
function rcmail_get_skins()
{
$path = 'skins';
$skins = array();
$dir = opendir($path);
if (!$dir)
return false;
while (($file = readdir($dir)) !== false)
{
$filename = $path.'/'.$file;
if (is_dir($filename) && is_readable($filename)
&& !in_array($file, array('.', '..', '.svn')))
$skins[] = $file;
}
closedir($dir);
return $skins;
}
$OUTPUT->set_env('multiple_identities', $RCMAIL->config->get('multiple_identities', true));
// register UI objects
$OUTPUT->add_handlers(array(
'userprefs' => 'rcmail_user_prefs_form',
'identitieslist' => 'rcmail_identities_list',
'itentitieslist' => 'rcmail_identities_list' // keep this for backward compatibility
));
?>
diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc
index 8e2a27953..b3b75ffe4 100644
--- a/program/steps/settings/save_prefs.inc
+++ b/program/steps/settings/save_prefs.inc
@@ -1,85 +1,86 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/steps/settings/save_prefs.inc |
| |
| This file is part of the RoundCube Webmail client |
| Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
| Save user preferences to DB and to the current session |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
$a_user_prefs = array(
'language' => isset($_POST['_language']) ? get_input_value('_language', RCUBE_INPUT_POST) : $CONFIG['language'],
'timezone' => isset($_POST['_timezone']) ? (is_numeric($_POST['_timezone']) ? floatval($_POST['_timezone']) : get_input_value('_timezone', RCUBE_INPUT_POST)) : $CONFIG['timezone'],
'dst_active' => isset($_POST['_dst_active']) ? TRUE : FALSE,
'pagesize' => is_numeric($_POST['_pagesize']) ? max(2, intval($_POST['_pagesize'])) : $CONFIG['pagesize'],
'prettydate' => isset($_POST['_pretty_date']) ? TRUE : FALSE,
'prefer_html' => isset($_POST['_prefer_html']) ? TRUE : FALSE,
'addrbook_show_images' => isset($_POST['_addrbook_show_images']) ? TRUE : FALSE,
'htmleditor' => isset($_POST['_htmleditor']) ? TRUE : FALSE,
'inline_images' => isset($_POST['_inline_images']) ? TRUE : FALSE,
'preview_pane' => isset($_POST['_preview_pane']) ? TRUE : FALSE,
'read_when_deleted' => isset($_POST['_read_when_deleted']) ? TRUE : FALSE,
'flag_for_deletion' => isset($_POST['_flag_for_deletion']) ? TRUE : FALSE,
'logout_purge' => isset($_POST['_logout_purge']) ? TRUE : FALSE,
'logout_expunge' => isset($_POST['_logout_expunge']) ? TRUE : FALSE,
'draft_autosave' => isset($_POST['_draft_autosave']) ? intval($_POST['_draft_autosave']) : 0,
+ 'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0,
'mdn_requests' => isset($_POST['_mdn_requests']) ? intval($_POST['_mdn_requests']) : 0,
'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
'drafts_mbox' => get_input_value('_drafts_mbox', RCUBE_INPUT_POST),
'sent_mbox' => get_input_value('_sent_mbox', RCUBE_INPUT_POST),
'junk_mbox' => get_input_value('_junk_mbox', RCUBE_INPUT_POST),
'trash_mbox' => get_input_value('_trash_mbox', RCUBE_INPUT_POST),
);
// don't override these parameters
foreach ((array)$CONFIG['dont_override'] as $p)
$a_user_prefs[$p] = $CONFIG[$p];
// special handling for 'default_imap_folders'
if (in_array('default_imap_folders', (array)$CONFIG['dont_override'])) {
foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p)
$a_user_prefs[$p] = $CONFIG[$p];
}
else {
$a_user_prefs['default_imap_folders'] = array('INBOX');
foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) {
if ($a_user_prefs[$p])
$a_user_prefs['default_imap_folders'][] = $a_user_prefs[$p];
}
}
// switch UI language
if (isset($_POST['_language'])) {
$RCMAIL->load_language($a_user_prefs['language']);
}
// switch skin
$OUTPUT->set_skin($a_user_prefs['skin']);
// force min size
if ($a_user_prefs['pagesize'] < 1)
$a_user_prefs['pagesize'] = 10;
if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['pagesize'] > $CONFIG['max_pagesize']))
$a_user_prefs['pagesize'] = (int) $CONFIG['max_pagesize'];
if ($USER->save_prefs($a_user_prefs))
$OUTPUT->show_message('successfullysaved', 'confirmation');
// go to next step
rcmail_overwrite_action('preferences');
?>
diff --git a/skins/default/settings.css b/skins/default/settings.css
index 8c229a15c..9621a21a2 100644
--- a/skins/default/settings.css
+++ b/skins/default/settings.css
@@ -1,255 +1,270 @@
/***** RoundCube|Mail settings task styles *****/
#tabsbar
{
position: absolute;
top: 50px;
left: 220px;
right: 20px;
height: 22px;
border-bottom: 1px solid #999999;
white-space: nowrap;
/* css hack for IE */
width: expression((parseInt(document.documentElement.clientWidth)-240)+'px');
}
span.tablink,
span.tablink-selected
{
float: left;
width: 100px;
height: 24px !important;
height: 22px;
background: url('images/tab_pas.gif') top left no-repeat;
}
span.tablink-selected
{
background: url('images/tab_act.gif') top left no-repeat;
}
span.tablink a,
span.tablink-selected a
{
display: block;
padding-left: 10px;
padding-top: 5px;
color: #555555;
text-decoration: none;
}
span.tablink-selected a
{
color: #000000;
}
#userprefs-box
{
position: absolute;
top: 95px;
left: 20px;
bottom: 60px;
width: 640px;
overflow: auto;
border: 1px solid #999999;
/* css hack for IE */
height: expression((parseInt(document.documentElement.clientHeight)-155)+'px');
}
#userprefs-box table td.title
{
color: #666666;
padding-right: 10px;
}
+#userprefs-box table tr.advanced
+{
+ display: none;
+}
+
#identities-list,
#folder-manager
{
position: absolute;
top: 95px;
left: 20px;
}
#folder-manager
{
width: 600px;
bottom: 140px;
overflow: auto;
border: 1px solid #999999;
/* css hack for IE */
height: expression((parseInt(document.documentElement.clientHeight)-235)+'px');
}
#folder-manager.droptarget
{
border: 1px solid #CC3333;
background-color: #FFFFA6;
}
#identities-list
{
bottom: 60px;
width: 420px;
border: 1px solid #999999;
/* css hack for IE */
height: expression((parseInt(document.documentElement.clientHeight)-160)+'px');
}
#listbuttons
{
position: absolute;
left: 20px;
bottom: 18px;
}
#identities-table
{
width: 420px;
table-layout: fixed;
background-color: #F9F9F9;
}
#identities-table tbody td
{
cursor: default;
overflow: hidden;
text-overflow: ellipsis;
}
#identities-table thead td.name
{
width: 55%;
}
#identities-table thead td.email
{
width: 45%;
}
#identity-frame
{
position: relative;
margin-top: 20px;
border: 1px solid #999999;
}
#identity-details
{
position: absolute;
top: 95px;
left: 450px;
right: 20px;
bottom: 60px;
border: 1px solid #999999;
overflow: auto;
/* css hack for IE */
width: expression((parseInt(document.documentElement.clientWidth)-470)+'px');
height: expression((parseInt(document.documentElement.clientHeight)-160)+'px');
}
#identity-details table td.title
{
color: #666666;
font-weight: bold;
text-align: right;
padding-right: 10px;
}
#bottomboxes
{
position: absolute;
width: 600px;
height: 120px;
left: 20px;
bottom: 20px;
}
#userprefs-title,
#identity-title,
div.boxtitle,
#subscription-table thead td
{
height: 12px !important;
padding: 4px 20px 3px 6px;
border-bottom: 1px solid #999999;
color: #333333;
font-size: 11px;
font-weight: bold;
background-color: #EBEBEB;
background-image: url(images/listheader_aqua.gif);
}
div.settingsbox
{
width: 600px;
margin-top: 20px;
border: 1px solid #999999;
}
div.settingspart
{
display: block;
padding: 10px;
}
#subscription-table
{
width: 100%;
}
#subscription-table tbody td
{
height: 20px;
padding-left: 6px;
padding-right: 10px;
white-space: nowrap;
border-bottom: 1px solid #EBEBEB;
background-color: #F9F9F9;
cursor: default;
}
#subscription-table tr.virtual td
{
color: #666;
}
#subscription-table tr.selected td,
#subscription-table tr.selected td a
{
color: #FFFFFF;
background-color: #CC3333;
}
#subscription-table tr.droptarget td,
#subscription-table tr.droptarget td a
{
background-color: #FFFFA6;
}
#subscription-table thead td.name
{
width: 250px;
}
#subscription-table thead td.msgcount
{
width: 90px;
}
#subscription-table thead td.subscribed
{
width: 90px;
}
fieldset
{
margin-bottom: 0.5em;
border: 1px solid #999999;
padding: 4px 8px 9px 8px;
}
legend
{
color: #999999;
}
+
+div.advswitch
+{
+ white-space: nowrap;
+ text-align: right;
+ position: absolute;
+ bottom: 35px;
+ left: 20px;
+ width: 640px;
+}
diff --git a/skins/default/templates/settings.html b/skins/default/templates/settings.html
index 2b69f423d..0bc0f1853 100644
--- a/skins/default/templates/settings.html
+++ b/skins/default/templates/settings.html
@@ -1,27 +1,43 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
<link rel="stylesheet" type="text/css" href="/settings.css" />
+<script type="text/javascript">
+function show_adv(box)
+{
+ var rows = document.getElementsByTagName('TR');
+ for(var i=0; i<rows.length; i++)
+ if(rows[i].className && rows[i].className.match(/advanced/))
+ rows[i].style.display = box.checked ? (bw.ie ? 'block' : 'table-row') : 'none';
+}
+</script>
</head>
<body>
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
<roundcube:include file="/includes/settingstabs.html" />
<div id="userprefs-box">
<div id="userprefs-title"><roundcube:label name="userpreferences" /></div>
<div style="padding:15px">
<roundcube:object name="userprefs">
</div>
</div>
-<p id="listbuttons"><roundcube:button command="save" type="input" class="button mainaction" label="save" /></p>
+<p id="listbuttons">
+<roundcube:button command="save" type="input" class="button mainaction" label="save" />
+</p>
+
+<div class="advswitch">
+<label for="advswitch"><roundcube:label name="advancedoptions"><label>
+<input type="checkbox" id="advswitch" name="_advanced" value="0" onclick="show_adv(this)" />
+</div>
<roundcube:include file="/includes/settingscripts.html" />
</body>
</html>

File Metadata

Mime Type
text/x-diff
Expires
Sat, Mar 1, 10:25 AM (10 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
166678
Default Alt Text
(239 KB)

Event Timeline