From 9b0096dfd647b506f22ea836649accc763e1f3e8 Mon Sep 17 00:00:00 2001 From: Mariusz Krzaczkowski Date: Thu, 23 Feb 2017 10:32:38 +0100 Subject: [PATCH 01/10] Updated Thunderbird Labels Plugin for Roundcube Webmail --- plugins/thunderbird_labels/Changelog | 7 + plugins/thunderbird_labels/LICENSE.md | 10 + plugins/thunderbird_labels/README | 41 --- plugins/thunderbird_labels/composer.json | 1 + .../skins/yetiforce/tb_label.css | 245 ------------------ .../skins/yetiforce/thunderbird_24.png | Bin 1770 -> 0 bytes .../skins/yetiforce/thunderbird_32.png | Bin 2662 -> 0 bytes .../thunderbird_labels/thunderbird_labels.php | 56 ++-- version.php | 4 +- 9 files changed, 47 insertions(+), 317 deletions(-) create mode 100644 plugins/thunderbird_labels/LICENSE.md delete mode 100644 plugins/thunderbird_labels/README delete mode 100644 plugins/thunderbird_labels/skins/yetiforce/tb_label.css delete mode 100644 plugins/thunderbird_labels/skins/yetiforce/thunderbird_24.png delete mode 100644 plugins/thunderbird_labels/skins/yetiforce/thunderbird_32.png diff --git a/plugins/thunderbird_labels/Changelog b/plugins/thunderbird_labels/Changelog index e989e8a0..f576f0f0 100644 --- a/plugins/thunderbird_labels/Changelog +++ b/plugins/thunderbird_labels/Changelog @@ -1,3 +1,10 @@ +v1.1.3 +--- +- dsoares pull request: Enable or disable the plugin button on message selection. +- dsoares pull request: unecessary skin checks removed +- dsoares pull request: deprecated code fixed +- petrkle pull request: Czech translation fixes + v1.0 --- + added Ukranian translation by Mykyta Solomko diff --git a/plugins/thunderbird_labels/LICENSE.md b/plugins/thunderbird_labels/LICENSE.md new file mode 100644 index 00000000..ec629c5e --- /dev/null +++ b/plugins/thunderbird_labels/LICENSE.md @@ -0,0 +1,10 @@ +Copyright (c) Michael Kefeder (MK) and contributors +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. + +THIS SOFTWARE IS PROVIDED BY MK AND THE 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 MK 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. diff --git a/plugins/thunderbird_labels/README b/plugins/thunderbird_labels/README deleted file mode 100644 index 0bb54b65..00000000 --- a/plugins/thunderbird_labels/README +++ /dev/null @@ -1,41 +0,0 @@ -Thunderbird Labels Plugin for Roundcube Webmail ---- - -Features ---- -- Displays the message rows using the same colors as Thunderbird does -- Label of a message can be changed/set exactly like in Thunderbird -- works together with the contextmenu plugin (when it's active and configured) -- Shortcut keys 0-5 set the label for the marked messages -- currently available translations: English, French, German, Polish, Russian - -TODO ---- -- allow users to have an arbitrary number of labels - -INSTALL ---- -- unpack to plugins directory -- add 'thunderbird_labels' to $rcmail_config['plugins'] in main.inc.php - -CONFIGURE ---- -See config.inc.php - - - tb_label_enable = true/false (can be changed by user in prefs UI) - - tb_label_modify_labels/false = true - - tb_label_enable_contextmenu = true/false - - tb_label_enable_shortcuts = true/false (can be changed by user in prefs UI) - - tb_label_style = 'bullets' or 'thunderbird' - -Author ---- -Michael Kefeder -http://code.google.com/p/rcmail-thunderbird-labels/ - -History ---- -This plugin is based on a patch I found for roundcube 0.3 a long time ago. -Since roundcube is now able to handle the labels without modification of its source I decided to create a plugin. -There exists a "Tags plugin for RoundCube" http://sourceforge.net/projects/tagspluginrc/ which does something similar, my plugin emulates thunderbirds behaviour better I think (coloring the message rows for example) - diff --git a/plugins/thunderbird_labels/composer.json b/plugins/thunderbird_labels/composer.json index f0af1415..47b1cf06 100644 --- a/plugins/thunderbird_labels/composer.json +++ b/plugins/thunderbird_labels/composer.json @@ -2,6 +2,7 @@ "name": "weird-birds/thunderbird_labels", "type": "roundcube-plugin", "keywords": ["mail","labels","tags"], + "license": "BSD-2-Clause", "authors": [ { "name": "Michael Kefeder", diff --git a/plugins/thunderbird_labels/skins/yetiforce/tb_label.css b/plugins/thunderbird_labels/skins/yetiforce/tb_label.css deleted file mode 100644 index d44d8eb2..00000000 --- a/plugins/thunderbird_labels/skins/yetiforce/tb_label.css +++ /dev/null @@ -1,245 +0,0 @@ -/** -* Author: -* Michael Kefeder -* http://code.google.com/p/rcmail-thunderbird-labels/ -* -* CSS is Based on a patch for roundcube 0.3 I found a long time ago -*/ - -#tb_label_popuplink { - background-image: url(thunderbird_32.png); - /*background-repeat: repeat;*/ - background-position: 50% 0px; - width: 32px; - height: 13px; - padding: 28px 2px 0px 2px; - margin: 0px 5px 0px 5px; -} - -#tb_label_popup -{ - width: auto; - position: absolute; -} - -#tb_label_popup a.active -{ - color: inherit; /* fix for firefox */ -} - -.toolbarmenu li.label0, -.toolbarmenu li.label0 a.active -{ - color: #EEE; -} -/* Colors for single/preview message window headers display */ -table.label1 -{ - background-color: #FCC; -} -table.label2 -{ - background-color: #FC3; -} -table.label3 -{ - background-color: #3C3; -} -table.label4 -{ - background-color: #99F; -} -table.label5 -{ - background-color: #C9C; -} - -/* Support for Thunderbird label: definition of the 5 label color */ -/* Unselected (unfocused) messages */ -#messagelist tr.label1 td, -#messagelist tr.label1 td a, -.toolbarmenu li.label1, -.toolbarmenu li.label1 a.active, -span.label1, -.records-table tr.selected td span.label1 -{ - color: #FF0000 !important; -} - -#messagelist tr.label2 td, -#messagelist tr.label2 td a, -.toolbarmenu li.label2, -.toolbarmenu li.label2 a.active, -span.label2, -.records-table tr.selected td span.label2 -{ - color: #FF9900 !important; -} - - -#messagelist tr.label3 td, -#messagelist tr.label3 td a, -.toolbarmenu li.label3, -.toolbarmenu li.label3 a.active, -span.label3, -.records-table tr.selected td span.label3 -{ - color: #009900 !important; -} - -#messagelist tr.label4 td, -#messagelist tr.label4 td a, -span.label4, -.records-table tr.selected td span.label4 -{ - color: #3333FF !important; -} - -/* lighter blue for dark-grey popup... */ -.toolbarmenu li.label4, -.toolbarmenu li.label4 a.active -{ - color: #0CF; -} - -#messagelist tr.label5 td, -#messagelist tr.label5 td a, -span.label5, -.records-table tr.selected td span.label5 -{ - color: #993399 !important; -} - -/* lighter purple for dark-grey popup... */ -.toolbarmenu li.label5, -.toolbarmenu li.label5 a.active -{ - color: #B6F; -} - -/* Selected messages */ -#messagelist tr.selected.label1 td, -#messagelist tr.selected.label1 td a -{ - color: #FFFFFF; - background-color: #FF0000; -} - -#messagelist tr.selected.label2 td, -#messagelist tr.selected.label2 td a -{ - color: #FFFFFF; - background-color: #FF9900; -} - -#messagelist tr.selected.label3 td, -#messagelist tr.selected.label3 td a -{ - color: #FFFFFF; - background-color: #009900; -} - -#messagelist tr.selected.label4 td, -#messagelist tr.selected.label4 td a -{ - color: #FFFFFF; - background-color: #3333FF; -} - -#messagelist tr.selected.label5 td, -#messagelist tr.selected.label5 td a -{ - color: #FFFFFF; - background-color: #993399; -} - -span.tb_label_dots { -float: right; -height: 0px; -display: block; -position:relative; -} - -/* hack for firefox : doesnt display the bullets at the correct height */ -@-moz-document url-prefix() { - span.tb_label_dots { - top: -19px; - } -} - -span.tb_label_dots span { - font-size: 32px; - vertical-align: middle; - line-height: 0px; -} - - - -div#labelbox { - white-space: nowrap; - position: absolute; - right: 67px; - top: 40px; -} - -div#labelbox span { - margin: 0 3px; - padding: 3px; - border: 1px solid black; - border-radius: 3px; - color: #black; - font-weight: bold; -} - -div#labelbox span.tb_label_span1 { - background-color: #FF2200; -} - -div#labelbox span.tb_label_span2 { - background-color: #FF9900; -} - -div#labelbox span.tb_label_span3 { - background-color: #00CC00; -} - -div#labelbox span.tb_label_span4 { - background-color: #0CF; -} - -div#labelbox span.tb_label_span5 { - background-color: #FF33FF; -} - -/* icon for settings-section */ -#sections-table tbody #rcmrowthunderbird_labels td.section { - background-image: url(thunderbird_24.png); - background-position: 3px 3px; -} - -/* Non-labeled selected message: changed to make it look "like" Thunderbird */ -/*#messagelist tr.selected td -{ - color: #000000; - background-color: #F0CB82; -} -*/ -/* Addition for selected RCM "flagged" message */ -/*#messagelist tr.selected.flagged td -{ - color: #FFFFFF; - background-color: #CC3333; -} -*/ -/* Non specific message : changed to make it look like Thunderbird */ -/*#messagelist tr.selected td a -{ - color: #000000; -} -*/ -/* Addition for selected RCM "flagged" message */ -/*#messagelist tr.selected.flagged td a -{ - color: #FFFFFF; -} -*/ diff --git a/plugins/thunderbird_labels/skins/yetiforce/thunderbird_24.png b/plugins/thunderbird_labels/skins/yetiforce/thunderbird_24.png deleted file mode 100644 index bf89c13bc39ccbc3e47780089ed6879e44a49bc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1770 zcmVBi6LUaH~epZ;D2IA^O1> ztuZDh5{)q=Viu#p1{SXyErD>a_G*EKHi8iagQzJXA^5`kvTrl9^K$y3Fc+^)`~NbN zoHPIDd46Z|KLr1!+S=ME0A5&F$N}K`_3NmttVDNrHwFg>AqWCVPEJNN8U-N)4u^ve z4-eDNpFgh>MRBF7svnmuS>hpt{F(l|d3$?10GNe^g}kk;4FFJCS&6%M?~>fyTsRz# zWdJe({Bmk)3aP27Y}>YNa5|kNJw5$br%#^_o+kOe0E9vzoIQIMZnxVzGc)r<*L9H)0?zr|R_mjM3l}01i7dZ( z@#3FkS^oQl3m2xX#g2{+lAoW?=O?;x;|8gysNlh1FfSgD-%}Ljo25&aLf3VKLZL4V z&6O<6i6cjj*a6`2qa7U`bMEoz(W5yR@cDdbY;4>xIy(ATmSw@^ zav>`#3#Ms;F$S;K3rUioC<=64hpMVjRnA~iJ?s;WZQb!eIf#u(PETldY;qeqRyhYy3! zqS1rFAgZgYQCwWi@7=ri>rg1v7L7*J+-^7Zcswvo6Pl*MZnr}a1cbw32!enO8#ch{ zbV8P8XqpCH*Wq%x8~~u}I_TKg81nP;k(QQ*)vH%izu%uXJUrYT4u_4btSn?_X9EBd zi3CJZv=FAGq=0h{Q53Od%NC@jrXn7X6Gc(5Y}vBSvzS14?b?MqckYmaf&#pK`*z*f z*jUrd%#4_woh_|hyVl}sv)RBHgQ6&wkfv$SGz|dY^Z7t2MKl_Pq9_CaR8`~5g{ z=n!gaYx9POho2~lVk;;ppdOD0hG8I)NWgBlgAjsfG>YWpWa}&_r4U6Clu|S{He!5y z9Fvoi&9PYQ+eM2OnKd;vCINseSFU7DOia8=BobmyP7d3=c{Ao5*zI=f-Db1FVoNC) zW6(4W_wV1w=;){s4u_vcB9Y%qlB5R$0bX8S4hjH6Lqp@SSnQvwsSW8O_PM$m| zuUfULQIe#*>FMbeZ{EB?W@aWF4hLjehA4^+rLl6WILLf;J{C+LR7Fc@Ksp}4phe!m|8Kp#AK003CLc(D-~=dSrPkpx z#sC1 znxG!&> z7f6yM96NRl4Gj%^WMqUe#-605rR|8tVywQtUIBpe@^T9w0GOr;(=_qbye%my!NZ3S z0Ra2=?{`EZks4js%NS#(s;bmxvpr2uPyb_WZEXku_U+q;`ucis&T;eRO&Ep&UDx6D zdXbx(3v_jL(XOtpU(6TTv}x1)3k4-5C4Va_D&jkL?rb@6;)K1lw3GqBo;`d1Gv{ab za?Ww-(j`n!PydAI*|TS0j1fWzr<5WmCkFsfTwILi=4QBDE|QXxLNYTm_i38e;B-0> z2m}lO7#J7;0Jz<5aL%o}VgB>0>gnl0Pfrj2SCy5OVOD_5iS+mPV{~-XO48TYhrYf( zQ2d{I{`@%rV8@OfIB?(q0HC3v0RsaAaJ${y?RHy9CMG5T;ETWM-;tv@Y}G_wk^lez M07*qoM6N<$f>cpG;Q#;t diff --git a/plugins/thunderbird_labels/skins/yetiforce/thunderbird_32.png b/plugins/thunderbird_labels/skins/yetiforce/thunderbird_32.png deleted file mode 100644 index c8254dd650a3d70d25484defeb5d0690a94413f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2662 zcmWkw2|QF?AHE~T*r&cJlk6thVq!{TZxVwB&6}7gWX3YKYAlf$J7sC`+DFLpSsGh! z7;6nuYVaweWY7ytk<3%n^29OVx> z3<{oUp`ky)0eZ{I+!Xk8a1^$cr-Lg(xA7zz00{p$=nz~rCL6qfT9{tA>cDw#?|b>G zy;L~2IoK#$+_qLq!SjF0@BMsytfHdwtdAeQ?tPt@=kUP`m*`?_TG3KXM722bg7!T{ z!qufThKo#e2-Nh?uuE!ZTo^@19A{FMTatZeU`&xuUFB0-<8SiU z+rO{3_TT3!WWVS){v)k^tr`HFn(qpLt?Bj@pMZR(mb2y$_04bPPtqJT%v4Hyxm+l4 zlSsT()9B69WZzr8r7A66vv$uQr_Nz%qPe*_HVrj4(sXBrly-f7Z+m^S*v4R$e`j|$ z5zg0_r6p--Xc&yuR9EM8b^^ywoKVU;=Q|AyeE4807yipN9%T`8rU#N>syKzfB~(;Y zbPRv|*v80>_&GoLS551h<==bjvDmr!<>lCk?~=g4&`@-Jy*6Ot>?~(#X?ZZs%se)| zzTNey!6Pd;Fz|E+DzVv#l~7sfmO;!RQtxmHjiaYS3}mz5I6gX?t+zDMA-8(Z01B+V ztA-RdHcFP3mLBX5=c7<4^NWjz6!^=$_<-=eRr9sa-ZhD-#=o1C8TjXSxi7KtUb*ry zo%I?39gaKHdDZSH1K*_=wB+!uPpf0ET*Bzrqy(?VxkCsbEB`T$_?@<~wKW6=8QC(n zB9>dmBqs@3r1_NVBmsZ|f1InllF}gtp8sJnCa(wlN`K=_AnP?X-``p( z#ld*f-H-lxEf?W5kQ1S%sd-FiYHN4D>E5bh`>$z{iWe`g1q26olvGlyD5O^y!q!Cz z!PW7DHI~8GVr~q7VZn?ZJZwg*w`Tz-WlQy(E{Z zAMed$F{Y<)4S)L7Y<(rejm@GBVcsaE8bsyiOXtaE^~IjF%Iy4l_X01_Ayc5Q-X*up zkchBIL#e5$*%FCS2)=@hSwJ2kTvS}lXJ2#kWKH`{<@pCYKjRV;6I00A6*@ihPg9K^ zg4k>=U6D{x4oJ6VmWWlBW-MIqivFV5Oc^a=~Oi&9b7Zun+*X?vnHpEeg>4zT&9uuV*e?xpG+Z2AluV z6%$paonWG=q8R;0Xj|~V0G&co6zFh8diwj9tJ||?eSLk8J}k~32xJ~A1S>5Yl!wN9 zeWvwjbFs=~KFHp5-D}y4W@aGT>`Sj7Y>j1If*qcCuq6{_G{FR}RXaq|=C}~xs@>me z>gplh-ivXotE<*_c4sYBZ?FSYk7+o#aJblb&Qxt_S*6-a+txVZ^=&=okL|GDw{LOU zIWextF0|-9g901?0z@K_P5&|R_tz>2T~Kvux_#khgS(i1=ub}q>IgOmk7^qF7O)#; zH2d{yg%RtSlcRKQl99i#RC`40>J_6&D}(%35AtE~&34K7an)2Pr3KoO4-u+OA95VmG9J3C7!3KNC^z`A_M?^$|!I^M>nvBRwn z>7*%1+>L_s$;ilL=jLj=)nzNmrhXTKMvFz7(D|b;)ZO3m!(cFb{<^Ip>+YKYPYWLw zoA3gG+S1I*O~ew3M4HSmFA-=Q^|i8wMQ&~eb zFREb*@-ZX%{YwGh`+K^&Vr=a`LJFI!suukhc{K;lDK7{-=@$eV;I)r#^H?`LsZ<<+ zAZB=Hn!kp{GGcjsHp3-Y!0zz#K{T#Ehhqp&Y4f76(I+#@^*`^c&MYb?TIm+fuR@*9(oje9g{o|KCWD;SiUtl`&g{0MM0r z+R@X|add)03eTcxo=mrB1vdv321Qx$xrt^Fmqr^U7m^Y-nl<{XK!DC*Fi2^I_AIBO=;-KR0RT9A_UuS&NW%>s8{_?e4G@YhK|c#{;pSuU z0t~6APoDzx!NDs@DJfC3n?~o(Dff$-6qL~qb=Fh*+`SM$Tzq^T`OOh0c7Twege-!? z;dIqkzo7JGu7bSH?0)a?sOWni&`=D-uoe}KjU$HdBoRY{$YgTRrm7X?2{nD{c6QkI z*DQekf!1GO2+;TT!iaWumm!d=MwdQKgjVg diff --git a/plugins/thunderbird_labels/thunderbird_labels.php b/plugins/thunderbird_labels/thunderbird_labels.php index 1ade296c..13960a14 100644 --- a/plugins/thunderbird_labels/thunderbird_labels.php +++ b/plugins/thunderbird_labels/thunderbird_labels.php @@ -114,7 +114,7 @@ public function prefs_section($args) { $args['list']['thunderbird_labels'] = array( 'id' => 'thunderbird_labels', - 'section' => Q($this->gettext('tb_label_options')) + 'section' => rcube::Q($this->gettext('tb_label_options')) ); return $args; @@ -213,24 +213,24 @@ public function prefs_save($args) $dont_override = (array) $this->rc->config->get('dont_override', array()); if (!in_array('tb_label_enable', $dont_override)) - $args['prefs']['tb_label_enable'] = get_input_value('tb_label_enable', RCUBE_INPUT_POST) ? true : false; + $args['prefs']['tb_label_enable'] = rcube_utils::get_input_value('tb_label_enable', rcube_utils::INPUT_POST) ? true : false; if (!in_array('tb_label_enable_shortcuts', $dont_override)) - $args['prefs']['tb_label_enable_shortcuts'] = get_input_value('tb_label_enable_shortcuts', RCUBE_INPUT_POST) ? true : false; + $args['prefs']['tb_label_enable_shortcuts'] = rcube_utils::get_input_value('tb_label_enable_shortcuts', rcube_utils::INPUT_POST) ? true : false; if (!in_array('tb_label_style', $dont_override)) - $args['prefs']['tb_label_style'] = get_input_value('tb_label_style', RCUBE_INPUT_POST); + $args['prefs']['tb_label_style'] = rcube_utils::get_input_value('tb_label_style', rcube_utils::INPUT_POST); if (!in_array('tb_label_custom_labels', $dont_override) && $this->rc->config->get('tb_label_modify_labels')) { $args['prefs']['tb_label_custom_labels'] = array( 0 => $this->gettext('label0'), - 1 => get_input_value('tb_label_custom_labels1', RCUBE_INPUT_POST), - 2 => get_input_value('tb_label_custom_labels2', RCUBE_INPUT_POST), - 3 => get_input_value('tb_label_custom_labels3', RCUBE_INPUT_POST), - 4 => get_input_value('tb_label_custom_labels4', RCUBE_INPUT_POST), - 5 => get_input_value('tb_label_custom_labels5', RCUBE_INPUT_POST) + 1 => rcube_utils::get_input_value('tb_label_custom_labels1', rcube_utils::INPUT_POST), + 2 => rcube_utils::get_input_value('tb_label_custom_labels2', rcube_utils::INPUT_POST), + 3 => rcube_utils::get_input_value('tb_label_custom_labels3', rcube_utils::INPUT_POST), + 4 => rcube_utils::get_input_value('tb_label_custom_labels4', rcube_utils::INPUT_POST), + 5 => rcube_utils::get_input_value('tb_label_custom_labels5', rcube_utils::INPUT_POST) ); } @@ -243,7 +243,7 @@ public function show_tb_label_contextmenu($args) $li = html::tag('li', array('class' => 'submenu'), - ''.Q($this->gettext('tb_label_contextmenu_title')).'' . $this->_gen_label_submenu($args, 'tb_label_ctxm_submenu')); + ''.rcube::Q($this->gettext('tb_label_contextmenu_title')).'' . $this->_gen_label_submenu($args, 'tb_label_ctxm_submenu')); $out .= html::tag('ul', array('id' => 'tb_label_ctxm_mainmenu'), $li); $this->api->output->add_footer(html::div(array('style' => 'display: none;'), $out)); } @@ -266,7 +266,7 @@ private function _gen_label_submenu($args, $id) public function read_single_flags($args) { - #write_log($this->name, print_r(($args['object']), true)); + #rcube::write_log($this->name, print_r(($args['object']), true)); if (!isset($args['object'])) { return; } @@ -281,7 +281,7 @@ public function read_single_flags($args) if (preg_match('/^\$?label/', $flag)) { $flag_no = preg_replace('/^\$?label/', '', $flag); - #write_log($this->name, "Single message Flag: ".$flag." Flag_no:".$flag_no); + #rcube::write_log($this->name, "Single message Flag: ".$flag." Flag_no:".$flag_no); $this->message_tb_labels[] = (int)$flag_no; } } @@ -295,19 +295,17 @@ public function read_single_flags($args) */ public function color_headers($p) { - #write_log($this->name, print_r($p, true)); + #rcube::write_log($this->name, print_r($p, true)); # -- always write array, even when empty - if($p['class'] == 'headers-table'){ - $p['content'] .= ''; - } + $p['content'] .= ''; return $p; } public function read_flags($args) { - #write_log($this->name, print_r($args, true)); + #rcube::write_log($this->name, print_r($args, true)); // add color information for all messages // dont loop over all messages if we dont have any highlights or no msgs if (!isset($args['messages']) or !is_array($args['messages'])) { @@ -317,7 +315,7 @@ public function read_flags($args) // loop over all messages and add $LabelX info to the extra_flags foreach($args['messages'] as $message) { - #write_log($this->name, print_r($message->flags, true)); + #rcube::write_log($this->name, print_r($message->flags, true)); $message->list_flags['extra_flags']['tb_labels'] = array(); # always set extra_flags, needed for javascript later! if (is_array($message->flags)) foreach ($message->flags as $flagname => $flagvalue) @@ -327,7 +325,7 @@ public function read_flags($args) if (preg_match('/^\$?label/', $flag)) { $flag_no = preg_replace('/^\$?label/', '', $flag); - #write_log($this->name, "Flag:".$flag." Flag_no:".$flag_no); + #rcube::write_log($this->name, "Flag:".$flag." Flag_no:".$flag_no); $message->list_flags['extra_flags']['tb_labels'][] = (int)$flag_no; } } @@ -338,21 +336,21 @@ public function read_flags($args) // set flags in IMAP server function set_flags() { - #write_log($this->name, print_r($_GET, true)); + #rcube::write_log($this->name, print_r($_GET, true)); $imap = $this->rc->imap; - $cbox = get_input_value('_cur', RCUBE_INPUT_GET); - $mbox = get_input_value('_mbox', RCUBE_INPUT_GET); - $toggle_label = get_input_value('_toggle_label', RCUBE_INPUT_GET); - $flag_uids = get_input_value('_flag_uids', RCUBE_INPUT_GET); + $cbox = rcube_utils::get_input_value('_cur', rcube_utils::INPUT_GET); + $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GET); + $toggle_label = rcube_utils::get_input_value('_toggle_label', rcube_utils::INPUT_GET); + $flag_uids = rcube_utils::get_input_value('_flag_uids', rcube_utils::INPUT_GET); $flag_uids = explode(',', $flag_uids); - $unflag_uids = get_input_value('_unflag_uids', RCUBE_INPUT_GET); + $unflag_uids = rcube_utils::get_input_value('_unflag_uids', rcube_utils::INPUT_GET); $unflag_uids = explode(',', $unflag_uids); $imap->conn->flags = array_merge($imap->conn->flags, $this->add_tb_flags); - #write_log($this->name, print_r($flag_uids, true)); - #write_log($this->name, print_r($unflag_uids, true)); + #rcube::write_log($this->name, print_r($flag_uids, true)); + #rcube::write_log($this->name, print_r($unflag_uids, true)); if (!is_array($unflag_uids) || !is_array($flag_uids)) diff --git a/version.php b/version.php index efbd0f56..eec05b05 100644 --- a/version.php +++ b/version.php @@ -1,5 +1,5 @@ '2017.01.31', - 'version' => '0.0.24' + 'patch' => '2017.02.23', + 'version' => '0.0.25' ]; From af372a8729b9dea376fbbeb1604cd30d18b45bd4 Mon Sep 17 00:00:00 2001 From: Mariusz Krzaczkowski Date: Tue, 28 Feb 2017 08:57:37 +0100 Subject: [PATCH 02/10] Updated Thunderbird Labels Plugin for Roundcube Webmail --- plugins/thunderbird_labels/composer.json | 40 +- plugins/thunderbird_labels/config.inc.php | 20 +- .../thunderbird_labels/localization/bg_BG.inc | 9 +- .../thunderbird_labels/localization/ca_ES.inc | 9 +- .../thunderbird_labels/localization/cs_CZ.inc | 1 - .../thunderbird_labels/localization/de_DE.inc | 9 +- .../thunderbird_labels/localization/en_US.inc | 9 +- .../thunderbird_labels/localization/es_ES.inc | 18 +- .../thunderbird_labels/localization/fr_FR.inc | 11 +- .../thunderbird_labels/localization/hu_HU.inc | 9 +- .../thunderbird_labels/localization/it_IT.inc | 9 +- .../thunderbird_labels/localization/lv_LV.inc | 9 +- .../thunderbird_labels/localization/pl_PL.inc | 9 +- .../thunderbird_labels/localization/ru_RU.inc | 9 +- .../thunderbird_labels/localization/uk_UA.inc | 9 +- .../skins/classic/tb_label.css | 116 ++--- .../skins/classic/tb_label.min.css | 2 + .../skins/default/tb_label.css | 72 +-- .../skins/default/tb_label.min.css | 2 + .../skins/larry/tb_label.css | 106 ++-- .../skins/larry/tb_label.min.css | 2 + .../skins/yetiforce/tb_label.css | 245 ++++++++++ .../skins/yetiforce/tb_label.min.css | 2 + .../skins/yetiforce/thunderbird_24.png | Bin 0 -> 1770 bytes .../skins/yetiforce/thunderbird_32.png | Bin 0 -> 2662 bytes plugins/thunderbird_labels/tb_label.js | 458 +++++++++--------- plugins/thunderbird_labels/tb_label.min.js | 2 + .../thunderbird_labels/thunderbird_labels.php | 254 +++++----- 28 files changed, 830 insertions(+), 611 deletions(-) create mode 100644 plugins/thunderbird_labels/skins/classic/tb_label.min.css create mode 100644 plugins/thunderbird_labels/skins/default/tb_label.min.css create mode 100644 plugins/thunderbird_labels/skins/larry/tb_label.min.css create mode 100644 plugins/thunderbird_labels/skins/yetiforce/tb_label.css create mode 100644 plugins/thunderbird_labels/skins/yetiforce/tb_label.min.css create mode 100644 plugins/thunderbird_labels/skins/yetiforce/thunderbird_24.png create mode 100644 plugins/thunderbird_labels/skins/yetiforce/thunderbird_32.png create mode 100644 plugins/thunderbird_labels/tb_label.min.js diff --git a/plugins/thunderbird_labels/composer.json b/plugins/thunderbird_labels/composer.json index 47b1cf06..29e9fbb0 100644 --- a/plugins/thunderbird_labels/composer.json +++ b/plugins/thunderbird_labels/composer.json @@ -1,22 +1,22 @@ { - "name": "weird-birds/thunderbird_labels", - "type": "roundcube-plugin", - "keywords": ["mail","labels","tags"], - "license": "BSD-2-Clause", - "authors": [ - { - "name": "Michael Kefeder", - "homepage": "https://github.com/mike-kfed/rcmail-thunderbird-labels", - "role": "Developer" - } - ], - "repositories": [ - { - "type": "composer", - "url": "http://plugins.roundcube.net" - } - ], - "require": { - "roundcube/plugin-installer": ">=0.1.3" - } + "name": "weird-birds/thunderbird_labels", + "type": "roundcube-plugin", + "keywords": ["mail", "labels", "tags"], + "license": "BSD-2-Clause", + "authors": [ + { + "name": "Michael Kefeder", + "homepage": "https://github.com/mike-kfed/rcmail-thunderbird-labels", + "role": "Developer" + } + ], + "repositories": [ + { + "type": "composer", + "url": "http://plugins.roundcube.net" + } + ], + "require": { + "roundcube/plugin-installer": ">=0.1.3" + } } diff --git a/plugins/thunderbird_labels/config.inc.php b/plugins/thunderbird_labels/config.inc.php index 45be1658..50fdcfe2 100644 --- a/plugins/thunderbird_labels/config.inc.php +++ b/plugins/thunderbird_labels/config.inc.php @@ -1,12 +1,12 @@ -* http://code.google.com/p/rcmail-thunderbird-labels/ -*/ - + * Author: + * Samuele Tognini + * http://code.google.com/p/rcmail-thunderbird-labels/ + */ $labels = array(); $labels['label'] = 'Etichette Thunderbird'; $labels['label0'] = 'Nessuna etichetta'; diff --git a/plugins/thunderbird_labels/localization/lv_LV.inc b/plugins/thunderbird_labels/localization/lv_LV.inc index 00d557c7..835de68b 100644 --- a/plugins/thunderbird_labels/localization/lv_LV.inc +++ b/plugins/thunderbird_labels/localization/lv_LV.inc @@ -1,10 +1,9 @@ Bi6LUaH~epZ;D2IA^O1> ztuZDh5{)q=Viu#p1{SXyErD>a_G*EKHi8iagQzJXA^5`kvTrl9^K$y3Fc+^)`~NbN zoHPIDd46Z|KLr1!+S=ME0A5&F$N}K`_3NmttVDNrHwFg>AqWCVPEJNN8U-N)4u^ve z4-eDNpFgh>MRBF7svnmuS>hpt{F(l|d3$?10GNe^g}kk;4FFJCS&6%M?~>fyTsRz# zWdJe({Bmk)3aP27Y}>YNa5|kNJw5$br%#^_o+kOe0E9vzoIQIMZnxVzGc)r<*L9H)0?zr|R_mjM3l}01i7dZ( z@#3FkS^oQl3m2xX#g2{+lAoW?=O?;x;|8gysNlh1FfSgD-%}Ljo25&aLf3VKLZL4V z&6O<6i6cjj*a6`2qa7U`bMEoz(W5yR@cDdbY;4>xIy(ATmSw@^ zav>`#3#Ms;F$S;K3rUioC<=64hpMVjRnA~iJ?s;WZQb!eIf#u(PETldY;qeqRyhYy3! zqS1rFAgZgYQCwWi@7=ri>rg1v7L7*J+-^7Zcswvo6Pl*MZnr}a1cbw32!enO8#ch{ zbV8P8XqpCH*Wq%x8~~u}I_TKg81nP;k(QQ*)vH%izu%uXJUrYT4u_4btSn?_X9EBd zi3CJZv=FAGq=0h{Q53Od%NC@jrXn7X6Gc(5Y}vBSvzS14?b?MqckYmaf&#pK`*z*f z*jUrd%#4_woh_|hyVl}sv)RBHgQ6&wkfv$SGz|dY^Z7t2MKl_Pq9_CaR8`~5g{ z=n!gaYx9POho2~lVk;;ppdOD0hG8I)NWgBlgAjsfG>YWpWa}&_r4U6Clu|S{He!5y z9Fvoi&9PYQ+eM2OnKd;vCINseSFU7DOia8=BobmyP7d3=c{Ao5*zI=f-Db1FVoNC) zW6(4W_wV1w=;){s4u_vcB9Y%qlB5R$0bX8S4hjH6Lqp@SSnQvwsSW8O_PM$m| zuUfULQIe#*>FMbeZ{EB?W@aWF4hLjehA4^+rLl6WILLf;J{C+LR7Fc@Ksp}4phe!m|8Kp#AK003CLc(D-~=dSrPkpx z#sC1 znxG!&> z7f6yM96NRl4Gj%^WMqUe#-605rR|8tVywQtUIBpe@^T9w0GOr;(=_qbye%my!NZ3S z0Ra2=?{`EZks4js%NS#(s;bmxvpr2uPyb_WZEXku_U+q;`ucis&T;eRO&Ep&UDx6D zdXbx(3v_jL(XOtpU(6TTv}x1)3k4-5C4Va_D&jkL?rb@6;)K1lw3GqBo;`d1Gv{ab za?Ww-(j`n!PydAI*|TS0j1fWzr<5WmCkFsfTwILi=4QBDE|QXxLNYTm_i38e;B-0> z2m}lO7#J7;0Jz<5aL%o}VgB>0>gnl0Pfrj2SCy5OVOD_5iS+mPV{~-XO48TYhrYf( zQ2d{I{`@%rV8@OfIB?(q0HC3v0RsaAaJ${y?RHy9CMG5T;ETWM-;tv@Y}G_wk^lez M07*qoM6N<$f>cpG;Q#;t literal 0 HcmV?d00001 diff --git a/plugins/thunderbird_labels/skins/yetiforce/thunderbird_32.png b/plugins/thunderbird_labels/skins/yetiforce/thunderbird_32.png new file mode 100644 index 0000000000000000000000000000000000000000..c8254dd650a3d70d25484defeb5d0690a94413f5 GIT binary patch literal 2662 zcmWkw2|QF?AHE~T*r&cJlk6thVq!{TZxVwB&6}7gWX3YKYAlf$J7sC`+DFLpSsGh! z7;6nuYVaweWY7ytk<3%n^29OVx> z3<{oUp`ky)0eZ{I+!Xk8a1^$cr-Lg(xA7zz00{p$=nz~rCL6qfT9{tA>cDw#?|b>G zy;L~2IoK#$+_qLq!SjF0@BMsytfHdwtdAeQ?tPt@=kUP`m*`?_TG3KXM722bg7!T{ z!qufThKo#e2-Nh?uuE!ZTo^@19A{FMTatZeU`&xuUFB0-<8SiU z+rO{3_TT3!WWVS){v)k^tr`HFn(qpLt?Bj@pMZR(mb2y$_04bPPtqJT%v4Hyxm+l4 zlSsT()9B69WZzr8r7A66vv$uQr_Nz%qPe*_HVrj4(sXBrly-f7Z+m^S*v4R$e`j|$ z5zg0_r6p--Xc&yuR9EM8b^^ywoKVU;=Q|AyeE4807yipN9%T`8rU#N>syKzfB~(;Y zbPRv|*v80>_&GoLS551h<==bjvDmr!<>lCk?~=g4&`@-Jy*6Ot>?~(#X?ZZs%se)| zzTNey!6Pd;Fz|E+DzVv#l~7sfmO;!RQtxmHjiaYS3}mz5I6gX?t+zDMA-8(Z01B+V ztA-RdHcFP3mLBX5=c7<4^NWjz6!^=$_<-=eRr9sa-ZhD-#=o1C8TjXSxi7KtUb*ry zo%I?39gaKHdDZSH1K*_=wB+!uPpf0ET*Bzrqy(?VxkCsbEB`T$_?@<~wKW6=8QC(n zB9>dmBqs@3r1_NVBmsZ|f1InllF}gtp8sJnCa(wlN`K=_AnP?X-``p( z#ld*f-H-lxEf?W5kQ1S%sd-FiYHN4D>E5bh`>$z{iWe`g1q26olvGlyD5O^y!q!Cz z!PW7DHI~8GVr~q7VZn?ZJZwg*w`Tz-WlQy(E{Z zAMed$F{Y<)4S)L7Y<(rejm@GBVcsaE8bsyiOXtaE^~IjF%Iy4l_X01_Ayc5Q-X*up zkchBIL#e5$*%FCS2)=@hSwJ2kTvS}lXJ2#kWKH`{<@pCYKjRV;6I00A6*@ihPg9K^ zg4k>=U6D{x4oJ6VmWWlBW-MIqivFV5Oc^a=~Oi&9b7Zun+*X?vnHpEeg>4zT&9uuV*e?xpG+Z2AluV z6%$paonWG=q8R;0Xj|~V0G&co6zFh8diwj9tJ||?eSLk8J}k~32xJ~A1S>5Yl!wN9 zeWvwjbFs=~KFHp5-D}y4W@aGT>`Sj7Y>j1If*qcCuq6{_G{FR}RXaq|=C}~xs@>me z>gplh-ivXotE<*_c4sYBZ?FSYk7+o#aJblb&Qxt_S*6-a+txVZ^=&=okL|GDw{LOU zIWextF0|-9g901?0z@K_P5&|R_tz>2T~Kvux_#khgS(i1=ub}q>IgOmk7^qF7O)#; zH2d{yg%RtSlcRKQl99i#RC`40>J_6&D}(%35AtE~&34K7an)2Pr3KoO4-u+OA95VmG9J3C7!3KNC^z`A_M?^$|!I^M>nvBRwn z>7*%1+>L_s$;ilL=jLj=)nzNmrhXTKMvFz7(D|b;)ZO3m!(cFb{<^Ip>+YKYPYWLw zoA3gG+S1I*O~ew3M4HSmFA-=Q^|i8wMQ&~eb zFREb*@-ZX%{YwGh`+K^&Vr=a`LJFI!suukhc{K;lDK7{-=@$eV;I)r#^H?`LsZ<<+ zAZB=Hn!kp{GGcjsHp3-Y!0zz#K{T#Ehhqp&Y4f76(I+#@^*`^c&MYb?TIm+fuR@*9(oje9g{o|KCWD;SiUtl`&g{0MM0r z+R@X|add)03eTcxo=mrB1vdv321Qx$xrt^Fmqr^U7m^Y-nl<{XK!DC*Fi2^I_AIBO=;-KR0RT9A_UuS&NW%>s8{_?e4G@YhK|c#{;pSuU z0t~6APoDzx!NDs@DJfC3n?~o(Dff$-6qL~qb=Fh*+`SM$Tzq^T`OOh0c7Twege-!? z;dIqkzo7JGu7bSH?0)a?sOWni&`=D-uoe}KjU$HdBoRY{$YgTRrm7X?2{nD{c6QkI z*DQekf!1GO2+;TT!iaWumm!d=MwdQKgjVg literal 0 HcmV?d00001 diff --git a/plugins/thunderbird_labels/tb_label.js b/plugins/thunderbird_labels/tb_label.js index e0156fba..1b435ebf 100644 --- a/plugins/thunderbird_labels/tb_label.js +++ b/plugins/thunderbird_labels/tb_label.js @@ -15,7 +15,7 @@ function rcmail_tb_label_menu(p) rcmail_ui = UI; if (!rcmail_ui.check_tb_popup()) rcmail_ui.tb_label_popup_add(); - + // Show the popup menu with tags // -- skin larry vs classic if (typeof rcmail_ui.show_popupmenu == "undefined") @@ -27,10 +27,10 @@ function rcmail_tb_label_menu(p) } /** -* Shows the colors based on flag info like in Thunderbird -* (called when a new message in inserted in list of messages) -* maybe slow ? called for each message in mailbox at init -*/ + * Shows the colors based on flag info like in Thunderbird + * (called when a new message in inserted in list of messages) + * maybe slow ? called for each message in mailbox at init + */ function rcm_tb_label_insert(uid, row) { if (typeof rcmail.env == 'undefined' || typeof rcmail.env.messages == 'undefined') @@ -39,36 +39,38 @@ function rcm_tb_label_insert(uid, row) var rowobj = $(row.obj); // add span container for little colored bullets rowobj.find("td.subject").append(""); - + if (message.flags && message.flags.tb_labels) { - if (message.flags.tb_labels.length) { - var spanobj = rowobj.find("td.subject span.tb_label_dots"); - message.flags.tb_labels.sort(function(a,b) {return a-b;}); - if (rcmail.env.tb_label_style=='bullets') { - // bullets UI style - for (idx in message.flags.tb_labels) { - spanobj.append(""); - } - } else { - // thunderbird UI style - for (idx in message.flags.tb_labels) { - rowobj.addClass('label' + message.flags.tb_labels[idx]); - } - } + if (message.flags.tb_labels.length) { + var spanobj = rowobj.find("td.subject span.tb_label_dots"); + message.flags.tb_labels.sort(function (a, b) { + return a - b; + }); + if (rcmail.env.tb_label_style == 'bullets') { + // bullets UI style + for (idx in message.flags.tb_labels) { + spanobj.append(""); + } + } else { + // thunderbird UI style + for (idx in message.flags.tb_labels) { + rowobj.addClass('label' + message.flags.tb_labels[idx]); + } + } } } } /** -* Shows the submenu of thunderbird labels -*/ + * Shows the submenu of thunderbird labels + */ function rcm_tb_label_submenu(p) { if (typeof rcmail_ui == "undefined") rcmail_ui = UI; // setup onclick and active/non active classes rcm_tb_label_create_popupmenu(); - + // -- create sensible popup, using roundcubes internals if (!rcmail_ui.check_tb_popup()) rcmail_ui.tb_label_popup_add(); @@ -90,31 +92,30 @@ function rcm_tb_label_flag_toggle(flag_uids, toggle_label_no, onoff) tb_labels_for_message = preview_frame.get(0).contentWindow.tb_labels_for_message; headers_table = preview_frame.contents().find('table.headers-table'); } - + if (!rcmail.message_list - && !headers_table) + && !headers_table) return; // for single message view if (headers_table.length && flag_uids.length) { if (onoff == true) { - if (rcmail.env.tb_label_style=='bullets') { - $('#labelbox').append("" + - rcmail.env.tb_label_custom_labels[toggle_label_no] + ""); - } else { - headers_table.addClass('label'+toggle_label_no); - } + if (rcmail.env.tb_label_style == 'bullets') { + $('#labelbox').append("" + + rcmail.env.tb_label_custom_labels[toggle_label_no] + ""); + } else { + headers_table.addClass('label' + toggle_label_no); + } // add to flag list tb_labels_for_message.push(toggle_label_no); - - } - else + + } else { - if (rcmail.env.tb_label_style=='bullets') { - $("span.tb_label_span"+toggle_label_no).remove(); + if (rcmail.env.tb_label_style == 'bullets') { + $("span.tb_label_span" + toggle_label_no).remove(); } else { - headers_table.removeClass('label'+toggle_label_no); + headers_table.removeClass('label' + toggle_label_no); } - + var pos = jQuery.inArray(toggle_label_no, tb_labels_for_message); if (pos > -1) { tb_labels_for_message.splice(pos, 1); @@ -126,37 +127,36 @@ function rcm_tb_label_flag_toggle(flag_uids, toggle_label_no, onoff) } } jQuery.each(flag_uids, function (idx, uid) { - var message = rcmail.env.messages[uid]; - var row = rcmail.message_list.rows[uid]; - if (onoff == true) - { - // add colors - var rowobj = $(row.obj); - var spanobj = rowobj.find("td.subject span.tb_label_dots"); - if (rcmail.env.tb_label_style=='bullets') { - spanobj.append(""); - } else { - rowobj.addClass('label'+toggle_label_no); - } - - // add to flag list - message.flags.tb_labels.push(toggle_label_no); + var message = rcmail.env.messages[uid]; + var row = rcmail.message_list.rows[uid]; + if (onoff == true) + { + // add colors + var rowobj = $(row.obj); + var spanobj = rowobj.find("td.subject span.tb_label_dots"); + if (rcmail.env.tb_label_style == 'bullets') { + spanobj.append(""); + } else { + rowobj.addClass('label' + toggle_label_no); } - else - { - // remove colors - var rowobj = $(row.obj); - if (rcmail.env.tb_label_style=='bullets') { - rowobj.find("td.subject span.tb_label_dots span.label"+toggle_label_no).remove(); - } else { - rowobj.removeClass('label'+toggle_label_no); - } - - // remove from flag list - var pos = jQuery.inArray(toggle_label_no, message.flags.tb_labels); - if (pos > -1) - message.flags.tb_labels.splice(pos, 1); + + // add to flag list + message.flags.tb_labels.push(toggle_label_no); + } else + { + // remove colors + var rowobj = $(row.obj); + if (rcmail.env.tb_label_style == 'bullets') { + rowobj.find("td.subject span.tb_label_dots span.label" + toggle_label_no).remove(); + } else { + rowobj.removeClass('label' + toggle_label_no); } + + // remove from flag list + var pos = jQuery.inArray(toggle_label_no, message.flags.tb_labels); + if (pos > -1) + message.flags.tb_labels.splice(pos, 1); + } }); } @@ -183,11 +183,11 @@ function rcm_tb_label_create_popupmenu() { for (i = 0; i < 6; i++) { - var cur_a = $('li.label' + i +' a'); - + var cur_a = $('li.label' + i + ' a'); + // add/remove active class var selection = rcm_tb_label_get_selection(); - + if (selection.length == 0) cur_a.removeClass('active'); else @@ -199,105 +199,103 @@ function rcm_tb_label_init_onclick() { for (i = 0; i < 6; i++) { - // find the "HTML a tags" of tb-label submenus - var cur_a = $('#tb_label_popup li.label' + i +' a'); - + // find the "HTML a tags" of tb-label submenus + var cur_a = $('#tb_label_popup li.label' + i + ' a'); + // TODO check if click event is defined instead of unbinding? cur_a.unbind('click'); - cur_a.click(function() { - var toggle_label = $(this).parent().attr('class'); - var toggle_label_no = parseInt(toggle_label.replace('label', '')); - var selection = rcm_tb_label_get_selection(); - - if (!selection.length) - return; - - var from = toggle_label_no; - var to = toggle_label_no + 1; - var unset_all = false; - // special case flag 0 means remove all flags - if (toggle_label_no == 0) - { - from = 1; - to = 6; - unset_all = true; - } - for (i = from; i < to; i++) + cur_a.click(function () { + var toggle_label = $(this).parent().attr('class'); + var toggle_label_no = parseInt(toggle_label.replace('label', '')); + var selection = rcm_tb_label_get_selection(); + + if (!selection.length) + return; + + var from = toggle_label_no; + var to = toggle_label_no + 1; + var unset_all = false; + // special case flag 0 means remove all flags + if (toggle_label_no == 0) + { + from = 1; + to = 6; + unset_all = true; + } + for (i = from; i < to; i++) + { + toggle_label = 'label' + i; + toggle_label_no = i; + // compile list of unflag and flag msgs and then send command + // Thunderbird modifies multiple message flags like it did the first in the selection + // e.g. first message has flag1, you click flag1, every message select loses flag1, the ones not having flag1 don't get it! + var first_toggle_mode = 'on'; + if (rcmail.env.messages) { - toggle_label = 'label' + i; - toggle_label_no = i; - // compile list of unflag and flag msgs and then send command - // Thunderbird modifies multiple message flags like it did the first in the selection - // e.g. first message has flag1, you click flag1, every message select loses flag1, the ones not having flag1 don't get it! - var first_toggle_mode = 'on'; - if (rcmail.env.messages) - { - var first_message = rcmail.env.messages[selection[0]]; - if (first_message.flags + var first_message = rcmail.env.messages[selection[0]]; + if (first_message.flags && jQuery.inArray(toggle_label_no, first_message.flags.tb_labels) >= 0 ) - first_toggle_mode = 'off'; + first_toggle_mode = 'off'; + else + first_toggle_mode = 'on'; + } else // single message display + { + // flag already set? + if (jQuery.inArray(toggle_label_no, + tb_labels_for_message) >= 0) + first_toggle_mode = 'off'; + } + var flag_uids = []; + var unflag_uids = []; + jQuery.each(selection, function (idx, uid) { + // message list not available (example: in detailview) + if (!rcmail.env.messages) + { + if (first_toggle_mode == 'on') + flag_uids.push(uid); else - first_toggle_mode = 'on'; + unflag_uids.push(uid); + // make sure for unset all there is the single message id + if (unset_all && unflag_uids.length == 0) + unflag_uids.push(uid); + return; } - else // single message display + var message = rcmail.env.messages[uid]; + if (message.flags + && jQuery.inArray(toggle_label_no, + message.flags.tb_labels) >= 0 + ) + { + if (first_toggle_mode == 'off') + unflag_uids.push(uid); + } else { - // flag already set? - if (jQuery.inArray(toggle_label_no, - tb_labels_for_message) >= 0) - first_toggle_mode = 'off'; + if (first_toggle_mode == 'on') + flag_uids.push(uid); } - var flag_uids = []; - var unflag_uids = []; - jQuery.each(selection, function (idx, uid) { - // message list not available (example: in detailview) - if (!rcmail.env.messages) - { - if (first_toggle_mode == 'on') - flag_uids.push(uid); - else - unflag_uids.push(uid); - // make sure for unset all there is the single message id - if (unset_all && unflag_uids.length == 0) - unflag_uids.push(uid); - return; - } - var message = rcmail.env.messages[uid]; - if (message.flags - && jQuery.inArray(toggle_label_no, - message.flags.tb_labels) >= 0 - ) - { - if (first_toggle_mode == 'off') - unflag_uids.push(uid); - } - else - { - if (first_toggle_mode == 'on') - flag_uids.push(uid); - } - }); - - if (unset_all) - flag_uids = []; - - // skip sending flags to backend that are not set anywhere - if (flag_uids.length == 0 + }); + + if (unset_all) + flag_uids = []; + + // skip sending flags to backend that are not set anywhere + if (flag_uids.length == 0 && unflag_uids.length == 0) - continue; - - var str_flag_uids = flag_uids.join(','); - var str_unflag_uids = unflag_uids.join(','); - - var lock = rcmail.set_busy(true, 'loading'); - // call PHP set_flags to set the flags in IMAP server - rcmail.http_request('plugin.thunderbird_labels.set_flags', '_flag_uids=' + str_flag_uids + '&_unflag_uids=' + str_unflag_uids + '&_mbox=' + urlencode(rcmail.env.mailbox) + "&_toggle_label=" + toggle_label, lock); - - // remove/add classes and tb labels from messages in JS - rcm_tb_label_flag_msgs(flag_uids, toggle_label_no); - rcm_tb_label_unflag_msgs(unflag_uids, toggle_label_no); - } + continue; + + var str_flag_uids = flag_uids.join(','); + var str_unflag_uids = unflag_uids.join(','); + + var lock = rcmail.set_busy(true, 'loading'); + // call PHP set_flags to set the flags in IMAP server + rcmail.http_request('plugin.thunderbird_labels.set_flags', '_flag_uids=' + str_flag_uids + '&_unflag_uids=' + str_unflag_uids + '&_mbox=' + urlencode(rcmail.env.mailbox) + "&_toggle_label=" + toggle_label, lock); + + // remove/add classes and tb labels from messages in JS + rcm_tb_label_flag_msgs(flag_uids, toggle_label_no); + rcm_tb_label_unflag_msgs(unflag_uids, toggle_label_no); + } }); } } @@ -307,18 +305,18 @@ function rcmail_ctxm_label(command, el, pos) // my code works only on selected rows, contextmenu also on unselected // so if no selection is available, use the uid set by contextmenu plugin var selection = rcmail.message_list ? rcmail.message_list.get_selection() : []; - + if (!selection.length && !rcmail.env.uid) return; if (!selection.length && rcmail.env.uid) rcmail.message_list.select_row(rcmail.env.uid); - - var cur_a = $('#tb_label_popup li.label' + rcmail.tb_label_no +' a'); + + var cur_a = $('#tb_label_popup li.label' + rcmail.tb_label_no + ' a'); if (cur_a) { cur_a.click(); } - + return; } @@ -329,98 +327,102 @@ function rcmail_ctxm_label_set(which) } -$(document).ready(function() { +$(document).ready(function () { rcm_tb_label_init_onclick(); // add keyboard shortcuts for keyboard and keypad if pref tb_label_enable_shortcuts=true if (rcmail.env.tb_label_enable_shortcuts) { - $(document).keyup(function(e) { - //console.log('Handler for .keyup() called.' + e.which); - var k = e.which; - if ((k > 47 && k < 58) || (k > 95 && k < 106)) - { - var label_no = k % 48; - var cur_a = $('#tb_label_popup li.label' + label_no + ' a'); - - if (cur_a) - { - cur_a.click(); - } - } - }); - } - + $(document).keyup(function (e) { + //console.log('Handler for .keyup() called.' + e.which); + var k = e.which; + if ((k > 47 && k < 58) || (k > 95 && k < 106)) + { + var label_no = k % 48; + var cur_a = $('#tb_label_popup li.label' + label_no + ' a'); + + if (cur_a) + { + cur_a.click(); + } + } + }); + } + // if exists add contextmenu entries if (window.rcm_contextmenu_register_command) { rcm_contextmenu_register_command('ctxm_tb_label', rcmail_ctxm_label, $('#tb_label_ctxm_mainmenu'), 'moreacts', 'after', true); } - + // single message displayed? if (window.tb_labels_for_message) { - var labelbox_parent = $('div.message-headers'); // larry skin - if (!labelbox_parent.length) { - labelbox_parent = $("table.headers-table tbody tr:first-child"); // classic skin - } - labelbox_parent.append("
"); - tb_labels_for_message.sort(function(a,b) {return a-b;}); - jQuery.each(tb_labels_for_message, function(idx, val) - { - rcm_tb_label_flag_msgs([-1,], val); - } + var labelbox_parent = $('div.message-headers'); // larry skin + if (!labelbox_parent.length) { + labelbox_parent = $("table.headers-table tbody tr:first-child"); // classic skin + } + labelbox_parent.append("
"); + tb_labels_for_message.sort(function (a, b) { + return a - b; + }); + jQuery.each(tb_labels_for_message, function (idx, val) + { + rcm_tb_label_flag_msgs([-1, ], val); + } ); } - + // add roundcube events - rcmail.addEventListener('insertrow', function(event) { rcm_tb_label_insert(event.uid, event.row); }); - - rcmail.addEventListener('init', function(evt) { + rcmail.addEventListener('insertrow', function (event) { + rcm_tb_label_insert(event.uid, event.row); + }); + + rcmail.addEventListener('init', function (evt) { // create custom button, JS method, broken layout in Firefox 9 using PHP method now /*var button = $('
').attr('href', '#').attr('id', 'tb_label_popuplink').attr('title', rcmail.gettext('label', 'thunderbird_labels')).html(''); - - button.bind('click', function(e) { - rcmail.command('plugin.thunderbird_labels.rcm_tb_label_submenu', this); - return false; - }); - - // add and register - rcmail.add_element(button, 'toolbar'); - rcmail.register_button('plugin.thunderbird_labels.rcm_tb_label_submenu', 'tb_label_popuplink', 'link'); - */ + + button.bind('click', function(e) { + rcmail.command('plugin.thunderbird_labels.rcm_tb_label_submenu', this); + return false; + }); + + // add and register + rcmail.add_element(button, 'toolbar'); + rcmail.register_button('plugin.thunderbird_labels.rcm_tb_label_submenu', 'tb_label_popuplink', 'link'); + */ //rcmail.register_command('plugin.thunderbird_labels.rcm_tb_label_submenu', rcm_tb_label_submenu, true); rcmail.register_command('plugin.thunderbird_labels.rcm_tb_label_submenu', rcm_tb_label_submenu, rcmail.env.uid); // add event-listener to message list if (rcmail.message_list) { - rcmail.message_list.addEventListener('select', function(list){ - rcmail.enable_command('plugin.thunderbird_labels.rcm_tb_label_submenu', list.get_selection().length > 0); + rcmail.message_list.addEventListener('select', function (list) { + rcmail.enable_command('plugin.thunderbird_labels.rcm_tb_label_submenu', list.get_selection().length > 0); }); } }); - + // -- add my submenu to roundcubes UI (for roundcube classic only?) if (window.rcube_mail_ui) - rcube_mail_ui.prototype.tb_label_popup_add = function() { - add = { - tb_label_popup: {id:'tb_label_popup'} + rcube_mail_ui.prototype.tb_label_popup_add = function () { + add = { + tb_label_popup: {id: 'tb_label_popup'} + }; + this.popups = $.extend(this.popups, add); + var obj = $('#' + this.popups.tb_label_popup.id); + if (obj.length) + this.popups.tb_label_popup.obj = obj; + else + delete this.popups.tb_label_popup; }; - this.popups = $.extend(this.popups, add); - var obj = $('#'+this.popups.tb_label_popup.id); - if (obj.length) - this.popups.tb_label_popup.obj = obj; - else - delete this.popups.tb_label_popup; - }; - + if (window.rcube_mail_ui) - rcube_mail_ui.prototype.check_tb_popup = function() { - // larry skin doesn't have that variable, popup works automagically, return true - if (typeof this.popups == 'undefined') - return true; - if (this.popups.tb_label_popup) - return true; - else - return false; - }; - + rcube_mail_ui.prototype.check_tb_popup = function () { + // larry skin doesn't have that variable, popup works automagically, return true + if (typeof this.popups == 'undefined') + return true; + if (this.popups.tb_label_popup) + return true; + else + return false; + }; + }); diff --git a/plugins/thunderbird_labels/tb_label.min.js b/plugins/thunderbird_labels/tb_label.min.js new file mode 100644 index 00000000..520b2346 --- /dev/null +++ b/plugins/thunderbird_labels/tb_label.min.js @@ -0,0 +1,2 @@ + +rcmail.tb_label_no="";function rcmail_tb_label_menu(a){if(typeof rcmail_ui=="undefined"){rcmail_ui=UI}if(!rcmail_ui.check_tb_popup()){rcmail_ui.tb_label_popup_add()}if(typeof rcmail_ui.show_popupmenu=="undefined"){rcmail_ui.show_popup("tb_label_popup")}else{rcmail_ui.show_popupmenu("tb_label_popup")}return false}function rcm_tb_label_insert(b,e){if(typeof rcmail.env=="undefined"||typeof rcmail.env.messages=="undefined"){return}var c=rcmail.env.messages[b];var d=$(e.obj);d.find("td.subject").append("");if(c.flags&&c.flags.tb_labels){if(c.flags.tb_labels.length){var a=d.find("td.subject span.tb_label_dots");c.flags.tb_labels.sort(function(g,f){return g-f});if(rcmail.env.tb_label_style=="bullets"){for(idx in c.flags.tb_labels){a.append("")}}else{for(idx in c.flags.tb_labels){d.addClass("label"+c.flags.tb_labels[idx])}}}}}function rcm_tb_label_submenu(a){if(typeof rcmail_ui=="undefined"){rcmail_ui=UI}rcm_tb_label_create_popupmenu();if(!rcmail_ui.check_tb_popup()){rcmail_ui.tb_label_popup_add()}if(typeof rcmail_ui.show_popupmenu=="undefined"){rcmail_ui.show_popup("tb_label_popup")}else{rcmail_ui.show_popupmenu("tb_label_popup")}return false}function rcm_tb_label_flag_toggle(a,d,b){var e=$("table.headers-table");var c=$("#messagecontframe");if(c.length){tb_labels_for_message=c.get(0).contentWindow.tb_labels_for_message;e=c.contents().find("table.headers-table")}if(!rcmail.message_list&&!e){return}if(e.length&&a.length){if(b==true){if(rcmail.env.tb_label_style=="bullets"){$("#labelbox").append(""+rcmail.env.tb_label_custom_labels[d]+"")}else{e.addClass("label"+d)}tb_labels_for_message.push(d)}else{if(rcmail.env.tb_label_style=="bullets"){$("span.tb_label_span"+d).remove()}else{e.removeClass("label"+d)}var f=jQuery.inArray(d,tb_labels_for_message);if(f>-1){tb_labels_for_message.splice(f,1)}}if(!rcmail.env.messages){return}}jQuery.each(a,function(g,j){var k=rcmail.env.messages[j];var m=rcmail.message_list.rows[j];if(b==true){var l=$(m.obj);var h=l.find("td.subject span.tb_label_dots");if(rcmail.env.tb_label_style=="bullets"){h.append("")}else{l.addClass("label"+d)}k.flags.tb_labels.push(d)}else{var l=$(m.obj);if(rcmail.env.tb_label_style=="bullets"){l.find("td.subject span.tb_label_dots span.label"+d).remove()}else{l.removeClass("label"+d)}var n=jQuery.inArray(d,k.flags.tb_labels);if(n>-1){k.flags.tb_labels.splice(n,1)}}})}function rcm_tb_label_flag_msgs(a,b){rcm_tb_label_flag_toggle(a,b,true)}function rcm_tb_label_unflag_msgs(b,a){rcm_tb_label_flag_toggle(b,a,false)}function rcm_tb_label_get_selection(){var a=rcmail.message_list?rcmail.message_list.get_selection():[];if(a.length==0&&rcmail.env.uid){a=[rcmail.env.uid,]}return a}function rcm_tb_label_create_popupmenu(){for(i=0;i<6;i++){var a=$("li.label"+i+" a");var b=rcm_tb_label_get_selection();if(b.length==0){a.removeClass("active")}else{a.addClass("active")}}}function rcm_tb_label_init_onclick(){for(i=0;i<6;i++){var a=$("#tb_label_popup li.label"+i+" a");a.unbind("click");a.click(function(){var g=$(this).parent().attr("class");var d=parseInt(g.replace("label",""));var l=rcm_tb_label_get_selection();if(!l.length){return}var j=d;var k=d+1;var b=false;if(d==0){j=1;k=6;b=true}for(i=j;i=0){e="off"}else{e="on"}}else{if(jQuery.inArray(d,tb_labels_for_message)>=0){e="off"}}var c=[];var h=[];jQuery.each(l,function(p,q){if(!rcmail.env.messages){if(e=="on"){c.push(q)}else{h.push(q)}if(b&&h.length==0){h.push(q)}return}var r=rcmail.env.messages[q];if(r.flags&&jQuery.inArray(d,r.flags.tb_labels)>=0){if(e=="off"){h.push(q)}}else{if(e=="on"){c.push(q)}}});if(b){c=[]}if(c.length==0&&h.length==0){continue}var o=c.join(",");var n=h.join(",");var m=rcmail.set_busy(true,"loading");rcmail.http_request("plugin.thunderbird_labels.set_flags","_flag_uids="+o+"&_unflag_uids="+n+"&_mbox="+urlencode(rcmail.env.mailbox)+"&_toggle_label="+g,m);rcm_tb_label_flag_msgs(c,d);rcm_tb_label_unflag_msgs(h,d)}})}}function rcmail_ctxm_label(d,c,e){var b=rcmail.message_list?rcmail.message_list.get_selection():[];if(!b.length&&!rcmail.env.uid){return}if(!b.length&&rcmail.env.uid){rcmail.message_list.select_row(rcmail.env.uid)}var a=$("#tb_label_popup li.label"+rcmail.tb_label_no+" a");if(a){a.click()}return}function rcmail_ctxm_label_set(a){rcmail.tb_label_no=a}$(document).ready(function(){rcm_tb_label_init_onclick();if(rcmail.env.tb_label_enable_shortcuts){$(document).keyup(function(f){var c=f.which;if((c>47&&c<58)||(c>95&&c<106)){var d=c%48;var b=$("#tb_label_popup li.label"+d+" a");if(b){b.click()}}})}if(window.rcm_contextmenu_register_command){rcm_contextmenu_register_command("ctxm_tb_label",rcmail_ctxm_label,$("#tb_label_ctxm_mainmenu"),"moreacts","after",true)}if(window.tb_labels_for_message){var a=$("div.message-headers");if(!a.length){a=$("table.headers-table tbody tr:first-child")}a.append("
");tb_labels_for_message.sort(function(d,c){return d-c});jQuery.each(tb_labels_for_message,function(b,c){rcm_tb_label_flag_msgs([-1,],c)})}rcmail.addEventListener("insertrow",function(b){rcm_tb_label_insert(b.uid,b.row)});rcmail.addEventListener("init",function(b){rcmail.register_command("plugin.thunderbird_labels.rcm_tb_label_submenu",rcm_tb_label_submenu,rcmail.env.uid);if(rcmail.message_list){rcmail.message_list.addEventListener("select",function(c){rcmail.enable_command("plugin.thunderbird_labels.rcm_tb_label_submenu",c.get_selection().length>0)})}});if(window.rcube_mail_ui){rcube_mail_ui.prototype.tb_label_popup_add=function(){add={tb_label_popup:{id:"tb_label_popup"}};this.popups=$.extend(this.popups,add);var b=$("#"+this.popups.tb_label_popup.id);if(b.length){this.popups.tb_label_popup.obj=b}else{delete this.popups.tb_label_popup}}}if(window.rcube_mail_ui){rcube_mail_ui.prototype.check_tb_popup=function(){if(typeof this.popups=="undefined"){return true}if(this.popups.tb_label_popup){return true}else{return false}}}}); \ No newline at end of file diff --git a/plugins/thunderbird_labels/thunderbird_labels.php b/plugins/thunderbird_labels/thunderbird_labels.php index 13960a14..ab78764b 100644 --- a/plugins/thunderbird_labels/thunderbird_labels.php +++ b/plugins/thunderbird_labels/thunderbird_labels.php @@ -1,4 +1,5 @@ rc = rcmail::get_instance(); $this->load_config(); $this->add_texts('localization/', false); - + $this->setCustomLabels(); - if ($this->rc->task == 'mail') - { + if ($this->rc->task == 'mail') { # -- disable plugin when printing message if ($this->rc->action == 'print') return; - + if (!$this->rc->config->get('tb_label_enable')) // disable plugin according to prefs return; - + // pass 'tb_label_enable_shortcuts' and 'tb_label_style' prefs to JS $this->rc->output->set_env('tb_label_enable_shortcuts', $this->rc->config->get('tb_label_enable_shortcuts')); $this->rc->output->set_env('tb_label_style', $this->rc->config->get('tb_label_style')); - + $this->include_script('tb_label.js'); $this->add_hook('messages_list', array($this, 'read_flags')); $this->add_hook('message_load', array($this, 'read_single_flags')); $this->add_hook('template_object_messageheaders', array($this, 'color_headers')); $this->add_hook('render_page', array($this, 'tb_label_popup')); $this->include_stylesheet($this->local_skin_path() . '/tb_label.css'); - + $this->name = get_class($this); # -- additional TB flags $this->add_tb_flags = array( - 'LABEL1' => '$Label1', - 'LABEL2' => '$Label2', - 'LABEL3' => '$Label3', - 'LABEL4' => '$Label4', - 'LABEL5' => '$Label5', + 'LABEL1' => '$Label1', + 'LABEL2' => '$Label2', + 'LABEL3' => '$Label3', + 'LABEL4' => '$Label4', + 'LABEL5' => '$Label5', ); $this->message_tb_labels = array(); - + $this->add_button( array( - 'command' => 'plugin.thunderbird_labels.rcm_tb_label_submenu', - 'id' => 'tb_label_popuplink', - 'title' => 'tb_label_button_title', - 'domain' => $this->ID, - 'type' => 'link', - 'content' => $this->gettext('tb_label_button_label'), - 'class' => 'button buttonPas disabled', - 'classact' => 'button', - ), - 'toolbar' + 'command' => 'plugin.thunderbird_labels.rcm_tb_label_submenu', + 'id' => 'tb_label_popuplink', + 'title' => 'tb_label_button_title', + 'domain' => $this->ID, + 'type' => 'link', + 'content' => $this->gettext('tb_label_button_label'), + 'class' => 'button buttonPas disabled', + 'classact' => 'button', + ), 'toolbar' ); - + // JS function "set_flags" => PHP function "set_flags" $this->register_action('plugin.thunderbird_labels.set_flags', array($this, 'set_flags')); - - - if (method_exists($this, 'require_plugin') - && in_array('contextmenu', $this->rc->config->get('plugins')) - && $this->require_plugin('contextmenu') - && $this->rc->config->get('tb_label_enable_contextmenu')) - { + + + if (method_exists($this, 'require_plugin') && in_array('contextmenu', $this->rc->config->get('plugins')) && $this->require_plugin('contextmenu') && $this->rc->config->get('tb_label_enable_contextmenu')) { if ($this->rc->action == '') $this->add_hook('render_mailboxlist', array($this, 'show_tb_label_contextmenu')); } } - elseif ($this->rc->task == 'settings') - { + elseif ($this->rc->task == 'settings') { $this->include_stylesheet($this->local_skin_path() . '/tb_label.css'); $this->add_hook('preferences_list', array($this, 'prefs_list')); $this->add_hook('preferences_sections_list', array($this, 'prefs_section')); @@ -93,8 +88,7 @@ function init() private function setCustomLabels() { $c = $this->rc->config->get('tb_label_custom_labels'); - if (empty($c)) - { + if (empty($c)) { // if no user specific labels, use localized strings by default $this->rc->config->set('tb_label_custom_labels', array( 0 => $this->getText('label0'), @@ -111,14 +105,14 @@ private function setCustomLabels() // create a section for the tb-labels Settings public function prefs_section($args) - { - $args['list']['thunderbird_labels'] = array( - 'id' => 'thunderbird_labels', - 'section' => rcube::Q($this->gettext('tb_label_options')) + { + $args['list']['thunderbird_labels'] = array( + 'id' => 'thunderbird_labels', + 'section' => rcube::Q($this->gettext('tb_label_options')) ); - return $args; - } + return $args; + } // display thunderbird-labels prefs in Roundcube Settings public function prefs_list($args) @@ -128,13 +122,12 @@ public function prefs_list($args) $this->load_config(); $dont_override = (array) $this->rc->config->get('dont_override', array()); - + $args['blocks']['tb_label'] = array(); $args['blocks']['tb_label']['name'] = $this->gettext('tb_label_options'); - + $key = 'tb_label_enable'; - if (!in_array($key, $dont_override)) - { + if (!in_array($key, $dont_override)) { $input = new html_checkbox(array( 'name' => $key, 'id' => $key, @@ -146,10 +139,9 @@ public function prefs_list($args) 'content' => $content ); } - + $key = 'tb_label_enable_shortcuts'; - if (!in_array($key, $dont_override)) - { + if (!in_array($key, $dont_override)) { $input = new html_checkbox(array( 'name' => $key, 'id' => $key, @@ -161,44 +153,40 @@ public function prefs_list($args) 'content' => $content ); } - + $key = 'tb_label_style'; - if (!in_array($key, $dont_override)) - { + if (!in_array($key, $dont_override)) { $select = new html_select(array( 'name' => $key, 'id' => $key )); $select->add(array($this->gettext('thunderbird'), $this->gettext('bullets')), array('thunderbird', 'bullets')); $content = $select->show($this->rc->config->get($key)); - + $args['blocks']['tb_label']['options'][$key] = array( 'title' => $this->gettext('tb_label_style_option'), 'content' => $content - ); + ); } - + $key = 'tb_label_custom_labels'; - if (!in_array($key, $dont_override) - && $this->rc->config->get('tb_label_modify_labels')) - { + if (!in_array($key, $dont_override) && $this->rc->config->get('tb_label_modify_labels')) { $old = $this->rc->config->get($key); - for($i=1; $i<=5; $i++) - { + for ($i = 1; $i <= 5; $i++) { $input = new html_inputfield(array( - 'name' => $key.$i, - 'id' => $key.$i, + 'name' => $key . $i, + 'id' => $key . $i, 'type' => 'text', 'autocomplete' => 'off', 'value' => $old[$i])); - - $args['blocks']['tb_label']['options'][$key.$i] = array( - 'title' => $this->gettext('tb_label_label')." ".$i, + + $args['blocks']['tb_label']['options'][$key . $i] = array( + 'title' => $this->gettext('tb_label_label') . " " . $i, 'content' => $input->show() - ); + ); } } - + return $args; } @@ -206,133 +194,122 @@ public function prefs_list($args) public function prefs_save($args) { if ($args['section'] != 'thunderbird_labels') - return $args; + return $args; + - $this->load_config(); $dont_override = (array) $this->rc->config->get('dont_override', array()); - + if (!in_array('tb_label_enable', $dont_override)) $args['prefs']['tb_label_enable'] = rcube_utils::get_input_value('tb_label_enable', rcube_utils::INPUT_POST) ? true : false; - + if (!in_array('tb_label_enable_shortcuts', $dont_override)) - $args['prefs']['tb_label_enable_shortcuts'] = rcube_utils::get_input_value('tb_label_enable_shortcuts', rcube_utils::INPUT_POST) ? true : false; + $args['prefs']['tb_label_enable_shortcuts'] = rcube_utils::get_input_value('tb_label_enable_shortcuts', rcube_utils::INPUT_POST) ? true : false; - if (!in_array('tb_label_style', $dont_override)) + if (!in_array('tb_label_style', $dont_override)) $args['prefs']['tb_label_style'] = rcube_utils::get_input_value('tb_label_style', rcube_utils::INPUT_POST); - - if (!in_array('tb_label_custom_labels', $dont_override) - && $this->rc->config->get('tb_label_modify_labels')) - { + + if (!in_array('tb_label_custom_labels', $dont_override) && $this->rc->config->get('tb_label_modify_labels')) { $args['prefs']['tb_label_custom_labels'] = array( - 0 => $this->gettext('label0'), - 1 => rcube_utils::get_input_value('tb_label_custom_labels1', rcube_utils::INPUT_POST), - 2 => rcube_utils::get_input_value('tb_label_custom_labels2', rcube_utils::INPUT_POST), - 3 => rcube_utils::get_input_value('tb_label_custom_labels3', rcube_utils::INPUT_POST), - 4 => rcube_utils::get_input_value('tb_label_custom_labels4', rcube_utils::INPUT_POST), - 5 => rcube_utils::get_input_value('tb_label_custom_labels5', rcube_utils::INPUT_POST) + 0 => $this->gettext('label0'), + 1 => rcube_utils::get_input_value('tb_label_custom_labels1', rcube_utils::INPUT_POST), + 2 => rcube_utils::get_input_value('tb_label_custom_labels2', rcube_utils::INPUT_POST), + 3 => rcube_utils::get_input_value('tb_label_custom_labels3', rcube_utils::INPUT_POST), + 4 => rcube_utils::get_input_value('tb_label_custom_labels4', rcube_utils::INPUT_POST), + 5 => rcube_utils::get_input_value('tb_label_custom_labels5', rcube_utils::INPUT_POST) ); } - + return $args; } - + public function show_tb_label_contextmenu($args) { #$this->api->output->add_label('copymessage.copyingmessage'); - $li = html::tag('li', - array('class' => 'submenu'), - ''.rcube::Q($this->gettext('tb_label_contextmenu_title')).'' . $this->_gen_label_submenu($args, 'tb_label_ctxm_submenu')); + $li = html::tag('li', array('class' => 'submenu'), '' . rcube::Q($this->gettext('tb_label_contextmenu_title')) . '' . $this->_gen_label_submenu($args, 'tb_label_ctxm_submenu')); $out .= html::tag('ul', array('id' => 'tb_label_ctxm_mainmenu'), $li); $this->api->output->add_footer(html::div(array('style' => 'display: none;'), $out)); } - + private function _gen_label_submenu($args, $id) { $out = ''; $custom_labels = $this->rc->config->get('tb_label_custom_labels'); - for ($i = 0; $i < 6; $i++) - { - $separator = ($i == 0)? ' separator_below' :''; - $out .= '
  • '. - $i.' '.$custom_labels[$i]. - '
  • '; + for ($i = 0; $i < 6; $i++) { + $separator = ($i == 0) ? ' separator_below' : ''; + $out .= '
  • ' . + $i . ' ' . $custom_labels[$i] . + '
  • '; } $out = html::tag('ul', array('class' => 'popupmenu toolbarmenu folders', 'id' => $id), $out); return $out; } - + public function read_single_flags($args) { #rcube::write_log($this->name, print_r(($args['object']), true)); if (!isset($args['object'])) { - return; + return; } - - if (is_array($args['object']->headers->flags)) - { + + if (is_array($args['object']->headers->flags)) { $this->message_tb_labels = array(); - foreach ($args['object']->headers->flags as $flagname => $flagvalue) - { - $flag = is_numeric("$flagvalue")? $flagname:$flagvalue;// for compatibility with < 0.5.4 + foreach ($args['object']->headers->flags as $flagname => $flagvalue) { + $flag = is_numeric("$flagvalue") ? $flagname : $flagvalue; // for compatibility with < 0.5.4 $flag = strtolower($flag); - if (preg_match('/^\$?label/', $flag)) - { + if (preg_match('/^\$?label/', $flag)) { $flag_no = preg_replace('/^\$?label/', '', $flag); #rcube::write_log($this->name, "Single message Flag: ".$flag." Flag_no:".$flag_no); - $this->message_tb_labels[] = (int)$flag_no; + $this->message_tb_labels[] = (int) $flag_no; } } } # -- no return value for this hook } - + /** - * Writes labelnumbers for single message display - * Coloring of Message header table happens via Javascript - */ + * Writes labelnumbers for single message display + * Coloring of Message header table happens via Javascript + */ public function color_headers($p) { #rcube::write_log($this->name, print_r($p, true)); # -- always write array, even when empty $p['content'] .= ''; return $p; } - + public function read_flags($args) { #rcube::write_log($this->name, print_r($args, true)); // add color information for all messages // dont loop over all messages if we dont have any highlights or no msgs - if (!isset($args['messages']) or !is_array($args['messages'])) { - return $args; + if (!isset($args['messages']) or ! is_array($args['messages'])) { + return $args; } // loop over all messages and add $LabelX info to the extra_flags - foreach($args['messages'] as $message) - { + foreach ($args['messages'] as $message) { #rcube::write_log($this->name, print_r($message->flags, true)); $message->list_flags['extra_flags']['tb_labels'] = array(); # always set extra_flags, needed for javascript later! if (is_array($message->flags)) - foreach ($message->flags as $flagname => $flagvalue) - { - $flag = is_numeric("$flagvalue")? $flagname:$flagvalue;// for compatibility with < 0.5.4 - $flag = strtolower($flag); - if (preg_match('/^\$?label/', $flag)) - { - $flag_no = preg_replace('/^\$?label/', '', $flag); - #rcube::write_log($this->name, "Flag:".$flag." Flag_no:".$flag_no); - $message->list_flags['extra_flags']['tb_labels'][] = (int)$flag_no; + foreach ($message->flags as $flagname => $flagvalue) { + $flag = is_numeric("$flagvalue") ? $flagname : $flagvalue; // for compatibility with < 0.5.4 + $flag = strtolower($flag); + if (preg_match('/^\$?label/', $flag)) { + $flag_no = preg_replace('/^\$?label/', '', $flag); + #rcube::write_log($this->name, "Flag:".$flag." Flag_no:".$flag_no); + $message->list_flags['extra_flags']['tb_labels'][] = (int) $flag_no; + } } - } } return($args); } - + // set flags in IMAP server function set_flags() { @@ -346,14 +323,13 @@ function set_flags() $flag_uids = explode(',', $flag_uids); $unflag_uids = rcube_utils::get_input_value('_unflag_uids', rcube_utils::INPUT_GET); $unflag_uids = explode(',', $unflag_uids); - + $imap->conn->flags = array_merge($imap->conn->flags, $this->add_tb_flags); - + #rcube::write_log($this->name, print_r($flag_uids, true)); #rcube::write_log($this->name, print_r($unflag_uids, true)); - if (!is_array($unflag_uids) - || !is_array($flag_uids)) + if (!is_array($unflag_uids) || !is_array($flag_uids)) return false; $imap->set_flag($flag_uids, $toggle_label, $mbox); @@ -361,21 +337,19 @@ function set_flags() $this->api->output->send(); } - + function tb_label_popup() { - $custom_labels = $this->rc->config->get('tb_label_custom_labels'); + $custom_labels = $this->rc->config->get('tb_label_custom_labels'); $out = '
    '; $this->rc->output->add_gui_object('tb_label_popup_obj', 'tb_label_popup'); - $this->rc->output->add_footer($out); + $this->rc->output->add_footer($out); } } - From f09d37d8f1dcee296adc2338eb5fa21ab0173c01 Mon Sep 17 00:00:00 2001 From: Mariusz Krzaczkowski Date: Tue, 28 Feb 2017 08:57:56 +0100 Subject: [PATCH 03/10] Updated Thunderbird Labels Plugin for Roundcube Webmail --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index eec05b05..da8e7e00 100644 --- a/version.php +++ b/version.php @@ -1,5 +1,5 @@ '2017.02.23', - 'version' => '0.0.25' + 'patch' => '2017.02.28', + 'version' => '0.0.26' ]; From 48d331d93100bf325ee762a08ec9c5d2c8f77ecc Mon Sep 17 00:00:00 2001 From: Mariusz Krzaczkowski Date: Fri, 17 Mar 2017 16:21:05 +0100 Subject: [PATCH 04/10] Enhanced prefix support in mail scanners --- plugins/yetiforce/yetiforce.php | 1370 +++++++++++++++---------------- version.php | 10 +- 2 files changed, 690 insertions(+), 690 deletions(-) diff --git a/plugins/yetiforce/yetiforce.php b/plugins/yetiforce/yetiforce.php index 6f3672c1..2439f0b5 100644 --- a/plugins/yetiforce/yetiforce.php +++ b/plugins/yetiforce/yetiforce.php @@ -1,685 +1,685 @@ - - */ -class yetiforce extends rcube_plugin -{ - - private $rc; - private $autologin; - private $currentUser; - private $viewData = []; - - public function init() - { - $this->rc = rcmail::get_instance(); - $this->add_hook('login_after', [$this, 'loginAfter']); - $this->add_hook('startup', [$this, 'startup']); - $this->add_hook('authenticate', [$this, 'authenticate']); - - if ($this->rc->task == 'mail') { - $this->register_action('plugin.yetiforce.addFilesToMail', [$this, 'addFilesToMail']); - $this->register_action('plugin.yetiforce.getEmailTemplates', [$this, 'getEmailTemplates']); - $this->register_action('plugin.yetiforce.getEmailFromCRM', [$this, 'getEmailFromCRM']); - $this->register_action('plugin.yetiforce.getConntentEmailTemplate', [$this, 'getConntentEmailTemplate']); - $this->rc->output->set_env('site_URL', $this->rc->config->get('site_URL')); - $this->include_stylesheet($this->rc->config->get('site_URL') . 'layouts/basic/skins/icons/userIcons.css'); - - $currentPath = getcwd(); - chdir($this->rc->config->get('root_directory')); - $this->loadCurrentUser(); - - if ($this->rc->action == 'compose') { - $composeAddressModules = []; - foreach (AppConfig::module('Mail', 'RC_COMPOSE_ADDRESS_MODULES') as $moduleName) { - if (\App\Privilege::isPermitted($moduleName)) { - $composeAddressModules[$moduleName] = \App\Language::translate($moduleName, $moduleName); - } - } - $this->viewData['compose']['composeAddressModules'] = $composeAddressModules; - $this->rc->output->set_env('isPermittedMailTemplates', \App\Privilege::isPermitted('EmailTemplates')); - - $this->add_texts('localization/', false); - $this->include_script('compose.js'); - - $this->add_hook('message_compose_body', [$this, 'messageComposeBody']); - $this->add_hook('message_compose', [$this, 'messageComposeHead']); - $this->add_hook('render_page', [$this, 'loadSignature']); - $this->add_hook('template_object_yt_adress_button', [$this, 'ytAdressButton']); - - $id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); - if ($id && isset($_SESSION['compose_data_' . $id]['param']['crmmodule'])) { - $this->rc->output->set_env('crmModule', $_SESSION['compose_data_' . $id]['param']['crmmodule']); - } - if ($id && isset($_SESSION['compose_data_' . $id]['param']['crmrecord'])) { - $this->rc->output->set_env('crmRecord', $_SESSION['compose_data_' . $id]['param']['crmrecord']); - } - if ($id && isset($_SESSION['compose_data_' . $id]['param']['crmview'])) { - $this->rc->output->set_env('crmView', $_SESSION['compose_data_' . $id]['param']['crmview']); - } - } - if ($this->rc->action == 'preview' || $this->rc->action == 'show') { - $this->include_script('preview.js'); - $this->include_stylesheet($this->rc->config->get('site_URL') . 'libraries/bootstrap3/css/glyphicon.css'); - $this->include_stylesheet('preview.css'); - $this->add_hook('message_load', [$this, 'messageLoad']); - } - if (empty($this->rc->action)) { - //$this->add_hook('preferences_save', array($this, 'prefsSave')); - - $this->include_script('colResizable.js'); - $this->include_script('list.js'); - } - chdir($currentPath); - } - } - - public function startup($args) - { - $row = $this->getAutoLogin(); - if (!$row || empty($_GET['_autologin'])) { - return $args; - } - if (!empty($_SESSION['user_id']) && $_SESSION['user_id'] != $row['user_id']) { - $this->rc->logout_actions(); - $this->rc->kill_session(); - $this->rc->plugins->exec_hook('logout_after', [ - 'user' => $_SESSION['username'], - 'host' => $_SESSION['storage_host'], - 'lang' => $this->rc->user->language - ]); - } - if (empty($_SESSION['user_id']) && !empty($_GET['_autologin'])) { - $args['action'] = 'login'; - } - return $args; - } - - public function authenticate($args) - { - if (empty($_GET['_autologin'])) { - return $args; - } - $row = $this->getAutoLogin(); - if ($row) { - $host = false; - foreach ($this->rc->config->get('default_host') as $key => $value) { - if (strpos($key, $row['mail_host']) !== false) { - $host = $key; - } - } - if ($host) { - $args['user'] = $row['username']; - $args['pass'] = $row['password']; - $args['host'] = $host; - $args['cookiecheck'] = false; - $args['valid'] = true; - } - $db = $this->rc->get_dbh(); - $db->query('DELETE FROM `u_yf_mail_autologin` WHERE `cuid` = ?;', $row['cuid']); - } - return $args; - } - - public function loginAfter($args) - { - // Password saving - $this->rc = rcmail::get_instance(); - $pass = rcube_utils::get_input_value('_pass', rcube_utils::INPUT_POST); - if (!empty($pass)) { - $sql = "UPDATE " . $this->rc->db->table_name('users') . " SET password = ? WHERE user_id = ?"; - call_user_func_array(array($this->rc->db, 'query'), array_merge(array($sql), array($pass, $this->rc->get_user_id()))); - $this->rc->db->affected_rows(); - } - if ($_GET['_autologin'] && !empty($_REQUEST['_composeKey'])) { - $args['_action'] = 'compose'; - $args['_task'] = 'mail'; - $args['_composeKey'] = rcube_utils::get_input_value('_composeKey', rcube_utils::INPUT_GET); - } - if ($row = $this->getAutoLogin()) { - $_SESSION['crm']['id'] = $row['cuid']; - if (isset($row['params']['language'])) { - $languages = $this->rc->list_languages(); - $lang = explode('_', $row['params']['language']); - $lang[1] = strtoupper($lang[1]); - $lang = implode('_', $lang); - if (!isset($languages[$lang])) { - $lang = substr($lang, 0, 2); - } - if (isset($languages[$lang])) { - $this->rc->config->set('language', $lang); - $this->rc->load_language($lang); - $this->rc->user->save_prefs(['language' => $lang]); - } - } - } - return $args; - } - - public function messageLoad($args) - { - if (!isset($args['object'])) { - return; - } - $this->rc->output->set_env('subject', $args['object']->headers->subject); - $from = $args['object']->headers->from; - $from = explode('<', rtrim($from, '>'), 2); - $fromName = ''; - if (count($from) > 1) { - $fromName = $from[0]; - $fromMail = $from[1]; - } else { - $fromMail = $from[0]; - } - $this->rc->output->set_env('fromName', $fromName); - $this->rc->output->set_env('fromMail', $fromMail); - } - - public function messageComposeHead($args) - { - $this->rc = rcmail::get_instance(); - $db = $this->rc->get_dbh(); - global $COMPOSE_ID; - - $composeKey = rcube_utils::get_input_value('_composeKey', rcube_utils::INPUT_GET); - $result = $db->query('SELECT * FROM `u_yf_mail_compose_data` WHERE `key` = ?', $composeKey); - $params = $db->fetch_assoc($result); - $db->query('DELETE FROM `u_yf_mail_compose_data` WHERE `key` = ?;', $composeKey); - if (!empty($params)) { - $params = json_decode($params['data'], true); - - foreach ($params as $key => &$value) { - $args['param'][$key] = $value; - } - if ((isset($params['crmmodule']) && $params['crmmodule'] == 'Documents') || (isset($params['filePath']) && $params['filePath'])) { - $userid = $this->rc->user->ID; - list($usec, $sec) = explode(' ', microtime()); - $dId = preg_replace('/[^0-9]/', '', $userid . $sec . $usec); - foreach (self::getAttachment($params['crmrecord'], $params['filePath']) as $index => $attachment) { - $attachment['group'] = $COMPOSE_ID; - $attachment['id'] = $dId . $index; - $args['attachments'][$attachment['id']] = $attachment; - } - } - if (!isset($params['mailId'])) { - return $args; - } - $mailId = $params['mailId']; - $result = $db->query('SELECT content,reply_to_email,date,from_email,to_email,cc_email,subject FROM vtiger_ossmailview WHERE ossmailviewid = ?;', $mailId); - $row = $db->fetch_assoc($result); - $args['param']['type'] = $params['type']; - $args['param']['mailData'] = $row; - switch ($params['type']) { - case 'replyAll': - $cc = $row['to_email']; - $cc .= ',' . $row['cc_email']; - $cc = str_replace($row['from_email'] . ',', '', $cc); - $cc = trim($cc, ','); - case 'reply': - $to = $row['reply_to_email']; - if (preg_match('/^re:/i', $row['subject'])) - $subject = $row['subject']; - else - $subject = 'Re: ' . $row['subject']; - $subject = preg_replace('/\s*\([wW]as:[^\)]+\)\s*$/', '', $subject); - break; - case 'forward': - if (preg_match('/^fwd:/i', $row['subject'])) - $subject = $row['subject']; - else - $subject = 'Fwd: ' . $row['subject']; - break; - } - if (!empty($params['recordNumber']) && !empty($params['crmmodule'])) { - $currentPath = getcwd(); - chdir($this->rc->config->get('root_directory')); - $this->loadCurrentUser(); - - $subjectNumber = \App\Fields\Email::findRecordNumber($subject, $params['crmmodule']); - $recordNumber = \App\Fields\Email::findRecordNumber('[' . $params['recordNumber'] . ']', $params['crmmodule']); - if ($subject === false || ($subject !== false && $subjectNumber != $recordNumber)) { - $subject .= ' [' . $params['recordNumber'] . ']'; - } - - chdir($currentPath); - } - $args['param']['to'] = $to; - $args['param']['cc'] = $cc; - $args['param']['subject'] = $subject; - } - return $args; - } - - public function messageComposeBody($args) - { - $this->rc = rcmail::get_instance(); - - $id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); - $row = $_SESSION['compose_data_' . $id]['param']['mailData']; - $type = $_SESSION['compose_data_' . $id]['param']['type']; - if (!$row) { - return; - } - $bodyIsHtml = $args['html']; - $date = $row['date']; - $from = $row['from_email']; - $to = $row['to_email']; - $body = $row['content']; - $subject = $row['subject']; - $replyto = $row['reply_to_email']; - - $prefix = $suffix = ''; - if ($type == 'forward') { - if (!$bodyIsHtml) { - $prefix = "\n\n\n-------- " . $this->rc->gettext('originalmessage') . " --------\n"; - $prefix .= $this->rc->gettext('subject') . ': ' . $subject . "\n"; - $prefix .= $this->rc->gettext('date') . ': ' . $date . "\n"; - $prefix .= $this->rc->gettext('from') . ': ' . $from . "\n"; - $prefix .= $this->rc->gettext('to') . ': ' . $to . "\n"; - if ($cc = $row['cc_email']) { - $prefix .= $this->rc->gettext('cc') . ': ' . $cc . "\n"; - } - if ($replyto != $from) { - $prefix .= $this->rc->gettext('replyto') . ': ' . $replyto . "\n"; - } - $prefix .= "\n"; - global $LINE_LENGTH; - $txt = new rcube_html2text($body, false, true, $LINE_LENGTH); - $body = $txt->get_text(); - $body = preg_replace('/\r?\n/', "\n", $body); - $body = trim($body, "\n"); - } else { - $prefix = sprintf( - "

    -------- " . $this->rc->gettext('originalmessage') . " --------

    " . - "" . - "" . - "" . - "" . - "", $this->rc->gettext('subject'), rcube::Q($subject), $this->rc->gettext('date'), rcube::Q($date), $this->rc->gettext('from'), rcube::Q($from, 'replace'), $this->rc->gettext('to'), rcube::Q($to, 'replace')); - if ($cc = $row['cc_email']) - $prefix .= sprintf("", $this->rc->gettext('cc'), rcube::Q($cc, 'replace')); - if ($replyto != $from) - $prefix .= sprintf("", $this->rc->gettext('replyto'), rcube::Q($replyto, 'replace')); - $prefix .= "
    %s: %s
    %s: %s
    %s: %s
    %s: %s
    %s: %s
    %s: %s

    "; - } - $body = $prefix . $body; - }else { - $prefix = $this->rc->gettext(array( - 'name' => 'mailreplyintro', - 'vars' => array( - 'date' => $this->rc->format_date($date, $this->rc->config->get('date_long')), - 'sender' => $from, - ) - )); - if (!$bodyIsHtml) { - global $LINE_LENGTH; - $txt = new rcube_html2text($body, false, true, $LINE_LENGTH); - $body = $txt->get_text(); - $body = preg_replace('/\r?\n/', "\n", $body); - $body = trim($body, "\n"); - $body = rcmailWrapAndQuote($body, $LINE_LENGTH); - $prefix .= "\n"; - $body = $prefix . $body . $suffix; - } else { - $prefix = '

    ' . rcube::Q($prefix) . "

    \n"; - $body = $prefix . '
    ' . $body . '
    ' . $suffix; - } - } - $this->rc->output->set_env('compose_mode', $type); - $args['body'] = $body; - return $args; - } - - // Loading signature - public function loadSignature($response) - { - global $OUTPUT, $MESSAGE; - if ($this->rc->config->get('enable_variables_in_signature') && !empty($OUTPUT->get_env('signatures'))) { - $signatures = []; - foreach ($OUTPUT->get_env('signatures') as $identityId => $signature) { - $signatures[$identityId]['text'] = $this->parseVariables($signature['text']); - $signatures[$identityId]['html'] = $this->parseVariables($signature['html']); - } - $OUTPUT->set_env('signatures', $signatures); - } - if ($this->checkAddSignature()) { - return; - } - $gS = $this->getGlobalSignature(); - if (empty($gS['html'])) { - return; - } - $signatures = []; - foreach ($OUTPUT->get_env('signatures') as $identityId => $signature) { - $signatures[$identityId]['text'] = $signature['text'] . PHP_EOL . $gS['text']; - $signatures[$identityId]['html'] = $signature['html'] . '
    ' . $gS['html'] . '
    '; - } - if (count($MESSAGE->identities)) { - foreach ($MESSAGE->identities as &$identity) { - $identityId = $identity['identity_id']; - if (!isset($signatures[$identityId])) { - $signatures[$identityId]['text'] = "--\n" . $gS['text']; - $signatures[$identityId]['html'] = '--
    ' . $gS['html'] . '
    '; - } - } - } - $OUTPUT->set_env('signatures', $signatures); - } - - public function getGlobalSignature() - { - global $RCMAIL; - $db = $RCMAIL->get_dbh(); - $result = []; - $sql_result = $db->query("SELECT * FROM yetiforce_mail_config WHERE `type` = 'signature' AND `name` = 'signature';"); - - while ($sql_arr = $db->fetch_assoc($sql_result)) { - $result['html'] = $sql_arr['value']; - $result['text'] = $sql_arr['value']; - } - return $result; - } - - public function checkAddSignature() - { - global $RCMAIL; - $db = $RCMAIL->get_dbh(); - $result = []; - $sql_result = $db->query("SELECT * FROM yetiforce_mail_config WHERE `type` = 'signature' AND `name` = 'addSignature';"); - - while ($sql_arr = $db->fetch_assoc($sql_result)) { - return $sql_arr['value'] == 'false' ? true : false; - } - return true; - } - - // Adding attachments - public function addFilesToMail() - { - $COMPOSE_ID = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); - $uploadid = rcube_utils::get_input_value('_uploadid', rcube_utils::INPUT_GPC); - $ids = rcube_utils::get_input_value('ids', rcube_utils::INPUT_GPC); - $COMPOSE = null; - - if ($COMPOSE_ID && $_SESSION['compose_data_' . $COMPOSE_ID]) { - $SESSION_KEY = 'compose_data_' . $COMPOSE_ID; - $COMPOSE = & $_SESSION[$SESSION_KEY]; - } - if (!$COMPOSE) { - die('Invalid session var!'); - } - $this->rc = rcmail::get_instance(); - $index = 0; - - $attachments = $this->getAttachment($ids, false); - foreach ($attachments as $attachment) { - $index++; - $attachment['group'] = $COMPOSE_ID; - $userid = rcmail::get_instance()->user->ID; - list($usec, $sec) = explode(' ', microtime()); - $id = preg_replace('/[^0-9]/', '', $userid . $sec . $usec) . $index; - $attachment['id'] = $id; - - $_SESSION['plugins']['filesystem_attachments'][$COMPOSE_ID][$id] = $attachment['path']; - $this->rc->session->append($SESSION_KEY . '.attachments', $id, $attachment); - if (($icon = $COMPOSE['deleteicon']) && is_file($icon)) { - $button = html::img(array( - 'src' => $icon, - 'alt' => $this->rc->gettext('delete') - )); - } else if ($COMPOSE['textbuttons']) { - $button = rcube::Q($this->rc->gettext('delete')); - } else { - $button = ''; - } - - $content = html::a(array( - 'href' => "#delete", - 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", rcmail_output::JS_OBJECT_NAME, $id), - 'title' => $this->rc->gettext('delete'), - 'class' => 'delete', - 'aria-label' => $this->rc->gettext('delete') . ' ' . $attachment['name'], - ), $button - ); - - $content .= rcube::Q($attachment['name']); - $htmlAttachments .= 'window.rcmail.add2attachment_list("rcmfile' . $id . '",{html:"rc->gettext('delete') . '\" class=\"delete\" aria-label=\"' . $this->rc->gettext('delete') . ' ' . $attachment['name'] . '\"><\/a>' . $attachment['name'] . '",name:"' . $attachment['name'] . '",mimetype:"' . $attachment['mimetype'] . '",classname:"' . rcube_utils::file2class($attachment['mimetype'], $attachment['name']) . '",complete:true},"' . $uploadid . '");' . PHP_EOL; - } - $response = ' - - - - - - -'; - echo $response; - exit; - } - - public function getAttachment($ids, $files) - { - - $attachments = []; - if (empty($ids) && empty($files)) { - return $attachments; - } - if (is_array($ids)) { - $ids = implode(',', $ids); - } - $this->rc = rcmail::get_instance(); - $db = $this->rc->get_dbh(); - $userid = $this->rc->user->ID; - $index = 0; - if ($ids) { - $sql_result = $db->query("SELECT vtiger_attachments.* FROM vtiger_attachments INNER JOIN vtiger_seattachmentsrel ON vtiger_seattachmentsrel.attachmentsid=vtiger_attachments.attachmentsid WHERE vtiger_seattachmentsrel.crmid IN ($ids);"); - while ($row = $db->fetch_assoc($sql_result)) { - $orgFile = $this->rc->config->get('root_directory') . $row['path'] . $row['attachmentsid'] . '_' . $row['name']; - list($usec, $sec) = explode(' ', microtime()); - $filepath = $this->rc->config->get('root_directory') . 'cache/mail/' . $sec . $userid . $row['attachmentsid'] . $index . '.tmp'; - if (file_exists($orgFile)) { - copy($orgFile, $filepath); - $attachment = [ - 'path' => $filepath, - 'size' => filesize($filepath), - 'name' => $row['name'], - 'mimetype' => rcube_mime::file_content_type($filepath, $row['name'], $row['type']), - ]; - $attachments[] = $attachment; - } - $index++; - } - } - if ($files) { - $orgFile = $this->rc->config->get('root_directory') . $files; - list($usec, $sec) = explode(' ', microtime()); - $filepath = $this->rc->config->get('root_directory') . 'cache/mail/' . $sec . $userid . $index . '.tmp'; - if (file_exists($orgFile)) { - copy($orgFile, $filepath); - $attachment = [ - 'path' => $filepath, - 'size' => filesize($filepath), - 'name' => basename($orgFile), - 'mimetype' => rcube_mime::file_content_type($filepath, basename($orgFile)), - ]; - $attachments[] = $attachment; - } - $index++; - } - return $attachments; - } - - public function rcmailWrapAndQuote($text, $length = 72) - { - // Rebuild the message body with a maximum of $max chars, while keeping quoted message. - $max = max(75, $length + 8); - $lines = preg_split('/\r?\n/', trim($text)); - $out = ''; - foreach ($lines as $line) { - // don't wrap already quoted lines - if ($line[0] == '>') { - $line = '>' . rtrim($line); - } else if (mb_strlen($line) > $max) { - $newline = ''; - - foreach (explode("\n", rcube_mime::wordwrap($line, $length - 2)) as $l) { - if (strlen($l)) - $newline .= '> ' . $l . "\n"; - else - $newline .= ">\n"; - } - - $line = rtrim($newline); - } else { - $line = '> ' . $line; - } - // Append the line - $out .= $line . "\n"; - } - return rtrim($out, "\n"); - } - - protected function getAutoLogin() - { - if (empty($_GET['_autologinKey'])) { - return false; - } - if (isset($this->autologin)) { - return $this->autologin; - } - $key = rcube_utils::get_input_value('_autologinKey', rcube_utils::INPUT_GPC); - $db = $this->rc->get_dbh(); - $sqlResult = $db->query('SELECT * FROM u_yf_mail_autologin INNER JOIN roundcube_users ON roundcube_users.user_id = u_yf_mail_autologin.ruid WHERE roundcube_users.password <> \'\' AND u_yf_mail_autologin.`key` = ?;', $key); - $autologin = false; - if ($row = $db->fetch_assoc($sqlResult)) { - $autologin = $row; - $autologin['params'] = json_decode($autologin['params'], true); - } - $this->autologin = $autologin; - return $autologin; - } - - /** - * Parse variables - * @param string $text - * @return string - */ - protected function parseVariables($text) - { - $currentPath = getcwd(); - chdir($this->rc->config->get('root_directory')); - $this->loadCurrentUser(); - - $text = \App\TextParser::getInstance() - ->setContent($text) - ->parse() - ->getContent(); - - chdir($currentPath); - return $text; - } - - protected function loadCurrentUser() - { - if (isset($this->currentUser)) { - return true; - } - require 'include/main/WebUI.php'; - $ownerObject = CRMEntity::getInstance('Users'); - $ownerObject->retrieveCurrentUserInfoFromFile($_SESSION['crm']['id']); - $this->currentUser = $ownerObject; - vglobal('current_user', $ownerObject); - App\User::setCurrentUserId($_SESSION['crm']['id']); - return true; - } - - public function ytAdressButton($p) - { - if (empty($this->viewData['compose']['composeAddressModules'])) { - return $p; - } - $content = ''; - foreach ($this->viewData['compose']['composeAddressModules'] as $moduleName => $value) { - $text = html::span(['class' => "userIcon-$moduleName"], '') . ' ' . $value; - $content .= html::a(['class' => 'button', 'data-input' => $p['part'], 'data-module' => $moduleName], $text); - } - $p['content'] = $content; - return $p; - } - - /** - * Get address email from CRM - */ - public function getEmailFromCRM() - { - $currentPath = getcwd(); - chdir($this->rc->config->get('root_directory')); - $this->loadCurrentUser(); - $ids = rcube_utils::get_input_value('recordsId', rcube_utils::INPUT_GPC); - $sourceModule = rcube_utils::get_input_value('moduleName', rcube_utils::INPUT_GPC); - $emailFields = OSSMailScanner_Record_Model::getEmailSearch($sourceModule); - $addresEmails = []; - foreach ($ids as $id) { - $recordModel = Vtiger_Record_Model::getInstanceById($id, $sourceModule); - foreach ($emailFields as &$emailField) { - $email = $recordModel->get($emailField['fieldname']); - if (!empty($email)) { - $addresEmails[] = $email; - } - } - } - echo App\Json::encode($addresEmails); - chdir($currentPath); - exit; - } - - /** - * Function to get templates - */ - public function getEmailTemplates() - { - $currentPath = getcwd(); - chdir($this->rc->config->get('root_directory')); - $this->loadCurrentUser(); - $emailTemplates = App\Mail::getTempleteList(false, 'PLL_MAIL'); - echo App\Json::encode($emailTemplates); - chdir($currentPath); - exit; - } - - /** - * Function to get info about email template - */ - public function getConntentEmailTemplate() - { - $templeteId = rcube_utils::get_input_value('id', rcube_utils::INPUT_GPC); - $recordId = rcube_utils::get_input_value('record_id', rcube_utils::INPUT_GPC); - $moduleName = rcube_utils::get_input_value('select_module', rcube_utils::INPUT_GPC); - $currentPath = getcwd(); - chdir($this->rc->config->get('root_directory')); - $this->loadCurrentUser(); - $mail = App\Mail::getTemplete($templeteId); - if ($recordId) { - $textParser = \App\TextParser::getInstanceById($recordId, $moduleName); - $mail['subject'] = $textParser->setContent($mail['subject'])->parse()->getContent(); - $mail['content'] = $textParser->setContent($mail['content'])->parse()->getContent(); - } - echo App\Json::encode([ - 'subject' => $mail['subject'], - 'content' => $mail['content'], - 'attachments' => $mail['attachments'], - ]); - chdir($currentPath); - exit; - } -} + + */ +class yetiforce extends rcube_plugin +{ + + private $rc; + private $autologin; + private $currentUser; + private $viewData = []; + + public function init() + { + $this->rc = rcmail::get_instance(); + $this->add_hook('login_after', [$this, 'loginAfter']); + $this->add_hook('startup', [$this, 'startup']); + $this->add_hook('authenticate', [$this, 'authenticate']); + + if ($this->rc->task == 'mail') { + $this->register_action('plugin.yetiforce.addFilesToMail', [$this, 'addFilesToMail']); + $this->register_action('plugin.yetiforce.getEmailTemplates', [$this, 'getEmailTemplates']); + $this->register_action('plugin.yetiforce.getEmailFromCRM', [$this, 'getEmailFromCRM']); + $this->register_action('plugin.yetiforce.getConntentEmailTemplate', [$this, 'getConntentEmailTemplate']); + $this->rc->output->set_env('site_URL', $this->rc->config->get('site_URL')); + $this->include_stylesheet($this->rc->config->get('site_URL') . 'layouts/basic/skins/icons/userIcons.css'); + + $currentPath = getcwd(); + chdir($this->rc->config->get('root_directory')); + $this->loadCurrentUser(); + + if ($this->rc->action == 'compose') { + $composeAddressModules = []; + foreach (AppConfig::module('Mail', 'RC_COMPOSE_ADDRESS_MODULES') as $moduleName) { + if (\App\Privilege::isPermitted($moduleName)) { + $composeAddressModules[$moduleName] = \App\Language::translate($moduleName, $moduleName); + } + } + $this->viewData['compose']['composeAddressModules'] = $composeAddressModules; + $this->rc->output->set_env('isPermittedMailTemplates', \App\Privilege::isPermitted('EmailTemplates')); + + $this->add_texts('localization/', false); + $this->include_script('compose.js'); + + $this->add_hook('message_compose_body', [$this, 'messageComposeBody']); + $this->add_hook('message_compose', [$this, 'messageComposeHead']); + $this->add_hook('render_page', [$this, 'loadSignature']); + $this->add_hook('template_object_yt_adress_button', [$this, 'ytAdressButton']); + + $id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); + if ($id && isset($_SESSION['compose_data_' . $id]['param']['crmmodule'])) { + $this->rc->output->set_env('crmModule', $_SESSION['compose_data_' . $id]['param']['crmmodule']); + } + if ($id && isset($_SESSION['compose_data_' . $id]['param']['crmrecord'])) { + $this->rc->output->set_env('crmRecord', $_SESSION['compose_data_' . $id]['param']['crmrecord']); + } + if ($id && isset($_SESSION['compose_data_' . $id]['param']['crmview'])) { + $this->rc->output->set_env('crmView', $_SESSION['compose_data_' . $id]['param']['crmview']); + } + } + if ($this->rc->action == 'preview' || $this->rc->action == 'show') { + $this->include_script('preview.js'); + $this->include_stylesheet($this->rc->config->get('site_URL') . 'libraries/bootstrap3/css/glyphicon.css'); + $this->include_stylesheet('preview.css'); + $this->add_hook('message_load', [$this, 'messageLoad']); + } + if (empty($this->rc->action)) { + //$this->add_hook('preferences_save', array($this, 'prefsSave')); + + $this->include_script('colResizable.js'); + $this->include_script('list.js'); + } + chdir($currentPath); + } + } + + public function startup($args) + { + $row = $this->getAutoLogin(); + if (!$row || empty($_GET['_autologin'])) { + return $args; + } + if (!empty($_SESSION['user_id']) && $_SESSION['user_id'] != $row['user_id']) { + $this->rc->logout_actions(); + $this->rc->kill_session(); + $this->rc->plugins->exec_hook('logout_after', [ + 'user' => $_SESSION['username'], + 'host' => $_SESSION['storage_host'], + 'lang' => $this->rc->user->language + ]); + } + if (empty($_SESSION['user_id']) && !empty($_GET['_autologin'])) { + $args['action'] = 'login'; + } + return $args; + } + + public function authenticate($args) + { + if (empty($_GET['_autologin'])) { + return $args; + } + $row = $this->getAutoLogin(); + if ($row) { + $host = false; + foreach ($this->rc->config->get('default_host') as $key => $value) { + if (strpos($key, $row['mail_host']) !== false) { + $host = $key; + } + } + if ($host) { + $args['user'] = $row['username']; + $args['pass'] = $row['password']; + $args['host'] = $host; + $args['cookiecheck'] = false; + $args['valid'] = true; + } + $db = $this->rc->get_dbh(); + $db->query('DELETE FROM `u_yf_mail_autologin` WHERE `cuid` = ?;', $row['cuid']); + } + return $args; + } + + public function loginAfter($args) + { + // Password saving + $this->rc = rcmail::get_instance(); + $pass = rcube_utils::get_input_value('_pass', rcube_utils::INPUT_POST); + if (!empty($pass)) { + $sql = "UPDATE " . $this->rc->db->table_name('users') . " SET password = ? WHERE user_id = ?"; + call_user_func_array(array($this->rc->db, 'query'), array_merge(array($sql), array($pass, $this->rc->get_user_id()))); + $this->rc->db->affected_rows(); + } + if ($_GET['_autologin'] && !empty($_REQUEST['_composeKey'])) { + $args['_action'] = 'compose'; + $args['_task'] = 'mail'; + $args['_composeKey'] = rcube_utils::get_input_value('_composeKey', rcube_utils::INPUT_GET); + } + if ($row = $this->getAutoLogin()) { + $_SESSION['crm']['id'] = $row['cuid']; + if (isset($row['params']['language'])) { + $languages = $this->rc->list_languages(); + $lang = explode('_', $row['params']['language']); + $lang[1] = strtoupper($lang[1]); + $lang = implode('_', $lang); + if (!isset($languages[$lang])) { + $lang = substr($lang, 0, 2); + } + if (isset($languages[$lang])) { + $this->rc->config->set('language', $lang); + $this->rc->load_language($lang); + $this->rc->user->save_prefs(['language' => $lang]); + } + } + } + return $args; + } + + public function messageLoad($args) + { + if (!isset($args['object'])) { + return; + } + $this->rc->output->set_env('subject', $args['object']->headers->subject); + $from = $args['object']->headers->from; + $from = explode('<', rtrim($from, '>'), 2); + $fromName = ''; + if (count($from) > 1) { + $fromName = $from[0]; + $fromMail = $from[1]; + } else { + $fromMail = $from[0]; + } + $this->rc->output->set_env('fromName', $fromName); + $this->rc->output->set_env('fromMail', $fromMail); + } + + public function messageComposeHead($args) + { + $this->rc = rcmail::get_instance(); + $db = $this->rc->get_dbh(); + global $COMPOSE_ID; + + $composeKey = rcube_utils::get_input_value('_composeKey', rcube_utils::INPUT_GET); + $result = $db->query('SELECT * FROM `u_yf_mail_compose_data` WHERE `key` = ?', $composeKey); + $params = $db->fetch_assoc($result); + $db->query('DELETE FROM `u_yf_mail_compose_data` WHERE `key` = ?;', $composeKey); + if (!empty($params)) { + $params = json_decode($params['data'], true); + + foreach ($params as $key => &$value) { + $args['param'][$key] = $value; + } + if ((isset($params['crmmodule']) && $params['crmmodule'] == 'Documents') || (isset($params['filePath']) && $params['filePath'])) { + $userid = $this->rc->user->ID; + list($usec, $sec) = explode(' ', microtime()); + $dId = preg_replace('/[^0-9]/', '', $userid . $sec . $usec); + foreach (self::getAttachment($params['crmrecord'], $params['filePath']) as $index => $attachment) { + $attachment['group'] = $COMPOSE_ID; + $attachment['id'] = $dId . $index; + $args['attachments'][$attachment['id']] = $attachment; + } + } + if (!isset($params['mailId'])) { + return $args; + } + $mailId = $params['mailId']; + $result = $db->query('SELECT content,reply_to_email,date,from_email,to_email,cc_email,subject FROM vtiger_ossmailview WHERE ossmailviewid = ?;', $mailId); + $row = $db->fetch_assoc($result); + $args['param']['type'] = $params['type']; + $args['param']['mailData'] = $row; + switch ($params['type']) { + case 'replyAll': + $cc = $row['to_email']; + $cc .= ',' . $row['cc_email']; + $cc = str_replace($row['from_email'] . ',', '', $cc); + $cc = trim($cc, ','); + case 'reply': + $to = $row['reply_to_email']; + if (preg_match('/^re:/i', $row['subject'])) + $subject = $row['subject']; + else + $subject = 'Re: ' . $row['subject']; + $subject = preg_replace('/\s*\([wW]as:[^\)]+\)\s*$/', '', $subject); + break; + case 'forward': + if (preg_match('/^fwd:/i', $row['subject'])) + $subject = $row['subject']; + else + $subject = 'Fwd: ' . $row['subject']; + break; + } + if (!empty($params['recordNumber']) && !empty($params['crmmodule'])) { + $currentPath = getcwd(); + chdir($this->rc->config->get('root_directory')); + $this->loadCurrentUser(); + + $subjectNumber = \App\Fields\Email::findRecordNumber($subject, $params['crmmodule']); + $recordNumber = \App\Fields\Email::findRecordNumber("[{$params['recordNumber']}]", $params['crmmodule']); + if ($subject === false || ($subject !== false && $subjectNumber !== $recordNumber)) { + $subject = "[{$params['recordNumber']}] $subject"; + } + + chdir($currentPath); + } + $args['param']['to'] = $to; + $args['param']['cc'] = $cc; + $args['param']['subject'] = $subject; + } + return $args; + } + + public function messageComposeBody($args) + { + $this->rc = rcmail::get_instance(); + + $id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); + $row = $_SESSION['compose_data_' . $id]['param']['mailData']; + $type = $_SESSION['compose_data_' . $id]['param']['type']; + if (!$row) { + return; + } + $bodyIsHtml = $args['html']; + $date = $row['date']; + $from = $row['from_email']; + $to = $row['to_email']; + $body = $row['content']; + $subject = $row['subject']; + $replyto = $row['reply_to_email']; + + $prefix = $suffix = ''; + if ($type == 'forward') { + if (!$bodyIsHtml) { + $prefix = "\n\n\n-------- " . $this->rc->gettext('originalmessage') . " --------\n"; + $prefix .= $this->rc->gettext('subject') . ': ' . $subject . "\n"; + $prefix .= $this->rc->gettext('date') . ': ' . $date . "\n"; + $prefix .= $this->rc->gettext('from') . ': ' . $from . "\n"; + $prefix .= $this->rc->gettext('to') . ': ' . $to . "\n"; + if ($cc = $row['cc_email']) { + $prefix .= $this->rc->gettext('cc') . ': ' . $cc . "\n"; + } + if ($replyto != $from) { + $prefix .= $this->rc->gettext('replyto') . ': ' . $replyto . "\n"; + } + $prefix .= "\n"; + global $LINE_LENGTH; + $txt = new rcube_html2text($body, false, true, $LINE_LENGTH); + $body = $txt->get_text(); + $body = preg_replace('/\r?\n/', "\n", $body); + $body = trim($body, "\n"); + } else { + $prefix = sprintf( + "

    -------- " . $this->rc->gettext('originalmessage') . " --------

    " . + "" . + "" . + "" . + "" . + "", $this->rc->gettext('subject'), rcube::Q($subject), $this->rc->gettext('date'), rcube::Q($date), $this->rc->gettext('from'), rcube::Q($from, 'replace'), $this->rc->gettext('to'), rcube::Q($to, 'replace')); + if ($cc = $row['cc_email']) + $prefix .= sprintf("", $this->rc->gettext('cc'), rcube::Q($cc, 'replace')); + if ($replyto != $from) + $prefix .= sprintf("", $this->rc->gettext('replyto'), rcube::Q($replyto, 'replace')); + $prefix .= "
    %s: %s
    %s: %s
    %s: %s
    %s: %s
    %s: %s
    %s: %s

    "; + } + $body = $prefix . $body; + }else { + $prefix = $this->rc->gettext(array( + 'name' => 'mailreplyintro', + 'vars' => array( + 'date' => $this->rc->format_date($date, $this->rc->config->get('date_long')), + 'sender' => $from, + ) + )); + if (!$bodyIsHtml) { + global $LINE_LENGTH; + $txt = new rcube_html2text($body, false, true, $LINE_LENGTH); + $body = $txt->get_text(); + $body = preg_replace('/\r?\n/', "\n", $body); + $body = trim($body, "\n"); + $body = rcmailWrapAndQuote($body, $LINE_LENGTH); + $prefix .= "\n"; + $body = $prefix . $body . $suffix; + } else { + $prefix = '

    ' . rcube::Q($prefix) . "

    \n"; + $body = $prefix . '
    ' . $body . '
    ' . $suffix; + } + } + $this->rc->output->set_env('compose_mode', $type); + $args['body'] = $body; + return $args; + } + + // Loading signature + public function loadSignature($response) + { + global $OUTPUT, $MESSAGE; + if ($this->rc->config->get('enable_variables_in_signature') && !empty($OUTPUT->get_env('signatures'))) { + $signatures = []; + foreach ($OUTPUT->get_env('signatures') as $identityId => $signature) { + $signatures[$identityId]['text'] = $this->parseVariables($signature['text']); + $signatures[$identityId]['html'] = $this->parseVariables($signature['html']); + } + $OUTPUT->set_env('signatures', $signatures); + } + if ($this->checkAddSignature()) { + return; + } + $gS = $this->getGlobalSignature(); + if (empty($gS['html'])) { + return; + } + $signatures = []; + foreach ($OUTPUT->get_env('signatures') as $identityId => $signature) { + $signatures[$identityId]['text'] = $signature['text'] . PHP_EOL . $gS['text']; + $signatures[$identityId]['html'] = $signature['html'] . '
    ' . $gS['html'] . '
    '; + } + if (count($MESSAGE->identities)) { + foreach ($MESSAGE->identities as &$identity) { + $identityId = $identity['identity_id']; + if (!isset($signatures[$identityId])) { + $signatures[$identityId]['text'] = "--\n" . $gS['text']; + $signatures[$identityId]['html'] = '--
    ' . $gS['html'] . '
    '; + } + } + } + $OUTPUT->set_env('signatures', $signatures); + } + + public function getGlobalSignature() + { + global $RCMAIL; + $db = $RCMAIL->get_dbh(); + $result = []; + $sql_result = $db->query("SELECT * FROM yetiforce_mail_config WHERE `type` = 'signature' AND `name` = 'signature';"); + + while ($sql_arr = $db->fetch_assoc($sql_result)) { + $result['html'] = $sql_arr['value']; + $result['text'] = $sql_arr['value']; + } + return $result; + } + + public function checkAddSignature() + { + global $RCMAIL; + $db = $RCMAIL->get_dbh(); + $result = []; + $sql_result = $db->query("SELECT * FROM yetiforce_mail_config WHERE `type` = 'signature' AND `name` = 'addSignature';"); + + while ($sql_arr = $db->fetch_assoc($sql_result)) { + return $sql_arr['value'] == 'false' ? true : false; + } + return true; + } + + // Adding attachments + public function addFilesToMail() + { + $COMPOSE_ID = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); + $uploadid = rcube_utils::get_input_value('_uploadid', rcube_utils::INPUT_GPC); + $ids = rcube_utils::get_input_value('ids', rcube_utils::INPUT_GPC); + $COMPOSE = null; + + if ($COMPOSE_ID && $_SESSION['compose_data_' . $COMPOSE_ID]) { + $SESSION_KEY = 'compose_data_' . $COMPOSE_ID; + $COMPOSE = & $_SESSION[$SESSION_KEY]; + } + if (!$COMPOSE) { + die('Invalid session var!'); + } + $this->rc = rcmail::get_instance(); + $index = 0; + + $attachments = $this->getAttachment($ids, false); + foreach ($attachments as $attachment) { + $index++; + $attachment['group'] = $COMPOSE_ID; + $userid = rcmail::get_instance()->user->ID; + list($usec, $sec) = explode(' ', microtime()); + $id = preg_replace('/[^0-9]/', '', $userid . $sec . $usec) . $index; + $attachment['id'] = $id; + + $_SESSION['plugins']['filesystem_attachments'][$COMPOSE_ID][$id] = $attachment['path']; + $this->rc->session->append($SESSION_KEY . '.attachments', $id, $attachment); + if (($icon = $COMPOSE['deleteicon']) && is_file($icon)) { + $button = html::img(array( + 'src' => $icon, + 'alt' => $this->rc->gettext('delete') + )); + } else if ($COMPOSE['textbuttons']) { + $button = rcube::Q($this->rc->gettext('delete')); + } else { + $button = ''; + } + + $content = html::a(array( + 'href' => "#delete", + 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", rcmail_output::JS_OBJECT_NAME, $id), + 'title' => $this->rc->gettext('delete'), + 'class' => 'delete', + 'aria-label' => $this->rc->gettext('delete') . ' ' . $attachment['name'], + ), $button + ); + + $content .= rcube::Q($attachment['name']); + $htmlAttachments .= 'window.rcmail.add2attachment_list("rcmfile' . $id . '",{html:"
    rc->gettext('delete') . '\" class=\"delete\" aria-label=\"' . $this->rc->gettext('delete') . ' ' . $attachment['name'] . '\"><\/a>' . $attachment['name'] . '",name:"' . $attachment['name'] . '",mimetype:"' . $attachment['mimetype'] . '",classname:"' . rcube_utils::file2class($attachment['mimetype'], $attachment['name']) . '",complete:true},"' . $uploadid . '");' . PHP_EOL; + } + $response = ' + + + + + + +'; + echo $response; + exit; + } + + public function getAttachment($ids, $files) + { + + $attachments = []; + if (empty($ids) && empty($files)) { + return $attachments; + } + if (is_array($ids)) { + $ids = implode(',', $ids); + } + $this->rc = rcmail::get_instance(); + $db = $this->rc->get_dbh(); + $userid = $this->rc->user->ID; + $index = 0; + if ($ids) { + $sql_result = $db->query("SELECT vtiger_attachments.* FROM vtiger_attachments INNER JOIN vtiger_seattachmentsrel ON vtiger_seattachmentsrel.attachmentsid=vtiger_attachments.attachmentsid WHERE vtiger_seattachmentsrel.crmid IN ($ids);"); + while ($row = $db->fetch_assoc($sql_result)) { + $orgFile = $this->rc->config->get('root_directory') . $row['path'] . $row['attachmentsid'] . '_' . $row['name']; + list($usec, $sec) = explode(' ', microtime()); + $filepath = $this->rc->config->get('root_directory') . 'cache/mail/' . $sec . $userid . $row['attachmentsid'] . $index . '.tmp'; + if (file_exists($orgFile)) { + copy($orgFile, $filepath); + $attachment = [ + 'path' => $filepath, + 'size' => filesize($filepath), + 'name' => $row['name'], + 'mimetype' => rcube_mime::file_content_type($filepath, $row['name'], $row['type']), + ]; + $attachments[] = $attachment; + } + $index++; + } + } + if ($files) { + $orgFile = $this->rc->config->get('root_directory') . $files; + list($usec, $sec) = explode(' ', microtime()); + $filepath = $this->rc->config->get('root_directory') . 'cache/mail/' . $sec . $userid . $index . '.tmp'; + if (file_exists($orgFile)) { + copy($orgFile, $filepath); + $attachment = [ + 'path' => $filepath, + 'size' => filesize($filepath), + 'name' => basename($orgFile), + 'mimetype' => rcube_mime::file_content_type($filepath, basename($orgFile)), + ]; + $attachments[] = $attachment; + } + $index++; + } + return $attachments; + } + + public function rcmailWrapAndQuote($text, $length = 72) + { + // Rebuild the message body with a maximum of $max chars, while keeping quoted message. + $max = max(75, $length + 8); + $lines = preg_split('/\r?\n/', trim($text)); + $out = ''; + foreach ($lines as $line) { + // don't wrap already quoted lines + if ($line[0] == '>') { + $line = '>' . rtrim($line); + } else if (mb_strlen($line) > $max) { + $newline = ''; + + foreach (explode("\n", rcube_mime::wordwrap($line, $length - 2)) as $l) { + if (strlen($l)) + $newline .= '> ' . $l . "\n"; + else + $newline .= ">\n"; + } + + $line = rtrim($newline); + } else { + $line = '> ' . $line; + } + // Append the line + $out .= $line . "\n"; + } + return rtrim($out, "\n"); + } + + protected function getAutoLogin() + { + if (empty($_GET['_autologinKey'])) { + return false; + } + if (isset($this->autologin)) { + return $this->autologin; + } + $key = rcube_utils::get_input_value('_autologinKey', rcube_utils::INPUT_GPC); + $db = $this->rc->get_dbh(); + $sqlResult = $db->query('SELECT * FROM u_yf_mail_autologin INNER JOIN roundcube_users ON roundcube_users.user_id = u_yf_mail_autologin.ruid WHERE roundcube_users.password <> \'\' AND u_yf_mail_autologin.`key` = ?;', $key); + $autologin = false; + if ($row = $db->fetch_assoc($sqlResult)) { + $autologin = $row; + $autologin['params'] = json_decode($autologin['params'], true); + } + $this->autologin = $autologin; + return $autologin; + } + + /** + * Parse variables + * @param string $text + * @return string + */ + protected function parseVariables($text) + { + $currentPath = getcwd(); + chdir($this->rc->config->get('root_directory')); + $this->loadCurrentUser(); + + $text = \App\TextParser::getInstance() + ->setContent($text) + ->parse() + ->getContent(); + + chdir($currentPath); + return $text; + } + + protected function loadCurrentUser() + { + if (isset($this->currentUser)) { + return true; + } + require 'include/main/WebUI.php'; + $ownerObject = CRMEntity::getInstance('Users'); + $ownerObject->retrieveCurrentUserInfoFromFile($_SESSION['crm']['id']); + $this->currentUser = $ownerObject; + vglobal('current_user', $ownerObject); + App\User::setCurrentUserId($_SESSION['crm']['id']); + return true; + } + + public function ytAdressButton($p) + { + if (empty($this->viewData['compose']['composeAddressModules'])) { + return $p; + } + $content = ''; + foreach ($this->viewData['compose']['composeAddressModules'] as $moduleName => $value) { + $text = html::span(['class' => "userIcon-$moduleName"], '') . ' ' . $value; + $content .= html::a(['class' => 'button', 'data-input' => $p['part'], 'data-module' => $moduleName], $text); + } + $p['content'] = $content; + return $p; + } + + /** + * Get address email from CRM + */ + public function getEmailFromCRM() + { + $currentPath = getcwd(); + chdir($this->rc->config->get('root_directory')); + $this->loadCurrentUser(); + $ids = rcube_utils::get_input_value('recordsId', rcube_utils::INPUT_GPC); + $sourceModule = rcube_utils::get_input_value('moduleName', rcube_utils::INPUT_GPC); + $emailFields = OSSMailScanner_Record_Model::getEmailSearch($sourceModule); + $addresEmails = []; + foreach ($ids as $id) { + $recordModel = Vtiger_Record_Model::getInstanceById($id, $sourceModule); + foreach ($emailFields as &$emailField) { + $email = $recordModel->get($emailField['fieldname']); + if (!empty($email)) { + $addresEmails[] = $email; + } + } + } + echo App\Json::encode($addresEmails); + chdir($currentPath); + exit; + } + + /** + * Function to get templates + */ + public function getEmailTemplates() + { + $currentPath = getcwd(); + chdir($this->rc->config->get('root_directory')); + $this->loadCurrentUser(); + $emailTemplates = App\Mail::getTempleteList(false, 'PLL_MAIL'); + echo App\Json::encode($emailTemplates); + chdir($currentPath); + exit; + } + + /** + * Function to get info about email template + */ + public function getConntentEmailTemplate() + { + $templeteId = rcube_utils::get_input_value('id', rcube_utils::INPUT_GPC); + $recordId = rcube_utils::get_input_value('record_id', rcube_utils::INPUT_GPC); + $moduleName = rcube_utils::get_input_value('select_module', rcube_utils::INPUT_GPC); + $currentPath = getcwd(); + chdir($this->rc->config->get('root_directory')); + $this->loadCurrentUser(); + $mail = App\Mail::getTemplete($templeteId); + if ($recordId) { + $textParser = \App\TextParser::getInstanceById($recordId, $moduleName); + $mail['subject'] = $textParser->setContent($mail['subject'])->parse()->getContent(); + $mail['content'] = $textParser->setContent($mail['content'])->parse()->getContent(); + } + echo App\Json::encode([ + 'subject' => $mail['subject'], + 'content' => $mail['content'], + 'attachments' => $mail['attachments'], + ]); + chdir($currentPath); + exit; + } +} diff --git a/version.php b/version.php index da8e7e00..77d57cb6 100644 --- a/version.php +++ b/version.php @@ -1,5 +1,5 @@ - '2017.02.28', - 'version' => '0.0.26' -]; + '2017.03.17', + 'version' => '0.0.27' +]; From 54bcbf107cf1da093196d09e1dc47c7e75a894af Mon Sep 17 00:00:00 2001 From: Mariusz Krzaczkowski Date: Mon, 20 Mar 2017 13:47:11 +0100 Subject: [PATCH 05/10] Improved email address search --- program/steps/mail/autocomplete.inc | 58 ++++++++++++++--------------- version.php | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/program/steps/mail/autocomplete.inc b/program/steps/mail/autocomplete.inc index 841cadfe..c80ff866 100644 --- a/program/steps/mail/autocomplete.inc +++ b/program/steps/mail/autocomplete.inc @@ -1,29 +1,29 @@ - -$search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true); -$sid = rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC); -if (strlen($search)) { - $contacts = []; - $crmUserId = false; - if (isset($_SESSION['crm']['id'])) { - $crmUserId = $_SESSION['crm']['id']; - } - if ($RCMAIL->user->data['crm_user_id']) { - $crmUserId = $RCMAIL->user->data['crm_user_id']; - } - if ($crmUserId) { - $addressBookFile = '../../../cache/addressBook/mails_' . $crmUserId . '.php'; - if (is_file($addressBookFile)) { - include $addressBookFile; - foreach ($bookMails as $row) { - if (strpos($row, $search) !== false) { - $contacts[] = $row; - } - } - } - } -} -$OUTPUT->command('ksearch_query_results', $contacts, $search, $sid); -$OUTPUT->send(); -// <-------- YetiForce Sp. z o.o. --------> + +$search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true); +$sid = rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC); +if (strlen($search)) { + $contacts = []; + $crmUserId = false; + if (isset($_SESSION['crm']['id'])) { + $crmUserId = $_SESSION['crm']['id']; + } + if ($RCMAIL->user->data['crm_user_id']) { + $crmUserId = $RCMAIL->user->data['crm_user_id']; + } + if ($crmUserId) { + $addressBookFile = '../../../cache/addressBook/mails_' . $crmUserId . '.php'; + if (is_file($addressBookFile)) { + include $addressBookFile; + foreach ($bookMails as $row) { + if (stripos($row, $search) !== false) { + $contacts[] = $row; + } + } + } + } +} +$OUTPUT->command('ksearch_query_results', $contacts, $search, $sid); +$OUTPUT->send(); +// <-------- YetiForce Sp. z o.o. --------> diff --git a/version.php b/version.php index 77d57cb6..62fda710 100644 --- a/version.php +++ b/version.php @@ -1,5 +1,5 @@ '2017.03.17', - 'version' => '0.0.27' + 'version' => '0.0.28' ]; From 62604f9f7f9fb327c3880c1fa5331a0cbda97f86 Mon Sep 17 00:00:00 2001 From: Mariusz Krzaczkowski Date: Mon, 20 Mar 2017 15:26:09 +0100 Subject: [PATCH 06/10] Improved appearance of integrating bar in mail --- skins/yetiforce/ui.js | 3068 ++++++++++++++++++------------------- skins/yetiforce/ui.min.js | 2 +- version.php | 2 +- 3 files changed, 1536 insertions(+), 1536 deletions(-) diff --git a/skins/yetiforce/ui.js b/skins/yetiforce/ui.js index d028a9e9..0573863a 100644 --- a/skins/yetiforce/ui.js +++ b/skins/yetiforce/ui.js @@ -1,1534 +1,1534 @@ -/** - * Roundcube functions for default skin interface - * - * Copyright (c) 2013, The Roundcube Dev Team - * - * The contents are subject to the Creative Commons Attribution-ShareAlike - * License. It is allowed to copy, distribute, transmit and to adapt the work - * by keeping credits to the original autors in the README file. - * See http://creativecommons.org/licenses/by-sa/3.0/ for details. - * - * @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt CC0-1.0 - */ - -function rcube_mail_ui() -{ - var env = {}; - var popups = {}; - var popupconfig = { - forwardmenu: { editable:1 }, - searchmenu: { editable:1, callback:searchmenu }, - attachmentmenu: { }, - listoptions: { editable:1 }, - groupmenu: { above:1 }, - mailboxmenu: { above:1 }, - spellmenu: { callback: spellmenu }, - 'folder-selector': { iconized:1 } - }; - - var me = this; - var mailviewsplit; - var compose_headers = {}; - var prefs; - - // export public methods - this.set = setenv; - this.init = init; - this.init_tabs = init_tabs; - this.show_about = show_about; - this.show_popup = show_popup; - this.toggle_popup = toggle_popup; - this.add_popup = add_popup; - this.set_searchmod = set_searchmod; - this.set_searchscope = set_searchscope; - this.show_uploadform = show_uploadform; - this.show_header_row = show_header_row; - this.hide_header_row = hide_header_row; - this.update_quota = update_quota; - this.get_pref = get_pref; - this.save_pref = save_pref; - this.folder_search_init = folder_search_init; - - - // set minimal mode on small screens (don't wait for document.ready) - if (window.$ && document.body) { - var minmode = get_pref('minimalmode'); - if (parseInt(minmode) || (minmode === null && $(window).height() < 850)) { - $(document.body).addClass('minimal'); - } - - if (bw.tablet) { - $('#viewport').attr('content', "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"); - } - - $(document).ready(function() { me.init(); }); - } - - - /** - * - */ - function setenv(key, val) - { - env[key] = val; - } - - /** - * Get preference stored in browser - */ - function get_pref(key) - { - if (!prefs) { - prefs = rcmail.local_storage_get_item('prefs.larry', {}); - } - - // fall-back to cookies - if (prefs[key] == null) { - var cookie = rcmail.get_cookie(key); - if (cookie != null) { - prefs[key] = cookie; - - // copy value to local storage and remove cookie (if localStorage is supported) - if (rcmail.local_storage_set_item('prefs.larry', prefs)) { - rcmail.set_cookie(key, cookie, new Date()); // expire cookie - } - } - } - - return prefs[key]; - } - - /** - * Saves preference value to browser storage - */ - function save_pref(key, val) - { - prefs[key] = val; - - // write prefs to local storage (if supported) - if (!rcmail.local_storage_set_item('prefs.larry', prefs)) { - // store value in cookie - var exp = new Date(); - exp.setYear(exp.getFullYear() + 1); - rcmail.set_cookie(key, val, exp); - } - } - - /** - * Initialize UI - * Called on document.ready - */ - function init() - { - rcmail.addEventListener('message', message_displayed); - - /*** prepare minmode functions ***/ - $('#taskbar a').each(function(i,elem){ - $(elem).append('' + $('.button-inner', this).html() + '') - }); - - $('#taskbar .minmodetoggle').click(function(e){ - var ismin = $(document.body).toggleClass('minimal').hasClass('minimal'); - save_pref('minimalmode', ismin?1:0); - $(window).resize(); - }); - - /*** mail task ***/ - if (rcmail.env.task == 'mail') { - rcmail.addEventListener('menu-open', menu_toggle) - .addEventListener('menu-close', menu_toggle) - .addEventListener('menu-save', save_listoptions) - .addEventListener('enable-command', enable_command) - .addEventListener('responseafterlist', function(e){ switch_view_mode(rcmail.env.threading ? 'thread' : 'list', true) }) - .addEventListener('responseaftersearch', function(e){ switch_view_mode(rcmail.env.threading ? 'thread' : 'list', true) }); - - var dragmenu = $('#dragmessagemenu'); - if (dragmenu.length) { - rcmail.gui_object('dragmenu', 'dragmessagemenu'); - popups.dragmenu = dragmenu; - } - - if (rcmail.env.action == 'show' || rcmail.env.action == 'preview') { - rcmail.addEventListener('aftershow-headers', function() { layout_messageview(); }) - .addEventListener('afterhide-headers', function() { layout_messageview(); }); - - $('#previewheaderstoggle').click(function(e) { - toggle_preview_headers(); - if (this.blur && !rcube_event.is_keyboard(e)) - this.blur(); - return false; - }); - - // add menu link for each attachment - $('#attachment-list > li').each(function() { - $(this).append($('Show options') - .on('click keypress', function(e) { - if (e.type != 'keypress' || rcube_event.get_keycode(e) == 13) { - attachmentmenu(this, e); - return false; - } - }) - ); - }); - - if (get_pref('previewheaders') == '1') { - toggle_preview_headers(); - } - } - else if (rcmail.env.action == 'compose') { - rcmail.addEventListener('aftersend-attachment', show_uploadform) - .addEventListener('aftertoggle-editor', function(e) { - window.setTimeout(function(){ layout_composeview() }, 200); - if (e && e.mode) - $("select[name='editorSelector']").val(e.mode); - }) - .addEventListener('compose-encrypted', function(e) { - $("select[name='editorSelector']").prop('disabled', e.active); - $('a.button.attach, a.button.responses')[(e.active?'addClass':'removeClass')]('disabled'); - $('#responseslist a.insertresponse')[(e.active?'removeClass':'addClass')]('active'); - }); - - // Show input elements with non-empty value - var f, v, field, fields = ['cc', 'bcc', 'replyto', 'followupto']; - for (f=0; f < fields.length; f++) { - v = fields[f]; field = $('#_'+v); - if (field.length) { - field.on('change', {v: v}, function(e) { if (this.value) show_header_row(e.data.v, true); }); - if (field.val() != '') - show_header_row(v, true); - } - } - - $('#composeoptionstoggle').click(function(e){ - var expanded = $('#composeoptions').toggle().is(':visible'); - $('#composeoptionstoggle').toggleClass('remove').attr('aria-expanded', expanded ? 'true' : 'false'); - layout_composeview(); - save_pref('composeoptions', expanded ? '1' : '0'); - if (!rcube_event.is_keyboard(e)) - this.blur(); - return false; - }).css('cursor', 'pointer'); - - if (get_pref('composeoptions') !== '0') { - $('#composeoptionstoggle').click(); - } - - // adjust hight when textarea starts to scroll - $("textarea[name='_to'], textarea[name='_cc'], textarea[name='_bcc']").change(function(e){ adjust_compose_editfields(this); }).change(); - rcmail.addEventListener('autocomplete_insert', function(p){ adjust_compose_editfields(p.field); }); - - // toggle compose options if opened in new window and they were visible before - var opener_rc = rcmail.opener(); - if (opener_rc && opener_rc.env.action == 'compose' && $('#composeoptionstoggle', opener.document).hasClass('remove')) - $('#composeoptionstoggle').click(); - - new rcube_splitter({ id:'composesplitterv', p1:'#composeview-left', p2:'#composeview-right', - orientation:'v', relative:true, start:206, min:170, size:12, render:layout_composeview }).init(); - } - else if (rcmail.env.action == 'list' || !rcmail.env.action) { - /** Yetiforce **/ - var previewFrame = $('#mailpreviewframe'); - var previewFrameType = previewFrame.data('type'); - var isPreview = previewFrame.is(':visible'); - $('#mailpreviewtogglebtn .mailpreviewtoggle').each(function (n, e) { - var btn = $(e); - if (isPreview && btn.data('type') == previewFrameType) { - btn.addClass('enabled').attr('aria-expanded', 'true'); - } else { - btn.addClass('closed').attr('aria-expanded', 'false'); - } - }).click(function (e) { - toggle_preview_pane(e); - return false; - }); - /** Yetiforce **/ - $('#maillistmode').addClass(rcmail.env.threading ? '' : 'selected').click(function(e) { switch_view_mode('list'); return false; }); - $('#mailthreadmode').addClass(rcmail.env.threading ? 'selected' : '').click(function(e) { switch_view_mode('thread'); return false; }); - - /** Yetiforce **/ - mailviewsplit = { - v: new rcube_splitter({id: 'mailviewsplitter_v', p1: '#mailview-top', p2: '#mailview-bottom', - orientation: 'v', relative: true, start: 276, min: 560, size: 12, offset: 4}), - h: new rcube_splitter({id: 'mailviewsplitter_h', p1: '#mailview-top', p2: '#mailview-bottom', - orientation: 'h', relative: true, start: 276, min: 150, size: 12, offset: 4}) - }; - if (isPreview && mailviewsplit[previewFrameType] != undefined) { - mailviewsplit[previewFrameType].init(); - } - /** Yetiforce **/ - - rcmail.init_pagejumper('#pagejumper'); - - rcmail.addEventListener('setquota', update_quota) - .addEventListener('afterimport-messages', show_uploadform); - } - else if (rcmail.env.action == 'get') { - new rcube_splitter({ id:'mailpartsplitterv', p1:'#messagepartheader', p2:'#messagepartcontainer', - orientation:'v', relative:true, start:226, min:150, size:12}).init(); - } - - if ($('#mailview-left').length) { - new rcube_splitter({ id:'mailviewsplitterv', p1:'#mailview-left', p2:'#mailview-right', - orientation:'v', relative:true, start:206, min:150, size:12, callback:render_mailboxlist, render:resize_leftcol }).init(); - } - } - /*** settings task ***/ - else if (rcmail.env.task == 'settings') { - rcmail.addEventListener('init', function(){ - var tab = '#settingstabpreferences'; - if (rcmail.env.action) - tab = '#settingstab' + (rcmail.env.action.indexOf('identity')>0 ? 'identities' : rcmail.env.action.replace(/\./g, '')); - - $(tab).addClass('selected') - .children().first().removeAttr('onclick').click(function() { return false; }); - }); - - if (rcmail.env.action == 'folders') { - new rcube_splitter({ id:'folderviewsplitter', p1:'#folderslist', p2:'#folder-details', - orientation:'v', relative:true, start:266, min:180, size:12 }).init(); - - rcmail.addEventListener('setquota', update_quota); - - folder_search_init($('#folderslist')); - } - else if (rcmail.env.action == 'identities') { - new rcube_splitter({ id:'identviewsplitter', p1:'#identitieslist', p2:'#identity-details', - orientation:'v', relative:true, start:266, min:180, size:12 }).init(); - } - else if (rcmail.env.action == 'responses') { - new rcube_splitter({ id:'responseviewsplitter', p1:'#identitieslist', p2:'#identity-details', - orientation:'v', relative:true, start:266, min:180, size:12 }).init(); - } - else if (rcmail.env.action == 'preferences' || !rcmail.env.action) { - new rcube_splitter({ id:'prefviewsplitter', p1:'#sectionslist', p2:'#preferences-box', - orientation:'v', relative:true, start:266, min:180, size:12 }).init(); - } - else if (rcmail.env.action == 'edit-prefs') { - var legend = $('#preferences-details fieldset.advanced legend'), - toggle = $('') - .text(rcmail.gettext('toggleadvancedoptions')) - .attr('title', rcmail.gettext('toggleadvancedoptions')) - .addClass('advanced-toggle'); - - legend.click(function(e) { - toggle.html($(this).hasClass('collapsed') ? '▲' : '▼'); - - $(this).toggleClass('collapsed') - .closest('fieldset').children('.propform').toggle() - }).append(toggle).addClass('collapsed') - - // this magically fixes incorrect position of toggle link created above in Firefox 3.6 - if (bw.mz) - legend.parents('form').css('display', 'inline'); - } - } - /*** addressbook task ***/ - else if (rcmail.env.task == 'addressbook') { - rcmail.addEventListener('afterupload-photo', show_uploadform) - .addEventListener('beforepushgroup', push_contactgroup) - .addEventListener('beforepopgroup', pop_contactgroup) - .addEventListener('menu-open', menu_toggle) - .addEventListener('menu-close', menu_toggle); - - if (rcmail.env.action == '') { - new rcube_splitter({ id:'addressviewsplitterd', p1:'#addressview-left', p2:'#addressview-right', - orientation:'v', relative:true, start:206, min:150, size:12, render:resize_leftcol }).init(); - new rcube_splitter({ id:'addressviewsplitter', p1:'#addresslist', p2:'#contacts-box', - orientation:'v', relative:true, start:266, min:260, size:12 }).init(); - } - - var dragmenu = $('#dragcontactmenu'); - if (dragmenu.length) { - rcmail.gui_object('dragmenu', 'dragcontactmenu'); - popups.dragmenu = dragmenu; - } - } - - // turn a group of fieldsets into tabs - $('.tabbed').each(function(idx, elem){ init_tabs(elem); }) - - // decorate select elements - $('select.decorated').each(function(){ - if (bw.opera) { - $(this).removeClass('decorated'); - return; - } - - var select = $(this), - parent = select.parent(), - height = Math.max(select.height(), 26) - 2, - width = select.width() - 22, - title = $('option', this).first().text(); - - if ($('option:selected', this).val() != '') - title = $('option:selected', this).text(); - - var overlay = $('' + title + '') - .css('position', 'absolute') - .offset(select.position()) - .insertAfter(select); - - overlay.children().width(width).height(height).css('line-height', (height - 1) + 'px'); - - if (parent.css('position') != 'absolute') - parent.css('position', 'relative'); - - // re-set original select width to fix click action and options width in some browsers - select.width(overlay.width()) - .on(bw.mz ? 'change keyup' : 'change', function() { - var val = $('option:selected', this).text(); - $(this).next().children().text(val); - }); - - select - .on('focus', function(e){ overlay.addClass('focus'); }) - .on('blur', function(e){ overlay.removeClass('focus'); }); - }); - - // set min-width to show all toolbar buttons - var screen = $('body.minwidth'); - if (screen.length) { - screen.css('min-width', $('.toolbar').width() + $('#quicksearchbar').width() + $('#searchfilter').width() + 30); - } - - // don't use $(window).resize() due to some unwanted side-effects - window.onresize = resize; - resize(); - } - - /** - * Update UI on window resize - */ - function resize(e) - { - // resize in intervals to prevent lags and double onresize calls in Chrome (#1489005) - var interval = e ? 10 : 0; - - if (rcmail.resize_timeout) - window.clearTimeout(rcmail.resize_timeout); - - rcmail.resize_timeout = window.setTimeout(function() { - if (rcmail.env.task == 'mail') { - if (rcmail.env.action == 'show' || rcmail.env.action == 'preview') - layout_messageview(); - else if (rcmail.env.action == 'compose') - layout_composeview(); - } - - // make iframe footer buttons float if scrolling is active - $('body.iframe .footerleft').each(function(){ - var footer = $(this), - body = $(document.body), - floating = footer.hasClass('floating'), - overflow = body.outerHeight(true) > $(window).height(); - - if (overflow != floating) { - var action = overflow ? 'addClass' : 'removeClass'; - footer[action]('floating'); - body[action]('floatingbuttons'); - } - }); - }, interval); - } - - /** - * Triggered when a new user message is displayed - */ - function message_displayed(p) - { - var siblings = $(p.object).siblings('div'); - if (siblings.length) - $(p.object).insertBefore(siblings.first()); - - // show a popup dialog on errors - if (p.type == 'error' && rcmail.env.task != 'login') { - // hide original message object, we don't want both - rcmail.hide_message(p.object); - - if (me.message_timer) { - window.clearTimeout(me.message_timer); - } - - if (!me.messagedialog) { - me.messagedialog = $('
    ').addClass('popupdialog').hide(); - } - - var msg = p.message, - dialog_close = function() { - // check if dialog is still displayed, to prevent from js error - me.messagedialog.is(':visible') && me.messagedialog.dialog('destroy').hide(); - }; - - if (me.messagedialog.is(':visible') && me.messagedialog.text() != msg) - msg = me.messagedialog.html() + '

    ' + p.message + '

    '; - - me.messagedialog.html(msg) - .dialog({ - resizable: false, - closeOnEscape: true, - dialogClass: 'popupmessage ' + p.type, - title: rcmail.gettext('errortitle'), - close: dialog_close, - position: ['center', 'center'], - hide: {effect: 'fadeOut'}, - width: 420, - minHeight: 90 - }).show(); - - me.messagedialog.closest('div[role=dialog]').attr('role', 'alertdialog'); - - if (p.timeout > 0) - me.message_timer = window.setTimeout(dialog_close, p.timeout); - } - } - - - /** - * Adjust UI objects of the mail view screen - */ - function layout_messageview() - { - $('#messagecontent').css('top', ($('#messageheader').outerHeight() + 1) + 'px'); - $('#message-objects div a').addClass('button'); - - if (!$('#attachment-list li').length) { - $('div.rightcol').hide().attr('aria-hidden', 'true'); - $('div.leftcol').css('margin-right', '0'); - } - - var mvlpe = $('#messagebody.mailvelope, #messagebody > .mailvelope'); - if (mvlpe.length) { - var h = $('#messagecontent').length ? - $('#messagecontent').height() - 16 : - $(window).height() - mvlpe.offset().top - 10; - mvlpe.height(h); - } - } - - - function render_mailboxlist(splitter) - { - // TODO: implement smart shortening of long folder names - } - - - function resize_leftcol(splitter) - { - // STUB - } - - function adjust_compose_editfields(elem) - { - if (elem.nodeName == 'TEXTAREA') { - var $elem = $(elem), line_height = 14, // hard-coded because some browsers only provide the outer height in elem.clientHeight - content_height = elem.scrollHeight, - rows = elem.value.length > 80 && content_height > line_height*1.5 ? 2 : 1; - $elem.css('height', (line_height*rows) + 'px'); - layout_composeview(); - } - } - - function layout_composeview() - { - var body = $('#composebody'), - form = $('#compose-content'), - bottom = $('#composeview-bottom'), - w, h, bh, ovflw, btns = 0, - minheight = 300, - - bh = form.height() - bottom.position().top; - ovflw = minheight - bh; - btns = ovflw > -100 ? 0 : 40; - bottom.height(Math.max(minheight, bh)); - form.css('overflow', ovflw > 0 ? 'auto' : 'hidden'); - - w = body.parent().width() - 5; - h = body.parent().height() - 8; - body.width(w).height(h); - - $('#composebodycontainer > div').width(w+8); - $('#composebody_ifr').height(h + 4 - $('div.mce-toolbar').height()); - $('#googie_edit_layer').width(w).height(h); -// $('#composebodycontainer')[(btns ? 'addClass' : 'removeClass')]('buttons'); -// $('#composeformbuttons')[(btns ? 'show' : 'hide')](); - - var abooks = $('#directorylist'); - if (abooks.length) - $('#compose-contacts .scroller').css('top', abooks.position().top + abooks.outerHeight()); - } - - - function update_quota(p) - { - var element = $('#quotadisplay'), menu = $('#quotamenu'), - step = 24, step_count = 20, - y = p.total ? Math.ceil(p.percent / 100 * step_count) * step : 0; - - // never show full-circle if quota is close to 100% but below. - if (p.total && y == step * step_count && p.percent < 100) - y -= step; - - element.css('background-position', '0 -' + y + 'px'); - element.attr('class', 'countdisplay p' + (Math.round(p.percent / 10) * 10)); - - if (p.table) { - if (!menu.length) - menu = $('
    ').appendTo($('body')); - - menu.html(p.table); - element.css('cursor', 'pointer').off('click').on('click', function(e) { - return rcmail.command('menu-open', 'quotamenu', e.target, e); - }); - } - } - - function folder_search_init(container) - { - // animation to unfold list search box - $('.boxtitle a.search', container).click(function(e) { - var title = $('.boxtitle', container), - box = $('.listsearchbox', container), - dir = box.is(':visible') ? -1 : 1, - height = 34 + ($('select', box).length ? 22 : 0); - - box.slideToggle({ - duration: 160, - progress: function(animation, progress) { - if (dir < 0) progress = 1 - progress; - $('.scroller', container).css('top', (title.outerHeight() + height * progress) + 'px'); - }, - complete: function() { - box.toggleClass('expanded'); - if (box.is(':visible')) { - box.find('input[type=text]').focus(); - height = 34 + ($('select', box).length ? $('select', box).outerHeight() + 4 : 0); - $('.scroller', container).css('top', (title.outerHeight() + height) + 'px'); - } - else { - $('a.reset', box).click(); - } - // TODO: save state in localStorage - } - }); - - return false; - }); - } - - function enable_command(p) - { - if (p.command == 'reply-list' && rcmail.env.reply_all_mode == 1) { - var label = rcmail.gettext(p.status ? 'replylist' : 'replyall'); - if (rcmail.env.action == 'preview') - $('a.button.replyall').attr('title', label); - else - $('a.button.reply-all').text(label).attr('title', label); - } - else if (p.command == 'compose-encrypted') { - // show the toolbar button for Mailvelope - $('a.button.encrypt').show(); - } - } - - - /** - * Register a popup menu - */ - function add_popup(popup, config) - { - var obj = popups[popup] = $('#'+popup); - obj.appendTo(document.body); // move it to top for proper absolute positioning - - if (obj.length) - popupconfig[popup] = $.extend(popupconfig[popup] || {}, config || {}); - } - - /** - * Trigger for popup menus - */ - function toggle_popup(popup, e, config) - { - // auto-register menu object - if (config || !popupconfig[popup]) - add_popup(popup, config); - - return rcmail.command('menu-open', popup, e.target, e); - } - - /** - * (Deprecated) trigger for popup menus - */ - function show_popup(popup, show, config) - { - // auto-register menu object - if (config || !popupconfig[popup]) - add_popup(popup, config); - - config = popupconfig[popup] || {}; - var ref = $(config.link ? config.link : '#'+popup+'link'), - pos = ref.offset(); - if (ref.has('.inner')) - ref = ref.children('.inner'); - - // fire command with simulated mouse click event - return rcmail.command('menu-open', - { menu:popup, show:show }, - ref.get(0), - $.Event('click', { target:ref.get(0), pageX:pos.left, pageY:pos.top, clientX:pos.left, clientY:pos.top })); - } - - - /** - * Show/hide the preview pane - */ - function toggle_preview_pane(e) - { - var button = $(e.currentTarget), - type = button.data('type'), - frame = $('#mailpreviewframe'), - visible = !frame.is(':visible'), - splitter = mailviewsplit[type], - //splitter = mailviewsplit.pos || parseInt(get_pref('mailviewsplitter') || 320), - topstyles, bottomstyles, uid, css; - frame.toggle(); - button.toggleClass('enabled closed').attr('aria-expanded', visible ? 'true' : 'false'); - if (type == 'v') { - css = {height: 'auto', width: 'auto'}; - if (mailviewsplit.h.handle) - mailviewsplit.h.handle.hide(); - if (!$('#mailview-right').hasClass('verticalPanel')) { - $('#mailview-right').addClass('verticalPanel'); - } - } else { - css = {width: 'auto', height: 'auto', left: '0'}; - if (mailviewsplit.v.handle) - mailviewsplit.v.handle.hide(); - if ($('#mailview-right').hasClass('verticalPanel')) { - $('#mailview-right').removeClass('verticalPanel'); - } - } - if (visible) { - $('#mailview-top').removeClass('fullheight').css({bottom: 'auto'}); - $('#mailview-bottom').css(css).show(); - rcmail.env.contentframe = 'messagecontframe'; - if (uid = rcmail.message_list.get_single_selection()) - rcmail.show_message(uid, false, true); - // let the splitter set the correct size and position - if (splitter.handle) { - splitter.handle.show(); - splitter.resize(); - } else - splitter.init(); - if (type == 'v') { - $('#mailpreviewtogglebtn .mailpreviewtoggle[data-type="h"]').hide(); - } else { - $('#mailpreviewtogglebtn .mailpreviewtoggle[data-type="v"]').hide(); - } - } else { - rcmail.env.contentframe = null; - rcmail.show_contentframe(false); - $('#mailview-top').addClass('fullheight').css($.extend({bottom: '0px'}, css)); - css[Object.keys(css)[0]] = '0px'; - $('#mailview-bottom').css($.extend({top: 'auto'}, css)).hide(); - if (splitter.handle) - splitter.handle.hide(); - if (type == 'v') { - $('#mailpreviewtogglebtn .mailpreviewtoggle[data-type="h"]').show(); - } else { - $('#mailpreviewtogglebtn .mailpreviewtoggle[data-type="v"]').show(); - } - } - if (rcmail.message_list) { - if (visible && uid) - rcmail.message_list.scrollto(uid); - rcmail.message_list.resize(); - } - rcmail.command('save-pref', {name: 'preview_pane', value: (visible ? type : 0)}); - } - - - /** - * Switch between short and full headers display in message preview - */ - function toggle_preview_headers() - { - $('#preview-shortheaders').toggle(); - var full = $('#preview-allheaders').toggle(), - button = $('a#previewheaderstoggle'); - - // add toggle button to full headers table - if (full.is(':visible')) - button.attr('href', '#hide').removeClass('add').addClass('remove').attr('aria-expanded', 'true'); - else - button.attr('href', '#details').removeClass('remove').addClass('add').attr('aria-expanded', 'false'); - - save_pref('previewheaders', full.is(':visible') ? '1' : '0'); - } - - - /** - * - */ - function switch_view_mode(mode, force) - { - if (force || !$('#mail'+mode+'mode').hasClass('disabled')) { - $('#maillistmode, #mailthreadmode').removeClass('selected').attr('tabindex', '0').attr('aria-disabled', 'false'); - $('#mail'+mode+'mode').addClass('selected').attr('tabindex', '-1').attr('aria-disabled', 'true'); - } - } - - - /**** popup menu callbacks ****/ - - /** - * Handler for menu-open and menu-close events - */ - function menu_toggle(p) - { - if (p && p.name == 'messagelistmenu') { - show_listoptions(p); - } - else if (p) { - // adjust menu position according to config - var config = popupconfig[p.name] || {}, - ref = $(config.link || '#'+p.name+'link'), - visible = p.obj && p.obj.is(':visible'), - above = config.above; - - // fix position according to config - if (p.obj && visible && ref.length) { - var parent = ref.parent(), - win = $(window), pos; - - if (parent.hasClass('dropbutton')) - ref = parent; - - if (config.above || ref.hasClass('dropbutton')) { - pos = ref.offset(); - p.obj.css({ left:pos.left+'px', top:(pos.top + (config.above ? -p.obj.height() : ref.outerHeight()))+'px' }); - } - } - - // add the right classes - if (p.obj && config.iconized) { - p.obj.children('ul').addClass('iconized'); - } - - // apply some data-attributes from menu config - if (p.obj && config.editable) - p.obj.attr('data-editable', 'true'); - - // trigger callback function - if (typeof config.callback == 'function') { - config.callback(visible, p); - } - } - } - - function searchmenu(show) - { - if (show && rcmail.env.search_mods) { - var n, all, - obj = popups['searchmenu'], - list = $('input:checkbox[name="s_mods[]"]', obj), - mbox = rcmail.env.mailbox, - mods = rcmail.env.search_mods, - scope = rcmail.env.search_scope || 'base'; - - if (rcmail.env.task == 'mail') { - if (scope == 'all') - mbox = '*'; - mods = mods[mbox] ? mods[mbox] : mods['*']; - all = 'text'; - $('input:radio[name="s_scope"]').prop('checked', false).filter('#s_scope_'+scope).prop('checked', true); - } - else { - all = '*'; - } - - if (mods[all]) - list.map(function() { - this.checked = true; - this.disabled = this.value != all; - }); - else { - list.prop('disabled', false).prop('checked', false); - for (n in mods) - $('#s_mod_' + n).prop('checked', true); - } - } - } - - function attachmentmenu(elem, event) - { - var id = elem.parentNode.id.replace(/^attach/, ''); - - $('#attachmenuopen').off('click').attr('onclick', '').click(function(e) { - return rcmail.command('open-attachment', id, this); - }); - - $('#attachmenudownload').off('click').attr('onclick', '').click(function() { - rcmail.command('download-attachment', id, this); - }); - - popupconfig.attachmentmenu.link = elem; - rcmail.command('menu-open', {menu: 'attachmentmenu', id: id}, elem, event); - } - - function spellmenu(show, p) - { - var k, link, li, - lang = rcmail.spellcheck_lang(), - ul = $('ul', p.obj); - - if (!ul.length) { - ul = $('