From 426e369ef13825f76b3f7fc887294c7e2c421624 Mon Sep 17 00:00:00 2001 From: liuhong Date: Thu, 2 Mar 2023 00:22:30 +0000 Subject: [PATCH 01/24] * Fix the lack of story data --- module/story/model.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/module/story/model.php b/module/story/model.php index 1a9cd5724f..17bde87147 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -3023,11 +3023,6 @@ class storyModel extends model */ public function getProductStoryPairs($productID = 0, $branch = 'all', $moduleIdList = 0, $status = 'all', $order = 'id_desc', $limit = 0, $type = 'full', $storyType = 'story', $hasParent = true) { - if($moduleIdList) - { - $moduleInfo = $this->loadModel('tree')->getByID($moduleIdList); - $moduleIdList = (isset($moduleInfo->type) and $moduleInfo->type == 'bug') ? 0 : $moduleIdList; - } $stories = $this->dao->select('t1.id, t1.title, t1.module, t1.pri, t1.estimate, t2.name AS product') ->from(TABLE_STORY)->alias('t1')->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->where('1=1') From f898b790ef5a51f7f226b4a3659e65be3e63d105 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 2 Mar 2023 03:23:59 +0000 Subject: [PATCH 02/24] * Fix bug #32588. --- module/execution/view/view.html.php | 2 +- module/project/view/view.html.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/execution/view/view.html.php b/module/execution/view/view.html.php index 69b3611ff1..a680f2da7d 100644 --- a/module/execution/view/view.html.php +++ b/module/execution/view/view.html.php @@ -398,7 +398,7 @@ execution->totalEstimate;?> totalEstimate . $lang->execution->workHour;?> execution->totalDays;?> - days;?> + days . $lang->execution->day;?> execution->totalConsumed;?> diff --git a/module/project/view/view.html.php b/module/project/view/view.html.php index 6d72bc4611..cabc758530 100644 --- a/module/project/view/view.html.php +++ b/module/project/view/view.html.php @@ -226,7 +226,7 @@ execution->totalEstimate;?> totalEstimate . $lang->execution->workHour;?> execution->totalDays;?> - days;?> + days . $lang->execution->day;?> execution->totalConsumed;?> From aba725ef304f16894488ac89b4fdf70aeebd51ca Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 2 Mar 2023 13:12:55 +0800 Subject: [PATCH 03/24] * Code for fix bug 32562. --- module/execution/control.php | 19 ++----------------- module/kanban/model.php | 3 +++ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index 153deec30c..a59b74b8e8 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -2633,25 +2633,10 @@ class execution extends control $this->session->set('execGroupBy', $groupBy); $this->session->set('storyList', $this->app->getURI(true), 'execution'); $this->session->set('rdSearchValue', ''); - - $features = $this->execution->getExecutionFeatures($execution); - $kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $browseType, $orderBy, 0, $groupBy); - - /* Set lane type. */ - if(!$features['story'] and !$features['qa']) $browseType = 'task'; $this->session->set('execLaneType', $browseType); - /* Remove lanes if no feature. */ - foreach($kanbanData as $regionID => $region) - { - foreach($region->groups as $groupID => $group) - { - if(!$features['story'] and $group->lanes[0]->type == 'story') unset($kanbanData[$regionID]->groups[$groupID]); - if(!$features['qa'] and $group->lanes[0]->type == 'bug') unset($kanbanData[$regionID]->groups[$groupID]); - } - $kanbanData[$regionID]->groups = array_values($kanbanData[$regionID]->groups); - } - + $features = $this->execution->getExecutionFeatures($execution); + $kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $browseType, $orderBy, 0, $groupBy); $executionActions = array(); foreach($this->config->execution->statusActions as $action) { diff --git a/module/kanban/model.php b/module/kanban/model.php index 570468ead2..c7c9db3a13 100755 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -927,6 +927,7 @@ class kanbanModel extends model $laneGroup = $this->getLaneGroupByRegions($regionIDList, $browseType); $columnGroup = $this->getRDColumnGroupByRegions($regionIDList, array_keys($laneGroup)); $cardGroup = $this->getCardGroupByExecution($executionID, $browseType, $orderBy, $searchValue); + $execution = $this->loadModel('execution')->getByID($executionID); foreach($regions as $regionID => $regionName) { @@ -943,6 +944,8 @@ class kanbanModel extends model foreach($lanes as $key => $lane) { + if(in_array($execution->attribute, array('request', 'design', 'review')) and $lane->type == 'bug') continue 2; + if(in_array($execution->attribute, array('request', 'review')) and $lane->type == 'story') continue 2; $this->refreshCards($lane); $lane->items = isset($cardGroup[$lane->id]) ? $cardGroup[$lane->id] : array(); $lane->defaultCardType = $lane->type; From 89db51f678e053a606cd21e04ab0bba003b84bd3 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 2 Mar 2023 13:30:19 +0800 Subject: [PATCH 04/24] * Code for fix bug 32562. --- module/execution/control.php | 6 +++++- module/execution/js/kanban.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index a59b74b8e8..0c473b3597 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -2633,7 +2633,6 @@ class execution extends control $this->session->set('execGroupBy', $groupBy); $this->session->set('storyList', $this->app->getURI(true), 'execution'); $this->session->set('rdSearchValue', ''); - $this->session->set('execLaneType', $browseType); $features = $this->execution->getExecutionFeatures($execution); $kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $browseType, $orderBy, 0, $groupBy); @@ -2643,6 +2642,11 @@ class execution extends control if($this->execution->isClickable($execution, $action)) $executionActions[] = $action; } + /* Set lane type. */ + if(!$features['story'] and !$features['qa']) $browseType = 'task'; + if(!$features['story']) unset($this->lang->kanban->group->task['story']); + $this->session->set('execLaneType', $browseType); + $userList = array(); $users = $this->loadModel('user')->getPairs('noletter|nodeleted'); $avatarPairs = $this->user->getAvatarPairs('all'); diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 87ac799f21..13228c26c6 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -215,7 +215,7 @@ $('.c-group').change(function() { $('.c-group').show(); - var type = $('#type').val(); + var type = $('#type').val() ? $('#type').val() : browseType; var group = $('#group').val(); var link = createLink('execution', 'kanban', 'executionID=' + executionID + '&type=' + type + '&orderBy=id_asc' + '&groupBy=' + group); location.href = link; From c5b40fea231290fb6a5168de35595fc87fd2021e Mon Sep 17 00:00:00 2001 From: hufangzhou Date: Thu, 2 Mar 2023 05:34:58 +0000 Subject: [PATCH 05/24] * Change weixin images. --- www/theme/default/images/main/weixin.jpg | Bin 29869 -> 9156 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/www/theme/default/images/main/weixin.jpg b/www/theme/default/images/main/weixin.jpg index 8ce38e4b869f2770382c3db1f7c9714cefee8483..df0c55442e3848ba64b1fe3a90faa76ba4c2fbed 100644 GIT binary patch literal 9156 zcmdUUc{r5&`~NcrgDk00Dp655+GLb{I2~(QvLsZ~iDO9{lHHI>%@MLxN0zA!DU3uZ zGL*fAkSRskw`3g#vwZJIozLm}`Cgyv`u={`_50&Dd17Xs<$d4x>vg~H`*ri*^S>ZV zElkW!5DW%EFz^rIe?)d8SOEd_2VR2kBP1duBq%5(hQkSqh>MAfFA-a^L_%`eQVB_E z$t6pcu2?F)94{jyBQCX4b_HH`8D0jD-UNe%YXpTvg@i=$5=$iT|Hm(W1tKkiIetFj%aBAQoLUoE-+=BZAUG z%hszK2`}IGJ8pvyen;fhTOx|TKB$zjeLJqCan$#msMv~?va42a+@!3c`U^pG=PoU6 zo!!3~o0yuJTiDq<>~}oiZU$_{3=`tlDF)8`l^&5Ys z+`f}Z%gVl+bFc7WQSqb4B~P9{e^FIkQ(ITx(A?7cu8sNrLwi?uPj6rUz~IpE#N^a8 zYi5=`H;>wdL9pM=g8#o8_HTAcgIxlGf>=QuY8OTz01m9QpwN1C;blhqaKHO3->@T6 z1pn*RTMsHl6*X+fWsds36=KSQGmDn(eSV%?aNg_08R;n9etk0j7bj8@V6j-;j_ynCvm z)mzpN8H$!f#e@^6y^fO)Q+PQM)rercX!W||DZKqgmGt3MaT|fR#&{&jaq@vN+`ame zR<(+@3?~;$dZ#5zMN-8Kt5T09#V{ueEaB_vAE*7>ZwLH7W908cIheO!Z9aPp77SPP zesOD(^im5j3UZjm$#rB|XXL?|MiUDqUVlyUEfpXJANuZkl!xXA~m&gvGzQUtJ@ zWu*ZjSH^CN>9y%ln{)2T9x)W9@Ny#S=zZR2RhI|^qY)xCFlb~48P5HA^j$oTfW2zw zsN~nqNY0J3KzKQW^gdUERsjvv#FHiTK6u<|uoUb9Fi{159D=A*$oAZk@82+z!{2f3 z9VhAS5n?L0;Yte6fvYxum)=K0?{nM(;*elTw(lthSS*5o!rQMx#bJibO!YnMM@a9s z%i z^5Uw8;GNd!qD6}kjesfC`lXQoOwA@MuM@$oV*n{IS9udCR_?} z6k7BW>QAN&*Deu!W$KLV1-!JS7-`Y_j;9CP2w)OTq-bRO*Dc`VhR%@iBIFZ#!VO<* z8d>f96zcY)r+0YPQDflpNLduYrO|mvubs#MqnVNXJZQ*JMA%Z+Aen0yZ&u?&YH0g* zE@BNu1gMl0RXH=LHs_+4o{8cNb%I<qs#xadi@VL6xDuSC$&|2>~=dVKlilf=syyN5}Yj7u0e@AdNFDFhB zg~ErSk6?I?FVYWB$W9L$f?z*n(tboJ0l=rPuX=~cEJny`f%@dkSYj7 zGzf0$&|yv%nGujrZcQeTlCznRV(SL7`%u6@Dq0(2(;=mm6=^7`1mHJO?R?Mi%FaU& zHzvzU(reAFfyrBedNu;Hi@D>(C+6fs3WC(rD#3O82ZL&1J!LaoAS>;S5Yp=gaWJb< zo2Ov~B38st(=rtaKvCCC=eB##XSMsK!nR-q`T9TRW%Q|g5`5Jcz3%xM(LL#BW{+)) zNiPOqMWTsU4)Q^~UrK;8Z@(y2NLe@`w#Y^xveB7$w{}xT8zVUb&3d8(DGq~LoFN}D zRkR*5N7_?Br)Nw+7DOcD8Tjgm$1}3MYqkZNx#fe<+%jcm0)U|U!{15iLA1kBac^P( zob`>taKk#Fxb_g~ojxR)Boslh`cIjYk4yn%Srv*YNCj1@&sE8hWeMyA-02Tu=bYX^ zG^)vJ^2Jf1mCh7C#DRGnO~?~q` z(0DYL<FYW4^^TVZ@eURZtnQ70*YC zJ{G8DOI^&PWIVjJQn@#%gi|Ye&DMXyAFnttA3)r}N4o0y2>yBo+bVSZbjSDG>v@z1 zpQXq9XT+`kc6;Efq1W5Q=d`NA?ee{kiSfDCY-iptpGy}`PH{i$Kj4fEdyVHC_>|?A zd-VHrtm<>D6QoninjiPSog{IzcXwYS_Xhs6axHOju{o>>do2He*1{3q+c>@Gl4RMq zyC;c?hiku({ydDIh8S z_vW_)Qm~oY+I@O*Upn# z`}Zqll$jXS4HO6BIu%}aknJma?T`4yCUf!!+9NLs1Mmca!jclYr-#NM(QG>iyCsxM zGMrq<;8y59q$Hn&jcUHGT|pHTSS&nhf*QN5)*xPsHet2 z8VX@SI!?E?Zh(v!48;Ii5TM8E*HP$3egNQYw^Yg*7=R>Tv@$z@acKRPAq!8qF8`d7 z9Mwia_SKKfFPl}0IyWYxluu_Y|vOOCo80m_;?8swF=6t_$DJo+04^v0vM^zHn&G&wBJo zboSyOCtm5#)wWWGUi>~l$y>d>bMKd0SJf}uTdG>y)y5|0QfI69$mRLQ82=%?^*-3d>m+pv^}{TE+*y<`EuT_U|}SGg^P~tzXo)QRZa+{pTZHj1PRIa(`pq zLDLmEXKtG}Txo7#*E@VOe51-+&CLqk*1h)R=e=h1ElMTv#`whBqnpi;(^eWJm(}mv z2?u?jp0JCZdPFZ}xK7S}*-_@cK{N2;y=1RZ%a>-#g@q#>g-MLU@(5Rh!`XKgXEw(3 zk*~!A=>+c0Vm>1EV&j{?c6hHCsy9BAh~bT`8nD5L2gkYpUF2>3`TA zU|c-JN50G&P}plG+C5KF$N9)5WKXM!j?Yr=0n7IdWX|RJWql$U)m*gC2PVu((OU393Sx>+U4VX@Zv)4vb*Bs z4MZ#{&Bw&STEc-z%`G|+%p!V!*}Ncq`F6p9dOv4Q-dMKj0mwgWYwcN8t+OO%%Q-ppJ|* z6xP469=70zP$`N9v+hjLhi{)J) zDNSmq`!Y?N*#L|={JrEpavIWpHL?~M`dXp|x&*f_>~jHpsIjqD8poa>EirRJ|$^OB87zHH{<#|-vRR&_8W zjIB*o%w^)^Vr2=-<4C1*Vr*}oNLp=eqg)T~0wfihjpJKBBI~c3YoNlu^LypBpxfHS z=g#G|7q@2|thN#zX&9X9dO~ z`G|iimNPOYMIkTE<>A?z4*ga`-_X5ePv{rD8@i?iJ=65!Zaw4Uaw>g+vL9Z%SbcN~ z&PY35eki)ufqt{!YWQaPvsnfQTTs@Tccx^u_x&3uZduVaE?_4#uV-@%$2;>*uPbC0 zjpSUeh*isUCmKqGO60Rkt3I#L+r6yA+JF|KJ9@5JFX`aSZ-WMmwBXMd$*$Z0yGOBM zE>4e|QzJrebZb22TG>mrmAgp42s~b%5XiAO|M|E4uty4%2T!he$UPQq6na-mt}uAw zF7avm3?0L+UD&07Km0P6eWK?PBk5auyLIwLVyE5vW-mS>9=?gAetuVUnI-O0-iCvG z#Di2*UlP3aK+lwn#~$weGcM+R1rt`uA=G09YZHwhzOwneuaRM0Q}#+m+O#|^_F zd(L)t`UIzE{qBOf(KKJ~XWm@?=_9FO&+f)>+3?12wc?5Lw4hw4Ey)*>Ms(|%g*zSN z@lrmHWoziQG+tA=Qb8mic}xFx{tw4n{>f{m-i*C@tQWR$c<}9zol)1HUSr#OZFBr| zj>i&b9<*|a&g1l`*{RQ=PEFYfCf9;aUF|)qy?M_$bI$9q7*BUu&Q9f(H(n(BI;pvw zIOW0=bB^;PPyYAxp>FDqYCSc8hkB>oJ zsF*zfdyE<3JgRM21qZhn4HKPxK#y=sK>~84MeZGB487Yb={N=LGW&@j8VK z!xbUi7B*$hk0)}Ik8B*PCCzNk;Qn%sVOFlk(JPstzxX{QOL1rMosQQ5C;DPaF={9G zjYVeMm6_&f$2o<&iY0s)xh> z)8OHr^?ti9a#a0R{qE+T#8~LVXAjC3g-daC*nShI_B@!dX})9Wyi8~`b%)Gl54ps? z*zLiwpP0F!PHevu6Wb~sgOzgE-^gF^dXTZzXx6&r!3;g`RY{bT-bac3_MZ-IYNZc+ zYSUxiPR#QsNfVE& zjVf2~3MNMvjhN@2a8uW;ZtLGsprwSE2ph5J%ZlZ{h!gQ;1Pq zfBpRzp2GkU_R|+HT^QoV-8Tcz2VY426aVcF*Uhq`u|#X&Q(N@c$Z;MYc`h$j-pZ1d zZwqs_5A2Fx`kR?#v+40~uG7^{+yXtvQ@2C6oY1@xMz>4b5W6F2y_q}lBCcO;DpXJL zLbpoG%Z{Em36D=Qwlp@Wiv^ZNzLbCV&1K~CtqJ9{v6LBw4^g|rJZk$FytWV3B`klh zVL`dWI#tJvzHF|wHpHbGrw*@Z=%c(^Z`=7*laFkx;&k(obMIYwD+eM0rwa29`r&88HMx5q z>mwR5+lK5F@^C*ao_K3v?Yzi;O48*1*sZE#^ z4P$6}?XK2ZfTZIQ>pf3XR1}UmVuKZ(p8|f!vF<=yaWV-h`blqFzs{d3M=?2={_Oso za~&$Br60HQ~OzJ`J2Z#x8w{CXWpOPjQ7VS)~=h>WgZ&u znaLj~T{%KoGg3XyyL*~`DzwrrU}0N}!ok(7thTS8!Pku?0L`r%UMMZiqA^T{SSv^=-P>1es0-X zL1^jRcIvuo`_?1PWqVu;Jx4Y7sNyr^ggqf4JXGjLHgV(iEj1t$*>JFf%Frjb=J%>Gw451u@3CU~*e-sBwsb<>O_q zH}EoT;&ey9Mha*>M>g` z{CQa+;7HYJ#+A@56U6TH`xACm&BvbJ6tvMR4Y4O~R!zMi&&w)RkO;3&C$!Oa-xWDy zX1zaM)eT~WG3MPazsh!5&lz}UD_Z2*>AJ5I|F=yPlDfy@9TS6VXOWn`4ZBT*=^C00$ zyD5&kHrjcf>AdF57ab`b1@7vksDlp;4O}8{T%DJEr0SjMH>C-=rb>yji38QYyxcss zKIVx@or7KdTtt1%c3?77v&x+veJP*2^0!jOuajS&#=02W-hM{%J8V5Cs=ScV%ABkx zwWiV9Nu>JC9%sBK)g;;UzM@#~TK#=UJye2n&GJU8s1jKb_;{TrN#pgapp|k1vCl?_ z31YF28K``BXaI5jd0UTms1}c+(ySt$`emA$_B>*#II6$^C-%f^Why746rKKwUYa*? z*|3)upc2G7`68%bF-ihH=B1jP+^B!lvom^fwm^M5P)Hjp(5>yNuca;&pu*_m%s_o~ zi&+hdE4nlOE%D(d3v__tAx{$>n;*{nno!%Wom8L@Ym{FIYDISh(b$x;qPF|G_V})- zDc&d(xRyyAcTu1iX0UICuID469ps5&&PaVf;~w#0H6PJS;GdZ?6-ftuk*OrwePB25~A?cm$qf6wMN_?c;7zx*cJpI)`)s;AYj=g*G zDIe*1H=n^rL<1-$e%bGP$%TA`;}DGd(7jf1-!wkM{ZEDA#b>d*pkaE*&I}G*Sqb&% z*%3Yx=Xiw^0$K4!s0VwFdMGe_%;v#(eq?|`vcGHB`@;%F>&0{96ic=DOI$qkUTY|3 zV7BG!1i6ubE=1)D{xmgA2(fF~y#I}mp%#{QxJDNmZ7WMW;-2JZZi-4yzNXKhte0}$ z3!w!CFgd1~?rfoh*6@BUENFXKd_+vcXmMuJeKn^w%@aH4JUcx~dZ!|H=8izbcIbRP zZ&MJJAIGoIhG^s4o11ZhCV&X&}EMsk9$CxQiFoCDEIPClu;3YPjq zu-*%k8#OJ+*BS6^gCyuicy}x2rwpamszMtx(w;a@6@;;b0*I|QZw!?LTB80&M2e6yYsT+>);4(TC$~p*d z{{9 z@+?j+1cC|bW1cI60V_4^p~>Pgk^imFlN@VHlxK16B$J8|+vODJ-7uZ;S*%QD2_C}V zM-YmzS>~N>q#r{!!^%5w4^G|;giW^h3}R_V-ld ze+tv+n2V#rfo3xs!V~vA?m4RKpdYFR%bUQ*w7L-xUl;Y-k0~}Hh&y08LIYH!4UFW- zwzSc>8o1zKEbQqA6hQ($^kmFJYw;wg7Up4a6SJK3PJN&~0)G{(mCcs)MaIm6zN^}@ z1XR}Fsy$*T`9mu%PS^D#z54}fgTAAYs4%%ek!rO;fLx$k?eu|Z3%XEc8BXq1xa-i6 zB{qkv0>l|IR$WC%0#_zRCYl&afCil#6Q&EU{u{x?oLtoLR>GF6{u!ANShtf{nZTd_ zC_j_!2O^u}<$fA0vS;wF?|%%P*uv1A1FF!O8}O=!wq@PW9>}XDT0l5hBc$sP7(NtO z6WmeJ3uQ;oWG1c&G;wqm%3iAr6TU|XF>O(KM#Z_d2#DG1#Y!iA8fjrF;r6I%~ zW`PS(f1&fE4H3&I>L_RyCxeW|F(Dc-ltPt|3+!axs2Z-rq#&Xd^>?)K%WFY%E<|b> z&WP8Dv0(oqlYg2|o_K+dQA&ONGMx1N} zgig88&>nPTSpz*EP>_=){Vm1+@L%EDX)pi) literal 29869 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 From bf3081471dd59c0ced23f510053dcac9cd9b5914 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 2 Mar 2023 13:48:04 +0800 Subject: [PATCH 06/24] * Optimized creating requirements page. --- module/execution/view/kanban.html.php | 2 +- module/story/view/create.html.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php index 58293d2cde..5b88da0f03 100644 --- a/module/execution/view/kanban.html.php +++ b/module/execution/view/kanban.html.php @@ -199,7 +199,7 @@ js::set('priv', + 1):?>
+ From 6aaea2823eb2a2dd53d3e2be8b9361163bdc09a5 Mon Sep 17 00:00:00 2001 From: liuhong Date: Thu, 2 Mar 2023 06:09:51 +0000 Subject: [PATCH 07/24] * Fix bug for testcase create view --- module/testcase/js/common.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/testcase/js/common.js b/module/testcase/js/common.js index 0a4a973edd..ae902f070d 100644 --- a/module/testcase/js/common.js +++ b/module/testcase/js/common.js @@ -96,8 +96,9 @@ function loadProductModules(productID, branch) $inputGroup.find('select').chosen() if(typeof(caseModule) == 'string') $('#moduleIdBox').prepend("" + caseModule + ""); $inputGroup.fixInputGroup(); + + setStories(); }); - setStories(); } /** From 75b2f2abe6e200fc219ec40759ecd7c53abef899 Mon Sep 17 00:00:00 2001 From: guofeilong Date: Thu, 2 Mar 2023 14:34:20 +0800 Subject: [PATCH 08/24] * Code for view refactors in admin . --- module/admin/css/index.css | 3 ++- module/admin/view/index.html.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/module/admin/css/index.css b/module/admin/css/index.css index e3770ac26c..9aaf48f125 100755 --- a/module/admin/css/index.css +++ b/module/admin/css/index.css @@ -84,7 +84,8 @@ /* css for without internet */ .main.without-internet {display: flex; flex-wrap: wrap;} -.main.without-internet > .plug.panel {flex: 1 1 60%; margin-bottom: unset; margin-right: 16px;} +.main.without-internet > .plug.panel {flex: 1 1 60%; margin-bottom: unset;} +.main.without-internet > .bottom {flex: 1 1 100%;} .main.without-internet > .bottom > .official.panel {margin-right: unset;} .main.without-internet > .bottom > .official.panel > .main-panel {flex-direction: row-reverse;} diff --git a/module/admin/view/index.html.php b/module/admin/view/index.html.php index 594c0b0270..8ffa2416c2 100755 --- a/module/admin/view/index.html.php +++ b/module/admin/view/index.html.php @@ -26,7 +26,7 @@ - admin->helpURL[$menuKey], " ", '_blank', 'class="text-muted setting-help"');?> + admin->helpURL[$menuKey], "help} class='icon icon-help'> ", '_blank', 'class="text-muted setting-help"');?>

From a261f37af4a4287a3eb007072e9a95ee64a7be7d Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 2 Mar 2023 14:51:35 +0800 Subject: [PATCH 09/24] * Add zentao api get. --- module/admin/control.php | 41 +++++++++++++++++++++++++------- module/admin/model.php | 10 ++++---- module/admin/view/index.html.php | 2 +- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/module/admin/control.php b/module/admin/control.php index 2a38dac0ef..ed73da9f31 100755 --- a/module/admin/control.php +++ b/module/admin/control.php @@ -53,23 +53,46 @@ class admin extends control $this->loadModel('misc'); - $hasInternet = $this->admin->checkInternet(); - $clientLang = $this->app->getClientLang(); - $langNotCN = common::checkNotCN(); - $dateUsed = $this->admin->genDateUsed(); + $clientLang = $this->app->getClientLang(); + $langNotCN = common::checkNotCN(); + $dateUsed = $this->admin->genDateUsed(); $this->view->title = $this->lang->admin->common; $this->view->position[] = $this->lang->admin->index; - $this->view->plugins = $this->admin->getExtensionsByAPI('plugin', $langNotCN ? 5 : 6, $hasInternet); - $this->view->patches = $this->admin->getExtensionsByAPI('patch', 5, $hasInternet); + $this->view->plugins = $this->admin->getExtensionsByAPI('plugin'); + $this->view->patches = $this->admin->getExtensionsByAPI('patch'); $this->view->dateUsed = $dateUsed; - $this->view->hasInternet = $hasInternet; - $this->view->dynamics = ($hasInternet and !$langNotCN) ? $this->admin->getDynamicsByAPI(3) : array(); - $this->view->publicClass = ($hasInternet and !$langNotCN) ? $this->admin->getPublicClassByAPI(3) : array(); + $this->view->dynamics = array(); + $this->view->publicClass = array(); $this->view->langNotCN = $langNotCN; $this->display(); } + /** + * Get zentao.net data by api. + * + * @access public + * @return void + */ + public function ajaxGetZentaoData() + { + $hasInternet = $this->admin->checkInternet(); + $langNotCN = common::checkNotCN(); + + $data['result'] = $hasInternet ? 'success' : 'fail'; + $data['data'] = new stdClass(); + + if($hasInternet) + { + $data['data']->plugins = $this->admin->getExtensionsByAPI('plugin', $langNotCN ? 5 : 6, true); + $data['data']->patches = $this->admin->getExtensionsByAPI('patch', 5, true); + $data['data']->dynamics = !$langNotCN ? $this->admin->getDynamicsByAPI(3) : array(); + $data['data']->publicClass = !$langNotCN ? $this->admin->getPublicClassByAPI(3) : array(); + } + + return $this->send($data); + } + /** * Ignore notice of register and bind. * diff --git a/module/admin/model.php b/module/admin/model.php index a85a8f49a6..0ed3137ced 100755 --- a/module/admin/model.php +++ b/module/admin/model.php @@ -514,7 +514,7 @@ class adminModel extends model * @access public * @return array */ - public function getExtensionsByAPI($type = 'plugin', $limit = 6, $hasInternet = true) + public function getExtensionsByAPI($type = 'plugin', $limit = 6, $hasInternet = false) { if($hasInternet) { @@ -643,11 +643,11 @@ class adminModel extends model */ public function checkInternet() { - $timeoutMS = 400; - $curl = curl_init(); + $timeout = 3; + $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $this->config->admin->apiSite); - curl_setopt($curl, CURLOPT_TIMEOUT_MS, $timeoutMS); - curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, $timeoutMS); + curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); diff --git a/module/admin/view/index.html.php b/module/admin/view/index.html.php index 594c0b0270..b675190512 100755 --- a/module/admin/view/index.html.php +++ b/module/admin/view/index.html.php @@ -11,7 +11,7 @@ */ ?> - +
From 7ebf700fd4efdd269593bc9d04fd58ede820a9bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E9=A3=9E=E9=BE=99?= Date: Thu, 2 Mar 2023 06:57:28 +0000 Subject: [PATCH 10/24] * Adjust code. --- module/admin/view/index.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/admin/view/index.html.php b/module/admin/view/index.html.php index 8ffa2416c2..cc7e7ec861 100755 --- a/module/admin/view/index.html.php +++ b/module/admin/view/index.html.php @@ -26,7 +26,7 @@
- admin->helpURL[$menuKey], "help} class='icon icon-help'> ", '_blank', 'class="text-muted setting-help"');?> + admin->helpURL[$menuKey], " ", '_blank', 'class="text-muted setting-help"');?>

From ee007fe1f68862a1a3d2a11bd22a411b80937d2a Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 2 Mar 2023 07:35:35 +0000 Subject: [PATCH 11/24] * Fix bug #32513. --- module/execution/model.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/module/execution/model.php b/module/execution/model.php index 4a4e430561..935e2f2758 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -1458,32 +1458,34 @@ class executionModel extends model } /* The total workload of the first stage should not exceed 100%. */ - if($type == 'create' or (!empty($oldExecution) and $oldExecution->grade == 1)) + if($type == 'create' or (!empty($oldExecution) and $oldExecution->grade == 1 and isset($this->lang->execution->typeList[$oldExecution->type]))) { $oldPercentTotal = $this->dao->select('SUM(t2.percent) as total')->from(TABLE_PROJECTPRODUCT)->alias('t1') ->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.project=t2.id') ->where('t1.product')->eq($this->post->products[0]) + ->beginIF(!empty($_POST['branch']))->andWhere('t1.branch')->eq(current($this->post->branch[0]))->fi() ->andWhere('t2.type')->eq('stage') ->andWhere('t2.grade')->eq(1) ->andWhere('t2.deleted')->eq(0) - ->andWhere('t2.parent')->eq($oldExecution->parent) + ->beginIF($type == 'create')->andWhere('t2.parent')->eq($oldExecution->id)->fi() + ->beginIF(!empty($oldExecution) and isset($this->lang->execution->typeList[$oldExecution->type]))->andWhere('t2.parent')->eq($oldExecution->parent)->fi() ->fetch('total'); if(!$oldPercentTotal) $oldPercentTotal = 0; if($type == 'create') $percentTotal = $percent + $oldPercentTotal; - if(!empty($oldExecution) and $oldExecution->grade == 1) $percentTotal = $oldPercentTotal - $oldExecution->percent + $this->post->percent; + if(!empty($oldExecution) and isset($this->lang->execution->typeList[$oldExecution->type])) $percentTotal = $oldPercentTotal - $oldExecution->percent + $percent; if($percentTotal > 100) { - dao::$errors['percent'] = sprintf($this->lang->execution->workloadTotal, '%', $oldPercentTotal . '%'); + $printPercent = $type == 'create' ? $oldPercentTotal : $percentTotal; + dao::$errors['percent'] = sprintf($this->lang->execution->workloadTotal, '%', $printPercent . '%'); return false; } } if($type == 'update' and $oldExecution->grade > 1) { - $parentPlan = $this->loadModel('programPlan')->getByID($oldExecution->parent); - $childrenTotalPercent = $this->dao->select('SUM(percent) as total')->from(TABLE_EXECUTION)->where('parent')->eq($oldExecution->parent)->andWhere('deleted')->eq(0)->fetch('total'); + $childrenTotalPercent = $this->dao->select('SUM(percent) as total')->from(TABLE_EXECUTION)->where('parent')->eq($oldExecution->parent)->andWhere('project')->eq($oldExecution->project)->andWhere('deleted')->eq(0)->fetch('total'); $childrenTotalPercent = $childrenTotalPercent - $oldExecution->percent + $this->post->percent; if($childrenTotalPercent > 100) From 7dce298f902e4eac2969bb1f67dc58524084c9bf Mon Sep 17 00:00:00 2001 From: zhujinyong Date: Thu, 2 Mar 2023 15:37:05 +0800 Subject: [PATCH 12/24] * Fix bug: hide execution of request, design. --- module/bug/js/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/bug/js/common.js b/module/bug/js/common.js index 8c1fb0a745..e50f5bf3ed 100644 --- a/module/bug/js/common.js +++ b/module/bug/js/common.js @@ -369,7 +369,7 @@ function loadProductExecutions(productID, projectID = 0) var execution = $('#execution').val(); } - link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID + '&branch=' + branch + '&number=&executionID=' + execution); + link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID + '&branch=' + branch + '&number=&executionID=' + execution + '&from=&mode=stagefilter'); $('#executionIdBox').load(link, function() { $(this).find('select').chosen(); From 17bc1bfacc983d55d2d47bc81d0df12b75d991e1 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 2 Mar 2023 07:47:56 +0000 Subject: [PATCH 13/24] * Fix bug #32592. --- module/execution/lang/de.php | 2 +- module/execution/lang/en.php | 2 +- module/execution/lang/fr.php | 2 +- module/execution/lang/zh-cn.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/module/execution/lang/de.php b/module/execution/lang/de.php index eec5fc176e..c7edb3a7d8 100644 --- a/module/execution/lang/de.php +++ b/module/execution/lang/de.php @@ -282,7 +282,7 @@ $lang->execution->treeViewTask = 'Tree View Task'; $lang->execution->treeViewStory = 'Tree View Story'; $lang->execution->storyKanban = 'Story Kanban'; $lang->execution->storySort = 'Story sortieren'; -$lang->execution->importPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? The stories in the draft will be automatically filtered out when imported.'; +$lang->execution->importPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? Only active ' . $lang->SRCommon . ' can be imported.'; $lang->execution->importEditPlanStory = $lang->executionCommon . ' is edited!\nDo you want to import stories that have been linked to the plan? The stories in the draft will be automatically filtered out when imported.'; $lang->execution->importBranchPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? Only the activation stories of the branch associated with this ' .$lang->executionCommon. ' will be associated with the import'; $lang->execution->importBranchEditPlanStory = $lang->executionCommon . ' is edited!\nDo you want to import stories that have been linked to the plan? Only the activation stories of the branch associated with this ' .$lang->executionCommon. ' will be associated with the import'; diff --git a/module/execution/lang/en.php b/module/execution/lang/en.php index f3e870debd..b9d06aa7ad 100644 --- a/module/execution/lang/en.php +++ b/module/execution/lang/en.php @@ -282,7 +282,7 @@ $lang->execution->treeViewTask = 'Tree View Task'; $lang->execution->treeViewStory = 'Tree View Story'; $lang->execution->storyKanban = 'Story Kanban'; $lang->execution->storySort = 'Rank Story'; -$lang->execution->importPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? The stories in the draft will be automatically filtered out when imported.'; +$lang->execution->importPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? Only active ' . $lang->SRCommon . ' can be imported.'; $lang->execution->importEditPlanStory = $lang->executionCommon . ' is edited!\nDo you want to import stories that have been linked to the plan? The stories in the draft will be automatically filtered out when imported.'; $lang->execution->importBranchPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? Only the activation stories of the branch associated with this ' .$lang->executionCommon. ' will be associated with the import'; $lang->execution->importBranchEditPlanStory = $lang->executionCommon . ' is edited!\nDo you want to import stories that have been linked to the plan? Only the activation stories of the branch associated with this ' .$lang->executionCommon. ' will be associated with the import'; diff --git a/module/execution/lang/fr.php b/module/execution/lang/fr.php index f7f699c520..15d6cc69c0 100644 --- a/module/execution/lang/fr.php +++ b/module/execution/lang/fr.php @@ -282,7 +282,7 @@ $lang->execution->treeViewTask = 'Tree View Task'; $lang->execution->treeViewStory = 'Tree View Story'; $lang->execution->storyKanban = 'Story Kanban'; $lang->execution->storySort = 'Rank Story'; -$lang->execution->importPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? The stories in the draft will be automatically filtered out when imported.'; +$lang->execution->importPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? Only active ' . $lang->SRCommon . ' can be imported.'; $lang->execution->importEditPlanStory = $lang->executionCommon . ' is edited!\nDo you want to import stories that have been linked to the plan? The stories in the draft will be automatically filtered out when imported.'; $lang->execution->importBranchPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? Only the activation stories of the branch associated with this ' .$lang->executionCommon. ' will be associated with the import'; $lang->execution->importBranchEditPlanStory = $lang->executionCommon . ' is edited!\nDo you want to import stories that have been linked to the plan? Only the activation stories of the branch associated with this ' .$lang->executionCommon. ' will be associated with the import'; diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php index a746b5ece4..2430c2b7af 100644 --- a/module/execution/lang/zh-cn.php +++ b/module/execution/lang/zh-cn.php @@ -282,7 +282,7 @@ $lang->execution->treeViewTask = '树状图查看任务'; $lang->execution->treeViewStory = "树状图查看{$lang->SRCommon}"; $lang->execution->storyKanban = "{$lang->SRCommon}看板"; $lang->execution->storySort = "{$lang->SRCommon}排序"; -$lang->execution->importPlanStory = '创建' . $lang->executionCommon . '成功!\n是否导入计划关联的相关' . $lang->SRCommon . '?导入时将自动过滤掉草稿状态的' . $lang->SRCommon . '。'; +$lang->execution->importPlanStory = '创建' . $lang->executionCommon . '成功!\n是否导入计划关联的相关' . $lang->SRCommon . '?导入时只能导入激活状态的' . $lang->SRCommon . '。'; $lang->execution->importEditPlanStory = '编辑' . $lang->executionCommon . '成功!\n是否导入计划关联的相关' . $lang->SRCommon . '?导入时将自动过滤掉草稿状态的' . $lang->SRCommon . '。'; $lang->execution->importBranchPlanStory = '创建' . $lang->executionCommon . '成功!\n是否导入计划关联的相关' . $lang->SRCommon . '?导入时将只关联本' . $lang->executionCommon . '所关联分支的激活需求。'; $lang->execution->importBranchEditPlanStory = '编辑' . $lang->executionCommon . '成功!\n是否导入计划关联的相关' . $lang->SRCommon . '?导入时将只关联本' . $lang->executionCommon . '所关联分支的激活需求。'; From fc444462240d9ebdfb912322c4bdf6b9ce6a2f4d Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 2 Mar 2023 07:49:41 +0000 Subject: [PATCH 14/24] * Fix bug #32603. --- module/project/model.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/project/model.php b/module/project/model.php index e089889aaf..6108d7bd8d 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -1250,6 +1250,7 @@ class projectModel extends model ->setDefault('team', $this->post->name) ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', helper::now()) + ->setDefault('days', '0') ->add('type', 'project') ->join('whitelist', ',') ->stripTags($this->config->project->editor->create['id'], $this->config->allowedTags) From 285dcf409bcba2955e1c3b1135f947114c58e555 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 2 Mar 2023 07:56:48 +0000 Subject: [PATCH 15/24] * Fix bug #32513. --- module/execution/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/execution/model.php b/module/execution/model.php index 935e2f2758..0f09524fa6 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -1463,7 +1463,7 @@ class executionModel extends model $oldPercentTotal = $this->dao->select('SUM(t2.percent) as total')->from(TABLE_PROJECTPRODUCT)->alias('t1') ->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.project=t2.id') ->where('t1.product')->eq($this->post->products[0]) - ->beginIF(!empty($_POST['branch']))->andWhere('t1.branch')->eq(current($this->post->branch[0]))->fi() + ->beginIF(!empty($_POST['branch'][0]))->andWhere('t1.branch')->eq(current($this->post->branch[0]))->fi() ->andWhere('t2.type')->eq('stage') ->andWhere('t2.grade')->eq(1) ->andWhere('t2.deleted')->eq(0) From 3935b867755ef5b2d9382eb81a95a33d41697e8d Mon Sep 17 00:00:00 2001 From: wangyidong Date: Thu, 2 Mar 2023 16:01:53 +0800 Subject: [PATCH 16/24] * fix bug #32306. --- module/user/control.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/user/control.php b/module/user/control.php index f36e1f5652..4870995750 100755 --- a/module/user/control.php +++ b/module/user/control.php @@ -978,6 +978,7 @@ class user extends control } else { + setcookie('tab', false, time(), $this->config->webRoot); $loginExpired = !(preg_match("/(m=|\/)(index)(&f=|-)(index)(&|-|\.)?/", strtolower($this->referer), $output) or $this->referer == $this->config->webRoot or empty($this->referer) or preg_match("/\/www\/$/", strtolower($this->referer), $output)); $this->loadModel('misc'); @@ -1050,7 +1051,7 @@ class user extends control if(isset($this->app->user->id)) $this->loadModel('action')->create('user', $this->app->user->id, 'logout'); setcookie('za', false, time() - 3600, $this->config->webRoot); setcookie('zp', false, time() - 3600, $this->config->webRoot); - setcookie('tab', false, time() - 3600, $this->config->webRoot); ; + setcookie('tab', false, time() - 3600, $this->config->webRoot); session_destroy(); if($this->app->getViewType() == 'json') return print(json_encode(array('status' => 'success'))); From fda9efd09c560a04d41c9ac8af606ccdec198faa Mon Sep 17 00:00:00 2001 From: Yagami Date: Thu, 2 Mar 2023 16:05:35 +0800 Subject: [PATCH 17/24] * Remove request stages in bug batch-create page. --- module/bug/config.php | 2 +- module/bug/control.php | 2 +- module/product/control.php | 2 +- module/product/model.php | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) mode change 100644 => 100755 module/bug/config.php mode change 100644 => 100755 module/product/model.php diff --git a/module/bug/config.php b/module/bug/config.php old mode 100644 new mode 100755 index 060992e9ab..d9c707e2f2 --- a/module/bug/config.php +++ b/module/bug/config.php @@ -223,7 +223,7 @@ $config->bug->datatable->fieldList['execution']['title'] = 'execution'; $config->bug->datatable->fieldList['execution']['fixed'] = 'no'; $config->bug->datatable->fieldList['execution']['width'] = '120'; $config->bug->datatable->fieldList['execution']['required'] = 'no'; -$config->bug->datatable->fieldList['execution']['dataSource'] = array('module' => 'product', 'method' =>'getAllExecutionPairsByProduct', 'params' => '$productID&$branch'); +$config->bug->datatable->fieldList['execution']['dataSource'] = array('module' => 'product', 'method' =>'getAllExecutionPairsByProduct', 'params' => '$productID&$branch&0&stagefilter'); $config->bug->datatable->fieldList['plan']['title'] = 'plan'; $config->bug->datatable->fieldList['plan']['fixed'] = 'no'; diff --git a/module/bug/control.php b/module/bug/control.php index f9727a0d45..94660d0e2b 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -859,7 +859,7 @@ class bug extends control $this->view->users = $this->user->getPairs('devfirst|noclosed'); $this->view->projects = array('' => '') + $this->product->getProjectPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID); $this->view->projectID = $projectID; - $this->view->executions = array('' => '') + $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID, 'multiple'); + $this->view->executions = array('' => '') + $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID, 'multiple,stagefilter'); $this->view->executionID = $executionID; $this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch === 'all' ? 0 : $branch); $this->view->moduleID = $moduleID; diff --git a/module/product/control.php b/module/product/control.php index e4ac5a9fe4..fd081a90cd 100755 --- a/module/product/control.php +++ b/module/product/control.php @@ -1031,7 +1031,7 @@ class product extends control public function ajaxGetExecutionsByProject($productID, $projectID = 0, $branch = 0, $number = 0) { $noMultipleExecutionID = $projectID ? $this->loadModel('execution')->getNoMultipleID($projectID) : ''; - $executions = $this->product->getExecutionPairsByProduct($productID, $branch, 'id_desc', $projectID, 'multiple'); + $executions = $this->product->getExecutionPairsByProduct($productID, $branch, 'id_desc', $projectID, 'multiple,stagefilter'); $disabled = $noMultipleExecutionID ? "disabled='disabled'" : ''; $html = html::select("executions[{$number}]", array('' => '') + $executions, 0, "class='form-control' onchange='loadExecutionBuilds($productID, this.value, $number)' $disabled"); diff --git a/module/product/model.php b/module/product/model.php old mode 100644 new mode 100755 index 4461499a2b..5494bb053d --- a/module/product/model.php +++ b/module/product/model.php @@ -1537,6 +1537,8 @@ class productModel extends model if($projectID) $executions = $this->loadModel('execution')->resetExecutionSorts($executions); foreach($executions as $execution) { + if(strpos($mode, 'stagefilter') !== false and in_array($execution->attribute, array('request', 'design', 'review'))) continue; + if(isset($execution->children)) { $executionPairs = $executionPairs + $execution->children; @@ -1544,7 +1546,6 @@ class productModel extends model } /* Some stage of waterfall not need.*/ - if(strpos($mode, 'stagefilter') !== false and in_array($execution->attribute, array('request', 'design', 'review'))) continue; if(isset($projectPairs[$execution->project])) $executionPairs[$execution->id] = $projectPairs[$execution->project] . '/' . $execution->name; } From d693d5884c747081c6d738b0a2516fa8d93a8ab4 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Thu, 2 Mar 2023 16:20:20 +0800 Subject: [PATCH 18/24] * fix bug #32431. --- module/bug/control.php | 2 +- module/bug/view/batchedit.html.php | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/module/bug/control.php b/module/bug/control.php index 94660d0e2b..de0279b862 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -1398,7 +1398,7 @@ class bug extends control } /* Set users. */ - $users = $this->user->getPairs('devfirst', '', $this->config->maxCount); + $users = $this->user->getPairs('devfirst'); $users = array('' => '', 'ditto' => $this->lang->bug->ditto) + $users; /* Assign. */ diff --git a/module/bug/view/batchedit.html.php b/module/bug/view/batchedit.html.php index c3ed89d702..95cf0ba72d 100644 --- a/module/bug/view/batchedit.html.php +++ b/module/bug/view/batchedit.html.php @@ -74,9 +74,6 @@ $bug):?> - config->user->moreLink)) $this->config->moreLinks["assignedTos[$bugID]"] = $this->config->user->moreLink; - ?> >type, 'class=form-control');?> From f1c5c8c82c4917d8c65eeae139c397eabdcb2919 Mon Sep 17 00:00:00 2001 From: guofeilong Date: Thu, 2 Mar 2023 16:58:42 +0800 Subject: [PATCH 19/24] * Adjust code in admin. --- module/admin/control.php | 2 +- module/admin/css/index.css | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/admin/control.php b/module/admin/control.php index 2a38dac0ef..d400508562 100755 --- a/module/admin/control.php +++ b/module/admin/control.php @@ -53,7 +53,7 @@ class admin extends control $this->loadModel('misc'); - $hasInternet = $this->admin->checkInternet(); + $hasInternet = !$this->admin->checkInternet(); $clientLang = $this->app->getClientLang(); $langNotCN = common::checkNotCN(); $dateUsed = $this->admin->genDateUsed(); diff --git a/module/admin/css/index.css b/module/admin/css/index.css index 9aaf48f125..d457164dbc 100755 --- a/module/admin/css/index.css +++ b/module/admin/css/index.css @@ -84,8 +84,8 @@ /* css for without internet */ .main.without-internet {display: flex; flex-wrap: wrap;} -.main.without-internet > .plug.panel {flex: 1 1 60%; margin-bottom: unset;} -.main.without-internet > .bottom {flex: 1 1 100%;} +.main.without-internet > .plug.panel {flex: 1 1 60%; margin-bottom: unset; margin-right: 16px;} +.main.without-internet > .bottom {flex: 1 1 30%;} .main.without-internet > .bottom > .official.panel {margin-right: unset;} .main.without-internet > .bottom > .official.panel > .main-panel {flex-direction: row-reverse;} From 95184b53a36492aa6d59084c97b82b3566e53572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E9=A3=9E=E9=BE=99?= Date: Thu, 2 Mar 2023 09:00:04 +0000 Subject: [PATCH 20/24] * Adjust code in control.php. --- module/admin/control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/admin/control.php b/module/admin/control.php index d400508562..2a38dac0ef 100755 --- a/module/admin/control.php +++ b/module/admin/control.php @@ -53,7 +53,7 @@ class admin extends control $this->loadModel('misc'); - $hasInternet = !$this->admin->checkInternet(); + $hasInternet = $this->admin->checkInternet(); $clientLang = $this->app->getClientLang(); $langNotCN = common::checkNotCN(); $dateUsed = $this->admin->genDateUsed(); From 58d9fd2ee95b1ff71e41f3798445b9d84ae57def Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 2 Mar 2023 17:04:44 +0800 Subject: [PATCH 21/24] * Fix bug #32593. --- module/admin/control.php | 34 ++++---- module/admin/js/index.js | 2 + module/admin/model.php | 132 +++++++++++++++++++------------ module/admin/view/index.html.php | 2 +- module/block/model.php | 39 +++++++++ module/index/js/index.js | 3 + module/index/view/index.html.php | 1 + 7 files changed, 149 insertions(+), 64 deletions(-) diff --git a/module/admin/control.php b/module/admin/control.php index ed73da9f31..97238f0cfe 100755 --- a/module/admin/control.php +++ b/module/admin/control.php @@ -57,13 +57,17 @@ class admin extends control $langNotCN = common::checkNotCN(); $dateUsed = $this->admin->genDateUsed(); + $zentaoData = $this->admin->getZentaoData(); + $hasInternet = $zentaoData->hasData; + $this->view->title = $this->lang->admin->common; $this->view->position[] = $this->lang->admin->index; - $this->view->plugins = $this->admin->getExtensionsByAPI('plugin'); - $this->view->patches = $this->admin->getExtensionsByAPI('patch'); + $this->view->plugins = $zentaoData->plugins; + $this->view->patches = $zentaoData->patches; $this->view->dateUsed = $dateUsed; - $this->view->dynamics = array(); - $this->view->publicClass = array(); + $this->view->hasInternet = $hasInternet; + $this->view->dynamics = $zentaoData->news; + $this->view->publicClass = $zentaoData->publicclass; $this->view->langNotCN = $langNotCN; $this->display(); } @@ -74,23 +78,25 @@ class admin extends control * @access public * @return void */ - public function ajaxGetZentaoData() + public function ajaxSetZentaoData() { $hasInternet = $this->admin->checkInternet(); - $langNotCN = common::checkNotCN(); - - $data['result'] = $hasInternet ? 'success' : 'fail'; - $data['data'] = new stdClass(); if($hasInternet) { - $data['data']->plugins = $this->admin->getExtensionsByAPI('plugin', $langNotCN ? 5 : 6, true); - $data['data']->patches = $this->admin->getExtensionsByAPI('patch', 5, true); - $data['data']->dynamics = !$langNotCN ? $this->admin->getDynamicsByAPI(3) : array(); - $data['data']->publicClass = !$langNotCN ? $this->admin->getPublicClassByAPI(3) : array(); + $nextWeek = date('Y-m-d', strtotime('-7 days')); + $zentaoData = $this->loadModel('block')->getZentaoData($nextWeek); + + if(empty($zentaoData)) + { + $this->admin->setExtensionsByAPI('plugin', 6); + $this->admin->setExtensionsByAPI('patch', 5); + $this->admin->setDynamicsByAPI(3); + $this->admin->setPublicClassByAPI(3); + } } - return $this->send($data); + return $this->send(array('result' => 'success')); } /** diff --git a/module/admin/js/index.js b/module/admin/js/index.js index f97411945c..fed2be7c68 100644 --- a/module/admin/js/index.js +++ b/module/admin/js/index.js @@ -10,4 +10,6 @@ $(function() { window.open($(this).data('link')); }); + + if(!hasInternet) $.get(createLink('admin', 'ajaxSetZentaoData')); }); diff --git a/module/admin/model.php b/module/admin/model.php index 0ed3137ced..faa37c44d4 100755 --- a/module/admin/model.php +++ b/module/admin/model.php @@ -506,7 +506,7 @@ class adminModel extends model } /** - * Get extensions from zentao.net. + * Set extensions from zentao.net. * * @param string $type plugin|patch * @param int $limit @@ -514,44 +514,22 @@ class adminModel extends model * @access public * @return array */ - public function getExtensionsByAPI($type = 'plugin', $limit = 6, $hasInternet = false) + public function setExtensionsByAPI($type = 'plugin', $limit = 5) { - if($hasInternet) + $searchType = $type == 'plugin' ? 'byModule,offcial' : 'byModule'; + $param = $type == 'plugin' ? '' : 'MTIxOA=='; + $extensions = $this->loadModel('extension')->getExtensionsByAPI($searchType, $param, 0, $limit); + $extensions = isset($extensions->extensions) ? (array)$extensions->extensions : array(); + $plugins = array(); + foreach($extensions as $extension) { - $searchType = $type == 'plugin' ? 'byModule,offcial' : 'byModule'; - $param = $type == 'plugin' ? '' : 'MTIxOA=='; - $extensions = $this->loadModel('extension')->getExtensionsByAPI($searchType, $param, 0, $limit); - $extensions = isset($extensions->extensions) ? (array)$extensions->extensions : array(); - $plugins = array(); - foreach($extensions as $extension) - { - if($type == 'patch' and !isset($extension->compatibleRelease)) continue; + if($type == 'patch' and !isset($extension->compatibleRelease)) continue; - $extension->viewLink = str_replace(array('info', 'client'), '', $extension->viewLink); - $plugins[] = $extension; - } - } - else - { - if($this->config->edition == 'open') - { - $plugins = array( - $this->config->admin->plugins[27], - $this->config->admin->plugins[26], - $this->config->admin->plugins[30] - ); - } - else - { - $plugins = array( - $this->config->admin->plugins[198], - $this->config->admin->plugins[194], - $this->config->admin->plugins[203] - ); - } + $extension->viewLink = str_replace(array('info', 'client'), '', $extension->viewLink); + $plugins[] = $extension; } - return $plugins; + return $this->loadModel('block')->setZentaoData($type, $plugins); } /** @@ -575,13 +553,13 @@ class adminModel extends model } /** - * Get public class from zentao.net. + * Set public class from zentao.net. * * @param int $limit * @access public - * @return array + * @return void */ - public function getPublicClassByAPI($limit = 2) + public function setPublicClassByAPI($limit = 3) { $apiURL = $this->config->admin->videoAPIURL; $data = $this->fetchAPI($apiURL); @@ -599,24 +577,25 @@ class adminModel extends model $publicClass[$index]->viewLink = $this->config->admin->apiRoot . '/publicclass/' . ($course->alias ? "{$course->alias}-" : '') . "{$course->id}.html"; $index ++; } - return $publicClass; + + return $this->loadModel('block')->setZentaoData('publicclass', $publicClass); } /** - * Get dynamics by API. + * Set dynamics by API. * * @param int $limit * @access public - * @return array + * @return void */ - public function getDynamicsByAPI($limit = 2) + public function setDynamicsByAPI($limit = 2) { $apiURL = $this->config->admin->downloadAPIURL; $data = $this->fetchAPI($apiURL); $articles = $data->articles; - $index = 1; - $downloads = array(); + $index = 1; + $news = array(); foreach($articles as $article) { if($index > $limit) break; @@ -625,14 +604,15 @@ class adminModel extends model if(!isset($this->lang->admin->$tagKey)) break; if(!preg_match("/{$this->lang->admin->$tagKey}\d/", $article->title)) continue; - $downloads[$index] = new stdClass(); - $downloads[$index]->id = $article->id; - $downloads[$index]->title = $article->title; - $downloads[$index]->addedDate = $article->addedDate; - $downloads[$index]->link = $this->config->admin->apiRoot . "/download/{$article->alias}-{$article->id}.html"; + $news[$index] = new stdClass(); + $news[$index]->id = $article->id; + $news[$index]->title = $article->title; + $news[$index]->addedDate = $article->addedDate; + $news[$index]->link = $this->config->admin->apiRoot . "/download/{$article->alias}-{$article->id}.html"; $index ++; } - return $downloads; + + return $this->loadModel('block')->setZentaoData('news', $news); } /** @@ -674,4 +654,58 @@ class adminModel extends model return helper::getDateInterval($firstUseDate); } + + /** + * Get zentao.net data. + * + * @access public + * @return object + */ + public function getZentaoData() + { + $zentaoData = $this->loadModel('block')->getZentaoData(); + + $data = new stdclass(); + $data->hasData = true; + + $news = array(); + $publicclass = array(); + $plugins = array(); + $patches = array(); + if(empty($zentaoData)) + { + $data->hasData = false; + if($this->config->edition == 'open') + { + $plugins = array( + $this->config->admin->plugins[27], + $this->config->admin->plugins[26], + $this->config->admin->plugins[30] + ); + } + else + { + $plugins = array( + $this->config->admin->plugins[198], + $this->config->admin->plugins[194], + $this->config->admin->plugins[203] + ); + } + } + else + { + $news = json_decode($zentaoData['news']); + $publicclass = json_decode($zentaoData['publicclass']); + $plugins = json_decode($zentaoData['plugin']); + $patches = json_decode($zentaoData['patch']); + if(common::checkNotCN()) array_pop($plugins); + } + + $data->news = $news; + $data->publicclass = $publicclass; + $data->plugins = $plugins; + $data->patches = $patches; + + return $data; + } } diff --git a/module/admin/view/index.html.php b/module/admin/view/index.html.php index b675190512..594c0b0270 100755 --- a/module/admin/view/index.html.php +++ b/module/admin/view/index.html.php @@ -11,7 +11,7 @@ */ ?> - +
diff --git a/module/block/model.php b/module/block/model.php index 383315585e..fcb3d99bab 100644 --- a/module/block/model.php +++ b/module/block/model.php @@ -1072,4 +1072,43 @@ class blockModel extends model { return $this->dao->select('count(estimate) as estimate')->from(TABLE_STORY)->where('id')->in($storyID)->fetch('estimate'); } + + /** + * Get zentao.net data. + * + * @param string $minTime + * @access public + * @return array + */ + public function getZentaoData($minTime = '') + { + return $this->dao->select('type,params')->from(TABLE_BLOCK) + ->where('account')->eq('system') + ->andWhere('vision')->eq('rnd') + ->andWhere('module')->eq('zentao') + ->beginIF($minTime)->andWhere('source')->ge($minTime)->fi() + ->andWhere('type')->in('plugin,patch,publicclass,news') + ->fetchPairs('type'); + } + + /** + * Set zentao data. + * + * @param string $type + * @param string $params + * @access public + * @return void + */ + public function setZentaoData($type = 'patch', $params = '') + { + $data = new stdclass(); + $data->account = 'system'; + $data->vision = 'rnd'; + $data->module = 'zentao'; + $data->type = $type; + $data->source = date('Y-m-d'); + $data->params = json_encode($params); + + $this->dao->replace(TABLE_BLOCK)->data($data)->exec(); + } } diff --git a/module/index/js/index.js b/module/index/js/index.js index 86ab05c19c..591c1b3753 100644 --- a/module/index/js/index.js +++ b/module/index/js/index.js @@ -891,6 +891,9 @@ $(function() { $('#globalSearchInput').click(); }); + + /* Update patch, plugin, news, publicclass from zetao.net. */ + if(isAdminUser) $.get(createLink('admin', 'ajaxSetZentaoData')); }); /* Change the search object according to the module and method. */ diff --git a/module/index/view/index.html.php b/module/index/view/index.html.php index be9093fc00..bb74a7d06c 100644 --- a/module/index/view/index.html.php +++ b/module/index/view/index.html.php @@ -21,6 +21,7 @@ js::set('appsMenuItems', commonModel::getMainNavList($app->rawModule)); js::set('defaultOpen', (isset($open) and !empty($open)) ? $open : ''); js::set('manualText', $lang->manual); js::set('manualUrl', ((!empty($config->isINT)) ? $config->manualUrl['int'] : $config->manualUrl['home']) . '&theme=' . $_COOKIE['theme']); +js::set('isAdminUser', $this->app->user->admin); ?>