forumfunction.inc.php 174 KB

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