social.lib.php 124 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use ChamiloSession as Session;
  4. use Zend\Feed\Reader\Entry\Rss;
  5. use Zend\Feed\Reader\Reader;
  6. /**
  7. * Class SocialManager.
  8. *
  9. * This class provides methods for the social network management.
  10. * Include/require it in your code to use its features.
  11. *
  12. * @package chamilo.social
  13. */
  14. class SocialManager extends UserManager
  15. {
  16. const DEFAULT_WALL_POSTS = 10;
  17. const DEFAULT_SCROLL_NEW_POST = 5;
  18. /**
  19. * Constructor.
  20. */
  21. public function __construct()
  22. {
  23. }
  24. /**
  25. * Allow to see contacts list.
  26. *
  27. * @author isaac flores paz
  28. *
  29. * @return array
  30. */
  31. public static function show_list_type_friends()
  32. {
  33. $table = Database::get_main_table(TABLE_MAIN_USER_FRIEND_RELATION_TYPE);
  34. $sql = 'SELECT id, title FROM '.$table.'
  35. WHERE id<>6
  36. ORDER BY id ASC';
  37. $result = Database::query($sql);
  38. $friend_relation_list = [];
  39. while ($row = Database::fetch_array($result, 'ASSOC')) {
  40. $friend_relation_list[] = $row;
  41. }
  42. $count_list = count($friend_relation_list);
  43. if ($count_list == 0) {
  44. $friend_relation_list[] = get_lang('Unknown');
  45. } else {
  46. return $friend_relation_list;
  47. }
  48. }
  49. /**
  50. * Get relation type contact by name.
  51. *
  52. * @param string names of the kind of relation
  53. *
  54. * @return int
  55. *
  56. * @author isaac flores paz
  57. */
  58. public static function get_relation_type_by_name($relation_type_name)
  59. {
  60. $list_type_friend = self::show_list_type_friends();
  61. foreach ($list_type_friend as $value_type_friend) {
  62. if (strtolower($value_type_friend['title']) == $relation_type_name) {
  63. return $value_type_friend['id'];
  64. }
  65. }
  66. }
  67. /**
  68. * Get the kind of relation between contacts.
  69. *
  70. * @param int user id
  71. * @param int user friend id
  72. * @param string
  73. *
  74. * @return int
  75. *
  76. * @author isaac flores paz
  77. */
  78. public static function get_relation_between_contacts($user_id, $user_friend)
  79. {
  80. $table = Database::get_main_table(TABLE_MAIN_USER_FRIEND_RELATION_TYPE);
  81. $userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
  82. $sql = 'SELECT rt.id as id
  83. FROM '.$table.' rt
  84. WHERE rt.id = (
  85. SELECT uf.relation_type
  86. FROM '.$userRelUserTable.' uf
  87. WHERE
  88. user_id='.((int) $user_id).' AND
  89. friend_user_id='.((int) $user_friend).' AND
  90. uf.relation_type <> '.USER_RELATION_TYPE_RRHH.'
  91. LIMIT 1
  92. )';
  93. $res = Database::query($sql);
  94. if (Database::num_rows($res) > 0) {
  95. $row = Database::fetch_array($res, 'ASSOC');
  96. return $row['id'];
  97. } else {
  98. return USER_UNKNOWN;
  99. }
  100. }
  101. /**
  102. * Get count of friends from user.
  103. *
  104. * @param int $userId
  105. *
  106. * @return int
  107. */
  108. public static function getCountFriends($userId)
  109. {
  110. $table = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
  111. $userId = (int) $userId;
  112. if (empty($userId)) {
  113. return 0;
  114. }
  115. $sql = 'SELECT count(friend_user_id) count
  116. FROM '.$table.'
  117. WHERE
  118. relation_type NOT IN ('.USER_RELATION_TYPE_DELETED.', '.USER_RELATION_TYPE_RRHH.') AND
  119. friend_user_id<>'.$userId.' AND
  120. user_id='.$userId;
  121. $res = Database::query($sql);
  122. if (Database::num_rows($res)) {
  123. $row = Database::fetch_array($res, 'ASSOC');
  124. return (int) $row['count'];
  125. }
  126. return 0;
  127. }
  128. /**
  129. * Gets friends id list.
  130. *
  131. * @param int user id
  132. * @param int group id
  133. * @param string name to search
  134. * @param bool true will load firstname, lastname, and image name
  135. *
  136. * @return array
  137. *
  138. * @author Julio Montoya <gugli100@gmail.com> Cleaning code, function renamed, $load_extra_info option added
  139. * @author isaac flores paz
  140. */
  141. public static function get_friends(
  142. $user_id,
  143. $id_group = null,
  144. $search_name = null,
  145. $load_extra_info = true
  146. ) {
  147. $user_id = (int) $user_id;
  148. $tbl_my_friend = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
  149. $tbl_my_user = Database::get_main_table(TABLE_MAIN_USER);
  150. $sql = 'SELECT friend_user_id FROM '.$tbl_my_friend.'
  151. WHERE
  152. relation_type NOT IN ('.USER_RELATION_TYPE_DELETED.', '.USER_RELATION_TYPE_RRHH.') AND
  153. friend_user_id<>'.$user_id.' AND
  154. user_id='.$user_id;
  155. if (isset($id_group) && $id_group > 0) {
  156. $sql .= ' AND relation_type='.$id_group;
  157. }
  158. if (isset($search_name)) {
  159. $search_name = trim($search_name);
  160. $search_name = str_replace(' ', '', $search_name);
  161. $sql .= ' AND friend_user_id IN (
  162. SELECT user_id FROM '.$tbl_my_user.'
  163. WHERE
  164. firstName LIKE "%'.Database::escape_string($search_name).'%" OR
  165. lastName LIKE "%'.Database::escape_string($search_name).'%" OR
  166. '.(api_is_western_name_order() ? 'concat(firstName, lastName)' : 'concat(lastName, firstName)').' LIKE concat("%","'.Database::escape_string($search_name).'","%")
  167. ) ';
  168. }
  169. $res = Database::query($sql);
  170. $list = [];
  171. while ($row = Database::fetch_array($res, 'ASSOC')) {
  172. if ($load_extra_info) {
  173. $userInfo = api_get_user_info($row['friend_user_id']);
  174. $list[] = [
  175. 'friend_user_id' => $row['friend_user_id'],
  176. 'firstName' => $userInfo['firstName'],
  177. 'lastName' => $userInfo['lastName'],
  178. 'username' => $userInfo['username'],
  179. 'image' => $userInfo['avatar'],
  180. 'user_info' => $userInfo,
  181. ];
  182. } else {
  183. $list[] = $row;
  184. }
  185. }
  186. return $list;
  187. }
  188. /**
  189. * get web path of user invitate.
  190. *
  191. * @author isaac flores paz
  192. * @author Julio Montoya setting variable array
  193. *
  194. * @param int user id
  195. *
  196. * @return array
  197. */
  198. public static function get_list_web_path_user_invitation_by_user_id($user_id)
  199. {
  200. $list_ids = self::get_list_invitation_of_friends_by_user_id($user_id);
  201. $list = [];
  202. foreach ($list_ids as $values_ids) {
  203. $list[] = UserManager::get_user_picture_path_by_id(
  204. $values_ids['user_sender_id'],
  205. 'web'
  206. );
  207. }
  208. return $list;
  209. }
  210. /**
  211. * Sends an invitation to contacts.
  212. *
  213. * @param int user id
  214. * @param int user friend id
  215. * @param string title of the message
  216. * @param string content of the message
  217. *
  218. * @return bool
  219. *
  220. * @author isaac flores paz
  221. * @author Julio Montoya <gugli100@gmail.com> Cleaning code
  222. */
  223. public static function send_invitation_friend(
  224. $user_id,
  225. $friend_id,
  226. $message_title,
  227. $message_content
  228. ) {
  229. $tbl_message = Database::get_main_table(TABLE_MESSAGE);
  230. $user_id = (int) $user_id;
  231. $friend_id = (int) $friend_id;
  232. //Just in case we replace the and \n and \n\r while saving in the DB
  233. $message_content = str_replace(["\n", "\n\r"], '<br />', $message_content);
  234. $clean_message_content = Database::escape_string($message_content);
  235. $now = api_get_utc_datetime();
  236. $sql = 'SELECT COUNT(*) AS count FROM '.$tbl_message.'
  237. WHERE
  238. user_sender_id='.$user_id.' AND
  239. user_receiver_id='.$friend_id.' AND
  240. msg_status IN('.MESSAGE_STATUS_INVITATION_PENDING.', '.MESSAGE_STATUS_INVITATION_ACCEPTED.', '.MESSAGE_STATUS_INVITATION_DENIED.');
  241. ';
  242. $res_exist = Database::query($sql);
  243. $row_exist = Database::fetch_array($res_exist, 'ASSOC');
  244. if ($row_exist['count'] == 0) {
  245. $params = [
  246. 'user_sender_id' => $user_id,
  247. 'user_receiver_id' => $friend_id,
  248. 'msg_status' => MESSAGE_STATUS_INVITATION_PENDING,
  249. 'send_date' => $now,
  250. 'title' => $message_title,
  251. 'content' => $message_content,
  252. 'group_id' => 0,
  253. 'parent_id' => 0,
  254. 'update_date' => $now,
  255. ];
  256. $messageId = Database::insert($tbl_message, $params);
  257. $senderInfo = api_get_user_info($user_id);
  258. $notification = new Notification();
  259. $notification->saveNotification(
  260. $messageId,
  261. Notification::NOTIFICATION_TYPE_INVITATION,
  262. [$friend_id],
  263. $message_title,
  264. $message_content,
  265. $senderInfo
  266. );
  267. return true;
  268. } else {
  269. // invitation already exist
  270. $sql = 'SELECT COUNT(*) AS count, id FROM '.$tbl_message.'
  271. WHERE user_sender_id='.$user_id.' AND user_receiver_id='.$friend_id.' AND msg_status = 7';
  272. $res_if_exist = Database::query($sql);
  273. $row_if_exist = Database::fetch_array($res_if_exist, 'ASSOC');
  274. if ($row_if_exist['count'] == 1) {
  275. $sql = 'UPDATE '.$tbl_message.' SET
  276. msg_status=5, content = "'.$clean_message_content.'"
  277. WHERE user_sender_id='.$user_id.' AND user_receiver_id='.$friend_id.' AND msg_status = 7 ';
  278. Database::query($sql);
  279. return true;
  280. } else {
  281. return false;
  282. }
  283. }
  284. }
  285. /**
  286. * Get number messages of the inbox.
  287. *
  288. * @author isaac flores paz
  289. *
  290. * @param int $userId user receiver id
  291. *
  292. * @return int
  293. */
  294. public static function get_message_number_invitation_by_user_id($userId)
  295. {
  296. $table = Database::get_main_table(TABLE_MESSAGE);
  297. $userId = (int) $userId;
  298. $sql = 'SELECT COUNT(*) as count_message_in_box FROM '.$table.'
  299. WHERE
  300. user_receiver_id='.$userId.' AND
  301. msg_status='.MESSAGE_STATUS_INVITATION_PENDING;
  302. $res = Database::query($sql);
  303. $row = Database::fetch_array($res, 'ASSOC');
  304. if ($row) {
  305. return (int) $row['count_message_in_box'];
  306. }
  307. return 0;
  308. }
  309. /**
  310. * Get number of messages sent to other users.
  311. *
  312. * @param int $userId
  313. *
  314. * @return int
  315. */
  316. public static function getCountMessagesSent($userId)
  317. {
  318. $userId = (int) $userId;
  319. $table = Database::get_main_table(TABLE_MESSAGE);
  320. $sql = 'SELECT COUNT(*) FROM '.$table.'
  321. WHERE
  322. user_sender_id='.$userId.' AND
  323. msg_status < 5';
  324. $res = Database::query($sql);
  325. $row = Database::fetch_row($res);
  326. return $row[0];
  327. }
  328. /**
  329. * Get number of messages received from other users.
  330. *
  331. * @param int $receiver_id
  332. *
  333. * @return int
  334. */
  335. public static function getCountMessagesReceived($receiver_id)
  336. {
  337. $table = Database::get_main_table(TABLE_MESSAGE);
  338. $sql = 'SELECT COUNT(*) FROM '.$table.'
  339. WHERE
  340. user_receiver_id='.intval($receiver_id).' AND
  341. msg_status < 4';
  342. $res = Database::query($sql);
  343. $row = Database::fetch_row($res);
  344. return $row[0];
  345. }
  346. /**
  347. * Get number of messages posted on own wall.
  348. *
  349. * @param int $userId
  350. *
  351. * @return int
  352. */
  353. public static function getCountWallPostedMessages($userId)
  354. {
  355. $userId = (int) $userId;
  356. if (empty($userId)) {
  357. return 0;
  358. }
  359. $table = Database::get_main_table(TABLE_MESSAGE);
  360. $sql = 'SELECT COUNT(*)
  361. FROM '.$table.'
  362. WHERE
  363. user_sender_id='.$userId.' AND
  364. (msg_status = '.MESSAGE_STATUS_WALL.' OR
  365. msg_status = '.MESSAGE_STATUS_WALL_POST.') AND
  366. parent_id = 0';
  367. $res = Database::query($sql);
  368. $row = Database::fetch_row($res);
  369. return $row[0];
  370. }
  371. /**
  372. * Get invitation list received by user.
  373. *
  374. * @author isaac flores paz
  375. *
  376. * @param int $userId
  377. * @param int $limit
  378. *
  379. * @return array
  380. */
  381. public static function get_list_invitation_of_friends_by_user_id($userId, $limit = 0)
  382. {
  383. $userId = (int) $userId;
  384. $limit = (int) $limit;
  385. if (empty($userId)) {
  386. return [];
  387. }
  388. $table = Database::get_main_table(TABLE_MESSAGE);
  389. $sql = 'SELECT user_sender_id, send_date, title, content
  390. FROM '.$table.'
  391. WHERE
  392. user_receiver_id = '.$userId.' AND
  393. msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
  394. if ($limit != null && $limit > 0) {
  395. $sql .= ' LIMIT '.$limit;
  396. }
  397. $res = Database::query($sql);
  398. $list = [];
  399. while ($row = Database::fetch_array($res, 'ASSOC')) {
  400. $list[] = $row;
  401. }
  402. return $list;
  403. }
  404. /**
  405. * Get invitation list sent by user.
  406. *
  407. * @author Julio Montoya <gugli100@gmail.com>
  408. *
  409. * @param int $userId
  410. *
  411. * @return array
  412. */
  413. public static function get_list_invitation_sent_by_user_id($userId)
  414. {
  415. $userId = (int) $userId;
  416. if (empty($userId)) {
  417. return [];
  418. }
  419. $table = Database::get_main_table(TABLE_MESSAGE);
  420. $sql = 'SELECT user_receiver_id, send_date,title,content
  421. FROM '.$table.'
  422. WHERE
  423. user_sender_id = '.$userId.' AND
  424. msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
  425. $res = Database::query($sql);
  426. $list = [];
  427. while ($row = Database::fetch_array($res, 'ASSOC')) {
  428. $list[$row['user_receiver_id']] = $row;
  429. }
  430. return $list;
  431. }
  432. /**
  433. * Get count invitation sent by user.
  434. *
  435. * @author Julio Montoya <gugli100@gmail.com>
  436. *
  437. * @param int $userId
  438. *
  439. * @return int
  440. */
  441. public static function getCountInvitationSent($userId)
  442. {
  443. $userId = (int) $userId;
  444. if (empty($userId)) {
  445. return 0;
  446. }
  447. $table = Database::get_main_table(TABLE_MESSAGE);
  448. $sql = 'SELECT count(user_receiver_id) count
  449. FROM '.$table.'
  450. WHERE
  451. user_sender_id = '.$userId.' AND
  452. msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
  453. $res = Database::query($sql);
  454. if (Database::num_rows($res)) {
  455. $row = Database::fetch_array($res, 'ASSOC');
  456. return (int) $row['count'];
  457. }
  458. return 0;
  459. }
  460. /**
  461. * Accepts invitation.
  462. *
  463. * @param int $user_send_id
  464. * @param int $user_receiver_id
  465. *
  466. * @return bool
  467. *
  468. * @author isaac flores paz
  469. * @author Julio Montoya <gugli100@gmail.com> Cleaning code
  470. */
  471. public static function invitation_accepted($user_send_id, $user_receiver_id)
  472. {
  473. if (empty($user_send_id) || empty($user_receiver_id)) {
  474. return false;
  475. }
  476. $table = Database::get_main_table(TABLE_MESSAGE);
  477. $sql = "UPDATE $table
  478. SET msg_status = ".MESSAGE_STATUS_INVITATION_ACCEPTED."
  479. WHERE
  480. user_sender_id = ".((int) $user_send_id)." AND
  481. user_receiver_id=".((int) $user_receiver_id)." AND
  482. msg_status = ".MESSAGE_STATUS_INVITATION_PENDING;
  483. Database::query($sql);
  484. return true;
  485. }
  486. /**
  487. * Denies invitation.
  488. *
  489. * @param int user sender id
  490. * @param int user receiver id
  491. *
  492. * @return bool
  493. *
  494. * @author isaac flores paz
  495. * @author Julio Montoya <gugli100@gmail.com> Cleaning code
  496. */
  497. public static function invitation_denied($user_send_id, $user_receiver_id)
  498. {
  499. if (empty($user_send_id) || empty($user_receiver_id)) {
  500. return false;
  501. }
  502. $table = Database::get_main_table(TABLE_MESSAGE);
  503. $sql = 'DELETE FROM '.$table.'
  504. WHERE
  505. user_sender_id = '.((int) $user_send_id).' AND
  506. user_receiver_id='.((int) $user_receiver_id).' AND
  507. msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
  508. Database::query($sql);
  509. return true;
  510. }
  511. /**
  512. * Allow attaching to group.
  513. *
  514. * @author Isaac Flores Paz
  515. *
  516. * @param int $id_friend_qualify User to qualify
  517. * @param int $type_qualify Kind of rating
  518. *
  519. * @deprecated 2017-03
  520. */
  521. public static function qualify_friend($id_friend_qualify, $type_qualify)
  522. {
  523. $table = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
  524. $user_id = api_get_user_id();
  525. $sql = 'UPDATE '.$table.' SET relation_type='.((int) $type_qualify).'
  526. WHERE user_id = '.$user_id.' AND friend_user_id='.(int) $id_friend_qualify;
  527. Database::query($sql);
  528. }
  529. /**
  530. * Get user's feeds.
  531. *
  532. * @param int $user User ID
  533. * @param int $limit Limit of posts per feed
  534. *
  535. * @return string HTML section with all feeds included
  536. *
  537. * @author Yannick Warnier
  538. *
  539. * @since Dokeos 1.8.6.1
  540. */
  541. public static function getUserRssFeed($user, $limit = 5)
  542. {
  543. $feed = UserManager::get_extra_user_data_by_field($user, 'rssfeeds');
  544. if (empty($feed)) {
  545. return '';
  546. }
  547. $feeds = explode(';', $feed['rssfeeds']);
  548. if (count($feeds) == 0) {
  549. return '';
  550. }
  551. $res = '';
  552. foreach ($feeds as $url) {
  553. if (empty($url)) {
  554. continue;
  555. }
  556. try {
  557. $channel = Reader::import($url);
  558. $i = 1;
  559. if (!empty($channel)) {
  560. $iconRss = '';
  561. if (!empty($feed)) {
  562. $iconRss = Display::url(
  563. Display::return_icon('social_rss.png', '', [], 22),
  564. Security::remove_XSS($feed['rssfeeds']),
  565. ['target' => '_blank']
  566. );
  567. }
  568. $res .= '<h3 class="title-rss">'.$iconRss.' '.$channel->getTitle().'</h3>';
  569. $res .= '<div class="rss-items">';
  570. /** @var Rss $item */
  571. foreach ($channel as $item) {
  572. if ($limit >= 0 and $i > $limit) {
  573. break;
  574. }
  575. $res .= '<h4 class="rss-title"><a href="'.$item->getLink().'">'.$item->getTitle().'</a></h4>';
  576. $res .= '<div class="rss-date">'.api_get_local_time($item->getDateCreated()).'</div>';
  577. $res .= '<div class="rss-content"><p>'.$item->getDescription().'</p></div>';
  578. $i++;
  579. }
  580. $res .= '</div>';
  581. }
  582. } catch (Exception $e) {
  583. error_log($e->getMessage());
  584. }
  585. }
  586. return $res;
  587. }
  588. /**
  589. * Sends invitations to friends.
  590. *
  591. * @param int $userId
  592. * @param string $subject
  593. * @param string $content
  594. *
  595. * @return bool
  596. */
  597. public static function sendInvitationToUser($userId, $subject = '', $content = '')
  598. {
  599. $user_info = api_get_user_info($userId);
  600. $success = get_lang('MessageSentTo');
  601. $success .= ' : '.api_get_person_name($user_info['firstName'], $user_info['lastName']);
  602. if (isset($subject) && isset($content) && isset($userId)) {
  603. $result = MessageManager::send_message($userId, $subject, $content);
  604. if ($result) {
  605. Display::addFlash(
  606. Display::return_message($success, 'normal', false)
  607. );
  608. } else {
  609. Display::addFlash(
  610. Display::return_message(get_lang('ErrorSendingMessage'), 'error', false)
  611. );
  612. }
  613. return false;
  614. } elseif (isset($userId) && !isset($subject)) {
  615. if (isset($userId) && $userId > 0) {
  616. $count = self::send_invitation_friend(
  617. api_get_user_id(),
  618. $userId,
  619. get_lang('Invitation'),
  620. $content
  621. );
  622. if ($count) {
  623. Display::addFlash(
  624. Display::return_message(
  625. api_htmlentities(get_lang('InvitationHasBeenSent')),
  626. 'normal',
  627. false
  628. )
  629. );
  630. } else {
  631. Display::addFlash(
  632. Display::return_message(
  633. api_htmlentities(get_lang('YouAlreadySentAnInvitation')),
  634. 'warning',
  635. false
  636. )
  637. );
  638. }
  639. }
  640. }
  641. }
  642. /**
  643. * Helper functions definition.
  644. */
  645. public static function get_logged_user_course_html($my_course, $count)
  646. {
  647. $result = '';
  648. $count = (int) $count;
  649. // Table definitions
  650. $main_user_table = Database::get_main_table(TABLE_MAIN_USER);
  651. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  652. $course_directory = $my_course['course_info']['directory'];
  653. $course_title = $my_course['course_info']['title'];
  654. $course_visibility = $my_course['course_info']['visibility'];
  655. $user_in_course_status = CourseManager::getUserInCourseStatus(
  656. api_get_user_id(),
  657. $my_course['course_info']['real_id']
  658. );
  659. $course_path = api_get_path(SYS_COURSE_PATH).$course_directory; // course path
  660. if (api_get_setting('course_images_in_courses_list') === 'true') {
  661. if (file_exists($course_path.'/course-pic85x85.png')) {
  662. $image = $my_course['course_info']['course_image'];
  663. $imageCourse = Display::img($image, $course_title, ['class' => 'img-course']);
  664. } else {
  665. $imageCourse = Display::return_icon(
  666. 'session_default_small.png',
  667. $course_title,
  668. ['class' => 'img-course']
  669. );
  670. }
  671. } else {
  672. $imageCourse = Display::return_icon(
  673. 'course.png',
  674. get_lang('Course'),
  675. ['class' => 'img-default']
  676. );
  677. }
  678. //display course entry
  679. if (api_get_setting('course_images_in_courses_list') === 'true') {
  680. $result .= '<li id="course_'.$count.'" class="list-group-item" style="min-height:65px;">';
  681. } else {
  682. $result .= '<li id="course_'.$count.'" class="list-group-item" style="min-height:44px;">';
  683. }
  684. $result .= $imageCourse;
  685. //show a hyperlink to the course, unless the course is closed and user is not course admin
  686. if ($course_visibility != COURSE_VISIBILITY_HIDDEN &&
  687. ($course_visibility != COURSE_VISIBILITY_CLOSED || $user_in_course_status == COURSEMANAGER)
  688. ) {
  689. $result .= '<span class="title">'.$course_title.'<span>';
  690. } else {
  691. $result .= $course_title.' '.get_lang('CourseClosed');
  692. }
  693. $result .= '</li>';
  694. $session = '';
  695. if (!empty($my_course['session_name']) && !empty($my_course['id_session'])) {
  696. // Request for the name of the general coach
  697. $sql = 'SELECT lastname, firstname
  698. FROM '.$tbl_session.' ts
  699. LEFT JOIN '.$main_user_table.' tu
  700. ON ts.id_coach = tu.user_id
  701. WHERE ts.id='.(int) $my_course['id_session'].' LIMIT 1';
  702. $rs = Database::query($sql);
  703. $sessioncoach = Database::store_result($rs);
  704. $sessioncoach = $sessioncoach[0];
  705. $session = [];
  706. $session['title'] = $my_course['session_name'];
  707. if ($my_course['access_start_date'] == '0000-00-00') {
  708. $session['dates'] = get_lang('WithoutTimeLimits');
  709. if (api_get_setting('show_session_coach') === 'true') {
  710. $session['coach'] = get_lang('GeneralCoach').': '.
  711. api_get_person_name($sessioncoach['firstname'], $sessioncoach['lastname']);
  712. }
  713. } else {
  714. $session['dates'] = ' - '.get_lang('From').' '.$my_course['access_start_date'].' '.get_lang('To').' '.$my_course['access_end_date'];
  715. if (api_get_setting('show_session_coach') === 'true') {
  716. $session['coach'] = get_lang('GeneralCoach').': '.
  717. api_get_person_name($sessioncoach['firstname'], $sessioncoach['lastname']);
  718. }
  719. }
  720. }
  721. $my_course['id_session'] = isset($my_course['id_session']) ? $my_course['id_session'] : 0;
  722. $output = [
  723. $my_course['user_course_cat'],
  724. $result,
  725. $my_course['id_session'],
  726. $session,
  727. ];
  728. return $output;
  729. }
  730. /**
  731. * Shows the avatar block in social pages.
  732. *
  733. * @param string $show highlight link possible values:
  734. * group_add,
  735. * home,
  736. * messages,
  737. * messages_inbox,
  738. * messages_compose,
  739. * messages_outbox,
  740. * invitations,
  741. * shared_profile,
  742. * friends,
  743. * groups search
  744. * @param int $group_id
  745. * @param int $user_id
  746. */
  747. public static function show_social_avatar_block($show = '', $group_id = 0, $user_id = 0)
  748. {
  749. $user_id = (int) $user_id;
  750. $group_id = (int) $group_id;
  751. if (empty($user_id)) {
  752. $user_id = api_get_user_id();
  753. }
  754. $show_groups = [
  755. 'groups',
  756. 'group_messages',
  757. 'messages_list',
  758. 'group_add',
  759. 'mygroups',
  760. 'group_edit',
  761. 'member_list',
  762. 'invite_friends',
  763. 'waiting_list',
  764. 'browse_groups',
  765. ];
  766. $template = new Template(null, false, false, false, false, false);
  767. if (in_array($show, $show_groups) && !empty($group_id)) {
  768. // Group image
  769. $userGroup = new UserGroup();
  770. $group_info = $userGroup->get($group_id);
  771. $userGroupImage = $userGroup->get_picture_group(
  772. $group_id,
  773. $group_info['picture'],
  774. 128,
  775. GROUP_IMAGE_SIZE_BIG
  776. );
  777. $template->assign('show_group', true);
  778. $template->assign('group_id', $group_id);
  779. $template->assign('user_group_image', $userGroupImage);
  780. $template->assign(
  781. 'user_is_group_admin',
  782. $userGroup->is_group_admin(
  783. $group_id,
  784. api_get_user_id()
  785. )
  786. );
  787. } else {
  788. $template->assign('show_group', false);
  789. $template->assign('show_user', true);
  790. $template->assign(
  791. 'user_image',
  792. [
  793. 'big' => UserManager::getUserPicture(
  794. $user_id,
  795. USER_IMAGE_SIZE_BIG
  796. ),
  797. 'normal' => UserManager::getUserPicture(
  798. $user_id,
  799. USER_IMAGE_SIZE_MEDIUM
  800. ),
  801. ]
  802. );
  803. }
  804. $skillBlock = $template->get_template('social/avatar_block.tpl');
  805. return $template->fetch($skillBlock);
  806. }
  807. /**
  808. * Shows the right menu of the Social Network tool.
  809. *
  810. * @param string $show highlight link possible values:
  811. * group_add,
  812. * home,
  813. * messages,
  814. * messages_inbox,
  815. * messages_compose ,
  816. * messages_outbox,
  817. * invitations,
  818. * shared_profile,
  819. * friends,
  820. * groups search
  821. * @param int $group_id group id
  822. * @param int $user_id user id
  823. * @param bool $show_full_profile show profile or not (show or hide the user image/information)
  824. * @param bool $show_delete_account_button
  825. */
  826. public static function show_social_menu(
  827. $show = '',
  828. $group_id = 0,
  829. $user_id = 0,
  830. $show_full_profile = false,
  831. $show_delete_account_button = false
  832. ) {
  833. $user_id = (int) $user_id;
  834. $group_id = (int) $group_id;
  835. if (empty($user_id)) {
  836. $user_id = api_get_user_id();
  837. }
  838. $usergroup = new UserGroup();
  839. $show_groups = [
  840. 'groups',
  841. 'group_messages',
  842. 'messages_list',
  843. 'group_add',
  844. 'mygroups',
  845. 'group_edit',
  846. 'member_list',
  847. 'invite_friends',
  848. 'waiting_list',
  849. 'browse_groups',
  850. ];
  851. // get count unread message and total invitations
  852. $count_unread_message = MessageManager::getNumberOfMessages(true);
  853. $count_unread_message = !empty($count_unread_message) ? Display::badge($count_unread_message) : null;
  854. $number_of_new_messages_of_friend = self::get_message_number_invitation_by_user_id(api_get_user_id());
  855. $group_pending_invitations = $usergroup->get_groups_by_user(
  856. api_get_user_id(),
  857. GROUP_USER_PERMISSION_PENDING_INVITATION,
  858. false
  859. );
  860. $group_pending_invitations = count($group_pending_invitations);
  861. $total_invitations = $number_of_new_messages_of_friend + $group_pending_invitations;
  862. $total_invitations = (!empty($total_invitations) ? Display::badge($total_invitations) : '');
  863. $filesIcon = Display::return_icon('sn-files.png', get_lang('MyFiles'), null, ICON_SIZE_SMALL);
  864. $friendsIcon = Display::return_icon('sn-friends.png', get_lang('Friends'), null, ICON_SIZE_SMALL);
  865. $groupsIcon = Display::return_icon('sn-groups.png', get_lang('SocialGroups'), null, ICON_SIZE_SMALL);
  866. $homeIcon = Display::return_icon('sn-home.png', get_lang('Home'), null, ICON_SIZE_SMALL);
  867. $invitationsIcon = Display::return_icon('sn-invitations.png', get_lang('Invitations'), null, ICON_SIZE_SMALL);
  868. $messagesIcon = Display::return_icon('sn-message.png', get_lang('Messages'), null, ICON_SIZE_SMALL);
  869. $sharedProfileIcon = Display::return_icon('sn-profile.png', get_lang('ViewMySharedProfile'));
  870. $searchIcon = Display::return_icon('sn-search.png', get_lang('Search'), null, ICON_SIZE_SMALL);
  871. $portfolioIcon = Display::return_icon('wiki_task.png', get_lang('Portfolio'));
  872. $personalDataIcon = Display::return_icon('database.png', get_lang('PersonalDataReport'));
  873. $forumCourseId = api_get_configuration_value('global_forums_course_id');
  874. $groupUrl = api_get_path(WEB_CODE_PATH).'social/groups.php';
  875. if (!empty($forumCourseId)) {
  876. $courseInfo = api_get_course_info_by_id($forumCourseId);
  877. if (!empty($courseInfo)) {
  878. $groupUrl = api_get_path(WEB_CODE_PATH).'forum/index.php?cidReq='.$courseInfo['code'];
  879. }
  880. }
  881. $html = '';
  882. $active = null;
  883. if (!in_array(
  884. $show,
  885. ['shared_profile', 'groups', 'group_edit', 'member_list', 'waiting_list', 'invite_friends']
  886. )) {
  887. $links = '<ul class="nav nav-pills nav-stacked">';
  888. $active = $show === 'home' ? 'active' : null;
  889. $links .= '
  890. <li class="home-icon '.$active.'">
  891. <a href="'.api_get_path(WEB_CODE_PATH).'social/home.php">
  892. '.$homeIcon.' '.get_lang('Home').'
  893. </a>
  894. </li>';
  895. $active = $show == 'messages' ? 'active' : null;
  896. $links .= '
  897. <li class="messages-icon '.$active.'">
  898. <a href="'.api_get_path(WEB_CODE_PATH).'messages/inbox.php">
  899. '.$messagesIcon.' '.get_lang('Messages').$count_unread_message.'
  900. </a>
  901. </li>';
  902. // Invitations
  903. $active = $show == 'invitations' ? 'active' : null;
  904. $links .= '
  905. <li class="invitations-icon '.$active.'">
  906. <a href="'.api_get_path(WEB_CODE_PATH).'social/invitations.php">
  907. '.$invitationsIcon.' '.get_lang('Invitations').$total_invitations.'
  908. </a>
  909. </li>';
  910. // Shared profile and groups
  911. $active = $show == 'shared_profile' ? 'active' : null;
  912. $links .= '
  913. <li class="shared-profile-icon'.$active.'">
  914. <a href="'.api_get_path(WEB_CODE_PATH).'social/profile.php">
  915. '.$sharedProfileIcon.' '.get_lang('ViewMySharedProfile').'
  916. </a>
  917. </li>';
  918. $active = $show == 'friends' ? 'active' : null;
  919. $links .= '
  920. <li class="friends-icon '.$active.'">
  921. <a href="'.api_get_path(WEB_CODE_PATH).'social/friends.php">
  922. '.$friendsIcon.' '.get_lang('Friends').'
  923. </a>
  924. </li>';
  925. $active = $show === 'browse_groups' ? 'active' : null;
  926. $links .= '
  927. <li class="browse-groups-icon '.$active.'">
  928. <a href="'.$groupUrl.'">
  929. '.$groupsIcon.' '.get_lang('SocialGroups').'
  930. </a>
  931. </li>';
  932. // Search users
  933. $active = $show == 'search' ? 'active' : null;
  934. $links .= '
  935. <li class="search-icon '.$active.'">
  936. <a href="'.api_get_path(WEB_CODE_PATH).'social/search.php">
  937. '.$searchIcon.' '.get_lang('Search').'
  938. </a>
  939. </li>';
  940. // My files
  941. $active = $show == 'myfiles' ? 'active' : null;
  942. $myFiles = '
  943. <li class="myfiles-icon '.$active.'">
  944. <a href="'.api_get_path(WEB_CODE_PATH).'social/myfiles.php">
  945. '.$filesIcon.' '.get_lang('MyFiles').'
  946. </a>
  947. </li>';
  948. if (api_get_setting('allow_my_files') === 'false') {
  949. $myFiles = '';
  950. }
  951. $links .= $myFiles;
  952. if (api_get_configuration_value('allow_portfolio_tool')) {
  953. $links .= '
  954. <li class="portoflio-icon '.($show == 'portfolio' ? 'active' : '').'">
  955. <a href="'.api_get_path(WEB_CODE_PATH).'portfolio/index.php">
  956. '.$portfolioIcon.' '.get_lang('Portfolio').'
  957. </a>
  958. </li>
  959. ';
  960. }
  961. if (!api_get_configuration_value('disable_gdpr')) {
  962. $active = $show == 'personal-data' ? 'active' : null;
  963. $personalData = '
  964. <li class="personal-data-icon '.$active.'">
  965. <a href="'.api_get_path(WEB_CODE_PATH).'social/personal_data.php">
  966. '.$personalDataIcon.' '.get_lang('PersonalDataReport').'
  967. </a>
  968. </li>';
  969. $links .= $personalData;
  970. $links .= '</ul>';
  971. }
  972. $html .= Display::panelCollapse(
  973. get_lang('SocialNetwork'),
  974. $links,
  975. 'social-network-menu',
  976. null,
  977. 'sn-sidebar',
  978. 'sn-sidebar-collapse'
  979. );
  980. }
  981. if (in_array($show, $show_groups) && !empty($group_id)) {
  982. $html .= $usergroup->show_group_column_information(
  983. $group_id,
  984. api_get_user_id(),
  985. $show
  986. );
  987. }
  988. if ($show === 'shared_profile') {
  989. $links = '<ul class="nav nav-pills nav-stacked">';
  990. // My own profile
  991. if ($show_full_profile && $user_id == api_get_user_id()) {
  992. $links .= '
  993. <li class="home-icon '.$active.'">
  994. <a href="'.api_get_path(WEB_CODE_PATH).'social/home.php">
  995. '.$homeIcon.' '.get_lang('Home').'
  996. </a>
  997. </li>
  998. <li class="messages-icon '.$active.'">
  999. <a href="'.api_get_path(WEB_CODE_PATH).'messages/inbox.php">
  1000. '.$messagesIcon.' '.get_lang('Messages').$count_unread_message.'
  1001. </a>
  1002. </li>';
  1003. $active = $show === 'invitations' ? 'active' : null;
  1004. $links .= '
  1005. <li class="invitations-icon'.$active.'">
  1006. <a href="'.api_get_path(WEB_CODE_PATH).'social/invitations.php">
  1007. '.$invitationsIcon.' '.get_lang('Invitations').$total_invitations.'
  1008. </a>
  1009. </li>';
  1010. $links .= '
  1011. <li class="shared-profile-icon active">
  1012. <a href="'.api_get_path(WEB_CODE_PATH).'social/profile.php">
  1013. '.$sharedProfileIcon.' '.get_lang('ViewMySharedProfile').'
  1014. </a>
  1015. </li>
  1016. <li class="friends-icon">
  1017. <a href="'.api_get_path(WEB_CODE_PATH).'social/friends.php">
  1018. '.$friendsIcon.' '.get_lang('Friends').'
  1019. </a>
  1020. </li>';
  1021. $links .= '<li class="browse-groups-icon">
  1022. <a href="'.$groupUrl.'">
  1023. '.$groupsIcon.' '.get_lang('SocialGroups').'
  1024. </a>
  1025. </li>';
  1026. $active = $show == 'search' ? 'active' : null;
  1027. $links .= '
  1028. <li class="search-icon '.$active.'">
  1029. <a href="'.api_get_path(WEB_CODE_PATH).'social/search.php">
  1030. '.$searchIcon.' '.get_lang('Search').'
  1031. </a>
  1032. </li>';
  1033. $active = $show == 'myfiles' ? 'active' : null;
  1034. $myFiles = '
  1035. <li class="myfiles-icon '.$active.'">
  1036. <a href="'.api_get_path(WEB_CODE_PATH).'social/myfiles.php">
  1037. '.$filesIcon.' '.get_lang('MyFiles').'
  1038. </a>
  1039. </li>';
  1040. if (api_get_setting('allow_my_files') === 'false') {
  1041. $myFiles = '';
  1042. }
  1043. $links .= $myFiles;
  1044. if (api_get_configuration_value('allow_portfolio_tool')) {
  1045. $links .= '
  1046. <li class="portoflio-icon '.($show == 'portfolio' ? 'active' : '').'">
  1047. <a href="'.api_get_path(WEB_CODE_PATH).'portfolio/index.php">
  1048. '.$portfolioIcon.' '.get_lang('Portfolio').'
  1049. </a>
  1050. </li>
  1051. ';
  1052. }
  1053. if (!api_get_configuration_value('disable_gdpr')) {
  1054. $active = $show == 'personal-data' ? 'active' : null;
  1055. $personalData = '
  1056. <li class="personal-data-icon '.$active.'">
  1057. <a href="'.api_get_path(WEB_CODE_PATH).'social/personal_data.php">
  1058. '.$personalDataIcon.' '.get_lang('PersonalDataReport').'
  1059. </a>
  1060. </li>';
  1061. $links .= $personalData;
  1062. $links .= '</ul>';
  1063. }
  1064. }
  1065. // My friend profile.
  1066. if ($user_id != api_get_user_id()) {
  1067. $sendMessageText = get_lang('SendMessage');
  1068. $sendMessageIcon = Display::return_icon(
  1069. 'new-message.png',
  1070. $sendMessageText
  1071. );
  1072. $sendMessageUrl = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?'.http_build_query([
  1073. 'a' => 'get_user_popup',
  1074. 'user_id' => $user_id,
  1075. ]);
  1076. $links .= '<li>';
  1077. $links .= Display::url(
  1078. "$sendMessageIcon $sendMessageText",
  1079. $sendMessageUrl,
  1080. [
  1081. 'class' => 'ajax',
  1082. 'title' => $sendMessageText,
  1083. 'data-title' => $sendMessageText,
  1084. ]
  1085. );
  1086. $links .= '</li>';
  1087. if (api_get_configuration_value('allow_portfolio_tool')) {
  1088. $links .= '
  1089. <li class="portoflio-icon '.($show == 'portfolio' ? 'active' : '').'">
  1090. <a href="'.api_get_path(WEB_CODE_PATH).'portfolio/index.php?user='.$user_id.'">
  1091. '.$portfolioIcon.' '.get_lang('Portfolio').'
  1092. </a>
  1093. </li>
  1094. ';
  1095. }
  1096. }
  1097. // Check if I already sent an invitation message
  1098. $invitation_sent_list = self::get_list_invitation_sent_by_user_id(api_get_user_id());
  1099. if (isset($invitation_sent_list[$user_id]) && is_array($invitation_sent_list[$user_id]) &&
  1100. count($invitation_sent_list[$user_id]) > 0
  1101. ) {
  1102. $links .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/invitations.php">'.
  1103. Display::return_icon('invitation.png', get_lang('YouAlreadySentAnInvitation'))
  1104. .'&nbsp;&nbsp;'.get_lang('YouAlreadySentAnInvitation').'</a></li>';
  1105. } else {
  1106. if (!$show_full_profile) {
  1107. $links .= '<li>
  1108. <a class="btn-to-send-invitation" href="#" data-send-to="'.$user_id.'" title="'.get_lang('SendInvitation').'">'.
  1109. Display::return_icon('invitation.png', get_lang('SocialInvitationToFriends')).'&nbsp;'.get_lang('SendInvitation').
  1110. '</a></li>';
  1111. }
  1112. }
  1113. $links .= '</ul>';
  1114. $html .= Display::panelCollapse(
  1115. get_lang('SocialNetwork'),
  1116. $links,
  1117. 'social-network-menu',
  1118. null,
  1119. 'sn-sidebar',
  1120. 'sn-sidebar-collapse'
  1121. );
  1122. if ($show_full_profile && $user_id == api_get_user_id()) {
  1123. $personal_course_list = UserManager::get_personal_session_course_list($user_id);
  1124. $course_list_code = [];
  1125. $i = 1;
  1126. if (is_array($personal_course_list)) {
  1127. foreach ($personal_course_list as $my_course) {
  1128. if ($i <= 10) {
  1129. $course_list_code[] = ['code' => $my_course['code']];
  1130. } else {
  1131. break;
  1132. }
  1133. $i++;
  1134. }
  1135. // To avoid repeated courses
  1136. $course_list_code = array_unique_dimensional($course_list_code);
  1137. }
  1138. // Announcements
  1139. $announcements = [];
  1140. foreach ($course_list_code as $course) {
  1141. $course_info = api_get_course_info($course['code']);
  1142. if (!empty($course_info)) {
  1143. $content = AnnouncementManager::get_all_annoucement_by_user_course(
  1144. $course_info['code'],
  1145. $user_id
  1146. );
  1147. if (!empty($content)) {
  1148. $url = Display::url(
  1149. Display::return_icon(
  1150. 'announcement.png',
  1151. get_lang('Announcements')
  1152. ).$course_info['name'].' ('.$content['count'].')',
  1153. api_get_path(WEB_CODE_PATH).'announcements/announcements.php?cidReq='.$course['code']
  1154. );
  1155. $announcements[] = Display::tag('li', $url);
  1156. }
  1157. }
  1158. }
  1159. if (!empty($announcements)) {
  1160. $html .= '<div class="social_menu_items">';
  1161. $html .= '<ul>';
  1162. foreach ($announcements as $announcement) {
  1163. $html .= $announcement;
  1164. }
  1165. $html .= '</ul>';
  1166. $html .= '</div>';
  1167. }
  1168. }
  1169. }
  1170. if ($show_delete_account_button) {
  1171. $html .= '<div class="panel panel-default"><div class="panel-body">';
  1172. $html .= '<ul class="nav nav-pills nav-stacked"><li>';
  1173. $url = api_get_path(WEB_CODE_PATH).'auth/unsubscribe_account.php';
  1174. $html .= Display::url(
  1175. Display::return_icon(
  1176. 'delete.png',
  1177. get_lang('Unsubscribe'),
  1178. [],
  1179. ICON_SIZE_TINY
  1180. ).get_lang('Unsubscribe'),
  1181. $url
  1182. );
  1183. $html .= '</li></ul>';
  1184. $html .= '</div></div>';
  1185. }
  1186. $html .= '';
  1187. return $html;
  1188. }
  1189. /**
  1190. * Displays a sortable table with the list of online users.
  1191. *
  1192. * @param array $user_list The list of users to be shown
  1193. * @param bool $wrap Whether we want the function to wrap the spans list in a div or not
  1194. *
  1195. * @return string HTML block or null if and ID was defined
  1196. * @assert (null) === false
  1197. */
  1198. public static function display_user_list($user_list, $wrap = true)
  1199. {
  1200. $html = '';
  1201. if (isset($_GET['id']) || count($user_list) < 1) {
  1202. return false;
  1203. }
  1204. $course_url = '';
  1205. if (isset($_GET['cidReq']) && strlen($_GET['cidReq']) > 0) {
  1206. $course_url = '&amp;cidReq='.Security::remove_XSS($_GET['cidReq']);
  1207. }
  1208. $hide = api_get_configuration_value('hide_complete_name_in_whoisonline');
  1209. foreach ($user_list as $uid) {
  1210. $user_info = api_get_user_info($uid, true);
  1211. $lastname = $user_info['lastname'];
  1212. $firstname = $user_info['firstname'];
  1213. $completeName = $firstname.', '.$lastname;
  1214. $user_rol = $user_info['status'] == 1 ? Display::return_icon('teacher.png', get_lang('Teacher'), null, ICON_SIZE_TINY) : Display::return_icon('user.png', get_lang('Student'), null, ICON_SIZE_TINY);
  1215. $status_icon_chat = null;
  1216. if (isset($user_info['user_is_online_in_chat']) && $user_info['user_is_online_in_chat'] == 1) {
  1217. $status_icon_chat = Display::return_icon('online.png', get_lang('Online'));
  1218. } else {
  1219. $status_icon_chat = Display::return_icon('offline.png', get_lang('Offline'));
  1220. }
  1221. $userPicture = $user_info['avatar'];
  1222. $officialCode = '';
  1223. if (api_get_setting('show_official_code_whoisonline') == 'true') {
  1224. $officialCode .= '<div class="items-user-official-code"><p style="min-height: 30px;" title="'.get_lang('OfficialCode').'">'.$user_info['official_code'].'</p></div>';
  1225. }
  1226. if ($hide === true) {
  1227. $completeName = '';
  1228. $firstname = '';
  1229. $lastname = '';
  1230. }
  1231. $img = '<img class="img-responsive img-circle" title="'.$completeName.'" alt="'.$completeName.'" src="'.$userPicture.'">';
  1232. $url = null;
  1233. // Anonymous users can't have access to the profile
  1234. if (!api_is_anonymous()) {
  1235. if (api_get_setting('allow_social_tool') === 'true') {
  1236. $url = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$uid.$course_url;
  1237. } else {
  1238. $url = '?id='.$uid.$course_url;
  1239. }
  1240. } else {
  1241. $url = null;
  1242. }
  1243. $name = '<a href="'.$url.'">'.$firstname.'<br>'.$lastname.'</a>';
  1244. $html .= '<div class="col-xs-6 col-md-2">
  1245. <div class="items-user">
  1246. <div class="items-user-avatar"><a href="'.$url.'">'.$img.'</a></div>
  1247. <div class="items-user-name">
  1248. '.$name.'
  1249. </div>
  1250. '.$officialCode.'
  1251. <div class="items-user-status">'.$status_icon_chat.' '.$user_rol.'</div>
  1252. </div>
  1253. </div>';
  1254. }
  1255. return $html;
  1256. }
  1257. /**
  1258. * Displays the information of an individual user.
  1259. *
  1260. * @param int $user_id
  1261. *
  1262. * @return string
  1263. */
  1264. public static function display_individual_user($user_id)
  1265. {
  1266. global $interbreadcrumb;
  1267. $safe_user_id = (int) $user_id;
  1268. $currentUserId = api_get_user_id();
  1269. $user_table = Database::get_main_table(TABLE_MAIN_USER);
  1270. $sql = "SELECT * FROM $user_table WHERE user_id = ".$safe_user_id;
  1271. $result = Database::query($sql);
  1272. $html = null;
  1273. if (Database::num_rows($result) == 1) {
  1274. $user_object = Database::fetch_object($result);
  1275. $userInfo = api_get_user_info($user_id);
  1276. $alt = $userInfo['complete_name'].($currentUserId == $user_id ? '&nbsp;('.get_lang('Me').')' : '');
  1277. $status = get_status_from_code($user_object->status);
  1278. $interbreadcrumb[] = ['url' => 'whoisonline.php', 'name' => get_lang('UsersOnLineList')];
  1279. $html .= '<div class ="thumbnail">';
  1280. $fullurl = $userInfo['avatar'];
  1281. $html .= '<img src="'.$fullurl.'" alt="'.$alt.'" />';
  1282. if (!empty($status)) {
  1283. $html .= '<div class="caption">'.$status.'</div>';
  1284. }
  1285. $html .= '</div>';
  1286. if (api_get_setting('show_email_addresses') == 'true') {
  1287. $html .= Display::encrypted_mailto_link($user_object->email, $user_object->email).'<br />';
  1288. }
  1289. if ($user_object->competences) {
  1290. $html .= Display::page_subheader(get_lang('MyCompetences'));
  1291. $html .= '<p>'.$user_object->competences.'</p>';
  1292. }
  1293. if ($user_object->diplomas) {
  1294. $html .= Display::page_subheader(get_lang('MyDiplomas'));
  1295. $html .= '<p>'.$user_object->diplomas.'</p>';
  1296. }
  1297. if ($user_object->teach) {
  1298. $html .= Display::page_subheader(get_lang('MyTeach'));
  1299. $html .= '<p>'.$user_object->teach.'</p>';
  1300. }
  1301. self::display_productions($user_object->user_id);
  1302. if ($user_object->openarea) {
  1303. $html .= Display::page_subheader(get_lang('MyPersonalOpenArea'));
  1304. $html .= '<p>'.$user_object->openarea.'</p>';
  1305. }
  1306. } else {
  1307. $html .= '<div class="actions-title">';
  1308. $html .= get_lang('UsersOnLineList');
  1309. $html .= '</div>';
  1310. }
  1311. return $html;
  1312. }
  1313. /**
  1314. * Display productions in who is online.
  1315. *
  1316. * @param int $user_id User id
  1317. */
  1318. public static function display_productions($user_id)
  1319. {
  1320. $webdir_array = UserManager::get_user_picture_path_by_id($user_id, 'web');
  1321. $sysdir = UserManager::getUserPathById($user_id, 'system');
  1322. $webdir = UserManager::getUserPathById($user_id, 'web');
  1323. if (!is_dir($sysdir)) {
  1324. mkdir($sysdir, api_get_permissions_for_new_directories(), true);
  1325. }
  1326. $productions = UserManager::get_user_productions($user_id);
  1327. if (count($productions) > 0) {
  1328. echo '<dt><strong>'.get_lang('Productions').'</strong></dt>';
  1329. echo '<dd><ul>';
  1330. foreach ($productions as $file) {
  1331. // Only display direct file links to avoid browsing an empty directory
  1332. if (is_file($sysdir.$file) && $file != $webdir_array['file']) {
  1333. echo '<li><a href="'.$webdir.urlencode($file).'" target=_blank>'.$file.'</a></li>';
  1334. }
  1335. // Real productions are under a subdirectory by the User's id
  1336. if (is_dir($sysdir.$file)) {
  1337. $subs = scandir($sysdir.$file);
  1338. foreach ($subs as $my => $sub) {
  1339. if (substr($sub, 0, 1) != '.' && is_file($sysdir.$file.'/'.$sub)) {
  1340. echo '<li><a href="'.$webdir.urlencode($file).'/'.urlencode($sub).'" target=_blank>'.$sub.'</a></li>';
  1341. }
  1342. }
  1343. }
  1344. }
  1345. echo '</ul></dd>';
  1346. }
  1347. }
  1348. /**
  1349. * @param string $content
  1350. * @param string $span_count
  1351. *
  1352. * @return string
  1353. */
  1354. public static function social_wrapper_div($content, $span_count)
  1355. {
  1356. $span_count = (int) $span_count;
  1357. $html = '<div class="span'.$span_count.'">';
  1358. $html .= '<div class="well_border">';
  1359. $html .= $content;
  1360. $html .= '</div></div>';
  1361. return $html;
  1362. }
  1363. /**
  1364. * Dummy function.
  1365. */
  1366. public static function get_plugins($place = SOCIAL_CENTER_PLUGIN)
  1367. {
  1368. $content = '';
  1369. switch ($place) {
  1370. case SOCIAL_CENTER_PLUGIN:
  1371. $social_plugins = [1, 2];
  1372. if (is_array($social_plugins) && count($social_plugins) > 0) {
  1373. $content .= '<div id="social-plugins">';
  1374. foreach ($social_plugins as $plugin) {
  1375. $content .= '<div class="social-plugin-item">';
  1376. $content .= $plugin;
  1377. $content .= '</div>';
  1378. }
  1379. $content .= '</div>';
  1380. }
  1381. break;
  1382. case SOCIAL_LEFT_PLUGIN:
  1383. break;
  1384. case SOCIAL_RIGHT_PLUGIN:
  1385. break;
  1386. }
  1387. return $content;
  1388. }
  1389. /**
  1390. * Sends a message to someone's wall.
  1391. *
  1392. * @param int $userId id of author
  1393. * @param int $friendId id where we send the message
  1394. * @param string $messageContent of the message
  1395. * @param int $messageId id parent
  1396. * @param string $messageStatus status type of message
  1397. *
  1398. * @return int
  1399. *
  1400. * @author Yannick Warnier
  1401. */
  1402. public static function sendWallMessage(
  1403. $userId,
  1404. $friendId,
  1405. $messageContent,
  1406. $messageId = 0,
  1407. $messageStatus = ''
  1408. ) {
  1409. $tblMessage = Database::get_main_table(TABLE_MESSAGE);
  1410. $userId = (int) $userId;
  1411. $friendId = (int) $friendId;
  1412. $messageId = (int) $messageId;
  1413. if (empty($userId) || empty($friendId)) {
  1414. return 0;
  1415. }
  1416. // Just in case we replace the and \n and \n\r while saving in the DB
  1417. $messageContent = str_replace(["\n", "\n\r"], '<br />', $messageContent);
  1418. $now = api_get_utc_datetime();
  1419. $attributes = [
  1420. 'user_sender_id' => $userId,
  1421. 'user_receiver_id' => $friendId,
  1422. 'msg_status' => $messageStatus,
  1423. 'send_date' => $now,
  1424. 'title' => '',
  1425. 'content' => $messageContent,
  1426. 'parent_id' => $messageId,
  1427. 'group_id' => 0,
  1428. 'update_date' => $now,
  1429. ];
  1430. return Database::insert($tblMessage, $attributes);
  1431. }
  1432. /**
  1433. * Send File attachment (jpg,png).
  1434. *
  1435. * @author Anibal Copitan
  1436. *
  1437. * @param int $userId id user
  1438. * @param array $fileAttach
  1439. * @param int $messageId id message (relation with main message)
  1440. * @param string $fileComment description attachment file
  1441. *
  1442. * @return bool|int
  1443. */
  1444. public static function sendWallMessageAttachmentFile(
  1445. $userId,
  1446. $fileAttach,
  1447. $messageId,
  1448. $fileComment = ''
  1449. ) {
  1450. $safeFileName = Database::escape_string($fileAttach['name']);
  1451. $extension = strtolower(substr(strrchr($safeFileName, '.'), 1));
  1452. $allowedTypes = api_get_supported_image_extensions();
  1453. $allowedTypes[] = 'mp4';
  1454. $allowedTypes[] = 'webm';
  1455. $allowedTypes[] = 'ogg';
  1456. if (in_array($extension, $allowedTypes)) {
  1457. return MessageManager::saveMessageAttachmentFile($fileAttach, $fileComment, $messageId, $userId);
  1458. }
  1459. return false;
  1460. }
  1461. /**
  1462. * Gets all messages from someone's wall (within specific limits).
  1463. *
  1464. * @param int $userId id of wall shown
  1465. * @param int|string $parentId id message (Post main)
  1466. * @param int|array $groupId
  1467. * @param int|array $friendId
  1468. * @param string $startDate Date from which we want to show the messages, in UTC time
  1469. * @param int $start Limit for the number of parent messages we want to show
  1470. * @param int $length Wall message query offset
  1471. * @param bool $getCount
  1472. * @param array $threadList
  1473. *
  1474. * @return array|int
  1475. *
  1476. * @author Yannick Warnier
  1477. */
  1478. public static function getWallMessages(
  1479. $userId,
  1480. $parentId = 0,
  1481. $groupId = 0,
  1482. $friendId = 0,
  1483. $startDate = '',
  1484. $start = 0,
  1485. $length = 10,
  1486. $getCount = false,
  1487. $threadList = []
  1488. ) {
  1489. $tblMessage = Database::get_main_table(TABLE_MESSAGE);
  1490. $parentId = (int) $parentId;
  1491. $userId = (int) $userId;
  1492. $start = (int) $start;
  1493. $length = (int) $length;
  1494. $startDate = Database::escape_string($startDate);
  1495. $select = " SELECT
  1496. id,
  1497. user_sender_id,
  1498. user_receiver_id,
  1499. send_date,
  1500. content,
  1501. parent_id,
  1502. msg_status,
  1503. group_id,
  1504. '' as forum_id,
  1505. '' as thread_id,
  1506. '' as c_id
  1507. ";
  1508. if ($getCount) {
  1509. $select = ' SELECT count(id) count ';
  1510. }
  1511. $sql = "$select
  1512. FROM $tblMessage tm
  1513. WHERE
  1514. msg_status <> ".MESSAGE_STATUS_WALL_DELETE.' AND ';
  1515. // My own posts
  1516. $userReceiverCondition = ' (
  1517. user_receiver_id = '.$userId.' AND
  1518. msg_status IN ('.MESSAGE_STATUS_WALL_POST.', '.MESSAGE_STATUS_WALL.') AND
  1519. parent_id = '.$parentId.'
  1520. )';
  1521. // User condition
  1522. $sql .= $userReceiverCondition;
  1523. // Get my group posts
  1524. $groupCondition = '';
  1525. if (!empty($groupId)) {
  1526. if (is_array($groupId)) {
  1527. $groupId = array_map('intval', $groupId);
  1528. $groupId = implode("','", $groupId);
  1529. $groupCondition = " OR ( group_id IN ('$groupId') ";
  1530. } else {
  1531. $groupId = (int) $groupId;
  1532. $groupCondition = " OR ( group_id = '$groupId' ";
  1533. }
  1534. $groupCondition .= ' AND msg_status IN ('.MESSAGE_STATUS_NEW.', '.MESSAGE_STATUS_UNREAD.')) ';
  1535. }
  1536. $friendCondition = '';
  1537. // Get my friend posts
  1538. if (!empty($friendId)) {
  1539. if (is_array($friendId)) {
  1540. $friendId = array_map('intval', $friendId);
  1541. $friendId = implode("','", $friendId);
  1542. $friendCondition = " OR ( user_receiver_id IN ('$friendId') ";
  1543. } else {
  1544. $friendId = (int) $friendId;
  1545. $friendCondition = " OR ( user_receiver_id = '$friendId' ";
  1546. }
  1547. $friendCondition .= ' AND msg_status IN ('.MESSAGE_STATUS_WALL_POST.') AND parent_id = 0) ';
  1548. }
  1549. if (!empty($groupCondition) || !empty($friendCondition)) {
  1550. $sql .= " $groupCondition $friendCondition ";
  1551. }
  1552. if (!empty($threadList)) {
  1553. if ($getCount) {
  1554. $select = ' SELECT count(iid) count ';
  1555. } else {
  1556. $select = " SELECT
  1557. iid,
  1558. poster_id,
  1559. '' as user_receiver_id,
  1560. post_date,
  1561. post_text,
  1562. '' as parent_id,
  1563. ".MESSAGE_STATUS_FORUM.",
  1564. '' as group_id,
  1565. forum_id,
  1566. thread_id,
  1567. c_id
  1568. ";
  1569. }
  1570. $threadList = array_map('intval', $threadList);
  1571. $threadList = implode("','", $threadList);
  1572. $condition = " thread_id IN ('$threadList') ";
  1573. $sql .= "
  1574. UNION (
  1575. $select
  1576. FROM c_forum_post
  1577. WHERE $condition
  1578. )
  1579. ";
  1580. }
  1581. if ($getCount) {
  1582. $res = Database::query($sql);
  1583. $row = Database::fetch_array($res);
  1584. return (int) $row['count'];
  1585. }
  1586. $sql .= ' ORDER BY send_date DESC ';
  1587. $sql .= " LIMIT $start, $length ";
  1588. $messages = [];
  1589. $res = Database::query($sql);
  1590. $em = Database::getManager();
  1591. if (Database::num_rows($res) > 0) {
  1592. $repo = $em->getRepository('ChamiloCourseBundle:CForumPost');
  1593. $repoThread = $em->getRepository('ChamiloCourseBundle:CForumThread');
  1594. $groups = [];
  1595. $forums = [];
  1596. $userGroup = new UserGroup();
  1597. $urlGroup = api_get_path(WEB_CODE_PATH).'social/group_view.php?id=';
  1598. while ($row = Database::fetch_array($res, 'ASSOC')) {
  1599. $row['group_info'] = [];
  1600. if (!empty($row['group_id'])) {
  1601. if (!in_array($row['group_id'], $groups)) {
  1602. $group = $userGroup->get($row['group_id']);
  1603. $group['url'] = $urlGroup.$group['id'];
  1604. $groups[$row['group_id']] = $group;
  1605. $row['group_info'] = $group;
  1606. } else {
  1607. $row['group_info'] = $groups[$row['group_id']];
  1608. }
  1609. }
  1610. // forums
  1611. $row['post_title'] = '';
  1612. $row['forum_title'] = '';
  1613. $row['thread_url'] = '';
  1614. if ($row['msg_status'] == MESSAGE_STATUS_FORUM) {
  1615. /** @var \Chamilo\CourseBundle\Entity\CForumPost $post */
  1616. $post = $repo->find($row['id']);
  1617. /** @var \Chamilo\CourseBundle\Entity\CForumThread $thread */
  1618. $thread = $repoThread->find($row['thread_id']);
  1619. if ($post && $thread) {
  1620. $courseInfo = api_get_course_info_by_id($post->getCId());
  1621. $row['post_title'] = $post->getForumId();
  1622. $row['forum_title'] = $thread->getThreadTitle();
  1623. $row['thread_url'] = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.http_build_query([
  1624. 'cidReq' => $courseInfo['code'],
  1625. 'forum' => $post->getForumId(),
  1626. 'thread' => $post->getThreadId(),
  1627. 'post_id' => $post->getIid(),
  1628. ]).'#post_id_'.$post->getIid();
  1629. }
  1630. }
  1631. $messages[] = $row;
  1632. }
  1633. }
  1634. return $messages;
  1635. }
  1636. /**
  1637. * Gets all messages from someone's wall (within specific limits), formatted.
  1638. *
  1639. * @param int $userId USER ID of the person's wall
  1640. * @param array $messageInfo
  1641. * @param string $start Start date (from when we want the messages until today)
  1642. * @param int $limit Limit to the number of messages we want
  1643. * @param int $offset Wall messages offset
  1644. *
  1645. * @return string HTML formatted string to show messages
  1646. */
  1647. public static function getWallPostComments(
  1648. $userId,
  1649. $messageInfo,
  1650. $start = null,
  1651. $limit = 10,
  1652. $offset = 0
  1653. ) {
  1654. $messageId = $messageInfo['id'];
  1655. $messages = MessageManager::getMessagesByParent($messageInfo['id'], 0, $offset, $limit);
  1656. $formattedList = '<div class="sub-mediapost row">';
  1657. $users = [];
  1658. // The messages are ordered by date descendant, for comments we need ascendant
  1659. krsort($messages);
  1660. foreach ($messages as $message) {
  1661. $userIdLoop = $message['user_sender_id'];
  1662. if (!isset($users[$userIdLoop])) {
  1663. $users[$userIdLoop] = api_get_user_info($userIdLoop);
  1664. }
  1665. $media = self::processPostComment($message, $users);
  1666. $formattedList .= $media;
  1667. }
  1668. $formattedList .= '</div>';
  1669. $formattedList .= '<div class="mediapost-form">';
  1670. $formattedList .= '<form class="form-horizontal" id="form_comment_'.$messageId.'" name="post_comment" method="POST">
  1671. <div class="col-sm-9">
  1672. <label for="comment" class="hide">'.get_lang('SocialWriteNewComment').'</label>
  1673. <input type="hidden" name = "messageId" value="'.$messageId.'" />
  1674. <textarea rows="3" class="form-control" placeholder="'.get_lang('SocialWriteNewComment').'" name="comment" rows="1" ></textarea>
  1675. </div>
  1676. <div class="col-sm-3">
  1677. <a onclick="submitComment('.$messageId.');" href="javascript:void(0);" name="social_wall_new_msg_submit" class="btn btn-default btn-post">
  1678. <em class="fa fa-pencil"></em> '.get_lang('Post').'
  1679. </a>
  1680. </div>
  1681. </form>';
  1682. $formattedList .= '</div>';
  1683. return $formattedList;
  1684. }
  1685. /**
  1686. * @param array $message
  1687. * @param array $users
  1688. *
  1689. * @return string
  1690. */
  1691. public static function processPostComment($message, $users = [])
  1692. {
  1693. if (empty($message)) {
  1694. return false;
  1695. }
  1696. $date = Display::dateToStringAgoAndLongDate($message['send_date']);
  1697. $currentUserId = api_get_user_id();
  1698. $userIdLoop = $message['user_sender_id'];
  1699. $receiverId = $message['user_receiver_id'];
  1700. if (!isset($users[$userIdLoop])) {
  1701. $users[$userIdLoop] = api_get_user_info($userIdLoop);
  1702. }
  1703. $iconStatus = $users[$userIdLoop]['icon_status'];
  1704. $nameComplete = $users[$userIdLoop]['complete_name'];
  1705. $url = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$userIdLoop;
  1706. $comment = '<div class="rep-post col-md-12">';
  1707. $comment .= '<div class="col-md-2 col-xs-2 social-post-answers">';
  1708. $comment .= '<div class="user-image pull-right">';
  1709. $comment .= '<a href="'.$url.'">
  1710. <img src="'.$users[$userIdLoop]['avatar'].'"
  1711. alt="'.$users[$userIdLoop]['complete_name'].'"
  1712. class="avatar-thumb">
  1713. </a>';
  1714. $comment .= '</div>';
  1715. $comment .= '</div>';
  1716. $comment .= '<div class="col-md-7 col-xs-7 social-post-answers">';
  1717. $comment .= '<div class="user-data">';
  1718. $comment .= $iconStatus;
  1719. $comment .= '<div class="username"><a href="'.$url.'">'.$nameComplete.'</a>
  1720. <span>'.Security::remove_XSS($message['content']).'</span>
  1721. </div>';
  1722. $comment .= '<div>'.$date.'</div>';
  1723. $comment .= '<br />';
  1724. $comment .= '</div>';
  1725. $comment .= '</div>';
  1726. $comment .= '<div class="col-md-3 col-xs-3 social-post-answers">';
  1727. $comment .= '<div class="pull-right btn-group btn-group-sm">';
  1728. $comment .= MessageManager::getLikesButton(
  1729. $message['id'],
  1730. $currentUserId
  1731. );
  1732. $isOwnWall = $currentUserId == $userIdLoop || $currentUserId == $receiverId;
  1733. if ($isOwnWall) {
  1734. $comment .= Display::url(
  1735. Display::returnFontAwesomeIcon('trash', '', true),
  1736. 'javascript:void(0)',
  1737. [
  1738. 'id' => 'message_'.$message['id'],
  1739. 'title' => get_lang('SocialMessageDelete'),
  1740. 'onclick' => 'deleteComment('.$message['id'].')',
  1741. 'class' => 'btn btn-default',
  1742. ]
  1743. );
  1744. }
  1745. $comment .= '</div>';
  1746. $comment .= '</div>';
  1747. $comment .= '</div>';
  1748. return $comment;
  1749. }
  1750. /**
  1751. * @param array $message
  1752. *
  1753. * @return array
  1754. */
  1755. public static function getAttachmentPreviewList($message)
  1756. {
  1757. $messageId = $message['id'];
  1758. $list = [];
  1759. if (empty($message['group_id'])) {
  1760. $files = MessageManager::getAttachmentList($messageId);
  1761. if ($files) {
  1762. $downloadUrl = api_get_path(WEB_CODE_PATH).'social/download.php?message_id='.$messageId;
  1763. foreach ($files as $row_file) {
  1764. $url = $downloadUrl.'&attachment_id='.$row_file['id'];
  1765. $display = Display::fileHtmlGuesser($row_file['filename'], $url);
  1766. $list[] = $display;
  1767. }
  1768. }
  1769. } else {
  1770. $list = MessageManager::getAttachmentLinkList($messageId);
  1771. }
  1772. return $list;
  1773. }
  1774. /**
  1775. * @param array $message
  1776. *
  1777. * @return string
  1778. */
  1779. public static function getPostAttachment($message)
  1780. {
  1781. $previews = self::getAttachmentPreviewList($message);
  1782. if (empty($previews)) {
  1783. return '';
  1784. }
  1785. return implode('', $previews);
  1786. }
  1787. /**
  1788. * @param array $messages
  1789. *
  1790. * @return array
  1791. */
  1792. public static function formatWallMessages($messages)
  1793. {
  1794. $data = [];
  1795. $users = [];
  1796. foreach ($messages as $key => $message) {
  1797. $userIdLoop = $message['user_sender_id'];
  1798. $userFriendIdLoop = $message['user_receiver_id'];
  1799. if (!isset($users[$userIdLoop])) {
  1800. $users[$userIdLoop] = api_get_user_info($userIdLoop);
  1801. }
  1802. if (!isset($users[$userFriendIdLoop])) {
  1803. $users[$userFriendIdLoop] = api_get_user_info($userFriendIdLoop);
  1804. }
  1805. $html = self::headerMessagePost(
  1806. $users[$userIdLoop],
  1807. $users[$userFriendIdLoop],
  1808. $message
  1809. );
  1810. $data[$key] = $message;
  1811. $data[$key]['html'] = $html;
  1812. }
  1813. return $data;
  1814. }
  1815. /**
  1816. * get html data with OpenGrap passing the URL.
  1817. *
  1818. * @param $link url
  1819. *
  1820. * @return string data html
  1821. */
  1822. public static function readContentWithOpenGraph($link)
  1823. {
  1824. if (strpos($link, "://") === false && substr($link, 0, 1) != "/") {
  1825. $link = "http://".$link;
  1826. }
  1827. $graph = OpenGraph::fetch($link);
  1828. $link = parse_url($link);
  1829. $host = $link['host'] ? strtoupper($link['host']) : $link['path'];
  1830. if (!$graph) {
  1831. return false;
  1832. }
  1833. $url = $graph->url;
  1834. $image = $graph->image;
  1835. $description = $graph->description;
  1836. $title = $graph->title;
  1837. $html = '<div class="thumbnail social-thumbnail">';
  1838. $html .= empty($image) ? '' : '<a target="_blank" href="'.$url.'">
  1839. <img class="img-responsive social-image" src="'.$image.'" /></a>';
  1840. $html .= '<div class="social-description">';
  1841. $html .= '<a target="_blank" href="'.$url.'"><h5 class="social-title"><b>'.$title.'</b></h5></a>';
  1842. $html .= empty($description) ? '' : '<span>'.$description.'</span>';
  1843. $html .= empty($host) ? '' : '<p>'.$host.'</p>';
  1844. $html .= '</div>';
  1845. $html .= '</div>';
  1846. return $html;
  1847. }
  1848. /**
  1849. * verify if Url Exist - Using Curl.
  1850. *
  1851. * @param $uri url
  1852. *
  1853. * @return bool
  1854. */
  1855. public static function verifyUrl($uri)
  1856. {
  1857. $curl = curl_init($uri);
  1858. curl_setopt($curl, CURLOPT_FAILONERROR, true);
  1859. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  1860. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  1861. curl_setopt($curl, CURLOPT_TIMEOUT, 15);
  1862. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  1863. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  1864. curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
  1865. $response = curl_exec($curl);
  1866. curl_close($curl);
  1867. if (!empty($response)) {
  1868. return true;
  1869. }
  1870. return false;
  1871. }
  1872. /**
  1873. * Soft delete a message and his chidren.
  1874. *
  1875. * @param int $id id message to delete
  1876. *
  1877. * @return bool status query
  1878. */
  1879. public static function deleteMessage($id)
  1880. {
  1881. $id = (int) $id;
  1882. $messageInfo = MessageManager::get_message_by_id($id);
  1883. if (!empty($messageInfo)) {
  1884. // Delete comments too
  1885. $messages = MessageManager::getMessagesByParent($id);
  1886. if (!empty($messages)) {
  1887. foreach ($messages as $message) {
  1888. self::deleteMessage($message['id']);
  1889. }
  1890. }
  1891. // Soft delete message
  1892. $tblMessage = Database::get_main_table(TABLE_MESSAGE);
  1893. $statusMessage = MESSAGE_STATUS_WALL_DELETE;
  1894. $sql = "UPDATE $tblMessage SET msg_status = '$statusMessage' WHERE id = '{$id}' ";
  1895. Database::query($sql);
  1896. MessageManager::delete_message_attachment_file($id, $messageInfo['user_sender_id']);
  1897. MessageManager::delete_message_attachment_file($id, $messageInfo['user_receiver_id']);
  1898. return true;
  1899. }
  1900. return false;
  1901. }
  1902. /**
  1903. * Generate the social block for a user.
  1904. *
  1905. * @param Template $template
  1906. * @param int $userId The user id
  1907. * @param string $groupBlock Optional. Highlight link possible values:
  1908. * group_add, home, messages, messages_inbox, messages_compose,
  1909. * messages_outbox, invitations, shared_profile, friends, groups, search
  1910. * @param int $groupId Optional. Group ID
  1911. * @param bool $show_full_profile
  1912. *
  1913. * @return string The HTML code with the social block
  1914. */
  1915. public static function setSocialUserBlock(
  1916. Template $template,
  1917. $userId,
  1918. $groupBlock = '',
  1919. $groupId = 0,
  1920. $show_full_profile = true
  1921. ) {
  1922. if (api_get_setting('allow_social_tool') != 'true') {
  1923. return '';
  1924. }
  1925. $currentUserId = api_get_user_id();
  1926. $userId = (int) $userId;
  1927. $userRelationType = 0;
  1928. $socialAvatarBlock = self::show_social_avatar_block(
  1929. $groupBlock,
  1930. $groupId,
  1931. $userId
  1932. );
  1933. $profileEditionLink = null;
  1934. if ($currentUserId === $userId) {
  1935. $profileEditionLink = Display::getProfileEditionLink($userId);
  1936. } else {
  1937. $userRelationType = self::get_relation_between_contacts($currentUserId, $userId);
  1938. }
  1939. $options = api_get_configuration_value('profile_fields_visibility');
  1940. if (isset($options['options'])) {
  1941. $options = $options['options'];
  1942. }
  1943. $vCardUserLink = Display::getVCardUserLink($userId);
  1944. if (isset($options['vcard']) && $options['vcard'] === false) {
  1945. $vCardUserLink = '';
  1946. }
  1947. $userInfo = api_get_user_info($userId, true, false, true, true);
  1948. if (isset($options['firstname']) && $options['firstname'] === false) {
  1949. $userInfo['firstname'] = '';
  1950. }
  1951. if (isset($options['lastname']) && $options['lastname'] === false) {
  1952. $userInfo['lastname'] = '';
  1953. }
  1954. if (isset($options['email']) && $options['email'] === false) {
  1955. $userInfo['email'] = '';
  1956. }
  1957. // Ofaj
  1958. $hasCertificates = Certificate::getCertificateByUser($userId);
  1959. $userInfo['has_certificates'] = 0;
  1960. if (!empty($hasCertificates)) {
  1961. $userInfo['has_certificates'] = 1;
  1962. }
  1963. $userInfo['is_admin'] = UserManager::is_admin($userId);
  1964. $languageId = api_get_language_id($userInfo['language']);
  1965. $languageInfo = api_get_language_info($languageId);
  1966. if ($languageInfo) {
  1967. $userInfo['language'] = [
  1968. 'label' => $languageInfo['original_name'],
  1969. 'value' => $languageInfo['english_name'],
  1970. 'code' => $languageInfo['isocode'],
  1971. ];
  1972. }
  1973. if (isset($options['language']) && $options['language'] === false) {
  1974. $userInfo['language'] = '';
  1975. }
  1976. if (isset($options['photo']) && $options['photo'] === false) {
  1977. $socialAvatarBlock = '';
  1978. }
  1979. $extraFieldBlock = self::getExtraFieldBlock($userId, true);
  1980. $showLanguageFlag = api_get_configuration_value('social_show_language_flag_in_profile');
  1981. $template->assign('user', $userInfo);
  1982. $template->assign('show_language_flag', $showLanguageFlag);
  1983. $template->assign('extra_info', $extraFieldBlock);
  1984. $template->assign('social_avatar_block', $socialAvatarBlock);
  1985. $template->assign('profile_edition_link', $profileEditionLink);
  1986. //Added the link to export the vCard to the Template
  1987. //If not friend $show_full_profile is False and the user can't see Email Address and Vcard Download Link
  1988. if ($show_full_profile) {
  1989. $template->assign('vcard_user_link', $vCardUserLink);
  1990. }
  1991. if (api_get_setting('gamification_mode') === '1') {
  1992. $gamificationPoints = GamificationUtils::getTotalUserPoints(
  1993. $userId,
  1994. $userInfo['status']
  1995. );
  1996. $template->assign('gamification_points', $gamificationPoints);
  1997. }
  1998. $chatEnabled = api_is_global_chat_enabled();
  1999. if (isset($options['chat']) && $options['chat'] === false) {
  2000. $chatEnabled = '';
  2001. }
  2002. $template->assign('chat_enabled', $chatEnabled);
  2003. $template->assign('user_relation', $userRelationType);
  2004. $template->assign('user_relation_type_friend', USER_RELATION_TYPE_FRIEND);
  2005. $template->assign('show_full_profile', $show_full_profile);
  2006. $templateName = $template->get_template('social/user_block.tpl');
  2007. if (in_array($groupBlock, ['groups', 'group_edit', 'member_list'])) {
  2008. $templateName = $template->get_template('social/group_block.tpl');
  2009. }
  2010. $template->assign('social_avatar_block', $template->fetch($templateName));
  2011. }
  2012. /**
  2013. * @param int $user_id
  2014. * @param $link_shared
  2015. * @param $show_full_profile
  2016. *
  2017. * @return string
  2018. */
  2019. public static function listMyFriends($user_id, $link_shared, $show_full_profile)
  2020. {
  2021. // SOCIALGOODFRIEND , USER_RELATION_TYPE_FRIEND, USER_RELATION_TYPE_PARENT
  2022. $friends = self::get_friends($user_id, USER_RELATION_TYPE_FRIEND);
  2023. $number_of_images = 30;
  2024. $number_friends = count($friends);
  2025. $friendHtml = '';
  2026. if ($number_friends != 0) {
  2027. if ($number_friends > $number_of_images) {
  2028. if (api_get_user_id() == $user_id) {
  2029. $friendHtml .= ' <span><a href="friends.php">'.get_lang('SeeAll').'</a></span>';
  2030. } else {
  2031. $friendHtml .= ' <span>'
  2032. .'<a href="'.api_get_path(WEB_CODE_PATH).'social/profile_friends_and_groups.inc.php'
  2033. .'?view=friends&height=390&width=610&user_id='.$user_id.'"'
  2034. .'class="ajax" data-title="'.get_lang('SeeAll').'" title="'.get_lang('SeeAll').'" >'.get_lang('SeeAll').'</a></span>';
  2035. }
  2036. }
  2037. $friendHtml .= '<ul class="nav nav-list">';
  2038. $j = 1;
  2039. for ($k = 0; $k < $number_friends; $k++) {
  2040. if ($j > $number_of_images) {
  2041. break;
  2042. }
  2043. if (isset($friends[$k])) {
  2044. $friend = $friends[$k];
  2045. $name_user = api_get_person_name($friend['firstName'], $friend['lastName']);
  2046. $user_info_friend = api_get_user_info($friend['friend_user_id'], true);
  2047. if ($user_info_friend['user_is_online']) {
  2048. $statusIcon = Display::span('', ['class' => 'online_user_in_text']);
  2049. } else {
  2050. $statusIcon = Display::span('', ['class' => 'offline_user_in_text']);
  2051. }
  2052. $friendHtml .= '<li>';
  2053. $friendHtml .= '<div>';
  2054. // the height = 92 must be the same in the image_friend_network span style in default.css
  2055. $friends_profile = UserManager::getUserPicture(
  2056. $friend['friend_user_id'],
  2057. USER_IMAGE_SIZE_SMALL
  2058. );
  2059. $friendHtml .= '<img src="'.$friends_profile.'" id="imgfriend_'.$friend['friend_user_id'].'" title="'.$name_user.'"/>';
  2060. $link_shared = (empty($link_shared)) ? '' : '&'.$link_shared;
  2061. $friendHtml .= $statusIcon.'<a href="profile.php?'.'u='.$friend['friend_user_id'].$link_shared.'">'.$name_user.'</a>';
  2062. $friendHtml .= '</div>';
  2063. $friendHtml .= '</li>';
  2064. }
  2065. $j++;
  2066. }
  2067. $friendHtml .= '</ul>';
  2068. } else {
  2069. $friendHtml .= '<div class="">'.get_lang('NoFriendsInYourContactList').'<br />
  2070. <a class="btn btn-primary" href="'.api_get_path(WEB_PATH).'whoisonline.php">
  2071. <em class="fa fa-search"></em> '.get_lang('TryAndFindSomeFriends').'</a></div>';
  2072. }
  2073. $friendHtml = Display::panel($friendHtml, get_lang('SocialFriend').' ('.$number_friends.')');
  2074. return $friendHtml;
  2075. }
  2076. /**
  2077. * @param int $user_id
  2078. * @param $link_shared
  2079. * @param bool $showLinkToChat
  2080. *
  2081. * @return string
  2082. */
  2083. public static function listMyFriendsBlock($user_id, $link_shared = '', $showLinkToChat = false)
  2084. {
  2085. //SOCIALGOODFRIEND , USER_RELATION_TYPE_FRIEND, USER_RELATION_TYPE_PARENT
  2086. $friends = self::get_friends($user_id, USER_RELATION_TYPE_FRIEND);
  2087. $numberFriends = count($friends);
  2088. $friendHtml = '';
  2089. if (!empty($numberFriends)) {
  2090. $friendHtml .= '<div class="list-group contact-list">';
  2091. $j = 1;
  2092. usort(
  2093. $friends,
  2094. function ($a, $b) {
  2095. return strcmp($b['user_info']['user_is_online_in_chat'], $a['user_info']['user_is_online_in_chat']);
  2096. }
  2097. );
  2098. foreach ($friends as $friend) {
  2099. if ($j > $numberFriends) {
  2100. break;
  2101. }
  2102. $name_user = api_get_person_name($friend['firstName'], $friend['lastName']);
  2103. $user_info_friend = api_get_user_info($friend['friend_user_id'], true);
  2104. $statusIcon = Display::return_icon('statusoffline.png', get_lang('Offline'));
  2105. $status = 0;
  2106. if (!empty($user_info_friend['user_is_online_in_chat'])) {
  2107. $statusIcon = Display::return_icon('statusonline.png', get_lang('Online'));
  2108. $status = 1;
  2109. }
  2110. $friendAvatarMedium = UserManager::getUserPicture(
  2111. $friend['friend_user_id'],
  2112. USER_IMAGE_SIZE_MEDIUM
  2113. );
  2114. $friendAvatarSmall = UserManager::getUserPicture(
  2115. $friend['friend_user_id'],
  2116. USER_IMAGE_SIZE_SMALL
  2117. );
  2118. $friend_avatar = '<img src="'.$friendAvatarMedium.'" id="imgfriend_'.$friend['friend_user_id'].'" title="'.$name_user.'" class="user-image"/>';
  2119. $relation = self::get_relation_between_contacts(
  2120. $friend['friend_user_id'],
  2121. api_get_user_id()
  2122. );
  2123. if ($showLinkToChat) {
  2124. $friendHtml .= '<a onclick="javascript:chatWith(\''.$friend['friend_user_id'].'\', \''.$name_user.'\', \''.$status.'\',\''.$friendAvatarSmall.'\')" href="javascript:void(0);" class="list-group-item">';
  2125. $friendHtml .= $friend_avatar.' <span class="username">'.$name_user.'</span>';
  2126. $friendHtml .= '<span class="status">'.$statusIcon.'</span>';
  2127. } else {
  2128. $link_shared = empty($link_shared) ? '' : '&'.$link_shared;
  2129. $friendHtml .= '<a href="profile.php?'.'u='.$friend['friend_user_id'].$link_shared.'" class="list-group-item">';
  2130. $friendHtml .= $friend_avatar.' <span class="username">'.$name_user.'</span>';
  2131. $friendHtml .= '<span class="status">'.$statusIcon.'</span>';
  2132. }
  2133. $friendHtml .= '</a>';
  2134. $j++;
  2135. }
  2136. $friendHtml .= '</div>';
  2137. } else {
  2138. $friendHtml = Display::return_message(get_lang('NoFriendsInYourContactList'), 'warning');
  2139. }
  2140. return $friendHtml;
  2141. }
  2142. /**
  2143. * @return string Get the JS code necessary for social wall to load open graph from URLs.
  2144. */
  2145. public static function getScriptToGetOpenGraph()
  2146. {
  2147. return '<script>
  2148. $(function() {
  2149. $("[name=\'social_wall_new_msg_main\']").on("paste", function(e) {
  2150. $.ajax({
  2151. contentType: "application/x-www-form-urlencoded",
  2152. beforeSend: function() {
  2153. $("[name=\'wall_post_button\']").prop( "disabled", true );
  2154. $(".panel-preview").hide();
  2155. $(".spinner").html("'
  2156. .'<div class=\'text-center\'>'
  2157. .'<em class=\'fa fa-spinner fa-pulse fa-1x\'></em>'
  2158. .'<p>'.get_lang('Loading').' '.get_lang('Preview').'</p>'
  2159. .'</div>'
  2160. .'");
  2161. },
  2162. type: "POST",
  2163. url: "'.api_get_path(WEB_AJAX_PATH).'social.ajax.php?a=read_url_with_open_graph",
  2164. data: "social_wall_new_msg_main=" + e.originalEvent.clipboardData.getData("text"),
  2165. success: function(response) {
  2166. $("[name=\'wall_post_button\']").prop("disabled", false);
  2167. if (!response == false) {
  2168. $(".spinner").html("");
  2169. $(".panel-preview").show();
  2170. $(".url_preview").html(response);
  2171. $("[name=\'url_content\']").val(response);
  2172. $(".url_preview img").addClass("img-responsive");
  2173. } else {
  2174. $(".spinner").html("");
  2175. }
  2176. }
  2177. });
  2178. });
  2179. });
  2180. </script>';
  2181. }
  2182. /**
  2183. * @param string $urlForm
  2184. *
  2185. * @return string
  2186. */
  2187. public static function getWallForm($urlForm)
  2188. {
  2189. $userId = isset($_GET['u']) ? '?u='.intval($_GET['u']) : '';
  2190. $form = new FormValidator(
  2191. 'social_wall_main',
  2192. 'post',
  2193. $urlForm.$userId,
  2194. null,
  2195. ['enctype' => 'multipart/form-data'],
  2196. FormValidator::LAYOUT_HORIZONTAL
  2197. );
  2198. $socialWallPlaceholder = isset($_GET['u']) ? get_lang('SocialWallWriteNewPostToFriend') : get_lang(
  2199. 'SocialWallWhatAreYouThinkingAbout'
  2200. );
  2201. $form->addTextarea(
  2202. 'social_wall_new_msg_main',
  2203. null,
  2204. [
  2205. 'placeholder' => $socialWallPlaceholder,
  2206. 'cols-size' => [1, 10, 1],
  2207. 'aria-label' => $socialWallPlaceholder,
  2208. ]
  2209. );
  2210. $form->addHtml('<div class="form-group">');
  2211. $form->addHtml('<div class="col-sm-4 col-md-offset-1">');
  2212. $form->addFile('picture', get_lang('UploadFile'), ['custom' => true]);
  2213. $form->addHtml('</div>');
  2214. $form->addHtml('<div class="col-sm-6">');
  2215. $form->addButtonSend(
  2216. get_lang('Post'),
  2217. 'wall_post_button',
  2218. false,
  2219. [
  2220. 'cols-size' => [1, 10, 1],
  2221. 'custom' => true,
  2222. ]
  2223. );
  2224. $form->addHtml('</div>');
  2225. $form->addHtml('</div>');
  2226. $form->addHidden('url_content', '');
  2227. $html = Display::panel($form->returnForm(), get_lang('SocialWall'));
  2228. return $html;
  2229. }
  2230. /**
  2231. * @param int $userId
  2232. * @param int $start
  2233. * @param int $length
  2234. * @param array $threadList
  2235. *
  2236. * @return array
  2237. */
  2238. public static function getMyWallMessages($userId, $start = 0, $length = 10, $threadList = [])
  2239. {
  2240. $userGroup = new UserGroup();
  2241. $groups = $userGroup->get_groups_by_user($userId, [GROUP_USER_PERMISSION_READER, GROUP_USER_PERMISSION_ADMIN]);
  2242. $groupList = [];
  2243. if (!empty($groups)) {
  2244. $groupList = array_column($groups, 'id');
  2245. }
  2246. $friends = self::get_friends($userId, USER_RELATION_TYPE_FRIEND);
  2247. $friendList = [];
  2248. if (!empty($friends)) {
  2249. $friendList = array_column($friends, 'friend_user_id');
  2250. }
  2251. $messages = self::getWallMessages(
  2252. $userId,
  2253. 0,
  2254. $groupList,
  2255. $friendList,
  2256. '',
  2257. $start,
  2258. $length,
  2259. false,
  2260. $threadList
  2261. );
  2262. $countPost = self::getCountWallMessagesByUser($userId, $groupList, $friendList, $threadList);
  2263. $messages = self::formatWallMessages($messages);
  2264. $html = '';
  2265. foreach ($messages as $message) {
  2266. $post = $message['html'];
  2267. $comments = '';
  2268. if ($message['msg_status'] == MESSAGE_STATUS_WALL_POST) {
  2269. $comments = self::getWallPostComments($userId, $message);
  2270. }
  2271. $html .= self::wrapPost($message, $post.$comments);
  2272. }
  2273. return [
  2274. 'posts' => $html,
  2275. 'count' => $countPost,
  2276. ];
  2277. }
  2278. /**
  2279. * @param string $message
  2280. * @param string $content
  2281. *
  2282. * @return string
  2283. */
  2284. public static function wrapPost($message, $content)
  2285. {
  2286. return Display::panel($content, '',
  2287. '',
  2288. 'default',
  2289. '',
  2290. 'post_'.$message['id']
  2291. );
  2292. }
  2293. /**
  2294. * @param int $userId
  2295. *
  2296. * @return int
  2297. */
  2298. public static function getCountWallMessagesByUser($userId, $groupList = [], $friendList = [], $threadList = [])
  2299. {
  2300. $count = self::getWallMessages(
  2301. $userId,
  2302. 0,
  2303. $groupList,
  2304. $friendList,
  2305. '',
  2306. 0,
  2307. 0,
  2308. true,
  2309. $threadList
  2310. );
  2311. return $count;
  2312. }
  2313. /**
  2314. * @param int $userId
  2315. *
  2316. * @return string
  2317. */
  2318. public static function getWallMessagesByUser($userId)
  2319. {
  2320. $messages = self::getWallMessages($userId);
  2321. $messages = self::formatWallMessages($messages);
  2322. $html = '';
  2323. foreach ($messages as $message) {
  2324. $post = $message['html'];
  2325. $comments = self::getWallPostComments($userId, $message);
  2326. $html .= self::wrapPost($message, $post.$comments);
  2327. }
  2328. return $html;
  2329. }
  2330. /**
  2331. * Get HTML code block for user skills.
  2332. *
  2333. * @param int $userId The user ID
  2334. * @param string $orientation
  2335. *
  2336. * @return string
  2337. */
  2338. public static function getSkillBlock($userId, $orientation = 'horizontal')
  2339. {
  2340. if (Skill::isAllowed($userId, false) === false) {
  2341. return '';
  2342. }
  2343. $skill = new Skill();
  2344. $ranking = $skill->getUserSkillRanking($userId);
  2345. $template = new Template(null, false, false, false, false, false);
  2346. $template->assign('ranking', $ranking);
  2347. $template->assign('orientation', $orientation);
  2348. $template->assign('skills', $skill->getUserSkillsTable($userId, 0, 0, false)['skills']);
  2349. $template->assign('user_id', $userId);
  2350. $template->assign('show_skills_report_link', api_is_student() || api_is_student_boss() || api_is_drh());
  2351. $skillBlock = $template->get_template('social/skills_block.tpl');
  2352. return $template->fetch($skillBlock);
  2353. }
  2354. /**
  2355. * @param int $user_id
  2356. *
  2357. * @return string|array
  2358. */
  2359. public static function getExtraFieldBlock($user_id, $isArray = false)
  2360. {
  2361. $fieldVisibility = api_get_configuration_value('profile_fields_visibility');
  2362. $fieldVisibilityKeys = [];
  2363. if (isset($fieldVisibility['options'])) {
  2364. $fieldVisibility = $fieldVisibility['options'];
  2365. $fieldVisibilityKeys = array_keys($fieldVisibility);
  2366. }
  2367. $t_ufo = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
  2368. $extra_user_data = UserManager::get_extra_user_data($user_id);
  2369. $extra_information = '';
  2370. if (is_array($extra_user_data) && count($extra_user_data) > 0) {
  2371. $extra_information_value = '';
  2372. $extraField = new ExtraField('user');
  2373. $listType = [];
  2374. $extraFieldItem = [];
  2375. foreach ($extra_user_data as $key => $data) {
  2376. if (empty($data)) {
  2377. continue;
  2378. }
  2379. if (in_array($key, $fieldVisibilityKeys) && $fieldVisibility[$key] === false) {
  2380. continue;
  2381. }
  2382. // Avoiding parameters
  2383. if (in_array(
  2384. $key,
  2385. [
  2386. 'mail_notify_invitation',
  2387. 'mail_notify_message',
  2388. 'mail_notify_group_message',
  2389. ]
  2390. )) {
  2391. continue;
  2392. }
  2393. // get display text, visibility and type from user_field table
  2394. $field_variable = str_replace('extra_', '', $key);
  2395. $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
  2396. $field_variable
  2397. );
  2398. if (in_array($extraFieldInfo['variable'], ['skype', 'linkedin_url'])) {
  2399. continue;
  2400. }
  2401. // if is not visible skip
  2402. if ($extraFieldInfo['visible_to_self'] != 1) {
  2403. continue;
  2404. }
  2405. // if is not visible to others skip also
  2406. if ($extraFieldInfo['visible_to_others'] != 1) {
  2407. continue;
  2408. }
  2409. if (is_array($data)) {
  2410. switch ($extraFieldInfo['field_type']) {
  2411. case ExtraField::FIELD_TYPE_RADIO:
  2412. $objEfOption = new ExtraFieldOption('user');
  2413. $value = $data['extra_'.$extraFieldInfo['variable']];
  2414. $optionInfo = $objEfOption->get_field_option_by_field_and_option(
  2415. $extraFieldInfo['id'],
  2416. $value
  2417. );
  2418. if ($optionInfo && isset($optionInfo[0])) {
  2419. $optionInfo = $optionInfo[0];
  2420. $extraFieldItem = [
  2421. 'variable' => $extraFieldInfo['variable'],
  2422. 'label' => ucfirst($extraFieldInfo['display_text']),
  2423. 'value' => $optionInfo['display_text'],
  2424. ];
  2425. } else {
  2426. $extraFieldItem = [
  2427. 'variable' => $extraFieldInfo['variable'],
  2428. 'label' => ucfirst($extraFieldInfo['display_text']),
  2429. 'value' => implode(',', $data),
  2430. ];
  2431. }
  2432. break;
  2433. default:
  2434. $extra_information_value .=
  2435. '<li class="list-group-item">'.ucfirst($extraFieldInfo['display_text']).' '
  2436. .' '.implode(',', $data).'</li>';
  2437. $extraFieldItem = [
  2438. 'variable' => $extraFieldInfo['variable'],
  2439. 'label' => ucfirst($extraFieldInfo['display_text']),
  2440. 'value' => implode(',', $data),
  2441. ];
  2442. break;
  2443. }
  2444. } else {
  2445. switch ($extraFieldInfo['field_type']) {
  2446. case ExtraField::FIELD_TYPE_RADIO:
  2447. $objEfOption = new ExtraFieldOption('user');
  2448. $optionInfo = $objEfOption->get_field_option_by_field_and_option($extraFieldInfo['id'], $extraFieldInfo['value']);
  2449. break;
  2450. case ExtraField::FIELD_TYPE_GEOLOCALIZATION_COORDINATES:
  2451. case ExtraField::FIELD_TYPE_GEOLOCALIZATION:
  2452. $data = explode('::', $data);
  2453. $data = $data[0];
  2454. $extra_information_value .= '<li class="list-group-item">'.ucfirst($extraFieldInfo['display_text']).': '.$data.'</li>';
  2455. $extraFieldItem = [
  2456. 'variable' => $extraFieldInfo['variable'],
  2457. 'label' => ucfirst($extraFieldInfo['display_text']),
  2458. 'value' => $data,
  2459. ];
  2460. break;
  2461. case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
  2462. $id_options = explode('::', $data);
  2463. $value_options = [];
  2464. // get option display text from user_field_options table
  2465. foreach ($id_options as $id_option) {
  2466. $sql = "SELECT display_text
  2467. FROM $t_ufo
  2468. WHERE id = '$id_option'";
  2469. $res_options = Database::query($sql);
  2470. $row_options = Database::fetch_row($res_options);
  2471. $value_options[] = $row_options[0];
  2472. }
  2473. $extra_information_value .= '<li class="list-group-item">'.ucfirst($extraFieldInfo['display_text']).': '
  2474. .' '.implode(' ', $value_options).'</li>';
  2475. $extraFieldItem = [
  2476. 'variable' => $extraFieldInfo['variable'],
  2477. 'label' => ucfirst($extraFieldInfo['display_text']),
  2478. 'value' => $value_options,
  2479. ];
  2480. break;
  2481. case ExtraField::FIELD_TYPE_TAG:
  2482. $user_tags = UserManager::get_user_tags($user_id, $extraFieldInfo['id']);
  2483. $tag_tmp = '';
  2484. foreach ($user_tags as $tags) {
  2485. $tag_tmp .= '<a class="label label_tag"'
  2486. .' href="'.api_get_path(WEB_PATH).'main/social/search.php?q='.$tags['tag'].'">'
  2487. .$tags['tag']
  2488. .'</a>';
  2489. }
  2490. if (is_array($user_tags) && count($user_tags) > 0) {
  2491. $extra_information_value .= '<li class="list-group-item">'.ucfirst($extraFieldInfo['display_text']).': '
  2492. .' '.$tag_tmp.'</li>';
  2493. }
  2494. $extraFieldItem = [
  2495. 'variable' => $extraFieldInfo['variable'],
  2496. 'label' => ucfirst($extraFieldInfo['display_text']),
  2497. 'value' => $tag_tmp,
  2498. ];
  2499. break;
  2500. case ExtraField::FIELD_TYPE_SOCIAL_PROFILE:
  2501. $icon_path = UserManager::get_favicon_from_url($data);
  2502. if (self::verifyUrl($icon_path) == false) {
  2503. break;
  2504. }
  2505. $bottom = '0.2';
  2506. //quick hack for hi5
  2507. $domain = parse_url($icon_path, PHP_URL_HOST);
  2508. if ($domain == 'www.hi5.com' || $domain == 'hi5.com') {
  2509. $bottom = '-0.8';
  2510. }
  2511. $data = '<a href="'.$data.'">'
  2512. .'<img src="'.$icon_path.'" alt="icon"'
  2513. .' style="margin-right:0.5em;margin-bottom:'.$bottom.'em;" />'
  2514. .$extraFieldInfo['display_text']
  2515. .'</a>';
  2516. $extra_information_value .= '<li class="list-group-item">'.$data.'</li>';
  2517. $extraFieldItem = [
  2518. 'variable' => $extraFieldInfo['variable'],
  2519. 'label' => ucfirst($extraFieldInfo['display_text']),
  2520. 'value' => $data,
  2521. ];
  2522. break;
  2523. case ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
  2524. $parsedData = explode('::', $data);
  2525. if (!$parsedData) {
  2526. break;
  2527. }
  2528. $objEfOption = new ExtraFieldOption('user');
  2529. $optionInfo = $objEfOption->get($parsedData[0]);
  2530. $extra_information_value .= '<li class="list-group-item">'
  2531. .$optionInfo['display_text'].': '
  2532. .$parsedData[1].'</li>';
  2533. $extraFieldItem = [
  2534. 'variable' => $extraFieldInfo['variable'],
  2535. 'label' => ucfirst($extraFieldInfo['display_text']),
  2536. 'value' => $parsedData[1],
  2537. ];
  2538. break;
  2539. case ExtraField::FIELD_TYPE_TRIPLE_SELECT:
  2540. $optionIds = explode(';', $data);
  2541. $optionValues = [];
  2542. foreach ($optionIds as $optionId) {
  2543. $objEfOption = new ExtraFieldOption('user');
  2544. $optionInfo = $objEfOption->get($optionId);
  2545. $optionValues[] = $optionInfo['display_text'];
  2546. }
  2547. $extra_information_value .= '<li class="list-group-item">'
  2548. .ucfirst($extraFieldInfo['display_text']).': '
  2549. .implode(' ', $optionValues).'</li>';
  2550. $extraFieldItem = [
  2551. 'variable' => $extraFieldInfo['variable'],
  2552. 'label' => ucfirst($extraFieldInfo['display_text']),
  2553. 'value' => implode(' ', $optionValues),
  2554. ];
  2555. break;
  2556. default:
  2557. // Ofaj
  2558. // Converts "Date of birth" into "age"
  2559. if ($key === 'terms_datedenaissance') {
  2560. $dataArray = date_to_str_ago($data, 'UTC', true);
  2561. $dataToString = isset($dataArray['years']) && !empty($dataArray['years']) ? $dataArray['years'] : 0;
  2562. if (!empty($dataToString)) {
  2563. $data = $dataToString;
  2564. $extraFieldInfo['display_text'] = get_lang('Age');
  2565. }
  2566. }
  2567. $extra_information_value .= '<li class="list-group-item">'.ucfirst($extraFieldInfo['display_text']).': '.$data.'</li>';
  2568. $extraFieldItem = [
  2569. 'variable' => $extraFieldInfo['variable'],
  2570. 'label' => ucfirst($extraFieldInfo['display_text']),
  2571. 'value' => $data,
  2572. ];
  2573. break;
  2574. }
  2575. }
  2576. $listType[] = $extraFieldItem;
  2577. }
  2578. if ($isArray) {
  2579. return $listType;
  2580. } else {
  2581. // if there are information to show
  2582. if (!empty($extra_information_value)) {
  2583. $extra_information_value = '<ul class="list-group">'.$extra_information_value.'</ul>';
  2584. $extra_information .= Display::panelCollapse(
  2585. get_lang('ExtraInformation'),
  2586. $extra_information_value,
  2587. 'sn-extra-information',
  2588. null,
  2589. 'sn-extra-accordion',
  2590. 'sn-extra-collapse'
  2591. );
  2592. }
  2593. }
  2594. }
  2595. return $extra_information;
  2596. }
  2597. /**
  2598. * @param string $url
  2599. */
  2600. public static function handlePosts($url)
  2601. {
  2602. $friendId = isset($_GET['u']) ? (int) $_GET['u'] : api_get_user_id();
  2603. $url = Security::remove_XSS($url);
  2604. // Main post
  2605. if (!empty($_POST['social_wall_new_msg_main']) || !empty($_FILES['picture']['tmp_name'])) {
  2606. $messageContent = $_POST['social_wall_new_msg_main'];
  2607. if (!empty($_POST['url_content'])) {
  2608. $messageContent = $_POST['social_wall_new_msg_main'].'<br /><br />'.$_POST['url_content'];
  2609. }
  2610. $messageId = self::sendWallMessage(
  2611. api_get_user_id(),
  2612. $friendId,
  2613. $messageContent,
  2614. 0,
  2615. MESSAGE_STATUS_WALL_POST
  2616. );
  2617. if ($messageId && !empty($_FILES['picture']['tmp_name'])) {
  2618. self::sendWallMessageAttachmentFile(
  2619. api_get_user_id(),
  2620. $_FILES['picture'],
  2621. $messageId
  2622. );
  2623. }
  2624. Display::addFlash(Display::return_message(get_lang('MessageSent')));
  2625. header('Location: '.$url);
  2626. exit;
  2627. }
  2628. }
  2629. /**
  2630. * @param int $countPost
  2631. * @param array $htmlHeadXtra
  2632. */
  2633. public static function getScrollJs($countPost, &$htmlHeadXtra)
  2634. {
  2635. // $ajax_url = api_get_path(WEB_AJAX_PATH).'message.ajax.php';
  2636. $socialAjaxUrl = api_get_path(WEB_AJAX_PATH).'social.ajax.php';
  2637. $javascriptDir = api_get_path(LIBRARY_PATH).'javascript/';
  2638. $locale = api_get_language_isocode();
  2639. // Add Jquery scroll pagination plugin
  2640. $htmlHeadXtra[] = api_get_js('jscroll/jquery.jscroll.js');
  2641. // Add Jquery Time ago plugin
  2642. $htmlHeadXtra[] = api_get_asset('jquery-timeago/jquery.timeago.js');
  2643. $timeAgoLocaleDir = $javascriptDir.'jquery-timeago/locales/jquery.timeago.'.$locale.'.js';
  2644. if (file_exists($timeAgoLocaleDir)) {
  2645. $htmlHeadXtra[] = api_get_js('jquery-timeago/locales/jquery.timeago.'.$locale.'.js');
  2646. }
  2647. if ($countPost > self::DEFAULT_WALL_POSTS) {
  2648. $htmlHeadXtra[] = '<script>
  2649. $(function() {
  2650. var container = $("#wallMessages");
  2651. container.jscroll({
  2652. loadingHtml: "<div class=\"well_border\">'.get_lang('Loading').' </div>",
  2653. nextSelector: "a.nextPage:last",
  2654. contentSelector: "",
  2655. callback: timeAgo
  2656. });
  2657. });
  2658. </script>';
  2659. }
  2660. $htmlHeadXtra[] = '<script>
  2661. function deleteMessage(id)
  2662. {
  2663. $.ajax({
  2664. url: "'.$socialAjaxUrl.'?a=delete_message" + "&id=" + id,
  2665. success: function (result) {
  2666. if (result) {
  2667. $("#message_" + id).parent().parent().parent().parent().html(result);
  2668. }
  2669. }
  2670. });
  2671. }
  2672. function deleteComment(id)
  2673. {
  2674. $.ajax({
  2675. url: "'.$socialAjaxUrl.'?a=delete_message" + "&id=" + id,
  2676. success: function (result) {
  2677. if (result) {
  2678. $("#message_" + id).parent().parent().parent().html(result);
  2679. }
  2680. }
  2681. });
  2682. }
  2683. function submitComment(messageId)
  2684. {
  2685. var data = $("#form_comment_"+messageId).serializeArray();
  2686. $.ajax({
  2687. type : "POST",
  2688. url: "'.$socialAjaxUrl.'?a=send_comment" + "&id=" + messageId,
  2689. data: data,
  2690. success: function (result) {
  2691. if (result) {
  2692. $("#post_" + messageId + " textarea").val("");
  2693. $("#post_" + messageId + " .sub-mediapost").prepend(result);
  2694. $("#post_" + messageId + " .sub-mediapost").append(
  2695. $(\'<div id=result_\' + messageId +\'>'.addslashes(get_lang('Saved')).'</div>\')
  2696. );
  2697. $("#result_" + messageId + "").fadeIn("fast", function() {
  2698. $("#result_" + messageId + "").delay(1000).fadeOut("fast", function() {
  2699. $(this).remove();
  2700. });
  2701. });
  2702. }
  2703. }
  2704. });
  2705. }
  2706. $(function() {
  2707. timeAgo();
  2708. /*$(".delete_message").on("click", function() {
  2709. var id = $(this).attr("id");
  2710. id = id.split("_")[1];
  2711. $.ajax({
  2712. url: "'.$socialAjaxUrl.'?a=delete_message" + "&id=" + id,
  2713. success: function (result) {
  2714. if (result) {
  2715. $("#message_" + id).parent().parent().parent().parent().html(result);
  2716. }
  2717. }
  2718. });
  2719. });
  2720. $(".delete_comment").on("click", function() {
  2721. var id = $(this).attr("id");
  2722. id = id.split("_")[1];
  2723. $.ajax({
  2724. url: "'.$socialAjaxUrl.'?a=delete_message" + "&id=" + id,
  2725. success: function (result) {
  2726. if (result) {
  2727. $("#message_" + id).parent().parent().parent().html(result);
  2728. }
  2729. }
  2730. });
  2731. });
  2732. */
  2733. });
  2734. function timeAgo() {
  2735. $(".timeago").timeago();
  2736. }
  2737. </script>';
  2738. }
  2739. /**
  2740. * @param int $userId
  2741. * @param int $countPost
  2742. *
  2743. * @return string
  2744. */
  2745. public static function getAutoExtendLink($userId, $countPost)
  2746. {
  2747. $userId = (int) $userId;
  2748. $socialAjaxUrl = api_get_path(WEB_AJAX_PATH).'social.ajax.php';
  2749. $socialAutoExtendLink = '';
  2750. if ($countPost > self::DEFAULT_WALL_POSTS) {
  2751. $socialAutoExtendLink = Display::url(
  2752. get_lang('SeeMore'),
  2753. $socialAjaxUrl.'?u='.$userId.'&a=list_wall_message&start='.
  2754. self::DEFAULT_WALL_POSTS.'&length='.self::DEFAULT_SCROLL_NEW_POST,
  2755. [
  2756. 'class' => 'nextPage next',
  2757. ]
  2758. );
  2759. }
  2760. return $socialAutoExtendLink;
  2761. }
  2762. /**
  2763. * @param int $userId
  2764. *
  2765. * @return array
  2766. */
  2767. public static function getThreadList($userId)
  2768. {
  2769. $forumCourseId = api_get_configuration_value('global_forums_course_id');
  2770. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  2771. $threads = [];
  2772. if (!empty($forumCourseId)) {
  2773. $courseInfo = api_get_course_info_by_id($forumCourseId);
  2774. getNotificationsPerUser($userId, true, $forumCourseId);
  2775. $notification = Session::read('forum_notification');
  2776. Session::erase('forum_notification');
  2777. $threadUrlBase = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.http_build_query([
  2778. 'cidReq' => $courseInfo['code'],
  2779. ]).'&';
  2780. if (isset($notification['thread']) && !empty($notification['thread'])) {
  2781. $threadList = array_filter(array_unique($notification['thread']));
  2782. $em = Database::getManager();
  2783. $repo = $em->getRepository('ChamiloCourseBundle:CForumThread');
  2784. foreach ($threadList as $threadId) {
  2785. /** @var \Chamilo\CourseBundle\Entity\CForumThread $thread */
  2786. $thread = $repo->find($threadId);
  2787. if ($thread) {
  2788. $threadUrl = $threadUrlBase.http_build_query([
  2789. 'forum' => $thread->getForumId(),
  2790. 'thread' => $thread->getIid(),
  2791. ]);
  2792. $threads[] = [
  2793. 'id' => $threadId,
  2794. 'url' => Display::url(
  2795. $thread->getThreadTitle(),
  2796. $threadUrl
  2797. ),
  2798. 'name' => Display::url(
  2799. $thread->getThreadTitle(),
  2800. $threadUrl
  2801. ),
  2802. 'description' => '',
  2803. ];
  2804. }
  2805. }
  2806. }
  2807. }
  2808. return $threads;
  2809. }
  2810. /**
  2811. * @param int $userId
  2812. *
  2813. * @return string
  2814. */
  2815. public static function getGroupBlock($userId)
  2816. {
  2817. $threadList = self::getThreadList($userId);
  2818. $userGroup = new UserGroup();
  2819. $forumCourseId = api_get_configuration_value('global_forums_course_id');
  2820. $courseInfo = null;
  2821. if (!empty($forumCourseId)) {
  2822. $courseInfo = api_get_course_info_by_id($forumCourseId);
  2823. }
  2824. $social_group_block = '';
  2825. if (!empty($courseInfo)) {
  2826. if (!empty($threadList)) {
  2827. $social_group_block .= '<div class="list-group">';
  2828. foreach ($threadList as $group) {
  2829. $social_group_block .= ' <li class="list-group-item">';
  2830. $social_group_block .= $group['name'];
  2831. $social_group_block .= '</li>';
  2832. }
  2833. $social_group_block .= '</div>';
  2834. }
  2835. $social_group_block .= Display::url(
  2836. get_lang('SeeAllCommunities'),
  2837. api_get_path(WEB_CODE_PATH).'forum/index.php?cidReq='.$courseInfo['code']
  2838. );
  2839. if (!empty($social_group_block)) {
  2840. $social_group_block = Display::panelCollapse(
  2841. get_lang('MyCommunities'),
  2842. $social_group_block,
  2843. 'sm-groups',
  2844. null,
  2845. 'grups-acordion',
  2846. 'groups-collapse'
  2847. );
  2848. }
  2849. } else {
  2850. // Load my groups
  2851. $results = $userGroup->get_groups_by_user(
  2852. $userId,
  2853. [
  2854. GROUP_USER_PERMISSION_ADMIN,
  2855. GROUP_USER_PERMISSION_READER,
  2856. GROUP_USER_PERMISSION_MODERATOR,
  2857. GROUP_USER_PERMISSION_HRM,
  2858. ]
  2859. );
  2860. $myGroups = [];
  2861. if (!empty($results)) {
  2862. foreach ($results as $result) {
  2863. $id = $result['id'];
  2864. $result['description'] = Security::remove_XSS($result['description'], STUDENT, true);
  2865. $result['name'] = Security::remove_XSS($result['name'], STUDENT, true);
  2866. $group_url = "group_view.php?id=$id";
  2867. $link = Display::url(
  2868. api_ucwords(cut($result['name'], 40, true)),
  2869. $group_url
  2870. );
  2871. $result['name'] = $link;
  2872. $picture = $userGroup->get_picture_group(
  2873. $id,
  2874. $result['picture'],
  2875. null,
  2876. GROUP_IMAGE_SIZE_BIG
  2877. );
  2878. $result['picture'] = '<img class="img-responsive" src="'.$picture['file'].'" />';
  2879. $group_actions = '<div class="group-more"><a class="btn btn-default" href="groups.php?#tab_browse-2">'.
  2880. get_lang('SeeMore').'</a></div>';
  2881. $group_info = '<div class="description"><p>'.cut($result['description'], 120, true)."</p></div>";
  2882. $myGroups[] = [
  2883. 'url' => Display::url(
  2884. $result['picture'],
  2885. $group_url
  2886. ),
  2887. 'name' => $result['name'],
  2888. 'description' => $group_info.$group_actions,
  2889. ];
  2890. }
  2891. $social_group_block .= '<div class="list-group">';
  2892. foreach ($myGroups as $group) {
  2893. $social_group_block .= ' <li class="list-group-item">';
  2894. $social_group_block .= $group['name'];
  2895. $social_group_block .= '</li>';
  2896. }
  2897. $social_group_block .= '</div>';
  2898. $form = new FormValidator(
  2899. 'find_groups_form',
  2900. 'get',
  2901. api_get_path(WEB_CODE_PATH).'social/search.php?search_type=2',
  2902. null,
  2903. null,
  2904. FormValidator::LAYOUT_BOX_NO_LABEL
  2905. );
  2906. $form->addHidden('search_type', 2);
  2907. $form->addText(
  2908. 'q',
  2909. get_lang('Search'),
  2910. false,
  2911. [
  2912. 'aria-label' => get_lang('Search'),
  2913. 'custom' => true,
  2914. 'placeholder' => get_lang('Search'),
  2915. ]
  2916. );
  2917. $social_group_block .= $form->returnForm();
  2918. if (!empty($social_group_block)) {
  2919. $social_group_block = Display::panelCollapse(
  2920. get_lang('MyGroups'),
  2921. $social_group_block,
  2922. 'sm-groups',
  2923. null,
  2924. 'grups-acordion',
  2925. 'groups-collapse'
  2926. );
  2927. }
  2928. }
  2929. }
  2930. return $social_group_block;
  2931. }
  2932. /**
  2933. * Returns the formatted header message post.
  2934. *
  2935. * @param int $authorInfo
  2936. * @param int $receiverInfo
  2937. * @param array $message Message data
  2938. *
  2939. * @return string $html The formatted header message post
  2940. */
  2941. private static function headerMessagePost($authorInfo, $receiverInfo, $message)
  2942. {
  2943. $currentUserId = api_get_user_id();
  2944. $authorId = (int) $authorInfo['user_id'];
  2945. $receiverId = (int) $receiverInfo['user_id'];
  2946. $iconStatus = $authorInfo['icon_status'];
  2947. $date = Display::dateToStringAgoAndLongDate($message['send_date']);
  2948. $avatarAuthor = $authorInfo['avatar'];
  2949. $urlAuthor = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$authorId;
  2950. $nameCompleteAuthor = $authorInfo['complete_name'];
  2951. $urlReceiver = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$receiverId;
  2952. $nameCompleteReceiver = $receiverInfo['complete_name'];
  2953. $htmlReceiver = '';
  2954. if ($authorId !== $receiverId) {
  2955. $htmlReceiver = ' > <a href="'.$urlReceiver.'">'.$nameCompleteReceiver.'</a> ';
  2956. }
  2957. if (!empty($message['group_info'])) {
  2958. $htmlReceiver = ' > <a href="'.$message['group_info']['url'].'">'.$message['group_info']['name'].'</a> ';
  2959. }
  2960. $canEdit = ($currentUserId == $authorInfo['user_id'] || $currentUserId == $receiverInfo['user_id']) && empty($message['group_info']);
  2961. if (!empty($message['thread_id'])) {
  2962. $htmlReceiver = ' > <a href="'.$message['thread_url'].'">'.$message['forum_title'].'</a> ';
  2963. $canEdit = false;
  2964. }
  2965. $postAttachment = self::getPostAttachment($message);
  2966. $html = '';
  2967. $html .= '<div class="top-mediapost" >';
  2968. $html .= '<div class="pull-right btn-group btn-group-sm">';
  2969. $html .= MessageManager::getLikesButton(
  2970. $message['id'],
  2971. $currentUserId,
  2972. !empty($message['group_info']['id']) ? (int) $message['group_info']['id'] : 0
  2973. );
  2974. if ($canEdit) {
  2975. $htmlDelete = Display::url(
  2976. Display::returnFontAwesomeIcon('trash', '', true),
  2977. 'javascript:void(0)',
  2978. [
  2979. 'id' => 'message_'.$message['id'],
  2980. 'title' => get_lang('SocialMessageDelete'),
  2981. 'onclick' => 'deleteMessage('.$message['id'].')',
  2982. 'class' => 'btn btn-default',
  2983. ]
  2984. );
  2985. $html .= $htmlDelete;
  2986. }
  2987. $html .= '</div>';
  2988. $html .= '<div class="user-image" >';
  2989. $html .= '<a href="'.$urlAuthor.'">
  2990. <img class="avatar-thumb" src="'.$avatarAuthor.'" alt="'.$nameCompleteAuthor.'"></a>';
  2991. $html .= '</div>';
  2992. $html .= '<div class="user-data">';
  2993. $html .= $iconStatus;
  2994. $html .= '<div class="username"><a href="'.$urlAuthor.'">'.$nameCompleteAuthor.'</a>'.$htmlReceiver.'</div>';
  2995. $html .= '<div class="post-date">'.$date.'</div>';
  2996. $html .= '</div>';
  2997. $html .= '<div class="msg-content">';
  2998. if (!empty($postAttachment)) {
  2999. $html .= '<div class="post-attachment thumbnail">';
  3000. $html .= $postAttachment;
  3001. $html .= '</div>';
  3002. }
  3003. $html .= '<div>'.Security::remove_XSS($message['content']).'</div>';
  3004. $html .= '</div>';
  3005. $html .= '</div>'; // end mediaPost
  3006. // Popularity post functionality
  3007. $html .= '<div class="popularity-mediapost"></div>';
  3008. return $html;
  3009. }
  3010. }