PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i5h-3LL

HOME


5h-3LL 1.0
DIR: /srv/http/vyvoj.adent.cz/vyvoj/moodle_esf_vz/mod/workshop
/srv/http/vyvoj.adent.cz/vyvoj/moodle_esf_vz/mod/workshop/
Upload File:
Current File : /srv/http/vyvoj.adent.cz/vyvoj/moodle_esf_vz/mod/workshop/lib.php
<?php  // $Id: lib.php,v 1.95.2.1 2007/03/07 07:49:03 moodler Exp $

// workshop constants and standard Moodle functions plus the workshop functions 
// called by the standard functions

// see also locallib.php for other non-standard workshop functions

require_once($CFG->libdir.'/filelib.php');

/*** Constants **********************************/


$WORKSHOP_EWEIGHTS = array(  0 => -4.0, 1 => -2.0, 2 => -1.5, 3 => -1.0, 4 => -0.75, 5 => -0.5,  6 => -0.25, 
                             7 => 0.0, 8 => 0.25, 9 => 0.5, 10 => 0.75, 11=> 1.0, 12 => 1.5, 13=> 2.0, 
                             14 => 4.0); 

$WORKSHOP_FWEIGHTS = array(  0 => 0, 1 => 0.1, 2 => 0.25, 3 => 0.5, 4 => 0.75, 5 => 1.0,  6 => 1.5, 
                             7 => 2.0, 8 => 3.0, 9 => 5.0, 10 => 7.5, 11=> 10.0, 12=>50.0); 


$WORKSHOP_ASSESSMENT_COMPS = array (
                          0 => array('name' => get_string('verylax', 'workshop'), 'value' => 1),
                          1 => array('name' => get_string('lax', 'workshop'), 'value' => 0.6),
                          2 => array('name' => get_string('fair', 'workshop'), 'value' => 0.4),
                          3 => array('name' => get_string('strict', 'workshop'), 'value' => 0.33),
                          4 => array('name' => get_string('verystrict', 'workshop'), 'value' => 0.2) );


/*** Moodle 1.7 compatibility functions *****
 *
 ********************************************/
function workshop_context($workshop) {
    //TODO: add some $cm caching if needed
    if (is_object($workshop)) {
        $workshop = $workshop->id;
    }
    if (! $cm = get_coursemodule_from_instance('workshop', $workshop)) {
        error('Course Module ID was incorrect');
    }

    return get_context_instance(CONTEXT_MODULE, $cm->id);
}

function workshop_is_teacher($workshop, $userid=NULL) {
    return has_capability('mod/workshop:manage', workshop_context($workshop), $userid);
}
 
function workshop_is_teacheredit($workshop, $userid=NULL) {
    return has_capability('mod/workshop:manage', workshop_context($workshop), $userid)
       and has_capability('moodle/site:accessallgroups', workshop_context($workshop), $userid);
}

function workshop_is_student($workshop, $userid=NULL) {
    return has_capability('mod/workshop:participate', workshop_context($workshop), $userid);
}

function workshop_get_students($workshop, $sort='u.lastaccess', $fields='u.*') {
    return $users = get_users_by_capability(workshop_context($workshop), 'mod/workshop:participate', $fields, $sort);
}

function workshop_get_teachers($workshop, $sort='u.lastaccess', $fields='u.*') {
    return $users = get_users_by_capability(workshop_context($workshop), 'mod/workshop:manage', $fields, $sort);
}


/*** Standard Moodle functions ******************
workshop_add_instance($workshop) 
workshop_check_dates($workshop)
workshop_cron () 
workshop_delete_instance($id) 
workshop_grades($workshopid) 
workshop_print_recent_activity(&$logs, $isteacher=false) 
workshop_refresh_events($workshop) 
workshop_update_instance($workshop) 
workshop_user_complete($course, $user, $mod, $workshop) 
workshop_user_outline($course, $user, $mod, $workshop) 
**********************************************/

///////////////////////////////////////////////////////////////////////////////
function workshop_add_instance($workshop) {
// Given an object containing all the necessary data, 
// (defined by the form in mod.html) this function 
// will create a new instance and return the id number 
// of the new instance.

    $workshop->timemodified = time();

    $workshop->submissionstart = make_timestamp($workshop->submissionstartyear, 
            $workshop->submissionstartmonth, $workshop->submissionstartday, $workshop->submissionstarthour, 
            $workshop->submissionstartminute);

    $workshop->assessmentstart = make_timestamp($workshop->assessmentstartyear, 
            $workshop->assessmentstartmonth, $workshop->assessmentstartday, $workshop->assessmentstarthour, 
            $workshop->assessmentstartminute);

    $workshop->submissionend = make_timestamp($workshop->submissionendyear, 
            $workshop->submissionendmonth, $workshop->submissionendday, $workshop->submissionendhour, 
            $workshop->submissionendminute);

    $workshop->assessmentend = make_timestamp($workshop->assessmentendyear, 
            $workshop->assessmentendmonth, $workshop->assessmentendday, $workshop->assessmentendhour, 
            $workshop->assessmentendminute);

    $workshop->releasegrades = make_timestamp($workshop->releaseyear, 
            $workshop->releasemonth, $workshop->releaseday, $workshop->releasehour, 
            $workshop->releaseminute);
    
    if (!workshop_check_dates($workshop)) {
        return get_string('invaliddates', 'workshop');
    }

    if ($returnid = insert_record("workshop", $workshop)) {

        $event = NULL;
        $event->name        = get_string('submissionstartevent','workshop', $workshop->name);
        $event->description = $workshop->description;
        $event->courseid    = $workshop->course;
        $event->groupid     = 0;
        $event->userid      = 0;
        $event->modulename  = 'workshop';
        $event->instance    = $returnid;
        $event->eventtype   = 'submissionstart';
        $event->timestart   = $workshop->submissionstart;
        $event->timeduration = 0;
        add_event($event);

        $event->name        = get_string('submissionendevent','workshop', $workshop->name);
        $event->eventtype   = 'submissionend';
        $event->timestart   = $workshop->submissionend;
        add_event($event);

        $event->name        = get_string('assessmentstartevent','workshop', $workshop->name);
        $event->eventtype   = 'assessmentstart';
        $event->timestart   = $workshop->assessmentstart;
        add_event($event);

        $event->name        = get_string('assessmentendevent','workshop', $workshop->name);
        $event->eventtype   = 'assessmentend';
        $event->timestart   = $workshop->assessmentend;
        add_event($event);
    }

    return $returnid;
}

///////////////////////////////////////////////////////////////////////////////
// returns true if the dates are valid, false otherwise
function workshop_check_dates($workshop) {
    // allow submission and assessment to start on the same date and to end on the same date
    // but enforce non-empty submission period and non-empty assessment period.
    return ($workshop->submissionstart < $workshop->submissionend and
            $workshop->submissionstart <= $workshop->assessmentstart and
            $workshop->assessmentstart < $workshop->assessmentend and
            $workshop->submissionend <= $workshop->assessmentend);
}


///////////////////////////////////////////////////////////////////////////////
function workshop_cron () {
// Function to be run periodically according to the moodle cron

    global $CFG, $USER;
    
    // if there any ungraded assessments run the grading routine
    if ($workshops = get_records("workshop")) {
        foreach ($workshops as $workshop) {
            // automatically grade assessments if workshop has examples and/or peer assessments
            if ($workshop->gradingstrategy and ($workshop->ntassessments or $workshop->nsassessments)) {
                workshop_grade_assessments($workshop);
            }
        }
    }
    $timenow = time();

    $CFG->enablerecordcache = true;      // We want all the caching we can get
    
    // Find all workshop notifications that have yet to be mailed out, and mails them
    $cutofftime = $timenow - $CFG->maxeditingtime;

    // look for new assessments
    if ($assessments = workshop_get_unmailed_assessments($cutofftime)) {
        foreach ($assessments as $assessment) {

            echo "Processing workshop assessment $assessment->id\n";
            
            // only process the entry once
            if (! set_field("workshop_assessments", "mailed", "1", "id", "$assessment->id")) {
                echo "Could not update the mailed field for id $assessment->id\n";
            }
            
            if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
                echo "Could not find submission $assessment->submissionid\n";
                continue;
            }
            if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
                echo "Could not find workshop id $submission->workshopid\n";
                continue;
            }
            if (! $course = get_record("course", "id", $workshop->course)) {
                error("Could not find course id $workshop->course");
                continue;
            }
            if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
                error("Course Module ID was incorrect");
                continue;
            }
            if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
                echo "Could not find user $submission->userid\n";
                continue;
            }
            if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
                echo "Could not find user $assessment->userid\n";
                continue;
            }
            if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop, 
                        $submissionowner->id)) {
                continue;  // Not an active participant
            }
            if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop, 
                        $assessmentowner->id)) {
                continue;  // Not an active participant
            }
            // don't sent self assessment
            if ($submissionowner->id == $assessmentowner->id) {
                continue;
            }
            $strworkshops = get_string("modulenameplural", "workshop");
            $strworkshop  = get_string("modulename", "workshop");
    
            // it's an assessment, tell the submission owner
            $USER->lang = $submissionowner->lang;
            $sendto = $submissionowner;
            // "Your assignment \"$submission->title\" has been assessed by"
            if (workshop_is_student($workshop, $assessmentowner->id)) {
                $msg = get_string("mail1", "workshop", $submission->title)." a $course->student.\n";
            }
            else {
                $msg = get_string("mail1", "workshop", $submission->title).
                    " ".fullname($assessmentowner)."\n";
            }
            // "The comments and grade can be seen in the workshop assignment '$workshop->name'
            // I have taken the following line out because the info is repeated below.
            // $msg .= get_string("mail2", "workshop", $workshop->name)."\n\n";
    
            $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true);
            $posttext  = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n";
            $posttext .= "---------------------------------------------------------------------\n";
            $posttext .= $msg;
            // "The comments and grade can be seen in ..."
            $posttext .= get_string("mail2", "workshop", 
                format_string($workshop->name,true).",   $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
            $posttext .= "---------------------------------------------------------------------\n";
            if ($sendto->mailformat == 1) {  // HTML
                $posthtml = "<p><font face=\"sans-serif\">".
                    "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
                    "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
                    "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a></font></p>";
                $posthtml .= "<hr><font face=\"sans-serif\">";
                $posthtml .= "<p>$msg</p>";
                $posthtml .= "<p>".get_string("mail2", "workshop",
                    " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a>")."</p></font><hr>";
            } else {
                $posthtml = "";
            }
    
            if (!$teacher = get_teacher($course->id)) {
                echo "Error: can not find teacher for course $course->id!\n";
            }
                
            if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
                echo "Error: workshop cron: Could not send out mail for id $submission->id to 
                    user $sendto->id ($sendto->email)\n";
            }
        }
    }
        
    // look for new assessments of resubmissions
    if ($assessments = workshop_get_unmailed_resubmissions($cutofftime)) {
        $timenow = time();

        foreach ($assessments as $assessment) {

            echo "Processing workshop assessment $assessment->id\n";
            
            // only process the entry once
            if (! set_field("workshop_assessments", "mailed", "1", "id", "$assessment->id")) {
                echo "Could not update the mailed field for id $assessment->id\n";
            }
            
            if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
                echo "Could not find submission $assessment->submissionid\n";
                continue;
            }
            if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
                echo "Could not find workshop id $submission->workshopid\n";
                continue;
            }
            if (! $course = get_record("course", "id", $workshop->course)) {
                error("Could not find course id $workshop->course");
                continue;
            }
            if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
                error("Course Module ID was incorrect");
                continue;
            }
            if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
                echo "Could not find user $submission->userid\n";
                continue;
            }
            if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
                echo "Could not find user $assessment->userid\n";
                continue;
            }
            if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop, 
                        $submissionowner->id)) {
                continue;  // Not an active participant
            }
            if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop, 
                        $assessmentowner->id)) {
                continue;  // Not an active participant
            }
    
            $strworkshops = get_string("modulenameplural", "workshop");
            $strworkshop  = get_string("modulename", "workshop");
    
            // it's a resubission assessment, tell the assessment owner to (re)assess
            $USER->lang = $assessmentowner->lang;
            $sendto = $assessmentowner;
            // "The assignment \"$submission->title\" is a revised piece of work. "
            $msg = get_string("mail8", "workshop", $submission->title)."\n";
            // "Please assess it in the workshop assignment '$workshop->name'
            // $msg .= get_string("mail9", "workshop", $workshop->name)."\n\n";
    
            $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true);
            $posttext  = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n";
            $posttext .= "---------------------------------------------------------------------\n";
            $posttext .= $msg;
            // "Please assess it in ..."
            $posttext .= get_string("mail9", "workshop", 
                           format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
            $posttext .= "---------------------------------------------------------------------\n";
            if ($sendto->mailformat == 1) {  // HTML
                $posthtml = "<p><font face=\"sans-serif\">".
                  "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
                  "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
                  "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a></font></p>";
                $posthtml .= "<hr><font face=\"sans-serif\">";
                $posthtml .= "<p>$msg</p>";
                $posthtml .= "<p>".get_string("mail9", "workshop",
                  " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a>").'</p></font><hr>';
            } 
            else {
              $posthtml = "";
            }
    
            if (!$teacher = get_teacher($course->id)) {
                echo "Error: can not find teacher for course $course->id!\n";
            }
                
            if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
                echo "Error: workshop cron: Could not send out mail for id $submission->id to 
                    user $sendto->id ($sendto->email)\n";
            }
        }
    }
    
    // look for new comments
    if ($comments = workshop_get_unmailed_comments($cutofftime)) {
        $timenow = time();

        foreach ($comments as $comment) {

            echo "Processing workshop comment $comment->id\n";
            
            // only process the entry once
            if (! set_field("workshop_comments", "mailed", "1", "id", "$comment->id")) {
                echo "Could not update the mailed field for comment id $comment->id\n";
            }
            
            if (! $assessment = get_record("workshop_assessments", "id", "$comment->assessmentid")) {
                echo "Could not find assessment $comment->assessmentid\n";
                continue;
            }
            if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
                echo "Could not find submission $assessment->submissionid\n";
                continue;
            }
            if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
                echo "Could not find workshop id $submission->workshopid\n";
                continue;
            }
            if (! $course = get_record("course", "id", $workshop->course)) {
                error("Could not find course id $workshop->course");
                continue;
            }
            if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
                error("Course Module ID was incorrect");
                continue;
            }
            if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
                echo "Could not find user $submission->userid\n";
                continue;
            }
            if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
                echo "Could not find user $assessment->userid\n";
                continue;
            }
            if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop, 
                        $submissionowner->id)) {
                continue;  // Not an active participant
            }
            if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop, 
                        $assessmentowner->id)) {
                continue;  // Not an active participant
            }
    
            $strworkshops = get_string("modulenameplural", "workshop");
            $strworkshop  = get_string("modulename", "workshop");
    
            // see if the submission owner needs to be told
            if ($comment->userid != $submission->userid) {
                $USER->lang = $submissionowner->lang;
                $sendto = $submissionowner;
                // "A comment has been added to the assignment \"$submission->title\" by
                if (workshop_is_student($workshop, $assessmentowner->id)) {
                    $msg = get_string("mail4", "workshop", $submission->title)." a $course->student.\n";
                }
                else {
                    $msg = get_string("mail4", "workshop", $submission->title)." ".fullname($assessmentowner)."\n";
                }
                // "The new comment can be seen in the workshop assignment '$workshop->name'
                // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n";
    
                $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true);
                $posttext  = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n";
                $posttext .= "---------------------------------------------------------------------\n";
                $posttext .= $msg;
                // "The new comment can be seen in ..."
                $posttext .= get_string("mail5", "workshop",
                    format_string($workshop->name,true).",   $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
                $posttext .= "---------------------------------------------------------------------\n";
                if ($sendto->mailformat == 1) {  // HTML
                    $posthtml = "<p><font face=\"sans-serif\">".
                    "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
                    "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
                    "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a></font></p>";
                    $posthtml .= "<hr><font face=\"sans-serif\">";
                    $posthtml .= "<p>$msg</p>";
                    $posthtml .= "<p>".get_string("mail5", "workshop",
                        " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a>")
                        ."</p></font><hr>";
                } 
                else {
                    $posthtml = "";
                }
    
                if (!$teacher = get_teacher($course->id)) {
                    echo "Error: can not find teacher for course $course->id!\n";
                }
                    
                if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
                    echo "Error: workshop cron: Could not send out mail for id $submission->id to user 
                        $sendto->id ($sendto->email)\n";
                }
            }
            // see if the assessor needs to to told
            if ($comment->userid != $assessment->userid) {
                $USER->lang = $assessmentowner->lang;
                $sendto = $assessmentowner;
                // "A comment has been added to the assignment \"$submission->title\" by
                if (workshop_is_student($workshop, $submissionowner->id)) {
                    $msg = get_string("mail4", "workshop", $submission->title)." a $course->student.\n";
                }
                else {
                    $msg = get_string("mail4", "workshop", $submission->title).
                        " ".fullname($submissionowner)."\n";
                }
                // "The new comment can be seen in the workshop assignment '$workshop->name'
                // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n";
    
                $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true);
                $posttext  = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n";
                $posttext .= "---------------------------------------------------------------------\n";
                $posttext .= $msg;
                // "The new comment can be seen in ..."
                $posttext .= get_string("mail5", "workshop",
                    format_string($workshop->name,true).",  $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
                $posttext .= "---------------------------------------------------------------------\n";
                if ($sendto->mailformat == 1) {  // HTML
                    $posthtml = "<p><font face=\"sans-serif\">".
                    "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
                    "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
                    "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a></font></p>";
                    $posthtml .= "<hr><font face=\"sans-serif\">";
                    $posthtml .= "<p>$msg</p>";
                    $posthtml .= "<p>".get_string("mail5", "workshop",
                        " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a>")
                        ."</p></font><hr>";
                } 
                else {
                    $posthtml = "";
                }
    
                if (!$teacher = get_teacher($course->id)) {
                    echo "Error: can not find teacher for course $course->id!\n";
                }
                    
                if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
                    echo "Error: workshop cron: Could not send out mail for id $submission->id to user 
                        $sendto->id ($sendto->email)\n";
                }
                if (! set_field("workshop_comments", "mailed", "1", "id", "$comment->id")) {
                    echo "Could not update the mailed field for comment id $comment->id\n";
                }
            }
        }
    }
    return true;
}


///////////////////////////////////////////////////////////////////////////////
function workshop_delete_instance($id) {
// Given an ID of an instance of this module, 
// this function will permanently delete the instance 
// and any data that depends on it.  

    if (! $workshop = get_record("workshop", "id", "$id")) {
        return false;
    }
    
    // delete all the associated records in the workshop tables, start positive...
    $result = true;

    if (! delete_records("workshop_comments", "workshopid", "$workshop->id")) {
        $result = false;
    }

    if (! delete_records("workshop_stockcomments", "workshopid", "$workshop->id")) {
        $result = false;
    }

    if (! delete_records("workshop_grades", "workshopid", "$workshop->id")) {
        $result = false;
    }

    if (! delete_records("workshop_elements", "workshopid", "$workshop->id")) {
        $result = false;
    }

    if (! delete_records("workshop_assessments", "workshopid", "$workshop->id")) {
        $result = false;
    }

    if (! delete_records("workshop_submissions", "workshopid", "$workshop->id")) {
        $result = false;
    }

    if (! delete_records("workshop", "id", "$workshop->id")) {
        $result = false;
    }

    if (! delete_records('event', 'modulename', 'workshop', 'instance', $workshop->id)) {
        $result = false;    
    }   

    return $result;
}


///////////////////////////////////////////////////////////////////////////////
function workshop_grades($workshopid) {
/// Must return an array of grades, indexed by user, and a max grade.
/// only returns grades once assessment has started
/// returns nothing if workshop is not graded
    global $CFG;

    $return = null;
    if ($workshop = get_record("workshop", "id", $workshopid)) {
        if (($workshop->assessmentstart < time()) and $workshop->gradingstrategy) {
            if ($students = workshop_get_students($workshop)) {
                foreach ($students as $student) {
                    if ($workshop->wtype) {
                        $gradinggrade = workshop_gradinggrade($workshop, $student);
                    } else { // ignore grading grades for simple assignments
                        $gradinggrade = 0;
                    }
                    $bestgrade = 0;
                    if ($submissions = workshop_get_user_submissions($workshop, $student)) {
                        foreach ($submissions as $submission) {
                            if (!$submission->late) {
                                $grade = workshop_submission_grade($workshop, $submission);
                            } else {
                                $grade = 0.01;
                            }
                            if ($grade > $bestgrade) {
                                $bestgrade = $grade;
                            }
                        }
                    }
                    $return->grades[$student->id] = $gradinggrade + $bestgrade;
                }
            }
        }
        // set maximum grade if graded
        if ($workshop->gradingstrategy) {
            if ($workshop->wtype) {
                $return->maxgrade = $workshop->grade + $workshop->gradinggrade;
            } else { // ignore grading grades for simple assignemnts
                $return->maxgrade = $workshop->grade;
            }
        }
    }
    return $return;
}

//////////////////////////////////////////////////////////////////////////////////////
function workshop_is_recent_activity($course, $isteacher, $timestart) {//jlw1 added for adding mark to courses with activity in My Moodle
    global $CFG;

    // have a look for agreed assessments for this user (agree) 
    $agreecontent = false;
    if (!$isteacher) { // teachers only need to see submissions
        if ($logs = workshop_get_agree_logs($course, $timestart)) {
            // got some, see if any belong to a visible module
            foreach ($logs as $log) {
                // Create a temp valid module structure (only need courseid, moduleid)
                $tempmod->course = $course->id;
                $tempmod->id = $log->workshopid;
                //Obtain the visible property from the instance
                if (instance_is_visible("workshop",$tempmod)) {
                    $agreecontent = true;
                    break;
                }
            }
        }
    }
    return false;
}


///////////////////////////////////////////////////////////////////////////////
//
// NOTE: $isteacher usage should be converted to use roles.
// TODO: Fix this function.
//
function workshop_print_recent_activity($course, $isteacher, $timestart) {
    global $CFG;

    // have a look for agreed assessments for this user (agree) 
    $agreecontent = false;
    if (!$isteacher) { // teachers only need to see submissions
        if ($logs = workshop_get_agree_logs($course, $timestart)) {
            // got some, see if any belong to a visible module
            foreach ($logs as $log) {
                // Create a temp valid module structure (only need courseid, moduleid)
                $tempmod->course = $course->id;
                $tempmod->id = $log->workshopid;
                //Obtain the visible property from the instance
                if (instance_is_visible("workshop",$tempmod)) {
                    $agreecontent = true;
                    break;
                    }
                }
            // if we got some "live" ones then output them
            if ($agreecontent) {
                print_headline(get_string("workshopagreedassessments", "workshop").":");
                foreach ($logs as $log) {
                    //Create a temp valid module structure (only need courseid, moduleid)
                    $tempmod->course = $course->id;
                    $tempmod->id = $log->workshopid;
                    //Obtain the visible property from the instance
                    if (instance_is_visible("workshop",$tempmod)) {
                        if (!workshop_is_teacher($workshop, $log->userid)) {  // don't break anonymous rule
                            $log->firstname = $course->student;
                            $log->lastname = '';
                        }
                        print_recent_activity_note($log->time, $log, $log->name,
                                                   $CFG->wwwroot.'/mod/workshop/'.$log->url);
                    }
                }
            }
        }
    }

    // have a look for new assessments for this user (assess) 
    $assesscontent = false;
    if (!$isteacher) { // teachers only need to see submissions
        if ($logs = workshop_get_assess_logs($course, $timestart)) {
            // got some, see if any belong to a visible module
            foreach ($logs as $log) {
                // Create a temp valid module structure (only need courseid, moduleid)
                $tempmod->course = $course->id;
                $tempmod->id = $log->workshopid;
                //Obtain the visible property from the instance
                if (instance_is_visible("workshop",$tempmod)) {
                    $assesscontent = true;
                    break;
                    }
                }
            // if we got some "live" ones then output them
            if ($assesscontent) {
                print_headline(get_string("workshopassessments", "workshop").":");
                foreach ($logs as $log) {
                    //Create a temp valid module structure (only need courseid, moduleid)
                    $tempmod->course = $course->id;
                    $tempmod->id = $log->workshopid;
                    //Obtain the visible property from the instance
                    if (instance_is_visible("workshop",$tempmod)) {
                        if (!workshop_is_teacher($tempmod->id, $log->userid)) {  // don't break anonymous rule
                            $log->firstname = $course->student;
                            $log->lastname = '';
                        }
                        print_recent_activity_note($log->time, $log, $log->name,
                                                   $CFG->wwwroot.'/mod/workshop/'.$log->url);
                    }
                }
            }
        }
    }
    // have a look for new comments for this user (comment) 
    $commentcontent = false;
    if (!$isteacher) { // teachers only need to see submissions
        if ($logs = workshop_get_comment_logs($course, $timestart)) {
            // got some, see if any belong to a visible module
            foreach ($logs as $log) {
                // Create a temp valid module structure (only need courseid, moduleid)
                $tempmod->course = $course->id;
                $tempmod->id = $log->workshopid;
                //Obtain the visible property from the instance
                if (instance_is_visible("workshop",$tempmod)) {
                    $commentcontent = true;
                    break;
                    }
                }
            // if we got some "live" ones then output them
            if ($commentcontent) {
                print_headline(get_string("workshopcomments", "workshop").":");
                foreach ($logs as $log) {
                    //Create a temp valid module structure (only need courseid, moduleid)
                    $tempmod->course = $course->id;
                    $tempmod->id = $log->workshopid;
                    //Obtain the visible property from the instance
                    if (instance_is_visible("workshop",$tempmod)) {
                        $log->firstname = $course->student;    // Keep anonymous
                        $log->lastname = '';
                        print_recent_activity_note($log->time, $log, $log->name,
                                                   $CFG->wwwroot.'/mod/workshop/'.$log->url);
                    }
                }
            }
        }
    }

    // have a look for new assessment gradings for this user (grade)
    $gradecontent = false;
    if ($logs = workshop_get_grade_logs($course, $timestart)) {
        // got some, see if any belong to a visible module
        foreach ($logs as $log) {
            // Create a temp valid module structure (only need courseid, moduleid)
            $tempmod->course = $course->id;
            $tempmod->id = $log->workshopid;
            //Obtain the visible property from the instance
            if (instance_is_visible("workshop",$tempmod)) {
                $gradecontent = true;
                break;
                }
            }
        // if we got some "live" ones then output them
        if ($gradecontent) {
            print_headline(get_string("workshopfeedback", "workshop").":");
            foreach ($logs as $log) {
                //Create a temp valid module structure (only need courseid, moduleid)
                $tempmod->course = $course->id;
                $tempmod->id = $log->workshopid;
                //Obtain the visible property from the instance
                if (instance_is_visible("workshop",$tempmod)) {
                    $log->firstname = $course->teacher;    // Keep anonymous
                    $log->lastname = '';
                    print_recent_activity_note($log->time, $log, $log->name,
                                               $CFG->wwwroot.'/mod/workshop/'.$log->url);
                }
            }
        }
    }

    // have a look for new submissions (only show to teachers) (submit)
    $submitcontent = false;
    if ($isteacher) {
        if ($logs = workshop_get_submit_logs($course, $timestart)) {
            // got some, see if any belong to a visible module
            foreach ($logs as $log) {
                // Create a temp valid module structure (only need courseid, moduleid)
                $tempmod->course = $course->id;
                $tempmod->id = $log->workshopid;
                //Obtain the visible property from the instance
                if (instance_is_visible("workshop",$tempmod)) {
                    $submitcontent = true;
                    break;
                    }
                }
            // if we got some "live" ones then output them
            if ($submitcontent) {
                print_headline(get_string("workshopsubmissions", "workshop").":");
                foreach ($logs as $log) {
                    //Create a temp valid module structure (only need courseid, moduleid)
                    $tempmod->course = $course->id;
                    $tempmod->id = $log->workshopid;
                    //Obtain the visible property from the instance
                    if (instance_is_visible("workshop",$tempmod)) {
                        print_recent_activity_note($log->time, $log, $log->name,
                                                   $CFG->wwwroot.'/mod/workshop/'.$log->url);
                    }
                }
            }
        }
    }

    return $agreecontent or $assesscontent or $commentcontent or $gradecontent or $submitcontent;
}


///////////////////////////////////////////////////////////////////////////////
function workshop_refresh_events($courseid = 0) {
// This standard function will check all instances of this module
// and make sure there are up-to-date events created for each of them.
// If courseid = 0, then every workshop event in the site is checked, else
// only workshop events belonging to the course specified are checked.
// This function is used, in its new format, by restore_refresh_events()

    if ($courseid == 0) {
        if (! $workshops = get_records("workshop")) {
            return true;        
        }   
    } else {
        if (! $workshops = get_records("workshop", "course", $courseid)) {
            return true;
        }
    }
    $moduleid = get_field('modules', 'id', 'name', 'workshop');
    
    foreach ($workshops as $workshop) {
    
        $dates = array(
            'submissionstart' => $workshop->submissionstart,
            'submissionend' => $workshop->submissionend,
            'assessmentstart' => $workshop->assessmentstart,
            'assessmentend' => $workshop->assessmentend
        );
        
        foreach ($dates as $type => $date) {
        
            if ($date) {
                if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id, 'eventtype', $type)) {
                    $event->name        = addslashes(get_string($type.'event','workshop', $workshop->name));
                    $event->description = addslashes($workshop->description);
                    $event->eventtype   = $type;
                    $event->timestart   = $date;
                    update_event($event);
                } else {
                    $event->courseid    = $workshop->course;
                    $event->modulename  = 'workshop';
                    $event->instance    = $workshop->id; 
                    $event->name        = addslashes(get_string($type.'event','workshop', $workshop->name));
                    $event->description = addslashes($workshop->description);
                    $event->eventtype   = $type;
                    $event->timestart   = $date;
                    $event->timeduration = 0;
                    $event->visible     = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id); 
                    add_event($event);
                }
            }
        }
    }
    return true;
}   


///////////////////////////////////////////////////////////////////////////////
function workshop_update_instance($workshop) {
// Given an object containing all the necessary data, 
// (defined by the form in mod.html) this function 
// will update an existing instance with new data.
    global $CFG;

    $workshop->timemodified = time();

    $workshop->submissionstart = make_timestamp($workshop->submissionstartyear, 
            $workshop->submissionstartmonth, $workshop->submissionstartday, $workshop->submissionstarthour, 
            $workshop->submissionstartminute);

    $workshop->assessmentstart = make_timestamp($workshop->assessmentstartyear, 
            $workshop->assessmentstartmonth, $workshop->assessmentstartday, $workshop->assessmentstarthour, 
            $workshop->assessmentstartminute);

    $workshop->submissionend = make_timestamp($workshop->submissionendyear, 
            $workshop->submissionendmonth, $workshop->submissionendday, $workshop->submissionendhour, 
            $workshop->submissionendminute);

    $workshop->assessmentend = make_timestamp($workshop->assessmentendyear, 
            $workshop->assessmentendmonth, $workshop->assessmentendday, $workshop->assessmentendhour, 
            $workshop->assessmentendminute);

    $workshop->releasegrades = make_timestamp($workshop->releaseyear, 
            $workshop->releasemonth, $workshop->releaseday, $workshop->releasehour, 
            $workshop->releaseminute);
            
    if (!workshop_check_dates($workshop)) {
        return get_string('invaliddates', 'workshop');
    }

    // set the workshop's type
    $wtype = 0; // 3 phases, no grading grades
    if ($workshop->includeself or $workshop->ntassessments) $wtype = 1; // 3 phases with grading grades
    if ($workshop->nsassessments) $wtype = 2; // 5 phases with grading grades 
    $workshop->wtype = $wtype;
    
    // encode password if necessary
    if (!empty($workshop->password)) {
        $workshop->password = md5($workshop->password);
    } else {
        unset($workshop->password);
    }

    $workshop->id = $workshop->instance;

    if ($returnid = update_record("workshop", $workshop)) {

        $dates = array(
            'submissionstart' => $workshop->submissionstart,
            'submissionend' => $workshop->submissionend,
            'assessmentstart' => $workshop->assessmentstart,
            'assessmentend' => $workshop->assessmentend
        );
        $moduleid = get_field('modules', 'id', 'name', 'workshop');
        
        foreach ($dates as $type => $date) {
            if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id, 'eventtype', $type)) {
                $event->name        = get_string($type.'event','workshop', $workshop->name);
                $event->description = $workshop->description;
                $event->eventtype   = $type;
                $event->timestart   = $date;
                update_event($event);
            } else if ($date) {
                $event = NULL;
                $event->name        = get_string($type.'event','workshop', $workshop->name);
                $event->description = $workshop->description;
                $event->courseid    = $workshop->course;
                $event->groupid     = 0;
                $event->userid      = 0;
                $event->modulename  = 'workshop';
                $event->instance    = $workshop->instance;
                $event->eventtype   = $type;
                $event->timestart   = $date;
                $event->timeduration = 0;
                $event->visible     = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id); 
                add_event($event);
            }
        }
    }

    if (time() > $workshop->assessmentstart) {
        // regrade all the submissions...
        set_field("workshop_submissions", "nassessments", 0, "workshopid", $workshop->id);
        workshop_grade_assessments($workshop);
    }

    return $returnid;
}

///////////////////////////////////////////////////////////////////////////////
function workshop_user_complete($course, $user, $mod, $workshop) {
    if ($submission = workshop_get_student_submission($workshop, $user)) {
        if ($basedir = workshop_file_area($workshop, $user)) {
            if ($files = get_directory_list($basedir)) {
                $countfiles = count($files).' '.get_string('submissions', 'workshop');
                foreach ($files as $file) {
                    $countfiles .= "; $file";
                }
            }
        }

        print_simple_box_start();

        echo $submission->description.'<br />';

        if (!empty($countfiles)) {
            echo $countfiles,'<br />';
        }
        
        workshop_print_feedback($course, $submission);

        print_simple_box_end();

    } else {
        print_string('notsubmittedyet', 'workshop');
    }
}

//////////////////////////////////////////////////////////////////////////////////////
function workshop_print_feedback($course, $submission) {
    global $CFG, $RATING;

    if (! $feedbacks = get_records('workshop_assessments', 'submissionid', $submission->id)) {
        return;
    }

    $strgrade = get_string('grade');
    $strnograde = get_string('nograde');

    foreach ($feedbacks as $feedback) {
        if (! $user = get_record('user', 'id', $feedback->userid)) {
            /// Weird error but we'll just ignore it and continue with other feedback
            continue;
        }

        echo '<table cellspacing="0" class="workshop_feedbackbox">';

        echo '<tr>';
        echo '<td class="picture left">';
        print_user_picture($user->id, $course->id, $user->picture);
        echo '</td>';
        echo '<td><span class="author">'.fullname($user).'</span>';
        echo '<span class="time">'.userdate($feedback->timegraded).'</span>';
        echo '</tr>';

        echo '<tr><td class="left side">&nbsp;</td>';
        echo '<td class="content">';

        if ($feedback->grade) {
            echo $strgrade.': '.$feedback->grade;
        } else {
            echo $strnograde;
        }

        echo '<span class="comment">'.format_text($feedback->generalcomment).'</span>';
        echo '<span class="teachercomment">'.format_text($feedback->teachercomment).'</span>';
        echo '</td></tr></table>';

    }
}




///////////////////////////////////////////////////////////////////////////////
function workshop_user_outline($course, $user, $mod, $workshop) {
    if ($submissions = workshop_get_user_submissions($workshop, $user)) {
        $result->info = count($submissions)." ".get_string("submissions", "workshop");
        // workshop_get_user_submissions returns the newest one first
        foreach ($submissions as $submission) {
            $result->time = $submission->timecreated;
            break;
            }
        return $result;
    }
    return NULL;
}

//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_participants($workshopid) {      
//Returns the users with data in one workshop
//(users with records in workshop_submissions, workshop_assessments and workshop_comments, students)

    global $CFG;

    //Get students from workshop_submissions
    $st_submissions = get_records_sql("SELECT DISTINCT u.id, u.id
                                       FROM {$CFG->prefix}user u,
                                            {$CFG->prefix}workshop_submissions s
                                       WHERE s.workshopid = '$workshopid' and
                                             u.id = s.userid");
    //Get students from workshop_assessments
    $st_assessments = get_records_sql("SELECT DISTINCT u.id, u.id
                                 FROM {$CFG->prefix}user u,
                                      {$CFG->prefix}workshop_assessments a
                                 WHERE a.workshopid = '$workshopid' and
                                       u.id = a.userid");

    //Get students from workshop_comments
    $st_comments = get_records_sql("SELECT DISTINCT u.id, u.id
                                   FROM {$CFG->prefix}user u,
                                        {$CFG->prefix}workshop_comments c
                                   WHERE c.workshopid = '$workshopid' and
                                         u.id = c.userid");

    //Add st_assessments to st_submissions
    if ($st_assessments) {
        foreach ($st_assessments as $st_assessment) {
            $st_submissions[$st_assessment->id] = $st_assessment;
        }
    }
    //Add st_comments to st_submissions
    if ($st_comments) {
        foreach ($st_comments as $st_comment) {
            $st_submissions[$st_comment->id] = $st_comment;
        }
    }
    //Return st_submissions array (it contains an array of unique users)
    return ($st_submissions);
}

//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid, 
                                           $workshop="0", $user="", $groupid="") {
    // Returns all workshop posts since a given time.  If workshop is specified then
    // this restricts the results

    global $CFG;

    if ($workshop) {
        $workshopselect = " AND cm.id = '$workshop'";
    } else {
        $workshopselect = "";
    }

    if ($user) {
        $userselect = " AND u.id = '$user'";
    } else {
        $userselect = "";
    }

    $posts = get_records_sql("SELECT s.*, u.firstname, u.lastname,
            u.picture, cm.instance, w.name, cm.section
            FROM {$CFG->prefix}workshop_submissions s,
            {$CFG->prefix}user u,
            {$CFG->prefix}course_modules cm,
            {$CFG->prefix}workshop w
            WHERE s.timecreated  > '$sincetime' $workshopselect
            AND s.userid = u.id $userselect
            AND w.course = '$courseid' 
            AND cm.instance = w.id
            AND cm.course = w.course
            AND s.workshopid = w.id
            ORDER BY s.id");


    if (empty($posts)) {
        return;
    }

    foreach ($posts as $post) {

        if (empty($groupid) || ismember($groupid, $post->userid)) {

            $tmpactivity = new Object;

            $tmpactivity->type = "workshop";
            $tmpactivity->defaultindex = $index;
            $tmpactivity->instance = $post->instance;
            $tmpactivity->name = $post->name;
            $tmpactivity->section = $post->section;

            $tmpactivity->content->id = $post->id;
            $tmpactivity->content->title = $post->title;

            $tmpactivity->user->userid = $post->userid;
            $tmpactivity->user->fullname = fullname($post);
            $tmpactivity->user->picture = $post->picture;

            $tmpactivity->timestamp = $post->timecreated;
            $activities[] = $tmpactivity;

            $index++;
        }
    }

    return;
}

//////////////////////////////////////////////////////////////////////////////////////
function workshop_print_recent_mod_activity($activity, $course, $detail=false) {

    global $CFG;

    echo '<table border="0" cellpadding="3" cellspacing="0">';

    if (!empty($activity->content->parent)) {
        $openformat = "<font size=\"2\"><i>";
        $closeformat = "</i></font>";
    } else {
        $openformat = "<b>";
        $closeformat = "</b>";
    }

    echo "<tr><td class=\"workshoppostpicture\" width=\"35\" valign=\"top\">";
    print_user_picture($activity->user->userid, $course, $activity->user->picture);
    echo "</td><td>$openformat";

    if ($detail) {
        echo "<img src=\"$CFG->modpixpath/$activity->type/icon.gif\" ".
            "class=\"icon\" alt=\"".strip_tags(format_string($activity->name,true))."\" />  ";
    }
    echo "<a href=\"$CFG->wwwroot/mod/workshop/view.php?" 
        . "#" . $activity->content->id . "\">".$activity->content->title;

    echo "</a>$closeformat";

    echo "<br /><font size=\"2\">";
    echo "<a href=\"$CFG->wwwroot/user/view.php?id=" . $activity->user->userid . "&amp;course=" . "$course\">"
        . $activity->user->fullname . "</a>";
    echo " - " . userdate($activity->timestamp) . "</font></td></tr>";
    echo "</table>";

    return;

}


//////////////////////////////////////////////////////////////////////////////////////
// Non-standard workshop functions
///////////////////////////////////////////////////////////////////////////////////////////////
function workshop_compare_assessments($workshop, $assessment1, $assessment2) {
    global $WORKSHOP_ASSESSMENT_COMPS, $WORKSHOP_EWEIGHTS;
    // first get the assignment elements for maxscores...
    $elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC");
    foreach ($elementsraw as $element) {
        $maxscore[] = $element->maxscore;   // to renumber index 0,1,2...
        $weight[] = $WORKSHOP_EWEIGHTS[$element->weight];   // get real value and renumber index 0,1,2...
    }

    $grades = array();
    for ($i = 0; $i < 2; $i++) {
        if ($i) {
            $rawgrades = get_records("workshop_grades", "assessmentid", $assessment1->id, "elementno ASC");
        } else {
            $rawgrades = get_records("workshop_grades", "assessmentid", $assessment2->id, "elementno ASC");
        }
        if ($rawgrades) {
            foreach ($rawgrades as $grade) {
                $grades[$i][] = $grade->grade;
            }
        }
    }
    $sumdiffs = 0;
    $sumweights = 0;
    switch ($workshop->gradingstrategy) {
        case 1 : // accumulative grading and...
        case 4 : // ...rubic grading
            for ($i=0; $i < $workshop->nelements; $i++) {
                $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i] / $maxscore[$i];
                $sumdiffs += $diff * $diff; // use squared distances
                $sumweights += $weight[$i];
                }
            break;
        case 2 :  // error banded grading
            // ignore maxscores here, the grades are either 0 or 1,
            for ($i=0; $i < $workshop->nelements; $i++) {
                $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i];
                $sumdiffs += $diff * $diff; // use squared distances
                $sumweights += $weight[$i];
                }
            break;
        case 3 : // criterion grading
            // here we only need to look at the difference between the "zero" grade elements
            $diff = ($grades[0][0] - $grades[1][0]) / (count($elementsraw) - 1);
            $sumdiffs = $diff * $diff;
            $sumweights = 1;
            break;
    }            
    // convert to a sensible grade (always out of 100)
    $COMP = (object)$WORKSHOP_ASSESSMENT_COMPS[$workshop->assessmentcomps];
    $factor = $COMP->value;
    $gradinggrade = (($factor - ($sumdiffs / $sumweights)) / $factor) * 100;
    if ($gradinggrade < 0) {
        $gradinggrade = 0;
    }
    return $gradinggrade;
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_count_assessments($submission) {
    // Return the (real) assessments for this submission, 
    $timenow = time();
   return count_records_select("workshop_assessments", 
           "submissionid = $submission->id AND timecreated < $timenow");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_count_ungraded_assessments($workshop) {
    // function returns the number of ungraded assessments by students
    global $CFG;
    
    $timenow = time();
    $n = 0;
    // get all the cold assessments that have not been graded
    if ($assessments = get_records_select("workshop_assessments", "workshopid = $workshop->id AND 
            (timecreated + $CFG->maxeditingtime) < $timenow AND timegraded = 0")) {
        foreach ($assessments as $assessment) {
            if (workshop_is_student($workshop, $assessment->userid)) {
                $n++;
            }
        }
    }
    return $n;
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_file_area($workshop, $submission) {
    return make_upload_directory( workshop_file_area_name($workshop, $submission) );
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_file_area_name($workshop, $submission) {
//  Creates a directory file name, suitable for make_upload_directory()
    global $CFG;

    return "$workshop->course/$CFG->moddata/workshop/$submission->id";
}


///////////////////////////////////////////////////////////////////////////////////////////////
function workshop_get_agree_logs($course, $timestart) {
    // get the "agree" entries for this user (the assessment owner) and add the first and last names 
    // the last two probably wont be used...
    global $CFG, $USER;
    if (empty($USER->id)) {
        return false;
    }
    
    $timethen = time() - $CFG->maxeditingtime;
    return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name
                             FROM {$CFG->prefix}log l,
                                {$CFG->prefix}workshop e, 
                                {$CFG->prefix}workshop_submissions s, 
                                {$CFG->prefix}workshop_assessments a, 
                                {$CFG->prefix}user u
                            WHERE l.time > $timestart AND l.time < $timethen 
                                AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'agree'
                                AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
                                AND u.id = s.userid AND e.id = a.workshopid");
}


///////////////////////////////////////////////////////////////////////////////////////////////
function workshop_get_assess_logs($course, $timestart) {
    // get the "assess" entries for this user and add the first and last names...
    global $CFG, $USER;
    if (empty($USER->id)) {
        return false;
    }
    
    $timethen = time() - $CFG->maxeditingtime;
    return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name
                             FROM {$CFG->prefix}log l,
                                {$CFG->prefix}workshop e, 
                                {$CFG->prefix}workshop_submissions s, 
                                {$CFG->prefix}workshop_assessments a, 
                                {$CFG->prefix}user u
                            WHERE l.time > $timestart AND l.time < $timethen 
                                AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'assess'
                                AND a.id = l.info AND s.id = a.submissionid AND s.userid = $USER->id
                                AND u.id = a.userid AND e.id = a.workshopid");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_assessments($submission, $all = '', $order = '') {
    // Return assessments for this submission ordered oldest first, newest last
    // new assessments made within the editing time are NOT returned unless they
    // belong to the user or the second argument is set to ALL
    global $CFG, $USER;

    $timenow = time();
    if (!$order) {
        $order = "timecreated DESC";
    }
    if ($all != 'ALL') {
        return get_records_select("workshop_assessments", "(submissionid = $submission->id) AND 
            ((timecreated < $timenow - $CFG->maxeditingtime) or 
                ((timecreated < $timenow) AND (userid = $USER->id)))", $order);
    } else {
        return get_records_select("workshop_assessments", "submissionid = $submission->id AND 
            (timecreated < $timenow)", $order);
    }
}


///////////////////////////////////////////////////////////////////////////////////////////////
function workshop_get_comment_logs($course, $timestart) {
    // get the "comment" entries for this user and add the first and last names (which may not be used)...
    global $CFG, $USER;
    if (empty($USER->id)) {
        return false;
    }
    
    $timethen = time() - $CFG->maxeditingtime;
    return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name
                             FROM {$CFG->prefix}log l,
                                {$CFG->prefix}workshop e, 
                                {$CFG->prefix}workshop_submissions s, 
                                {$CFG->prefix}workshop_assessments a, 
                                {$CFG->prefix}workshop_comments c, 
                                {$CFG->prefix}user u
                            WHERE l.time > $timestart AND l.time < $timethen 
                                AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'comment'
                                AND c.id = l.info AND c.userid != $USER->id AND a.id = c.assessmentid
                                AND s.id = a.submissionid AND (s.userid = $USER->id OR a.userid = $USER->id)
                                AND u.id = a.userid AND e.id = a.workshopid");
}


///////////////////////////////////////////////////////////////////////////////////////////////
function workshop_get_grade_logs($course, $timestart) {
    // get the "grade" entries for this user and add the first and last names (of submission owner, 
    // better to get name of teacher...
    // ...but not available in assessment record...)
    global $CFG, $USER;
    if (empty($USER->id)) {
        return false;
    }
    
    $timethen = time() - $CFG->maxeditingtime;
    return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name
                             FROM {$CFG->prefix}log l,
                                {$CFG->prefix}workshop e, 
                                {$CFG->prefix}workshop_submissions s, 
                                {$CFG->prefix}workshop_assessments a, 
                                {$CFG->prefix}user u
                            WHERE l.time > $timestart AND l.time < $timethen 
                                AND l.course = $course->id AND l.module = 'workshop'    AND l.action = 'grade'
                                AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
                                AND u.id = s.userid AND e.id = a.workshopid");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_student_submission($workshop, $user) {
// Return a submission for a particular user
    global $CFG;

    $submission = get_record("workshop_submissions", "workshopid", $workshop->id, "userid", $user->id);
    if (!empty($submission->timecreated)) {
        return $submission;
    }
    return NULL;
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_student_submissions($workshop, $order = "title") {
// Return all  ENROLLED student submissions
    global $CFG;
    
    if ($order == "title") {
        $order = "s.title";
        }
    if ($order == "name") {
        $order = "a.lastname, a.firstname";
        }
    if ($order == "time") {
        $order = "s.timecreated ASC";
    }

    if (!$students = workshop_get_students($workshop)) {
        return false;
    }
    $list = "(";
    foreach ($students as $student) {
        $list .= "$student->id,";
    }
    $list = rtrim($list, ',').")";

    return get_records_sql("SELECT s.* FROM {$CFG->prefix}workshop_submissions s, {$CFG->prefix}user a 
                            WHERE s.userid IN $list
                              AND s.workshopid = $workshop->id
                              AND s.timecreated > 0
                              AND s.userid = a.id
                            ORDER BY $order");
}


///////////////////////////////////////////////////////////////////////////////////////////////
function workshop_get_submit_logs($course, $timestart) {
    // get the "submit" entries and add the first and last names...
    global $CFG, $USER;
    
    $timethen = time() - $CFG->maxeditingtime;
    return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, l.info as workshopid, e.name
                             FROM {$CFG->prefix}log l,
                                {$CFG->prefix}workshop e, 
                                {$CFG->prefix}user u
                            WHERE l.time > $timestart AND l.time < $timethen 
                                AND l.course = $course->id AND l.module = 'workshop'
                                AND l.action = 'submit'
                                AND e.id = l.info 
                                AND u.id = l.userid");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_unmailed_assessments($cutofftime) {
    /// Return list of assessments that have not been mailed out
    global $CFG;
    return get_records_sql("SELECT a.*, g.course, g.name
                              FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g
                             WHERE a.mailed = 0 
                               AND a.timecreated < $cutofftime 
                               AND g.id = a.workshopid
                               AND g.releasegrades < $cutofftime");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_unmailed_comments($cutofftime) {
    /// Return list of comments that have not been mailed out
    global $CFG;
    return get_records_sql("SELECT c.*, g.course, g.name
                              FROM {$CFG->prefix}workshop_comments c, {$CFG->prefix}workshop g
                             WHERE c.mailed = 0 
                               AND c.timecreated < $cutofftime 
                               AND g.id = c.workshopid");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_unmailed_graded_assessments($cutofftime) {
    /// Return list of graded assessments that have not been mailed out
    global $CFG;
    return get_records_sql("SELECT a.*, g.course, g.name
                              FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g
                             WHERE a.mailed = 0 
                               AND a.timegraded < $cutofftime 
                               AND a.timegraded > 0
                               AND g.id = a.workshopid");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_unmailed_resubmissions($cutofftime) {
    /// Return list of assessments of resubmissions that have not been mailed out
    global $CFG;
    return get_records_sql("SELECT a.*, w.course, w.name
                              FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop w
                             WHERE a.mailed = 0 
                               AND a.resubmission = 1
                               AND w.id = a.workshopid");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_user_assessments($workshop, $user) {
// Return all the  user's assessments, newest first, oldest last (hot, warm and cold ones)
    return get_records_select("workshop_assessments", "workshopid = $workshop->id AND userid = $user->id", 
                "timecreated DESC");
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_get_user_submissions($workshop, $user) {
    // return real submissions of user newest first, oldest last. Ignores the dummy submissions
    // which get created to hold the final grades for users that make no submissions
    return get_records_select("workshop_submissions", "workshopid = $workshop->id AND 
        userid = $user->id AND timecreated > 0", "timecreated DESC" );
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_grade_assessments($workshop, $verbose=false) {
    global $WORKSHOP_EWEIGHTS;
    
    // timeout after 10 minutes
    @set_time_limit(600);

    $timenow = time();
    
    // set minumim value for the variance (of the elements)
    $minvar = 0.05;

    // check when the standard deviations were calculated
    $oldtotalassessments = get_field("workshop_elements", "totalassessments", "workshopid", $workshop->id, 
                "elementno", 0);
    $totalassessments = count_records("workshop_assessments", "workshopid", $workshop->id);
    // calculate the std. devs every 10 assessments for low numbers of assessments, thereafter every 100 new assessments
    if ((($totalassessments < 100) and (($totalassessments - $oldtotalassessments) > 10)) or 
            (($totalassessments - $oldtotalassessments) > 100)) {
        // calculate the means for each submission using just the "good" assessments 
        if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) {
            foreach ($submissions as $submission) {
                $nassessments[$submission->id] = 0;
                if ($assessments = workshop_get_assessments($submission)) {
                    foreach ($assessments as $assessment) {
                        // test if assessment is "good", a teacher assessment always "good", but may be weighted out 
                        if (workshop_is_teacher($workshop, $assessment->userid)) {
                            if (!$workshop->teacherweight) {
                                // drop teacher's assessment as weight is zero
                                continue;
                            }
                        } elseif ((!$assessment->gradinggrade and $assessment->timegraded) or 
                                ($workshop->agreeassessments and !$assessment->timeagreed)) {
                            // it's a duff assessment, or it's not been agreed
                            continue;
                        }
                        if (isset($num[$submission->id])) {
                            if (workshop_is_teacher($workshop, $assessment->userid)) {
                                $num[$submission->id] += $workshop->teacherweight; // weight teacher's assessment
                            } else {
                                $num[$submission->id]++; // number of assessments
                            }
                            $nassessments[$submission->id]++;
                        } else {
                            if (workshop_is_teacher($workshop, $assessment->userid)) {
                                $num[$submission->id] = $workshop->teacherweight;
                            } else {
                                $num[$submission->id] = 1;
                            }
                            $nassessments[$submission->id] = 1;
                        }
                        for ($i = 0; $i < $workshop->nelements; $i++) {
                            $grade =  get_field("workshop_grades", "grade",
                                    "assessmentid", $assessment->id, "elementno", $i);
                            if (isset($sum[$submission->id][$i])) {
                                if (workshop_is_teacher($workshop, $assessment->userid)) {
                                    $sum[$submission->id][$i] += $workshop->teacherweight * $grade; // teacher's grade
                                } else {
                                    $sum[$submission->id][$i] += $grade; // student's grade
                                }
                            } else { 
                                if (workshop_is_teacher($workshop, $assessment->userid)) {
                                    $sum[$submission->id][$i] = $workshop->teacherweight * $grade; // teacher's grade
                                } else {
                                    $sum[$submission->id][$i] = $grade; // students's grade
                                }
                            }
                        }
                    }
                }
            }

            if (!isset($num)) { 
                // no assessments yet
                return;
            }
            reset($num);
            // calculate the means for each submission
            $total = 0;
            foreach ($num as $submissionid => $n) {
                if ($n) { // stop division by zero
                    for ($i = 0; $i < $workshop->nelements; $i++) {
                        $mean[$submissionid][$i] = $sum[$submissionid][$i] / $n;
                        // echo "Submission: $submissionid; Element: $i; Mean: {$mean[$submissionid][$i]}<br />\n";
                    }
                    $total += $n; // weighted total
                }
            }
            if ($verbose) {
                echo "<p style=\"text-align:center\">".get_string("numberofsubmissions", "workshop", count($num))."<br />\n";
                echo get_string("numberofassessmentsweighted", "workshop", $total)."</p>\n";
            }

            // now get an estimate of the standard deviation of each element in the assessment
            // this is just a rough measure, all assessments are included and teacher's assesments are not weighted
            $n = 0;
            for ($i = 0; $i < $workshop->nelements; $i++) {
                $var[$i] = 0;
            }
            foreach ($submissions as $submission) {
                if ($assessments = workshop_get_assessments($submission)) {
                    foreach ($assessments as $assessment) {
                        $n++;
                        for ($i = 0; $i < $workshop->nelements; $i++) {
                            $grade =  get_field("workshop_grades", "grade",
                                    "assessmentid", $assessment->id, "elementno", $i);
                            $temp = $mean[$submission->id][$i] - $grade;
                            $var[$i] += $temp * $temp;
                        }
                    }
                }
            }
            for ($i = 0; $i < $workshop->nelements; $i++) {
                if ($n > 1) {
                    $sd[$i] = sqrt($var[$i] / ($n - 1));
                } else {
                    $sd[$i] = 0;
                }
                set_field("workshop_elements", "stddev", $sd[$i], "workshopid", $workshop->id, "elementno", $i);
                set_field("workshop_elements", "totalassessments", $totalassessments, "workshopid", $workshop->id,
                        "elementno", $i);
                if ($verbose) {
                    echo get_string("standarddeviationofelement", "workshop", $i+1)." $sd[$i]<br />";
                    if ($sd[$i] <= $minvar) {
                        print_string("standarddeviationnote", "workshop")."<br />\n";
                    }
                }
            }
        } 
    }

    // this section looks at each submission if the number of assessments made has increased it recalculates the
    // grading grades for those assessments
    // first get the assignment elements for the weights and the stddevs...
    if ($elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC")) {
        foreach ($elementsraw as $element) {
            $weight[] = $element->weight;   // to renumber index 0,1,2...
            $sd[] = $element->stddev;   // to renumber index 0,1,2...
        }
    }

    unset($num); // may have been used in calculating stddevs
    unset($sum); // ditto
    if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) {
        foreach ($submissions as $submission) {
            // see if the number of assessments has changed
            $nassessments = workshop_count_assessments($submission);
            if ($submission->nassessments <> $nassessments) {
                // ...if there are three or more assessments calculate the variance of each assessment.
                // Use the variance to find the "best" assessment. (When there is only one or two assessments they 
                // are not altered by this routine.)
                if ($verbose) {
                    echo "Processing submission $submission->id ($nassessments asessments)...\n"; 
                }
                if ($nassessments > 2) {
                    $num = 0; // weighted number of assessments
                    for ($i = 0; $i < $workshop->nelements; $i++) {
                        $sum[$i] = 0; // weighted sum of grades
                    }
                    if ($assessments = workshop_get_assessments($submission)) {
                        // first calculate the mean grades for each element
                        foreach ($assessments as $assessment) {
                            // test if assessment is "good", a teacher assessment always "good", but may be weighted out 
                            if (workshop_is_teacher($workshop, $assessment->userid)) {
                                if (!$workshop->teacherweight) {
                                    // drop teacher's assessment as weight is zero
                                    continue;
                                }
                            } else if ((!$assessment->gradinggrade and $assessment->timegraded) or 
                                    ($workshop->agreeassessments and !$assessment->timeagreed)) {
                                // it's a duff assessment, or it's not been agreed
                                continue;
                            }
                            if (workshop_is_teacher($workshop, $assessment->userid)) {
                                $num += $workshop->teacherweight; // weight teacher's assessment
                            } else {
                                $num++; // student assessment just add one
                            }
                            for ($i = 0; $i < $workshop->nelements; $i++) {
                                $grade =  get_field("workshop_grades", "grade",
                                        "assessmentid", $assessment->id, "elementno", $i);
                                if (workshop_is_teacher($workshop, $assessment->userid)) {
                                    $sum[$i] += $workshop->teacherweight * $grade; // teacher's grade
                                } else {
                                    $sum[$i] += $grade; // student's grade
                                }
                            }
                        }
                        if ($num) { // could all the assessments be duff? 
                            for ($i = 0; $i < $workshop->nelements; $i++) {
                                $mean[$i] = $sum[$i] / $num;
                                if ($verbose) echo "Submission: $submission->id; Element: $i; Mean: {$mean[$i]}\n";
                            }
                        } else {
                            continue; // move to the next submission
                        }
                        // run through the assessments again to see which is the "best" one (the one
                        // closest to the mean)
                        $lowest = 10e9;
                        foreach ($assessments as $assessment) {
                            if ($workshop->agreeassessments and !$assessment->timeagreed) {
                                // ignore assessments that have not been agreed
                                continue;
                            }
                            $var = 0;
                            for ($i = 0; $i < $workshop->nelements; $i++) {
                                $grade =  get_field("workshop_grades", "grade",
                                        "assessmentid", $assessment->id, "elementno", $i);
                                if ($sd[$i] > $minvar) {
                                    $temp = ($mean[$i] - $grade) * 
                                        $WORKSHOP_EWEIGHTS[$weight[$i]] / $sd[$i];
                                } else {
                                    $temp = 0;
                                }
                                $var += $temp * $temp;
                            }
                            // find the "best" assessment of this submission
                            if ($lowest > $var) {
                                $lowest = $var;
                                $bestassessmentid = $assessment->id;
                            }
                        }

                        if (!$best = get_record("workshop_assessments", "id", $bestassessmentid)) {
                            notify("Workshop grade assessments: cannot find best assessment");
                            continue;
                        }
                        if ($verbose) {
                            echo "Best assessment is $bestassessmentid;\n";
                        }
                        foreach ($assessments as $assessment) {
                            // don't overwrite teacher's grade
                            if ($assessment->teachergraded) {
                                continue;
                            }
                            if ($assessment->id == $bestassessmentid) { 
                                // it's the best one, set the grading grade to the maximum 
                                set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id);
                                set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
                            } else {
                                // it's one of the pack, compare with the best...
                                $gradinggrade = workshop_compare_assessments($workshop, $best, $assessment);
                                // ...and save the grade for the assessment 
                                set_field("workshop_assessments", "gradinggrade", $gradinggrade, "id", $assessment->id);
                                set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
                            }
                        }
                    }
                } else {
                    // there are less than 3 assessments for this submission
                    if ($assessments = workshop_get_assessments($submission)) {
                        foreach ($assessments as $assessment) {
                            if (!$assessment->timegraded and !$assessment->teachergraded) {
                                // set the grading grade to the maximum and say it's been graded 
                                set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id);
                                set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
                            }
                        }
                    }
                }       
                // set the number of assessments for this submission
                set_field("workshop_submissions", "nassessments", $nassessments, "id", $submission->id);    
            }
        }
    }
    return;
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_gradinggrade($workshop, $student) {
    // returns the current (external) grading grade of the based on their (cold) assessments
    // (needed as it's called by grade)
    
    $gradinggrade = 0;
    if ($assessments = workshop_get_user_assessments($workshop, $student)) {
        $n = 0;
        foreach ($assessments as $assessment) {
            $gradinggrade += $assessment->gradinggrade;
            $n++;
        }
        if ($n < ($workshop->ntassessments + $workshop->nsassessments)) { // the minimum students should do
            $n = $workshop->ntassessments + $workshop->nsassessments;
        }
        $gradinggrade = $gradinggrade / $n;
    }
    return number_format($gradinggrade * $workshop->gradinggrade / 100, 1);
}


//////////////////////////////////////////////////////////////////////////////////////
function workshop_submission_grade($workshop, $submission) {
    // returns the current (external) grade of the submission based on the "good" (cold) assessments
    // (needed as it's called by grade)
    
    $grade = 0;
    if ($assessments = workshop_get_assessments($submission)) {
        $n = 0;
        foreach ($assessments as $assessment) {
            if ($workshop->agreeassessments and !$assessment->timeagreed) {
                // ignore assessments which have not been agreed
                continue;
            }
            if ($assessment->gradinggrade or !$assessment->timegraded) { 
                // a good assessment (or one that has not been graded yet)
                if (workshop_is_teacher($workshop, $assessment->userid)) {
                    $timenow = time();
                    if ($timenow > $workshop->releasegrades) {
                        // teacher's grade is available
                        $grade += $workshop->teacherweight * $assessment->grade;
                        $n += $workshop->teacherweight;
                    }
                } else {
                    $grade += $assessment->grade;
                    $n++;
                }
            }
        }
        if ($n) { // stop division by zero
            $grade = $grade / $n;
        }
    }
    return number_format($grade * $workshop->grade / 100, 1);
}


/////////////////////////////////////////////////////////////////////////////
function workshop_fullname($userid, $courseid) {
    global $CFG;
    if (!$user = get_record('user', 'id', $userid)) {
        return '';
    }
    return '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$courseid.'">'.
        fullname($user).'</a>';
}

function workshop_get_view_actions() {
    return array('view','view all');
}

function workshop_get_post_actions() {
    return array('agree','assess','comment','grade','newattachment','removeattachments','resubmit','submit');
}

?>