forumfunction.inc.php 200 KB

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