link.lib.php 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Function library for the links tool.
  5. *
  6. * This is a complete remake of the original link tool.
  7. * New features:
  8. * - Organize links into categories;
  9. * - favorites/bookmarks interface;
  10. * - move links up/down within a category;
  11. * - move categories up/down;
  12. * - expand/collapse all categories;
  13. * - add link to 'root' category => category-less link is always visible.
  14. *
  15. * @author Patrick Cool, complete remake (December 2003 - January 2004)
  16. * @author René Haentjens, CSV file import (October 2004)
  17. * @package chamilo.link
  18. */
  19. class Link extends Model
  20. {
  21. public $table;
  22. public $is_course_model = true;
  23. public $columns = array(
  24. 'id',
  25. 'c_id',
  26. 'url',
  27. 'title',
  28. 'description',
  29. 'category_id',
  30. 'display_order',
  31. 'on_homepage',
  32. 'target',
  33. 'session_id'
  34. );
  35. public $required = array('url', 'title');
  36. /**
  37. *
  38. */
  39. public function __construct()
  40. {
  41. $this->table = Database::get_course_table(TABLE_LINK);
  42. }
  43. /**
  44. * Organize the saving of a link, using the parent's save method and
  45. * updating the item_property table
  46. * @param array $params
  47. * @param boolean $show_query Whether to show the query in logs when
  48. * calling parent's save method
  49. *
  50. * @return bool True if link could be saved, false otherwise
  51. */
  52. public function save($params, $show_query = null)
  53. {
  54. $course_info = api_get_course_info();
  55. $params['session_id'] = api_get_session_id();
  56. $params['category_id'] = isset($params['category_id']) ? $params['category_id'] : 0;
  57. $id = parent::save($params, $show_query);
  58. if (!empty($id)) {
  59. api_item_property_update(
  60. $course_info,
  61. TOOL_LINK,
  62. $id,
  63. 'LinkAdded',
  64. api_get_user_id()
  65. );
  66. }
  67. return $id;
  68. }
  69. /**
  70. * Update a link in the database
  71. * @param int $linkId The ID of the link to update
  72. * @param string $linkUrl The new URL to be saved
  73. * @param int Course ID
  74. * @param int Session ID
  75. * @return bool
  76. */
  77. public function updateLink($linkId, $linkUrl, $courseId = null, $sessionId = null)
  78. {
  79. $tblLink = Database :: get_course_table(TABLE_LINK);
  80. $linkUrl = Database::escape_string($linkUrl);
  81. $linkId = intval($linkId);
  82. if (is_null($courseId)) {
  83. $courseId = api_get_course_int_id();
  84. }
  85. $courseId = intval($courseId);
  86. if (is_null($sessionId)) {
  87. $sessionId = api_get_session_id();
  88. }
  89. $sessionId = intval($sessionId);
  90. if ($linkUrl != '') {
  91. $sql = "UPDATE $tblLink SET url = '$linkUrl'
  92. WHERE id = $linkId AND c_id = $courseId AND session_id = $sessionId";
  93. $resLink = Database::query($sql);
  94. return $resLink;
  95. }
  96. return false;
  97. }
  98. /**
  99. *
  100. * Get link info
  101. * @param int link id
  102. * @return array link info
  103. *
  104. **/
  105. public static function get_link_info($id)
  106. {
  107. $tbl_link = Database:: get_course_table(TABLE_LINK);
  108. $course_id = api_get_course_int_id();
  109. $sql = "SELECT * FROM " . $tbl_link . "
  110. WHERE c_id = $course_id AND id='" . intval($id) . "' ";
  111. $result = Database::query($sql);
  112. $data = array();
  113. if (Database::num_rows($result)) {
  114. $data = Database::fetch_array($result);
  115. }
  116. return $data;
  117. }
  118. }
  119. /**
  120. * Used to add a link or a category
  121. * @param string $type, "link" or "category"
  122. * @todo replace strings by constants
  123. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  124. * @return bool True on success, false on failure
  125. */
  126. function addlinkcategory($type)
  127. {
  128. global $catlinkstatus;
  129. global $msgErr;
  130. $ok = true;
  131. $course_id = api_get_course_int_id();
  132. if ($type == 'link') {
  133. $tbl_link = Database :: get_course_table(TABLE_LINK);
  134. $title = Security :: remove_XSS(stripslashes($_POST['title']));
  135. $urllink = Security :: remove_XSS($_POST['urllink']);
  136. $description = Security :: remove_XSS($_POST['description']);
  137. $selectcategory = Security :: remove_XSS($_POST['selectcategory']);
  138. if ($_POST['onhomepage'] == '') {
  139. $onhomepage = 0;
  140. } else {
  141. $onhomepage = Security :: remove_XSS($_POST['onhomepage']);
  142. }
  143. if (empty($_POST['target_link'])) {
  144. $target = '_self'; // Default target.
  145. } else {
  146. $target = Security :: remove_XSS($_POST['target_link']);
  147. }
  148. $urllink = trim($urllink);
  149. $title = trim($title);
  150. $description = trim($description);
  151. // We ensure URL to be absolute.
  152. if (strpos($urllink, '://') === false) {
  153. $urllink = 'http://' . $urllink;
  154. }
  155. // If the title is empty, we use the URL as title.
  156. if ($title == '') {
  157. $title = $urllink;
  158. }
  159. // If the URL is invalid, an error occurs.
  160. if (!api_valid_url($urllink, true)) { // A check against an absolute URL
  161. $msgErr = get_lang('GiveURL');
  162. Display :: display_error_message(get_lang('GiveURL'));
  163. $ok = false;
  164. } else {
  165. // Looking for the largest order number for this category.
  166. $result = Database :: query(
  167. "SELECT MAX(display_order) FROM " . $tbl_link . "
  168. WHERE
  169. c_id = $course_id AND
  170. category_id = '" . intval($_POST['selectcategory']) . "'"
  171. );
  172. list ($orderMax) = Database :: fetch_row($result);
  173. $order = $orderMax + 1;
  174. $session_id = api_get_session_id();
  175. $sql = "INSERT INTO " . $tbl_link . "
  176. (c_id, url, title, description, category_id, display_order, on_homepage, target, session_id)
  177. VALUES
  178. (" . $course_id . ",
  179. '" . Database :: escape_string($urllink) . "',
  180. '" . Database :: escape_string($title) . "',
  181. '" . Database :: escape_string($description) . "',
  182. '" . Database :: escape_string($selectcategory) . "',
  183. '" . Database :: escape_string($order) . "',
  184. '" . Database :: escape_string($onhomepage) . "',
  185. '" . Database :: escape_string($target) . "',
  186. '" . Database :: escape_string($session_id) . "')";
  187. $catlinkstatus = get_lang('LinkAdded');
  188. Database :: query($sql);
  189. $link_id = Database :: insert_id();
  190. if ($link_id) {
  191. api_set_default_visibility($link_id, TOOL_LINK);
  192. }
  193. if ((api_get_setting('search_enabled') == 'true') &&
  194. $link_id && extension_loaded('xapian')
  195. ) {
  196. require_once api_get_path(LIBRARY_PATH) . 'search/ChamiloIndexer.class.php';
  197. require_once api_get_path(LIBRARY_PATH) . 'search/IndexableChunk.class.php';
  198. require_once api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php';
  199. $course_int_id = api_get_course_int_id();
  200. $courseid = api_get_course_id();
  201. $specific_fields = get_specific_field_list();
  202. $ic_slide = new IndexableChunk();
  203. // Add all terms to db.
  204. $all_specific_terms = '';
  205. foreach ($specific_fields as $specific_field) {
  206. if (isset ($_REQUEST[$specific_field['code']])) {
  207. $sterms = trim($_REQUEST[$specific_field['code']]);
  208. if (!empty ($sterms)) {
  209. $all_specific_terms .= ' ' . $sterms;
  210. $sterms = explode(',', $sterms);
  211. foreach ($sterms as $sterm) {
  212. $ic_slide->addTerm(
  213. trim($sterm),
  214. $specific_field['code']
  215. );
  216. add_specific_field_value(
  217. $specific_field['id'],
  218. $courseid,
  219. TOOL_LINK,
  220. $link_id,
  221. $sterm
  222. );
  223. }
  224. }
  225. }
  226. }
  227. // Build the chunk to index.
  228. $ic_slide->addValue('title', $title);
  229. $ic_slide->addCourseId($courseid);
  230. $ic_slide->addToolId(TOOL_LINK);
  231. $xapian_data = array(
  232. SE_COURSE_ID => $courseid,
  233. SE_TOOL_ID => TOOL_LINK,
  234. SE_DATA => array(
  235. 'link_id' => (int)$link_id
  236. ),
  237. SE_USER => (int)api_get_user_id(),
  238. );
  239. $ic_slide->xapian_data = serialize($xapian_data);
  240. $description = $all_specific_terms . ' ' . $description;
  241. $ic_slide->addValue('content', $description);
  242. // Add category name if set.
  243. if (isset ($_POST['selectcategory']) && $selectcategory > 0) {
  244. $table_link_category = Database :: get_course_table(
  245. TABLE_LINK_CATEGORY
  246. );
  247. $sql_cat = 'SELECT * FROM %s WHERE id=%d AND c_id = %d LIMIT 1';
  248. $sql_cat = sprintf(
  249. $sql_cat,
  250. $table_link_category,
  251. (int)$selectcategory,
  252. $course_int_id
  253. );
  254. $result = Database :: query($sql_cat);
  255. if (Database :: num_rows($result) == 1) {
  256. $row = Database :: fetch_array($result);
  257. $ic_slide->addValue('category', $row['category_title']);
  258. }
  259. }
  260. $di = new ChamiloIndexer();
  261. isset ($_POST['language']) ? $lang = Database :: escape_string(
  262. $_POST['language']
  263. ) : $lang = 'english';
  264. $di->connectDb(null, null, $lang);
  265. $di->addChunk($ic_slide);
  266. // Index and return search engine document id.
  267. $did = $di->index();
  268. if ($did) {
  269. // Save it to db.
  270. $tbl_se_ref = Database :: get_main_table(
  271. TABLE_MAIN_SEARCH_ENGINE_REF
  272. );
  273. $sql = 'INSERT INTO %s (c_id, id, course_code, tool_id, ref_id_high_level, search_did)
  274. VALUES (NULL , \'%s\', \'%s\', %s, %s)';
  275. $sql = sprintf(
  276. $sql,
  277. $tbl_se_ref,
  278. $course_int_id,
  279. $courseid,
  280. TOOL_LINK,
  281. $link_id,
  282. $did
  283. );
  284. Database :: query($sql);
  285. }
  286. }
  287. unset ($urllink, $title, $description, $selectcategory);
  288. Display :: display_confirmation_message(get_lang('LinkAdded'));
  289. }
  290. } elseif ($type == 'category') {
  291. $tbl_categories = Database :: get_course_table(TABLE_LINK_CATEGORY);
  292. $category_title = trim($_POST['category_title']);
  293. $description = trim($_POST['description']);
  294. if (empty($category_title)) {
  295. $msgErr = get_lang('GiveCategoryName');
  296. Display :: display_error_message(get_lang('GiveCategoryName'));
  297. $ok = false;
  298. } else {
  299. // Looking for the largest order number for this category.
  300. $result = Database :: query(
  301. "SELECT MAX(display_order) FROM " . $tbl_categories . " WHERE c_id = $course_id "
  302. );
  303. list ($orderMax) = Database :: fetch_row($result);
  304. $order = $orderMax + 1;
  305. $order = intval($order);
  306. $session_id = api_get_session_id();
  307. $sql = "INSERT INTO " . $tbl_categories . " (c_id, category_title, description, display_order, session_id)
  308. VALUES (" . $course_id . ",
  309. '" . Database::escape_string($category_title) . "',
  310. '" . Database::escape_string($description) . "',
  311. '$order',
  312. '$session_id'
  313. )";
  314. Database :: query($sql);
  315. $linkId = Database :: insert_id();
  316. if ($linkId) {
  317. // add link_category visibility
  318. // course ID is taken from context in api_set_default_visibility
  319. api_set_default_visibility($linkId, TOOL_LINK_CATEGORY);
  320. }
  321. $catlinkstatus = get_lang('CategoryAdded');
  322. unset ($category_title, $description);
  323. Display :: display_confirmation_message(get_lang('CategoryAdded'));
  324. }
  325. }
  326. // "WHAT'S NEW" notification : update last tool Edit.
  327. if ($type == 'link') {
  328. global $_user;
  329. global $_course;
  330. global $nameTools;
  331. api_item_property_update(
  332. $_course,
  333. TOOL_LINK,
  334. $link_id,
  335. 'LinkAdded',
  336. $_user['user_id']
  337. );
  338. }
  339. return $ok;
  340. }
  341. /**
  342. * Used to delete a link or a category
  343. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  344. * @param int $id
  345. * @param string $type The type of item to delete
  346. * @return bool
  347. */
  348. function deletelinkcategory($id, $type)
  349. {
  350. $courseInfo = api_get_course_info();
  351. $tbl_link = Database :: get_course_table(TABLE_LINK);
  352. $tbl_categories = Database :: get_course_table(TABLE_LINK_CATEGORY);
  353. $course_id = api_get_course_int_id();
  354. $id = intval($id);
  355. if (empty($id)) {
  356. return false;
  357. }
  358. $result = false;
  359. switch ($type) {
  360. case 'link':
  361. // -> Items are no longer physically deleted,
  362. // but the visibility is set to 2 (in item_property).
  363. // This will make a restore function possible for the platform administrator.
  364. $sql = "UPDATE $tbl_link SET on_homepage='0'
  365. WHERE c_id = $course_id AND id='" . $id . "'";
  366. Database :: query($sql);
  367. api_item_property_update(
  368. $courseInfo,
  369. TOOL_LINK,
  370. $id,
  371. 'delete',
  372. api_get_user_id()
  373. );
  374. delete_link_from_search_engine(api_get_course_id(), $id);
  375. Display :: display_confirmation_message(get_lang('LinkDeleted'));
  376. $result = true;
  377. break;
  378. case 'category':
  379. // First we delete the category itself and afterwards all the links of this category.
  380. $sql = "DELETE FROM " . $tbl_categories . "
  381. WHERE c_id = $course_id AND id='" . $id. "'";
  382. Database :: query($sql);
  383. $sql = "DELETE FROM " . $tbl_link . "
  384. WHERE c_id = $course_id AND category_id='" . $id . "'";
  385. Database :: query($sql);
  386. api_item_property_update(
  387. $courseInfo,
  388. TOOL_LINK_CATEGORY,
  389. $id,
  390. 'delete',
  391. api_get_user_id()
  392. );
  393. Display :: display_confirmation_message(
  394. get_lang('CategoryDeleted')
  395. );
  396. $result = true;
  397. break;
  398. }
  399. return $result;
  400. }
  401. /**
  402. * Removes a link from search engine database
  403. * @param string $course_id Course code
  404. * @param int $link_id Document id to delete
  405. * @return void
  406. */
  407. function delete_link_from_search_engine($course_id, $link_id)
  408. {
  409. // Remove from search engine if enabled.
  410. if (api_get_setting('search_enabled') == 'true') {
  411. $tbl_se_ref = Database :: get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF);
  412. $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
  413. $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_LINK, $link_id);
  414. $res = Database :: query($sql);
  415. if (Database :: num_rows($res) > 0) {
  416. $row = Database :: fetch_array($res);
  417. require_once api_get_path(LIBRARY_PATH) . 'search/ChamiloIndexer.class.php';
  418. $di = new ChamiloIndexer();
  419. $di->remove_document((int)$row['search_did']);
  420. }
  421. $sql = 'DELETE FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
  422. $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_LINK, $link_id);
  423. Database :: query($sql);
  424. // Remove terms from db.
  425. require_once(api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php');
  426. delete_all_values_for_item($course_id, TOOL_DOCUMENT, $link_id);
  427. }
  428. }
  429. /**
  430. *
  431. * Get link info
  432. * @param int link id
  433. * @return array link info
  434. *
  435. **/
  436. function get_link_info($id)
  437. {
  438. $tbl_link = Database :: get_course_table(TABLE_LINK);
  439. $course_id = api_get_course_int_id();
  440. $sql = "SELECT * FROM " . $tbl_link . "
  441. WHERE c_id = $course_id AND id='" . intval($id) . "' ";
  442. $result = Database::query($sql);
  443. $data = array();
  444. if (Database::num_rows($result)) {
  445. $data = Database::fetch_array($result);
  446. }
  447. return $data;
  448. }
  449. /**
  450. * Used to edit a link or a category
  451. * @todo Rewrite the whole links tool because it is becoming completely cluttered,
  452. * code does not follow the coding conventions, does not use html_quickform, ...
  453. * Some features were patched in.
  454. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  455. * @todo replace the globals with the appropriate $_POST or $_GET values
  456. */
  457. function editlinkcategory($type)
  458. {
  459. global $catlinkstatus;
  460. global $id;
  461. global $submit_link;
  462. global $submit_category;
  463. global $_user;
  464. global $_course;
  465. global $nameTools;
  466. global $urllink;
  467. global $title;
  468. global $description;
  469. global $category;
  470. global $selectcategory;
  471. global $description;
  472. global $category_title;
  473. global $onhomepage;
  474. global $target_link;
  475. $tbl_link = Database :: get_course_table(TABLE_LINK);
  476. $tbl_categories = Database :: get_course_table(TABLE_LINK_CATEGORY);
  477. $course_id = api_get_course_int_id();
  478. if ($type == 'link') {
  479. // This is used to populate the link-form with the info found in the database.
  480. if (!empty ($_GET['id'])) {
  481. $sql = "SELECT * FROM " . $tbl_link . "
  482. WHERE c_id = $course_id AND id='" . intval($_GET['id']) . "'";
  483. $result = Database :: query($sql);
  484. if ($myrow = Database :: fetch_array($result)) {
  485. $urllink = $myrow['url'];
  486. $title = $myrow['title'];
  487. $description = $myrow['description'];
  488. $category = $myrow['category_id'];
  489. if ($myrow['on_homepage'] != 0) {
  490. $onhomepage = 'checked';
  491. }
  492. $target_link = $myrow['target'];
  493. }
  494. }
  495. // This is used to put the modified info of the link-form into the database.
  496. if ($_POST['submitLink']) {
  497. // Ivan, 13-OCT-2010: It is a litle bit messy code below, just in case I added some extra-security checks here.
  498. $_POST['urllink'] = trim($_POST['urllink']);
  499. $_POST['title'] = trim(Security :: remove_XSS($_POST['title']));
  500. $_POST['description'] = trim(
  501. Security :: remove_XSS($_POST['description'])
  502. );
  503. $_POST['selectcategory'] = intval($_POST['selectcategory']);
  504. $_POST['id'] = intval($_POST['id']);
  505. // We ensure URL to be absolute.
  506. if (strpos($_POST['urllink'], '://') === false) {
  507. $_POST['urllink'] = 'http://' . $_POST['urllink'];
  508. }
  509. // If the title is empty, we use the URL as title.
  510. if ($_POST['title'] == '') {
  511. $_POST['title'] = $_POST['urllink'];
  512. }
  513. // If the URL is invalid, an error occurs.
  514. if (!api_valid_url($urllink, true)) {
  515. // A check against an absolute URL.
  516. $msgErr = get_lang('GiveURL');
  517. Display :: display_error_message(get_lang('GiveURL'));
  518. return false;
  519. }
  520. $onhomepage = Security :: remove_XSS($_POST['onhomepage']);
  521. $target = Database::escape_string($_POST['target_link']);
  522. if (empty ($mytarget)) {
  523. $mytarget = '_self';
  524. }
  525. $mytarget = ", target='" . $target . "'";
  526. // Finding the old category_id.
  527. $sql = "SELECT * FROM " . $tbl_link . "
  528. WHERE c_id = $course_id AND id='" . intval($_POST['id']) . "'";
  529. $result = Database :: query($sql);
  530. $row = Database :: fetch_array($result);
  531. $category_id = $row['category_id'];
  532. if ($category_id != $_POST['selectcategory']) {
  533. $sql = "SELECT MAX(display_order)
  534. FROM " . $tbl_link . "
  535. WHERE c_id = $course_id
  536. AND category_id='" . intval($_POST['selectcategory']) . "'";
  537. $result = Database :: query($sql);
  538. list ($max_display_order) = Database :: fetch_row($result);
  539. $max_display_order++;
  540. } else {
  541. $max_display_order = $row['display_order'];
  542. }
  543. $sql = "UPDATE " . $tbl_link . " SET " .
  544. "url='" . Database :: escape_string($_POST['urllink']) . "', " .
  545. "title='" . Database :: escape_string($_POST['title']) . "', " .
  546. "description='" . Database :: escape_string($_POST['description']) . "', " .
  547. "category_id='" . Database :: escape_string($_POST['selectcategory']) . "', " .
  548. "display_order='" . $max_display_order . "', " .
  549. "on_homepage= '" . Database :: escape_string($onhomepage) ."' $mytarget " .
  550. " WHERE c_id = $course_id AND id='" . intval($_POST['id']) . "'";
  551. Database :: query($sql);
  552. // Update search enchine and its values table if enabled.
  553. if (api_get_setting('search_enabled') == 'true') {
  554. $link_id = intval($_POST['id']);
  555. $course_int_id = api_get_course_int_id();
  556. $course_id = api_get_course_id();
  557. $link_url = Database :: escape_string($_POST['urllink']);
  558. $link_title = Database :: escape_string($_POST['title']);
  559. $link_description = Database :: escape_string(
  560. $_POST['description']
  561. );
  562. // Actually, it consists on delete terms from db, insert new ones, create a new search engine document, and remove the old one.
  563. // Get search_did.
  564. $tbl_se_ref = Database :: get_main_table(
  565. TABLE_MAIN_SEARCH_ENGINE_REF
  566. );
  567. $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
  568. $sql = sprintf(
  569. $sql,
  570. $tbl_se_ref,
  571. $course_id,
  572. TOOL_LINK,
  573. $link_id
  574. );
  575. $res = Database :: query($sql);
  576. if (Database :: num_rows($res) > 0) {
  577. require_once api_get_path(LIBRARY_PATH) . 'search/ChamiloIndexer.class.php';
  578. require_once api_get_path(LIBRARY_PATH) . 'search/IndexableChunk.class.php';
  579. require_once api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php';
  580. $se_ref = Database :: fetch_array($res);
  581. $specific_fields = get_specific_field_list();
  582. $ic_slide = new IndexableChunk();
  583. $all_specific_terms = '';
  584. foreach ($specific_fields as $specific_field) {
  585. delete_all_specific_field_value(
  586. $course_id,
  587. $specific_field['id'],
  588. TOOL_LINK,
  589. $link_id
  590. );
  591. if (isset ($_REQUEST[$specific_field['code']])) {
  592. $sterms = trim($_REQUEST[$specific_field['code']]);
  593. if (!empty ($sterms)) {
  594. $all_specific_terms .= ' ' . $sterms;
  595. $sterms = explode(',', $sterms);
  596. foreach ($sterms as $sterm) {
  597. $ic_slide->addTerm(
  598. trim($sterm),
  599. $specific_field['code']
  600. );
  601. add_specific_field_value(
  602. $specific_field['id'],
  603. $course_id,
  604. TOOL_LINK,
  605. $link_id,
  606. $sterm
  607. );
  608. }
  609. }
  610. }
  611. }
  612. // Build the chunk to index.
  613. $ic_slide->addValue("title", $link_title);
  614. $ic_slide->addCourseId($course_id);
  615. $ic_slide->addToolId(TOOL_LINK);
  616. $xapian_data = array(
  617. SE_COURSE_ID => $course_id,
  618. SE_TOOL_ID => TOOL_LINK,
  619. SE_DATA => array(
  620. 'link_id' => (int)$link_id
  621. ),
  622. SE_USER => (int)api_get_user_id(),
  623. );
  624. $ic_slide->xapian_data = serialize($xapian_data);
  625. $link_description = $all_specific_terms . ' ' . $link_description;
  626. $ic_slide->addValue('content', $link_description);
  627. // Add category name if set.
  628. if (isset ($_POST['selectcategory']) && $selectcategory > 0) {
  629. $table_link_category = Database :: get_course_table(
  630. TABLE_LINK_CATEGORY
  631. );
  632. $sql_cat = 'SELECT * FROM %s WHERE id=%d and c_id = %d LIMIT 1';
  633. $sql_cat = sprintf(
  634. $sql_cat,
  635. $table_link_category,
  636. (int)$selectcategory,
  637. $course_int_id
  638. );
  639. $result = Database :: query($sql_cat);
  640. if (Database :: num_rows($result) == 1) {
  641. $row = Database :: fetch_array($result);
  642. $ic_slide->addValue(
  643. 'category',
  644. $row['category_title']
  645. );
  646. }
  647. }
  648. $di = new ChamiloIndexer();
  649. isset ($_POST['language']) ? $lang = Database :: escape_string(
  650. $_POST['language']
  651. ) : $lang = 'english';
  652. $di->connectDb(null, null, $lang);
  653. $di->remove_document((int)$se_ref['search_did']);
  654. $di->addChunk($ic_slide);
  655. // Index and return search engine document id.
  656. $did = $di->index();
  657. if ($did) {
  658. // Save it to db.
  659. $sql = 'DELETE FROM %s
  660. WHERE course_code=\'%s\'
  661. AND tool_id=\'%s\'
  662. AND ref_id_high_level=\'%s\'';
  663. $sql = sprintf(
  664. $sql,
  665. $tbl_se_ref,
  666. $course_id,
  667. TOOL_LINK,
  668. $link_id
  669. );
  670. Database :: query($sql);
  671. $sql = 'INSERT INTO %s (c_id, id, course_code, tool_id, ref_id_high_level, search_did)
  672. VALUES (NULL , \'%s\', \'%s\', %s, %s)';
  673. $sql = sprintf(
  674. $sql,
  675. $tbl_se_ref,
  676. $course_int_id,
  677. $course_id,
  678. TOOL_LINK,
  679. $link_id,
  680. $did
  681. );
  682. Database :: query($sql);
  683. }
  684. }
  685. }
  686. // "WHAT'S NEW" notification: update table last_toolEdit.
  687. api_item_property_update(
  688. $_course,
  689. TOOL_LINK,
  690. $_POST['id'],
  691. 'LinkUpdated',
  692. $_user['user_id']
  693. );
  694. Display :: display_confirmation_message(get_lang('LinkModded'));
  695. }
  696. }
  697. if ($type == 'category') {
  698. // This is used to populate the category-form with the info found in the database.
  699. if (!$submit_category) {
  700. $sql = "SELECT * FROM " . $tbl_categories . "
  701. WHERE c_id = $course_id AND id='" . intval($_GET['id']) . "'";
  702. $result = Database :: query($sql);
  703. if ($myrow = Database :: fetch_array($result)) {
  704. $category_title = $myrow['category_title'];
  705. $description = $myrow['description'];
  706. }
  707. }
  708. // This is used to put the modified info of the category-form into the database.
  709. if ($submit_category) {
  710. $sql = "UPDATE " . $tbl_categories . "
  711. SET category_title='" . Database :: escape_string($_POST['category_title']) . "',
  712. description='" . Database :: escape_string($_POST['description']) . "'
  713. WHERE c_id = $course_id AND id='" . Database :: escape_string($_POST['id']) . "'";
  714. Database :: query($sql);
  715. Display :: display_confirmation_message(get_lang('CategoryModded'));
  716. }
  717. }
  718. return true; // On errors before this statement, exit from this function by returning false value.
  719. }
  720. /**
  721. * Creates a correct $view for in the URL
  722. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  723. */
  724. function makedefaultviewcode($locatie)
  725. {
  726. global $aantalcategories, $view;
  727. for ($j = 0; $j <= $aantalcategories - 1; $j++) {
  728. $view[$j] = 0;
  729. }
  730. $view[intval($locatie)] = '1';
  731. }
  732. /**
  733. * Changes the visibility of a link
  734. * @todo add the changing of the visibility of a course
  735. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  736. */
  737. function change_visibility_link($id, $scope)
  738. {
  739. $_course = api_get_course_info();
  740. $_user = api_get_user_info();
  741. if ($scope == TOOL_LINK) {
  742. api_item_property_update(
  743. $_course,
  744. TOOL_LINK,
  745. $id,
  746. $_GET['action'],
  747. $_user['user_id']
  748. );
  749. Display :: display_confirmation_message(get_lang('VisibilityChanged'));
  750. } elseif ($scope == TOOL_LINK_CATEGORY) {
  751. api_item_property_update(
  752. $_course,
  753. TOOL_LINK_CATEGORY,
  754. $id,
  755. $_GET['action'],
  756. $_user['user_id']
  757. );
  758. Display :: display_confirmation_message(get_lang('VisibilityChanged'));
  759. }
  760. }
  761. /**
  762. * Generate SQL to select all the links categories in the current course and
  763. * session
  764. * @param int $courseId
  765. * @param int $sessionId
  766. * @return resource
  767. */
  768. function getLinkCategories($courseId, $sessionId)
  769. {
  770. $tblLinkCategory = Database :: get_course_table(TABLE_LINK_CATEGORY);
  771. $tblItemProperty = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  772. $courseId = intval($courseId);
  773. // Condition for the session.
  774. $sessionCondition = api_get_session_condition($sessionId, true, true);
  775. // Getting links
  776. $sql = "SELECT *, linkcat.id
  777. FROM $tblLinkCategory linkcat
  778. WHERE
  779. linkcat.c_id = " . $courseId."
  780. $sessionCondition
  781. ORDER BY linkcat.display_order DESC";
  782. $result = Database::query($sql);
  783. $categories = Database::store_result($result);
  784. $sql = "SELECT *, linkcat.id
  785. FROM $tblLinkCategory linkcat
  786. INNER JOIN $tblItemProperty itemproperties
  787. ON (linkcat.id = itemproperties.ref AND linkcat.c_id = itemproperties.c_id)
  788. WHERE
  789. itemproperties.tool = '" . TOOL_LINK_CATEGORY . "' AND
  790. (itemproperties.visibility = '0' OR itemproperties.visibility = '1')
  791. $sessionCondition AND
  792. linkcat.c_id = " . $courseId . "
  793. ORDER BY linkcat.display_order DESC";
  794. $result = Database::query($sql);
  795. $categoryInItemProperty = array();
  796. if (Database::num_rows($result)) {
  797. while ($row = Database::fetch_array($result, 'ASSOC')) {
  798. $categoryInItemProperty[$row['id']] = $row;
  799. }
  800. }
  801. foreach ($categories as & $category) {
  802. if (!isset($categoryInItemProperty[$category['id']])) {
  803. api_set_default_visibility($category['id'], TOOL_LINK_CATEGORY);
  804. }
  805. }
  806. $sql = "SELECT DISTINCT linkcat.*, visibility
  807. FROM $tblLinkCategory linkcat
  808. INNER JOIN $tblItemProperty itemproperties
  809. ON (linkcat.id = itemproperties.ref AND linkcat.c_id = itemproperties.c_id)
  810. WHERE
  811. itemproperties.tool = '" . TOOL_LINK_CATEGORY . "' AND
  812. (itemproperties.visibility = '0' OR itemproperties.visibility = '1')
  813. $sessionCondition AND
  814. linkcat.c_id = " . $courseId . "
  815. GROUP BY c_id, id
  816. ORDER BY linkcat.display_order DESC
  817. ";
  818. $result = Database::query($sql);
  819. return Database::store_result($result, 'ASSOC');
  820. }
  821. /**
  822. * Displays all the links of a given category.
  823. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  824. */
  825. function showlinksofcategory($catid)
  826. {
  827. global $urlview, $up, $down, $_user, $token;
  828. $tbl_link = Database :: get_course_table(TABLE_LINK);
  829. $TABLE_ITEM_PROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  830. // Condition for the session.
  831. $session_id = api_get_session_id();
  832. $catid = intval($catid);
  833. $course_id = api_get_course_int_id();
  834. $courseInfo = api_get_course_info();
  835. if (empty($session_id)) {
  836. $visibleCondition = " ( (id_session = 0 OR id_session IS NULL) AND (itemproperties.visibility = '0' OR itemproperties.visibility = '1') ) ";
  837. } else {
  838. $visibleCondition = " (( (id_session = 0 OR id_session is NULL) AND itemproperties.visibility = '1') OR ";
  839. $visibleCondition .= " ( id_session = $session_id AND (itemproperties.visibility = '0' OR itemproperties.visibility = '1') )) ";
  840. }
  841. $sql = "SELECT DISTINCT
  842. link.id,
  843. url,
  844. title,
  845. target,
  846. description,
  847. id_session as session_id
  848. FROM $tbl_link link
  849. INNER JOIN $TABLE_ITEM_PROPERTY itemproperties
  850. ON (link.id = itemproperties.ref AND link.c_id = itemproperties.c_id)
  851. WHERE
  852. itemproperties.tool = '" . TOOL_LINK . "' AND
  853. link.category_id = '" . $catid . "' AND
  854. link.c_id = $course_id AND
  855. itemproperties.c_id = $course_id AND
  856. $visibleCondition
  857. ORDER BY link.display_order";
  858. $result = Database :: query($sql);
  859. $numberoflinks = Database :: num_rows($result);
  860. if ($numberoflinks > 0) {
  861. echo '<table class="data_table" width="100%">';
  862. $i = 1;
  863. while ($myrow = Database :: fetch_array($result)) {
  864. // Validation when belongs to a session.
  865. $session_img = null;
  866. $css_class = $i % 2 == 0 ? $css_class = 'row_odd' : $css_class = 'row_even';
  867. $visibility = api_get_item_visibility(
  868. $courseInfo,
  869. TOOL_LINK,
  870. $myrow['id'],
  871. 0
  872. );
  873. if ($visibility == -1) {
  874. if (!empty($session_id)) {
  875. $visibility = api_get_item_visibility(
  876. $courseInfo,
  877. TOOL_LINK,
  878. $myrow['id'],
  879. $session_id
  880. );
  881. if ($visibility != -1) {
  882. $session_img = api_get_session_image(
  883. $session_id,
  884. $_user['status']
  885. );
  886. }
  887. }
  888. } else {
  889. if (!empty($session_id)) {
  890. if ($visibility == 0) {
  891. continue;
  892. }
  893. $visibility = api_get_item_visibility(
  894. $courseInfo,
  895. TOOL_LINK,
  896. $myrow['id'],
  897. $session_id
  898. );
  899. }
  900. }
  901. $link_validator = '';
  902. if (api_is_allowed_to_edit(null, true)) {
  903. $link_validator = '' . Display::url(
  904. Display::return_icon(
  905. 'preview_view.png',
  906. get_lang('CheckURL'),
  907. array(),
  908. 16
  909. ),
  910. '#',
  911. array(
  912. 'onclick' => "check_url('" . $myrow['id'] . "', '" . addslashes(
  913. $myrow['url']
  914. ) . "');"
  915. )
  916. );
  917. $link_validator .= Display::span(
  918. '',
  919. array('id' => 'url_id_' . $myrow['id'])
  920. );
  921. }
  922. if ($visibility == '1') {
  923. echo '<tr class="' . $css_class . '">';
  924. echo '<td align="center" valign="middle" width="5%">';
  925. echo '<a href="link_goto.php?' . api_get_cidreq() .
  926. '&amp;link_id=' . $myrow['id'] .
  927. '&amp;link_url=' . urlencode($myrow['url']) . '" target="_blank">
  928. <img src="../../main/img/link.gif" border="0" alt="' . get_lang('Link') . '"/></a></td>
  929. <td width="80%" valign="top"><a href="link_goto.php?' . api_get_cidreq() .
  930. '&amp;link_id=' . $myrow['id'] .
  931. '&amp;link_url=' . urlencode($myrow['url']) . '" target="' . $myrow['target'] . '">';
  932. echo Security :: remove_XSS($myrow['title']);
  933. echo '</a>';
  934. echo $link_validator;
  935. echo $session_img;
  936. echo '<br />' . $myrow['description'];
  937. } else {
  938. if (api_is_allowed_to_edit(null, true)) {
  939. echo '<tr class="' . $css_class . '">';
  940. echo '<td align="center" valign="middle" width="5%">
  941. <a href="link_goto.php?' . api_get_cidreq() .
  942. '&amp;link_id=' . $myrow['id'] . "
  943. &amp;link_url=" . urlencode($myrow['url']) . '"
  944. target="_blank" class="invisible">';
  945. echo Display :: return_icon(
  946. 'link_na.gif',
  947. get_lang('Link')
  948. ), '</a>';
  949. echo '</td><td width="80%" valign="top"><a href="link_goto.php?', api_get_cidreq(
  950. ), '&amp;link_id=', $myrow['id'], '&amp;link_url=', urlencode(
  951. $myrow['url']
  952. ), '" target="', $myrow['target'], '" class="invisible">';
  953. echo Security :: remove_XSS($myrow['url']);
  954. echo "</a>";
  955. echo $link_validator;
  956. echo $session_img, '<br />', $myrow['title'];
  957. }
  958. }
  959. if (api_is_allowed_to_edit(null, true)) {
  960. echo '<td style="text-align:center;">';
  961. if ($session_id == $myrow['session_id']) {
  962. echo '<a href="' . api_get_self() . '?' . api_get_cidreq() .
  963. '&amp;sec_token=' . $token .
  964. '&amp;action=editlink&amp;category=' . (!empty ($category) ? $category : '') .
  965. '&amp;id=' . $myrow['id'] .
  966. '&amp;urlview=' . $urlview . '"title="' . get_lang('Modify') . '">' .
  967. Display :: return_icon(
  968. 'edit.png',
  969. get_lang('Modify'),
  970. array(),
  971. ICON_SIZE_SMALL
  972. ) . '</a>';
  973. // DISPLAY MOVE UP COMMAND only if it is not the top link.
  974. /* commented at least since 2014-10-11
  975. if ($i != 1) {
  976. echo '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;sec_token='.$token.'&amp;urlview=' . $urlview . '&amp;up=', $myrow[0], '" title="' . get_lang('Up') . '">' . Display :: return_icon('up.png', get_lang('Up'), array (), ICON_SIZE_SMALL) . '', "</a>\n";
  977. } else {
  978. echo Display :: return_icon('up_na.png', get_lang('Up'), array (), ICON_SIZE_SMALL) . '</a>';
  979. }
  980. // DISPLAY MOVE DOWN COMMAND only if it is not the bottom link.
  981. if ($i < $numberoflinks) {
  982. echo '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;sec_token='.$token.'&amp;urlview=' . $urlview . '&amp;down=' . $myrow[0] . '" title="' . get_lang('Down') . '">' . Display :: return_icon('down.png', get_lang('Down'), array (), ICON_SIZE_SMALL) . '', "</a>\n";
  983. } else {
  984. echo Display :: return_icon('down_na.png', get_lang('Down'), array (), ICON_SIZE_SMALL) . '', "</a>\n";
  985. }*/
  986. if ($visibility == '1') {
  987. echo '<a href="link.php?' . api_get_cidreq() .
  988. '&amp;sec_token=' . $token .
  989. '&amp;action=invisible&amp;id=' . $myrow['id'] .
  990. '&amp;scope=link&amp;urlview=' . $urlview . '" title="' . get_lang('Hide') . '">' .
  991. Display :: return_icon(
  992. 'visible.png',
  993. get_lang('Hide'),
  994. array(),
  995. ICON_SIZE_SMALL
  996. ) . '</a>';
  997. }
  998. if ($visibility == '0') {
  999. echo ' <a href="link.php?' . api_get_cidreq() .
  1000. '&amp;sec_token=' . $token .
  1001. '&amp;action=visible&amp;id=' . $myrow['id'] .
  1002. '&amp;scope=link&amp;urlview=' . $urlview . '" title="' . get_lang('Show') . '">' .
  1003. Display :: return_icon(
  1004. 'invisible.png',
  1005. get_lang('Show'),
  1006. array(),
  1007. ICON_SIZE_SMALL
  1008. ) . '</a>';
  1009. }
  1010. echo ' <a href="' . api_get_self() . '?' . api_get_cidreq() .
  1011. '&amp;sec_token=' . $token .
  1012. '&amp;action=deletelink&amp;id='. $myrow['id'].
  1013. '&amp;urlview='. $urlview. "\"
  1014. onclick=\"javascript: if(!confirm('" . get_lang('LinkDelconfirm') . "'))
  1015. return false;\" title=\"" . get_lang('Delete') . '">' .
  1016. Display :: return_icon(
  1017. 'delete.png',
  1018. get_lang('Delete'),
  1019. array(),
  1020. ICON_SIZE_SMALL
  1021. ) . '</a>';
  1022. } else {
  1023. echo Display :: return_icon(
  1024. 'edit_na.png',
  1025. get_lang('EditionNotAvailableFromSession'),
  1026. array(),
  1027. ICON_SIZE_SMALL
  1028. );
  1029. if ($visibility == '1') {
  1030. echo '<a href="link.php?'.api_get_cidreq().
  1031. '&amp;sec_token='.$token.
  1032. '&amp;action=invisible&amp;id='.$myrow['id'].
  1033. '&amp;scope=link&amp;urlview='.$urlview.'" title="'.get_lang(
  1034. 'Hide'
  1035. ).'">'.
  1036. Display:: return_icon(
  1037. 'visible.png',
  1038. get_lang('Hide'),
  1039. array(),
  1040. ICON_SIZE_SMALL
  1041. ).'</a>';
  1042. }
  1043. if ($visibility== '0') {
  1044. echo ' <a href="link.php?'.api_get_cidreq().
  1045. '&amp;sec_token='.$token.
  1046. '&amp;action=visible&amp;id='.$myrow['id'].
  1047. '&amp;scope=link&amp;urlview='.$urlview.'" title="'.get_lang(
  1048. 'Show'
  1049. ).'">'.
  1050. Display:: return_icon(
  1051. 'invisible.png',
  1052. get_lang('Show'),
  1053. array(),
  1054. ICON_SIZE_SMALL
  1055. ).'</a>';
  1056. }
  1057. }
  1058. echo '</td>';
  1059. }
  1060. echo '</tr>';
  1061. $i++;
  1062. }
  1063. echo '</table>';
  1064. }
  1065. }
  1066. /**
  1067. * Displays the edit, delete and move icons
  1068. * @param int Category ID
  1069. * @return void
  1070. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1071. */
  1072. function showcategoryadmintools($categoryid)
  1073. {
  1074. global $urlview, $aantalcategories, $catcounter, $token;
  1075. echo '<a href="' . api_get_self() . '?' . api_get_cidreq(
  1076. ) . '&amp;sec_token=' . $token . '&amp;action=editcategory&amp;id=' . $categoryid . '&amp;urlview=' . $urlview . '" title=' . get_lang(
  1077. 'Modify'
  1078. ) . '">' . Display :: return_icon(
  1079. 'edit.png',
  1080. get_lang('Modify'),
  1081. array(),
  1082. ICON_SIZE_SMALL
  1083. ) . '</a>';
  1084. // DISPLAY MOVE UP COMMAND only if it is not the top link.
  1085. if ($catcounter != 1) {
  1086. echo '<a href="' . api_get_self() . '?' . api_get_cidreq(
  1087. ) . '&amp;sec_token=' . $token . '&amp;catmove=true&amp;up=', $categoryid, '&amp;urlview=' . $urlview . '" title="' . get_lang(
  1088. 'Up'
  1089. ) . '">' . Display :: return_icon(
  1090. 'up.png',
  1091. get_lang('Up'),
  1092. array(),
  1093. ICON_SIZE_SMALL
  1094. ) . '</a>';
  1095. } else {
  1096. echo Display :: return_icon(
  1097. 'up_na.png',
  1098. get_lang('Up'),
  1099. array(),
  1100. ICON_SIZE_SMALL
  1101. ) . '</a>';
  1102. }
  1103. // DISPLAY MOVE DOWN COMMAND only if it is not the bottom link.
  1104. if ($catcounter < $aantalcategories) {
  1105. echo '<a href="' . api_get_self() . '?' . api_get_cidreq() .
  1106. '&amp;sec_token=' . $token .
  1107. '&amp;catmove=true&amp;down=' . $categoryid .
  1108. '&amp;urlview=' . $urlview . '">
  1109. ' .
  1110. Display :: return_icon(
  1111. 'down.png',
  1112. get_lang('Down'),
  1113. array(),
  1114. ICON_SIZE_SMALL
  1115. ) . '</a>';
  1116. } else {
  1117. echo Display :: return_icon('down_na.png', get_lang('Down'), array(), ICON_SIZE_SMALL) . '</a>';
  1118. }
  1119. echo '<a href="' . api_get_self() . '?' . api_get_cidreq() .
  1120. '&amp;sec_token=' . $token .
  1121. '&amp;action=deletecategory&amp;id=', $categoryid,
  1122. "&amp;urlview=$urlview\"
  1123. onclick=\"javascript: if(!confirm('" . get_lang('CategoryDelconfirm') . "')) return false;\">",
  1124. Display :: return_icon(
  1125. 'delete.png',
  1126. get_lang('Delete'),
  1127. array(),
  1128. ICON_SIZE_SMALL
  1129. ) . '</a>';
  1130. $catcounter++;
  1131. }
  1132. /**
  1133. * move a link or a linkcategory up or down
  1134. * @param int Category ID
  1135. * @param int Course ID
  1136. * @param int Session ID
  1137. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1138. * @todo support sessions
  1139. */
  1140. function movecatlink($catlinkid, $courseId = null, $sessionId = null)
  1141. {
  1142. global $catmove;
  1143. global $up;
  1144. global $down;
  1145. $tbl_link = Database :: get_course_table(TABLE_LINK);
  1146. $tbl_categories = Database :: get_course_table(TABLE_LINK_CATEGORY);
  1147. if (is_null($courseId)) {
  1148. $courseId = api_get_course_int_id();
  1149. }
  1150. $courseId = intval($courseId);
  1151. if (is_null($sessionId)) {
  1152. $sessionId = api_get_session_id();
  1153. }
  1154. $sessionId = intval($sessionId);
  1155. if (!empty ($down)) {
  1156. $thiscatlinkId = intval($down);
  1157. $sortDirection = 'DESC';
  1158. }
  1159. if (!empty ($up)) {
  1160. $thiscatlinkId = intval($up);
  1161. $sortDirection = 'ASC';
  1162. }
  1163. // We check if it is a category we are moving or a link.
  1164. // If it is a category, a querystring catmove = true is present in the url.
  1165. if ($catmove == 'true') {
  1166. $movetable = $tbl_categories;
  1167. $catid = $catlinkid;
  1168. } else {
  1169. $movetable = $tbl_link;
  1170. // Getting the category of the link.
  1171. if (!empty ($thiscatlinkId)) {
  1172. $sql = "SELECT category_id FROM " . $movetable . " WHERE c_id = $courseId AND id='$thiscatlinkId'";
  1173. $result = Database :: query($sql);
  1174. $catid = Database :: fetch_array($result);
  1175. }
  1176. }
  1177. // This code is copied and modified from announcements.php.
  1178. if (!empty($sortDirection)) {
  1179. if (!in_array(trim(strtoupper($sortDirection)), array('ASC', 'DESC'))) {
  1180. $sortDirection = 'ASC';
  1181. }
  1182. if ($catmove == 'true') {
  1183. $sqlcatlinks = "SELECT id, display_order FROM " . $movetable . "
  1184. WHERE c_id = $courseId ORDER BY display_order $sortDirection";
  1185. } else {
  1186. $sqlcatlinks = "SELECT id, display_order FROM " . $movetable . "
  1187. WHERE c_id = $courseId AND category_id='" . $catid[0] . "'
  1188. ORDER BY display_order $sortDirection";
  1189. }
  1190. $linkresult = Database :: query($sqlcatlinks);
  1191. $thislinkOrder = 1;
  1192. while ($sortrow = Database :: fetch_array($linkresult)) {
  1193. // STEP 2 : FOUND THE NEXT LINK ID AND ORDER, COMMIT SWAP
  1194. // This part seems unlogic, but it isn't . We first look for the current link with the querystring ID
  1195. // and we know the next iteration of the while loop is the next one. These should be swapped.
  1196. if (isset ($thislinkFound) && $thislinkFound) {
  1197. $nextlinkId = $sortrow['id'];
  1198. $nextlinkOrder = $sortrow['display_order'];
  1199. Database :: query(
  1200. "UPDATE " . $movetable . "
  1201. SET display_order = '$nextlinkOrder'
  1202. WHERE c_id = $courseId AND id = '$thiscatlinkId'"
  1203. );
  1204. Database :: query(
  1205. "UPDATE " . $movetable . "
  1206. SET display_order = '$thislinkOrder'
  1207. WHERE c_id = $courseId AND id = '$nextlinkId'"
  1208. );
  1209. break;
  1210. }
  1211. if ($sortrow['id'] == $thiscatlinkId) {
  1212. $thislinkOrder = $sortrow['display_order'];
  1213. $thislinkFound = true;
  1214. }
  1215. }
  1216. }
  1217. Display :: display_confirmation_message(get_lang('LinkMoved'));
  1218. }
  1219. /**
  1220. * CSV file import functions
  1221. * @author René Haentjens , Ghent University
  1222. */
  1223. function get_cat($catname)
  1224. {
  1225. // Get category id (existing or make new).
  1226. $tbl_categories = Database :: get_course_table(TABLE_LINK_CATEGORY);
  1227. $course_id = api_get_course_int_id();
  1228. $result = Database :: query(
  1229. "SELECT id FROM " . $tbl_categories . "
  1230. WHERE c_id = $course_id AND category_title='" . Database::escape_string(
  1231. $catname
  1232. ) . "'"
  1233. );
  1234. if (Database :: num_rows($result) >= 1 && ($row = Database :: fetch_array($result))) {
  1235. return $row['id']; // Several categories with same name: take the first.
  1236. }
  1237. $result = Database :: query(
  1238. "SELECT MAX(display_order) FROM " . $tbl_categories . " WHERE c_id = $course_id "
  1239. );
  1240. list ($max_order) = Database :: fetch_row($result);
  1241. Database :: query(
  1242. "INSERT INTO " . $tbl_categories . " (c_id, category_title, description, display_order)
  1243. VALUES (" . $course_id . ", '" . Database::escape_string($catname) . "','','" . ($max_order + 1) . "')"
  1244. );
  1245. return Database :: insert_id();
  1246. }
  1247. /**
  1248. * CSV file import functions
  1249. * @author René Haentjens , Ghent University
  1250. */
  1251. function put_link($url, $cat, $title, $description, $on_homepage, $hidden)
  1252. {
  1253. $tbl_link = Database :: get_course_table(TABLE_LINK);
  1254. $course_id = api_get_course_int_id();
  1255. $urleq = "url='" . Database :: escape_string($url) . "'";
  1256. $cateq = "category_id=" . intval($cat);
  1257. $result = Database :: query(
  1258. "SELECT id FROM $tbl_link WHERE c_id = $course_id AND " . $urleq . ' AND ' . $cateq
  1259. );
  1260. if (Database :: num_rows($result) >= 1 && ($row = Database :: fetch_array($result))) {
  1261. Database :: query(
  1262. "UPDATE $tbl_link set title='" . Database :: escape_string(
  1263. $title
  1264. ) . "', description='" . Database :: escape_string($description) . "'
  1265. WHERE c_id = $course_id AND id='" . Database :: escape_string(
  1266. $row['id']
  1267. ) . "'"
  1268. );
  1269. $ipu = 'LinkUpdated';
  1270. $rv = 1; // 1 = upd
  1271. } else {
  1272. // Add new link
  1273. $result = Database :: query(
  1274. "SELECT MAX(display_order) FROM $tbl_link WHERE c_id = $course_id AND category_id='" . intval(
  1275. $cat
  1276. ) . "'"
  1277. );
  1278. list ($max_order) = Database :: fetch_row($result);
  1279. Database :: query(
  1280. "INSERT INTO $tbl_link (c_id, url, title, description, category_id, display_order, on_homepage)
  1281. VALUES (" . api_get_course_int_id() . ",
  1282. '" . Database :: escape_string($url) . "',
  1283. '" . Database :: escape_string($title) . "',
  1284. '" . Database :: escape_string($description) . "',
  1285. '" . intval($cat) . "','" . (intval($max_order) + 1) . "',
  1286. '" . intval($on_homepage) .
  1287. "')"
  1288. );
  1289. $id = Database :: insert_id();
  1290. $ipu = 'LinkAdded';
  1291. $rv = 2; // 2 = new
  1292. }
  1293. global $_course, $nameTools, $_user;
  1294. api_item_property_update($_course, TOOL_LINK, $id, $ipu, $_user['user_id']);
  1295. if ($hidden && $ipu == 'LinkAdded') {
  1296. api_item_property_update(
  1297. $_course,
  1298. TOOL_LINK,
  1299. $id,
  1300. 'invisible',
  1301. $_user['user_id']
  1302. );
  1303. }
  1304. return $rv;
  1305. }
  1306. /**
  1307. * CSV file import functions
  1308. * @author René Haentjens , Ghent University
  1309. */
  1310. function import_link($linkdata)
  1311. {
  1312. // url, category_id, title, description, ...
  1313. // Field names used in the uploaded file
  1314. $known_fields = array(
  1315. 'url',
  1316. 'category',
  1317. 'title',
  1318. 'description',
  1319. 'on_homepage',
  1320. 'hidden'
  1321. );
  1322. $hide_fields = array(
  1323. 'kw',
  1324. 'kwd',
  1325. 'kwds',
  1326. 'keyword',
  1327. 'keywords'
  1328. );
  1329. // All other fields are added to description, as "name:value".
  1330. // Only one hide_field is assumed to be present, <> is removed from value.
  1331. if (!($url = trim($linkdata['url'])) || !($title = trim($linkdata['title']))
  1332. ) {
  1333. return 0; // 0 = fail
  1334. }
  1335. $cat = ($catname = trim($linkdata['category'])) ? get_cat($catname) : 0;
  1336. $regs = array(); // Will be passed to ereg()
  1337. $d = '';
  1338. foreach ($linkdata as $key => $value) {
  1339. if (!in_array($key, $known_fields)) {
  1340. if (in_array($key, $hide_fields) && ereg('^<?([^>]*)>?$', $value, $regs)) { // possibly in <...>
  1341. if (($kwlist = trim($regs[1])) != '') {
  1342. $kw = '<i kw="' . htmlspecialchars($kwlist) . '">';
  1343. } else {
  1344. $kw = '';
  1345. }
  1346. // i.e. assume only one of the $hide_fields will be present
  1347. // and if found, hide the value as expando property of an <i> tag
  1348. }elseif (trim($value)) {
  1349. $d .= ', ' . $key . ':' . $value;
  1350. }
  1351. }
  1352. }
  1353. if (!empty($d)) {
  1354. $d = substr($d, 2) . ' - ';
  1355. }
  1356. return put_link(
  1357. $url,
  1358. $cat,
  1359. $title,
  1360. $kw . ereg_replace(
  1361. '\[((/?(b|big|i|small|sub|sup|u))|br/)\]',
  1362. '<\\1>',
  1363. htmlspecialchars($d . $linkdata['description'])
  1364. ) . ($kw ? '</i>' : ''),
  1365. $linkdata['on_homepage'] ? '1' : '0',
  1366. $linkdata['hidden'] ? '1' : '0'
  1367. );
  1368. // i.e. allow some BBcode tags, e.g. [b]...[/b]
  1369. }
  1370. /**
  1371. * CSV file import functions
  1372. * @author René Haentjens , Ghent University
  1373. */
  1374. function import_csvfile()
  1375. {
  1376. global $catlinkstatus; // Feedback message to user.
  1377. if (is_uploaded_file($filespec = $_FILES['import_file']['tmp_name'])
  1378. && filesize($filespec) && ($myFile = @ fopen($filespec, 'r'))
  1379. ) {
  1380. // read first line of file (column names) and find ',' or ';'
  1381. $listsep = strpos(
  1382. $colnames = trim(fgets($myFile)),
  1383. ','
  1384. ) !== false ? ',' : (strpos($colnames, ';') !== false ? ';' : '');
  1385. if ($listsep) {
  1386. $columns = array_map('strtolower', explode($listsep, $colnames));
  1387. if (in_array('url', $columns) && in_array('title', $columns)) {
  1388. $stats = array(
  1389. 0,
  1390. 0,
  1391. 0
  1392. ); // fails, updates, inserts
  1393. while (($data = api_fgetcsv($myFile, null, $listsep))) {
  1394. //
  1395. foreach ($data as $i => & $text) {
  1396. $linkdata[$columns[$i]] = $text;
  1397. }
  1398. $stats[import_link($linkdata)]++;
  1399. unset ($linkdata);
  1400. }
  1401. $catlinkstatus = '';
  1402. if ($stats[0]) {
  1403. $catlinkstatus .= $stats[0] . ' ' . get_lang('CsvLinesFailed');
  1404. }
  1405. if ($stats[1]) {
  1406. $catlinkstatus .= $stats[1] . ' ' . get_lang('CsvLinesOld');
  1407. }
  1408. if ($stats[2]) {
  1409. $catlinkstatus .= $stats[2] . ' ' . get_lang('CsvLinesNew');
  1410. }
  1411. } else {
  1412. $catlinkstatus = get_lang('CsvFileNoURL') . ($colnames ? get_lang('CsvFileLine1') . htmlspecialchars(substr($colnames, 0, 200)) . '...' : '');
  1413. }
  1414. } else {
  1415. $catlinkstatus = get_lang('CsvFileNoSeps') . ($colnames ? get_lang('CsvFileLine1') . htmlspecialchars(substr($colnames, 0, 200)) . '...' : '');
  1416. }
  1417. fclose($myFile);
  1418. } else {
  1419. $catlinkstatus = get_lang('CsvFileNotFound');
  1420. }
  1421. }
  1422. /**
  1423. * This function checks if the url is a vimeo link
  1424. * @author Julio Montoya
  1425. * @version 1.0
  1426. */
  1427. function isVimeoLink($url)
  1428. {
  1429. $isLink = strrpos($url, "vimeo.com");
  1430. return $isLink;
  1431. }
  1432. /**
  1433. * Get vimeo id from URL
  1434. * @param string $url
  1435. * @return bool|mixed
  1436. */
  1437. function getVimeoLinkId($url)
  1438. {
  1439. $possibleUrls = array(
  1440. 'http://www.vimeo.com/',
  1441. 'http://vimeo.com/',
  1442. 'https://www.vimeo.com/',
  1443. 'https://vimeo.com/'
  1444. );
  1445. $url = str_replace($possibleUrls, '', $url);
  1446. if (is_numeric($url)) {
  1447. return $url;
  1448. }
  1449. return false;
  1450. }
  1451. /**
  1452. * This function checks if the url is a youtube link
  1453. * @author Jorge Frisancho
  1454. * @author Julio Montoya - Fixing code
  1455. * @version 1.0
  1456. */
  1457. function is_youtube_link($url)
  1458. {
  1459. $is_youtube_link = strrpos($url, "youtube") || strrpos($url, "youtu.be");
  1460. return $is_youtube_link;
  1461. }
  1462. /**
  1463. * Get youtube id from an URL
  1464. * @param string $url
  1465. * @return string
  1466. */
  1467. function get_youtube_video_id($url)
  1468. {
  1469. // This is the length of YouTube's video IDs
  1470. $len = 11;
  1471. // The ID string starts after "v=", which is usually right after
  1472. // "youtube.com/watch?" in the URL
  1473. $pos = strpos($url, "v=");
  1474. $id = '';
  1475. //If false try other options
  1476. if ($pos === false) {
  1477. $url_parsed = parse_url($url);
  1478. //Youtube shortener
  1479. //http://youtu.be/ID
  1480. $pos = strpos($url, "youtu.be");
  1481. if ($pos == false) {
  1482. $id = '';
  1483. } else {
  1484. return substr($url_parsed['path'], 1);
  1485. }
  1486. //if empty try the youtube.com/embed/ID
  1487. if (empty($id)) {
  1488. $pos = strpos($url, "embed");
  1489. if ($pos === false) {
  1490. return '';
  1491. } else {
  1492. return substr($url_parsed['path'], 7);
  1493. }
  1494. }
  1495. } else {
  1496. // Offset the start location to match the beginning of the ID string
  1497. $pos += 2;
  1498. // Get the ID string and return it
  1499. $id = substr($url, $pos, $len);
  1500. return $id;
  1501. }
  1502. }