forumfunction.inc.php 204 KB

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