forumfunction.inc.php 203 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * These files are a complete rework of the forum. The database structure is
  5. * based on phpBB but all the code is rewritten. A lot of new functionalities
  6. * are added:
  7. * - forum categories and forums can be sorted up or down, locked or made invisible
  8. * - consistent and integrated forum administration
  9. * - forum options: are students allowed to edit their post?
  10. * moderation of posts (approval)
  11. * reply only forums (students cannot create new threads)
  12. * multiple forums per group
  13. * - sticky messages
  14. * - new view option: nested view
  15. * - quoting a message
  16. *
  17. * @package chamilo.forum
  18. *
  19. * @todo several functions have to be moved to the itemmanager library
  20. * @todo displaying icons => display library
  21. * @todo complete the missing phpdoc the correct order should be
  22. */
  23. /**
  24. * code
  25. */
  26. use \ChamiloSession as Session;
  27. require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/gradebook_functions.inc.php';
  28. get_notifications_of_user();
  29. /* Javascript */
  30. $htmlHeadXtra[] = '<script type="text/javascript">
  31. function setFocus(){
  32. $("#forum_title").focus();
  33. $("#category_title").focus();
  34. $("#search_title").focus();
  35. }
  36. $(document).ready(function () {
  37. setFocus();
  38. });
  39. </script>';
  40. /**
  41. * This function handles all the forum and forumcategories actions. This is a wrapper for the
  42. * forum and forum categories. All this code code could go into the section where this function is
  43. * called but this make the code there cleaner.
  44. * @param int Learning path ID
  45. * @return void
  46. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  47. * @author Juan Carlos Raña Trabado (return to lp_id)
  48. * @version may 2011, Chamilo 1.8.8
  49. */
  50. function handle_forum_and_forumcategories($lp_id = null)
  51. {
  52. $action_forum_cat = isset($_GET['action']) ? $_GET['action'] : '';
  53. $post_submit_cat = isset($_POST['SubmitForumCategory']) ? true : false;
  54. $post_submit_forum = isset($_POST['SubmitForum']) ? true : false;
  55. $get_id = isset($_GET['id']) ? $_GET['id'] : '';
  56. // Adding a forum category
  57. if (($action_forum_cat == 'add' && $_GET['content'] == 'forumcategory') || $post_submit_cat) {
  58. show_add_forumcategory_form(array(), $lp_id); //$lp_id when is called from learning path
  59. }
  60. // Adding a forum
  61. if ((($action_forum_cat == 'add' || $action_forum_cat == 'edit') && $_GET['content'] == 'forum') || $post_submit_forum) {
  62. if ($action_forum_cat == 'edit' && $get_id || $post_submit_forum) {
  63. $inputvalues = get_forums(intval($get_id)); // Note: This has to be cleaned first.
  64. } else {
  65. $inputvalues = array();
  66. }
  67. show_add_forum_form($inputvalues, $lp_id);
  68. }
  69. // Edit a forum category
  70. if (($action_forum_cat == 'edit' && $_GET['content'] == 'forumcategory' && isset($_GET['id'])) || (isset($_POST['SubmitEditForumCategory'])) ? true : false) {
  71. $forum_category = get_forum_categories(strval(intval($_GET['id']))); // Note: This has to be cleaned first.
  72. show_edit_forumcategory_form($forum_category);
  73. }
  74. // Delete a forum category
  75. if ((isset($_GET['action']) && $_GET['action'] == 'delete') && isset($_GET['content']) && $get_id) {
  76. $id_forum = intval($get_id);
  77. $list_threads = get_threads($id_forum);
  78. for ($i = 0; $i < count($list_threads); $i++) {
  79. delete_forum_forumcategory_thread('thread', $list_threads[$i]['thread_id']);
  80. require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/gradebook_functions.inc.php';
  81. $link_info = is_resource_in_course_gradebook(
  82. api_get_course_id(),
  83. 5,
  84. intval($list_threads[$i]['thread_id']),
  85. api_get_session_id()
  86. );
  87. if ($link_info !== false) {
  88. remove_resource_from_course_gradebook($link_info['id']);
  89. }
  90. }
  91. $return_message = delete_forum_forumcategory_thread($_GET['content'], $_GET['id']);
  92. Display::display_confirmation_message($return_message, false);
  93. }
  94. // Change visibility of a forum or a forum category.
  95. if (($action_forum_cat == 'invisible' || $action_forum_cat == 'visible') && isset($_GET['content']) && isset($_GET['id'])) {
  96. $return_message = change_visibility(
  97. $_GET['content'],
  98. $_GET['id'],
  99. $_GET['action']
  100. ); // Note: This has to be cleaned first.
  101. Display::display_confirmation_message($return_message, false);
  102. }
  103. // Change lock status of a forum or a forum category.
  104. if (($action_forum_cat == 'lock' || $action_forum_cat == 'unlock') && isset($_GET['content']) && isset($_GET['id'])) {
  105. $return_message = change_lock_status(
  106. $_GET['content'],
  107. $_GET['id'],
  108. $_GET['action']
  109. ); // Note: This has to be cleaned first.
  110. Display::display_confirmation_message($return_message, false);
  111. }
  112. // Move a forum or a forum category.
  113. if ($action_forum_cat == 'move' && isset($_GET['content']) && isset($_GET['id']) && isset($_GET['direction'])) {
  114. $return_message = move_up_down(
  115. $_GET['content'],
  116. $_GET['direction'],
  117. $_GET['id']
  118. ); // Note: This has to be cleaned first.
  119. Display::display_confirmation_message($return_message, false);
  120. }
  121. }
  122. /**
  123. * This function displays the form that is used to add a forum category.
  124. *
  125. * @param array input values (deprecated, set to null when calling)
  126. * @param int Learning path ID
  127. * @return void HTML
  128. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  129. * @author Juan Carlos Raña Trabado (return to lp_id)
  130. * @version may 2011, Chamilo 1.8.8
  131. */
  132. function show_add_forumcategory_form($inputvalues = array(), $lp_id)
  133. {
  134. $gradebook = Security::remove_XSS($_GET['gradebook']);
  135. // Initialize the object.
  136. $form = new FormValidator('forumcategory', 'post', 'index.php?gradebook='.$gradebook.'&'.api_get_cidreq());
  137. // hidden field if from learning path
  138. $form->addElement('hidden', 'lp_id', $lp_id);
  139. // Settting the form elements.
  140. $form->addElement('header', '', get_lang('AddForumCategory'));
  141. $form->addElement('text', 'forum_category_title', get_lang('Title'), 'class="input_titles" id="category_title"');
  142. //$form->applyFilter('forum_category_title', 'html_filter');
  143. $form->addElement(
  144. 'html_editor',
  145. 'forum_category_comment',
  146. get_lang('Description'),
  147. null,
  148. array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
  149. );
  150. //$form->applyFilter('forum_category_comment', 'html_filter');
  151. $form->addElement('style_submit_button', 'SubmitForumCategory', get_lang('CreateCategory'), 'class="add"');
  152. // Setting the rules.
  153. $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
  154. // The validation or display
  155. if ($form->validate()) {
  156. $check = Security::check_token('post');
  157. if ($check) {
  158. $values = $form->exportValues();
  159. store_forumcategory($values);
  160. }
  161. Security::clear_token();
  162. } else {
  163. $token = Security::get_token();
  164. $form->addElement('hidden', 'sec_token');
  165. $form->setConstants(array('sec_token' => $token));
  166. $form->display();
  167. }
  168. }
  169. /**
  170. * This function displays the form that is used to add a forum category.
  171. *
  172. * @param array
  173. * @return void HTML
  174. *
  175. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  176. *
  177. * Juan Carlos Raña Trabado (return to lp_id)
  178. *
  179. * @version may 2011, Chamilo 1.8.8
  180. */
  181. function show_add_forum_form($inputvalues = array(), $lp_id)
  182. {
  183. $_course = api_get_course_info();
  184. $gradebook = Security::remove_XSS($_GET['gradebook']);
  185. // Initialize the object.
  186. $form = new FormValidator('forumcategory', 'post', 'index.php?gradebook='.$gradebook.'&'.api_get_cidreq());
  187. // The header for the form
  188. if (!empty($inputvalues)) {
  189. $form_title = get_lang('EditForum');
  190. } else {
  191. $form_title = get_lang('AddForum');
  192. }
  193. $session_header = isset($_SESSION['session_name']) ? ' ('.$_SESSION['session_name'].') ' : '';
  194. $form->addElement('header', $form_title.$session_header);
  195. // We have a hidden field if we are editing.
  196. if (!empty($inputvalues) && is_array($inputvalues)) {
  197. $my_forum_id = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
  198. $form->addElement('hidden', 'forum_id', $my_forum_id);
  199. }
  200. $lp_id = intval($lp_id);
  201. // hidden field if from learning path
  202. $form->addElement('hidden', 'lp_id', $lp_id);
  203. // The title of the forum
  204. $form->addElement('text', 'forum_title', get_lang('Title'), 'class="input_titles" id="forum_title"');
  205. // The comment of the forum.
  206. $form->addElement(
  207. 'html_editor',
  208. 'forum_comment',
  209. get_lang('Description'),
  210. null,
  211. array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
  212. );
  213. // Dropdown list: Forum categories
  214. $forum_categories = get_forum_categories();
  215. foreach ($forum_categories as $key => $value) {
  216. $forum_categories_titles[$value['cat_id']] = $value['cat_title'];
  217. }
  218. $form->addElement('select', 'forum_category', get_lang('InForumCategory'), $forum_categories_titles);
  219. $form->applyFilter('forum_category', 'html_filter');
  220. if ($_course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD) {
  221. // This is for horizontal
  222. $group = array();
  223. $group[] = $form->createElement('radio', 'allow_anonymous', null, get_lang('Yes'), 1);
  224. $group[] = $form->createElement('radio', 'allow_anonymous', null, get_lang('No'), 0);
  225. $form->addGroup($group, 'allow_anonymous_group', get_lang('AllowAnonymousPosts'), '&nbsp;');
  226. }
  227. $form->addElement('advanced_settings', 'options', get_lang('AdvancedParameters'));
  228. $form->addElement('html', '<div id="options_options" style="display:none">');
  229. $group = array();
  230. $group[] = $form->createElement('radio', 'students_can_edit', null, get_lang('Yes'), 1);
  231. $group[] = $form->createElement('radio', 'students_can_edit', null, get_lang('No'), 0);
  232. $form->addGroup($group, 'students_can_edit_group', get_lang('StudentsCanEdit'), '&nbsp;');
  233. $group = array();
  234. $group[] = $form->createElement('radio', 'approval_direct', null, get_lang('Approval'), 1);
  235. $group[] = $form->createElement('radio', 'approval_direct', null, get_lang('Direct'), 0);
  236. $group = array();
  237. $group[] = $form->createElement('radio', 'allow_attachments', null, get_lang('Yes'), 1);
  238. $group[] = $form->createElement('radio', 'allow_attachments', null, get_lang('No'), 0);
  239. $group = array();
  240. $group[] = $form->createElement('radio', 'allow_new_threads', null, get_lang('Yes'), 1);
  241. $group[] = $form->createElement('radio', 'allow_new_threads', null, get_lang('No'), 0);
  242. $form->addGroup($group, 'allow_new_threads_group', get_lang('AllowNewThreads'), '&nbsp;');
  243. $group = array();
  244. $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Flat'), 'flat');
  245. $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Threaded'), 'threaded');
  246. $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Nested'), 'nested');
  247. $form->addGroup($group, 'default_view_type_group', get_lang('DefaultViewType'), '&nbsp;');
  248. // Dropdown list: Groups
  249. $groups = GroupManager::get_group_list();
  250. $groups_titles[0] = get_lang('NotAGroupForum');
  251. foreach ($groups as $key => $value) {
  252. $groups_titles[$value['id']] = $value['name'];
  253. }
  254. $form->addElement('select', 'group_forum', get_lang('ForGroup'), $groups_titles);
  255. // Public or private group forum
  256. $group = array();
  257. $group[] = $form->createElement('radio', 'public_private_group_forum', null, get_lang('Public'), 'public');
  258. $group[] = $form->createElement('radio', 'public_private_group_forum', null, get_lang('Private'), 'private');
  259. $form->addGroup($group, 'public_private_group_forum_group', get_lang('PublicPrivateGroupForum'), '&nbsp;');
  260. // Forum image
  261. $form->add_progress_bar();
  262. if (isset($inputvalues['forum_image']) && strlen($inputvalues['forum_image']) > 0) {
  263. $image_path = api_get_path(WEB_COURSE_PATH).api_get_course_path(
  264. ).'/upload/forum/images/'.$inputvalues['forum_image'];
  265. $image_size = api_getimagesize($image_path);
  266. $img_attributes = '';
  267. if (!empty($image_size)) {
  268. if ($image_size['width'] > 100 || $image_size['height'] > 100) {
  269. //limit display width and height to 100px
  270. $img_attributes = 'width="100" height="100"';
  271. }
  272. $show_preview_image = '<img src="'.$image_path.'" '.$img_attributes.'>';
  273. $form->addElement('label', get_lang('PreviewImage'), $show_preview_image);
  274. $form->addElement('checkbox', 'remove_picture', null, get_lang('DelImage'));
  275. }
  276. }
  277. $forum_image = isset($inputvalues['forum_image']) ? $inputvalues['forum_image'] : '';
  278. $form->addElement('file', 'picture', ($forum_image != '' ? get_lang('UpdateImage') : get_lang('AddImage')));
  279. $form->addRule('picture', get_lang('OnlyImagesAllowed'), 'filetype', array('jpg', 'jpeg', 'png', 'gif'));
  280. $form->addElement('html', '</div>');
  281. // The OK button
  282. if (isset($_GET['id']) && $_GET['action'] == 'edit') {
  283. $class = 'save';
  284. $text = get_lang('ModifyForum');
  285. } else {
  286. $class = 'add';
  287. $text = get_lang('CreateForum');
  288. }
  289. $form->addElement('style_submit_button', 'SubmitForum', $text, 'class="'.$class.'"');
  290. // setting the rules
  291. $form->addRule('forum_title', get_lang('ThisFieldIsRequired'), 'required');
  292. $form->addRule('forum_category', get_lang('ThisFieldIsRequired'), 'required');
  293. // Settings the defaults
  294. if (empty($inputvalues) || !is_array($inputvalues)) {
  295. $defaults['allow_anonymous_group']['allow_anonymous'] = 0;
  296. $defaults['students_can_edit_group']['students_can_edit'] = 0;
  297. $defaults['approval_direct_group']['approval_direct'] = 0;
  298. $defaults['allow_attachments_group']['allow_attachments'] = 1;
  299. $defaults['allow_new_threads_group']['allow_new_threads'] = 0;
  300. $defaults['default_view_type_group']['default_view_type'] = api_get_setting('default_forum_view');
  301. $defaults['public_private_group_forum_group']['public_private_group_forum'] = 'public';
  302. if (isset($_GET['forumcategory'])) {
  303. $defaults['forum_category'] = Security::remove_XSS($_GET['forumcategory']);
  304. }
  305. } else { // the default values when editing = the data in the table
  306. $defaults['forum_id'] = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
  307. $defaults['forum_title'] = prepare4display(
  308. isset($inputvalues['forum_title']) ? $inputvalues['forum_title'] : null
  309. );
  310. $defaults['forum_comment'] = prepare4display(
  311. isset($inputvalues['forum_comment']) ? $inputvalues['forum_comment'] : null
  312. );
  313. $defaults['forum_category'] = isset($inputvalues['forum_category']) ? $inputvalues['forum_category'] : null;
  314. $defaults['allow_anonymous_group']['allow_anonymous'] = isset($inputvalues['allow_anonymous']) ? $inputvalues['allow_anonymous'] : null;
  315. $defaults['students_can_edit_group']['students_can_edit'] = isset($inputvalues['allow_edit']) ? $inputvalues['allow_edit'] : null;
  316. $defaults['approval_direct_group']['approval_direct'] = isset($inputvalues['approval_direct_post']) ? $inputvalues['approval_direct_post'] : null;
  317. $defaults['allow_attachments_group']['allow_attachments'] = isset($inputvalues['allow_attachments']) ? $inputvalues['allow_attachments'] : null;
  318. $defaults['allow_new_threads_group']['allow_new_threads'] = isset($inputvalues['allow_new_threads']) ? $inputvalues['allow_new_threads'] : null;
  319. $defaults['default_view_type_group']['default_view_type'] = isset($inputvalues['default_view']) ? $inputvalues['default_view'] : null;
  320. $defaults['public_private_group_forum_group']['public_private_group_forum'] = isset($inputvalues['forum_group_public_private']) ? $inputvalues['forum_group_public_private'] : null;
  321. $defaults['group_forum'] = isset($inputvalues['forum_of_group']) ? $inputvalues['forum_of_group'] : null;
  322. }
  323. $form->setDefaults($defaults);
  324. // Validation or display
  325. if ($form->validate()) {
  326. $check = Security::check_token('post');
  327. if ($check) {
  328. $values = $form->exportValues();
  329. $return_message = store_forum($values);
  330. Display :: display_confirmation_message($return_message);
  331. }
  332. Security::clear_token();
  333. } else {
  334. $token = Security::get_token();
  335. $form->addElement('hidden', 'sec_token');
  336. $form->setConstants(array('sec_token' => $token));
  337. $form->display();
  338. }
  339. }
  340. /**
  341. * This function deletes the forum image if exists
  342. *
  343. * @param int forum id
  344. * @return boolean true if success
  345. * @author Julio Montoya <gugli100@gmail.com>
  346. * @version february 2006, dokeos 1.8
  347. */
  348. function delete_forum_image($forum_id)
  349. {
  350. $table_forums = Database::get_course_table(TABLE_FORUM);
  351. $course_id = api_get_course_int_id();
  352. $forum_id = Database::escape_string($forum_id);
  353. $sql = "SELECT forum_image FROM $table_forums WHERE forum_id = '".$forum_id."' AND c_id = $course_id";
  354. $result = Database::query($sql);
  355. $row = Database::fetch_array($result);
  356. if ($row['forum_image'] != '') {
  357. $del_file = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/upload/forum/images/'.$row['forum_image'];
  358. return @unlink($del_file);
  359. } else {
  360. return false;
  361. }
  362. }
  363. /**
  364. * This function displays the form that is used to edit a forum category.
  365. * This is more or less a copy from the show_add_forumcategory_form function with the only difference that is uses
  366. * some default values. I tried to have both in one function but this gave problems with the handle_forum_and_forumcategories function
  367. * (storing was done twice)
  368. *
  369. * @param array
  370. * @return void HTML
  371. *
  372. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  373. * @version february 2006, dokeos 1.8
  374. */
  375. function show_edit_forumcategory_form($inputvalues = array())
  376. {
  377. // Initialize the object.
  378. $gradebook = Security::remove_XSS($_GET['gradebook']);
  379. $form = new FormValidator('forumcategory', 'post', 'index.php?&amp;gradebook='.$gradebook.'');
  380. // Settting the form elements.
  381. $form->addElement('header', '', get_lang('EditForumCategory'));
  382. $form->addElement('hidden', 'forum_category_id');
  383. $form->addElement('text', 'forum_category_title', get_lang('Title'), 'class="input_titles"');
  384. //$form->applyFilter('forum_category_title', 'html_filter');
  385. $form->addElement(
  386. 'html_editor',
  387. 'forum_category_comment',
  388. get_lang('Comment'),
  389. null,
  390. array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
  391. );
  392. //$form->applyFilter('forum_category_comment', 'html_filter');
  393. $form->addElement('style_submit_button', 'SubmitEditForumCategory', get_lang('ModifyCategory'), 'class="save"');
  394. // Setting the default values.
  395. $defaultvalues['forum_category_id'] = $inputvalues['cat_id'];
  396. $defaultvalues['forum_category_title'] = $inputvalues['cat_title'];
  397. $defaultvalues['forum_category_comment'] = $inputvalues['cat_comment'];
  398. $form->setDefaults($defaultvalues);
  399. // Setting the rules.
  400. $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
  401. // Validation or display
  402. if ($form->validate()) {
  403. $check = Security::check_token('post');
  404. if ($check) {
  405. $values = $form->exportValues();
  406. store_forumcategory($values);
  407. }
  408. Security::clear_token();
  409. } else {
  410. $token = Security::get_token();
  411. $form->addElement('hidden', 'sec_token');
  412. $form->setConstants(array('sec_token' => $token));
  413. $form->display();
  414. }
  415. }
  416. /**
  417. * This function stores the forum category in the database. The new category is added to the end.
  418. *
  419. * @param array
  420. * @return void HMTL language variable
  421. *
  422. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  423. * @version february 2006, dokeos 1.8
  424. */
  425. function store_forumcategory($values)
  426. {
  427. $_course = api_get_course_info();
  428. $course_id = api_get_course_int_id();
  429. $table_categories = Database::get_course_table(TABLE_FORUM_CATEGORY);
  430. // Find the max cat_order. The new forum category is added at the end => max cat_order + &
  431. $sql = "SELECT MAX(cat_order) as sort_max FROM $table_categories WHERE c_id = $course_id";
  432. $result = Database::query($sql);
  433. $row = Database::fetch_array($result);
  434. $new_max = $row['sort_max'] + 1;
  435. $session_id = api_get_session_id();
  436. $clean_cat_title = Database::escape_string($values['forum_category_title']);
  437. if (isset($values['forum_category_id'])) { // Storing after edition.
  438. $sql = "UPDATE ".$table_categories." SET cat_title='".$clean_cat_title."', cat_comment='".Database::escape_string(
  439. $values['forum_category_comment']
  440. )."'
  441. WHERE c_id = $course_id AND cat_id='".Database::escape_string($values['forum_category_id'])."'";
  442. Database::query($sql);
  443. $last_id = Database::insert_id();
  444. api_item_property_update(
  445. api_get_course_info(),
  446. TOOL_FORUM_CATEGORY,
  447. $values['forum_category_id'],
  448. 'ForumCategoryUpdated',
  449. api_get_user_id()
  450. );
  451. $return_message = get_lang('ForumCategoryEdited');
  452. } else {
  453. $sql = "INSERT INTO ".$table_categories." (c_id, cat_title, cat_comment, cat_order, session_id)
  454. VALUES (".$course_id.", '".$clean_cat_title."','".Database::escape_string(
  455. $values['forum_category_comment']
  456. )."','".Database::escape_string($new_max)."','".Database::escape_string($session_id)."')";
  457. Database::query($sql);
  458. $last_id = Database::insert_id();
  459. if ($last_id > 0) {
  460. api_item_property_update(
  461. api_get_course_info(),
  462. TOOL_FORUM_CATEGORY,
  463. $last_id,
  464. 'ForumCategoryAdded',
  465. api_get_user_id()
  466. );
  467. api_set_default_visibility($_course, $last_id, TOOL_FORUM_CATEGORY);
  468. }
  469. $return_message = get_lang('ForumCategoryAdded');
  470. }
  471. Display :: display_confirmation_message($return_message);
  472. }
  473. /**
  474. * This function stores the forum in the database. The new forum is added to the end.
  475. *
  476. * @param array
  477. * @return string language variable
  478. *
  479. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  480. * @version february 2006, dokeos 1.8
  481. */
  482. function store_forum($values)
  483. {
  484. $_course = api_get_course_info();
  485. $course_id = api_get_course_int_id();
  486. $session_id = api_get_session_id();
  487. if (isset($values['group_id']) && !empty($values['group_id'])) {
  488. $group_id = $values['group_id'];
  489. } else {
  490. $group_id = api_get_group_id();
  491. }
  492. $table_forums = Database::get_course_table(TABLE_FORUM);
  493. // Find the max forum_order for the given category. The new forum is added at the end => max cat_order + &
  494. if (is_null($values['forum_category'])) {
  495. $new_max = null;
  496. } else {
  497. $sql = "SELECT MAX(forum_order) as sort_max
  498. FROM ".$table_forums."
  499. WHERE c_id = $course_id AND
  500. forum_category='".Database::escape_string($values['forum_category'])."'";
  501. $result = Database::query($sql);
  502. $row = Database::fetch_array($result);
  503. $new_max = $row['sort_max'] + 1;
  504. }
  505. $clean_title = Database::escape_string($values['forum_title']);
  506. // Forum images
  507. $image_moved = false;
  508. if (!empty($_FILES['picture']['name'])) {
  509. $upload_ok = FileManager::process_uploaded_file($_FILES['picture']);
  510. $has_attachment = true;
  511. } else {
  512. $image_moved = true;
  513. }
  514. // Remove existing picture if it was requested.
  515. if (!empty($_POST['remove_picture'])) {
  516. delete_forum_image($values['forum_id']);
  517. }
  518. if (isset($upload_ok)) {
  519. if ($has_attachment) {
  520. $course_dir = $_course['path'].'/upload/forum/images';
  521. $sys_course_path = api_get_path(SYS_COURSE_PATH);
  522. $updir = $sys_course_path.$course_dir;
  523. // Try to add an extension to the file if it hasn't one.
  524. $new_file_name = FileManager::add_ext_on_mime(
  525. Database::escape_string($_FILES['picture']['name']),
  526. $_FILES['picture']['type']
  527. );
  528. // User's file name
  529. $file_name = $_FILES['picture']['name'];
  530. if (!FileManager::filter_extension($new_file_name)) {
  531. //Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
  532. $image_moved = false;
  533. } else {
  534. $file_extension = explode('.', $_FILES['picture']['name']);
  535. $file_extension = strtolower($file_extension[sizeof($file_extension) - 1]);
  536. $new_file_name = uniqid('').'.'.$file_extension;
  537. $new_path = $updir.'/'.$new_file_name;
  538. $result = @move_uploaded_file($_FILES['picture']['tmp_name'], $new_path);
  539. // Storing the attachments if any
  540. if ($result) {
  541. $image_moved = true;
  542. }
  543. }
  544. }
  545. }
  546. if (isset($values['forum_id'])) {
  547. $sql_image = isset($sql_image) ? $sql_image : '';
  548. $new_file_name = isset($new_file_name) ? $new_file_name : '';
  549. if ($image_moved) {
  550. if (empty($_FILES['picture']['name'])) {
  551. $sql_image = " ";
  552. } else {
  553. $sql_image = " forum_image='".Database::escape_string($new_file_name)."', ";
  554. delete_forum_image($values['forum_id']);
  555. }
  556. }
  557. // Storing after edition.
  558. $sql = "UPDATE ".$table_forums." SET
  559. forum_title='".$clean_title."',
  560. ".$sql_image."
  561. forum_comment='".Database::escape_string(stripslashes($values['forum_comment']))."',
  562. forum_category='".Database::escape_string(stripslashes($values['forum_category']))."',
  563. allow_anonymous='".Database::escape_string(
  564. isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null
  565. )."',
  566. allow_edit='".Database::escape_string($values['students_can_edit_group']['students_can_edit'])."',
  567. approval_direct_post='".Database::escape_string(
  568. isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null
  569. )."',
  570. allow_attachments='".Database::escape_string(
  571. isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null
  572. )."',
  573. allow_new_threads='".Database::escape_string($values['allow_new_threads_group']['allow_new_threads'])."',
  574. forum_group_public_private='".Database::escape_string(
  575. $values['public_private_group_forum_group']['public_private_group_forum']
  576. )."',
  577. default_view='".Database::escape_string($values['default_view_type_group']['default_view_type'])."',
  578. forum_of_group='".Database::escape_string($values['group_forum'])."'
  579. WHERE c_id = $course_id AND forum_id='".Database::escape_string($values['forum_id'])."'";
  580. Database::query($sql);
  581. api_item_property_update(
  582. $_course,
  583. TOOL_FORUM,
  584. Database::escape_string($values['forum_id']),
  585. 'ForumUpdated',
  586. api_get_user_id(),
  587. $group_id
  588. );
  589. $return_message = get_lang('ForumEdited');
  590. } else {
  591. $sql_image = '';
  592. if ($image_moved) {
  593. $new_file_name = isset($new_file_name) ? $new_file_name : '';
  594. $sql_image = "'".$new_file_name."', ";
  595. }
  596. $b = isset($values['forum_comment']) ? $values['forum_comment'] : null;
  597. $sql = "INSERT INTO ".$table_forums." (c_id, forum_title, forum_image, forum_comment, forum_category, allow_anonymous, allow_edit, approval_direct_post, allow_attachments, allow_new_threads, default_view, forum_of_group, forum_group_public_private, forum_order, session_id)
  598. VALUES (
  599. ".$course_id.",
  600. '".$clean_title."',
  601. ".$sql_image."
  602. '".Database::escape_string(isset($values['forum_comment']) ? $values['forum_comment'] : null)."',
  603. '".Database::escape_string(isset($values['forum_category']) ? $values['forum_category'] : null)."',
  604. '".Database::escape_string(
  605. isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null
  606. )."',
  607. '".Database::escape_string(
  608. isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null
  609. )."',
  610. '".Database::escape_string(
  611. isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null
  612. )."',
  613. '".Database::escape_string(
  614. isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null
  615. )."',
  616. '".Database::escape_string(
  617. isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null
  618. )."',
  619. '".Database::escape_string(
  620. isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null
  621. )."',
  622. '".Database::escape_string(isset($values['group_forum']) ? $values['group_forum'] : null)."',
  623. '".Database::escape_string(
  624. isset($values['public_private_group_forum_group']['public_private_group_forum']) ? $values['public_private_group_forum_group']['public_private_group_forum'] : null
  625. )."',
  626. '".Database::escape_string(isset($new_max) ? $new_max : null)."',
  627. ".intval($session_id).")";
  628. Database::query($sql);
  629. $last_id = Database::insert_id();
  630. if ($last_id > 0) {
  631. api_item_property_update($_course, TOOL_FORUM, $last_id, 'ForumAdded', api_get_user_id(), $group_id);
  632. api_set_default_visibility($_course, $last_id, TOOL_FORUM, $group_id);
  633. }
  634. $return_message = get_lang('ForumAdded');
  635. }
  636. return $return_message;
  637. }
  638. /**
  639. * This function deletes a forum or a forum category
  640. * This function currently does not delete the forums inside the category, nor the threads and replies inside these forums.
  641. * For the moment this is the easiest method and it has the advantage that it allows to recover fora that were acidently deleted
  642. * when the forum category got deleted.
  643. *
  644. * @param $content = what we are deleting (a forum or a forum category)
  645. * @param $id The id of the forum category that has to be deleted.
  646. *
  647. * @todo write the code for the cascading deletion of the forums inside a forum category and also the threads and replies inside these forums
  648. * @todo config setting for recovery or not (see also the documents tool: real delete or not).
  649. * @return void
  650. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  651. * @version february 2006, dokeos 1.8
  652. */
  653. function delete_forum_forumcategory_thread($content, $id)
  654. {
  655. $_course = api_get_course_info();
  656. $table_forums = Database::get_course_table(TABLE_FORUM);
  657. $table_forums_post = Database::get_course_table(TABLE_FORUM_POST);
  658. $table_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
  659. $course_id = api_get_course_int_id();
  660. // Delete all attachment file about this tread id.
  661. $sql = "SELECT post_id FROM $table_forums_post WHERE c_id = $course_id AND thread_id = '".(int)$id."' ";
  662. $res = Database::query($sql);
  663. while ($poster_id = Database::fetch_row($res)) {
  664. delete_attachment($poster_id[0]);
  665. }
  666. if ($content == 'forumcategory') {
  667. $tool_constant = TOOL_FORUM_CATEGORY;
  668. $return_message = get_lang('ForumCategoryDeleted');
  669. if (!empty($forum_list)) {
  670. $sql = "SELECT forum_id FROM ".$table_forums."WHERE c_id = $course_id AND forum_category='".$id."'";
  671. $result = Database::query($sql);
  672. $row = Database::fetch_array($result);
  673. foreach ($row as $arr_forum) {
  674. $forum_id = $arr_forum['forum_id'];
  675. api_item_property_update($_course, 'forum', $forum_id, 'delete', api_get_user_id());
  676. }
  677. }
  678. }
  679. if ($content == 'forum') {
  680. $tool_constant = TOOL_FORUM;
  681. $return_message = get_lang('ForumDeleted');
  682. if (!empty($number_threads)) {
  683. $sql = "SELECT thread_id FROM".$table_forum_thread."WHERE c_id = $course_id AND forum_id='".$id."'";
  684. $result = Database::query($sql);
  685. $row = Database::fetch_array($result);
  686. foreach ($row as $arr_forum) {
  687. $forum_id = $arr_forum['thread_id'];
  688. api_item_property_update($_course, 'forum_thread', $forum_id, 'delete', api_get_user_id());
  689. }
  690. }
  691. }
  692. if ($content == 'thread') {
  693. $tool_constant = TOOL_FORUM_THREAD;
  694. $return_message = get_lang('ThreadDeleted');
  695. }
  696. api_item_property_update(
  697. $_course,
  698. $tool_constant,
  699. $id,
  700. 'delete',
  701. api_get_user_id()
  702. ); // Note: Check if this returns a true and if so => return $return_message, if not => return false;
  703. return $return_message;
  704. }
  705. /**
  706. * This function deletes a forum post. This separate function is needed because forum posts do not appear in the item_property table (yet)
  707. * and because deleting a post also has consequence on the posts that have this post as parent_id (they are also deleted).
  708. * an alternative would be to store the posts also in item_property and mark this post as deleted (visibility = 2).
  709. * We also have to decrease the number of replies in the thread table
  710. *
  711. * @param $post_id the id of the post that will be deleted
  712. * @todo write recursive function that deletes all the posts that have this message as parent
  713. * @return string language variable
  714. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  715. * @author Hubert Borderiou Function cleanead and fixed
  716. * @version february 2006
  717. */
  718. function delete_post($post_id)
  719. {
  720. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  721. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  722. $post_id = intval($post_id);
  723. $course_id = api_get_course_int_id();
  724. // Get parent_post_id of deleted post.
  725. $tab_post_info = get_post_information($post_id);
  726. if ($tab_post_info) {
  727. $post_parent_id_of_deleted_post = $tab_post_info['post_parent_id'];
  728. $thread_id_of_deleted_post = $tab_post_info['thread_id'];
  729. $forum_if_of_deleted_post = $tab_post_info['forum_id'];
  730. $sql = "UPDATE $table_posts SET post_parent_id=$post_parent_id_of_deleted_post
  731. WHERE c_id = $course_id AND post_parent_id=$post_id AND thread_id=$thread_id_of_deleted_post AND forum_id=$forum_if_of_deleted_post;";
  732. Database::query($sql);
  733. $sql = "DELETE FROM $table_posts WHERE c_id = $course_id AND post_id='".Database::escape_string(
  734. $post_id
  735. )."'"; // Note: This has to be a recursive function that deletes all of the posts in this block.
  736. Database::query($sql);
  737. // Delete attachment file about this post id.
  738. delete_attachment($post_id);
  739. }
  740. $last_post_of_thread = check_if_last_post_of_thread($_GET['thread']);
  741. if (is_array($last_post_of_thread)) {
  742. // Decreasing the number of replies for this thread and also changing the last post information.
  743. $sql = "UPDATE $table_threads SET thread_replies=thread_replies-1,
  744. thread_last_post='".Database::escape_string($last_post_of_thread['post_id'])."',
  745. thread_date='".Database::escape_string($last_post_of_thread['post_date'])."'
  746. WHERE c_id = $course_id AND thread_id='".intval($_GET['thread'])."'";
  747. Database::query($sql);
  748. return 'PostDeleted';
  749. }
  750. if (!$last_post_of_thread) {
  751. // We deleted the very single post of the thread so we need to delete the entry in the thread table also.
  752. $sql = "DELETE FROM $table_threads WHERE c_id = $course_id AND thread_id='".intval($_GET['thread'])."'";
  753. Database::query($sql);
  754. return 'PostDeletedSpecial';
  755. }
  756. }
  757. /**
  758. * This function gets the all information of the last (=most recent) post of the thread
  759. * This can be done by sorting the posts that have the field thread_id=$thread_id and sort them by post_date
  760. *
  761. * @param $thread_id the id of the thread we want to know the last post of.
  762. * @return an array or bool if there is a last post found, false if there is no post entry linked to that thread => thread will be deleted
  763. *
  764. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  765. * @version february 2006, dokeos 1.8
  766. */
  767. function check_if_last_post_of_thread($thread_id)
  768. {
  769. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  770. $course_id = api_get_course_int_id();
  771. $sql = "SELECT * FROM $table_posts WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  772. $thread_id
  773. )."' ORDER BY post_date DESC";
  774. $result = Database::query($sql);
  775. if (Database::num_rows($result) > 0) {
  776. $row = Database::fetch_array($result);
  777. return $row;
  778. } else {
  779. return false;
  780. }
  781. }
  782. /**
  783. * This function takes care of the display of the visibility icon
  784. *
  785. * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
  786. * @param $id the id of the content we want to make invisible
  787. * @param $current_visibility_status what is the current status of the visibility (0 = invisible, 1 = visible)
  788. * @return void string HTML
  789. *
  790. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  791. * @version february 2006, dokeos 1.8
  792. */
  793. function display_visible_invisible_icon($content, $id, $current_visibility_status, $additional_url_parameters = '')
  794. {
  795. global $origin;
  796. $gradebook = Security::remove_XSS($_GET['gradebook']);
  797. $id = Security::remove_XSS($id);
  798. if ($current_visibility_status == '1') {
  799. echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gidReq='.api_get_group_id().'&amp;';
  800. if (is_array($additional_url_parameters)) {
  801. foreach ($additional_url_parameters as $key => $value) {
  802. echo $key.'='.$value.'&amp;';
  803. }
  804. }
  805. echo 'action=invisible&amp;content='.$content.'&amp;id='.$id.'&gradebook='.$gradebook.'&amp;origin='.$origin.'">'.Display::return_icon(
  806. 'visible.png',
  807. get_lang('MakeInvisible'),
  808. array(),
  809. ICON_SIZE_SMALL
  810. ).'</a>';
  811. }
  812. if ($current_visibility_status == '0') {
  813. echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;';
  814. if (is_array($additional_url_parameters)) {
  815. foreach ($additional_url_parameters as $key => $value) {
  816. echo $key.'='.$value.'&amp;';
  817. }
  818. }
  819. echo 'action=visible&amp;content='.$content.'&amp;id='.$id.'&gradebook='.$gradebook.'&amp;origin='.$origin.'">'.Display::return_icon(
  820. 'invisible.png',
  821. get_lang('MakeVisible'),
  822. array(),
  823. ICON_SIZE_SMALL
  824. ).'</a>';
  825. }
  826. }
  827. /**
  828. * This function takes care of the display of the lock icon
  829. *
  830. * @param $content what is it that we want to (un)lock: forum category, forum, thread, post
  831. * @param $id the id of the content we want to (un)lock
  832. * @param $current_visibility_status what is the current status of the visibility (0 = invisible, 1 = visible)
  833. * @return void display the lock HTML.
  834. *
  835. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  836. * @version february 2006, dokeos 1.8
  837. */
  838. function display_lock_unlock_icon($content, $id, $current_lock_status, $additional_url_parameters = '')
  839. {
  840. $id = intval($id);
  841. //check if the forum is blocked due
  842. if ($content == 'thread') {
  843. if (api_resource_is_locked_by_gradebook($id, LINK_FORUM_THREAD)) {
  844. echo Display::return_icon('lock_na.png', get_lang('ResourceLockedByGradebook'), array(), ICON_SIZE_SMALL);
  845. return;
  846. }
  847. }
  848. if ($current_lock_status == '1') {
  849. echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;';
  850. if (is_array($additional_url_parameters)) {
  851. foreach ($additional_url_parameters as $key => $value) {
  852. echo $key.'='.$value.'&amp;';
  853. }
  854. }
  855. echo 'action=unlock&amp;content='.$content.'&amp;id='.$id.'">'.Display::return_icon(
  856. 'lock.png',
  857. get_lang('Unlock'),
  858. array(),
  859. ICON_SIZE_SMALL
  860. ).'</a>';
  861. }
  862. if ($current_lock_status == '0') {
  863. echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;';
  864. if (is_array($additional_url_parameters)) {
  865. foreach ($additional_url_parameters as $key => $value) {
  866. echo $key.'='.$value.'&amp;';
  867. }
  868. }
  869. echo 'action=lock&amp;content='.$content.'&amp;id='.$id.'">'.Display::return_icon(
  870. 'unlock.png',
  871. get_lang('Lock'),
  872. array(),
  873. ICON_SIZE_SMALL
  874. ).'</a>';
  875. }
  876. }
  877. /**
  878. * This function takes care of the display of the up and down icon
  879. *
  880. * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
  881. * @param $id is the id of the item we want to display the icons for
  882. * @param $list is an array of all the items. All items in this list should have an up and down icon except for the first (no up icon) and the last (no down icon)
  883. * The key of this $list array is the id of the item.
  884. *
  885. * @return void HTML
  886. *
  887. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  888. * @version february 2006, dokeos 1.8
  889. */
  890. function display_up_down_icon($content, $id, $list)
  891. {
  892. $id = strval(intval($id));
  893. $total_items = count($list);
  894. $position = 0;
  895. $internal_counter = 0;
  896. if (is_array($list)) {
  897. foreach ($list as $key => $listitem) {
  898. $internal_counter++;
  899. if ($id == $key) {
  900. $position = $internal_counter;
  901. }
  902. }
  903. }
  904. if ($position > 1) {
  905. $return_value = '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gidReq='.Security::remove_XSS(
  906. $_GET['gidReq']
  907. ).'&action=move&amp;direction=up&amp;content='.$content.'&amp;forumcategory='.Security::remove_XSS(
  908. $_GET['forumcategory']
  909. ).'&amp;id='.$id.'" title="'.get_lang('MoveUp').'">'.Display::return_icon(
  910. 'up.png',
  911. get_lang('MoveUp'),
  912. array(),
  913. ICON_SIZE_SMALL
  914. ).'</a>';
  915. } else {
  916. $return_value = Display::return_icon('up_na.png', '-', array(), ICON_SIZE_SMALL);
  917. }
  918. if ($position < $total_items) {
  919. $return_value .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gidReq='.Security::remove_XSS(
  920. $_GET['gidReq']
  921. ).'&action=move&amp;direction=down&amp;content='.$content.'&amp;forumcategory='.Security::remove_XSS(
  922. $_GET['forumcategory']
  923. ).'&amp;id='.$id.'" title="'.get_lang('MoveDown').'" >'.Display::return_icon(
  924. 'down.png',
  925. get_lang('MoveDown'),
  926. array(),
  927. ICON_SIZE_SMALL
  928. ).'</a>';
  929. } else {
  930. $return_value .= Display::return_icon('down_na.png', '-', array(), ICON_SIZE_SMALL);
  931. }
  932. echo $return_value;
  933. }
  934. /**
  935. * This function changes the visibility in the database (item_property)
  936. *
  937. * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
  938. * @param $id the id of the content we want to make invisible
  939. * @param $target_visibility what is the current status of the visibility (0 = invisible, 1 = visible)
  940. *
  941. * @todo change the get parameter so that it matches the tool constants.
  942. * @todo check if api_item_property_update returns true or false => returnmessage depends on it.
  943. * @todo move to itemmanager
  944. *
  945. * @return string language variable
  946. *
  947. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  948. * @version february 2006, dokeos 1.8
  949. */
  950. function change_visibility($content, $id, $target_visibility)
  951. {
  952. $_course = api_get_course_info();
  953. $constants = array('forumcategory' => TOOL_FORUM_CATEGORY, 'forum' => TOOL_FORUM, 'thread' => TOOL_FORUM_THREAD);
  954. api_item_property_update(
  955. $_course,
  956. $constants[$content],
  957. $id,
  958. $target_visibility,
  959. api_get_user_id()
  960. ); // Note: Check if this returns true or false => returnmessage depends on it.
  961. if ($target_visibility == 'visible') {
  962. handle_mail_cue($content, $id);
  963. }
  964. return get_lang('VisibilityChanged');
  965. }
  966. /**
  967. * This function changes the lock status in the database
  968. *
  969. * @param $content what is it that we want to (un)lock: forum category, forum, thread, post
  970. * @param $id the id of the content we want to (un)lock
  971. * @param $action do we lock (=>locked value in db = 1) or unlock (=> locked value in db = 0)
  972. * @return string, language variable
  973. *
  974. * @todo move to itemmanager
  975. *
  976. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  977. * @version february 2006, dokeos 1.8
  978. */
  979. function change_lock_status($content, $id, $action)
  980. {
  981. $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
  982. $table_forums = Database :: get_course_table(TABLE_FORUM);
  983. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  984. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  985. // Determine the relevant table.
  986. if ($content == 'forumcategory') {
  987. $table = $table_categories;
  988. $id_field = 'cat_id';
  989. } elseif ($content == 'forum') {
  990. $table = $table_forums;
  991. $id_field = 'forum_id';
  992. } elseif ($content == 'thread') {
  993. $table = $table_threads;
  994. $id_field = 'thread_id';
  995. } else {
  996. return get_lang('Error');
  997. }
  998. // Determine what we are doing => defines the value for the database and the return message.
  999. if ($action == 'lock') {
  1000. $db_locked = 1;
  1001. $return_message = get_lang('Locked');
  1002. } elseif ($action == 'unlock') {
  1003. $db_locked = 0;
  1004. $return_message = get_lang('Unlocked');
  1005. } else {
  1006. return get_lang('Error');
  1007. }
  1008. $course_id = api_get_course_int_id();
  1009. // Doing the change in the database
  1010. $sql = "UPDATE $table SET locked='".Database::escape_string(
  1011. $db_locked
  1012. )."' WHERE c_id = $course_id AND $id_field='".Database::escape_string($id)."'";
  1013. if (Database::query($sql)) {
  1014. return $return_message;
  1015. } else {
  1016. return get_lang('Error');
  1017. }
  1018. }
  1019. /**
  1020. * This function moves a forum or a forum category up or down
  1021. *
  1022. * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
  1023. * @param $direction do we want to move it up or down.
  1024. * @param $id the id of the content we want to make invisible
  1025. * @todo consider removing the table_item_property calls here but this can prevent unwanted side effects when a forum does not have an entry in
  1026. * the item_property table but does have one in the forum table.
  1027. * @return string language variable
  1028. *
  1029. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1030. * @version february 2006, dokeos 1.8
  1031. */
  1032. function move_up_down($content, $direction, $id)
  1033. {
  1034. $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
  1035. $table_forums = Database :: get_course_table(TABLE_FORUM);
  1036. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1037. $course_id = api_get_course_int_id();
  1038. // Determine which field holds the sort order.
  1039. if ($content == 'forumcategory') {
  1040. $table = $table_categories;
  1041. $sort_column = 'cat_order';
  1042. $id_column = 'cat_id';
  1043. $sort_column = 'cat_order';
  1044. } elseif ($content == 'forum') {
  1045. $table = $table_forums;
  1046. $sort_column = 'forum_order';
  1047. $id_column = 'forum_id';
  1048. $sort_column = 'forum_order';
  1049. // We also need the forum_category of this forum.
  1050. $sql = "SELECT forum_category FROM $table_forums WHERE c_id = $course_id AND forum_id=".Database::escape_string(
  1051. $id
  1052. );
  1053. $result = Database::query($sql);
  1054. $row = Database::fetch_array($result);
  1055. $forum_category = $row['forum_category'];
  1056. } else {
  1057. return get_lang('Error');
  1058. }
  1059. // Determine the need for sorting ascending or descending order.
  1060. if ($direction == 'down') {
  1061. $sort_direction = 'ASC';
  1062. } elseif ($direction == 'up') {
  1063. $sort_direction = 'DESC';
  1064. } else {
  1065. return get_lang('Error');
  1066. }
  1067. // The SQL statement
  1068. if ($content == 'forumcategory') {
  1069. $sql = "SELECT * FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties
  1070. WHERE
  1071. forum_categories.c_id = $course_id AND
  1072. item_properties.c_id = $course_id AND
  1073. forum_categories.cat_id=item_properties.ref
  1074. AND item_properties.tool='".TOOL_FORUM_CATEGORY."'
  1075. ORDER BY forum_categories.cat_order $sort_direction";
  1076. }
  1077. if ($content == 'forum') {
  1078. $sql = "SELECT * FROM ".$table." WHERE c_id = $course_id AND forum_category='".Database::escape_string(
  1079. $forum_category
  1080. )."' ORDER BY forum_order $sort_direction";
  1081. }
  1082. // echo $sql.'<br />';
  1083. // Finding the items that need to be switched.
  1084. $result = Database::query($sql);
  1085. $found = false;
  1086. while ($row = Database::fetch_array($result)) {
  1087. //echo $row[$id_column].'-';
  1088. if ($found) {
  1089. $next_id = $row[$id_column];
  1090. $next_sort = $row[$sort_column];
  1091. $found = false;
  1092. }
  1093. if ($id == $row[$id_column]) {
  1094. $this_id = $id;
  1095. $this_sort = $row[$sort_column];
  1096. $found = true;
  1097. }
  1098. }
  1099. // Committing the switch.
  1100. // We do an extra check if we do not have illegal values. If your remove this if statment you will
  1101. // be able to mess with the sorting by refreshing the page over and over again.
  1102. if ($this_sort != '' && $next_sort != '' && $next_id != '' && $this_id != '') {
  1103. $sql_update1 = "UPDATE $table SET $sort_column='".Database::escape_string(
  1104. $this_sort
  1105. )."' WHERE c_id = $course_id AND $id_column='".Database::escape_string($next_id)."'";
  1106. $sql_update2 = "UPDATE $table SET $sort_column='".Database::escape_string(
  1107. $next_sort
  1108. )."' WHERE c_id = $course_id AND $id_column='".Database::escape_string($this_id)."'";
  1109. Database::query($sql_update1);
  1110. Database::query($sql_update2);
  1111. }
  1112. return get_lang(ucfirst($content).'Moved');
  1113. }
  1114. /**
  1115. * This function returns a piece of html code that make the links grey (=invisible for the student)
  1116. *
  1117. * @param boolean 0/1: 0 = invisible, 1 = visible
  1118. * @return string language variable
  1119. *
  1120. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1121. * @version february 2006, dokeos 1.8
  1122. */
  1123. function class_visible_invisible($current_visibility_status)
  1124. {
  1125. if ($current_visibility_status == '0') {
  1126. return 'class="invisible"';
  1127. }
  1128. }
  1129. /**
  1130. * Retrieve all the information off the forum categories (or one specific) for the current course.
  1131. * The categories are sorted according to their sorting order (cat_order
  1132. *
  1133. * @param $id default ''. When an id is passed we only find the information about that specific forum category. If no id is passed we get all the forum categories.
  1134. * @return an array containing all the information about all the forum categories
  1135. *
  1136. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1137. * @version february 2006, dokeos 1.8
  1138. */
  1139. function get_forum_categories($id = '')
  1140. {
  1141. $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
  1142. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1143. $forum_categories_list = array();
  1144. // Condition for the session
  1145. $session_id = api_get_session_id();
  1146. $condition_session = api_get_session_condition($session_id);
  1147. $course_id = api_get_course_int_id();
  1148. $condition_session .= "AND forum_categories.c_id = $course_id AND item_properties.c_id = $course_id";
  1149. if ($id == '') {
  1150. $sql = "SELECT * FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties
  1151. WHERE forum_categories.cat_id=item_properties.ref
  1152. AND item_properties.visibility=1
  1153. AND item_properties.tool='".TOOL_FORUM_CATEGORY."' $condition_session
  1154. ORDER BY forum_categories.cat_order ASC";
  1155. if (is_allowed_to_edit()) {
  1156. $sql = "SELECT * FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties
  1157. WHERE forum_categories.cat_id=item_properties.ref
  1158. AND item_properties.visibility<>2
  1159. AND item_properties.tool='".TOOL_FORUM_CATEGORY."' $condition_session
  1160. ORDER BY forum_categories.cat_order ASC";
  1161. }
  1162. } else {
  1163. $sql = "SELECT * FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties
  1164. WHERE forum_categories.cat_id=item_properties.ref
  1165. AND item_properties.tool='".TOOL_FORUM_CATEGORY."'
  1166. AND forum_categories.cat_id='".Database::escape_string($id)."' $condition_session
  1167. ORDER BY forum_categories.cat_order ASC";
  1168. }
  1169. $result = Database::query($sql);
  1170. while ($row = Database::fetch_array($result)) {
  1171. if ($id == '') {
  1172. $forum_categories_list[$row['cat_id']] = $row;
  1173. } else {
  1174. $forum_categories_list = $row;
  1175. }
  1176. }
  1177. return $forum_categories_list;
  1178. }
  1179. /**
  1180. * This function retrieves all the fora in a given forum category
  1181. *
  1182. * @param integer $cat_id the id of the forum category
  1183. * @return an array containing all the information about the forums (regardless of their category)
  1184. *
  1185. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1186. * @version february 2006, dokeos 1.8
  1187. */
  1188. function get_forums_in_category($cat_id)
  1189. {
  1190. $table_forums = Database :: get_course_table(TABLE_FORUM);
  1191. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1192. $forum_list = array();
  1193. $course_id = api_get_course_int_id();
  1194. $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties
  1195. WHERE forum.forum_category='".Database::escape_string($cat_id)."'
  1196. AND forum.forum_id=item_properties.ref
  1197. AND item_properties.visibility=1
  1198. AND item_properties.c_id = $course_id
  1199. AND item_properties.tool='".TOOL_FORUM."' AND
  1200. forum.c_id = $course_id
  1201. ORDER BY forum.forum_order ASC";
  1202. if (is_allowed_to_edit()) {
  1203. $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties
  1204. WHERE forum.forum_category = '".Database::escape_string($cat_id)."' AND
  1205. forum.forum_id = item_properties.ref AND
  1206. item_properties.visibility<>2 AND
  1207. item_properties.tool = '".TOOL_FORUM."' AND
  1208. item_properties.c_id = $course_id AND
  1209. forum.c_id = $course_id
  1210. ORDER BY forum_order ASC";
  1211. }
  1212. $result = Database::query($sql);
  1213. while ($row = Database::fetch_array($result)) {
  1214. $forum_list[$row['forum_id']] = $row;
  1215. }
  1216. return $forum_list;
  1217. }
  1218. /**
  1219. * Retrieve all the forums (regardless of their category) or of only one. The forums are sorted according to the forum_order.
  1220. * Since it does not take the forum category into account there probably will be two or more forums that have forum_order=1, ...
  1221. * @param int forum id
  1222. * @param string course db name
  1223. * @return an array containing all the information about the forums (regardless of their category)
  1224. * @todo check $sql4 because this one really looks fishy.
  1225. *
  1226. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1227. * @version february 2006, dokeos 1.8
  1228. */
  1229. function get_forums($id = '', $course_code = '')
  1230. {
  1231. $course_info = api_get_course_info($course_code);
  1232. $table_users = Database :: get_main_table(TABLE_MAIN_USER);
  1233. $table_forums = Database :: get_course_table(TABLE_FORUM);
  1234. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  1235. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1236. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1237. // GETTING ALL THE FORUMS
  1238. // Condition for the session
  1239. $session_id = api_get_session_id();
  1240. $condition_session = api_get_session_condition($session_id);
  1241. $course_id = $course_info['real_id'];
  1242. $forum_list = array();
  1243. if ($id == '') {
  1244. // Student
  1245. // Select all the forum information of all forums (that are visible to students).
  1246. $sql = "SELECT * FROM $table_forums forum , ".$table_item_property." item_properties
  1247. WHERE forum.forum_id=item_properties.ref
  1248. AND item_properties.visibility=1
  1249. AND item_properties.tool='".TOOL_FORUM."'
  1250. $condition_session AND forum.c_id = $course_id AND item_properties.c_id = $course_id
  1251. ORDER BY forum.forum_order ASC";
  1252. // Select the number of threads of the forums (only the threads that are visible).
  1253. $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id FROM $table_threads threads, ".$table_item_property." item_properties
  1254. WHERE threads.thread_id=item_properties.ref
  1255. AND item_properties.visibility=1
  1256. AND item_properties.tool='".TOOL_FORUM_THREAD."' AND threads.c_id = $course_id AND item_properties.c_id = $course_id
  1257. GROUP BY threads.forum_id";
  1258. // Select the number of posts of the forum (post that are visible and that are in a thread that is visible).
  1259. $sql3 = "SELECT count(*) AS number_of_posts, posts.forum_id FROM $table_posts posts, $table_threads threads, ".$table_item_property." item_properties
  1260. WHERE posts.visible=1
  1261. AND posts.thread_id=threads.thread_id
  1262. AND threads.thread_id=item_properties.ref
  1263. AND item_properties.visibility=1
  1264. AND item_properties.tool='".TOOL_FORUM_THREAD."' AND threads.c_id = $course_id AND posts.c_id = $course_id AND item_properties.c_id = $course_id
  1265. GROUP BY threads.forum_id";
  1266. //-------------- Course Admin -----------------//
  1267. if (is_allowed_to_edit()) {
  1268. // Select all the forum information of all forums (that are not deleted).
  1269. $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties
  1270. WHERE forum.forum_id=item_properties.ref
  1271. AND item_properties.visibility<>2
  1272. AND item_properties.tool='".TOOL_FORUM."'
  1273. $condition_session AND forum.c_id = $course_id AND item_properties.c_id = $course_id
  1274. ORDER BY forum_order ASC";
  1275. //echo $sql.'<hr />';
  1276. // Select the number of threads of the forums (only the threads that are not deleted).
  1277. $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id FROM $table_threads threads, ".$table_item_property." item_properties
  1278. WHERE threads.thread_id=item_properties.ref
  1279. AND item_properties.visibility<>2
  1280. AND item_properties.tool='".TOOL_FORUM_THREAD."' AND threads.c_id = $course_id AND item_properties.c_id = $course_id
  1281. GROUP BY threads.forum_id";
  1282. //echo $sql2.'<hr />';
  1283. // Select the number of posts of the forum.
  1284. $sql3 = "SELECT count(*) AS number_of_posts, posts.forum_id FROM $table_posts posts, $table_threads threads, ".$table_item_property." item_properties
  1285. WHERE posts.thread_id=threads.thread_id
  1286. AND threads.thread_id=item_properties.ref
  1287. AND item_properties.visibility=1
  1288. AND item_properties.tool='".TOOL_FORUM_THREAD."' AND posts.c_id = $course_id AND threads.c_id = $course_id AND item_properties.c_id = $course_id
  1289. GROUP BY threads.forum_id";
  1290. //echo $sql3.'<hr />';
  1291. }
  1292. } else {
  1293. // GETTING ONE SPECIFIC FORUM
  1294. // We could do the splitup into student and course admin also but we want to have as much as information about a certain forum as possible
  1295. // so we do not take too much information into account. This function (or this section of the function) is namely used to fill the forms
  1296. // when editing a forum (and for the moment it is the only place where we use this part of the function)
  1297. //
  1298. // Select all the forum information of the given forum (that is not deleted).
  1299. $sql = "SELECT * FROM $table_forums forum , ".$table_item_property." item_properties
  1300. WHERE forum.forum_id=item_properties.ref
  1301. AND forum_id='".Database::escape_string($id)."'
  1302. AND item_properties.visibility<>2
  1303. AND item_properties.tool='".TOOL_FORUM."'
  1304. $condition_session AND forum.c_id = $course_id AND item_properties.c_id = $course_id
  1305. ORDER BY forum_order ASC";
  1306. // Select the number of threads of the forum.
  1307. $sql2 = "SELECT count(*) AS number_of_threads, forum_id FROM $table_threads
  1308. WHERE forum_id=".Database::escape_string($id)." AND c_id = $course_id
  1309. GROUP BY forum_id";
  1310. // Select the number of posts of the forum.
  1311. $sql3 = "SELECT count(*) AS number_of_posts, forum_id FROM $table_posts
  1312. WHERE forum_id=".Database::escape_string($id)." AND c_id = $course_id
  1313. GROUP BY forum_id";
  1314. // Select the last post and the poster (note: this is probably no longer needed).
  1315. $sql4 = "SELECT post.post_id, post.forum_id, post.poster_id, post.poster_name, post.post_date, users.lastname, users.firstname
  1316. FROM $table_posts post, $table_users users
  1317. WHERE forum_id=".Database::escape_string($id)."
  1318. AND post.poster_id=users.user_id AND post.c_id = $course_id
  1319. GROUP BY post.forum_id
  1320. ORDER BY post.post_id ASC";
  1321. }
  1322. // Handling all the forum information.
  1323. $result = Database::query($sql);
  1324. while ($row = Database::fetch_array($result)) {
  1325. if ($id == '') {
  1326. $forum_list[$row['forum_id']] = $row;
  1327. } else {
  1328. $forum_list = $row;
  1329. }
  1330. }
  1331. // Handling the threadcount information.
  1332. $result2 = Database::query($sql2);
  1333. while ($row2 = Database::fetch_array($result2)) {
  1334. if ($id == '') {
  1335. $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
  1336. } else {
  1337. $forum_list['number_of_threads'] = $row2['number_of_threads'];
  1338. }
  1339. }
  1340. // Handling the postcount information.
  1341. $result3 = Database::query($sql3);
  1342. while ($row3 = Database::fetch_array($result3)) {
  1343. if ($id == '') {
  1344. if (array_key_exists(
  1345. $row3['forum_id'],
  1346. $forum_list
  1347. )
  1348. ) { // This is needed because sql3 takes also the deleted forums into account.
  1349. $forum_list[$row3['forum_id']]['number_of_posts'] = $row3['number_of_posts'];
  1350. }
  1351. } else {
  1352. $forum_list['number_of_posts'] = $row3['number_of_posts'];
  1353. }
  1354. }
  1355. // Finding the last post information (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname).
  1356. if ($id == '') {
  1357. if (is_array($forum_list)) {
  1358. foreach ($forum_list as $key => $value) {
  1359. $last_post_info_of_forum = get_last_post_information($key, api_is_allowed_to_edit(), $course_id);
  1360. $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
  1361. $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
  1362. $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
  1363. $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
  1364. $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
  1365. $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
  1366. }
  1367. } else {
  1368. $forum_list = array();
  1369. }
  1370. } else {
  1371. $last_post_info_of_forum = get_last_post_information($id, api_is_allowed_to_edit(), $course_id);
  1372. $forum_list['last_post_id'] = $last_post_info_of_forum['last_post_id'];
  1373. $forum_list['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
  1374. $forum_list['last_post_date'] = $last_post_info_of_forum['last_post_date'];
  1375. $forum_list['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
  1376. $forum_list['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
  1377. $forum_list['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
  1378. }
  1379. return $forum_list;
  1380. }
  1381. function get_last_post_by_thread($course_id, $thread_id, $forum_id, $show_visible = true)
  1382. {
  1383. if (empty($thread_id) || empty($forum_id) || empty($course_id)) {
  1384. return false;
  1385. }
  1386. $thread_id = intval($thread_id);
  1387. $forum_id = intval($forum_id);
  1388. $course_id = intval($course_id);
  1389. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1390. $sql = "SELECT * FROM $table_posts
  1391. WHERE c_id = $course_id AND thread_id = $thread_id AND forum_id = $forum_id";
  1392. if ($show_visible == false) {
  1393. $sql .= " AND visible = 1 ";
  1394. }
  1395. $sql .= " ORDER BY post_id DESC LIMIT 1";
  1396. $result = Database::query($sql);
  1397. if (Database::num_rows($result)) {
  1398. return Database::fetch_array($result, 'ASSOC');
  1399. } else {
  1400. return false;
  1401. }
  1402. }
  1403. /**
  1404. * This function gets all the last post information of a certain forum
  1405. *
  1406. * @param int $forum_id the id of the forum we want to know the last post information of.
  1407. * @param bool $show_invisibles
  1408. * @param string course db name
  1409. * @return array containing all the information about the last post (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)
  1410. *
  1411. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1412. * @version february 2006, dokeos 1.8
  1413. */
  1414. function get_last_post_information($forum_id, $show_invisibles = false, $course_id = null)
  1415. {
  1416. if (!isset($course_id)) {
  1417. $course_id = api_get_course_int_id();
  1418. } else {
  1419. $course_id = intval($course_id);
  1420. }
  1421. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1422. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1423. $table_users = Database :: get_main_table(TABLE_MAIN_USER);
  1424. $sql = "SELECT post.post_id, post.forum_id, post.poster_id, post.poster_name, post.post_date, users.lastname, users.firstname, post.visible, thread_properties.visibility AS thread_visibility, forum_properties.visibility AS forum_visibility
  1425. FROM $table_posts post, $table_users users, $table_item_property thread_properties, $table_item_property forum_properties
  1426. WHERE post.forum_id=".Database::escape_string($forum_id)."
  1427. AND post.poster_id=users.user_id
  1428. AND post.thread_id=thread_properties.ref
  1429. AND thread_properties.tool='".TOOL_FORUM_THREAD."'
  1430. AND post.forum_id=forum_properties.ref
  1431. AND forum_properties.tool='".TOOL_FORUM."'
  1432. AND post.c_id = $course_id AND
  1433. thread_properties.c_id = $course_id AND
  1434. forum_properties.c_id = $course_id
  1435. ORDER BY post.post_id DESC";
  1436. $result = Database::query($sql);
  1437. if ($show_invisibles) {
  1438. $row = Database::fetch_array($result);
  1439. $return_array['last_post_id'] = $row['post_id'];
  1440. $return_array['last_poster_id'] = $row['poster_id'];
  1441. $return_array['last_post_date'] = $row['post_date'];
  1442. $return_array['last_poster_name'] = $row['poster_name'];
  1443. $return_array['last_poster_lastname'] = $row['lastname'];
  1444. $return_array['last_poster_firstname'] = $row['firstname'];
  1445. return $return_array;
  1446. } else {
  1447. // We have to loop through the results to find the first one that is actually visible to students (forum_category, forum, thread AND post are visible).
  1448. while ($row = Database::fetch_array($result)) {
  1449. if ($row['visible'] == '1' && $row['thread_visibility'] == '1' && $row['forum_visibility'] == '1') {
  1450. $return_array['last_post_id'] = $row['post_id'];
  1451. $return_array['last_poster_id'] = $row['poster_id'];
  1452. $return_array['last_post_date'] = $row['post_date'];
  1453. $return_array['last_poster_name'] = $row['poster_name'];
  1454. $return_array['last_poster_lastname'] = $row['lastname'];
  1455. $return_array['last_poster_firstname'] = $row['firstname'];
  1456. return $return_array;
  1457. }
  1458. }
  1459. }
  1460. }
  1461. /**
  1462. * Retrieve all the threads of a given forum
  1463. *
  1464. * @param int forum id
  1465. * @param string course db name
  1466. * @return an array containing all the information about the threads
  1467. *
  1468. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1469. * @version february 2006, dokeos 1.8
  1470. */
  1471. function get_threads($forum_id, $course_code = null)
  1472. {
  1473. $course_info = api_get_course_info($course_code);
  1474. if (empty($course_info)) {
  1475. return array();
  1476. }
  1477. $course_id = $course_info['real_id'];
  1478. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1479. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  1480. $table_users = Database :: get_main_table(TABLE_MAIN_USER);
  1481. $thread_list = array();
  1482. // important note: it might seem a little bit awkward that we have 'thread.locked as locked' in the sql statement
  1483. // because we also have thread.* in it. This is because thread has a field locked and post also has the same field
  1484. // since we are merging these we would have the post.locked value but in fact we want the thread.locked value
  1485. // This is why it is added to the end of the field selection
  1486. $sql = "SELECT thread.*,
  1487. item_properties.*,
  1488. users.firstname,
  1489. users.lastname,
  1490. users.user_id,
  1491. thread.locked as locked
  1492. FROM $table_threads thread
  1493. INNER JOIN $table_item_property item_properties
  1494. ON thread.thread_id=item_properties.ref AND
  1495. item_properties.c_id = $course_id AND
  1496. thread.c_id = $course_id AND
  1497. item_properties.tool='".TABLE_FORUM_THREAD."'
  1498. LEFT JOIN $table_users users
  1499. ON thread.thread_poster_id=users.user_id
  1500. WHERE
  1501. item_properties.visibility='1' AND
  1502. thread.forum_id='".Database::escape_string($forum_id)."'
  1503. ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
  1504. if (is_allowed_to_edit()) {
  1505. // important note: it might seem a little bit awkward that we have 'thread.locked as locked' in the sql statement
  1506. // because we also have thread.* in it. This is because thread has a field locked and post also has the same field
  1507. // since we are merging these we would have the post.locked value but in fact we want the thread.locked value
  1508. // This is why it is added to the end of the field selection
  1509. $sql = "SELECT thread.*,
  1510. item_properties.*,
  1511. users.firstname,
  1512. users.lastname,
  1513. users.user_id,
  1514. thread.locked as locked
  1515. FROM $table_threads thread
  1516. INNER JOIN $table_item_property item_properties
  1517. ON thread.thread_id=item_properties.ref AND
  1518. item_properties.c_id = $course_id AND
  1519. thread.c_id = $course_id AND
  1520. item_properties.tool='".TABLE_FORUM_THREAD."'
  1521. LEFT JOIN $table_users users
  1522. ON thread.thread_poster_id=users.user_id
  1523. WHERE
  1524. item_properties.visibility<>2 AND
  1525. thread.forum_id='".Database::escape_string($forum_id)."'
  1526. ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
  1527. }
  1528. $result = Database::query($sql);
  1529. while ($row = Database::fetch_array($result, 'ASSOC')) {
  1530. $thread_list[] = $row;
  1531. }
  1532. return $thread_list;
  1533. }
  1534. /**
  1535. * Retrieve all posts of a given thread
  1536. *
  1537. * @return an array containing all the information about the posts of a given thread
  1538. *
  1539. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1540. * @version february 2006, dokeos 1.8
  1541. */
  1542. function get_posts($thread_id)
  1543. {
  1544. $table_users = Database :: get_main_table(TABLE_MAIN_USER);
  1545. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1546. $course_id = api_get_course_int_id();
  1547. // note: change these SQL so that only the relevant fields of the user table are used
  1548. if (api_is_allowed_to_edit(null, true)) {
  1549. $sql = "SELECT * FROM $table_posts posts
  1550. LEFT JOIN $table_users users
  1551. ON posts.poster_id=users.user_id
  1552. WHERE
  1553. c_id = $course_id AND
  1554. posts.thread_id='".Database::escape_string($thread_id)."'
  1555. ORDER BY posts.post_id ASC";
  1556. } else {
  1557. // students can only se the posts that are approved (posts.visible='1')
  1558. $sql = "SELECT * FROM $table_posts posts
  1559. LEFT JOIN $table_users users
  1560. ON posts.poster_id=users.user_id
  1561. WHERE
  1562. c_id = $course_id AND
  1563. posts.thread_id='".Database::escape_string($thread_id)."'
  1564. AND posts.visible='1'
  1565. ORDER BY posts.post_id ASC";
  1566. }
  1567. $result = Database::query($sql);
  1568. while ($row = Database::fetch_array($result)) {
  1569. $post_list[] = $row;
  1570. }
  1571. return $post_list;
  1572. }
  1573. // NEW TOPIC FUNCTIONS
  1574. /**
  1575. * This function retrieves all the information of a post
  1576. *
  1577. * @param $forum_id integer that indicates the forum
  1578. * @return array returns
  1579. *
  1580. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1581. * @version february 2006, dokeos 1.8
  1582. */
  1583. function get_post_information($post_id)
  1584. {
  1585. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1586. $table_users = Database :: get_main_table(TABLE_MAIN_USER);
  1587. $course_id = api_get_course_int_id();
  1588. $sql = "SELECT * FROM ".$table_posts."posts, ".$table_users." users
  1589. WHERE c_id = $course_id AND posts.poster_id=users.user_id AND posts.post_id='".Database::escape_string(
  1590. $post_id
  1591. )."'";
  1592. $result = Database::query($sql);
  1593. $row = Database::fetch_array($result);
  1594. return $row;
  1595. }
  1596. /**
  1597. * This function retrieves all the information of a thread
  1598. *
  1599. * @param $forum_id integer that indicates the forum
  1600. * @return array returns
  1601. *
  1602. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1603. * @version february 2006, dokeos 1.8
  1604. */
  1605. function get_thread_information($thread_id)
  1606. {
  1607. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1608. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  1609. $course_id = api_get_course_int_id();
  1610. $sql = "SELECT * FROM ".$table_threads." threads, ".$table_item_property." item_properties
  1611. WHERE item_properties.tool= '".TOOL_FORUM_THREAD."' AND
  1612. item_properties.c_id = $course_id AND
  1613. item_properties.ref = '".Database::escape_string($thread_id)."' AND
  1614. threads.thread_id = '".Database::escape_string($thread_id)."' AND
  1615. threads.c_id = $course_id
  1616. ";
  1617. $result = Database::query($sql);
  1618. $row = Database::fetch_array($result);
  1619. return $row;
  1620. }
  1621. /**
  1622. * This function retrieves forum thread users details
  1623. * @param int Thread ID
  1624. * @param string Course DB name (optional)
  1625. * @return resource array Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
  1626. * @author Christian Fasanando <christian.fasanando@dokeos.com>,
  1627. * @todo this function need to be improved
  1628. * @version octubre 2008, dokeos 1.8
  1629. */
  1630. function get_thread_users_details($thread_id)
  1631. {
  1632. $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1633. $t_users = Database :: get_main_table(TABLE_MAIN_USER);
  1634. $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1635. $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1636. $course_code = api_get_course_id();
  1637. $course_code = Database::escape_string($course_code);
  1638. $course_id = api_get_course_int_id();
  1639. $is_western_name_order = api_is_western_name_order();
  1640. if ($is_western_name_order) {
  1641. $orderby = 'ORDER BY user.firstname, user.lastname ';
  1642. } else {
  1643. $orderby = 'ORDER BY user.lastname, user.firstname';
  1644. }
  1645. if (api_get_session_id()) {
  1646. $session_info = api_get_session_info(api_get_session_id());
  1647. $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
  1648. //not showing coaches
  1649. $sql = "SELECT DISTINCT user.user_id, user.lastname, user.firstname, thread_id
  1650. FROM $t_posts , $t_users user, $t_session_rel_user session_rel_user_rel_course
  1651. WHERE poster_id = user.user_id AND
  1652. user.user_id = session_rel_user_rel_course.id_user AND
  1653. session_rel_user_rel_course.status<>'2' AND
  1654. session_rel_user_rel_course.id_user NOT IN ($user_to_avoid) AND
  1655. thread_id = '".Database::escape_string($thread_id)."' AND
  1656. id_session = '".api_get_session_id()."' AND
  1657. c_id = $course_id AND
  1658. course_code = '".$course_code."' $orderby ";
  1659. } else {
  1660. $sql = "SELECT DISTINCT user.user_id, user.lastname, user.firstname, thread_id
  1661. FROM $t_posts, $t_users user, $t_course_user course_user
  1662. WHERE poster_id = user.user_id AND
  1663. course_user.c_id = $t_posts.c_id
  1664. user.user_id = course_user.user_id AND
  1665. course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH." AND
  1666. thread_id = '".Database::escape_string($thread_id)."' AND
  1667. course_user.status NOT IN('1') AND
  1668. course_user.c_id = $course_id
  1669. $orderby";
  1670. }
  1671. $result = Database::query($sql);
  1672. return $result;
  1673. }
  1674. /**
  1675. * This function retrieves forum thread users qualify
  1676. * @param int Thread ID
  1677. * @param string Course DB name (optional)
  1678. * @return array Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
  1679. * @author Jhon Hinojosa<jhon.hinojosa@dokeos.com>,
  1680. * @todo this function need to be improved
  1681. * @version octubre 2008, dokeos 1.8
  1682. */
  1683. function get_thread_users_qualify($thread_id)
  1684. {
  1685. $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1686. $t_qualify = Database :: get_course_table(TABLE_FORUM_THREAD_QUALIFY);
  1687. $t_users = Database :: get_main_table(TABLE_MAIN_USER);
  1688. $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1689. $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1690. $course_id = api_get_course_int_id();
  1691. $course_code = api_get_course_id();
  1692. $course_code = Database::escape_string($course_code);
  1693. $is_western_name_order = api_is_western_name_order();
  1694. if ($is_western_name_order) {
  1695. $orderby = 'ORDER BY user.firstname, user.lastname ';
  1696. } else {
  1697. $orderby = 'ORDER BY user.lastname, user.firstname';
  1698. }
  1699. if (api_get_session_id()) {
  1700. $session_info = api_get_session_info(api_get_session_id());
  1701. $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
  1702. //not showing coaches
  1703. $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.user_id,qualify.qualify
  1704. FROM $t_posts post , $t_users user, $t_session_rel_user session_rel_user_rel_course, $t_qualify qualify
  1705. WHERE poster_id = user.user_id
  1706. AND post.poster_id = qualify.user_id
  1707. AND user.user_id = session_rel_user_rel_course.id_user
  1708. AND session_rel_user_rel_course.status<>'2'
  1709. AND session_rel_user_rel_course.id_user NOT IN ($user_to_avoid)
  1710. AND qualify.thread_id = '".Database::escape_string($thread_id)."
  1711. AND thread_id = '".Database::escape_string($thread_id)."'
  1712. AND id_session = '".api_get_session_id()."'
  1713. AND course_code = '".$course_code."' AND
  1714. qualify.c_id = $course_id AND
  1715. post.c_id = $course_id
  1716. $orderby ";
  1717. } else {
  1718. $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.user_id,qualify.qualify
  1719. FROM $t_posts post,
  1720. $t_qualify qualify,
  1721. $t_users user,
  1722. $t_course_user course_user
  1723. WHERE
  1724. post.poster_id = user.user_id
  1725. AND post.poster_id = qualify.user_id
  1726. AND user.user_id = course_user.user_id
  1727. AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
  1728. AND qualify.thread_id = '".Database::escape_string($thread_id)."'
  1729. AND post.thread_id = '".Database::escape_string($thread_id)."'
  1730. AND course_user.status not in('1')
  1731. AND course_user.c_id = $course_id AND
  1732. qualify.c_id = $course_id AND
  1733. post.c_id = $course_id
  1734. $orderby ";
  1735. }
  1736. $result = Database::query($sql);
  1737. return $result;
  1738. }
  1739. /**
  1740. * This function retrieves forum thread users not qualify
  1741. * @param int Thread ID
  1742. * @param string Course DB name (optional)
  1743. * @return array Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
  1744. * @author Jhon Hinojosa<jhon.hinojosa@dokeos.com>,
  1745. * @todo i'm a horrible function fix me
  1746. * @version octubre 2008, dokeos 1.8
  1747. */
  1748. function get_thread_users_not_qualify($thread_id)
  1749. {
  1750. $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1751. $t_qualify = Database :: get_course_table(TABLE_FORUM_THREAD_QUALIFY);
  1752. $t_users = Database :: get_main_table(TABLE_MAIN_USER);
  1753. $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1754. $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1755. $is_western_name_order = api_is_western_name_order();
  1756. if ($is_western_name_order) {
  1757. $orderby = 'ORDER BY user.firstname, user.lastname ';
  1758. } else {
  1759. $orderby = 'ORDER BY user.lastname, user.firstname';
  1760. }
  1761. $course_id = api_get_course_int_id();
  1762. $course_code = api_get_course_id();
  1763. $sql1 = "select user_id FROM $t_qualify WHERE c_id = $course_id AND thread_id = '".$thread_id."'";
  1764. $result1 = Database::query($sql1);
  1765. $cad = '';
  1766. while ($row = Database::fetch_array($result1)) {
  1767. $cad .= $row['user_id'].',';
  1768. }
  1769. if ($cad == '') {
  1770. $cad = '0';
  1771. } else {
  1772. $cad = substr($cad, 0, strlen($cad) - 1);
  1773. }
  1774. if (api_get_session_id()) {
  1775. $session_info = api_get_session_info(api_get_session_id());
  1776. $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
  1777. //not showing coaches
  1778. $sql = "SELECT DISTINCT user.user_id, user.lastname, user.firstname, post.thread_id
  1779. FROM $t_posts post , $t_users user, $t_session_rel_user session_rel_user_rel_course
  1780. WHERE poster_id = user.user_id
  1781. AND user.user_id NOT IN (".$cad.")
  1782. AND user.user_id = session_rel_user_rel_course.id_user
  1783. AND session_rel_user_rel_course.status<>'2'
  1784. AND session_rel_user_rel_course.id_user NOT IN ($user_to_avoid)
  1785. AND post.thread_id = '".Database::escape_string($thread_id)."'
  1786. AND id_session = '".api_get_session_id()."'
  1787. AND course_code = '".$course_code."' AND post.c_id = $course_id $orderby ";
  1788. } else {
  1789. $sql = "SELECT DISTINCT user.user_id, user.lastname, user.firstname, post.thread_id
  1790. FROM $t_posts post, $t_users user,$t_course_user course_user
  1791. WHERE post.poster_id = user.user_id
  1792. AND user.user_id NOT IN (".$cad.")
  1793. AND user.user_id = course_user.user_id
  1794. AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
  1795. AND post.thread_id = '".Database::escape_string($thread_id)."'
  1796. AND course_user.status not in('1')
  1797. AND course_user.c_id = $course_id AND post.c_id = $course_id $orderby";
  1798. }
  1799. $result = Database::query($sql);
  1800. return $result;
  1801. }
  1802. /**
  1803. * This function retrieves all the information of a given forum_id
  1804. *
  1805. * @param $forum_id integer that indicates the forum
  1806. * @return array returns
  1807. *
  1808. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1809. * @version february 2006, dokeos 1.8
  1810. *
  1811. * @deprecated this functionality is now moved to get_forums($forum_id)
  1812. */
  1813. function get_forum_information($forum_id)
  1814. {
  1815. $table_forums = Database :: get_course_table(TABLE_FORUM);
  1816. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1817. $sql = "SELECT * FROM ".$table_forums." forums, ".$table_item_property." item_properties
  1818. WHERE item_properties.tool = '".TOOL_FORUM."' AND
  1819. item_properties.ref = '".Database::escape_string($forum_id)."' AND
  1820. item_properties.c_id = ".api_get_course_int_id()." AND
  1821. forums.forum_id = '".Database::escape_string($forum_id)."' AND
  1822. forums.c_id = ".api_get_course_int_id()."
  1823. ";
  1824. $result = Database::query($sql);
  1825. $row = Database::fetch_array($result);
  1826. $row['approval_direct_post'] = 0; // We can't anymore change this option, so it should always be activated.
  1827. return $row;
  1828. }
  1829. /**
  1830. * This function retrieves all the information of a given forumcategory id
  1831. *
  1832. * @param $forum_id integer that indicates the forum
  1833. * @return array returns if there are category or bool returns if there aren't category
  1834. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1835. * @version february 2006, dokeos 1.8
  1836. */
  1837. function get_forumcategory_information($cat_id)
  1838. {
  1839. $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
  1840. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  1841. $course_id = api_get_course_int_id();
  1842. $sql = "SELECT * FROM ".$table_categories." forumcategories, ".$table_item_property." item_properties
  1843. WHERE forumcategories.c_id = $course_id AND
  1844. item_properties.c_id = $course_id AND
  1845. item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
  1846. item_properties.ref='".Database::escape_string($cat_id)."' AND
  1847. forumcategories.cat_id='".Database::escape_string($cat_id)."'";
  1848. $result = Database::query($sql);
  1849. $row = Database::fetch_array($result);
  1850. return $row;
  1851. }
  1852. /**
  1853. * This function counts the number of forums inside a given category
  1854. *
  1855. * @param $cat_id the id of the forum category
  1856. * @todo an additional parameter that takes the visibility into account. For instance $countinvisible=0 would return the number
  1857. * of visible forums, $countinvisible=1 would return the number of visible and invisible forums
  1858. * @return int the number of forums inside the given category
  1859. *
  1860. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1861. * @version february 2006, dokeos 1.8
  1862. */
  1863. function count_number_of_forums_in_category($cat_id)
  1864. {
  1865. $table_forums = Database :: get_course_table(TABLE_FORUM);
  1866. $course_id = api_get_course_int_id();
  1867. $sql = "SELECT count(*) AS number_of_forums FROM ".$table_forums." WHERE c_id = $course_id AND forum_category='".Database::escape_string(
  1868. $cat_id
  1869. )."'";
  1870. $result = Database::query($sql);
  1871. $row = Database::fetch_array($result);
  1872. return $row['number_of_forums'];
  1873. }
  1874. /**
  1875. * This function stores a new thread. This is done through an entry in the forum_thread table AND
  1876. * in the forum_post table because. The threads are also stored in the item_property table. (forum posts are not (yet))
  1877. *
  1878. * @param array
  1879. * @return void HTML
  1880. *
  1881. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1882. * @version february 2006, dokeos 1.8
  1883. */
  1884. function store_thread($values)
  1885. {
  1886. global $_user;
  1887. $_course = api_get_course_info();
  1888. global $current_forum;
  1889. global $origin;
  1890. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  1891. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  1892. $course_id = api_get_course_int_id();
  1893. $gradebook = Security::remove_XSS($_GET['gradebook']);
  1894. $upload_ok = 1;
  1895. $has_attachment = false;
  1896. if (!empty($_FILES['user_upload']['name'])) {
  1897. $upload_ok = FileManager::process_uploaded_file($_FILES['user_upload']);
  1898. $has_attachment = true;
  1899. }
  1900. if ($upload_ok) {
  1901. $post_date = api_get_utc_datetime();
  1902. if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
  1903. $visible = 0; // The post has not been approved yet.
  1904. } else {
  1905. $visible = 1;
  1906. }
  1907. $clean_post_title = Database::escape_string(stripslashes($values['post_title']));
  1908. // We first store an entry in the forum_thread table because the thread_id is used in the forum_post table.
  1909. $sql = "INSERT INTO $table_threads (c_id, thread_title, forum_id, thread_poster_id, thread_poster_name, thread_date, thread_sticky,thread_title_qualify,thread_qualify_max,thread_weight,session_id)
  1910. VALUES (
  1911. ".$course_id.",
  1912. '".$clean_post_title."',
  1913. '".Database::escape_string($values['forum_id'])."',
  1914. '".Database::escape_string($_user['user_id'])."',
  1915. '".Database::escape_string(
  1916. stripslashes(isset($values['poster_name']) ? $values['poster_name'] : null)
  1917. )."',
  1918. '".Database::escape_string($post_date)."',
  1919. '".Database::escape_string(
  1920. isset($values['thread_sticky']) ? $values['thread_sticky'] : null
  1921. )."',".
  1922. "'".Database::escape_string(stripslashes($values['calification_notebook_title']))."',".
  1923. "'".Database::escape_string($values['numeric_calification'])."',".
  1924. "'".Database::escape_string($values['weight_calification'])."',".
  1925. "'".api_get_session_id()."')";
  1926. $result = Database::query($sql);
  1927. $last_thread_id = Database::insert_id();
  1928. // Add option gradebook qualify.
  1929. if (isset($values['thread_qualify_gradebook']) && 1 == $values['thread_qualify_gradebook']) {
  1930. // Add function gradebook.
  1931. $coursecode = api_get_course_id();
  1932. $resourcetype = 5;
  1933. $resourceid = $last_thread_id;
  1934. $resourcename = stripslashes($values['calification_notebook_title']);
  1935. $maxqualify = $values['numeric_calification'];
  1936. $weigthqualify = $values['weight_calification'];
  1937. $resourcedescription = '';
  1938. add_resource_to_course_gradebook(
  1939. $values['category_id'],
  1940. $coursecode,
  1941. $resourcetype,
  1942. $resourceid,
  1943. $resourcename,
  1944. $weigthqualify,
  1945. $maxqualify,
  1946. $resourcedescription,
  1947. 0,
  1948. api_get_session_id()
  1949. );
  1950. }
  1951. if ($last_thread_id) {
  1952. api_item_property_update(
  1953. $_course,
  1954. TOOL_FORUM_THREAD,
  1955. $last_thread_id,
  1956. 'ForumThreadAdded',
  1957. api_get_user_id()
  1958. );
  1959. // If the forum properties tell that the posts have to be approved we have to put the whole thread invisible,
  1960. // because otherwise the students will see the thread and not the post in the thread.
  1961. // We also have to change $visible because the post itself has to be visible in this case (otherwise the teacher would have
  1962. // to make the thread visible AND the post.
  1963. //Default behaviour
  1964. api_set_default_visibility($_course, $last_thread_id, TOOL_FORUM_THREAD);
  1965. if ($visible == 0) {
  1966. api_item_property_update($_course, TOOL_FORUM_THREAD, $last_thread_id, 'invisible', api_get_user_id());
  1967. $visible = 1;
  1968. }
  1969. }
  1970. // We now store the content in the table_post table.
  1971. $sql = "INSERT INTO $table_posts (c_id, post_title, post_text, thread_id, forum_id, poster_id, poster_name, post_date, post_notification, post_parent_id, visible)
  1972. VALUES (
  1973. ".$course_id.",
  1974. '".$clean_post_title."',
  1975. '".Database::escape_string($values['post_text'])."',
  1976. '".Database::escape_string($last_thread_id)."',
  1977. '".Database::escape_string($values['forum_id'])."',
  1978. '".Database::escape_string($_user['user_id'])."',
  1979. '".Database::escape_string(stripslashes(isset($values['poster_name']) ? $values['poster_name'] : null))."',
  1980. '".Database::escape_string($post_date)."',
  1981. '".Database::escape_string(isset($values['post_notification']) ? $values['post_notification'] : null)."','0',
  1982. '".Database::escape_string($visible)."')";
  1983. Database::query($sql);
  1984. $last_post_id = Database::insert_id();
  1985. // Now we have to update the thread table to fill the thread_last_post field (so that we know when the thread has been updated for the last time).
  1986. $sql = "UPDATE $table_threads SET thread_last_post='".Database::escape_string(
  1987. $last_post_id
  1988. )."' WHERE c_id = $course_id AND thread_id='".Database::escape_string($last_thread_id)."'";
  1989. $result = Database::query($sql);
  1990. $message = get_lang('NewThreadStored');
  1991. // Storing the attachments if any.
  1992. if ($has_attachment) {
  1993. $course_dir = $_course['path'].'/upload/forum';
  1994. $sys_course_path = api_get_path(SYS_COURSE_PATH);
  1995. $updir = $sys_course_path.$course_dir;
  1996. // Try to add an extension to the file if it hasn't one.
  1997. $new_file_name = FileManager::add_ext_on_mime(
  1998. stripslashes($_FILES['user_upload']['name']),
  1999. $_FILES['user_upload']['type']
  2000. );
  2001. // User's file name
  2002. $file_name = $_FILES['user_upload']['name'];
  2003. if (!FileManager::filter_extension($new_file_name)) {
  2004. Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
  2005. } else {
  2006. if ($result) {
  2007. $comment = Database::escape_string($comment);
  2008. add_forum_attachment_file($comment, $last_post_id);
  2009. }
  2010. }
  2011. } else {
  2012. $message .= '<br />';
  2013. }
  2014. if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
  2015. $message .= get_lang('MessageHasToBeApproved').'<br />';
  2016. $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq(
  2017. ).'&amp;forum='.$values['forum_id'].'&amp;gidReq='.$_SESSION['toolgroup'].'&amp;origin='.$origin.'">'.get_lang(
  2018. 'Forum'
  2019. ).'</a><br />';
  2020. } else {
  2021. $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq(
  2022. ).'&amp;forum='.$values['forum_id'].'&amp;gidReq='.$_SESSION['toolgroup'].'&amp;origin='.$origin.'">'.get_lang(
  2023. 'Forum'
  2024. ).'</a><br />';
  2025. $message .= get_lang('ReturnTo').' <a href="viewthread.php?'.api_get_cidreq(
  2026. ).'&amp;forum='.$values['forum_id'].'&amp;gidReq='.$_SESSION['toolgroup'].'&amp;origin='.$origin.'&amp;gradebook='.$gradebook.'&amp;thread='.$last_thread_id.'">'.get_lang(
  2027. 'Message'
  2028. ).'</a>';
  2029. }
  2030. $reply_info['new_post_id'] = $last_post_id;
  2031. $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
  2032. if ($my_post_notification == 1) {
  2033. set_notification('thread', $last_thread_id, true);
  2034. }
  2035. send_notification_mails($last_thread_id, $reply_info);
  2036. Session::erase('formelements');
  2037. Session::erase('origin');
  2038. Session::erase('breadcrumbs');
  2039. Session::erase('addedresource');
  2040. Session::erase('addedresourceid');
  2041. Display :: display_confirmation_message($message, false);
  2042. } else {
  2043. Display::display_error_message(get_lang('UplNoFileUploaded'));
  2044. }
  2045. }
  2046. /**
  2047. * This function displays the form that is used to add a post. This can be a new thread or a reply.
  2048. * @param $action is the parameter that determines if we are
  2049. * 1. newthread: adding a new thread (both empty) => No I-frame
  2050. * 2. replythread: Replying to a thread ($action = replythread) => I-frame with the complete thread (if enabled)
  2051. * 3. replymessage: Replying to a message ($action =replymessage) => I-frame with the complete thread (if enabled) (I first thought to put and I-frame with the message only)
  2052. * 4. quote: Quoting a message ($action= quotemessage) => I-frame with the complete thread (if enabled). The message will be in the reply. (I first thought not to put an I-frame here)
  2053. * @return void HMTL
  2054. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2055. * @version february 2006, dokeos 1.8
  2056. */
  2057. function show_add_post_form($action = '', $id = '', $form_values = '')
  2058. {
  2059. global $forum_setting;
  2060. global $current_forum;
  2061. global $_user;
  2062. global $origin;
  2063. $gradebook = Security::remove_XSS($_GET['gradebook']);
  2064. // Setting the class and text of the form title and submit button.
  2065. if ($_GET['action'] == 'quote') {
  2066. $class = 'save';
  2067. $text = get_lang('QuoteMessage');
  2068. } elseif ($_GET['action'] == 'replythread') {
  2069. $class = 'save';
  2070. $text = get_lang('ReplyToThread');
  2071. } elseif ($_GET['action'] == 'replymessage') {
  2072. $class = 'save';
  2073. $text = get_lang('ReplyToMessage');
  2074. } else {
  2075. $class = 'add';
  2076. $text = get_lang('CreateThread');
  2077. }
  2078. // Initialize the object.
  2079. $my_thread = isset($_GET['thread']) ? $_GET['thread'] : '';
  2080. $my_forum = isset($_GET['forum']) ? $_GET['forum'] : '';
  2081. $my_action = isset($_GET['action']) ? $_GET['action'] : '';
  2082. $my_post = isset($_GET['post']) ? $_GET['post'] : '';
  2083. $my_gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
  2084. $form = new FormValidator('thread', 'post', api_get_self().'?forum='.Security::remove_XSS(
  2085. $my_forum
  2086. ).'&gradebook='.$gradebook.'&thread='.Security::remove_XSS($my_thread).'&post='.Security::remove_XSS(
  2087. $my_post
  2088. ).'&action='.Security::remove_XSS($my_action).'&origin='.$origin);
  2089. $form->setConstants(array('forum' => '5'));
  2090. $form->addElement('header', $text);
  2091. // Settting the form elements.
  2092. $form->addElement('hidden', 'forum_id', intval($my_forum));
  2093. $form->addElement('hidden', 'thread_id', intval($my_thread));
  2094. $form->addElement('hidden', 'gradebook', $my_gradebook);
  2095. // If anonymous posts are allowed we also display a form to allow the user to put his name or username in.
  2096. if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
  2097. $form->addElement('text', 'poster_name', get_lang('Name'));
  2098. $form->applyFilter('poster_name', 'html_filter');
  2099. }
  2100. $form->addElement('text', 'post_title', get_lang('Title'));
  2101. $form->addElement(
  2102. 'html_editor',
  2103. 'post_text',
  2104. get_lang('Text'),
  2105. true,
  2106. api_is_allowed_to_edit(null, true)
  2107. ? array('ToolbarSet' => 'Forum', 'Width' => '100%', 'Height' => '300')
  2108. : array('ToolbarSet' => 'ForumStudent', 'Width' => '100%', 'Height' => '300', 'UserStatus' => 'student')
  2109. );
  2110. $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
  2111. $form->addElement('advanced_settings', 'id_qualify', get_lang('AdvancedParameters'));
  2112. $form->addElement('html', '<div id="id_qualify_options" style="display:none">');
  2113. if ((api_is_course_admin() || api_is_course_coach() || api_is_course_tutor()) && !($my_thread)) {
  2114. // Thread qualify
  2115. if (Gradebook::is_active()) {
  2116. //Loading gradebook select
  2117. load_gradebook_select_in_tool($form);
  2118. $form->addElement(
  2119. 'checkbox',
  2120. 'thread_qualify_gradebook',
  2121. '',
  2122. get_lang('QualifyThreadGradebook'),
  2123. 'onclick="javascript:if(this.checked==true){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
  2124. );
  2125. } else {
  2126. $form->addElement('hidden', 'thread_qualify_gradebook', false);
  2127. }
  2128. $form->addElement('html', '<div id="options_field" style="display:none">');
  2129. $form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
  2130. $form->applyFilter('numeric_calification', 'html_filter');
  2131. $form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
  2132. $form->applyFilter('calification_notebook_title', 'html_filter');
  2133. $form->addElement(
  2134. 'text',
  2135. 'weight_calification',
  2136. get_lang('QualifyWeight'),
  2137. 'value="0.00" Style="width:40px" onfocus="javascript: this.select();"'
  2138. );
  2139. $form->applyFilter('weight_calification', 'html_filter');
  2140. $form->addElement('html', '</div>');
  2141. }
  2142. if ($forum_setting['allow_post_notification'] && isset($_user['user_id'])) {
  2143. $form->addElement('checkbox', 'post_notification', '', get_lang('NotifyByEmail').' ('.$_user['mail'].')');
  2144. }
  2145. if ($forum_setting['allow_sticky'] && api_is_allowed_to_edit(null, true) && $action == 'newthread') {
  2146. $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
  2147. }
  2148. if ($current_forum['allow_attachments'] == '1' || api_is_allowed_to_edit(null, true)) {
  2149. $values = $form->exportValues();
  2150. }
  2151. // User upload
  2152. $form->addElement('static', null, null, get_lang('AddAnAttachment'));
  2153. $form->addElement('file', 'user_upload', get_lang('FileName'), '');
  2154. $form->addElement('textarea', 'file_comment', get_lang('FileComment'), array('rows' => 4, 'cols' => 34));
  2155. $form->applyFilter('file_comment', 'html_filter');
  2156. $form->addElement('html', '</div>');
  2157. $form->addElement('style_submit_button', 'SubmitPost', $text, 'class="'.$class.'"');
  2158. $form->add_real_progress_bar('DocumentUpload', 'user_upload');
  2159. if (!empty($form_values)) {
  2160. $defaults['post_title'] = prepare4display($form_values['post_title']);
  2161. $defaults['post_text'] = prepare4display($form_values['post_text']);
  2162. $defaults['post_notification'] = strval(intval($form_values['post_notification']));
  2163. $defaults['thread_sticky'] = strval(intval($form_values['thread_sticky']));
  2164. }
  2165. // If we are quoting a message we have to retrieve the information of the post we are quoting so that
  2166. // we can add this as default to the textarea.
  2167. if (($action == 'quote' || $action == 'replymessage') && isset($my_post)) {
  2168. // We also need to put the parent_id of the post in a hidden form when we are quoting or replying to a message (<> reply to a thread !!!)
  2169. $form->addElement('hidden', 'post_parent_id', strval(intval($my_post))); // Note: This has to be cleaned first.
  2170. // If we are replying or are quoting then we display a default title.
  2171. $values = get_post_information($my_post); // Note: This has to be cleaned first.
  2172. $defaults['post_title'] = get_lang('ReplyShort').api_html_entity_decode($values['post_title'], ENT_QUOTES);
  2173. // When we are quoting a message then we have to put that message into the wysiwyg editor.
  2174. // Note: The style has to be hardcoded here because using class="quote" didn't work.
  2175. if ($action == 'quote') {
  2176. $defaults['post_text'] = '<div>&nbsp;</div><div style="margin: 5px;"><div style="font-size: 90%; font-style: italic;">'.get_lang(
  2177. 'Quoting'
  2178. ).' '.api_get_person_name(
  2179. $values['firstname'],
  2180. $values['lastname']
  2181. ).':</div><div style="color: #006600; font-size: 90%; font-style: italic; background-color: #FAFAFA; border: #D1D7DC 1px solid; padding: 3px;">'.prepare4display(
  2182. $values['post_text']
  2183. ).'</div></div><div>&nbsp;</div><div>&nbsp;</div>';
  2184. }
  2185. }
  2186. $form->setDefaults(isset($defaults) ? $defaults : null);
  2187. // The course admin can make a thread sticky (=appears with special icon and always on top).
  2188. $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
  2189. if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
  2190. $form->addRule('poster_name', get_lang('ThisFieldIsRequired'), 'required');
  2191. }
  2192. // Validation or display
  2193. if ($form->validate()) {
  2194. $check = Security::check_token('post');
  2195. if ($check) {
  2196. $values = $form->exportValues();
  2197. if ($values['thread_qualify_gradebook'] == '1' && empty($values['weight_calification'])) {
  2198. Display::display_error_message(
  2199. get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.back()">'.get_lang(
  2200. 'Back'
  2201. ).'</a>',
  2202. false
  2203. );
  2204. return false;
  2205. }
  2206. Security::clear_token();
  2207. return $values;
  2208. }
  2209. } else {
  2210. $token = Security::get_token();
  2211. $form->addElement('hidden', 'sec_token');
  2212. $form->setConstants(array('sec_token' => $token));
  2213. $iframe = null;
  2214. if ($forum_setting['show_thread_iframe_on_reply'] && $action != 'newthread') {
  2215. $iframe = "<iframe style=\"border: 1px solid black\" src=\"iframe_thread.php?forum=".Security::remove_XSS(
  2216. $my_forum
  2217. )."&amp;thread=".Security::remove_XSS($my_thread)."#".Security::remove_XSS(
  2218. $my_post
  2219. )."\" width=\"100%\"></iframe>";
  2220. }
  2221. if (!empty($iframe)) {
  2222. $form->addElement('label', get_lang('Thread'), $iframe);
  2223. }
  2224. $form->display();
  2225. }
  2226. }
  2227. /**
  2228. * @param integer contains the information of user id
  2229. * @param integer contains the information of thread id
  2230. * @param integer contains the information of thread qualify
  2231. * @param integer contains the information of user id of qualifier
  2232. * @param integer contains the information of time
  2233. * @param integer contains the information of session id
  2234. * @return Array() optional
  2235. * @author Isaac Flores <isaac.flores@dokeos.com>, U.N.A.S University
  2236. * @version October 2008, dokeos 1.8.6
  2237. */
  2238. function store_theme_qualify(
  2239. $user_id,
  2240. $thread_id,
  2241. $thread_qualify = 0,
  2242. $qualify_user_id = 0,
  2243. $qualify_time,
  2244. $session_id = null
  2245. ) {
  2246. $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
  2247. $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
  2248. $course_id = api_get_course_int_id();
  2249. if ($user_id == strval(intval($user_id)) && $thread_id == strval(intval($thread_id)) && $thread_qualify == strval(
  2250. floatval($thread_qualify)
  2251. )
  2252. ) {
  2253. // Testing
  2254. $sql_string = "SELECT thread_qualify_max FROM ".$table_threads." WHERE c_id = $course_id AND thread_id=".$thread_id.";";
  2255. $res_string = Database::query($sql_string);
  2256. $row_string = Database::fetch_array($res_string);
  2257. if ($thread_qualify <= $row_string[0]) {
  2258. $sql1 = "SELECT COUNT(*) FROM ".$table_threads_qualify." WHERE c_id = $course_id AND user_id=".$user_id." and thread_id=".$thread_id.";";
  2259. $res1 = Database::query($sql1);
  2260. $row = Database::fetch_array($res1);
  2261. if ($row[0] == 0) {
  2262. $sql = "INSERT INTO $table_threads_qualify (c_id, user_id, thread_id,qualify,qualify_user_id,qualify_time,session_id)
  2263. VALUES (".$course_id.", '".$user_id."','".$thread_id."',".(float)$thread_qualify.", '".$qualify_user_id."','".$qualify_time."','".$session_id."')";
  2264. $res = Database::query($sql);
  2265. return $res;
  2266. } else {
  2267. $sql1 = "SELECT qualify FROM ".$table_threads_qualify." WHERE c_id = $course_id AND user_id=".$user_id." and thread_id=".$thread_id.";";
  2268. $rs = Database::query($sql1);
  2269. $row = Database::fetch_array($rs);
  2270. $row[1] = "update";
  2271. return $row;
  2272. }
  2273. } else {
  2274. return null;
  2275. }
  2276. }
  2277. }
  2278. /**
  2279. * This function shows qualify.
  2280. * @param string contains the information of option to run
  2281. * @param string contains the information the current course id
  2282. * @param integer contains the information the current forum id
  2283. * @param integer contains the information the current user id
  2284. * @param integer contains the information the current thread id
  2285. * @return integer qualify
  2286. * <code> $option=1 obtained the qualification of the current thread</code>
  2287. * @author Isaac Flores <isaac.flores@dokeos.com>, U.N.A.S University
  2288. * @version October 2008, dokeos 1.8.6
  2289. */
  2290. function show_qualify($option, $user_id, $thread_id)
  2291. {
  2292. $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
  2293. $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
  2294. $course_id = api_get_course_int_id();
  2295. $user_id = intval($user_id);
  2296. $thread_id = intval($thread_id);
  2297. if (empty($user_id) || empty($thread_id)) {
  2298. return false;
  2299. }
  2300. switch ($option) {
  2301. case 1:
  2302. $sql = "SELECT qualify FROM ".$table_threads_qualify." WHERE c_id = $course_id AND user_id=".$user_id." and thread_id=".$thread_id;
  2303. break;
  2304. case 2:
  2305. $sql = "SELECT thread_qualify_max FROM ".$table_threads." WHERE c_id = $course_id AND thread_id=".$thread_id.";";
  2306. break;
  2307. }
  2308. $rs = Database::query($sql);
  2309. $row = Database::fetch_array($rs);
  2310. return $row[0];
  2311. }
  2312. /**
  2313. * This function gets qualify historical.
  2314. * @param integer contains the information the current user id
  2315. * @param integer contains the information the current thread id
  2316. * @param boolean contains the information of option to run
  2317. * @return array()
  2318. * @author Christian Fasanando <christian.fasanando@dokeos.com>,
  2319. * @author Isaac Flores <isaac.flores@dokeos.com>,
  2320. * @version October 2008, dokeos 1.8.6
  2321. */
  2322. function get_historical_qualify($user_id, $thread_id, $opt)
  2323. {
  2324. $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
  2325. $course_id = api_get_course_int_id();
  2326. $my_qualify_log = array();
  2327. if ($opt == 'false') {
  2328. $sql = "SELECT * FROM ".$table_threads_qualify_log." WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  2329. $thread_id
  2330. )."' and user_id='".Database::escape_string($user_id)."' ORDER BY qualify_time";
  2331. } else {
  2332. $sql = "SELECT * FROM ".$table_threads_qualify_log." WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  2333. $thread_id
  2334. )."' and user_id='".Database::escape_string($user_id)."' ORDER BY qualify_time DESC";
  2335. }
  2336. $rs = Database::query($sql);
  2337. while ($row = Database::fetch_array($rs, 'ASSOC')) {
  2338. $my_qualify_log[] = $row;
  2339. }
  2340. return $my_qualify_log;
  2341. }
  2342. /**
  2343. * This function stores qualify historical.
  2344. * @param boolean contains the information of option to run
  2345. * @param string contains the information the current course id
  2346. * @param integer contains the information the current forum id
  2347. * @param integer contains the information the current user id
  2348. * @param integer contains the information the current thread id
  2349. * @param integer contains the information the current qualify
  2350. * @return void
  2351. * <code>$option=1 obtained the qualification of the current thread</code>
  2352. * @author Isaac Flores <isaac.flores@dokeos.com>, U.N.A.S University
  2353. * @version October 2008, dokeos 1.8.6
  2354. */
  2355. function store_qualify_historical(
  2356. $option,
  2357. $couser_id,
  2358. $forum_id,
  2359. $user_id,
  2360. $thread_id,
  2361. $current_qualify,
  2362. $qualify_user_id
  2363. ) {
  2364. $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
  2365. $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
  2366. $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
  2367. $current_date = date('Y-m-d H:i:s');
  2368. $course_id = api_get_course_int_id();
  2369. if ($user_id == strval(intval($user_id)) && $thread_id == strval(intval($thread_id)) && $option == 1) {
  2370. // Extract information of thread_qualify.
  2371. $sql = "SELECT qualify,qualify_time FROM ".$table_threads_qualify." WHERE c_id = $course_id AND user_id=".$user_id." and thread_id=".$thread_id.";";
  2372. $rs = Database::query($sql);
  2373. $row = Database::fetch_array($rs);
  2374. // Insert thread_historical.
  2375. $sql1 = "INSERT INTO $table_threads_qualify_log (c_id, user_id, thread_id,qualify,qualify_user_id,qualify_time,session_id)
  2376. VALUES(".$course_id.", '".$user_id."','".$thread_id."',".(float)$row[0].", '".$qualify_user_id."','".$row[1]."','')";
  2377. Database::query($sql1);
  2378. // Update
  2379. $sql2 = "UPDATE ".$table_threads_qualify." SET qualify=".$current_qualify.",qualify_time='".$current_date."' WHERE c_id = $course_id AND user_id=".$user_id." and thread_id=".$thread_id.";";
  2380. Database::query($sql2);
  2381. }
  2382. }
  2383. /**
  2384. * This function shows current thread qualify .
  2385. * @param integer contains the information the current thread id
  2386. * @param integer contains the information the current session id
  2387. * @return array or null if is empty
  2388. * @author Isaac Flores <isaac.flores@dokeos.com>, U.N.A.S University
  2389. * @version December 2008, dokeos 1.8.6
  2390. */
  2391. function current_qualify_of_thread($thread_id, $session_id)
  2392. {
  2393. $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
  2394. $course_id = api_get_course_int_id();
  2395. $res = Database::query(
  2396. "SELECT qualify FROM $table_threads_qualify WHERE c_id = $course_id AND thread_id = $thread_id AND session_id = $session_id"
  2397. );
  2398. $row = Database::fetch_array($res, 'ASSOC');
  2399. return $row['qualify'];
  2400. }
  2401. /**
  2402. * This function stores a reply in the forum_post table.
  2403. * It also updates the forum_threads table (thread_replies +1 , thread_last_post, thread_date)
  2404. *
  2405. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2406. * @version february 2006, dokeos 1.8
  2407. */
  2408. function store_reply($values)
  2409. {
  2410. $_course = api_get_course_info();
  2411. global $current_forum;
  2412. global $origin;
  2413. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  2414. $forum_table_attachment = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
  2415. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  2416. $gradebook = Security::remove_XSS($_GET['gradebook']);
  2417. $post_date = api_get_utc_datetime();
  2418. if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
  2419. $visible = 0; // The post has not been approved yet.
  2420. } else {
  2421. $visible = 1;
  2422. }
  2423. $upload_ok = 1;
  2424. $has_attachment = false;
  2425. if (!empty($_FILES['user_upload']['name'])) {
  2426. $upload_ok = FileManager::process_uploaded_file($_FILES['user_upload']);
  2427. $has_attachment = true;
  2428. }
  2429. $return = array();
  2430. if ($upload_ok) {
  2431. // We first store an entry in the forum_post table.
  2432. $sql = "INSERT INTO $table_posts (c_id, post_title, post_text, thread_id, forum_id, poster_id, post_date, post_notification, post_parent_id, visible)
  2433. VALUES (
  2434. ".api_get_course_int_id().",
  2435. '".Database::escape_string($values['post_title'])."',
  2436. '".Database::escape_string(isset($values['post_text']) ? ($values['post_text']) : null)."',
  2437. '".Database::escape_string($values['thread_id'])."',
  2438. '".Database::escape_string($values['forum_id'])."',
  2439. '".api_get_user_id()."',
  2440. '".$post_date."',
  2441. '".Database::escape_string(
  2442. isset($values['post_notification']) ? $values['post_notification'] : null
  2443. )."',
  2444. '".Database::escape_string(isset($values['post_parent_id']) ? $values['post_parent_id'] : null)."',
  2445. '".Database::escape_string($visible)."')";
  2446. $result = Database::query($sql);
  2447. $new_post_id = Database::insert_id();
  2448. $values['new_post_id'] = $new_post_id;
  2449. $message = get_lang('ReplyAdded');
  2450. if ($has_attachment) {
  2451. $course_dir = $_course['path'].'/upload/forum';
  2452. $sys_course_path = api_get_path(SYS_COURSE_PATH);
  2453. $updir = $sys_course_path.$course_dir;
  2454. // Try to add an extension to the file if it hasn't one.
  2455. $new_file_name = FileManager::add_ext_on_mime(
  2456. stripslashes($_FILES['user_upload']['name']),
  2457. $_FILES['user_upload']['type']
  2458. );
  2459. // User's file name
  2460. $file_name = $_FILES['user_upload']['name'];
  2461. if (!FileManager::filter_extension($new_file_name)) {
  2462. $return['msg'] = get_lang('UplUnableToSaveFileFilteredExtension');
  2463. $return['type'] = 'error';
  2464. } else {
  2465. $new_file_name = uniqid('');
  2466. $new_path = $updir.'/'.$new_file_name;
  2467. $result = @move_uploaded_file($_FILES['user_upload']['tmp_name'], $new_path);
  2468. $comment = $values['file_comment'];
  2469. // Storing the attachments if any.
  2470. if ($result) {
  2471. $sql = 'INSERT INTO '.$forum_table_attachment.'(c_id, filename,comment, path, post_id,size) '.
  2472. "VALUES (".api_get_course_int_id().", '".Database::escape_string(
  2473. $file_name
  2474. )."', '".Database::escape_string($comment)."', '".Database::escape_string(
  2475. $new_file_name
  2476. )."' , '".$new_post_id."', '".intval($_FILES['user_upload']['size'])."' )";
  2477. $result = Database::query($sql);
  2478. $message .= ' / '.get_lang('FileUploadSucces');
  2479. $last_id = Database::insert_id();
  2480. api_item_property_update(
  2481. $_course,
  2482. TOOL_FORUM_ATTACH,
  2483. $last_id,
  2484. 'ForumAttachmentAdded',
  2485. api_get_user_id()
  2486. );
  2487. }
  2488. }
  2489. }
  2490. // Update the thread.
  2491. update_thread($values['thread_id'], $new_post_id, $post_date);
  2492. // Update the forum.
  2493. api_item_property_update($_course, TOOL_FORUM, $values['forum_id'], 'NewMessageInForum', api_get_user_id());
  2494. if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
  2495. $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
  2496. }
  2497. //$message .= '<br />'.get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&amp;forum='.$values['forum_id'].'&amp;gidReq='.$_SESSION['toolgroup'].'&amp;origin='.$origin.'">'.get_lang('Forum').'</a><br />';
  2498. //$message .= get_lang('ReturnTo').' <a href="viewthread.php?'.api_get_cidreq().'&amp;forum='.$values['forum_id'].'&amp;thread='.$values['thread_id'].'&amp;gidReq='.$_SESSION['toolgroup'].'&amp;origin='.$origin.'&amp;gradebook='.$gradebook.'">'.get_lang('Message').'</a>';
  2499. // Setting the notification correctly.
  2500. $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
  2501. if ($my_post_notification == 1) {
  2502. set_notification('thread', $values['thread_id'], true);
  2503. }
  2504. send_notification_mails($values['thread_id'], $values);
  2505. Session::erase('formelements');
  2506. Session::erase('origin');
  2507. Session::erase('breadcrumbs');
  2508. Session::erase('addedresource');
  2509. Session::erase('addedresourceid');
  2510. $return['msg'] = $message;
  2511. $return['type'] = 'confirmation';
  2512. } else {
  2513. $return['msg'] = get_lang('UplNoFileUploaded').' '.get_lang('UplSelectFileFirst');
  2514. $return['type'] = 'error';
  2515. }
  2516. return $return;
  2517. }
  2518. /**
  2519. * This function displays the form that is used to edit a post. This can be a new thread or a reply.
  2520. * @param array contains all the information about the current post
  2521. * @param array contains all the information about the current thread
  2522. * @param array contains all info about the current forum (to check if attachments are allowed)
  2523. * @param array contains the default values to fill the form
  2524. * @return void
  2525. *
  2526. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2527. * @version february 2006, dokeos 1.8
  2528. */
  2529. function show_edit_post_form($current_post, $current_thread, $current_forum, $form_values = '', $id_attach = 0)
  2530. {
  2531. global $forum_setting;
  2532. global $origin;
  2533. $gradebook = Security::remove_XSS($_GET['gradebook']);
  2534. // Initialize the object.
  2535. $form = new FormValidator('edit_post', 'post', api_get_self().'?forum='.Security::remove_XSS(
  2536. $_GET['forum']
  2537. ).'&amp;gradebook='.$gradebook.'&amp;origin='.$origin.'&amp;thread='.Security::remove_XSS(
  2538. $_GET['thread']
  2539. ).'&amp;post='.Security::remove_XSS($_GET['post']));
  2540. $form->addElement('header', get_lang('EditPost'));
  2541. // Settting the form elements.
  2542. $form->addElement('hidden', 'post_id', $current_post['post_id']);
  2543. $form->addElement('hidden', 'thread_id', $current_thread['thread_id']);
  2544. $form->addElement('hidden', 'id_attach', $id_attach);
  2545. if ($current_post['post_parent_id'] == 0) {
  2546. $form->addElement('hidden', 'is_first_post_of_thread', '1');
  2547. }
  2548. $form->addElement('text', 'post_title', get_lang('Title'), 'class="input_titles"');
  2549. $form->applyFilter('post_title', 'html_filter');
  2550. $form->addElement(
  2551. 'html_editor',
  2552. 'post_text',
  2553. get_lang('Text'),
  2554. null,
  2555. api_is_allowed_to_edit(null, true)
  2556. ? array('ToolbarSet' => 'Forum', 'Width' => '100%', 'Height' => '400')
  2557. : array('ToolbarSet' => 'ForumStudent', 'Width' => '100%', 'Height' => '400', 'UserStatus' => 'student')
  2558. );
  2559. $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
  2560. $form->addElement('advanced_settings', 'id_qualify', get_lang('AdvancedParameters'));
  2561. $form->addElement('html', '<div id="id_qualify_options" style="display:none">');
  2562. if (!isset($_GET['edit'])) {
  2563. if (Gradebook::is_active()) {
  2564. $form->addElement('label', '<strong>'.get_lang('AlterQualifyThread').'</strong>');
  2565. $form->addElement(
  2566. 'checkbox',
  2567. 'thread_qualify_gradebook',
  2568. '',
  2569. get_lang('QualifyThreadGradebook'),
  2570. 'onclick="javascript: if(this.checked){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
  2571. );
  2572. $link_info = is_resource_in_course_gradebook(api_get_course_id(), 5, $_GET['thread'], api_get_session_id());
  2573. if (!empty($link_info)) {
  2574. $defaults['thread_qualify_gradebook'] = true;
  2575. $defaults['category_id'] = $link_info['category_id'];
  2576. } else {
  2577. $defaults['thread_qualify_gradebook'] = false;
  2578. $defaults['category_id'] = '';
  2579. }
  2580. } else {
  2581. $form->addElement('hidden', 'thread_qualify_gradebook', false);
  2582. $defaults['thread_qualify_gradebook'] = false;
  2583. }
  2584. if (!empty($defaults['thread_qualify_gradebook'])) {
  2585. $form->addElement('html', '<div id="options_field" style="display:block">');
  2586. } else {
  2587. $form->addElement('html', '<div id="options_field" style="display:none">');
  2588. }
  2589. //Loading gradebook select
  2590. load_gradebook_select_in_tool($form);
  2591. $form->addElement(
  2592. 'text',
  2593. 'numeric_calification',
  2594. get_lang('QualificationNumeric'),
  2595. 'value="'.$current_thread['thread_qualify_max'].'" style="width:40px"'
  2596. );
  2597. $form->applyFilter('numeric_calification', 'html_filter');
  2598. $form->addElement(
  2599. 'text',
  2600. 'calification_notebook_title',
  2601. get_lang('TitleColumnGradebook'),
  2602. 'value="'.$current_thread['thread_title_qualify'].'"'
  2603. );
  2604. $form->applyFilter('calification_notebook_title', 'html_filter');
  2605. $form->addElement(
  2606. 'text',
  2607. 'weight_calification',
  2608. array(get_lang('QualifyWeight'), null, ''),
  2609. 'value="'.$current_thread['thread_weight'].'" style="width:40px"'
  2610. );
  2611. $form->applyFilter('weight_calification', 'html_filter');
  2612. $form->addElement('html', '</div>');
  2613. }
  2614. if ($forum_setting['allow_post_notification']) {
  2615. $form->addElement(
  2616. 'checkbox',
  2617. 'post_notification',
  2618. '',
  2619. get_lang('NotifyByEmail').' ('.$current_post['email'].')'
  2620. );
  2621. }
  2622. if ($forum_setting['allow_sticky'] && api_is_allowed_to_edit(
  2623. null,
  2624. true
  2625. ) && $current_post['post_parent_id'] == 0
  2626. ) { // The sticky checkbox only appears when it is the first post of a thread.
  2627. $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
  2628. if ($current_thread['thread_sticky'] == 1) {
  2629. $defaults['thread_sticky'] = true;
  2630. }
  2631. }
  2632. $attachment_list = get_attachment($current_post['post_id']);
  2633. $message = get_lang('AddAnAttachment');
  2634. if (!empty($attachment_list)) {
  2635. //$message = ;
  2636. $form->addElement(
  2637. 'label',
  2638. get_lang('EditAnAttachment'),
  2639. Display::return_icon(
  2640. 'attachment.gif',
  2641. get_lang('Attachment')
  2642. ).'&nbsp;'.$attachment_list['filename'].(!empty($attachment_list['comment']) ? '('.$attachment_list['comment'].')' : '')
  2643. );
  2644. $form->addElement('checkbox', 'remove_attach', null, get_lang('DeleteAttachmentFile'));
  2645. } else {
  2646. // User upload
  2647. $form->addElement('label', $message);
  2648. $form->addElement('file', 'user_upload', get_lang('FileName'), '');
  2649. $form->addElement('textarea', 'file_comment', get_lang('FileComment'), array('rows' => 4, 'cols' => 34));
  2650. $form->applyFilter('file_comment', 'html_filter');
  2651. }
  2652. if ($current_forum['allow_attachments'] == '1' || api_is_allowed_to_edit(null, true)) {
  2653. if (empty($form_values) && !isset($_POST['SubmitPost'])) {
  2654. //edit_added_resources('forum_post', $current_post['post_id']);
  2655. }
  2656. }
  2657. $form->addElement('html', '</div>');
  2658. $form->addElement('style_submit_button', 'SubmitPost', get_lang('ModifyThread'), 'class="save"');
  2659. // Setting the default values for the form elements.
  2660. $defaults['post_title'] = $current_post['post_title'];
  2661. $defaults['post_text'] = $current_post['post_text'];
  2662. if ($current_post['post_notification'] == 1) {
  2663. $defaults['post_notification'] = true;
  2664. }
  2665. if (!empty($form_values)) {
  2666. $defaults['post_notification'] = Security::remove_XSS($form_values['post_notification']);
  2667. $defaults['thread_sticky'] = Security::remove_XSS($form_values['thread_sticky']);
  2668. }
  2669. $form->setDefaults($defaults);
  2670. // The course admin can make a thread sticky (=appears with special icon and always on top).
  2671. $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
  2672. // Validation or display
  2673. if ($form->validate()) {
  2674. $values = $form->exportValues();
  2675. if ($values['thread_qualify_gradebook'] == '1' && empty($values['weight_calification'])) {
  2676. Display::display_error_message(
  2677. get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.back()">'.get_lang(
  2678. 'Back'
  2679. ).'</a>',
  2680. false
  2681. );
  2682. return false;
  2683. }
  2684. return $values;
  2685. } else {
  2686. $form->display();
  2687. }
  2688. }
  2689. /**
  2690. * This function stores the edit of a post in the forum_post table.
  2691. *
  2692. * @param array
  2693. * @return void HTML
  2694. *
  2695. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2696. * @version february 2006, dokeos 1.8
  2697. */
  2698. function store_edit_post($values)
  2699. {
  2700. global $origin;
  2701. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  2702. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  2703. $gradebook = Security::remove_XSS($_GET['gradebook']);
  2704. $course_id = api_get_course_int_id();
  2705. // First we check if the change affects the thread and if so we commit the changes (sticky and post_title=thread_title are relevant).
  2706. //if (array_key_exists('is_first_post_of_thread',$values) AND $values['is_first_post_of_thread']=='1') {
  2707. $posts = get_posts($values['thread_id']);
  2708. $first_post = null;
  2709. if (!empty($posts)) {
  2710. $first_post = $posts[0];
  2711. }
  2712. if (!empty($first_post) && $first_post['post_id'] == $values['post_id']) {
  2713. $sql = "UPDATE $table_threads SET
  2714. thread_title ='".Database::escape_string($values['post_title'])."',
  2715. thread_sticky ='".Database::escape_string(isset($values['thread_sticky']) ? $values['thread_sticky'] : null)."'," .
  2716. "thread_title_qualify ='".Database::escape_string($values['calification_notebook_title'])."',".
  2717. "thread_qualify_max ='".Database::escape_string($values['numeric_calification'])."',".
  2718. "thread_weight ='".Database::escape_string($values['weight_calification'])."'".
  2719. " WHERE c_id = $course_id AND thread_id='".intval($values['thread_id'])."'";
  2720. Database::query($sql);
  2721. }
  2722. //}
  2723. // Update the post_title and the post_text.
  2724. $sql = "UPDATE $table_posts SET
  2725. post_title ='".Database::escape_string($values['post_title'])."',
  2726. post_text ='".Database::escape_string($values['post_text'])."',
  2727. post_notification ='".Database::escape_string(isset($values['post_notification'])?$values['post_notification']:null)."'
  2728. WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
  2729. Database::query($sql);
  2730. if (!empty($values['remove_attach'])) {
  2731. delete_attachment($values['post_id']);
  2732. }
  2733. if (empty($values['id_attach'])) {
  2734. add_forum_attachment_file($values['file_comment'], $values['post_id']);
  2735. } else {
  2736. edit_forum_attachment_file($values['file_comment'], $values['post_id'], $values['id_attach']);
  2737. }
  2738. if (api_is_course_admin() == true) {
  2739. $ccode = api_get_course_id();
  2740. $sid = api_get_session_id();
  2741. $link_info = is_resource_in_course_gradebook($ccode, 5, $values['thread_id'], $sid);
  2742. $link_id = $link_info['id'];
  2743. $thread_qualify_gradebook = isset($values['thread_qualify_gradebook']) ? $values['thread_qualify_gradebook'] : null;
  2744. if ($thread_qualify_gradebook != 1) {
  2745. if ($link_info !== false) {
  2746. remove_resource_from_course_gradebook($link_id);
  2747. }
  2748. } else {
  2749. if ($link_info === false && !$_GET['thread']) {
  2750. $weigthqualify = $values['weight_calification'];
  2751. add_resource_to_course_gradebook(
  2752. $values['category_id'],
  2753. $ccode,
  2754. 5,
  2755. $values['thread_id'],
  2756. Database::escape_string(stripslashes($values['calification_notebook_title'])),
  2757. $weigthqualify,
  2758. $values['numeric_calification'],
  2759. null,
  2760. 0,
  2761. $sid
  2762. );
  2763. }
  2764. }
  2765. }
  2766. // Storing the attachments if any.
  2767. //update_added_resources('forum_post', $values['post_id']);
  2768. $message = get_lang('EditPostStored').'<br />';
  2769. $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS(
  2770. $_GET['forum']
  2771. ).'&amp;gidReq='.$_SESSION['toolgroup'].'&amp;origin='.$origin.'">'.get_lang('Forum').'</a><br />';
  2772. $message .= get_lang('ReturnTo').' <a href="viewthread.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS(
  2773. $_GET['forum']
  2774. ).'&amp;gidReq='.$_SESSION['toolgroup'].'&amp;origin='.$origin.'&amp;gradebook='.$gradebook.'&amp;thread='.$values['thread_id'].'&amp;post='.Security::remove_XSS(
  2775. $_GET['post']
  2776. ).'">'.get_lang('Message').'</a>';
  2777. Session::erase('formelements');
  2778. Session::erase('origin');
  2779. Session::erase('breadcrumbs');
  2780. Session::erase('addedresource');
  2781. Session::erase('addedresourceid');
  2782. Display :: display_confirmation_message($message, false);
  2783. }
  2784. /**
  2785. * This function displays the firstname and lastname of the user as a link to the user tool.
  2786. *
  2787. * @param string names
  2788. * @ in_title : title tootip
  2789. * @return string HTML
  2790. *
  2791. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2792. * @version february 2006, dokeos 1.8
  2793. */
  2794. function display_user_link($user_id, $name, $origin = '', $in_title = '')
  2795. {
  2796. if ($user_id != 0) {
  2797. return '<a title="'.api_htmlentities(
  2798. $in_title,
  2799. ENT_QUOTES
  2800. ).'" href="../user/userInfo.php?uInfo='.$user_id.'" '.(!empty($origin) ? 'target="_self"' : '').'>'.$name.'</a>';
  2801. } else {
  2802. return $name.' ('.get_lang('Anonymous').')';
  2803. }
  2804. }
  2805. /**
  2806. * This function displays the user image from the profile, with a link to the user's details.
  2807. * @param int User's database ID
  2808. * @param str User's name
  2809. * @return string An HTML with the anchor and the image of the user
  2810. * @author Julio Montoya <gugli100@gmail.com>
  2811. */
  2812. function display_user_image($user_id, $name, $origin = '')
  2813. {
  2814. $link = '<a href="../user/userInfo.php?uInfo='.$user_id.'" '.(!empty($origin) ? 'target="_self"' : '').'>';
  2815. $attrb = array();
  2816. if ($user_id != 0) {
  2817. $image_path = UserManager::get_user_picture_path_by_id($user_id, 'web', false, true);
  2818. $image_repository = $image_path['dir'];
  2819. $existing_image = $image_path['file'];
  2820. $friends_profile = UserManager::get_picture_user(
  2821. $user_id,
  2822. $image_path['file'],
  2823. 0,
  2824. USER_IMAGE_SIZE_MEDIUM,
  2825. 'width="96" height="96" '
  2826. );
  2827. return $link.'<img src="'.$friends_profile['file'].'" '.$friends_profile['style'].' alt="'.$name.'" title="'.$name.'" /></a>';
  2828. } else {
  2829. return $link.Display::return_icon('unknown.jpg', $name).'</a>';
  2830. }
  2831. }
  2832. /**
  2833. * The thread view counter gets increased every time someone looks at the thread
  2834. *
  2835. * @param int
  2836. * @return void
  2837. *
  2838. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2839. * @version february 2006, dokeos 1.8
  2840. */
  2841. function increase_thread_view($thread_id)
  2842. {
  2843. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  2844. $course_id = api_get_course_int_id();
  2845. $sql = "UPDATE $table_threads SET thread_views=thread_views+1
  2846. WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  2847. $thread_id
  2848. )."'"; // This needs to be cleaned first.
  2849. $result = Database::query($sql);
  2850. }
  2851. /**
  2852. * The relies counter gets increased every time somebody replies to the thread
  2853. *
  2854. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2855. * @version february 2006, dokeos 1.8
  2856. */
  2857. function update_thread($thread_id, $last_post_id, $post_date)
  2858. {
  2859. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  2860. $course_id = api_get_course_int_id();
  2861. $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1,
  2862. thread_last_post='".Database::escape_string($last_post_id)."',
  2863. thread_date='".Database::escape_string($post_date)."'
  2864. WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  2865. $thread_id
  2866. )."'"; // this needs to be cleaned first
  2867. $result = Database::query($sql);
  2868. }
  2869. /**
  2870. * This function is called when the user is not allowed in this forum/thread/...
  2871. * @return bool display message of "not allowed"
  2872. *
  2873. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2874. * @version february 2006, dokeos 1.8
  2875. */
  2876. function forum_not_allowed_here()
  2877. {
  2878. Display :: display_error_message(get_lang('NotAllowedHere'));
  2879. Display :: display_footer();
  2880. return false;
  2881. }
  2882. /**
  2883. * This function is used to find all the information about what's new in the forum tool
  2884. * @return void
  2885. *
  2886. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2887. * @version february 2006, dokeos 1.8
  2888. */
  2889. function get_whats_new()
  2890. {
  2891. global $_user;
  2892. $_course = api_get_course_info();
  2893. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  2894. $tracking_last_tool_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
  2895. // Note: This has to be replaced by the tool constant later. But temporarily bb_forum is used since this is the only thing that is in the tracking currently.
  2896. //$tool = TOOL_FORUM;
  2897. $tool = TOOL_FORUM; //
  2898. // to do: Remove this. For testing purposes only.
  2899. //Session::erase('last_forum_access');
  2900. //Session::erase('whatsnew_post_info');
  2901. $course_id = api_get_course_int_id();
  2902. if (!$_SESSION['last_forum_access']) {
  2903. $sql = "SELECT * FROM ".$tracking_last_tool_access."
  2904. WHERE access_user_id='".Database::escape_string($_user['user_id'])."' AND c_id='".$course_id."' AND access_tool='".Database::escape_string($tool)."'";
  2905. $result = Database::query($sql);
  2906. $row = Database::fetch_array($result);
  2907. $_SESSION['last_forum_access'] = $row['access_date'];
  2908. }
  2909. if (!$_SESSION['whatsnew_post_info']) {
  2910. if ($_SESSION['last_forum_access'] != '') {
  2911. $whatsnew_post_info = array();
  2912. $sql = "SELECT * FROM ".$table_posts." WHERE c_id = $course_id AND post_date>'".Database::escape_string(
  2913. $_SESSION['last_forum_access']
  2914. )."'"; // note: check the performance of this query.
  2915. $result = Database::query($sql);
  2916. while ($row = Database::fetch_array($result)) {
  2917. $whatsnew_post_info[$row['forum_id']][$row['thread_id']][$row['post_id']] = $row['post_date'];
  2918. }
  2919. $_SESSION['whatsnew_post_info'] = $whatsnew_post_info;
  2920. }
  2921. }
  2922. }
  2923. /**
  2924. * With this function we find the number of posts and topics in a given forum.
  2925. *
  2926. * @todo consider to call this function only once and let it return an array where the key is the forum id and the value is an array with number_of_topics and number of post
  2927. * as key of this array and the value as a value. This could reduce the number of queries needed (especially when there are more forums)
  2928. * @todo consider merging both in one query.
  2929. *
  2930. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2931. * @version february 2006, dokeos 1.8
  2932. *
  2933. * @deprecated the counting mechanism is now inside the function get_forums
  2934. */
  2935. function get_post_topics_of_forum($forum_id)
  2936. {
  2937. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  2938. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  2939. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  2940. $course_id = api_get_course_int_id();
  2941. $sql = "SELECT count(*) as number_of_posts FROM $table_posts WHERE forum_id='".$forum_id."'";
  2942. if (api_is_allowed_to_edit(null, true)) {
  2943. $sql = "SELECT count(*) as number_of_posts
  2944. FROM $table_posts posts, $table_threads threads, $table_item_property item_property
  2945. WHERE
  2946. posts.c_id = $course_id AND
  2947. item_property.c_id = $course_id AND
  2948. posts.forum_id='".Database::escape_string($forum_id)."'
  2949. AND posts.thread_id=threads.thread_id
  2950. AND item_property.ref=threads.thread_id
  2951. AND item_property.visibility<>2
  2952. AND item_property.tool='".TOOL_FORUM_THREAD."'
  2953. ";
  2954. } else {
  2955. $sql = "SELECT count(*) as number_of_posts
  2956. FROM $table_posts posts, $table_threads threads, $table_item_property item_property
  2957. WHERE
  2958. posts.c_id = $course_id AND
  2959. item_property.c_id = $course_id AND
  2960. posts.forum_id='".Database::escape_string($forum_id)."'
  2961. AND posts.thread_id=threads.thread_id
  2962. AND item_property.ref=threads.thread_id
  2963. AND item_property.visibility=1
  2964. AND posts.visible=1
  2965. AND item_property.tool='".TOOL_FORUM_THREAD."'
  2966. ";
  2967. }
  2968. $result = Database::query($sql);
  2969. $row = Database::fetch_array($result);
  2970. $number_of_posts = $row['number_of_posts'];
  2971. // We could loop through the result array and count the number of different group_ids, but I have chosen to use a second sql statement.
  2972. if (api_is_allowed_to_edit(null, true)) {
  2973. $sql = "SELECT count(*) as number_of_topics
  2974. FROM $table_threads threads, $table_item_property item_property
  2975. WHERE
  2976. threads.c_id = $course_id AND
  2977. item_property.c_id = $course_id AND
  2978. threads.forum_id='".Database::escape_string($forum_id)."'
  2979. AND item_property.ref=threads.thread_id
  2980. AND item_property.visibility<>2
  2981. AND item_property.tool='".TOOL_FORUM_THREAD."'
  2982. ";
  2983. } else {
  2984. $sql = "SELECT count(*) as number_of_topics
  2985. FROM $table_threads threads, $table_item_property item_property
  2986. WHERE
  2987. threads.c_id = $course_id AND
  2988. item_property.c_id = $course_id AND
  2989. threads.forum_id='".Database::escape_string($forum_id)."'
  2990. AND item_property.ref=threads.thread_id
  2991. AND item_property.visibility=1
  2992. AND item_property.tool='".TOOL_FORUM_THREAD."'
  2993. ";
  2994. }
  2995. $result = Database::query($sql);
  2996. $row = Database::fetch_array($result);
  2997. $number_of_topics = $row['number_of_topics'];
  2998. if ($number_of_topics == '') {
  2999. $number_of_topics = 0; // Due to the nature of the group by this can result in an empty string.
  3000. }
  3001. $return = array('number_of_topics' => $number_of_topics, 'number_of_posts' => $number_of_posts);
  3002. return $return;
  3003. }
  3004. /**
  3005. * This function approves a post = change
  3006. *
  3007. * @param $post_id the id of the post that will be deleted
  3008. * @param $action make the post visible or invisible
  3009. * @return string language variable
  3010. *
  3011. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3012. * @version february 2006, dokeos 1.8
  3013. */
  3014. function approve_post($post_id, $action)
  3015. {
  3016. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  3017. $course_id = api_get_course_int_id();
  3018. if ($action == 'invisible') {
  3019. $visibility_value = 0;
  3020. }
  3021. if ($action == 'visible') {
  3022. $visibility_value = 1;
  3023. handle_mail_cue('post', $post_id);
  3024. }
  3025. $sql = "UPDATE $table_posts SET visible='".Database::escape_string($visibility_value)."'
  3026. WHERE c_id = $course_id AND post_id='".Database::escape_string($post_id)."'";
  3027. $return = Database::query($sql);
  3028. if ($return) {
  3029. return 'PostVisibilityChanged';
  3030. }
  3031. }
  3032. /**
  3033. * This function retrieves all the unapproved messages for a given forum
  3034. * This is needed to display the icon that there are unapproved messages in that thread (only the courseadmin can see this)
  3035. *
  3036. * @param $forum_id the forum where we want to know the unapproved messages of
  3037. * @return array returns
  3038. *
  3039. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3040. * @version february 2006, dokeos 1.8
  3041. */
  3042. function get_unaproved_messages($forum_id)
  3043. {
  3044. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  3045. $course_id = api_get_course_int_id();
  3046. $return_array = array();
  3047. $sql = "SELECT DISTINCT thread_id FROM $table_posts WHERE c_id = $course_id AND forum_id='".Database::escape_string(
  3048. $forum_id
  3049. )."' AND visible='0'";
  3050. $result = Database::query($sql);
  3051. while ($row = Database::fetch_array($result)) {
  3052. $return_array[] = $row['thread_id'];
  3053. }
  3054. return $return_array;
  3055. }
  3056. /**
  3057. * This function sends the notification mails to everybody who stated that they wanted to be informed when a new post
  3058. * was added to a given thread.
  3059. *
  3060. * @param array reply information
  3061. * @return void
  3062. *
  3063. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3064. * @version february 2006, dokeos 1.8
  3065. */
  3066. function send_notification_mails($thread_id, $reply_info)
  3067. {
  3068. $table_mailcue = Database :: get_course_table(TABLE_FORUM_MAIL_QUEUE);
  3069. // First we need to check if
  3070. // 1. the forum category is visible
  3071. // 2. the forum is visible
  3072. // 3. the thread is visible
  3073. // 4. the reply is visible (=when there is)
  3074. $current_thread = get_thread_information($thread_id);
  3075. $current_forum = get_forum_information($current_thread['forum_id']);
  3076. $current_forum_category = get_forumcategory_information($current_forum['forum_category']);
  3077. if ($current_thread['visibility'] == '1' && $current_forum['visibility'] == '1' && ($current_forum_category && $current_forum_category['visibility'] == '1') && $current_forum['approval_direct_post'] != '1') {
  3078. $send_mails = true;
  3079. } else {
  3080. $send_mails = false;
  3081. }
  3082. // The forum category, the forum, the thread and the reply are visible to the user
  3083. if ($send_mails) {
  3084. send_notifications($current_thread['forum_id'], $thread_id);
  3085. } else {
  3086. $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
  3087. $sql = "SELECT * FROM $table_notification WHERE c_id = ".api_get_course_int_id(
  3088. )." AND (forum_id = '".Database::escape_string(
  3089. $current_forum['forum_id']
  3090. )."' OR thread_id = '".Database::escape_string($thread_id)."' ) ";
  3091. $result = Database::query($sql);
  3092. $user_id = api_get_user_id();
  3093. while ($row = Database::fetch_array($result)) {
  3094. $sql_mailcue = "INSERT INTO $table_mailcue (c_id, thread_id, post_id, user_id)
  3095. VALUES (".api_get_course_int_id().", '".Database::escape_string(
  3096. $thread_id
  3097. )."', '".Database::escape_string($reply_info['new_post_id'])."', '$user_id' )";
  3098. Database::query($sql_mailcue);
  3099. }
  3100. }
  3101. }
  3102. /**
  3103. * This function is called whenever something is made visible because there might
  3104. * be new posts and the user might have indicated that (s)he wanted to be
  3105. * informed about the new posts by mail.
  3106. *
  3107. * @param string Content type (post, thread, forum, forum_category)
  3108. * @param int Item DB ID
  3109. * @return string language variable
  3110. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3111. * @version february 2006, dokeos 1.8
  3112. */
  3113. function handle_mail_cue($content, $id)
  3114. {
  3115. $table_mailcue = Database :: get_course_table(TABLE_FORUM_MAIL_QUEUE);
  3116. $table_forums = Database :: get_course_table(TABLE_FORUM);
  3117. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  3118. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  3119. $table_users = Database :: get_main_table(TABLE_MAIN_USER);
  3120. $course_id = api_get_course_int_id();
  3121. // If the post is made visible we only have to send mails to the people who indicated that they wanted to be informed for that thread.
  3122. if ($content == 'post') {
  3123. // Getting the information about the post (need the thread_id).
  3124. $post_info = get_post_information($id);
  3125. $thread_id = Database::escape_string($post_info['thread_id']);
  3126. // Sending the mail to all the users that wanted to be informed for replies on this thread.
  3127. $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
  3128. FROM $table_mailcue mailcue, $table_posts posts, $table_users users
  3129. WHERE
  3130. posts.c_id = $course_id AND
  3131. mailcue.c_id = $course_id AND
  3132. posts.thread_id='$thread_id'
  3133. AND posts.post_notification='1'
  3134. AND mailcue.thread_id='$thread_id'
  3135. AND users.user_id=posts.poster_id
  3136. AND users.active=1
  3137. GROUP BY users.email";
  3138. $result = Database::query($sql);
  3139. while ($row = Database::fetch_array($result)) {
  3140. send_mail($row, get_thread_information($post_info['thread_id']));
  3141. }
  3142. // Deleting the relevant entries from the mailcue.
  3143. $sql_delete_mailcue = "DELETE FROM $table_mailcue WHERE c_id = $course_id AND post_id='".Database::escape_string(
  3144. $id
  3145. )."' AND thread_id='".Database::escape_string($post_info['thread_id'])."'";
  3146. //$result = Database::query($sql_delete_mailcue);
  3147. } elseif ($content == 'thread') {
  3148. // Sending the mail to all the users that wanted to be informed for replies on this thread.
  3149. $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
  3150. FROM $table_mailcue mailcue, $table_posts posts, $table_users users
  3151. WHERE
  3152. posts.c_id = $course_id AND
  3153. mailcue.c_id = $course_id AND
  3154. posts.thread_id='".Database::escape_string($id)."'
  3155. AND posts.post_notification='1'
  3156. AND mailcue.thread_id='".Database::escape_string($id)."'
  3157. AND users.user_id=posts.poster_id
  3158. AND users.active=1
  3159. GROUP BY users.email";
  3160. $result = Database::query($sql);
  3161. while ($row = Database::fetch_array($result)) {
  3162. send_mail($row, get_thread_information($id));
  3163. }
  3164. // Deleting the relevant entries from the mailcue.
  3165. $sql_delete_mailcue = "DELETE FROM $table_mailcue WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  3166. $id
  3167. )."'";
  3168. $result = Database::query($sql_delete_mailcue);
  3169. } elseif ($content == 'forum') {
  3170. $sql = "SELECT thread_id FROM $table_threads WHERE c_id = $course_id AND forum_id='".Database::escape_string(
  3171. $id
  3172. )."'";
  3173. $result = Database::query($sql);
  3174. while ($row = Database::fetch_array($result)) {
  3175. handle_mail_cue('thread', $row['thread_id']);
  3176. }
  3177. } elseif ($content == 'forum_category') {
  3178. $sql = "SELECT forum_id FROM $table_forums WHERE c_id = $course_id AND forum_category ='".Database::escape_string(
  3179. $id
  3180. )."'";
  3181. $result = Database::query($sql);
  3182. while ($row = Database::fetch_array($result)) {
  3183. handle_mail_cue('forum', $row['forum_id']);
  3184. }
  3185. } else {
  3186. return get_lang('Error');
  3187. }
  3188. }
  3189. /**
  3190. * This function sends the mails for the mail notification
  3191. *
  3192. * @param array
  3193. * @param array
  3194. * @return void
  3195. *
  3196. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3197. * @version february 2006, dokeos 1.8
  3198. */
  3199. function send_mail($user_info = array(), $thread_information = array())
  3200. {
  3201. $_course = api_get_course_info();
  3202. $user_id = api_get_user_id();
  3203. $subject = get_lang('NewForumPost').' - '.$_course['official_code'];
  3204. if (isset($thread_information) && is_array($thread_information)) {
  3205. $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq(
  3206. ).'&amp;forum='.$thread_information['forum_id'].'&amp;thread='.$thread_information['thread_id'];
  3207. }
  3208. $email_body = get_lang('Dear').' '.api_get_person_name(
  3209. $user_info['firstname'],
  3210. $user_info['lastname'],
  3211. null,
  3212. PERSON_NAME_EMAIL_ADDRESS
  3213. ).", <br />\n\r";
  3214. $email_body .= get_lang('NewForumPost')."\n";
  3215. $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."] - <br />\n";
  3216. $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
  3217. $email_body .= get_lang('ThreadCanBeFoundHere')." : <br /><a href=\"".$thread_link."\">".$thread_link."</a>\n";
  3218. if ($user_info['user_id'] <> $user_id) {
  3219. MessageManager::send_message(
  3220. $user_info['user_id'],
  3221. $subject,
  3222. $email_body,
  3223. null,
  3224. null,
  3225. null,
  3226. null,
  3227. null,
  3228. null,
  3229. $user_id
  3230. );
  3231. }
  3232. }
  3233. /**
  3234. * This function displays the form for moving a thread to a different (already existing) forum
  3235. * @return void HTML
  3236. *
  3237. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3238. * @version february 2006, dokeos 1.8
  3239. */
  3240. function move_thread_form()
  3241. {
  3242. global $origin;
  3243. $gradebook = Security::remove_XSS($_GET['gradebook']);
  3244. // Initialize the object.
  3245. $form = new FormValidator('movepost', 'post', api_get_self().'?forum='.Security::remove_XSS(
  3246. $_GET['forum']
  3247. ).'&gradebook='.$gradebook.'&thread='.Security::remove_XSS($_GET['thread']).'&action='.Security::remove_XSS(
  3248. $_GET['action']
  3249. ).'&origin='.$origin);
  3250. // The header for the form
  3251. $form->addElement('header', '', get_lang('MoveThread'));
  3252. // Invisible form: the thread_id
  3253. $form->addElement('hidden', 'thread_id', intval($_GET['thread'])); // Note: This has to be cleaned first.
  3254. // the fora
  3255. $forum_categories = get_forum_categories();
  3256. $forums = get_forums();
  3257. $htmlcontent .= '<div class="row">
  3258. <div class="label">
  3259. <span class="form_required">*</span>'.get_lang('MoveTo').'
  3260. </div>
  3261. <div class="formw">';
  3262. $htmlcontent .= '<select name="forum">';
  3263. foreach ($forum_categories as $key => $category) {
  3264. $htmlcontent .= '<optgroup label="'.$category['cat_title'].'">';
  3265. foreach ($forums as $key => $forum) {
  3266. if ($forum['forum_category'] == $category['cat_id']) {
  3267. $htmlcontent .= '<option value="'.$forum['forum_id'].'">'.$forum['forum_title'].'</option>';
  3268. }
  3269. }
  3270. $htmlcontent .= '</optgroup>';
  3271. }
  3272. $htmlcontent .= "</select>";
  3273. $htmlcontent .= ' </div>
  3274. </div>';
  3275. $form->addElement('html', $htmlcontent);
  3276. // The OK button
  3277. $form->addElement('style_submit_button', 'SubmitForum', get_lang('MoveThread'), 'class="save"');
  3278. // Validation or display
  3279. if ($form->validate()) {
  3280. $values = $form->exportValues();
  3281. if (isset($_POST['forum'])) {
  3282. store_move_thread($values);
  3283. }
  3284. } else {
  3285. $form->display();
  3286. }
  3287. }
  3288. /**
  3289. * This function displays the form for moving a post message to a different (already existing) or a new thread.
  3290. * @return void HTML
  3291. *
  3292. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3293. * @version february 2006, dokeos 1.8
  3294. */
  3295. function move_post_form()
  3296. {
  3297. global $origin;
  3298. $gradebook = Security::remove_XSS($_GET['gradebook']);
  3299. // initiate the object
  3300. $form = new FormValidator('movepost', 'post', api_get_self().'?forum='.Security::remove_XSS(
  3301. $_GET['forum']
  3302. ).'&thread='.Security::remove_XSS(
  3303. $_GET['thread']
  3304. ).'&origin='.$origin.'&gradebook='.$gradebook.'&post='.Security::remove_XSS(
  3305. $_GET['post']
  3306. ).'&action='.Security::remove_XSS($_GET['action']).'&post='.Security::remove_XSS($_GET['post']));
  3307. // The header for the form
  3308. $form->addElement('header', '', get_lang('MovePost'));
  3309. // Invisible form: the post_id
  3310. $form->addElement('hidden', 'post_id', strval(intval($_GET['post']))); // Note: This has to be cleaned first.
  3311. // Dropdown list: Threads of this forum
  3312. $threads = get_threads(strval(intval($_GET['forum']))); // Note: This has to be cleaned.
  3313. //my_print_r($threads);
  3314. $threads_list[0] = get_lang('ANewThread');
  3315. foreach ($threads as $key => $value) {
  3316. $threads_list[$value['thread_id']] = $value['thread_title'];
  3317. }
  3318. $form->addElement('select', 'thread', get_lang('MoveToThread'), $threads_list);
  3319. $form->applyFilter('thread', 'html_filter');
  3320. // The OK button
  3321. $form->addElement('style_submit_button', 'submit', get_lang('MovePost'), 'class="save"');
  3322. // Setting the rules
  3323. $form->addRule('thread', get_lang('ThisFieldIsRequired'), 'required');
  3324. // Validation or display
  3325. if ($form->validate()) {
  3326. $values = $form->exportValues();
  3327. store_move_post($values);
  3328. } else {
  3329. $form->display();
  3330. }
  3331. }
  3332. /**
  3333. *
  3334. * @param array
  3335. * @return string HTML language variable
  3336. *
  3337. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3338. * @version february 2006, dokeos 1.8
  3339. */
  3340. function store_move_post($values)
  3341. {
  3342. $_course = api_get_course_info();
  3343. $table_forums = Database :: get_course_table(TABLE_FORUM);
  3344. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  3345. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  3346. $course_id = api_get_course_int_id();
  3347. if ($values['thread'] == '0') {
  3348. $current_post = get_post_information($values['post_id']);
  3349. // Storing a new thread.
  3350. $sql = "INSERT INTO $table_threads (c_id, thread_title, forum_id, thread_poster_id, thread_poster_name, thread_last_post, thread_date)
  3351. VALUES (
  3352. ".$course_id.",
  3353. '".Database::escape_string($current_post['post_title'])."',
  3354. '".Database::escape_string($current_post['forum_id'])."',
  3355. '".Database::escape_string($current_post['poster_id'])."',
  3356. '".Database::escape_string($current_post['poster_name'])."',
  3357. '".Database::escape_string($values['post_id'])."',
  3358. '".Database::escape_string($current_post['post_date'])."'
  3359. )";
  3360. $result = Database::query($sql);
  3361. $new_thread_id = Database::insert_id();
  3362. api_item_property_update($_course, TOOL_FORUM_THREAD, $new_thread_id, 'visible', $current_post['poster_id']);
  3363. // Moving the post to the newly created thread.
  3364. $sql = "UPDATE $table_posts SET thread_id='".Database::escape_string(
  3365. $new_thread_id
  3366. )."', post_parent_id='0' WHERE c_id = $course_id AND post_id='".Database::escape_string($values['post_id'])."'";
  3367. $result = Database::query($sql);
  3368. // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
  3369. $sql = "UPDATE $table_posts SET post_parent_id='0' WHERE c_id = $course_id AND post_parent_id='".Database::escape_string(
  3370. $values['post_id']
  3371. )."'";
  3372. $result = Database::query($sql);
  3373. // Updating updating the number of threads in the forum.
  3374. $sql = "UPDATE $table_forums SET forum_threads=forum_threads+1 WHERE c_id = $course_id AND forum_id='".Database::escape_string(
  3375. $current_post['forum_id']
  3376. )."'";
  3377. $result = Database::query($sql);
  3378. // Resetting the last post of the old thread and decreasing the number of replies and the thread.
  3379. $sql = "SELECT * FROM $table_posts WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  3380. $current_post['thread_id']
  3381. )."' ORDER BY post_id DESC";
  3382. $result = Database::query($sql);
  3383. $row = Database::fetch_array($result);
  3384. $sql = "UPDATE $table_threads SET thread_last_post='".$row['post_id']."', thread_replies=thread_replies-1 WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  3385. $current_post['thread_id']
  3386. )."'";
  3387. $result = Database::query($sql);
  3388. } else {
  3389. // Moving to the chosen thread.
  3390. //Old code
  3391. //$sql = "UPDATE $table_posts SET thread_id='".Database::escape_string($_POST['thread'])."', post_parent_id='0' WHERE post_id='".Database::escape_string($values['post_id'])."'";
  3392. //$result = Database::query($sql);
  3393. // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
  3394. //$sql = "UPDATE $table_posts SET post_parent_id='0' WHERE post_parent_id='".Database::escape_string($values['post_id'])."'";
  3395. //$result = Database::query($sql);
  3396. // If this post is the last post of the thread we must update the thread_last_post with a new post_id
  3397. // Search for the original thread_id
  3398. $sql = "SELECT thread_id FROM ".$table_posts." WHERE c_id = $course_id AND post_id = '".$values['post_id']."' ";
  3399. $result = Database::query($sql);
  3400. $row = Database::fetch_array($result);
  3401. $original_thread_id = $row['thread_id'];
  3402. $sql = "SELECT thread_last_post FROM ".$table_threads." WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
  3403. $result = Database::query($sql);
  3404. $row = Database::fetch_array($result);
  3405. $thread_is_last_post = $row['thread_last_post'];
  3406. // If is this thread, update the thread_last_post with the last one.
  3407. if ($thread_is_last_post == $values['post_id']) {
  3408. $sql = "SELECT post_id FROM ".$table_posts." WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' AND post_id <> '".$values['post_id']."' ORDER BY post_date DESC LIMIT 1";
  3409. $result = Database::query($sql);
  3410. $row = Database::fetch_array($result);
  3411. $thread_new_last_post = $row['post_id'];
  3412. $sql = "UPDATE ".$table_threads." SET thread_last_post = '".$thread_new_last_post."' WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
  3413. $result = Database::query($sql);
  3414. }
  3415. $sql = "UPDATE $table_threads SET thread_replies=thread_replies-1 WHERE c_id = $course_id AND thread_id='".$original_thread_id."'";
  3416. $result = Database::query($sql);
  3417. // moving to the chosen thread
  3418. $sql = "UPDATE $table_posts SET thread_id='".intval(
  3419. $_POST['thread']
  3420. )."', post_parent_id='0' WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
  3421. $result = Database::query($sql);
  3422. // resetting the parent_id of the thread to 0 for all those who had this moved post as parent
  3423. $sql = "UPDATE $table_posts SET post_parent_id='0' WHERE c_id = $course_id AND post_parent_id='".intval(
  3424. $values['post_id']
  3425. )."'";
  3426. $result = Database::query($sql);
  3427. $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1 WHERE c_id = $course_id AND thread_id='".intval(
  3428. $_POST['thread']
  3429. )."'";
  3430. $result = Database::query($sql);
  3431. }
  3432. return get_lang('ThreadMoved');
  3433. }
  3434. /**
  3435. *
  3436. * @param array
  3437. * @return string HTML language variable
  3438. *
  3439. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  3440. * @version february 2006, dokeos 1.8
  3441. */
  3442. function store_move_thread($values)
  3443. {
  3444. $_course = api_get_course_info();
  3445. $table_forums = Database :: get_course_table(TABLE_FORUM);
  3446. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  3447. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  3448. $course_id = api_get_course_int_id();
  3449. // Change the thread table: Setting the forum_id to the new forum.
  3450. $sql = "UPDATE $table_threads SET forum_id='".Database::escape_string(
  3451. $_POST['forum']
  3452. )."' WHERE c_id = $course_id AND thread_id='".Database::escape_string($_POST['thread_id'])."'";
  3453. $result = Database::query($sql);
  3454. // Changing all the posts of the thread: setting the forum_id to the new forum.
  3455. $sql = "UPDATE $table_posts SET forum_id='".Database::escape_string(
  3456. $_POST['forum']
  3457. )."' WHERE c_id = $course_id AND thread_id='".Database::escape_string($_POST['thread_id'])."'";
  3458. $result = Database::query($sql);
  3459. return get_lang('ThreadMoved');
  3460. }
  3461. /**
  3462. * Prepares a string for displaying by highlighting the search results inside, if any.
  3463. * @param string $input The input string.
  3464. * @return string The same string with highlighted hits inside.
  3465. *
  3466. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, February 2006 - the initial version.
  3467. * @author Ivan Tcholakov, March 2011 - adaptation for Chamilo LMS.
  3468. */
  3469. function prepare4display($input)
  3470. {
  3471. static $highlightcolors = array('yellow', '#33CC33', '#3399CC', '#9999FF', '#33CC33');
  3472. static $search;
  3473. if (!isset($search)) {
  3474. if (isset($_POST['search_term'])) {
  3475. $search = $_POST['search_term']; // No html at all.
  3476. } elseif (isset($_GET['search'])) {
  3477. $search = $_GET['search'];
  3478. } else {
  3479. $search = '';
  3480. }
  3481. }
  3482. if (!empty($search)) {
  3483. if (strstr($search, '+')) {
  3484. $search_terms = explode('+', $search);
  3485. } else {
  3486. $search_terms[] = trim($search);
  3487. }
  3488. $counter = 0;
  3489. foreach ($search_terms as $key => $search_term) {
  3490. $input = api_preg_replace(
  3491. '/'.preg_quote(trim($search_term), '/').'/i',
  3492. '<span style="background-color: '.$highlightcolors[$counter].'">$0</span>',
  3493. $input
  3494. );
  3495. $counter++;
  3496. }
  3497. }
  3498. // TODO: Security should be implemented outside this function.
  3499. // Change this to COURSEMANAGERLOWSECURITY or COURSEMANAGER to lower filtering and allow more styles (see comments of Security::remove_XSS() method to learn about other levels).
  3500. return Security::remove_XSS($input, STUDENT, true);
  3501. }
  3502. /**
  3503. * Display the search form for the forum and display the search results
  3504. * @return void display an HTML search results
  3505. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  3506. * @version march 2008, dokeos 1.8.5
  3507. */
  3508. function forum_search()
  3509. {
  3510. global $origin;
  3511. // Initialize the object.
  3512. $form = new FormValidator('forumsearch', 'post', 'forumsearch.php?origin='.$origin.'');
  3513. // Settting the form elements.
  3514. $form->addElement('header', '', get_lang('ForumSearch'));
  3515. $form->addElement('text', 'search_term', get_lang('SearchTerm'), 'class="input_titles" id="search_title"');
  3516. $form->applyFilter('search_term', 'html_filter');
  3517. $form->addElement(
  3518. 'static',
  3519. 'search_information',
  3520. '',
  3521. get_lang('ForumSearchInformation') /*, $dissertation[$_GET['opleidingsonderdeelcode']]['code']*/
  3522. );
  3523. $form->addElement('style_submit_button', null, get_lang('Search'), 'class="search"');
  3524. // Setting the rules.
  3525. $form->addRule('search_term', get_lang('ThisFieldIsRequired'), 'required');
  3526. $form->addRule('search_term', get_lang('TooShort'), 'minlength', 3);
  3527. // Validation or display.
  3528. if ($form->validate()) {
  3529. $values = $form->exportValues();
  3530. $form->setDefaults($values);
  3531. $form->display();
  3532. // Display the search results.
  3533. display_forum_search_results(stripslashes($values['search_term']));
  3534. } else {
  3535. $form->display();
  3536. }
  3537. }
  3538. /**
  3539. * Display the search results
  3540. * @param string
  3541. * @return void display the results
  3542. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  3543. * @version march 2008, dokeos 1.8.5
  3544. */
  3545. function display_forum_search_results($search_term)
  3546. {
  3547. global $origin;
  3548. $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
  3549. $table_forums = Database :: get_course_table(TABLE_FORUM);
  3550. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  3551. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  3552. $gradebook = Security::remove_XSS($_GET['gradebook']);
  3553. $course_id = api_get_course_int_id();
  3554. // Defining the search strings as an array.
  3555. if (strstr($search_term, '+')) {
  3556. $search_terms = explode('+', $search_term);
  3557. } else {
  3558. $search_terms[] = $search_term;
  3559. }
  3560. // Search restriction.
  3561. foreach ($search_terms as $key => $value) {
  3562. $search_restriction[] = "(posts.post_title LIKE '%".Database::escape_string(trim($value))."%'
  3563. OR posts.post_text LIKE '%".Database::escape_string(trim($value))."%')";
  3564. }
  3565. $sql = "SELECT * FROM $table_posts posts
  3566. WHERE c_id = $course_id AND ".implode(' AND ', $search_restriction)."
  3567. GROUP BY posts.post_id";
  3568. // Getting all the information of the forum categories.
  3569. $forum_categories_list = get_forum_categories();
  3570. // Getting all the information of the forums.
  3571. $forum_list = get_forums();
  3572. $result = Database::query($sql);
  3573. while ($row = Database::fetch_array($result, 'ASSOC')) {
  3574. $display_result = false;
  3575. /*
  3576. We only show it when
  3577. 1. forum cateogory is visible
  3578. 2. forum is visible
  3579. 3. thread is visible (to do)
  3580. 4. post is visible
  3581. */
  3582. if (!api_is_allowed_to_edit(null, true)) {
  3583. if ($forum_categories_list[$row['forum_id']['forum_category']]['visibility'] == '1' AND $forum_list[$row['forum_id']]['visibility'] == '1' AND $row['visible'] == '1') {
  3584. $display_result = true;
  3585. }
  3586. } else {
  3587. $display_result = true;
  3588. }
  3589. if ($display_result) {
  3590. $search_results_item = '<li><a href="viewforumcategory.php?forumcategory='.$forum_list[$row['forum_id']]['forum_category'].'&amp;origin='.$origin.'&amp;search='.urlencode(
  3591. $search_term
  3592. ).'">'.prepare4display(
  3593. $forum_categories_list[$row['forum_id']['forum_category']]['cat_title']
  3594. ).'</a> &gt; ';
  3595. $search_results_item .= '<a href="viewforum.php?forum='.$row['forum_id'].'&amp;origin='.$origin.'&amp;search='.urlencode(
  3596. $search_term
  3597. ).'">'.prepare4display($forum_list[$row['forum_id']]['forum_title']).'</a> &gt; ';
  3598. //$search_results_item .= '<a href="">THREAD</a> &gt; ';
  3599. $search_results_item .= '<a href="viewthread.php?forum='.$row['forum_id'].'&amp;gradebook='.$gradebook.'&amp;origin='.$origin.'&amp;thread='.$row['thread_id'].'&amp;search='.urlencode(
  3600. $search_term
  3601. ).'">'.prepare4display($row['post_title']).'</a>';
  3602. $search_results_item .= '<br />';
  3603. if (api_strlen($row['post_title']) > 200) {
  3604. $search_results_item .= prepare4display(api_substr(strip_tags($row['post_title']), 0, 200)).'...';
  3605. } else {
  3606. $search_results_item .= prepare4display($row['post_title']);
  3607. }
  3608. $search_results_item .= '</li>';
  3609. $search_results[] = $search_results_item;
  3610. }
  3611. }
  3612. echo '<legend>'.count($search_results).' '.get_lang('ForumSearchResults').'</legend>';
  3613. echo '<ol>';
  3614. if ($search_results) {
  3615. echo implode($search_results);
  3616. }
  3617. echo '</ol>';
  3618. }
  3619. /**
  3620. * Return the link to the forum search page
  3621. *
  3622. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  3623. * @version April 2008, dokeos 1.8.5
  3624. */
  3625. function search_link()
  3626. {
  3627. global $origin;
  3628. $return = '';
  3629. if ($origin != 'learnpath') {
  3630. $return = '<a href="forumsearch.php?'.api_get_cidreq().'&amp;gidReq='.api_get_group_id(
  3631. ).'&amp;action=search&amp;origin='.$origin.'"> ';
  3632. $return .= Display::return_icon('search.png', get_lang('Search'), '', ICON_SIZE_MEDIUM).'</a>';
  3633. if (!empty($_GET['search'])) {
  3634. $return .= ': '.Security::remove_XSS($_GET['search']).' ';
  3635. $url = api_get_self().'?';
  3636. $url_parameter = array();
  3637. foreach ($_GET as $key => $value) {
  3638. if ($key != 'search') {
  3639. $url_parameter[] = Security::remove_XSS($key).'='.Security::remove_XSS($value);
  3640. }
  3641. }
  3642. $url = $url.implode('&amp;', $url_parameter);
  3643. $return .= '<a href="'.$url.'">'.Display::return_icon('delete.gif', get_lang('RemoveSearchResults')).'</a>';
  3644. }
  3645. }
  3646. return $return;
  3647. }
  3648. /**
  3649. * This function adds an attachment file into a forum
  3650. * @param string a comment about file
  3651. * @param int last id from forum_post table
  3652. * @return void
  3653. */
  3654. function add_forum_attachment_file($file_comment, $last_id)
  3655. {
  3656. $_course = api_get_course_info();
  3657. $agenda_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
  3658. // Storing the attachments
  3659. if (!empty($_FILES['user_upload']['name'])) {
  3660. $upload_ok = FileManager::process_uploaded_file($_FILES['user_upload']);
  3661. }
  3662. if (!empty($upload_ok)) {
  3663. $course_dir = $_course['path'].'/upload/forum';
  3664. $sys_course_path = api_get_path(SYS_COURSE_PATH);
  3665. $updir = $sys_course_path.$course_dir;
  3666. // Try to add an extension to the file if it hasn't one.
  3667. $new_file_name = FileManager::add_ext_on_mime(
  3668. stripslashes($_FILES['user_upload']['name']),
  3669. $_FILES['user_upload']['type']
  3670. );
  3671. // User's file name
  3672. $file_name = $_FILES['user_upload']['name'];
  3673. if (!FileManager::filter_extension($new_file_name)) {
  3674. Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
  3675. } else {
  3676. $new_file_name = uniqid('');
  3677. $new_path = $updir.'/'.$new_file_name;
  3678. $result = @move_uploaded_file($_FILES['user_upload']['tmp_name'], $new_path);
  3679. $safe_file_comment = Database::escape_string($file_comment);
  3680. $safe_file_name = Database::escape_string($file_name);
  3681. $safe_new_file_name = Database::escape_string($new_file_name);
  3682. $last_id = intval($last_id);
  3683. // Storing the attachments if any.
  3684. if ($result) {
  3685. $sql = "INSERT INTO $agenda_forum_attachment (c_id, filename, comment, path, post_id, size)
  3686. VALUES (".api_get_course_int_id(
  3687. ).", '$safe_file_name', '$safe_file_comment', '$safe_new_file_name' , '$last_id', '".intval(
  3688. $_FILES['user_upload']['size']
  3689. )."' )";
  3690. $result = Database::query($sql);
  3691. $message .= ' / '.get_lang('FileUploadSucces').'<br />';
  3692. $last_id_file = Database::insert_id();
  3693. api_item_property_update(
  3694. $_course,
  3695. TOOL_FORUM_ATTACH,
  3696. $last_id_file,
  3697. 'ForumAttachmentAdded',
  3698. api_get_user_id()
  3699. );
  3700. }
  3701. }
  3702. }
  3703. }
  3704. /**
  3705. * This function edits an attachment file into a forum
  3706. * @param string a comment about file
  3707. * @param int Post Id
  3708. * @param int attachment file Id
  3709. * @return void
  3710. */
  3711. function edit_forum_attachment_file($file_comment, $post_id, $id_attach)
  3712. {
  3713. $_course = api_get_course_info();
  3714. $table_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
  3715. $course_id = api_get_course_int_id();
  3716. // Storing the attachments.
  3717. if (!empty($_FILES['user_upload']['name'])) {
  3718. $upload_ok = FileManager::process_uploaded_file($_FILES['user_upload']);
  3719. }
  3720. if (!empty($upload_ok)) {
  3721. $course_dir = $_course['path'].'/upload/forum';
  3722. $sys_course_path = api_get_path(SYS_COURSE_PATH);
  3723. $updir = $sys_course_path.$course_dir;
  3724. // Try to add an extension to the file if it hasn't one.
  3725. $new_file_name = FileManager::add_ext_on_mime(
  3726. stripslashes($_FILES['user_upload']['name']),
  3727. $_FILES['user_upload']['type']
  3728. );
  3729. // User's file name
  3730. $file_name = $_FILES['user_upload']['name'];
  3731. if (!FileManager::filter_extension($new_file_name)) {
  3732. Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
  3733. } else {
  3734. $new_file_name = uniqid('');
  3735. $new_path = $updir.'/'.$new_file_name;
  3736. $result = @move_uploaded_file($_FILES['user_upload']['tmp_name'], $new_path);
  3737. $safe_file_comment = Database::escape_string($file_comment);
  3738. $safe_file_name = Database::escape_string($file_name);
  3739. $safe_new_file_name = Database::escape_string($new_file_name);
  3740. $safe_post_id = (int)$post_id;
  3741. $safe_id_attach = (int)$id_attach;
  3742. // Storing the attachments if any.
  3743. if ($result) {
  3744. $sql = "UPDATE $table_forum_attachment SET filename = '$safe_file_name', comment = '$safe_file_comment', path = '$safe_new_file_name', post_id = '$safe_post_id', size ='".$_FILES['user_upload']['size']."'
  3745. WHERE c_id = $course_id AND id = '$safe_id_attach'";
  3746. $result = Database::query($sql);
  3747. api_item_property_update(
  3748. $_course,
  3749. TOOL_FORUM_ATTACH,
  3750. $safe_id_attach,
  3751. 'ForumAttachmentUpdated',
  3752. api_get_user_id()
  3753. );
  3754. }
  3755. }
  3756. }
  3757. }
  3758. /**
  3759. * Show a list with all the attachments according to the post's id
  3760. * @param the post's id
  3761. * @return array with the post info
  3762. * @author Julio Montoya Dokeos
  3763. * @version avril 2008, dokeos 1.8.5
  3764. */
  3765. function get_attachment($post_id)
  3766. {
  3767. $forum_table_attachment = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
  3768. $course_id = api_get_course_int_id();
  3769. $row = array();
  3770. $post_id = intval($post_id);
  3771. $sql = "SELECT id, path, filename,comment FROM $forum_table_attachment
  3772. WHERE c_id = $course_id AND post_id = $post_id";
  3773. $result = Database::query($sql);
  3774. if (Database::num_rows($result) != 0) {
  3775. $row = Database::fetch_array($result);
  3776. }
  3777. return $row;
  3778. }
  3779. /**
  3780. * Delete the all the attachments from the DB and the file according to the post's id or attach id(optional)
  3781. * @param post id
  3782. * @param attach id (optional)
  3783. * @return void
  3784. * @author Julio Montoya Dokeos
  3785. * @version avril 2008, dokeos 1.8.5
  3786. */
  3787. function delete_attachment($post_id, $id_attach = 0)
  3788. {
  3789. $_course = api_get_course_info();
  3790. $forum_table_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
  3791. $course_id = api_get_course_int_id();
  3792. $cond = (!empty($id_attach)) ? " id = ".(int)$id_attach."" : " post_id = ".(int)$post_id."";
  3793. $sql = "SELECT path FROM $forum_table_attachment WHERE c_id = $course_id AND $cond";
  3794. $res = Database::query($sql);
  3795. $row = Database::fetch_array($res);
  3796. $course_dir = $_course['path'].'/upload/forum';
  3797. $sys_course_path = api_get_path(SYS_COURSE_PATH);
  3798. $updir = $sys_course_path.$course_dir;
  3799. $my_path = isset($row['path']) ? $row['path'] : null;
  3800. $file = $updir.'/'.$my_path;
  3801. if (Security::check_abs_path($file, $updir)) {
  3802. @unlink($file);
  3803. }
  3804. // Delete from forum_attachment table.
  3805. $sql = "DELETE FROM $forum_table_attachment WHERE c_id = $course_id AND $cond ";
  3806. $result = Database::query($sql);
  3807. $last_id_file = Database::insert_id();
  3808. // Update item_property.
  3809. api_item_property_update($_course, TOOL_FORUM_ATTACH, $id_attach, 'ForumAttachmentDelete', api_get_user_id());
  3810. if (!empty($result) && !empty($id_attach)) {
  3811. $message = get_lang(get_lang('AttachmentFileDeleteSuccess'));
  3812. Display::display_confirmation_message($message);
  3813. }
  3814. }
  3815. /**
  3816. * This function gets all the forum information of the all the forum of the group
  3817. *
  3818. * @param integer $group_id the id of the group we need the fora of (see forum.forum_of_group)
  3819. * @return array
  3820. *
  3821. * @todo this is basically the same code as the get_forums function. Consider merging the two.
  3822. */
  3823. function get_forums_of_group($group_id)
  3824. {
  3825. $table_forums = Database :: get_course_table(TABLE_FORUM);
  3826. $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
  3827. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  3828. $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  3829. $table_users = Database :: get_main_table(TABLE_MAIN_USER);
  3830. $course_id = api_get_course_int_id();
  3831. // Student
  3832. // Select all the forum information of all forums (that are visible to students).
  3833. $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties
  3834. WHERE forum.forum_of_group = '".Database::escape_string($group_id)."' AND
  3835. forum.c_id = $course_id AND
  3836. item_properties.c_id = $course_id AND
  3837. forum.forum_id=item_properties.ref AND
  3838. item_properties.visibility=1 AND
  3839. item_properties.tool='".TOOL_FORUM."'
  3840. ORDER BY forum.forum_order ASC";
  3841. // Select the number of threads of the forums (only the threads that are visible).
  3842. $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id FROM $table_threads threads, ".$table_item_property." item_properties
  3843. WHERE threads.thread_id=item_properties.ref AND
  3844. threads.c_id = $course_id AND
  3845. item_properties.c_id = $course_id AND
  3846. item_properties.visibility=1 AND
  3847. item_properties.tool='".TOOL_FORUM_THREAD."'
  3848. GROUP BY threads.forum_id";
  3849. // Select the number of posts of the forum (post that are visible and that are in a thread that is visible).
  3850. $sql3 = "SELECT count(post_id) AS number_of_posts, posts.forum_id FROM $table_posts posts, $table_threads threads, ".$table_item_property." item_properties
  3851. WHERE posts.visible=1 AND
  3852. posts.c_id = $course_id AND
  3853. item_properties.c_id = $course_id AND
  3854. threads.c_id = $course_id
  3855. AND posts.thread_id=threads.thread_id
  3856. AND threads.thread_id=item_properties.ref
  3857. AND item_properties.visibility=1
  3858. AND item_properties.tool='".TOOL_FORUM_THREAD."'
  3859. GROUP BY threads.forum_id";
  3860. //-------------- Course Admin -----------------//
  3861. if (is_allowed_to_edit()) {
  3862. // Select all the forum information of all forums (that are not deleted).
  3863. $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties
  3864. WHERE forum.forum_of_group = '".Database::escape_string($group_id)."' AND
  3865. forum.c_id = $course_id AND
  3866. item_properties.c_id = $course_id AND
  3867. forum.forum_id=item_properties.ref AND
  3868. item_properties.visibility<>2 AND
  3869. item_properties.tool='".TOOL_FORUM."'
  3870. ORDER BY forum_order ASC";
  3871. // Select the number of threads of the forums (only the threads that are not deleted).
  3872. $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id FROM $table_threads threads, ".$table_item_property." item_properties
  3873. WHERE threads.thread_id=item_properties.ref AND
  3874. threads.c_id = $course_id AND
  3875. item_properties.c_id = $course_id AND
  3876. item_properties.visibility<>2 AND
  3877. item_properties.tool='".TOOL_FORUM_THREAD."'
  3878. GROUP BY threads.forum_id";
  3879. // Select the number of posts of the forum.
  3880. $sql3 = "SELECT count(post_id) AS number_of_posts, forum_id FROM $table_posts WHERE c_id = $course_id GROUP BY forum_id";
  3881. }
  3882. // Handling all the forum information.
  3883. $result = Database::query($sql);
  3884. while ($row = Database::fetch_array($result, 'ASSOC')) {
  3885. $forum_list[$row['forum_id']] = $row;
  3886. }
  3887. // Handling the threadcount information.
  3888. $result2 = Database::query($sql2);
  3889. while ($row2 = Database::fetch_array($result2, 'ASSOC')) {
  3890. if (is_array($forum_list)) {
  3891. if (array_key_exists($row2['forum_id'], $forum_list)) {
  3892. $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
  3893. }
  3894. }
  3895. }
  3896. // Handling the postcount information.
  3897. $result3 = Database::query($sql3);
  3898. while ($row3 = Database::fetch_array($result3, 'ASSOC')) {
  3899. if (is_array($forum_list)) {
  3900. if (array_key_exists(
  3901. $row3['forum_id'],
  3902. $forum_list
  3903. )
  3904. ) { // This is needed because sql3 takes also the deleted forums into account.
  3905. $forum_list[$row3['forum_id']]['number_of_posts'] = $row3['number_of_posts'];
  3906. }
  3907. }
  3908. }
  3909. // Finding the last post information (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname).
  3910. if (is_array($forum_list)) {
  3911. foreach ($forum_list as $key => $value) {
  3912. $last_post_info_of_forum = get_last_post_information($key, is_allowed_to_edit());
  3913. $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
  3914. $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
  3915. $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
  3916. $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
  3917. $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
  3918. $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
  3919. }
  3920. }
  3921. return $forum_list;
  3922. }
  3923. /**
  3924. * This function stores which users have to be notified of which forums or threads
  3925. *
  3926. * @param string $content does the user want to be notified about a forum or about a thread
  3927. * @param integer $id the id of the forum or thread
  3928. * @return string language variable
  3929. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  3930. * @version May 2008, dokeos 1.8.5
  3931. * @since May 2008, dokeos 1.8.5
  3932. */
  3933. function set_notification($content, $id, $add_only = false)
  3934. {
  3935. global $_user;
  3936. // Database table definition
  3937. $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
  3938. $course_id = api_get_course_int_id();
  3939. // Which database field do we have to store the id in?
  3940. if ($content == 'forum') {
  3941. $database_field = 'forum_id';
  3942. } else {
  3943. $database_field = 'thread_id';
  3944. }
  3945. // First we check if the notification is already set for this.
  3946. $sql = "SELECT * FROM $table_notification WHERE c_id = $course_id AND $database_field = '".Database::escape_string(
  3947. $id
  3948. )."' AND user_id = '".Database::escape_string($_user['user_id'])."'";
  3949. $result = Database::query($sql);
  3950. $total = Database::num_rows($result);
  3951. // If the user did not indicate that (s)he wanted to be notified already then we store the notification request (to prevent double notification requests).
  3952. if ($total <= 0) {
  3953. $sql = "INSERT INTO $table_notification (c_id, $database_field, user_id) VALUES (".$course_id.", '".Database::escape_string(
  3954. $id
  3955. )."','".Database::escape_string($_user['user_id'])."')";
  3956. $result = Database::query($sql);
  3957. Session::erase('forum_notification');
  3958. get_notifications_of_user(0, true);
  3959. return get_lang('YouWillBeNotifiedOfNewPosts');
  3960. } else {
  3961. if (!$add_only) {
  3962. $sql = "DELETE FROM $table_notification
  3963. WHERE c_id = $course_id AND $database_field = '".Database::escape_string(
  3964. $id
  3965. )."' AND user_id = '".Database::escape_string($_user['user_id'])."'";
  3966. $result = Database::query($sql);
  3967. Session::erase('forum_notification');
  3968. get_notifications_of_user(0, true);
  3969. return get_lang('YouWillNoLongerBeNotifiedOfNewPosts');
  3970. }
  3971. }
  3972. }
  3973. /**
  3974. * This function retrieves all the email adresses of the users who wanted to be notified
  3975. * about a new post in a certain forum or thread
  3976. *
  3977. * @param string $content does the user want to be notified about a forum or about a thread
  3978. * @param integer $id the id of the forum or thread
  3979. * @return array returns
  3980. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  3981. * @version May 2008, dokeos 1.8.5
  3982. * @since May 2008, dokeos 1.8.5
  3983. */
  3984. function get_notifications($content, $id)
  3985. {
  3986. // Database table definition
  3987. $table_users = Database::get_main_table(TABLE_MAIN_USER);
  3988. $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
  3989. $course_id = api_get_course_int_id();
  3990. // Which database field contains the notification?
  3991. if ($content == 'forum') {
  3992. $database_field = 'forum_id';
  3993. } else {
  3994. $database_field = 'thread_id';
  3995. }
  3996. $sql = "SELECT user.user_id, user.firstname, user.lastname, user.email, user.user_id user
  3997. FROM $table_users user, $table_notification notification
  3998. WHERE notification.c_id = $course_id AND user.active = 1 AND
  3999. user.user_id = notification.user_id AND
  4000. notification.$database_field= '".Database::escape_string($id)."'";
  4001. $result = Database::query($sql);
  4002. $return = array();
  4003. while ($row = Database::fetch_array($result)) {
  4004. $return['user'.$row['user_id']] = array('email' => $row['email'], 'user_id' => $row['user_id']);
  4005. }
  4006. return $return;
  4007. }
  4008. /**
  4009. * Get all the users who need to receive a notification of a new post (those subscribed to
  4010. * the forum or the thread)
  4011. *
  4012. * @param integer $forum_id the id of the forum
  4013. * @param integer $thread_id the id of the thread
  4014. * @param integer $post_id the id of the post
  4015. * @return bool
  4016. *
  4017. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  4018. * @version May 2008, dokeos 1.8.5
  4019. * @since May 2008, dokeos 1.8.5
  4020. */
  4021. function send_notifications($forum_id = 0, $thread_id = 0, $post_id = 0)
  4022. {
  4023. global $_user;
  4024. $_course = api_get_course_info();
  4025. // The content of the mail
  4026. $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq(
  4027. ).'&amp;forum='.$forum_id.'&amp;thread='.$thread_id;
  4028. // Users who subscribed to the forum
  4029. if ($forum_id != 0) {
  4030. $users_to_be_notified_by_forum = get_notifications('forum', $forum_id);
  4031. } else {
  4032. return false;
  4033. }
  4034. $current_thread = get_thread_information($thread_id);
  4035. $current_forum = get_forum_information($current_thread['forum_id']);
  4036. $subject = get_lang(
  4037. 'NewForumPost'
  4038. ).' - '.$_course['official_code'].' - '.$current_forum['forum_title'].' - '.$current_thread['thread_title'];
  4039. // User who subscribed to the thread
  4040. if ($thread_id != 0) {
  4041. $users_to_be_notified_by_thread = get_notifications('thread', $thread_id);
  4042. }
  4043. // Merging the two
  4044. $users_to_be_notified = array_merge($users_to_be_notified_by_forum, $users_to_be_notified_by_thread);
  4045. $sender_id = api_get_user_id();
  4046. if (is_array($users_to_be_notified)) {
  4047. foreach ($users_to_be_notified as $value) {
  4048. if ($value['email'] != $_user['email']) {
  4049. $user_info = api_get_user_info($value['user_id']);
  4050. $email_body = get_lang('Dear').' '.api_get_person_name(
  4051. $user_info['firstname'],
  4052. $user_info['lastname'],
  4053. null,
  4054. PERSON_NAME_EMAIL_ADDRESS
  4055. ).", <br />\n\r";
  4056. $email_body .= get_lang(
  4057. 'NewForumPost'
  4058. ).": ".$current_forum['forum_title'].' - '.$current_thread['thread_title']." <br />\n";
  4059. $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."] <br />\n";
  4060. $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
  4061. $email_body .= get_lang(
  4062. 'ThreadCanBeFoundHere'
  4063. ).': <br /> <a href="'.$thread_link.'">'.$thread_link."</a>\n";
  4064. MessageManager::send_message(
  4065. $value['user_id'],
  4066. $subject,
  4067. $email_body,
  4068. null,
  4069. null,
  4070. null,
  4071. null,
  4072. null,
  4073. null,
  4074. $sender_id
  4075. );
  4076. }
  4077. }
  4078. }
  4079. }
  4080. /**
  4081. * Get all the notification subscriptions of the user
  4082. * = which forums and which threads does the user wants to be informed of when a new
  4083. * post is added to this thread
  4084. *
  4085. * @param integer $user_id the user_id of a user (default = 0 => the current user)
  4086. * @param boolean $force force get the notification subscriptions (even if the information is already in the session
  4087. * @return array returns
  4088. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  4089. * @version May 2008, dokeos 1.8.5
  4090. * @since May 2008, dokeos 1.8.5
  4091. */
  4092. function get_notifications_of_user($user_id = 0, $force = false)
  4093. {
  4094. // Database table definition
  4095. $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
  4096. $course_id = api_get_course_int_id();
  4097. if (empty($course_id) || $course_id == -1) {
  4098. return null;
  4099. }
  4100. if ($user_id == 0) {
  4101. $user_id = api_get_user_id();
  4102. }
  4103. if (!isset($_SESSION['forum_notification']) || $_SESSION['forum_notification']['course'] != $course_id || $force = true) {
  4104. $_SESSION['forum_notification']['course'] = $course_id;
  4105. $sql = "SELECT * FROM $table_notification WHERE c_id = $course_id AND user_id='".Database::escape_string(
  4106. $user_id
  4107. )."'";
  4108. $result = Database::query($sql);
  4109. while ($row = Database::fetch_array($result)) {
  4110. if (!is_null($row['forum_id'])) {
  4111. $_SESSION['forum_notification']['forum'][] = $row['forum_id'];
  4112. }
  4113. if (!is_null($row['thread_id'])) {
  4114. $_SESSION['forum_notification']['thread'][] = $row['thread_id'];
  4115. }
  4116. }
  4117. }
  4118. }
  4119. /**
  4120. * This function counts the number of post inside a thread
  4121. * @param int Thread ID
  4122. * @return int the number of post inside a thread
  4123. * @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>,
  4124. * @version octubre 2008, dokeos 1.8
  4125. */
  4126. function count_number_of_post_in_thread($thread_id)
  4127. {
  4128. $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
  4129. $course_id = api_get_course_int_id();
  4130. if (empty($course_id)) {
  4131. return 0;
  4132. }
  4133. $sql = "SELECT * FROM $table_posts WHERE c_id = $course_id AND thread_id='".Database::escape_string(
  4134. $thread_id
  4135. )."' ";
  4136. $result = Database::query($sql);
  4137. return count(Database::store_result($result));
  4138. }
  4139. /**
  4140. * This function counts the number of post inside a thread user
  4141. * @param int thread ID
  4142. * @param int user ID
  4143. * @return int the number of post inside a thread user
  4144. */
  4145. function count_number_of_post_for_user_thread($thread_id, $user_id)
  4146. {
  4147. $table_posts = Database::get_course_table(TABLE_FORUM_POST);
  4148. $course_id = api_get_course_int_id();
  4149. $sql = "SELECT count(*) as count FROM $table_posts
  4150. WHERE c_id = $course_id AND
  4151. thread_id=".Database::escape_string($thread_id)." AND
  4152. poster_id = ".Database::escape_string($user_id)." AND visible = 1 ";
  4153. $result = Database::query($sql);
  4154. $count = 0;
  4155. if (Database::num_rows($result) > 0) {
  4156. $count = Database::fetch_array($result);
  4157. $count = $count['count'];
  4158. }
  4159. return $count;
  4160. }
  4161. /**
  4162. * This function counts the number of user register in course
  4163. * @param int Course ID
  4164. * @return int the number of user register in course
  4165. * @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>,
  4166. * @version octubre 2008, dokeos 1.8
  4167. */
  4168. function count_number_of_user_in_course($course_id)
  4169. {
  4170. $table_course_rel_user = Database::get_main_table('course_rel_user');
  4171. $sql = "SELECT * FROM $table_course_rel_user WHERE course_code ='".Database::escape_string($course_id)."' ";
  4172. $result = Database::query($sql);
  4173. return count(Database::store_result($result));
  4174. }
  4175. /**
  4176. * This function retrieves information of statistical
  4177. * @param int Thread ID
  4178. * @param int User ID
  4179. * @param int Course ID
  4180. * @return array the information of statistical
  4181. * @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>,
  4182. * @version octubre 2008, dokeos 1.8
  4183. */
  4184. function get_statistical_information($thread_id, $user_id, $course_id)
  4185. {
  4186. $stadistic = array();
  4187. $stadistic['user_course'] = count_number_of_user_in_course($course_id);
  4188. $stadistic['post'] = count_number_of_post_in_thread($thread_id);
  4189. $stadistic['user_post'] = count_number_of_post_for_user_thread($thread_id, $user_id);
  4190. //$stadistic['average'] = get_average_of_thread_post_user();
  4191. return $stadistic;
  4192. }
  4193. /**
  4194. * This function return the posts inside a thread from a given user
  4195. * @param course code
  4196. * @param int Thread ID
  4197. * @param int User ID
  4198. * @return int the number of post inside a thread
  4199. * @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>,
  4200. * @version octubre 2008, dokeos 1.8
  4201. */
  4202. function get_thread_user_post($course_code, $thread_id, $user_id)
  4203. {
  4204. $table_posts = Database::get_course_table(TABLE_FORUM_POST);
  4205. $table_users = Database::get_main_table(TABLE_MAIN_USER);
  4206. $thread_id = intval($thread_id);
  4207. $user_id = intval($user_id);
  4208. $course_info = api_get_user_info($course_code);
  4209. $course_id = $course_info['real_id'];
  4210. if (empty($course_id)) {
  4211. $course_id = api_get_course_int_id();
  4212. }
  4213. $sql = "SELECT * FROM $table_posts posts
  4214. LEFT JOIN $table_users users
  4215. ON posts.poster_id=users.user_id
  4216. WHERE
  4217. posts.c_id = $course_id AND
  4218. posts.thread_id='$thread_id'
  4219. AND posts.poster_id='$user_id'
  4220. ORDER BY posts.post_id ASC";
  4221. $result = Database::query($sql);
  4222. $post_list = array();
  4223. while ($row = Database::fetch_array($result)) {
  4224. $row['status'] = '1';
  4225. $post_list[] = $row;
  4226. $sql = "SELECT * FROM $table_posts posts
  4227. LEFT JOIN $table_users users
  4228. ON posts.poster_id=users.user_id
  4229. WHERE
  4230. posts.c_id = $course_id AND
  4231. posts.thread_id='$thread_id'
  4232. AND posts.post_parent_id='".$row['post_id']."'
  4233. ORDER BY posts.post_id ASC";
  4234. $result2 = Database::query($sql);
  4235. while ($row2 = Database::fetch_array($result2)) {
  4236. $row2['status'] = '0';
  4237. $post_list[] = $row2;
  4238. }
  4239. }
  4240. return $post_list;
  4241. }
  4242. /**
  4243. * This function get the name of an thread by id
  4244. * @param int thread_id
  4245. * @return String
  4246. * @author Christian Fasanando
  4247. * @author Julio Montoya <gugli100@gmail.com> Adding security
  4248. */
  4249. function get_name_thread_by_id($thread_id)
  4250. {
  4251. $t_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
  4252. $course_id = api_get_course_int_id();
  4253. $sql = "SELECT thread_title FROM ".$t_forum_thread." WHERE c_id = $course_id AND thread_id = '".intval(
  4254. $thread_id
  4255. )."' ";
  4256. $result = Database::query($sql);
  4257. $row = Database::fetch_array($result);
  4258. return $row[0];
  4259. }
  4260. /**
  4261. * This function gets all the post written by an user
  4262. * @param int user id
  4263. * @param string db course name
  4264. * @return string
  4265. */
  4266. function get_all_post_from_user($user_id, $course_code)
  4267. {
  4268. $j = 0;
  4269. $forums = get_forums('', $course_code);
  4270. krsort($forums);
  4271. $forum_results = '';
  4272. foreach ($forums as $forum) {
  4273. if ($forum['visibility'] == 0) {
  4274. continue;
  4275. }
  4276. if ($j <= 4) {
  4277. $threads = get_threads($forum['forum_id'], $course_code);
  4278. if (is_array($threads)) {
  4279. $i = 0;
  4280. $hand_forums = '';
  4281. $post_counter = 0;
  4282. foreach ($threads as $thread) {
  4283. if ($thread['visibility'] == 0) {
  4284. continue;
  4285. }
  4286. if ($i <= 4) {
  4287. $post_list = get_thread_user_post_limit($course_code, $thread['thread_id'], $user_id, 1);
  4288. $post_counter = count($post_list);
  4289. if (is_array($post_list) && count($post_list) > 0) {
  4290. $hand_forums .= '<div id="social-thread">';
  4291. $hand_forums .= Display::return_icon(
  4292. 'thread.png',
  4293. get_lang('Thread'),
  4294. '',
  4295. ICON_SIZE_MEDIUM
  4296. );
  4297. $hand_forums .= '&nbsp;'.Security::remove_XSS($thread['thread_title'], STUDENT);
  4298. $hand_forums .= '</div>';
  4299. foreach ($post_list as $posts) {
  4300. $hand_forums .= '<div id="social-post">';
  4301. $hand_forums .= '<strong>'.Security::remove_XSS(
  4302. $posts['post_title'],
  4303. STUDENT
  4304. ).'</strong>';
  4305. $hand_forums .= '<br / >';
  4306. $hand_forums .= Security::remove_XSS($posts['post_text'], STUDENT);
  4307. $hand_forums .= '</div>';
  4308. $hand_forums .= '<br / >';
  4309. }
  4310. }
  4311. }
  4312. $i++;
  4313. }
  4314. $forum_results .= '<div id="social-forum">';
  4315. $forum_results .= '<div class="clear"></div><br />';
  4316. $forum_results .= '<div id="social-forum-title">'.
  4317. Display::return_icon('forum.gif', get_lang('Forum')).'&nbsp;'.Security::remove_XSS(
  4318. $forum['forum_title'],
  4319. STUDENT
  4320. ).
  4321. '<div style="float:right;margin-top:-35px">
  4322. <a href="../forum/viewforum.php?cidReq='.$course_code.'&amp;gidReq=&amp;forum='.$forum['forum_id'].' " >'.get_lang(
  4323. 'SeeForum'
  4324. ).'</a>
  4325. </div></div>';
  4326. $forum_results .= '<br / >';
  4327. if ($post_counter > 0) {
  4328. $forum_results .= $hand_forums;
  4329. }
  4330. $forum_results .= '</div>';
  4331. }
  4332. $j++;
  4333. }
  4334. }
  4335. return $forum_results;
  4336. }
  4337. /**
  4338. * @param string
  4339. * @param int
  4340. * @param int
  4341. * @param int
  4342. * @return void
  4343. */
  4344. function get_thread_user_post_limit($course_code, $thread_id, $user_id, $limit = 10)
  4345. {
  4346. $table_posts = Database::get_course_table(TABLE_FORUM_POST);
  4347. $table_users = Database::get_main_table(TABLE_MAIN_USER);
  4348. $course_info = api_get_course_info($course_code);
  4349. $course_id = $course_info['real_id'];
  4350. $sql = "SELECT * FROM $table_posts posts
  4351. LEFT JOIN $table_users users
  4352. ON posts.poster_id=users.user_id
  4353. WHERE
  4354. posts.c_id = $course_id AND
  4355. posts.thread_id='".Database::escape_string($thread_id)."'
  4356. AND posts.poster_id='".Database::escape_string($user_id)."'
  4357. ORDER BY posts.post_id DESC LIMIT $limit ";
  4358. $result = Database::query($sql);
  4359. while ($row = Database::fetch_array($result)) {
  4360. $row['status'] = '1';
  4361. $post_list[] = $row;
  4362. }
  4363. return $post_list;
  4364. }
  4365. /**
  4366. * This function builds an array of all the posts in a given thread where the key of the array is the post_id
  4367. * It also adds an element children to the array which itself is an array that contains all the id's of the first-level children
  4368. * @return an array containing all the information on the posts of a thread
  4369. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  4370. */
  4371. function calculate_children($rows)
  4372. {
  4373. $sorted_rows = array(0 => array());
  4374. if (!empty($rows)) {
  4375. foreach ($rows as $row) {
  4376. $rows_with_children[$row['post_id']] = $row;
  4377. $rows_with_children[$row['post_parent_id']]['children'][] = $row['post_id'];
  4378. }
  4379. $rows = $rows_with_children;
  4380. _phorum_recursive_sort($rows, $sorted_rows);
  4381. unset($sorted_rows[0]);
  4382. }
  4383. return $sorted_rows;
  4384. }
  4385. function _phorum_recursive_sort($rows, &$threads, $seed = 0, $indent = 0)
  4386. {
  4387. if ($seed > 0) {
  4388. $threads[$rows[$seed]['post_id']] = $rows[$seed];
  4389. $threads[$rows[$seed]['post_id']]['indent_cnt'] = $indent;
  4390. $indent++;
  4391. }
  4392. if (isset($rows[$seed]['children'])) {
  4393. foreach ($rows[$seed]['children'] as $child) {
  4394. _phorum_recursive_sort($rows, $threads, $child, $indent);
  4395. }
  4396. }
  4397. }