sessionmanager.lib.php 301 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
  4. use Chamilo\CoreBundle\Framework\Container;
  5. use Chamilo\CoreBundle\Entity\Session;
  6. /**
  7. * Class SessionManager
  8. *
  9. * This is the session library for Chamilo.
  10. * All main sessions functions should be placed here.
  11. * This class provides methods for sessions management.
  12. * Include/require it in your code to use its features.
  13. *
  14. * @package chamilo.library
  15. *
  16. */
  17. class SessionManager
  18. {
  19. //See BT#4871
  20. CONST SESSION_CHANGE_USER_REASON_SCHEDULE = 1;
  21. CONST SESSION_CHANGE_USER_REASON_CLASSROOM = 2;
  22. CONST SESSION_CHANGE_USER_REASON_LOCATION = 3;
  23. CONST SESSION_CHANGE_USER_REASON_ENROLLMENT_ANNULATION = 4;
  24. CONST DEFAULT_VISIBILITY = 4; //SESSION_AVAILABLE
  25. public static $_debug = false;
  26. /**
  27. * Constructor
  28. */
  29. public function __construct()
  30. {
  31. }
  32. /**
  33. * Fetches a session from the database
  34. * @param int $id Session Id
  35. *
  36. * @return array Session details
  37. */
  38. public static function fetch($id)
  39. {
  40. $t = Database::get_main_table(TABLE_MAIN_SESSION);
  41. if ($id != strval(intval($id))) {
  42. return array();
  43. }
  44. $s = "SELECT * FROM $t WHERE id = $id";
  45. $r = Database::query($s);
  46. if (Database::num_rows($r) != 1) {
  47. return array();
  48. }
  49. return Database::fetch_array($r, 'ASSOC');
  50. }
  51. /**
  52. * Create a session
  53. * @author Carlos Vargas <carlos.vargas@beeznest.com>, from existing code
  54. * @param string $name
  55. * @param string $startDate (YYYY-MM-DD hh:mm:ss)
  56. * @param string $endDate (YYYY-MM-DD hh:mm:ss)
  57. * @param string $displayStartDate (YYYY-MM-DD hh:mm:ss)
  58. * @param string $displayEndDate (YYYY-MM-DD hh:mm:ss)
  59. * @param string $coachStartDate (YYYY-MM-DD hh:mm:ss)
  60. * @param string $coachEndDate (YYYY-MM-DD hh:mm:ss)
  61. * @param mixed $coachId If integer, this is the session coach id, if string, the coach ID will be looked for from the user table
  62. * @param integer $sessionCategoryId ID of the session category in which this session is registered
  63. * @param integer $visibility Visibility after end date (0 = read-only, 1 = invisible, 2 = accessible)
  64. * @param bool $fixSessionNameIfExists
  65. * @param string $duration
  66. * @param string $description Optional. The session description
  67. * @param int $showDescription Optional. Whether show the session description
  68. * @param array $extraFields
  69. * @param int $sessionAdminId Optional. If this sessions was created by a session admin, assign it to him
  70. * @param boolean $sendSubscritionNotification Optional.
  71. * Whether send a mail notification to users being subscribed
  72. * @todo use an array to replace all this parameters or use the model.lib.php ...
  73. * @return mixed Session ID on success, error message otherwise
  74. * */
  75. public static function create_session(
  76. $name,
  77. $startDate,
  78. $endDate,
  79. $displayStartDate,
  80. $displayEndDate,
  81. $coachStartDate,
  82. $coachEndDate,
  83. $coachId,
  84. $sessionCategoryId,
  85. $visibility = 1,
  86. $fixSessionNameIfExists = false,
  87. $duration = null,
  88. $description = null,
  89. $showDescription = 0,
  90. $extraFields = array(),
  91. $sessionAdminId = 0,
  92. $sendSubscritionNotification = false
  93. ) {
  94. $em = Database::getManager();
  95. /*
  96. if (is_array($_configuration[$access_url_id]) &&
  97. isset($_configuration[$access_url_id]['hosting_limit_sessions']) &&
  98. $_configuration[$access_url_id]['hosting_limit_sessions'] > 0
  99. ) {
  100. $num = self::count_sessions();
  101. if ($num >= $_configuration[$access_url_id]['hosting_limit_sessions']) {
  102. api_warn_hosting_contact('hosting_limit_sessions');
  103. return get_lang('PortalSessionsLimitReached');
  104. }
  105. }*/
  106. $name = trim($name);
  107. $sessionCategoryId = intval($sessionCategoryId);
  108. $visibility = intval($visibility);
  109. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  110. if (empty($name)) {
  111. $msg = get_lang('SessionNameIsRequired');
  112. return $msg;
  113. } elseif (empty($coachId)) {
  114. $msg = get_lang('CoachIsRequired');
  115. return $msg;
  116. } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') && !api_is_valid_date($startDate, 'Y-m-d H:i:s')) {
  117. $msg = get_lang('InvalidStartDate');
  118. return $msg;
  119. } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') && !api_is_valid_date($endDate, 'Y-m-d H:i:s')) {
  120. $msg = get_lang('InvalidEndDate');
  121. return $msg;
  122. } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
  123. $msg = get_lang('StartDateShouldBeBeforeEndDate');
  124. return $msg;
  125. } else {
  126. $ready_to_create = false;
  127. if ($fixSessionNameIfExists) {
  128. $name = self::generateNextSessionName($name);
  129. if ($name) {
  130. $ready_to_create = true;
  131. } else {
  132. $msg = get_lang('SessionNameAlreadyExists');
  133. return $msg;
  134. }
  135. } else {
  136. $rs = Database::query("SELECT 1 FROM $tbl_session WHERE name='" . $name . "'");
  137. if (Database::num_rows($rs)) {
  138. $msg = get_lang('SessionNameAlreadyExists');
  139. return $msg;
  140. }
  141. $ready_to_create = true;
  142. }
  143. if ($ready_to_create) {
  144. $sessionAdminId = !empty($sessionAdminId) ? $sessionAdminId : api_get_user_id();
  145. $session = new Session();
  146. $session
  147. ->setName($name)
  148. ->setVisibility($visibility)
  149. ->setDescription($description)
  150. ->setShowDescription($showDescription)
  151. ->setSendSubscriptionNotification($sendSubscritionNotification)
  152. ->setSessionAdminId($sessionAdminId)
  153. ;
  154. if (!empty($coachId)) {
  155. $coach = UserManager::getManager()->find($coachId);
  156. if ($coach) {
  157. $session->setGeneralCoach($coach);
  158. }
  159. }
  160. if (!empty($startDate)) {
  161. $session->setAccessStartDate(new \DateTime($startDate));
  162. }
  163. if (!empty($endDate)) {
  164. $session->setAccessEndDate(new \DateTime($endDate));
  165. }
  166. if (!empty($displayStartDate)) {
  167. $session->setDisplayStartDate(new \DateTime($displayStartDate));
  168. }
  169. if (!empty($displayEndDate)) {
  170. $session->setDisplayEndDate(new \DateTime($displayEndDate));
  171. }
  172. if (!empty($coachStartDate)) {
  173. $session->setCoachAccessStartDate(new \DateTime($coachStartDate));
  174. }
  175. if (!empty($coachEndDate)) {
  176. $session->setCoachAccessEndDate(new \DateTime($coachEndDate));
  177. }
  178. if (!empty($sessionCategoryId)) {
  179. $session->setCategory($sessionCategoryId);
  180. }
  181. $duration = intval($duration);
  182. if (!empty($duration)) {
  183. $session->setDuration($duration);
  184. $session->setAccessStartDate(null);
  185. $session->setAccessEndDate(null);
  186. $session->setDisplayStartDate(null);
  187. $session->setDisplayEndDate(null);
  188. $session->setCoachAccessStartDate(null);
  189. $session->setCoachAccessEndDate(null);
  190. } else {
  191. $session->setDuration(0);
  192. }
  193. $url = $em->getRepository('ChamiloCoreBundle:AccessUrl')->find(api_get_current_access_url_id());
  194. $accessRelSession = new \Chamilo\CoreBundle\Entity\AccessUrlRelSession();
  195. $accessRelSession->setUrl($url);
  196. $session->addUrls($accessRelSession);
  197. $em->persist($session);
  198. $em->flush();
  199. $session_id = $session->getId();
  200. if (!empty($session_id)) {
  201. $extraFields['item_id'] = $session_id;
  202. $sessionFieldValue = new ExtraFieldValue('session');
  203. $sessionFieldValue->saveFieldValues($extraFields);
  204. /*
  205. Sends a message to the user_id = 1
  206. $user_info = api_get_user_info(1);
  207. $complete_name = $user_info['firstname'].' '.$user_info['lastname'];
  208. $subject = api_get_setting('platform.site_name').' - '.get_lang('ANewSessionWasCreated');
  209. $message = get_lang('ANewSessionWasCreated')." <br /> ".get_lang('NameOfTheSession').' : '.$name;
  210. api_mail_html($complete_name, $user_info['email'], $subject, $message);
  211. *
  212. */
  213. //Adding to the correct URL
  214. $access_url_id = api_get_current_access_url_id();
  215. UrlManager::add_session_to_url($session_id, $access_url_id);
  216. // add event to system log
  217. $user_id = api_get_user_id();
  218. Event::addEvent(
  219. LOG_SESSION_CREATE,
  220. LOG_SESSION_ID,
  221. $session_id,
  222. api_get_utc_datetime(),
  223. $user_id
  224. );
  225. }
  226. return $session_id;
  227. }
  228. }
  229. }
  230. /**
  231. * @param string $name
  232. *
  233. * @return bool
  234. */
  235. public static function session_name_exists($name)
  236. {
  237. $name = Database::escape_string($name);
  238. $sql = "SELECT COUNT(*) as count FROM " . Database::get_main_table(TABLE_MAIN_SESSION) . "
  239. WHERE name = '$name'";
  240. $result = Database::fetch_array(Database::query($sql));
  241. return $result['count'] > 0;
  242. }
  243. /**
  244. * @param string $where_condition
  245. *
  246. * @return mixed
  247. */
  248. public static function get_count_admin($where_condition = '')
  249. {
  250. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  251. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  252. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  253. $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  254. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  255. $where = 'WHERE 1=1 ';
  256. $user_id = api_get_user_id();
  257. $extraJoin = '';
  258. if (api_is_session_admin() &&
  259. api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
  260. ) {
  261. $where .= " AND (
  262. s.session_admin_id = $user_id OR
  263. sru.user_id = '$user_id' AND
  264. sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "'
  265. )
  266. ";
  267. $extraJoin = " INNER JOIN $tbl_session_rel_user sru
  268. ON sru.session_id = s.id ";
  269. }
  270. $today = api_get_utc_datetime();
  271. $today = api_strtotime($today, 'UTC');
  272. $today = date('Y-m-d', $today);
  273. if (!empty($where_condition)) {
  274. $where_condition = str_replace("( session_active = ':' )", '1=1', $where_condition);
  275. $where_condition = str_replace('category_name', 'sc.name', $where_condition);
  276. $where_condition = str_replace(
  277. array("AND session_active = '1' )", " AND ( session_active = '1' )"),
  278. array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
  279. , $where_condition
  280. );
  281. $where_condition = str_replace(
  282. array("AND session_active = '0' )", " AND ( session_active = '0' )"),
  283. array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
  284. $where_condition
  285. );
  286. } else {
  287. $where_condition = " AND 1 = 1";
  288. }
  289. $courseCondition = null;
  290. if (strpos($where_condition, 'c.id')) {
  291. $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  292. $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
  293. $courseCondition = " INNER JOIN $table course_rel_session
  294. ON (s.id = course_rel_session.session_id)
  295. INNER JOIN $tableCourse c
  296. ON (course_rel_session.c_id = c.id)
  297. ";
  298. }
  299. $sql = "SELECT COUNT(id) as total_rows FROM (
  300. SELECT DISTINCT
  301. IF (
  302. (s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
  303. (s.access_start_date IS NULL AND s.access_end_date = IS NULL ) OR
  304. (s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
  305. ('$today' <= s.access_end_date AND s.access_start_date IS NULL)
  306. , 1, 0) as session_active,
  307. s.id
  308. FROM $tbl_session s
  309. LEFT JOIN $tbl_session_category sc
  310. ON s.session_category_id = sc.id
  311. INNER JOIN $tbl_user u
  312. ON s.id_coach = u.user_id
  313. $courseCondition
  314. $extraJoin
  315. $where $where_condition ) as session_table";
  316. if (api_is_multiple_url_enabled()) {
  317. $access_url_id = api_get_current_access_url_id();
  318. if ($access_url_id != -1) {
  319. $where.= " AND ar.access_url_id = $access_url_id ";
  320. $sql = "SELECT count(id) as total_rows FROM (
  321. SELECT DISTINCT
  322. IF (
  323. (s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
  324. (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
  325. (s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
  326. ('$today' <= s.access_end_date AND s.access_start_date IS NULL)
  327. , 1, 0)
  328. as session_active,
  329. s.id
  330. FROM $tbl_session s
  331. LEFT JOIN $tbl_session_category sc
  332. ON s.session_category_id = sc.id
  333. INNER JOIN $tbl_user u ON s.id_coach = u.user_id
  334. INNER JOIN $table_access_url_rel_session ar
  335. ON ar.session_id = s.id
  336. $courseCondition
  337. $extraJoin
  338. $where $where_condition) as session_table";
  339. }
  340. }
  341. $result_rows = Database::query($sql);
  342. $row = Database::fetch_array($result_rows);
  343. $num = $row['total_rows'];
  344. return $num;
  345. }
  346. /**
  347. * Gets the admin session list callback of the session/session_list.php page
  348. * @param array $options order and limit keys
  349. * @param boolean $get_count Whether to get all the results or only the count
  350. * @return mixed Integer for number of rows, or array of results
  351. * @assert (array(),true) !== false
  352. */
  353. public static function get_sessions_admin($options = array(), $get_count = false)
  354. {
  355. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  356. $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  357. $where = 'WHERE 1 = 1 ';
  358. $user_id = api_get_user_id();
  359. if (!api_is_platform_admin()) {
  360. if (api_is_session_admin() &&
  361. api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
  362. ) {
  363. $where .=" AND s.session_admin_id = $user_id ";
  364. }
  365. }
  366. if (!api_is_platform_admin() && api_is_teacher() &&
  367. api_get_setting('session.allow_teachers_to_create_sessions') == 'true'
  368. ) {
  369. $where .=" AND s.id_coach = $user_id ";
  370. }
  371. $extra_field = new ExtraField('session');
  372. $conditions = $extra_field->parseConditions($options);
  373. $inject_joins = $conditions['inject_joins'];
  374. $where .= $conditions['where'];
  375. $inject_where = $conditions['inject_where'];
  376. $inject_extra_fields = $conditions['inject_extra_fields'];
  377. $order = $conditions['order'];
  378. $limit = $conditions['limit'];
  379. $isMakingOrder = false;
  380. if ($get_count == true) {
  381. $select = " SELECT count(*) as total_rows";
  382. } else {
  383. $select =
  384. "SELECT DISTINCT ".
  385. " s.name, ".
  386. " s.display_start_date, ".
  387. " s.display_end_date, ".
  388. " access_start_date, ".
  389. " access_end_date, ".
  390. " s.visibility, ".
  391. " s.session_category_id, ".
  392. " $inject_extra_fields ".
  393. " s.id ";
  394. $isMakingOrder = strpos($options['order'], 'category_name') === 0;
  395. }
  396. $isFilteringSessionCategory = strpos($where, 'category_name') !== false;
  397. if ($isMakingOrder || $isFilteringSessionCategory) {
  398. $inject_joins .= " LEFT JOIN $sessionCategoryTable sc ON s.session_category_id = sc.id ";
  399. if ($isFilteringSessionCategory) {
  400. $where = str_replace('category_name', 'sc.name', $where);
  401. }
  402. if ($isMakingOrder) {
  403. $order = str_replace('category_name', 'sc.name', $order);
  404. }
  405. }
  406. $query = "$select FROM $tbl_session s $inject_joins $where $inject_where";
  407. if (api_is_multiple_url_enabled()) {
  408. $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  409. $access_url_id = api_get_current_access_url_id();
  410. if ($access_url_id != -1) {
  411. $where.= " AND ar.access_url_id = $access_url_id ";
  412. $query = "$select
  413. FROM $tbl_session s $inject_joins
  414. INNER JOIN $table_access_url_rel_session ar
  415. ON (ar.session_id = s.id) $where";
  416. }
  417. }
  418. $query .= $order;
  419. $query .= $limit;
  420. $result = Database::query($query);
  421. $categories = self::get_all_session_category();
  422. $orderedCategories = array();
  423. if (!empty($categories)) {
  424. foreach ($categories as $category) {
  425. $orderedCategories[$category['id']] = $category['name'];
  426. }
  427. }
  428. $formatted_sessions = array();
  429. if (Database::num_rows($result)) {
  430. $sessions = Database::store_result($result, 'ASSOC');
  431. if ($get_count) {
  432. return $sessions[0]['total_rows'];
  433. }
  434. foreach ($sessions as $session) {
  435. $session_id = $session['id'];
  436. $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
  437. if (isset($session['session_active']) && $session['session_active'] == 1) {
  438. $session['session_active'] = Display::return_icon('accept.png', get_lang('Active'), array(), ICON_SIZE_SMALL);
  439. } else {
  440. $session['session_active'] = Display::return_icon('error.png', get_lang('Inactive'), array(), ICON_SIZE_SMALL);
  441. }
  442. $session = self::convert_dates_to_local($session, true);
  443. switch ($session['visibility']) {
  444. case SESSION_VISIBLE_READ_ONLY: //1
  445. $session['visibility'] = get_lang('ReadOnly');
  446. break;
  447. case SESSION_VISIBLE: //2
  448. case SESSION_AVAILABLE: //4
  449. $session['visibility'] = get_lang('Visible');
  450. break;
  451. case SESSION_INVISIBLE: //3
  452. $session['visibility'] = api_ucfirst(get_lang('Invisible'));
  453. break;
  454. }
  455. // Cleaning double selects.
  456. foreach ($session as $key => &$value) {
  457. if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
  458. $options = explode('::', $value);
  459. }
  460. $original_key = $key;
  461. if (strpos($key, '_second') === false) {
  462. } else {
  463. $key = str_replace('_second', '', $key);
  464. }
  465. if (isset($options_by_double[$key])) {
  466. if (isset($options[0])) {
  467. if (isset($options_by_double[$key][$options[0]])) {
  468. if (strpos($original_key, '_second') === false) {
  469. $value = $options_by_double[$key][$options[0]]['option_display_text'];
  470. } else {
  471. $value = $options_by_double[$key][$options[1]]['option_display_text'];
  472. }
  473. }
  474. }
  475. }
  476. }
  477. $formatted_sessions[$session_id] = $session;
  478. $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
  479. $formatted_sessions[$session_id]['category_name'] = $categoryName;
  480. }
  481. }
  482. return $formatted_sessions;
  483. }
  484. /**
  485. * Get total of records for progress of learning paths in the given session
  486. * @param int session id
  487. * @return int
  488. */
  489. public static function get_count_session_lp_progress($sessionId = 0)
  490. {
  491. $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
  492. $tbl_lp_view = Database::get_course_table(TABLE_LP_VIEW);
  493. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  494. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  495. $sessionId = intval($sessionId);
  496. $sql = "SELECT count(*) as total_rows
  497. FROM $tbl_lp_view v
  498. INNER JOIN $tbl_lp l ON l.id = v.lp_id
  499. INNER JOIN $tbl_user u ON u.user_id = v.user_id
  500. INNER JOIN $tbl_course c
  501. WHERE v.session_id = " . $sessionId;
  502. $result_rows = Database::query($sql);
  503. $row = Database::fetch_array($result_rows);
  504. $num = $row['total_rows'];
  505. return $num;
  506. }
  507. /**
  508. * Gets the progress of learning paths in the given session
  509. * @param int $sessionId
  510. * @param int $courseId
  511. * @param string $date_from
  512. * @param string $date_to
  513. * @param array options order and limit keys
  514. * @return array table with user name, lp name, progress
  515. */
  516. public static function get_session_lp_progress($sessionId = 0, $courseId = 0, $date_from, $date_to, $options)
  517. {
  518. //escaping vars
  519. $sessionId = $sessionId == 'T' ? 'T' : intval($sessionId);
  520. $courseId = intval($courseId);
  521. $date_from = Database :: escape_string($date_from);
  522. $date_to = Database :: escape_string($date_to);
  523. //tables
  524. $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  525. $user = Database::get_main_table(TABLE_MAIN_USER);
  526. $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
  527. $course = api_get_course_info_by_id($courseId);
  528. //getting all the students of the course
  529. //we are not using this because it only returns user ids
  530. /* if (empty($sessionId)
  531. {
  532. // Registered students in a course outside session.
  533. $users = CourseManager :: get_student_list_from_course_code($course_code);
  534. } else {
  535. // Registered students in session.
  536. $users = CourseManager :: get_student_list_from_course_code($course_code, true, $sessionId);
  537. } */
  538. $sessionCond = 'and session_id = %s';
  539. if ($sessionId == 'T') {
  540. $sessionCond = "";
  541. }
  542. $where = " WHERE c_id = '%s' AND s.status <> 2 $sessionCond";
  543. $limit = null;
  544. if (!empty($options['limit'])) {
  545. $limit = " LIMIT " . $options['limit'];
  546. }
  547. if (!empty($options['where'])) {
  548. $where .= ' '.$options['where'];
  549. }
  550. $order = null;
  551. if (!empty($options['order'])) {
  552. $order = " ORDER BY " . $options['order'];
  553. }
  554. $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
  555. FROM $session_course_user s
  556. INNER JOIN $user u ON u.user_id = s.user_id
  557. $where
  558. $order
  559. $limit";
  560. $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
  561. $rs = Database::query($sql_query);
  562. while ($user = Database::fetch_array($rs)) {
  563. $users[$user['user_id']] = $user;
  564. }
  565. //Get lessons
  566. $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
  567. $table = array();
  568. foreach ($users as $user) {
  569. $data = array(
  570. 'lastname' => $user[1],
  571. 'firstname' => $user[2],
  572. 'username' => $user[3],
  573. );
  574. $sessionCond = 'AND v.session_id = %d';
  575. if ($sessionId == 'T') {
  576. $sessionCond = "";
  577. }
  578. //Get lessons progress by user
  579. $sql = "SELECT v.lp_id as id, v.progress
  580. FROM $tbl_course_lp_view v
  581. WHERE v.c_id = %d
  582. AND v.user_id = %d
  583. $sessionCond";
  584. $sql_query = sprintf($sql,
  585. intval($courseId),
  586. intval($user['user_id']),
  587. $sessionId
  588. );
  589. $result = Database::query($sql_query);
  590. $user_lessons = array();
  591. while ($row = Database::fetch_array($result)) {
  592. $user_lessons[$row['id']] = $row;
  593. }
  594. //Match course lessons with user progress
  595. $progress = 0;
  596. $count = 0;
  597. foreach ($lessons as $lesson) {
  598. $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
  599. $progress += $data[$lesson['id']];
  600. $data[$lesson['id']] = $data[$lesson['id']] . '%';
  601. $count++;
  602. }
  603. if ($count == 0) {
  604. $data['total'] = 0;
  605. } else {
  606. $data['total'] = round($progress / $count, 2) . '%';
  607. }
  608. $table[] = $data;
  609. }
  610. return $table;
  611. }
  612. /**
  613. * Gets the survey answers
  614. * @param int $sessionId
  615. * @param int $courseId
  616. * @param int $surveyId
  617. * @param array options order and limit keys
  618. * @todo fix the query
  619. * @return array table with user name, lp name, progress
  620. */
  621. public static function get_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $date_from, $date_to, $options)
  622. {
  623. //escaping vars
  624. $sessionId = intval($sessionId);
  625. $courseId = intval($courseId);
  626. $surveyId = intval($surveyId);
  627. $date_from = Database::escape_string($date_from);
  628. $date_to = Database::escape_string($date_to);
  629. //tables
  630. $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  631. $user = Database::get_main_table(TABLE_MAIN_USER);
  632. $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
  633. $c_survey = Database::get_course_table(TABLE_SURVEY);
  634. $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
  635. $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
  636. $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
  637. $course = api_get_course_info_by_id($courseId);
  638. $where = " WHERE c_id = '%s' AND s.status <> 2 AND session_id = %s";
  639. $limit = null;
  640. if (!empty($options['limit'])) {
  641. $limit = " LIMIT " . $options['limit'];
  642. }
  643. if (!empty($options['where'])) {
  644. $where .= ' '.$options['where'];
  645. }
  646. $order = null;
  647. if (!empty($options['order'])) {
  648. $order = " ORDER BY " . $options['order'];
  649. }
  650. $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
  651. FROM $session_course_user s
  652. INNER JOIN $user u ON u.user_id = s.user_id
  653. $where $order $limit";
  654. $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
  655. $rs = Database::query($sql_query);
  656. while ($user = Database::fetch_array($rs)) {
  657. $users[$user['user_id']] = $user;
  658. }
  659. //Get survey questions
  660. $questions = SurveyManager::get_questions($surveyId, $courseId);
  661. //Survey is anonymous?
  662. $result = Database::query(sprintf("SELECT anonymous FROM $c_survey WHERE survey_id = %d", $surveyId));
  663. $row = Database::fetch_array($result);
  664. $anonymous = ($row['anonymous'] == 1) ? true : false;
  665. $table = array();
  666. foreach ($users as $user) {
  667. $data = array(
  668. 'lastname' => ($anonymous ? '***' : $user[1]),
  669. 'firstname' => ($anonymous ? '***' : $user[2]),
  670. 'username' => ($anonymous ? '***' : $user[3]),
  671. );
  672. //Get questions by user
  673. $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
  674. FROM $c_survey_answer sa
  675. INNER JOIN $c_survey_question sq
  676. ON sq.question_id = sa.question_id
  677. LEFT JOIN $c_survey_question_option sqo
  678. ON
  679. sqo.c_id = sa.c_id AND
  680. sqo.question_id = sq.question_id AND
  681. sqo.question_option_id = sa.option_id AND
  682. sqo.survey_id = sq.survey_id
  683. WHERE
  684. sa.survey_id = %d AND
  685. sa.c_id = %d AND
  686. sa.user = %d
  687. "; //. $where_survey;
  688. $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
  689. $result = Database::query($sql_query);
  690. $user_questions = array();
  691. while ($row = Database::fetch_array($result)) {
  692. $user_questions[$row['question_id']] = $row;
  693. }
  694. //Match course lessons with user progress
  695. foreach ($questions as $question_id => $question) {
  696. $option_text = 'option_text';
  697. if ($user_questions[$question_id]['type'] == 'open') {
  698. $option_text = 'option_id';
  699. }
  700. $data[$question_id] = $user_questions[$question_id][$option_text];
  701. }
  702. $table[] = $data;
  703. }
  704. return $table;
  705. }
  706. /**
  707. * Gets the progress of the given session
  708. * @param int $sessionId
  709. * @param int $courseId
  710. * @param array options order and limit keys
  711. *
  712. * @return array table with user name, lp name, progress
  713. */
  714. public static function get_session_progress($sessionId, $courseId, $date_from, $date_to, $options)
  715. {
  716. $sessionId = intval($sessionId);
  717. $getAllSessions = false;
  718. if (empty($sessionId)) {
  719. $sessionId = 0;
  720. $getAllSessions = true;
  721. }
  722. //tables
  723. $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  724. $user = Database::get_main_table(TABLE_MAIN_USER);
  725. $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
  726. $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
  727. $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
  728. $wiki = Database::get_course_table(TABLE_WIKI);
  729. $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
  730. $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
  731. $course = api_get_course_info_by_id($courseId);
  732. $where = " WHERE c_id = '%s' AND s.status <> 2 ";
  733. $limit = null;
  734. if (!empty($options['limit'])) {
  735. $limit = " LIMIT " . $options['limit'];
  736. }
  737. if (!empty($options['where'])) {
  738. $where .= ' '.$options['where'];
  739. }
  740. $order = null;
  741. if (!empty($options['order'])) {
  742. $order = " ORDER BY " . $options['order'];
  743. }
  744. //TODO, fix create report without session
  745. $queryVariables = array($course['real_id']);
  746. if (!empty($sessionId)) {
  747. $where .= ' AND session_id = %s';
  748. $queryVariables[] = $sessionId;
  749. $sql = "SELECT
  750. u.user_id, u.lastname, u.firstname, u.username,
  751. u.email, s.c_id, s.session_id
  752. FROM $session_course_user s
  753. INNER JOIN $user u
  754. ON u.user_id = s.user_id
  755. $where $order $limit";
  756. } else {
  757. $sql = "SELECT
  758. u.user_id, u.lastname, u.firstname, u.username,
  759. u.email, s.c_id, s.session_id
  760. FROM $session_course_user s
  761. INNER JOIN $user u ON u.user_id = s.user_id
  762. $where $order $limit";
  763. }
  764. $sql_query = vsprintf($sql, $queryVariables);
  765. $rs = Database::query($sql_query);
  766. while ($user = Database::fetch_array($rs)) {
  767. $users[$user['user_id']] = $user;
  768. }
  769. /**
  770. * Lessons
  771. */
  772. $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s "; //AND session_id = %s
  773. $sql_query = sprintf($sql, $course['real_id']);
  774. $result = Database::query($sql_query);
  775. $arrLesson = array(array());
  776. while ($row = Database::fetch_array($result)) {
  777. if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
  778. $arrLesson[$row['session_id']]['lessons_total'] = 1;
  779. } else {
  780. $arrLesson[$row['session_id']]['lessons_total'] ++;
  781. }
  782. }
  783. /**
  784. * Exercises
  785. */
  786. $exercises = ExerciseLib::get_all_exercises($course, $sessionId, false, '', $getAllSessions);
  787. $exercises_total = count($exercises);
  788. /**
  789. * Assignments
  790. */
  791. //total
  792. if ($getAllSessions) {
  793. $sql = "SELECT count(w.id) as count
  794. FROM $workTable w
  795. LEFT JOIN $workTableAssignment a
  796. ON (a.publication_id = w.id AND a.c_id = w.c_id)
  797. WHERE w.c_id = %s
  798. AND parent_id = 0
  799. AND active IN (1, 0)";
  800. } else {
  801. $sql = "SELECT count(w.id) as count
  802. FROM $workTable w
  803. LEFT JOIN $workTableAssignment a
  804. ON (a.publication_id = w.id AND a.c_id = w.c_id)
  805. WHERE w.c_id = %s
  806. AND parent_id = 0
  807. AND active IN (1, 0)
  808. AND session_id = %s";
  809. }
  810. $sql_query = sprintf($sql, $course['real_id'], $sessionId);
  811. $result = Database::query($sql_query);
  812. $row = Database::fetch_array($result);
  813. $assignments_total = $row['count'];
  814. /**
  815. * Wiki
  816. */
  817. if ($getAllSessions) {
  818. $sql = "SELECT count(distinct page_id) as count FROM $wiki
  819. WHERE c_id = %s";
  820. } else {
  821. $sql = "SELECT count(distinct page_id) as count FROM $wiki
  822. WHERE c_id = %s and session_id = %s";
  823. }
  824. $sql_query = sprintf($sql, $course['real_id'], $sessionId);
  825. $result = Database::query($sql_query);
  826. $row = Database::fetch_array($result);
  827. $wiki_total = $row['count'];
  828. /**
  829. * Surveys
  830. */
  831. $survey_user_list = array();
  832. $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
  833. $surveys_total = count($survey_list);
  834. foreach ($survey_list as $survey) {
  835. $user_list = SurveyManager::get_people_who_filled_survey(
  836. $survey['survey_id'],
  837. false,
  838. $course['real_id']
  839. );
  840. foreach ($user_list as $user_id) {
  841. isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id] ++ : $survey_user_list[$user_id] = 1;
  842. }
  843. }
  844. /**
  845. * Forums
  846. */
  847. $forums_total = CourseManager::getCountForum(
  848. $course['real_id'],
  849. $sessionId,
  850. $getAllSessions
  851. );
  852. //process table info
  853. foreach ($users as $user) {
  854. //Course description
  855. $sql = "SELECT count(*) as count
  856. FROM $table_stats_access
  857. WHERE access_tool = 'course_description'
  858. AND c_id = '%s'
  859. AND access_session_id = %s
  860. AND access_user_id = %s ";
  861. $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
  862. $result = Database::query($sql_query);
  863. $row = Database::fetch_array($result);
  864. $course_description_progress = ($row['count'] > 0) ? 100 : 0;
  865. if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
  866. $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
  867. } else {
  868. $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
  869. }
  870. //Lessons
  871. //TODO: Lessons done and left is calculated by progress per item in lesson, maybe we should calculate it only per completed lesson?
  872. $lessons_progress = Tracking::get_avg_student_progress(
  873. $user['user_id'],
  874. $course['code'],
  875. array(),
  876. $user['id_session']
  877. );
  878. $lessons_done = ($lessons_progress * $lessons_total) / 100;
  879. $lessons_left = $lessons_total - $lessons_done;
  880. //Exercises
  881. $exercises_progress = str_replace('%', '', Tracking::get_exercise_student_progress($exercises, $user['user_id'], $course['real_id'], $user['id_session']));
  882. $exercises_done = round(($exercises_progress * $exercises_total) / 100);
  883. $exercises_left = $exercises_total - $exercises_done;
  884. //Assignments
  885. $assignments_done = Tracking::count_student_assignments($user['user_id'], $course['code'], $user['id_session']);
  886. $assignments_left = $assignments_total - $assignments_done;
  887. if (!empty($assignments_total)) {
  888. $assignments_progress = round((( $assignments_done * 100 ) / $assignments_total), 2);
  889. } else {
  890. $assignments_progress = 0;
  891. }
  892. //Wiki
  893. //total revisions per user
  894. $sql = "SELECT count(*) as count
  895. FROM $wiki
  896. WHERE c_id = %s and session_id = %s and user_id = %s";
  897. $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
  898. $result = Database::query($sql_query);
  899. $row = Database::fetch_array($result);
  900. $wiki_revisions = $row['count'];
  901. //count visited wiki pages
  902. $sql = "SELECT count(distinct default_value) as count
  903. FROM $table_stats_default
  904. WHERE
  905. default_user_id = %s AND
  906. default_event_type = 'wiki_page_view' AND
  907. default_value_type = 'wiki_page_id' AND
  908. c_id = %s
  909. ";
  910. $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
  911. $result = Database::query($sql_query);
  912. $row = Database::fetch_array($result);
  913. $wiki_read = $row['count'];
  914. $wiki_unread = $wiki_total - $wiki_read;
  915. if (!empty($wiki_total)) {
  916. $wiki_progress = round((( $wiki_read * 100 ) / $wiki_total), 2);
  917. } else {
  918. $wiki_progress = 0;
  919. }
  920. //Surveys
  921. $surveys_done = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0);
  922. $surveys_left = $surveys_total - $surveys_done;
  923. if (!empty($surveys_total)) {
  924. $surveys_progress = round((( $surveys_done * 100 ) / $surveys_total), 2);
  925. } else {
  926. $surveys_progress = 0;
  927. }
  928. //Forums
  929. $forums_done = CourseManager::getCountForumPerUser(
  930. $user['user_id'],
  931. $course['real_id'],
  932. $user['id_session']
  933. );
  934. $forums_left = $forums_total - $forums_done;
  935. if (!empty($forums_total)) {
  936. $forums_progress = round((( $forums_done * 100 ) / $forums_total), 2);
  937. } else {
  938. $forums_progress = 0;
  939. }
  940. //Overall Total
  941. $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
  942. $link = '<a href="' . api_get_path(WEB_CODE_PATH) . 'mySpace/myStudents.php?student=' . $user[0] . '&details=true&course=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
  943. $linkForum = '<a href="' . api_get_path(WEB_CODE_PATH) . 'forum/index.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
  944. $linkWork = '<a href="' . api_get_path(WEB_CODE_PATH) . 'work/work.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
  945. $linkWiki = '<a href="' . api_get_path(WEB_CODE_PATH) . 'wiki/index.php?cidReq=' . $course['code'] . '&session_id=' . $user['id_session'] . '&action=statistics"> %s </a>';
  946. $linkSurvey = '<a href="' . api_get_path(WEB_CODE_PATH) . 'survey/survey_list.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
  947. $table[] = array(
  948. 'lastname' => $user[1],
  949. 'firstname' => $user[2],
  950. 'username' => $user[3],
  951. #'profile' => '',
  952. 'total' => round($overall_total, 2) . '%',
  953. 'courses' => sprintf($link, $course_description_progress . '%'),
  954. 'lessons' => sprintf($link, $lessons_progress . '%'),
  955. 'exercises' => sprintf($link, $exercises_progress . '%'),
  956. 'forums' => sprintf($link, $forums_progress . '%'),
  957. 'homeworks' => sprintf($link, $assignments_progress . '%'),
  958. 'wikis' => sprintf($link, $wiki_progress . '%'),
  959. 'surveys' => sprintf($link, $surveys_progress . '%'),
  960. //course description
  961. 'course_description_progress' => $course_description_progress . '%',
  962. //lessons
  963. 'lessons_total' => sprintf($link, $lessons_total),
  964. 'lessons_done' => sprintf($link, $lessons_done),
  965. 'lessons_left' => sprintf($link, $lessons_left),
  966. 'lessons_progress' => sprintf($link, $lessons_progress . '%'),
  967. //exercises
  968. 'exercises_total' => sprintf($link, $exercises_total),
  969. 'exercises_done' => sprintf($link, $exercises_done),
  970. 'exercises_left' => sprintf($link, $exercises_left),
  971. 'exercises_progress' => sprintf($link, $exercises_progress . '%'),
  972. //forums
  973. 'forums_total' => sprintf($linkForum, $forums_total),
  974. 'forums_done' => sprintf($linkForum, $forums_done),
  975. 'forums_left' => sprintf($linkForum, $forums_left),
  976. 'forums_progress' => sprintf($linkForum, $forums_progress . '%'),
  977. //assignments
  978. 'assignments_total' => sprintf($linkWork, $assignments_total),
  979. 'assignments_done' => sprintf($linkWork, $assignments_done),
  980. 'assignments_left' => sprintf($linkWork, $assignments_left),
  981. 'assignments_progress' => sprintf($linkWork, $assignments_progress . '%'),
  982. //wiki
  983. 'wiki_total' => sprintf($linkWiki, $wiki_total),
  984. 'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
  985. 'wiki_read' => sprintf($linkWiki, $wiki_read),
  986. 'wiki_unread' => sprintf($linkWiki, $wiki_unread),
  987. 'wiki_progress' => sprintf($linkWiki, $wiki_progress . '%'),
  988. //survey
  989. 'surveys_total' => sprintf($linkSurvey, $surveys_total),
  990. 'surveys_done' => sprintf($linkSurvey, $surveys_done),
  991. 'surveys_left' => sprintf($linkSurvey, $surveys_left),
  992. 'surveys_progress' => sprintf($linkSurvey, $surveys_progress . '%'),
  993. );
  994. }
  995. return $table;
  996. }
  997. /**
  998. * @return int
  999. */
  1000. public static function get_number_of_tracking_access_overview()
  1001. {
  1002. // database table definition
  1003. $track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
  1004. return Database::count_rows($track_e_course_access);
  1005. }
  1006. /**
  1007. * Get the ip, total of clicks, login date and time logged in for all user, in one session
  1008. * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
  1009. *
  1010. * @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
  1011. * @version 1.9.6
  1012. */
  1013. public static function get_user_data_access_tracking_overview(
  1014. $sessionId,
  1015. $courseId,
  1016. $studentId = 0,
  1017. $profile = '',
  1018. $date_from = '',
  1019. $date_to = '',
  1020. $options
  1021. ) {
  1022. //escaping variables
  1023. $sessionId = intval($sessionId);
  1024. $courseId = intval($courseId);
  1025. $studentId = intval($studentId);
  1026. $profile = intval($profile);
  1027. $date_from = Database::escape_string($date_from);
  1028. $date_to = Database::escape_string($date_to);
  1029. // database table definition
  1030. $user = Database :: get_main_table(TABLE_MAIN_USER);
  1031. $course = Database :: get_main_table(TABLE_MAIN_COURSE);
  1032. $track_e_login = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
  1033. $track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
  1034. $sessionTable = Database :: get_main_table(TABLE_MAIN_SESSION);
  1035. global $export_csv;
  1036. if ($export_csv) {
  1037. $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
  1038. } else {
  1039. $is_western_name_order = api_is_western_name_order();
  1040. }
  1041. $where = null;
  1042. if (isset($sessionId) && !empty($sessionId)) {
  1043. $where = sprintf(" WHERE a.session_id = %d", $sessionId);
  1044. }
  1045. if (isset($courseId) && !empty($courseId)) {
  1046. $where .= sprintf(" AND c.id = %d", $courseId);
  1047. }
  1048. if (isset($studentId) && !empty($studentId)) {
  1049. $where .= sprintf(" AND u.user_id = %d", $studentId);
  1050. }
  1051. if (isset($profile) && !empty($profile)) {
  1052. $where .= sprintf(" AND u.status = %d", $profile);
  1053. }
  1054. if (!empty($date_to) && !empty($date_from)) {
  1055. $where .= sprintf(
  1056. " AND a.login_course_date >= '%s 00:00:00'
  1057. AND a.login_course_date <= '%s 23:59:59'",
  1058. $date_from,
  1059. $date_to
  1060. );
  1061. }
  1062. $limit = null;
  1063. if (!empty($options['limit'])) {
  1064. $limit = " LIMIT " . $options['limit'];
  1065. }
  1066. if (!empty($options['where'])) {
  1067. $where .= ' '.$options['where'];
  1068. }
  1069. $order = null;
  1070. if (!empty($options['order'])) {
  1071. $order = " ORDER BY " . $options['order'];
  1072. }
  1073. //TODO add course name
  1074. $sql = "SELECT
  1075. a.login_course_date ,
  1076. u.username ,
  1077. " . ($is_western_name_order ? "
  1078. u.firstname,
  1079. u.lastname,
  1080. " : "
  1081. u.lastname,
  1082. u.firstname,
  1083. ") . "
  1084. a.logout_course_date,
  1085. a.counter,
  1086. c.title,
  1087. c.code,
  1088. u.user_id,
  1089. a.session_id
  1090. FROM $track_e_course_access a
  1091. INNER JOIN $user u ON a.user_id = u.user_id
  1092. INNER JOIN $course c ON a.c_id = c.id
  1093. $where $order $limit";
  1094. $result = Database::query(sprintf($sql, $sessionId, $courseId));
  1095. $data = array();
  1096. while ($user = Database::fetch_assoc($result)) {
  1097. $data[] = $user;
  1098. }
  1099. //foreach
  1100. foreach ($data as $key => $info) {
  1101. $sql = "SELECT
  1102. name
  1103. FROM $sessionTable
  1104. WHERE
  1105. id = {$info['session_id']}";
  1106. $result = Database::query($sql);
  1107. $session = Database::fetch_assoc($result);
  1108. // building array to display
  1109. $return[] = array(
  1110. 'user_id' => $info['user_id'],
  1111. 'logindate' => $info['login_course_date'],
  1112. 'username' => $info['username'],
  1113. 'firstname' => $info['firstname'],
  1114. 'lastname' => $info['lastname'],
  1115. 'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
  1116. 'ip' => '',
  1117. 'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
  1118. 'session' => $session['name']
  1119. );
  1120. }
  1121. foreach ($return as $key => $info) {
  1122. //Search for ip, we do less querys if we iterate the final array
  1123. $sql = sprintf("SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date < '%s' ORDER BY login_date DESC LIMIT 1", $info['user_id'], $info['logindate']); //TODO add select by user too
  1124. $result = Database::query($sql);
  1125. $ip = Database::fetch_assoc($result);
  1126. //if no ip founded, we search the closest higher ip
  1127. if (empty($ip['user_ip'])) {
  1128. $sql = sprintf("SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date > '%s' ORDER BY login_date ASC LIMIT 1", $info['user_id'], $info['logindate']); //TODO add select by user too
  1129. $result = Database::query($sql);
  1130. $ip = Database::fetch_assoc($result);
  1131. }
  1132. #add ip to final array
  1133. $return[$key]['ip'] = $ip['user_ip'];
  1134. }
  1135. return $return;
  1136. }
  1137. /**
  1138. * Creates a new course code based in given code
  1139. *
  1140. * @param string $session_name
  1141. * <code>
  1142. * $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
  1143. * if the course code doest not exist in the DB the same course code will be returned
  1144. * </code>
  1145. * @return string wanted unused code
  1146. */
  1147. public static function generateNextSessionName($session_name)
  1148. {
  1149. $session_name_ok = !self::session_name_exists($session_name);
  1150. if (!$session_name_ok) {
  1151. $table = Database::get_main_table(TABLE_MAIN_SESSION);
  1152. $session_name = Database::escape_string($session_name);
  1153. $sql = "SELECT count(*) as count FROM $table
  1154. WHERE name LIKE '$session_name%'";
  1155. $result = Database::query($sql);
  1156. if (Database::num_rows($result) > 0) {
  1157. $row = Database::fetch_array($result);
  1158. $count = $row['count'] + 1;
  1159. $session_name = $session_name . '_' . $count;
  1160. $result = self::session_name_exists($session_name);
  1161. if (!$result) {
  1162. return $session_name;
  1163. }
  1164. }
  1165. return false;
  1166. }
  1167. return $session_name;
  1168. }
  1169. /**
  1170. * Edit a session
  1171. * @author Carlos Vargas from existing code
  1172. * @param integer $id Session primary key
  1173. * @param string $name
  1174. * @param string $startDate
  1175. * @param string $endDate
  1176. * @param string $displayStartDate
  1177. * @param string $displayEndDate
  1178. * @param string $coachStartDate
  1179. * @param string $coachEndDate
  1180. * @param integer $coachId
  1181. * @param integer $sessionCategoryId
  1182. * @param int $visibility
  1183. * @param string $description
  1184. * @param bool $showDescription
  1185. * @param int $duration
  1186. * @param array $extraFields
  1187. * @param int $sessionAdminId
  1188. * @param boolean $sendSubscriptionNotification Optional.
  1189. * Whether send a mail notification to users being subscribed
  1190. * @return mixed
  1191. */
  1192. public static function edit_session(
  1193. $id,
  1194. $name,
  1195. $startDate,
  1196. $endDate,
  1197. $displayStartDate,
  1198. $displayEndDate,
  1199. $coachStartDate,
  1200. $coachEndDate,
  1201. $coachId,
  1202. $sessionCategoryId,
  1203. $visibility,
  1204. $description = null,
  1205. $showDescription = 0,
  1206. $duration = null,
  1207. $extraFields = array(),
  1208. $sessionAdminId = 0,
  1209. $sendSubscriptionNotification = false
  1210. ) {
  1211. $name = trim(stripslashes($name));
  1212. $coachId = intval($coachId);
  1213. $sessionCategoryId = intval($sessionCategoryId);
  1214. $visibility = intval($visibility);
  1215. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1216. if (empty($name)) {
  1217. Display::return_message(get_lang('SessionNameIsRequired'), 'warning');
  1218. return false;
  1219. } elseif (empty($coachId)) {
  1220. Display::return_message(get_lang('CoachIsRequired'), 'warning');
  1221. return false;
  1222. } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i')) {
  1223. Display::return_message(get_lang('InvalidStartDate'), 'warning');
  1224. return false;
  1225. } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i')) {
  1226. Display::return_message(get_lang('InvalidEndDate'), 'warning');
  1227. return false;
  1228. } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
  1229. Display::return_message(get_lang('StartDateShouldBeBeforeEndDate'), 'warning');
  1230. return false;
  1231. } else {
  1232. $sql = "SELECT id FROM $tbl_session WHERE name='" . Database::escape_string($name) . "'";
  1233. $rs = Database::query($sql);
  1234. $exists = false;
  1235. while ($row = Database::fetch_array($rs)) {
  1236. if ($row['id'] != $id) {
  1237. $exists = true;
  1238. }
  1239. }
  1240. if ($exists) {
  1241. Display::return_message(get_lang('SessionNameAlreadyExists'), 'warning');
  1242. return false;
  1243. } else {
  1244. $values = [
  1245. 'name' => $name,
  1246. 'duration' => $duration,
  1247. 'id_coach' => $coachId,
  1248. 'description'=> $description,
  1249. 'show_description' => intval($showDescription),
  1250. 'visibility' => $visibility,
  1251. 'send_subscription_notification' => $sendSubscriptionNotification
  1252. ];
  1253. if (!empty($sessionAdminId)) {
  1254. $values['session_admin_id'] = $sessionAdminId;
  1255. }
  1256. if (!empty($startDate)) {
  1257. $values['access_start_date'] = api_get_utc_datetime($startDate);
  1258. }
  1259. if (!empty($endDate)) {
  1260. $values['access_end_date'] = api_get_utc_datetime($endDate);
  1261. }
  1262. if (!empty($displayStartDate)) {
  1263. $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
  1264. }
  1265. if (!empty($displayEndDate)) {
  1266. $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
  1267. }
  1268. if (!empty($coachStartDate)) {
  1269. $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
  1270. }
  1271. if (!empty($coachEndDate)) {
  1272. $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
  1273. }
  1274. if (!empty($sessionCategoryId)) {
  1275. $values['session_category_id'] = $sessionCategoryId;
  1276. }
  1277. Database::update($tbl_session, $values, array(
  1278. 'id = ?' => $id
  1279. ));
  1280. if (!empty($extraFields)) {
  1281. $extraFields['item_id'] = $id;
  1282. $sessionFieldValue = new ExtraFieldValue('session');
  1283. $sessionFieldValue->saveFieldValues($extraFields);
  1284. }
  1285. return $id;
  1286. }
  1287. }
  1288. }
  1289. /**
  1290. * Delete session
  1291. * @author Carlos Vargas from existing code
  1292. * @param array $id_checked an array to delete sessions
  1293. * @param boolean $from_ws optional, true if the function is called
  1294. * by a webservice, false otherwise.
  1295. * @return void Nothing, or false on error
  1296. * */
  1297. public static function delete($id_checked, $from_ws = false)
  1298. {
  1299. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1300. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  1301. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1302. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  1303. $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  1304. $tbl_item_properties = Database::get_course_table(TABLE_ITEM_PROPERTY);
  1305. $em = Database::getManager();
  1306. $userId = api_get_user_id();
  1307. if (is_array($id_checked)) {
  1308. foreach ($id_checked as $sessionId) {
  1309. self::delete($sessionId);
  1310. }
  1311. } else {
  1312. $id_checked = intval($id_checked);
  1313. }
  1314. if (SessionManager::allowed($id_checked) && !$from_ws) {
  1315. $qb = $em
  1316. ->createQuery('
  1317. SELECT s.sessionAdminId FROM ChamiloCoreBundle:Session s
  1318. WHERE s.id = ?1
  1319. ')
  1320. ->setParameter(1, $id_checked);
  1321. $res = $qb->getSingleScalarResult();
  1322. if ($res != $userId && !api_is_platform_admin()) {
  1323. api_not_allowed(true);
  1324. }
  1325. }
  1326. // Delete documents inside a session
  1327. $courses = SessionManager::getCoursesInSession($id_checked);
  1328. foreach ($courses as $courseId) {
  1329. $courseInfo = api_get_course_info_by_id($courseId);
  1330. DocumentManager::deleteDocumentsFromSession($courseInfo, $id_checked);
  1331. }
  1332. Database::query("DELETE FROM $tbl_session_rel_course WHERE session_id IN($id_checked)");
  1333. Database::query("DELETE FROM $tbl_session_rel_course_rel_user WHERE session_id IN($id_checked)");
  1334. Database::query("DELETE FROM $tbl_session_rel_user WHERE session_id IN($id_checked)");
  1335. Database::query("DELETE FROM $tbl_item_properties WHERE session_id IN ($id_checked)");
  1336. Database::query("DELETE FROM $tbl_url_session WHERE session_id IN($id_checked)");
  1337. Database::query("DELETE FROM $tbl_session WHERE id IN ($id_checked)");
  1338. $extraFieldValue = new ExtraFieldValue('session');
  1339. $extraFieldValue->deleteValuesByItem($id_checked);
  1340. /** @var \Chamilo\CoreBundle\Entity\Repository\SequenceRepository $repo */
  1341. $repo = Database::getManager()->getRepository('ChamiloCoreBundle:SequenceResource');
  1342. $repo->deleteResource(
  1343. $id_checked,
  1344. \Chamilo\CoreBundle\Entity\SequenceResource::SESSION_TYPE
  1345. );
  1346. // Add event to system log
  1347. Event::addEvent(
  1348. LOG_SESSION_DELETE,
  1349. LOG_SESSION_ID,
  1350. $id_checked,
  1351. api_get_utc_datetime(),
  1352. $userId
  1353. );
  1354. }
  1355. /**
  1356. * @param int $id_promotion
  1357. *
  1358. * @return bool
  1359. */
  1360. public static function clear_session_ref_promotion($id_promotion)
  1361. {
  1362. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1363. $id_promotion = intval($id_promotion);
  1364. $sql = "UPDATE $tbl_session SET promotion_id=0
  1365. WHERE promotion_id = $id_promotion";
  1366. if (Database::query($sql)) {
  1367. return true;
  1368. } else {
  1369. return false;
  1370. }
  1371. }
  1372. /**
  1373. * Subscribes students to the given session and optionally (default) unsubscribes previous users
  1374. *
  1375. * @author Carlos Vargas from existing code
  1376. * @author Julio Montoya. Cleaning code.
  1377. * @param int $id_session
  1378. * @param array $user_list
  1379. * @param int $session_visibility
  1380. * @param bool $empty_users
  1381. * @return bool
  1382. */
  1383. public static function suscribe_users_to_session(
  1384. $id_session,
  1385. $user_list,
  1386. $session_visibility = SESSION_VISIBLE_READ_ONLY,
  1387. $empty_users = true
  1388. ) {
  1389. if ($id_session != strval(intval($id_session))) {
  1390. return false;
  1391. }
  1392. foreach ($user_list as $intUser) {
  1393. if ($intUser != strval(intval($intUser))) {
  1394. return false;
  1395. }
  1396. }
  1397. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  1398. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1399. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  1400. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1401. $entityManager = Database::getManager();
  1402. $session = $entityManager->find('ChamiloCoreBundle:Session', $id_session);
  1403. // from function parameter
  1404. if (empty($session_visibility)) {
  1405. $session_visibility = $session->getVisibility();
  1406. //default status loaded if empty
  1407. if (empty($session_visibility))
  1408. $session_visibility = SESSION_VISIBLE_READ_ONLY; // by default readonly 1
  1409. } else {
  1410. if (!in_array($session_visibility, array(SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_INVISIBLE))) {
  1411. $session_visibility = SESSION_VISIBLE_READ_ONLY;
  1412. }
  1413. }
  1414. $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
  1415. WHERE session_id = $id_session AND status = 0";
  1416. $result = Database::query($sql);
  1417. $existingUsers = array();
  1418. while ($row = Database::fetch_array($result)) {
  1419. $existingUsers[] = $row['user_id'];
  1420. }
  1421. $sql = "SELECT c_id FROM $tbl_session_rel_course
  1422. WHERE session_id = $id_session";
  1423. $result = Database::query($sql);
  1424. $course_list = array();
  1425. while ($row = Database::fetch_array($result)) {
  1426. $course_list[] = $row['c_id'];
  1427. }
  1428. if (
  1429. $session->getSendSubscriptionNotification() &&
  1430. is_array($user_list)
  1431. ) {
  1432. // Sending emails only
  1433. foreach ($user_list as $user_id) {
  1434. if (in_array($user_id, $existingUsers)) {
  1435. continue;
  1436. }
  1437. $subject = Container::getTemplating()->render(
  1438. '@template_style/mail/subject_subscription_to_session_confirmation.html.twig'
  1439. );
  1440. $user_info = api_get_user_info($user_id);
  1441. $content = Container::getTemplating()->render(
  1442. '@template_style/mail/content_subscription_to_session_confirmation.html.twig',
  1443. [
  1444. 'complete_name' => stripslashes($user_info['complete_name']),
  1445. 'session_name' => $session->getName(),
  1446. 'session_coach' => $session->getGeneralCoach()->getCompleteName()
  1447. ]
  1448. );
  1449. api_mail_html(
  1450. $user_info['complete_name'],
  1451. $user_info['mail'],
  1452. $subject,
  1453. $content,
  1454. api_get_person_name(
  1455. api_get_setting('admin.administrator_name'),
  1456. api_get_setting('admin.administrator_surname')
  1457. ),
  1458. api_get_setting('admin.administrator_email')
  1459. );
  1460. }
  1461. }
  1462. foreach ($course_list as $courseId) {
  1463. // for each course in the session
  1464. $nbr_users = 0;
  1465. $courseId = intval($courseId);
  1466. $sql = "SELECT DISTINCT user_id
  1467. FROM $tbl_session_rel_course_rel_user
  1468. WHERE
  1469. session_id = $id_session AND
  1470. c_id = $courseId AND
  1471. status = 0
  1472. ";
  1473. $result = Database::query($sql);
  1474. $existingUsers = array();
  1475. while ($row = Database::fetch_array($result)) {
  1476. $existingUsers[] = $row['user_id'];
  1477. }
  1478. // Delete existing users
  1479. if ($empty_users) {
  1480. foreach ($existingUsers as $existing_user) {
  1481. if (!in_array($existing_user, $user_list)) {
  1482. $sql = "DELETE FROM $tbl_session_rel_course_rel_user
  1483. WHERE
  1484. session_id = $id_session AND
  1485. c_id = $courseId AND
  1486. user_id = $existing_user AND
  1487. status = 0 ";
  1488. $result = Database::query($sql);
  1489. Event::addEvent(
  1490. LOG_SESSION_DELETE_USER_COURSE,
  1491. LOG_USER_ID,
  1492. $existing_user,
  1493. api_get_utc_datetime(),
  1494. api_get_user_id(),
  1495. $courseId,
  1496. $id_session
  1497. );
  1498. if (Database::affected_rows($result)) {
  1499. $nbr_users--;
  1500. }
  1501. }
  1502. }
  1503. }
  1504. // Replace with this new function
  1505. // insert new users into session_rel_course_rel_user and ignore if they already exist
  1506. foreach ($user_list as $enreg_user) {
  1507. if (!in_array($enreg_user, $existingUsers)) {
  1508. $enreg_user = Database::escape_string($enreg_user);
  1509. $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility, status)
  1510. VALUES($id_session, $courseId, $enreg_user, $session_visibility, 0)";
  1511. $result = Database::query($sql);
  1512. Event::addEvent(
  1513. LOG_SESSION_ADD_USER_COURSE,
  1514. LOG_USER_ID,
  1515. $enreg_user,
  1516. api_get_utc_datetime(),
  1517. api_get_user_id(),
  1518. $courseId,
  1519. $id_session
  1520. );
  1521. if (Database::affected_rows($result)) {
  1522. $nbr_users++;
  1523. }
  1524. }
  1525. }
  1526. // Count users in this session-course relation
  1527. $sql = "SELECT COUNT(user_id) as nbUsers
  1528. FROM $tbl_session_rel_course_rel_user
  1529. WHERE session_id = $id_session AND c_id = $courseId AND status<>2";
  1530. $rs = Database::query($sql);
  1531. list($nbr_users) = Database::fetch_array($rs);
  1532. // update the session-course relation to add the users total
  1533. $sql = "UPDATE $tbl_session_rel_course SET nbr_users = $nbr_users
  1534. WHERE session_id = $id_session AND c_id = $courseId";
  1535. Database::query($sql);
  1536. }
  1537. // Delete users from the session
  1538. if ($empty_users === true) {
  1539. $sql = "DELETE FROM $tbl_session_rel_user
  1540. WHERE session_id = $id_session AND relation_type<>" . SESSION_RELATION_TYPE_RRHH . "";
  1541. Database::query($sql);
  1542. }
  1543. // Insert missing users into session
  1544. $nbr_users = 0;
  1545. foreach ($user_list as $enreg_user) {
  1546. $enreg_user = Database::escape_string($enreg_user);
  1547. $nbr_users++;
  1548. $sql = "INSERT IGNORE INTO $tbl_session_rel_user (relation_type, session_id, user_id, registered_at)
  1549. VALUES (0, $id_session, $enreg_user, '" . api_get_utc_datetime() . "')";
  1550. Database::query($sql);
  1551. }
  1552. // update number of users in the session
  1553. $nbr_users = count($user_list);
  1554. if ($empty_users) {
  1555. // update number of users in the session
  1556. $sql = "UPDATE $tbl_session SET nbr_users= $nbr_users
  1557. WHERE id = $id_session ";
  1558. Database::query($sql);
  1559. } else {
  1560. $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + $nbr_users
  1561. WHERE id = $id_session";
  1562. Database::query($sql);
  1563. }
  1564. }
  1565. /**
  1566. * Returns user list of the current users subscribed in the course-session
  1567. * @param int $sessionId
  1568. * @param array $courseInfo
  1569. * @param int $status
  1570. *
  1571. * @return array
  1572. */
  1573. public static function getUsersByCourseSession(
  1574. $sessionId,
  1575. $courseInfo,
  1576. $status = null
  1577. ) {
  1578. $sessionId = intval($sessionId);
  1579. $courseCode = $courseInfo['code'];
  1580. $courseId = $courseInfo['real_id'];
  1581. if (empty($sessionId) || empty($courseCode)) {
  1582. return array();
  1583. }
  1584. $statusCondition = null;
  1585. if (isset($status) && !is_null($status)) {
  1586. $status = intval($status);
  1587. $statusCondition = " AND status = $status";
  1588. }
  1589. $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1590. $sql = "SELECT DISTINCT user_id
  1591. FROM $table
  1592. WHERE
  1593. session_id = $sessionId AND
  1594. c_id = $courseId
  1595. $statusCondition
  1596. ";
  1597. $result = Database::query($sql);
  1598. $existingUsers = array();
  1599. while ($row = Database::fetch_array($result)) {
  1600. $existingUsers[] = $row['user_id'];
  1601. }
  1602. return $existingUsers;
  1603. }
  1604. /**
  1605. * Remove a list of users from a course-session
  1606. * @param array $userList
  1607. * @param int $sessionId
  1608. * @param array $courseInfo
  1609. * @param int $status
  1610. * @param bool $updateTotal
  1611. * @return bool
  1612. */
  1613. public static function removeUsersFromCourseSession(
  1614. $userList,
  1615. $sessionId,
  1616. $courseInfo,
  1617. $status = null,
  1618. $updateTotal = true
  1619. ) {
  1620. $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1621. $tableSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  1622. $sessionId = intval($sessionId);
  1623. if (empty($sessionId) || empty($userList) || empty($courseInfo)) {
  1624. return false;
  1625. }
  1626. is_array($courseInfo) ? $courseId = $courseInfo['real_id'] : $courseId = $courseInfo;
  1627. $statusCondition = null;
  1628. if (isset($status) && !is_null($status)) {
  1629. $status = intval($status);
  1630. $statusCondition = " AND status = $status";
  1631. }
  1632. foreach ($userList as $userId) {
  1633. $userId = intval($userId);
  1634. $sql = "DELETE FROM $table
  1635. WHERE
  1636. session_id = $sessionId AND
  1637. c_id = $courseId AND
  1638. user_id = $userId
  1639. $statusCondition
  1640. ";
  1641. Database::query($sql);
  1642. }
  1643. if ($updateTotal) {
  1644. // Count users in this session-course relation
  1645. $sql = "SELECT COUNT(user_id) as nbUsers
  1646. FROM $table
  1647. WHERE
  1648. session_id = $sessionId AND
  1649. c_id = $courseId AND
  1650. status <> 2";
  1651. $result = Database::query($sql);
  1652. list($userCount) = Database::fetch_array($result);
  1653. // update the session-course relation to add the users total
  1654. $sql = "UPDATE $tableSessionCourse
  1655. SET nbr_users = $userCount
  1656. WHERE
  1657. session_id = $sessionId AND
  1658. c_id = $courseId";
  1659. Database::query($sql);
  1660. }
  1661. }
  1662. /**
  1663. * Subscribe a user to an specific course inside a session.
  1664. *
  1665. * @param array $user_list
  1666. * @param int $session_id
  1667. * @param string $course_code
  1668. * @param int $session_visibility
  1669. * @param bool $removeUsersNotInList
  1670. * @return bool
  1671. */
  1672. public static function subscribe_users_to_session_course(
  1673. $user_list,
  1674. $session_id,
  1675. $course_code,
  1676. $session_visibility = SESSION_VISIBLE_READ_ONLY,
  1677. $removeUsersNotInList = false
  1678. ) {
  1679. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1680. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  1681. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1682. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  1683. if (empty($session_id) || empty($course_code)) {
  1684. return false;
  1685. }
  1686. $session_id = intval($session_id);
  1687. $course_code = Database::escape_string($course_code);
  1688. $courseInfo = api_get_course_info($course_code);
  1689. $courseId = $courseInfo['real_id'];
  1690. $session_visibility = intval($session_visibility);
  1691. if ($removeUsersNotInList) {
  1692. $currentUsers = self::getUsersByCourseSession($session_id, $courseInfo, 0);
  1693. if (!empty($user_list)) {
  1694. $userToDelete = array_diff($currentUsers, $user_list);
  1695. } else {
  1696. $userToDelete = $currentUsers;
  1697. }
  1698. if (!empty($userToDelete)) {
  1699. self::removeUsersFromCourseSession(
  1700. $userToDelete,
  1701. $session_id,
  1702. $courseInfo,
  1703. 0,
  1704. true
  1705. );
  1706. }
  1707. }
  1708. $nbr_users = 0;
  1709. foreach ($user_list as $enreg_user) {
  1710. $enreg_user = intval($enreg_user);
  1711. // Checking if user exists in session - course - user table.
  1712. $sql = "SELECT count(user_id) as count
  1713. FROM $tbl_session_rel_course_rel_user
  1714. WHERE
  1715. session_id = $session_id AND
  1716. c_id = $courseId and
  1717. user_id = $enreg_user ";
  1718. $result = Database::query($sql);
  1719. $count = 0;
  1720. if (Database::num_rows($result) > 0) {
  1721. $row = Database::fetch_array($result, 'ASSOC');
  1722. $count = $row['count'];
  1723. }
  1724. if ($count == 0) {
  1725. $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility)
  1726. VALUES ($session_id, $courseId, $enreg_user, $session_visibility)";
  1727. $result = Database::query($sql);
  1728. if (Database::affected_rows($result)) {
  1729. $nbr_users++;
  1730. }
  1731. }
  1732. // Checking if user exists in session - user table.
  1733. $sql = "SELECT count(user_id) as count
  1734. FROM $tbl_session_rel_user
  1735. WHERE session_id = $session_id AND user_id = $enreg_user ";
  1736. $result = Database::query($sql);
  1737. $count = 0;
  1738. if (Database::num_rows($result) > 0) {
  1739. $row = Database::fetch_array($result, 'ASSOC');
  1740. $count = $row['count'];
  1741. }
  1742. if (empty($count)) {
  1743. // If user is not registered to a session then add it.
  1744. $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, registered_at)
  1745. VALUES ($session_id, $enreg_user, '" . api_get_utc_datetime() . "')";
  1746. Database::query($sql);
  1747. $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + 1
  1748. WHERE id = $session_id ";
  1749. Database::query($sql);
  1750. }
  1751. }
  1752. // count users in this session-course relation
  1753. $sql = "SELECT COUNT(user_id) as nbUsers
  1754. FROM $tbl_session_rel_course_rel_user
  1755. WHERE session_id = $session_id AND c_id = $courseId AND status <> 2";
  1756. $rs = Database::query($sql);
  1757. list($nbr_users) = Database::fetch_array($rs);
  1758. // update the session-course relation to add the users total
  1759. $sql = "UPDATE $tbl_session_rel_course
  1760. SET nbr_users = $nbr_users
  1761. WHERE session_id = $session_id AND c_id = $courseId";
  1762. Database::query($sql);
  1763. }
  1764. /**
  1765. * Unsubscribe user from session
  1766. *
  1767. * @param int Session id
  1768. * @param int User id
  1769. * @return bool True in case of success, false in case of error
  1770. */
  1771. public static function unsubscribe_user_from_session($session_id, $user_id)
  1772. {
  1773. $session_id = (int) $session_id;
  1774. $user_id = (int) $user_id;
  1775. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1776. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  1777. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  1778. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1779. $delete_sql = "DELETE FROM $tbl_session_rel_user
  1780. WHERE
  1781. session_id = $session_id AND
  1782. user_id = $user_id AND
  1783. relation_type <> " . SESSION_RELATION_TYPE_RRHH . "";
  1784. $result = Database::query($delete_sql);
  1785. $return = Database::affected_rows($result);
  1786. // Update number of users
  1787. $sql = "UPDATE $tbl_session
  1788. SET nbr_users = nbr_users - $return
  1789. WHERE id = $session_id ";
  1790. Database::query($sql);
  1791. // Get the list of courses related to this session
  1792. $course_list = SessionManager::get_course_list_by_session_id($session_id);
  1793. if (!empty($course_list)) {
  1794. foreach ($course_list as $course) {
  1795. $courseId = $course['id'];
  1796. // Delete user from course
  1797. $sql = "DELETE FROM $tbl_session_rel_course_rel_user
  1798. WHERE session_id = $session_id AND c_id = $courseId AND user_id = $user_id";
  1799. $result = Database::query($sql);
  1800. Event::addEvent(
  1801. LOG_SESSION_DELETE_USER_COURSE,
  1802. LOG_USER_ID,
  1803. $user_id,
  1804. api_get_utc_datetime(),
  1805. api_get_user_id(),
  1806. $courseId,
  1807. $session_id
  1808. );
  1809. if (Database::affected_rows($result)) {
  1810. // Update number of users in this relation
  1811. $sql = "UPDATE $tbl_session_rel_course SET nbr_users = nbr_users - 1
  1812. WHERE session_id = $session_id AND c_id = $courseId";
  1813. Database::query($sql);
  1814. }
  1815. }
  1816. }
  1817. return true;
  1818. }
  1819. /**
  1820. * Subscribes courses to the given session and optionally (default)
  1821. * unsubscribes previous users
  1822. * @author Carlos Vargas from existing code
  1823. * @param int $sessionId
  1824. * @param array $courseList List of courses int ids
  1825. * @param bool $removeExistingCoursesWithUsers Whether to unsubscribe
  1826. * existing courses and users (true, default) or not (false)
  1827. * @param $copyEvaluation from base course to session course
  1828. * @return void Nothing, or false on error
  1829. * */
  1830. public static function add_courses_to_session(
  1831. $sessionId,
  1832. $courseList,
  1833. $removeExistingCoursesWithUsers = true,
  1834. $copyEvaluation = false
  1835. ) {
  1836. $sessionId = intval($sessionId);
  1837. if (empty($sessionId) || empty($courseList)) {
  1838. return false;
  1839. }
  1840. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1841. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1842. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  1843. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  1844. // Get list of courses subscribed to this session
  1845. $sql = "SELECT c_id
  1846. FROM $tbl_session_rel_course
  1847. WHERE session_id = $sessionId";
  1848. $rs = Database::query($sql);
  1849. $existingCourses = Database::store_result($rs);
  1850. $nbr_courses = count($existingCourses);
  1851. // Get list of users subscribed to this session
  1852. $sql = "SELECT user_id
  1853. FROM $tbl_session_rel_user
  1854. WHERE
  1855. session_id = $sessionId AND
  1856. relation_type<>" . SESSION_RELATION_TYPE_RRHH;
  1857. $result = Database::query($sql);
  1858. $user_list = Database::store_result($result);
  1859. // Remove existing courses from the session.
  1860. if ($removeExistingCoursesWithUsers === true && !empty($existingCourses)) {
  1861. foreach ($existingCourses as $existingCourse) {
  1862. if (!in_array($existingCourse['c_id'], $courseList)) {
  1863. $sql = "DELETE FROM $tbl_session_rel_course
  1864. WHERE
  1865. c_id = " . $existingCourse['c_id'] . " AND
  1866. session_id = $sessionId";
  1867. Database::query($sql);
  1868. $sql = "DELETE FROM $tbl_session_rel_course_rel_user
  1869. WHERE
  1870. c_id = ".$existingCourse['c_id']." AND
  1871. session_id = $sessionId";
  1872. Database::query($sql);
  1873. Event::addEvent(
  1874. LOG_SESSION_DELETE_COURSE,
  1875. LOG_COURSE_ID,
  1876. $existingCourse['c_id'],
  1877. api_get_utc_datetime(),
  1878. api_get_user_id(),
  1879. $existingCourse['c_id'],
  1880. $sessionId
  1881. );
  1882. CourseManager::remove_course_ranking(
  1883. $existingCourse['c_id'],
  1884. $sessionId
  1885. );
  1886. $nbr_courses--;
  1887. }
  1888. }
  1889. }
  1890. // Pass through the courses list we want to add to the session
  1891. foreach ($courseList as $courseId) {
  1892. $courseInfo = api_get_course_info_by_id($courseId);
  1893. // If course doesn't exists continue!
  1894. if (empty($courseInfo)) {
  1895. continue;
  1896. }
  1897. $exists = false;
  1898. // check if the course we want to add is already subscribed
  1899. foreach ($existingCourses as $existingCourse) {
  1900. if ($courseId == $existingCourse['c_id']) {
  1901. $exists = true;
  1902. }
  1903. }
  1904. if (!$exists) {
  1905. // Copy gradebook categories and links (from base course)
  1906. // to the new course session
  1907. if ($copyEvaluation) {
  1908. $cats = Category::load(null, null, $courseInfo['code']);
  1909. if (!empty($cats)) {
  1910. $categoryIdList = [];
  1911. /** @var Category $cat */
  1912. foreach ($cats as $cat) {
  1913. $categoryIdList[$cat->get_id()] = $cat->get_id();
  1914. }
  1915. $newCategoryIdList = [];
  1916. foreach ($cats as $cat) {
  1917. $links = $cat->get_links(null, false, $courseInfo['code'], 0);
  1918. $cat->set_session_id($sessionId);
  1919. $oldCategoryId= $cat->get_id();
  1920. $newId = $cat->add();
  1921. $newCategoryIdList[$oldCategoryId] = $newId;
  1922. $parentId = $cat->get_parent_id();
  1923. if (!empty($parentId)) {
  1924. $newParentId = $newCategoryIdList[$parentId];
  1925. $cat->set_parent_id($newParentId);
  1926. $cat->save();
  1927. }
  1928. /** @var AbstractLink $link */
  1929. foreach ($links as $link) {
  1930. $newCategoryId = $newCategoryIdList[$link->get_category_id()];
  1931. $link->set_category_id($newCategoryId);
  1932. $link->add();
  1933. }
  1934. }
  1935. // Create
  1936. DocumentManager::generateDefaultCertificate(
  1937. $courseInfo,
  1938. true,
  1939. $sessionId
  1940. );
  1941. }
  1942. }
  1943. // If the course isn't subscribed yet
  1944. $sql = "INSERT INTO $tbl_session_rel_course (session_id, c_id)
  1945. VALUES ($sessionId, $courseId)";
  1946. Database::query($sql);
  1947. Event::addEvent(
  1948. LOG_SESSION_ADD_COURSE,
  1949. LOG_COURSE_ID,
  1950. $courseId,
  1951. api_get_utc_datetime(),
  1952. api_get_user_id(),
  1953. $courseId,
  1954. $sessionId
  1955. );
  1956. // We add the current course in the existing courses array,
  1957. // to avoid adding another time the current course
  1958. $existingCourses[] = array('c_id' => $courseId);
  1959. $nbr_courses++;
  1960. // subscribe all the users from the session to this course inside the session
  1961. $nbr_users = 0;
  1962. foreach ($user_list as $enreg_user) {
  1963. $enreg_user_id = intval($enreg_user['user_id']);
  1964. $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id)
  1965. VALUES ($sessionId, $courseId, $enreg_user_id)";
  1966. $result = Database::query($sql);
  1967. Event::addEvent(
  1968. LOG_SESSION_ADD_USER_COURSE,
  1969. LOG_USER_ID,
  1970. $enreg_user_id,
  1971. api_get_utc_datetime(),
  1972. api_get_user_id(),
  1973. $courseId,
  1974. $sessionId
  1975. );
  1976. if (Database::affected_rows($result)) {
  1977. $nbr_users++;
  1978. }
  1979. }
  1980. $sql = "UPDATE $tbl_session_rel_course
  1981. SET nbr_users = $nbr_users
  1982. WHERE session_id = $sessionId AND c_id = $courseId";
  1983. Database::query($sql);
  1984. }
  1985. }
  1986. $sql = "UPDATE $tbl_session
  1987. SET nbr_courses = $nbr_courses
  1988. WHERE id = $sessionId";
  1989. Database::query($sql);
  1990. }
  1991. /**
  1992. * Unsubscribe course from a session
  1993. *
  1994. * @param int Session id
  1995. * @param int Course id
  1996. * @return bool True in case of success, false otherwise
  1997. */
  1998. public static function unsubscribe_course_from_session($session_id, $course_id)
  1999. {
  2000. $session_id = (int) $session_id;
  2001. $course_id = (int) $course_id;
  2002. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  2003. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  2004. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  2005. // Get course code
  2006. $course_code = CourseManager::get_course_code_from_course_id($course_id);
  2007. $course_id = intval($course_id);
  2008. if (empty($course_code)) {
  2009. return false;
  2010. }
  2011. // Unsubscribe course
  2012. $sql = "DELETE FROM $tbl_session_rel_course
  2013. WHERE c_id = $course_id AND session_id = $session_id";
  2014. $result = Database::query($sql);
  2015. $nb_affected = Database::affected_rows($result);
  2016. $sql = "DELETE FROM $tbl_session_rel_course_rel_user
  2017. WHERE c_id = $course_id AND session_id = $session_id";
  2018. Database::query($sql);
  2019. Event::addEvent(
  2020. LOG_SESSION_DELETE_COURSE,
  2021. LOG_COURSE_ID,
  2022. $course_id,
  2023. api_get_utc_datetime(),
  2024. api_get_user_id(),
  2025. $course_id,
  2026. $session_id
  2027. );
  2028. if ($nb_affected > 0) {
  2029. // Update number of courses in the session
  2030. $sql = "UPDATE $tbl_session SET nbr_courses= nbr_courses - $nb_affected
  2031. WHERE id = $session_id";
  2032. Database::query($sql);
  2033. return true;
  2034. } else {
  2035. return false;
  2036. }
  2037. }
  2038. /**
  2039. * Creates a new extra field for a given session
  2040. * @param string $variable Field's internal variable name
  2041. * @param int $fieldType Field's type
  2042. * @param string $displayText Field's language var name
  2043. * @return int new extra field id
  2044. */
  2045. public static function create_session_extra_field($variable, $fieldType, $displayText)
  2046. {
  2047. $extraField = new ExtraField('session');
  2048. $params = [
  2049. 'variable' => $variable,
  2050. 'field_type' => $fieldType,
  2051. 'display_text' => $displayText,
  2052. ];
  2053. return $extraField->save($params);
  2054. }
  2055. /**
  2056. * Update an extra field value for a given session
  2057. * @param integer Course ID
  2058. * @param string Field variable name
  2059. * @param string Field value
  2060. * @return boolean true if field updated, false otherwise
  2061. */
  2062. public static function update_session_extra_field_value($sessionId, $variable, $value = '')
  2063. {
  2064. $extraFieldValue = new ExtraFieldValue('session');
  2065. $params = [
  2066. 'item_id' => $sessionId,
  2067. 'variable' => $variable,
  2068. 'value' => $value,
  2069. ];
  2070. $extraFieldValue->save($params);
  2071. }
  2072. /**
  2073. * Checks the relationship between a session and a course.
  2074. * @param int $session_id
  2075. * @param int $courseId
  2076. * @return bool Returns TRUE if the session and the course are related, FALSE otherwise.
  2077. * */
  2078. public static function relation_session_course_exist($session_id, $courseId)
  2079. {
  2080. $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  2081. $return_value = false;
  2082. $sql = "SELECT c_id FROM $tbl_session_course
  2083. WHERE
  2084. session_id = " . intval($session_id) . " AND
  2085. c_id = " . intval($courseId) . "";
  2086. $result = Database::query($sql);
  2087. $num = Database::num_rows($result);
  2088. if ($num > 0) {
  2089. $return_value = true;
  2090. }
  2091. return $return_value;
  2092. }
  2093. /**
  2094. * Get the session information by name
  2095. * @param string session name
  2096. * @return mixed false if the session does not exist, array if the session exist
  2097. * */
  2098. public static function get_session_by_name($session_name)
  2099. {
  2100. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  2101. $session_name = trim($session_name);
  2102. if (empty($session_name)) {
  2103. return false;
  2104. }
  2105. $sql = 'SELECT *
  2106. FROM ' . $tbl_session . '
  2107. WHERE name = "' . Database::escape_string($session_name) . '"';
  2108. $result = Database::query($sql);
  2109. $num = Database::num_rows($result);
  2110. if ($num > 0) {
  2111. return Database::fetch_array($result);
  2112. } else {
  2113. return false;
  2114. }
  2115. }
  2116. /**
  2117. * Create a session category
  2118. * @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>, from existing code
  2119. * @param string name
  2120. * @param integer year_start
  2121. * @param integer month_start
  2122. * @param integer day_start
  2123. * @param integer year_end
  2124. * @param integer month_end
  2125. * @param integer day_end
  2126. * @return $id_session;
  2127. * */
  2128. public static function create_category_session(
  2129. $sname,
  2130. $syear_start,
  2131. $smonth_start,
  2132. $sday_start,
  2133. $syear_end,
  2134. $smonth_end,
  2135. $sday_end
  2136. ) {
  2137. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  2138. $name = trim($sname);
  2139. $year_start = intval($syear_start);
  2140. $month_start = intval($smonth_start);
  2141. $day_start = intval($sday_start);
  2142. $year_end = intval($syear_end);
  2143. $month_end = intval($smonth_end);
  2144. $day_end = intval($sday_end);
  2145. $date_start = "$year_start-" . (($month_start < 10) ? "0$month_start" : $month_start) . "-" . (($day_start < 10) ? "0$day_start" : $day_start);
  2146. $date_end = "$year_end-" . (($month_end < 10) ? "0$month_end" : $month_end) . "-" . (($day_end < 10) ? "0$day_end" : $day_end);
  2147. if (empty($name)) {
  2148. $msg = get_lang('SessionCategoryNameIsRequired');
  2149. return $msg;
  2150. } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
  2151. $msg = get_lang('InvalidStartDate');
  2152. return $msg;
  2153. } elseif (!$month_end && !$day_end && !$year_end) {
  2154. $date_end = "null";
  2155. } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
  2156. $msg = get_lang('InvalidEndDate');
  2157. return $msg;
  2158. } elseif ($date_start >= $date_end) {
  2159. $msg = get_lang('StartDateShouldBeBeforeEndDate');
  2160. return $msg;
  2161. }
  2162. $access_url_id = api_get_current_access_url_id();
  2163. $params = [
  2164. 'name' => $name,
  2165. 'date_start' => $date_start,
  2166. 'date_end' => $date_end,
  2167. 'access_url_id' => $access_url_id
  2168. ];
  2169. $id_session = Database::insert($tbl_session_category, $params);
  2170. // Add event to system log
  2171. $user_id = api_get_user_id();
  2172. Event::addEvent(
  2173. LOG_SESSION_CATEGORY_CREATE,
  2174. LOG_SESSION_CATEGORY_ID,
  2175. $id_session,
  2176. api_get_utc_datetime(),
  2177. $user_id
  2178. );
  2179. return $id_session;
  2180. }
  2181. /**
  2182. * Edit a sessions categories
  2183. * @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>,from existing code
  2184. * @param integer id
  2185. * @param string name
  2186. * @param integer year_start
  2187. * @param integer month_start
  2188. * @param integer day_start
  2189. * @param integer year_end
  2190. * @param integer month_end
  2191. * @param integer day_end
  2192. * @return $id;
  2193. * The parameter id is a primary key
  2194. * */
  2195. public static function edit_category_session(
  2196. $id,
  2197. $sname,
  2198. $syear_start,
  2199. $smonth_start,
  2200. $sday_start,
  2201. $syear_end,
  2202. $smonth_end,
  2203. $sday_end
  2204. ) {
  2205. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  2206. $name = trim($sname);
  2207. $year_start = intval($syear_start);
  2208. $month_start = intval($smonth_start);
  2209. $day_start = intval($sday_start);
  2210. $year_end = intval($syear_end);
  2211. $month_end = intval($smonth_end);
  2212. $day_end = intval($sday_end);
  2213. $id = intval($id);
  2214. $date_start = "$year_start-" . (($month_start < 10) ? "0$month_start" : $month_start) . "-" . (($day_start < 10) ? "0$day_start" : $day_start);
  2215. $date_end = "$year_end-" . (($month_end < 10) ? "0$month_end" : $month_end) . "-" . (($day_end < 10) ? "0$day_end" : $day_end);
  2216. if (empty($name)) {
  2217. $msg = get_lang('SessionCategoryNameIsRequired');
  2218. return $msg;
  2219. } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
  2220. $msg = get_lang('InvalidStartDate');
  2221. return $msg;
  2222. } elseif (!$month_end && !$day_end && !$year_end) {
  2223. $date_end = null;
  2224. } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
  2225. $msg = get_lang('InvalidEndDate');
  2226. return $msg;
  2227. } elseif ($date_start >= $date_end) {
  2228. $msg = get_lang('StartDateShouldBeBeforeEndDate');
  2229. return $msg;
  2230. }
  2231. if ($date_end <> null) {
  2232. $sql = "UPDATE $tbl_session_category
  2233. SET
  2234. name = '" . Database::escape_string($name) . "',
  2235. date_start = '$date_start' ,
  2236. date_end = '$date_end'
  2237. WHERE id= $id";
  2238. } else {
  2239. $sql = "UPDATE $tbl_session_category SET
  2240. name = '" . Database::escape_string($name) . "',
  2241. date_start = '$date_start',
  2242. date_end = NULL
  2243. WHERE id= $id";
  2244. }
  2245. $result = Database::query($sql);
  2246. return ($result ? true : false);
  2247. }
  2248. /**
  2249. * Delete sessions categories
  2250. * @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>, from existing code
  2251. * @param array id_checked
  2252. * @param bool include delete session
  2253. * @param bool optional, true if the function is called by a webservice, false otherwise.
  2254. * @return void Nothing, or false on error
  2255. * The parameters is a array to delete sessions
  2256. * */
  2257. public static function delete_session_category($id_checked, $delete_session = false, $from_ws = false)
  2258. {
  2259. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  2260. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  2261. if (is_array($id_checked)) {
  2262. $id_checked = Database::escape_string(implode(',', $id_checked));
  2263. } else {
  2264. $id_checked = intval($id_checked);
  2265. }
  2266. //Setting session_category_id to 0
  2267. $sql = "UPDATE $tbl_session SET session_category_id = 0
  2268. WHERE session_category_id IN (" . $id_checked . ")";
  2269. Database::query($sql);
  2270. $sql = "SELECT id FROM $tbl_session WHERE session_category_id IN (" . $id_checked . ")";
  2271. $result = Database::query($sql);
  2272. while ($rows = Database::fetch_array($result)) {
  2273. $session_id = $rows['id'];
  2274. if ($delete_session) {
  2275. if ($from_ws) {
  2276. SessionManager::delete($session_id, true);
  2277. } else {
  2278. SessionManager::delete($session_id);
  2279. }
  2280. }
  2281. }
  2282. $sql = "DELETE FROM $tbl_session_category WHERE id IN (" . $id_checked . ")";
  2283. Database::query($sql);
  2284. // Add event to system log
  2285. $user_id = api_get_user_id();
  2286. Event::addEvent(
  2287. LOG_SESSION_CATEGORY_DELETE,
  2288. LOG_SESSION_CATEGORY_ID,
  2289. $id_checked,
  2290. api_get_utc_datetime(),
  2291. $user_id
  2292. );
  2293. return true;
  2294. }
  2295. /**
  2296. * Get a list of sessions of which the given conditions match with an = 'cond'
  2297. * @param array $conditions a list of condition example :
  2298. * array('status' => STUDENT) or
  2299. * array('s.name' => array('operator' => 'LIKE', value = '%$needle%'))
  2300. * @param array $order_by a list of fields on which sort
  2301. * @return array An array with all sessions of the platform.
  2302. * @todo optional course code parameter, optional sorting parameters...
  2303. */
  2304. public static function get_sessions_list($conditions = array(), $order_by = array(), $from = null, $to = null)
  2305. {
  2306. $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
  2307. $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  2308. $user_table = Database::get_main_table(TABLE_MAIN_USER);
  2309. $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  2310. $session_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  2311. $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
  2312. $access_url_id = api_get_current_access_url_id();
  2313. $return_array = array();
  2314. $sql_query = " SELECT
  2315. s.id,
  2316. s.name,
  2317. s.nbr_courses,
  2318. s.access_start_date,
  2319. s.access_end_date,
  2320. u.firstname,
  2321. u.lastname,
  2322. sc.name as category_name,
  2323. s.promotion_id
  2324. FROM $session_table s
  2325. INNER JOIN $user_table u ON s.id_coach = u.user_id
  2326. INNER JOIN $table_access_url_rel_session ar ON ar.session_id = s.id
  2327. LEFT JOIN $session_category_table sc ON s.session_category_id = sc.id
  2328. LEFT JOIN $session_course_table sco ON (sco.session_id = s.id)
  2329. INNER JOIN $course_table c ON sco.c_id = c.id
  2330. WHERE ar.access_url_id = $access_url_id ";
  2331. $availableFields = array(
  2332. 's.id',
  2333. 's.name',
  2334. 'c.id'
  2335. );
  2336. $availableOperator = array(
  2337. 'like',
  2338. '>=',
  2339. '<=',
  2340. '=',
  2341. );
  2342. if (count($conditions) > 0) {
  2343. foreach ($conditions as $field => $options) {
  2344. $operator = strtolower($options['operator']);
  2345. $value = Database::escape_string($options['value']);
  2346. $sql_query .= ' AND ';
  2347. if (in_array($field, $availableFields) && in_array($operator, $availableOperator)) {
  2348. $sql_query .= $field . " $operator '" . $value . "'";
  2349. }
  2350. }
  2351. }
  2352. $orderAvailableList = array('name');
  2353. if (count($order_by) > 0) {
  2354. $order = null;
  2355. $direction = null;
  2356. if (isset($order_by[0]) && in_array($order_by[0], $orderAvailableList)) {
  2357. $order = $order_by[0];
  2358. }
  2359. if (isset($order_by[1]) && in_array(strtolower($order_by[1]), array('desc', 'asc'))) {
  2360. $direction = $order_by[1];
  2361. }
  2362. if (!empty($order)) {
  2363. $sql_query .= " ORDER BY $order $direction ";
  2364. }
  2365. }
  2366. if (!is_null($from) && !is_null($to)) {
  2367. $to = intval($to);
  2368. $from = intval($from);
  2369. $sql_query .= "LIMIT $from, $to";
  2370. }
  2371. $sql_result = Database::query($sql_query);
  2372. if (Database::num_rows($sql_result) > 0) {
  2373. while ($result = Database::fetch_array($sql_result)) {
  2374. $return_array[$result['id']] = $result;
  2375. }
  2376. }
  2377. return $return_array;
  2378. }
  2379. /**
  2380. * Get the session category information by id
  2381. * @param string session category ID
  2382. * @return mixed false if the session category does not exist, array if the session category exists
  2383. */
  2384. public static function get_session_category($id)
  2385. {
  2386. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  2387. $id = intval($id);
  2388. $sql = "SELECT id, name, date_start, date_end
  2389. FROM $tbl_session_category
  2390. WHERE id= $id";
  2391. $result = Database::query($sql);
  2392. $num = Database::num_rows($result);
  2393. if ($num > 0) {
  2394. return Database::fetch_array($result);
  2395. } else {
  2396. return false;
  2397. }
  2398. }
  2399. /**
  2400. * Get all session categories (filter by access_url_id)
  2401. * @return mixed false if the session category does not exist, array if the session category exists
  2402. */
  2403. public static function get_all_session_category()
  2404. {
  2405. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  2406. $id = api_get_current_access_url_id();
  2407. $sql = 'SELECT * FROM ' . $tbl_session_category . '
  2408. WHERE access_url_id = ' . $id . '
  2409. ORDER BY name ASC';
  2410. $result = Database::query($sql);
  2411. if (Database::num_rows($result) > 0) {
  2412. $data = Database::store_result($result, 'ASSOC');
  2413. return $data;
  2414. } else {
  2415. return false;
  2416. }
  2417. }
  2418. /**
  2419. * Assign a coach to course in session with status = 2
  2420. * @param int $user_id
  2421. * @param int $session_id
  2422. * @param int $courseId
  2423. * @param bool $nocoach optional, if is true the user don't be a coach now,
  2424. * otherwise it'll assign a coach
  2425. * @return bool true if there are affected rows, otherwise false
  2426. */
  2427. public static function set_coach_to_course_session(
  2428. $user_id,
  2429. $session_id = 0,
  2430. $courseId = 0,
  2431. $nocoach = false
  2432. ) {
  2433. // Definition of variables
  2434. $user_id = intval($user_id);
  2435. if (!empty($session_id)) {
  2436. $session_id = intval($session_id);
  2437. } else {
  2438. $session_id = api_get_session_id();
  2439. }
  2440. if (!empty($courseId)) {
  2441. $courseId = intval($courseId);
  2442. } else {
  2443. $courseId = api_get_course_id();
  2444. }
  2445. // Table definition
  2446. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  2447. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  2448. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  2449. // check if user is a teacher
  2450. $sql = "SELECT * FROM $tbl_user
  2451. WHERE status = 1 AND user_id = $user_id";
  2452. $rs_check_user = Database::query($sql);
  2453. if (Database::num_rows($rs_check_user) > 0) {
  2454. if ($nocoach) {
  2455. // check if user_id exists in session_rel_user (if the user is
  2456. // subscribed to the session in any manner)
  2457. $sql = "SELECT user_id FROM $tbl_session_rel_user
  2458. WHERE
  2459. session_id = $session_id AND
  2460. user_id = $user_id";
  2461. $res = Database::query($sql);
  2462. if (Database::num_rows($res) > 0) {
  2463. // The user is already subscribed to the session. Change the
  2464. // record so the user is NOT a coach for this course anymore
  2465. // and then exit
  2466. $sql = "UPDATE $tbl_session_rel_course_rel_user
  2467. SET status = 0
  2468. WHERE
  2469. session_id = $session_id AND
  2470. c_id = $courseId AND
  2471. user_id = $user_id ";
  2472. $result = Database::query($sql);
  2473. if (Database::affected_rows($result) > 0)
  2474. return true;
  2475. else
  2476. return false;
  2477. } else {
  2478. // The user is not subscribed to the session, so make sure
  2479. // he isn't subscribed to a course in this session either
  2480. // and then exit
  2481. $sql = "DELETE FROM $tbl_session_rel_course_rel_user
  2482. WHERE
  2483. session_id = $session_id AND
  2484. c_id = $courseId AND
  2485. user_id = $user_id ";
  2486. $result = Database::query($sql);
  2487. if (Database::affected_rows($result) > 0)
  2488. return true;
  2489. else
  2490. return false;
  2491. }
  2492. } else {
  2493. // Assign user as a coach to course
  2494. // First check if the user is registered to the course
  2495. $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
  2496. WHERE
  2497. session_id = $session_id AND
  2498. c_id = $courseId AND
  2499. user_id = $user_id";
  2500. $rs_check = Database::query($sql);
  2501. // Then update or insert.
  2502. if (Database::num_rows($rs_check) > 0) {
  2503. $sql = "UPDATE $tbl_session_rel_course_rel_user SET status = 2
  2504. WHERE
  2505. session_id = $session_id AND
  2506. c_id = $courseId AND
  2507. user_id = $user_id ";
  2508. $result = Database::query($sql);
  2509. if (Database::affected_rows($result) > 0) {
  2510. return true;
  2511. } else {
  2512. return false;
  2513. }
  2514. } else {
  2515. $sql = "INSERT INTO $tbl_session_rel_course_rel_user(session_id, c_id, user_id, status)
  2516. VALUES($session_id, $courseId, $user_id, 2)";
  2517. $result = Database::query($sql);
  2518. if (Database::affected_rows($result) > 0) {
  2519. return true;
  2520. } else {
  2521. return false;
  2522. }
  2523. }
  2524. }
  2525. } else {
  2526. return false;
  2527. }
  2528. }
  2529. /**
  2530. * Subscribes sessions to human resource manager (Dashboard feature)
  2531. * @param array $userInfo Human Resource Manager info
  2532. * @param array $sessions_list Sessions id
  2533. * @param bool $sendEmail
  2534. * @param bool $removeOldConnections
  2535. * @return int
  2536. * */
  2537. public static function suscribe_sessions_to_hr_manager(
  2538. $userInfo,
  2539. $sessions_list,
  2540. $sendEmail = false,
  2541. $removeOldConnections = true
  2542. ) {
  2543. // Database Table Definitions
  2544. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  2545. $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  2546. if (empty($userInfo)) {
  2547. return 0;
  2548. }
  2549. $userId = $userInfo['user_id'];
  2550. // Only subscribe DRH users.
  2551. $rolesAllowed = array(
  2552. DRH,
  2553. SESSIONADMIN,
  2554. PLATFORM_ADMIN,
  2555. COURSE_TUTOR
  2556. );
  2557. $isAdmin = api_is_platform_admin_by_id($userInfo['user_id']);
  2558. if (!$isAdmin && !in_array($userInfo['status'], $rolesAllowed)) {
  2559. return 0;
  2560. }
  2561. $affected_rows = 0;
  2562. // Deleting assigned sessions to hrm_id.
  2563. if ($removeOldConnections) {
  2564. if (api_is_multiple_url_enabled()) {
  2565. $sql = "SELECT session_id
  2566. FROM $tbl_session_rel_user s
  2567. INNER JOIN $tbl_session_rel_access_url a ON (a.session_id = s.session_id)
  2568. WHERE
  2569. s.user_id = $userId AND
  2570. relation_type=" . SESSION_RELATION_TYPE_RRHH . " AND
  2571. access_url_id = " . api_get_current_access_url_id() . "";
  2572. } else {
  2573. $sql = "SELECT session_id FROM $tbl_session_rel_user s
  2574. WHERE user_id = $userId AND relation_type=" . SESSION_RELATION_TYPE_RRHH . "";
  2575. }
  2576. $result = Database::query($sql);
  2577. if (Database::num_rows($result) > 0) {
  2578. while ($row = Database::fetch_array($result)) {
  2579. $sql = "DELETE FROM $tbl_session_rel_user
  2580. WHERE
  2581. session_id = {$row['session_id']} AND
  2582. user_id = $userId AND
  2583. relation_type=" . SESSION_RELATION_TYPE_RRHH . " ";
  2584. Database::query($sql);
  2585. }
  2586. }
  2587. }
  2588. // Inserting new sessions list.
  2589. if (!empty($sessions_list) && is_array($sessions_list)) {
  2590. foreach ($sessions_list as $session_id) {
  2591. $session_id = intval($session_id);
  2592. $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, relation_type, registered_at)
  2593. VALUES (
  2594. $session_id,
  2595. $userId,
  2596. '" . SESSION_RELATION_TYPE_RRHH . "',
  2597. '" . api_get_utc_datetime() . "'
  2598. )";
  2599. Database::query($sql);
  2600. $affected_rows++;
  2601. }
  2602. }
  2603. return $affected_rows;
  2604. }
  2605. /**
  2606. * @param int $sessionId
  2607. * @return array
  2608. */
  2609. public static function getDrhUsersInSession($sessionId)
  2610. {
  2611. return self::get_users_by_session($sessionId, SESSION_RELATION_TYPE_RRHH);
  2612. }
  2613. /**
  2614. * @param int $userId
  2615. * @param int $sessionId
  2616. * @return array
  2617. */
  2618. public static function getSessionFollowedByDrh($userId, $sessionId)
  2619. {
  2620. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  2621. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  2622. $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  2623. $userId = intval($userId);
  2624. $sessionId = intval($sessionId);
  2625. $select = " SELECT * ";
  2626. if (api_is_multiple_url_enabled()) {
  2627. $sql = " $select FROM $tbl_session s
  2628. INNER JOIN $tbl_session_rel_user sru ON (sru.session_id = s.id)
  2629. LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
  2630. WHERE
  2631. sru.user_id = '$userId' AND
  2632. sru.session_id = '$sessionId' AND
  2633. sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "' AND
  2634. access_url_id = " . api_get_current_access_url_id() . "
  2635. ";
  2636. } else {
  2637. $sql = "$select FROM $tbl_session s
  2638. INNER JOIN $tbl_session_rel_user sru
  2639. ON
  2640. sru.session_id = s.id AND
  2641. sru.user_id = '$userId' AND
  2642. sru.session_id = '$sessionId' AND
  2643. sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "'
  2644. ";
  2645. }
  2646. $result = Database::query($sql);
  2647. if (Database::num_rows($result)) {
  2648. $row = Database::fetch_array($result, 'ASSOC');
  2649. $row['course_list'] = self::get_course_list_by_session_id($sessionId);
  2650. return $row;
  2651. }
  2652. return array();
  2653. }
  2654. /**
  2655. * Get sessions followed by human resources manager
  2656. * @param int $userId
  2657. * @param int $start
  2658. * @param int $limit
  2659. * @param bool $getCount
  2660. * @param bool $getOnlySessionId
  2661. * @param bool $getSql
  2662. * @param string $orderCondition
  2663. * @param string $description
  2664. *
  2665. * @return array sessions
  2666. */
  2667. public static function get_sessions_followed_by_drh(
  2668. $userId,
  2669. $start = null,
  2670. $limit = null,
  2671. $getCount = false,
  2672. $getOnlySessionId = false,
  2673. $getSql = false,
  2674. $orderCondition = null,
  2675. $keyword = '',
  2676. $description = ''
  2677. ) {
  2678. return self::getSessionsFollowedByUser(
  2679. $userId,
  2680. DRH,
  2681. $start,
  2682. $limit,
  2683. $getCount,
  2684. $getOnlySessionId,
  2685. $getSql,
  2686. $orderCondition,
  2687. $keyword,
  2688. $description
  2689. );
  2690. }
  2691. /**
  2692. * Get sessions followed by human resources manager
  2693. * @param int $userId
  2694. * @param int $start
  2695. * @param int $limit
  2696. * @param bool $getCount
  2697. * @param bool $getOnlySessionId
  2698. * @param bool $getSql
  2699. * @param string $orderCondition
  2700. * @param string $keyword
  2701. * @param string $description
  2702. * @return array sessions
  2703. */
  2704. public static function getSessionsFollowedByUser(
  2705. $userId,
  2706. $status = null,
  2707. $start = null,
  2708. $limit = null,
  2709. $getCount = false,
  2710. $getOnlySessionId = false,
  2711. $getSql = false,
  2712. $orderCondition = null,
  2713. $keyword = '',
  2714. $description = ''
  2715. ) {
  2716. // Database Table Definitions
  2717. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  2718. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  2719. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  2720. $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  2721. $userId = intval($userId);
  2722. $select = " SELECT DISTINCT * ";
  2723. if ($getCount) {
  2724. $select = " SELECT count(DISTINCT(s.id)) as count ";
  2725. }
  2726. if ($getOnlySessionId) {
  2727. $select = " SELECT DISTINCT(s.id) ";
  2728. }
  2729. $limitCondition = null;
  2730. if (!empty($start) && !empty($limit)) {
  2731. $limitCondition = " LIMIT " . intval($start) . ", " . intval($limit);
  2732. }
  2733. if (empty($orderCondition)) {
  2734. $orderCondition = " ORDER BY s.name ";
  2735. }
  2736. $whereConditions = null;
  2737. $sessionCourseConditions = null;
  2738. $sessionConditions = null;
  2739. $sessionQuery = null;
  2740. $courseSessionQuery = null;
  2741. switch ($status) {
  2742. case DRH:
  2743. $sessionQuery = "SELECT sru.session_id
  2744. FROM
  2745. $tbl_session_rel_user sru
  2746. WHERE
  2747. sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
  2748. sru.user_id = $userId";
  2749. break;
  2750. case COURSEMANAGER:
  2751. $courseSessionQuery = "
  2752. SELECT scu.session_id as id
  2753. FROM $tbl_session_rel_course_rel_user scu
  2754. WHERE (scu.status = 2 AND scu.user_id = $userId)";
  2755. $whereConditions = " OR (s.id_coach = $userId) ";
  2756. break;
  2757. default:
  2758. $sessionQuery = "SELECT sru.session_id
  2759. FROM
  2760. $tbl_session_rel_user sru
  2761. WHERE
  2762. sru.user_id = $userId";
  2763. break;
  2764. }
  2765. $keywordCondition = '';
  2766. if (!empty($keyword)) {
  2767. $keyword = Database::escape_string($keyword);
  2768. $keywordCondition = " AND (s.name LIKE '%$keyword%' ) ";
  2769. if (!empty($description)) {
  2770. $description = Database::escape_string($description);
  2771. $keywordCondition = " AND (s.name LIKE '%$keyword%' OR s.description LIKE '%$description%' ) ";
  2772. }
  2773. }
  2774. $whereConditions .= $keywordCondition;
  2775. $subQuery = $sessionQuery.$courseSessionQuery;
  2776. $sql = " $select FROM $tbl_session s
  2777. INNER JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
  2778. WHERE
  2779. access_url_id = ".api_get_current_access_url_id()." AND
  2780. s.id IN (
  2781. $subQuery
  2782. )
  2783. $whereConditions
  2784. $orderCondition
  2785. $limitCondition";
  2786. if ($getSql) {
  2787. return $sql;
  2788. }
  2789. $result = Database::query($sql);
  2790. if ($getCount) {
  2791. $row = Database::fetch_array($result);
  2792. return $row['count'];
  2793. }
  2794. $sessions = array();
  2795. if (Database::num_rows($result) > 0) {
  2796. $sysUploadPath = api_get_path(SYS_UPLOAD_PATH). 'sessions/';
  2797. $webUploadPath = api_get_path(WEB_UPLOAD_PATH). 'sessions/';
  2798. $imgPath = Display::returnIconPath('session_default_small.png');
  2799. $tableExtraFields = Database::get_main_table(TABLE_EXTRA_FIELD);
  2800. $sql = "SELECT id FROM " . $tableExtraFields . "
  2801. WHERE extra_field_type = 3 AND variable='image'";
  2802. $resultField = Database::query($sql);
  2803. $imageFieldId = Database::fetch_assoc($resultField);
  2804. while ($row = Database::fetch_array($result)) {
  2805. $row['image'] = null;
  2806. $sessionImage = $sysUploadPath . $imageFieldId['id'] . '_' . $row['id'] . '.png';
  2807. if (is_file($sessionImage)) {
  2808. $sessionImage = $webUploadPath . $imageFieldId['id'] . '_' . $row['id'] . '.png';
  2809. $row['image'] = $sessionImage;
  2810. } else {
  2811. $row['image'] = $imgPath;
  2812. }
  2813. $sessions[$row['id']] = $row;
  2814. }
  2815. }
  2816. return $sessions;
  2817. }
  2818. /**
  2819. * Gets the list (or the count) of courses by session filtered by access_url
  2820. * @param int $session_id The session id
  2821. * @param string $course_name The course code
  2822. * @param string $orderBy Field to order the data
  2823. * @param boolean $getCount Optional. Count the session courses
  2824. * @return array|int List of courses. Whether $getCount is true, return the count
  2825. */
  2826. public static function get_course_list_by_session_id(
  2827. $session_id,
  2828. $course_name = '',
  2829. $orderBy = null,
  2830. $getCount = false
  2831. ) {
  2832. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  2833. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  2834. $session_id = intval($session_id);
  2835. $sqlSelect = "SELECT *";
  2836. if ($getCount) {
  2837. $sqlSelect = "SELECT COUNT(1)";
  2838. }
  2839. // select the courses
  2840. $sql = "SELECT *, c.id, c.id as real_id
  2841. FROM $tbl_course c
  2842. INNER JOIN $tbl_session_rel_course src
  2843. ON c.id = src.c_id
  2844. WHERE src.session_id = '$session_id' ";
  2845. if (!empty($course_name)) {
  2846. $course_name = Database::escape_string($course_name);
  2847. $sql .= " AND c.title LIKE '%$course_name%' ";
  2848. }
  2849. if (!empty($orderBy)) {
  2850. $orderBy = Database::escape_string($orderBy);
  2851. $orderBy = " ORDER BY $orderBy";
  2852. } else {
  2853. if (SessionManager::orderCourseIsEnabled()) {
  2854. $orderBy .= " ORDER BY position ";
  2855. } else {
  2856. $orderBy .= " ORDER BY title ";
  2857. }
  2858. }
  2859. $sql .= Database::escape_string($orderBy);
  2860. $result = Database::query($sql);
  2861. $num_rows = Database::num_rows($result);
  2862. $courses = array();
  2863. if ($num_rows > 0) {
  2864. if ($getCount) {
  2865. $count = Database::fetch_array($result);
  2866. return intval($count[0]);
  2867. }
  2868. while ($row = Database::fetch_array($result,'ASSOC')) {
  2869. $courses[$row['real_id']] = $row;
  2870. }
  2871. }
  2872. return $courses;
  2873. }
  2874. /**
  2875. * Gets the list of courses by session filtered by access_url
  2876. *
  2877. * @param $userId
  2878. * @param $sessionId
  2879. * @param null $from
  2880. * @param null $limit
  2881. * @param null $column
  2882. * @param null $direction
  2883. * @param bool $getCount
  2884. * @return array
  2885. */
  2886. public static function getAllCoursesFollowedByUser(
  2887. $userId,
  2888. $sessionId,
  2889. $from = null,
  2890. $limit = null,
  2891. $column = null,
  2892. $direction = null,
  2893. $getCount = false,
  2894. $keyword = null
  2895. ) {
  2896. if (empty($sessionId)) {
  2897. $sessionsSQL = SessionManager::get_sessions_followed_by_drh(
  2898. $userId,
  2899. null,
  2900. null,
  2901. null,
  2902. true,
  2903. true
  2904. );
  2905. } else {
  2906. $sessionsSQL = intval($sessionId);
  2907. }
  2908. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  2909. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  2910. if ($getCount) {
  2911. $select = "SELECT COUNT(DISTINCT(c.code)) as count ";
  2912. } else {
  2913. $select = "SELECT DISTINCT c.* ";
  2914. }
  2915. $keywordCondition = null;
  2916. if (!empty($keyword)) {
  2917. $keyword = Database::escape_string($keyword);
  2918. $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
  2919. }
  2920. // Select the courses
  2921. $sql = "$select
  2922. FROM $tbl_course c
  2923. INNER JOIN $tbl_session_rel_course src
  2924. ON c.id = src.c_id
  2925. WHERE
  2926. src.session_id IN ($sessionsSQL)
  2927. $keywordCondition
  2928. ";
  2929. if ($getCount) {
  2930. $result = Database::query($sql);
  2931. $row = Database::fetch_array($result,'ASSOC');
  2932. return $row['count'];
  2933. }
  2934. if (isset($from) && isset($limit)) {
  2935. $from = intval($from);
  2936. $limit = intval($limit);
  2937. $sql .= " LIMIT $from, $limit";
  2938. }
  2939. $result = Database::query($sql);
  2940. $num_rows = Database::num_rows($result);
  2941. $courses = array();
  2942. if ($num_rows > 0) {
  2943. while ($row = Database::fetch_array($result,'ASSOC')) {
  2944. $courses[$row['id']] = $row;
  2945. }
  2946. }
  2947. return $courses;
  2948. }
  2949. /**
  2950. * Gets the list of courses by session filtered by access_url
  2951. * @param int $session_id
  2952. * @param string $course_name
  2953. * @return array list of courses
  2954. */
  2955. public static function get_course_list_by_session_id_like($session_id, $course_name = '')
  2956. {
  2957. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  2958. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  2959. $session_id = intval($session_id);
  2960. $course_name = Database::escape_string($course_name);
  2961. // select the courses
  2962. $sql = "SELECT c.id, c.title FROM $tbl_course c
  2963. INNER JOIN $tbl_session_rel_course src
  2964. ON c.id = src.c_id
  2965. WHERE ";
  2966. if (!empty($session_id)) {
  2967. $sql .= "src.session_id LIKE '$session_id' AND ";
  2968. }
  2969. if (!empty($course_name)) {
  2970. $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') ";
  2971. }
  2972. $sql .= "ORDER BY title;";
  2973. $result = Database::query($sql);
  2974. $num_rows = Database::num_rows($result);
  2975. $courses = array();
  2976. if ($num_rows > 0) {
  2977. while ($row = Database::fetch_array($result, 'ASSOC')) {
  2978. $courses[$row['id']] = $row;
  2979. }
  2980. }
  2981. return $courses;
  2982. }
  2983. /**
  2984. * Gets the count of courses by session filtered by access_url
  2985. * @param int session id
  2986. * @return array list of courses
  2987. */
  2988. public static function getCourseCountBySessionId($session_id, $keyword = null)
  2989. {
  2990. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  2991. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  2992. $session_id = intval($session_id);
  2993. // select the courses
  2994. $sql = "SELECT COUNT(c.code) count
  2995. FROM $tbl_course c
  2996. INNER JOIN $tbl_session_rel_course src
  2997. ON c.id = src.c_id
  2998. WHERE src.session_id = '$session_id' ";
  2999. $keywordCondition = null;
  3000. if (!empty($keyword)) {
  3001. $keyword = Database::escape_string($keyword);
  3002. $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
  3003. }
  3004. $sql .= $keywordCondition;
  3005. $result = Database::query($sql);
  3006. $num_rows = Database::num_rows($result);
  3007. if ($num_rows > 0) {
  3008. $row = Database::fetch_array($result,'ASSOC');
  3009. return $row['count'];
  3010. }
  3011. return null;
  3012. }
  3013. /**
  3014. * Get the session id based on the original id and field name in the extra fields.
  3015. * Returns 0 if session was not found
  3016. *
  3017. * @param string $value Original session id
  3018. * @param string $variable Original field name
  3019. * @return int Session id
  3020. */
  3021. public static function getSessionIdFromOriginalId($value, $variable)
  3022. {
  3023. $extraFieldValue = new ExtraFieldValue('session');
  3024. $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
  3025. $variable,
  3026. $value
  3027. );
  3028. if (!empty($result)) {
  3029. return $result['item_id'];
  3030. }
  3031. return 0;
  3032. }
  3033. /**
  3034. * Get users by session
  3035. * @param int $id session id
  3036. * @param int $status filter by status coach = 2
  3037. * @return array a list with an user list
  3038. */
  3039. public static function get_users_by_session($id, $status = null)
  3040. {
  3041. if (empty($id)) {
  3042. return array();
  3043. }
  3044. $id = intval($id);
  3045. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  3046. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  3047. $table_access_url_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  3048. $sql = "SELECT
  3049. u.user_id,
  3050. lastname,
  3051. firstname,
  3052. username,
  3053. relation_type,
  3054. access_url_id
  3055. FROM $tbl_user u
  3056. INNER JOIN $tbl_session_rel_user
  3057. ON u.user_id = $tbl_session_rel_user.user_id AND
  3058. $tbl_session_rel_user.session_id = $id
  3059. LEFT OUTER JOIN $table_access_url_user uu
  3060. ON (uu.user_id = u.user_id)
  3061. ";
  3062. $urlId = api_get_current_access_url_id();
  3063. if (isset($status) && $status != '') {
  3064. $status = intval($status);
  3065. $sql .= " WHERE relation_type = $status AND (access_url_id = $urlId OR access_url_id is null )";
  3066. } else {
  3067. $sql .= " WHERE (access_url_id = $urlId OR access_url_id is null )";
  3068. }
  3069. $sql .= " ORDER BY relation_type, ";
  3070. $sql .= api_sort_by_first_name() ? ' firstname, lastname' : ' lastname, firstname';
  3071. $result = Database::query($sql);
  3072. $return = array();
  3073. while ($row = Database::fetch_array($result, 'ASSOC')) {
  3074. $return[] = $row;
  3075. }
  3076. return $return;
  3077. }
  3078. /**
  3079. * The general coach (field: session.id_coach)
  3080. * @param int $user_id user id
  3081. * @param boolean $asPlatformAdmin The user is platform admin, return everything
  3082. * @return array
  3083. */
  3084. public static function get_sessions_by_general_coach($user_id, $asPlatformAdmin = false)
  3085. {
  3086. $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
  3087. $user_id = intval($user_id);
  3088. // Session where we are general coach
  3089. $sql = "SELECT DISTINCT *
  3090. FROM $session_table";
  3091. if (!$asPlatformAdmin) {
  3092. $sql .= " WHERE id_coach = $user_id";
  3093. }
  3094. if (api_is_multiple_url_enabled()) {
  3095. $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  3096. $access_url_id = api_get_current_access_url_id();
  3097. $sqlCoach = '';
  3098. if (!$asPlatformAdmin) {
  3099. $sqlCoach = " id_coach = $user_id AND ";
  3100. }
  3101. if ($access_url_id != -1) {
  3102. $sql = 'SELECT DISTINCT session.*
  3103. FROM ' . $session_table . ' session INNER JOIN ' . $tbl_session_rel_access_url . ' session_rel_url
  3104. ON (session.id = session_rel_url.session_id)
  3105. WHERE '.$sqlCoach.' access_url_id = ' . $access_url_id;
  3106. }
  3107. }
  3108. $sql .= ' ORDER by name';
  3109. $result = Database::query($sql);
  3110. return Database::store_result($result, 'ASSOC');
  3111. }
  3112. /**
  3113. * @param int $user_id
  3114. * @return array
  3115. * @deprecated use get_sessions_by_general_coach()
  3116. */
  3117. public static function get_sessions_by_coach($user_id)
  3118. {
  3119. $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
  3120. return Database::select('*', $session_table, array('where' => array('id_coach = ?' => $user_id)));
  3121. }
  3122. /**
  3123. * @param int $user_id
  3124. * @param int $courseId
  3125. * @param int $session_id
  3126. * @return array|bool
  3127. */
  3128. public static function get_user_status_in_course_session($user_id, $courseId, $session_id)
  3129. {
  3130. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  3131. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  3132. $sql = "SELECT session_rcru.status
  3133. FROM $tbl_session_rel_course_rel_user session_rcru, $tbl_user user
  3134. WHERE
  3135. session_rcru.user_id = user.user_id AND
  3136. session_rcru.session_id = '" . intval($session_id) . "' AND
  3137. session_rcru.c_id ='" . intval($courseId) . "' AND
  3138. user.user_id = " . intval($user_id);
  3139. $result = Database::query($sql);
  3140. $status = false;
  3141. if (Database::num_rows($result)) {
  3142. $status = Database::fetch_row($result);
  3143. $status = $status['0'];
  3144. }
  3145. return $status;
  3146. }
  3147. /**
  3148. * Gets user status within a session
  3149. * @param int $user_id
  3150. * @param int $courseId
  3151. * @param $session_id
  3152. * @return int
  3153. * @assert (null,null,null) === false
  3154. */
  3155. public static function get_user_status_in_session($user_id, $courseId, $session_id)
  3156. {
  3157. if (empty($user_id) or empty($courseId) or empty($session_id)) {
  3158. return false;
  3159. }
  3160. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  3161. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  3162. $sql = "SELECT session_rcru.status
  3163. FROM $tbl_session_rel_course_rel_user session_rcru, $tbl_user user
  3164. WHERE session_rcru.user_id = user.user_id AND
  3165. session_rcru.session_id = '" . intval($session_id) . "' AND
  3166. session_rcru.c_id ='" . intval($courseId) . "' AND
  3167. user.user_id = " . intval($user_id);
  3168. $result = Database::query($sql);
  3169. $status = false;
  3170. if (Database::num_rows($result)) {
  3171. $status = Database::fetch_row($result);
  3172. $status = $status['0'];
  3173. }
  3174. return $status;
  3175. }
  3176. /**
  3177. * @param int $id
  3178. * @return array
  3179. */
  3180. public static function get_all_sessions_by_promotion($id)
  3181. {
  3182. $t = Database::get_main_table(TABLE_MAIN_SESSION);
  3183. return Database::select('*', $t, array('where' => array('promotion_id = ?' => $id)));
  3184. }
  3185. /**
  3186. * @param int $promotion_id
  3187. * @param array $list
  3188. */
  3189. public static function suscribe_sessions_to_promotion($promotion_id, $list)
  3190. {
  3191. $t = Database::get_main_table(TABLE_MAIN_SESSION);
  3192. $params = array();
  3193. $params['promotion_id'] = 0;
  3194. Database::update($t, $params, array('promotion_id = ?' => $promotion_id));
  3195. $params['promotion_id'] = $promotion_id;
  3196. if (!empty($list)) {
  3197. foreach ($list as $session_id) {
  3198. $session_id = intval($session_id);
  3199. Database::update($t, $params, array('id = ?' => $session_id));
  3200. }
  3201. }
  3202. }
  3203. /**
  3204. * Updates a session status
  3205. * @param int session id
  3206. * @param int status
  3207. */
  3208. public static function set_session_status($session_id, $status)
  3209. {
  3210. $t = Database::get_main_table(TABLE_MAIN_SESSION);
  3211. $params['visibility'] = $status;
  3212. Database::update($t, $params, array('id = ?' => $session_id));
  3213. }
  3214. /**
  3215. * Copies a session with the same data to a new session.
  3216. * The new copy is not assigned to the same promotion. @see suscribe_sessions_to_promotions() for that
  3217. * @param int Session ID
  3218. * @param bool Whether to copy the relationship with courses
  3219. * @param bool Whether to copy the relationship with users
  3220. * @param bool New courses will be created
  3221. * @param bool Whether to set exercises and learning paths in the new session to invisible by default
  3222. * @return int The new session ID on success, 0 otherwise
  3223. * @todo make sure the extra session fields are copied too
  3224. */
  3225. public static function copy(
  3226. $id,
  3227. $copy_courses = true,
  3228. $copy_users = true,
  3229. $create_new_courses = false,
  3230. $set_exercises_lp_invisible = false
  3231. ) {
  3232. $id = intval($id);
  3233. $s = self::fetch($id);
  3234. // Check all dates before copying
  3235. // Get timestamp for now in UTC - see http://php.net/manual/es/function.time.php#117251
  3236. $now = time() - date('Z');
  3237. // Timestamp in one month
  3238. $inOneMonth = $now + (30*24*3600);
  3239. $inOneMonth = api_get_local_time($inOneMonth);
  3240. if (api_strtotime($s['access_start_date']) < $now) {
  3241. $s['access_start_date'] = api_get_local_time($now);
  3242. }
  3243. if (api_strtotime($s['display_start_date']) < $now) {
  3244. $s['display_start_date'] = api_get_local_time($now);
  3245. }
  3246. if (api_strtotime($s['coach_access_start_date']) < $now) {
  3247. $s['coach_access_start_date'] = api_get_local_time($now);
  3248. }
  3249. if (api_strtotime($s['access_end_date']) < $now) {
  3250. $s['access_end_date'] = $inOneMonth;
  3251. }
  3252. if (api_strtotime($s['display_end_date']) < $now) {
  3253. $s['display_end_date'] = $inOneMonth;
  3254. }
  3255. if (api_strtotime($s['coach_access_end_date']) < $now) {
  3256. $s['coach_access_end_date'] = $inOneMonth;
  3257. }
  3258. // Now try to create the session
  3259. $sid = self::create_session(
  3260. $s['name'] . ' ' . get_lang('CopyLabelSuffix'),
  3261. $s['access_start_date'],
  3262. $s['access_end_date'],
  3263. $s['display_start_date'],
  3264. $s['display_end_date'],
  3265. $s['coach_access_start_date'],
  3266. $s['coach_access_end_date'],
  3267. (int)$s['id_coach'],
  3268. $s['session_category_id'],
  3269. (int)$s['visibility'],
  3270. true
  3271. );
  3272. if (!is_numeric($sid) || empty($sid)) {
  3273. return false;
  3274. }
  3275. if ($copy_courses) {
  3276. // Register courses from the original session to the new session
  3277. $courses = self::get_course_list_by_session_id($id);
  3278. $short_courses = $new_short_courses = array();
  3279. if (is_array($courses) && count($courses) > 0) {
  3280. foreach ($courses as $course) {
  3281. $short_courses[] = $course;
  3282. }
  3283. }
  3284. $courses = null;
  3285. //We will copy the current courses of the session to new courses
  3286. if (!empty($short_courses)) {
  3287. if ($create_new_courses) {
  3288. //Just in case
  3289. if (function_exists('ini_set')) {
  3290. api_set_memory_limit('256M');
  3291. ini_set('max_execution_time', 0);
  3292. }
  3293. $params = array();
  3294. $params['skip_lp_dates'] = true;
  3295. foreach ($short_courses as $course_data) {
  3296. $course_info = CourseManager::copy_course_simple(
  3297. $course_data['title'].' '.get_lang(
  3298. 'CopyLabelSuffix'
  3299. ),
  3300. $course_data['course_code'],
  3301. $id,
  3302. $sid,
  3303. $params
  3304. );
  3305. if ($course_info) {
  3306. //By default new elements are invisible
  3307. if ($set_exercises_lp_invisible) {
  3308. $list = new LearnpathList('', $course_info['code'], $sid);
  3309. $flat_list = $list->get_flat_list();
  3310. if (!empty($flat_list)) {
  3311. foreach ($flat_list as $lp_id => $data) {
  3312. api_item_property_update(
  3313. $course_info,
  3314. TOOL_LEARNPATH,
  3315. $lp_id,
  3316. 'invisible',
  3317. api_get_user_id(),
  3318. 0,
  3319. 0,
  3320. 0,
  3321. 0,
  3322. $sid
  3323. );
  3324. }
  3325. }
  3326. $quiz_table = Database::get_course_table(TABLE_QUIZ_TEST);
  3327. $course_id = $course_info['real_id'];
  3328. //@todo check this query
  3329. $sql = "UPDATE $quiz_table SET active = 0
  3330. WHERE c_id = $course_id AND session_id = $sid";
  3331. Database::query($sql);
  3332. }
  3333. $new_short_courses[] = $course_info['real_id'];
  3334. }
  3335. }
  3336. } else {
  3337. foreach ($short_courses as $course_data) {
  3338. $new_short_courses[] = $course_data['id'];
  3339. }
  3340. }
  3341. $short_courses = $new_short_courses;
  3342. self::add_courses_to_session($sid, $short_courses, true);
  3343. $short_courses = null;
  3344. }
  3345. }
  3346. if ($copy_users) {
  3347. // Register users from the original session to the new session
  3348. $users = self::get_users_by_session($id);
  3349. $short_users = array();
  3350. if (is_array($users) && count($users) > 0) {
  3351. foreach ($users as $user) {
  3352. $short_users[] = $user['user_id'];
  3353. }
  3354. }
  3355. $users = null;
  3356. //Subscribing in read only mode
  3357. self::suscribe_users_to_session($sid, $short_users, SESSION_VISIBLE_READ_ONLY, true);
  3358. $short_users = null;
  3359. }
  3360. return $sid;
  3361. }
  3362. /**
  3363. * @param int $user_id
  3364. * @param int $session_id
  3365. * @return bool
  3366. */
  3367. static function user_is_general_coach($user_id, $session_id)
  3368. {
  3369. $session_id = intval($session_id);
  3370. $user_id = intval($user_id);
  3371. $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
  3372. $sql = "SELECT DISTINCT id
  3373. FROM $session_table
  3374. WHERE session.id_coach = '" . $user_id . "' AND id = '$session_id'";
  3375. $result = Database::query($sql);
  3376. if ($result && Database::num_rows($result)) {
  3377. return true;
  3378. }
  3379. return false;
  3380. }
  3381. /**
  3382. * Get the number of sessions
  3383. * @param int ID of the URL we want to filter on (optional)
  3384. * @return int Number of sessions
  3385. */
  3386. public static function count_sessions($access_url_id = null)
  3387. {
  3388. $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
  3389. $access_url_rel_session_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  3390. $sql = "SELECT count(id) FROM $session_table s";
  3391. if (!empty($access_url_id) && $access_url_id == intval($access_url_id)) {
  3392. $sql .= ", $access_url_rel_session_table u " .
  3393. " WHERE s.id = u.session_id AND u.access_url_id = $access_url_id";
  3394. }
  3395. $res = Database::query($sql);
  3396. $row = Database::fetch_row($res);
  3397. return $row[0];
  3398. }
  3399. /**
  3400. * Protect a session to be edited.
  3401. * @param int $id
  3402. * @param bool $checkSession
  3403. */
  3404. public static function protectSession($id, $checkSession = true)
  3405. {
  3406. // api_protect_admin_script(true);
  3407. if (self::allowToManageSessions()) {
  3408. if (api_is_platform_admin()) {
  3409. return true;
  3410. }
  3411. if ($checkSession) {
  3412. if (self::allowed($id)) {
  3413. return true;
  3414. } else {
  3415. api_not_allowed(true);
  3416. }
  3417. }
  3418. } else {
  3419. api_not_allowed(true);
  3420. }
  3421. }
  3422. /**
  3423. * @param int $id
  3424. * @return bool
  3425. */
  3426. private static function allowed($id)
  3427. {
  3428. $sessionInfo = self::fetch($id);
  3429. if (empty($sessionInfo)) {
  3430. return false;
  3431. }
  3432. if (api_is_platform_admin()) {
  3433. return true;
  3434. }
  3435. $userId = api_get_user_id();
  3436. if (api_is_session_admin() &&
  3437. api_get_setting('allow_session_admins_to_manage_all_sessions') != 'true'
  3438. ) {
  3439. if ($sessionInfo['session_admin_id'] != $userId) {
  3440. return false;
  3441. }
  3442. }
  3443. if (api_is_teacher() &&
  3444. api_get_setting('session.allow_teachers_to_create_sessions') == 'true'
  3445. ) {
  3446. if ($sessionInfo['id_coach'] != $userId) {
  3447. return false;
  3448. }
  3449. }
  3450. return true;
  3451. }
  3452. /**
  3453. * @return bool
  3454. */
  3455. public static function allowToManageSessions()
  3456. {
  3457. if (self::allowManageAllSessions()) {
  3458. return true;
  3459. }
  3460. $setting = api_get_setting('session.allow_teachers_to_create_sessions');
  3461. if (api_is_teacher() && $setting == 'true') {
  3462. return true;
  3463. }
  3464. return false;
  3465. }
  3466. /**
  3467. * @return bool
  3468. */
  3469. public static function allowOnlyMySessions()
  3470. {
  3471. if (self::allowToManageSessions() &&
  3472. !api_is_platform_admin() &&
  3473. api_is_teacher()
  3474. ) {
  3475. return true;
  3476. }
  3477. return false;
  3478. }
  3479. /**
  3480. * @return bool
  3481. */
  3482. public static function allowManageAllSessions()
  3483. {
  3484. if (api_is_platform_admin()) {
  3485. return true;
  3486. }
  3487. return false;
  3488. }
  3489. /**
  3490. * @param $id
  3491. * @return bool
  3492. */
  3493. public static function protect_teacher_session_edit($id)
  3494. {
  3495. if (!api_is_coach($id) && !api_is_platform_admin()) {
  3496. api_not_allowed(true);
  3497. } else {
  3498. return true;
  3499. }
  3500. }
  3501. /**
  3502. * @param int $courseId
  3503. * @return array
  3504. */
  3505. public static function get_session_by_course($courseId)
  3506. {
  3507. $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  3508. $table_session = Database::get_main_table(TABLE_MAIN_SESSION);
  3509. $courseId = intval($courseId);
  3510. $sql = "SELECT name, s.id
  3511. FROM $table_session_course sc
  3512. INNER JOIN $table_session s ON (sc.session_id = s.id)
  3513. WHERE sc.c_id = '$courseId' ";
  3514. $result = Database::query($sql);
  3515. return Database::store_result($result);
  3516. }
  3517. /**
  3518. * @param int $user_id
  3519. * @param bool $ignore_visibility_for_admins
  3520. * @param bool $ignoreTimeLimit
  3521. *
  3522. * @return array
  3523. */
  3524. public static function get_sessions_by_user($user_id, $ignore_visibility_for_admins = false, $ignoreTimeLimit = false)
  3525. {
  3526. $sessionCategories = UserManager::get_sessions_by_category(
  3527. $user_id,
  3528. $ignoreTimeLimit,
  3529. false,
  3530. null,
  3531. null,
  3532. null,
  3533. $ignore_visibility_for_admins,
  3534. $ignoreTimeLimit
  3535. );
  3536. $sessionArray = array();
  3537. if (!empty($sessionCategories)) {
  3538. foreach ($sessionCategories as $category) {
  3539. if (isset($category['sessions'])) {
  3540. foreach ($category['sessions'] as $session) {
  3541. $sessionArray[] = $session;
  3542. }
  3543. }
  3544. }
  3545. }
  3546. return $sessionArray;
  3547. }
  3548. /**
  3549. * @param string $file
  3550. * @param bool $updateSession options:
  3551. * true: if the session exists it will be updated.
  3552. * false: if session exists a new session will be created adding a counter session1, session2, etc
  3553. * @param int $defaultUserId
  3554. * @param mixed $logger
  3555. * @param array $extraFields convert a file row to an extra field. Example in CSV file there's a SessionID then it will
  3556. * converted to extra_external_session_id if you set this: array('SessionId' => 'extra_external_session_id')
  3557. * @param string $extraFieldId
  3558. * @param int $daysCoachAccessBeforeBeginning
  3559. * @param int $daysCoachAccessAfterBeginning
  3560. * @param int $sessionVisibility
  3561. * @param array $fieldsToAvoidUpdate
  3562. * @param bool $deleteUsersNotInList
  3563. * @param bool $updateCourseCoaches
  3564. * @param bool $sessionWithCoursesModifier
  3565. * @param int $showDescription
  3566. * @param array $teacherBackupList
  3567. * @param array $groupBackup
  3568. * @return array
  3569. */
  3570. static function importCSV(
  3571. $file,
  3572. $updateSession,
  3573. $defaultUserId = null,
  3574. $logger = null,
  3575. $extraFields = array(),
  3576. $extraFieldId = null,
  3577. $daysCoachAccessBeforeBeginning = null,
  3578. $daysCoachAccessAfterBeginning = null,
  3579. $sessionVisibility = 1,
  3580. $fieldsToAvoidUpdate = array(),
  3581. $deleteUsersNotInList = false,
  3582. $updateCourseCoaches = false,
  3583. $sessionWithCoursesModifier = false,
  3584. $addOriginalCourseTeachersAsCourseSessionCoaches = true,
  3585. $removeAllTeachersFromCourse = true,
  3586. $showDescription = null,
  3587. &$teacherBackupList = array(),
  3588. &$groupBackup = array()
  3589. ) {
  3590. $content = file($file);
  3591. $error_message = null;
  3592. $session_counter = 0;
  3593. if (empty($defaultUserId)) {
  3594. $defaultUserId = api_get_user_id();
  3595. }
  3596. $eol = PHP_EOL;
  3597. if (PHP_SAPI != 'cli') {
  3598. $eol = '<br />';
  3599. }
  3600. $debug = false;
  3601. if (isset($logger)) {
  3602. $debug = true;
  3603. }
  3604. $extraParameters = null;
  3605. if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
  3606. $extraParameters .= ' , nb_days_access_before_beginning = '.intval($daysCoachAccessBeforeBeginning);
  3607. $extraParameters .= ' , nb_days_access_after_end = '.intval($daysCoachAccessAfterBeginning);
  3608. }
  3609. if (!is_null($showDescription)) {
  3610. $extraParameters .= ' , show_description = '.intval($showDescription);
  3611. }
  3612. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  3613. $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  3614. $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  3615. $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  3616. $sessions = array();
  3617. if (!api_strstr($content[0], ';')) {
  3618. $error_message = get_lang('NotCSV');
  3619. } else {
  3620. $tag_names = array();
  3621. foreach ($content as $key => $enreg) {
  3622. $enreg = explode(';', trim($enreg));
  3623. if ($key) {
  3624. foreach ($tag_names as $tag_key => $tag_name) {
  3625. $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
  3626. }
  3627. } else {
  3628. foreach ($enreg as $tag_name) {
  3629. $tag_names[] = api_preg_replace('/[^a-zA-Z0-9_\-]/', '', $tag_name);
  3630. }
  3631. if (!in_array('SessionName', $tag_names) ||
  3632. !in_array('DateStart', $tag_names) ||
  3633. !in_array('DateEnd', $tag_names)
  3634. ) {
  3635. $error_message = get_lang('NoNeededData');
  3636. break;
  3637. }
  3638. }
  3639. }
  3640. $sessionList = array();
  3641. // Looping the sessions.
  3642. foreach ($sessions as $enreg) {
  3643. $user_counter = 0;
  3644. $course_counter = 0;
  3645. if (isset($extraFields) && !empty($extraFields)) {
  3646. foreach ($extraFields as $original => $to) {
  3647. $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
  3648. }
  3649. }
  3650. $session_name = Database::escape_string($enreg['SessionName']);
  3651. // Default visibility
  3652. $visibilityAfterExpirationPerSession = $sessionVisibility;
  3653. if (isset($enreg['VisibilityAfterExpiration'])) {
  3654. $visibility = $enreg['VisibilityAfterExpiration'];
  3655. switch ($visibility) {
  3656. case 'read_only':
  3657. $visibilityAfterExpirationPerSession = SESSION_VISIBLE_READ_ONLY;
  3658. break;
  3659. case 'accessible':
  3660. $visibilityAfterExpirationPerSession = SESSION_VISIBLE;
  3661. break;
  3662. case 'not_accessible':
  3663. $visibilityAfterExpirationPerSession = SESSION_INVISIBLE;
  3664. break;
  3665. }
  3666. }
  3667. if (empty($session_name)) {
  3668. continue;
  3669. }
  3670. $date_start = $enreg['DateStart'];
  3671. $date_end = $enreg['DateEnd'];
  3672. $session_category_id = isset($enreg['SessionCategory']) ? $enreg['SessionCategory'] : null;
  3673. $sessionDescription = isset($enreg['SessionDescription']) ? $enreg['SessionDescription'] : null;
  3674. $extraSessionParameters = null;
  3675. if (!empty($sessionDescription)) {
  3676. $extraSessionParameters = " , description = '".Database::escape_string($sessionDescription)."'";
  3677. }
  3678. // Searching a general coach.
  3679. if (!empty($enreg['Coach'])) {
  3680. $coach_id = UserManager::get_user_id_from_username($enreg['Coach']);
  3681. if ($coach_id === false) {
  3682. // If the coach-user does not exist - I'm the coach.
  3683. $coach_id = $defaultUserId;
  3684. }
  3685. } else {
  3686. $coach_id = $defaultUserId;
  3687. }
  3688. if (!$updateSession) {
  3689. // Always create a session.
  3690. $unique_name = false;
  3691. $i = 0;
  3692. // Change session name, verify that session doesn't exist.
  3693. $suffix = null;
  3694. while (!$unique_name) {
  3695. if ($i > 1) {
  3696. $suffix = ' - ' . $i;
  3697. }
  3698. $sql = 'SELECT 1 FROM ' . $tbl_session . '
  3699. WHERE name="' . $session_name . $suffix . '"';
  3700. $rs = Database::query($sql);
  3701. if (Database::result($rs, 0, 0)) {
  3702. $i++;
  3703. } else {
  3704. $unique_name = true;
  3705. $session_name .= $suffix;
  3706. }
  3707. }
  3708. $sessionCondition = '';
  3709. if (!empty($session_category_id)) {
  3710. $sessionCondition = "session_category_id = '$session_category_id',";
  3711. }
  3712. // Creating the session.
  3713. $sql = "INSERT IGNORE INTO $tbl_session SET
  3714. name = '" . $session_name . "',
  3715. id_coach = '$coach_id',
  3716. access_start_date = '$date_start',
  3717. access_end_date = '$date_end',
  3718. visibility = '$visibilityAfterExpirationPerSession',
  3719. $sessionCondition
  3720. session_admin_id = " . intval($defaultUserId) . $extraParameters . $extraSessionParameters;
  3721. Database::query($sql);
  3722. $session_id = Database::insert_id();
  3723. if ($debug) {
  3724. if ($session_id) {
  3725. foreach ($enreg as $key => $value) {
  3726. if (substr($key, 0, 6) == 'extra_') { //an extra field
  3727. self::update_session_extra_field_value($session_id, substr($key, 6), $value);
  3728. }
  3729. }
  3730. $logger->addInfo("Sessions - Session created: #$session_id - $session_name");
  3731. } else {
  3732. $logger->addError("Sessions - Session NOT created: $session_name");
  3733. }
  3734. }
  3735. $session_counter++;
  3736. } else {
  3737. $sessionId = null;
  3738. if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
  3739. $sessionId = self::getSessionIdFromOriginalId($enreg['extra_'.$extraFieldId], $extraFieldId);
  3740. if (empty($sessionId)) {
  3741. $my_session_result = false;
  3742. } else {
  3743. $my_session_result = true;
  3744. }
  3745. } else {
  3746. $my_session_result = self::get_session_by_name($enreg['SessionName']);
  3747. }
  3748. if ($my_session_result === false) {
  3749. // Creating a session.
  3750. $sql = "INSERT IGNORE INTO $tbl_session SET
  3751. name = '$session_name',
  3752. id_coach = '$coach_id',
  3753. access_start_date = '$date_start',
  3754. access_end_date = '$date_end',
  3755. visibility = '$visibilityAfterExpirationPerSession',
  3756. session_category_id = '$session_category_id' " . $extraParameters . $extraSessionParameters;
  3757. Database::query($sql);
  3758. // We get the last insert id.
  3759. $my_session_result = SessionManager::get_session_by_name($enreg['SessionName']);
  3760. $session_id = $my_session_result['id'];
  3761. if ($session_id) {
  3762. foreach ($enreg as $key => $value) {
  3763. if (substr($key, 0, 6) == 'extra_') { //an extra field
  3764. self::update_session_extra_field_value($session_id, substr($key, 6), $value);
  3765. }
  3766. }
  3767. if ($debug) {
  3768. $logger->addInfo("Sessions - #$session_id created: $session_name");
  3769. }
  3770. // Delete session-user relation only for students
  3771. $sql = "DELETE FROM $tbl_session_user
  3772. WHERE session_id = '$session_id' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
  3773. Database::query($sql);
  3774. $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
  3775. Database::query($sql);
  3776. // Delete session-course-user relationships students and coaches.
  3777. if ($updateCourseCoaches) {
  3778. $sql = "DELETE FROM $tbl_session_course_user
  3779. WHERE session_id = '$session_id' AND status in ('0', '2')";
  3780. Database::query($sql);
  3781. } else {
  3782. // Delete session-course-user relation ships *only* for students.
  3783. $sql = "DELETE FROM $tbl_session_course_user
  3784. WHERE session_id = '$session_id' AND status <> 2";
  3785. Database::query($sql);
  3786. }
  3787. }
  3788. } else {
  3789. if ($debug) {
  3790. $logger->addError("Sessions - Session to be updated: $session_name");
  3791. }
  3792. // Updating the session.
  3793. $params = array(
  3794. 'id_coach' => $coach_id,
  3795. 'access_start_date' => $date_start,
  3796. 'access_end_date' => $date_end,
  3797. 'visibility' => $visibilityAfterExpirationPerSession,
  3798. 'session_category_id' => $session_category_id,
  3799. );
  3800. if (!empty($sessionDescription)) {
  3801. $params['description'] = $sessionDescription;
  3802. }
  3803. if (!empty($fieldsToAvoidUpdate)) {
  3804. foreach ($fieldsToAvoidUpdate as $field) {
  3805. unset($params[$field]);
  3806. }
  3807. }
  3808. if (isset($sessionId) && !empty($sessionId)) {
  3809. if (!empty($enreg['SessionName'])) {
  3810. $params['name'] = $enreg['SessionName'];
  3811. }
  3812. $session_id = $sessionId;
  3813. } else {
  3814. $row = Database::query("SELECT id FROM $tbl_session WHERE name = '$session_name'");
  3815. list($session_id) = Database::fetch_array($row);
  3816. }
  3817. if ($session_id) {
  3818. if ($debug) {
  3819. $logger->addError("Sessions - Session to be updated #$session_id");
  3820. }
  3821. $sessionInfo = api_get_session_info($session_id);
  3822. $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
  3823. if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
  3824. if (empty($sessionInfo['nb_days_access_before_beginning']) ||
  3825. (!empty($sessionInfo['nb_days_access_before_beginning']) &&
  3826. $sessionInfo['nb_days_access_before_beginning'] < $daysCoachAccessBeforeBeginning)
  3827. ) {
  3828. $params['nb_days_access_before_beginning'] = intval($daysCoachAccessBeforeBeginning);
  3829. }
  3830. if (empty($sessionInfo['nb_days_access_after_end']) ||
  3831. (!empty($sessionInfo['nb_days_access_after_end']) &&
  3832. $sessionInfo['nb_days_access_after_end'] < $daysCoachAccessAfterBeginning)
  3833. ) {
  3834. $params['nb_days_access_after_end'] = intval($daysCoachAccessAfterBeginning);
  3835. }
  3836. }
  3837. Database::update($tbl_session, $params, array('id = ?' => $session_id));
  3838. foreach ($enreg as $key => $value) {
  3839. if (substr($key, 0, 6) == 'extra_') { //an extra field
  3840. self::update_session_extra_field_value($session_id, substr($key, 6), $value);
  3841. }
  3842. }
  3843. // Delete session-user relation only for students
  3844. $sql = "DELETE FROM $tbl_session_user
  3845. WHERE session_id = '$session_id' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
  3846. Database::query($sql);
  3847. $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
  3848. Database::query($sql);
  3849. // Delete session-course-user relationships students and coaches.
  3850. if ($updateCourseCoaches) {
  3851. $sql = "DELETE FROM $tbl_session_course_user
  3852. WHERE session_id = '$session_id' AND status in ('0', '2')";
  3853. Database::query($sql);
  3854. } else {
  3855. // Delete session-course-user relation ships *only* for students.
  3856. $sql = "DELETE FROM $tbl_session_course_user
  3857. WHERE session_id = '$session_id' AND status <> 2";
  3858. Database::query($sql);
  3859. }
  3860. } else {
  3861. if ($debug) {
  3862. $logger->addError(
  3863. "Sessions - Session not found"
  3864. );
  3865. }
  3866. }
  3867. }
  3868. $session_counter++;
  3869. }
  3870. $sessionList[] = $session_id;
  3871. $users = explode('|', $enreg['Users']);
  3872. // Adding the relationship "Session - User" for students
  3873. $userList = array();
  3874. if (is_array($users)) {
  3875. foreach ($users as $user) {
  3876. $user_id = UserManager::get_user_id_from_username($user);
  3877. if ($user_id !== false) {
  3878. $userList[] = $user_id;
  3879. // Insert new users.
  3880. $sql = "INSERT IGNORE INTO $tbl_session_user SET
  3881. user_id = '$user_id',
  3882. session_id = '$session_id',
  3883. registered_at = '" . api_get_utc_datetime() . "'";
  3884. Database::query($sql);
  3885. if ($debug) {
  3886. $logger->addInfo("Sessions - Adding User #$user_id ($user) to session #$session_id");
  3887. }
  3888. $user_counter++;
  3889. }
  3890. }
  3891. }
  3892. if ($deleteUsersNotInList) {
  3893. // Getting user in DB in order to compare to the new list.
  3894. $usersListInDatabase = self::get_users_by_session($session_id, 0);
  3895. if (!empty($usersListInDatabase)) {
  3896. if (empty($userList)) {
  3897. foreach ($usersListInDatabase as $userInfo) {
  3898. self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
  3899. }
  3900. } else {
  3901. foreach ($usersListInDatabase as $userInfo) {
  3902. if (!in_array($userInfo['user_id'], $userList)) {
  3903. self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
  3904. }
  3905. }
  3906. }
  3907. }
  3908. }
  3909. $courses = explode('|', $enreg['Courses']);
  3910. // See BT#6449
  3911. $onlyAddFirstCoachOrTeacher = false;
  3912. if ($sessionWithCoursesModifier) {
  3913. if (count($courses) >= 2) {
  3914. // Only first teacher in course session;
  3915. $onlyAddFirstCoachOrTeacher = true;
  3916. // Remove all teachers from course.
  3917. $removeAllTeachersFromCourse = false;
  3918. }
  3919. }
  3920. foreach ($courses as $course) {
  3921. $courseArray = bracketsToArray($course);
  3922. $course_code = $courseArray[0];
  3923. if (CourseManager::course_exists($course_code)) {
  3924. $courseInfo = api_get_course_info($course_code);
  3925. $courseId = $courseInfo['real_id'];
  3926. // Adding the course to a session.
  3927. $sql = "INSERT IGNORE INTO $tbl_session_course
  3928. SET c_id = '$courseId', session_id='$session_id'";
  3929. Database::query($sql);
  3930. SessionManager::installCourse($session_id, $courseInfo['real_id']);
  3931. if ($debug) {
  3932. $logger->addInfo("Sessions - Adding course '$course_code' to session #$session_id");
  3933. }
  3934. $course_counter++;
  3935. $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
  3936. $course_users = isset($courseArray[2]) ? $courseArray[2] : null;
  3937. $course_users = explode(',', $course_users);
  3938. $course_coaches = explode(',', $course_coaches);
  3939. // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
  3940. $addTeachersToSession = true;
  3941. if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
  3942. $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
  3943. }
  3944. // If any user provided for a course, use the users array.
  3945. if (empty($course_users)) {
  3946. if (!empty($userList)) {
  3947. SessionManager::subscribe_users_to_session_course(
  3948. $userList,
  3949. $session_id,
  3950. $course_code
  3951. );
  3952. if ($debug) {
  3953. $msg = "Sessions - Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
  3954. $logger->addInfo($msg);
  3955. }
  3956. }
  3957. }
  3958. // Adding coaches to session course user.
  3959. if (!empty($course_coaches)) {
  3960. $savedCoaches = array();
  3961. // only edit if add_teachers_to_sessions_courses is set.
  3962. if ($addTeachersToSession) {
  3963. if ($addOriginalCourseTeachersAsCourseSessionCoaches) {
  3964. // Adding course teachers as course session teachers.
  3965. $alreadyAddedTeachers = CourseManager::getTeacherListFromCourse(
  3966. $course_code
  3967. );
  3968. if (!empty($alreadyAddedTeachers)) {
  3969. $teachersToAdd = array();
  3970. foreach ($alreadyAddedTeachers as $user) {
  3971. $teachersToAdd[] = $user['username'];
  3972. }
  3973. $course_coaches = array_merge(
  3974. $course_coaches,
  3975. $teachersToAdd
  3976. );
  3977. }
  3978. }
  3979. foreach ($course_coaches as $course_coach) {
  3980. $coach_id = UserManager::get_user_id_from_username($course_coach);
  3981. if ($coach_id !== false) {
  3982. // Just insert new coaches
  3983. SessionManager::updateCoaches($session_id, $courseId, array($coach_id), false);
  3984. if ($debug) {
  3985. $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
  3986. }
  3987. $savedCoaches[] = $coach_id;
  3988. } else {
  3989. $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
  3990. }
  3991. }
  3992. }
  3993. // Custom courses/session coaches
  3994. $teacherToAdd = null;
  3995. // Only one coach is added.
  3996. if ($onlyAddFirstCoachOrTeacher == true) {
  3997. foreach ($course_coaches as $course_coach) {
  3998. $coach_id = UserManager::get_user_id_from_username($course_coach);
  3999. if ($coach_id !== false) {
  4000. $teacherToAdd = $coach_id;
  4001. break;
  4002. }
  4003. }
  4004. // Un subscribe everyone that's not in the list.
  4005. $teacherList = CourseManager::getTeacherListFromCourse(
  4006. $courseId
  4007. );
  4008. if (!empty($teacherList)) {
  4009. foreach ($teacherList as $teacher) {
  4010. if ($teacherToAdd != $teacher['user_id']) {
  4011. $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
  4012. WHERE
  4013. user_id = ".$teacher['user_id']." AND
  4014. course_code = '".$course_code."'
  4015. ";
  4016. $result = Database::query($sql);
  4017. $userCourseData = Database::fetch_array($result, 'ASSOC');
  4018. $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
  4019. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
  4020. WHERE
  4021. user_id = ".$teacher['user_id']." AND
  4022. c_id = '".$courseInfo['real_id']."'
  4023. ";
  4024. $result = Database::query($sql);
  4025. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  4026. $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
  4027. }
  4028. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
  4029. WHERE
  4030. user_id = ".$teacher['user_id']." AND
  4031. c_id = '".$courseInfo['real_id']."'
  4032. ";
  4033. $result = Database::query($sql);
  4034. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  4035. $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
  4036. }
  4037. CourseManager::unsubscribe_user(
  4038. $teacher['user_id'],
  4039. $course_code
  4040. );
  4041. }
  4042. }
  4043. }
  4044. if (!empty($teacherToAdd)) {
  4045. SessionManager::updateCoaches($session_id, $courseId, array($teacherToAdd), true);
  4046. $userCourseCategory = '';
  4047. if (isset($teacherBackupList[$teacherToAdd]) &&
  4048. isset($teacherBackupList[$teacherToAdd][$course_code])
  4049. ) {
  4050. $courseUserData = $teacherBackupList[$teacherToAdd][$course_code];
  4051. $userCourseCategory = $courseUserData['user_course_cat'];
  4052. }
  4053. CourseManager::subscribe_user(
  4054. $teacherToAdd,
  4055. $course_code,
  4056. COURSEMANAGER,
  4057. 0,
  4058. $userCourseCategory
  4059. );
  4060. if (isset($groupBackup['user'][$teacherToAdd]) &&
  4061. isset($groupBackup['user'][$teacherToAdd][$course_code]) &&
  4062. !empty($groupBackup['user'][$teacherToAdd][$course_code])
  4063. ) {
  4064. foreach ($groupBackup['user'][$teacherToAdd][$course_code] as $data) {
  4065. GroupManager::subscribe_users(
  4066. $teacherToAdd,
  4067. $data['group_id'],
  4068. $data['c_id']
  4069. );
  4070. }
  4071. }
  4072. if (isset($groupBackup['tutor'][$teacherToAdd]) &&
  4073. isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
  4074. !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
  4075. ) {
  4076. foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
  4077. GroupManager::subscribe_tutors(
  4078. $teacherToAdd,
  4079. $data['group_id'],
  4080. $data['c_id']
  4081. );
  4082. }
  4083. }
  4084. }
  4085. }
  4086. // See BT#6449#note-195
  4087. // All coaches are added.
  4088. if ($removeAllTeachersFromCourse) {
  4089. $teacherToAdd = null;
  4090. foreach ($course_coaches as $course_coach) {
  4091. $coach_id = UserManager::get_user_id_from_username(
  4092. $course_coach
  4093. );
  4094. if ($coach_id !== false) {
  4095. $teacherToAdd[] = $coach_id;
  4096. }
  4097. }
  4098. if (!empty($teacherToAdd)) {
  4099. // Deleting all course teachers and adding the only coach as teacher.
  4100. $teacherList = CourseManager::getTeacherListFromCourse(
  4101. $courseId
  4102. );
  4103. if (!empty($teacherList)) {
  4104. foreach ($teacherList as $teacher) {
  4105. if (!in_array($teacher['user_id'], $teacherToAdd)) {
  4106. $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
  4107. WHERE
  4108. user_id = ".$teacher['user_id']." AND
  4109. course_code = '".$course_code."'
  4110. ";
  4111. $result = Database::query($sql);
  4112. $userCourseData = Database::fetch_array($result, 'ASSOC');
  4113. $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
  4114. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
  4115. WHERE
  4116. user_id = ".$teacher['user_id']." AND
  4117. c_id = '".$courseInfo['real_id']."'
  4118. ";
  4119. $result = Database::query($sql);
  4120. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  4121. $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
  4122. }
  4123. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
  4124. WHERE
  4125. user_id = ".$teacher['user_id']." AND
  4126. c_id = '".$courseInfo['real_id']."'
  4127. ";
  4128. $result = Database::query($sql);
  4129. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  4130. $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
  4131. }
  4132. CourseManager::unsubscribe_user(
  4133. $teacher['user_id'],
  4134. $course_code
  4135. );
  4136. }
  4137. }
  4138. }
  4139. foreach ($teacherToAdd as $teacherId) {
  4140. $userCourseCategory = '';
  4141. if (isset($teacherBackupList[$teacherId]) &&
  4142. isset($teacherBackupList[$teacherId][$course_code])
  4143. ) {
  4144. $courseUserData = $teacherBackupList[$teacherId][$course_code];
  4145. $userCourseCategory = $courseUserData['user_course_cat'];
  4146. }
  4147. CourseManager::subscribe_user(
  4148. $teacherId,
  4149. $course_code,
  4150. COURSEMANAGER,
  4151. 0,
  4152. $userCourseCategory
  4153. );
  4154. if (isset($groupBackup['user'][$teacherId]) &&
  4155. isset($groupBackup['user'][$teacherId][$course_code]) &&
  4156. !empty($groupBackup['user'][$teacherId][$course_code])
  4157. ) {
  4158. foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
  4159. GroupManager::subscribe_users(
  4160. $teacherId,
  4161. $data['group_id'],
  4162. $data['c_id']
  4163. );
  4164. }
  4165. }
  4166. if (isset($groupBackup['tutor'][$teacherId]) &&
  4167. isset($groupBackup['tutor'][$teacherId][$course_code]) &&
  4168. !empty($groupBackup['tutor'][$teacherId][$course_code])
  4169. ) {
  4170. foreach ($groupBackup['tutor'][$teacherId][$course_code] as $data) {
  4171. GroupManager::subscribe_tutors(
  4172. $teacherId,
  4173. $data['group_id'],
  4174. $data['c_id']
  4175. );
  4176. }
  4177. }
  4178. }
  4179. }
  4180. }
  4181. // Continue default behaviour.
  4182. if ($onlyAddFirstCoachOrTeacher == false) {
  4183. // Checking one more time see BT#6449#note-149
  4184. $coaches = SessionManager::getCoachesByCourseSession($session_id, $courseId);
  4185. // Update coaches if only there's 1 course see BT#6449#note-189
  4186. if (empty($coaches) || count($courses) == 1) {
  4187. foreach ($course_coaches as $course_coach) {
  4188. $course_coach = trim($course_coach);
  4189. $coach_id = UserManager::get_user_id_from_username($course_coach);
  4190. if ($coach_id !== false) {
  4191. // Just insert new coaches
  4192. SessionManager::updateCoaches(
  4193. $session_id,
  4194. $courseId,
  4195. array($coach_id),
  4196. false
  4197. );
  4198. if ($debug) {
  4199. $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
  4200. }
  4201. $savedCoaches[] = $coach_id;
  4202. } else {
  4203. $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
  4204. }
  4205. }
  4206. }
  4207. }
  4208. }
  4209. // Adding Students, updating relationship "Session - Course - User".
  4210. $course_users = array_filter($course_users);
  4211. if (!empty($course_users)) {
  4212. foreach ($course_users as $user) {
  4213. $user_id = UserManager::get_user_id_from_username($user);
  4214. if ($user_id !== false) {
  4215. SessionManager::subscribe_users_to_session_course(
  4216. array($user_id),
  4217. $session_id,
  4218. $course_code
  4219. );
  4220. if ($debug) {
  4221. $logger->addInfo("Sessions - Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
  4222. }
  4223. } else {
  4224. $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
  4225. }
  4226. }
  4227. }
  4228. $inserted_in_course[$course_code] = $courseInfo['title'];
  4229. }
  4230. }
  4231. $access_url_id = api_get_current_access_url_id();
  4232. UrlManager::add_session_to_url($session_id, $access_url_id);
  4233. $sql = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter' WHERE id = '$session_id'";
  4234. Database::query($sql);
  4235. }
  4236. }
  4237. return array(
  4238. 'error_message' => $error_message,
  4239. 'session_counter' => $session_counter,
  4240. 'session_list' => $sessionList,
  4241. );
  4242. }
  4243. /**
  4244. * @param int $sessionId
  4245. * @param int $courseId
  4246. * @return array
  4247. */
  4248. public static function getCoachesByCourseSession($sessionId, $courseId)
  4249. {
  4250. $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  4251. $sessionId = intval($sessionId);
  4252. $courseId = intval($courseId);
  4253. $sql = "SELECT user_id FROM $table
  4254. WHERE
  4255. session_id = '$sessionId' AND
  4256. c_id = '$courseId' AND
  4257. status = 2";
  4258. $result = Database::query($sql);
  4259. $coaches = array();
  4260. if (Database::num_rows($result) > 0) {
  4261. while ($row = Database::fetch_row($result)) {
  4262. $coaches[] = $row[0];
  4263. }
  4264. }
  4265. return $coaches;
  4266. }
  4267. /**
  4268. * @param int $sessionId
  4269. * @param int $courseId
  4270. * @return string
  4271. */
  4272. public static function getCoachesByCourseSessionToString(
  4273. $sessionId,
  4274. $courseId
  4275. ) {
  4276. $coaches = self::getCoachesByCourseSession($sessionId, $courseId);
  4277. $list = array();
  4278. if (!empty($coaches)) {
  4279. foreach ($coaches as $coachId) {
  4280. $userInfo = api_get_user_info($coachId);
  4281. $list[] = api_get_person_name(
  4282. $userInfo['firstname'],
  4283. $userInfo['lastname']
  4284. );
  4285. }
  4286. }
  4287. return array_to_string($list, CourseManager::USER_SEPARATOR);
  4288. }
  4289. /**
  4290. * Get all coaches added in the session - course relationship
  4291. * @param int $sessionId
  4292. * @return array
  4293. */
  4294. public static function getCoachesBySession($sessionId)
  4295. {
  4296. $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  4297. $sessionId = intval($sessionId);
  4298. $sql = "SELECT DISTINCT user_id
  4299. FROM $table
  4300. WHERE session_id = '$sessionId' AND status = 2";
  4301. $result = Database::query($sql);
  4302. $coaches = array();
  4303. if (Database::num_rows($result) > 0) {
  4304. while ($row = Database::fetch_array($result)) {
  4305. $coaches[] = $row['user_id'];
  4306. }
  4307. }
  4308. return $coaches;
  4309. }
  4310. /**
  4311. * @param int $userId
  4312. * @return array
  4313. */
  4314. public static function getAllCoursesFromAllSessionFromDrh($userId)
  4315. {
  4316. $sessions = SessionManager::get_sessions_followed_by_drh($userId);
  4317. $coursesFromSession = array();
  4318. if (!empty($sessions)) {
  4319. foreach ($sessions as $session) {
  4320. $courseList = SessionManager::get_course_list_by_session_id($session['id']);
  4321. foreach ($courseList as $course) {
  4322. $coursesFromSession[] = $course['code'];
  4323. }
  4324. }
  4325. }
  4326. return $coursesFromSession;
  4327. }
  4328. /**
  4329. * @param string $status
  4330. * @param int $userId
  4331. * @param bool $getCount
  4332. * @param int $from
  4333. * @param int $numberItems
  4334. * @param int $column
  4335. * @param string $direction
  4336. * @param string $keyword
  4337. * @param string $active
  4338. * @param string $lastConnectionDate
  4339. * @param array $sessionIdList
  4340. * @param array $studentIdList
  4341. * @param int $filterByStatus
  4342. * @return array|int
  4343. */
  4344. public static function getAllUsersFromCoursesFromAllSessionFromStatus(
  4345. $status,
  4346. $userId,
  4347. $getCount = false,
  4348. $from = null,
  4349. $numberItems = null,
  4350. $column = 1,
  4351. $direction = 'asc',
  4352. $keyword = null,
  4353. $active = null,
  4354. $lastConnectionDate = null,
  4355. $sessionIdList = array(),
  4356. $studentIdList = array(),
  4357. $filterByStatus = null
  4358. ) {
  4359. $filterByStatus = intval($filterByStatus);
  4360. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  4361. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  4362. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  4363. $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  4364. $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
  4365. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  4366. $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  4367. $direction = in_array(strtolower($direction), array('asc', 'desc')) ? $direction : 'asc';
  4368. $column = Database::escape_string($column);
  4369. $userId = intval($userId);
  4370. $limitCondition = null;
  4371. if (isset($from) && isset($numberItems)) {
  4372. $from = intval($from);
  4373. $numberItems = intval($numberItems);
  4374. $limitCondition = "LIMIT $from, $numberItems";
  4375. }
  4376. $urlId = api_get_current_access_url_id();
  4377. $sessionConditions = null;
  4378. $courseConditions = null;
  4379. $userConditions = null;
  4380. if (isset($active)) {
  4381. $active = intval($active);
  4382. $userConditions .= " AND active = $active";
  4383. }
  4384. switch ($status) {
  4385. case 'drh':
  4386. // Classic DRH
  4387. if (empty($studentIdList)) {
  4388. $studentListSql = UserManager::get_users_followed_by_drh(
  4389. $userId,
  4390. $filterByStatus,
  4391. true,
  4392. false
  4393. );
  4394. $studentIdList = array_keys($studentListSql);
  4395. $studentListSql = "'".implode("','", $studentIdList)."'";
  4396. } else {
  4397. $studentIdList = array_map('intval', $studentIdList);
  4398. $studentListSql = "'".implode("','", $studentIdList)."'";
  4399. }
  4400. if (!empty($studentListSql)) {
  4401. $userConditions = " AND u.user_id IN (".$studentListSql.") ";
  4402. }
  4403. break;
  4404. case 'drh_all':
  4405. // Show all by DRH
  4406. if (empty($sessionIdList)) {
  4407. $sessionsListSql = SessionManager::get_sessions_followed_by_drh(
  4408. $userId,
  4409. null,
  4410. null,
  4411. false,
  4412. true,
  4413. true
  4414. );
  4415. } else {
  4416. $sessionIdList = array_map('intval', $sessionIdList);
  4417. $sessionsListSql = "'".implode("','", $sessionIdList)."'";
  4418. }
  4419. if (!empty($sessionsListSql)) {
  4420. $sessionConditions = " AND s.id IN (".$sessionsListSql.") ";
  4421. }
  4422. break;
  4423. case 'session_admin';
  4424. $sessionConditions = " AND s.id_coach = $userId ";
  4425. break;
  4426. case 'admin':
  4427. break;
  4428. case 'teacher':
  4429. $sessionConditions = " AND s.id_coach = $userId ";
  4430. break;
  4431. }
  4432. $select = "SELECT DISTINCT u.* ";
  4433. $masterSelect = "SELECT DISTINCT * FROM ";
  4434. if ($getCount) {
  4435. $select = "SELECT DISTINCT u.user_id ";
  4436. $masterSelect = "SELECT COUNT(DISTINCT(user_id)) as count FROM ";
  4437. }
  4438. if (!empty($filterByStatus)) {
  4439. $userConditions .= " AND u.status = ".$filterByStatus;
  4440. }
  4441. if (!empty($lastConnectionDate)) {
  4442. $lastConnectionDate = Database::escape_string($lastConnectionDate);
  4443. $userConditions .= " AND u.last_login <= '$lastConnectionDate' ";
  4444. }
  4445. if (!empty($keyword)) {
  4446. $keyword = Database::escape_string($keyword);
  4447. $userConditions .= " AND (
  4448. u.username LIKE '%$keyword%' OR
  4449. u.firstname LIKE '%$keyword%' OR
  4450. u.lastname LIKE '%$keyword%' OR
  4451. u.official_code LIKE '%$keyword%' OR
  4452. u.email LIKE '%$keyword%'
  4453. )";
  4454. }
  4455. $where = " WHERE
  4456. access_url_id = $urlId
  4457. $userConditions
  4458. ";
  4459. $sql = "$masterSelect (
  4460. ($select
  4461. FROM $tbl_session s
  4462. INNER JOIN $tbl_session_rel_course_rel_user su ON (s.id = su.session_id)
  4463. INNER JOIN $tbl_user u ON (u.user_id = su.user_id)
  4464. INNER JOIN $tbl_session_rel_access_url url ON (url.session_id = s.id)
  4465. $where
  4466. $sessionConditions
  4467. )
  4468. UNION (
  4469. $select
  4470. FROM $tbl_course c
  4471. INNER JOIN $tbl_course_user cu ON (cu.c_id = c.id)
  4472. INNER JOIN $tbl_user u ON (u.user_id = cu.user_id)
  4473. INNER JOIN $tbl_course_rel_access_url url ON (url.c_id = c.id)
  4474. $where
  4475. $courseConditions
  4476. )
  4477. ) as t1
  4478. ";
  4479. if ($getCount) {
  4480. $result = Database::query($sql);
  4481. $count = 0;
  4482. if (Database::num_rows($result)) {
  4483. $rows = Database::fetch_array($result);
  4484. $count = $rows['count'];
  4485. }
  4486. return $count;
  4487. }
  4488. if (!empty($column) && !empty($direction)) {
  4489. $column = str_replace('u.', '', $column);
  4490. $sql .= " ORDER BY $column $direction ";
  4491. }
  4492. $sql .= $limitCondition;
  4493. $result = Database::query($sql);
  4494. $result = Database::store_result($result);
  4495. return $result ;
  4496. }
  4497. /**
  4498. * @param int $sessionId
  4499. * @param int $courseId
  4500. * @param array $coachList
  4501. * @param bool $deleteCoachesNotInList
  4502. */
  4503. public static function updateCoaches(
  4504. $sessionId,
  4505. $courseId,
  4506. $coachList,
  4507. $deleteCoachesNotInList = false
  4508. ) {
  4509. $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseId);
  4510. if (!empty($coachList)) {
  4511. foreach ($coachList as $userId) {
  4512. self::set_coach_to_course_session($userId, $sessionId, $courseId);
  4513. }
  4514. }
  4515. if ($deleteCoachesNotInList) {
  4516. if (!empty($coachList)) {
  4517. $coachesToDelete = array_diff($currentCoaches, $coachList);
  4518. } else {
  4519. $coachesToDelete = $currentCoaches;
  4520. }
  4521. if (!empty($coachesToDelete)) {
  4522. foreach ($coachesToDelete as $userId) {
  4523. self::set_coach_to_course_session(
  4524. $userId,
  4525. $sessionId,
  4526. $courseId,
  4527. true
  4528. );
  4529. }
  4530. }
  4531. }
  4532. }
  4533. /**
  4534. * @param array $sessions
  4535. * @param array $sessionsDestination
  4536. * @return string
  4537. */
  4538. public static function copyStudentsFromSession($sessions, $sessionsDestination)
  4539. {
  4540. $messages = array();
  4541. if (!empty($sessions)) {
  4542. foreach ($sessions as $sessionId) {
  4543. $sessionInfo = self::fetch($sessionId);
  4544. $userList = self::get_users_by_session($sessionId, 0);
  4545. if (!empty($userList)) {
  4546. $newUserList = array();
  4547. $userToString = null;
  4548. foreach ($userList as $userInfo) {
  4549. $newUserList[] = $userInfo['user_id'];
  4550. $userToString .= $userInfo['firstname'] . ' ' . $userInfo['lastname'] . '<br />';
  4551. }
  4552. if (!empty($sessionsDestination)) {
  4553. foreach ($sessionsDestination as $sessionDestinationId) {
  4554. $sessionDestinationInfo = self::fetch($sessionDestinationId);
  4555. $messages[] = Display::return_message(
  4556. sprintf(get_lang('AddingStudentsFromSessionXToSessionY'), $sessionInfo['name'], $sessionDestinationInfo['name']), 'info', false
  4557. );
  4558. if ($sessionId == $sessionDestinationId) {
  4559. $messages[] = Display::return_message(sprintf(get_lang('SessionXSkipped'), $sessionDestinationId), 'warning', false);
  4560. continue;
  4561. }
  4562. $messages[] = Display::return_message(get_lang('StudentList') . '<br />' . $userToString, 'info', false);
  4563. SessionManager::suscribe_users_to_session(
  4564. $sessionDestinationId,
  4565. $newUserList,
  4566. SESSION_VISIBLE_READ_ONLY,
  4567. false
  4568. );
  4569. }
  4570. } else {
  4571. $messages[] = Display::return_message(get_lang('NoDestinationSessionProvided'), 'warning');
  4572. }
  4573. } else {
  4574. $messages[] = Display::return_message(
  4575. get_lang('NoStudentsFoundForSession').' #'.$sessionInfo['name'],
  4576. 'warning'
  4577. );
  4578. }
  4579. }
  4580. } else {
  4581. $messages[] = Display::return_message(get_lang('NoData'), 'warning');
  4582. }
  4583. return $messages;
  4584. }
  4585. /**
  4586. * Assign coaches of a session(s) as teachers to a given course (or courses)
  4587. * @param array A list of session IDs
  4588. * @param array A list of course IDs
  4589. * @return string
  4590. */
  4591. public static function copyCoachesFromSessionToCourse($sessions, $courses)
  4592. {
  4593. $coachesPerSession = array();
  4594. foreach ($sessions as $sessionId) {
  4595. $coaches = self::getCoachesBySession($sessionId);
  4596. $coachesPerSession[$sessionId] = $coaches;
  4597. }
  4598. $result = array();
  4599. if (!empty($courses)) {
  4600. foreach ($courses as $courseId) {
  4601. $courseInfo = api_get_course_info_by_id($courseId);
  4602. foreach ($coachesPerSession as $sessionId => $coachList) {
  4603. CourseManager::updateTeachers(
  4604. $courseInfo['real_id'], $coachList, false, false, false
  4605. );
  4606. $result[$courseInfo['code']][$sessionId] = $coachList;
  4607. }
  4608. }
  4609. }
  4610. $sessionUrl = api_get_path(WEB_CODE_PATH) . 'admin/resume_session.php?id_session=';
  4611. $htmlResult = null;
  4612. if (!empty($result)) {
  4613. foreach ($result as $courseCode => $data) {
  4614. $url = api_get_course_url($courseCode);
  4615. $htmlResult .= sprintf(
  4616. get_lang('CoachesSubscribedAsATeacherInCourseX'),
  4617. Display::url($courseCode, $url, array('target' => '_blank'))
  4618. );
  4619. foreach ($data as $sessionId => $coachList) {
  4620. $sessionInfo = self::fetch($sessionId);
  4621. $htmlResult .= '<br />';
  4622. $htmlResult .= Display::url(
  4623. get_lang('Session') . ': ' . $sessionInfo['name'] . ' <br />', $sessionUrl . $sessionId, array('target' => '_blank')
  4624. );
  4625. $teacherList = array();
  4626. foreach ($coachList as $coachId) {
  4627. $userInfo = api_get_user_info($coachId);
  4628. $teacherList[] = $userInfo['complete_name'];
  4629. }
  4630. if (!empty($teacherList)) {
  4631. $htmlResult .= implode(', ', $teacherList);
  4632. } else {
  4633. $htmlResult .= get_lang('NothingToAdd');
  4634. }
  4635. }
  4636. $htmlResult .= '<br />';
  4637. }
  4638. $htmlResult = Display::return_message($htmlResult, 'normal', false);
  4639. }
  4640. return $htmlResult;
  4641. }
  4642. /**
  4643. * @param string $keyword
  4644. * @param string $active
  4645. * @param string $lastConnectionDate
  4646. * @param array $sessionIdList
  4647. * @param array $studentIdList
  4648. * @param int $userStatus STUDENT|COURSEMANAGER constants
  4649. *
  4650. * @return array|int
  4651. */
  4652. public static function getCountUserTracking(
  4653. $keyword = null,
  4654. $active = null,
  4655. $lastConnectionDate = null,
  4656. $sessionIdList = array(),
  4657. $studentIdList = array(),
  4658. $filterUserStatus = null
  4659. ) {
  4660. $userId = api_get_user_id();
  4661. $drhLoaded = false;
  4662. if (api_is_drh()) {
  4663. if (api_drh_can_access_all_session_content()) {
  4664. $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
  4665. 'drh_all',
  4666. $userId,
  4667. true,
  4668. null,
  4669. null,
  4670. null,
  4671. null,
  4672. $keyword,
  4673. $active,
  4674. $lastConnectionDate,
  4675. $sessionIdList,
  4676. $studentIdList,
  4677. $filterUserStatus
  4678. );
  4679. $drhLoaded = true;
  4680. }
  4681. }
  4682. if ($drhLoaded == false) {
  4683. $count = UserManager::getUsersFollowedByUser(
  4684. $userId,
  4685. $filterUserStatus,
  4686. false,
  4687. false,
  4688. true,
  4689. null,
  4690. null,
  4691. null,
  4692. null,
  4693. $active,
  4694. $lastConnectionDate,
  4695. api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
  4696. $keyword
  4697. );
  4698. }
  4699. return $count;
  4700. }
  4701. /**
  4702. * Get teachers followed by a user
  4703. * @param int $userId
  4704. * @param int $active
  4705. * @param string $lastConnectionDate
  4706. * @param bool $getCount
  4707. * @param array $sessionIdList
  4708. * @return array|int
  4709. */
  4710. public static function getTeacherTracking(
  4711. $userId,
  4712. $active = 1,
  4713. $lastConnectionDate = null,
  4714. $getCount = false,
  4715. $sessionIdList = array()
  4716. ) {
  4717. $teacherListId = array();
  4718. if (api_is_drh() || api_is_platform_admin()) {
  4719. // Followed teachers by drh
  4720. if (api_drh_can_access_all_session_content()) {
  4721. if (empty($sessionIdList)) {
  4722. $sessions = SessionManager::get_sessions_followed_by_drh($userId);
  4723. $sessionIdList = array();
  4724. foreach ($sessions as $session) {
  4725. $sessionIdList[] = $session['id'];
  4726. }
  4727. }
  4728. $sessionIdList = array_map('intval', $sessionIdList);
  4729. $sessionToString = implode("', '", $sessionIdList);
  4730. $course = Database::get_main_table(TABLE_MAIN_COURSE);
  4731. $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  4732. $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  4733. // Select the teachers.
  4734. $sql = "SELECT DISTINCT(cu.user_id) FROM $course c
  4735. INNER JOIN $sessionCourse src ON c.id = src.c_id
  4736. INNER JOIN $courseUser cu ON (cu.c_id = c.id)
  4737. WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
  4738. $result = Database::query($sql);
  4739. while($row = Database::fetch_array($result, 'ASSOC')) {
  4740. $teacherListId[$row['user_id']] = $row['user_id'];
  4741. }
  4742. } else {
  4743. $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
  4744. foreach ($teacherResult as $userInfo) {
  4745. $teacherListId[] = $userInfo['user_id'];
  4746. }
  4747. }
  4748. }
  4749. if (!empty($teacherListId)) {
  4750. $tableUser = Database::get_main_table(TABLE_MAIN_USER);
  4751. $select = "SELECT DISTINCT u.* ";
  4752. if ($getCount) {
  4753. $select = "SELECT count(DISTINCT(u.user_id)) as count";
  4754. }
  4755. $sql = "$select FROM $tableUser u";
  4756. if (!empty($lastConnectionDate)) {
  4757. $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
  4758. //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
  4759. }
  4760. $active = intval($active);
  4761. $teacherListId = implode("','", $teacherListId);
  4762. $where = " WHERE u.active = $active AND u.user_id IN ('$teacherListId') ";
  4763. if (!empty($lastConnectionDate)) {
  4764. $lastConnectionDate = Database::escape_string($lastConnectionDate);
  4765. //$where .= " AND l.login_date <= '$lastConnectionDate' ";
  4766. }
  4767. $sql .= $where;
  4768. $result = Database::query($sql);
  4769. if (Database::num_rows($result)) {
  4770. if ($getCount) {
  4771. $row = Database::fetch_array($result);
  4772. return $row['count'];
  4773. } else {
  4774. return Database::store_result($result, 'ASSOC');
  4775. }
  4776. }
  4777. }
  4778. return 0;
  4779. }
  4780. /**
  4781. * Get the list of course tools that have to be dealt with in case of
  4782. * registering any course to a session
  4783. * @return array The list of tools to be dealt with (literal names)
  4784. */
  4785. public static function getCourseToolToBeManaged()
  4786. {
  4787. return array(
  4788. 'courseDescription',
  4789. 'courseIntroduction',
  4790. );
  4791. }
  4792. /**
  4793. * Calls the methods bound to each tool when a course is registered into a session
  4794. * @param int $sessionId
  4795. * @param int $courseId
  4796. * @return void
  4797. */
  4798. public static function installCourse($sessionId, $courseId)
  4799. {
  4800. return true;
  4801. $toolList = self::getCourseToolToBeManaged();
  4802. foreach ($toolList as $tool) {
  4803. $method = 'add' . $tool;
  4804. if (method_exists(get_class(), $method)) {
  4805. self::$method($sessionId, $courseId);
  4806. }
  4807. }
  4808. }
  4809. /**
  4810. * Calls the methods bound to each tool when a course is unregistered from
  4811. * a session
  4812. * @param int $sessionId
  4813. * @param int $courseId
  4814. */
  4815. public static function unInstallCourse($sessionId, $courseId)
  4816. {
  4817. return true;
  4818. $toolList = self::getCourseToolToBeManaged();
  4819. foreach ($toolList as $tool) {
  4820. $method = 'remove' . $tool;
  4821. if (method_exists(get_class(), $method)) {
  4822. self::$method($sessionId, $courseId);
  4823. }
  4824. }
  4825. }
  4826. /**
  4827. * @param int $sessionId
  4828. * @param int $courseId
  4829. */
  4830. public static function addCourseIntroduction($sessionId, $courseId)
  4831. {
  4832. // @todo create a tool intro lib
  4833. $sessionId = intval($sessionId);
  4834. $courseId = intval($courseId);
  4835. $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
  4836. $sql = "SELECT * FROM $TBL_INTRODUCTION WHERE c_id = $courseId";
  4837. $result = Database::query($sql);
  4838. $result = Database::store_result($result, 'ASSOC');
  4839. if (!empty($result)) {
  4840. foreach ($result as $result) {
  4841. // @todo check if relation exits.
  4842. $result['session_id'] = $sessionId;
  4843. Database::insert($TBL_INTRODUCTION, $result);
  4844. }
  4845. }
  4846. }
  4847. /**
  4848. * @param int $sessionId
  4849. * @param int $courseId
  4850. */
  4851. public static function removeCourseIntroduction($sessionId, $courseId)
  4852. {
  4853. $sessionId = intval($sessionId);
  4854. $courseId = intval($courseId);
  4855. $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
  4856. $sql = "DELETE FROM $TBL_INTRODUCTION
  4857. WHERE c_id = $courseId AND session_id = $sessionId";
  4858. Database::query($sql);
  4859. }
  4860. /**
  4861. * @param int $sessionId
  4862. * @param int $courseId
  4863. */
  4864. public static function addCourseDescription($sessionId, $courseId)
  4865. {
  4866. /* $description = new CourseDescription();
  4867. $descriptions = $description->get_descriptions($courseId);
  4868. foreach ($descriptions as $description) {
  4869. } */
  4870. }
  4871. /**
  4872. * @param int $sessionId
  4873. * @param int $courseId
  4874. */
  4875. public static function removeCourseDescription($sessionId, $courseId)
  4876. {
  4877. }
  4878. /**
  4879. * @param array $userSessionList format see self::importSessionDrhCSV()
  4880. * @param bool $sendEmail
  4881. * @param bool $removeOldRelationShips
  4882. * @return string
  4883. */
  4884. public static function subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips)
  4885. {
  4886. if (!empty($userSessionList)) {
  4887. foreach ($userSessionList as $userId => $data) {
  4888. $sessionList = array();
  4889. foreach ($data['session_list'] as $sessionInfo) {
  4890. $sessionList[] = $sessionInfo['session_id'];
  4891. }
  4892. $userInfo = $data['user_info'];
  4893. self::suscribe_sessions_to_hr_manager(
  4894. $userInfo,
  4895. $sessionList,
  4896. $sendEmail,
  4897. $removeOldRelationShips
  4898. );
  4899. }
  4900. }
  4901. }
  4902. /**
  4903. * @param array $userSessionList format see self::importSessionDrhCSV()
  4904. *
  4905. * @return string
  4906. */
  4907. public static function checkSubscribeDrhToSessionList($userSessionList)
  4908. {
  4909. $message = null;
  4910. if (!empty($userSessionList)) {
  4911. if (!empty($userSessionList)) {
  4912. foreach ($userSessionList as $userId => $data) {
  4913. $userInfo = $data['user_info'];
  4914. $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
  4915. if (!empty($sessionListSubscribed)) {
  4916. $sessionListSubscribed = array_keys($sessionListSubscribed);
  4917. }
  4918. $sessionList = array();
  4919. if (!empty($data['session_list'])) {
  4920. foreach ($data['session_list'] as $sessionInfo) {
  4921. if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
  4922. $sessionList[] = $sessionInfo['session_info']['name'];
  4923. }
  4924. }
  4925. }
  4926. $message .= '<strong>' . get_lang('User') . '</strong> ' . $userInfo['complete_name'] . ' <br />';
  4927. if (!in_array($userInfo['status'], array(DRH)) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
  4928. $message .= get_lang('UserMustHaveTheDrhRole') . '<br />';
  4929. continue;
  4930. }
  4931. if (!empty($sessionList)) {
  4932. $message .= '<strong>' . get_lang('Sessions') . ':</strong> <br />';
  4933. $message .= implode(', ', $sessionList) . '<br /><br />';
  4934. } else {
  4935. $message .= get_lang('NoSessionProvided') . ' <br /><br />';
  4936. }
  4937. }
  4938. }
  4939. }
  4940. return $message;
  4941. }
  4942. /**
  4943. * @param string $file
  4944. * @param bool $sendEmail
  4945. * @param bool $removeOldRelationShips
  4946. *
  4947. * @return string
  4948. */
  4949. public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
  4950. {
  4951. $list = Import::csv_reader($file);
  4952. if (!empty($list)) {
  4953. $userSessionList = array();
  4954. foreach ($list as $data) {
  4955. $userInfo = api_get_user_info_from_username($data['Username']);
  4956. $sessionInfo = self::get_session_by_name($data['SessionName']);
  4957. if (!empty($userInfo) && !empty($sessionInfo)) {
  4958. $userSessionList[$userInfo['user_id']]['session_list'][] = array(
  4959. 'session_id' => $sessionInfo['id'],
  4960. 'session_info' => $sessionInfo,
  4961. );
  4962. $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
  4963. }
  4964. }
  4965. self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
  4966. return self::checkSubscribeDrhToSessionList($userSessionList);
  4967. }
  4968. }
  4969. /**
  4970. * Courses re-ordering in resume_session.php flag see BT#8316
  4971. */
  4972. public static function orderCourseIsEnabled()
  4973. {
  4974. $sessionCourseOrder = api_get_setting(
  4975. 'session.session_course_ordering'
  4976. );
  4977. if ($sessionCourseOrder === 'true') {
  4978. return true;
  4979. }
  4980. return false;
  4981. }
  4982. /**
  4983. * @param string $direction (up/down)
  4984. * @param int $sessionId
  4985. * @param int $courseId
  4986. * @return bool
  4987. */
  4988. public static function move($direction, $sessionId, $courseId)
  4989. {
  4990. if (!self::orderCourseIsEnabled()) {
  4991. return false;
  4992. }
  4993. $sessionId = intval($sessionId);
  4994. $courseId = intval($courseId);
  4995. $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  4996. $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
  4997. $position = array();
  4998. $count = 0;
  4999. foreach ($courseList as $course) {
  5000. if ($course['position'] == '') {
  5001. $course['position'] = $count;
  5002. }
  5003. $position[$course['code']] = $course['position'];
  5004. // Saving current order.
  5005. $sql = "UPDATE $table SET position = $count
  5006. WHERE session_id = $sessionId AND c_id = '".$course['real_id']."'";
  5007. Database::query($sql);
  5008. $count++;
  5009. }
  5010. // Loading new positions.
  5011. $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
  5012. $found = false;
  5013. switch ($direction) {
  5014. case 'up':
  5015. $courseList = array_reverse($courseList);
  5016. break;
  5017. case 'down':
  5018. break;
  5019. }
  5020. foreach ($courseList as $course) {
  5021. if ($found) {
  5022. $nextId = $course['real_id'];
  5023. $nextOrder = $course['position'];
  5024. break;
  5025. }
  5026. if ($courseId == $course['real_id']) {
  5027. $thisCourseCode = $course['real_id'];
  5028. $thisOrder = $course['position'];
  5029. $found = true;
  5030. }
  5031. }
  5032. $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
  5033. WHERE session_id = $sessionId AND c_id = $thisCourseCode";
  5034. Database::query($sql1);
  5035. $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
  5036. WHERE session_id = $sessionId AND c_id = $nextId";
  5037. Database::query($sql2);
  5038. return true;
  5039. }
  5040. /**
  5041. * @param int $sessionId
  5042. * @param int $courseId
  5043. * @return bool
  5044. */
  5045. public static function moveUp($sessionId, $courseId)
  5046. {
  5047. return self::move('up', $sessionId, $courseId);
  5048. }
  5049. /**
  5050. * @param int $sessionId
  5051. * @param string $courseCode
  5052. * @return bool
  5053. */
  5054. public static function moveDown($sessionId, $courseCode)
  5055. {
  5056. return self::move('down', $sessionId, $courseCode);
  5057. }
  5058. /**
  5059. * Use the session duration to allow/block user access see BT#8317
  5060. * Needs these DB changes
  5061. * ALTER TABLE session ADD COLUMN duration int;
  5062. * ALTER TABLE session_rel_user ADD COLUMN duration int;
  5063. */
  5064. public static function durationPerUserIsEnabled()
  5065. {
  5066. return api_get_configuration_value('session_duration_feature');
  5067. }
  5068. /**
  5069. * Returns the number of days the student has left in a session when using
  5070. * sessions durations
  5071. * @param int $userId
  5072. * @param int $sessionId
  5073. * @param int $duration in days
  5074. * @return int
  5075. */
  5076. public static function getDayLeftInSession($sessionId, $userId, $duration)
  5077. {
  5078. // Get an array with the details of the first access of the student to
  5079. // this session
  5080. $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
  5081. $sessionId,
  5082. $userId
  5083. );
  5084. $currentTime = time();
  5085. // If no previous access, return false
  5086. if (count($courseAccess) == 0) {
  5087. return false;
  5088. }
  5089. $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
  5090. $endDateInSeconds = $firstAccess + $duration*24*60*60;
  5091. $leftDays = round(($endDateInSeconds- $currentTime) / 60 / 60 / 24);
  5092. return $leftDays;
  5093. }
  5094. /**
  5095. * @param int $duration
  5096. * @param int $userId
  5097. * @param int $sessionId
  5098. */
  5099. public static function editUserSessionDuration($duration, $userId, $sessionId)
  5100. {
  5101. $duration = intval($duration);
  5102. $userId = intval($userId);
  5103. $sessionId = intval($sessionId);
  5104. if (empty($userId) || empty($sessionId)) {
  5105. return false;
  5106. }
  5107. $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  5108. $parameters = array('duration' => $duration);
  5109. $where = array('session_id = ? AND user_id = ? ' => array($sessionId, $userId));
  5110. Database::update($table, $parameters, $where);
  5111. }
  5112. /**
  5113. * Gets one row from the session_rel_user table
  5114. * @param int $userId
  5115. * @param int $sessionId
  5116. *
  5117. * @return array
  5118. */
  5119. public static function getUserSession($userId, $sessionId)
  5120. {
  5121. $userId = intval($userId);
  5122. $sessionId = intval($sessionId);
  5123. if (empty($userId) || empty($sessionId)) {
  5124. return false;
  5125. }
  5126. $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  5127. $sql = "SELECT * FROM $table
  5128. WHERE session_id = $sessionId AND user_id = $userId";
  5129. $result = Database::query($sql);
  5130. $values = array();
  5131. if (Database::num_rows($result)) {
  5132. $values = Database::fetch_array($result, 'ASSOC');
  5133. }
  5134. return $values;
  5135. }
  5136. /**
  5137. * Check if user is subscribed inside a session as student
  5138. * @param int $sessionId The session id
  5139. * @param int $userId The user id
  5140. * @return boolean Whether is subscribed
  5141. */
  5142. public static function isUserSubscribedAsStudent($sessionId, $userId)
  5143. {
  5144. $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  5145. $sessionId = intval($sessionId);
  5146. $userId = intval($userId);
  5147. // COUNT(1) actually returns the number of rows from the table (as if
  5148. // counting the results from the first column)
  5149. $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
  5150. WHERE
  5151. session_id = $sessionId AND
  5152. user_id = $userId AND
  5153. relation_type = 0";
  5154. $result = Database::fetch_assoc(Database::query($sql));
  5155. if (!empty($result) && $result['qty'] > 0) {
  5156. return true;
  5157. }
  5158. return false;
  5159. }
  5160. /**
  5161. * Get the session coached by a user (general coach and course-session coach)
  5162. * @param int $coachId The coach id
  5163. * @param boolean $checkSessionRelUserVisibility Check the session visibility
  5164. * @param boolean $asPlatformAdmin The user is a platform admin and we want all sessions
  5165. * @return array The session list
  5166. */
  5167. public static function getSessionsCoachedByUser($coachId, $checkSessionRelUserVisibility = false, $asPlatformAdmin = false)
  5168. {
  5169. // Get all sessions where $coachId is the general coach
  5170. $sessions = self::get_sessions_by_general_coach($coachId, $asPlatformAdmin);
  5171. // Get all sessions where $coachId is the course - session coach
  5172. $courseSessionList = self::getCoursesListByCourseCoach($coachId);
  5173. $sessionsByCoach = array();
  5174. if (!empty($courseSessionList)) {
  5175. foreach ($courseSessionList as $userCourseSubscription) {
  5176. $session = $userCourseSubscription->getSession();
  5177. $sessionsByCoach[$session->getId()] = api_get_session_info(
  5178. $session->getId()
  5179. );
  5180. }
  5181. }
  5182. if (!empty($sessionsByCoach)) {
  5183. $sessions = array_merge($sessions, $sessionsByCoach);
  5184. }
  5185. // Remove repeated sessions
  5186. if (!empty($sessions)) {
  5187. $cleanSessions = array();
  5188. foreach ($sessions as $session) {
  5189. $cleanSessions[$session['id']] = $session;
  5190. }
  5191. $sessions = $cleanSessions;
  5192. }
  5193. if ($checkSessionRelUserVisibility) {
  5194. if (!empty($sessions)) {
  5195. $newSessions = array();
  5196. foreach ($sessions as $session) {
  5197. $visibility = api_get_session_visibility($session['id']);
  5198. if ($visibility == SESSION_INVISIBLE) {
  5199. continue;
  5200. }
  5201. $newSessions[] = $session;
  5202. }
  5203. $sessions = $newSessions;
  5204. }
  5205. }
  5206. return $sessions;
  5207. }
  5208. /**
  5209. * Check if the course belongs to the session
  5210. * @param int $sessionId The session id
  5211. * @param string $courseCode The course code
  5212. *
  5213. * @return bool
  5214. */
  5215. public static function sessionHasCourse($sessionId, $courseCode)
  5216. {
  5217. $sessionId = intval($sessionId);
  5218. $courseCode = Database::escape_string($courseCode);
  5219. $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
  5220. $sessionRelCourseTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  5221. $sql = "SELECT COUNT(1) AS qty
  5222. FROM $courseTable c
  5223. INNER JOIN $sessionRelCourseTable src
  5224. ON c.id = src.c_id
  5225. WHERE src.session_id = $sessionId
  5226. AND c.code = '$courseCode' ";
  5227. $result = Database::query($sql);
  5228. if ($result !== false) {
  5229. $data = Database::fetch_assoc($result);
  5230. if ($data['qty'] > 0) {
  5231. return true;
  5232. }
  5233. }
  5234. return false;
  5235. }
  5236. /**
  5237. * Get the list of course coaches
  5238. * @return array The list
  5239. */
  5240. public static function getAllCourseCoaches()
  5241. {
  5242. $coaches = array();
  5243. $scuTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  5244. $userTable = Database::get_main_table(TABLE_MAIN_USER);
  5245. $idResult = Database::select('DISTINCT user_id', $scuTable, array(
  5246. 'where' => array(
  5247. 'status = ?' => 2,
  5248. ),
  5249. ));
  5250. if ($idResult != false) {
  5251. foreach ($idResult as $idData) {
  5252. $userResult = Database::select('user_id, lastname, firstname, username', $userTable, array(
  5253. 'where' => array(
  5254. 'user_id = ?' => $idData['user_id'],
  5255. ),
  5256. ), 'first');
  5257. if ($userResult != false) {
  5258. $coaches[] = array(
  5259. 'id' => $userResult['user_id'],
  5260. 'lastname' => $userResult['lastname'],
  5261. 'firstname' => $userResult['firstname'],
  5262. 'username' => $userResult['username'],
  5263. 'completeName' => api_get_person_name(
  5264. $userResult['firstname'],
  5265. $userResult['lastname']
  5266. ),
  5267. );
  5268. }
  5269. }
  5270. }
  5271. return $coaches;
  5272. }
  5273. /**
  5274. * Calculate the total user time in the platform
  5275. * @param int $userId The user id
  5276. * @param string $from Optional. From date
  5277. * @param string $until Optional. Until date
  5278. * @return string The time (hh:mm:ss)
  5279. */
  5280. public static function getTotalUserTimeInPlatform($userId, $from = '', $until = '')
  5281. {
  5282. $userId = intval($userId);
  5283. $trackLoginTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
  5284. $whereConditions = array(
  5285. 'login_user_id = ? ' => $userId,
  5286. );
  5287. if (!empty($from) && !empty($until)) {
  5288. $whereConditions["AND (login_date >= '?' "] = $from;
  5289. $whereConditions["AND logout_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until;
  5290. }
  5291. $trackResult = Database::select(
  5292. 'SEC_TO_TIME(SUM(UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date))) as total_time',
  5293. $trackLoginTable,
  5294. array(
  5295. 'where' => $whereConditions,
  5296. ), 'first'
  5297. );
  5298. if ($trackResult != false) {
  5299. return $trackResult['total_time'] ? $trackResult['total_time'] : '00:00:00';
  5300. }
  5301. return '00:00:00';
  5302. }
  5303. /**
  5304. * Get the courses list by a course coach
  5305. * @param int $coachId The coach id
  5306. * @return array (id, user_id, session_id, c_id, visibility, status, legal_agreement)
  5307. */
  5308. public static function getCoursesListByCourseCoach($coachId)
  5309. {
  5310. $entityManager = Database::getManager();
  5311. $scuRepo = $entityManager->getRepository(
  5312. 'ChamiloCoreBundle:SessionRelCourseRelUser'
  5313. );
  5314. return $scuRepo->findBy([
  5315. 'user' => $coachId,
  5316. 'status' => SessionRelCourseRelUser::STATUS_COURSE_COACH
  5317. ]);
  5318. }
  5319. /**
  5320. * Get the count of user courses in session
  5321. * @param int $sessionId The session id
  5322. * @return array
  5323. */
  5324. public static function getTotalUserCoursesInSession($sessionId)
  5325. {
  5326. $tableUser = Database::get_main_table(TABLE_MAIN_USER);
  5327. $tableSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  5328. $sql = "SELECT COUNT(1) as count, u.id, scu.status status_in_session, u.status user_status
  5329. FROM $tableSessionRelCourseRelUser scu
  5330. INNER JOIN $tableUser u ON scu.user_id = u.id
  5331. WHERE scu.session_id = " . intval($sessionId) ."
  5332. GROUP BY u.id";
  5333. $result = Database::query($sql);
  5334. $list = array();
  5335. while ($data = Database::fetch_assoc($result)) {
  5336. $list[] = $data;
  5337. }
  5338. return $list;
  5339. }
  5340. /**
  5341. * Returns list of a few data from session (name, short description, start
  5342. * date, end date) and the given extra fields if defined based on a
  5343. * session category Id.
  5344. * @param int $categoryId The internal ID of the session category
  5345. * @param string $target Value to search for in the session field values
  5346. * @param array $extraFields A list of fields to be scanned and returned
  5347. * @return mixed
  5348. */
  5349. public static function getShortSessionListAndExtraByCategory($categoryId, $target, $extraFields = null, $publicationDate = null)
  5350. {
  5351. // Init variables
  5352. $categoryId = (int) $categoryId;
  5353. $sessionList = array();
  5354. // Check if categoryId is valid
  5355. if ($categoryId > 0) {
  5356. $target = Database::escape_string($target);
  5357. $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
  5358. $sfTable = Database::get_main_table(TABLE_EXTRA_FIELD);
  5359. $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
  5360. // Join session field and session field values tables
  5361. $joinTable = $sfTable . ' sf INNER JOIN ' . $sfvTable . ' sfv ON sf.id = sfv.field_id';
  5362. $fieldsArray = array();
  5363. foreach ($extraFields as $field) {
  5364. $fieldsArray[] = Database::escape_string($field);
  5365. }
  5366. $extraFieldType = \Chamilo\CoreBundle\Entity\ExtraField::SESSION_FIELD_TYPE;
  5367. if (isset ($publicationDate)) {
  5368. $publicationDateString = $publicationDate->format('Y-m-d H:i:s');
  5369. $wherePublication = " AND id NOT IN (
  5370. SELECT sfv.item_id FROM $joinTable
  5371. WHERE
  5372. sf.extra_field_type = $extraFieldType AND
  5373. ((sf.variable = 'publication_start_date' AND sfv.value > '$publicationDateString' and sfv.value != '') OR
  5374. (sf.variable = 'publication_end_date' AND sfv.value < '$publicationDateString' and sfv.value != ''))
  5375. )";
  5376. }
  5377. // Get the session list from session category and target
  5378. $sessionList = Database::select(
  5379. 'id, name, access_start_date, access_end_date',
  5380. $sTable,
  5381. array(
  5382. 'where' => array(
  5383. "session_category_id = ? AND id IN (
  5384. SELECT sfv.item_id FROM $joinTable
  5385. WHERE
  5386. sf.extra_field_type = $extraFieldType AND
  5387. sfv.item_id = session.id AND
  5388. sf.variable = 'target' AND
  5389. sfv.value = ?
  5390. ) $wherePublication" => array($categoryId, $target),
  5391. ),
  5392. )
  5393. );
  5394. $whereFieldVariables = array();
  5395. $whereFieldIds = array();
  5396. if (
  5397. is_array($fieldsArray) &&
  5398. count($fieldsArray) > 0
  5399. ) {
  5400. $whereParams = '?';
  5401. for ($i = 1; $i < count($fieldsArray); $i++) {
  5402. $whereParams .= ', ?';
  5403. }
  5404. $whereFieldVariables = ' variable IN ( ' . $whereParams .' )';
  5405. $whereFieldIds = 'field_id IN ( ' . $whereParams . ' )';
  5406. }
  5407. // Get session fields
  5408. $extraField = new ExtraField('session');
  5409. $questionMarks = substr(str_repeat('?, ', count($fieldsArray)), 0, -2);
  5410. $fieldsList = $extraField->get_all(array(
  5411. ' variable IN ( ' . $questionMarks . ' )' => $fieldsArray,
  5412. ));
  5413. // Index session fields
  5414. foreach ($fieldsList as $field) {
  5415. $fields[$field['id']] = $field['variable'];
  5416. }
  5417. // Get session field values
  5418. $extra = new ExtraFieldValue('session');
  5419. $questionMarksFields = substr(str_repeat('?, ', count($fields)), 0, -2);
  5420. $sessionFieldValueList = $extra->get_all(array ('where' => array('field_id IN ( ' . $questionMarksFields . ' )' => array_keys($fields))));
  5421. // Add session fields values to session list
  5422. foreach ($sessionList as $id => &$session) {
  5423. foreach ($sessionFieldValueList as $sessionFieldValue) {
  5424. // Match session field values to session
  5425. if ($sessionFieldValue['item_id'] == $id) {
  5426. // Check if session field value is set in session field list
  5427. if (isset($fields[$sessionFieldValue['field_id']])) {
  5428. // Avoid overwriting the session's ID field
  5429. if ($fields[$sessionFieldValue['field_id']] != 'id') {
  5430. $var = $fields[$sessionFieldValue['field_id']];
  5431. $val = $sessionFieldValue['value'];
  5432. // Assign session field value to session
  5433. $session[$var] = $val;
  5434. }
  5435. }
  5436. }
  5437. }
  5438. }
  5439. }
  5440. return $sessionList;
  5441. }
  5442. /**
  5443. * Return the Session Category id searched by name
  5444. * @param string $categoryName Name attribute of session category used for search query
  5445. * @param bool $force boolean used to get even if something is wrong (e.g not unique name)
  5446. * @return int|array If success, return category id (int), else it will return an array
  5447. * with the next structure:
  5448. * array('error' => true, 'errorMessage' => ERROR_MESSAGE)
  5449. */
  5450. public static function getSessionCategoryIdByName($categoryName, $force = false)
  5451. {
  5452. // Start error result
  5453. $errorResult = array('error' => true, 'errorMessage' => get_lang('ThereWasAnError'));
  5454. $categoryName = Database::escape_string($categoryName);
  5455. // Check if is not empty category name
  5456. if (!empty($categoryName)) {
  5457. $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  5458. // Get all session category with same name
  5459. $result = Database::select(
  5460. 'id',
  5461. $sessionCategoryTable,
  5462. array(
  5463. 'where' => array(
  5464. 'name = ?' => $categoryName,
  5465. ),
  5466. )
  5467. );
  5468. // Check the result
  5469. if ($result < 1) {
  5470. // If not found any result, update error message
  5471. $errorResult['errorMessage'] = 'Not found any session category name ' . $categoryName;
  5472. } elseif (count($result) > 1 && !$force) {
  5473. // If found more than one result and force is disabled, update error message
  5474. $errorResult['errorMessage'] = 'Found many session categories';
  5475. } elseif (count($result) == 1 || $force) {
  5476. // If found just one session category or force option is enabled
  5477. return key($result);
  5478. }
  5479. } else {
  5480. // category name is empty, update error message
  5481. $errorResult['errorMessage'] = 'Not valid category name';
  5482. }
  5483. return $errorResult;
  5484. }
  5485. /**
  5486. * Return all data from sessions (plus extra field, course and coach data) by category id
  5487. * @param int $sessionCategoryId session category id used to search sessions
  5488. * @return array If success, return session list and more session related data, else it will return an array
  5489. * with the next structure:
  5490. * array('error' => true, 'errorMessage' => ERROR_MESSAGE)
  5491. */
  5492. public static function getSessionListAndExtraByCategoryId($sessionCategoryId)
  5493. {
  5494. // Start error result
  5495. $errorResult = array(
  5496. 'error' => true,
  5497. 'errorMessage' => get_lang('ThereWasAnError'),
  5498. );
  5499. $sessionCategoryId = intval($sessionCategoryId);
  5500. // Check if session category id is valid
  5501. if ($sessionCategoryId > 0) {
  5502. // Get table names
  5503. $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
  5504. $sessionFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
  5505. $sessionFieldValueTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
  5506. $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  5507. $userTable = Database::get_main_table(TABLE_MAIN_USER);
  5508. $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
  5509. // Get all data from all sessions whit the session category specified
  5510. $sessionList = Database::select(
  5511. '*',
  5512. $sessionTable,
  5513. array(
  5514. 'where' => array(
  5515. 'session_category_id = ?' => $sessionCategoryId,
  5516. ),
  5517. )
  5518. );
  5519. $extraFieldType = \Chamilo\CoreBundle\Entity\ExtraField::SESSION_FIELD_TYPE;
  5520. // Check if session list query had result
  5521. if (!empty($sessionList)) {
  5522. // implode all session id
  5523. $sessionIdsString = '(' . implode(', ', array_keys($sessionList)) . ')';
  5524. // Get all field variables
  5525. $sessionFieldList = Database::select(
  5526. 'id, variable',
  5527. $sessionFieldTable,
  5528. array('extra_field_type = ? ' => array($extraFieldType))
  5529. );
  5530. // Get all field values
  5531. $sql = "SELECT item_id, field_id, value FROM
  5532. $sessionFieldValueTable v INNER JOIN $sessionFieldTable f
  5533. ON (f.id = v.field_id)
  5534. WHERE
  5535. item_id IN $sessionIdsString AND
  5536. extra_field_type = $extraFieldType
  5537. ";
  5538. $result = Database::query($sql);
  5539. $sessionFieldValueList = Database::store_result($result, 'ASSOC');
  5540. // Check if session field values had result
  5541. if (!empty($sessionFieldValueList)) {
  5542. $sessionFieldValueListBySession = array();
  5543. foreach ($sessionFieldValueList as $key => $sessionFieldValue) {
  5544. // Create an array to index ids to session id
  5545. $sessionFieldValueListBySession[$sessionFieldValue['item_id']][] = $key;
  5546. }
  5547. }
  5548. // Query used to find course-coaches from sessions
  5549. $sql = "SELECT
  5550. scu.session_id,
  5551. c.id AS course_id,
  5552. c.code AS course_code,
  5553. c.title AS course_title,
  5554. u.username AS coach_username,
  5555. u.firstname AS coach_firstname,
  5556. u.lastname AS coach_lastname
  5557. FROM $courseTable c
  5558. INNER JOIN $sessionCourseUserTable scu ON c.id = scu.c_id
  5559. INNER JOIN $userTable u ON scu.user_id = u.user_id
  5560. WHERE scu.status = 2 AND scu.session_id IN $sessionIdsString
  5561. ORDER BY scu.session_id ASC ";
  5562. $res = Database::query($sql);
  5563. $sessionCourseList = Database::store_result($res, 'ASSOC');
  5564. // Check if course list had result
  5565. if (!empty($sessionCourseList)) {
  5566. foreach ($sessionCourseList as $key => $sessionCourse) {
  5567. // Create an array to index ids to session_id
  5568. $sessionCourseListBySession[$sessionCourse['session_id']][] = $key;
  5569. }
  5570. }
  5571. // Join lists
  5572. if (is_array($sessionList)) {
  5573. foreach ($sessionList as $id => &$row) {
  5574. if (
  5575. !empty($sessionFieldValueListBySession) &&
  5576. is_array($sessionFieldValueListBySession[$id])
  5577. ) {
  5578. // If have an index array for session extra fields, use it to join arrays
  5579. foreach ($sessionFieldValueListBySession[$id] as $key) {
  5580. $row['extra'][$key] = array(
  5581. 'field_name' => $sessionFieldList[$sessionFieldValueList[$key]['field_id']]['variable'],
  5582. 'value' => $sessionFieldValueList[$key]['value'],
  5583. );
  5584. }
  5585. }
  5586. if (
  5587. !empty($sessionCourseListBySession) &&
  5588. is_array($sessionCourseListBySession[$id])
  5589. ) {
  5590. // If have an index array for session course coach, use it to join arrays
  5591. foreach ($sessionCourseListBySession[$id] as $key) {
  5592. $row['course'][$key] = array(
  5593. 'course_id' => $sessionCourseList[$key]['course_id'],
  5594. 'course_code' => $sessionCourseList[$key]['course_code'],
  5595. 'course_title' => $sessionCourseList[$key]['course_title'],
  5596. 'coach_username' => $sessionCourseList[$key]['coach_username'],
  5597. 'coach_firstname' => $sessionCourseList[$key]['coach_firstname'],
  5598. 'coach_lastname' => $sessionCourseList[$key]['coach_lastname'],
  5599. );
  5600. }
  5601. }
  5602. }
  5603. }
  5604. return $sessionList;
  5605. } else {
  5606. // Not found result, update error message
  5607. $errorResult['errorMessage'] = 'Not found any session for session category id ' . $sessionCategoryId;
  5608. }
  5609. }
  5610. return $errorResult;
  5611. }
  5612. /**
  5613. * Return session description from session id
  5614. * @param int $sessionId
  5615. * @return string
  5616. */
  5617. public static function getDescriptionFromSessionId($sessionId)
  5618. {
  5619. // Init variables
  5620. $sessionId = intval($sessionId);
  5621. $description = '';
  5622. // Check if session id is valid
  5623. if ($sessionId > 0) {
  5624. // Select query from session id
  5625. $rows = Database::select(
  5626. 'description',
  5627. Database::get_main_table(TABLE_MAIN_SESSION),
  5628. array(
  5629. 'where' => array(
  5630. 'id = ?' => $sessionId,
  5631. ),
  5632. )
  5633. );
  5634. // Check if select query result is not empty
  5635. if (!empty($rows)) {
  5636. // Get session description
  5637. $description = $rows[0]['description'];
  5638. }
  5639. }
  5640. return $description;
  5641. }
  5642. /**
  5643. * Get a session list filtered by name, description or any of the given extra fields
  5644. * @param string $term The term to search
  5645. * @param array $extraFieldsToInclude Extra fields to include in the session data
  5646. * @return array The list
  5647. */
  5648. public static function searchSession($term, $extraFieldsToInclude = array())
  5649. {
  5650. $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
  5651. $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
  5652. $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
  5653. $term = Database::escape_string($term);
  5654. $extraFieldType = \Chamilo\CoreBundle\Entity\ExtraField::SESSION_FIELD_TYPE;
  5655. if (is_array($extraFieldsToInclude) && count($extraFieldsToInclude) > 0) {
  5656. $resultData = Database::select('*', $sTable, array(
  5657. 'where' => array(
  5658. "name LIKE %?% " => $term,
  5659. " OR description LIKE %?% " => $term,
  5660. " OR id IN (
  5661. SELECT item_id
  5662. FROM $sfvTable v INNER JOIN $extraFieldTable e
  5663. ON (v.field_id = e.id)
  5664. WHERE value LIKE %?% AND extra_field_type = $extraFieldType
  5665. ) " => $term,
  5666. ),
  5667. ));
  5668. } else {
  5669. $resultData = Database::select('*', $sTable, array(
  5670. 'where' => array(
  5671. "name LIKE %?% " => $term,
  5672. "OR description LIKE %?% " => $term,
  5673. ),
  5674. ));
  5675. return $resultData;
  5676. }
  5677. foreach ($resultData as $id => &$session) {
  5678. $session['extra'] = self::getFilteredExtraFields($id, $extraFieldsToInclude);
  5679. }
  5680. return $resultData;
  5681. }
  5682. /**
  5683. * @param $sessionId
  5684. * @param array $extraFieldsToInclude
  5685. * @return array
  5686. */
  5687. public static function getFilteredExtraFields($sessionId, $extraFieldsToInclude = array())
  5688. {
  5689. $extraData = array();
  5690. $variables = array();
  5691. $variablePlaceHolders = array();
  5692. foreach ($extraFieldsToInclude as $sessionExtraField) {
  5693. $variablePlaceHolders[] = "?";
  5694. $variables[] = Database::escape_string($sessionExtraField);
  5695. }
  5696. $sessionExtraField = new ExtraField('session');
  5697. $fieldList = $sessionExtraField->get_all(array(
  5698. "variable IN ( " . implode(", ", $variablePlaceHolders) . " ) " => $variables,
  5699. ));
  5700. $fields = array();
  5701. // Index session fields
  5702. foreach ($fieldList as $field) {
  5703. $fields[$field['id']] = $field['variable'];
  5704. }
  5705. // Get session field values
  5706. $extra = new ExtraFieldValue('session');
  5707. $sessionFieldValueList = $extra->get_all(
  5708. array(
  5709. "field_id IN ( " . implode(", ", $variablePlaceHolders) . " )" => array_keys($fields),
  5710. )
  5711. );
  5712. foreach ($sessionFieldValueList as $sessionFieldValue) {
  5713. // Match session field values to session
  5714. if ($sessionFieldValue['item_id'] != $sessionId) {
  5715. continue;
  5716. }
  5717. // Check if session field value is set in session field list
  5718. if (!isset($fields[$sessionFieldValue['field_id']])) {
  5719. continue;
  5720. }
  5721. $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
  5722. $extrafieldValue = $sessionFieldValue['value'];
  5723. $extraData[] = array(
  5724. 'variable' => $extrafieldVariable,
  5725. 'value' => $extrafieldValue,
  5726. );
  5727. }
  5728. return $extraData;
  5729. }
  5730. /**
  5731. * @param int $sessionId
  5732. *
  5733. * @return bool
  5734. */
  5735. public static function isValidId($sessionId)
  5736. {
  5737. $sessionId = intval($sessionId);
  5738. if ($sessionId > 0) {
  5739. $rows = Database::select(
  5740. 'id',
  5741. Database::get_main_table(TABLE_MAIN_SESSION),
  5742. array('where' => array('id = ?' => $sessionId))
  5743. );
  5744. if (!empty($rows)) {
  5745. return true;
  5746. }
  5747. }
  5748. return false;
  5749. }
  5750. /**
  5751. * Get list of sessions based on users of a group for a group admin
  5752. * @param int $userId The user id
  5753. * @return array
  5754. */
  5755. public static function getSessionsFollowedForGroupAdmin($userId)
  5756. {
  5757. $sessionList = array();
  5758. $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
  5759. $sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  5760. $userGroup = new UserGroup();
  5761. $userIdList = $userGroup->getGroupUsersByUser($userId);
  5762. if (empty($userIdList)) {
  5763. return [];
  5764. }
  5765. $sql = "SELECT DISTINCT s.*
  5766. FROM $sessionTable s
  5767. INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
  5768. WHERE
  5769. (sru.id_user IN (" . implode(', ', $userIdList) . ")
  5770. AND sru.relation_type = 0
  5771. )";
  5772. if (api_is_multiple_url_enabled()) {
  5773. $sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  5774. $accessUrlId = api_get_current_access_url_id();
  5775. if ($accessUrlId != -1) {
  5776. $sql = "SELECT DISTINCT s.*
  5777. FROM $sessionTable s
  5778. INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
  5779. INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id
  5780. WHERE
  5781. srau.access_url_id = $accessUrlId
  5782. AND (
  5783. sru.id_user IN (" . implode(', ', $userIdList) . ")
  5784. AND sru.relation_type = 0
  5785. )";
  5786. }
  5787. }
  5788. $result = Database::query($sql);
  5789. while ($row = Database::fetch_assoc($result)) {
  5790. $sessionList[] = $row;
  5791. }
  5792. return $sessionList;
  5793. }
  5794. /**
  5795. * @param array $sessionInfo
  5796. * @return string
  5797. */
  5798. public static function getSessionVisibility($sessionInfo)
  5799. {
  5800. switch($sessionInfo['visibility']) {
  5801. case 1:
  5802. return get_lang('ReadOnly');
  5803. case 2:
  5804. return get_lang('Visible');
  5805. case 3:
  5806. return api_ucfirst(get_lang('Invisible'));
  5807. }
  5808. }
  5809. /**
  5810. * Converts "start date" and "end date" to "From start date to end date" string
  5811. * @param string $startDate
  5812. * @param string $endDate
  5813. *
  5814. * @return string
  5815. */
  5816. private static function convertSessionDateToString($startDate, $endDate)
  5817. {
  5818. $startDateToLocal = '';
  5819. $endDateToLocal = '';
  5820. // This will clean the variables if 0000-00-00 00:00:00 the variable will be empty
  5821. if (isset($startDateToLocal)) {
  5822. $startDateToLocal = api_get_local_time($startDate, null, null, true);
  5823. }
  5824. if (isset($endDateToLocal)) {
  5825. $endDateToLocal = api_get_local_time($endDate, null, null, true);
  5826. }
  5827. $result = '';
  5828. if (!empty($startDateToLocal) && !empty($endDateToLocal)) {
  5829. $result = sprintf(get_lang('FromDateXToDateY'), $startDateToLocal, $endDateToLocal);
  5830. } else {
  5831. if (!empty($startDateToLocal)) {
  5832. $result = get_lang('From').' '.$startDateToLocal;
  5833. }
  5834. if (!empty($endDateToLocal)) {
  5835. $result = get_lang('Until').' '.$endDateToLocal;
  5836. }
  5837. }
  5838. if (empty($result)) {
  5839. $result = get_lang('NoTimeLimits');
  5840. }
  5841. return $result;
  5842. }
  5843. /**
  5844. * Returns a human readable string
  5845. * @params array $sessionInfo An array with all the session dates
  5846. * @return string
  5847. */
  5848. public static function parseSessionDates($sessionInfo)
  5849. {
  5850. $displayDates = self::convertSessionDateToString(
  5851. $sessionInfo['display_start_date'],
  5852. $sessionInfo['display_end_date']
  5853. );
  5854. $accessDates = self::convertSessionDateToString(
  5855. $sessionInfo['access_start_date'],
  5856. $sessionInfo['access_end_date']
  5857. );
  5858. $coachDates = self::convertSessionDateToString(
  5859. $sessionInfo['coach_access_start_date'],
  5860. $sessionInfo['coach_access_end_date']
  5861. );
  5862. $result = [
  5863. 'access' => $accessDates,
  5864. 'display' => $displayDates,
  5865. 'coach' => $coachDates,
  5866. ];
  5867. return $result;
  5868. }
  5869. /**
  5870. * @param FormValidator $form
  5871. *
  5872. * @return array
  5873. */
  5874. public static function setForm(FormValidator & $form, $sessionId = 0)
  5875. {
  5876. $categoriesList = SessionManager::get_all_session_category();
  5877. $userInfo = api_get_user_info();
  5878. $categoriesOptions = array(
  5879. '0' => get_lang('None'),
  5880. );
  5881. if ($categoriesList != false) {
  5882. foreach ($categoriesList as $categoryItem) {
  5883. $categoriesOptions[$categoryItem['id']] = $categoryItem['name'];
  5884. }
  5885. }
  5886. // Database Table Definitions
  5887. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  5888. $form->addElement('text', 'name', get_lang('SessionName'), array(
  5889. 'maxlength' => 50,
  5890. ));
  5891. $form->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
  5892. $form->addRule('name', get_lang('SessionNameAlreadyExists'), 'callback', 'check_session_name');
  5893. if (!api_is_platform_admin() && api_is_teacher()) {
  5894. $form->addElement(
  5895. 'select',
  5896. 'coach_username',
  5897. get_lang('CoachName'),
  5898. [api_get_user_id() => $userInfo['complete_name']],
  5899. array(
  5900. 'id' => 'coach_username',
  5901. 'style' => 'width:370px;',
  5902. )
  5903. );
  5904. } else {
  5905. $sql = "SELECT COUNT(1) FROM $tbl_user WHERE status = 1";
  5906. $rs = Database::query($sql);
  5907. $countUsers = Database::result($rs, 0, 0);
  5908. if (intval($countUsers) < 50) {
  5909. $orderClause = "ORDER BY ";
  5910. $orderClause .= api_sort_by_first_name() ? "firstname, lastname, username" : "lastname, firstname, username";
  5911. /*$repo = UserManager::getRepository();
  5912. $users = $repo->findByRole('ROLE_TEACHER');*/
  5913. $sql = "SELECT user_id, lastname, firstname, username
  5914. FROM $tbl_user
  5915. WHERE status = '1' ".
  5916. $orderClause;
  5917. if (api_is_multiple_url_enabled()) {
  5918. $userRelAccessUrlTable = Database::get_main_table(
  5919. TABLE_MAIN_ACCESS_URL_REL_USER
  5920. );
  5921. $accessUrlId = api_get_current_access_url_id();
  5922. if ($accessUrlId != -1) {
  5923. $sql = "SELECT user.user_id, username, lastname, firstname
  5924. FROM $tbl_user user
  5925. INNER JOIN $userRelAccessUrlTable url_user
  5926. ON (url_user.user_id = user.user_id)
  5927. WHERE
  5928. access_url_id = $accessUrlId AND
  5929. status = 1 "
  5930. .$orderClause;
  5931. }
  5932. }
  5933. $result = Database::query($sql);
  5934. $coachesList = Database::store_result($result);
  5935. $coachesOptions = array();
  5936. foreach ($coachesList as $coachItem) {
  5937. $coachesOptions[$coachItem['user_id']] =
  5938. api_get_person_name($coachItem['firstname'], $coachItem['lastname']).' ('.$coachItem['username'].')';
  5939. }
  5940. $form->addElement(
  5941. 'select',
  5942. 'coach_username',
  5943. get_lang('CoachName'),
  5944. $coachesOptions
  5945. );
  5946. } else {
  5947. $form->addElement(
  5948. 'select_ajax',
  5949. 'coach_username',
  5950. get_lang('CoachName'),
  5951. null,
  5952. [
  5953. 'url' => api_get_path(WEB_AJAX_PATH) . 'session.ajax.php?a=search_general_coach',
  5954. 'width' => '100%',
  5955. ]
  5956. );
  5957. }
  5958. }
  5959. $form->addRule('coach_username', get_lang('ThisFieldIsRequired'), 'required');
  5960. $form->addHtml('<div id="ajax_list_coachs"></div>');
  5961. $form->addButtonAdvancedSettings('advanced_params');
  5962. $form->addElement('html','<div id="advanced_params_options" style="display:none">');
  5963. $form->addSelect('session_category', get_lang('SessionCategory'), $categoriesOptions, array(
  5964. 'id' => 'session_category'
  5965. ));
  5966. $form->addHtmlEditor(
  5967. 'description',
  5968. get_lang('Description'),
  5969. false,
  5970. false,
  5971. array(
  5972. 'ToolbarSet' => 'Minimal',
  5973. )
  5974. );
  5975. $form->addElement('checkbox', 'show_description', null, get_lang('ShowDescription'));
  5976. $visibilityGroup = array();
  5977. $visibilityGroup[] = $form->createElement('select', 'session_visibility', null, array(
  5978. SESSION_VISIBLE_READ_ONLY => get_lang('SessionReadOnly'),
  5979. SESSION_VISIBLE => get_lang('SessionAccessible'),
  5980. SESSION_INVISIBLE => api_ucfirst(get_lang('SessionNotAccessible')),
  5981. ));
  5982. $form->addGroup($visibilityGroup, 'visibility_group', get_lang('SessionVisibility'), null, false);
  5983. $options = [
  5984. 0 => get_lang('ByDuration'),
  5985. 1 => get_lang('ByDates'),
  5986. ];
  5987. $form->addSelect('access', get_lang('Access'), $options, array(
  5988. 'onchange' => 'accessSwitcher()',
  5989. 'id' => 'access',
  5990. ));
  5991. $form->addElement('html', '<div id="duration" style="display:none">');
  5992. $form->addElement(
  5993. 'number',
  5994. 'duration',
  5995. array(
  5996. get_lang('SessionDurationTitle'),
  5997. get_lang('SessionDurationDescription'),
  5998. ),
  5999. array(
  6000. 'maxlength' => 50,
  6001. )
  6002. );
  6003. $form->addElement('html', '</div>');
  6004. $form->addElement('html', '<div id="date_fields" style="display:none">');
  6005. // Dates
  6006. $form->addDateTimePicker(
  6007. 'access_start_date',
  6008. array(get_lang('SessionStartDate'), get_lang('SessionStartDateComment')),
  6009. array('id' => 'access_start_date')
  6010. );
  6011. $form->addDateTimePicker(
  6012. 'access_end_date',
  6013. array(get_lang('SessionEndDate'), get_lang('SessionEndDateComment')),
  6014. array('id' => 'access_end_date')
  6015. );
  6016. $form->addRule(
  6017. array('access_start_date', 'access_end_date'),
  6018. get_lang('StartDateMustBeBeforeTheEndDate'),
  6019. 'compare_datetime_text',
  6020. '< allow_empty'
  6021. );
  6022. $form->addDateTimePicker(
  6023. 'display_start_date',
  6024. array(
  6025. get_lang('SessionDisplayStartDate'),
  6026. get_lang('SessionDisplayStartDateComment'),
  6027. ),
  6028. array('id' => 'display_start_date')
  6029. );
  6030. $form->addDateTimePicker(
  6031. 'display_end_date',
  6032. array(
  6033. get_lang('SessionDisplayEndDate'),
  6034. get_lang('SessionDisplayEndDateComment'),
  6035. ),
  6036. array('id' => 'display_end_date')
  6037. );
  6038. $form->addRule(
  6039. array('display_start_date', 'display_end_date'),
  6040. get_lang('StartDateMustBeBeforeTheEndDate'),
  6041. 'compare_datetime_text',
  6042. '< allow_empty'
  6043. );
  6044. $form->addDateTimePicker(
  6045. 'coach_access_start_date',
  6046. array(
  6047. get_lang('SessionCoachStartDate'),
  6048. get_lang('SessionCoachStartDateComment'),
  6049. ),
  6050. array('id' => 'coach_access_start_date')
  6051. );
  6052. $form->addDateTimePicker(
  6053. 'coach_access_end_date',
  6054. array(
  6055. get_lang('SessionCoachEndDate'),
  6056. get_lang('SessionCoachEndDateComment'),
  6057. ),
  6058. array('id' => 'coach_access_end_date')
  6059. );
  6060. $form->addRule(
  6061. array('coach_access_start_date', 'coach_access_end_date'),
  6062. get_lang('StartDateMustBeBeforeTheEndDate'),
  6063. 'compare_datetime_text',
  6064. '< allow_empty'
  6065. );
  6066. $form->addElement('html', '</div>');
  6067. $form->addCheckBox(
  6068. 'send_subscription_notification',
  6069. [
  6070. get_lang('SendSubscriptionNotification'),
  6071. get_lang('SendAnEmailWhenAUserBeingSubscribed')
  6072. ]
  6073. );
  6074. // Extra fields
  6075. $extra_field = new ExtraField('session');
  6076. $extra = $extra_field->addElements($form, $sessionId);
  6077. $form->addElement('html','</div>');
  6078. $js = $extra['jquery_ready_content'];
  6079. return ['js' => $js];
  6080. }
  6081. /**
  6082. * Gets the number of rows in the session table filtered through the given
  6083. * array of parameters
  6084. * @param array Array of options/filters/keys
  6085. * @return integer The number of rows, or false on wrong param
  6086. * @assert ('a') === false
  6087. */
  6088. static function get_count_admin_complete($options = array())
  6089. {
  6090. if (!is_array($options)) {
  6091. return false;
  6092. }
  6093. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  6094. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  6095. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  6096. $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  6097. $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
  6098. $where = 'WHERE 1 = 1 ';
  6099. $user_id = api_get_user_id();
  6100. if (api_is_session_admin() &&
  6101. api_get_setting('allow_session_admins_to_see_all_sessions') == 'false'
  6102. ) {
  6103. $where.=" WHERE s.session_admin_id = $user_id ";
  6104. }
  6105. if (!empty($options['where'])) {
  6106. $options['where'] = str_replace('course_title', 'c.title', $options['where']);
  6107. $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
  6108. $options['where'] = str_replace(
  6109. array("AND session_active = '1' )", " AND ( session_active = '1' )"),
  6110. array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
  6111. , $options['where']
  6112. );
  6113. $options['where'] = str_replace(
  6114. array("AND session_active = '0' )", " AND ( session_active = '0' )"),
  6115. array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
  6116. $options['where']
  6117. );
  6118. if (!empty($options['extra'])) {
  6119. $options['where'] = str_replace(' 1 = 1 AND', '', $options['where']);
  6120. $options['where'] = str_replace('AND', 'OR', $options['where']);
  6121. foreach ($options['extra'] as $extra) {
  6122. $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
  6123. }
  6124. }
  6125. $where .= ' AND '.$options['where'];
  6126. }
  6127. $today = api_get_utc_datetime();
  6128. $query_rows = "SELECT count(*) as total_rows, c.title as course_title, s.name,
  6129. IF (
  6130. (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
  6131. (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
  6132. (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
  6133. (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
  6134. ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
  6135. , 1, 0) as session_active
  6136. FROM $tbl_session s
  6137. LEFT JOIN $tbl_session_category sc
  6138. ON s.session_category_id = sc.id
  6139. INNER JOIN $tbl_user u
  6140. ON s.id_coach = u.user_id
  6141. INNER JOIN $sessionCourseUserTable scu
  6142. ON s.id = scu.session_id
  6143. INNER JOIN $courseTable c
  6144. ON c.id = scu.c_id
  6145. $where ";
  6146. if (api_is_multiple_url_enabled()) {
  6147. $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  6148. $access_url_id = api_get_current_access_url_id();
  6149. if ($access_url_id != -1) {
  6150. $where.= " AND ar.access_url_id = $access_url_id ";
  6151. $query_rows = "SELECT count(*) as total_rows
  6152. FROM $tbl_session s
  6153. LEFT JOIN $tbl_session_category sc
  6154. ON s.session_category_id = sc.id
  6155. INNER JOIN $tbl_user u
  6156. ON s.id_coach = u.user_id
  6157. INNER JOIN $table_access_url_rel_session ar
  6158. ON ar.session_id = s.id $where ";
  6159. }
  6160. }
  6161. $result = Database::query($query_rows);
  6162. $num = 0;
  6163. if (Database::num_rows($result)) {
  6164. $rows = Database::fetch_array($result);
  6165. $num = $rows['total_rows'];
  6166. }
  6167. return $num;
  6168. }
  6169. /**
  6170. * @param string $list_type
  6171. * @return array
  6172. */
  6173. public static function getGridColumns($list_type = 'simple')
  6174. {
  6175. // Column config
  6176. $operators = array('cn', 'nc');
  6177. $date_operators = array('gt', 'ge', 'lt', 'le');
  6178. switch ($list_type) {
  6179. case 'simple':
  6180. $columns = array(
  6181. get_lang('Name'),
  6182. get_lang('Category'),
  6183. get_lang('SessionDisplayStartDate'),
  6184. get_lang('SessionDisplayEndDate'),
  6185. //get_lang('Coach'),
  6186. //get_lang('Status'),
  6187. //get_lang('CourseTitle'),
  6188. get_lang('Visibility'),
  6189. );
  6190. $column_model = array (
  6191. array('name'=>'name', 'index'=>'s.name', 'width'=>'160', 'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
  6192. array('name'=>'category_name', 'index'=>'category_name', 'width'=>'40', 'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
  6193. array('name'=>'display_start_date', 'index'=>'display_start_date', 'width'=>'50', 'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_today', 'sopt' => $date_operators)),
  6194. array('name'=>'display_end_date', 'index'=>'display_end_date', 'width'=>'50', 'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_one_month', 'sopt' => $date_operators)),
  6195. array('name'=>'visibility', 'index'=>'visibility', 'width'=>'40', 'align'=>'left', 'search' => 'false'),
  6196. );
  6197. break;
  6198. case 'complete':
  6199. $columns = array(
  6200. get_lang('Name'),
  6201. get_lang('SessionDisplayStartDate'),
  6202. get_lang('SessionDisplayEndDate'),
  6203. get_lang('Coach'),
  6204. get_lang('Status'),
  6205. get_lang('Visibility'),
  6206. get_lang('CourseTitle'),
  6207. );
  6208. $column_model = array (
  6209. array('name'=>'name', 'index'=>'s.name', 'width'=>'200', 'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
  6210. array('name'=>'display_start_date', 'index'=>'display_start_date', 'width'=>'70', 'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_today', 'sopt' => $date_operators)),
  6211. array('name'=>'display_end_date', 'index'=>'display_end_date', 'width'=>'70', 'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_one_month', 'sopt' => $date_operators)),
  6212. array('name'=>'coach_name', 'index'=>'coach_name', 'width'=>'70', 'align'=>'left', 'search' => 'false', 'searchoptions' => array('sopt' => $operators)),
  6213. array('name'=>'session_active', 'index'=>'session_active', 'width'=>'25', 'align'=>'left', 'search' => 'true', 'stype'=>'select',
  6214. // for the bottom bar
  6215. 'searchoptions' => array(
  6216. 'defaultValue' => '1',
  6217. 'value' => '1:'.get_lang('Active').';0:'.get_lang('Inactive')),
  6218. // for the top bar
  6219. 'editoptions' => array('value' => '" ":'.get_lang('All').';1:'.get_lang('Active').';0:'.get_lang('Inactive')),
  6220. ),
  6221. array('name'=>'visibility', 'index'=>'visibility', 'width'=>'40', 'align'=>'left', 'search' => 'false'),
  6222. array('name'=>'course_title', 'index'=>'course_title', 'width'=>'50', 'hidden' => 'true', 'search' => 'true', 'searchoptions' => array('searchhidden' =>'true','sopt' => $operators)),
  6223. );
  6224. break;
  6225. }
  6226. // Inject extra session fields
  6227. $session_field = new ExtraField('session');
  6228. $rules = $session_field->getRules($columns, $column_model);
  6229. $column_model[] = array('name'=>'actions', 'index'=>'actions', 'width'=>'80', 'align'=>'left','formatter'=>'action_formatter','sortable'=>'false', 'search' => 'false');
  6230. $columns[] = get_lang('Actions');
  6231. foreach ($column_model as $col_model) {
  6232. $simple_column_name[] = $col_model['name'];
  6233. }
  6234. $return_array = array(
  6235. 'columns' => $columns,
  6236. 'column_model' => $column_model,
  6237. 'rules' => $rules,
  6238. 'simple_column_name' => $simple_column_name,
  6239. );
  6240. return $return_array;
  6241. }
  6242. /**
  6243. * Converts all dates sent through the param array (given form) to correct dates with timezones
  6244. * @param array The dates The same array, with times converted
  6245. * @param boolean $applyFormat Whether apply the DATE_TIME_FORMAT_SHORT format for sessions
  6246. * @return array The same array, with times converted
  6247. */
  6248. static function convert_dates_to_local($params, $applyFormat = false)
  6249. {
  6250. if (!is_array($params)) {
  6251. return false;
  6252. }
  6253. $params['display_start_date'] = api_get_local_time($params['display_start_date'], null, null, true);
  6254. $params['display_end_date'] = api_get_local_time($params['display_end_date'], null, null, true);
  6255. $params['access_start_date'] = api_get_local_time($params['access_start_date'], null, null, true);
  6256. $params['access_end_date'] = api_get_local_time($params['access_end_date'], null, null, true);
  6257. $params['coach_access_start_date'] = isset($params['coach_access_start_date']) ? api_get_local_time($params['coach_access_start_date'], null, null, true) : null;
  6258. $params['coach_access_end_date'] = isset($params['coach_access_end_date']) ? api_get_local_time($params['coach_access_end_date'], null, null, true) : null;
  6259. if ($applyFormat) {
  6260. if (isset($params['display_start_date'])) {
  6261. $params['display_start_date'] = api_format_date($params['display_start_date'], DATE_TIME_FORMAT_SHORT);
  6262. }
  6263. if (isset($params['display_end_date'])) {
  6264. $params['display_end_date'] = api_format_date($params['display_end_date'], DATE_TIME_FORMAT_SHORT);
  6265. }
  6266. if (isset($params['access_start_date'])) {
  6267. $params[''] = api_format_date($params['access_start_date'], DATE_TIME_FORMAT_SHORT);
  6268. }
  6269. if (isset($params['access_end_date'])) {
  6270. $params['access_end_date'] = api_format_date($params['access_end_date'], DATE_TIME_FORMAT_SHORT);
  6271. }
  6272. if (isset($params['coach_access_start_date'])) {
  6273. $params['coach_access_start_date'] = api_format_date($params['coach_access_start_date'], DATE_TIME_FORMAT_SHORT);
  6274. }
  6275. if (isset($params['coach_access_end_date'])) {
  6276. $params['coach_access_end_date'] = api_format_date($params['coach_access_end_date'], DATE_TIME_FORMAT_SHORT);
  6277. }
  6278. }
  6279. return $params;
  6280. }
  6281. /**
  6282. * Gets the admin session list callback of the session/session_list.php
  6283. * page with all user/details in the right fomat
  6284. * @param array
  6285. * @result array Array of rows results
  6286. * @asset ('a') === false
  6287. */
  6288. public static function get_sessions_admin_complete($options = array())
  6289. {
  6290. if (!is_array($options)) {
  6291. return false;
  6292. }
  6293. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  6294. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  6295. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  6296. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  6297. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  6298. $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
  6299. $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
  6300. $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
  6301. $where = 'WHERE 1 = 1 ';
  6302. $user_id = api_get_user_id();
  6303. if (!api_is_platform_admin()) {
  6304. if (api_is_session_admin() &&
  6305. api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
  6306. ) {
  6307. $where.=" AND s.session_admin_id = $user_id ";
  6308. }
  6309. }
  6310. $coach_name = " CONCAT(u.lastname , ' ', u.firstname) as coach_name ";
  6311. if (api_is_western_name_order()) {
  6312. $coach_name = " CONCAT(u.firstname, ' ', u.lastname) as coach_name ";
  6313. }
  6314. $today = api_get_utc_datetime();
  6315. $inject_extra_fields = null;
  6316. $extra_fields = array();
  6317. $extra_fields_info = array();
  6318. //for now only sessions
  6319. $extra_field = new ExtraField('session');
  6320. $double_fields = array();
  6321. $extra_field_option = new ExtraFieldOption('session');
  6322. if (isset($options['extra'])) {
  6323. $extra_fields = $options['extra'];
  6324. if (!empty($extra_fields)) {
  6325. foreach ($extra_fields as $extra) {
  6326. $inject_extra_fields .= " IF (fv.field_id = {$extra['id']}, fvo.option_display_text, NULL ) as {$extra['field']} , ";
  6327. if (isset($extra_fields_info[$extra['id']])) {
  6328. $info = $extra_fields_info[$extra['id']];
  6329. } else {
  6330. $info = $extra_field->get($extra['id']);
  6331. $extra_fields_info[$extra['id']] = $info;
  6332. }
  6333. if ($info['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
  6334. $double_fields[$info['id']] = $info;
  6335. }
  6336. }
  6337. }
  6338. }
  6339. $options_by_double = array();
  6340. foreach ($double_fields as $double) {
  6341. $my_options = $extra_field_option->get_field_options_by_field(
  6342. $double['id'],
  6343. true
  6344. );
  6345. $options_by_double['extra_'.$double['field_variable']] = $my_options;
  6346. }
  6347. //sc.name as category_name,
  6348. $select = "
  6349. SELECT * FROM (
  6350. SELECT DISTINCT
  6351. IF (
  6352. (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
  6353. (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
  6354. (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
  6355. (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
  6356. ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
  6357. , 1, 0) as session_active,
  6358. s.name,
  6359. s.nbr_courses,
  6360. s.nbr_users,
  6361. s.display_start_date,
  6362. s.display_end_date,
  6363. $coach_name,
  6364. access_start_date,
  6365. access_end_date,
  6366. s.visibility,
  6367. u.user_id,
  6368. $inject_extra_fields
  6369. c.title as course_title,
  6370. s.id ";
  6371. if (!empty($options['where'])) {
  6372. if (!empty($options['extra'])) {
  6373. $options['where'] = str_replace(' 1 = 1 AND', '', $options['where']);
  6374. $options['where'] = str_replace('AND', 'OR', $options['where']);
  6375. foreach ($options['extra'] as $extra) {
  6376. $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
  6377. }
  6378. }
  6379. $options['where'] = str_replace('course_title', 'c.title', $options['where']);
  6380. $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
  6381. $options['where'] = str_replace(
  6382. array("AND session_active = '1' )", " AND ( session_active = '1' )"),
  6383. array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
  6384. , $options['where']
  6385. );
  6386. $options['where'] = str_replace(
  6387. array("AND session_active = '0' )", " AND ( session_active = '0' )"),
  6388. array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
  6389. $options['where']
  6390. );
  6391. $where .= ' AND '.$options['where'];
  6392. }
  6393. if (!empty($options['limit'])) {
  6394. $where .= " LIMIT ".$options['limit'];
  6395. }
  6396. $query = "$select FROM $tbl_session s
  6397. LEFT JOIN $tbl_session_field_values fv
  6398. ON (fv.item_id = s.id)
  6399. LEFT JOIN $extraFieldTable f
  6400. ON f.id = fv.field_id
  6401. LEFT JOIN $tbl_session_field_options fvo
  6402. ON (fv.field_id = fvo.field_id)
  6403. LEFT JOIN $tbl_session_rel_course src
  6404. ON (src.session_id = s.id)
  6405. LEFT JOIN $tbl_course c
  6406. ON (src.c_id = c.id)
  6407. LEFT JOIN $tbl_session_category sc
  6408. ON (s.session_category_id = sc.id)
  6409. INNER JOIN $tbl_user u
  6410. ON (s.id_coach = u.user_id) ".
  6411. $where;
  6412. if (api_is_multiple_url_enabled()) {
  6413. $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  6414. $access_url_id = api_get_current_access_url_id();
  6415. if ($access_url_id != -1) {
  6416. $where.= " AND ar.access_url_id = $access_url_id ";
  6417. $query = "$select
  6418. FROM $tbl_session s
  6419. LEFT JOIN $tbl_session_field_values fv ON (fv.session_id = s.id)
  6420. LEFT JOIN $tbl_session_field_options fvo ON (fv.field_id = fvo.field_id)
  6421. LEFT JOIN $tbl_session_rel_course src ON (src.id_session = s.id)
  6422. LEFT JOIN $tbl_course c ON (src.c_id = c.id)
  6423. LEFT JOIN $tbl_session_category sc ON (s.session_category_id = sc.id)
  6424. INNER JOIN $tbl_user u ON (s.id_coach = u.user_id)
  6425. INNER JOIN $table_access_url_rel_session ar ON (ar.session_id = s.id)
  6426. $where";
  6427. }
  6428. }
  6429. $query .= ") AS session_table";
  6430. if (!empty($options['order'])) {
  6431. $query .= " ORDER BY ".$options['order'];
  6432. }
  6433. //error_log($query);
  6434. //echo $query;
  6435. $result = Database::query($query);
  6436. $formatted_sessions = array();
  6437. if (Database::num_rows($result)) {
  6438. $sessions = Database::store_result($result, 'ASSOC');
  6439. foreach ($sessions as $session) {
  6440. $session_id = $session['id'];
  6441. $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
  6442. $session['coach_name'] = Display::url($session['coach_name'], "user_information.php?user_id=".$session['user_id']);
  6443. if ($session['session_active'] == 1) {
  6444. $session['session_active'] = Display::return_icon('accept.png', get_lang('Active'), array(), ICON_SIZE_SMALL);
  6445. } else {
  6446. $session['session_active'] = Display::return_icon('error.png', get_lang('Inactive'), array(), ICON_SIZE_SMALL);
  6447. }
  6448. $session = self::convert_dates_to_local($session);
  6449. switch ($session['visibility']) {
  6450. case SESSION_VISIBLE_READ_ONLY: //1
  6451. $session['visibility'] = get_lang('ReadOnly');
  6452. break;
  6453. case SESSION_VISIBLE: //2
  6454. case SESSION_AVAILABLE: //4
  6455. $session['visibility'] = get_lang('Visible');
  6456. break;
  6457. case SESSION_INVISIBLE: //3
  6458. $session['visibility'] = api_ucfirst(get_lang('Invisible'));
  6459. break;
  6460. }
  6461. // Cleaning double selects
  6462. foreach ($session as $key => &$value) {
  6463. if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
  6464. $options = explode('::', $value);
  6465. }
  6466. $original_key = $key;
  6467. if (strpos($key, '_second') === false) {
  6468. } else {
  6469. $key = str_replace('_second', '', $key);
  6470. }
  6471. if (isset($options_by_double[$key])) {
  6472. if (isset($options[0])) {
  6473. if (isset($options_by_double[$key][$options[0]])) {
  6474. if (strpos($original_key, '_second') === false) {
  6475. $value = $options_by_double[$key][$options[0]]['option_display_text'];
  6476. } else {
  6477. $value = $options_by_double[$key][$options[1]]['option_display_text'];
  6478. }
  6479. }
  6480. }
  6481. }
  6482. }
  6483. // Magic filter
  6484. if (isset($formatted_sessions[$session_id])) {
  6485. $formatted_sessions[$session_id] = self::compareArraysToMerge($formatted_sessions[$session_id], $session);
  6486. } else {
  6487. $formatted_sessions[$session_id] = $session;
  6488. }
  6489. }
  6490. }
  6491. return $formatted_sessions;
  6492. }
  6493. /**
  6494. * Compare two arrays
  6495. * @param array $array1
  6496. * @param array $array2
  6497. *
  6498. * @return array
  6499. */
  6500. static function compareArraysToMerge($array1, $array2)
  6501. {
  6502. if (empty($array2)) {
  6503. return $array1;
  6504. }
  6505. foreach ($array1 as $key => $item) {
  6506. if (!isset($array1[$key])) {
  6507. //My string is empty try the other one
  6508. if (isset($array2[$key]) && !empty($array2[$key])) {
  6509. $array1[$key] = $array2[$key];
  6510. }
  6511. }
  6512. }
  6513. return $array1;
  6514. }
  6515. /**
  6516. * Get link to the admin page for this session
  6517. * @param int $id Session ID
  6518. * @return mixed URL to the admin page to manage the session, or false on error
  6519. */
  6520. public static function getAdminPath($id)
  6521. {
  6522. $id = intval($id);
  6523. $session = self::fetch($id);
  6524. if (empty($session)) {
  6525. return false;
  6526. }
  6527. return api_get_path(WEB_CODE_PATH) . 'session/resume_session.php?id_session=' . $id;
  6528. }
  6529. /**
  6530. * Get link to the user page for this session.
  6531. * If a course is provided, build the link to the course
  6532. * @param int $id Session ID
  6533. * @param int $courseId Course ID (optional) in case the link has to send straight to the course
  6534. * @return mixed URL to the page to use the session, or false on error
  6535. */
  6536. public static function getPath($id, $courseId = 0)
  6537. {
  6538. $id = intval($id);
  6539. $session = self::fetch($id);
  6540. if (empty($session)) {
  6541. return false;
  6542. }
  6543. if (empty($courseId)) {
  6544. return api_get_path(WEB_CODE_PATH) . 'session/index.php?session_id=' . $id;
  6545. } else {
  6546. $courseInfo = api_get_course_info_by_id($courseId);
  6547. if ($courseInfo) {
  6548. return $courseInfo['course_public_url'].'?id_session='.$id;
  6549. }
  6550. }
  6551. return false;
  6552. }
  6553. /**
  6554. * Return an associative array 'id_course' => [id_session1, id_session2...]
  6555. * where course id_course is in sessions id_session1, id_session2
  6556. * for course where user is coach
  6557. * i.e. coach for the course or
  6558. * main coach for a session the course is in
  6559. * for a session category (or woth no session category if empty)
  6560. *
  6561. * @param $userId
  6562. *
  6563. * @return array
  6564. */
  6565. public static function getSessionCourseForUser($userId)
  6566. {
  6567. // list of COURSES where user is COURSE session coach
  6568. $listCourseCourseCoachSession = self::getCoursesForCourseSessionCoach($userId);
  6569. // list of courses where user is MAIN session coach
  6570. $listCourseMainCoachSession = self::getCoursesForMainSessionCoach($userId);
  6571. // merge these 2 array
  6572. $listResCourseSession = $listCourseCourseCoachSession;
  6573. foreach ($listCourseMainCoachSession as $courseId2 => $listSessionId2) {
  6574. if (isset($listResCourseSession[$courseId2])) {
  6575. // if sessionId array exists for this course
  6576. // same courseId, merge the list of session
  6577. foreach ($listCourseMainCoachSession[$courseId2] as $i => $sessionId2) {
  6578. if (!in_array($sessionId2, $listResCourseSession[$courseId2])) {
  6579. $listResCourseSession[$courseId2][] = $sessionId2;
  6580. }
  6581. }
  6582. } else {
  6583. $listResCourseSession[$courseId2] = $listSessionId2;
  6584. }
  6585. }
  6586. return $listResCourseSession;
  6587. }
  6588. /**
  6589. * Return an associative array 'id_course' => [id_session1, id_session2...]
  6590. * where course id_course is in sessions id_session1, id_session2
  6591. * @param $userId
  6592. *
  6593. * @return array
  6594. */
  6595. public static function getCoursesForCourseSessionCoach($userId)
  6596. {
  6597. $listResCourseSession = array();
  6598. $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
  6599. $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  6600. $sql = "SELECT session_id, c_id, c.id
  6601. FROM $tblSessionRelCourseRelUser srcru
  6602. LEFT JOIN $tblCourse c
  6603. ON c.id = srcru.c_id
  6604. WHERE
  6605. srcru.user_id =".intval($userId)." AND
  6606. srcru.status = 2";
  6607. $res = Database::query($sql);
  6608. while ($data = Database::fetch_assoc($res)) {
  6609. if (self::isSessionDateOkForCoach($data['session_id'])) {
  6610. if (!isset($listResCourseSession[$data['id']])) {
  6611. $listResCourseSession[$data['id']] = array();
  6612. }
  6613. $listResCourseSession[$data['id']][] = $data['session_id'];
  6614. }
  6615. }
  6616. return $listResCourseSession;
  6617. }
  6618. /**
  6619. * Return true if coach is allowed to access this session
  6620. * @param int $sessionId
  6621. * @return bool
  6622. */
  6623. public static function isSessionDateOkForCoach($sessionId)
  6624. {
  6625. return api_get_session_visibility($sessionId);
  6626. /*
  6627. $listSessionInfo = api_get_session_info($sessionId);
  6628. $dateStart = $listSessionInfo['date_start'];
  6629. $dateEnd = $listSessionInfo['date_end'];
  6630. $nbDaysAccessBeforeBeginning = $listSessionInfo['nb_days_access_before_beginning'];
  6631. $nbDaysAccessAfterEnd = $listSessionInfo['nb_days_access_after_end'];
  6632. // no start date
  6633. if ($dateStart == '0000-00-00') {
  6634. return true;
  6635. }
  6636. $now = time();
  6637. $dateStartForCoach = api_strtotime($dateStart.' 00:00:00') - ($nbDaysAccessBeforeBeginning * 86400);
  6638. $dateEndForCoach = api_strtotime($dateEnd.' 00:00:00') + ($nbDaysAccessAfterEnd * 86400);
  6639. if ($dateEnd == '0000-00-00') {
  6640. // start date but no end date
  6641. if ($dateStartForCoach <= $now) {
  6642. return true;
  6643. }
  6644. } else {
  6645. // start date and end date
  6646. if ($dateStartForCoach <= $now && $now <= $dateEndForCoach) {
  6647. return true;
  6648. }
  6649. }
  6650. return false;*/
  6651. }
  6652. /**
  6653. * Return an associative array 'id_course' => [id_session1, id_session2...]
  6654. * where course id_course is in sessions id_session1, id_session2
  6655. * @param $userId
  6656. *
  6657. * @return array
  6658. */
  6659. public static function getCoursesForMainSessionCoach($userId)
  6660. {
  6661. $listResCourseSession = array();
  6662. $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
  6663. // list of SESSION where user is session coach
  6664. $sql = "SELECT id FROM $tblSession
  6665. WHERE id_coach = ".intval($userId);
  6666. $res = Database::query($sql);
  6667. while ($data = Database::fetch_assoc($res)) {
  6668. $sessionId = $data['id'];
  6669. $listCoursesInSession = self::getCoursesInSession($sessionId);
  6670. foreach ($listCoursesInSession as $i => $courseId) {
  6671. if (self::isSessionDateOkForCoach($sessionId)) {
  6672. if (!isset($listResCourseSession[$courseId])) {
  6673. $listResCourseSession[$courseId] = array();
  6674. }
  6675. $listResCourseSession[$courseId][] = $sessionId;
  6676. }
  6677. }
  6678. }
  6679. return $listResCourseSession;
  6680. }
  6681. /**
  6682. * Return an array of course_id used in session $sessionId
  6683. * @param $sessionId
  6684. *
  6685. * @return array
  6686. */
  6687. public static function getCoursesInSession($sessionId)
  6688. {
  6689. $listResultsCourseId = array();
  6690. $tblSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  6691. $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
  6692. // list of course in this session
  6693. $sql = "SELECT session_id, c.id
  6694. FROM $tblSessionRelCourse src
  6695. LEFT JOIN $tblCourse c
  6696. ON c.id = src.c_id
  6697. WHERE session_id = ".intval($sessionId);
  6698. $res = Database::query($sql);
  6699. while ($data = Database::fetch_assoc($res)) {
  6700. $listResultsCourseId[] = $data['id'];
  6701. }
  6702. return $listResultsCourseId;
  6703. }
  6704. /**
  6705. * Return an array of courses in session for user
  6706. * and for each courses the list of session that use this course for user
  6707. *
  6708. * [0] => array
  6709. * userCatId
  6710. * userCatTitle
  6711. * courseInUserCatList
  6712. * [0] => array
  6713. * courseId
  6714. * title
  6715. * courseCode
  6716. * sessionCatList
  6717. * [0] => array
  6718. * catSessionId
  6719. * catSessionName
  6720. * sessionList
  6721. * [0] => array
  6722. * sessionId
  6723. * sessionName
  6724. *
  6725. * @param $userId
  6726. *
  6727. * @return array
  6728. *
  6729. */
  6730. public static function getNamedSessionCourseForCoach($userId)
  6731. {
  6732. $listResults = array();
  6733. $listCourseSession = self::getSessionCourseForUser($userId);
  6734. foreach ($listCourseSession as $courseId => $listSessionId) {
  6735. // Course info
  6736. $courseInfo = api_get_course_info_by_id($courseId);
  6737. $listOneCourse = array();
  6738. $listOneCourse['courseId'] = $courseId;
  6739. $listOneCourse['title'] = $courseInfo['title'];
  6740. //$listOneCourse['courseCode'] = $courseInfo['code'];
  6741. $listOneCourse['course'] = $courseInfo;
  6742. $listOneCourse['sessionCatList'] = array();
  6743. $listCat = array();
  6744. foreach ($listSessionId as $i => $sessionId) {
  6745. // here we got all session for this course
  6746. // lets check there session categories
  6747. $sessionInfo = SessionManager::fetch($sessionId);
  6748. $catId = $sessionInfo['session_category_id'];
  6749. if (!isset($listCat[$catId])) {
  6750. $listCatInfo = self::get_session_category($catId);
  6751. $listCat[$catId] = array();
  6752. $listCat[$catId]['catSessionId'] = $catId;
  6753. $listCat[$catId]['catSessionName'] = $listCatInfo['name'];
  6754. $listCat[$catId]['sessionList'] = array();
  6755. }
  6756. $listSessionInfo = SessionManager::fetch($sessionId);
  6757. $listSessionIdName = array(
  6758. "sessionId" => $sessionId,
  6759. "sessionName" => $listSessionInfo['name'],
  6760. );
  6761. $listCat[$catId]['sessionList'][] = $listSessionIdName;
  6762. }
  6763. // sort $listCat by catSessionName
  6764. usort($listCat, 'self::compareBySessionName');
  6765. // in each catSession sort sessionList by sessionName
  6766. foreach($listCat as $i => $listCatSessionInfo) {
  6767. $listSessionList = $listCatSessionInfo['sessionList'];
  6768. usort($listSessionList, 'self::compareCatSessionInfo');
  6769. $listCat[$i]['sessionList'] = $listSessionList;
  6770. }
  6771. $listOneCourse['sessionCatList'] = $listCat;
  6772. // user course category
  6773. list($userCatId, $userCatTitle) = CourseManager::getUserCourseCategoryForCourse(
  6774. $userId,
  6775. $courseId
  6776. );
  6777. $userCatId = intval($userCatId);
  6778. $listResults[$userCatId]['courseInUserCategoryId'] = $userCatId;
  6779. $listResults[$userCatId]['courseInUserCategoryTitle'] = $userCatTitle;
  6780. $listResults[$userCatId]['courseInUserCatList'][] = $listOneCourse;
  6781. }
  6782. // sort by user course cat
  6783. uasort($listResults, 'self::compareByUserCourseCat');
  6784. // sort by course title
  6785. foreach ($listResults as $userCourseCatId => $tabCoursesInCat) {
  6786. $courseInUserCatList = $tabCoursesInCat['courseInUserCatList'];
  6787. uasort($courseInUserCatList, 'self::compareByCourse');
  6788. $listResults[$userCourseCatId]['courseInUserCatList'] = $courseInUserCatList;
  6789. }
  6790. return $listResults;
  6791. }
  6792. /**
  6793. * @param array $listA
  6794. * @param array $listB
  6795. * @return int
  6796. */
  6797. private static function compareCatSessionInfo($listA, $listB)
  6798. {
  6799. if ($listA['sessionName'] == $listB['sessionName']) {
  6800. return 0;
  6801. } else if($listA['sessionName'] > $listB['sessionName']) {
  6802. return 1;
  6803. } else {
  6804. return -1;
  6805. }
  6806. }
  6807. /**
  6808. * @param array $listA
  6809. * @param array $listB
  6810. * @return int
  6811. */
  6812. private static function compareBySessionName($listA, $listB)
  6813. {
  6814. if ($listB['catSessionName'] == '') {
  6815. return -1;
  6816. } else if ($listA['catSessionName'] == '') {
  6817. return 1;
  6818. } else if ($listA['catSessionName'] == $listB['catSessionName']) {
  6819. return 0;
  6820. } else if($listA['catSessionName'] > $listB['catSessionName']) {
  6821. return 1;
  6822. } else {
  6823. return -1;
  6824. }
  6825. }
  6826. /**
  6827. * @param array $listA
  6828. * @param array $listB
  6829. * @return int
  6830. */
  6831. private static function compareByUserCourseCat($listA, $listB)
  6832. {
  6833. if ($listA['courseInUserCategoryTitle'] == $listB['courseInUserCategoryTitle']) {
  6834. return 0;
  6835. } else if($listA['courseInUserCategoryTitle'] > $listB['courseInUserCategoryTitle']) {
  6836. return 1;
  6837. } else {
  6838. return -1;
  6839. }
  6840. }
  6841. /**
  6842. * @param array $listA
  6843. * @param array $listB
  6844. * @return int
  6845. */
  6846. private static function compareByCourse($listA, $listB)
  6847. {
  6848. if ($listA['title'] == $listB['title']) {
  6849. return 0;
  6850. } else if($listA['title'] > $listB['title']) {
  6851. return 1;
  6852. } else {
  6853. return -1;
  6854. }
  6855. }
  6856. /**
  6857. * Return HTML code for displaying session_course_for_coach
  6858. * @param $userId
  6859. * @return string
  6860. */
  6861. public static function getHtmlNamedSessionCourseForCoach($userId)
  6862. {
  6863. $htmlRes = '';
  6864. $listInfo = self::getNamedSessionCourseForCoach($userId);
  6865. foreach ($listInfo as $i => $listCoursesInfo) {
  6866. $courseInfo = $listCoursesInfo['course'];
  6867. $courseCode = $listCoursesInfo['course']['code'];
  6868. $listParamsCourse = array();
  6869. $listParamsCourse['icon'] = '<div style="float:left">
  6870. <input style="border:none;" type="button" onclick="$(\'#course-'.$courseCode.'\').toggle(\'fast\')" value="+" /></div>'.
  6871. Display::return_icon('blackboard.png', $courseInfo['title'], array(), ICON_SIZE_LARGE);
  6872. $listParamsCourse['link'] = '';
  6873. $listParamsCourse['title'] = Display::tag(
  6874. 'a',
  6875. $courseInfo['title'],
  6876. array('href' => $listParamsCourse['link'])
  6877. );
  6878. $htmlCourse = '<div class="well" style="border-color:#27587D">'.
  6879. CourseManager::course_item_html($listParamsCourse, true);
  6880. // for each category of session
  6881. $htmlCatSessions = '';
  6882. foreach ($listCoursesInfo['sessionCatList'] as $j => $listCatSessionsInfo) {
  6883. // we got an array of session categories
  6884. $catSessionId = $listCoursesInfo['sessionCatList'][$j]['catSessionId'];
  6885. $catSessionName = $listCoursesInfo['sessionCatList'][$j]['catSessionName'];
  6886. $listParamsCatSession['icon'] = Display::return_icon('folder_blue.png', $catSessionName, array(), ICON_SIZE_LARGE);
  6887. $listParamsCatSession['link'] = '';
  6888. $listParamsCatSession['title'] = $catSessionName;
  6889. $marginShift = 20;
  6890. if ($catSessionName != '') {
  6891. $htmlCatSessions .= '<div style="margin-left:'.$marginShift.'px;">' .
  6892. CourseManager::course_item_html($listParamsCatSession, true) . '</div>';
  6893. $marginShift = 40;
  6894. }
  6895. // for each sessions
  6896. $listCatSessionSessionList = $listCoursesInfo['sessionCatList'][$j]['sessionList'];
  6897. $htmlSession = '';
  6898. foreach ($listCatSessionSessionList as $k => $listSessionInfo) {
  6899. // we got an array of session info
  6900. $sessionId = $listSessionInfo['sessionId'];
  6901. $sessionName = $listSessionInfo['sessionName'];
  6902. $listParamsSession['icon'] = Display::return_icon('blackboard_blue.png', $sessionName, array(), ICON_SIZE_LARGE);
  6903. $listParamsSession['link'] = '';
  6904. $linkToCourseSession = $courseInfo['course_public_url'].'?id_session='.$sessionId;
  6905. $listParamsSession['title'] =
  6906. $sessionName.'<div style="font-weight:normal; font-style:italic">
  6907. <a href="'.$linkToCourseSession.'">'.get_lang('GoToCourseInsideSession').'</a>
  6908. </div>';
  6909. $htmlSession .= '<div style="margin-left:'.$marginShift.'px;">'.
  6910. CourseManager::course_item_html($listParamsSession, true).'</div>';
  6911. }
  6912. $htmlCatSessions .= $htmlSession;
  6913. }
  6914. $htmlRes .= $htmlCourse.'<div style="display:none" id="course-'.$courseCode.'">'.$htmlCatSessions.'</div></div>';
  6915. }
  6916. return $htmlRes;
  6917. }
  6918. /**
  6919. * @todo Add constatns in a DB table
  6920. */
  6921. static function get_session_change_user_reasons()
  6922. {
  6923. return array(
  6924. self::SESSION_CHANGE_USER_REASON_SCHEDULE => get_lang(
  6925. 'ScheduleChanged'
  6926. ),
  6927. self::SESSION_CHANGE_USER_REASON_CLASSROOM => get_lang(
  6928. 'ClassRoomChanged'
  6929. ),
  6930. self::SESSION_CHANGE_USER_REASON_LOCATION => get_lang(
  6931. 'LocationChanged'
  6932. ),
  6933. //self::SESSION_CHANGE_USER_REASON_ENROLLMENT_ANNULATION => get_lang('EnrollmentAnnulation'),
  6934. );
  6935. }
  6936. /**
  6937. * Gets the reason name
  6938. * @param int $id reason id
  6939. */
  6940. static function get_session_change_user_reason($id)
  6941. {
  6942. $reasons = self::get_session_change_user_reasons();
  6943. return isset($reasons[$id]) ? $reasons[$id] : null;
  6944. }
  6945. }