usergroup.lib.php 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Class UserGroup
  5. *
  6. * This class provides methods for the UserGroup management.
  7. * Include/require it in your code to use its features.
  8. * @package chamilo.library
  9. *
  10. */
  11. class UserGroup extends Model
  12. {
  13. public $columns = [
  14. 'id',
  15. 'name',
  16. 'description',
  17. 'group_type',
  18. 'picture',
  19. 'url',
  20. 'allow_members_leave_group',
  21. 'visibility',
  22. 'updated_at',
  23. 'created_at'
  24. ];
  25. public $useMultipleUrl = false;
  26. const SOCIAL_CLASS = 1;
  27. const NORMAL_CLASS = 0;
  28. public $groupType = 0;
  29. public $showGroupTypeSetting = false;
  30. /**
  31. * Set ups DB tables
  32. */
  33. public function __construct()
  34. {
  35. $this->table = Database::get_main_table(TABLE_USERGROUP);
  36. $this->usergroup_rel_user_table = Database::get_main_table(TABLE_USERGROUP_REL_USER);
  37. $this->usergroup_rel_course_table = Database::get_main_table(TABLE_USERGROUP_REL_COURSE);
  38. $this->usergroup_rel_session_table = Database::get_main_table(TABLE_USERGROUP_REL_SESSION);
  39. $this->access_url_rel_usergroup = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USERGROUP);
  40. $this->table_course = Database::get_main_table(TABLE_MAIN_COURSE);
  41. $this->table_user = Database::get_main_table(TABLE_MAIN_USER);
  42. $this->useMultipleUrl = api_get_configuration_value('multiple_access_urls');
  43. }
  44. /**
  45. * @return bool
  46. */
  47. public function getUseMultipleUrl()
  48. {
  49. return $this->useMultipleUrl;
  50. }
  51. /**
  52. * @return int
  53. */
  54. public function getTotalCount()
  55. {
  56. $row = Database::select('count(*) as count', $this->table, [], 'first');
  57. return $row['count'];
  58. }
  59. /**
  60. * @param int $type
  61. *
  62. * @return int
  63. */
  64. public function get_count($type = -1)
  65. {
  66. if ($this->useMultipleUrl) {
  67. $urlId = api_get_current_access_url_id();
  68. $sql = "SELECT count(u.id) as count FROM ".$this->table." u
  69. INNER JOIN ".$this->access_url_rel_usergroup." a
  70. ON (u.id = a.usergroup_id)
  71. WHERE access_url_id = $urlId
  72. ";
  73. $result = Database::query($sql);
  74. if (Database::num_rows($result)) {
  75. $row = Database::fetch_array($result);
  76. return $row['count'];
  77. }
  78. return 0;
  79. } else {
  80. $typeCondition = '';
  81. if ($type != -1) {
  82. $type = intval($type);
  83. $typeCondition = " WHERE group_type = $type ";
  84. }
  85. $sql = "SELECT count(a.id) as count
  86. FROM {$this->table} a
  87. $typeCondition
  88. ";
  89. $result = Database::query($sql);
  90. if (Database::num_rows($result)) {
  91. $row = Database::fetch_array($result);
  92. return $row['count'];
  93. }
  94. }
  95. }
  96. /**
  97. * @param int $course_id
  98. * @param int $type
  99. *
  100. * @return mixed
  101. */
  102. public function getUserGroupByCourseWithDataCount($course_id, $type = -1)
  103. {
  104. if ($this->useMultipleUrl) {
  105. $course_id = intval($course_id);
  106. $urlId = api_get_current_access_url_id();
  107. $sql = "SELECT count(c.usergroup_id) as count
  108. FROM {$this->usergroup_rel_course_table} c
  109. INNER JOIN {$this->access_url_rel_usergroup} a
  110. ON (c.usergroup_id = a.usergroup_id)
  111. WHERE access_url_id = $urlId AND course_id = $course_id
  112. ";
  113. $result = Database::query($sql);
  114. if (Database::num_rows($result)) {
  115. $row = Database::fetch_array($result);
  116. return $row['count'];
  117. }
  118. return 0;
  119. } else {
  120. $typeCondition = '';
  121. if ($type != -1) {
  122. $type = intval($type);
  123. $typeCondition = " AND group_type = $type ";
  124. }
  125. $sql = "SELECT count(c.usergroup_id) as count
  126. FROM {$this->usergroup_rel_course_table} c
  127. INNER JOIN {$this->table} a
  128. ON (c.usergroup_id = a.id)
  129. WHERE
  130. course_id = $course_id
  131. $typeCondition
  132. ";
  133. $result = Database::query($sql);
  134. if (Database::num_rows($result)) {
  135. $row = Database::fetch_array($result);
  136. return $row['count'];
  137. }
  138. return 0;
  139. }
  140. }
  141. /**
  142. * @param string $name
  143. *
  144. * @return mixed
  145. */
  146. public function get_id_by_name($name)
  147. {
  148. $row = Database::select(
  149. 'id',
  150. $this->table,
  151. ['where' => ['name = ?' => $name]],
  152. 'first'
  153. );
  154. return $row['id'];
  155. }
  156. /**
  157. * Displays the title + grid
  158. */
  159. public function display()
  160. {
  161. // action links
  162. echo '<div class="actions">';
  163. echo '<a href="../admin/index.php">'.
  164. Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('PlatformAdmin'), '', '32').
  165. '</a>';
  166. echo '<a href="'.api_get_self().'?action=add">'.
  167. Display::return_icon('new_class.png', get_lang('AddClasses'), '', '32').
  168. '</a>';
  169. echo Display::url(
  170. Display::return_icon('import_csv.png', get_lang('Import'), [], ICON_SIZE_MEDIUM),
  171. 'usergroup_import.php'
  172. );
  173. echo Display::url(
  174. Display::return_icon('export_csv.png', get_lang('Export'), [], ICON_SIZE_MEDIUM),
  175. 'usergroup_export.php'
  176. );
  177. echo '</div>';
  178. echo Display::grid_html('usergroups');
  179. }
  180. /**
  181. * Get HTML grid
  182. */
  183. public function display_teacher_view()
  184. {
  185. echo Display::grid_html('usergroups');
  186. }
  187. /**
  188. * Gets a list of course ids by user group
  189. * @param int $id user group id
  190. * @param bool $loadCourseData
  191. *
  192. * @return array
  193. */
  194. public function get_courses_by_usergroup($id, $loadCourseData = false)
  195. {
  196. if ($this->useMultipleUrl) {
  197. $urlId = api_get_current_access_url_id();
  198. $from = $this->usergroup_rel_course_table." c
  199. INNER JOIN {$this->access_url_rel_usergroup} a
  200. ON (a.usergroup_id = c.usergroup_id) ";
  201. $whereConditionSql = 'a.usergroup_id = ? AND access_url_id = ? ';
  202. $whereConditionValues = [$id, $urlId];
  203. } else {
  204. $whereConditionSql = 'usergroup_id = ?';
  205. $whereConditionValues = [$id];
  206. $from = $this->usergroup_rel_course_table." c ";
  207. }
  208. if ($loadCourseData) {
  209. $from .= " INNER JOIN {$this->table_course} as course ON c.course_id = course.id";
  210. }
  211. /*
  212. if (!empty($conditionsLike)) {
  213. $from .= " INNER JOIN {$this->table_course} as course ON c.course_id = course.id";
  214. $conditionSql = [];
  215. foreach ($conditionsLike as $field => $value) {
  216. $conditionSql[] = $field.' LIKE %?%';
  217. $whereConditionValues[] = $value;
  218. }
  219. $whereConditionSql .= ' AND '.implode(' AND ', $conditionSql);
  220. }*/
  221. $where = ['where' => [$whereConditionSql => $whereConditionValues]];
  222. if ($loadCourseData) {
  223. $select = 'course.*';
  224. } else {
  225. $select = 'course_id';
  226. }
  227. $results = Database::select(
  228. $select,
  229. $from,
  230. $where
  231. );
  232. $array = [];
  233. if (!empty($results)) {
  234. foreach ($results as $row) {
  235. if ($loadCourseData) {
  236. $array[$row['id']] = $row;
  237. } else {
  238. $array[] = $row['course_id'];
  239. }
  240. }
  241. }
  242. return $array;
  243. }
  244. /**
  245. * @param array $options
  246. *
  247. * @return array
  248. */
  249. public function getUserGroupInCourse($options = [], $type = -1)
  250. {
  251. if ($this->useMultipleUrl) {
  252. $sql = "SELECT u.* FROM {$this->usergroup_rel_course_table} usergroup
  253. INNER JOIN {$this->table} u
  254. ON (u.id = usergroup.usergroup_id)
  255. INNER JOIN {$this->table_course} c
  256. ON (usergroup.course_id = c.id)
  257. INNER JOIN {$this->access_url_rel_usergroup} a
  258. ON (a.usergroup_id = u.id)
  259. ";
  260. } else {
  261. $sql = "SELECT u.* FROM {$this->usergroup_rel_course_table} usergroup
  262. INNER JOIN {$this->table} u
  263. ON (u.id = usergroup.usergroup_id)
  264. INNER JOIN {$this->table_course} c
  265. ON (usergroup.course_id = c.id)
  266. ";
  267. }
  268. $conditions = Database::parse_conditions($options);
  269. $typeCondition = '';
  270. if ($type != -1) {
  271. $type = intval($type);
  272. $typeCondition = " AND group_type = $type ";
  273. }
  274. if (empty($conditions)) {
  275. $conditions .= "WHERE 1 = 1 $typeCondition ";
  276. } else {
  277. $conditions .= " $typeCondition ";
  278. }
  279. $sql .= $conditions;
  280. if ($this->useMultipleUrl) {
  281. $urlId = api_get_current_access_url_id();
  282. $sql .= " AND access_url_id = $urlId ";
  283. }
  284. if (isset($options['LIMIT'])) {
  285. $limits = explode(',', $options['LIMIT']);
  286. $limits = array_map('intval', $limits);
  287. if (isset($limits[0]) && isset($limits[1])) {
  288. $sql .= " LIMIT ".$limits[0].', '.$limits[1];
  289. }
  290. }
  291. $result = Database::query($sql);
  292. $array = Database::store_result($result, 'ASSOC');
  293. return $array;
  294. }
  295. /**
  296. * @param array $options
  297. * @param int $type
  298. *
  299. * @return array|bool
  300. */
  301. public function getUserGroupNotInCourse($options = [], $type = -1)
  302. {
  303. $course_id = null;
  304. if (isset($options['course_id'])) {
  305. $course_id = intval($options['course_id']);
  306. unset($options['course_id']);
  307. }
  308. if (empty($course_id)) {
  309. return false;
  310. }
  311. $typeCondition = '';
  312. if ($type != -1) {
  313. $type = intval($type);
  314. $typeCondition = " AND group_type = $type ";
  315. }
  316. if ($this->useMultipleUrl) {
  317. $urlId = api_get_current_access_url_id();
  318. $sql = "SELECT DISTINCT u.*
  319. FROM {$this->table} u
  320. INNER JOIN {$this->access_url_rel_usergroup} a
  321. ON (a.usergroup_id = u.id)
  322. LEFT OUTER JOIN {$this->usergroup_rel_course_table} urc
  323. ON (u.id = urc.usergroup_id AND course_id = $course_id)
  324. ";
  325. } else {
  326. $sql = "SELECT DISTINCT u.*
  327. FROM {$this->table} u
  328. LEFT OUTER JOIN {$this->usergroup_rel_course_table} urc
  329. ON (u.id = urc.usergroup_id AND course_id = $course_id)
  330. ";
  331. }
  332. $conditions = Database::parse_conditions($options);
  333. if (empty($conditions)) {
  334. $conditions .= "WHERE 1 = 1 $typeCondition ";
  335. } else {
  336. $conditions .= " $typeCondition ";
  337. }
  338. $sql .= $conditions;
  339. if ($this->useMultipleUrl) {
  340. $sql .= " AND access_url_id = $urlId";
  341. }
  342. if (isset($options['LIMIT'])) {
  343. $limits = explode(',', $options['LIMIT']);
  344. $limits = array_map('intval', $limits);
  345. if (isset($limits[0]) && isset($limits[1])) {
  346. $sql .= " LIMIT ".$limits[0].', '.$limits[1];
  347. }
  348. }
  349. $result = Database::query($sql);
  350. $array = Database::store_result($result, 'ASSOC');
  351. return $array;
  352. }
  353. /**
  354. * @param int $course_id
  355. * @return array
  356. */
  357. public function get_usergroup_by_course($course_id)
  358. {
  359. if ($this->useMultipleUrl) {
  360. $urlId = api_get_current_access_url_id();
  361. $options = [
  362. 'where' => [
  363. 'c.course_id = ? AND access_url_id = ?' => [
  364. $course_id,
  365. $urlId,
  366. ],
  367. ],
  368. ];
  369. $from = $this->usergroup_rel_course_table." as c INNER JOIN ".$this->access_url_rel_usergroup." a
  370. ON c.usergroup_id = a.usergroup_id";
  371. } else {
  372. $options = ['where' => ['c.course_id = ?' => $course_id]];
  373. $from = $this->usergroup_rel_course_table." c";
  374. }
  375. $results = Database::select('c.usergroup_id', $from, $options);
  376. $array = [];
  377. if (!empty($results)) {
  378. foreach ($results as $row) {
  379. $array[] = $row['usergroup_id'];
  380. }
  381. }
  382. return $array;
  383. }
  384. /**
  385. * @param int $usergroup_id
  386. * @param int $course_id
  387. * @return bool
  388. */
  389. public function usergroup_was_added_in_course($usergroup_id, $course_id)
  390. {
  391. $results = Database::select(
  392. 'usergroup_id',
  393. $this->usergroup_rel_course_table,
  394. ['where' => ['course_id = ? AND usergroup_id = ?' => [$course_id, $usergroup_id]]]
  395. );
  396. if (empty($results)) {
  397. return false;
  398. }
  399. return true;
  400. }
  401. /**
  402. * Gets a list of session ids by user group
  403. * @param int $id user group id
  404. * @return array
  405. */
  406. public function get_sessions_by_usergroup($id)
  407. {
  408. $results = Database::select(
  409. 'session_id',
  410. $this->usergroup_rel_session_table,
  411. ['where' => ['usergroup_id = ?' => $id]]
  412. );
  413. $array = [];
  414. if (!empty($results)) {
  415. foreach ($results as $row) {
  416. $array[] = $row['session_id'];
  417. }
  418. }
  419. return $array;
  420. }
  421. /**
  422. * Gets a list of user ids by user group
  423. * @param int $id user group id
  424. * @param array $roles
  425. * @return array with a list of user ids
  426. */
  427. public function get_users_by_usergroup($id = null, $roles = [])
  428. {
  429. $relationCondition = '';
  430. if (!empty($roles)) {
  431. $relationConditionArray = [];
  432. foreach ($roles as $relation) {
  433. $relation = (int) $relation;
  434. if (empty($relation)) {
  435. $relationConditionArray[] = " (relation_type = 0 OR relation_type IS NULL OR relation_type = '') ";
  436. } else {
  437. $relationConditionArray[] = " relation_type = $relation ";
  438. }
  439. }
  440. $relationCondition = " AND ( ";
  441. $relationCondition .= implode('OR', $relationConditionArray);
  442. $relationCondition .= " ) ";
  443. }
  444. if (empty($id)) {
  445. $conditions = [];
  446. } else {
  447. $conditions = ['where' => ["usergroup_id = ? $relationCondition "=> $id]];
  448. }
  449. $results = Database::select(
  450. 'user_id',
  451. $this->usergroup_rel_user_table,
  452. $conditions
  453. );
  454. $array = [];
  455. if (!empty($results)) {
  456. foreach ($results as $row) {
  457. $array[] = $row['user_id'];
  458. }
  459. }
  460. return $array;
  461. }
  462. /**
  463. * Gets a list of user ids by user group
  464. * @param int $id user group id
  465. * @param int $relation
  466. * @return array with a list of user ids
  467. */
  468. public function getUsersByUsergroupAndRelation($id, $relation = 0)
  469. {
  470. $relation = (int) $relation;
  471. if (empty($relation)) {
  472. $conditions = ['where' => ['usergroup_id = ? AND (relation_type = 0 OR relation_type IS NULL OR relation_type = "") ' => [$id]]];
  473. } else {
  474. $conditions = ['where' => ['usergroup_id = ? AND relation_type = ?' => [$id, $relation]]];
  475. }
  476. $results = Database::select(
  477. 'user_id',
  478. $this->usergroup_rel_user_table,
  479. $conditions
  480. );
  481. $array = [];
  482. if (!empty($results)) {
  483. foreach ($results as $row) {
  484. $array[] = $row['user_id'];
  485. }
  486. }
  487. return $array;
  488. }
  489. /**
  490. * Get the group list for a user
  491. * @param int $userId The user ID
  492. * @param int $filterByType Optional. The type of group
  493. * @return array
  494. */
  495. public function getUserGroupListByUser($userId, $filterByType = null)
  496. {
  497. $userId = (int) $userId;
  498. if ($this->useMultipleUrl) {
  499. $urlId = api_get_current_access_url_id();
  500. $from = $this->usergroup_rel_user_table." u
  501. INNER JOIN {$this->access_url_rel_usergroup} a
  502. ON (a.usergroup_id AND u.usergroup_id)
  503. INNER JOIN {$this->table} g
  504. ON (u.usergroup_id = g.id)
  505. ";
  506. $where = ['where' => ['user_id = ? AND access_url_id = ? ' => [$userId, $urlId]]];
  507. } else {
  508. $from = $this->usergroup_rel_user_table." u
  509. INNER JOIN {$this->table} g
  510. ON (u.usergroup_id = g.id)
  511. ";
  512. $where = ['where' => ['user_id = ?' => $userId]];
  513. }
  514. if ($filterByType !== null) {
  515. $where['where'][' AND g.group_type = ?'] = (int) $filterByType;
  516. }
  517. $results = Database::select(
  518. 'g.*',
  519. $from,
  520. $where
  521. );
  522. $array = [];
  523. if (!empty($results)) {
  524. foreach ($results as $row) {
  525. $array[] = $row;
  526. }
  527. }
  528. return $array;
  529. }
  530. /**
  531. * Gets the usergroup id list by user id
  532. * @param int $userId user id
  533. * @return array
  534. */
  535. public function get_usergroup_by_user($userId)
  536. {
  537. $userId = (int) $userId;
  538. if ($this->useMultipleUrl) {
  539. $urlId = api_get_current_access_url_id();
  540. $from = $this->usergroup_rel_user_table." u
  541. INNER JOIN {$this->access_url_rel_usergroup} a ON (a.usergroup_id AND u.usergroup_id)";
  542. $where = ['where' => ['user_id = ? AND access_url_id = ? ' => [$userId, $urlId]]];
  543. } else {
  544. $from = $this->usergroup_rel_user_table." u ";
  545. $where = ['where' => ['user_id = ?' => $userId]];
  546. }
  547. $results = Database::select(
  548. 'u.usergroup_id',
  549. $from,
  550. $where
  551. );
  552. $array = [];
  553. if (!empty($results)) {
  554. foreach ($results as $row) {
  555. $array[] = $row['usergroup_id'];
  556. }
  557. }
  558. return $array;
  559. }
  560. /**
  561. * Subscribes sessions to a group (also adding the members of the group in the session and course)
  562. * @param int $usergroup_id usergroup id
  563. * @param array $list list of session ids
  564. * @param bool $deleteCurrentSessions Optional. Empty the session list for the usergroup (class)
  565. */
  566. public function subscribe_sessions_to_usergroup($usergroup_id, $list, $deleteCurrentSessions = true)
  567. {
  568. $current_list = self::get_sessions_by_usergroup($usergroup_id);
  569. $user_list = self::get_users_by_usergroup($usergroup_id);
  570. $delete_items = $new_items = [];
  571. if (!empty($list)) {
  572. foreach ($list as $session_id) {
  573. if (!in_array($session_id, $current_list)) {
  574. $new_items[] = $session_id;
  575. }
  576. }
  577. }
  578. if ($deleteCurrentSessions) {
  579. if (!empty($current_list)) {
  580. foreach ($current_list as $session_id) {
  581. if (!in_array($session_id, $list)) {
  582. $delete_items[] = $session_id;
  583. }
  584. }
  585. }
  586. // Deleting items
  587. if (!empty($delete_items)) {
  588. foreach ($delete_items as $session_id) {
  589. if (!empty($user_list)) {
  590. foreach ($user_list as $user_id) {
  591. SessionManager::unsubscribe_user_from_session($session_id, $user_id);
  592. }
  593. }
  594. Database::delete(
  595. $this->usergroup_rel_session_table,
  596. ['usergroup_id = ? AND session_id = ?' => [$usergroup_id, $session_id]]
  597. );
  598. }
  599. }
  600. }
  601. // Adding new relationships.
  602. if (!empty($new_items)) {
  603. foreach ($new_items as $session_id) {
  604. $params = ['session_id' => $session_id, 'usergroup_id' => $usergroup_id];
  605. Database::insert($this->usergroup_rel_session_table, $params);
  606. if (!empty($user_list)) {
  607. SessionManager::subscribe_users_to_session(
  608. $session_id,
  609. $user_list,
  610. null,
  611. false
  612. );
  613. }
  614. }
  615. }
  616. }
  617. /**
  618. * Subscribes courses to a group (also adding the members of the group in the course)
  619. * @param int $usergroup_id usergroup id
  620. * @param array $list list of course ids (integers)
  621. * @param bool $delete_groups
  622. */
  623. public function subscribe_courses_to_usergroup($usergroup_id, $list, $delete_groups = true)
  624. {
  625. $current_list = self::get_courses_by_usergroup($usergroup_id);
  626. $user_list = self::get_users_by_usergroup($usergroup_id);
  627. $delete_items = $new_items = [];
  628. if (!empty($list)) {
  629. foreach ($list as $id) {
  630. if (!in_array($id, $current_list)) {
  631. $new_items[] = $id;
  632. }
  633. }
  634. }
  635. if (!empty($current_list)) {
  636. foreach ($current_list as $id) {
  637. if (!in_array($id, $list)) {
  638. $delete_items[] = $id;
  639. }
  640. }
  641. }
  642. if ($delete_groups) {
  643. self::unsubscribe_courses_from_usergroup($usergroup_id, $delete_items);
  644. }
  645. // Adding new relationships
  646. if (!empty($new_items)) {
  647. foreach ($new_items as $course_id) {
  648. $course_info = api_get_course_info_by_id($course_id);
  649. if ($course_info) {
  650. if (!empty($user_list)) {
  651. foreach ($user_list as $user_id) {
  652. CourseManager::subscribe_user(
  653. $user_id,
  654. $course_info['code']
  655. );
  656. }
  657. }
  658. $params = [
  659. 'course_id' => $course_id,
  660. 'usergroup_id' => $usergroup_id,
  661. ];
  662. Database::insert(
  663. $this->usergroup_rel_course_table,
  664. $params
  665. );
  666. }
  667. }
  668. }
  669. }
  670. /**
  671. * @param int $usergroup_id
  672. * @param array $delete_items
  673. */
  674. public function unsubscribe_courses_from_usergroup($usergroup_id, $delete_items)
  675. {
  676. // Deleting items.
  677. if (!empty($delete_items)) {
  678. $user_list = self::get_users_by_usergroup($usergroup_id);
  679. foreach ($delete_items as $course_id) {
  680. $course_info = api_get_course_info_by_id($course_id);
  681. if ($course_info) {
  682. if (!empty($user_list)) {
  683. foreach ($user_list as $user_id) {
  684. CourseManager::unsubscribe_user(
  685. $user_id,
  686. $course_info['code']
  687. );
  688. }
  689. }
  690. Database::delete(
  691. $this->usergroup_rel_course_table,
  692. [
  693. 'usergroup_id = ? AND course_id = ?' => [
  694. $usergroup_id,
  695. $course_id
  696. ]
  697. ]
  698. );
  699. }
  700. }
  701. }
  702. }
  703. /**
  704. * Subscribe users to a group
  705. * @param int $usergroup_id usergroup id
  706. * @param array $list list of user ids
  707. * @param bool $delete_users_not_present_in_list
  708. * @param int $relationType
  709. */
  710. public function subscribe_users_to_usergroup(
  711. $usergroup_id,
  712. $list,
  713. $delete_users_not_present_in_list = true,
  714. $relationType = 0
  715. ) {
  716. $current_list = self::get_users_by_usergroup($usergroup_id);
  717. $course_list = self::get_courses_by_usergroup($usergroup_id);
  718. $session_list = self::get_sessions_by_usergroup($usergroup_id);
  719. $session_list = array_filter($session_list);
  720. $relationType = (int) $relationType;
  721. $delete_items = [];
  722. $new_items = [];
  723. if (!empty($list)) {
  724. foreach ($list as $user_id) {
  725. if (!in_array($user_id, $current_list)) {
  726. $new_items[] = $user_id;
  727. }
  728. }
  729. }
  730. if (!empty($current_list)) {
  731. foreach ($current_list as $user_id) {
  732. if (!in_array($user_id, $list)) {
  733. $delete_items[] = $user_id;
  734. }
  735. }
  736. }
  737. // Deleting items
  738. if (!empty($delete_items) && $delete_users_not_present_in_list) {
  739. foreach ($delete_items as $user_id) {
  740. // Removing courses
  741. if (!empty($course_list)) {
  742. foreach ($course_list as $course_id) {
  743. $course_info = api_get_course_info_by_id($course_id);
  744. CourseManager::unsubscribe_user($user_id, $course_info['code']);
  745. }
  746. }
  747. // Removing sessions
  748. if (!empty($session_list)) {
  749. foreach ($session_list as $session_id) {
  750. SessionManager::unsubscribe_user_from_session($session_id, $user_id);
  751. }
  752. }
  753. if (empty($relationType)) {
  754. Database::delete(
  755. $this->usergroup_rel_user_table,
  756. [
  757. 'usergroup_id = ? AND user_id = ? AND (relation_type = "0" OR relation_type IS NULL OR relation_type = "")' => [
  758. $usergroup_id,
  759. $user_id,
  760. ],
  761. ]
  762. );
  763. } else {
  764. Database::delete(
  765. $this->usergroup_rel_user_table,
  766. [
  767. 'usergroup_id = ? AND user_id = ? AND relation_type = ?' => [
  768. $usergroup_id,
  769. $user_id,
  770. $relationType,
  771. ],
  772. ]
  773. );
  774. }
  775. }
  776. }
  777. // Adding new relationships
  778. if (!empty($new_items)) {
  779. // Adding sessions
  780. if (!empty($session_list)) {
  781. foreach ($session_list as $session_id) {
  782. SessionManager::subscribe_users_to_session($session_id, $new_items, null, false);
  783. }
  784. }
  785. foreach ($new_items as $user_id) {
  786. // Adding courses
  787. if (!empty($course_list)) {
  788. foreach ($course_list as $course_id) {
  789. $course_info = api_get_course_info_by_id($course_id);
  790. CourseManager::subscribe_user($user_id, $course_info['code']);
  791. }
  792. }
  793. $params = [
  794. 'user_id' => $user_id,
  795. 'usergroup_id' => $usergroup_id,
  796. 'relation_type' => $relationType,
  797. ];
  798. Database::insert($this->usergroup_rel_user_table, $params);
  799. }
  800. }
  801. }
  802. /**
  803. * @param string $name
  804. * @return bool
  805. */
  806. public function usergroup_exists($name)
  807. {
  808. $name = Database::escape_string($name);
  809. if ($this->useMultipleUrl) {
  810. $urlId = api_get_current_access_url_id();
  811. $sql = "SELECT * FROM $this->table u
  812. INNER JOIN {$this->access_url_rel_usergroup} a
  813. ON (a.usergroup_id = u.id)
  814. WHERE name = '".$name."' AND access_url_id = $urlId";
  815. } else {
  816. $sql = "SELECT * FROM $this->table WHERE name = '".$name."'";
  817. }
  818. $res = Database::query($sql);
  819. return Database::num_rows($res) != 0;
  820. }
  821. /**
  822. * @param int $sidx
  823. * @param int $sord
  824. * @param int $start
  825. * @param int $limit
  826. * @return array
  827. */
  828. public function getUsergroupsPagination($sidx, $sord, $start, $limit)
  829. {
  830. $sord = in_array(strtolower($sord), ['asc', 'desc']) ? $sord : 'desc';
  831. $start = intval($start);
  832. $limit = intval($limit);
  833. if ($this->useMultipleUrl) {
  834. $urlId = api_get_current_access_url_id();
  835. $from = $this->table." u INNER JOIN {$this->access_url_rel_usergroup} a ON (u.id = a.usergroup_id)";
  836. $where = [' access_url_id = ?' => $urlId];
  837. } else {
  838. $from = $this->table." u ";
  839. $where = [];
  840. }
  841. $result = Database::select(
  842. 'u.*',
  843. $from,
  844. [
  845. 'where' => $where,
  846. 'order' => "name $sord",
  847. 'LIMIT' => "$start , $limit"
  848. ]
  849. );
  850. $new_result = [];
  851. if (!empty($result)) {
  852. foreach ($result as $group) {
  853. $group['sessions'] = count($this->get_sessions_by_usergroup($group['id']));
  854. $group['courses'] = count($this->get_courses_by_usergroup($group['id']));
  855. $roles = [];
  856. switch ($group['group_type']) {
  857. case 0:
  858. $group['group_type'] = Display::label(get_lang('Class'), 'info');
  859. $roles = [0];
  860. break;
  861. case 1:
  862. $group['group_type'] = Display::label(get_lang('Social'), 'success');
  863. $roles = [
  864. GROUP_USER_PERMISSION_ADMIN,
  865. GROUP_USER_PERMISSION_READER,
  866. GROUP_USER_PERMISSION_MODERATOR,
  867. GROUP_USER_PERMISSION_HRM
  868. ];
  869. break;
  870. }
  871. $group['users'] = count($this->get_users_by_usergroup($group['id'], $roles));
  872. $new_result[] = $group;
  873. }
  874. $result = $new_result;
  875. }
  876. $columns = ['name', 'users', 'courses', 'sessions', 'group_type'];
  877. if (!in_array($sidx, $columns)) {
  878. $sidx = 'name';
  879. }
  880. // Multidimensional sort
  881. $result = msort($result, $sidx, $sord);
  882. return $result;
  883. }
  884. /**
  885. * @param array $options
  886. * @return array
  887. */
  888. public function getDataToExport($options = [])
  889. {
  890. if ($this->useMultipleUrl) {
  891. $urlId = api_get_current_access_url_id();
  892. $from = $this->table." u INNER JOIN {$this->access_url_rel_usergroup} a
  893. ON (u.id = a.usergroup_id)";
  894. $options = ['where' => ['access_url_id = ? ' => $urlId]];
  895. $classes = Database::select('a.id, name, description', $from, $options);
  896. } else {
  897. $classes = Database::select('id, name, description', $this->table, $options);
  898. }
  899. $result = [];
  900. if (!empty($classes)) {
  901. foreach ($classes as $data) {
  902. $users = self::getUserListByUserGroup($data['id']);
  903. $userToString = null;
  904. if (!empty($users)) {
  905. $userNameList = [];
  906. foreach ($users as $userData) {
  907. $userNameList[] = $userData['username'];
  908. }
  909. $userToString = implode(',', $userNameList);
  910. }
  911. $data['users'] = $userToString;
  912. $result[] = $data;
  913. }
  914. }
  915. return $result;
  916. }
  917. /**
  918. * @param string $firstLetter
  919. * @return array
  920. */
  921. public function filterByFirstLetter($firstLetter)
  922. {
  923. $firstLetter = Database::escape_string($firstLetter);
  924. $sql = "SELECT id, name FROM $this->table
  925. WHERE
  926. name LIKE '".$firstLetter."%' OR
  927. name LIKE '".api_strtolower($firstLetter)."%'
  928. ORDER BY name DESC ";
  929. $result = Database::query($sql);
  930. return Database::store_result($result);
  931. }
  932. /**
  933. * Select user group not in list
  934. * @param array $list
  935. * @return array
  936. */
  937. public function getUserGroupNotInList($list)
  938. {
  939. if (empty($list)) {
  940. return [];
  941. }
  942. $list = array_map('intval', $list);
  943. $listToString = implode("','", $list);
  944. $sql = "SELECT * FROM {$this->table} WHERE id NOT IN ('$listToString')";
  945. $result = Database::query($sql);
  946. return Database::store_result($result, 'ASSOC');
  947. }
  948. /**
  949. * @param $params
  950. * @param bool $show_query
  951. * @return bool|int
  952. */
  953. public function save($params, $show_query = false)
  954. {
  955. $params['updated_at'] = $params['created_at'] = api_get_utc_datetime();
  956. $params['group_type'] = isset($params['group_type']) ? self::SOCIAL_CLASS : self::NORMAL_CLASS;
  957. $params['allow_members_leave_group'] = isset($params['allow_members_leave_group']) ? 1 : 0;
  958. $groupExists = $this->usergroup_exists(trim($params['name']));
  959. if ($groupExists == false) {
  960. $id = parent::save($params, $show_query);
  961. if ($id) {
  962. if ($this->useMultipleUrl) {
  963. $this->subscribeToUrl($id, api_get_current_access_url_id());
  964. }
  965. if ($params['group_type'] == self::SOCIAL_CLASS) {
  966. $this->add_user_to_group(
  967. api_get_user_id(),
  968. $id,
  969. $params['group_type']
  970. );
  971. }
  972. $picture = isset($_FILES['picture']) ? $_FILES['picture'] : null;
  973. $picture = $this->manageFileUpload($id, $picture);
  974. if ($picture) {
  975. $params = [
  976. 'id' => $id,
  977. 'picture' => $picture,
  978. 'group_type' => $params['group_type']
  979. ];
  980. $this->update($params);
  981. }
  982. }
  983. return $id;
  984. }
  985. return false;
  986. }
  987. /**
  988. * @inheritdoc
  989. */
  990. public function update($values, $showQuery = false)
  991. {
  992. $values['updated_on'] = api_get_utc_datetime();
  993. $values['group_type'] = isset($values['group_type']) ? self::SOCIAL_CLASS : self::NORMAL_CLASS;
  994. $values['allow_members_leave_group'] = isset($values['allow_members_leave_group']) ? 1 : 0;
  995. if (isset($values['id'])) {
  996. $picture = isset($_FILES['picture']) ? $_FILES['picture'] : null;
  997. if (!empty($picture)) {
  998. $picture = $this->manageFileUpload($values['id'], $picture);
  999. if ($picture) {
  1000. $values['picture'] = $picture;
  1001. }
  1002. }
  1003. if (isset($values['delete_picture'])) {
  1004. $values['picture'] = null;
  1005. }
  1006. }
  1007. parent::update($values, $showQuery);
  1008. if (isset($values['delete_picture'])) {
  1009. $this->delete_group_picture($values['id']);
  1010. }
  1011. return true;
  1012. }
  1013. /**
  1014. * @param int $groupId
  1015. * @param string $picture
  1016. *
  1017. * @return bool|string
  1018. */
  1019. public function manageFileUpload($groupId, $picture)
  1020. {
  1021. if (!empty($picture['name'])) {
  1022. return $this->update_group_picture(
  1023. $groupId,
  1024. $picture['name'],
  1025. $picture['tmp_name']
  1026. );
  1027. }
  1028. return false;
  1029. }
  1030. /**
  1031. * @param $group_id
  1032. * @return string
  1033. */
  1034. public function delete_group_picture($group_id)
  1035. {
  1036. return self::update_group_picture($group_id);
  1037. }
  1038. /**
  1039. * Creates new group pictures in various sizes of a user, or deletes user pfotos.
  1040. * Note: This method relies on configuration setting from main/inc/conf/profile.conf.php
  1041. * @param int The group id
  1042. * @param string $file The common file name for the newly created photos.
  1043. * It will be checked and modified for compatibility with the file system.
  1044. * If full name is provided, path component is ignored.
  1045. * If an empty name is provided, then old user photos are deleted only,
  1046. * @see UserManager::delete_user_picture() as the prefered way for deletion.
  1047. * @param string $source_file The full system name of the image from which user photos will be created.
  1048. * @return mixed Returns the resulting common file name of created images which usually should be stored in database.
  1049. * When an image is removed the function returns an empty string. In case of internal error or negative validation it returns FALSE.
  1050. */
  1051. public function update_group_picture($group_id, $file = null, $source_file = null)
  1052. {
  1053. // Validation 1.
  1054. if (empty($group_id)) {
  1055. return false;
  1056. }
  1057. $delete = empty($file);
  1058. if (empty($source_file)) {
  1059. $source_file = $file;
  1060. }
  1061. // User-reserved directory where photos have to be placed.
  1062. $path_info = self::get_group_picture_path_by_id($group_id, 'system', true);
  1063. $path = $path_info['dir'];
  1064. // If this directory does not exist - we create it.
  1065. if (!file_exists($path)) {
  1066. @mkdir($path, api_get_permissions_for_new_directories(), true);
  1067. }
  1068. // The old photos (if any).
  1069. $old_file = $path_info['file'];
  1070. // Let us delete them.
  1071. if (!empty($old_file)) {
  1072. if (KEEP_THE_OLD_IMAGE_AFTER_CHANGE) {
  1073. $prefix = 'saved_'.date('Y_m_d_H_i_s').'_'.uniqid('').'_';
  1074. @rename($path.'small_'.$old_file, $path.$prefix.'small_'.$old_file);
  1075. @rename($path.'medium_'.$old_file, $path.$prefix.'medium_'.$old_file);
  1076. @rename($path.'big_'.$old_file, $path.$prefix.'big_'.$old_file);
  1077. @rename($path.$old_file, $path.$prefix.$old_file);
  1078. } else {
  1079. @unlink($path.'small_'.$old_file);
  1080. @unlink($path.'medium_'.$old_file);
  1081. @unlink($path.'big_'.$old_file);
  1082. @unlink($path.$old_file);
  1083. }
  1084. }
  1085. // Exit if only deletion has been requested. Return an empty picture name.
  1086. if ($delete) {
  1087. return '';
  1088. }
  1089. // Validation 2.
  1090. $allowed_types = ['jpg', 'jpeg', 'png', 'gif'];
  1091. $file = str_replace('\\', '/', $file);
  1092. $filename = (($pos = strrpos($file, '/')) !== false) ? substr($file, $pos + 1) : $file;
  1093. $extension = strtolower(substr(strrchr($filename, '.'), 1));
  1094. if (!in_array($extension, $allowed_types)) {
  1095. return false;
  1096. }
  1097. // This is the common name for the new photos.
  1098. if (KEEP_THE_NAME_WHEN_CHANGE_IMAGE && !empty($old_file)) {
  1099. $old_extension = strtolower(substr(strrchr($old_file, '.'), 1));
  1100. $filename = in_array($old_extension, $allowed_types) ? substr($old_file, 0, -strlen($old_extension)) : $old_file;
  1101. $filename = (substr($filename, -1) == '.') ? $filename.$extension : $filename.'.'.$extension;
  1102. } else {
  1103. $filename = api_replace_dangerous_char($filename);
  1104. if (PREFIX_IMAGE_FILENAME_WITH_UID) {
  1105. $filename = uniqid('').'_'.$filename;
  1106. }
  1107. // We always prefix user photos with user ids, so on setting
  1108. // api_get_setting('split_users_upload_directory') === 'true'
  1109. // the correspondent directories to be found successfully.
  1110. $filename = $group_id.'_'.$filename;
  1111. }
  1112. // Storing the new photos in 4 versions with various sizes.
  1113. /*$image->resize(
  1114. // get original size and set width (widen) or height (heighten).
  1115. // width or height will be set maintaining aspect ratio.
  1116. $image->getSize()->widen( 700 )
  1117. );*/
  1118. // Usign the Imagine service
  1119. $imagine = new Imagine\Gd\Imagine();
  1120. $image = $imagine->open($source_file);
  1121. $options = [
  1122. 'quality' => 90,
  1123. ];
  1124. //$image->resize(new Imagine\Image\Box(200, 200))->save($path.'big_'.$filename);
  1125. $image->resize($image->getSize()->widen(200))->save($path.'big_'.$filename, $options);
  1126. $image = $imagine->open($source_file);
  1127. $image->resize(new Imagine\Image\Box(85, 85))->save($path.'medium_'.$filename, $options);
  1128. $image = $imagine->open($source_file);
  1129. $image->resize(new Imagine\Image\Box(22, 22))->save($path.'small_'.$filename);
  1130. /*
  1131. $small = self::resize_picture($source_file, 22);
  1132. $medium = self::resize_picture($source_file, 85);
  1133. $normal = self::resize_picture($source_file, 200);
  1134. $big = new Image($source_file); // This is the original picture.
  1135. $ok = $small && $small->send_image($path.'small_'.$filename)
  1136. && $medium && $medium->send_image($path.'medium_'.$filename)
  1137. && $normal && $normal->send_image($path.'big_'.$filename)
  1138. && $big && $big->send_image($path.$filename);
  1139. return $ok ? $filename : false;*/
  1140. return $filename;
  1141. }
  1142. /**
  1143. * @return mixed
  1144. */
  1145. public function getGroupType()
  1146. {
  1147. return $this->groupType;
  1148. }
  1149. /**
  1150. * @param int $id
  1151. * @return bool|void
  1152. */
  1153. public function delete($id)
  1154. {
  1155. $id = (int) $id;
  1156. if ($this->useMultipleUrl) {
  1157. $this->unsubscribeToUrl($id, api_get_current_access_url_id());
  1158. }
  1159. $sql = "DELETE FROM $this->usergroup_rel_user_table
  1160. WHERE usergroup_id = $id";
  1161. Database::query($sql);
  1162. $sql = "DELETE FROM $this->usergroup_rel_course_table
  1163. WHERE usergroup_id = $id";
  1164. Database::query($sql);
  1165. $sql = "DELETE FROM $this->usergroup_rel_session_table
  1166. WHERE usergroup_id = $id";
  1167. Database::query($sql);
  1168. /*$sql = "DELETE FROM $this->usergroup_rel_
  1169. WHERE usergroup_id = $id";
  1170. Database::query($sql);*/
  1171. parent::delete($id);
  1172. }
  1173. /**
  1174. * @param int $id
  1175. * @param int $urlId
  1176. */
  1177. public function subscribeToUrl($id, $urlId)
  1178. {
  1179. Database::insert(
  1180. $this->access_url_rel_usergroup,
  1181. [
  1182. 'access_url_id' => $urlId,
  1183. 'usergroup_id' =>$id
  1184. ]
  1185. );
  1186. }
  1187. /**
  1188. * @param int $id
  1189. * @param int $urlId
  1190. */
  1191. public function unsubscribeToUrl($id, $urlId)
  1192. {
  1193. Database::delete(
  1194. $this->access_url_rel_usergroup,
  1195. [
  1196. 'access_url_id = ? AND usergroup_id = ? ' => [$urlId, $id]
  1197. ]
  1198. );
  1199. }
  1200. /**
  1201. * @param $needle
  1202. * @return xajaxResponse
  1203. */
  1204. public static function searchUserGroupAjax($needle)
  1205. {
  1206. $response = new xajaxResponse();
  1207. $return = '';
  1208. if (!empty($needle)) {
  1209. // xajax send utf8 datas... datas in db can be non-utf8 datas
  1210. $charset = api_get_system_encoding();
  1211. $needle = api_convert_encoding($needle, $charset, 'utf-8');
  1212. $needle = Database::escape_string($needle);
  1213. // search courses where username or firstname or lastname begins likes $needle
  1214. $sql = 'SELECT id, name
  1215. FROM '.Database::get_main_table(TABLE_USERGROUP).' u
  1216. WHERE name LIKE "'.$needle.'%"
  1217. ORDER BY name
  1218. LIMIT 11';
  1219. $result = Database::query($sql);
  1220. $i = 0;
  1221. while ($data = Database::fetch_array($result)) {
  1222. $i++;
  1223. if ($i <= 10) {
  1224. $return .= '<a
  1225. href="javascript: void(0);"
  1226. onclick="javascript: add_user_to_url(\''.addslashes($data['id']).'\',\''.addslashes($data['name']).' \')">'.$data['name'].' </a><br />';
  1227. } else {
  1228. $return .= '...<br />';
  1229. }
  1230. }
  1231. }
  1232. $response->addAssign('ajax_list_courses', 'innerHTML', api_utf8_encode($return));
  1233. return $response;
  1234. }
  1235. /**
  1236. * Get user list by usergroup
  1237. * @param int $id
  1238. * @return array
  1239. */
  1240. public function getUserListByUserGroup($id)
  1241. {
  1242. $id = (int) $id;
  1243. $sql = "SELECT u.* FROM ".$this->table_user." u
  1244. INNER JOIN ".$this->usergroup_rel_user_table." c
  1245. ON c.user_id = u.id
  1246. WHERE c.usergroup_id = $id"
  1247. ;
  1248. $result = Database::query($sql);
  1249. return Database::store_result($result);
  1250. }
  1251. /**
  1252. * @param FormValidator $form
  1253. * @param string $type
  1254. * @param array $data
  1255. */
  1256. public function setForm($form, $type = 'add', $data = [])
  1257. {
  1258. switch ($type) {
  1259. case 'add':
  1260. $header = get_lang('Add');
  1261. break;
  1262. case 'edit':
  1263. $header = get_lang('Edit');
  1264. break;
  1265. }
  1266. $form->addElement('header', $header);
  1267. //Name
  1268. $form->addElement('text', 'name', get_lang('Name'), ['maxlength'=>255]);
  1269. $form->applyFilter('name', 'trim');
  1270. $form->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
  1271. $form->addRule('name', '', 'maxlength', 255);
  1272. // Description
  1273. $form->addTextarea('description', get_lang('Description'), ['cols' => 58]);
  1274. $form->applyFilter('description', 'trim');
  1275. if ($this->showGroupTypeSetting) {
  1276. $form->addElement(
  1277. 'checkbox',
  1278. 'group_type',
  1279. null,
  1280. get_lang('SocialGroup')
  1281. );
  1282. }
  1283. // url
  1284. $form->addElement('text', 'url', get_lang('Url'));
  1285. $form->applyFilter('url', 'trim');
  1286. // Picture
  1287. $allowed_picture_types = $this->getAllowedPictureExtensions();
  1288. $form->addElement('file', 'picture', get_lang('AddPicture'));
  1289. $form->addRule(
  1290. 'picture',
  1291. get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')',
  1292. 'filetype',
  1293. $allowed_picture_types
  1294. );
  1295. if (isset($data['picture']) && strlen($data['picture']) > 0) {
  1296. $picture = $this->get_picture_group($data['id'], $data['picture'], 80);
  1297. $img = '<img src="'.$picture['file'].'" />';
  1298. $form->addElement('label', null, $img);
  1299. $form->addElement('checkbox', 'delete_picture', '', get_lang('DelImage'));
  1300. }
  1301. $form->addElement('select', 'visibility', get_lang('GroupPermissions'), $this->getGroupStatusList());
  1302. $form->setRequiredNote('<span class="form_required">*</span> <small>'.get_lang('ThisFieldIsRequired').'</small>');
  1303. $form->addElement('checkbox', 'allow_members_leave_group', '', get_lang('AllowMemberLeaveGroup'));
  1304. // Setting the form elements
  1305. if ($type === 'add') {
  1306. $form->addButtonCreate($header);
  1307. } else {
  1308. $form->addButtonUpdate($header);
  1309. }
  1310. }
  1311. /**
  1312. * Gets the current group image
  1313. * @param string $id group id
  1314. * @param string picture group name
  1315. * @param string height
  1316. * @param string picture size it can be small_, medium_ or big_
  1317. * @param string style css
  1318. * @return array with the file and the style of an image i.e $array['file'] $array['style']
  1319. */
  1320. public function get_picture_group(
  1321. $id,
  1322. $picture_file,
  1323. $height,
  1324. $size_picture = GROUP_IMAGE_SIZE_MEDIUM,
  1325. $style = ''
  1326. ) {
  1327. $picture = [];
  1328. //$picture['style'] = $style;
  1329. if ($picture_file === 'unknown.jpg') {
  1330. $picture['file'] = Display::returnIconPath($picture_file);
  1331. return $picture;
  1332. }
  1333. switch ($size_picture) {
  1334. case GROUP_IMAGE_SIZE_ORIGINAL:
  1335. $size_picture = '';
  1336. break;
  1337. case GROUP_IMAGE_SIZE_BIG:
  1338. $size_picture = 'big_';
  1339. break;
  1340. case GROUP_IMAGE_SIZE_MEDIUM:
  1341. $size_picture = 'medium_';
  1342. break;
  1343. case GROUP_IMAGE_SIZE_SMALL:
  1344. $size_picture = 'small_';
  1345. break;
  1346. default:
  1347. $size_picture = 'medium_';
  1348. }
  1349. $image_array_sys = $this->get_group_picture_path_by_id($id, 'system', false, true);
  1350. $image_array = $this->get_group_picture_path_by_id($id, 'web', false, true);
  1351. $file = $image_array_sys['dir'].$size_picture.$picture_file;
  1352. if (file_exists($file)) {
  1353. $picture['file'] = $image_array['dir'].$size_picture.$picture_file;
  1354. //$picture['style'] = '';
  1355. if ($height > 0) {
  1356. $dimension = api_getimagesize($picture['file']);
  1357. $margin = ($height - $dimension['width']) / 2;
  1358. //@ todo the padding-top should not be here
  1359. }
  1360. } else {
  1361. $file = $image_array_sys['dir'].$picture_file;
  1362. if (file_exists($file) && !is_dir($file)) {
  1363. $picture['file'] = $image_array['dir'].$picture_file;
  1364. } else {
  1365. $picture['file'] = Display::returnIconPath('group_na.png', 64);
  1366. }
  1367. }
  1368. return $picture;
  1369. }
  1370. /**
  1371. * Gets the group picture URL or path from group ID (returns an array).
  1372. * The return format is a complete path, enabling recovery of the directory
  1373. * with dirname() or the file with basename(). This also works for the
  1374. * functions dealing with the user's productions, as they are located in
  1375. * the same directory.
  1376. * @param integer User ID
  1377. * @param string Type of path to return (can be 'none', 'system', 'rel', 'web')
  1378. * @param bool Whether we want to have the directory name returned 'as if'
  1379. * there was a file or not (in the case we want to know which directory to create -
  1380. * otherwise no file means no split subdir)
  1381. * @param bool If we want that the function returns the /main/img/unknown.jpg image set it at true
  1382. * @return array Array of 2 elements: 'dir' and 'file' which contain the dir
  1383. * and file as the name implies if image does not exist it will return the unknown
  1384. * image if anonymous parameter is true if not it returns an empty er's
  1385. */
  1386. public function get_group_picture_path_by_id($id, $type = 'none', $preview = false, $anonymous = false)
  1387. {
  1388. switch ($type) {
  1389. case 'system': // Base: absolute system path.
  1390. $base = api_get_path(SYS_UPLOAD_PATH);
  1391. break;
  1392. case 'rel': // Base: semi-absolute web path (no server base).
  1393. $base = api_get_path(REL_CODE_PATH);
  1394. break;
  1395. case 'web': // Base: absolute web path.
  1396. $base = api_get_path(WEB_UPLOAD_PATH);
  1397. break;
  1398. case 'none':
  1399. default: // Base: empty, the result path below will be relative.
  1400. $base = '';
  1401. }
  1402. if (empty($id) || empty($type)) {
  1403. return $anonymous ? ['dir' => $base.'img/', 'file' => 'unknown.jpg'] : ['dir' => '', 'file' => ''];
  1404. }
  1405. $id = intval($id);
  1406. $group_table = Database::get_main_table(TABLE_USERGROUP);
  1407. $sql = "SELECT picture FROM $group_table WHERE id = ".$id;
  1408. $res = Database::query($sql);
  1409. if (!Database::num_rows($res)) {
  1410. return $anonymous ? ['dir' => $base.'img/', 'file' => 'unknown.jpg'] : ['dir' => '', 'file' => ''];
  1411. }
  1412. $user = Database::fetch_array($res);
  1413. $picture_filename = trim($user['picture']);
  1414. if (api_get_setting('split_users_upload_directory') === 'true') {
  1415. if (!empty($picture_filename)) {
  1416. $dir = $base.'groups/'.substr($picture_filename, 0, 1).'/'.$id.'/';
  1417. } elseif ($preview) {
  1418. $dir = $base.'groups/'.substr((string) $id, 0, 1).'/'.$id.'/';
  1419. } else {
  1420. $dir = $base.'groups/'.$id.'/';
  1421. }
  1422. } else {
  1423. $dir = $base.'groups/'.$id.'/';
  1424. }
  1425. return ['dir' => $dir, 'file' => $picture_filename];
  1426. }
  1427. /**
  1428. * @return array
  1429. */
  1430. public function getAllowedPictureExtensions()
  1431. {
  1432. return ['jpg', 'jpeg', 'png', 'gif'];
  1433. }
  1434. /**
  1435. * @return array
  1436. */
  1437. public function getGroupStatusList()
  1438. {
  1439. $status = [
  1440. GROUP_PERMISSION_OPEN => get_lang('Open'),
  1441. GROUP_PERMISSION_CLOSED => get_lang('Closed')
  1442. ];
  1443. return $status;
  1444. }
  1445. /**
  1446. * @param int $type
  1447. */
  1448. public function setGroupType($type)
  1449. {
  1450. $this->groupType = intval($type);
  1451. }
  1452. /**
  1453. * @param int $group_id
  1454. * @param int $user_id
  1455. * @return bool
  1456. */
  1457. public function is_group_admin($group_id, $user_id = 0)
  1458. {
  1459. if (empty($user_id)) {
  1460. $user_id = api_get_user_id();
  1461. }
  1462. $user_role = $this->get_user_group_role($user_id, $group_id);
  1463. if (in_array($user_role, [GROUP_USER_PERMISSION_ADMIN])) {
  1464. return true;
  1465. } else {
  1466. return false;
  1467. }
  1468. }
  1469. /**
  1470. * @param int $group_id
  1471. * @param int $user_id
  1472. * @return bool
  1473. */
  1474. public function isGroupModerator($group_id, $user_id = 0)
  1475. {
  1476. if (empty($user_id)) {
  1477. $user_id = api_get_user_id();
  1478. }
  1479. $user_role = $this->get_user_group_role($user_id, $group_id);
  1480. if (in_array($user_role, [GROUP_USER_PERMISSION_ADMIN, GROUP_USER_PERMISSION_MODERATOR])) {
  1481. return true;
  1482. } else {
  1483. return false;
  1484. }
  1485. }
  1486. /**
  1487. * @param int $group_id
  1488. * @param int $user_id
  1489. * @return bool
  1490. */
  1491. public function is_group_member($group_id, $user_id = 0)
  1492. {
  1493. if (api_is_platform_admin()) {
  1494. return true;
  1495. }
  1496. if (empty($user_id)) {
  1497. $user_id = api_get_user_id();
  1498. }
  1499. $roles = [
  1500. GROUP_USER_PERMISSION_ADMIN,
  1501. GROUP_USER_PERMISSION_MODERATOR,
  1502. GROUP_USER_PERMISSION_READER,
  1503. GROUP_USER_PERMISSION_HRM,
  1504. ];
  1505. $user_role = self::get_user_group_role($user_id, $group_id);
  1506. if (in_array($user_role, $roles)) {
  1507. return true;
  1508. } else {
  1509. return false;
  1510. }
  1511. }
  1512. /**
  1513. * Gets the relationship between a group and a User
  1514. * @author Julio Montoya
  1515. * @param int $user_id
  1516. * @param int $group_id
  1517. * @return int 0 if there are not relationship otherwise returns the user group
  1518. * */
  1519. public function get_user_group_role($user_id, $group_id)
  1520. {
  1521. $table_group_rel_user = $this->usergroup_rel_user_table;
  1522. $return_value = 0;
  1523. if (!empty($user_id) && !empty($group_id)) {
  1524. $sql = "SELECT relation_type FROM $table_group_rel_user
  1525. WHERE
  1526. usergroup_id = ".intval($group_id)." AND
  1527. user_id = ".intval($user_id)." ";
  1528. $result = Database::query($sql);
  1529. if (Database::num_rows($result) > 0) {
  1530. $row = Database::fetch_array($result, 'ASSOC');
  1531. $return_value = $row['relation_type'];
  1532. }
  1533. }
  1534. return $return_value;
  1535. }
  1536. /**
  1537. * @param int $userId
  1538. * @param int $groupId
  1539. * @return string
  1540. */
  1541. public function getUserRoleToString($userId, $groupId)
  1542. {
  1543. $role = self::get_user_group_role($userId, $groupId);
  1544. $roleToString = '';
  1545. switch ($role) {
  1546. case GROUP_USER_PERMISSION_ADMIN:
  1547. $roleToString = get_lang('Admin');
  1548. break;
  1549. case GROUP_USER_PERMISSION_READER:
  1550. $roleToString = get_lang('Reader');
  1551. break;
  1552. case GROUP_USER_PERMISSION_PENDING_INVITATION:
  1553. $roleToString = get_lang('PendingInvitation');
  1554. break;
  1555. case GROUP_USER_PERMISSION_MODERATOR:
  1556. $roleToString = get_lang('Moderator');
  1557. break;
  1558. case GROUP_USER_PERMISSION_HRM:
  1559. $roleToString = get_lang('Drh');
  1560. break;
  1561. }
  1562. return $roleToString;
  1563. }
  1564. /**
  1565. * Add a group of users into a group of URLs
  1566. * @author Julio Montoya
  1567. * @param array $user_list
  1568. * @param array $group_list
  1569. * @param int $relation_type
  1570. *
  1571. * @return array
  1572. **/
  1573. public function add_users_to_groups($user_list, $group_list, $relation_type = GROUP_USER_PERMISSION_READER)
  1574. {
  1575. $table_url_rel_group = $this->usergroup_rel_user_table;
  1576. $result_array = [];
  1577. $relation_type = intval($relation_type);
  1578. if (is_array($user_list) && is_array($group_list)) {
  1579. foreach ($group_list as $group_id) {
  1580. foreach ($user_list as $user_id) {
  1581. $role = self::get_user_group_role($user_id, $group_id);
  1582. if ($role == 0) {
  1583. $sql = "INSERT INTO $table_url_rel_group
  1584. SET
  1585. user_id = ".intval($user_id).",
  1586. usergroup_id = ".intval($group_id).",
  1587. relation_type = ".intval($relation_type);
  1588. $result = Database::query($sql);
  1589. if ($result) {
  1590. $result_array[$group_id][$user_id] = 1;
  1591. } else {
  1592. $result_array[$group_id][$user_id] = 0;
  1593. }
  1594. }
  1595. }
  1596. }
  1597. }
  1598. return $result_array;
  1599. }
  1600. /**
  1601. * Deletes an url and session relationship
  1602. * @author Julio Montoya
  1603. * @param int $user_id
  1604. * @param int $group_id
  1605. * @return boolean true if success
  1606. * */
  1607. public function delete_user_rel_group($user_id, $group_id)
  1608. {
  1609. $table = $this->usergroup_rel_user_table;
  1610. $sql = "DELETE FROM $table
  1611. WHERE
  1612. user_id = ".intval($user_id)." AND
  1613. usergroup_id = ".intval($group_id)." ";
  1614. $result = Database::query($sql);
  1615. return $result;
  1616. }
  1617. /**
  1618. * Add a user into a group
  1619. * @author Julio Montoya
  1620. * @param int $user_id
  1621. * @param int $group_id
  1622. * @param int $relation_type
  1623. *
  1624. * @return boolean true if success
  1625. **/
  1626. public function add_user_to_group($user_id, $group_id, $relation_type = GROUP_USER_PERMISSION_READER)
  1627. {
  1628. $table_url_rel_group = $this->usergroup_rel_user_table;
  1629. if (!empty($user_id) && !empty($group_id)) {
  1630. $role = self::get_user_group_role($user_id, $group_id);
  1631. if ($role == 0) {
  1632. $sql = "INSERT INTO $table_url_rel_group
  1633. SET
  1634. user_id = ".intval($user_id).",
  1635. usergroup_id = ".intval($group_id).",
  1636. relation_type = ".intval($relation_type);
  1637. Database::query($sql);
  1638. } elseif ($role == GROUP_USER_PERMISSION_PENDING_INVITATION) {
  1639. //if somebody already invited me I can be added
  1640. self::update_user_role($user_id, $group_id, GROUP_USER_PERMISSION_READER);
  1641. }
  1642. }
  1643. return true;
  1644. }
  1645. /**
  1646. * Updates the group_rel_user table with a given user and group ids
  1647. * @author Julio Montoya
  1648. * @param int $user_id
  1649. * @param int $group_id
  1650. * @param int $relation_type
  1651. **/
  1652. public function update_user_role($user_id, $group_id, $relation_type = GROUP_USER_PERMISSION_READER)
  1653. {
  1654. $table_group_rel_user = $this->usergroup_rel_user_table;
  1655. $group_id = intval($group_id);
  1656. $user_id = intval($user_id);
  1657. $sql = "UPDATE $table_group_rel_user
  1658. SET relation_type = ".intval($relation_type)."
  1659. WHERE user_id = $user_id AND usergroup_id = $group_id";
  1660. Database::query($sql);
  1661. }
  1662. /**
  1663. * Gets the inner join from users and group table
  1664. *
  1665. * @return array Database::store_result of the result
  1666. *
  1667. * @author Julio Montoya
  1668. * */
  1669. public function get_groups_by_user($user_id = '', $relation_type = GROUP_USER_PERMISSION_READER, $with_image = false)
  1670. {
  1671. $table_group_rel_user = $this->usergroup_rel_user_table;
  1672. $tbl_group = $this->table;
  1673. if ($relation_type == 0) {
  1674. $relationCondition = '';
  1675. } else {
  1676. $relation_type = intval($relation_type);
  1677. $relationCondition = " AND gu.relation_type = $relation_type ";
  1678. }
  1679. $sql = "SELECT
  1680. g.picture,
  1681. g.name,
  1682. g.description,
  1683. g.id ,
  1684. gu.relation_type
  1685. FROM $tbl_group g
  1686. INNER JOIN $table_group_rel_user gu
  1687. ON gu.usergroup_id = g.id
  1688. WHERE
  1689. g.group_type = ".self::SOCIAL_CLASS." AND
  1690. gu.user_id = $user_id
  1691. $relationCondition
  1692. ORDER BY created_at DESC ";
  1693. $result = Database::query($sql);
  1694. $array = [];
  1695. if (Database::num_rows($result) > 0) {
  1696. while ($row = Database::fetch_array($result, 'ASSOC')) {
  1697. if ($with_image) {
  1698. $picture = self::get_picture_group($row['id'], $row['picture'], 80);
  1699. $img = '<img src="'.$picture['file'].'" />';
  1700. $row['picture'] = $img;
  1701. }
  1702. $array[$row['id']] = $row;
  1703. }
  1704. }
  1705. return $array;
  1706. }
  1707. /** Gets the inner join of users and group table
  1708. * @param int quantity of records
  1709. * @param bool show groups with image or not
  1710. * @return array with group content
  1711. * @author Julio Montoya
  1712. * */
  1713. public function get_groups_by_popularity($num = 6, $with_image = true)
  1714. {
  1715. $table_group_rel_user = $this->usergroup_rel_user_table;
  1716. $tbl_group = $this->table;
  1717. if (empty($num)) {
  1718. $num = 6;
  1719. } else {
  1720. $num = intval($num);
  1721. }
  1722. // only show admins and readers
  1723. $where_relation_condition = " WHERE g.group_type = ".self::SOCIAL_CLASS." AND
  1724. gu.relation_type IN ('".GROUP_USER_PERMISSION_ADMIN."' , '".GROUP_USER_PERMISSION_READER."', '".GROUP_USER_PERMISSION_HRM."') ";
  1725. $sql = "SELECT DISTINCT count(user_id) as count, g.picture, g.name, g.description, g.id
  1726. FROM $tbl_group g
  1727. INNER JOIN $table_group_rel_user gu
  1728. ON gu.usergroup_id = g.id $where_relation_condition
  1729. GROUP BY g.id
  1730. ORDER BY count DESC
  1731. LIMIT $num";
  1732. $result = Database::query($sql);
  1733. $array = [];
  1734. while ($row = Database::fetch_array($result, 'ASSOC')) {
  1735. if ($with_image) {
  1736. $picture = self::get_picture_group($row['id'], $row['picture'], 80);
  1737. $img = '<img src="'.$picture['file'].'" />';
  1738. $row['picture'] = $img;
  1739. }
  1740. if (empty($row['id'])) {
  1741. continue;
  1742. }
  1743. $array[$row['id']] = $row;
  1744. }
  1745. return $array;
  1746. }
  1747. /** Gets the last groups created
  1748. * @param int $num quantity of records
  1749. * @param bool $with_image show groups with image or not
  1750. * @return array with group content
  1751. * @author Julio Montoya
  1752. * */
  1753. public function get_groups_by_age($num = 6, $with_image = true)
  1754. {
  1755. $table_group_rel_user = $this->usergroup_rel_user_table;
  1756. $tbl_group = $this->table;
  1757. if (empty($num)) {
  1758. $num = 6;
  1759. } else {
  1760. $num = intval($num);
  1761. }
  1762. $where = " WHERE
  1763. g.group_type = ".self::SOCIAL_CLASS." AND
  1764. gu.relation_type IN
  1765. ('".GROUP_USER_PERMISSION_ADMIN."' ,
  1766. '".GROUP_USER_PERMISSION_READER."',
  1767. '".GROUP_USER_PERMISSION_MODERATOR."',
  1768. '".GROUP_USER_PERMISSION_HRM."')
  1769. ";
  1770. $sql = "SELECT DISTINCT
  1771. count(user_id) as count,
  1772. g.picture,
  1773. g.name,
  1774. g.description,
  1775. g.id
  1776. FROM $tbl_group g
  1777. INNER JOIN $table_group_rel_user gu
  1778. ON gu.usergroup_id = g.id
  1779. $where
  1780. GROUP BY g.id
  1781. ORDER BY created_at DESC
  1782. LIMIT $num ";
  1783. $result = Database::query($sql);
  1784. $array = [];
  1785. while ($row = Database::fetch_array($result, 'ASSOC')) {
  1786. if ($with_image) {
  1787. $picture = self::get_picture_group($row['id'], $row['picture'], 80);
  1788. $img = '<img src="'.$picture['file'].'" />';
  1789. $row['picture'] = $img;
  1790. }
  1791. if (empty($row['id'])) {
  1792. continue;
  1793. }
  1794. $array[$row['id']] = $row;
  1795. }
  1796. return $array;
  1797. }
  1798. /**
  1799. * Gets the group's members
  1800. * @param int group id
  1801. * @param bool show image or not of the group
  1802. * @param array list of relation type use constants
  1803. * @param int from value
  1804. * @param int limit
  1805. * @param array image configuration, i.e array('height'=>'20px', 'size'=> '20px')
  1806. * @return array list of users in a group
  1807. */
  1808. public function get_users_by_group(
  1809. $group_id,
  1810. $with_image = false,
  1811. $relation_type = [],
  1812. $from = null,
  1813. $limit = null,
  1814. $image_conf = ['size' => USER_IMAGE_SIZE_MEDIUM, 'height' => 80]
  1815. ) {
  1816. $table_group_rel_user = $this->usergroup_rel_user_table;
  1817. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  1818. $group_id = intval($group_id);
  1819. if (empty($group_id)) {
  1820. return [];
  1821. }
  1822. $limit_text = '';
  1823. if (isset($from) && isset($limit)) {
  1824. $from = intval($from);
  1825. $limit = intval($limit);
  1826. $limit_text = "LIMIT $from, $limit";
  1827. }
  1828. if (count($relation_type) == 0) {
  1829. $where_relation_condition = '';
  1830. } else {
  1831. $new_relation_type = [];
  1832. foreach ($relation_type as $rel) {
  1833. $rel = intval($rel);
  1834. $new_relation_type[] = "'$rel'";
  1835. }
  1836. $relation_type = implode(',', $new_relation_type);
  1837. if (!empty($relation_type)) {
  1838. $where_relation_condition = "AND gu.relation_type IN ($relation_type) ";
  1839. }
  1840. }
  1841. $sql = "SELECT picture_uri as image, u.id, CONCAT (u.firstname,' ', u.lastname) as fullname, relation_type
  1842. FROM $tbl_user u
  1843. INNER JOIN $table_group_rel_user gu
  1844. ON (gu.user_id = u.id)
  1845. WHERE
  1846. gu.usergroup_id= $group_id
  1847. $where_relation_condition
  1848. ORDER BY relation_type, firstname
  1849. $limit_text";
  1850. $result = Database::query($sql);
  1851. $array = [];
  1852. while ($row = Database::fetch_array($result, 'ASSOC')) {
  1853. if ($with_image) {
  1854. $userInfo = api_get_user_info($row['id']);
  1855. $userPicture = UserManager::getUserPicture($row['id']);
  1856. $row['image'] = '<img src="'.$userPicture.'" />';
  1857. $row['user_info'] = $userInfo;
  1858. }
  1859. $array[$row['id']] = $row;
  1860. }
  1861. return $array;
  1862. }
  1863. /**
  1864. * Gets all the members of a group no matter the relationship for
  1865. * more specifications use get_users_by_group
  1866. * @param int group id
  1867. * @return array
  1868. */
  1869. public function get_all_users_by_group($group_id)
  1870. {
  1871. $table_group_rel_user = $this->usergroup_rel_user_table;
  1872. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  1873. $group_id = intval($group_id);
  1874. if (empty($group_id)) {
  1875. return [];
  1876. }
  1877. $sql = "SELECT u.id, u.firstname, u.lastname, relation_type
  1878. FROM $tbl_user u
  1879. INNER JOIN $table_group_rel_user gu
  1880. ON (gu.user_id = u.id)
  1881. WHERE gu.usergroup_id= $group_id
  1882. ORDER BY relation_type, firstname";
  1883. $result = Database::query($sql);
  1884. $array = [];
  1885. while ($row = Database::fetch_array($result, 'ASSOC')) {
  1886. $array[$row['id']] = $row;
  1887. }
  1888. return $array;
  1889. }
  1890. /**
  1891. * Shows the left column of the group page
  1892. * @param int group id
  1893. * @param int user id
  1894. * @return string
  1895. */
  1896. public function show_group_column_information($group_id, $user_id, $show = '')
  1897. {
  1898. $html = '';
  1899. $group_info = $this->get($group_id);
  1900. //my relation with the group is set here
  1901. $my_group_role = self::get_user_group_role($user_id, $group_id);
  1902. // Loading group permission
  1903. $links = '';
  1904. switch ($my_group_role) {
  1905. case GROUP_USER_PERMISSION_READER:
  1906. // I'm just a reader
  1907. $relation_group_title = get_lang('IAmAReader');
  1908. $links .= '<li class="'.($show == 'invite_friends' ? 'active' : '').'"><a href="group_invitation.php?id='.$group_id.'">'.
  1909. Display::return_icon('invitation_friend.png', get_lang('InviteFriends')).get_lang('InviteFriends').'</a></li>';
  1910. if (self::canLeave($group_info)) {
  1911. $links .= '<li><a href="group_view.php?id='.$group_id.'&action=leave&u='.api_get_user_id().'">'.
  1912. Display::return_icon('group_leave.png', get_lang('LeaveGroup')).get_lang('LeaveGroup').'</a></li>';
  1913. }
  1914. break;
  1915. case GROUP_USER_PERMISSION_ADMIN:
  1916. $relation_group_title = get_lang('IAmAnAdmin');
  1917. $links .= '<li class="'.($show == 'group_edit' ? 'active' : '').'"><a href="group_edit.php?id='.$group_id.'">'.
  1918. Display::return_icon('group_edit.png', get_lang('EditGroup')).get_lang('EditGroup').'</a></li>';
  1919. $links .= '<li class="'.($show == 'member_list' ? 'active' : '').'"><a href="group_waiting_list.php?id='.$group_id.'">'.
  1920. Display::return_icon('waiting_list.png', get_lang('WaitingList')).get_lang('WaitingList').'</a></li>';
  1921. $links .= '<li class="'.($show == 'invite_friends' ? 'active' : '').'"><a href="group_invitation.php?id='.$group_id.'">'.
  1922. Display::return_icon('invitation_friend.png', get_lang('InviteFriends')).get_lang('InviteFriends').'</a></li>';
  1923. if (self::canLeave($group_info)) {
  1924. $links .= '<li><a href="group_view.php?id='.$group_id.'&action=leave&u='.api_get_user_id().'">'.
  1925. Display::return_icon('group_leave.png', get_lang('LeaveGroup')).get_lang('LeaveGroup').'</a></li>';
  1926. }
  1927. break;
  1928. case GROUP_USER_PERMISSION_PENDING_INVITATION:
  1929. // $links .= '<li><a href="groups.php?id='.$group_id.'&action=join&u='.api_get_user_id().'">'.Display::return_icon('addd.gif', get_lang('YouHaveBeenInvitedJoinNow'), array('hspace'=>'6')).'<span class="social-menu-text4" >'.get_lang('YouHaveBeenInvitedJoinNow').'</span></a></li>';
  1930. break;
  1931. case GROUP_USER_PERMISSION_PENDING_INVITATION_SENT_BY_USER:
  1932. $relation_group_title = get_lang('WaitingForAdminResponse');
  1933. break;
  1934. case GROUP_USER_PERMISSION_MODERATOR:
  1935. $relation_group_title = get_lang('IAmAModerator');
  1936. //$links .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="thickbox" title="'.get_lang('ComposeMessage').'">'.Display::return_icon('compose_message.png', get_lang('NewTopic'), array('hspace'=>'6')).'<span class="social-menu-text4" >'.get_lang('NewTopic').'</span></a></li>';
  1937. //$links .= '<li><a href="groups.php?id='.$group_id.'">'. Display::return_icon('message_list.png', get_lang('MessageList'), array('hspace'=>'6')).'<span class="'.($show=='messages_list'?'social-menu-text-active':'social-menu-text4').'" >'.get_lang('MessageList').'</span></a></li>';
  1938. //$links .= '<li><a href="group_members.php?id='.$group_id.'">'. Display::return_icon('member_list.png', get_lang('MemberList'), array('hspace'=>'6')).'<span class="'.($show=='member_list'?'social-menu-text-active':'social-menu-text4').'" >'.get_lang('MemberList').'</span></a></li>';
  1939. if ($group_info['visibility'] == GROUP_PERMISSION_CLOSED) {
  1940. $links .= '<li><a href="group_waiting_list.php?id='.$group_id.'">'.
  1941. Display::return_icon('waiting_list.png', get_lang('WaitingList')).get_lang('WaitingList').'</a></li>';
  1942. }
  1943. $links .= '<li><a href="group_invitation.php?id='.$group_id.'">'.
  1944. Display::return_icon('invitation_friend.png', get_lang('InviteFriends')).get_lang('InviteFriends').'</a></li>';
  1945. if (self::canLeave($group_info)) {
  1946. $links .= '<li><a href="group_view.php?id='.$group_id.'&action=leave&u='.api_get_user_id().'">'.
  1947. Display::return_icon('group_leave.png', get_lang('LeaveGroup')).get_lang('LeaveGroup').'</a></li>';
  1948. }
  1949. break;
  1950. case GROUP_USER_PERMISSION_HRM:
  1951. $relation_group_title = get_lang('IAmAHRM');
  1952. $links .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="ajax" title="'.get_lang('ComposeMessage').'" data-size="lg" data-title="'.get_lang('ComposeMessage').'">'.
  1953. Display::return_icon('new-message.png', get_lang('NewTopic')).get_lang('NewTopic').'</a></li>';
  1954. $links .= '<li><a href="group_view.php?id='.$group_id.'">'.
  1955. Display::return_icon('message_list.png', get_lang('MessageList')).get_lang('MessageList').'</a></li>';
  1956. $links .= '<li><a href="group_invitation.php?id='.$group_id.'">'.
  1957. Display::return_icon('invitation_friend.png', get_lang('InviteFriends')).get_lang('InviteFriends').'</a></li>';
  1958. $links .= '<li><a href="group_members.php?id='.$group_id.'">'.
  1959. Display::return_icon('member_list.png', get_lang('MemberList')).get_lang('MemberList').'</a></li>';
  1960. $links .= '<li><a href="group_view.php?id='.$group_id.'&action=leave&u='.api_get_user_id().'">'.
  1961. Display::return_icon('delete_data.gif', get_lang('LeaveGroup')).get_lang('LeaveGroup').'</a></li>';
  1962. break;
  1963. default:
  1964. //$links .= '<li><a href="groups.php?id='.$group_id.'&action=join&u='.api_get_user_id().'">'.Display::return_icon('addd.gif', get_lang('JoinGroup'), array('hspace'=>'6')).'<span class="social-menu-text4" >'.get_lang('JoinGroup').'</a></span></li>';
  1965. break;
  1966. }
  1967. if (!empty($links)) {
  1968. $list = '<ul class="nav nav-pills">';
  1969. $list .= $links;
  1970. $list .= '</ul>';
  1971. $html .= Display::panelCollapse(
  1972. get_lang('SocialGroups'),
  1973. $list,
  1974. 'sm-groups',
  1975. [],
  1976. 'groups-acordeon',
  1977. 'groups-collapse'
  1978. );
  1979. }
  1980. return $html;
  1981. }
  1982. /**
  1983. * @param int $group_id
  1984. * @param int $topic_id
  1985. */
  1986. public function delete_topic($group_id, $topic_id)
  1987. {
  1988. $table_message = Database::get_main_table(TABLE_MESSAGE);
  1989. $topic_id = intval($topic_id);
  1990. $group_id = intval($group_id);
  1991. $sql = "UPDATE $table_message SET
  1992. msg_status = 3
  1993. WHERE
  1994. group_id = $group_id AND
  1995. (id = '$topic_id' OR parent_id = $topic_id)
  1996. ";
  1997. Database::query($sql);
  1998. }
  1999. /**
  2000. * @param string $user_id
  2001. * @param string $relation_type
  2002. * @param bool $with_image
  2003. * @return int
  2004. */
  2005. public function get_groups_by_user_count(
  2006. $user_id = '',
  2007. $relation_type = GROUP_USER_PERMISSION_READER,
  2008. $with_image = false
  2009. ) {
  2010. $table_group_rel_user = $this->usergroup_rel_user_table;
  2011. $tbl_group = $this->table;
  2012. $user_id = intval($user_id);
  2013. if ($relation_type == 0) {
  2014. $where_relation_condition = '';
  2015. } else {
  2016. $relation_type = intval($relation_type);
  2017. $where_relation_condition = "AND gu.relation_type = $relation_type ";
  2018. }
  2019. $sql = "SELECT count(g.id) as count
  2020. FROM $tbl_group g
  2021. INNER JOIN $table_group_rel_user gu
  2022. ON gu.usergroup_id = g.id
  2023. WHERE gu.user_id = $user_id $where_relation_condition ";
  2024. $result = Database::query($sql);
  2025. if (Database::num_rows($result) > 0) {
  2026. $row = Database::fetch_array($result, 'ASSOC');
  2027. return $row['count'];
  2028. }
  2029. return 0;
  2030. }
  2031. /**
  2032. * @param string $tag
  2033. * @param int $from
  2034. * @param int $number_of_items
  2035. *
  2036. * @return array
  2037. */
  2038. public function get_all_group_tags($tag, $from = 0, $number_of_items = 10, $getCount = false)
  2039. {
  2040. $group_table = $this->table;
  2041. $tag = Database::escape_string($tag);
  2042. $from = intval($from);
  2043. $number_of_items = intval($number_of_items);
  2044. $return = [];
  2045. $keyword = $tag;
  2046. $sql = "SELECT g.id, g.name, g.description, g.url, g.picture
  2047. FROM $group_table g";
  2048. if (isset($keyword)) {
  2049. $sql .= " WHERE (
  2050. g.name LIKE '%".$keyword."%' OR
  2051. g.description LIKE '%".$keyword."%' OR
  2052. g.url LIKE '%".$keyword."%'
  2053. )";
  2054. }
  2055. $direction = 'ASC';
  2056. if (!in_array($direction, ['ASC', 'DESC'])) {
  2057. $direction = 'ASC';
  2058. }
  2059. $from = intval($from);
  2060. $number_of_items = intval($number_of_items);
  2061. //$sql .= " ORDER BY col$column $direction ";
  2062. $sql .= " LIMIT $from,$number_of_items";
  2063. $res = Database::query($sql);
  2064. if (Database::num_rows($res) > 0) {
  2065. while ($row = Database::fetch_array($res, 'ASSOC')) {
  2066. if (!in_array($row['id'], $return)) {
  2067. $return[$row['id']] = $row;
  2068. }
  2069. }
  2070. }
  2071. return $return;
  2072. }
  2073. /**
  2074. * @param int $group_id
  2075. * @return array
  2076. */
  2077. public static function get_parent_groups($group_id)
  2078. {
  2079. $t_rel_group = Database::get_main_table(TABLE_USERGROUP_REL_USERGROUP);
  2080. $max_level = 10;
  2081. $select_part = "SELECT ";
  2082. $cond_part = '';
  2083. for ($i = 1; $i <= $max_level; $i++) {
  2084. $g_number = $i;
  2085. $rg_number = $i - 1;
  2086. if ($i == $max_level) {
  2087. $select_part .= "rg$rg_number.group_id as id_$rg_number ";
  2088. } else {
  2089. $select_part .= "rg$rg_number.group_id as id_$rg_number, ";
  2090. }
  2091. if ($i == 1) {
  2092. $cond_part .= "FROM $t_rel_group rg0 LEFT JOIN $t_rel_group rg$i on rg$rg_number.group_id = rg$i.subgroup_id ";
  2093. } else {
  2094. $cond_part .= " LEFT JOIN $t_rel_group rg$i on rg$rg_number.group_id = rg$i.subgroup_id ";
  2095. }
  2096. }
  2097. $sql = $select_part.' '.$cond_part."WHERE rg0.subgroup_id='$group_id'";
  2098. $res = Database::query($sql);
  2099. $temp_arr = Database::fetch_array($res, 'NUM');
  2100. $toReturn = [];
  2101. if (is_array($temp_arr)) {
  2102. foreach ($temp_arr as $elt) {
  2103. if (isset($elt)) {
  2104. $toReturn[] = $elt;
  2105. }
  2106. }
  2107. }
  2108. return $toReturn;
  2109. }
  2110. /**
  2111. * Get the group member list by a user and his group role
  2112. * @param int $userId The user ID
  2113. * @param int $relationType Optional. The relation type. GROUP_USER_PERMISSION_ADMIN by default
  2114. * @param boolean $includeSubgroupsUsers Optional. Whether include the users from subgroups
  2115. * @return array
  2116. */
  2117. public function getGroupUsersByUser(
  2118. $userId,
  2119. $relationType = GROUP_USER_PERMISSION_ADMIN,
  2120. $includeSubgroupsUsers = true
  2121. ) {
  2122. $userId = intval($userId);
  2123. $groups = $this->get_groups_by_user($userId, $relationType);
  2124. $groupsId = array_keys($groups);
  2125. $subgroupsId = [];
  2126. $userIdList = [];
  2127. if ($includeSubgroupsUsers) {
  2128. foreach ($groupsId as $groupId) {
  2129. $subgroupsId = array_merge($subgroupsId, self::getGroupsByDepthLevel($groupId));
  2130. }
  2131. $groupsId = array_merge($groupsId, $subgroupsId);
  2132. }
  2133. $groupsId = array_unique($groupsId);
  2134. if (empty($groupsId)) {
  2135. return [];
  2136. }
  2137. foreach ($groupsId as $groupId) {
  2138. $groupUsers = self::get_users_by_group($groupId);
  2139. if (empty($groupUsers)) {
  2140. continue;
  2141. }
  2142. foreach ($groupUsers as $member) {
  2143. if ($member['user_id'] == $userId) {
  2144. continue;
  2145. }
  2146. $userIdList[] = intval($member['user_id']);
  2147. }
  2148. }
  2149. return array_unique($userIdList);
  2150. }
  2151. /**
  2152. * Get the subgroups ID from a group.
  2153. * The default $levels value is 10 considering it as a extensive level of depth
  2154. * @param int $groupId The parent group ID
  2155. * @param int $levels The depth levels
  2156. * @return array The list of ID
  2157. */
  2158. public static function getGroupsByDepthLevel($groupId, $levels = 10)
  2159. {
  2160. $groups = [];
  2161. $groupId = intval($groupId);
  2162. $groupTable = Database::get_main_table(TABLE_USERGROUP);
  2163. $groupRelGroupTable = Database::get_main_table(TABLE_USERGROUP_REL_USERGROUP);
  2164. $select = "SELECT ";
  2165. $from = "FROM $groupTable g1 ";
  2166. for ($i = 1; $i <= $levels; $i++) {
  2167. $tableIndexNumber = $i;
  2168. $tableIndexJoinNumber = $i - 1;
  2169. $select .= "g$i.id as id_$i ";
  2170. $select .= ($i != $levels ? ", " : null);
  2171. if ($i == 1) {
  2172. $from .= "INNER JOIN $groupRelGroupTable gg0 ON g1.id = gg0.subgroup_id and gg0.group_id = $groupId ";
  2173. } else {
  2174. $from .= "LEFT JOIN $groupRelGroupTable gg$tableIndexJoinNumber ";
  2175. $from .= " ON g$tableIndexJoinNumber.id = gg$tableIndexJoinNumber.group_id ";
  2176. $from .= "LEFT JOIN $groupTable g$tableIndexNumber ";
  2177. $from .= " ON gg$tableIndexJoinNumber.subgroup_id = g$tableIndexNumber.id ";
  2178. }
  2179. }
  2180. $result = Database::query("$select $from");
  2181. while ($item = Database::fetch_assoc($result)) {
  2182. foreach ($item as $myGroupId) {
  2183. if (!empty($myGroupId)) {
  2184. $groups[] = $myGroupId;
  2185. }
  2186. }
  2187. }
  2188. return array_map('intval', $groups);
  2189. }
  2190. /**
  2191. * Set a parent group
  2192. * @param int $group_id
  2193. * @param int $parent_group_id if 0, we delete the parent_group association
  2194. * @param int $relation_type
  2195. * @return \Doctrine\DBAL\Statement
  2196. **/
  2197. public function setParentGroup($group_id, $parent_group_id, $relation_type = 1)
  2198. {
  2199. $table = Database::get_main_table(TABLE_USERGROUP_REL_USERGROUP);
  2200. $group_id = intval($group_id);
  2201. $parent_group_id = intval($parent_group_id);
  2202. if ($parent_group_id == 0) {
  2203. $sql = "DELETE FROM $table WHERE subgroup_id = $group_id";
  2204. } else {
  2205. $sql = "SELECT group_id FROM $table WHERE subgroup_id = $group_id";
  2206. $res = Database::query($sql);
  2207. if (Database::num_rows($res) == 0) {
  2208. $sql = "INSERT INTO $table SET
  2209. group_id = $parent_group_id,
  2210. subgroup_id = $group_id,
  2211. relation_type = $relation_type";
  2212. } else {
  2213. $sql = "UPDATE $table SET
  2214. group_id = $parent_group_id,
  2215. relation_type = $relation_type
  2216. WHERE subgroup_id = $group_id";
  2217. }
  2218. }
  2219. $res = Database::query($sql);
  2220. return $res;
  2221. }
  2222. /**
  2223. * Filter the groups/classes info to get a name list only
  2224. * @param int $userId The user ID
  2225. * @param int $filterByType Optional. The type of group
  2226. * @return array
  2227. */
  2228. public function getNameListByUser($userId, $filterByType = null)
  2229. {
  2230. $userClasses = $this->getUserGroupListByUser($userId, $filterByType);
  2231. return array_column($userClasses, 'name');
  2232. }
  2233. /**
  2234. * Get the HTML necessary for display the groups/classes name list
  2235. * @param int $userId The user ID
  2236. * @param int $filterByType Optional. The type of group
  2237. * @return string
  2238. */
  2239. public function getLabelsFromNameList($userId, $filterByType = null)
  2240. {
  2241. $groupsNameListParsed = $this->getNameListByUser($userId, $filterByType);
  2242. if (empty($groupsNameListParsed)) {
  2243. return '';
  2244. }
  2245. $nameList = '<ul class="list-unstyled">';
  2246. foreach ($groupsNameListParsed as $name) {
  2247. $nameList .= '<li>'.Display::span($name, ['class' => 'label label-info']).'</li>';
  2248. }
  2249. $nameList .= '</ul>';
  2250. return $nameList;
  2251. }
  2252. /**
  2253. * @param array $groupInfo
  2254. * @return bool
  2255. */
  2256. public static function canLeave($groupInfo)
  2257. {
  2258. return $groupInfo['allow_members_leave_group'] == 1 ? true : false;
  2259. }
  2260. }